16 #include "my_global.h"
21 #include "probes_mysql.h"
24 #include "sp_rcontext.h"
27 #include "sql_parse.h"
28 #include "sql_prepare.h"
29 #include "transaction.h"
38 static int cmp_splocal_locations(
Item_splocal *
const *a,
41 return (
int)((*a)->pos_in_query - (*b)->pos_in_query);
141 char *pbuf, *cur, buffer[512];
142 String qbuf(buffer,
sizeof(buffer), &my_charset_bin);
143 int prev_pos, res, buf_len;
146 for (
Item *item= instr->free_list; item; item= item->next)
148 if (item->is_splocal())
151 if (item_spl->pos_in_query)
152 sp_vars_uses.
append(item_spl);
156 if (!sp_vars_uses.elements())
160 sp_vars_uses.sort(cmp_splocal_locations);
169 thd->query_name_consts= 0;
172 splocal <= sp_vars_uses.
back(); splocal++)
176 char str_buffer[STRING_BUFFER_USUAL_SIZE];
177 String str_value_holder(str_buffer,
sizeof(str_buffer),
182 res|= qbuf.append(cur + prev_pos, (*splocal)->pos_in_query - prev_pos);
183 prev_pos= (*splocal)->pos_in_query + (*splocal)->len_in_query;
185 res|= (*splocal)->fix_fields(thd, (
Item **) splocal);
189 if ((*splocal)->limit_clause_param)
191 res|= qbuf.append_ulonglong((*splocal)->val_uint());
198 res|= qbuf.append(STRING_WITH_LEN(
" NAME_CONST('"));
199 res|= qbuf.append((*splocal)->m_name);
200 res|= qbuf.append(STRING_WITH_LEN(
"',"));
205 val= (*splocal)->this_item();
206 str_value= sp_get_item_value(thd, val, &str_value_holder);
208 res|= qbuf.append(*str_value);
210 res|= qbuf.append(STRING_WITH_LEN(
"NULL"));
211 res|= qbuf.append(
')');
215 thd->query_name_consts++;
218 qbuf.append(cur + prev_pos, query_str->length - prev_pos))
233 buf_len= qbuf.length() + 1 +
sizeof(size_t) + thd->db_length +
234 QUERY_CACHE_FLAGS_SIZE + 1;
235 if ((pbuf= (
char *) alloc_root(thd->mem_root, buf_len)))
237 memcpy(pbuf, qbuf.ptr(), qbuf.length());
238 pbuf[qbuf.length()]= 0;
239 memcpy(pbuf+qbuf.length()+1, (
char *) &thd->db_length,
sizeof(
size_t));
244 thd->set_query(pbuf, qbuf.length());
253 #define SP_INSTR_UINT_MAXLEN 8
254 #define SP_STMT_PRINT_MAXLEN 40
261 bool sp_lex_instr::reset_lex_and_exec_core(THD *thd,
273 unsigned int parent_unsafe_rollback_flags=
274 thd->transaction.stmt.get_unsafe_rollback_flags();
275 thd->transaction.stmt.reset_unsafe_rollback_flags();
279 DBUG_ASSERT(!thd->derived_tables);
280 DBUG_ASSERT(thd->change_list.is_empty());
291 LEX *lex_saved= thd->lex;
296 thd->set_query_id(next_query_id());
298 if (thd->locked_tables_mode <= LTM_LOCK_TABLES)
305 if (m_lex_query_tables_own_last)
312 *m_lex_query_tables_own_last= m_prelocking_tables;
313 m_lex->mark_as_requiring_prelocking(m_lex_query_tables_own_last);
331 &m_lex->var_list, NULL, 0,
this,
332 thd->variables.character_set_client);
342 if (m_lex->query_tables)
353 DBUG_PRINT(
"info",(
"exec_core returned: %d", rc));
361 m_lex->unit.cleanup();
365 if (! thd->in_sub_stmt)
367 thd->get_stmt_da()->set_overwrite_status(
true);
368 thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
369 thd->get_stmt_da()->set_overwrite_status(
false);
371 thd_proc_info(thd,
"closing tables");
372 close_thread_tables(thd);
373 thd_proc_info(thd, 0);
375 if (! thd->in_sub_stmt)
377 if (thd->transaction_rollback_request)
379 trans_rollback_implicit(thd);
380 thd->mdl_context.release_transactional_locks();
382 else if (! thd->in_multi_stmt_transaction_mode())
383 thd->mdl_context.release_transactional_locks();
385 thd->mdl_context.release_statement_locks();
391 DBUG_PRINT(
"info",(
"exec_core returned: %d", rc));
394 if (m_lex->query_tables_own_last)
405 m_lex_query_tables_own_last= m_lex->query_tables_own_last;
406 m_prelocking_tables= *m_lex_query_tables_own_last;
407 *m_lex_query_tables_own_last= NULL;
408 m_lex->mark_as_requiring_prelocking(NULL);
413 thd->rollback_item_tree_changes();
420 if (!rc || !thd->is_error() ||
421 (thd->get_stmt_da()->sql_errno() != ER_CANT_REOPEN_TABLE &&
422 thd->get_stmt_da()->sql_errno() != ER_NO_SUCH_TABLE &&
423 thd->get_stmt_da()->sql_errno() != ER_UPDATE_TABLE_USED))
424 thd->stmt_arena->state= Query_arena::STMT_EXECUTED;
431 thd->transaction.stmt.add_unsafe_rollback_flags(parent_unsafe_rollback_flags);
447 return rc || thd->is_error();
451 LEX *sp_lex_instr::parse_expr(THD *thd,
sp_head *sp)
454 PSI_statement_locker *parent_locker= thd->m_statement_psi;
455 sql_query.set_charset(system_charset_info);
459 if (sql_query.length() == 0)
465 my_error(ER_UNKNOWN_ERROR, MYF(0));
473 free_root(&m_lex_mem_root, MYF(0));
474 init_sql_alloc(&m_lex_mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
482 MEM_ROOT *execution_mem_root= thd->mem_root;
483 Query_arena parse_arena(&m_lex_mem_root, thd->stmt_arena->state);
485 thd->mem_root= &m_lex_mem_root;
486 thd->stmt_arena->set_query_arena(&parse_arena);
491 Parser_state parser_state;
493 if (parser_state.init(thd, sql_query.c_ptr(), sql_query.length()))
499 Item *execution_free_list= thd->free_list;
500 thd->free_list= NULL;
504 LEX *lex_saved= thd->lex;
506 thd->lex=
new (thd->mem_root) st_lex_local;
509 thd->lex->sphead= sp;
510 thd->lex->set_sp_current_parsing_ctx(get_parsing_ctx());
511 sp->
m_parser_data.set_current_stmt_start_ptr(sql_query.c_ptr());
515 thd->m_statement_psi= NULL;
516 bool parsing_failed=
parse_sql(thd, &parser_state, NULL);
517 thd->m_statement_psi= parent_locker;
521 thd->lex->set_trg_event_type_for_tables();
523 if (sp->
m_type == SP_TYPE_TRIGGER)
541 trg_field= trg_field->next_trg_field)
543 trg_field->setup_field(thd, ttl->
trigger_table, grant_table);
554 free_list= thd->free_list;
559 thd->lex->sphead= NULL;
560 thd->lex->set_sp_current_parsing_ctx(NULL);
562 LEX *expr_lex= thd->lex;
567 thd->mem_root= execution_mem_root;
568 thd->free_list= execution_free_list;
572 return parsing_failed ? NULL : expr_lex;
581 int reprepare_attempt= 0;
587 LEX *lex= parse_expr(thd, thd->sp_runtime_ctx->sp);
594 m_first_execution=
true;
616 if (!m_first_execution &&
618 m_lex->sql_command == SQLCOM_END))
620 reprepare_observer.reset_reprepare_observer();
621 stmt_reprepare_observer= &reprepare_observer;
624 thd->push_reprepare_observer(stmt_reprepare_observer);
626 bool rc= reset_lex_and_exec_core(thd, nextp, open_tables);
628 thd->pop_reprepare_observer();
630 m_first_execution=
false;
647 if (stmt_reprepare_observer &&
648 !thd->is_fatal_error &&
650 thd->get_stmt_da()->sql_errno() == ER_NEED_REPREPARE &&
651 reprepare_attempt++ < 3)
653 DBUG_ASSERT(stmt_reprepare_observer->is_invalidated());
665 void sp_lex_instr::set_lex(LEX *lex,
bool is_lex_owner)
670 m_is_lex_owner= is_lex_owner;
671 m_lex_query_tables_own_last= NULL;
674 m_lex->sp_lex_in_use=
true;
678 void sp_lex_instr::free_lex()
680 if (!m_is_lex_owner || !m_lex)
686 delete (st_lex_local *) m_lex;
689 m_is_lex_owner=
false;
690 m_lex_query_tables_own_last= NULL;
711 sp_head *sp= thd->sp_runtime_ctx->sp;
713 if (sp->
m_type == SP_TYPE_TRIGGER)
724 sql_query->length(0);
728 sql_query->append(
"SELECT ");
729 sql_query->append(expr_query.str, expr_query.length);
740 bool need_subst=
false;
743 DBUG_PRINT(
"info", (
"query: '%.*s'", (
int) m_query.length, m_query.str));
747 #if defined(ENABLED_PROFILING)
749 thd->profiling.set_query_source(m_query.str, m_query.length);
782 need_subst= ((thd->variables.option_bits & OPTION_LOG_OFF) &&
783 (!(thd->variables.option_bits & OPTION_BIN_LOG) ||
784 !mysql_bin_log.is_open() ||
785 thd->is_current_stmt_binlog_format_row())) ? FALSE : TRUE;
791 if (need_subst && subst_spvars(thd,
this, &m_query))
798 if (unlikely((thd->variables.option_bits & OPTION_LOG_OFF)==0))
799 general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
801 if (query_cache_send_result_to_client(thd, thd->query(),
802 thd->query_length()) <= 0)
806 if (thd->get_stmt_da()->is_eof())
809 thd->update_server_status();
811 thd->protocol->end_statement();
814 query_cache_end_of_result(thd);
825 rc= subst_spvars(thd,
this, &m_query);
836 DBUG_ASSERT((thd->query_name_consts == 0) ||
837 (thd->rewritten_query.length() == 0));
840 *nextp= get_ip() + 1;
842 thd->set_query(query_backup);
843 thd->query_name_consts= 0;
845 if (!thd->is_error())
846 thd->get_stmt_da()->reset_diagnostics_area();
848 return rc || thd->is_error();
852 void sp_instr_stmt::print(
String *str)
855 if (str->reserve(SP_STMT_PRINT_MAXLEN + SP_INSTR_UINT_MAXLEN + 8))
857 str->qs_append(STRING_WITH_LEN(
"stmt"));
858 str->qs_append(STRING_WITH_LEN(
" \""));
864 uint len= m_query.length;
865 if (len > SP_STMT_PRINT_MAXLEN)
866 len= SP_STMT_PRINT_MAXLEN-3;
869 for (uint
i= 0 ;
i < len ;
i++)
871 char c= m_query.str[
i];
876 if (m_query.length > SP_STMT_PRINT_MAXLEN)
877 str->qs_append(STRING_WITH_LEN(
"..."));
884 MYSQL_QUERY_EXEC_START(thd->query(),
886 (
char *) (thd->db ? thd->db :
""),
887 &thd->security_ctx->priv_user[0],
888 (
char *)thd->security_ctx->host_or_ip,
891 thd->lex->set_sp_current_parsing_ctx(get_parsing_ctx());
892 thd->lex->sphead= thd->sp_runtime_ctx->sp;
894 PSI_statement_locker *statement_psi_saved= thd->m_statement_psi;
895 thd->m_statement_psi= NULL;
899 thd->lex->set_sp_current_parsing_ctx(NULL);
900 thd->lex->sphead= NULL;
901 thd->m_statement_psi= statement_psi_saved;
903 MYSQL_QUERY_EXEC_DONE(rc);
905 *nextp= get_ip() + 1;
918 *nextp= get_ip() + 1;
920 if (!thd->sp_runtime_ctx->set_variable(thd, m_offset, &m_value_item))
925 if (thd->sp_runtime_ctx->set_variable(thd, m_offset, 0))
928 my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
935 void sp_instr_set::print(
String *str)
938 int rsrv = SP_INSTR_UINT_MAXLEN+6;
943 rsrv+= var->
name.length;
944 if (str->reserve(rsrv))
946 str->qs_append(STRING_WITH_LEN(
"set "));
949 str->qs_append(var->
name.str, var->
name.length);
952 str->qs_append(m_offset);
954 m_value_item->
print(str, QT_ORDINARY);
965 *nextp= get_ip() + 1;
966 thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
967 return m_trigger_field->set_value(thd, &m_value_item);
971 void sp_instr_set_trigger_field::print(
String *str)
973 str->append(STRING_WITH_LEN(
"set_trigger_field "));
974 m_trigger_field->print(str, QT_ORDINARY);
975 str->append(STRING_WITH_LEN(
":="));
976 m_value_item->
print(str, QT_ORDINARY);
982 DBUG_ASSERT(thd->lex->select_lex.item_list.elements == 1);
984 m_value_item= thd->lex->select_lex.item_list.head();
986 DBUG_ASSERT(!m_trigger_field);
990 Item_trigger_field::NEW_ROW,
991 m_trigger_field_name.str,
995 return m_value_item == NULL || m_trigger_field == NULL;
1003 m_trigger_field= NULL;
1012 void sp_instr_jump::print(
String *str)
1015 if (str->reserve(SP_INSTR_UINT_MAXLEN+5))
1017 str->qs_append(STRING_WITH_LEN(
"jump "));
1025 if (
m_dest != get_ip() + 1)
1041 if (start == i ||
this == i)
1055 bp->push_back(
this);
1057 m_dest= m_optdest->get_ip();
1082 void sp_instr_jump_if_not::print(
String *str)
1085 if (str->reserve(2*SP_INSTR_UINT_MAXLEN+14+32))
1087 str->qs_append(STRING_WITH_LEN(
"jump_if_not "));
1089 str->qs_append(
'(');
1091 str->qs_append(STRING_WITH_LEN(
") "));
1125 return get_ip() + 1;
1140 bp->push_back(
this);
1142 else if (m_cont_optdest)
1147 bp->push_back(
this);
1149 m_dest= m_optdest->get_ip();
1161 DBUG_ASSERT(m_eq_item);
1163 Item *item= sp_prepare_func_item(thd, &m_eq_item);
1174 void sp_instr_jump_case_when::print(
String *str)
1177 if (str->reserve(2*SP_INSTR_UINT_MAXLEN+14+32))
1179 str->qs_append(STRING_WITH_LEN(
"jump_if_not_case_when "));
1181 str->qs_append(
'(');
1183 str->qs_append(STRING_WITH_LEN(
") "));
1184 m_eq_item->
print(str, QT_ORDINARY);
1188 bool sp_instr_jump_case_when::build_expr_items(THD *thd)
1194 if (!m_case_expr_item)
1198 m_case_expr_item->m_sp= thd->lex->sphead;
1215 DBUG_ASSERT(thd->lex->select_lex.item_list.elements == 1);
1217 m_expr_item= thd->lex->select_lex.item_list.head();
1244 da->clear_warning_info(da->warning_info_id());
1261 return thd->sp_runtime_ctx->set_return_value(thd, &m_expr_item);
1265 void sp_instr_freturn::print(
String *str)
1268 if (str->reserve(1024+8+32))
1270 str->qs_append(STRING_WITH_LEN(
"freturn "));
1271 str->qs_append((uint) m_return_field_type);
1272 str->qs_append(
' ');
1273 m_expr_item->
print(str, QT_ORDINARY);
1286 return thd->sp_runtime_ctx->push_handler(m_handler, get_ip() + 1);
1290 void sp_instr_hpush_jump::print(
String *str)
1293 if (str->reserve(SP_INSTR_UINT_MAXLEN*2 + 21))
1296 str->qs_append(STRING_WITH_LEN(
"hpush_jump "));
1298 str->qs_append(
' ');
1299 str->qs_append(m_frame);
1301 switch (m_handler->
type) {
1302 case sp_handler::EXIT:
1303 str->qs_append(STRING_WITH_LEN(
" EXIT"));
1305 case sp_handler::CONTINUE:
1306 str->qs_append(STRING_WITH_LEN(
" CONTINUE"));
1339 if (m_handler->
type == sp_handler::CONTINUE)
1341 for (uint scope_ip=
m_dest+1; scope_ip <= m_opt_hpop; scope_ip++)
1345 return get_ip() + 1;
1357 *nextp= get_ip() + 1;
1374 thd->get_stmt_da()->remove_marked_sql_conditions();
1397 void sp_instr_hreturn::print(
String *str)
1400 if (str->reserve(SP_INSTR_UINT_MAXLEN*2 + 9))
1402 str->qs_append(STRING_WITH_LEN(
"hreturn "));
1407 str->qs_append(STRING_WITH_LEN(
"0 "));
1412 str->qs_append(m_frame);
1444 *nextp= get_ip() + 1;
1448 return thd->sp_runtime_ctx->push_cursor(
this);
1454 sp_cursor *c= thd->sp_runtime_ctx->get_cursor(m_cursor_idx);
1459 return c ? c->
open(thd) :
true;
1463 void sp_instr_cpush::print(
String *str)
1467 uint rsrv= SP_INSTR_UINT_MAXLEN + 7 + m_cursor_query.length + 1;
1470 rsrv+= cursor_name->length;
1471 if (str->reserve(rsrv))
1473 str->qs_append(STRING_WITH_LEN(
"cpush "));
1476 str->qs_append(cursor_name->str, cursor_name->length);
1477 str->qs_append(
'@');
1479 str->qs_append(m_cursor_idx);
1481 str->qs_append(
':');
1482 str->qs_append(m_cursor_query.str, m_cursor_query.length);
1493 thd->sp_runtime_ctx->pop_cursors(m_count);
1494 *nextp= get_ip() + 1;
1500 void sp_instr_cpop::print(
String *str)
1503 if (str->reserve(SP_INSTR_UINT_MAXLEN+5))
1505 str->qs_append(STRING_WITH_LEN(
"cpop "));
1506 str->qs_append(m_count);
1517 *nextp= get_ip() + 1;
1521 sp_cursor *c= thd->sp_runtime_ctx->get_cursor(m_cursor_idx);
1534 Query_arena *stmt_arena_saved= thd->stmt_arena;
1535 thd->stmt_arena= push_instr;
1546 if (push_instr->free_list)
1551 thd->stmt_arena= stmt_arena_saved;
1557 void sp_instr_copen::print(
String *str)
1562 uint rsrv= SP_INSTR_UINT_MAXLEN+7;
1565 rsrv+= cursor_name->length;
1566 if (str->reserve(rsrv))
1568 str->qs_append(STRING_WITH_LEN(
"copen "));
1571 str->qs_append(cursor_name->str, cursor_name->length);
1572 str->qs_append(
'@');
1574 str->qs_append(m_cursor_idx);
1585 *nextp= get_ip() + 1;
1587 sp_cursor *c= thd->sp_runtime_ctx->get_cursor(m_cursor_idx);
1589 return c ? c->close(thd) :
true;
1593 void sp_instr_cclose::print(
String *str)
1598 uint rsrv= SP_INSTR_UINT_MAXLEN+8;
1601 rsrv+= cursor_name->length;
1602 if (str->reserve(rsrv))
1604 str->qs_append(STRING_WITH_LEN(
"cclose "));
1607 str->qs_append(cursor_name->str, cursor_name->length);
1608 str->qs_append(
'@');
1610 str->qs_append(m_cursor_idx);
1621 *nextp= get_ip() + 1;
1623 sp_cursor *c= thd->sp_runtime_ctx->get_cursor(m_cursor_idx);
1625 return c ? c->fetch(thd, &m_varlist) :
true;
1629 void sp_instr_cfetch::print(
String *str)
1636 uint rsrv= SP_INSTR_UINT_MAXLEN+8;
1639 rsrv+= cursor_name->length;
1640 if (str->reserve(rsrv))
1642 str->qs_append(STRING_WITH_LEN(
"cfetch "));
1645 str->qs_append(cursor_name->str, cursor_name->length);
1646 str->qs_append(
'@');
1648 str->qs_append(m_cursor_idx);
1651 if (str->reserve(pv->
name.length+SP_INSTR_UINT_MAXLEN+2))
1653 str->qs_append(
' ');
1654 str->qs_append(pv->
name.str, pv->
name.length);
1655 str->qs_append(
'@');
1656 str->qs_append(pv->
offset);
1666 void sp_instr_error::print(
String *str)
1669 if (str->reserve(SP_INSTR_UINT_MAXLEN+6))
1671 str->qs_append(STRING_WITH_LEN(
"error "));
1672 str->qs_append(m_errcode);
1683 *nextp= get_ip() + 1;
1688 !rctx->get_case_expr(m_case_expr_id))
1695 if (!null_item || rctx->
set_case_expr(thd, m_case_expr_id, &null_item))
1698 my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
1708 void sp_instr_set_case_expr::print(
String *str)
1711 str->reserve(2*SP_INSTR_UINT_MAXLEN+18+32);
1712 str->qs_append(STRING_WITH_LEN(
"set_case_expr ("));
1714 str->qs_append(STRING_WITH_LEN(
") "));
1715 str->qs_append(m_case_expr_id);
1716 str->qs_append(
' ');
1734 return get_ip() + 1;
1741 bp->push_back(
this);
1742 else if (m_cont_optdest)