mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / sql / sp_head.cc
blob4268c9370db8b6a3a07618f6b861f63c113f5ca4
1 /*
2 Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 #include "mysql_priv.h"
19 #ifdef USE_PRAGMA_IMPLEMENTATION
20 #pragma implementation
21 #endif
22 #include "sp_head.h"
23 #include "sp.h"
24 #include "sp_pcontext.h"
25 #include "sp_rcontext.h"
26 #include "sp_cache.h"
29 Sufficient max length of printed destinations and frame offsets (all uints).
31 #define SP_INSTR_UINT_MAXLEN 8
32 #define SP_STMT_PRINT_MAXLEN 40
35 #include <my_user.h>
37 extern "C" uchar *sp_table_key(const uchar *ptr, size_t *plen, my_bool first);
39 /**
40 Helper function which operates on a THD object to set the query start_time to
41 the current time.
43 @param[in, out] thd The session object
47 static void reset_start_time_for_sp(THD *thd)
50 Do nothing if the context is a trigger or function because time should be
51 constant during the execution of those.
53 if (!thd->in_sub_stmt)
56 First investigate if there is a cached time stamp
58 if (thd->user_time)
60 thd->start_time= thd->user_time;
62 else
64 my_micro_time_and_time(&thd->start_time);
69 Item_result
70 sp_map_result_type(enum enum_field_types type)
72 switch (type) {
73 case MYSQL_TYPE_BIT:
74 case MYSQL_TYPE_TINY:
75 case MYSQL_TYPE_SHORT:
76 case MYSQL_TYPE_LONG:
77 case MYSQL_TYPE_LONGLONG:
78 case MYSQL_TYPE_INT24:
79 return INT_RESULT;
80 case MYSQL_TYPE_DECIMAL:
81 case MYSQL_TYPE_NEWDECIMAL:
82 return DECIMAL_RESULT;
83 case MYSQL_TYPE_FLOAT:
84 case MYSQL_TYPE_DOUBLE:
85 return REAL_RESULT;
86 default:
87 return STRING_RESULT;
92 Item::Type
93 sp_map_item_type(enum enum_field_types type)
95 switch (type) {
96 case MYSQL_TYPE_BIT:
97 case MYSQL_TYPE_TINY:
98 case MYSQL_TYPE_SHORT:
99 case MYSQL_TYPE_LONG:
100 case MYSQL_TYPE_LONGLONG:
101 case MYSQL_TYPE_INT24:
102 return Item::INT_ITEM;
103 case MYSQL_TYPE_DECIMAL:
104 case MYSQL_TYPE_NEWDECIMAL:
105 return Item::DECIMAL_ITEM;
106 case MYSQL_TYPE_FLOAT:
107 case MYSQL_TYPE_DOUBLE:
108 return Item::REAL_ITEM;
109 default:
110 return Item::STRING_ITEM;
116 Return a string representation of the Item value.
118 @param thd thread handle
119 @param str string buffer for representation of the value
121 @note
122 If the item has a string result type, the string is escaped
123 according to its character set.
125 @retval
126 NULL on error
127 @retval
128 non-NULL a pointer to valid a valid string on success
131 static String *
132 sp_get_item_value(THD *thd, Item *item, String *str)
134 switch (item->result_type()) {
135 case REAL_RESULT:
136 case INT_RESULT:
137 case DECIMAL_RESULT:
138 if (item->field_type() != MYSQL_TYPE_BIT)
139 return item->val_str(str);
140 else {/* Bit type is handled as binary string */}
141 case STRING_RESULT:
143 String *result= item->val_str(str);
145 if (!result)
146 return NULL;
149 char buf_holder[STRING_BUFFER_USUAL_SIZE];
150 String buf(buf_holder, sizeof(buf_holder), result->charset());
151 CHARSET_INFO *cs= thd->variables.character_set_client;
153 /* We must reset length of the buffer, because of String specificity. */
154 buf.length(0);
156 buf.append('_');
157 buf.append(result->charset()->csname);
158 if (cs->escape_with_backslash_is_dangerous)
159 buf.append(' ');
160 append_query_string(thd, cs, result, &buf);
161 buf.append(" COLLATE '");
162 buf.append(item->collation.collation->name);
163 buf.append('\'');
164 str->copy(buf);
166 return str;
170 case ROW_RESULT:
171 default:
172 return NULL;
178 Returns a combination of:
179 - sp_head::MULTI_RESULTS: added if the 'cmd' is a command that might
180 result in multiple result sets being sent back.
181 - sp_head::CONTAINS_DYNAMIC_SQL: added if 'cmd' is one of PREPARE,
182 EXECUTE, DEALLOCATE.
185 uint
186 sp_get_flags_for_command(LEX *lex)
188 uint flags;
190 switch (lex->sql_command) {
191 case SQLCOM_SELECT:
192 if (lex->result)
194 flags= 0; /* This is a SELECT with INTO clause */
195 break;
197 /* fallthrough */
198 case SQLCOM_ANALYZE:
199 case SQLCOM_BACKUP_TABLE:
200 case SQLCOM_OPTIMIZE:
201 case SQLCOM_PRELOAD_KEYS:
202 case SQLCOM_ASSIGN_TO_KEYCACHE:
203 case SQLCOM_CHECKSUM:
204 case SQLCOM_CHECK:
205 case SQLCOM_HA_READ:
206 case SQLCOM_SHOW_AUTHORS:
207 case SQLCOM_SHOW_BINLOGS:
208 case SQLCOM_SHOW_BINLOG_EVENTS:
209 case SQLCOM_SHOW_CHARSETS:
210 case SQLCOM_SHOW_COLLATIONS:
211 case SQLCOM_SHOW_COLUMN_TYPES:
212 case SQLCOM_SHOW_CONTRIBUTORS:
213 case SQLCOM_SHOW_CREATE:
214 case SQLCOM_SHOW_CREATE_DB:
215 case SQLCOM_SHOW_CREATE_FUNC:
216 case SQLCOM_SHOW_CREATE_PROC:
217 case SQLCOM_SHOW_CREATE_EVENT:
218 case SQLCOM_SHOW_CREATE_TRIGGER:
219 case SQLCOM_SHOW_DATABASES:
220 case SQLCOM_SHOW_ERRORS:
221 case SQLCOM_SHOW_FIELDS:
222 case SQLCOM_SHOW_FUNC_CODE:
223 case SQLCOM_SHOW_GRANTS:
224 case SQLCOM_SHOW_ENGINE_STATUS:
225 case SQLCOM_SHOW_ENGINE_LOGS:
226 case SQLCOM_SHOW_ENGINE_MUTEX:
227 case SQLCOM_SHOW_EVENTS:
228 case SQLCOM_SHOW_KEYS:
229 case SQLCOM_SHOW_MASTER_STAT:
230 case SQLCOM_SHOW_NEW_MASTER:
231 case SQLCOM_SHOW_OPEN_TABLES:
232 case SQLCOM_SHOW_PRIVILEGES:
233 case SQLCOM_SHOW_PROCESSLIST:
234 case SQLCOM_SHOW_PROC_CODE:
235 case SQLCOM_SHOW_SLAVE_HOSTS:
236 case SQLCOM_SHOW_SLAVE_STAT:
237 case SQLCOM_SHOW_STATUS:
238 case SQLCOM_SHOW_STATUS_FUNC:
239 case SQLCOM_SHOW_STATUS_PROC:
240 case SQLCOM_SHOW_STORAGE_ENGINES:
241 case SQLCOM_SHOW_TABLES:
242 case SQLCOM_SHOW_TABLE_STATUS:
243 case SQLCOM_SHOW_VARIABLES:
244 case SQLCOM_SHOW_WARNS:
245 case SQLCOM_REPAIR:
246 case SQLCOM_RESTORE_TABLE:
247 flags= sp_head::MULTI_RESULTS;
248 break;
250 EXECUTE statement may return a result set, but doesn't have to.
251 We can't, however, know it in advance, and therefore must add
252 this statement here. This is ok, as is equivalent to a result-set
253 statement within an IF condition.
255 case SQLCOM_EXECUTE:
256 flags= sp_head::MULTI_RESULTS | sp_head::CONTAINS_DYNAMIC_SQL;
257 break;
258 case SQLCOM_PREPARE:
259 case SQLCOM_DEALLOCATE_PREPARE:
260 flags= sp_head::CONTAINS_DYNAMIC_SQL;
261 break;
262 case SQLCOM_CREATE_TABLE:
263 if (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)
264 flags= 0;
265 else
266 flags= sp_head::HAS_COMMIT_OR_ROLLBACK;
267 break;
268 case SQLCOM_DROP_TABLE:
269 if (lex->drop_temporary)
270 flags= 0;
271 else
272 flags= sp_head::HAS_COMMIT_OR_ROLLBACK;
273 break;
274 case SQLCOM_FLUSH:
275 flags= sp_head::HAS_SQLCOM_FLUSH;
276 break;
277 case SQLCOM_RESET:
278 flags= sp_head::HAS_SQLCOM_RESET;
279 break;
280 case SQLCOM_CREATE_INDEX:
281 case SQLCOM_CREATE_DB:
282 case SQLCOM_CREATE_VIEW:
283 case SQLCOM_CREATE_TRIGGER:
284 case SQLCOM_CREATE_USER:
285 case SQLCOM_ALTER_TABLE:
286 case SQLCOM_GRANT:
287 case SQLCOM_REVOKE:
288 case SQLCOM_BEGIN:
289 case SQLCOM_RENAME_TABLE:
290 case SQLCOM_RENAME_USER:
291 case SQLCOM_DROP_INDEX:
292 case SQLCOM_DROP_DB:
293 case SQLCOM_REVOKE_ALL:
294 case SQLCOM_DROP_USER:
295 case SQLCOM_DROP_VIEW:
296 case SQLCOM_DROP_TRIGGER:
297 case SQLCOM_TRUNCATE:
298 case SQLCOM_COMMIT:
299 case SQLCOM_ROLLBACK:
300 case SQLCOM_LOAD:
301 case SQLCOM_LOAD_MASTER_DATA:
302 case SQLCOM_LOCK_TABLES:
303 case SQLCOM_CREATE_PROCEDURE:
304 case SQLCOM_CREATE_SPFUNCTION:
305 case SQLCOM_ALTER_PROCEDURE:
306 case SQLCOM_ALTER_FUNCTION:
307 case SQLCOM_DROP_PROCEDURE:
308 case SQLCOM_DROP_FUNCTION:
309 case SQLCOM_CREATE_EVENT:
310 case SQLCOM_ALTER_EVENT:
311 case SQLCOM_DROP_EVENT:
312 case SQLCOM_INSTALL_PLUGIN:
313 case SQLCOM_UNINSTALL_PLUGIN:
314 flags= sp_head::HAS_COMMIT_OR_ROLLBACK;
315 break;
316 default:
317 flags= 0;
318 break;
320 return flags;
324 Prepare an Item for evaluation (call of fix_fields).
326 @param thd thread handler
327 @param it_addr pointer on item refernce
329 @retval
330 NULL error
331 @retval
332 non-NULL prepared item
335 Item *
336 sp_prepare_func_item(THD* thd, Item **it_addr)
338 DBUG_ENTER("sp_prepare_func_item");
339 it_addr= (*it_addr)->this_item_addr(thd, it_addr);
341 if (!(*it_addr)->fixed &&
342 ((*it_addr)->fix_fields(thd, it_addr) ||
343 (*it_addr)->check_cols(1)))
345 DBUG_PRINT("info", ("fix_fields() failed"));
346 DBUG_RETURN(NULL);
348 DBUG_RETURN(*it_addr);
353 Evaluate an expression and store the result in the field.
355 @param thd current thread object
356 @param result_field the field to store the result
357 @param expr_item_ptr the root item of the expression
359 @retval
360 FALSE on success
361 @retval
362 TRUE on error
365 bool
366 sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
368 Item *expr_item;
369 enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
370 bool save_abort_on_warning= thd->abort_on_warning;
371 bool save_stmt_modified_non_trans_table=
372 thd->transaction.stmt.modified_non_trans_table;
374 DBUG_ENTER("sp_eval_expr");
376 if (!*expr_item_ptr)
377 goto error;
379 if (!(expr_item= sp_prepare_func_item(thd, expr_item_ptr)))
380 goto error;
383 Set THD flags to emit warnings/errors in case of overflow/type errors
384 during saving the item into the field.
386 Save original values and restore them after save.
389 thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
390 thd->abort_on_warning=
391 thd->variables.sql_mode &
392 (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES);
393 thd->transaction.stmt.modified_non_trans_table= FALSE;
395 /* Save the value in the field. Convert the value if needed. */
397 expr_item->save_in_field(result_field, 0);
399 thd->count_cuted_fields= save_count_cuted_fields;
400 thd->abort_on_warning= save_abort_on_warning;
401 thd->transaction.stmt.modified_non_trans_table= save_stmt_modified_non_trans_table;
403 if (!thd->is_error())
404 DBUG_RETURN(FALSE);
406 error:
408 In case of error during evaluation, leave the result field set to NULL.
409 Sic: we can't do it in the beginning of the function because the
410 result field might be needed for its own re-evaluation, e.g. case of
411 set x = x + 1;
413 result_field->set_null();
414 DBUG_RETURN (TRUE);
420 * sp_name
424 sp_name::sp_name(THD *thd, char *key, uint key_len)
426 m_sroutines_key.str= key;
427 m_sroutines_key.length= key_len;
428 m_qname.str= ++key;
429 m_qname.length= key_len - 1;
430 if ((m_name.str= strchr(m_qname.str, '.')))
432 m_db.length= m_name.str - key;
433 m_db.str= strmake_root(thd->mem_root, key, m_db.length);
434 m_name.str++;
435 m_name.length= m_qname.length - m_db.length - 1;
437 else
439 m_name.str= m_qname.str;
440 m_name.length= m_qname.length;
441 m_db.str= 0;
442 m_db.length= 0;
444 m_explicit_name= false;
449 Init the qualified name from the db and name.
451 void
452 sp_name::init_qname(THD *thd)
454 const uint dot= !!m_db.length;
455 /* m_sroutines format: m_type + [database + dot] + name + nul */
456 m_sroutines_key.length= 1 + m_db.length + dot + m_name.length;
457 if (!(m_sroutines_key.str= (char*) thd->alloc(m_sroutines_key.length + 1)))
458 return;
459 m_qname.length= m_sroutines_key.length - 1;
460 m_qname.str= m_sroutines_key.str + 1;
461 sprintf(m_qname.str, "%.*s%.*s%.*s",
462 (int) m_db.length, (m_db.length ? m_db.str : ""),
463 dot, ".",
464 (int) m_name.length, m_name.str);
469 Check that the name 'ident' is ok. It's assumed to be an 'ident'
470 from the parser, so we only have to check length and trailing spaces.
471 The former is a standard requirement (and 'show status' assumes a
472 non-empty name), the latter is a mysql:ism as trailing spaces are
473 removed by get_field().
475 @retval
476 TRUE bad name
477 @retval
478 FALSE name is ok
481 bool
482 check_routine_name(LEX_STRING *ident)
484 if (!ident || !ident->str || !ident->str[0] ||
485 ident->str[ident->length-1] == ' ')
487 my_error(ER_SP_WRONG_NAME, MYF(0), ident->str);
488 return TRUE;
490 if (check_string_char_length(ident, "", NAME_CHAR_LEN,
491 system_charset_info, 1))
493 my_error(ER_TOO_LONG_IDENT, MYF(0), ident->str);
494 return TRUE;
497 return FALSE;
503 * sp_head
507 void *
508 sp_head::operator new(size_t size) throw()
510 DBUG_ENTER("sp_head::operator new");
511 MEM_ROOT own_root;
512 sp_head *sp;
514 init_sql_alloc(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
515 sp= (sp_head *) alloc_root(&own_root, size);
516 if (sp == NULL)
517 DBUG_RETURN(NULL);
518 sp->main_mem_root= own_root;
519 DBUG_PRINT("info", ("mem_root 0x%lx", (ulong) &sp->mem_root));
520 DBUG_RETURN(sp);
523 void
524 sp_head::operator delete(void *ptr, size_t size) throw()
526 DBUG_ENTER("sp_head::operator delete");
527 MEM_ROOT own_root;
529 if (ptr == NULL)
530 DBUG_VOID_RETURN;
532 sp_head *sp= (sp_head *) ptr;
534 /* Make a copy of main_mem_root as free_root will free the sp */
535 own_root= sp->main_mem_root;
536 DBUG_PRINT("info", ("mem_root 0x%lx moved to 0x%lx",
537 (ulong) &sp->mem_root, (ulong) &own_root));
538 free_root(&own_root, MYF(0));
540 DBUG_VOID_RETURN;
544 sp_head::sp_head()
545 :Query_arena(&main_mem_root, INITIALIZED_FOR_SP),
546 m_flags(0), m_recursion_level(0), m_next_cached_sp(0),
547 m_cont_level(0)
549 const LEX_STRING str_reset= { NULL, 0 };
551 m_first_instance= this;
552 m_first_free_instance= this;
553 m_last_cached_sp= this;
555 m_return_field_def.charset = NULL;
557 FIXME: the only use case when name is NULL is events, and it should
558 be rewritten soon. Remove the else part and replace 'if' with
559 an assert when this is done.
561 m_db= m_name= m_qname= str_reset;
563 DBUG_ENTER("sp_head::sp_head");
565 m_backpatch.empty();
566 m_cont_backpatch.empty();
567 m_lex.empty();
568 hash_init(&m_sptabs, system_charset_info, 0, 0, 0, sp_table_key, 0, 0);
569 hash_init(&m_sroutines, system_charset_info, 0, 0, 0, sp_sroutine_key, 0, 0);
571 m_body_utf8.str= NULL;
572 m_body_utf8.length= 0;
574 DBUG_VOID_RETURN;
578 void
579 sp_head::init(LEX *lex)
581 DBUG_ENTER("sp_head::init");
583 lex->spcont= m_pcont= new sp_pcontext();
585 if (!lex->spcont)
586 DBUG_VOID_RETURN;
589 Altough trg_table_fields list is used only in triggers we init for all
590 types of stored procedures to simplify reset_lex()/restore_lex() code.
592 lex->trg_table_fields.empty();
593 my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8);
595 m_param_begin= NULL;
596 m_param_end= NULL;
598 m_body_begin= NULL ;
600 m_qname.str= NULL;
601 m_qname.length= 0;
603 m_explicit_name= false;
605 m_db.str= NULL;
606 m_db.length= 0;
608 m_name.str= NULL;
609 m_name.length= 0;
611 m_params.str= NULL;
612 m_params.length= 0;
614 m_body.str= NULL;
615 m_body.length= 0;
617 m_defstr.str= NULL;
618 m_defstr.length= 0;
620 m_sroutines_key.str= NULL;
621 m_sroutines_key.length= 0;
623 m_return_field_def.charset= NULL;
625 DBUG_VOID_RETURN;
629 void
630 sp_head::init_sp_name(THD *thd, sp_name *spname)
632 DBUG_ENTER("sp_head::init_sp_name");
634 /* Must be initialized in the parser. */
636 DBUG_ASSERT(spname && spname->m_db.str && spname->m_db.length);
638 /* We have to copy strings to get them into the right memroot. */
640 m_db.length= spname->m_db.length;
641 m_db.str= strmake_root(thd->mem_root, spname->m_db.str, spname->m_db.length);
643 m_name.length= spname->m_name.length;
644 m_name.str= strmake_root(thd->mem_root, spname->m_name.str,
645 spname->m_name.length);
647 m_explicit_name= spname->m_explicit_name;
649 if (spname->m_qname.length == 0)
650 spname->init_qname(thd);
652 m_sroutines_key.length= spname->m_sroutines_key.length;
653 m_sroutines_key.str= (char*) memdup_root(thd->mem_root,
654 spname->m_sroutines_key.str,
655 spname->m_sroutines_key.length + 1);
656 m_sroutines_key.str[0]= static_cast<char>(m_type);
658 m_qname.length= m_sroutines_key.length - 1;
659 m_qname.str= m_sroutines_key.str + 1;
661 DBUG_VOID_RETURN;
665 void
666 sp_head::set_body_start(THD *thd, const char *begin_ptr)
668 m_body_begin= begin_ptr;
669 thd->m_parser_state->m_lip.body_utf8_start(thd, begin_ptr);
673 void
674 sp_head::set_stmt_end(THD *thd)
676 Lex_input_stream *lip= & thd->m_parser_state->m_lip; /* shortcut */
677 const char *end_ptr= lip->get_cpp_ptr(); /* shortcut */
679 /* Make the string of parameters. */
681 if (m_param_begin && m_param_end)
683 m_params.length= m_param_end - m_param_begin;
684 m_params.str= thd->strmake(m_param_begin, m_params.length);
687 /* Remember end pointer for further dumping of whole statement. */
689 thd->lex->stmt_definition_end= end_ptr;
691 /* Make the string of body (in the original character set). */
693 m_body.length= end_ptr - m_body_begin;
694 m_body.str= thd->strmake(m_body_begin, m_body.length);
695 trim_whitespace(thd->charset(), & m_body);
697 /* Make the string of UTF-body. */
699 lip->body_utf8_append(end_ptr);
701 m_body_utf8.length= lip->get_body_utf8_length();
702 m_body_utf8.str= thd->strmake(lip->get_body_utf8_str(), m_body_utf8.length);
703 trim_whitespace(thd->charset(), & m_body_utf8);
706 Make the string of whole stored-program-definition query (in the
707 original character set).
710 m_defstr.length= end_ptr - lip->get_cpp_buf();
711 m_defstr.str= thd->strmake(lip->get_cpp_buf(), m_defstr.length);
712 trim_whitespace(thd->charset(), & m_defstr);
716 static TYPELIB *
717 create_typelib(MEM_ROOT *mem_root, Create_field *field_def, List<String> *src)
719 TYPELIB *result= NULL;
720 CHARSET_INFO *cs= field_def->charset;
721 DBUG_ENTER("create_typelib");
723 if (src->elements)
725 result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
726 result->count= src->elements;
727 result->name= "";
728 if (!(result->type_names=(const char **)
729 alloc_root(mem_root,(sizeof(char *)+sizeof(int))*(result->count+1))))
730 DBUG_RETURN(0);
731 result->type_lengths= (uint*)(result->type_names + result->count+1);
732 List_iterator<String> it(*src);
733 String conv;
734 for (uint i=0; i < result->count; i++)
736 uint32 dummy;
737 uint length;
738 String *tmp= it++;
740 if (String::needs_conversion(tmp->length(), tmp->charset(),
741 cs, &dummy))
743 uint cnv_errs;
744 conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
746 length= conv.length();
747 result->type_names[i]= (char*) strmake_root(mem_root, conv.ptr(),
748 length);
750 else
752 length= tmp->length();
753 result->type_names[i]= strmake_root(mem_root, tmp->ptr(), length);
756 // Strip trailing spaces.
757 length= cs->cset->lengthsp(cs, result->type_names[i], length);
758 result->type_lengths[i]= length;
759 ((uchar *)result->type_names[i])[length]= '\0';
761 result->type_names[result->count]= 0;
762 result->type_lengths[result->count]= 0;
764 DBUG_RETURN(result);
769 sp_head::create(THD *thd)
771 DBUG_ENTER("sp_head::create");
772 DBUG_PRINT("info", ("type: %d name: %s params: %s body: %s",
773 m_type, m_name.str, m_params.str, m_body.str));
775 DBUG_RETURN(sp_create_routine(thd, m_type, this));
778 sp_head::~sp_head()
780 LEX *lex;
781 sp_instr *i;
782 DBUG_ENTER("sp_head::~sp_head");
784 /* sp_head::restore_thd_mem_root() must already have been called. */
785 DBUG_ASSERT(m_thd == NULL);
787 for (uint ip = 0 ; (i = get_instr(ip)) ; ip++)
788 delete i;
789 delete_dynamic(&m_instr);
790 m_pcont->destroy();
791 free_items();
794 If we have non-empty LEX stack then we just came out of parser with
795 error. Now we should delete all auxilary LEXes and restore original
796 THD::lex. It is safe to not update LEX::ptr because further query
797 string parsing and execution will be stopped anyway.
799 while ((lex= (LEX *)m_lex.pop()))
801 THD *thd= lex->thd;
802 lex_end(thd->lex);
803 delete thd->lex;
804 thd->lex= lex;
807 hash_free(&m_sptabs);
808 hash_free(&m_sroutines);
810 delete m_next_cached_sp;
812 DBUG_VOID_RETURN;
817 This is only used for result fields from functions (both during
818 fix_length_and_dec() and evaluation).
821 Field *
822 sp_head::create_result_field(uint field_max_length, const char *field_name,
823 TABLE *table)
825 uint field_length;
826 Field *field;
828 DBUG_ENTER("sp_head::create_result_field");
830 field_length= !m_return_field_def.length ?
831 field_max_length : m_return_field_def.length;
833 field= ::make_field(table->s, /* TABLE_SHARE ptr */
834 (uchar*) 0, /* field ptr */
835 field_length, /* field [max] length */
836 (uchar*) "", /* null ptr */
837 0, /* null bit */
838 m_return_field_def.pack_flag,
839 m_return_field_def.sql_type,
840 m_return_field_def.charset,
841 m_return_field_def.geom_type,
842 Field::NONE, /* unreg check */
843 m_return_field_def.interval,
844 field_name ? field_name : (const char *) m_name.str);
846 if (field)
847 field->init(table);
849 DBUG_RETURN(field);
853 int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b)
855 return (int)((*a)->pos_in_query - (*b)->pos_in_query);
860 StoredRoutinesBinlogging
861 This paragraph applies only to statement-based binlogging. Row-based
862 binlogging does not need anything special like this.
864 Top-down overview:
866 1. Statements
868 Statements that have is_update_query(stmt) == TRUE are written into the
869 binary log verbatim.
870 Examples:
871 UPDATE tbl SET tbl.x = spfunc_w_side_effects()
872 UPDATE tbl SET tbl.x=1 WHERE spfunc_w_side_effect_that_returns_false(tbl.y)
874 Statements that have is_update_query(stmt) == FALSE (e.g. SELECTs) are not
875 written into binary log. Instead we catch function calls the statement
876 makes and write it into binary log separately (see #3).
878 2. PROCEDURE calls
880 CALL statements are not written into binary log. Instead
881 * Any FUNCTION invocation (in SET, IF, WHILE, OPEN CURSOR and other SP
882 instructions) is written into binlog separately.
884 * Each statement executed in SP is binlogged separately, according to rules
885 in #1, with the exception that we modify query string: we replace uses
886 of SP local variables with NAME_CONST('spvar_name', <spvar-value>) calls.
887 This substitution is done in subst_spvars().
889 3. FUNCTION calls
891 In sp_head::execute_function(), we check
892 * If this function invocation is done from a statement that is written
893 into the binary log.
894 * If there were any attempts to write events to the binary log during
895 function execution (grep for start_union_events and stop_union_events)
897 If the answers are No and Yes, we write the function call into the binary
898 log as "SELECT spfunc(<param1value>, <param2value>, ...)"
901 4. Miscellaneous issues.
903 4.1 User variables.
905 When we call mysql_bin_log.write() for an SP statement, thd->user_var_events
906 must hold set<{var_name, value}> pairs for all user variables used during
907 the statement execution.
908 This set is produced by tracking user variable reads during statement
909 execution.
911 For SPs, this has the following implications:
912 1) thd->user_var_events may contain events from several SP statements and
913 needs to be valid after exection of these statements was finished. In
914 order to achieve that, we
915 * Allocate user_var_events array elements on appropriate mem_root (grep
916 for user_var_events_alloc).
917 * Use is_query_in_union() to determine if user_var_event is created.
919 2) We need to empty thd->user_var_events after we have wrote a function
920 call. This is currently done by making
921 reset_dynamic(&thd->user_var_events);
922 calls in several different places. (TODO cosider moving this into
923 mysql_bin_log.write() function)
925 4.2 Auto_increment storage in binlog
927 As we may write two statements to binlog from one single logical statement
928 (case of "SELECT func1(),func2()": it is binlogged as "SELECT func1()" and
929 then "SELECT func2()"), we need to reset auto_increment binlog variables
930 after each binlogged SELECT. Otherwise, the auto_increment value of the
931 first SELECT would be used for the second too.
936 Replace thd->query{_length} with a string that one can write to
937 the binlog.
939 The binlog-suitable string is produced by replacing references to SP local
940 variables with NAME_CONST('sp_var_name', value) calls.
942 @param thd Current thread.
943 @param instr Instruction (we look for Item_splocal instances in
944 instr->free_list)
945 @param query_str Original query string
947 @return
948 - FALSE on success.
949 thd->query{_length} either has been appropriately replaced or there
950 is no need for replacements.
951 - TRUE out of memory error.
954 static bool
955 subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
957 DBUG_ENTER("subst_spvars");
959 Dynamic_array<Item_splocal*> sp_vars_uses;
960 char *pbuf, *cur, buffer[512];
961 String qbuf(buffer, sizeof(buffer), &my_charset_bin);
962 int prev_pos, res, buf_len;
964 /* Find all instances of Item_splocal used in this statement */
965 for (Item *item= instr->free_list; item; item= item->next)
967 if (item->is_splocal())
969 Item_splocal *item_spl= (Item_splocal*)item;
970 if (item_spl->pos_in_query)
971 sp_vars_uses.append(item_spl);
974 if (!sp_vars_uses.elements())
975 DBUG_RETURN(FALSE);
977 /* Sort SP var refs by their occurences in the query */
978 sp_vars_uses.sort(cmp_splocal_locations);
981 Construct a statement string where SP local var refs are replaced
982 with "NAME_CONST(name, value)"
984 qbuf.length(0);
985 cur= query_str->str;
986 prev_pos= res= 0;
987 thd->query_name_consts= 0;
989 for (Item_splocal **splocal= sp_vars_uses.front();
990 splocal < sp_vars_uses.back(); splocal++)
992 Item *val;
994 char str_buffer[STRING_BUFFER_USUAL_SIZE];
995 String str_value_holder(str_buffer, sizeof(str_buffer),
996 &my_charset_latin1);
997 String *str_value;
999 /* append the text between sp ref occurences */
1000 res|= qbuf.append(cur + prev_pos, (*splocal)->pos_in_query - prev_pos);
1001 prev_pos= (*splocal)->pos_in_query + (*splocal)->len_in_query;
1003 /* append the spvar substitute */
1004 res|= qbuf.append(STRING_WITH_LEN(" NAME_CONST('"));
1005 res|= qbuf.append((*splocal)->m_name.str, (*splocal)->m_name.length);
1006 res|= qbuf.append(STRING_WITH_LEN("',"));
1007 res|= (*splocal)->fix_fields(thd, (Item **) splocal);
1009 if (res)
1010 break;
1012 val= (*splocal)->this_item();
1013 DBUG_PRINT("info", ("print 0x%lx", (long) val));
1014 str_value= sp_get_item_value(thd, val, &str_value_holder);
1015 if (str_value)
1016 res|= qbuf.append(*str_value);
1017 else
1018 res|= qbuf.append(STRING_WITH_LEN("NULL"));
1019 res|= qbuf.append(')');
1020 if (res)
1021 break;
1023 thd->query_name_consts++;
1025 res|= qbuf.append(cur + prev_pos, query_str->length - prev_pos);
1026 if (res)
1027 DBUG_RETURN(TRUE);
1030 Allocate additional space at the end of the new query string for the
1031 query_cache_send_result_to_client function.
1033 The query buffer layout is:
1034 buffer :==
1035 <statement> The input statement(s)
1036 '\0' Terminating null char
1037 <length> Length of following current database name (size_t)
1038 <db_name> Name of current database
1039 <flags> Flags struct
1041 buf_len= qbuf.length() + 1 + sizeof(size_t) + thd->db_length +
1042 QUERY_CACHE_FLAGS_SIZE + 1;
1043 if ((pbuf= (char *) alloc_root(thd->mem_root, buf_len)))
1045 memcpy(pbuf, qbuf.ptr(), qbuf.length());
1046 pbuf[qbuf.length()]= 0;
1047 memcpy(pbuf+qbuf.length()+1, (char *) &thd->db_length, sizeof(size_t));
1049 else
1050 DBUG_RETURN(TRUE);
1052 thd->set_query(pbuf, qbuf.length());
1054 DBUG_RETURN(FALSE);
1059 Return appropriate error about recursion limit reaching
1061 SYNOPSIS
1062 sp_head::recursion_level_error()
1063 thd Thread handle
1065 NOTE
1066 For functions and triggers we return error about prohibited recursion.
1067 For stored procedures we return about reaching recursion limit.
1070 void sp_head::recursion_level_error(THD *thd)
1072 if (m_type == TYPE_ENUM_PROCEDURE)
1074 my_error(ER_SP_RECURSION_LIMIT, MYF(0),
1075 static_cast<int>(thd->variables.max_sp_recursion_depth),
1076 m_name.str);
1078 else
1079 my_error(ER_SP_NO_RECURSION, MYF(0));
1084 Execute the routine. The main instruction jump loop is there.
1085 Assume the parameters already set.
1086 @todo
1087 - Will write this SP statement into binlog separately
1088 (TODO: consider changing the condition to "not inside event union")
1090 @retval
1091 FALSE on success
1092 @retval
1093 TRUE on error
1096 bool
1097 sp_head::execute(THD *thd)
1099 DBUG_ENTER("sp_head::execute");
1100 char saved_cur_db_name_buf[NAME_LEN+1];
1101 LEX_STRING saved_cur_db_name=
1102 { saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
1103 bool cur_db_changed= FALSE;
1104 sp_rcontext *ctx;
1105 bool err_status= FALSE;
1106 uint ip= 0;
1107 ulong save_sql_mode;
1108 bool save_abort_on_warning;
1109 Query_arena *old_arena;
1110 /* per-instruction arena */
1111 MEM_ROOT execute_mem_root;
1112 Query_arena execute_arena(&execute_mem_root, INITIALIZED_FOR_SP),
1113 backup_arena;
1114 query_id_t old_query_id;
1115 TABLE *old_derived_tables;
1116 LEX *old_lex;
1117 Item_change_list old_change_list;
1118 String old_packet;
1119 Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer;
1121 Object_creation_ctx *saved_creation_ctx;
1123 /* Use some extra margin for possible SP recursion and functions */
1124 if (check_stack_overrun(thd, 8 * STACK_MIN_SIZE, (uchar*)&old_packet))
1125 DBUG_RETURN(TRUE);
1127 /* init per-instruction memroot */
1128 init_sql_alloc(&execute_mem_root, MEM_ROOT_BLOCK_SIZE, 0);
1130 DBUG_ASSERT(!(m_flags & IS_INVOKED));
1131 m_flags|= IS_INVOKED;
1132 m_first_instance->m_first_free_instance= m_next_cached_sp;
1133 if (m_next_cached_sp)
1135 DBUG_PRINT("info",
1136 ("first free for 0x%lx ++: 0x%lx->0x%lx level: %lu flags %x",
1137 (ulong)m_first_instance, (ulong) this,
1138 (ulong) m_next_cached_sp,
1139 m_next_cached_sp->m_recursion_level,
1140 m_next_cached_sp->m_flags));
1143 Check that if there are not any instances after this one then
1144 pointer to the last instance points on this instance or if there are
1145 some instances after this one then recursion level of next instance
1146 greater then recursion level of current instance on 1
1148 DBUG_ASSERT((m_next_cached_sp == 0 &&
1149 m_first_instance->m_last_cached_sp == this) ||
1150 (m_recursion_level + 1 == m_next_cached_sp->m_recursion_level));
1153 NOTE: The SQL Standard does not specify the context that should be
1154 preserved for stored routines. However, at SAP/Walldorf meeting it was
1155 decided that current database should be preserved.
1158 if (m_db.length &&
1159 (err_status= mysql_opt_change_db(thd, &m_db, &saved_cur_db_name, FALSE,
1160 &cur_db_changed)))
1162 goto done;
1165 if ((ctx= thd->spcont))
1166 ctx->clear_handler();
1167 thd->is_slave_error= 0;
1168 old_arena= thd->stmt_arena;
1171 Switch query context. This has to be done early as this is sometimes
1172 allocated trough sql_alloc
1174 saved_creation_ctx= m_creation_ctx->set_n_backup(thd);
1177 We have to save/restore this info when we are changing call level to
1178 be able properly do close_thread_tables() in instructions.
1180 old_query_id= thd->query_id;
1181 old_derived_tables= thd->derived_tables;
1182 thd->derived_tables= 0;
1183 save_sql_mode= thd->variables.sql_mode;
1184 thd->variables.sql_mode= m_sql_mode;
1185 save_abort_on_warning= thd->abort_on_warning;
1186 thd->abort_on_warning= 0;
1188 When inside a substatement (a stored function or trigger
1189 statement), clear the metadata observer in THD, if any.
1190 Remember the value of the observer here, to be able
1191 to restore it when leaving the substatement.
1193 We reset the observer to suppress errors when a substatement
1194 uses temporary tables. If a temporary table does not exist
1195 at start of the main statement, it's not prelocked
1196 and thus is not validated with other prelocked tables.
1198 Later on, when the temporary table is opened, metadata
1199 versions mismatch, expectedly.
1201 The proper solution for the problem is to re-validate tables
1202 of substatements (Bug#12257, Bug#27011, Bug#32868, Bug#33000),
1203 but it's not implemented yet.
1205 thd->m_reprepare_observer= 0;
1208 It is also more efficient to save/restore current thd->lex once when
1209 do it in each instruction
1211 old_lex= thd->lex;
1213 We should also save Item tree change list to avoid rollback something
1214 too early in the calling query.
1216 old_change_list= thd->change_list;
1217 thd->change_list.empty();
1219 Cursors will use thd->packet, so they may corrupt data which was prepared
1220 for sending by upper level. OTOH cursors in the same routine can share this
1221 buffer safely so let use use routine-local packet instead of having own
1222 packet buffer for each cursor.
1224 It is probably safe to use same thd->convert_buff everywhere.
1226 old_packet.swap(thd->packet);
1229 Switch to per-instruction arena here. We can do it since we cleanup
1230 arena after every instruction.
1232 thd->set_n_backup_active_arena(&execute_arena, &backup_arena);
1235 Save callers arena in order to store instruction results and out
1236 parameters in it later during sp_eval_func_item()
1238 thd->spcont->callers_arena= &backup_arena;
1240 #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
1241 /* Discard the initial part of executing routines. */
1242 thd->profiling.discard_current_query();
1243 #endif
1246 sp_instr *i;
1247 uint hip; // Handler ip
1249 #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
1251 Treat each "instr" of a routine as discrete unit that could be profiled.
1252 Profiling only records information for segments of code that set the
1253 source of the query, and almost all kinds of instructions in s-p do not.
1255 thd->profiling.finish_current_query();
1256 thd->profiling.start_new_query("continuing inside routine");
1257 #endif
1259 i = get_instr(ip); // Returns NULL when we're done.
1260 if (i == NULL)
1262 #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
1263 thd->profiling.discard_current_query();
1264 #endif
1265 break;
1268 DBUG_PRINT("execute", ("Instruction %u", ip));
1271 We need to reset start_time to allow for time to flow inside a stored
1272 procedure. This is only done for SP since time is suppose to be constant
1273 during execution of triggers and functions.
1275 reset_start_time_for_sp(thd);
1278 We have to set thd->stmt_arena before executing the instruction
1279 to store in the instruction free_list all new items, created
1280 during the first execution (for example expanding of '*' or the
1281 items made during other permanent subquery transformations).
1283 thd->stmt_arena= i;
1286 Will write this SP statement into binlog separately
1287 (TODO: consider changing the condition to "not inside event union")
1289 if (thd->prelocked_mode == NON_PRELOCKED)
1290 thd->user_var_events_alloc= thd->mem_root;
1292 err_status= i->execute(thd, &ip);
1294 if (i->free_list)
1295 cleanup_items(i->free_list);
1298 If we've set thd->user_var_events_alloc to mem_root of this SP
1299 statement, clean all the events allocated in it.
1301 if (thd->prelocked_mode == NON_PRELOCKED)
1303 reset_dynamic(&thd->user_var_events);
1304 thd->user_var_events_alloc= NULL;//DEBUG
1307 /* we should cleanup free_list and memroot, used by instruction */
1308 thd->cleanup_after_query();
1309 free_root(&execute_mem_root, MYF(0));
1312 Check if an exception has occurred and a handler has been found
1313 Note: We have to check even if err_status == FALSE, since warnings (and
1314 some errors) don't return a non-zero value. We also have to check even
1315 if thd->killed != 0, since some errors return with this even when a
1316 handler has been found (e.g. "bad data").
1318 if (ctx)
1320 uint hf;
1322 switch (ctx->found_handler(&hip, &hf)) {
1323 case SP_HANDLER_NONE:
1324 break;
1325 case SP_HANDLER_CONTINUE:
1326 thd->restore_active_arena(&execute_arena, &backup_arena);
1327 thd->set_n_backup_active_arena(&execute_arena, &backup_arena);
1328 ctx->push_hstack(i->get_cont_dest());
1329 // Fall through
1330 default:
1331 ip= hip;
1332 err_status= FALSE;
1333 ctx->clear_handler();
1334 ctx->enter_handler(hip);
1335 thd->clear_error();
1336 thd->is_fatal_error= 0;
1337 thd->killed= THD::NOT_KILLED;
1338 thd->mysys_var->abort= 0;
1339 continue;
1342 } while (!err_status && !thd->killed);
1344 #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
1345 thd->profiling.finish_current_query();
1346 thd->profiling.start_new_query("tail end of routine");
1347 #endif
1349 /* Restore query context. */
1351 m_creation_ctx->restore_env(thd, saved_creation_ctx);
1353 /* Restore arena. */
1355 thd->restore_active_arena(&execute_arena, &backup_arena);
1357 thd->spcont->pop_all_cursors(); // To avoid memory leaks after an error
1359 /* Restore all saved */
1360 old_packet.swap(thd->packet);
1361 DBUG_ASSERT(thd->change_list.is_empty());
1362 thd->change_list= old_change_list;
1363 /* To avoid wiping out thd->change_list on old_change_list destruction */
1364 old_change_list.empty();
1365 thd->lex= old_lex;
1366 thd->query_id= old_query_id;
1367 DBUG_ASSERT(!thd->derived_tables);
1368 thd->derived_tables= old_derived_tables;
1369 thd->variables.sql_mode= save_sql_mode;
1370 thd->abort_on_warning= save_abort_on_warning;
1371 thd->m_reprepare_observer= save_reprepare_observer;
1373 thd->stmt_arena= old_arena;
1374 state= EXECUTED;
1376 done:
1377 DBUG_PRINT("info", ("err_status: %d killed: %d is_slave_error: %d report_error: %d",
1378 err_status, thd->killed, thd->is_slave_error,
1379 thd->is_error()));
1381 if (thd->killed)
1382 err_status= TRUE;
1384 If the DB has changed, the pointer has changed too, but the
1385 original thd->db will then have been freed
1387 if (cur_db_changed && thd->killed != THD::KILL_CONNECTION)
1390 Force switching back to the saved current database, because it may be
1391 NULL. In this case, mysql_change_db() would generate an error.
1394 err_status|= mysql_change_db(thd, &saved_cur_db_name, TRUE);
1396 m_flags&= ~IS_INVOKED;
1397 DBUG_PRINT("info",
1398 ("first free for 0x%lx --: 0x%lx->0x%lx, level: %lu, flags %x",
1399 (ulong) m_first_instance,
1400 (ulong) m_first_instance->m_first_free_instance,
1401 (ulong) this, m_recursion_level, m_flags));
1403 Check that we have one of following:
1405 1) there are not free instances which means that this instance is last
1406 in the list of instances (pointer to the last instance point on it and
1407 ther are not other instances after this one in the list)
1409 2) There are some free instances which mean that first free instance
1410 should go just after this one and recursion level of that free instance
1411 should be on 1 more then recursion level of this instance.
1413 DBUG_ASSERT((m_first_instance->m_first_free_instance == 0 &&
1414 this == m_first_instance->m_last_cached_sp &&
1415 m_next_cached_sp == 0) ||
1416 (m_first_instance->m_first_free_instance != 0 &&
1417 m_first_instance->m_first_free_instance == m_next_cached_sp &&
1418 m_first_instance->m_first_free_instance->m_recursion_level ==
1419 m_recursion_level + 1));
1420 m_first_instance->m_first_free_instance= this;
1422 DBUG_RETURN(err_status);
1426 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1428 set_routine_security_ctx() changes routine security context, and
1429 checks if there is an EXECUTE privilege in new context. If there is
1430 no EXECUTE privilege, it changes the context back and returns a
1431 error.
1433 @param thd thread handle
1434 @param sp stored routine to change the context for
1435 @param is_proc TRUE is procedure, FALSE if function
1436 @param save_ctx pointer to an old security context
1438 @todo
1439 - Cache if the definer has the right to use the object on the
1440 first usage and only reset the cache if someone does a GRANT
1441 statement that 'may' affect this.
1443 @retval
1444 TRUE if there was a error, and the context wasn't changed.
1445 @retval
1446 FALSE if the context was changed.
1449 bool
1450 set_routine_security_ctx(THD *thd, sp_head *sp, bool is_proc,
1451 Security_context **save_ctx)
1453 *save_ctx= 0;
1454 if (sp->m_chistics->suid != SP_IS_NOT_SUID &&
1455 sp->m_security_ctx.change_security_context(thd, &sp->m_definer_user,
1456 &sp->m_definer_host,
1457 &sp->m_db,
1458 save_ctx))
1459 return TRUE;
1462 If we changed context to run as another user, we need to check the
1463 access right for the new context again as someone may have revoked
1464 the right to use the procedure from this user.
1466 TODO:
1467 Cache if the definer has the right to use the object on the
1468 first usage and only reset the cache if someone does a GRANT
1469 statement that 'may' affect this.
1471 if (*save_ctx &&
1472 check_routine_access(thd, EXECUTE_ACL,
1473 sp->m_db.str, sp->m_name.str, is_proc, FALSE))
1475 sp->m_security_ctx.restore_security_context(thd, *save_ctx);
1476 *save_ctx= 0;
1477 return TRUE;
1480 return FALSE;
1482 #endif // ! NO_EMBEDDED_ACCESS_CHECKS
1486 Execute trigger stored program.
1488 - changes security context for triggers
1489 - switch to new memroot
1490 - call sp_head::execute
1491 - restore old memroot
1492 - restores security context
1494 @param thd Thread handle
1495 @param db database name
1496 @param table table name
1497 @param grant_info GRANT_INFO structure to be filled with
1498 information about definer's privileges
1499 on subject table
1501 @todo
1502 - TODO: we should create sp_rcontext once per command and reuse it
1503 on subsequent executions of a trigger.
1505 @retval
1506 FALSE on success
1507 @retval
1508 TRUE on error
1511 bool
1512 sp_head::execute_trigger(THD *thd,
1513 const LEX_STRING *db_name,
1514 const LEX_STRING *table_name,
1515 GRANT_INFO *grant_info)
1517 sp_rcontext *octx = thd->spcont;
1518 sp_rcontext *nctx = NULL;
1519 bool err_status= FALSE;
1520 MEM_ROOT call_mem_root;
1521 Query_arena call_arena(&call_mem_root, Query_arena::INITIALIZED_FOR_SP);
1522 Query_arena backup_arena;
1524 DBUG_ENTER("sp_head::execute_trigger");
1525 DBUG_PRINT("info", ("trigger %s", m_name.str));
1527 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1528 Security_context *save_ctx= NULL;
1531 if (m_chistics->suid != SP_IS_NOT_SUID &&
1532 m_security_ctx.change_security_context(thd,
1533 &m_definer_user,
1534 &m_definer_host,
1535 &m_db,
1536 &save_ctx))
1537 DBUG_RETURN(TRUE);
1540 Fetch information about table-level privileges for subject table into
1541 GRANT_INFO instance. The access check itself will happen in
1542 Item_trigger_field, where this information will be used along with
1543 information about column-level privileges.
1546 fill_effective_table_privileges(thd,
1547 grant_info,
1548 db_name->str,
1549 table_name->str);
1551 /* Check that the definer has TRIGGER privilege on the subject table. */
1553 if (!(grant_info->privilege & TRIGGER_ACL))
1555 char priv_desc[128];
1556 get_privilege_desc(priv_desc, sizeof(priv_desc), TRIGGER_ACL);
1558 my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), priv_desc,
1559 thd->security_ctx->priv_user, thd->security_ctx->host_or_ip,
1560 table_name->str);
1562 m_security_ctx.restore_security_context(thd, save_ctx);
1563 DBUG_RETURN(TRUE);
1565 #endif // NO_EMBEDDED_ACCESS_CHECKS
1568 Prepare arena and memroot for objects which lifetime is whole
1569 duration of trigger call (sp_rcontext, it's tables and items,
1570 sp_cursor and Item_cache holders for case expressions). We can't
1571 use caller's arena/memroot for those objects because in this case
1572 some fixed amount of memory will be consumed for each trigger
1573 invocation and so statements which involve lot of them will hog
1574 memory.
1576 TODO: we should create sp_rcontext once per command and reuse it
1577 on subsequent executions of a trigger.
1579 init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0);
1580 thd->set_n_backup_active_arena(&call_arena, &backup_arena);
1582 if (!(nctx= new sp_rcontext(m_pcont, 0, octx)) ||
1583 nctx->init(thd))
1585 err_status= TRUE;
1586 goto err_with_cleanup;
1589 #ifndef DBUG_OFF
1590 nctx->sp= this;
1591 #endif
1593 thd->spcont= nctx;
1595 err_status= execute(thd);
1597 err_with_cleanup:
1598 thd->restore_active_arena(&call_arena, &backup_arena);
1600 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1601 m_security_ctx.restore_security_context(thd, save_ctx);
1602 #endif // NO_EMBEDDED_ACCESS_CHECKS
1604 delete nctx;
1605 call_arena.free_items();
1606 free_root(&call_mem_root, MYF(0));
1607 thd->spcont= octx;
1609 if (thd->killed)
1610 thd->send_kill_message();
1612 DBUG_RETURN(err_status);
1617 Execute a function.
1619 - evaluate parameters
1620 - changes security context for SUID routines
1621 - switch to new memroot
1622 - call sp_head::execute
1623 - restore old memroot
1624 - evaluate the return value
1625 - restores security context
1627 @param thd Thread handle
1628 @param argp Passed arguments (these are items from containing
1629 statement?)
1630 @param argcount Number of passed arguments. We need to check if
1631 this is correct.
1632 @param return_value_fld Save result here.
1634 @todo
1635 We should create sp_rcontext once per command and reuse
1636 it on subsequent executions of a function/trigger.
1638 @todo
1639 In future we should associate call arena/mem_root with
1640 sp_rcontext and allocate all these objects (and sp_rcontext
1641 itself) on it directly rather than juggle with arenas.
1643 @retval
1644 FALSE on success
1645 @retval
1646 TRUE on error
1649 bool
1650 sp_head::execute_function(THD *thd, Item **argp, uint argcount,
1651 Field *return_value_fld)
1653 ulonglong binlog_save_options;
1654 bool need_binlog_call;
1655 uint arg_no;
1656 sp_rcontext *octx = thd->spcont;
1657 sp_rcontext *nctx = NULL;
1658 char buf[STRING_BUFFER_USUAL_SIZE];
1659 String binlog_buf(buf, sizeof(buf), &my_charset_bin);
1660 bool err_status= FALSE;
1661 MEM_ROOT call_mem_root;
1662 Query_arena call_arena(&call_mem_root, Query_arena::INITIALIZED_FOR_SP);
1663 Query_arena backup_arena;
1664 DBUG_ENTER("sp_head::execute_function");
1665 DBUG_PRINT("info", ("function %s", m_name.str));
1667 LINT_INIT(binlog_save_options);
1670 Check that the function is called with all specified arguments.
1672 If it is not, use my_error() to report an error, or it will not terminate
1673 the invoking query properly.
1675 if (argcount != m_pcont->context_var_count())
1678 Need to use my_error here, or it will not terminate the
1679 invoking query properly.
1681 my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0),
1682 "FUNCTION", m_qname.str, m_pcont->context_var_count(), argcount);
1683 DBUG_RETURN(TRUE);
1686 Prepare arena and memroot for objects which lifetime is whole
1687 duration of function call (sp_rcontext, it's tables and items,
1688 sp_cursor and Item_cache holders for case expressions).
1689 We can't use caller's arena/memroot for those objects because
1690 in this case some fixed amount of memory will be consumed for
1691 each function/trigger invocation and so statements which involve
1692 lot of them will hog memory.
1693 TODO: we should create sp_rcontext once per command and reuse
1694 it on subsequent executions of a function/trigger.
1696 init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0);
1697 thd->set_n_backup_active_arena(&call_arena, &backup_arena);
1699 if (!(nctx= new sp_rcontext(m_pcont, return_value_fld, octx)) ||
1700 nctx->init(thd))
1702 thd->restore_active_arena(&call_arena, &backup_arena);
1703 err_status= TRUE;
1704 goto err_with_cleanup;
1708 We have to switch temporarily back to callers arena/memroot.
1709 Function arguments belong to the caller and so the may reference
1710 memory which they will allocate during calculation long after
1711 this function call will be finished (e.g. in Item::cleanup()).
1713 thd->restore_active_arena(&call_arena, &backup_arena);
1715 #ifndef DBUG_OFF
1716 nctx->sp= this;
1717 #endif
1719 /* Pass arguments. */
1720 for (arg_no= 0; arg_no < argcount; arg_no++)
1722 /* Arguments must be fixed in Item_func_sp::fix_fields */
1723 DBUG_ASSERT(argp[arg_no]->fixed);
1725 if ((err_status= nctx->set_variable(thd, arg_no, &(argp[arg_no]))))
1726 goto err_with_cleanup;
1730 If row-based binlogging, we don't need to binlog the function's call, let
1731 each substatement be binlogged its way.
1733 need_binlog_call= mysql_bin_log.is_open() &&
1734 (thd->options & OPTION_BIN_LOG) && !thd->current_stmt_binlog_row_based;
1737 Remember the original arguments for unrolled replication of functions
1738 before they are changed by execution.
1740 if (need_binlog_call)
1742 binlog_buf.length(0);
1743 binlog_buf.append(STRING_WITH_LEN("SELECT "));
1744 append_identifier(thd, &binlog_buf, m_db.str, m_db.length);
1745 binlog_buf.append('.');
1746 append_identifier(thd, &binlog_buf, m_name.str, m_name.length);
1747 binlog_buf.append('(');
1748 for (arg_no= 0; arg_no < argcount; arg_no++)
1750 String str_value_holder;
1751 String *str_value;
1753 if (arg_no)
1754 binlog_buf.append(',');
1756 str_value= sp_get_item_value(thd, nctx->get_item(arg_no),
1757 &str_value_holder);
1759 if (str_value)
1760 binlog_buf.append(*str_value);
1761 else
1762 binlog_buf.append(STRING_WITH_LEN("NULL"));
1764 binlog_buf.append(')');
1766 thd->spcont= nctx;
1768 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1769 Security_context *save_security_ctx;
1770 if (set_routine_security_ctx(thd, this, FALSE, &save_security_ctx))
1772 err_status= TRUE;
1773 goto err_with_cleanup;
1775 #endif
1777 if (need_binlog_call)
1779 query_id_t q;
1780 reset_dynamic(&thd->user_var_events);
1782 In case of artificially constructed events for function calls
1783 we have separate union for each such event and hence can't use
1784 query_id of real calling statement as the start of all these
1785 unions (this will break logic of replication of user-defined
1786 variables). So we use artifical value which is guaranteed to
1787 be greater than all query_id's of all statements belonging
1788 to previous events/unions.
1789 Possible alternative to this is logging of all function invocations
1790 as one select and not resetting THD::user_var_events before
1791 each invocation.
1793 VOID(pthread_mutex_lock(&LOCK_thread_count));
1794 q= global_query_id;
1795 VOID(pthread_mutex_unlock(&LOCK_thread_count));
1796 mysql_bin_log.start_union_events(thd, q + 1);
1797 binlog_save_options= thd->options;
1798 thd->options&= ~OPTION_BIN_LOG;
1802 Switch to call arena/mem_root so objects like sp_cursor or
1803 Item_cache holders for case expressions can be allocated on it.
1805 TODO: In future we should associate call arena/mem_root with
1806 sp_rcontext and allocate all these objects (and sp_rcontext
1807 itself) on it directly rather than juggle with arenas.
1809 thd->set_n_backup_active_arena(&call_arena, &backup_arena);
1811 err_status= execute(thd);
1813 thd->restore_active_arena(&call_arena, &backup_arena);
1815 if (need_binlog_call)
1817 mysql_bin_log.stop_union_events(thd);
1818 thd->options= binlog_save_options;
1819 if (thd->binlog_evt_union.unioned_events)
1821 int errcode = query_error_code(thd, thd->killed == THD::NOT_KILLED);
1822 Query_log_event qinfo(thd, binlog_buf.ptr(), binlog_buf.length(),
1823 thd->binlog_evt_union.unioned_events_trans, FALSE, errcode);
1824 if (mysql_bin_log.write(&qinfo) &&
1825 thd->binlog_evt_union.unioned_events_trans)
1827 push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
1828 "Invoked ROUTINE modified a transactional table but MySQL "
1829 "failed to reflect this change in the binary log");
1830 err_status= TRUE;
1832 reset_dynamic(&thd->user_var_events);
1833 /* Forget those values, in case more function calls are binlogged: */
1834 thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
1835 thd->auto_inc_intervals_in_cur_stmt_for_binlog.empty();
1839 if (!err_status)
1841 /* We need result only in function but not in trigger */
1843 if (!nctx->is_return_value_set())
1845 my_error(ER_SP_NORETURNEND, MYF(0), m_name.str);
1846 err_status= TRUE;
1850 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1851 m_security_ctx.restore_security_context(thd, save_security_ctx);
1852 #endif
1854 err_with_cleanup:
1855 delete nctx;
1856 call_arena.free_items();
1857 free_root(&call_mem_root, MYF(0));
1858 thd->spcont= octx;
1860 DBUG_RETURN(err_status);
1865 Execute a procedure.
1867 The function does the following steps:
1868 - Set all parameters
1869 - changes security context for SUID routines
1870 - call sp_head::execute
1871 - copy back values of INOUT and OUT parameters
1872 - restores security context
1874 @param thd Thread handle
1875 @param args List of values passed as arguments.
1877 @retval
1878 FALSE on success
1879 @retval
1880 TRUE on error
1883 bool
1884 sp_head::execute_procedure(THD *thd, List<Item> *args)
1886 bool err_status= FALSE;
1887 uint params = m_pcont->context_var_count();
1888 sp_rcontext *save_spcont, *octx;
1889 sp_rcontext *nctx = NULL;
1890 bool save_enable_slow_log= false;
1891 bool save_log_general= false;
1892 DBUG_ENTER("sp_head::execute_procedure");
1893 DBUG_PRINT("info", ("procedure %s", m_name.str));
1895 if (args->elements != params)
1897 my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0), "PROCEDURE",
1898 m_qname.str, params, args->elements);
1899 DBUG_RETURN(TRUE);
1902 save_spcont= octx= thd->spcont;
1903 if (! octx)
1904 { // Create a temporary old context
1905 if (!(octx= new sp_rcontext(m_pcont, NULL, octx)) ||
1906 octx->init(thd))
1908 delete octx; /* Delete octx if it was init() that failed. */
1909 DBUG_RETURN(TRUE);
1912 #ifndef DBUG_OFF
1913 octx->sp= 0;
1914 #endif
1915 thd->spcont= octx;
1917 /* set callers_arena to thd, for upper-level function to work */
1918 thd->spcont->callers_arena= thd;
1921 if (!(nctx= new sp_rcontext(m_pcont, NULL, octx)) ||
1922 nctx->init(thd))
1924 delete nctx; /* Delete nctx if it was init() that failed. */
1925 thd->spcont= save_spcont;
1926 DBUG_RETURN(TRUE);
1928 #ifndef DBUG_OFF
1929 nctx->sp= this;
1930 #endif
1932 if (params > 0)
1934 List_iterator<Item> it_args(*args);
1936 DBUG_PRINT("info",(" %.*s: eval args", (int) m_name.length, m_name.str));
1938 for (uint i= 0 ; i < params ; i++)
1940 Item *arg_item= it_args++;
1942 if (!arg_item)
1943 break;
1945 sp_variable_t *spvar= m_pcont->find_variable(i);
1947 if (!spvar)
1948 continue;
1950 if (spvar->mode != sp_param_in)
1952 Settable_routine_parameter *srp=
1953 arg_item->get_settable_routine_parameter();
1955 if (!srp)
1957 my_error(ER_SP_NOT_VAR_ARG, MYF(0), i+1, m_qname.str);
1958 err_status= TRUE;
1959 break;
1962 srp->set_required_privilege(spvar->mode == sp_param_inout);
1965 if (spvar->mode == sp_param_out)
1967 Item_null *null_item= new Item_null();
1969 if (!null_item ||
1970 nctx->set_variable(thd, i, (Item **)&null_item))
1972 err_status= TRUE;
1973 break;
1976 else
1978 if (nctx->set_variable(thd, i, it_args.ref()))
1980 err_status= TRUE;
1981 break;
1987 Okay, got values for all arguments. Close tables that might be used by
1988 arguments evaluation. If arguments evaluation required prelocking mode,
1989 we'll leave it here.
1991 if (!thd->in_sub_stmt)
1993 thd->lex->unit.cleanup();
1994 close_thread_tables(thd);
1995 thd->rollback_item_tree_changes();
1998 DBUG_PRINT("info",(" %.*s: eval args done", (int) m_name.length,
1999 m_name.str));
2001 if (!(m_flags & LOG_SLOW_STATEMENTS) && thd->enable_slow_log)
2003 DBUG_PRINT("info", ("Disabling slow log for the execution"));
2004 save_enable_slow_log= true;
2005 thd->enable_slow_log= FALSE;
2007 if (!(m_flags & LOG_GENERAL_LOG) && !(thd->options & OPTION_LOG_OFF))
2009 DBUG_PRINT("info", ("Disabling general log for the execution"));
2010 save_log_general= true;
2011 /* disable this bit */
2012 thd->options |= OPTION_LOG_OFF;
2014 thd->spcont= nctx;
2016 #ifndef NO_EMBEDDED_ACCESS_CHECKS
2017 Security_context *save_security_ctx= 0;
2018 if (!err_status)
2019 err_status= set_routine_security_ctx(thd, this, TRUE, &save_security_ctx);
2020 #endif
2022 if (!err_status)
2023 err_status= execute(thd);
2025 if (save_log_general)
2026 thd->options &= ~OPTION_LOG_OFF;
2027 if (save_enable_slow_log)
2028 thd->enable_slow_log= true;
2030 In the case when we weren't able to employ reuse mechanism for
2031 OUT/INOUT paranmeters, we should reallocate memory. This
2032 allocation should be done on the arena which will live through
2033 all execution of calling routine.
2035 thd->spcont->callers_arena= octx->callers_arena;
2037 if (!err_status && params > 0)
2039 List_iterator<Item> it_args(*args);
2042 Copy back all OUT or INOUT values to the previous frame, or
2043 set global user variables
2045 for (uint i= 0 ; i < params ; i++)
2047 Item *arg_item= it_args++;
2049 if (!arg_item)
2050 break;
2052 sp_variable_t *spvar= m_pcont->find_variable(i);
2054 if (spvar->mode == sp_param_in)
2055 continue;
2057 Settable_routine_parameter *srp=
2058 arg_item->get_settable_routine_parameter();
2060 DBUG_ASSERT(srp);
2062 if (srp->set_value(thd, octx, nctx->get_item_addr(i)))
2064 err_status= TRUE;
2065 break;
2070 #ifndef NO_EMBEDDED_ACCESS_CHECKS
2071 if (save_security_ctx)
2072 m_security_ctx.restore_security_context(thd, save_security_ctx);
2073 #endif
2075 if (!save_spcont)
2076 delete octx;
2078 delete nctx;
2079 thd->spcont= save_spcont;
2080 DBUG_RETURN(err_status);
2085 Reset lex during parsing, before we parse a sub statement.
2087 @param thd Thread handler.
2089 @return Error state
2090 @retval true An error occurred.
2091 @retval false Success.
2094 bool
2095 sp_head::reset_lex(THD *thd)
2097 DBUG_ENTER("sp_head::reset_lex");
2098 LEX *sublex;
2099 LEX *oldlex= thd->lex;
2101 sublex= new (thd->mem_root)st_lex_local;
2102 if (sublex == 0)
2103 DBUG_RETURN(TRUE);
2105 thd->lex= sublex;
2106 (void)m_lex.push_front(oldlex);
2108 /* Reset most stuff. */
2109 lex_start(thd);
2111 /* And keep the SP stuff too */
2112 sublex->sphead= oldlex->sphead;
2113 sublex->spcont= oldlex->spcont;
2114 /* And trigger related stuff too */
2115 sublex->trg_chistics= oldlex->trg_chistics;
2116 sublex->trg_table_fields.empty();
2117 sublex->sp_lex_in_use= FALSE;
2119 /* Reset type info. */
2121 sublex->charset= NULL;
2122 sublex->length= NULL;
2123 sublex->dec= NULL;
2124 sublex->interval_list.empty();
2125 sublex->type= 0;
2127 DBUG_RETURN(FALSE);
2132 Restore lex during parsing, after we have parsed a sub statement.
2134 @param thd Thread handle
2136 @return
2137 @retval TRUE failure
2138 @retval FALSE success
2141 bool
2142 sp_head::restore_lex(THD *thd)
2144 DBUG_ENTER("sp_head::restore_lex");
2145 LEX *sublex= thd->lex;
2146 LEX *oldlex;
2148 sublex->set_trg_event_type_for_tables();
2150 oldlex= (LEX *)m_lex.pop();
2151 if (! oldlex)
2152 DBUG_RETURN(FALSE); // Nothing to restore
2154 oldlex->trg_table_fields.push_back(&sublex->trg_table_fields);
2157 If this substatement needs row-based, the entire routine does too (we
2158 cannot switch from statement-based to row-based only for this
2159 substatement).
2161 if (sublex->is_stmt_unsafe())
2162 m_flags|= BINLOG_ROW_BASED_IF_MIXED;
2165 Add routines which are used by statement to respective set for
2166 this routine.
2168 if (sp_update_sp_used_routines(&m_sroutines, &sublex->sroutines))
2169 DBUG_RETURN(TRUE);
2171 Merge tables used by this statement (but not by its functions or
2172 procedures) to multiset of tables used by this routine.
2174 merge_table_list(thd, sublex->query_tables, sublex);
2175 if (! sublex->sp_lex_in_use)
2177 lex_end(sublex);
2178 delete sublex;
2180 thd->lex= oldlex;
2181 DBUG_RETURN(FALSE);
2185 Put the instruction on the backpatch list, associated with the label.
2188 sp_head::push_backpatch(sp_instr *i, sp_label_t *lab)
2190 bp_t *bp= (bp_t *)sql_alloc(sizeof(bp_t));
2192 if (!bp)
2193 return 1;
2194 bp->lab= lab;
2195 bp->instr= i;
2196 return m_backpatch.push_front(bp);
2200 Update all instruction with this label in the backpatch list to
2201 the current position.
2203 void
2204 sp_head::backpatch(sp_label_t *lab)
2206 bp_t *bp;
2207 uint dest= instructions();
2208 List_iterator_fast<bp_t> li(m_backpatch);
2210 DBUG_ENTER("sp_head::backpatch");
2211 while ((bp= li++))
2213 if (bp->lab == lab)
2215 DBUG_PRINT("info", ("backpatch: (m_ip %d, label 0x%lx <%s>) to dest %d",
2216 bp->instr->m_ip, (ulong) lab, lab->name, dest));
2217 bp->instr->backpatch(dest, lab->ctx);
2220 DBUG_VOID_RETURN;
2224 Prepare an instance of Create_field for field creation (fill all necessary
2225 attributes).
2227 @param[in] thd Thread handle
2228 @param[in] lex Yacc parsing context
2229 @param[in] field_type Field type
2230 @param[out] field_def An instance of create_field to be filled
2232 @retval
2233 FALSE on success
2234 @retval
2235 TRUE on error
2238 bool
2239 sp_head::fill_field_definition(THD *thd, LEX *lex,
2240 enum enum_field_types field_type,
2241 Create_field *field_def)
2243 LEX_STRING cmt = { 0, 0 };
2244 uint unused1= 0;
2245 int unused2= 0;
2247 if (field_def->init(thd, (char*) "", field_type, lex->length, lex->dec,
2248 lex->type, (Item*) 0, (Item*) 0, &cmt, 0,
2249 &lex->interval_list,
2250 lex->charset ? lex->charset :
2251 thd->variables.collation_database,
2252 lex->uint_geom_type))
2253 return TRUE;
2255 if (field_def->interval_list.elements)
2256 field_def->interval= create_typelib(mem_root, field_def,
2257 &field_def->interval_list);
2259 sp_prepare_create_field(thd, field_def);
2261 if (prepare_create_field(field_def, &unused1, &unused2, &unused2,
2262 HA_CAN_GEOMETRY))
2264 return TRUE;
2267 return FALSE;
2272 sp_head::new_cont_backpatch(sp_instr_opt_meta *i)
2274 m_cont_level+= 1;
2275 if (i)
2277 /* Use the cont. destination slot to store the level */
2278 i->m_cont_dest= m_cont_level;
2279 if (m_cont_backpatch.push_front(i))
2280 return 1;
2282 return 0;
2286 sp_head::add_cont_backpatch(sp_instr_opt_meta *i)
2288 i->m_cont_dest= m_cont_level;
2289 return m_cont_backpatch.push_front(i);
2292 void
2293 sp_head::do_cont_backpatch()
2295 uint dest= instructions();
2296 uint lev= m_cont_level--;
2297 sp_instr_opt_meta *i;
2299 while ((i= m_cont_backpatch.head()) && i->m_cont_dest == lev)
2301 i->m_cont_dest= dest;
2302 (void)m_cont_backpatch.pop();
2306 void
2307 sp_head::set_info(longlong created, longlong modified,
2308 st_sp_chistics *chistics, ulong sql_mode)
2310 m_created= created;
2311 m_modified= modified;
2312 m_chistics= (st_sp_chistics *) memdup_root(mem_root, (char*) chistics,
2313 sizeof(*chistics));
2314 if (m_chistics->comment.length == 0)
2315 m_chistics->comment.str= 0;
2316 else
2317 m_chistics->comment.str= strmake_root(mem_root,
2318 m_chistics->comment.str,
2319 m_chistics->comment.length);
2320 m_sql_mode= sql_mode;
2324 void
2325 sp_head::set_definer(const char *definer, uint definerlen)
2327 char user_name_holder[USERNAME_LENGTH + 1];
2328 LEX_STRING user_name= { user_name_holder, USERNAME_LENGTH };
2330 char host_name_holder[HOSTNAME_LENGTH + 1];
2331 LEX_STRING host_name= { host_name_holder, HOSTNAME_LENGTH };
2333 parse_user(definer, definerlen, user_name.str, &user_name.length,
2334 host_name.str, &host_name.length);
2336 set_definer(&user_name, &host_name);
2340 void
2341 sp_head::set_definer(const LEX_STRING *user_name, const LEX_STRING *host_name)
2343 m_definer_user.str= strmake_root(mem_root, user_name->str, user_name->length);
2344 m_definer_user.length= user_name->length;
2346 m_definer_host.str= strmake_root(mem_root, host_name->str, host_name->length);
2347 m_definer_host.length= host_name->length;
2351 void
2352 sp_head::reset_thd_mem_root(THD *thd)
2354 DBUG_ENTER("sp_head::reset_thd_mem_root");
2355 m_thd_root= thd->mem_root;
2356 thd->mem_root= &main_mem_root;
2357 DBUG_PRINT("info", ("mem_root 0x%lx moved to thd mem root 0x%lx",
2358 (ulong) &mem_root, (ulong) &thd->mem_root));
2359 free_list= thd->free_list; // Keep the old list
2360 thd->free_list= NULL; // Start a new one
2361 m_thd= thd;
2362 DBUG_VOID_RETURN;
2365 void
2366 sp_head::restore_thd_mem_root(THD *thd)
2368 DBUG_ENTER("sp_head::restore_thd_mem_root");
2371 In some cases our parser detects a syntax error and calls
2372 LEX::cleanup_lex_after_parse_error() method only after
2373 finishing parsing the whole routine. In such a situation
2374 sp_head::restore_thd_mem_root() will be called twice - the
2375 first time as part of normal parsing process and the second
2376 time by cleanup_lex_after_parse_error().
2377 To avoid ruining active arena/mem_root state in this case we
2378 skip restoration of old arena/mem_root if this method has been
2379 already called for this routine.
2381 if (!m_thd)
2382 DBUG_VOID_RETURN;
2384 Item *flist= free_list; // The old list
2385 set_query_arena(thd); // Get new free_list and mem_root
2386 state= INITIALIZED_FOR_SP;
2388 DBUG_PRINT("info", ("mem_root 0x%lx returned from thd mem root 0x%lx",
2389 (ulong) &mem_root, (ulong) &thd->mem_root));
2390 thd->free_list= flist; // Restore the old one
2391 thd->mem_root= m_thd_root;
2392 m_thd= NULL;
2393 DBUG_VOID_RETURN;
2398 Check if a user has access right to a routine.
2400 @param thd Thread handler
2401 @param sp SP
2402 @param full_access Set to 1 if the user has SELECT right to the
2403 'mysql.proc' able or is the owner of the routine
2404 @retval
2405 false ok
2406 @retval
2407 true error
2410 bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access)
2412 TABLE_LIST tables;
2413 bzero((char*) &tables,sizeof(tables));
2414 tables.db= (char*) "mysql";
2415 tables.table_name= tables.alias= (char*) "proc";
2416 *full_access= ((!check_table_access(thd, SELECT_ACL, &tables, 1, TRUE) &&
2417 (tables.grant.privilege & SELECT_ACL) != 0) ||
2418 (!strcmp(sp->m_definer_user.str,
2419 thd->security_ctx->priv_user) &&
2420 !strcmp(sp->m_definer_host.str,
2421 thd->security_ctx->priv_host)));
2422 if (!*full_access)
2423 return check_some_routine_access(thd, sp->m_db.str, sp->m_name.str,
2424 sp->m_type == TYPE_ENUM_PROCEDURE);
2425 return 0;
2430 Implement SHOW CREATE statement for stored routines.
2432 @param thd Thread context.
2433 @param type Stored routine type
2434 (TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION)
2436 @return Error status.
2437 @retval FALSE on success
2438 @retval TRUE on error
2441 bool
2442 sp_head::show_create_routine(THD *thd, int type)
2444 const char *col1_caption= type == TYPE_ENUM_PROCEDURE ?
2445 "Procedure" : "Function";
2447 const char *col3_caption= type == TYPE_ENUM_PROCEDURE ?
2448 "Create Procedure" : "Create Function";
2450 bool err_status;
2452 Protocol *protocol= thd->protocol;
2453 List<Item> fields;
2455 LEX_STRING sql_mode;
2457 bool full_access;
2459 DBUG_ENTER("sp_head::show_create_routine");
2460 DBUG_PRINT("info", ("routine %s", m_name.str));
2462 DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE ||
2463 type == TYPE_ENUM_FUNCTION);
2465 if (check_show_routine_access(thd, this, &full_access))
2466 DBUG_RETURN(TRUE);
2468 sys_var_thd_sql_mode::symbolic_mode_representation(
2469 thd, m_sql_mode, &sql_mode);
2471 /* Send header. */
2473 fields.push_back(new Item_empty_string(col1_caption, NAME_CHAR_LEN));
2474 fields.push_back(new Item_empty_string("sql_mode", sql_mode.length));
2478 NOTE: SQL statement field must be not less than 1024 in order not to
2479 confuse old clients.
2482 Item_empty_string *stmt_fld=
2483 new Item_empty_string(col3_caption,
2484 max(m_defstr.length, 1024));
2486 stmt_fld->maybe_null= TRUE;
2488 fields.push_back(stmt_fld);
2491 fields.push_back(new Item_empty_string("character_set_client",
2492 MY_CS_NAME_SIZE));
2494 fields.push_back(new Item_empty_string("collation_connection",
2495 MY_CS_NAME_SIZE));
2497 fields.push_back(new Item_empty_string("Database Collation",
2498 MY_CS_NAME_SIZE));
2500 if (protocol->send_fields(&fields,
2501 Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
2503 DBUG_RETURN(TRUE);
2506 /* Send data. */
2508 protocol->prepare_for_resend();
2510 protocol->store(m_name.str, m_name.length, system_charset_info);
2511 protocol->store(sql_mode.str, sql_mode.length, system_charset_info);
2513 if (full_access)
2514 protocol->store(m_defstr.str, m_defstr.length,
2515 m_creation_ctx->get_client_cs());
2516 else
2517 protocol->store_null();
2520 protocol->store(m_creation_ctx->get_client_cs()->csname, system_charset_info);
2521 protocol->store(m_creation_ctx->get_connection_cl()->name, system_charset_info);
2522 protocol->store(m_creation_ctx->get_db_cl()->name, system_charset_info);
2524 err_status= protocol->write();
2526 if (!err_status)
2527 my_eof(thd);
2529 DBUG_RETURN(err_status);
2536 Add instruction to SP.
2538 @param instr Instruction
2541 int sp_head::add_instr(sp_instr *instr)
2543 instr->free_list= m_thd->free_list;
2544 m_thd->free_list= 0;
2546 Memory root of every instruction is designated for permanent
2547 transformations (optimizations) made on the parsed tree during
2548 the first execution. It points to the memory root of the
2549 entire stored procedure, as their life span is equal.
2551 instr->mem_root= &main_mem_root;
2552 return insert_dynamic(&m_instr, (uchar*)&instr);
2557 Do some minimal optimization of the code:
2558 -# Mark used instructions
2559 -# While doing this, shortcut jumps to jump instructions
2560 -# Compact the code, removing unused instructions.
2562 This is the main mark and move loop; it relies on the following methods
2563 in sp_instr and its subclasses:
2565 - opt_mark() : Mark instruction as reachable
2566 - opt_shortcut_jump(): Shortcut jumps to the final destination;
2567 used by opt_mark().
2568 - opt_move() : Update moved instruction
2569 - set_destination() : Set the new destination (jump instructions only)
2572 void sp_head::optimize()
2574 List<sp_instr> bp;
2575 sp_instr *i;
2576 uint src, dst;
2578 opt_mark();
2580 bp.empty();
2581 src= dst= 0;
2582 while ((i= get_instr(src)))
2584 if (! i->marked)
2586 delete i;
2587 src+= 1;
2589 else
2591 if (src != dst)
2592 { // Move the instruction and update prev. jumps
2593 sp_instr *ibp;
2594 List_iterator_fast<sp_instr> li(bp);
2596 set_dynamic(&m_instr, (uchar*)&i, dst);
2597 while ((ibp= li++))
2599 sp_instr_opt_meta *im= static_cast<sp_instr_opt_meta *>(ibp);
2600 im->set_destination(src, dst);
2603 i->opt_move(dst, &bp);
2604 src+= 1;
2605 dst+= 1;
2608 m_instr.elements= dst;
2609 bp.empty();
2612 void sp_head::add_mark_lead(uint ip, List<sp_instr> *leads)
2614 sp_instr *i= get_instr(ip);
2616 if (i && ! i->marked)
2617 leads->push_front(i);
2620 void
2621 sp_head::opt_mark()
2623 uint ip;
2624 sp_instr *i;
2625 List<sp_instr> leads;
2628 Forward flow analysis algorithm in the instruction graph:
2629 - first, add the entry point in the graph (the first instruction) to the
2630 'leads' list of paths to explore.
2631 - while there are still leads to explore:
2632 - pick one lead, and follow the path forward. Mark instruction reached.
2633 Stop only if the end of the routine is reached, or the path converge
2634 to code already explored (marked).
2635 - while following a path, collect in the 'leads' list any fork to
2636 another path (caused by conditional jumps instructions), so that these
2637 paths can be explored as well.
2640 /* Add the entry point */
2641 i= get_instr(0);
2642 leads.push_front(i);
2644 /* For each path of code ... */
2645 while (leads.elements != 0)
2647 i= leads.pop();
2649 /* Mark the entire path, collecting new leads. */
2650 while (i && ! i->marked)
2652 ip= i->opt_mark(this, & leads);
2653 i= get_instr(ip);
2659 #ifndef DBUG_OFF
2661 Return the routine instructions as a result set.
2662 @return
2663 0 if ok, !=0 on error.
2666 sp_head::show_routine_code(THD *thd)
2668 Protocol *protocol= thd->protocol;
2669 char buff[2048];
2670 String buffer(buff, sizeof(buff), system_charset_info);
2671 List<Item> field_list;
2672 sp_instr *i;
2673 bool full_access;
2674 int res= 0;
2675 uint ip;
2676 DBUG_ENTER("sp_head::show_routine_code");
2677 DBUG_PRINT("info", ("procedure: %s", m_name.str));
2679 if (check_show_routine_access(thd, this, &full_access) || !full_access)
2680 DBUG_RETURN(1);
2682 field_list.push_back(new Item_uint("Pos", 9));
2683 // 1024 is for not to confuse old clients
2684 field_list.push_back(new Item_empty_string("Instruction",
2685 max(buffer.length(), 1024)));
2686 if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
2687 Protocol::SEND_EOF))
2688 DBUG_RETURN(1);
2690 for (ip= 0; (i = get_instr(ip)) ; ip++)
2693 Consistency check. If these are different something went wrong
2694 during optimization.
2696 if (ip != i->m_ip)
2698 const char *format= "Instruction at position %u has m_ip=%u";
2699 char tmp[sizeof(format) + 2*SP_INSTR_UINT_MAXLEN + 1];
2701 sprintf(tmp, format, ip, i->m_ip);
2703 Since this is for debugging purposes only, we don't bother to
2704 introduce a special error code for it.
2706 push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR, tmp);
2708 protocol->prepare_for_resend();
2709 protocol->store((longlong)ip);
2711 buffer.set("", 0, system_charset_info);
2712 i->print(&buffer);
2713 protocol->store(buffer.ptr(), buffer.length(), system_charset_info);
2714 if ((res= protocol->write()))
2715 break;
2718 if (!res)
2719 my_eof(thd);
2721 DBUG_RETURN(res);
2723 #endif // ifndef DBUG_OFF
2727 Prepare LEX and thread for execution of instruction, if requested open
2728 and lock LEX's tables, execute instruction's core function, perform
2729 cleanup afterwards.
2731 @param thd thread context
2732 @param nextp out - next instruction
2733 @param open_tables if TRUE then check read access to tables in LEX's table
2734 list and open and lock them (used in instructions which
2735 need to calculate some expression and don't execute
2736 complete statement).
2737 @param sp_instr instruction for which we prepare context, and which core
2738 function execute by calling its exec_core() method.
2740 @note
2741 We are not saving/restoring some parts of THD which may need this because
2742 we do this once for whole routine execution in sp_head::execute().
2744 @return
2745 0/non-0 - Success/Failure
2749 sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
2750 bool open_tables, sp_instr* instr)
2752 int res= 0;
2753 DBUG_ENTER("reset_lex_and_exec_core");
2756 The flag is saved at the entry to the following substatement.
2757 It's reset further in the common code part.
2758 It's merged with the saved parent's value at the exit of this func.
2760 bool parent_modified_non_trans_table= thd->transaction.stmt.modified_non_trans_table;
2761 thd->transaction.stmt.modified_non_trans_table= FALSE;
2762 DBUG_ASSERT(!thd->derived_tables);
2763 DBUG_ASSERT(thd->change_list.is_empty());
2765 Use our own lex.
2766 We should not save old value since it is saved/restored in
2767 sp_head::execute() when we are entering/leaving routine.
2769 thd->lex= m_lex;
2771 VOID(pthread_mutex_lock(&LOCK_thread_count));
2772 thd->query_id= next_query_id();
2773 VOID(pthread_mutex_unlock(&LOCK_thread_count));
2775 if (thd->prelocked_mode == NON_PRELOCKED)
2778 This statement will enter/leave prelocked mode on its own.
2779 Entering prelocked mode changes table list and related members
2780 of LEX, so we'll need to restore them.
2782 if (lex_query_tables_own_last)
2785 We've already entered/left prelocked mode with this statement.
2786 Attach the list of tables that need to be prelocked and mark m_lex
2787 as having such list attached.
2789 *lex_query_tables_own_last= prelocking_tables;
2790 m_lex->mark_as_requiring_prelocking(lex_query_tables_own_last);
2794 reinit_stmt_before_use(thd, m_lex);
2796 if (open_tables)
2797 res= instr->exec_open_and_lock_tables(thd, m_lex->query_tables);
2799 if (!res)
2801 res= instr->exec_core(thd, nextp);
2802 DBUG_PRINT("info",("exec_core returned: %d", res));
2805 m_lex->unit.cleanup();
2807 thd_proc_info(thd, "closing tables");
2808 /* Here we also commit or rollback the current statement. */
2809 close_thread_tables(thd);
2810 thd_proc_info(thd, 0);
2812 if (m_lex->query_tables_own_last)
2815 We've entered and left prelocking mode when executing statement
2816 stored in m_lex.
2817 m_lex->query_tables(->next_global)* list now has a 'tail' - a list
2818 of tables that are added for prelocking. (If this is the first
2819 execution, the 'tail' was added by open_tables(), otherwise we've
2820 attached it above in this function).
2821 Now we'll save the 'tail', and detach it.
2823 lex_query_tables_own_last= m_lex->query_tables_own_last;
2824 prelocking_tables= *lex_query_tables_own_last;
2825 *lex_query_tables_own_last= NULL;
2826 m_lex->mark_as_requiring_prelocking(NULL);
2828 thd->rollback_item_tree_changes();
2830 Update the state of the active arena if no errors on
2831 open_tables stage.
2833 if (!res || !thd->is_error() ||
2834 (thd->main_da.sql_errno() != ER_CANT_REOPEN_TABLE &&
2835 thd->main_da.sql_errno() != ER_NO_SUCH_TABLE &&
2836 thd->main_da.sql_errno() != ER_UPDATE_TABLE_USED))
2837 thd->stmt_arena->state= Query_arena::EXECUTED;
2840 Merge here with the saved parent's values
2841 what is needed from the substatement gained
2843 thd->transaction.stmt.modified_non_trans_table |= parent_modified_non_trans_table;
2845 Unlike for PS we should not call Item's destructors for newly created
2846 items after execution of each instruction in stored routine. This is
2847 because SP often create Item (like Item_int, Item_string etc...) when
2848 they want to store some value in local variable, pass return value and
2849 etc... So their life time should be longer than one instruction.
2851 cleanup_items() is called in sp_head::execute()
2853 DBUG_RETURN(res || thd->is_error());
2858 sp_instr class functions
2861 int sp_instr::exec_open_and_lock_tables(THD *thd, TABLE_LIST *tables)
2863 int result;
2866 Check whenever we have access to tables for this statement
2867 and open and lock them before executing instructions core function.
2869 if (check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE)
2870 || open_and_lock_tables(thd, tables))
2871 result= -1;
2872 else
2873 result= 0;
2875 return result;
2878 uint sp_instr::get_cont_dest()
2880 return (m_ip+1);
2884 int sp_instr::exec_core(THD *thd, uint *nextp)
2886 DBUG_ASSERT(0);
2887 return 0;
2891 sp_instr_stmt class functions
2895 sp_instr_stmt::execute(THD *thd, uint *nextp)
2897 char *query;
2898 uint32 query_length;
2899 int res;
2900 DBUG_ENTER("sp_instr_stmt::execute");
2901 DBUG_PRINT("info", ("command: %d", m_lex_keeper.sql_command()));
2903 query= thd->query();
2904 query_length= thd->query_length();
2905 #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
2906 /* This s-p instr is profilable and will be captured. */
2907 thd->profiling.set_query_source(m_query.str, m_query.length);
2908 #endif
2909 if (!(res= alloc_query(thd, m_query.str, m_query.length)) &&
2910 !(res=subst_spvars(thd, this, &m_query)))
2913 (the order of query cache and subst_spvars calls is irrelevant because
2914 queries with SP vars can't be cached)
2916 if (unlikely((thd->options & OPTION_LOG_OFF)==0))
2917 general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
2919 if (query_cache_send_result_to_client(thd,
2920 thd->query(),
2921 thd->query_length()) <= 0)
2923 res= m_lex_keeper.reset_lex_and_exec_core(thd, nextp, FALSE, this);
2925 if (thd->main_da.is_eof())
2926 net_end_statement(thd);
2928 query_cache_end_of_result(thd);
2930 if (!res && unlikely(thd->enable_slow_log))
2931 log_slow_statement(thd);
2933 else
2934 *nextp= m_ip+1;
2935 thd->set_query(query, query_length);
2936 thd->query_name_consts= 0;
2938 if (!thd->is_error())
2939 thd->main_da.reset_diagnostics_area();
2941 DBUG_RETURN(res || thd->is_error());
2945 void
2946 sp_instr_stmt::print(String *str)
2948 uint i, len;
2950 /* stmt CMD "..." */
2951 if (str->reserve(SP_STMT_PRINT_MAXLEN+SP_INSTR_UINT_MAXLEN+8))
2952 return;
2953 str->qs_append(STRING_WITH_LEN("stmt "));
2954 str->qs_append((uint)m_lex_keeper.sql_command());
2955 str->qs_append(STRING_WITH_LEN(" \""));
2956 len= m_query.length;
2958 Print the query string (but not too much of it), just to indicate which
2959 statement it is.
2961 if (len > SP_STMT_PRINT_MAXLEN)
2962 len= SP_STMT_PRINT_MAXLEN-3;
2963 /* Copy the query string and replace '\n' with ' ' in the process */
2964 for (i= 0 ; i < len ; i++)
2966 char c= m_query.str[i];
2967 if (c == '\n')
2968 c= ' ';
2969 str->qs_append(c);
2971 if (m_query.length > SP_STMT_PRINT_MAXLEN)
2972 str->qs_append(STRING_WITH_LEN("...")); /* Indicate truncated string */
2973 str->qs_append('"');
2978 sp_instr_stmt::exec_core(THD *thd, uint *nextp)
2980 int res= mysql_execute_command(thd);
2981 *nextp= m_ip+1;
2982 return res;
2987 sp_instr_set class functions
2991 sp_instr_set::execute(THD *thd, uint *nextp)
2993 DBUG_ENTER("sp_instr_set::execute");
2994 DBUG_PRINT("info", ("offset: %u", m_offset));
2996 DBUG_RETURN(m_lex_keeper.reset_lex_and_exec_core(thd, nextp, TRUE, this));
3001 sp_instr_set::exec_core(THD *thd, uint *nextp)
3003 int res= thd->spcont->set_variable(thd, m_offset, &m_value);
3005 if (res && thd->spcont->found_handler_here())
3008 Failed to evaluate the value, and a handler has been found. Reset the
3009 variable to NULL.
3012 if (thd->spcont->set_variable(thd, m_offset, 0))
3014 /* If this also failed, let's abort. */
3016 sp_rcontext *spcont= thd->spcont;
3018 thd->spcont= NULL; /* Avoid handlers */
3019 my_error(ER_OUT_OF_RESOURCES, MYF(0));
3020 spcont->clear_handler();
3021 thd->spcont= spcont;
3025 *nextp = m_ip+1;
3026 return res;
3029 void
3030 sp_instr_set::print(String *str)
3032 /* set name@offset ... */
3033 int rsrv = SP_INSTR_UINT_MAXLEN+6;
3034 sp_variable_t *var = m_ctx->find_variable(m_offset);
3036 /* 'var' should always be non-null, but just in case... */
3037 if (var)
3038 rsrv+= var->name.length;
3039 if (str->reserve(rsrv))
3040 return;
3041 str->qs_append(STRING_WITH_LEN("set "));
3042 if (var)
3044 str->qs_append(var->name.str, var->name.length);
3045 str->qs_append('@');
3047 str->qs_append(m_offset);
3048 str->qs_append(' ');
3049 m_value->print(str, QT_ORDINARY);
3054 sp_instr_set_trigger_field class functions
3058 sp_instr_set_trigger_field::execute(THD *thd, uint *nextp)
3060 DBUG_ENTER("sp_instr_set_trigger_field::execute");
3061 thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
3062 DBUG_RETURN(m_lex_keeper.reset_lex_and_exec_core(thd, nextp, TRUE, this));
3067 sp_instr_set_trigger_field::exec_core(THD *thd, uint *nextp)
3069 const int res= (trigger_field->set_value(thd, &value) ? -1 : 0);
3070 *nextp = m_ip+1;
3071 return res;
3074 void
3075 sp_instr_set_trigger_field::print(String *str)
3077 str->append(STRING_WITH_LEN("set_trigger_field "));
3078 trigger_field->print(str, QT_ORDINARY);
3079 str->append(STRING_WITH_LEN(":="));
3080 value->print(str, QT_ORDINARY);
3084 sp_instr_opt_meta
3087 uint sp_instr_opt_meta::get_cont_dest()
3089 return m_cont_dest;
3094 sp_instr_jump class functions
3098 sp_instr_jump::execute(THD *thd, uint *nextp)
3100 DBUG_ENTER("sp_instr_jump::execute");
3101 DBUG_PRINT("info", ("destination: %u", m_dest));
3103 *nextp= m_dest;
3104 DBUG_RETURN(0);
3107 void
3108 sp_instr_jump::print(String *str)
3110 /* jump dest */
3111 if (str->reserve(SP_INSTR_UINT_MAXLEN+5))
3112 return;
3113 str->qs_append(STRING_WITH_LEN("jump "));
3114 str->qs_append(m_dest);
3117 uint
3118 sp_instr_jump::opt_mark(sp_head *sp, List<sp_instr> *leads)
3120 m_dest= opt_shortcut_jump(sp, this);
3121 if (m_dest != m_ip+1) /* Jumping to following instruction? */
3122 marked= 1;
3123 m_optdest= sp->get_instr(m_dest);
3124 return m_dest;
3127 uint
3128 sp_instr_jump::opt_shortcut_jump(sp_head *sp, sp_instr *start)
3130 uint dest= m_dest;
3131 sp_instr *i;
3133 while ((i= sp->get_instr(dest)))
3135 uint ndest;
3137 if (start == i || this == i)
3138 break;
3139 ndest= i->opt_shortcut_jump(sp, start);
3140 if (ndest == dest)
3141 break;
3142 dest= ndest;
3144 return dest;
3147 void
3148 sp_instr_jump::opt_move(uint dst, List<sp_instr> *bp)
3150 if (m_dest > m_ip)
3151 bp->push_back(this); // Forward
3152 else if (m_optdest)
3153 m_dest= m_optdest->m_ip; // Backward
3154 m_ip= dst;
3159 sp_instr_jump_if_not class functions
3163 sp_instr_jump_if_not::execute(THD *thd, uint *nextp)
3165 DBUG_ENTER("sp_instr_jump_if_not::execute");
3166 DBUG_PRINT("info", ("destination: %u", m_dest));
3167 DBUG_RETURN(m_lex_keeper.reset_lex_and_exec_core(thd, nextp, TRUE, this));
3172 sp_instr_jump_if_not::exec_core(THD *thd, uint *nextp)
3174 Item *it;
3175 int res;
3177 it= sp_prepare_func_item(thd, &m_expr);
3178 if (! it)
3180 res= -1;
3182 else
3184 res= 0;
3185 if (! it->val_bool())
3186 *nextp = m_dest;
3187 else
3188 *nextp = m_ip+1;
3191 return res;
3195 void
3196 sp_instr_jump_if_not::print(String *str)
3198 /* jump_if_not dest(cont) ... */
3199 if (str->reserve(2*SP_INSTR_UINT_MAXLEN+14+32)) // Add some for the expr. too
3200 return;
3201 str->qs_append(STRING_WITH_LEN("jump_if_not "));
3202 str->qs_append(m_dest);
3203 str->qs_append('(');
3204 str->qs_append(m_cont_dest);
3205 str->qs_append(STRING_WITH_LEN(") "));
3206 m_expr->print(str, QT_ORDINARY);
3210 uint
3211 sp_instr_jump_if_not::opt_mark(sp_head *sp, List<sp_instr> *leads)
3213 sp_instr *i;
3215 marked= 1;
3216 if ((i= sp->get_instr(m_dest)))
3218 m_dest= i->opt_shortcut_jump(sp, this);
3219 m_optdest= sp->get_instr(m_dest);
3221 sp->add_mark_lead(m_dest, leads);
3222 if ((i= sp->get_instr(m_cont_dest)))
3224 m_cont_dest= i->opt_shortcut_jump(sp, this);
3225 m_cont_optdest= sp->get_instr(m_cont_dest);
3227 sp->add_mark_lead(m_cont_dest, leads);
3228 return m_ip+1;
3231 void
3232 sp_instr_jump_if_not::opt_move(uint dst, List<sp_instr> *bp)
3235 cont. destinations may point backwards after shortcutting jumps
3236 during the mark phase. If it's still pointing forwards, only
3237 push this for backpatching if sp_instr_jump::opt_move() will not
3238 do it (i.e. if the m_dest points backwards).
3240 if (m_cont_dest > m_ip)
3241 { // Forward
3242 if (m_dest < m_ip)
3243 bp->push_back(this);
3245 else if (m_cont_optdest)
3246 m_cont_dest= m_cont_optdest->m_ip; // Backward
3247 /* This will take care of m_dest and m_ip */
3248 sp_instr_jump::opt_move(dst, bp);
3253 sp_instr_freturn class functions
3257 sp_instr_freturn::execute(THD *thd, uint *nextp)
3259 DBUG_ENTER("sp_instr_freturn::execute");
3260 DBUG_RETURN(m_lex_keeper.reset_lex_and_exec_core(thd, nextp, TRUE, this));
3265 sp_instr_freturn::exec_core(THD *thd, uint *nextp)
3268 Change <next instruction pointer>, so that this will be the last
3269 instruction in the stored function.
3272 *nextp= UINT_MAX;
3275 Evaluate the value of return expression and store it in current runtime
3276 context.
3278 NOTE: It's necessary to evaluate result item right here, because we must
3279 do it in scope of execution the current context/block.
3282 return thd->spcont->set_return_value(thd, &m_value);
3285 void
3286 sp_instr_freturn::print(String *str)
3288 /* freturn type expr... */
3289 if (str->reserve(1024+8+32)) // Add some for the expr. too
3290 return;
3291 str->qs_append(STRING_WITH_LEN("freturn "));
3292 str->qs_append((uint)m_type);
3293 str->qs_append(' ');
3294 m_value->print(str, QT_ORDINARY);
3298 sp_instr_hpush_jump class functions
3302 sp_instr_hpush_jump::execute(THD *thd, uint *nextp)
3304 DBUG_ENTER("sp_instr_hpush_jump::execute");
3305 List_iterator_fast<sp_cond_type_t> li(m_cond);
3306 sp_cond_type_t *p;
3308 while ((p= li++))
3309 thd->spcont->push_handler(p, m_ip+1, m_type, m_frame);
3311 *nextp= m_dest;
3312 DBUG_RETURN(0);
3316 void
3317 sp_instr_hpush_jump::print(String *str)
3319 /* hpush_jump dest fsize type */
3320 if (str->reserve(SP_INSTR_UINT_MAXLEN*2 + 21))
3321 return;
3322 str->qs_append(STRING_WITH_LEN("hpush_jump "));
3323 str->qs_append(m_dest);
3324 str->qs_append(' ');
3325 str->qs_append(m_frame);
3326 switch (m_type) {
3327 case SP_HANDLER_NONE:
3328 str->qs_append(STRING_WITH_LEN(" NONE")); // This would be a bug
3329 break;
3330 case SP_HANDLER_EXIT:
3331 str->qs_append(STRING_WITH_LEN(" EXIT"));
3332 break;
3333 case SP_HANDLER_CONTINUE:
3334 str->qs_append(STRING_WITH_LEN(" CONTINUE"));
3335 break;
3336 case SP_HANDLER_UNDO:
3337 str->qs_append(STRING_WITH_LEN(" UNDO"));
3338 break;
3339 default:
3340 // This would be a bug as well
3341 str->qs_append(STRING_WITH_LEN(" UNKNOWN:"));
3342 str->qs_append(m_type);
3347 uint
3348 sp_instr_hpush_jump::opt_mark(sp_head *sp, List<sp_instr> *leads)
3350 sp_instr *i;
3352 marked= 1;
3353 if ((i= sp->get_instr(m_dest)))
3355 m_dest= i->opt_shortcut_jump(sp, this);
3356 m_optdest= sp->get_instr(m_dest);
3358 sp->add_mark_lead(m_dest, leads);
3361 For continue handlers, all instructions in the scope of the handler
3362 are possible leads. For example, the instruction after freturn might
3363 be executed if the freturn triggers the condition handled by the
3364 continue handler.
3366 m_dest marks the start of the handler scope. It's added as a lead
3367 above, so we start on m_dest+1 here.
3368 m_opt_hpop is the hpop marking the end of the handler scope.
3370 if (m_type == SP_HANDLER_CONTINUE)
3372 for (uint scope_ip= m_dest+1; scope_ip <= m_opt_hpop; scope_ip++)
3373 sp->add_mark_lead(scope_ip, leads);
3376 return m_ip+1;
3381 sp_instr_hpop class functions
3385 sp_instr_hpop::execute(THD *thd, uint *nextp)
3387 DBUG_ENTER("sp_instr_hpop::execute");
3388 thd->spcont->pop_handlers(m_count);
3389 *nextp= m_ip+1;
3390 DBUG_RETURN(0);
3393 void
3394 sp_instr_hpop::print(String *str)
3396 /* hpop count */
3397 if (str->reserve(SP_INSTR_UINT_MAXLEN+5))
3398 return;
3399 str->qs_append(STRING_WITH_LEN("hpop "));
3400 str->qs_append(m_count);
3405 sp_instr_hreturn class functions
3409 sp_instr_hreturn::execute(THD *thd, uint *nextp)
3411 DBUG_ENTER("sp_instr_hreturn::execute");
3412 if (m_dest)
3413 *nextp= m_dest;
3414 else
3416 *nextp= thd->spcont->pop_hstack();
3418 thd->spcont->exit_handler();
3419 DBUG_RETURN(0);
3423 void
3424 sp_instr_hreturn::print(String *str)
3426 /* hreturn framesize dest */
3427 if (str->reserve(SP_INSTR_UINT_MAXLEN*2 + 9))
3428 return;
3429 str->qs_append(STRING_WITH_LEN("hreturn "));
3430 str->qs_append(m_frame);
3431 if (m_dest)
3433 str->qs_append(' ');
3434 str->qs_append(m_dest);
3439 uint
3440 sp_instr_hreturn::opt_mark(sp_head *sp, List<sp_instr> *leads)
3442 marked= 1;
3444 if (m_dest)
3447 This is an EXIT handler; next instruction step is in m_dest.
3449 return m_dest;
3453 This is a CONTINUE handler; next instruction step will come from
3454 the handler stack and not from opt_mark.
3456 return UINT_MAX;
3461 sp_instr_cpush class functions
3465 sp_instr_cpush::execute(THD *thd, uint *nextp)
3467 Query_arena backup_arena;
3468 DBUG_ENTER("sp_instr_cpush::execute");
3471 We should create cursors in the callers arena, as
3472 it could be (and usually is) used in several instructions.
3474 thd->set_n_backup_active_arena(thd->spcont->callers_arena, &backup_arena);
3476 thd->spcont->push_cursor(&m_lex_keeper, this);
3478 thd->restore_active_arena(thd->spcont->callers_arena, &backup_arena);
3480 *nextp= m_ip+1;
3482 DBUG_RETURN(0);
3486 void
3487 sp_instr_cpush::print(String *str)
3489 LEX_STRING n;
3490 my_bool found= m_ctx->find_cursor(m_cursor, &n);
3491 /* cpush name@offset */
3492 uint rsrv= SP_INSTR_UINT_MAXLEN+7;
3494 if (found)
3495 rsrv+= n.length;
3496 if (str->reserve(rsrv))
3497 return;
3498 str->qs_append(STRING_WITH_LEN("cpush "));
3499 if (found)
3501 str->qs_append(n.str, n.length);
3502 str->qs_append('@');
3504 str->qs_append(m_cursor);
3509 sp_instr_cpop class functions
3513 sp_instr_cpop::execute(THD *thd, uint *nextp)
3515 DBUG_ENTER("sp_instr_cpop::execute");
3516 thd->spcont->pop_cursors(m_count);
3517 *nextp= m_ip+1;
3518 DBUG_RETURN(0);
3522 void
3523 sp_instr_cpop::print(String *str)
3525 /* cpop count */
3526 if (str->reserve(SP_INSTR_UINT_MAXLEN+5))
3527 return;
3528 str->qs_append(STRING_WITH_LEN("cpop "));
3529 str->qs_append(m_count);
3534 sp_instr_copen class functions
3538 @todo
3539 Assert that we either have an error or a cursor
3543 sp_instr_copen::execute(THD *thd, uint *nextp)
3546 We don't store a pointer to the cursor in the instruction to be
3547 able to reuse the same instruction among different threads in future.
3549 sp_cursor *c= thd->spcont->get_cursor(m_cursor);
3550 int res;
3551 DBUG_ENTER("sp_instr_copen::execute");
3553 if (! c)
3554 res= -1;
3555 else
3557 sp_lex_keeper *lex_keeper= c->get_lex_keeper();
3558 Query_arena *old_arena= thd->stmt_arena;
3561 Get the Query_arena from the cpush instruction, which contains
3562 the free_list of the query, so new items (if any) are stored in
3563 the right free_list, and we can cleanup after each open.
3565 thd->stmt_arena= c->get_instr();
3566 res= lex_keeper->reset_lex_and_exec_core(thd, nextp, FALSE, this);
3567 /* Cleanup the query's items */
3568 if (thd->stmt_arena->free_list)
3569 cleanup_items(thd->stmt_arena->free_list);
3570 thd->stmt_arena= old_arena;
3572 Work around the fact that errors in selects are not returned properly
3573 (but instead converted into a warning), so if a condition handler
3574 caught, we have lost the result code.
3576 if (!res)
3578 uint dummy1, dummy2;
3580 if (thd->spcont->found_handler(&dummy1, &dummy2))
3581 res= -1;
3583 /* TODO: Assert here that we either have an error or a cursor */
3585 DBUG_RETURN(res);
3590 sp_instr_copen::exec_core(THD *thd, uint *nextp)
3592 sp_cursor *c= thd->spcont->get_cursor(m_cursor);
3593 int res= c->open(thd);
3594 *nextp= m_ip+1;
3595 return res;
3598 void
3599 sp_instr_copen::print(String *str)
3601 LEX_STRING n;
3602 my_bool found= m_ctx->find_cursor(m_cursor, &n);
3603 /* copen name@offset */
3604 uint rsrv= SP_INSTR_UINT_MAXLEN+7;
3606 if (found)
3607 rsrv+= n.length;
3608 if (str->reserve(rsrv))
3609 return;
3610 str->qs_append(STRING_WITH_LEN("copen "));
3611 if (found)
3613 str->qs_append(n.str, n.length);
3614 str->qs_append('@');
3616 str->qs_append(m_cursor);
3621 sp_instr_cclose class functions
3625 sp_instr_cclose::execute(THD *thd, uint *nextp)
3627 sp_cursor *c= thd->spcont->get_cursor(m_cursor);
3628 int res;
3629 DBUG_ENTER("sp_instr_cclose::execute");
3631 if (! c)
3632 res= -1;
3633 else
3634 res= c->close(thd);
3635 *nextp= m_ip+1;
3636 DBUG_RETURN(res);
3640 void
3641 sp_instr_cclose::print(String *str)
3643 LEX_STRING n;
3644 my_bool found= m_ctx->find_cursor(m_cursor, &n);
3645 /* cclose name@offset */
3646 uint rsrv= SP_INSTR_UINT_MAXLEN+8;
3648 if (found)
3649 rsrv+= n.length;
3650 if (str->reserve(rsrv))
3651 return;
3652 str->qs_append(STRING_WITH_LEN("cclose "));
3653 if (found)
3655 str->qs_append(n.str, n.length);
3656 str->qs_append('@');
3658 str->qs_append(m_cursor);
3663 sp_instr_cfetch class functions
3667 sp_instr_cfetch::execute(THD *thd, uint *nextp)
3669 sp_cursor *c= thd->spcont->get_cursor(m_cursor);
3670 int res;
3671 Query_arena backup_arena;
3672 DBUG_ENTER("sp_instr_cfetch::execute");
3674 res= c ? c->fetch(thd, &m_varlist) : -1;
3676 *nextp= m_ip+1;
3677 DBUG_RETURN(res);
3681 void
3682 sp_instr_cfetch::print(String *str)
3684 List_iterator_fast<struct sp_variable> li(m_varlist);
3685 sp_variable_t *pv;
3686 LEX_STRING n;
3687 my_bool found= m_ctx->find_cursor(m_cursor, &n);
3688 /* cfetch name@offset vars... */
3689 uint rsrv= SP_INSTR_UINT_MAXLEN+8;
3691 if (found)
3692 rsrv+= n.length;
3693 if (str->reserve(rsrv))
3694 return;
3695 str->qs_append(STRING_WITH_LEN("cfetch "));
3696 if (found)
3698 str->qs_append(n.str, n.length);
3699 str->qs_append('@');
3701 str->qs_append(m_cursor);
3702 while ((pv= li++))
3704 if (str->reserve(pv->name.length+SP_INSTR_UINT_MAXLEN+2))
3705 return;
3706 str->qs_append(' ');
3707 str->qs_append(pv->name.str, pv->name.length);
3708 str->qs_append('@');
3709 str->qs_append(pv->offset);
3715 sp_instr_error class functions
3719 sp_instr_error::execute(THD *thd, uint *nextp)
3721 DBUG_ENTER("sp_instr_error::execute");
3723 my_message(m_errcode, ER(m_errcode), MYF(0));
3724 *nextp= m_ip+1;
3725 DBUG_RETURN(-1);
3729 void
3730 sp_instr_error::print(String *str)
3732 /* error code */
3733 if (str->reserve(SP_INSTR_UINT_MAXLEN+6))
3734 return;
3735 str->qs_append(STRING_WITH_LEN("error "));
3736 str->qs_append(m_errcode);
3740 /**************************************************************************
3741 sp_instr_set_case_expr class implementation
3742 **************************************************************************/
3745 sp_instr_set_case_expr::execute(THD *thd, uint *nextp)
3747 DBUG_ENTER("sp_instr_set_case_expr::execute");
3749 DBUG_RETURN(m_lex_keeper.reset_lex_and_exec_core(thd, nextp, TRUE, this));
3754 sp_instr_set_case_expr::exec_core(THD *thd, uint *nextp)
3756 int res= thd->spcont->set_case_expr(thd, m_case_expr_id, &m_case_expr);
3758 if (res &&
3759 !thd->spcont->get_case_expr(m_case_expr_id) &&
3760 thd->spcont->found_handler_here())
3763 Failed to evaluate the value, the case expression is still not
3764 initialized, and a handler has been found. Set to NULL so we can continue.
3767 Item *null_item= new Item_null();
3769 if (!null_item ||
3770 thd->spcont->set_case_expr(thd, m_case_expr_id, &null_item))
3772 /* If this also failed, we have to abort. */
3774 sp_rcontext *spcont= thd->spcont;
3776 thd->spcont= NULL; /* Avoid handlers */
3777 my_error(ER_OUT_OF_RESOURCES, MYF(0));
3778 spcont->clear_handler();
3779 thd->spcont= spcont;
3782 else
3783 *nextp= m_ip+1;
3785 return res;
3789 void
3790 sp_instr_set_case_expr::print(String *str)
3792 /* set_case_expr (cont) id ... */
3793 str->reserve(2*SP_INSTR_UINT_MAXLEN+18+32); // Add some extra for expr too
3794 str->qs_append(STRING_WITH_LEN("set_case_expr ("));
3795 str->qs_append(m_cont_dest);
3796 str->qs_append(STRING_WITH_LEN(") "));
3797 str->qs_append(m_case_expr_id);
3798 str->qs_append(' ');
3799 m_case_expr->print(str, QT_ORDINARY);
3802 uint
3803 sp_instr_set_case_expr::opt_mark(sp_head *sp, List<sp_instr> *leads)
3805 sp_instr *i;
3807 marked= 1;
3808 if ((i= sp->get_instr(m_cont_dest)))
3810 m_cont_dest= i->opt_shortcut_jump(sp, this);
3811 m_cont_optdest= sp->get_instr(m_cont_dest);
3813 sp->add_mark_lead(m_cont_dest, leads);
3814 return m_ip+1;
3817 void
3818 sp_instr_set_case_expr::opt_move(uint dst, List<sp_instr> *bp)
3820 if (m_cont_dest > m_ip)
3821 bp->push_back(this); // Forward
3822 else if (m_cont_optdest)
3823 m_cont_dest= m_cont_optdest->m_ip; // Backward
3824 m_ip= dst;
3828 /* ------------------------------------------------------------------ */
3832 Structure that represent all instances of one table
3833 in optimized multi-set of tables used by routine.
3836 typedef struct st_sp_table
3839 Multi-set key:
3840 db_name\0table_name\0alias\0 - for normal tables
3841 db_name\0table_name\0 - for temporary tables
3843 LEX_STRING qname;
3844 uint db_length, table_name_length;
3845 bool temp; /* true if corresponds to a temporary table */
3846 thr_lock_type lock_type; /* lock type used for prelocking */
3847 uint lock_count;
3848 uint query_lock_count;
3849 uint8 trg_event_map;
3850 } SP_TABLE;
3853 uchar *sp_table_key(const uchar *ptr, size_t *plen, my_bool first)
3855 SP_TABLE *tab= (SP_TABLE *)ptr;
3856 *plen= tab->qname.length;
3857 return (uchar *)tab->qname.str;
3862 Merge the list of tables used by some query into the multi-set of
3863 tables used by routine.
3865 @param thd thread context
3866 @param table table list
3867 @param lex_for_tmp_check LEX of the query for which we are merging
3868 table list.
3870 @note
3871 This method will use LEX provided to check whenever we are creating
3872 temporary table and mark it as such in target multi-set.
3874 @retval
3875 TRUE Success
3876 @retval
3877 FALSE Error
3880 bool
3881 sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
3883 SP_TABLE *tab;
3885 if (lex_for_tmp_check->sql_command == SQLCOM_DROP_TABLE &&
3886 lex_for_tmp_check->drop_temporary)
3887 return TRUE;
3889 for (uint i= 0 ; i < m_sptabs.records ; i++)
3891 tab= (SP_TABLE *)hash_element(&m_sptabs, i);
3892 tab->query_lock_count= 0;
3895 for (; table ; table= table->next_global)
3896 if (!table->derived && !table->schema_table)
3899 Structure of key for the multi-set is "db\0table\0alias\0".
3900 Since "alias" part can have arbitrary length we use String
3901 object to construct the key. By default String will use
3902 buffer allocated on stack with NAME_LEN bytes reserved for
3903 alias, since in most cases it is going to be smaller than
3904 NAME_LEN bytes.
3906 char tname_buff[(NAME_LEN + 1) * 3];
3907 String tname(tname_buff, sizeof(tname_buff), &my_charset_bin);
3908 uint temp_table_key_length;
3910 tname.length(0);
3911 tname.append(table->db, table->db_length);
3912 tname.append('\0');
3913 tname.append(table->table_name, table->table_name_length);
3914 tname.append('\0');
3915 temp_table_key_length= tname.length();
3916 tname.append(table->alias);
3917 tname.append('\0');
3920 Upgrade the lock type because this table list will be used
3921 only in pre-locked mode, in which DELAYED inserts are always
3922 converted to normal inserts.
3924 if (table->lock_type == TL_WRITE_DELAYED)
3925 table->lock_type= TL_WRITE;
3928 We ignore alias when we check if table was already marked as temporary
3929 (and therefore should not be prelocked). Otherwise we will erroneously
3930 treat table with same name but with different alias as non-temporary.
3932 if ((tab= (SP_TABLE *)hash_search(&m_sptabs, (uchar *)tname.ptr(),
3933 tname.length())) ||
3934 ((tab= (SP_TABLE *)hash_search(&m_sptabs, (uchar *)tname.ptr(),
3935 temp_table_key_length)) &&
3936 tab->temp))
3938 if (tab->lock_type < table->lock_type)
3939 tab->lock_type= table->lock_type; // Use the table with the highest lock type
3940 tab->query_lock_count++;
3941 if (tab->query_lock_count > tab->lock_count)
3942 tab->lock_count++;
3943 tab->trg_event_map|= table->trg_event_map;
3945 else
3947 if (!(tab= (SP_TABLE *)thd->calloc(sizeof(SP_TABLE))))
3948 return FALSE;
3949 if (lex_for_tmp_check->sql_command == SQLCOM_CREATE_TABLE &&
3950 lex_for_tmp_check->query_tables == table &&
3951 lex_for_tmp_check->create_info.options & HA_LEX_CREATE_TMP_TABLE)
3953 tab->temp= TRUE;
3954 tab->qname.length= temp_table_key_length;
3956 else
3957 tab->qname.length= tname.length();
3958 tab->qname.str= (char*) thd->memdup(tname.ptr(), tab->qname.length);
3959 if (!tab->qname.str)
3960 return FALSE;
3961 tab->table_name_length= table->table_name_length;
3962 tab->db_length= table->db_length;
3963 tab->lock_type= table->lock_type;
3964 tab->lock_count= tab->query_lock_count= 1;
3965 tab->trg_event_map= table->trg_event_map;
3966 if (my_hash_insert(&m_sptabs, (uchar *)tab))
3967 return FALSE;
3970 return TRUE;
3975 Add tables used by routine to the table list.
3977 Converts multi-set of tables used by this routine to table list and adds
3978 this list to the end of table list specified by 'query_tables_last_ptr'.
3980 Elements of list will be allocated in PS memroot, so this list will be
3981 persistent between PS executions.
3983 @param[in] thd Thread context
3984 @param[in,out] query_tables_last_ptr Pointer to the next_global member of
3985 last element of the list where tables
3986 will be added (or to its root).
3987 @param[in] belong_to_view Uppermost view which uses this routine,
3988 0 if none.
3990 @retval
3991 TRUE if some elements were added
3992 @retval
3993 FALSE otherwise.
3996 bool
3997 sp_head::add_used_tables_to_table_list(THD *thd,
3998 TABLE_LIST ***query_tables_last_ptr,
3999 TABLE_LIST *belong_to_view)
4001 uint i;
4002 Query_arena *arena, backup;
4003 bool result= FALSE;
4004 DBUG_ENTER("sp_head::add_used_tables_to_table_list");
4007 Use persistent arena for table list allocation to be PS/SP friendly.
4008 Note that we also have to copy database/table names and alias to PS/SP
4009 memory since current instance of sp_head object can pass away before
4010 next execution of PS/SP for which tables are added to prelocking list.
4011 This will be fixed by introducing of proper invalidation mechanism
4012 once new TDC is ready.
4014 arena= thd->activate_stmt_arena_if_needed(&backup);
4016 for (i=0 ; i < m_sptabs.records ; i++)
4018 char *tab_buff, *key_buff;
4019 TABLE_LIST *table;
4020 SP_TABLE *stab= (SP_TABLE *)hash_element(&m_sptabs, i);
4021 if (stab->temp)
4022 continue;
4024 if (!(tab_buff= (char *)thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST)) *
4025 stab->lock_count)) ||
4026 !(key_buff= (char*)thd->memdup(stab->qname.str,
4027 stab->qname.length)))
4028 DBUG_RETURN(FALSE);
4030 for (uint j= 0; j < stab->lock_count; j++)
4032 table= (TABLE_LIST *)tab_buff;
4034 table->db= key_buff;
4035 table->db_length= stab->db_length;
4036 table->table_name= table->db + table->db_length + 1;
4037 table->table_name_length= stab->table_name_length;
4038 table->alias= table->table_name + table->table_name_length + 1;
4039 table->lock_type= stab->lock_type;
4040 table->cacheable_table= 1;
4041 table->prelocking_placeholder= 1;
4042 table->belong_to_view= belong_to_view;
4043 table->trg_event_map= stab->trg_event_map;
4045 /* Everyting else should be zeroed */
4047 **query_tables_last_ptr= table;
4048 table->prev_global= *query_tables_last_ptr;
4049 *query_tables_last_ptr= &table->next_global;
4051 tab_buff+= ALIGN_SIZE(sizeof(TABLE_LIST));
4052 result= TRUE;
4056 if (arena)
4057 thd->restore_active_arena(arena, &backup);
4059 DBUG_RETURN(result);
4064 Simple function for adding an explicetly named (systems) table to
4065 the global table list, e.g. "mysql", "proc".
4068 TABLE_LIST *
4069 sp_add_to_query_tables(THD *thd, LEX *lex,
4070 const char *db, const char *name,
4071 thr_lock_type locktype)
4073 TABLE_LIST *table;
4075 if (!(table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST))))
4077 thd->fatal_error();
4078 return NULL;
4080 table->db_length= strlen(db);
4081 table->db= thd->strmake(db, table->db_length);
4082 table->table_name_length= strlen(name);
4083 table->table_name= thd->strmake(name, table->table_name_length);
4084 table->alias= thd->strdup(name);
4085 table->lock_type= locktype;
4086 table->select_lex= lex->current_select;
4087 table->cacheable_table= 1;
4089 lex->add_to_query_tables(table);
4090 return table;