1 /*
2 Copyright (c) 2002, 2016, Oracle and/or its affiliates.
3 Copyright (c) 2011, 2020, MariaDB
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; version 2 of the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
17
18 #include "mariadb.h" /* NO_EMBEDDED_ACCESS_CHECKS */
19 #include "sql_priv.h"
20 #include "unireg.h"
21 #include "sql_prepare.h"
22 #include "sql_cache.h" // query_cache_*
23 #include "probes_mysql.h"
24 #include "sql_show.h" // append_identifier
25 #include "sql_db.h" // mysql_opt_change_db, mysql_change_db
26 #include "sql_acl.h" // *_ACL
27 #include "sql_array.h" // Dynamic_array
28 #include "log_event.h" // Query_log_event
29 #include "sql_derived.h" // mysql_handle_derived
30 #include "sql_cte.h"
31 #include "sql_select.h" // Virtual_tmp_table
32 #include "opt_trace.h"
33 #include "my_json_writer.h"
34
35 #ifdef USE_PRAGMA_IMPLEMENTATION
36 #pragma implementation
37 #endif
38 #include "sp_head.h"
39 #include "sp.h"
40 #include "sp_pcontext.h"
41 #include "sp_rcontext.h"
42 #include "sp_cache.h"
43 #include "set_var.h"
44 #include "sql_parse.h" // cleanup_items
45 #include "sql_base.h" // close_thread_tables
46 #include "transaction.h" // trans_commit_stmt
47 #include "sql_audit.h"
48 #include "debug_sync.h"
49 #ifdef WITH_WSREP
50 #include "wsrep_trans_observer.h"
51 #endif /* WITH_WSREP */
52
53 /*
54 Sufficient max length of printed destinations and frame offsets (all uints).
55 */
56 #define SP_INSTR_UINT_MAXLEN 8
57 #define SP_STMT_PRINT_MAXLEN 40
58
59
60 #include <my_user.h>
61
62 extern "C" uchar *sp_table_key(const uchar *ptr, size_t *plen, my_bool first);
63
64 /**
65 Helper function which operates on a THD object to set the query start_time to
66 the current time.
67
68 @param[in, out] thd The session object
69
70 */
71
reset_start_time_for_sp(THD * thd)72 static void reset_start_time_for_sp(THD *thd)
73 {
74 if (!thd->in_sub_stmt)
75 thd->set_start_time();
76 }
77
78
append_for_log(THD * thd,String * str)79 bool Item_splocal::append_for_log(THD *thd, String *str)
80 {
81 if (fix_fields_if_needed(thd, NULL))
82 return true;
83
84 if (limit_clause_param)
85 return str->append_ulonglong(val_uint());
86
87 /*
88 ROW variables are currently not allowed in select_list, e.g.:
89 SELECT row_variable;
90 ROW variables can appear in query parts where name is not important, e.g.:
91 SELECT ROW(1,2)=row_variable FROM t1;
92 So we can skip using NAME_CONST() and use ROW() constants directly.
93 */
94 if (type_handler() == &type_handler_row)
95 return append_value_for_log(thd, str);
96
97 if (str->append(STRING_WITH_LEN(" NAME_CONST('")) ||
98 str->append(&m_name) ||
99 str->append(STRING_WITH_LEN("',")))
100 return true;
101 return append_value_for_log(thd, str) || str->append(')');
102 }
103
104
append_value_for_log(THD * thd,String * str)105 bool Item_splocal::append_value_for_log(THD *thd, String *str)
106 {
107 StringBuffer<STRING_BUFFER_USUAL_SIZE> str_value_holder(&my_charset_latin1);
108 Item *item= this_item();
109 String *str_value= item->type_handler()->print_item_value(thd, item,
110 &str_value_holder);
111 return str_value ?
112 str->append(*str_value) :
113 str->append(STRING_WITH_LEN("NULL"));
114 }
115
116
append_for_log(THD * thd,String * str)117 bool Item_splocal_row_field::append_for_log(THD *thd, String *str)
118 {
119 if (fix_fields_if_needed(thd, NULL))
120 return true;
121
122 if (limit_clause_param)
123 return str->append_ulonglong(val_uint());
124
125 if (str->append(STRING_WITH_LEN(" NAME_CONST('")) ||
126 str->append(&m_name) ||
127 str->append(".") ||
128 str->append(&m_field_name) ||
129 str->append(STRING_WITH_LEN("',")))
130 return true;
131 return append_value_for_log(thd, str) || str->append(')');
132 }
133
134
135 /**
136 Returns a combination of:
137 - sp_head::MULTI_RESULTS: added if the 'cmd' is a command that might
138 result in multiple result sets being sent back.
139 - sp_head::CONTAINS_DYNAMIC_SQL: added if 'cmd' is one of PREPARE,
140 EXECUTE, DEALLOCATE.
141 */
142
143 uint
sp_get_flags_for_command(LEX * lex)144 sp_get_flags_for_command(LEX *lex)
145 {
146 uint flags;
147
148 switch (lex->sql_command) {
149 case SQLCOM_SELECT:
150 if (lex->result && !lex->analyze_stmt)
151 {
152 flags= 0; /* This is a SELECT with INTO clause */
153 break;
154 }
155 /* fallthrough */
156 case SQLCOM_ANALYZE:
157 case SQLCOM_OPTIMIZE:
158 case SQLCOM_PRELOAD_KEYS:
159 case SQLCOM_ASSIGN_TO_KEYCACHE:
160 case SQLCOM_CHECKSUM:
161 case SQLCOM_CHECK:
162 case SQLCOM_HA_READ:
163 case SQLCOM_SHOW_AUTHORS:
164 case SQLCOM_SHOW_BINLOGS:
165 case SQLCOM_SHOW_BINLOG_EVENTS:
166 case SQLCOM_SHOW_RELAYLOG_EVENTS:
167 case SQLCOM_SHOW_CHARSETS:
168 case SQLCOM_SHOW_COLLATIONS:
169 case SQLCOM_SHOW_CONTRIBUTORS:
170 case SQLCOM_SHOW_CREATE:
171 case SQLCOM_SHOW_CREATE_DB:
172 case SQLCOM_SHOW_CREATE_FUNC:
173 case SQLCOM_SHOW_CREATE_PROC:
174 case SQLCOM_SHOW_CREATE_PACKAGE:
175 case SQLCOM_SHOW_CREATE_PACKAGE_BODY:
176 case SQLCOM_SHOW_CREATE_EVENT:
177 case SQLCOM_SHOW_CREATE_TRIGGER:
178 case SQLCOM_SHOW_CREATE_USER:
179 case SQLCOM_SHOW_DATABASES:
180 case SQLCOM_SHOW_ERRORS:
181 case SQLCOM_SHOW_EXPLAIN:
182 case SQLCOM_SHOW_FIELDS:
183 case SQLCOM_SHOW_FUNC_CODE:
184 case SQLCOM_SHOW_GENERIC:
185 case SQLCOM_SHOW_GRANTS:
186 case SQLCOM_SHOW_ENGINE_STATUS:
187 case SQLCOM_SHOW_ENGINE_LOGS:
188 case SQLCOM_SHOW_ENGINE_MUTEX:
189 case SQLCOM_SHOW_EVENTS:
190 case SQLCOM_SHOW_KEYS:
191 case SQLCOM_SHOW_MASTER_STAT:
192 case SQLCOM_SHOW_OPEN_TABLES:
193 case SQLCOM_SHOW_PRIVILEGES:
194 case SQLCOM_SHOW_PROCESSLIST:
195 case SQLCOM_SHOW_PROC_CODE:
196 case SQLCOM_SHOW_PACKAGE_BODY_CODE:
197 case SQLCOM_SHOW_SLAVE_HOSTS:
198 case SQLCOM_SHOW_SLAVE_STAT:
199 case SQLCOM_SHOW_STATUS:
200 case SQLCOM_SHOW_STATUS_FUNC:
201 case SQLCOM_SHOW_STATUS_PROC:
202 case SQLCOM_SHOW_STATUS_PACKAGE:
203 case SQLCOM_SHOW_STATUS_PACKAGE_BODY:
204 case SQLCOM_SHOW_STORAGE_ENGINES:
205 case SQLCOM_SHOW_TABLES:
206 case SQLCOM_SHOW_TABLE_STATUS:
207 case SQLCOM_SHOW_VARIABLES:
208 case SQLCOM_SHOW_WARNS:
209 case SQLCOM_REPAIR:
210 flags= sp_head::MULTI_RESULTS;
211 break;
212 /*
213 EXECUTE statement may return a result set, but doesn't have to.
214 We can't, however, know it in advance, and therefore must add
215 this statement here. This is ok, as is equivalent to a result-set
216 statement within an IF condition.
217 */
218 case SQLCOM_EXECUTE:
219 case SQLCOM_EXECUTE_IMMEDIATE:
220 flags= sp_head::MULTI_RESULTS | sp_head::CONTAINS_DYNAMIC_SQL;
221 break;
222 case SQLCOM_PREPARE:
223 case SQLCOM_DEALLOCATE_PREPARE:
224 flags= sp_head::CONTAINS_DYNAMIC_SQL;
225 break;
226 case SQLCOM_CREATE_TABLE:
227 case SQLCOM_CREATE_SEQUENCE:
228 if (lex->tmp_table())
229 flags= 0;
230 else
231 flags= sp_head::HAS_COMMIT_OR_ROLLBACK;
232 break;
233 case SQLCOM_DROP_TABLE:
234 case SQLCOM_DROP_SEQUENCE:
235 if (lex->tmp_table())
236 flags= 0;
237 else
238 flags= sp_head::HAS_COMMIT_OR_ROLLBACK;
239 break;
240 case SQLCOM_FLUSH:
241 flags= sp_head::HAS_SQLCOM_FLUSH;
242 break;
243 case SQLCOM_RESET:
244 flags= sp_head::HAS_SQLCOM_RESET;
245 break;
246 case SQLCOM_CREATE_INDEX:
247 case SQLCOM_CREATE_DB:
248 case SQLCOM_CREATE_PACKAGE:
249 case SQLCOM_CREATE_PACKAGE_BODY:
250 case SQLCOM_CREATE_VIEW:
251 case SQLCOM_CREATE_TRIGGER:
252 case SQLCOM_CREATE_USER:
253 case SQLCOM_CREATE_ROLE:
254 case SQLCOM_ALTER_TABLE:
255 case SQLCOM_ALTER_SEQUENCE:
256 case SQLCOM_ALTER_USER:
257 case SQLCOM_GRANT:
258 case SQLCOM_GRANT_ROLE:
259 case SQLCOM_REVOKE:
260 case SQLCOM_REVOKE_ROLE:
261 case SQLCOM_BEGIN:
262 case SQLCOM_RENAME_TABLE:
263 case SQLCOM_RENAME_USER:
264 case SQLCOM_DROP_INDEX:
265 case SQLCOM_DROP_DB:
266 case SQLCOM_DROP_PACKAGE:
267 case SQLCOM_DROP_PACKAGE_BODY:
268 case SQLCOM_REVOKE_ALL:
269 case SQLCOM_DROP_USER:
270 case SQLCOM_DROP_ROLE:
271 case SQLCOM_DROP_VIEW:
272 case SQLCOM_DROP_TRIGGER:
273 case SQLCOM_TRUNCATE:
274 case SQLCOM_COMMIT:
275 case SQLCOM_ROLLBACK:
276 case SQLCOM_LOAD:
277 case SQLCOM_LOCK_TABLES:
278 case SQLCOM_CREATE_PROCEDURE:
279 case SQLCOM_CREATE_SPFUNCTION:
280 case SQLCOM_ALTER_PROCEDURE:
281 case SQLCOM_ALTER_FUNCTION:
282 case SQLCOM_DROP_PROCEDURE:
283 case SQLCOM_DROP_FUNCTION:
284 case SQLCOM_CREATE_EVENT:
285 case SQLCOM_ALTER_EVENT:
286 case SQLCOM_DROP_EVENT:
287 case SQLCOM_INSTALL_PLUGIN:
288 case SQLCOM_UNINSTALL_PLUGIN:
289 flags= sp_head::HAS_COMMIT_OR_ROLLBACK;
290 break;
291 case SQLCOM_DELETE:
292 case SQLCOM_DELETE_MULTI:
293 {
294 /*
295 DELETE normally doesn't return resultset, but there are 3 exceptions:
296 - DELETE ... RETURNING
297 - EXPLAIN DELETE ...
298 - ANALYZE DELETE ...
299 */
300 if (lex->first_select_lex()->item_list.is_empty() &&
301 !lex->describe && !lex->analyze_stmt)
302 flags= 0;
303 else
304 flags= sp_head::MULTI_RESULTS;
305 break;
306 }
307 case SQLCOM_UPDATE:
308 case SQLCOM_UPDATE_MULTI:
309 case SQLCOM_INSERT:
310 case SQLCOM_REPLACE:
311 case SQLCOM_REPLACE_SELECT:
312 case SQLCOM_INSERT_SELECT:
313 {
314 if (!lex->describe && !lex->analyze_stmt)
315 flags= 0;
316 else
317 flags= sp_head::MULTI_RESULTS;
318 break;
319 }
320 default:
321 flags= 0;
322 break;
323 }
324 return flags;
325 }
326
327 /**
328 Prepare an Item for evaluation (call of fix_fields).
329
330 @param it_addr pointer on item refernce
331 @param cols expected number of elements (1 for scalar, >=1 for ROWs)
332
333 @retval
334 NULL error
335 @retval
336 non-NULL prepared item
337 */
338
sp_prepare_func_item(Item ** it_addr,uint cols)339 Item *THD::sp_prepare_func_item(Item **it_addr, uint cols)
340 {
341 DBUG_ENTER("THD::sp_prepare_func_item");
342 Item *res= sp_fix_func_item(it_addr);
343 if (res && res->check_cols(cols))
344 DBUG_RETURN(NULL);
345 DBUG_RETURN(res);
346 }
347
348
349 /**
350 Fix an Item for evaluation for SP.
351 */
352
sp_fix_func_item(Item ** it_addr)353 Item *THD::sp_fix_func_item(Item **it_addr)
354 {
355 DBUG_ENTER("THD::sp_fix_func_item");
356 if ((*it_addr)->fix_fields_if_needed(this, it_addr))
357 {
358 DBUG_PRINT("info", ("fix_fields() failed"));
359 DBUG_RETURN(NULL);
360 }
361 it_addr= (*it_addr)->this_item_addr(this, it_addr);
362
363 if ((*it_addr)->fix_fields_if_needed(this, it_addr))
364 {
365 DBUG_PRINT("info", ("fix_fields() failed"));
366 DBUG_RETURN(NULL);
367 }
368 DBUG_RETURN(*it_addr);
369 }
370
371
372 /**
373 Evaluate an expression and store the result in the field.
374
375 @param result_field the field to store the result
376 @param expr_item_ptr the root item of the expression
377
378 @retval
379 FALSE on success
380 @retval
381 TRUE on error
382 */
383
sp_eval_expr(Field * result_field,Item ** expr_item_ptr)384 bool THD::sp_eval_expr(Field *result_field, Item **expr_item_ptr)
385 {
386 DBUG_ENTER("THD::sp_eval_expr");
387 DBUG_ASSERT(*expr_item_ptr);
388 Sp_eval_expr_state state(this);
389 /* Save the value in the field. Convert the value if needed. */
390 DBUG_RETURN(result_field->sp_prepare_and_store_item(this, expr_item_ptr));
391 }
392
393
394 /**
395 Create temporary sp_name object from MDL key.
396
397 @note The lifetime of this object is bound to the lifetime of the MDL_key.
398 This should be fine as sp_name objects created by this constructor
399 are mainly used for SP-cache lookups.
400
401 @param key MDL key containing database and routine name.
402 @param qname_buff Buffer to be used for storing quoted routine name
403 (should be at least 2*NAME_LEN+1+1 bytes).
404 */
405
sp_name(const MDL_key * key,char * qname_buff)406 sp_name::sp_name(const MDL_key *key, char *qname_buff)
407 :Database_qualified_name(key->db_name(), key->db_name_length(),
408 key->name(), key->name_length()),
409 m_explicit_name(false)
410 {
411 if (m_db.length)
412 strxmov(qname_buff, m_db.str, ".", m_name.str, NullS);
413 else
414 strmov(qname_buff, m_name.str);
415 }
416
417
418 /**
419 Check that the name 'ident' is ok. It's assumed to be an 'ident'
420 from the parser, so we only have to check length and trailing spaces.
421 The former is a standard requirement (and 'show status' assumes a
422 non-empty name), the latter is a mysql:ism as trailing spaces are
423 removed by get_field().
424
425 @retval
426 TRUE bad name
427 @retval
428 FALSE name is ok
429 */
430
431 bool
check_routine_name(const LEX_CSTRING * ident)432 check_routine_name(const LEX_CSTRING *ident)
433 {
434 DBUG_ASSERT(ident);
435 DBUG_ASSERT(ident->str);
436
437 if (!ident->str[0] || ident->str[ident->length-1] == ' ')
438 {
439 my_error(ER_SP_WRONG_NAME, MYF(0), ident->str);
440 return TRUE;
441 }
442 if (check_ident_length(ident))
443 return TRUE;
444
445 return FALSE;
446 }
447
448
449 /*
450 *
451 * sp_head
452 *
453 */
454
create(sp_package * parent,const Sp_handler * handler,enum_sp_aggregate_type agg_type)455 sp_head *sp_head::create(sp_package *parent, const Sp_handler *handler,
456 enum_sp_aggregate_type agg_type)
457 {
458 MEM_ROOT own_root;
459 init_sql_alloc(&own_root, "sp_head", MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC,
460 MYF(0));
461 sp_head *sp;
462 if (!(sp= new (&own_root) sp_head(&own_root, parent, handler, agg_type)))
463 free_root(&own_root, MYF(0));
464
465 return sp;
466 }
467
468
destroy(sp_head * sp)469 void sp_head::destroy(sp_head *sp)
470 {
471 if (sp)
472 {
473 /* Make a copy of main_mem_root as free_root will free the sp */
474 MEM_ROOT own_root= sp->main_mem_root;
475 DBUG_PRINT("info", ("mem_root %p moved to %p",
476 &sp->mem_root, &own_root));
477 delete sp;
478
479
480 free_root(&own_root, MYF(0));
481 }
482 }
483
484 /*
485 *
486 * sp_head
487 *
488 */
489
sp_head(MEM_ROOT * mem_root_arg,sp_package * parent,const Sp_handler * sph,enum_sp_aggregate_type agg_type)490 sp_head::sp_head(MEM_ROOT *mem_root_arg, sp_package *parent,
491 const Sp_handler *sph, enum_sp_aggregate_type agg_type)
492 :Query_arena(NULL, STMT_INITIALIZED_FOR_SP),
493 Database_qualified_name(&null_clex_str, &null_clex_str),
494 main_mem_root(*mem_root_arg),
495 m_parent(parent),
496 m_handler(sph),
497 m_flags(0),
498 m_tmp_query(NULL),
499 m_explicit_name(false),
500 /*
501 FIXME: the only use case when name is NULL is events, and it should
502 be rewritten soon. Remove the else part and replace 'if' with
503 an assert when this is done.
504 */
505 m_qname(null_clex_str),
506 m_params(null_clex_str),
507 m_body(null_clex_str),
508 m_body_utf8(null_clex_str),
509 m_defstr(null_clex_str),
510 m_sp_cache_version(0),
511 m_creation_ctx(0),
512 unsafe_flags(0),
513 m_created(0),
514 m_modified(0),
515 m_recursion_level(0),
516 m_next_cached_sp(0),
517 m_param_begin(NULL),
518 m_param_end(NULL),
519 m_body_begin(NULL),
520 m_thd_root(NULL),
521 m_thd(NULL),
522 m_pcont(new (&main_mem_root) sp_pcontext()),
523 m_cont_level(0)
524 {
525 mem_root= &main_mem_root;
526
527 set_chistics_agg_type(agg_type);
528 m_first_instance= this;
529 m_first_free_instance= this;
530 m_last_cached_sp= this;
531
532 m_return_field_def.charset = NULL;
533
534 DBUG_ENTER("sp_head::sp_head");
535
536 m_security_ctx.init();
537 m_backpatch.empty();
538 m_backpatch_goto.empty();
539 m_cont_backpatch.empty();
540 m_lex.empty();
541 my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8, MYF(0));
542 my_hash_init(&m_sptabs, system_charset_info, 0, 0, 0, sp_table_key, 0, 0);
543 my_hash_init(&m_sroutines, system_charset_info, 0, 0, 0, sp_sroutine_key,
544 0, 0);
545 m_security_ctx.init();
546
547 DBUG_VOID_RETURN;
548 }
549
550
create(LEX * top_level_lex,const sp_name * name,const Sp_handler * sph)551 sp_package *sp_package::create(LEX *top_level_lex, const sp_name *name,
552 const Sp_handler *sph)
553 {
554 MEM_ROOT own_root;
555 init_sql_alloc(&own_root, "sp_package", MEM_ROOT_BLOCK_SIZE,
556 MEM_ROOT_PREALLOC, MYF(0));
557 sp_package *sp;
558 if (!(sp= new (&own_root) sp_package(&own_root, top_level_lex, name, sph)))
559 free_root(&own_root, MYF(0));
560
561 return sp;
562 }
563
564
sp_package(MEM_ROOT * mem_root_arg,LEX * top_level_lex,const sp_name * name,const Sp_handler * sph)565 sp_package::sp_package(MEM_ROOT *mem_root_arg,
566 LEX *top_level_lex,
567 const sp_name *name,
568 const Sp_handler *sph)
569 :sp_head(mem_root_arg, NULL, sph, DEFAULT_AGGREGATE),
570 m_current_routine(NULL),
571 m_top_level_lex(top_level_lex),
572 m_rcontext(NULL),
573 m_invoked_subroutine_count(0),
574 m_is_instantiated(false),
575 m_is_cloning_routine(false)
576 {
577 init_sp_name(name);
578 }
579
580
~sp_package()581 sp_package::~sp_package()
582 {
583 m_routine_implementations.cleanup();
584 m_routine_declarations.cleanup();
585 m_body= null_clex_str;
586 if (m_current_routine)
587 sp_head::destroy(m_current_routine->sphead);
588 delete m_rcontext;
589 }
590
591
592 /*
593 Test if two routines have equal specifications
594 */
595
eq_routine_spec(const sp_head * sp) const596 bool sp_head::eq_routine_spec(const sp_head *sp) const
597 {
598 // TODO: Add tests for equal return data types (in case of FUNCTION)
599 // TODO: Add tests for equal argument data types
600 return
601 m_handler->type() == sp->m_handler->type() &&
602 m_pcont->context_var_count() == sp->m_pcont->context_var_count();
603 }
604
605
validate_after_parser(THD * thd)606 bool sp_package::validate_after_parser(THD *thd)
607 {
608 if (m_handler->type() != TYPE_ENUM_PACKAGE_BODY)
609 return false;
610 sp_head *sp= sp_cache_lookup(&thd->sp_package_spec_cache, this);
611 sp_package *spec= sp ? sp->get_package() : NULL;
612 DBUG_ASSERT(spec); // CREATE PACKAGE must already be cached
613 return validate_public_routines(thd, spec) ||
614 validate_private_routines(thd);
615 }
616
617
validate_public_routines(THD * thd,sp_package * spec)618 bool sp_package::validate_public_routines(THD *thd, sp_package *spec)
619 {
620 /*
621 Check that all routines declared in CREATE PACKAGE
622 have implementations in CREATE PACKAGE BODY.
623 */
624 List_iterator<LEX> it(spec->m_routine_declarations);
625 for (LEX *lex; (lex= it++); )
626 {
627 bool found= false;
628 DBUG_ASSERT(lex->sphead);
629 List_iterator<LEX> it2(m_routine_implementations);
630 for (LEX *lex2; (lex2= it2++); )
631 {
632 DBUG_ASSERT(lex2->sphead);
633 if (Sp_handler::eq_routine_name(lex2->sphead->m_name,
634 lex->sphead->m_name) &&
635 lex2->sphead->eq_routine_spec(lex->sphead))
636 {
637 found= true;
638 break;
639 }
640 }
641 if (!found)
642 {
643 my_error(ER_PACKAGE_ROUTINE_IN_SPEC_NOT_DEFINED_IN_BODY, MYF(0),
644 ErrConvDQName(lex->sphead).ptr());
645 return true;
646 }
647 }
648 return false;
649 }
650
651
validate_private_routines(THD * thd)652 bool sp_package::validate_private_routines(THD *thd)
653 {
654 /*
655 Check that all forwad declarations in
656 CREATE PACKAGE BODY have implementations.
657 */
658 List_iterator<LEX> it(m_routine_declarations);
659 for (LEX *lex; (lex= it++); )
660 {
661 bool found= false;
662 DBUG_ASSERT(lex->sphead);
663 List_iterator<LEX> it2(m_routine_implementations);
664 for (LEX *lex2; (lex2= it2++); )
665 {
666 DBUG_ASSERT(lex2->sphead);
667 if (Sp_handler::eq_routine_name(lex2->sphead->m_name,
668 lex->sphead->m_name) &&
669 lex2->sphead->eq_routine_spec(lex->sphead))
670 {
671 found= true;
672 break;
673 }
674 }
675 if (!found)
676 {
677 my_error(ER_PACKAGE_ROUTINE_FORWARD_DECLARATION_NOT_DEFINED, MYF(0),
678 ErrConvDQName(lex->sphead).ptr());
679 return true;
680 }
681 }
682 return false;
683 }
684
685
find(const LEX_CSTRING & name,stored_procedure_type type)686 LEX *sp_package::LexList::find(const LEX_CSTRING &name,
687 stored_procedure_type type)
688 {
689 List_iterator<LEX> it(*this);
690 for (LEX *lex; (lex= it++); )
691 {
692 DBUG_ASSERT(lex->sphead);
693 const char *dot;
694 if (lex->sphead->m_handler->type() == type &&
695 (dot= strrchr(lex->sphead->m_name.str, '.')))
696 {
697 size_t ofs= dot + 1 - lex->sphead->m_name.str;
698 LEX_CSTRING non_qualified_sphead_name= lex->sphead->m_name;
699 non_qualified_sphead_name.str+= ofs;
700 non_qualified_sphead_name.length-= ofs;
701 if (Sp_handler::eq_routine_name(non_qualified_sphead_name, name))
702 return lex;
703 }
704 }
705 return NULL;
706 }
707
708
find_qualified(const LEX_CSTRING & name,stored_procedure_type type)709 LEX *sp_package::LexList::find_qualified(const LEX_CSTRING &name,
710 stored_procedure_type type)
711 {
712 List_iterator<LEX> it(*this);
713 for (LEX *lex; (lex= it++); )
714 {
715 DBUG_ASSERT(lex->sphead);
716 if (lex->sphead->m_handler->type() == type &&
717 Sp_handler::eq_routine_name(lex->sphead->m_name, name))
718 return lex;
719 }
720 return NULL;
721 }
722
723
724 void
init(LEX * lex)725 sp_head::init(LEX *lex)
726 {
727 DBUG_ENTER("sp_head::init");
728
729 lex->spcont= m_pcont;
730
731 if (!lex->spcont)
732 DBUG_VOID_RETURN;
733
734 /*
735 Altough trg_table_fields list is used only in triggers we init for all
736 types of stored procedures to simplify reset_lex()/restore_lex() code.
737 */
738 lex->trg_table_fields.empty();
739
740 DBUG_VOID_RETURN;
741 }
742
743
744 void
init_sp_name(const sp_name * spname)745 sp_head::init_sp_name(const sp_name *spname)
746 {
747 DBUG_ENTER("sp_head::init_sp_name");
748
749 /* Must be initialized in the parser. */
750
751 DBUG_ASSERT(spname && spname->m_db.str && spname->m_db.length);
752
753 /* We have to copy strings to get them into the right memroot. */
754 Database_qualified_name::copy(&main_mem_root, spname->m_db, spname->m_name);
755 m_explicit_name= spname->m_explicit_name;
756 DBUG_VOID_RETURN;
757 }
758
759
760 void
set_body_start(THD * thd,const char * begin_ptr)761 sp_head::set_body_start(THD *thd, const char *begin_ptr)
762 {
763 m_body_begin= begin_ptr;
764 thd->m_parser_state->m_lip.body_utf8_start(thd, begin_ptr);
765 }
766
767
768 void
set_stmt_end(THD * thd)769 sp_head::set_stmt_end(THD *thd)
770 {
771 Lex_input_stream *lip= & thd->m_parser_state->m_lip; /* shortcut */
772 const char *end_ptr= lip->get_cpp_ptr(); /* shortcut */
773
774 /* Make the string of parameters. */
775
776 if (m_param_begin && m_param_end)
777 {
778 m_params.length= m_param_end - m_param_begin;
779 m_params.str= thd->strmake(m_param_begin, m_params.length);
780 }
781
782 /* Remember end pointer for further dumping of whole statement. */
783
784 thd->lex->stmt_definition_end= end_ptr;
785
786 /* Make the string of body (in the original character set). */
787
788 m_body.length= end_ptr - m_body_begin;
789 m_body.str= thd->strmake(m_body_begin, m_body.length);
790 trim_whitespace(thd->charset(), &m_body);
791
792 /* Make the string of UTF-body. */
793
794 lip->body_utf8_append(end_ptr);
795
796 m_body_utf8.length= lip->get_body_utf8_length();
797 m_body_utf8.str= thd->strmake(lip->get_body_utf8_str(), m_body_utf8.length);
798 trim_whitespace(thd->charset(), &m_body_utf8);
799
800 /*
801 Make the string of whole stored-program-definition query (in the
802 original character set).
803 */
804
805 m_defstr.length= end_ptr - lip->get_cpp_buf();
806 m_defstr.str= thd->strmake(lip->get_cpp_buf(), m_defstr.length);
807 trim_whitespace(thd->charset(), &m_defstr);
808 }
809
810
~sp_head()811 sp_head::~sp_head()
812 {
813 LEX *lex;
814 sp_instr *i;
815 DBUG_ENTER("sp_head::~sp_head");
816
817 /* sp_head::restore_thd_mem_root() must already have been called. */
818 DBUG_ASSERT(m_thd == NULL);
819
820 for (uint ip = 0 ; (i = get_instr(ip)) ; ip++)
821 delete i;
822 delete_dynamic(&m_instr);
823 delete m_pcont;
824 free_items();
825
826 /*
827 If we have non-empty LEX stack then we just came out of parser with
828 error. Now we should delete all auxilary LEXes and restore original
829 THD::lex. It is safe to not update LEX::ptr because further query
830 string parsing and execution will be stopped anyway.
831 */
832 while ((lex= (LEX *)m_lex.pop()))
833 {
834 THD *thd= lex->thd;
835 thd->lex->sphead= NULL;
836 lex_end(thd->lex);
837 delete thd->lex;
838 thd->lex= lex;
839 }
840
841 my_hash_free(&m_sptabs);
842 my_hash_free(&m_sroutines);
843
844 sp_head::destroy(m_next_cached_sp);
845
846 DBUG_VOID_RETURN;
847 }
848
849
cleanup()850 void sp_package::LexList::cleanup()
851 {
852 List_iterator<LEX> it(*this);
853 for (LEX *lex; (lex= it++); )
854 {
855 lex_end(lex);
856 delete lex;
857 }
858 }
859
860
861 /**
862 This is only used for result fields from functions (both during
863 fix_length_and_dec() and evaluation).
864 */
865
866 Field *
create_result_field(uint field_max_length,const LEX_CSTRING * field_name,TABLE * table) const867 sp_head::create_result_field(uint field_max_length, const LEX_CSTRING *field_name,
868 TABLE *table) const
869 {
870 Field *field;
871 LEX_CSTRING name;
872
873 DBUG_ENTER("sp_head::create_result_field");
874
875 /*
876 m_return_field_def.length is always set to the field length calculated
877 by the parser, according to the RETURNS clause. See prepare_create_field()
878 in sql_table.cc. Value examples, depending on data type:
879 - 11 for INT (character representation length)
880 - 20 for BIGINT (character representation length)
881 - 22 for DOUBLE (character representation length)
882 - N for CHAR(N) CHARACTER SET latin1 (octet length)
883 - 3*N for CHAR(N) CHARACTER SET utf8 (octet length)
884 - 8 for blob-alike data types (packed length !!!)
885
886 field_max_length is also set according to the data type in the RETURNS
887 clause but can have different values depending on the execution stage:
888
889 1. During direct execution:
890 field_max_length is 0, because Item_func_sp::fix_length_and_dec() has
891 not been called yet, so Item_func_sp::max_length is 0 by default.
892
893 2a. During PREPARE:
894 field_max_length is 0, because Item_func_sp::fix_length_and_dec()
895 has not been called yet. It's called after create_result_field().
896
897 2b. During EXEC:
898 field_max_length is set to the maximum possible octet length of the
899 RETURNS data type.
900 - N for CHAR(N) CHARACTER SET latin1 (octet length)
901 - 3*N for CHAR(N) CHARACTER SET utf8 (octet length)
902 - 255 for TINYBLOB (octet length, not packed length !!!)
903
904 Perhaps we should refactor prepare_create_field() to set
905 Create_field::length to maximum octet length for BLOBs,
906 instead of packed length).
907
908 Note, for integer data types, field_max_length can be bigger
909 than the user specified length, e.g. a field of the INT(1) data type
910 is translated to the item with max_length=11.
911 */
912 DBUG_ASSERT(field_max_length <= m_return_field_def.length ||
913 m_return_field_def.type_handler()->cmp_type() == INT_RESULT ||
914 (current_thd->stmt_arena->is_stmt_execute() &&
915 m_return_field_def.length == 8 &&
916 (m_return_field_def.pack_flag &
917 (FIELDFLAG_BLOB|FIELDFLAG_GEOM))));
918
919 if (field_name)
920 name= *field_name;
921 else
922 name= m_name;
923 field= m_return_field_def.make_field(table->s, /* TABLE_SHARE ptr */
924 table->in_use->mem_root,
925 &name);
926
927 field->vcol_info= m_return_field_def.vcol_info;
928 if (field)
929 field->init(table);
930
931 DBUG_RETURN(field);
932 }
933
934
cmp_rqp_locations(Rewritable_query_parameter * const * a,Rewritable_query_parameter * const * b)935 int cmp_rqp_locations(Rewritable_query_parameter * const *a,
936 Rewritable_query_parameter * const *b)
937 {
938 return (int)((*a)->pos_in_query - (*b)->pos_in_query);
939 }
940
941
942 /*
943 StoredRoutinesBinlogging
944 This paragraph applies only to statement-based binlogging. Row-based
945 binlogging does not need anything special like this.
946
947 Top-down overview:
948
949 1. Statements
950
951 Statements that have is_update_query(stmt) == TRUE are written into the
952 binary log verbatim.
953 Examples:
954 UPDATE tbl SET tbl.x = spfunc_w_side_effects()
955 UPDATE tbl SET tbl.x=1 WHERE spfunc_w_side_effect_that_returns_false(tbl.y)
956
957 Statements that have is_update_query(stmt) == FALSE (e.g. SELECTs) are not
958 written into binary log. Instead we catch function calls the statement
959 makes and write it into binary log separately (see #3).
960
961 2. PROCEDURE calls
962
963 CALL statements are not written into binary log. Instead
964 * Any FUNCTION invocation (in SET, IF, WHILE, OPEN CURSOR and other SP
965 instructions) is written into binlog separately.
966
967 * Each statement executed in SP is binlogged separately, according to rules
968 in #1, with the exception that we modify query string: we replace uses
969 of SP local variables with NAME_CONST('spvar_name', <spvar-value>) calls.
970 This substitution is done in subst_spvars().
971
972 3. FUNCTION calls
973
974 In sp_head::execute_function(), we check
975 * If this function invocation is done from a statement that is written
976 into the binary log.
977 * If there were any attempts to write events to the binary log during
978 function execution (grep for start_union_events and stop_union_events)
979
980 If the answers are No and Yes, we write the function call into the binary
981 log as "SELECT spfunc(<param1value>, <param2value>, ...)"
982
983
984 4. Miscellaneous issues.
985
986 4.1 User variables.
987
988 When we call mysql_bin_log.write() for an SP statement, thd->user_var_events
989 must hold set<{var_name, value}> pairs for all user variables used during
990 the statement execution.
991 This set is produced by tracking user variable reads during statement
992 execution.
993
994 For SPs, this has the following implications:
995 1) thd->user_var_events may contain events from several SP statements and
996 needs to be valid after exection of these statements was finished. In
997 order to achieve that, we
998 * Allocate user_var_events array elements on appropriate mem_root (grep
999 for user_var_events_alloc).
1000 * Use is_query_in_union() to determine if user_var_event is created.
1001
1002 2) We need to empty thd->user_var_events after we have wrote a function
1003 call. This is currently done by making
1004 reset_dynamic(&thd->user_var_events);
1005 calls in several different places. (TODO cosider moving this into
1006 mysql_bin_log.write() function)
1007
1008 4.2 Auto_increment storage in binlog
1009
1010 As we may write two statements to binlog from one single logical statement
1011 (case of "SELECT func1(),func2()": it is binlogged as "SELECT func1()" and
1012 then "SELECT func2()"), we need to reset auto_increment binlog variables
1013 after each binlogged SELECT. Otherwise, the auto_increment value of the
1014 first SELECT would be used for the second too.
1015 */
1016
1017
1018 /**
1019 Replace thd->query{_length} with a string that one can write to
1020 the binlog.
1021
1022 The binlog-suitable string is produced by replacing references to SP local
1023 variables with NAME_CONST('sp_var_name', value) calls.
1024
1025 @param thd Current thread.
1026 @param instr Instruction (we look for Item_splocal instances in
1027 instr->free_list)
1028 @param query_str Original query string
1029
1030 @return
1031 - FALSE on success.
1032 thd->query{_length} either has been appropriately replaced or there
1033 is no need for replacements.
1034 - TRUE out of memory error.
1035 */
1036
1037 static bool
subst_spvars(THD * thd,sp_instr * instr,LEX_STRING * query_str)1038 subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
1039 {
1040 DBUG_ENTER("subst_spvars");
1041
1042 Dynamic_array<Rewritable_query_parameter*> rewritables;
1043 char *pbuf;
1044 StringBuffer<512> qbuf;
1045 Copy_query_with_rewrite acc(thd, query_str->str, query_str->length, &qbuf);
1046
1047 /* Find rewritable Items used in this statement */
1048 for (Item *item= instr->free_list; item; item= item->next)
1049 {
1050 Rewritable_query_parameter *rqp= item->get_rewritable_query_parameter();
1051 if (rqp && rqp->pos_in_query)
1052 rewritables.append(rqp);
1053 }
1054 if (!rewritables.elements())
1055 DBUG_RETURN(FALSE);
1056
1057 rewritables.sort(cmp_rqp_locations);
1058
1059 thd->query_name_consts= (uint)rewritables.elements();
1060
1061 for (Rewritable_query_parameter **rqp= rewritables.front();
1062 rqp <= rewritables.back(); rqp++)
1063 {
1064 if (acc.append(*rqp))
1065 DBUG_RETURN(TRUE);
1066 }
1067 if (acc.finalize())
1068 DBUG_RETURN(TRUE);
1069
1070 /*
1071 Allocate additional space at the end of the new query string for the
1072 query_cache_send_result_to_client function.
1073
1074 The query buffer layout is:
1075 buffer :==
1076 <statement> The input statement(s)
1077 '\0' Terminating null char
1078 <length> Length of following current database name 2
1079 <db_name> Name of current database
1080 <flags> Flags struct
1081 */
1082 size_t buf_len= (qbuf.length() + 1 + QUERY_CACHE_DB_LENGTH_SIZE +
1083 thd->db.length + QUERY_CACHE_FLAGS_SIZE + 1);
1084 if ((pbuf= (char *) alloc_root(thd->mem_root, buf_len)))
1085 {
1086 char *ptr= pbuf + qbuf.length();
1087 memcpy(pbuf, qbuf.ptr(), qbuf.length());
1088 *ptr= 0;
1089 int2store(ptr+1, thd->db.length);
1090 }
1091 else
1092 DBUG_RETURN(TRUE);
1093
1094 thd->set_query(pbuf, qbuf.length());
1095
1096 DBUG_RETURN(FALSE);
1097 }
1098
1099
recursion_level_error(THD * thd,const sp_head * sp) const1100 void Sp_handler_procedure::recursion_level_error(THD *thd,
1101 const sp_head *sp) const
1102 {
1103 my_error(ER_SP_RECURSION_LIMIT, MYF(0),
1104 static_cast<int>(thd->variables.max_sp_recursion_depth),
1105 sp->m_name.str);
1106 }
1107
1108
1109 /**
1110 Execute the routine. The main instruction jump loop is there.
1111 Assume the parameters already set.
1112
1113 @param thd Thread context.
1114 @param merge_da_on_success Flag specifying if Warning Info should be
1115 propagated to the caller on Completion
1116 Condition or not.
1117
1118 @todo
1119 - Will write this SP statement into binlog separately
1120 (TODO: consider changing the condition to "not inside event union")
1121
1122 @return Error status.
1123 @retval
1124 FALSE on success
1125 @retval
1126 TRUE on error
1127 */
1128
1129 bool
execute(THD * thd,bool merge_da_on_success)1130 sp_head::execute(THD *thd, bool merge_da_on_success)
1131 {
1132 DBUG_ENTER("sp_head::execute");
1133 char saved_cur_db_name_buf[SAFE_NAME_LEN+1];
1134 LEX_STRING saved_cur_db_name=
1135 { saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
1136 bool cur_db_changed= FALSE;
1137 sp_rcontext *ctx= thd->spcont;
1138 bool err_status= FALSE;
1139 uint ip= 0;
1140 sql_mode_t save_sql_mode;
1141
1142 // TODO(cvicentiu) See if you can drop this bit. This is used to resume
1143 // execution from where we left off.
1144 if (m_chistics.agg_type == GROUP_AGGREGATE)
1145 ip= thd->spcont->instr_ptr;
1146
1147 bool save_abort_on_warning;
1148 Query_arena *old_arena;
1149 /* per-instruction arena */
1150 MEM_ROOT execute_mem_root;
1151 Query_arena execute_arena(&execute_mem_root, STMT_INITIALIZED_FOR_SP),
1152 backup_arena;
1153 query_id_t old_query_id;
1154 TABLE *old_derived_tables;
1155 TABLE *old_rec_tables;
1156 LEX *old_lex;
1157 Item_change_list old_change_list;
1158 String old_packet;
1159 uint old_server_status;
1160 const uint status_backup_mask= SERVER_STATUS_CURSOR_EXISTS |
1161 SERVER_STATUS_LAST_ROW_SENT;
1162 MEM_ROOT *user_var_events_alloc_saved= 0;
1163 Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer;
1164 Object_creation_ctx *UNINIT_VAR(saved_creation_ctx);
1165 Diagnostics_area *da= thd->get_stmt_da();
1166 Warning_info sp_wi(da->warning_info_id(), false, true);
1167
1168 /* this 7*STACK_MIN_SIZE is a complex matter with a long history (see it!) */
1169 if (check_stack_overrun(thd, 7 * STACK_MIN_SIZE, (uchar*)&old_packet))
1170 DBUG_RETURN(TRUE);
1171
1172 opt_trace_disable_if_no_security_context_access(thd);
1173
1174 /* init per-instruction memroot */
1175 init_sql_alloc(&execute_mem_root, "per_instruction_memroot",
1176 MEM_ROOT_BLOCK_SIZE, 0, MYF(0));
1177
1178 DBUG_ASSERT(!(m_flags & IS_INVOKED));
1179 m_flags|= IS_INVOKED;
1180 if (m_parent)
1181 m_parent->m_invoked_subroutine_count++;
1182 m_first_instance->m_first_free_instance= m_next_cached_sp;
1183 if (m_next_cached_sp)
1184 {
1185 DBUG_PRINT("info",
1186 ("first free for %p ++: %p->%p level: %lu flags %x",
1187 m_first_instance, this,
1188 m_next_cached_sp,
1189 m_next_cached_sp->m_recursion_level,
1190 m_next_cached_sp->m_flags));
1191 }
1192 /*
1193 Check that if there are not any instances after this one then
1194 pointer to the last instance points on this instance or if there are
1195 some instances after this one then recursion level of next instance
1196 greater then recursion level of current instance on 1
1197 */
1198 DBUG_ASSERT((m_next_cached_sp == 0 &&
1199 m_first_instance->m_last_cached_sp == this) ||
1200 (m_recursion_level + 1 == m_next_cached_sp->m_recursion_level));
1201
1202 /*
1203 NOTE: The SQL Standard does not specify the context that should be
1204 preserved for stored routines. However, at SAP/Walldorf meeting it was
1205 decided that current database should be preserved.
1206 */
1207
1208 if (m_db.length &&
1209 (err_status= mysql_opt_change_db(thd, &m_db, &saved_cur_db_name, FALSE,
1210 &cur_db_changed)))
1211 {
1212 goto done;
1213 }
1214
1215 thd->is_slave_error= 0;
1216 old_arena= thd->stmt_arena;
1217
1218 /* Push a new warning information area. */
1219 da->copy_sql_conditions_to_wi(thd, &sp_wi);
1220 da->push_warning_info(&sp_wi);
1221
1222 /*
1223 Switch query context. This has to be done early as this is sometimes
1224 allocated on THD::mem_root
1225 */
1226 if (m_creation_ctx)
1227 saved_creation_ctx= m_creation_ctx->set_n_backup(thd);
1228
1229 /*
1230 We have to save/restore this info when we are changing call level to
1231 be able properly do close_thread_tables() in instructions.
1232 */
1233 old_query_id= thd->query_id;
1234 old_derived_tables= thd->derived_tables;
1235 thd->derived_tables= 0;
1236 old_rec_tables= thd->rec_tables;
1237 thd->rec_tables= 0;
1238 save_sql_mode= thd->variables.sql_mode;
1239 thd->variables.sql_mode= m_sql_mode;
1240 save_abort_on_warning= thd->abort_on_warning;
1241 thd->abort_on_warning= 0;
1242 /**
1243 When inside a substatement (a stored function or trigger
1244 statement), clear the metadata observer in THD, if any.
1245 Remember the value of the observer here, to be able
1246 to restore it when leaving the substatement.
1247
1248 We reset the observer to suppress errors when a substatement
1249 uses temporary tables. If a temporary table does not exist
1250 at start of the main statement, it's not prelocked
1251 and thus is not validated with other prelocked tables.
1252
1253 Later on, when the temporary table is opened, metadata
1254 versions mismatch, expectedly.
1255
1256 The proper solution for the problem is to re-validate tables
1257 of substatements (Bug#12257, Bug#27011, Bug#32868, Bug#33000),
1258 but it's not implemented yet.
1259 */
1260 thd->m_reprepare_observer= 0;
1261
1262 /*
1263 It is also more efficient to save/restore current thd->lex once when
1264 do it in each instruction
1265 */
1266 old_lex= thd->lex;
1267 /*
1268 We should also save Item tree change list to avoid rollback something
1269 too early in the calling query.
1270 */
1271 thd->Item_change_list::move_elements_to(&old_change_list);
1272 /*
1273 Cursors will use thd->packet, so they may corrupt data which was prepared
1274 for sending by upper level. OTOH cursors in the same routine can share this
1275 buffer safely so let use use routine-local packet instead of having own
1276 packet buffer for each cursor.
1277
1278 It is probably safe to use same thd->convert_buff everywhere.
1279 */
1280 old_packet.swap(thd->packet);
1281 old_server_status= thd->server_status & status_backup_mask;
1282
1283 /*
1284 Switch to per-instruction arena here. We can do it since we cleanup
1285 arena after every instruction.
1286 */
1287 thd->set_n_backup_active_arena(&execute_arena, &backup_arena);
1288
1289 /*
1290 Save callers arena in order to store instruction results and out
1291 parameters in it later during sp_eval_func_item()
1292 */
1293 thd->spcont->callers_arena= &backup_arena;
1294
1295 #if defined(ENABLED_PROFILING)
1296 /* Discard the initial part of executing routines. */
1297 thd->profiling.discard_current_query();
1298 #endif
1299 sp_instr *i;
1300 DEBUG_SYNC(thd, "sp_head_execute_before_loop");
1301 do
1302 {
1303 #if defined(ENABLED_PROFILING)
1304 /*
1305 Treat each "instr" of a routine as discrete unit that could be profiled.
1306 Profiling only records information for segments of code that set the
1307 source of the query, and almost all kinds of instructions in s-p do not.
1308 */
1309 thd->profiling.finish_current_query();
1310 thd->profiling.start_new_query("continuing inside routine");
1311 #endif
1312
1313 /* get_instr returns NULL when we're done. */
1314 i = get_instr(ip);
1315 if (i == NULL)
1316 {
1317 #if defined(ENABLED_PROFILING)
1318 thd->profiling.discard_current_query();
1319 #endif
1320 thd->spcont->quit_func= TRUE;
1321 break;
1322 }
1323
1324 /* Reset number of warnings for this query. */
1325 thd->get_stmt_da()->reset_for_next_command();
1326
1327 DBUG_PRINT("execute", ("Instruction %u", ip));
1328
1329 /*
1330 We need to reset start_time to allow for time to flow inside a stored
1331 procedure. This is only done for SP since time is suppose to be constant
1332 during execution of triggers and functions.
1333 */
1334 reset_start_time_for_sp(thd);
1335
1336 /*
1337 We have to set thd->stmt_arena before executing the instruction
1338 to store in the instruction free_list all new items, created
1339 during the first execution (for example expanding of '*' or the
1340 items made during other permanent subquery transformations).
1341 */
1342 thd->stmt_arena= i;
1343
1344 /*
1345 Will write this SP statement into binlog separately.
1346 TODO: consider changing the condition to "not inside event union".
1347 */
1348 if (thd->locked_tables_mode <= LTM_LOCK_TABLES)
1349 {
1350 user_var_events_alloc_saved= thd->user_var_events_alloc;
1351 thd->user_var_events_alloc= thd->mem_root;
1352 }
1353
1354 sql_digest_state *parent_digest= thd->m_digest;
1355 thd->m_digest= NULL;
1356
1357 #ifdef WITH_WSREP
1358 if (WSREP(thd) && thd->wsrep_next_trx_id() == WSREP_UNDEFINED_TRX_ID)
1359 {
1360 thd->set_wsrep_next_trx_id(thd->query_id);
1361 WSREP_DEBUG("assigned new next trx ID for SP, trx id: %" PRIu64, thd->wsrep_next_trx_id());
1362 }
1363 #endif /* WITH_WSREP */
1364 err_status= i->execute(thd, &ip);
1365
1366 #ifdef WITH_WSREP
1367 if (WSREP(thd))
1368 {
1369 if (((thd->wsrep_trx().state() == wsrep::transaction::s_executing || thd->in_sub_stmt) &&
1370 (thd->is_fatal_error || thd->killed)))
1371 {
1372 WSREP_DEBUG("SP abort err status %d in sub %d trx state %d",
1373 err_status, thd->in_sub_stmt, thd->wsrep_trx().state());
1374 err_status= 1;
1375 thd->is_fatal_error= 1;
1376 /*
1377 SP was killed, and it is not due to a wsrep conflict.
1378 We skip after_command hook at this point because
1379 otherwise it clears the error, and cleans up the
1380 whole transaction. For now we just return and finish
1381 our handling once we are back to mysql_parse.
1382
1383 Same applies to a SP execution, which was aborted due
1384 to wsrep related conflict, but which is executing as sub statement.
1385 SP in sub statement level should not commit not rollback,
1386 we have to call for rollback is up-most SP level.
1387 */
1388 WSREP_DEBUG("Skipping after_command hook for killed SP");
1389 }
1390 else
1391 {
1392 const bool must_replay= wsrep_must_replay(thd);
1393 if (must_replay)
1394 {
1395 WSREP_DEBUG("MUST_REPLAY set after SP, err_status %d trx state: %d",
1396 err_status, thd->wsrep_trx().state());
1397 }
1398 (void) wsrep_after_statement(thd);
1399
1400 /*
1401 Reset the return code to zero if the transaction was
1402 replayed succesfully.
1403 */
1404 if (must_replay && !wsrep_current_error(thd))
1405 {
1406 err_status= 0;
1407 thd->get_stmt_da()->reset_diagnostics_area();
1408 }
1409 /*
1410 Final wsrep error status for statement is known only after
1411 wsrep_after_statement() call. If the error is set, override
1412 error in thd diagnostics area and reset wsrep client_state error
1413 so that the error does not get propagated via client-server protocol.
1414 */
1415 if (wsrep_current_error(thd))
1416 {
1417 wsrep_override_error(thd, wsrep_current_error(thd),
1418 wsrep_current_error_status(thd));
1419 thd->wsrep_cs().reset_error();
1420 /* Reset also thd->killed if it has been set during BF abort. */
1421 if (thd->killed == KILL_QUERY)
1422 thd->killed= NOT_KILLED;
1423 /* if failed transaction was not replayed, must return with error from here */
1424 if (!must_replay) err_status = 1;
1425 }
1426 }
1427 }
1428 #endif /* WITH_WSREP */
1429 thd->m_digest= parent_digest;
1430
1431 if (i->free_list)
1432 cleanup_items(i->free_list);
1433
1434 /*
1435 If we've set thd->user_var_events_alloc to mem_root of this SP
1436 statement, clean all the events allocated in it.
1437 */
1438 if (thd->locked_tables_mode <= LTM_LOCK_TABLES)
1439 {
1440 reset_dynamic(&thd->user_var_events);
1441 thd->user_var_events_alloc= user_var_events_alloc_saved;
1442 }
1443
1444 /* we should cleanup free_list and memroot, used by instruction */
1445 thd->cleanup_after_query();
1446 free_root(&execute_mem_root, MYF(0));
1447
1448 /*
1449 Find and process SQL handlers unless it is a fatal error (fatal
1450 errors are not catchable by SQL handlers) or the connection has been
1451 killed during execution.
1452 */
1453 if (likely(!thd->is_fatal_error) && likely(!thd->killed_errno()) &&
1454 ctx->handle_sql_condition(thd, &ip, i))
1455 {
1456 err_status= FALSE;
1457 }
1458
1459 /* Reset sp_rcontext::end_partial_result_set flag. */
1460 ctx->end_partial_result_set= FALSE;
1461
1462 } while (!err_status && likely(!thd->killed) &&
1463 likely(!thd->is_fatal_error) &&
1464 !thd->spcont->pause_state);
1465
1466 #if defined(ENABLED_PROFILING)
1467 thd->profiling.finish_current_query();
1468 thd->profiling.start_new_query("tail end of routine");
1469 #endif
1470
1471 /* Restore query context. */
1472
1473 if (m_creation_ctx)
1474 m_creation_ctx->restore_env(thd, saved_creation_ctx);
1475
1476 /* Restore arena. */
1477
1478 thd->restore_active_arena(&execute_arena, &backup_arena);
1479
1480 /* Only pop cursors when we're done with group aggregate running. */
1481 if (m_chistics.agg_type != GROUP_AGGREGATE ||
1482 (m_chistics.agg_type == GROUP_AGGREGATE && thd->spcont->quit_func))
1483 thd->spcont->pop_all_cursors(thd); // To avoid memory leaks after an error
1484
1485 /* Restore all saved */
1486 if (m_chistics.agg_type == GROUP_AGGREGATE)
1487 thd->spcont->instr_ptr= ip;
1488 thd->server_status= (thd->server_status & ~status_backup_mask) | old_server_status;
1489 old_packet.swap(thd->packet);
1490 DBUG_ASSERT(thd->Item_change_list::is_empty());
1491 old_change_list.move_elements_to(thd);
1492 thd->lex= old_lex;
1493 thd->set_query_id(old_query_id);
1494 DBUG_ASSERT(!thd->derived_tables);
1495 thd->derived_tables= old_derived_tables;
1496 thd->rec_tables= old_rec_tables;
1497 thd->variables.sql_mode= save_sql_mode;
1498 thd->abort_on_warning= save_abort_on_warning;
1499 thd->m_reprepare_observer= save_reprepare_observer;
1500
1501 thd->stmt_arena= old_arena;
1502 state= STMT_EXECUTED;
1503
1504 /*
1505 Restore the caller's original warning information area:
1506 - warnings generated during trigger execution should not be
1507 propagated to the caller on success;
1508 - if there was an exception during execution, warning info should be
1509 propagated to the caller in any case.
1510 */
1511 da->pop_warning_info();
1512
1513 if (err_status || merge_da_on_success)
1514 {
1515 /*
1516 If a routine body is empty or if a routine did not generate any warnings,
1517 do not duplicate our own contents by appending the contents of the called
1518 routine. We know that the called routine did not change its warning info.
1519
1520 On the other hand, if the routine body is not empty and some statement in
1521 the routine generates a warning or uses tables, warning info is guaranteed
1522 to have changed. In this case we know that the routine warning info
1523 contains only new warnings, and thus we perform a copy.
1524 */
1525 if (da->warning_info_changed(&sp_wi))
1526 {
1527 /*
1528 If the invocation of the routine was a standalone statement,
1529 rather than a sub-statement, in other words, if it's a CALL
1530 of a procedure, rather than invocation of a function or a
1531 trigger, we need to clear the current contents of the caller's
1532 warning info.
1533
1534 This is per MySQL rules: if a statement generates a warning,
1535 warnings from the previous statement are flushed. Normally
1536 it's done in push_warning(). However, here we don't use
1537 push_warning() to avoid invocation of condition handlers or
1538 escalation of warnings to errors.
1539 */
1540 da->opt_clear_warning_info(thd->query_id);
1541 da->copy_sql_conditions_from_wi(thd, &sp_wi);
1542 da->remove_marked_sql_conditions();
1543 if (i != NULL)
1544 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
1545 ER_SP_STACK_TRACE,
1546 ER_THD(thd, ER_SP_STACK_TRACE),
1547 i->m_lineno,
1548 m_qname.str != NULL ? m_qname.str :
1549 "anonymous block");
1550 }
1551 }
1552
1553 done:
1554 DBUG_PRINT("info", ("err_status: %d killed: %d is_slave_error: %d report_error: %d",
1555 err_status, thd->killed, thd->is_slave_error,
1556 thd->is_error()));
1557
1558 if (thd->killed)
1559 err_status= TRUE;
1560 /*
1561 If the DB has changed, the pointer has changed too, but the
1562 original thd->db will then have been freed
1563 */
1564 if (cur_db_changed && thd->killed != KILL_CONNECTION)
1565 {
1566 /*
1567 Force switching back to the saved current database, because it may be
1568 NULL. In this case, mysql_change_db() would generate an error.
1569 */
1570
1571 err_status|= mysql_change_db(thd, (LEX_CSTRING*)&saved_cur_db_name, TRUE) != 0;
1572 }
1573 m_flags&= ~IS_INVOKED;
1574 if (m_parent)
1575 m_parent->m_invoked_subroutine_count--;
1576 DBUG_PRINT("info",
1577 ("first free for %p --: %p->%p, level: %lu, flags %x",
1578 m_first_instance,
1579 m_first_instance->m_first_free_instance,
1580 this, m_recursion_level, m_flags));
1581 /*
1582 Check that we have one of following:
1583
1584 1) there are not free instances which means that this instance is last
1585 in the list of instances (pointer to the last instance point on it and
1586 ther are not other instances after this one in the list)
1587
1588 2) There are some free instances which mean that first free instance
1589 should go just after this one and recursion level of that free instance
1590 should be on 1 more then recursion level of this instance.
1591 */
1592 DBUG_ASSERT((m_first_instance->m_first_free_instance == 0 &&
1593 this == m_first_instance->m_last_cached_sp &&
1594 m_next_cached_sp == 0) ||
1595 (m_first_instance->m_first_free_instance != 0 &&
1596 m_first_instance->m_first_free_instance == m_next_cached_sp &&
1597 m_first_instance->m_first_free_instance->m_recursion_level ==
1598 m_recursion_level + 1));
1599 m_first_instance->m_first_free_instance= this;
1600
1601 DBUG_RETURN(err_status);
1602 }
1603
1604
1605 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1606 /**
1607 set_routine_security_ctx() changes routine security context, and
1608 checks if there is an EXECUTE privilege in new context. If there is
1609 no EXECUTE privilege, it changes the context back and returns a
1610 error.
1611
1612 @param thd thread handle
1613 @param sp stored routine to change the context for
1614 @param save_ctx pointer to an old security context
1615
1616 @todo
1617 - Cache if the definer has the right to use the object on the
1618 first usage and only reset the cache if someone does a GRANT
1619 statement that 'may' affect this.
1620
1621 @retval
1622 TRUE if there was a error, and the context wasn't changed.
1623 @retval
1624 FALSE if the context was changed.
1625 */
1626
1627 bool
set_routine_security_ctx(THD * thd,sp_head * sp,Security_context ** save_ctx)1628 set_routine_security_ctx(THD *thd, sp_head *sp, Security_context **save_ctx)
1629 {
1630 *save_ctx= 0;
1631 if (sp->suid() != SP_IS_NOT_SUID &&
1632 sp->m_security_ctx.change_security_context(thd, &sp->m_definer.user,
1633 &sp->m_definer.host,
1634 &sp->m_db,
1635 save_ctx))
1636 return TRUE;
1637
1638 /*
1639 If we changed context to run as another user, we need to check the
1640 access right for the new context again as someone may have revoked
1641 the right to use the procedure from this user.
1642
1643 TODO:
1644 Cache if the definer has the right to use the object on the
1645 first usage and only reset the cache if someone does a GRANT
1646 statement that 'may' affect this.
1647 */
1648 if (*save_ctx &&
1649 sp->check_execute_access(thd))
1650 {
1651 sp->m_security_ctx.restore_security_context(thd, *save_ctx);
1652 *save_ctx= 0;
1653 return TRUE;
1654 }
1655
1656 return FALSE;
1657 }
1658 #endif // ! NO_EMBEDDED_ACCESS_CHECKS
1659
1660
check_execute_access(THD * thd) const1661 bool sp_head::check_execute_access(THD *thd) const
1662 {
1663 return m_parent ? m_parent->check_execute_access(thd) :
1664 check_routine_access(thd, EXECUTE_ACL,
1665 &m_db, &m_name,
1666 m_handler, false);
1667 }
1668
1669
1670 /**
1671 Create rcontext optionally using the routine security.
1672 This is important for sql_mode=ORACLE to make sure that the invoker has
1673 access to the tables mentioned in the %TYPE references.
1674
1675 In non-Oracle sql_modes we do not need access to any tables,
1676 so we can omit the security context switch for performance purposes.
1677
1678 @param thd
1679 @param ret_value
1680 @retval NULL - error (access denided or EOM)
1681 @retval !NULL - success (the invoker has rights to all %TYPE tables)
1682 */
1683
rcontext_create(THD * thd,Field * ret_value,Row_definition_list * defs,bool switch_security_ctx)1684 sp_rcontext *sp_head::rcontext_create(THD *thd, Field *ret_value,
1685 Row_definition_list *defs,
1686 bool switch_security_ctx)
1687 {
1688 if (!(m_flags & HAS_COLUMN_TYPE_REFS))
1689 return sp_rcontext::create(thd, this, m_pcont, ret_value, *defs);
1690 sp_rcontext *res= NULL;
1691 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1692 Security_context *save_security_ctx;
1693 if (switch_security_ctx &&
1694 set_routine_security_ctx(thd, this, &save_security_ctx))
1695 return NULL;
1696 #endif
1697 if (!defs->resolve_type_refs(thd))
1698 res= sp_rcontext::create(thd, this, m_pcont, ret_value, *defs);
1699 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1700 if (switch_security_ctx)
1701 m_security_ctx.restore_security_context(thd, save_security_ctx);
1702 #endif
1703 return res;
1704 }
1705
1706
rcontext_create(THD * thd,Field * ret_value,List<Item> * args)1707 sp_rcontext *sp_head::rcontext_create(THD *thd, Field *ret_value,
1708 List<Item> *args)
1709 {
1710 DBUG_ASSERT(args);
1711 Row_definition_list defs;
1712 m_pcont->retrieve_field_definitions(&defs);
1713 if (defs.adjust_formal_params_to_actual_params(thd, args))
1714 return NULL;
1715 return rcontext_create(thd, ret_value, &defs, true);
1716 }
1717
1718
rcontext_create(THD * thd,Field * ret_value,Item ** args,uint arg_count)1719 sp_rcontext *sp_head::rcontext_create(THD *thd, Field *ret_value,
1720 Item **args, uint arg_count)
1721 {
1722 Row_definition_list defs;
1723 m_pcont->retrieve_field_definitions(&defs);
1724 if (defs.adjust_formal_params_to_actual_params(thd, args, arg_count))
1725 return NULL;
1726 return rcontext_create(thd, ret_value, &defs, true);
1727 }
1728
1729
1730 /**
1731 Execute trigger stored program.
1732
1733 - changes security context for triggers
1734 - switch to new memroot
1735 - call sp_head::execute
1736 - restore old memroot
1737 - restores security context
1738
1739 @param thd Thread handle
1740 @param db database name
1741 @param table table name
1742 @param grant_info GRANT_INFO structure to be filled with
1743 information about definer's privileges
1744 on subject table
1745
1746 @todo
1747 - TODO: we should create sp_rcontext once per command and reuse it
1748 on subsequent executions of a trigger.
1749
1750 @retval
1751 FALSE on success
1752 @retval
1753 TRUE on error
1754 */
1755
1756 bool
execute_trigger(THD * thd,const LEX_CSTRING * db_name,const LEX_CSTRING * table_name,GRANT_INFO * grant_info)1757 sp_head::execute_trigger(THD *thd,
1758 const LEX_CSTRING *db_name,
1759 const LEX_CSTRING *table_name,
1760 GRANT_INFO *grant_info)
1761 {
1762 sp_rcontext *octx = thd->spcont;
1763 sp_rcontext *nctx = NULL;
1764 bool err_status= FALSE;
1765 MEM_ROOT call_mem_root;
1766 Query_arena call_arena(&call_mem_root, Query_arena::STMT_INITIALIZED_FOR_SP);
1767 Query_arena backup_arena;
1768 DBUG_ENTER("sp_head::execute_trigger");
1769 DBUG_PRINT("info", ("trigger %s", m_name.str));
1770
1771 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1772 Security_context *save_ctx= NULL;
1773
1774
1775 if (suid() != SP_IS_NOT_SUID &&
1776 m_security_ctx.change_security_context(thd,
1777 &m_definer.user,
1778 &m_definer.host,
1779 &m_db,
1780 &save_ctx))
1781 DBUG_RETURN(TRUE);
1782
1783 /*
1784 Fetch information about table-level privileges for subject table into
1785 GRANT_INFO instance. The access check itself will happen in
1786 Item_trigger_field, where this information will be used along with
1787 information about column-level privileges.
1788 */
1789
1790 fill_effective_table_privileges(thd,
1791 grant_info,
1792 db_name->str,
1793 table_name->str);
1794
1795 /* Check that the definer has TRIGGER privilege on the subject table. */
1796
1797 if (!(grant_info->privilege & TRIGGER_ACL))
1798 {
1799 char priv_desc[128];
1800 get_privilege_desc(priv_desc, sizeof(priv_desc), TRIGGER_ACL);
1801
1802 my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), priv_desc,
1803 thd->security_ctx->priv_user, thd->security_ctx->host_or_ip,
1804 table_name->str);
1805
1806 m_security_ctx.restore_security_context(thd, save_ctx);
1807 DBUG_RETURN(TRUE);
1808 }
1809 #endif // NO_EMBEDDED_ACCESS_CHECKS
1810
1811 /*
1812 Prepare arena and memroot for objects which lifetime is whole
1813 duration of trigger call (sp_rcontext, it's tables and items,
1814 sp_cursor and Item_cache holders for case expressions). We can't
1815 use caller's arena/memroot for those objects because in this case
1816 some fixed amount of memory will be consumed for each trigger
1817 invocation and so statements which involve lot of them will hog
1818 memory.
1819
1820 TODO: we should create sp_rcontext once per command and reuse it
1821 on subsequent executions of a trigger.
1822 */
1823 init_sql_alloc(&call_mem_root, "execute_trigger", MEM_ROOT_BLOCK_SIZE, 0,
1824 MYF(0));
1825 thd->set_n_backup_active_arena(&call_arena, &backup_arena);
1826
1827 Row_definition_list defs;
1828 m_pcont->retrieve_field_definitions(&defs);
1829 if (!(nctx= rcontext_create(thd, NULL, &defs, false)))
1830 {
1831 err_status= TRUE;
1832 goto err_with_cleanup;
1833 }
1834
1835 thd->spcont= nctx;
1836
1837 err_status= execute(thd, FALSE);
1838
1839 err_with_cleanup:
1840 thd->restore_active_arena(&call_arena, &backup_arena);
1841
1842 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1843 m_security_ctx.restore_security_context(thd, save_ctx);
1844 #endif // NO_EMBEDDED_ACCESS_CHECKS
1845
1846 delete nctx;
1847 call_arena.free_items();
1848 free_root(&call_mem_root, MYF(0));
1849 thd->spcont= octx;
1850
1851 if (thd->killed)
1852 thd->send_kill_message();
1853
1854 DBUG_RETURN(err_status);
1855 }
1856
1857
1858 /*
1859 Execute the package initialization section.
1860 */
1861
instantiate_if_needed(THD * thd)1862 bool sp_package::instantiate_if_needed(THD *thd)
1863 {
1864 List<Item> args;
1865 if (m_is_instantiated)
1866 return false;
1867 /*
1868 Set m_is_instantiated to true early, to avoid recursion in case if
1869 the package initialization section calls routines from the same package.
1870 */
1871 m_is_instantiated= true;
1872 /*
1873 Check that the initialization section doesn't contain Dynamic SQL
1874 and doesn't return result sets: such stored procedures can't
1875 be called from a function or trigger.
1876 */
1877 if (thd->in_sub_stmt)
1878 {
1879 const char *where= (thd->in_sub_stmt & SUB_STMT_TRIGGER ?
1880 "trigger" : "function");
1881 if (is_not_allowed_in_function(where))
1882 goto err;
1883 }
1884
1885 args.elements= 0;
1886 if (execute_procedure(thd, &args))
1887 goto err;
1888 return false;
1889 err:
1890 m_is_instantiated= false;
1891 return true;
1892 }
1893
1894
1895 /**
1896 Execute a function.
1897
1898 - evaluate parameters
1899 - changes security context for SUID routines
1900 - switch to new memroot
1901 - call sp_head::execute
1902 - restore old memroot
1903 - evaluate the return value
1904 - restores security context
1905
1906 @param thd Thread handle
1907 @param argp Passed arguments (these are items from containing
1908 statement?)
1909 @param argcount Number of passed arguments. We need to check if
1910 this is correct.
1911 @param return_value_fld Save result here.
1912
1913 @todo
1914 We should create sp_rcontext once per command and reuse
1915 it on subsequent executions of a function/trigger.
1916
1917 @todo
1918 In future we should associate call arena/mem_root with
1919 sp_rcontext and allocate all these objects (and sp_rcontext
1920 itself) on it directly rather than juggle with arenas.
1921
1922 @retval
1923 FALSE on success
1924 @retval
1925 TRUE on error
1926 */
1927
1928 bool
execute_function(THD * thd,Item ** argp,uint argcount,Field * return_value_fld,sp_rcontext ** func_ctx,Query_arena * call_arena)1929 sp_head::execute_function(THD *thd, Item **argp, uint argcount,
1930 Field *return_value_fld, sp_rcontext **func_ctx,
1931 Query_arena *call_arena)
1932 {
1933 ulonglong UNINIT_VAR(binlog_save_options);
1934 bool need_binlog_call= FALSE;
1935 uint arg_no;
1936 sp_rcontext *octx = thd->spcont;
1937 char buf[STRING_BUFFER_USUAL_SIZE];
1938 String binlog_buf(buf, sizeof(buf), &my_charset_bin);
1939 bool err_status= FALSE;
1940 Query_arena backup_arena;
1941 DBUG_ENTER("sp_head::execute_function");
1942 DBUG_PRINT("info", ("function %s", m_name.str));
1943
1944 if (m_parent && m_parent->instantiate_if_needed(thd))
1945 DBUG_RETURN(true);
1946
1947 /*
1948 Check that the function is called with all specified arguments.
1949
1950 If it is not, use my_error() to report an error, or it will not terminate
1951 the invoking query properly.
1952 */
1953 if (argcount != m_pcont->context_var_count())
1954 {
1955 /*
1956 Need to use my_error here, or it will not terminate the
1957 invoking query properly.
1958 */
1959 my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0),
1960 "FUNCTION", ErrConvDQName(this).ptr(),
1961 m_pcont->context_var_count(), argcount);
1962 DBUG_RETURN(TRUE);
1963 }
1964 /*
1965 Prepare arena and memroot for objects which lifetime is whole
1966 duration of function call (sp_rcontext, it's tables and items,
1967 sp_cursor and Item_cache holders for case expressions).
1968 We can't use caller's arena/memroot for those objects because
1969 in this case some fixed amount of memory will be consumed for
1970 each function/trigger invocation and so statements which involve
1971 lot of them will hog memory.
1972 TODO: we should create sp_rcontext once per command and reuse
1973 it on subsequent executions of a function/trigger.
1974 */
1975 if (!(*func_ctx))
1976 {
1977 thd->set_n_backup_active_arena(call_arena, &backup_arena);
1978
1979 if (!(*func_ctx= rcontext_create(thd, return_value_fld, argp, argcount)))
1980 {
1981 thd->restore_active_arena(call_arena, &backup_arena);
1982 err_status= TRUE;
1983 goto err_with_cleanup;
1984 }
1985
1986 /*
1987 We have to switch temporarily back to callers arena/memroot.
1988 Function arguments belong to the caller and so the may reference
1989 memory which they will allocate during calculation long after
1990 this function call will be finished (e.g. in Item::cleanup()).
1991 */
1992 thd->restore_active_arena(call_arena, &backup_arena);
1993 }
1994
1995 /* Pass arguments. */
1996 for (arg_no= 0; arg_no < argcount; arg_no++)
1997 {
1998 /* Arguments must be fixed in Item_func_sp::fix_fields */
1999 DBUG_ASSERT(argp[arg_no]->is_fixed());
2000
2001 if ((err_status= (*func_ctx)->set_parameter(thd, arg_no, &(argp[arg_no]))))
2002 goto err_with_cleanup;
2003 }
2004
2005 /*
2006 If row-based binlogging, we don't need to binlog the function's call, let
2007 each substatement be binlogged its way.
2008 */
2009 need_binlog_call= mysql_bin_log.is_open() &&
2010 (thd->variables.option_bits & OPTION_BIN_LOG) &&
2011 !thd->is_current_stmt_binlog_format_row();
2012
2013 /*
2014 Remember the original arguments for unrolled replication of functions
2015 before they are changed by execution.
2016 */
2017 if (need_binlog_call)
2018 {
2019 binlog_buf.length(0);
2020 binlog_buf.append(STRING_WITH_LEN("SELECT "));
2021 append_identifier(thd, &binlog_buf, &m_db);
2022 binlog_buf.append('.');
2023 append_identifier(thd, &binlog_buf, &m_name);
2024 binlog_buf.append('(');
2025 for (arg_no= 0; arg_no < argcount; arg_no++)
2026 {
2027 String str_value_holder;
2028 String *str_value;
2029
2030 if (arg_no)
2031 binlog_buf.append(',');
2032
2033 Item_field *item= (*func_ctx)->get_parameter(arg_no);
2034 str_value= item->type_handler()->print_item_value(thd, item,
2035 &str_value_holder);
2036 if (str_value)
2037 binlog_buf.append(*str_value);
2038 else
2039 binlog_buf.append(STRING_WITH_LEN("NULL"));
2040 }
2041 binlog_buf.append(')');
2042 }
2043 thd->spcont= *func_ctx;
2044
2045 #ifndef NO_EMBEDDED_ACCESS_CHECKS
2046 Security_context *save_security_ctx;
2047 if (set_routine_security_ctx(thd, this, &save_security_ctx))
2048 {
2049 err_status= TRUE;
2050 goto err_with_cleanup;
2051 }
2052 #endif
2053
2054 if (need_binlog_call)
2055 {
2056 query_id_t q;
2057 reset_dynamic(&thd->user_var_events);
2058 /*
2059 In case of artificially constructed events for function calls
2060 we have separate union for each such event and hence can't use
2061 query_id of real calling statement as the start of all these
2062 unions (this will break logic of replication of user-defined
2063 variables). So we use artifical value which is guaranteed to
2064 be greater than all query_id's of all statements belonging
2065 to previous events/unions.
2066 Possible alternative to this is logging of all function invocations
2067 as one select and not resetting THD::user_var_events before
2068 each invocation.
2069 */
2070 q= get_query_id();
2071 mysql_bin_log.start_union_events(thd, q + 1);
2072 binlog_save_options= thd->variables.option_bits;
2073 thd->variables.option_bits&= ~OPTION_BIN_LOG;
2074 }
2075
2076 opt_trace_disable_if_no_stored_proc_func_access(thd, this);
2077 /*
2078 Switch to call arena/mem_root so objects like sp_cursor or
2079 Item_cache holders for case expressions can be allocated on it.
2080
2081 TODO: In future we should associate call arena/mem_root with
2082 sp_rcontext and allocate all these objects (and sp_rcontext
2083 itself) on it directly rather than juggle with arenas.
2084 */
2085 thd->set_n_backup_active_arena(call_arena, &backup_arena);
2086
2087 err_status= execute(thd, TRUE);
2088
2089 thd->restore_active_arena(call_arena, &backup_arena);
2090
2091 if (need_binlog_call)
2092 {
2093 mysql_bin_log.stop_union_events(thd);
2094 thd->variables.option_bits= binlog_save_options;
2095 if (thd->binlog_evt_union.unioned_events)
2096 {
2097 int errcode = query_error_code(thd, thd->killed == NOT_KILLED);
2098 Query_log_event qinfo(thd, binlog_buf.ptr(), binlog_buf.length(),
2099 thd->binlog_evt_union.unioned_events_trans, FALSE, FALSE, errcode);
2100 if (mysql_bin_log.write(&qinfo) &&
2101 thd->binlog_evt_union.unioned_events_trans)
2102 {
2103 push_warning(thd, Sql_condition::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
2104 "Invoked ROUTINE modified a transactional table but MySQL "
2105 "failed to reflect this change in the binary log");
2106 err_status= TRUE;
2107 }
2108 reset_dynamic(&thd->user_var_events);
2109 /* Forget those values, in case more function calls are binlogged: */
2110 thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
2111 thd->auto_inc_intervals_in_cur_stmt_for_binlog.empty();
2112 }
2113 }
2114
2115 if (!err_status && thd->spcont->quit_func)
2116 {
2117 /* We need result only in function but not in trigger */
2118
2119 if (!(*func_ctx)->is_return_value_set())
2120 {
2121 my_error(ER_SP_NORETURNEND, MYF(0), m_name.str);
2122 err_status= TRUE;
2123 }
2124 }
2125
2126 #ifndef NO_EMBEDDED_ACCESS_CHECKS
2127 m_security_ctx.restore_security_context(thd, save_security_ctx);
2128 #endif
2129
2130 err_with_cleanup:
2131 thd->spcont= octx;
2132
2133 /*
2134 If not insided a procedure and a function printing warning
2135 messsages.
2136 */
2137 if (need_binlog_call &&
2138 thd->spcont == NULL && !thd->binlog_evt_union.do_union)
2139 thd->issue_unsafe_warnings();
2140
2141 DBUG_RETURN(err_status);
2142 }
2143
2144
2145 /**
2146 Execute a procedure.
2147
2148 The function does the following steps:
2149 - Set all parameters
2150 - changes security context for SUID routines
2151 - call sp_head::execute
2152 - copy back values of INOUT and OUT parameters
2153 - restores security context
2154
2155 @param thd Thread handle
2156 @param args List of values passed as arguments.
2157
2158 @retval
2159 FALSE on success
2160 @retval
2161 TRUE on error
2162 */
2163
2164 bool
execute_procedure(THD * thd,List<Item> * args)2165 sp_head::execute_procedure(THD *thd, List<Item> *args)
2166 {
2167 bool err_status= FALSE;
2168 uint params = m_pcont->context_var_count();
2169 /* Query start time may be reset in a multi-stmt SP; keep this for later. */
2170 ulonglong utime_before_sp_exec= thd->utime_after_lock;
2171 sp_rcontext *save_spcont, *octx;
2172 sp_rcontext *nctx = NULL;
2173 bool save_enable_slow_log;
2174 bool save_log_general= false;
2175 sp_package *pkg= get_package();
2176 DBUG_ENTER("sp_head::execute_procedure");
2177 DBUG_PRINT("info", ("procedure %s", m_name.str));
2178
2179 if (m_parent && m_parent->instantiate_if_needed(thd))
2180 DBUG_RETURN(true);
2181
2182 if (args->elements != params)
2183 {
2184 my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0), "PROCEDURE",
2185 ErrConvDQName(this).ptr(), params, args->elements);
2186 DBUG_RETURN(TRUE);
2187 }
2188
2189 save_spcont= octx= thd->spcont;
2190 if (! octx)
2191 {
2192 /* Create a temporary old context. */
2193 if (!(octx= rcontext_create(thd, NULL, args)))
2194 {
2195 DBUG_PRINT("error", ("Could not create octx"));
2196 DBUG_RETURN(TRUE);
2197 }
2198
2199 thd->spcont= octx;
2200
2201 /* set callers_arena to thd, for upper-level function to work */
2202 thd->spcont->callers_arena= thd;
2203 }
2204
2205 if (!pkg)
2206 {
2207 if (!(nctx= rcontext_create(thd, NULL, args)))
2208 {
2209 delete nctx; /* Delete nctx if it was init() that failed. */
2210 thd->spcont= save_spcont;
2211 DBUG_RETURN(TRUE);
2212 }
2213 }
2214 else
2215 {
2216 if (!pkg->m_rcontext)
2217 {
2218 Query_arena backup_arena;
2219 thd->set_n_backup_active_arena(this, &backup_arena);
2220 nctx= pkg->rcontext_create(thd, NULL, args);
2221 thd->restore_active_arena(this, &backup_arena);
2222 if (!nctx)
2223 {
2224 thd->spcont= save_spcont;
2225 DBUG_RETURN(TRUE);
2226 }
2227 pkg->m_rcontext= nctx;
2228 }
2229 else
2230 nctx= pkg->m_rcontext;
2231 }
2232
2233 if (params > 0)
2234 {
2235 List_iterator<Item> it_args(*args);
2236
2237 DBUG_PRINT("info",(" %.*s: eval args", (int) m_name.length, m_name.str));
2238
2239 for (uint i= 0 ; i < params ; i++)
2240 {
2241 Item *arg_item= it_args++;
2242
2243 if (!arg_item)
2244 break;
2245
2246 sp_variable *spvar= m_pcont->find_variable(i);
2247
2248 if (!spvar)
2249 continue;
2250
2251 if (spvar->mode != sp_variable::MODE_IN)
2252 {
2253 Settable_routine_parameter *srp=
2254 arg_item->get_settable_routine_parameter();
2255
2256 if (!srp)
2257 {
2258 my_error(ER_SP_NOT_VAR_ARG, MYF(0), i+1, ErrConvDQName(this).ptr());
2259 err_status= TRUE;
2260 break;
2261 }
2262
2263 srp->set_required_privilege(spvar->mode == sp_variable::MODE_INOUT);
2264 }
2265
2266 if (spvar->mode == sp_variable::MODE_OUT)
2267 {
2268 Item_null *null_item= new (thd->mem_root) Item_null(thd);
2269 Item *tmp_item= null_item;
2270
2271 if (!null_item ||
2272 nctx->set_parameter(thd, i, &tmp_item))
2273 {
2274 DBUG_PRINT("error", ("set variable failed"));
2275 err_status= TRUE;
2276 break;
2277 }
2278 }
2279 else
2280 {
2281 if (nctx->set_parameter(thd, i, it_args.ref()))
2282 {
2283 DBUG_PRINT("error", ("set variable 2 failed"));
2284 err_status= TRUE;
2285 break;
2286 }
2287 }
2288
2289 TRANSACT_TRACKER(add_trx_state_from_thd(thd));
2290 }
2291
2292 /*
2293 Okay, got values for all arguments. Close tables that might be used by
2294 arguments evaluation. If arguments evaluation required prelocking mode,
2295 we'll leave it here.
2296 */
2297 thd->lex->unit.cleanup();
2298
2299 if (!thd->in_sub_stmt)
2300 {
2301 thd->get_stmt_da()->set_overwrite_status(true);
2302 thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
2303 thd->get_stmt_da()->set_overwrite_status(false);
2304 }
2305
2306 close_thread_tables(thd);
2307 thd_proc_info(thd, 0);
2308
2309 if (! thd->in_sub_stmt)
2310 {
2311 if (thd->transaction_rollback_request)
2312 {
2313 trans_rollback_implicit(thd);
2314 thd->release_transactional_locks();
2315 }
2316 else if (! thd->in_multi_stmt_transaction_mode())
2317 thd->release_transactional_locks();
2318 else
2319 thd->mdl_context.release_statement_locks();
2320 }
2321
2322 thd->rollback_item_tree_changes();
2323
2324 DBUG_PRINT("info",(" %.*s: eval args done", (int) m_name.length,
2325 m_name.str));
2326 }
2327
2328 save_enable_slow_log= thd->enable_slow_log;
2329
2330 /*
2331 Disable slow log if:
2332 - Slow logging is enabled (no change needed)
2333 - This is a normal SP (not event log)
2334 - If we have not explicitely disabled logging of SP
2335 */
2336 if (save_enable_slow_log &&
2337 ((!(m_flags & LOG_SLOW_STATEMENTS) &&
2338 (thd->variables.log_slow_disabled_statements & LOG_SLOW_DISABLE_SP))))
2339 {
2340 DBUG_PRINT("info", ("Disabling slow log for the execution"));
2341 thd->enable_slow_log= FALSE;
2342 }
2343
2344 /*
2345 Disable general log if:
2346 - If general log is enabled (no change needed)
2347 - This is a normal SP (not event log)
2348 - If we have not explicitely disabled logging of SP
2349 */
2350 if (!(thd->variables.option_bits & OPTION_LOG_OFF) &&
2351 (!(m_flags & LOG_GENERAL_LOG) &&
2352 (thd->variables.log_disabled_statements & LOG_DISABLE_SP)))
2353 {
2354 DBUG_PRINT("info", ("Disabling general log for the execution"));
2355 save_log_general= true;
2356 /* disable this bit */
2357 thd->variables.option_bits |= OPTION_LOG_OFF;
2358 }
2359 thd->spcont= nctx;
2360
2361 #ifndef NO_EMBEDDED_ACCESS_CHECKS
2362 Security_context *save_security_ctx= 0;
2363 if (!err_status)
2364 err_status= set_routine_security_ctx(thd, this, &save_security_ctx);
2365 #endif
2366
2367 opt_trace_disable_if_no_stored_proc_func_access(thd, this);
2368 if (!err_status)
2369 {
2370 err_status= execute(thd, TRUE);
2371 DBUG_PRINT("info", ("execute returned %d", (int) err_status));
2372 }
2373
2374 if (save_log_general)
2375 thd->variables.option_bits &= ~OPTION_LOG_OFF;
2376 thd->enable_slow_log= save_enable_slow_log;
2377
2378 /*
2379 In the case when we weren't able to employ reuse mechanism for
2380 OUT/INOUT paranmeters, we should reallocate memory. This
2381 allocation should be done on the arena which will live through
2382 all execution of calling routine.
2383 */
2384 thd->spcont->callers_arena= octx->callers_arena;
2385
2386 if (!err_status && params > 0)
2387 {
2388 List_iterator<Item> it_args(*args);
2389
2390 /*
2391 Copy back all OUT or INOUT values to the previous frame, or
2392 set global user variables
2393 */
2394 for (uint i= 0 ; i < params ; i++)
2395 {
2396 Item *arg_item= it_args++;
2397
2398 if (!arg_item)
2399 break;
2400
2401 sp_variable *spvar= m_pcont->find_variable(i);
2402
2403 if (spvar->mode == sp_variable::MODE_IN)
2404 continue;
2405
2406 Settable_routine_parameter *srp=
2407 arg_item->get_settable_routine_parameter();
2408
2409 DBUG_ASSERT(srp);
2410
2411 if (srp->set_value(thd, octx, nctx->get_variable_addr(i)))
2412 {
2413 DBUG_PRINT("error", ("set value failed"));
2414 err_status= TRUE;
2415 break;
2416 }
2417
2418 Send_field *out_param_info= new (thd->mem_root) Send_field();
2419 nctx->get_parameter(i)->make_send_field(thd, out_param_info);
2420 out_param_info->db_name= m_db.str;
2421 out_param_info->table_name= m_name.str;
2422 out_param_info->org_table_name= m_name.str;
2423 out_param_info->col_name= spvar->name;
2424 out_param_info->org_col_name= spvar->name;
2425
2426 srp->set_out_param_info(out_param_info);
2427 }
2428 }
2429
2430 #ifndef NO_EMBEDDED_ACCESS_CHECKS
2431 if (save_security_ctx)
2432 m_security_ctx.restore_security_context(thd, save_security_ctx);
2433 #endif
2434
2435 if (!save_spcont)
2436 delete octx;
2437
2438 if (!pkg)
2439 delete nctx;
2440 thd->spcont= save_spcont;
2441 thd->utime_after_lock= utime_before_sp_exec;
2442
2443 /*
2444 If not insided a procedure and a function printing warning
2445 messsages.
2446 */
2447 bool need_binlog_call= mysql_bin_log.is_open() &&
2448 (thd->variables.option_bits & OPTION_BIN_LOG) &&
2449 !thd->is_current_stmt_binlog_format_row();
2450 if (need_binlog_call && thd->spcont == NULL &&
2451 !thd->binlog_evt_union.do_union)
2452 thd->issue_unsafe_warnings();
2453
2454 DBUG_RETURN(err_status);
2455 }
2456
2457
2458 /**
2459 Reset lex during parsing, before we parse a sub statement.
2460
2461 @param thd Thread handler.
2462
2463 @return Error state
2464 @retval true An error occurred.
2465 @retval false Success.
2466 */
2467
2468 bool
reset_lex(THD * thd,sp_lex_local * sublex)2469 sp_head::reset_lex(THD *thd, sp_lex_local *sublex)
2470 {
2471 DBUG_ENTER("sp_head::reset_lex");
2472 LEX *oldlex= thd->lex;
2473
2474 thd->set_local_lex(sublex);
2475
2476 DBUG_RETURN(m_lex.push_front(oldlex));
2477 }
2478
2479
2480 bool
reset_lex(THD * thd)2481 sp_head::reset_lex(THD *thd)
2482 {
2483 DBUG_ENTER("sp_head::reset_lex");
2484 sp_lex_local *sublex= new (thd->mem_root) sp_lex_local(thd, thd->lex);
2485 DBUG_RETURN(sublex ? reset_lex(thd, sublex) : true);
2486 }
2487
2488
2489 /**
2490 Restore lex during parsing, after we have parsed a sub statement.
2491
2492 @param thd Thread handle
2493 @param oldlex The upper level lex we're near to restore to
2494 @param sublex The local lex we're near to restore from
2495
2496 @return
2497 @retval TRUE failure
2498 @retval FALSE success
2499 */
2500
2501 bool
merge_lex(THD * thd,LEX * oldlex,LEX * sublex)2502 sp_head::merge_lex(THD *thd, LEX *oldlex, LEX *sublex)
2503 {
2504 DBUG_ENTER("sp_head::merge_lex");
2505
2506 sublex->set_trg_event_type_for_tables();
2507
2508 oldlex->trg_table_fields.push_back(&sublex->trg_table_fields);
2509
2510 /* If this substatement is unsafe, the entire routine is too. */
2511 DBUG_PRINT("info", ("sublex->get_stmt_unsafe_flags: 0x%x",
2512 sublex->get_stmt_unsafe_flags()));
2513 unsafe_flags|= sublex->get_stmt_unsafe_flags();
2514
2515 /*
2516 Add routines which are used by statement to respective set for
2517 this routine.
2518 */
2519 if (sp_update_sp_used_routines(&m_sroutines, &sublex->sroutines))
2520 DBUG_RETURN(TRUE);
2521
2522 /* If this substatement is a update query, then mark MODIFIES_DATA */
2523 if (is_update_query(sublex->sql_command))
2524 m_flags|= MODIFIES_DATA;
2525
2526 /*
2527 Merge tables used by this statement (but not by its functions or
2528 procedures) to multiset of tables used by this routine.
2529 */
2530 merge_table_list(thd, sublex->query_tables, sublex);
2531 /* Merge lists of PS parameters. */
2532 oldlex->param_list.append(&sublex->param_list);
2533
2534 DBUG_RETURN(FALSE);
2535 }
2536
2537 /**
2538 Put the instruction on the backpatch list, associated with the label.
2539 */
2540
2541 int
push_backpatch(THD * thd,sp_instr * i,sp_label * lab,List<bp_t> * list,backpatch_instr_type itype)2542 sp_head::push_backpatch(THD *thd, sp_instr *i, sp_label *lab,
2543 List<bp_t> *list, backpatch_instr_type itype)
2544 {
2545 bp_t *bp= (bp_t *) thd->alloc(sizeof(bp_t));
2546
2547 if (!bp)
2548 return 1;
2549 bp->lab= lab;
2550 bp->instr= i;
2551 bp->instr_type= itype;
2552 return list->push_front(bp);
2553 }
2554
2555 int
push_backpatch(THD * thd,sp_instr * i,sp_label * lab)2556 sp_head::push_backpatch(THD *thd, sp_instr *i, sp_label *lab)
2557 {
2558 return push_backpatch(thd, i, lab, &m_backpatch, GOTO);
2559 }
2560
2561 int
push_backpatch_goto(THD * thd,sp_pcontext * ctx,sp_label * lab)2562 sp_head::push_backpatch_goto(THD *thd, sp_pcontext *ctx, sp_label *lab)
2563 {
2564 uint ip= instructions();
2565
2566 /*
2567 Add cpop/hpop : they will be removed or updated later if target is in
2568 the same block or not
2569 */
2570 sp_instr_hpop *hpop= new (thd->mem_root) sp_instr_hpop(ip++, ctx, 0);
2571 if (hpop == NULL || add_instr(hpop))
2572 return true;
2573 if (push_backpatch(thd, hpop, lab, &m_backpatch_goto, HPOP))
2574 return true;
2575
2576 sp_instr_cpop *cpop= new (thd->mem_root) sp_instr_cpop(ip++, ctx, 0);
2577 if (cpop == NULL || add_instr(cpop))
2578 return true;
2579 if (push_backpatch(thd, cpop, lab, &m_backpatch_goto, CPOP))
2580 return true;
2581
2582 // Add jump with ip=0. IP will be updated when label is found.
2583 sp_instr_jump *i= new (thd->mem_root) sp_instr_jump(ip, ctx);
2584 if (i == NULL || add_instr(i))
2585 return true;
2586 if (push_backpatch(thd, i, lab, &m_backpatch_goto, GOTO))
2587 return true;
2588
2589 return false;
2590 }
2591
2592 /**
2593 Update all instruction with this label in the backpatch list to
2594 the current position.
2595 */
2596
2597 void
backpatch(sp_label * lab)2598 sp_head::backpatch(sp_label *lab)
2599 {
2600 bp_t *bp;
2601 uint dest= instructions();
2602 List_iterator_fast<bp_t> li(m_backpatch);
2603
2604 DBUG_ENTER("sp_head::backpatch");
2605 while ((bp= li++))
2606 {
2607 if (bp->lab == lab)
2608 {
2609 DBUG_PRINT("info", ("backpatch: (m_ip %d, label %p <%s>) to dest %d",
2610 bp->instr->m_ip, lab, lab->name.str, dest));
2611 bp->instr->backpatch(dest, lab->ctx);
2612 }
2613 }
2614 DBUG_VOID_RETURN;
2615 }
2616
2617 void
backpatch_goto(THD * thd,sp_label * lab,sp_label * lab_begin_block)2618 sp_head::backpatch_goto(THD *thd, sp_label *lab,sp_label *lab_begin_block)
2619 {
2620 bp_t *bp;
2621 uint dest= instructions();
2622 List_iterator<bp_t> li(m_backpatch_goto);
2623
2624 DBUG_ENTER("sp_head::backpatch_goto");
2625 while ((bp= li++))
2626 {
2627 if (bp->instr->m_ip < lab_begin_block->ip || bp->instr->m_ip > lab->ip)
2628 {
2629 /*
2630 Update only jump target from the beginning of the block where the
2631 label is defined.
2632 */
2633 continue;
2634 }
2635 if (lex_string_cmp(system_charset_info, &bp->lab->name, &lab->name) == 0)
2636 {
2637 if (bp->instr_type == GOTO)
2638 {
2639 DBUG_PRINT("info",
2640 ("backpatch_goto: (m_ip %d, label %p <%s>) to dest %d",
2641 bp->instr->m_ip, lab, lab->name.str, dest));
2642 bp->instr->backpatch(dest, lab->ctx);
2643 // Jump resolved, remove from the list
2644 li.remove();
2645 continue;
2646 }
2647 if (bp->instr_type == CPOP)
2648 {
2649 uint n= bp->instr->m_ctx->diff_cursors(lab_begin_block->ctx, true);
2650 if (n == 0)
2651 {
2652 // Remove cpop instr
2653 replace_instr_to_nop(thd,bp->instr->m_ip);
2654 }
2655 else
2656 {
2657 // update count of cpop
2658 static_cast<sp_instr_cpop*>(bp->instr)->update_count(n);
2659 n= 1;
2660 }
2661 li.remove();
2662 continue;
2663 }
2664 if (bp->instr_type == HPOP)
2665 {
2666 uint n= bp->instr->m_ctx->diff_handlers(lab_begin_block->ctx, true);
2667 if (n == 0)
2668 {
2669 // Remove hpop instr
2670 replace_instr_to_nop(thd,bp->instr->m_ip);
2671 }
2672 else
2673 {
2674 // update count of cpop
2675 static_cast<sp_instr_hpop*>(bp->instr)->update_count(n);
2676 n= 1;
2677 }
2678 li.remove();
2679 continue;
2680 }
2681 }
2682 }
2683 DBUG_VOID_RETURN;
2684 }
2685
2686 bool
check_unresolved_goto()2687 sp_head::check_unresolved_goto()
2688 {
2689 DBUG_ENTER("sp_head::check_unresolved_goto");
2690 bool has_unresolved_label=false;
2691 if (m_backpatch_goto.elements > 0)
2692 {
2693 List_iterator_fast<bp_t> li(m_backpatch_goto);
2694 while (bp_t* bp= li++)
2695 {
2696 if (bp->instr_type == GOTO)
2697 {
2698 my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "GOTO", bp->lab->name.str);
2699 has_unresolved_label=true;
2700 }
2701 }
2702 }
2703 DBUG_RETURN(has_unresolved_label);
2704 }
2705
2706 int
new_cont_backpatch(sp_instr_opt_meta * i)2707 sp_head::new_cont_backpatch(sp_instr_opt_meta *i)
2708 {
2709 m_cont_level+= 1;
2710 if (i)
2711 {
2712 /* Use the cont. destination slot to store the level */
2713 i->m_cont_dest= m_cont_level;
2714 if (m_cont_backpatch.push_front(i))
2715 return 1;
2716 }
2717 return 0;
2718 }
2719
2720 int
add_cont_backpatch(sp_instr_opt_meta * i)2721 sp_head::add_cont_backpatch(sp_instr_opt_meta *i)
2722 {
2723 i->m_cont_dest= m_cont_level;
2724 return m_cont_backpatch.push_front(i);
2725 }
2726
2727 void
do_cont_backpatch()2728 sp_head::do_cont_backpatch()
2729 {
2730 uint dest= instructions();
2731 uint lev= m_cont_level--;
2732 sp_instr_opt_meta *i;
2733
2734 while ((i= m_cont_backpatch.head()) && i->m_cont_dest == lev)
2735 {
2736 i->m_cont_dest= dest;
2737 (void)m_cont_backpatch.pop();
2738 }
2739 }
2740
2741
2742 bool
sp_add_instr_cpush_for_cursors(THD * thd,sp_pcontext * pcontext)2743 sp_head::sp_add_instr_cpush_for_cursors(THD *thd, sp_pcontext *pcontext)
2744 {
2745 for (uint i= 0; i < pcontext->frame_cursor_count(); i++)
2746 {
2747 const sp_pcursor *c= pcontext->get_cursor_by_local_frame_offset(i);
2748 sp_instr_cpush *instr= new (thd->mem_root)
2749 sp_instr_cpush(instructions(), pcontext, c->lex(),
2750 pcontext->cursor_offset() + i);
2751 if (instr == NULL || add_instr(instr))
2752 return true;
2753 }
2754 return false;
2755 }
2756
2757
2758 void
set_chistics(const st_sp_chistics & chistics)2759 sp_head::set_chistics(const st_sp_chistics &chistics)
2760 {
2761 m_chistics.set(chistics);
2762 if (m_chistics.comment.length == 0)
2763 m_chistics.comment.str= 0;
2764 else
2765 m_chistics.comment.str= strmake_root(mem_root,
2766 m_chistics.comment.str,
2767 m_chistics.comment.length);
2768 }
2769
2770
2771 void
set_c_chistics(const st_sp_chistics & chistics)2772 sp_head::set_c_chistics(const st_sp_chistics &chistics)
2773 {
2774 // Set all chistics but preserve agg_type.
2775 enum_sp_aggregate_type save_agg_type= agg_type();
2776 set_chistics(chistics);
2777 set_chistics_agg_type(save_agg_type);
2778 }
2779
2780
2781 void
set_info(longlong created,longlong modified,const st_sp_chistics & chistics,sql_mode_t sql_mode)2782 sp_head::set_info(longlong created, longlong modified,
2783 const st_sp_chistics &chistics, sql_mode_t sql_mode)
2784 {
2785 m_created= created;
2786 m_modified= modified;
2787 set_chistics(chistics);
2788 m_sql_mode= sql_mode;
2789 }
2790
2791
2792 void
reset_thd_mem_root(THD * thd)2793 sp_head::reset_thd_mem_root(THD *thd)
2794 {
2795 DBUG_ENTER("sp_head::reset_thd_mem_root");
2796 m_thd_root= thd->mem_root;
2797 thd->mem_root= &main_mem_root;
2798 DBUG_PRINT("info", ("mem_root %p moved to thd mem root %p",
2799 &mem_root, &thd->mem_root));
2800 free_list= thd->free_list; // Keep the old list
2801 thd->free_list= NULL; // Start a new one
2802 m_thd= thd;
2803 DBUG_VOID_RETURN;
2804 }
2805
2806 void
restore_thd_mem_root(THD * thd)2807 sp_head::restore_thd_mem_root(THD *thd)
2808 {
2809 DBUG_ENTER("sp_head::restore_thd_mem_root");
2810
2811 /*
2812 In some cases our parser detects a syntax error and calls
2813 LEX::cleanup_lex_after_parse_error() method only after
2814 finishing parsing the whole routine. In such a situation
2815 sp_head::restore_thd_mem_root() will be called twice - the
2816 first time as part of normal parsing process and the second
2817 time by cleanup_lex_after_parse_error().
2818 To avoid ruining active arena/mem_root state in this case we
2819 skip restoration of old arena/mem_root if this method has been
2820 already called for this routine.
2821 */
2822 if (!m_thd)
2823 DBUG_VOID_RETURN;
2824
2825 Item *flist= free_list; // The old list
2826 set_query_arena(thd); // Get new free_list and mem_root
2827 state= STMT_INITIALIZED_FOR_SP;
2828
2829 DBUG_PRINT("info", ("mem_root %p returned from thd mem root %p",
2830 &mem_root, &thd->mem_root));
2831 thd->free_list= flist; // Restore the old one
2832 thd->mem_root= m_thd_root;
2833 m_thd= NULL;
2834 DBUG_VOID_RETURN;
2835 }
2836
2837
2838 /**
2839 Check if a user has access right to a routine.
2840
2841 @param thd Thread handler
2842 @param sp SP
2843 @param full_access Set to 1 if the user has SELECT right to the
2844 'mysql.proc' able or is the owner of the routine
2845 @retval
2846 false ok
2847 @retval
2848 true error
2849 */
2850
check_show_routine_access(THD * thd,sp_head * sp,bool * full_access)2851 bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access)
2852 {
2853 TABLE_LIST tables;
2854 bzero((char*) &tables,sizeof(tables));
2855 tables.db= MYSQL_SCHEMA_NAME;
2856 tables.table_name= MYSQL_PROC_NAME;
2857 tables.alias= MYSQL_PROC_NAME;
2858
2859 *full_access= ((!check_table_access(thd, SELECT_ACL, &tables, FALSE,
2860 1, TRUE) &&
2861 (tables.grant.privilege & SELECT_ACL) != 0) ||
2862 /* Check if user owns the routine. */
2863 (!strcmp(sp->m_definer.user.str,
2864 thd->security_ctx->priv_user) &&
2865 !strcmp(sp->m_definer.host.str,
2866 thd->security_ctx->priv_host)) ||
2867 /* Check if current role or any of the sub-granted roles
2868 own the routine. */
2869 (sp->m_definer.host.length == 0 &&
2870 (!strcmp(sp->m_definer.user.str,
2871 thd->security_ctx->priv_role) ||
2872 check_role_is_granted(thd->security_ctx->priv_role, NULL,
2873 sp->m_definer.user.str))));
2874 if (!*full_access)
2875 return check_some_routine_access(thd, sp->m_db.str, sp->m_name.str,
2876 sp->m_handler);
2877 return 0;
2878 }
2879
2880
2881 /**
2882 Collect metadata for SHOW CREATE statement for stored routines.
2883
2884 @param thd Thread context.
2885 @param sph Stored routine handler
2886 @param fields Item list to populate
2887
2888 @return Error status.
2889 @retval FALSE on success
2890 @retval TRUE on error
2891 */
2892
2893 void
show_create_routine_get_fields(THD * thd,const Sp_handler * sph,List<Item> * fields)2894 sp_head::show_create_routine_get_fields(THD *thd, const Sp_handler *sph,
2895 List<Item> *fields)
2896 {
2897 const char *col1_caption= sph->show_create_routine_col1_caption();
2898 const char *col3_caption= sph->show_create_routine_col3_caption();
2899
2900 MEM_ROOT *mem_root= thd->mem_root;
2901
2902 /* Send header. */
2903
2904 fields->push_back(new (mem_root)
2905 Item_empty_string(thd, col1_caption, NAME_CHAR_LEN),
2906 mem_root);
2907 fields->push_back(new (mem_root)
2908 Item_empty_string(thd, "sql_mode", 256),
2909 mem_root);
2910
2911 {
2912 /*
2913 NOTE: SQL statement field must be not less than 1024 in order not to
2914 confuse old clients.
2915 */
2916
2917 Item_empty_string *stmt_fld=
2918 new (mem_root) Item_empty_string(thd, col3_caption, 1024);
2919 stmt_fld->maybe_null= TRUE;
2920
2921 fields->push_back(stmt_fld, mem_root);
2922 }
2923
2924 fields->push_back(new (mem_root)
2925 Item_empty_string(thd, "character_set_client",
2926 MY_CS_NAME_SIZE),
2927 mem_root);
2928
2929 fields->push_back(new (mem_root)
2930 Item_empty_string(thd, "collation_connection",
2931 MY_CS_NAME_SIZE),
2932 mem_root);
2933
2934 fields->push_back(new (mem_root)
2935 Item_empty_string(thd, "Database Collation",
2936 MY_CS_NAME_SIZE),
2937 mem_root);
2938 }
2939
2940
2941 /**
2942 Implement SHOW CREATE statement for stored routines.
2943
2944 @param thd Thread context.
2945 @param sph Stored routine handler
2946
2947 @return Error status.
2948 @retval FALSE on success
2949 @retval TRUE on error
2950 */
2951
2952 bool
show_create_routine(THD * thd,const Sp_handler * sph)2953 sp_head::show_create_routine(THD *thd, const Sp_handler *sph)
2954 {
2955 const char *col1_caption= sph->show_create_routine_col1_caption();
2956 const char *col3_caption= sph->show_create_routine_col3_caption();
2957
2958 bool err_status;
2959
2960 Protocol *protocol= thd->protocol;
2961 List<Item> fields;
2962
2963 LEX_CSTRING sql_mode;
2964
2965 bool full_access;
2966 MEM_ROOT *mem_root= thd->mem_root;
2967
2968 DBUG_ENTER("sp_head::show_create_routine");
2969 DBUG_PRINT("info", ("routine %s", m_name.str));
2970
2971 if (check_show_routine_access(thd, this, &full_access))
2972 DBUG_RETURN(TRUE);
2973
2974 sql_mode_string_representation(thd, m_sql_mode, &sql_mode);
2975
2976 /* Send header. */
2977
2978 fields.push_back(new (mem_root)
2979 Item_empty_string(thd, col1_caption, NAME_CHAR_LEN),
2980 thd->mem_root);
2981 fields.push_back(new (mem_root)
2982 Item_empty_string(thd, "sql_mode", (uint)sql_mode.length),
2983 thd->mem_root);
2984
2985 {
2986 /*
2987 NOTE: SQL statement field must be not less than 1024 in order not to
2988 confuse old clients.
2989 */
2990
2991 Item_empty_string *stmt_fld=
2992 new (mem_root) Item_empty_string(thd, col3_caption,
2993 (uint)MY_MAX(m_defstr.length, 1024));
2994
2995 stmt_fld->maybe_null= TRUE;
2996
2997 fields.push_back(stmt_fld, thd->mem_root);
2998 }
2999
3000 fields.push_back(new (mem_root)
3001 Item_empty_string(thd, "character_set_client",
3002 MY_CS_NAME_SIZE),
3003 thd->mem_root);
3004
3005 fields.push_back(new (mem_root)
3006 Item_empty_string(thd, "collation_connection",
3007 MY_CS_NAME_SIZE),
3008 thd->mem_root);
3009
3010 fields.push_back(new (mem_root)
3011 Item_empty_string(thd, "Database Collation",
3012 MY_CS_NAME_SIZE),
3013 thd->mem_root);
3014
3015 if (protocol->send_result_set_metadata(&fields,
3016 Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
3017 {
3018 DBUG_RETURN(TRUE);
3019 }
3020
3021 /* Send data. */
3022
3023 protocol->prepare_for_resend();
3024
3025 protocol->store(m_name.str, m_name.length, system_charset_info);
3026 protocol->store(sql_mode.str, sql_mode.length, system_charset_info);
3027
3028 if (full_access)
3029 protocol->store(m_defstr.str, m_defstr.length,
3030 m_creation_ctx->get_client_cs());
3031 else
3032 protocol->store_null();
3033
3034
3035 protocol->store(m_creation_ctx->get_client_cs()->csname, system_charset_info);
3036 protocol->store(m_creation_ctx->get_connection_cl()->name, system_charset_info);
3037 protocol->store(m_creation_ctx->get_db_cl()->name, system_charset_info);
3038
3039 err_status= protocol->write();
3040
3041 if (!err_status)
3042 my_eof(thd);
3043
3044 DBUG_RETURN(err_status);
3045 }
3046
3047
3048 /**
3049 Add instruction to SP.
3050
3051 @param instr Instruction
3052 */
3053
add_instr(sp_instr * instr)3054 int sp_head::add_instr(sp_instr *instr)
3055 {
3056 instr->free_list= m_thd->free_list;
3057 m_thd->free_list= 0;
3058 /*
3059 Memory root of every instruction is designated for permanent
3060 transformations (optimizations) made on the parsed tree during
3061 the first execution. It points to the memory root of the
3062 entire stored procedure, as their life span is equal.
3063 */
3064 instr->mem_root= &main_mem_root;
3065 instr->m_lineno= m_thd->m_parser_state->m_lip.yylineno;
3066 return insert_dynamic(&m_instr, (uchar*)&instr);
3067 }
3068
3069
add_instr_jump(THD * thd,sp_pcontext * spcont)3070 bool sp_head::add_instr_jump(THD *thd, sp_pcontext *spcont)
3071 {
3072 sp_instr_jump *i= new (thd->mem_root) sp_instr_jump(instructions(), spcont);
3073 return i == NULL || add_instr(i);
3074 }
3075
3076
add_instr_jump(THD * thd,sp_pcontext * spcont,uint dest)3077 bool sp_head::add_instr_jump(THD *thd, sp_pcontext *spcont, uint dest)
3078 {
3079 sp_instr_jump *i= new (thd->mem_root) sp_instr_jump(instructions(),
3080 spcont, dest);
3081 return i == NULL || add_instr(i);
3082 }
3083
3084
add_instr_jump_forward_with_backpatch(THD * thd,sp_pcontext * spcont,sp_label * lab)3085 bool sp_head::add_instr_jump_forward_with_backpatch(THD *thd,
3086 sp_pcontext *spcont,
3087 sp_label *lab)
3088 {
3089 sp_instr_jump *i= new (thd->mem_root) sp_instr_jump(instructions(), spcont);
3090 if (i == NULL || add_instr(i))
3091 return true;
3092 push_backpatch(thd, i, lab);
3093 return false;
3094 }
3095
3096
add_instr_freturn(THD * thd,sp_pcontext * spcont,Item * item,LEX * lex)3097 bool sp_head::add_instr_freturn(THD *thd, sp_pcontext *spcont,
3098 Item *item, LEX *lex)
3099 {
3100 sp_instr_freturn *i= new (thd->mem_root)
3101 sp_instr_freturn(instructions(), spcont, item,
3102 m_return_field_def.type_handler(), thd->lex);
3103 if (i == NULL || add_instr(i))
3104 return true;
3105 m_flags|= sp_head::HAS_RETURN;
3106 return false;
3107 }
3108
3109
add_instr_preturn(THD * thd,sp_pcontext * spcont)3110 bool sp_head::add_instr_preturn(THD *thd, sp_pcontext *spcont)
3111 {
3112 sp_instr_preturn *i= new (thd->mem_root)
3113 sp_instr_preturn(instructions(), spcont);
3114 if (i == NULL || add_instr(i))
3115 return true;
3116 return false;
3117 }
3118
3119
3120 /*
3121 Replace an instruction at position to "no operation".
3122
3123 @param thd - use mem_root of this THD for "new".
3124 @param ip - position of the operation
3125 @returns - true on error, false on success
3126
3127 When we need to remove an instruction that during compilation
3128 appeared to be useless (typically as useless jump), we replace
3129 it to a jump to exactly the next instruction.
3130 Such jumps are later removed during sp_head::optimize().
3131
3132 QQ: Perhaps we need a dedicated sp_instr_nop for this purpose.
3133 */
3134
replace_instr_to_nop(THD * thd,uint ip)3135 bool sp_head::replace_instr_to_nop(THD *thd, uint ip)
3136 {
3137 sp_instr *instr= get_instr(ip);
3138 sp_instr_jump *nop= new (thd->mem_root) sp_instr_jump(instr->m_ip,
3139 instr->m_ctx,
3140 instr->m_ip + 1);
3141 if (!nop)
3142 return true;
3143 delete instr;
3144 set_dynamic(&m_instr, (uchar *) &nop, ip);
3145 return false;
3146 }
3147
3148
3149 /**
3150 Do some minimal optimization of the code:
3151 -# Mark used instructions
3152 -# While doing this, shortcut jumps to jump instructions
3153 -# Compact the code, removing unused instructions.
3154
3155 This is the main mark and move loop; it relies on the following methods
3156 in sp_instr and its subclasses:
3157
3158 - opt_mark() : Mark instruction as reachable
3159 - opt_shortcut_jump(): Shortcut jumps to the final destination;
3160 used by opt_mark().
3161 - opt_move() : Update moved instruction
3162 - set_destination() : Set the new destination (jump instructions only)
3163 */
3164
optimize()3165 void sp_head::optimize()
3166 {
3167 List<sp_instr> bp;
3168 sp_instr *i;
3169 uint src, dst;
3170
3171 DBUG_EXECUTE_IF("sp_head_optimize_disable", return; );
3172
3173 opt_mark();
3174
3175 bp.empty();
3176 src= dst= 0;
3177 while ((i= get_instr(src)))
3178 {
3179 if (! i->marked)
3180 {
3181 delete i;
3182 src+= 1;
3183 }
3184 else
3185 {
3186 if (src != dst)
3187 {
3188 /* Move the instruction and update prev. jumps */
3189 sp_instr *ibp;
3190 List_iterator_fast<sp_instr> li(bp);
3191
3192 set_dynamic(&m_instr, (uchar*)&i, dst);
3193 while ((ibp= li++))
3194 {
3195 sp_instr_opt_meta *im= static_cast<sp_instr_opt_meta *>(ibp);
3196 im->set_destination(src, dst);
3197 }
3198 }
3199 i->opt_move(dst, &bp);
3200 src+= 1;
3201 dst+= 1;
3202 }
3203 }
3204 m_instr.elements= dst;
3205 bp.empty();
3206 }
3207
add_mark_lead(uint ip,List<sp_instr> * leads)3208 void sp_head::add_mark_lead(uint ip, List<sp_instr> *leads)
3209 {
3210 sp_instr *i= get_instr(ip);
3211
3212 if (i && ! i->marked)
3213 leads->push_front(i);
3214 }
3215
3216 void
opt_mark()3217 sp_head::opt_mark()
3218 {
3219 uint ip;
3220 sp_instr *i;
3221 List<sp_instr> leads;
3222
3223 /*
3224 Forward flow analysis algorithm in the instruction graph:
3225 - first, add the entry point in the graph (the first instruction) to the
3226 'leads' list of paths to explore.
3227 - while there are still leads to explore:
3228 - pick one lead, and follow the path forward. Mark instruction reached.
3229 Stop only if the end of the routine is reached, or the path converge
3230 to code already explored (marked).
3231 - while following a path, collect in the 'leads' list any fork to
3232 another path (caused by conditional jumps instructions), so that these
3233 paths can be explored as well.
3234 */
3235
3236 /* Add the entry point */
3237 i= get_instr(0);
3238 leads.push_front(i);
3239
3240 /* For each path of code ... */
3241 while (leads.elements != 0)
3242 {
3243 i= leads.pop();
3244
3245 /* Mark the entire path, collecting new leads. */
3246 while (i && ! i->marked)
3247 {
3248 ip= i->opt_mark(this, & leads);
3249 i= get_instr(ip);
3250 }
3251 }
3252 }
3253
3254
3255 #ifndef DBUG_OFF
3256 /**
3257 Return the routine instructions as a result set.
3258 @return
3259 0 if ok, !=0 on error.
3260 */
3261
3262 int
show_routine_code(THD * thd)3263 sp_head::show_routine_code(THD *thd)
3264 {
3265 Protocol *protocol= thd->protocol;
3266 char buff[2048];
3267 String buffer(buff, sizeof(buff), system_charset_info);
3268 List<Item> field_list;
3269 sp_instr *i;
3270 bool full_access;
3271 int res= 0;
3272 uint ip;
3273 DBUG_ENTER("sp_head::show_routine_code");
3274 DBUG_PRINT("info", ("procedure: %s", m_name.str));
3275
3276 if (check_show_routine_access(thd, this, &full_access) || !full_access)
3277 DBUG_RETURN(1);
3278
3279 field_list.push_back(new (thd->mem_root) Item_uint(thd, "Pos", 9),
3280 thd->mem_root);
3281 // 1024 is for not to confuse old clients
3282 field_list.push_back(new (thd->mem_root)
3283 Item_empty_string(thd, "Instruction",
3284 MY_MAX(buffer.length(), 1024)),
3285 thd->mem_root);
3286 if (protocol->send_result_set_metadata(&field_list, Protocol::SEND_NUM_ROWS |
3287 Protocol::SEND_EOF))
3288 DBUG_RETURN(1);
3289
3290 for (ip= 0; (i = get_instr(ip)) ; ip++)
3291 {
3292 /*
3293 Consistency check. If these are different something went wrong
3294 during optimization.
3295 */
3296 if (ip != i->m_ip)
3297 {
3298 const char *format= "Instruction at position %u has m_ip=%u";
3299 char tmp[sizeof(format) + 2*SP_INSTR_UINT_MAXLEN + 1];
3300
3301 my_snprintf(tmp, sizeof(tmp), format, ip, i->m_ip);
3302 /*
3303 Since this is for debugging purposes only, we don't bother to
3304 introduce a special error code for it.
3305 */
3306 push_warning(thd, Sql_condition::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR, tmp);
3307 }
3308 protocol->prepare_for_resend();
3309 protocol->store_long(ip);
3310
3311 buffer.set("", 0, system_charset_info);
3312 i->print(&buffer);
3313 protocol->store(buffer.ptr(), buffer.length(), system_charset_info);
3314 if ((res= protocol->write()))
3315 break;
3316 }
3317
3318 if (!res)
3319 my_eof(thd);
3320
3321 DBUG_RETURN(res);
3322 }
3323 #endif // ifndef DBUG_OFF
3324
3325
3326 /**
3327 Prepare LEX and thread for execution of instruction, if requested open
3328 and lock LEX's tables, execute instruction's core function, perform
3329 cleanup afterwards.
3330
3331 @param thd thread context
3332 @param nextp out - next instruction
3333 @param open_tables if TRUE then check read access to tables in LEX's table
3334 list and open and lock them (used in instructions which
3335 need to calculate some expression and don't execute
3336 complete statement).
3337 @param sp_instr instruction for which we prepare context, and which core
3338 function execute by calling its exec_core() method.
3339
3340 @note
3341 We are not saving/restoring some parts of THD which may need this because
3342 we do this once for whole routine execution in sp_head::execute().
3343
3344 @return
3345 0/non-0 - Success/Failure
3346 */
3347
3348 int
reset_lex_and_exec_core(THD * thd,uint * nextp,bool open_tables,sp_instr * instr)3349 sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
3350 bool open_tables, sp_instr* instr)
3351 {
3352 int res= 0;
3353 DBUG_ENTER("reset_lex_and_exec_core");
3354
3355 /*
3356 The flag is saved at the entry to the following substatement.
3357 It's reset further in the common code part.
3358 It's merged with the saved parent's value at the exit of this func.
3359 */
3360 bool parent_modified_non_trans_table=
3361 thd->transaction.stmt.modified_non_trans_table;
3362 unsigned int parent_unsafe_rollback_flags=
3363 thd->transaction.stmt.m_unsafe_rollback_flags;
3364 thd->transaction.stmt.modified_non_trans_table= FALSE;
3365 thd->transaction.stmt.m_unsafe_rollback_flags= 0;
3366
3367 DBUG_ASSERT(!thd->derived_tables);
3368 DBUG_ASSERT(thd->Item_change_list::is_empty());
3369 /*
3370 Use our own lex.
3371 We should not save old value since it is saved/restored in
3372 sp_head::execute() when we are entering/leaving routine.
3373 */
3374 thd->lex= m_lex;
3375
3376 thd->set_query_id(next_query_id());
3377
3378 if (thd->locked_tables_mode <= LTM_LOCK_TABLES)
3379 {
3380 /*
3381 This statement will enter/leave prelocked mode on its own.
3382 Entering prelocked mode changes table list and related members
3383 of LEX, so we'll need to restore them.
3384 */
3385 if (lex_query_tables_own_last)
3386 {
3387 /*
3388 We've already entered/left prelocked mode with this statement.
3389 Attach the list of tables that need to be prelocked and mark m_lex
3390 as having such list attached.
3391 */
3392 *lex_query_tables_own_last= prelocking_tables;
3393 m_lex->mark_as_requiring_prelocking(lex_query_tables_own_last);
3394 }
3395 }
3396
3397 reinit_stmt_before_use(thd, m_lex);
3398
3399 #ifndef EMBEDDED_LIBRARY
3400 /*
3401 If there was instruction which changed tracking state,
3402 the result of changed tracking state send to client in OK packed.
3403 So it changes result sent to client and probably can be different
3404 independent on query text. So we can't cache such results.
3405 */
3406 if ((thd->client_capabilities & CLIENT_SESSION_TRACK) &&
3407 (thd->server_status & SERVER_SESSION_STATE_CHANGED))
3408 thd->lex->safe_to_cache_query= 0;
3409 #endif
3410
3411 Opt_trace_start ots(thd, m_lex->query_tables,
3412 SQLCOM_SELECT, &m_lex->var_list,
3413 NULL, 0,
3414 thd->variables.character_set_client);
3415
3416 Json_writer_object trace_command(thd);
3417 Json_writer_array trace_command_steps(thd, "steps");
3418 if (open_tables)
3419 res= instr->exec_open_and_lock_tables(thd, m_lex->query_tables);
3420
3421 if (likely(!res))
3422 {
3423 res= instr->exec_core(thd, nextp);
3424 DBUG_PRINT("info",("exec_core returned: %d", res));
3425 }
3426
3427 /*
3428 Call after unit->cleanup() to close open table
3429 key read.
3430 */
3431 if (open_tables)
3432 {
3433 m_lex->unit.cleanup();
3434 /* Here we also commit or rollback the current statement. */
3435 if (! thd->in_sub_stmt)
3436 {
3437 thd->get_stmt_da()->set_overwrite_status(true);
3438 thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
3439 thd->get_stmt_da()->set_overwrite_status(false);
3440 }
3441 close_thread_tables(thd);
3442 thd_proc_info(thd, 0);
3443
3444 if (! thd->in_sub_stmt)
3445 {
3446 if (thd->transaction_rollback_request)
3447 {
3448 trans_rollback_implicit(thd);
3449 thd->release_transactional_locks();
3450 }
3451 else if (! thd->in_multi_stmt_transaction_mode())
3452 thd->release_transactional_locks();
3453 else
3454 thd->mdl_context.release_statement_locks();
3455 }
3456 }
3457 //TODO: why is this here if log_slow_query is in sp_instr_stmt_execute?
3458 delete_explain_query(m_lex);
3459
3460 if (m_lex->query_tables_own_last)
3461 {
3462 /*
3463 We've entered and left prelocking mode when executing statement
3464 stored in m_lex.
3465 m_lex->query_tables(->next_global)* list now has a 'tail' - a list
3466 of tables that are added for prelocking. (If this is the first
3467 execution, the 'tail' was added by open_tables(), otherwise we've
3468 attached it above in this function).
3469 Now we'll save the 'tail', and detach it.
3470 */
3471 lex_query_tables_own_last= m_lex->query_tables_own_last;
3472 prelocking_tables= *lex_query_tables_own_last;
3473 *lex_query_tables_own_last= NULL;
3474 m_lex->mark_as_requiring_prelocking(NULL);
3475 }
3476 thd->rollback_item_tree_changes();
3477 /*
3478 Update the state of the active arena if no errors on
3479 open_tables stage.
3480 */
3481 if (likely(!res) || likely(!thd->is_error()))
3482 thd->stmt_arena->state= Query_arena::STMT_EXECUTED;
3483
3484 /*
3485 Merge here with the saved parent's values
3486 what is needed from the substatement gained
3487 */
3488 thd->transaction.stmt.modified_non_trans_table |= parent_modified_non_trans_table;
3489 thd->transaction.stmt.m_unsafe_rollback_flags |= parent_unsafe_rollback_flags;
3490
3491 TRANSACT_TRACKER(add_trx_state_from_thd(thd));
3492
3493 /*
3494 Unlike for PS we should not call Item's destructors for newly created
3495 items after execution of each instruction in stored routine. This is
3496 because SP often create Item (like Item_int, Item_string etc...) when
3497 they want to store some value in local variable, pass return value and
3498 etc... So their life time should be longer than one instruction.
3499
3500 cleanup_items() is called in sp_head::execute()
3501 */
3502 thd->lex->restore_set_statement_var();
3503 DBUG_RETURN(res || thd->is_error());
3504 }
3505
3506
cursor_reset_lex_and_exec_core(THD * thd,uint * nextp,bool open_tables,sp_instr * instr)3507 int sp_lex_keeper::cursor_reset_lex_and_exec_core(THD *thd, uint *nextp,
3508 bool open_tables,
3509 sp_instr *instr)
3510 {
3511 Query_arena *old_arena= thd->stmt_arena;
3512 /*
3513 Get the Query_arena from the cursor statement LEX, which contains
3514 the free_list of the query, so new items (if any) are stored in
3515 the right free_list, and we can cleanup after each cursor operation,
3516 e.g. open or cursor_copy_struct (for cursor%ROWTYPE variables).
3517 */
3518 thd->stmt_arena= m_lex->query_arena();
3519 int res= reset_lex_and_exec_core(thd, nextp, open_tables, instr);
3520 cleanup_items(thd->stmt_arena->free_list);
3521 thd->stmt_arena= old_arena;
3522 return res;
3523 }
3524
3525
3526 /*
3527 sp_instr class functions
3528 */
3529
exec_open_and_lock_tables(THD * thd,TABLE_LIST * tables)3530 int sp_instr::exec_open_and_lock_tables(THD *thd, TABLE_LIST *tables)
3531 {
3532 int result;
3533
3534 /*
3535 Check whenever we have access to tables for this statement
3536 and open and lock them before executing instructions core function.
3537 */
3538 if (thd->open_temporary_tables(tables) ||
3539 check_table_access(thd, SELECT_ACL, tables, FALSE, UINT_MAX, FALSE)
3540 || open_and_lock_tables(thd, tables, TRUE, 0))
3541 result= -1;
3542 else
3543 result= 0;
3544 /* Prepare all derived tables/views to catch possible errors. */
3545 if (!result)
3546 result= mysql_handle_derived(thd->lex, DT_PREPARE) ? -1 : 0;
3547
3548 return result;
3549 }
3550
get_cont_dest() const3551 uint sp_instr::get_cont_dest() const
3552 {
3553 return (m_ip+1);
3554 }
3555
3556
exec_core(THD * thd,uint * nextp)3557 int sp_instr::exec_core(THD *thd, uint *nextp)
3558 {
3559 DBUG_ASSERT(0);
3560 return 0;
3561 }
3562
3563 /*
3564 sp_instr_stmt class functions
3565 */
3566
3567 int
execute(THD * thd,uint * nextp)3568 sp_instr_stmt::execute(THD *thd, uint *nextp)
3569 {
3570 int res;
3571 bool save_enable_slow_log;
3572 const CSET_STRING query_backup= thd->query_string;
3573 Sub_statement_state backup_state;
3574 DBUG_ENTER("sp_instr_stmt::execute");
3575 DBUG_PRINT("info", ("command: %d", m_lex_keeper.sql_command()));
3576
3577 #if defined(ENABLED_PROFILING)
3578 /* This s-p instr is profilable and will be captured. */
3579 thd->profiling.set_query_source(m_query.str, m_query.length);
3580 #endif
3581
3582 save_enable_slow_log= thd->enable_slow_log;
3583 thd->store_slow_query_state(&backup_state);
3584
3585 if (!(res= alloc_query(thd, m_query.str, m_query.length)) &&
3586 !(res=subst_spvars(thd, this, &m_query)))
3587 {
3588 /*
3589 (the order of query cache and subst_spvars calls is irrelevant because
3590 queries with SP vars can't be cached)
3591 */
3592 general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
3593
3594 if (query_cache_send_result_to_client(thd, thd->query(),
3595 thd->query_length()) <= 0)
3596 {
3597 thd->reset_slow_query_state();
3598 res= m_lex_keeper.reset_lex_and_exec_core(thd, nextp, FALSE, this);
3599 bool log_slow= !res && thd->enable_slow_log;
3600
3601 /* Finalize server status flags after executing a statement. */
3602 if (log_slow || thd->get_stmt_da()->is_eof())
3603 thd->update_server_status();
3604
3605 if (thd->get_stmt_da()->is_eof())
3606 thd->protocol->end_statement();
3607
3608 query_cache_end_of_result(thd);
3609
3610 mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_STATUS,
3611 thd->get_stmt_da()->is_error() ?
3612 thd->get_stmt_da()->sql_errno() : 0,
3613 command_name[COM_QUERY].str);
3614
3615 if (log_slow)
3616 log_slow_statement(thd);
3617
3618 /*
3619 Restore enable_slow_log, that can be changed by a admin or call
3620 command
3621 */
3622 thd->enable_slow_log= save_enable_slow_log;
3623
3624 /* Add the number of rows to thd for the 'call' statistics */
3625 thd->add_slow_query_state(&backup_state);
3626 }
3627 else
3628 {
3629 /* change statistics */
3630 enum_sql_command save_sql_command= thd->lex->sql_command;
3631 thd->lex->sql_command= SQLCOM_SELECT;
3632 status_var_increment(thd->status_var.com_stat[SQLCOM_SELECT]);
3633 thd->update_stats();
3634 thd->lex->sql_command= save_sql_command;
3635 *nextp= m_ip+1;
3636 }
3637 thd->set_query(query_backup);
3638 thd->query_name_consts= 0;
3639
3640 if (likely(!thd->is_error()))
3641 {
3642 res= 0;
3643 thd->get_stmt_da()->reset_diagnostics_area();
3644 }
3645 }
3646
3647 DBUG_RETURN(res || thd->is_error());
3648 }
3649
3650
3651 void
print(String * str)3652 sp_instr_stmt::print(String *str)
3653 {
3654 size_t i, len;
3655
3656 /* stmt CMD "..." */
3657 if (str->reserve(SP_STMT_PRINT_MAXLEN+SP_INSTR_UINT_MAXLEN+8))
3658 return;
3659 str->qs_append(STRING_WITH_LEN("stmt "));
3660 str->qs_append((uint)m_lex_keeper.sql_command());
3661 str->qs_append(STRING_WITH_LEN(" \""));
3662 len= m_query.length;
3663 /*
3664 Print the query string (but not too much of it), just to indicate which
3665 statement it is.
3666 */
3667 if (len > SP_STMT_PRINT_MAXLEN)
3668 len= SP_STMT_PRINT_MAXLEN-3;
3669 /* Copy the query string and replace '\n' with ' ' in the process */
3670 for (i= 0 ; i < len ; i++)
3671 {
3672 char c= m_query.str[i];
3673 if (c == '\n')
3674 c= ' ';
3675 str->qs_append(c);
3676 }
3677 if (m_query.length > SP_STMT_PRINT_MAXLEN)
3678 str->qs_append(STRING_WITH_LEN("...")); /* Indicate truncated string */
3679 str->qs_append('"');
3680 }
3681
3682
3683 int
exec_core(THD * thd,uint * nextp)3684 sp_instr_stmt::exec_core(THD *thd, uint *nextp)
3685 {
3686 MYSQL_QUERY_EXEC_START(thd->query(),
3687 thd->thread_id,
3688 thd->get_db(),
3689 &thd->security_ctx->priv_user[0],
3690 (char *)thd->security_ctx->host_or_ip,
3691 3);
3692 int res= mysql_execute_command(thd);
3693 MYSQL_QUERY_EXEC_DONE(res);
3694 *nextp= m_ip+1;
3695 return res;
3696 }
3697
3698
3699 /*
3700 sp_instr_set class functions
3701 */
3702
3703 int
execute(THD * thd,uint * nextp)3704 sp_instr_set::execute(THD *thd, uint *nextp)
3705 {
3706 DBUG_ENTER("sp_instr_set::execute");
3707 DBUG_PRINT("info", ("offset: %u", m_offset));
3708
3709 DBUG_RETURN(m_lex_keeper.reset_lex_and_exec_core(thd, nextp, TRUE, this));
3710 }
3711
3712
get_rcontext(THD * thd) const3713 sp_rcontext *sp_instr_set::get_rcontext(THD *thd) const
3714 {
3715 return m_rcontext_handler->get_rcontext(thd->spcont);
3716 }
3717
3718
3719 int
exec_core(THD * thd,uint * nextp)3720 sp_instr_set::exec_core(THD *thd, uint *nextp)
3721 {
3722 int res= get_rcontext(thd)->set_variable(thd, m_offset, &m_value);
3723 delete_explain_query(thd->lex);
3724 *nextp = m_ip+1;
3725 return res;
3726 }
3727
3728 void
print(String * str)3729 sp_instr_set::print(String *str)
3730 {
3731 /* set name@offset ... */
3732 size_t rsrv = SP_INSTR_UINT_MAXLEN+6;
3733 sp_variable *var = m_ctx->find_variable(m_offset);
3734 const LEX_CSTRING *prefix= m_rcontext_handler->get_name_prefix();
3735
3736 /* 'var' should always be non-null, but just in case... */
3737 if (var)
3738 rsrv+= var->name.length + prefix->length;
3739 if (str->reserve(rsrv))
3740 return;
3741 str->qs_append(STRING_WITH_LEN("set "));
3742 str->qs_append(prefix->str, prefix->length);
3743 if (var)
3744 {
3745 str->qs_append(&var->name);
3746 str->qs_append('@');
3747 }
3748 str->qs_append(m_offset);
3749 str->qs_append(' ');
3750 m_value->print(str, enum_query_type(QT_ORDINARY |
3751 QT_ITEM_ORIGINAL_FUNC_NULLIF));
3752 }
3753
3754
3755 /*
3756 sp_instr_set_field class functions
3757 */
3758
3759 int
exec_core(THD * thd,uint * nextp)3760 sp_instr_set_row_field::exec_core(THD *thd, uint *nextp)
3761 {
3762 int res= get_rcontext(thd)->set_variable_row_field(thd, m_offset,
3763 m_field_offset,
3764 &m_value);
3765 delete_explain_query(thd->lex);
3766 *nextp= m_ip + 1;
3767 return res;
3768 }
3769
3770
3771 void
print(String * str)3772 sp_instr_set_row_field::print(String *str)
3773 {
3774 /* set name@offset[field_offset] ... */
3775 size_t rsrv= SP_INSTR_UINT_MAXLEN + 6 + 6 + 3;
3776 sp_variable *var= m_ctx->find_variable(m_offset);
3777 const LEX_CSTRING *prefix= m_rcontext_handler->get_name_prefix();
3778 DBUG_ASSERT(var);
3779 DBUG_ASSERT(var->field_def.is_row());
3780 const Column_definition *def=
3781 var->field_def.row_field_definitions()->elem(m_field_offset);
3782 DBUG_ASSERT(def);
3783
3784 rsrv+= var->name.length + def->field_name.length + prefix->length;
3785 if (str->reserve(rsrv))
3786 return;
3787 str->qs_append(STRING_WITH_LEN("set "));
3788 str->qs_append(prefix);
3789 str->qs_append(&var->name);
3790 str->qs_append('.');
3791 str->qs_append(&def->field_name);
3792 str->qs_append('@');
3793 str->qs_append(m_offset);
3794 str->qs_append('[');
3795 str->qs_append(m_field_offset);
3796 str->qs_append(']');
3797 str->qs_append(' ');
3798 m_value->print(str, enum_query_type(QT_ORDINARY |
3799 QT_ITEM_ORIGINAL_FUNC_NULLIF));
3800 }
3801
3802
3803 /*
3804 sp_instr_set_field_by_name class functions
3805 */
3806
3807 int
exec_core(THD * thd,uint * nextp)3808 sp_instr_set_row_field_by_name::exec_core(THD *thd, uint *nextp)
3809 {
3810 int res= get_rcontext(thd)->set_variable_row_field_by_name(thd, m_offset,
3811 m_field_name,
3812 &m_value);
3813 delete_explain_query(thd->lex);
3814 *nextp= m_ip + 1;
3815 return res;
3816 }
3817
3818
3819 void
print(String * str)3820 sp_instr_set_row_field_by_name::print(String *str)
3821 {
3822 /* set name.field@offset["field"] ... */
3823 size_t rsrv= SP_INSTR_UINT_MAXLEN + 6 + 6 + 3 + 2;
3824 sp_variable *var= m_ctx->find_variable(m_offset);
3825 const LEX_CSTRING *prefix= m_rcontext_handler->get_name_prefix();
3826 DBUG_ASSERT(var);
3827 DBUG_ASSERT(var->field_def.is_table_rowtype_ref() ||
3828 var->field_def.is_cursor_rowtype_ref());
3829
3830 rsrv+= var->name.length + 2 * m_field_name.length + prefix->length;
3831 if (str->reserve(rsrv))
3832 return;
3833 str->qs_append(STRING_WITH_LEN("set "));
3834 str->qs_append(prefix);
3835 str->qs_append(&var->name);
3836 str->qs_append('.');
3837 str->qs_append(&m_field_name);
3838 str->qs_append('@');
3839 str->qs_append(m_offset);
3840 str->qs_append("[\"",2);
3841 str->qs_append(&m_field_name);
3842 str->qs_append("\"]",2);
3843 str->qs_append(' ');
3844 m_value->print(str, enum_query_type(QT_ORDINARY |
3845 QT_ITEM_ORIGINAL_FUNC_NULLIF));
3846 }
3847
3848
3849 /*
3850 sp_instr_set_trigger_field class functions
3851 */
3852
3853 int
execute(THD * thd,uint * nextp)3854 sp_instr_set_trigger_field::execute(THD *thd, uint *nextp)
3855 {
3856 DBUG_ENTER("sp_instr_set_trigger_field::execute");
3857 thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
3858 DBUG_RETURN(m_lex_keeper.reset_lex_and_exec_core(thd, nextp, TRUE, this));
3859 }
3860
3861
3862 int
exec_core(THD * thd,uint * nextp)3863 sp_instr_set_trigger_field::exec_core(THD *thd, uint *nextp)
3864 {
3865 bool sav_abort_on_warning= thd->abort_on_warning;
3866 thd->abort_on_warning= thd->is_strict_mode() && !thd->lex->ignore;
3867 const int res= (trigger_field->set_value(thd, &value) ? -1 : 0);
3868 thd->abort_on_warning= sav_abort_on_warning;
3869 *nextp = m_ip+1;
3870 return res;
3871 }
3872
3873 void
print(String * str)3874 sp_instr_set_trigger_field::print(String *str)
3875 {
3876 str->append(STRING_WITH_LEN("set_trigger_field "));
3877 trigger_field->print(str, enum_query_type(QT_ORDINARY |
3878 QT_ITEM_ORIGINAL_FUNC_NULLIF));
3879 str->append(STRING_WITH_LEN(":="));
3880 value->print(str, enum_query_type(QT_ORDINARY |
3881 QT_ITEM_ORIGINAL_FUNC_NULLIF));
3882 }
3883
3884 /*
3885 sp_instr_opt_meta
3886 */
3887
get_cont_dest() const3888 uint sp_instr_opt_meta::get_cont_dest() const
3889 {
3890 return m_cont_dest;
3891 }
3892
3893
3894 /*
3895 sp_instr_jump class functions
3896 */
3897
3898 int
execute(THD * thd,uint * nextp)3899 sp_instr_jump::execute(THD *thd, uint *nextp)
3900 {
3901 DBUG_ENTER("sp_instr_jump::execute");
3902 DBUG_PRINT("info", ("destination: %u", m_dest));
3903
3904 *nextp= m_dest;
3905 DBUG_RETURN(0);
3906 }
3907
3908 void
print(String * str)3909 sp_instr_jump::print(String *str)
3910 {
3911 /* jump dest */
3912 if (str->reserve(SP_INSTR_UINT_MAXLEN+5))
3913 return;
3914 str->qs_append(STRING_WITH_LEN("jump "));
3915 str->qs_append(m_dest);
3916 }
3917
3918 uint
opt_mark(sp_head * sp,List<sp_instr> * leads)3919 sp_instr_jump::opt_mark(sp_head *sp, List<sp_instr> *leads)
3920 {
3921 m_dest= opt_shortcut_jump(sp, this);
3922 if (m_dest != m_ip+1) /* Jumping to following instruction? */
3923 marked= 1;
3924 m_optdest= sp->get_instr(m_dest);
3925 return m_dest;
3926 }
3927
3928 uint
opt_shortcut_jump(sp_head * sp,sp_instr * start)3929 sp_instr_jump::opt_shortcut_jump(sp_head *sp, sp_instr *start)
3930 {
3931 uint dest= m_dest;
3932 sp_instr *i;
3933
3934 while ((i= sp->get_instr(dest)))
3935 {
3936 uint ndest;
3937
3938 if (start == i || this == i)
3939 break;
3940 ndest= i->opt_shortcut_jump(sp, start);
3941 if (ndest == dest)
3942 break;
3943 dest= ndest;
3944 }
3945 return dest;
3946 }
3947
3948 void
opt_move(uint dst,List<sp_instr> * bp)3949 sp_instr_jump::opt_move(uint dst, List<sp_instr> *bp)
3950 {
3951 if (m_dest > m_ip)
3952 bp->push_back(this); // Forward
3953 else if (m_optdest)
3954 m_dest= m_optdest->m_ip; // Backward
3955 m_ip= dst;
3956 }
3957
3958
3959 /*
3960 sp_instr_jump_if_not class functions
3961 */
3962
3963 int
execute(THD * thd,uint * nextp)3964 sp_instr_jump_if_not::execute(THD *thd, uint *nextp)
3965 {
3966 DBUG_ENTER("sp_instr_jump_if_not::execute");
3967 DBUG_PRINT("info", ("destination: %u", m_dest));
3968 DBUG_RETURN(m_lex_keeper.reset_lex_and_exec_core(thd, nextp, TRUE, this));
3969 }
3970
3971
3972 int
exec_core(THD * thd,uint * nextp)3973 sp_instr_jump_if_not::exec_core(THD *thd, uint *nextp)
3974 {
3975 Item *it;
3976 int res;
3977
3978 it= thd->sp_prepare_func_item(&m_expr);
3979 if (! it)
3980 {
3981 res= -1;
3982 }
3983 else
3984 {
3985 res= 0;
3986 if (! it->val_bool())
3987 *nextp = m_dest;
3988 else
3989 *nextp = m_ip+1;
3990 }
3991
3992 return res;
3993 }
3994
3995
3996 void
print(String * str)3997 sp_instr_jump_if_not::print(String *str)
3998 {
3999 /* jump_if_not dest(cont) ... */
4000 if (str->reserve(2*SP_INSTR_UINT_MAXLEN+14+32)) // Add some for the expr. too
4001 return;
4002 str->qs_append(STRING_WITH_LEN("jump_if_not "));
4003 str->qs_append(m_dest);
4004 str->qs_append('(');
4005 str->qs_append(m_cont_dest);
4006 str->qs_append(STRING_WITH_LEN(") "));
4007 m_expr->print(str, enum_query_type(QT_ORDINARY |
4008 QT_ITEM_ORIGINAL_FUNC_NULLIF));
4009 }
4010
4011
4012 uint
opt_mark(sp_head * sp,List<sp_instr> * leads)4013 sp_instr_jump_if_not::opt_mark(sp_head *sp, List<sp_instr> *leads)
4014 {
4015 sp_instr *i;
4016
4017 marked= 1;
4018 if ((i= sp->get_instr(m_dest)))
4019 {
4020 m_dest= i->opt_shortcut_jump(sp, this);
4021 m_optdest= sp->get_instr(m_dest);
4022 }
4023 sp->add_mark_lead(m_dest, leads);
4024 if ((i= sp->get_instr(m_cont_dest)))
4025 {
4026 m_cont_dest= i->opt_shortcut_jump(sp, this);
4027 m_cont_optdest= sp->get_instr(m_cont_dest);
4028 }
4029 sp->add_mark_lead(m_cont_dest, leads);
4030 return m_ip+1;
4031 }
4032
4033 void
opt_move(uint dst,List<sp_instr> * bp)4034 sp_instr_jump_if_not::opt_move(uint dst, List<sp_instr> *bp)
4035 {
4036 /*
4037 cont. destinations may point backwards after shortcutting jumps
4038 during the mark phase. If it's still pointing forwards, only
4039 push this for backpatching if sp_instr_jump::opt_move() will not
4040 do it (i.e. if the m_dest points backwards).
4041 */
4042 if (m_cont_dest > m_ip)
4043 { // Forward
4044 if (m_dest < m_ip)
4045 bp->push_back(this);
4046 }
4047 else if (m_cont_optdest)
4048 m_cont_dest= m_cont_optdest->m_ip; // Backward
4049 /* This will take care of m_dest and m_ip */
4050 sp_instr_jump::opt_move(dst, bp);
4051 }
4052
4053
4054 /*
4055 sp_instr_freturn class functions
4056 */
4057
4058 int
execute(THD * thd,uint * nextp)4059 sp_instr_freturn::execute(THD *thd, uint *nextp)
4060 {
4061 DBUG_ENTER("sp_instr_freturn::execute");
4062 DBUG_RETURN(m_lex_keeper.reset_lex_and_exec_core(thd, nextp, TRUE, this));
4063 }
4064
4065
4066 int
exec_core(THD * thd,uint * nextp)4067 sp_instr_freturn::exec_core(THD *thd, uint *nextp)
4068 {
4069 /*
4070 RETURN is a "procedure statement" (in terms of the SQL standard).
4071 That means, Diagnostics Area should be clean before its execution.
4072 */
4073
4074 if (!(thd->variables.sql_mode & MODE_ORACLE))
4075 {
4076 /*
4077 Don't clean warnings in ORACLE mode,
4078 as they are needed for SQLCODE and SQLERRM:
4079 BEGIN
4080 SELECT a INTO a FROM t1;
4081 RETURN 'No exception ' || SQLCODE || ' ' || SQLERRM;
4082 EXCEPTION WHEN NO_DATA_FOUND THEN
4083 RETURN 'Exception ' || SQLCODE || ' ' || SQLERRM;
4084 END;
4085 */
4086 Diagnostics_area *da= thd->get_stmt_da();
4087 da->clear_warning_info(da->warning_info_id());
4088 }
4089
4090 /*
4091 Change <next instruction pointer>, so that this will be the last
4092 instruction in the stored function.
4093 */
4094
4095 *nextp= UINT_MAX;
4096
4097 /*
4098 Evaluate the value of return expression and store it in current runtime
4099 context.
4100
4101 NOTE: It's necessary to evaluate result item right here, because we must
4102 do it in scope of execution the current context/block.
4103 */
4104
4105 return thd->spcont->set_return_value(thd, &m_value);
4106 }
4107
4108 void
print(String * str)4109 sp_instr_freturn::print(String *str)
4110 {
4111 /* freturn type expr... */
4112 if (str->reserve(1024+8+32)) // Add some for the expr. too
4113 return;
4114 str->qs_append(STRING_WITH_LEN("freturn "));
4115 str->qs_append(m_type_handler->name().ptr());
4116 str->qs_append(' ');
4117 m_value->print(str, enum_query_type(QT_ORDINARY |
4118 QT_ITEM_ORIGINAL_FUNC_NULLIF));
4119 }
4120
4121 /*
4122 sp_instr_hpush_jump class functions
4123 */
4124
4125 int
execute(THD * thd,uint * nextp)4126 sp_instr_hpush_jump::execute(THD *thd, uint *nextp)
4127 {
4128 DBUG_ENTER("sp_instr_hpush_jump::execute");
4129
4130 int ret= thd->spcont->push_handler(this);
4131
4132 *nextp= m_dest;
4133
4134 DBUG_RETURN(ret);
4135 }
4136
4137
4138 void
print(String * str)4139 sp_instr_hpush_jump::print(String *str)
4140 {
4141 /* hpush_jump dest fsize type */
4142 if (str->reserve(SP_INSTR_UINT_MAXLEN*2 + 21))
4143 return;
4144
4145 str->qs_append(STRING_WITH_LEN("hpush_jump "));
4146 str->qs_append(m_dest);
4147 str->qs_append(' ');
4148 str->qs_append(m_frame);
4149
4150 switch (m_handler->type) {
4151 case sp_handler::EXIT:
4152 str->qs_append(STRING_WITH_LEN(" EXIT"));
4153 break;
4154 case sp_handler::CONTINUE:
4155 str->qs_append(STRING_WITH_LEN(" CONTINUE"));
4156 break;
4157 default:
4158 // The handler type must be either CONTINUE or EXIT.
4159 DBUG_ASSERT(0);
4160 }
4161 }
4162
4163
4164 uint
opt_mark(sp_head * sp,List<sp_instr> * leads)4165 sp_instr_hpush_jump::opt_mark(sp_head *sp, List<sp_instr> *leads)
4166 {
4167 sp_instr *i;
4168
4169 marked= 1;
4170 if ((i= sp->get_instr(m_dest)))
4171 {
4172 m_dest= i->opt_shortcut_jump(sp, this);
4173 m_optdest= sp->get_instr(m_dest);
4174 }
4175 sp->add_mark_lead(m_dest, leads);
4176
4177 /*
4178 For continue handlers, all instructions in the scope of the handler
4179 are possible leads. For example, the instruction after freturn might
4180 be executed if the freturn triggers the condition handled by the
4181 continue handler.
4182
4183 m_dest marks the start of the handler scope. It's added as a lead
4184 above, so we start on m_dest+1 here.
4185 m_opt_hpop is the hpop marking the end of the handler scope.
4186 */
4187 if (m_handler->type == sp_handler::CONTINUE)
4188 {
4189 for (uint scope_ip= m_dest+1; scope_ip <= m_opt_hpop; scope_ip++)
4190 sp->add_mark_lead(scope_ip, leads);
4191 }
4192
4193 return m_ip+1;
4194 }
4195
4196
4197 /*
4198 sp_instr_hpop class functions
4199 */
4200
4201 int
execute(THD * thd,uint * nextp)4202 sp_instr_hpop::execute(THD *thd, uint *nextp)
4203 {
4204 DBUG_ENTER("sp_instr_hpop::execute");
4205 thd->spcont->pop_handlers(m_count);
4206 *nextp= m_ip+1;
4207 DBUG_RETURN(0);
4208 }
4209
4210 void
print(String * str)4211 sp_instr_hpop::print(String *str)
4212 {
4213 /* hpop count */
4214 if (str->reserve(SP_INSTR_UINT_MAXLEN+5))
4215 return;
4216 str->qs_append(STRING_WITH_LEN("hpop "));
4217 str->qs_append(m_count);
4218 }
4219
4220
4221 /*
4222 sp_instr_hreturn class functions
4223 */
4224
4225 int
execute(THD * thd,uint * nextp)4226 sp_instr_hreturn::execute(THD *thd, uint *nextp)
4227 {
4228 DBUG_ENTER("sp_instr_hreturn::execute");
4229
4230 uint continue_ip= thd->spcont->exit_handler(thd->get_stmt_da());
4231
4232 *nextp= m_dest ? m_dest : continue_ip;
4233
4234 DBUG_RETURN(0);
4235 }
4236
4237
4238 void
print(String * str)4239 sp_instr_hreturn::print(String *str)
4240 {
4241 /* hreturn framesize dest */
4242 if (str->reserve(SP_INSTR_UINT_MAXLEN*2 + 9))
4243 return;
4244 str->qs_append(STRING_WITH_LEN("hreturn "));
4245 if (m_dest)
4246 {
4247 // NOTE: this is legacy: hreturn instruction for EXIT handler
4248 // should print out 0 as frame index.
4249 str->qs_append(STRING_WITH_LEN("0 "));
4250 str->qs_append(m_dest);
4251 }
4252 else
4253 {
4254 str->qs_append(m_frame);
4255 }
4256 }
4257
4258
4259 uint
opt_mark(sp_head * sp,List<sp_instr> * leads)4260 sp_instr_hreturn::opt_mark(sp_head *sp, List<sp_instr> *leads)
4261 {
4262 marked= 1;
4263
4264 if (m_dest)
4265 {
4266 /*
4267 This is an EXIT handler; next instruction step is in m_dest.
4268 */
4269 return m_dest;
4270 }
4271
4272 /*
4273 This is a CONTINUE handler; next instruction step will come from
4274 the handler stack and not from opt_mark.
4275 */
4276 return UINT_MAX;
4277 }
4278
4279
4280 /*
4281 sp_instr_cpush class functions
4282 */
4283
4284 int
execute(THD * thd,uint * nextp)4285 sp_instr_cpush::execute(THD *thd, uint *nextp)
4286 {
4287 DBUG_ENTER("sp_instr_cpush::execute");
4288
4289 sp_cursor::reset(thd, &m_lex_keeper);
4290 m_lex_keeper.disable_query_cache();
4291 thd->spcont->push_cursor(this);
4292
4293 *nextp= m_ip+1;
4294
4295 DBUG_RETURN(false);
4296 }
4297
4298
4299 void
print(String * str)4300 sp_instr_cpush::print(String *str)
4301 {
4302 const LEX_CSTRING *cursor_name= m_ctx->find_cursor(m_cursor);
4303
4304 /* cpush name@offset */
4305 size_t rsrv= SP_INSTR_UINT_MAXLEN+7;
4306
4307 if (cursor_name)
4308 rsrv+= cursor_name->length;
4309 if (str->reserve(rsrv))
4310 return;
4311 str->qs_append(STRING_WITH_LEN("cpush "));
4312 if (cursor_name)
4313 {
4314 str->qs_append(cursor_name->str, cursor_name->length);
4315 str->qs_append('@');
4316 }
4317 str->qs_append(m_cursor);
4318 }
4319
4320
4321 /*
4322 sp_instr_cpop class functions
4323 */
4324
4325 int
execute(THD * thd,uint * nextp)4326 sp_instr_cpop::execute(THD *thd, uint *nextp)
4327 {
4328 DBUG_ENTER("sp_instr_cpop::execute");
4329 thd->spcont->pop_cursors(thd, m_count);
4330 *nextp= m_ip+1;
4331 DBUG_RETURN(0);
4332 }
4333
4334
4335 void
print(String * str)4336 sp_instr_cpop::print(String *str)
4337 {
4338 /* cpop count */
4339 if (str->reserve(SP_INSTR_UINT_MAXLEN+5))
4340 return;
4341 str->qs_append(STRING_WITH_LEN("cpop "));
4342 str->qs_append(m_count);
4343 }
4344
4345
4346 /*
4347 sp_instr_copen class functions
4348 */
4349
4350 /**
4351 @todo
4352 Assert that we either have an error or a cursor
4353 */
4354
4355 int
execute(THD * thd,uint * nextp)4356 sp_instr_copen::execute(THD *thd, uint *nextp)
4357 {
4358 /*
4359 We don't store a pointer to the cursor in the instruction to be
4360 able to reuse the same instruction among different threads in future.
4361 */
4362 sp_cursor *c= thd->spcont->get_cursor(m_cursor);
4363 int res;
4364 DBUG_ENTER("sp_instr_copen::execute");
4365
4366 if (! c)
4367 res= -1;
4368 else
4369 {
4370 sp_lex_keeper *lex_keeper= c->get_lex_keeper();
4371 res= lex_keeper->cursor_reset_lex_and_exec_core(thd, nextp, FALSE, this);
4372 /* TODO: Assert here that we either have an error or a cursor */
4373 }
4374 DBUG_RETURN(res);
4375 }
4376
4377
4378 int
exec_core(THD * thd,uint * nextp)4379 sp_instr_copen::exec_core(THD *thd, uint *nextp)
4380 {
4381 sp_cursor *c= thd->spcont->get_cursor(m_cursor);
4382 int res= c->open(thd);
4383 *nextp= m_ip+1;
4384 return res;
4385 }
4386
4387 void
print(String * str)4388 sp_instr_copen::print(String *str)
4389 {
4390 const LEX_CSTRING *cursor_name= m_ctx->find_cursor(m_cursor);
4391
4392 /* copen name@offset */
4393 size_t rsrv= SP_INSTR_UINT_MAXLEN+7;
4394
4395 if (cursor_name)
4396 rsrv+= cursor_name->length;
4397 if (str->reserve(rsrv))
4398 return;
4399 str->qs_append(STRING_WITH_LEN("copen "));
4400 if (cursor_name)
4401 {
4402 str->qs_append(cursor_name->str, cursor_name->length);
4403 str->qs_append('@');
4404 }
4405 str->qs_append(m_cursor);
4406 }
4407
4408
4409 /*
4410 sp_instr_cclose class functions
4411 */
4412
4413 int
execute(THD * thd,uint * nextp)4414 sp_instr_cclose::execute(THD *thd, uint *nextp)
4415 {
4416 sp_cursor *c= thd->spcont->get_cursor(m_cursor);
4417 int res;
4418 DBUG_ENTER("sp_instr_cclose::execute");
4419
4420 if (! c)
4421 res= -1;
4422 else
4423 res= c->close(thd);
4424 *nextp= m_ip+1;
4425 DBUG_RETURN(res);
4426 }
4427
4428
4429 void
print(String * str)4430 sp_instr_cclose::print(String *str)
4431 {
4432 const LEX_CSTRING *cursor_name= m_ctx->find_cursor(m_cursor);
4433
4434 /* cclose name@offset */
4435 size_t rsrv= SP_INSTR_UINT_MAXLEN+8;
4436
4437 if (cursor_name)
4438 rsrv+= cursor_name->length;
4439 if (str->reserve(rsrv))
4440 return;
4441 str->qs_append(STRING_WITH_LEN("cclose "));
4442 if (cursor_name)
4443 {
4444 str->qs_append(cursor_name->str, cursor_name->length);
4445 str->qs_append('@');
4446 }
4447 str->qs_append(m_cursor);
4448 }
4449
4450
4451 /*
4452 sp_instr_cfetch class functions
4453 */
4454
4455 int
execute(THD * thd,uint * nextp)4456 sp_instr_cfetch::execute(THD *thd, uint *nextp)
4457 {
4458 sp_cursor *c= thd->spcont->get_cursor(m_cursor);
4459 int res;
4460 Query_arena backup_arena;
4461 DBUG_ENTER("sp_instr_cfetch::execute");
4462
4463 res= c ? c->fetch(thd, &m_varlist, m_error_on_no_data) : -1;
4464
4465 *nextp= m_ip+1;
4466 DBUG_RETURN(res);
4467 }
4468
4469
4470 void
print(String * str)4471 sp_instr_cfetch::print(String *str)
4472 {
4473 List_iterator_fast<sp_variable> li(m_varlist);
4474 sp_variable *pv;
4475 const LEX_CSTRING *cursor_name= m_ctx->find_cursor(m_cursor);
4476
4477 /* cfetch name@offset vars... */
4478 size_t rsrv= SP_INSTR_UINT_MAXLEN+8;
4479
4480 if (cursor_name)
4481 rsrv+= cursor_name->length;
4482 if (str->reserve(rsrv))
4483 return;
4484 str->qs_append(STRING_WITH_LEN("cfetch "));
4485 if (cursor_name)
4486 {
4487 str->qs_append(cursor_name->str, cursor_name->length);
4488 str->qs_append('@');
4489 }
4490 str->qs_append(m_cursor);
4491 while ((pv= li++))
4492 {
4493 if (str->reserve(pv->name.length+SP_INSTR_UINT_MAXLEN+2))
4494 return;
4495 str->qs_append(' ');
4496 str->qs_append(&pv->name);
4497 str->qs_append('@');
4498 str->qs_append(pv->offset);
4499 }
4500 }
4501
4502 int
execute(THD * thd,uint * nextp)4503 sp_instr_agg_cfetch::execute(THD *thd, uint *nextp)
4504 {
4505 DBUG_ENTER("sp_instr_agg_cfetch::execute");
4506 int res= 0;
4507 if (!thd->spcont->instr_ptr)
4508 {
4509 *nextp= m_ip+1;
4510 thd->spcont->instr_ptr= m_ip + 1;
4511 }
4512 else if (!thd->spcont->pause_state)
4513 thd->spcont->pause_state= TRUE;
4514 else
4515 {
4516 thd->spcont->pause_state= FALSE;
4517 if (thd->server_status & SERVER_STATUS_LAST_ROW_SENT)
4518 {
4519 my_message(ER_SP_FETCH_NO_DATA,
4520 ER_THD(thd, ER_SP_FETCH_NO_DATA), MYF(0));
4521 res= -1;
4522 thd->spcont->quit_func= TRUE;
4523 }
4524 else
4525 *nextp= m_ip + 1;
4526 }
4527 DBUG_RETURN(res);
4528 }
4529
4530 void
print(String * str)4531 sp_instr_agg_cfetch::print(String *str)
4532 {
4533
4534 uint rsrv= SP_INSTR_UINT_MAXLEN+11;
4535
4536 if (str->reserve(rsrv))
4537 return;
4538 str->qs_append(STRING_WITH_LEN("agg_cfetch"));
4539 }
4540
4541 /*
4542 sp_instr_cursor_copy_struct class functions
4543 */
4544
4545 /**
4546 This methods processes cursor %ROWTYPE declarations, e.g.:
4547 CURSOR cur IS SELECT * FROM t1;
4548 rec cur%ROWTYPE;
4549 and does the following:
4550 - opens the cursor without copying data (materialization).
4551 - copies the cursor structure to the associated %ROWTYPE variable.
4552 */
4553
4554 int
exec_core(THD * thd,uint * nextp)4555 sp_instr_cursor_copy_struct::exec_core(THD *thd, uint *nextp)
4556 {
4557 DBUG_ENTER("sp_instr_cursor_copy_struct::exec_core");
4558 int ret= 0;
4559 Item_field_row *row= (Item_field_row*) thd->spcont->get_variable(m_var);
4560 DBUG_ASSERT(row->type_handler() == &type_handler_row);
4561
4562 /*
4563 Copy structure only once. If the cursor%ROWTYPE variable is declared
4564 inside a LOOP block, it gets its structure on the first loop interation
4565 and remembers the structure for all consequent loop iterations.
4566 It we recreated the structure on every iteration, we would get
4567 potential memory leaks, and it would be less efficient.
4568 */
4569 if (!row->arguments())
4570 {
4571 sp_cursor tmp(thd, &m_lex_keeper, true);
4572 // Open the cursor without copying data
4573 if (!(ret= tmp.open(thd)))
4574 {
4575 Row_definition_list defs;
4576 /*
4577 Create row elements on the caller arena.
4578 It's the same arena that was used during sp_rcontext::create().
4579 This puts cursor%ROWTYPE elements on the same mem_root
4580 where explicit ROW elements and table%ROWTYPE reside:
4581 - tmp.export_structure() allocates new Spvar_definition instances
4582 and their components (such as TYPELIBs).
4583 - row->row_create_items() creates new Item_field instances.
4584 They all are created on the same mem_root.
4585 */
4586 Query_arena current_arena;
4587 thd->set_n_backup_active_arena(thd->spcont->callers_arena, ¤t_arena);
4588 if (!(ret= tmp.export_structure(thd, &defs)))
4589 row->row_create_items(thd, &defs);
4590 thd->restore_active_arena(thd->spcont->callers_arena, ¤t_arena);
4591 tmp.close(thd);
4592 }
4593 }
4594 *nextp= m_ip + 1;
4595 DBUG_RETURN(ret);
4596 }
4597
4598
4599 int
execute(THD * thd,uint * nextp)4600 sp_instr_cursor_copy_struct::execute(THD *thd, uint *nextp)
4601 {
4602 DBUG_ENTER("sp_instr_cursor_copy_struct::execute");
4603 int ret= m_lex_keeper.cursor_reset_lex_and_exec_core(thd, nextp, FALSE, this);
4604 DBUG_RETURN(ret);
4605 }
4606
4607
4608 void
print(String * str)4609 sp_instr_cursor_copy_struct::print(String *str)
4610 {
4611 sp_variable *var= m_ctx->find_variable(m_var);
4612 const LEX_CSTRING *name= m_ctx->find_cursor(m_cursor);
4613 str->append(STRING_WITH_LEN("cursor_copy_struct "));
4614 str->append(name);
4615 str->append(' ');
4616 str->append(&var->name);
4617 str->append('@');
4618 str->append_ulonglong(m_var);
4619 }
4620
4621
4622 /*
4623 sp_instr_error class functions
4624 */
4625
4626 int
execute(THD * thd,uint * nextp)4627 sp_instr_error::execute(THD *thd, uint *nextp)
4628 {
4629 DBUG_ENTER("sp_instr_error::execute");
4630 my_message(m_errcode, ER_THD(thd, m_errcode), MYF(0));
4631 WSREP_DEBUG("sp_instr_error: %s %d", ER_THD(thd, m_errcode), thd->is_error());
4632 *nextp= m_ip+1;
4633 DBUG_RETURN(-1);
4634 }
4635
4636
4637 void
print(String * str)4638 sp_instr_error::print(String *str)
4639 {
4640 /* error code */
4641 if (str->reserve(SP_INSTR_UINT_MAXLEN+6))
4642 return;
4643 str->qs_append(STRING_WITH_LEN("error "));
4644 str->qs_append(m_errcode);
4645 }
4646
4647
4648 /**************************************************************************
4649 sp_instr_set_case_expr class implementation
4650 **************************************************************************/
4651
4652 int
execute(THD * thd,uint * nextp)4653 sp_instr_set_case_expr::execute(THD *thd, uint *nextp)
4654 {
4655 DBUG_ENTER("sp_instr_set_case_expr::execute");
4656
4657 DBUG_RETURN(m_lex_keeper.reset_lex_and_exec_core(thd, nextp, TRUE, this));
4658 }
4659
4660
4661 int
exec_core(THD * thd,uint * nextp)4662 sp_instr_set_case_expr::exec_core(THD *thd, uint *nextp)
4663 {
4664 int res= thd->spcont->set_case_expr(thd, m_case_expr_id, &m_case_expr);
4665
4666 if (res && !thd->spcont->get_case_expr(m_case_expr_id))
4667 {
4668 /*
4669 Failed to evaluate the value, the case expression is still not
4670 initialized. Set to NULL so we can continue.
4671 */
4672
4673 Item *null_item= new (thd->mem_root) Item_null(thd);
4674
4675 if (!null_item ||
4676 thd->spcont->set_case_expr(thd, m_case_expr_id, &null_item))
4677 {
4678 /* If this also failed, we have to abort. */
4679 my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATAL));
4680 }
4681 }
4682 else
4683 *nextp= m_ip+1;
4684
4685 return res;
4686 }
4687
4688
4689 void
print(String * str)4690 sp_instr_set_case_expr::print(String *str)
4691 {
4692 /* set_case_expr (cont) id ... */
4693 str->reserve(2*SP_INSTR_UINT_MAXLEN+18+32); // Add some extra for expr too
4694 str->qs_append(STRING_WITH_LEN("set_case_expr ("));
4695 str->qs_append(m_cont_dest);
4696 str->qs_append(STRING_WITH_LEN(") "));
4697 str->qs_append(m_case_expr_id);
4698 str->qs_append(' ');
4699 m_case_expr->print(str, enum_query_type(QT_ORDINARY |
4700 QT_ITEM_ORIGINAL_FUNC_NULLIF));
4701 }
4702
4703 uint
opt_mark(sp_head * sp,List<sp_instr> * leads)4704 sp_instr_set_case_expr::opt_mark(sp_head *sp, List<sp_instr> *leads)
4705 {
4706 sp_instr *i;
4707
4708 marked= 1;
4709 if ((i= sp->get_instr(m_cont_dest)))
4710 {
4711 m_cont_dest= i->opt_shortcut_jump(sp, this);
4712 m_cont_optdest= sp->get_instr(m_cont_dest);
4713 }
4714 sp->add_mark_lead(m_cont_dest, leads);
4715 return m_ip+1;
4716 }
4717
4718 void
opt_move(uint dst,List<sp_instr> * bp)4719 sp_instr_set_case_expr::opt_move(uint dst, List<sp_instr> *bp)
4720 {
4721 if (m_cont_dest > m_ip)
4722 bp->push_back(this); // Forward
4723 else if (m_cont_optdest)
4724 m_cont_dest= m_cont_optdest->m_ip; // Backward
4725 m_ip= dst;
4726 }
4727
4728
4729 /* ------------------------------------------------------------------ */
4730
4731
4732 /*
4733 Structure that represent all instances of one table
4734 in optimized multi-set of tables used by routine.
4735 */
4736
4737 typedef struct st_sp_table
4738 {
4739 /*
4740 Multi-set key:
4741 db_name\0table_name\0alias\0 - for normal tables
4742 db_name\0table_name\0 - for temporary tables
4743 */
4744 LEX_STRING qname;
4745 size_t db_length, table_name_length;
4746 bool temp; /* true if corresponds to a temporary table */
4747 thr_lock_type lock_type; /* lock type used for prelocking */
4748 uint lock_count;
4749 uint query_lock_count;
4750 uint8 trg_event_map;
4751 my_bool for_insert_data;
4752 } SP_TABLE;
4753
4754
sp_table_key(const uchar * ptr,size_t * plen,my_bool first)4755 uchar *sp_table_key(const uchar *ptr, size_t *plen, my_bool first)
4756 {
4757 SP_TABLE *tab= (SP_TABLE *)ptr;
4758 *plen= tab->qname.length;
4759 return (uchar *)tab->qname.str;
4760 }
4761
4762
4763 /**
4764 Merge the list of tables used by some query into the multi-set of
4765 tables used by routine.
4766
4767 @param thd thread context
4768 @param table table list
4769 @param lex_for_tmp_check LEX of the query for which we are merging
4770 table list.
4771
4772 @note
4773 This method will use LEX provided to check whenever we are creating
4774 temporary table and mark it as such in target multi-set.
4775
4776 @retval
4777 TRUE Success
4778 @retval
4779 FALSE Error
4780 */
4781
4782 bool
merge_table_list(THD * thd,TABLE_LIST * table,LEX * lex_for_tmp_check)4783 sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
4784 {
4785 SP_TABLE *tab;
4786
4787 if ((lex_for_tmp_check->sql_command == SQLCOM_DROP_TABLE ||
4788 lex_for_tmp_check->sql_command == SQLCOM_DROP_SEQUENCE) &&
4789 lex_for_tmp_check->tmp_table())
4790 return TRUE;
4791
4792 for (uint i= 0 ; i < m_sptabs.records ; i++)
4793 {
4794 tab= (SP_TABLE*) my_hash_element(&m_sptabs, i);
4795 tab->query_lock_count= 0;
4796 }
4797
4798 for (; table ; table= table->next_global)
4799 if (!table->derived && !table->schema_table)
4800 {
4801 /*
4802 Structure of key for the multi-set is "db\0table\0alias\0".
4803 Since "alias" part can have arbitrary length we use String
4804 object to construct the key. By default String will use
4805 buffer allocated on stack with NAME_LEN bytes reserved for
4806 alias, since in most cases it is going to be smaller than
4807 NAME_LEN bytes.
4808 */
4809 char tname_buff[(SAFE_NAME_LEN + 1) * 3];
4810 String tname(tname_buff, sizeof(tname_buff), &my_charset_bin);
4811 uint temp_table_key_length;
4812
4813 tname.length(0);
4814 tname.append(&table->db);
4815 tname.append('\0');
4816 tname.append(&table->table_name);
4817 tname.append('\0');
4818 temp_table_key_length= tname.length();
4819 tname.append(&table->alias);
4820 tname.append('\0');
4821
4822 /*
4823 Upgrade the lock type because this table list will be used
4824 only in pre-locked mode, in which DELAYED inserts are always
4825 converted to normal inserts.
4826 */
4827 if (table->lock_type == TL_WRITE_DELAYED)
4828 table->lock_type= TL_WRITE;
4829
4830 /*
4831 We ignore alias when we check if table was already marked as temporary
4832 (and therefore should not be prelocked). Otherwise we will erroneously
4833 treat table with same name but with different alias as non-temporary.
4834 */
4835 if ((tab= (SP_TABLE*) my_hash_search(&m_sptabs, (uchar *)tname.ptr(),
4836 tname.length())) ||
4837 ((tab= (SP_TABLE*) my_hash_search(&m_sptabs, (uchar *)tname.ptr(),
4838 temp_table_key_length)) &&
4839 tab->temp))
4840 {
4841 if (tab->lock_type < table->lock_type)
4842 tab->lock_type= table->lock_type; // Use the table with the highest lock type
4843 tab->query_lock_count++;
4844 if (tab->query_lock_count > tab->lock_count)
4845 tab->lock_count++;
4846 tab->trg_event_map|= table->trg_event_map;
4847 tab->for_insert_data|= table->for_insert_data;
4848 }
4849 else
4850 {
4851 if (!(tab= (SP_TABLE *)thd->calloc(sizeof(SP_TABLE))))
4852 return FALSE;
4853 if ((lex_for_tmp_check->sql_command == SQLCOM_CREATE_TABLE ||
4854 lex_for_tmp_check->sql_command == SQLCOM_CREATE_SEQUENCE) &&
4855 lex_for_tmp_check->query_tables == table &&
4856 lex_for_tmp_check->tmp_table())
4857 {
4858 tab->temp= TRUE;
4859 tab->qname.length= temp_table_key_length;
4860 }
4861 else
4862 tab->qname.length= tname.length();
4863 tab->qname.str= (char*) thd->memdup(tname.ptr(), tab->qname.length);
4864 if (!tab->qname.str)
4865 return FALSE;
4866 tab->table_name_length= table->table_name.length;
4867 tab->db_length= table->db.length;
4868 tab->lock_type= table->lock_type;
4869 tab->lock_count= tab->query_lock_count= 1;
4870 tab->trg_event_map= table->trg_event_map;
4871 tab->for_insert_data= table->for_insert_data;
4872 if (my_hash_insert(&m_sptabs, (uchar *)tab))
4873 return FALSE;
4874 }
4875 }
4876 return TRUE;
4877 }
4878
4879
4880 /**
4881 Add tables used by routine to the table list.
4882
4883 Converts multi-set of tables used by this routine to table list and adds
4884 this list to the end of table list specified by 'query_tables_last_ptr'.
4885
4886 Elements of list will be allocated in PS memroot, so this list will be
4887 persistent between PS executions.
4888
4889 @param[in] thd Thread context
4890 @param[in,out] query_tables_last_ptr Pointer to the next_global member of
4891 last element of the list where tables
4892 will be added (or to its root).
4893 @param[in] belong_to_view Uppermost view which uses this routine,
4894 0 if none.
4895
4896 @retval
4897 TRUE if some elements were added
4898 @retval
4899 FALSE otherwise.
4900 */
4901
4902 bool
add_used_tables_to_table_list(THD * thd,TABLE_LIST *** query_tables_last_ptr,TABLE_LIST * belong_to_view)4903 sp_head::add_used_tables_to_table_list(THD *thd,
4904 TABLE_LIST ***query_tables_last_ptr,
4905 TABLE_LIST *belong_to_view)
4906 {
4907 uint i;
4908 Query_arena *arena, backup;
4909 bool result= FALSE;
4910 DBUG_ENTER("sp_head::add_used_tables_to_table_list");
4911
4912 /*
4913 Use persistent arena for table list allocation to be PS/SP friendly.
4914 Note that we also have to copy database/table names and alias to PS/SP
4915 memory since current instance of sp_head object can pass away before
4916 next execution of PS/SP for which tables are added to prelocking list.
4917 This will be fixed by introducing of proper invalidation mechanism
4918 once new TDC is ready.
4919 */
4920 arena= thd->activate_stmt_arena_if_needed(&backup);
4921
4922 for (i=0 ; i < m_sptabs.records ; i++)
4923 {
4924 char *tab_buff, *key_buff;
4925 SP_TABLE *stab= (SP_TABLE*) my_hash_element(&m_sptabs, i);
4926 LEX_CSTRING db_name;
4927 if (stab->temp)
4928 continue;
4929
4930 if (!(tab_buff= (char *)thd->alloc(ALIGN_SIZE(sizeof(TABLE_LIST)) *
4931 stab->lock_count)) ||
4932 !(key_buff= (char*)thd->memdup(stab->qname.str,
4933 stab->qname.length)))
4934 DBUG_RETURN(FALSE);
4935
4936 db_name.str= key_buff;
4937 db_name.length= stab->db_length;
4938
4939
4940 for (uint j= 0; j < stab->lock_count; j++)
4941 {
4942 TABLE_LIST *table= (TABLE_LIST *)tab_buff;
4943 LEX_CSTRING table_name= { key_buff + stab->db_length + 1,
4944 stab->table_name_length };
4945 LEX_CSTRING alias= { table_name.str + table_name.length + 1,
4946 strlen(table_name.str + table_name.length + 1) };
4947
4948 table->init_one_table_for_prelocking(&db_name,
4949 &table_name,
4950 &alias,
4951 stab->lock_type,
4952 TABLE_LIST::PRELOCK_ROUTINE,
4953 belong_to_view,
4954 stab->trg_event_map,
4955 query_tables_last_ptr,
4956 stab->for_insert_data);
4957 tab_buff+= ALIGN_SIZE(sizeof(TABLE_LIST));
4958 result= TRUE;
4959 }
4960 }
4961
4962 if (arena)
4963 thd->restore_active_arena(arena, &backup);
4964
4965 DBUG_RETURN(result);
4966 }
4967
4968
4969 /**
4970 Simple function for adding an explicitly named (systems) table to
4971 the global table list, e.g. "mysql", "proc".
4972 */
4973
4974 TABLE_LIST *
sp_add_to_query_tables(THD * thd,LEX * lex,const LEX_CSTRING * db,const LEX_CSTRING * name,thr_lock_type locktype,enum_mdl_type mdl_type)4975 sp_add_to_query_tables(THD *thd, LEX *lex,
4976 const LEX_CSTRING *db, const LEX_CSTRING *name,
4977 thr_lock_type locktype,
4978 enum_mdl_type mdl_type)
4979 {
4980 TABLE_LIST *table;
4981
4982 if (!(table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST))))
4983 return NULL;
4984 if (!thd->make_lex_string(&table->db, db->str, db->length) ||
4985 !thd->make_lex_string(&table->table_name, name->str, name->length) ||
4986 !thd->make_lex_string(&table->alias, name->str, name->length))
4987 return NULL;
4988
4989 table->lock_type= locktype;
4990 table->select_lex= lex->current_select;
4991 table->cacheable_table= 1;
4992 table->mdl_request.init(MDL_key::TABLE, table->db.str, table->table_name.str,
4993 mdl_type, MDL_TRANSACTION);
4994
4995 lex->add_to_query_tables(table);
4996 return table;
4997 }
4998
4999
adjust_assignment_source(THD * thd,Item * val,Item * val2)5000 Item *sp_head::adjust_assignment_source(THD *thd, Item *val, Item *val2)
5001 {
5002 return val ? val : val2 ? val2 : new (thd->mem_root) Item_null(thd);
5003 }
5004
5005 /**
5006 Helper action for a SET statement.
5007 Used to push a SP local variable into the assignment list.
5008
5009 @param var_type the SP local variable
5010 @param val the value being assigned to the variable
5011
5012 @return TRUE if error, FALSE otherwise.
5013 */
5014
5015 bool
set_local_variable(THD * thd,sp_pcontext * spcont,const Sp_rcontext_handler * rh,sp_variable * spv,Item * val,LEX * lex,bool responsible_to_free_lex)5016 sp_head::set_local_variable(THD *thd, sp_pcontext *spcont,
5017 const Sp_rcontext_handler *rh,
5018 sp_variable *spv, Item *val, LEX *lex,
5019 bool responsible_to_free_lex)
5020 {
5021 if (!(val= adjust_assignment_source(thd, val, spv->default_value)))
5022 return true;
5023
5024 sp_instr_set *sp_set= new (thd->mem_root)
5025 sp_instr_set(instructions(), spcont, rh,
5026 spv->offset, val, lex,
5027 responsible_to_free_lex);
5028
5029 return sp_set == NULL || add_instr(sp_set);
5030 }
5031
5032
5033 /**
5034 Similar to set_local_variable(), but for ROW variable fields.
5035 */
5036
5037 bool
set_local_variable_row_field(THD * thd,sp_pcontext * spcont,const Sp_rcontext_handler * rh,sp_variable * spv,uint field_idx,Item * val,LEX * lex)5038 sp_head::set_local_variable_row_field(THD *thd, sp_pcontext *spcont,
5039 const Sp_rcontext_handler *rh,
5040 sp_variable *spv, uint field_idx,
5041 Item *val, LEX *lex)
5042 {
5043 if (!(val= adjust_assignment_source(thd, val, NULL)))
5044 return true;
5045
5046 sp_instr_set_row_field *sp_set= new (thd->mem_root)
5047 sp_instr_set_row_field(instructions(),
5048 spcont, rh,
5049 spv->offset,
5050 field_idx, val,
5051 lex, true);
5052 return sp_set == NULL || add_instr(sp_set);
5053 }
5054
5055
5056 bool
set_local_variable_row_field_by_name(THD * thd,sp_pcontext * spcont,const Sp_rcontext_handler * rh,sp_variable * spv,const LEX_CSTRING * field_name,Item * val,LEX * lex)5057 sp_head::set_local_variable_row_field_by_name(THD *thd, sp_pcontext *spcont,
5058 const Sp_rcontext_handler *rh,
5059 sp_variable *spv,
5060 const LEX_CSTRING *field_name,
5061 Item *val, LEX *lex)
5062 {
5063 if (!(val= adjust_assignment_source(thd, val, NULL)))
5064 return true;
5065
5066 sp_instr_set_row_field_by_name *sp_set=
5067 new (thd->mem_root) sp_instr_set_row_field_by_name(instructions(),
5068 spcont, rh,
5069 spv->offset,
5070 *field_name,
5071 val,
5072 lex, true);
5073 return sp_set == NULL || add_instr(sp_set);
5074 }
5075
5076
add_open_cursor(THD * thd,sp_pcontext * spcont,uint offset,sp_pcontext * param_spcont,List<sp_assignment_lex> * parameters)5077 bool sp_head::add_open_cursor(THD *thd, sp_pcontext *spcont, uint offset,
5078 sp_pcontext *param_spcont,
5079 List<sp_assignment_lex> *parameters)
5080 {
5081 /*
5082 The caller must make sure that the number of formal parameters matches
5083 the number of actual parameters.
5084 */
5085 DBUG_ASSERT((param_spcont ? param_spcont->context_var_count() : 0) ==
5086 (parameters ? parameters->elements : 0));
5087
5088 if (parameters &&
5089 add_set_cursor_param_variables(thd, param_spcont, parameters))
5090 return true;
5091
5092 sp_instr_copen *i= new (thd->mem_root)
5093 sp_instr_copen(instructions(), spcont, offset);
5094 return i == NULL || add_instr(i);
5095 }
5096
5097
add_for_loop_open_cursor(THD * thd,sp_pcontext * spcont,sp_variable * index,const sp_pcursor * pcursor,uint coffset,sp_assignment_lex * param_lex,Item_args * parameters)5098 bool sp_head::add_for_loop_open_cursor(THD *thd, sp_pcontext *spcont,
5099 sp_variable *index,
5100 const sp_pcursor *pcursor, uint coffset,
5101 sp_assignment_lex *param_lex,
5102 Item_args *parameters)
5103 {
5104 if (parameters &&
5105 add_set_for_loop_cursor_param_variables(thd, pcursor->param_context(),
5106 param_lex, parameters))
5107 return true;
5108
5109 sp_instr *instr_copy_struct=
5110 new (thd->mem_root) sp_instr_cursor_copy_struct(instructions(),
5111 spcont, coffset,
5112 pcursor->lex(),
5113 index->offset);
5114 if (instr_copy_struct == NULL || add_instr(instr_copy_struct))
5115 return true;
5116
5117 sp_instr_copen *instr_copen=
5118 new (thd->mem_root) sp_instr_copen(instructions(), spcont, coffset);
5119 if (instr_copen == NULL || add_instr(instr_copen))
5120 return true;
5121
5122 sp_instr_cfetch *instr_cfetch=
5123 new (thd->mem_root) sp_instr_cfetch(instructions(),
5124 spcont, coffset, false);
5125 if (instr_cfetch == NULL || add_instr(instr_cfetch))
5126 return true;
5127 instr_cfetch->add_to_varlist(index);
5128 return false;
5129 }
5130
5131
5132 bool
add_set_for_loop_cursor_param_variables(THD * thd,sp_pcontext * param_spcont,sp_assignment_lex * param_lex,Item_args * parameters)5133 sp_head::add_set_for_loop_cursor_param_variables(THD *thd,
5134 sp_pcontext *param_spcont,
5135 sp_assignment_lex *param_lex,
5136 Item_args *parameters)
5137 {
5138 DBUG_ASSERT(param_spcont->context_var_count() == parameters->argument_count());
5139 for (uint idx= 0; idx < parameters->argument_count(); idx ++)
5140 {
5141 /*
5142 param_lex is shared between multiple items (cursor parameters).
5143 Only the last sp_instr_set is responsible for freeing param_lex.
5144 See more comments in LEX::sp_for_loop_cursor_declarations in sql_lex.cc.
5145 */
5146 bool last= idx + 1 == parameters->argument_count();
5147 sp_variable *spvar= param_spcont->get_context_variable(idx);
5148 if (set_local_variable(thd, param_spcont,
5149 &sp_rcontext_handler_local,
5150 spvar, parameters->arguments()[idx],
5151 param_lex, last))
5152 return true;
5153 }
5154 return false;
5155 }
5156
5157
spvar_fill_row(THD * thd,sp_variable * spvar,Row_definition_list * defs)5158 bool sp_head::spvar_fill_row(THD *thd,
5159 sp_variable *spvar,
5160 Row_definition_list *defs)
5161 {
5162 spvar->field_def.set_row_field_definitions(defs);
5163 spvar->field_def.field_name= spvar->name;
5164 if (fill_spvar_definition(thd, &spvar->field_def))
5165 return true;
5166 row_fill_field_definitions(thd, defs);
5167 return false;
5168 }
5169
5170
spvar_fill_type_reference(THD * thd,sp_variable * spvar,const LEX_CSTRING & table,const LEX_CSTRING & col)5171 bool sp_head::spvar_fill_type_reference(THD *thd,
5172 sp_variable *spvar,
5173 const LEX_CSTRING &table,
5174 const LEX_CSTRING &col)
5175 {
5176 Qualified_column_ident *ref;
5177 if (!(ref= new (thd->mem_root) Qualified_column_ident(&table, &col)))
5178 return true;
5179 fill_spvar_using_type_reference(spvar, ref);
5180 return false;
5181 }
5182
5183
spvar_fill_type_reference(THD * thd,sp_variable * spvar,const LEX_CSTRING & db,const LEX_CSTRING & table,const LEX_CSTRING & col)5184 bool sp_head::spvar_fill_type_reference(THD *thd,
5185 sp_variable *spvar,
5186 const LEX_CSTRING &db,
5187 const LEX_CSTRING &table,
5188 const LEX_CSTRING &col)
5189 {
5190 Qualified_column_ident *ref;
5191 if (!(ref= new (thd->mem_root) Qualified_column_ident(thd, &db, &table, &col)))
5192 return true;
5193 fill_spvar_using_type_reference(spvar, ref);
5194 return false;
5195 }
5196
5197
spvar_fill_table_rowtype_reference(THD * thd,sp_variable * spvar,const LEX_CSTRING & table)5198 bool sp_head::spvar_fill_table_rowtype_reference(THD *thd,
5199 sp_variable *spvar,
5200 const LEX_CSTRING &table)
5201 {
5202 Table_ident *ref;
5203 if (!(ref= new (thd->mem_root) Table_ident(&table)))
5204 return true;
5205 fill_spvar_using_table_rowtype_reference(thd, spvar, ref);
5206 return false;
5207 }
5208
5209
spvar_fill_table_rowtype_reference(THD * thd,sp_variable * spvar,const LEX_CSTRING & db,const LEX_CSTRING & table)5210 bool sp_head::spvar_fill_table_rowtype_reference(THD *thd,
5211 sp_variable *spvar,
5212 const LEX_CSTRING &db,
5213 const LEX_CSTRING &table)
5214 {
5215 Table_ident *ref;
5216 if (!(ref= new (thd->mem_root) Table_ident(thd, &db, &table, false)))
5217 return true;
5218 fill_spvar_using_table_rowtype_reference(thd, spvar, ref);
5219 return false;
5220 }
5221
5222
check_group_aggregate_instructions_forbid() const5223 bool sp_head::check_group_aggregate_instructions_forbid() const
5224 {
5225 if (unlikely(m_flags & sp_head::HAS_AGGREGATE_INSTR))
5226 {
5227 my_error(ER_NOT_AGGREGATE_FUNCTION, MYF(0));
5228 return true;
5229 }
5230 return false;
5231 }
5232
5233
check_group_aggregate_instructions_require() const5234 bool sp_head::check_group_aggregate_instructions_require() const
5235 {
5236 if (unlikely(!(m_flags & HAS_AGGREGATE_INSTR)))
5237 {
5238 my_error(ER_INVALID_AGGREGATE_FUNCTION, MYF(0));
5239 return true;
5240 }
5241 return false;
5242 }
5243
5244
check_group_aggregate_instructions_function() const5245 bool sp_head::check_group_aggregate_instructions_function() const
5246 {
5247 return agg_type() == GROUP_AGGREGATE ?
5248 check_group_aggregate_instructions_require() :
5249 check_group_aggregate_instructions_forbid();
5250 }
5251
5252
5253 /*
5254 In Oracle mode stored routines have an optional name
5255 at the end of a declaration:
5256 PROCEDURE p1 AS
5257 BEGIN
5258 NULL
5259 END p1;
5260 Check that the first p1 and the last p1 match.
5261 */
5262
check_package_routine_end_name(const LEX_CSTRING & end_name) const5263 bool sp_head::check_package_routine_end_name(const LEX_CSTRING &end_name) const
5264 {
5265 LEX_CSTRING non_qualified_name= m_name;
5266 const char *errpos;
5267 size_t ofs;
5268 if (!end_name.length)
5269 return false; // No end name
5270 if (!(errpos= strrchr(m_name.str, '.')))
5271 {
5272 errpos= m_name.str;
5273 goto err;
5274 }
5275 errpos++;
5276 ofs= errpos - m_name.str;
5277 non_qualified_name.str+= ofs;
5278 non_qualified_name.length-= ofs;
5279 if (Sp_handler::eq_routine_name(end_name, non_qualified_name))
5280 return false;
5281 err:
5282 my_error(ER_END_IDENTIFIER_DOES_NOT_MATCH, MYF(0), end_name.str, errpos);
5283 return true;
5284 }
5285
5286
5287 bool
check_standalone_routine_end_name(const sp_name * end_name) const5288 sp_head::check_standalone_routine_end_name(const sp_name *end_name) const
5289 {
5290 if (end_name && !end_name->eq(this))
5291 {
5292 my_error(ER_END_IDENTIFIER_DOES_NOT_MATCH, MYF(0),
5293 ErrConvDQName(end_name).ptr(), ErrConvDQName(this).ptr());
5294 return true;
5295 }
5296 return false;
5297 }
5298
5299
sp_cache_version() const5300 ulong sp_head::sp_cache_version() const
5301 {
5302 return m_parent ? m_parent->sp_cache_version() : m_sp_cache_version;
5303 }
5304