MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sql_class.cc
1 /*
2  Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
3 
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.
7 
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.
12 
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
16 */
17 
18 
19 /*****************************************************************************
20 **
21 ** This file implements classes defined in sql_class.h
22 ** Especially the classes to handle a result from a select
23 **
24 *****************************************************************************/
25 
26 #include "my_global.h" /* NO_EMBEDDED_ACCESS_CHECKS */
27 #include "binlog.h"
28 #include "sql_priv.h"
29 #include "unireg.h" // REQUIRED: for other includes
30 #include "sql_class.h"
31 #include "sql_cache.h" // query_cache_abort
32 #include "sql_base.h" // close_thread_tables
33 #include "sql_time.h" // date_time_format_copy
34 #include "sql_acl.h" // NO_ACCESS,
35  // acl_getroot_no_password
36 #include "sql_base.h" // close_temporary_tables
37 #include "sql_handler.h" // mysql_ha_cleanup
38 #include "rpl_rli.h"
39 #include "rpl_filter.h"
40 #include "rpl_record.h"
41 #include "rpl_slave.h"
42 #include <my_bitmap.h>
43 #include "log_event.h"
44 #include "sql_audit.h"
45 #include <m_ctype.h>
46 #include <sys/stat.h>
47 #include <thr_alarm.h>
48 #ifdef __WIN__
49 #include <io.h>
50 #endif
51 #include <mysys_err.h>
52 #include <limits.h>
53 
54 #include "sp_rcontext.h"
55 #include "sp_cache.h"
56 #include "transaction.h"
57 #include "debug_sync.h"
58 #include "sql_parse.h" // is_update_query
59 #include "sql_callback.h"
60 #include "lock.h"
61 #include "global_threads.h"
62 #include "mysqld.h"
63 
65 
66 using std::min;
67 using std::max;
68 
69 /*
70  The following is used to initialise Table_ident with a internal
71  table name
72 */
73 char internal_table_name[2]= "*";
74 char empty_c_string[1]= {0}; /* used for not defined db */
75 
76 LEX_STRING EMPTY_STR= { (char *) "", 0 };
77 LEX_STRING NULL_STR= { NULL, 0 };
78 
79 const char * const THD::DEFAULT_WHERE= "field list";
80 
81 /****************************************************************************
82 ** User variables
83 ****************************************************************************/
84 
85 extern "C" uchar *get_var_key(user_var_entry *entry, size_t *length,
86  my_bool not_used __attribute__((unused)))
87 {
88  *length= entry->entry_name.length();
89  return (uchar*) entry->entry_name.ptr();
90 }
91 
92 extern "C" void free_user_var(user_var_entry *entry)
93 {
94  entry->destroy();
95 }
96 
97 bool Key_part_spec::operator==(const Key_part_spec& other) const
98 {
99  return length == other.length &&
100  !my_strcasecmp(system_charset_info, field_name.str,
101  other.field_name.str);
102 }
103 
111 Key::Key(const Key &rhs, MEM_ROOT *mem_root)
112  :type(rhs.type),
113  key_create_info(rhs.key_create_info),
114  columns(rhs.columns, mem_root),
115  name(rhs.name),
116  generated(rhs.generated)
117 {
118  list_copy_and_replace_each_value(columns, mem_root);
119 }
120 
128 Foreign_key::Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root)
129  :Key(rhs, mem_root),
130  ref_db(rhs.ref_db),
131  ref_table(rhs.ref_table),
132  ref_columns(rhs.ref_columns, mem_root),
133  delete_opt(rhs.delete_opt),
134  update_opt(rhs.update_opt),
135  match_opt(rhs.match_opt)
136 {
137  list_copy_and_replace_each_value(ref_columns, mem_root);
138 }
139 
140 /*
141  Test if a foreign key (= generated key) is a prefix of the given key
142  (ignoring key name, key type and order of columns)
143 
144  NOTES:
145  This is only used to test if an index for a FOREIGN KEY exists
146 
147  IMPLEMENTATION
148  We only compare field names
149 
150  RETURN
151  0 Generated key is a prefix of other key
152  1 Not equal
153 */
154 
155 bool foreign_key_prefix(Key *a, Key *b)
156 {
157  /* Ensure that 'a' is the generated key */
158  if (a->generated)
159  {
160  if (b->generated && a->columns.elements > b->columns.elements)
161  swap_variables(Key*, a, b); // Put shorter key in 'a'
162  }
163  else
164  {
165  if (!b->generated)
166  return TRUE; // No foreign key
167  swap_variables(Key*, a, b); // Put generated key in 'a'
168  }
169 
170  /* Test if 'a' is a prefix of 'b' */
171  if (a->columns.elements > b->columns.elements)
172  return TRUE; // Can't be prefix
173 
174  List_iterator<Key_part_spec> col_it1(a->columns);
175  List_iterator<Key_part_spec> col_it2(b->columns);
176  const Key_part_spec *col1, *col2;
177 
178 #ifdef ENABLE_WHEN_INNODB_CAN_HANDLE_SWAPED_FOREIGN_KEY_COLUMNS
179  while ((col1= col_it1++))
180  {
181  bool found= 0;
182  col_it2.rewind();
183  while ((col2= col_it2++))
184  {
185  if (*col1 == *col2)
186  {
187  found= TRUE;
188  break;
189  }
190  }
191  if (!found)
192  return TRUE; // Error
193  }
194  return FALSE; // Is prefix
195 #else
196  while ((col1= col_it1++))
197  {
198  col2= col_it2++;
199  if (!(*col1 == *col2))
200  return TRUE;
201  }
202  return FALSE; // Is prefix
203 #endif
204 }
205 
206 
207 /****************************************************************************
208 ** Thread specific functions
209 ****************************************************************************/
210 
218 void *thd_get_scheduler_data(THD *thd)
219 {
220  return thd->scheduler.data;
221 }
222 
229 void thd_set_scheduler_data(THD *thd, void *data)
230 {
231  thd->scheduler.data= data;
232 }
233 
241 PSI_thread *thd_get_psi(THD *thd)
242 {
243  return thd->scheduler.m_psi;
244 }
245 
253 ulong thd_get_net_wait_timeout(THD* thd)
254 {
255  return thd->variables.net_wait_timeout;
256 }
257 
264 void thd_set_psi(THD *thd, PSI_thread *psi)
265 {
266  thd->scheduler.m_psi= psi;
267 }
268 
274 void thd_set_killed(THD *thd)
275 {
276  thd->killed= THD::KILL_CONNECTION;
277 }
278 
284 void thd_clear_errors(THD *thd)
285 {
286  my_errno= 0;
287  thd->mysys_var->abort= 0;
288 }
289 
296 void thd_set_thread_stack(THD *thd, char *stack_start)
297 {
298  thd->thread_stack= stack_start;
299 }
300 
307 void thd_lock_thread_count(THD *)
308 {
309  mysql_mutex_lock(&LOCK_thread_count);
310 }
311 
318 void thd_unlock_thread_count(THD *)
319 {
320  mysql_cond_broadcast(&COND_thread_count);
321  mysql_mutex_unlock(&LOCK_thread_count);
322 }
323 
329 void thd_close_connection(THD *thd)
330 {
331  if (thd->net.vio)
332  vio_shutdown(thd->net.vio);
333 }
334 
340 THD *thd_get_current_thd()
341 {
342  return current_thd;
343 }
344 
350 Thread_iterator thd_get_global_thread_list_begin()
351 {
352  return global_thread_list_begin();
353 }
359 Thread_iterator thd_get_global_thread_list_end()
360 {
361  return global_thread_list_end();
362 }
363 
364 extern "C"
365 void thd_binlog_pos(const THD *thd,
366  const char **file_var,
367  unsigned long long *pos_var)
368 {
369  thd->get_trans_pos(file_var, pos_var);
370 }
371 
382 void thd_new_connection_setup(THD *thd, char *stack_start)
383 {
384  DBUG_ENTER("thd_new_connection_setup");
385  mysql_mutex_assert_owner(&LOCK_thread_count);
386 #ifdef HAVE_PSI_INTERFACE
387  thd_set_psi(thd,
388  PSI_THREAD_CALL(new_thread)
389  (key_thread_one_connection, thd, thd->thread_id));
390 #endif
391  thd->set_time();
392  thd->prior_thr_create_utime= thd->thr_create_utime= thd->start_utime=
393  my_micro_time();
394 
395  add_global_thread(thd);
396  mysql_mutex_unlock(&LOCK_thread_count);
397 
398  DBUG_PRINT("info", ("init new connection. thd: 0x%lx fd: %d",
399  (ulong)thd, mysql_socket_getfd(thd->net.vio->mysql_socket)));
400  thd_set_thread_stack(thd, stack_start);
401  DBUG_VOID_RETURN;
402 }
403 
409 void thd_lock_data(THD *thd)
410 {
411  mysql_mutex_lock(&thd->LOCK_thd_data);
412 }
413 
419 void thd_unlock_data(THD *thd)
420 {
421  mysql_mutex_unlock(&thd->LOCK_thd_data);
422 }
423 
431 bool thd_is_transaction_active(THD *thd)
432 {
433  return thd->transaction.is_active();
434 }
435 
441 int thd_connection_has_data(THD *thd)
442 {
443  Vio *vio= thd->net.vio;
444  return vio->has_data(vio);
445 }
446 
453 void thd_set_net_read_write(THD *thd, uint val)
454 {
455  thd->net.reading_or_writing= val;
456 }
457 
464 uint thd_get_net_read_write(THD *thd)
465 {
466  return thd->net.reading_or_writing;
467 }
468 
475 void thd_set_mysys_var(THD *thd, st_my_thread_var *mysys_var)
476 {
477  thd->set_mysys_var(mysys_var);
478 }
479 
487 my_socket thd_get_fd(THD *thd)
488 {
489  return mysql_socket_getfd(thd->net.vio->mysql_socket);
490 }
491 
499 int thd_store_globals(THD* thd)
500 {
501  return thd->store_globals();
502 }
503 
509 pthread_attr_t *get_connection_attrib(void)
510 {
511  return &connection_attrib;
512 }
513 
519 ulong get_max_connections(void)
520 {
521  return max_connections;
522 }
523 
524 /*
525  The following functions form part of the C plugin API
526 */
527 
528 extern "C" int mysql_tmpfile(const char *prefix)
529 {
530  char filename[FN_REFLEN];
531  File fd = create_temp_file(filename, mysql_tmpdir, prefix,
532 #ifdef __WIN__
533  O_BINARY | O_TRUNC | O_SEQUENTIAL |
534  O_SHORT_LIVED |
535 #endif /* __WIN__ */
536  O_CREAT | O_EXCL | O_RDWR | O_TEMPORARY,
537  MYF(MY_WME));
538  if (fd >= 0) {
539 #ifndef __WIN__
540  /*
541  This can be removed once the following bug is fixed:
542  Bug #28903 create_temp_file() doesn't honor O_TEMPORARY option
543  (file not removed) (Unix)
544  */
545  unlink(filename);
546 #endif /* !__WIN__ */
547  }
548 
549  return fd;
550 }
551 
552 
553 extern "C"
554 int thd_in_lock_tables(const THD *thd)
555 {
556  return test(thd->in_lock_tables);
557 }
558 
559 
560 extern "C"
561 int thd_tablespace_op(const THD *thd)
562 {
563  return test(thd->tablespace_op);
564 }
565 
566 
567 extern "C"
568 const char *set_thd_proc_info(void *thd_arg, const char *info,
569  const char *calling_function,
570  const char *calling_file,
571  const unsigned int calling_line)
572 {
573  PSI_stage_info old_stage;
574  PSI_stage_info new_stage;
575 
576  old_stage.m_key= 0;
577  old_stage.m_name= info;
578 
579  set_thd_stage_info(thd_arg, & old_stage, & new_stage,
580  calling_function, calling_file, calling_line);
581 
582  return new_stage.m_name;
583 }
584 
585 extern "C"
586 void set_thd_stage_info(void *opaque_thd,
587  const PSI_stage_info *new_stage,
588  PSI_stage_info *old_stage,
589  const char *calling_func,
590  const char *calling_file,
591  const unsigned int calling_line)
592 {
593  THD *thd= (THD*) opaque_thd;
594  if (thd == NULL)
595  thd= current_thd;
596 
597  thd->enter_stage(new_stage, old_stage, calling_func, calling_file, calling_line);
598 }
599 
600 void THD::enter_stage(const PSI_stage_info *new_stage,
601  PSI_stage_info *old_stage,
602  const char *calling_func,
603  const char *calling_file,
604  const unsigned int calling_line)
605 {
606  DBUG_PRINT("THD::enter_stage", ("%s:%d", calling_file, calling_line));
607 
608  if (old_stage != NULL)
609  {
610  old_stage->m_key= m_current_stage_key;
611  old_stage->m_name= proc_info;
612  }
613 
614  if (new_stage != NULL)
615  {
616  const char *msg= new_stage->m_name;
617 
618 #if defined(ENABLED_PROFILING)
619  profiling.status_change(msg, calling_func, calling_file, calling_line);
620 #endif
621 
622  m_current_stage_key= new_stage->m_key;
623  proc_info= msg;
624 
625  MYSQL_SET_STAGE(m_current_stage_key, calling_file, calling_line);
626  }
627  return;
628 }
629 
630 extern "C"
631 void thd_enter_cond(MYSQL_THD thd, mysql_cond_t *cond, mysql_mutex_t *mutex,
632  const PSI_stage_info *stage, PSI_stage_info *old_stage)
633 {
634  if (!thd)
635  thd= current_thd;
636 
637  return thd->ENTER_COND(cond, mutex, stage, old_stage);
638 }
639 
640 extern "C"
641 void thd_exit_cond(MYSQL_THD thd, const PSI_stage_info *stage)
642 {
643  if (!thd)
644  thd= current_thd;
645 
646  thd->EXIT_COND(stage);
647  return;
648 }
649 
650 extern "C"
651 void **thd_ha_data(const THD *thd, const struct handlerton *hton)
652 {
653  return (void **) &thd->ha_data[hton->slot].ha_ptr;
654 }
655 
656 extern "C"
657 void thd_storage_lock_wait(THD *thd, long long value)
658 {
659  thd->utime_after_lock+= value;
660 }
661 
665 extern "C"
666 void *thd_get_ha_data(const THD *thd, const struct handlerton *hton)
667 {
668  return *thd_ha_data(thd, hton);
669 }
670 
671 
676 extern "C"
677 void thd_set_ha_data(THD *thd, const struct handlerton *hton,
678  const void *ha_data)
679 {
680  plugin_ref *lock= &thd->ha_data[hton->slot].lock;
681  if (ha_data && !*lock)
682  *lock= ha_lock_engine(NULL, (handlerton*) hton);
683  else if (!ha_data && *lock)
684  {
685  plugin_unlock(NULL, *lock);
686  *lock= NULL;
687  }
688  *thd_ha_data(thd, hton)= (void*) ha_data;
689 }
690 
691 
692 extern "C"
693 long long thd_test_options(const THD *thd, long long test_options)
694 {
695  return thd->variables.option_bits & test_options;
696 }
697 
698 extern "C"
699 int thd_sql_command(const THD *thd)
700 {
701  return (int) thd->lex->sql_command;
702 }
703 
704 extern "C"
705 int thd_tx_isolation(const THD *thd)
706 {
707  return (int) thd->tx_isolation;
708 }
709 
710 extern "C"
711 int thd_tx_is_read_only(const THD *thd)
712 {
713  return (int) thd->tx_read_only;
714 }
715 
716 extern "C"
717 void thd_inc_row_count(THD *thd)
718 {
719  thd->get_stmt_da()->inc_current_row_for_warning();
720 }
721 
722 
741 extern "C"
742 char *thd_security_context(THD *thd, char *buffer, unsigned int length,
743  unsigned int max_query_len)
744 {
745  String str(buffer, length, &my_charset_latin1);
746  Security_context *sctx= &thd->main_security_ctx;
747  char header[256];
748  int len;
749  /*
750  The pointers thd->query and thd->proc_info might change since they are
751  being modified concurrently. This is acceptable for proc_info since its
752  values doesn't have to very accurate and the memory it points to is static,
753  but we need to attempt a snapshot on the pointer values to avoid using NULL
754  values. The pointer to thd->query however, doesn't point to static memory
755  and has to be protected by LOCK_thread_count or risk pointing to
756  uninitialized memory.
757  */
758  const char *proc_info= thd->proc_info;
759 
760  len= my_snprintf(header, sizeof(header),
761  "MySQL thread id %lu, OS thread handle 0x%lx, query id %lu",
762  thd->thread_id, (ulong) thd->real_id, (ulong) thd->query_id);
763  str.length(0);
764  str.append(header, len);
765 
766  if (sctx->get_host()->length())
767  {
768  str.append(' ');
769  str.append(sctx->get_host()->ptr());
770  }
771 
772  if (sctx->get_ip()->length())
773  {
774  str.append(' ');
775  str.append(sctx->get_ip()->ptr());
776  }
777 
778  if (sctx->user)
779  {
780  str.append(' ');
781  str.append(sctx->user);
782  }
783 
784  if (proc_info)
785  {
786  str.append(' ');
787  str.append(proc_info);
788  }
789 
790  mysql_mutex_lock(&thd->LOCK_thd_data);
791 
792  if (thd->query())
793  {
794  if (max_query_len < 1)
795  len= thd->query_length();
796  else
797  len= min(thd->query_length(), max_query_len);
798  str.append('\n');
799  str.append(thd->query(), len);
800  }
801 
802  mysql_mutex_unlock(&thd->LOCK_thd_data);
803 
804  if (str.c_ptr_safe() == buffer)
805  return buffer;
806 
807  /*
808  We have to copy the new string to the destination buffer because the string
809  was reallocated to a larger buffer to be able to fit.
810  */
811  DBUG_ASSERT(buffer != NULL);
812  length= min(str.length(), length-1);
813  memcpy(buffer, str.c_ptr_quick(), length);
814  /* Make sure that the new string is null terminated */
815  buffer[length]= '\0';
816  return buffer;
817 }
818 
819 
834 bool Drop_table_error_handler::handle_condition(THD *thd,
835  uint sql_errno,
836  const char* sqlstate,
837  Sql_condition::enum_warning_level level,
838  const char* msg,
839  Sql_condition ** cond_hdl)
840 {
841  *cond_hdl= NULL;
842  return ((sql_errno == EE_DELETE && my_errno == ENOENT) ||
843  sql_errno == ER_TRG_NO_DEFINER);
844 }
845 
846 
847 void Open_tables_state::set_open_tables_state(Open_tables_state *state)
848 {
849  this->open_tables= state->open_tables;
850 
851  this->temporary_tables= state->temporary_tables;
852  this->derived_tables= state->derived_tables;
853 
854  this->lock= state->lock;
855  this->extra_lock= state->extra_lock;
856 
857  this->locked_tables_mode= state->locked_tables_mode;
858  this->current_tablenr= state->current_tablenr;
859 
860  this->state_flags= state->state_flags;
861 
862  this->reset_reprepare_observers();
863  for (int i= 0; i < state->m_reprepare_observers.elements(); ++i)
864  this->push_reprepare_observer(state->m_reprepare_observers.at(i));
865 }
866 
867 
868 void Open_tables_state::reset_open_tables_state()
869 {
870  open_tables= NULL;
871  temporary_tables= NULL;
872  derived_tables= NULL;
873  lock= NULL;
874  extra_lock= NULL;
875  locked_tables_mode= LTM_NONE;
876  // JOH: What about resetting current_tablenr?
877  state_flags= 0U;
878  reset_reprepare_observers();
879 }
880 
881 
882 THD::THD(bool enable_plugins)
883  :Statement(&main_lex, &main_mem_root, STMT_CONVENTIONAL_EXECUTION,
884  /* statement id */ 0),
885  rli_fake(0), rli_slave(NULL),
886  in_sub_stmt(0),
887  fill_status_recursion_level(0),
888  binlog_row_event_extra_data(NULL),
889  binlog_unsafe_warning_flags(0),
890  binlog_table_maps(0),
891  binlog_accessed_db_names(NULL),
892  m_trans_log_file(NULL),
893  m_trans_fixed_log_file(NULL),
894  m_trans_end_pos(0),
895  table_map_for_update(0),
896  arg_of_last_insert_id_function(FALSE),
897  first_successful_insert_id_in_prev_stmt(0),
898  first_successful_insert_id_in_prev_stmt_for_binlog(0),
899  first_successful_insert_id_in_cur_stmt(0),
900  stmt_depends_on_first_successful_insert_id_in_prev_stmt(FALSE),
901  m_examined_row_count(0),
902  m_statement_psi(NULL),
903  m_idle_psi(NULL),
904  m_server_idle(false),
905  next_to_commit(NULL),
906  is_fatal_error(0),
907  transaction_rollback_request(0),
908  is_fatal_sub_stmt_error(0),
909  rand_used(0),
910  time_zone_used(0),
911  in_lock_tables(0),
912  bootstrap(0),
913  derived_tables_processing(FALSE),
914  sp_runtime_ctx(NULL),
915  m_parser_state(NULL),
916 #if defined(ENABLED_DEBUG_SYNC)
917  debug_sync_control(0),
918 #endif /* defined(ENABLED_DEBUG_SYNC) */
919  m_enable_plugins(enable_plugins),
920  owned_gtid_set(global_sid_map),
921  main_da(0, false),
922  m_stmt_da(&main_da)
923 {
924  ulong tmp;
925 
926  mdl_context.init(this);
927  /*
928  Pass nominal parameters to init_alloc_root only to ensure that
929  the destructor works OK in case of an error. The main_mem_root
930  will be re-initialized in init_for_queries().
931  */
932  init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
933  stmt_arena= this;
934  thread_stack= 0;
935  catalog= (char*)"std"; // the only catalog we have for now
936  main_security_ctx.init();
937  security_ctx= &main_security_ctx;
938  no_errors= 0;
939  password= 0;
940  query_start_used= query_start_usec_used= 0;
941  count_cuted_fields= CHECK_FIELD_IGNORE;
942  killed= NOT_KILLED;
943  col_access=0;
944  is_slave_error= thread_specific_used= FALSE;
945  my_hash_clear(&handler_tables_hash);
946  tmp_table=0;
947  cuted_fields= 0L;
948  m_sent_row_count= 0L;
949  limit_found_rows= 0;
950  m_row_count_func= -1;
951  statement_id_counter= 0UL;
952  // Must be reset to handle error with THD's created for init of mysqld
953  lex->current_select= 0;
954  user_time.tv_sec= 0;
955  user_time.tv_usec= 0;
956  start_time.tv_sec= 0;
957  start_time.tv_usec= 0;
958  start_utime= prior_thr_create_utime= 0L;
959  utime_after_lock= 0L;
960  current_linfo = 0;
961  slave_thread = 0;
962  memset(&variables, 0, sizeof(variables));
963  thread_id= 0;
964  one_shot_set= 0;
965  file_id = 0;
966  query_id= 0;
967  query_name_consts= 0;
968  db_charset= global_system_variables.collation_database;
969  memset(ha_data, 0, sizeof(ha_data));
970  mysys_var=0;
971  binlog_evt_union.do_union= FALSE;
972  enable_slow_log= 0;
973  commit_error= CE_NONE;
974  durability_property= HA_REGULAR_DURABILITY;
975 #ifndef DBUG_OFF
976  dbug_sentry=THD_SENTRY_MAGIC;
977 #endif
978 #ifndef EMBEDDED_LIBRARY
979  mysql_audit_init_thd(this);
980  net.vio=0;
981 #endif
982  client_capabilities= 0; // minimalistic client
983  ull=0;
984  system_thread= NON_SYSTEM_THREAD;
985  cleanup_done= abort_on_warning= 0;
986  m_release_resources_done= false;
987  peer_port= 0; // For SHOW PROCESSLIST
988  transaction.m_pending_rows_event= 0;
989  transaction.flags.enabled= true;
990 #ifdef SIGNAL_WITH_VIO_SHUTDOWN
991  active_vio = 0;
992 #endif
993  mysql_mutex_init(key_LOCK_thd_data, &LOCK_thd_data, MY_MUTEX_INIT_FAST);
994 
995  /* Variables with default values */
996  proc_info="login";
997  where= THD::DEFAULT_WHERE;
998  server_id = ::server_id;
999  unmasked_server_id = server_id;
1000  slave_net = 0;
1001  set_command(COM_CONNECT);
1002  *scramble= '\0';
1003 
1004  /* Call to init() below requires fully initialized Open_tables_state. */
1005  reset_open_tables_state();
1006 
1007  init();
1008 #if defined(ENABLED_PROFILING)
1009  profiling.set_thd(this);
1010 #endif
1011  m_user_connect= NULL;
1012  my_hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
1013  (my_hash_get_key) get_var_key,
1014  (my_hash_free_key) free_user_var, 0);
1015 
1016  sp_proc_cache= NULL;
1017  sp_func_cache= NULL;
1018 
1019  /* For user vars replication*/
1020  if (opt_bin_log)
1021  my_init_dynamic_array(&user_var_events,
1022  sizeof(BINLOG_USER_VAR_EVENT *), 16, 16);
1023  else
1024  memset(&user_var_events, 0, sizeof(user_var_events));
1025 
1026  /* Protocol */
1027  protocol= &protocol_text; // Default protocol
1028  protocol_text.init(this);
1029  protocol_binary.init(this);
1030 
1031  tablespace_op=FALSE;
1032  tmp= sql_rnd_with_mutex();
1033  randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id);
1034  substitute_null_with_insert_id = FALSE;
1035  thr_lock_info_init(&lock_info); /* safety: will be reset after start */
1036 
1037  m_internal_handler= NULL;
1038  m_binlog_invoker= FALSE;
1039  memset(&invoker_user, 0, sizeof(invoker_user));
1040  memset(&invoker_host, 0, sizeof(invoker_host));
1041 
1042  binlog_next_event_pos.file_name= NULL;
1043  binlog_next_event_pos.pos= 0;
1044 #ifndef DBUG_OFF
1045  gis_debug= 0;
1046 #endif
1047 }
1048 
1049 
1050 void THD::push_internal_handler(Internal_error_handler *handler)
1051 {
1052  if (m_internal_handler)
1053  {
1054  handler->m_prev_internal_handler= m_internal_handler;
1055  m_internal_handler= handler;
1056  }
1057  else
1058  {
1059  m_internal_handler= handler;
1060  }
1061 }
1062 
1063 bool THD::handle_condition(uint sql_errno,
1064  const char* sqlstate,
1065  Sql_condition::enum_warning_level level,
1066  const char* msg,
1067  Sql_condition ** cond_hdl)
1068 {
1069  if (!m_internal_handler)
1070  {
1071  *cond_hdl= NULL;
1072  return FALSE;
1073  }
1074 
1075  for (Internal_error_handler *error_handler= m_internal_handler;
1076  error_handler;
1077  error_handler= error_handler->m_prev_internal_handler)
1078  {
1079  if (error_handler->handle_condition(this, sql_errno, sqlstate, level, msg,
1080  cond_hdl))
1081  {
1082  return TRUE;
1083  }
1084  }
1085 
1086  return FALSE;
1087 }
1088 
1089 
1090 Internal_error_handler *THD::pop_internal_handler()
1091 {
1092  DBUG_ASSERT(m_internal_handler != NULL);
1093  Internal_error_handler *popped_handler= m_internal_handler;
1094  m_internal_handler= m_internal_handler->m_prev_internal_handler;
1095  return popped_handler;
1096 }
1097 
1098 
1099 void THD::raise_error(uint sql_errno)
1100 {
1101  const char* msg= ER(sql_errno);
1102  (void) raise_condition(sql_errno,
1103  NULL,
1104  Sql_condition::WARN_LEVEL_ERROR,
1105  msg);
1106 }
1107 
1108 void THD::raise_error_printf(uint sql_errno, ...)
1109 {
1110  va_list args;
1111  char ebuff[MYSQL_ERRMSG_SIZE];
1112  DBUG_ENTER("THD::raise_error_printf");
1113  DBUG_PRINT("my", ("nr: %d errno: %d", sql_errno, errno));
1114  const char* format= ER(sql_errno);
1115  va_start(args, sql_errno);
1116  my_vsnprintf(ebuff, sizeof(ebuff), format, args);
1117  va_end(args);
1118  (void) raise_condition(sql_errno,
1119  NULL,
1120  Sql_condition::WARN_LEVEL_ERROR,
1121  ebuff);
1122  DBUG_VOID_RETURN;
1123 }
1124 
1125 void THD::raise_warning(uint sql_errno)
1126 {
1127  const char* msg= ER(sql_errno);
1128  (void) raise_condition(sql_errno,
1129  NULL,
1130  Sql_condition::WARN_LEVEL_WARN,
1131  msg);
1132 }
1133 
1134 void THD::raise_warning_printf(uint sql_errno, ...)
1135 {
1136  va_list args;
1137  char ebuff[MYSQL_ERRMSG_SIZE];
1138  DBUG_ENTER("THD::raise_warning_printf");
1139  DBUG_PRINT("enter", ("warning: %u", sql_errno));
1140  const char* format= ER(sql_errno);
1141  va_start(args, sql_errno);
1142  my_vsnprintf(ebuff, sizeof(ebuff), format, args);
1143  va_end(args);
1144  (void) raise_condition(sql_errno,
1145  NULL,
1146  Sql_condition::WARN_LEVEL_WARN,
1147  ebuff);
1148  DBUG_VOID_RETURN;
1149 }
1150 
1151 void THD::raise_note(uint sql_errno)
1152 {
1153  DBUG_ENTER("THD::raise_note");
1154  DBUG_PRINT("enter", ("code: %d", sql_errno));
1155  if (!(variables.option_bits & OPTION_SQL_NOTES))
1156  DBUG_VOID_RETURN;
1157  const char* msg= ER(sql_errno);
1158  (void) raise_condition(sql_errno,
1159  NULL,
1160  Sql_condition::WARN_LEVEL_NOTE,
1161  msg);
1162  DBUG_VOID_RETURN;
1163 }
1164 
1165 void THD::raise_note_printf(uint sql_errno, ...)
1166 {
1167  va_list args;
1168  char ebuff[MYSQL_ERRMSG_SIZE];
1169  DBUG_ENTER("THD::raise_note_printf");
1170  DBUG_PRINT("enter",("code: %u", sql_errno));
1171  if (!(variables.option_bits & OPTION_SQL_NOTES))
1172  DBUG_VOID_RETURN;
1173  const char* format= ER(sql_errno);
1174  va_start(args, sql_errno);
1175  my_vsnprintf(ebuff, sizeof(ebuff), format, args);
1176  va_end(args);
1177  (void) raise_condition(sql_errno,
1178  NULL,
1179  Sql_condition::WARN_LEVEL_NOTE,
1180  ebuff);
1181  DBUG_VOID_RETURN;
1182 }
1183 
1184 
1185 struct timeval THD::query_start_timeval_trunc(uint decimals)
1186 {
1187  struct timeval tv;
1188  tv.tv_sec= start_time.tv_sec;
1189  query_start_used= 1;
1190  if (decimals)
1191  {
1192  tv.tv_usec= start_time.tv_usec;
1193  my_timeval_trunc(&tv, decimals);
1194  query_start_usec_used= 1;
1195  }
1196  else
1197  {
1198  tv.tv_usec= 0;
1199  }
1200  return tv;
1201 }
1202 
1203 
1204 Sql_condition* THD::raise_condition(uint sql_errno,
1205  const char* sqlstate,
1206  Sql_condition::enum_warning_level level,
1207  const char* msg)
1208 {
1209  Diagnostics_area *da= get_stmt_da();
1210  Sql_condition *cond= NULL;
1211  DBUG_ENTER("THD::raise_condition");
1212 
1213  if (!(variables.option_bits & OPTION_SQL_NOTES) &&
1214  (level == Sql_condition::WARN_LEVEL_NOTE))
1215  DBUG_RETURN(NULL);
1216 
1217  da->opt_clear_warning_info(query_id);
1218 
1219  /*
1220  TODO: replace by DBUG_ASSERT(sql_errno != 0) once all bugs similar to
1221  Bug#36768 are fixed: a SQL condition must have a real (!=0) error number
1222  so that it can be caught by handlers.
1223  */
1224  if (sql_errno == 0)
1225  sql_errno= ER_UNKNOWN_ERROR;
1226  if (msg == NULL)
1227  msg= ER(sql_errno);
1228  if (sqlstate == NULL)
1229  sqlstate= mysql_errno_to_sqlstate(sql_errno);
1230 
1231  if ((level == Sql_condition::WARN_LEVEL_WARN) &&
1232  really_abort_on_warning())
1233  {
1234  /*
1235  FIXME:
1236  push_warning and strict SQL_MODE case.
1237  */
1238  level= Sql_condition::WARN_LEVEL_ERROR;
1239  killed= THD::KILL_BAD_DATA;
1240  }
1241 
1242  switch (level)
1243  {
1244  case Sql_condition::WARN_LEVEL_NOTE:
1245  case Sql_condition::WARN_LEVEL_WARN:
1246  got_warning= 1;
1247  break;
1248  case Sql_condition::WARN_LEVEL_ERROR:
1249  break;
1250  default:
1251  DBUG_ASSERT(FALSE);
1252  }
1253 
1254  if (handle_condition(sql_errno, sqlstate, level, msg, &cond))
1255  DBUG_RETURN(cond);
1256 
1257  if (level == Sql_condition::WARN_LEVEL_ERROR)
1258  {
1259  is_slave_error= 1; // needed to catch query errors during replication
1260 
1261  /*
1262  thd->lex->current_select == 0 if lex structure is not inited
1263  (not query command (COM_QUERY))
1264  */
1265  if (lex->current_select &&
1266  lex->current_select->no_error && !is_fatal_error)
1267  {
1268  DBUG_PRINT("error",
1269  ("Error converted to warning: current_select: no_error %d "
1270  "fatal_error: %d",
1271  (lex->current_select ?
1272  lex->current_select->no_error : 0),
1273  (int) is_fatal_error));
1274  }
1275  else
1276  {
1277  if (!da->is_error())
1278  {
1279  set_row_count_func(-1);
1280  da->set_error_status(sql_errno, msg, sqlstate, cond);
1281  }
1282  }
1283  }
1284 
1285  query_cache_abort(&query_cache_tls);
1286 
1287  /*
1288  Avoid pushing a condition for fatal out of memory errors as this will
1289  require memory allocation and therefore might fail. Non fatal out of
1290  memory errors can occur if raised by SIGNAL/RESIGNAL statement.
1291  */
1292  if (!(is_fatal_error && (sql_errno == EE_OUTOFMEMORY ||
1293  sql_errno == ER_OUTOFMEMORY)))
1294  {
1295  cond= da->push_warning(this, sql_errno, sqlstate, level, msg);
1296  }
1297  DBUG_RETURN(cond);
1298 }
1299 
1300 extern "C"
1301 void *thd_alloc(MYSQL_THD thd, unsigned int size)
1302 {
1303  return thd->alloc(size);
1304 }
1305 
1306 extern "C"
1307 void *thd_calloc(MYSQL_THD thd, unsigned int size)
1308 {
1309  return thd->calloc(size);
1310 }
1311 
1312 extern "C"
1313 char *thd_strdup(MYSQL_THD thd, const char *str)
1314 {
1315  return thd->strdup(str);
1316 }
1317 
1318 extern "C"
1319 char *thd_strmake(MYSQL_THD thd, const char *str, unsigned int size)
1320 {
1321  return thd->strmake(str, size);
1322 }
1323 
1324 extern "C"
1325 LEX_STRING *thd_make_lex_string(THD *thd, LEX_STRING *lex_str,
1326  const char *str, unsigned int size,
1327  int allocate_lex_string)
1328 {
1329  return thd->make_lex_string(lex_str, str, size,
1330  (bool) allocate_lex_string);
1331 }
1332 
1333 extern "C"
1334 void *thd_memdup(MYSQL_THD thd, const void* str, unsigned int size)
1335 {
1336  return thd->memdup(str, size);
1337 }
1338 
1339 extern "C"
1340 void thd_get_xid(const MYSQL_THD thd, MYSQL_XID *xid)
1341 {
1342  *xid = *(MYSQL_XID *) &thd->transaction.xid_state.xid;
1343 }
1344 
1345 #ifdef _WIN32
1346 extern "C" THD *_current_thd_noinline(void)
1347 {
1348  return my_pthread_getspecific_ptr(THD*,THR_THD);
1349 }
1350 #endif
1351 /*
1352  Init common variables that has to be reset on start and on change_user
1353 */
1354 
1355 void THD::init(void)
1356 {
1357  mysql_mutex_lock(&LOCK_global_system_variables);
1358  plugin_thdvar_init(this, m_enable_plugins);
1359  /*
1360  variables= global_system_variables above has reset
1361  variables.pseudo_thread_id to 0. We need to correct it here to
1362  avoid temporary tables replication failure.
1363  */
1364  variables.pseudo_thread_id= thread_id;
1365  mysql_mutex_unlock(&LOCK_global_system_variables);
1366  server_status= SERVER_STATUS_AUTOCOMMIT;
1367  if (variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)
1368  server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES;
1369 
1370  transaction.all.reset_unsafe_rollback_flags();
1371  transaction.stmt.reset_unsafe_rollback_flags();
1372  open_options=ha_open_options;
1373  update_lock_default= (variables.low_priority_updates ?
1374  TL_WRITE_LOW_PRIORITY :
1375  TL_WRITE);
1376  tx_isolation= (enum_tx_isolation) variables.tx_isolation;
1377  tx_read_only= variables.tx_read_only;
1378  update_charset();
1379  reset_current_stmt_binlog_format_row();
1380  reset_binlog_local_stmt_filter();
1381  memset(&status_var, 0, sizeof(status_var));
1382  binlog_row_event_extra_data= 0;
1383 
1384  if (variables.sql_log_bin)
1385  variables.option_bits|= OPTION_BIN_LOG;
1386  else
1387  variables.option_bits&= ~OPTION_BIN_LOG;
1388 
1389 #if defined(ENABLED_DEBUG_SYNC)
1390  /* Initialize the Debug Sync Facility. See debug_sync.cc. */
1391  debug_sync_init_thread(this);
1392 #endif /* defined(ENABLED_DEBUG_SYNC) */
1393 
1394  owned_gtid.sidno= 0;
1395  owned_gtid.gno= 0;
1396 }
1397 
1398 
1399 /*
1400  Init THD for query processing.
1401  This has to be called once before we call mysql_parse.
1402  See also comments in sql_class.h.
1403 */
1404 
1405 void THD::init_for_queries(Relay_log_info *rli)
1406 {
1407  set_time();
1408  ha_enable_transaction(this,TRUE);
1409 
1410  reset_root_defaults(mem_root, variables.query_alloc_block_size,
1411  variables.query_prealloc_size);
1412  reset_root_defaults(&transaction.mem_root,
1413  variables.trans_alloc_block_size,
1414  variables.trans_prealloc_size);
1415  transaction.xid_state.xid.null();
1416  transaction.xid_state.in_thd=1;
1417 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
1418  if (rli)
1419  {
1420  if ((rli->deferred_events_collecting= rpl_filter->is_on()))
1421  {
1422  rli->deferred_events= new Deferred_log_events(rli);
1423  }
1424  rli_slave= rli;
1425 
1426  DBUG_ASSERT(rli_slave->info_thd == this && slave_thread);
1427  }
1428 #endif
1429 }
1430 
1431 
1432 /*
1433  Do what's needed when one invokes change user
1434 
1435  SYNOPSIS
1436  change_user()
1437 
1438  IMPLEMENTATION
1439  Reset all resources that are connection specific
1440 */
1441 
1442 
1443 void THD::change_user(void)
1444 {
1445  mysql_mutex_lock(&LOCK_status);
1446  add_to_status(&global_status_var, &status_var);
1447  mysql_mutex_unlock(&LOCK_status);
1448 
1449  cleanup();
1450  killed= NOT_KILLED;
1451  cleanup_done= 0;
1452  init();
1453  stmt_map.reset();
1454  my_hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
1455  (my_hash_get_key) get_var_key,
1456  (my_hash_free_key) free_user_var, 0);
1457  sp_cache_clear(&sp_proc_cache);
1458  sp_cache_clear(&sp_func_cache);
1459 }
1460 
1461 
1462 /*
1463  Do what's needed when one invokes change user.
1464  Also used during THD::release_resources, i.e. prior to THD destruction.
1465 */
1466 void THD::cleanup(void)
1467 {
1468  DBUG_ENTER("THD::cleanup");
1469  DBUG_ASSERT(cleanup_done == 0);
1470 
1471  killed= KILL_CONNECTION;
1472 #ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE
1473  if (transaction.xid_state.xa_state == XA_PREPARED)
1474  {
1475 #error xid_state in the cache should be replaced by the allocated value
1476  }
1477 #endif
1478  {
1479  transaction.xid_state.xa_state= XA_NOTR;
1480  trans_rollback(this);
1481  xid_cache_delete(&transaction.xid_state);
1482  }
1483 
1484  locked_tables_list.unlock_locked_tables(this);
1485  mysql_ha_cleanup(this);
1486 
1487  DBUG_ASSERT(open_tables == NULL);
1488  /*
1489  If the thread was in the middle of an ongoing transaction (rolled
1490  back a few lines above) or under LOCK TABLES (unlocked the tables
1491  and left the mode a few lines above), there will be outstanding
1492  metadata locks. Release them.
1493  */
1494  mdl_context.release_transactional_locks();
1495 
1496  /* Release the global read lock, if acquired. */
1497  if (global_read_lock.is_acquired())
1498  global_read_lock.unlock_global_read_lock(this);
1499 
1500  /* All metadata locks must have been released by now. */
1501  DBUG_ASSERT(!mdl_context.has_locks());
1502 
1503 #if defined(ENABLED_DEBUG_SYNC)
1504  /* End the Debug Sync Facility. See debug_sync.cc. */
1505  debug_sync_end_thread(this);
1506 #endif /* defined(ENABLED_DEBUG_SYNC) */
1507 
1508  delete_dynamic(&user_var_events);
1509  my_hash_free(&user_vars);
1510  if (gtid_mode > 0)
1511  variables.gtid_next.set_automatic();
1512  close_temporary_tables(this);
1513  sp_cache_clear(&sp_proc_cache);
1514  sp_cache_clear(&sp_func_cache);
1515 
1516  if (ull)
1517  {
1518  mysql_mutex_lock(&LOCK_user_locks);
1519  item_user_lock_release(ull);
1520  mysql_mutex_unlock(&LOCK_user_locks);
1521  ull= NULL;
1522  }
1523 
1524  /*
1525  Actions above might generate events for the binary log, so we
1526  commit the current transaction coordinator after executing cleanup
1527  actions.
1528  */
1529  if (tc_log)
1530  tc_log->commit(this, true);
1531 
1532  cleanup_done=1;
1533  DBUG_VOID_RETURN;
1534 }
1535 
1536 
1540 void THD::release_resources()
1541 {
1542  mysql_mutex_assert_not_owner(&LOCK_thread_count);
1543  DBUG_ASSERT(m_release_resources_done == false);
1544 
1545  mysql_mutex_lock(&LOCK_status);
1546  add_to_status(&global_status_var, &status_var);
1547  mysql_mutex_unlock(&LOCK_status);
1548 
1549  /* Ensure that no one is using THD */
1550  mysql_mutex_lock(&LOCK_thd_data);
1551 
1552  /* Close connection */
1553 #ifndef EMBEDDED_LIBRARY
1554  if (net.vio)
1555  {
1556  vio_delete(net.vio);
1557  net_end(&net);
1558  net.vio= NULL;
1559  }
1560 #endif
1561  mysql_mutex_unlock(&LOCK_thd_data);
1562 
1563  stmt_map.reset(); /* close all prepared statements */
1564  if (!cleanup_done)
1565  cleanup();
1566 
1567  mdl_context.destroy();
1568  ha_close_connection(this);
1569  mysql_audit_release(this);
1570  if (m_enable_plugins)
1571  plugin_thdvar_cleanup(this);
1572 
1573  m_release_resources_done= true;
1574 }
1575 
1576 
1577 THD::~THD()
1578 {
1579  mysql_mutex_assert_not_owner(&LOCK_thread_count);
1580  THD_CHECK_SENTRY(this);
1581  DBUG_ENTER("~THD()");
1582  DBUG_PRINT("info", ("THD dtor, this %p", this));
1583 
1584  if (!m_release_resources_done)
1585  release_resources();
1586 
1587  clear_next_event_pos();
1588 
1589  /* Ensure that no one is using THD */
1590  mysql_mutex_lock(&LOCK_thd_data);
1591  mysql_mutex_unlock(&LOCK_thd_data);
1592 
1593  DBUG_PRINT("info", ("freeing security context"));
1594  main_security_ctx.destroy();
1595  my_free(db);
1596  db= NULL;
1597  free_root(&transaction.mem_root,MYF(0));
1598  mysql_mutex_destroy(&LOCK_thd_data);
1599 #ifndef DBUG_OFF
1600  dbug_sentry= THD_SENTRY_GONE;
1601 #endif
1602 #ifndef EMBEDDED_LIBRARY
1603  if (rli_fake)
1604  {
1605  rli_fake->end_info();
1606  delete rli_fake;
1607  rli_fake= NULL;
1608  }
1609 
1610  if (variables.gtid_next_list.gtid_set != NULL)
1611  {
1612 #ifdef HAVE_GTID_NEXT_LIST
1613  delete variables.gtid_next_list.gtid_set;
1614  variables.gtid_next_list.gtid_set= NULL;
1615  variables.gtid_next_list.is_non_null= false;
1616 #else
1617  DBUG_ASSERT(0);
1618 #endif
1619  }
1620 
1621  mysql_audit_free_thd(this);
1622  if (rli_slave)
1623  rli_slave->cleanup_after_session();
1624 #endif
1625 
1626  free_root(&main_mem_root, MYF(0));
1627  DBUG_VOID_RETURN;
1628 }
1629 
1630 
1631 /*
1632  Add all status variables to another status variable array
1633 
1634  SYNOPSIS
1635  add_to_status()
1636  to_var add to this array
1637  from_var from this array
1638 
1639  NOTES
1640  This function assumes that all variables are longlong/ulonglong.
1641  If this assumption will change, then we have to explictely add
1642  the other variables after the while loop
1643 */
1644 
1645 void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
1646 {
1647  int c;
1648  ulonglong *end= (ulonglong*) ((uchar*) to_var +
1649  offsetof(STATUS_VAR, last_system_status_var) +
1650  sizeof(ulonglong));
1651  ulonglong *to= (ulonglong*) to_var, *from= (ulonglong*) from_var;
1652 
1653  while (to != end)
1654  *(to++)+= *(from++);
1655 
1656  to_var->com_other+= from_var->com_other;
1657 
1658  for (c= 0; c< SQLCOM_END; c++)
1659  to_var->com_stat[(uint) c] += from_var->com_stat[(uint) c];
1660 }
1661 
1662 /*
1663  Add the difference between two status variable arrays to another one.
1664 
1665  SYNOPSIS
1666  add_diff_to_status
1667  to_var add to this array
1668  from_var from this array
1669  dec_var minus this array
1670 
1671  NOTE
1672  This function assumes that all variables are longlong/ulonglong.
1673 */
1674 
1675 void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
1676  STATUS_VAR *dec_var)
1677 {
1678  int c;
1679  ulonglong *end= (ulonglong*) ((uchar*) to_var + offsetof(STATUS_VAR,
1680  last_system_status_var) +
1681  sizeof(ulonglong));
1682  ulonglong *to= (ulonglong*) to_var,
1683  *from= (ulonglong*) from_var,
1684  *dec= (ulonglong*) dec_var;
1685 
1686  while (to != end)
1687  *(to++)+= *(from++) - *(dec++);
1688 
1689  to_var->com_other+= from_var->com_other - dec_var->com_other;
1690 
1691  for (c= 0; c< SQLCOM_END; c++)
1692  to_var->com_stat[(uint) c] += from_var->com_stat[(uint) c] -dec_var->com_stat[(uint) c];
1693 }
1694 
1695 
1706 void THD::awake(THD::killed_state state_to_set)
1707 {
1708  DBUG_ENTER("THD::awake");
1709  DBUG_PRINT("enter", ("this: %p current_thd: %p", this, current_thd));
1710  THD_CHECK_SENTRY(this);
1711  mysql_mutex_assert_owner(&LOCK_thd_data);
1712 
1713  /* Set the 'killed' flag of 'this', which is the target THD object. */
1714  killed= state_to_set;
1715 
1716  if (state_to_set != THD::KILL_QUERY)
1717  {
1718 #ifdef SIGNAL_WITH_VIO_SHUTDOWN
1719  if (this != current_thd)
1720  {
1721  /*
1722  Before sending a signal, let's close the socket of the thread
1723  that is being killed ("this", which is not the current thread).
1724  This is to make sure it does not block if the signal is lost.
1725  This needs to be done only on platforms where signals are not
1726  a reliable interruption mechanism.
1727 
1728  Note that the downside of this mechanism is that we could close
1729  the connection while "this" target thread is in the middle of
1730  sending a result to the application, thus violating the client-
1731  server protocol.
1732 
1733  On the other hand, without closing the socket we have a race
1734  condition. If "this" target thread passes the check of
1735  thd->killed, and then the current thread runs through
1736  THD::awake(), sets the 'killed' flag and completes the
1737  signaling, and then the target thread runs into read(), it will
1738  block on the socket. As a result of the discussions around
1739  Bug#37780, it has been decided that we accept the race
1740  condition. A second KILL awakes the target from read().
1741 
1742  If we are killing ourselves, we know that we are not blocked.
1743  We also know that we will check thd->killed before we go for
1744  reading the next statement.
1745  */
1746 
1747  shutdown_active_vio();
1748  }
1749 #endif
1750 
1751  /* Mark the target thread's alarm request expired, and signal alarm. */
1752  thr_alarm_kill(thread_id);
1753 
1754  /* Send an event to the scheduler that a thread should be killed. */
1755  if (!slave_thread)
1756  MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (this));
1757  }
1758 
1759  /* Broadcast a condition to kick the target if it is waiting on it. */
1760  if (mysys_var)
1761  {
1762  mysql_mutex_lock(&mysys_var->mutex);
1763  if (!system_thread) // Don't abort locks
1764  mysys_var->abort=1;
1765  /*
1766  This broadcast could be up in the air if the victim thread
1767  exits the cond in the time between read and broadcast, but that is
1768  ok since all we want to do is to make the victim thread get out
1769  of waiting on current_cond.
1770  If we see a non-zero current_cond: it cannot be an old value (because
1771  then exit_cond() should have run and it can't because we have mutex); so
1772  it is the true value but maybe current_mutex is not yet non-zero (we're
1773  in the middle of enter_cond() and there is a "memory order
1774  inversion"). So we test the mutex too to not lock 0.
1775 
1776  Note that there is a small chance we fail to kill. If victim has locked
1777  current_mutex, but hasn't yet entered enter_cond() (which means that
1778  current_cond and current_mutex are 0), then the victim will not get
1779  a signal and it may wait "forever" on the cond (until
1780  we issue a second KILL or the status it's waiting for happens).
1781  It's true that we have set its thd->killed but it may not
1782  see it immediately and so may have time to reach the cond_wait().
1783 
1784  However, where possible, we test for killed once again after
1785  enter_cond(). This should make the signaling as safe as possible.
1786  However, there is still a small chance of failure on platforms with
1787  instruction or memory write reordering.
1788  */
1789  if (mysys_var->current_cond && mysys_var->current_mutex)
1790  {
1791  mysql_mutex_lock(mysys_var->current_mutex);
1792  mysql_cond_broadcast(mysys_var->current_cond);
1793  mysql_mutex_unlock(mysys_var->current_mutex);
1794  }
1795  mysql_mutex_unlock(&mysys_var->mutex);
1796  }
1797  DBUG_VOID_RETURN;
1798 }
1799 
1800 
1808 void THD::disconnect()
1809 {
1810  Vio *vio= NULL;
1811 
1812  mysql_mutex_lock(&LOCK_thd_data);
1813 
1814  killed= THD::KILL_CONNECTION;
1815 
1816 #ifdef SIGNAL_WITH_VIO_SHUTDOWN
1817  /*
1818  Since a active vio might might have not been set yet, in
1819  any case save a reference to avoid closing a inexistent
1820  one or closing the vio twice if there is a active one.
1821  */
1822  vio= active_vio;
1823  shutdown_active_vio();
1824 #endif
1825 
1826  /* Disconnect even if a active vio is not associated. */
1827  if (net.vio != vio && net.vio != NULL)
1828  {
1829  vio_shutdown(net.vio);
1830  }
1831 
1832  mysql_mutex_unlock(&LOCK_thd_data);
1833 }
1834 
1835 
1836 bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use,
1837  bool needs_thr_lock_abort)
1838 {
1839  THD *in_use= ctx_in_use->get_thd();
1840  bool signalled= FALSE;
1841  if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) &&
1842  !in_use->killed)
1843  {
1844  in_use->killed= THD::KILL_CONNECTION;
1845  mysql_mutex_lock(&in_use->mysys_var->mutex);
1846  if (in_use->mysys_var->current_cond)
1847  mysql_cond_broadcast(in_use->mysys_var->current_cond);
1848  mysql_mutex_unlock(&in_use->mysys_var->mutex);
1849  signalled= TRUE;
1850  }
1851 
1852  if (needs_thr_lock_abort)
1853  {
1854  mysql_mutex_lock(&in_use->LOCK_thd_data);
1855  for (TABLE *thd_table= in_use->open_tables;
1856  thd_table ;
1857  thd_table= thd_table->next)
1858  {
1859  /*
1860  Check for TABLE::needs_reopen() is needed since in some places we call
1861  handler::close() for table instance (and set TABLE::db_stat to 0)
1862  and do not remove such instances from the THD::open_tables
1863  for some time, during which other thread can see those instances
1864  (e.g. see partitioning code).
1865  */
1866  if (!thd_table->needs_reopen())
1867  signalled|= mysql_lock_abort_for_thread(this, thd_table);
1868  }
1869  mysql_mutex_unlock(&in_use->LOCK_thd_data);
1870  }
1871  return signalled;
1872 }
1873 
1874 
1875 /*
1876  Remember the location of thread info, the structure needed for
1877  sql_alloc() and the structure for the net buffer
1878 */
1879 
1880 bool THD::store_globals()
1881 {
1882  /*
1883  Assert that thread_stack is initialized: it's necessary to be able
1884  to track stack overrun.
1885  */
1886  DBUG_ASSERT(thread_stack);
1887 
1888  if (my_pthread_setspecific_ptr(THR_THD, this) ||
1889  my_pthread_setspecific_ptr(THR_MALLOC, &mem_root))
1890  return 1;
1891  /*
1892  mysys_var is concurrently readable by a killer thread.
1893  It is protected by LOCK_thd_data, it is not needed to lock while the
1894  pointer is changing from NULL not non-NULL. If the kill thread reads
1895  NULL it doesn't refer to anything, but if it is non-NULL we need to
1896  ensure that the thread doesn't proceed to assign another thread to
1897  have the mysys_var reference (which in fact refers to the worker
1898  threads local storage with key THR_KEY_mysys.
1899  */
1900  mysys_var=my_thread_var;
1901  DBUG_PRINT("debug", ("mysys_var: 0x%llx", (ulonglong) mysys_var));
1902  /*
1903  Let mysqld define the thread id (not mysys)
1904  This allows us to move THD to different threads if needed.
1905  */
1906  mysys_var->id= thread_id;
1907  real_id= pthread_self(); // For debugging
1908 
1909  /*
1910  We have to call thr_lock_info_init() again here as THD may have been
1911  created in another thread
1912  */
1913  thr_lock_info_init(&lock_info);
1914  return 0;
1915 }
1916 
1917 /*
1918  Remove the thread specific info (THD and mem_root pointer) stored during
1919  store_global call for this thread.
1920 */
1921 bool THD::restore_globals()
1922 {
1923  /*
1924  Assert that thread_stack is initialized: it's necessary to be able
1925  to track stack overrun.
1926  */
1927  DBUG_ASSERT(thread_stack);
1928 
1929  /* Undocking the thread specific data. */
1930  my_pthread_setspecific_ptr(THR_THD, NULL);
1931  my_pthread_setspecific_ptr(THR_MALLOC, NULL);
1932 
1933  return 0;
1934 }
1935 
1936 
1937 /*
1938  Cleanup after query.
1939 
1940  SYNOPSIS
1941  THD::cleanup_after_query()
1942 
1943  DESCRIPTION
1944  This function is used to reset thread data to its default state.
1945 
1946  NOTE
1947  This function is not suitable for setting thread data to some
1948  non-default values, as there is only one replication thread, so
1949  different master threads may overwrite data of each other on
1950  slave.
1951 */
1952 
1953 void THD::cleanup_after_query()
1954 {
1955  /*
1956  Reset rand_used so that detection of calls to rand() will save random
1957  seeds if needed by the slave.
1958 
1959  Do not reset rand_used if inside a stored function or trigger because
1960  only the call to these operations is logged. Thus only the calling
1961  statement needs to detect rand() calls made by its substatements. These
1962  substatements must not set rand_used to 0 because it would remove the
1963  detection of rand() by the calling statement.
1964  */
1965  if (!in_sub_stmt) /* stored functions and triggers are a special case */
1966  {
1967  /* Forget those values, for next binlogger: */
1968  stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
1969  auto_inc_intervals_in_cur_stmt_for_binlog.empty();
1970  rand_used= 0;
1971  binlog_accessed_db_names= NULL;
1972  m_trans_fixed_log_file= NULL;
1973 
1974  if (gtid_mode > 0)
1975  gtid_post_statement_checks(this);
1976 #ifndef EMBEDDED_LIBRARY
1977  /*
1978  Clean possible unused INSERT_ID events by current statement.
1979  is_update_query() is needed to ignore SET statements:
1980  Statements that don't update anything directly and don't
1981  used stored functions. This is mostly necessary to ignore
1982  statements in binlog between SET INSERT_ID and DML statement
1983  which is intended to consume its event (there can be other
1984  SET statements between them).
1985  */
1986  if ((rli_slave || rli_fake) && is_update_query(lex->sql_command))
1987  auto_inc_intervals_forced.empty();
1988 #endif
1989  }
1990  /*
1991  Forget the binlog stmt filter for the next query.
1992  There are some code paths that:
1993  - do not call THD::decide_logging_format()
1994  - do call THD::binlog_query(),
1995  making this reset necessary.
1996  */
1997  reset_binlog_local_stmt_filter();
1998  if (first_successful_insert_id_in_cur_stmt > 0)
1999  {
2000  /* set what LAST_INSERT_ID() will return */
2001  first_successful_insert_id_in_prev_stmt=
2002  first_successful_insert_id_in_cur_stmt;
2003  first_successful_insert_id_in_cur_stmt= 0;
2004  substitute_null_with_insert_id= TRUE;
2005  }
2006  arg_of_last_insert_id_function= 0;
2007  /* Free Items that were created during this execution */
2008  free_items();
2009  /* Reset where. */
2010  where= THD::DEFAULT_WHERE;
2011  /* reset table map for multi-table update */
2012  table_map_for_update= 0;
2013  m_binlog_invoker= FALSE;
2014  /* reset replication info structure */
2015  if (lex && lex->mi.repl_ignore_server_ids.buffer)
2016  {
2017  delete_dynamic(&lex->mi.repl_ignore_server_ids);
2018  }
2019 #ifndef EMBEDDED_LIBRARY
2020  if (rli_slave)
2021  rli_slave->cleanup_after_query();
2022 #endif
2023 }
2024 
2025 
2026 LEX_STRING *
2027 make_lex_string_root(MEM_ROOT *mem_root,
2028  LEX_STRING *lex_str, const char* str, uint length,
2029  bool allocate_lex_string)
2030 {
2031  if (allocate_lex_string)
2032  if (!(lex_str= (LEX_STRING *)alloc_root(mem_root, sizeof(LEX_STRING))))
2033  return 0;
2034  if (!(lex_str->str= strmake_root(mem_root, str, length)))
2035  return 0;
2036  lex_str->length= length;
2037  return lex_str;
2038 }
2039 
2050 LEX_STRING *THD::make_lex_string(LEX_STRING *lex_str,
2051  const char* str, uint length,
2052  bool allocate_lex_string)
2053 {
2054  return make_lex_string_root (mem_root, lex_str, str,
2055  length, allocate_lex_string);
2056 }
2057 
2058 
2059 /*
2060  Convert a string to another character set
2061 
2062  SYNOPSIS
2063  convert_string()
2064  to Store new allocated string here
2065  to_cs New character set for allocated string
2066  from String to convert
2067  from_length Length of string to convert
2068  from_cs Original character set
2069 
2070  NOTES
2071  to will be 0-terminated to make it easy to pass to system funcs
2072 
2073  RETURN
2074  0 ok
2075  1 End of memory.
2076  In this case to->str will point to 0 and to->length will be 0.
2077 */
2078 
2079 bool THD::convert_string(LEX_STRING *to, const CHARSET_INFO *to_cs,
2080  const char *from, uint from_length,
2081  const CHARSET_INFO *from_cs)
2082 {
2083  DBUG_ENTER("convert_string");
2084  size_t new_length= to_cs->mbmaxlen * from_length;
2085  uint dummy_errors;
2086  if (!(to->str= (char*) alloc(new_length+1)))
2087  {
2088  to->length= 0; // Safety fix
2089  DBUG_RETURN(1); // EOM
2090  }
2091  to->length= copy_and_convert((char*) to->str, new_length, to_cs,
2092  from, from_length, from_cs, &dummy_errors);
2093  to->str[to->length]=0; // Safety
2094  DBUG_RETURN(0);
2095 }
2096 
2097 
2098 /*
2099  Convert string from source character set to target character set inplace.
2100 
2101  SYNOPSIS
2102  THD::convert_string
2103 
2104  DESCRIPTION
2105  Convert string using convert_buffer - buffer for character set
2106  conversion shared between all protocols.
2107 
2108  RETURN
2109  0 ok
2110  !0 out of memory
2111 */
2112 
2113 bool THD::convert_string(String *s, const CHARSET_INFO *from_cs,
2114  const CHARSET_INFO *to_cs)
2115 {
2116  uint dummy_errors;
2117  if (convert_buffer.copy(s->ptr(), s->length(), from_cs, to_cs, &dummy_errors))
2118  return TRUE;
2119  /* If convert_buffer >> s copying is more efficient long term */
2120  if (convert_buffer.alloced_length() >= convert_buffer.length() * 2 ||
2121  !s->is_alloced())
2122  {
2123  return s->copy(convert_buffer);
2124  }
2125  s->swap(convert_buffer);
2126  return FALSE;
2127 }
2128 
2129 
2130 /*
2131  Update some cache variables when character set changes
2132 */
2133 
2134 void THD::update_charset()
2135 {
2136  uint32 not_used;
2137  charset_is_system_charset=
2138  !String::needs_conversion(0,
2139  variables.character_set_client,
2140  system_charset_info,
2141  &not_used);
2142  charset_is_collation_connection=
2143  !String::needs_conversion(0,
2144  variables.character_set_client,
2145  variables.collation_connection,
2146  &not_used);
2147  charset_is_character_set_filesystem=
2148  !String::needs_conversion(0,
2149  variables.character_set_client,
2150  variables.character_set_filesystem,
2151  &not_used);
2152 }
2153 
2154 
2155 /* routings to adding tables to list of changed in transaction tables */
2156 
2157 inline static void list_include(CHANGED_TABLE_LIST** prev,
2158  CHANGED_TABLE_LIST* curr,
2159  CHANGED_TABLE_LIST* new_table)
2160 {
2161  if (new_table)
2162  {
2163  *prev = new_table;
2164  (*prev)->next = curr;
2165  }
2166 }
2167 
2168 /* add table to list of changed in transaction tables */
2169 
2170 void THD::add_changed_table(TABLE *table)
2171 {
2172  DBUG_ENTER("THD::add_changed_table(table)");
2173 
2174  DBUG_ASSERT(in_multi_stmt_transaction_mode() && table->file->has_transactions());
2175  add_changed_table(table->s->table_cache_key.str,
2176  (long) table->s->table_cache_key.length);
2177  DBUG_VOID_RETURN;
2178 }
2179 
2180 
2181 void THD::add_changed_table(const char *key, long key_length)
2182 {
2183  DBUG_ENTER("THD::add_changed_table(key)");
2184  CHANGED_TABLE_LIST **prev_changed = &transaction.changed_tables;
2185  CHANGED_TABLE_LIST *curr = transaction.changed_tables;
2186 
2187  for (; curr; prev_changed = &(curr->next), curr = curr->next)
2188  {
2189  int cmp = (long)curr->key_length - (long)key_length;
2190  if (cmp < 0)
2191  {
2192  list_include(prev_changed, curr, changed_table_dup(key, key_length));
2193  DBUG_PRINT("info",
2194  ("key_length: %ld %u", key_length,
2195  (*prev_changed)->key_length));
2196  DBUG_VOID_RETURN;
2197  }
2198  else if (cmp == 0)
2199  {
2200  cmp = memcmp(curr->key, key, curr->key_length);
2201  if (cmp < 0)
2202  {
2203  list_include(prev_changed, curr, changed_table_dup(key, key_length));
2204  DBUG_PRINT("info",
2205  ("key_length: %ld %u", key_length,
2206  (*prev_changed)->key_length));
2207  DBUG_VOID_RETURN;
2208  }
2209  else if (cmp == 0)
2210  {
2211  DBUG_PRINT("info", ("already in list"));
2212  DBUG_VOID_RETURN;
2213  }
2214  }
2215  }
2216  *prev_changed = changed_table_dup(key, key_length);
2217  DBUG_PRINT("info", ("key_length: %ld %u", key_length,
2218  (*prev_changed)->key_length));
2219  DBUG_VOID_RETURN;
2220 }
2221 
2222 
2223 CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length)
2224 {
2225  CHANGED_TABLE_LIST* new_table =
2226  (CHANGED_TABLE_LIST*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TABLE_LIST))+
2227  key_length + 1);
2228  if (!new_table)
2229  {
2230  my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_FATALERROR),
2231  ALIGN_SIZE(sizeof(TABLE_LIST)) + key_length + 1);
2232  killed= KILL_CONNECTION;
2233  return 0;
2234  }
2235 
2236  new_table->key= ((char*)new_table)+ ALIGN_SIZE(sizeof(CHANGED_TABLE_LIST));
2237  new_table->next = 0;
2238  new_table->key_length = key_length;
2239  ::memcpy(new_table->key, key, key_length);
2240  return new_table;
2241 }
2242 
2243 
2244 int THD::send_explain_fields(select_result *result)
2245 {
2246  List<Item> field_list;
2247  Item *item;
2248  CHARSET_INFO *cs= system_charset_info;
2249  field_list.push_back(new Item_return_int("id",3, MYSQL_TYPE_LONGLONG));
2250  field_list.push_back(new Item_empty_string("select_type", 19, cs));
2251  field_list.push_back(item= new Item_empty_string("table", NAME_CHAR_LEN, cs));
2252  item->maybe_null= 1;
2253  if (lex->describe & DESCRIBE_PARTITIONS)
2254  {
2255  /* Maximum length of string that make_used_partitions_str() can produce */
2256  item= new Item_empty_string("partitions", MAX_PARTITIONS * (1 + FN_LEN),
2257  cs);
2258  field_list.push_back(item);
2259  item->maybe_null= 1;
2260  }
2261  field_list.push_back(item= new Item_empty_string("type", 10, cs));
2262  item->maybe_null= 1;
2263  field_list.push_back(item=new Item_empty_string("possible_keys",
2264  NAME_CHAR_LEN*MAX_KEY, cs));
2265  item->maybe_null=1;
2266  field_list.push_back(item=new Item_empty_string("key", NAME_CHAR_LEN, cs));
2267  item->maybe_null=1;
2268  field_list.push_back(item=new Item_empty_string("key_len",
2269  NAME_CHAR_LEN*MAX_KEY));
2270  item->maybe_null=1;
2271  field_list.push_back(item=new Item_empty_string("ref",
2272  NAME_CHAR_LEN*MAX_REF_PARTS,
2273  cs));
2274  item->maybe_null=1;
2275  field_list.push_back(item= new Item_return_int("rows", 10,
2276  MYSQL_TYPE_LONGLONG));
2277  item->maybe_null= 1;
2278  if (lex->describe & DESCRIBE_EXTENDED)
2279  {
2280  field_list.push_back(item= new Item_float(NAME_STRING("filtered"),
2281  0.1234, 2, 4));
2282  item->maybe_null=1;
2283  }
2284  field_list.push_back(new Item_empty_string("Extra", 255, cs));
2285  item->maybe_null= 1;
2286  return (result->send_result_set_metadata(field_list,
2287  Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF));
2288 }
2289 
2290 #ifdef SIGNAL_WITH_VIO_SHUTDOWN
2291 void THD::shutdown_active_vio()
2292 {
2293  DBUG_ENTER("shutdown_active_vio");
2294  mysql_mutex_assert_owner(&LOCK_thd_data);
2295 #ifndef EMBEDDED_LIBRARY
2296  if (active_vio)
2297  {
2298  vio_shutdown(active_vio);
2299  active_vio = 0;
2300  }
2301 #endif
2302  DBUG_VOID_RETURN;
2303 }
2304 #endif
2305 
2306 
2307 /*
2308  Register an item tree tree transformation, performed by the query
2309  optimizer. We need a pointer to runtime_memroot because it may be !=
2310  thd->mem_root (due to possible set_n_backup_active_arena called for thd).
2311 */
2312 
2313 void THD::nocheck_register_item_tree_change(Item **place, Item *old_value,
2314  MEM_ROOT *runtime_memroot)
2315 {
2316  Item_change_record *change;
2317  /*
2318  Now we use one node per change, which adds some memory overhead,
2319  but still is rather fast as we use alloc_root for allocations.
2320  A list of item tree changes of an average query should be short.
2321  */
2322  void *change_mem= alloc_root(runtime_memroot, sizeof(*change));
2323  if (change_mem == 0)
2324  {
2325  /*
2326  OOM, thd->fatal_error() is called by the error handler of the
2327  memroot. Just return.
2328  */
2329  return;
2330  }
2331  change= new (change_mem) Item_change_record;
2332  change->place= place;
2333  change->old_value= old_value;
2334  change_list.push_front(change);
2335 }
2336 
2337 
2338 void THD::change_item_tree_place(Item **old_ref, Item **new_ref)
2339 {
2340  I_List_iterator<Item_change_record> it(change_list);
2341  Item_change_record *change;
2342  while ((change= it++))
2343  {
2344  if (change->place == old_ref)
2345  {
2346  DBUG_PRINT("info", ("change_item_tree_place old_ref %p new_ref %p",
2347  old_ref, new_ref));
2348  change->place= new_ref;
2349  break;
2350  }
2351  }
2352 }
2353 
2354 
2355 void THD::rollback_item_tree_changes()
2356 {
2357  I_List_iterator<Item_change_record> it(change_list);
2358  Item_change_record *change;
2359  DBUG_ENTER("rollback_item_tree_changes");
2360 
2361  while ((change= it++))
2362  {
2363  DBUG_PRINT("info",
2364  ("rollback_item_tree_changes "
2365  "place %p curr_value %p old_value %p",
2366  change->place, *change->place, change->old_value));
2367  *change->place= change->old_value;
2368  }
2369  /* We can forget about changes memory: it's allocated in runtime memroot */
2370  change_list.empty();
2371  DBUG_VOID_RETURN;
2372 }
2373 
2374 
2375 /*****************************************************************************
2376 ** Functions to provide a interface to select results
2377 *****************************************************************************/
2378 
2379 select_result::select_result():
2380  estimated_rowcount(0)
2381 {
2382  thd=current_thd;
2383 }
2384 
2385 void select_result::send_error(uint errcode,const char *err)
2386 {
2387  my_message(errcode, err, MYF(0));
2388 }
2389 
2390 
2391 void select_result::cleanup()
2392 {
2393  /* do nothing */
2394 }
2395 
2397 {
2398  my_error(ER_SP_BAD_CURSOR_QUERY, MYF(0));
2399  return TRUE;
2400 }
2401 
2402 
2403 static const String default_line_term("\n",default_charset_info);
2404 static const String default_escaped("\\",default_charset_info);
2405 static const String default_field_term("\t",default_charset_info);
2406 static const String default_xml_row_term("<row>", default_charset_info);
2407 static const String my_empty_string("",default_charset_info);
2408 
2409 
2410 sql_exchange::sql_exchange(char *name, bool flag,
2411  enum enum_filetype filetype_arg)
2412  :file_name(name), opt_enclosed(0), dumpfile(flag), skip_lines(0)
2413 {
2414  filetype= filetype_arg;
2415  field_term= &default_field_term;
2416  enclosed= line_start= &my_empty_string;
2417  line_term= filetype == FILETYPE_CSV ?
2418  &default_line_term : &default_xml_row_term;
2419  escaped= &default_escaped;
2420  cs= NULL;
2421 }
2422 
2423 bool sql_exchange::escaped_given(void)
2424 {
2425  return escaped != &default_escaped;
2426 }
2427 
2428 
2429 bool select_send::send_result_set_metadata(List<Item> &list, uint flags)
2430 {
2431  bool res;
2432  if (!(res= thd->protocol->send_result_set_metadata(&list, flags)))
2433  is_result_set_started= 1;
2434  return res;
2435 }
2436 
2437 void select_send::abort_result_set()
2438 {
2439  DBUG_ENTER("select_send::abort_result_set");
2440 
2441  if (is_result_set_started && thd->sp_runtime_ctx)
2442  {
2443  /*
2444  We're executing a stored procedure, have an open result
2445  set and an SQL exception condition. In this situation we
2446  must abort the current statement, silence the error and
2447  start executing the continue/exit handler if one is found.
2448  Before aborting the statement, let's end the open result set, as
2449  otherwise the client will hang due to the violation of the
2450  client/server protocol.
2451  */
2452  thd->sp_runtime_ctx->end_partial_result_set= TRUE;
2453  }
2454  DBUG_VOID_RETURN;
2455 }
2456 
2457 
2464 void select_send::cleanup()
2465 {
2466  is_result_set_started= FALSE;
2467 }
2468 
2469 /* Send data to client. Returns 0 if ok */
2470 
2471 bool select_send::send_data(List<Item> &items)
2472 {
2473  Protocol *protocol= thd->protocol;
2474  DBUG_ENTER("select_send::send_data");
2475 
2476  if (unit->offset_limit_cnt)
2477  { // using limit offset,count
2478  unit->offset_limit_cnt--;
2479  DBUG_RETURN(FALSE);
2480  }
2481 
2482  /*
2483  We may be passing the control from mysqld to the client: release the
2484  InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
2485  by thd
2486  */
2488 
2489  protocol->prepare_for_resend();
2490  if (protocol->send_result_set_row(&items))
2491  {
2492  protocol->remove_last_row();
2493  DBUG_RETURN(TRUE);
2494  }
2495 
2496  thd->inc_sent_row_count(1);
2497 
2498  if (thd->vio_ok())
2499  DBUG_RETURN(protocol->write());
2500 
2501  DBUG_RETURN(0);
2502 }
2503 
2504 bool select_send::send_eof()
2505 {
2506  /*
2507  We may be passing the control from mysqld to the client: release the
2508  InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
2509  by thd
2510  */
2512 
2513  /*
2514  Don't send EOF if we're in error condition (which implies we've already
2515  sent or are sending an error)
2516  */
2517  if (thd->is_error())
2518  return TRUE;
2519  ::my_eof(thd);
2520  is_result_set_started= 0;
2521  return FALSE;
2522 }
2523 
2524 
2525 /************************************************************************
2526  Handling writing to file
2527 ************************************************************************/
2528 
2529 void select_to_file::send_error(uint errcode,const char *err)
2530 {
2531  my_message(errcode, err, MYF(0));
2532  if (file > 0)
2533  {
2534  (void) end_io_cache(&cache);
2535  mysql_file_close(file, MYF(0));
2536  /* Delete file on error */
2537  mysql_file_delete(key_select_to_file, path, MYF(0));
2538  file= -1;
2539  }
2540 }
2541 
2542 
2543 bool select_to_file::send_eof()
2544 {
2545  int error= test(end_io_cache(&cache));
2546  if (mysql_file_close(file, MYF(MY_WME)) || thd->is_error())
2547  error= true;
2548 
2549  if (!error)
2550  {
2551  ::my_ok(thd,row_count);
2552  }
2553  file= -1;
2554  return error;
2555 }
2556 
2557 
2558 void select_to_file::cleanup()
2559 {
2560  /* In case of error send_eof() may be not called: close the file here. */
2561  if (file >= 0)
2562  {
2563  (void) end_io_cache(&cache);
2564  mysql_file_close(file, MYF(0));
2565  file= -1;
2566  }
2567  path[0]= '\0';
2568  row_count= 0;
2569 }
2570 
2571 
2572 select_to_file::~select_to_file()
2573 {
2574  if (file >= 0)
2575  { // This only happens in case of error
2576  (void) end_io_cache(&cache);
2577  mysql_file_close(file, MYF(0));
2578  file= -1;
2579  }
2580 }
2581 
2582 /***************************************************************************
2583 ** Export of select to textfile
2584 ***************************************************************************/
2585 
2586 select_export::~select_export()
2587 {
2588  thd->set_sent_row_count(row_count);
2589 }
2590 
2591 
2592 /*
2593  Create file with IO cache
2594 
2595  SYNOPSIS
2596  create_file()
2597  thd Thread handle
2598  path File name
2599  exchange Excange class
2600  cache IO cache
2601 
2602  RETURN
2603  >= 0 File handle
2604  -1 Error
2605 */
2606 
2607 
2608 static File create_file(THD *thd, char *path, sql_exchange *exchange,
2609  IO_CACHE *cache)
2610 {
2611  File file;
2612  uint option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
2613 
2614 #ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
2615  option|= MY_REPLACE_DIR; // Force use of db directory
2616 #endif
2617 
2618  if (!dirname_length(exchange->file_name))
2619  {
2620  strxnmov(path, FN_REFLEN-1, mysql_real_data_home, thd->db ? thd->db : "",
2621  NullS);
2622  (void) fn_format(path, exchange->file_name, path, "", option);
2623  }
2624  else
2625  (void) fn_format(path, exchange->file_name, mysql_real_data_home, "", option);
2626 
2627  if (!is_secure_file_path(path))
2628  {
2629  /* Write only allowed to dir or subdir specified by secure_file_priv */
2630  my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
2631  return -1;
2632  }
2633 
2634  if (!access(path, F_OK))
2635  {
2636  my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
2637  return -1;
2638  }
2639  /* Create the file world readable */
2640  if ((file= mysql_file_create(key_select_to_file,
2641  path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
2642  return file;
2643 #ifdef HAVE_FCHMOD
2644  (void) fchmod(file, 0666); // Because of umask()
2645 #else
2646  (void) chmod(path, 0666);
2647 #endif
2648  if (init_io_cache(cache, file, 0L, WRITE_CACHE, 0L, 1, MYF(MY_WME)))
2649  {
2650  mysql_file_close(file, MYF(0));
2651  /* Delete file on error, it was just created */
2652  mysql_file_delete(key_select_to_file, path, MYF(0));
2653  return -1;
2654  }
2655  return file;
2656 }
2657 
2658 
2659 int
2660 select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
2661 {
2662  bool blob_flag=0;
2663  bool string_results= FALSE, non_string_results= FALSE;
2664  unit= u;
2665  if ((uint) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN)
2666  strmake(path,exchange->file_name,FN_REFLEN-1);
2667 
2668  write_cs= exchange->cs ? exchange->cs : &my_charset_bin;
2669 
2670  if ((file= create_file(thd, path, exchange, &cache)) < 0)
2671  return 1;
2672  /* Check if there is any blobs in data */
2673  {
2674  List_iterator_fast<Item> li(list);
2675  Item *item;
2676  while ((item=li++))
2677  {
2678  if (item->max_length >= MAX_BLOB_WIDTH)
2679  {
2680  blob_flag=1;
2681  break;
2682  }
2683  if (item->result_type() == STRING_RESULT)
2684  string_results= TRUE;
2685  else
2686  non_string_results= TRUE;
2687  }
2688  }
2689  if (exchange->escaped->numchars() > 1 || exchange->enclosed->numchars() > 1)
2690  {
2691  my_error(ER_WRONG_FIELD_TERMINATORS, MYF(0));
2692  return TRUE;
2693  }
2694  if (exchange->escaped->length() > 1 || exchange->enclosed->length() > 1 ||
2695  !my_isascii(exchange->escaped->ptr()[0]) ||
2696  !my_isascii(exchange->enclosed->ptr()[0]) ||
2697  !exchange->field_term->is_ascii() || !exchange->line_term->is_ascii() ||
2698  !exchange->line_start->is_ascii())
2699  {
2700  /*
2701  Current LOAD DATA INFILE recognizes field/line separators "as is" without
2702  converting from client charset to data file charset. So, it is supposed,
2703  that input file of LOAD DATA INFILE consists of data in one charset and
2704  separators in other charset. For the compatibility with that [buggy]
2705  behaviour SELECT INTO OUTFILE implementation has been saved "as is" too,
2706  but the new warning message has been added:
2707 
2708  Non-ASCII separator arguments are not fully supported
2709  */
2710  push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
2711  WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED,
2712  ER(WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED));
2713  }
2714  field_term_length=exchange->field_term->length();
2715  field_term_char= field_term_length ?
2716  (int) (uchar) (*exchange->field_term)[0] : INT_MAX;
2717  if (!exchange->line_term->length())
2718  exchange->line_term=exchange->field_term; // Use this if it exists
2719  field_sep_char= (exchange->enclosed->length() ?
2720  (int) (uchar) (*exchange->enclosed)[0] : field_term_char);
2721  if (exchange->escaped->length() && (exchange->escaped_given() ||
2722  !(thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)))
2723  escape_char= (int) (uchar) (*exchange->escaped)[0];
2724  else
2725  escape_char= -1;
2726  is_ambiguous_field_sep= test(strchr(ESCAPE_CHARS, field_sep_char));
2727  is_unsafe_field_sep= test(strchr(NUMERIC_CHARS, field_sep_char));
2728  line_sep_char= (exchange->line_term->length() ?
2729  (int) (uchar) (*exchange->line_term)[0] : INT_MAX);
2730  if (!field_term_length)
2731  exchange->opt_enclosed=0;
2732  if (!exchange->enclosed->length())
2733  exchange->opt_enclosed=1; // A little quicker loop
2734  fixed_row_size= (!field_term_length && !exchange->enclosed->length() &&
2735  !blob_flag);
2736  if ((is_ambiguous_field_sep && exchange->enclosed->is_empty() &&
2737  (string_results || is_unsafe_field_sep)) ||
2738  (exchange->opt_enclosed && non_string_results &&
2739  field_term_length && strchr(NUMERIC_CHARS, field_term_char)))
2740  {
2741  push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
2742  ER_AMBIGUOUS_FIELD_TERM, ER(ER_AMBIGUOUS_FIELD_TERM));
2743  is_ambiguous_field_term= TRUE;
2744  }
2745  else
2746  is_ambiguous_field_term= FALSE;
2747 
2748  return 0;
2749 }
2750 
2751 
2752 #define NEED_ESCAPING(x) ((int) (uchar) (x) == escape_char || \
2753  (enclosed ? (int) (uchar) (x) == field_sep_char \
2754  : (int) (uchar) (x) == field_term_char) || \
2755  (int) (uchar) (x) == line_sep_char || \
2756  !(x))
2757 
2758 bool select_export::send_data(List<Item> &items)
2759 {
2760 
2761  DBUG_ENTER("select_export::send_data");
2762  char buff[MAX_FIELD_WIDTH],null_buff[2],space[MAX_FIELD_WIDTH];
2763  char cvt_buff[MAX_FIELD_WIDTH];
2764  String cvt_str(cvt_buff, sizeof(cvt_buff), write_cs);
2765  bool space_inited=0;
2766  String tmp(buff,sizeof(buff),&my_charset_bin),*res;
2767  tmp.length(0);
2768 
2769  if (unit->offset_limit_cnt)
2770  { // using limit offset,count
2771  unit->offset_limit_cnt--;
2772  DBUG_RETURN(0);
2773  }
2774  row_count++;
2775  Item *item;
2776  uint used_length=0,items_left=items.elements;
2777  List_iterator_fast<Item> li(items);
2778 
2779  if (my_b_write(&cache,(uchar*) exchange->line_start->ptr(),
2780  exchange->line_start->length()))
2781  goto err;
2782  while ((item=li++))
2783  {
2784  Item_result result_type=item->result_type();
2785  bool enclosed = (exchange->enclosed->length() &&
2786  (!exchange->opt_enclosed || result_type == STRING_RESULT));
2787  res=item->str_result(&tmp);
2788  if (res && !my_charset_same(write_cs, res->charset()) &&
2789  !my_charset_same(write_cs, &my_charset_bin))
2790  {
2791  const char *well_formed_error_pos;
2792  const char *cannot_convert_error_pos;
2793  const char *from_end_pos;
2794  const char *error_pos;
2795  uint32 bytes;
2796  uint64 estimated_bytes=
2797  ((uint64) res->length() / res->charset()->mbminlen + 1) *
2798  write_cs->mbmaxlen + 1;
2799  set_if_smaller(estimated_bytes, UINT_MAX32);
2800  if (cvt_str.realloc((uint32) estimated_bytes))
2801  {
2802  my_error(ER_OUTOFMEMORY, MYF(ME_FATALERROR), (uint32) estimated_bytes);
2803  goto err;
2804  }
2805 
2806  bytes= well_formed_copy_nchars(write_cs, (char *) cvt_str.ptr(),
2807  cvt_str.alloced_length(),
2808  res->charset(), res->ptr(), res->length(),
2809  UINT_MAX32, // copy all input chars,
2810  // i.e. ignore nchars parameter
2811  &well_formed_error_pos,
2812  &cannot_convert_error_pos,
2813  &from_end_pos);
2814  error_pos= well_formed_error_pos ? well_formed_error_pos
2815  : cannot_convert_error_pos;
2816  if (error_pos)
2817  {
2818  char printable_buff[32];
2819  convert_to_printable(printable_buff, sizeof(printable_buff),
2820  error_pos, res->ptr() + res->length() - error_pos,
2821  res->charset(), 6);
2822  push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
2823  ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
2824  ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
2825  "string", printable_buff,
2826  item->item_name.ptr(), static_cast<long>(row_count));
2827  }
2828  else if (from_end_pos < res->ptr() + res->length())
2829  {
2830  /*
2831  result is longer than UINT_MAX32 and doesn't fit into String
2832  */
2833  push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
2834  WARN_DATA_TRUNCATED, ER(WARN_DATA_TRUNCATED),
2835  item->full_name(), static_cast<long>(row_count));
2836  }
2837  cvt_str.length(bytes);
2838  res= &cvt_str;
2839  }
2840  if (res && enclosed)
2841  {
2842  if (my_b_write(&cache,(uchar*) exchange->enclosed->ptr(),
2843  exchange->enclosed->length()))
2844  goto err;
2845  }
2846  if (!res)
2847  { // NULL
2848  if (!fixed_row_size)
2849  {
2850  if (escape_char != -1) // Use \N syntax
2851  {
2852  null_buff[0]=escape_char;
2853  null_buff[1]='N';
2854  if (my_b_write(&cache,(uchar*) null_buff,2))
2855  goto err;
2856  }
2857  else if (my_b_write(&cache,(uchar*) "NULL",4))
2858  goto err;
2859  }
2860  else
2861  {
2862  used_length=0; // Fill with space
2863  }
2864  }
2865  else
2866  {
2867  if (fixed_row_size)
2868  used_length=min(res->length(),item->max_length);
2869  else
2870  used_length=res->length();
2871  if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
2872  escape_char != -1)
2873  {
2874  char *pos, *start, *end;
2875  const CHARSET_INFO *res_charset= res->charset();
2876  const CHARSET_INFO *character_set_client=
2877  thd->variables.character_set_client;
2878  bool check_second_byte= (res_charset == &my_charset_bin) &&
2879  character_set_client->
2880  escape_with_backslash_is_dangerous;
2881  DBUG_ASSERT(character_set_client->mbmaxlen == 2 ||
2882  !character_set_client->escape_with_backslash_is_dangerous);
2883  for (start=pos=(char*) res->ptr(),end=pos+used_length ;
2884  pos != end ;
2885  pos++)
2886  {
2887 #ifdef USE_MB
2888  if (use_mb(res_charset))
2889  {
2890  int l;
2891  if ((l=my_ismbchar(res_charset, pos, end)))
2892  {
2893  pos += l-1;
2894  continue;
2895  }
2896  }
2897 #endif
2898 
2899  /*
2900  Special case when dumping BINARY/VARBINARY/BLOB values
2901  for the clients with character sets big5, cp932, gbk and sjis,
2902  which can have the escape character (0x5C "\" by default)
2903  as the second byte of a multi-byte sequence.
2904 
2905  If
2906  - pos[0] is a valid multi-byte head (e.g 0xEE) and
2907  - pos[1] is 0x00, which will be escaped as "\0",
2908 
2909  then we'll get "0xEE + 0x5C + 0x30" in the output file.
2910 
2911  If this file is later loaded using this sequence of commands:
2912 
2913  mysql> create table t1 (a varchar(128)) character set big5;
2914  mysql> LOAD DATA INFILE 'dump.txt' INTO TABLE t1;
2915 
2916  then 0x5C will be misinterpreted as the second byte
2917  of a multi-byte character "0xEE + 0x5C", instead of
2918  escape character for 0x00.
2919 
2920  To avoid this confusion, we'll escape the multi-byte
2921  head character too, so the sequence "0xEE + 0x00" will be
2922  dumped as "0x5C + 0xEE + 0x5C + 0x30".
2923 
2924  Note, in the condition below we only check if
2925  mbcharlen is equal to 2, because there are no
2926  character sets with mbmaxlen longer than 2
2927  and with escape_with_backslash_is_dangerous set.
2928  DBUG_ASSERT before the loop makes that sure.
2929  */
2930 
2931  if ((NEED_ESCAPING(*pos) ||
2932  (check_second_byte &&
2933  my_mbcharlen(character_set_client, (uchar) *pos) == 2 &&
2934  pos + 1 < end &&
2935  NEED_ESCAPING(pos[1]))) &&
2936  /*
2937  Don't escape field_term_char by doubling - doubling is only
2938  valid for ENCLOSED BY characters:
2939  */
2940  (enclosed || !is_ambiguous_field_term ||
2941  (int) (uchar) *pos != field_term_char))
2942  {
2943  char tmp_buff[2];
2944  tmp_buff[0]= ((int) (uchar) *pos == field_sep_char &&
2945  is_ambiguous_field_sep) ?
2946  field_sep_char : escape_char;
2947  tmp_buff[1]= *pos ? *pos : '0';
2948  if (my_b_write(&cache,(uchar*) start,(uint) (pos-start)) ||
2949  my_b_write(&cache,(uchar*) tmp_buff,2))
2950  goto err;
2951  start=pos+1;
2952  }
2953  }
2954  if (my_b_write(&cache,(uchar*) start,(uint) (pos-start)))
2955  goto err;
2956  }
2957  else if (my_b_write(&cache,(uchar*) res->ptr(),used_length))
2958  goto err;
2959  }
2960  if (fixed_row_size)
2961  { // Fill with space
2962  if (item->max_length > used_length)
2963  {
2964  /* QQ: Fix by adding a my_b_fill() function */
2965  if (!space_inited)
2966  {
2967  space_inited=1;
2968  memset(space, ' ', sizeof(space));
2969  }
2970  uint length=item->max_length-used_length;
2971  for (; length > sizeof(space) ; length-=sizeof(space))
2972  {
2973  if (my_b_write(&cache,(uchar*) space,sizeof(space)))
2974  goto err;
2975  }
2976  if (my_b_write(&cache,(uchar*) space,length))
2977  goto err;
2978  }
2979  }
2980  if (res && enclosed)
2981  {
2982  if (my_b_write(&cache, (uchar*) exchange->enclosed->ptr(),
2983  exchange->enclosed->length()))
2984  goto err;
2985  }
2986  if (--items_left)
2987  {
2988  if (my_b_write(&cache, (uchar*) exchange->field_term->ptr(),
2989  field_term_length))
2990  goto err;
2991  }
2992  }
2993  if (my_b_write(&cache,(uchar*) exchange->line_term->ptr(),
2994  exchange->line_term->length()))
2995  goto err;
2996  DBUG_RETURN(0);
2997 err:
2998  DBUG_RETURN(1);
2999 }
3000 
3001 
3002 /***************************************************************************
3003 ** Dump of select to a binary file
3004 ***************************************************************************/
3005 
3006 
3007 int
3008 select_dump::prepare(List<Item> &list __attribute__((unused)),
3009  SELECT_LEX_UNIT *u)
3010 {
3011  unit= u;
3012  return (int) ((file= create_file(thd, path, exchange, &cache)) < 0);
3013 }
3014 
3015 
3016 bool select_dump::send_data(List<Item> &items)
3017 {
3018  List_iterator_fast<Item> li(items);
3019  char buff[MAX_FIELD_WIDTH];
3020  String tmp(buff,sizeof(buff),&my_charset_bin),*res;
3021  tmp.length(0);
3022  Item *item;
3023  DBUG_ENTER("select_dump::send_data");
3024 
3025  if (unit->offset_limit_cnt)
3026  { // using limit offset,count
3027  unit->offset_limit_cnt--;
3028  DBUG_RETURN(0);
3029  }
3030  if (row_count++ > 1)
3031  {
3032  my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0));
3033  goto err;
3034  }
3035  while ((item=li++))
3036  {
3037  res=item->str_result(&tmp);
3038  if (!res) // If NULL
3039  {
3040  if (my_b_write(&cache,(uchar*) "",1))
3041  goto err;
3042  }
3043  else if (my_b_write(&cache,(uchar*) res->ptr(),res->length()))
3044  {
3045  char errbuf[MYSYS_STRERROR_SIZE];
3046  my_error(ER_ERROR_ON_WRITE, MYF(0), path, my_errno,
3047  my_strerror(errbuf, sizeof(errbuf), my_errno));
3048  goto err;
3049  }
3050  }
3051  DBUG_RETURN(0);
3052 err:
3053  DBUG_RETURN(1);
3054 }
3055 
3056 
3057 select_subselect::select_subselect(Item_subselect *item_arg)
3058 {
3059  item= item_arg;
3060 }
3061 
3062 
3063 bool select_singlerow_subselect::send_data(List<Item> &items)
3064 {
3065  DBUG_ENTER("select_singlerow_subselect::send_data");
3067  if (it->assigned())
3068  {
3069  my_message(ER_SUBQUERY_NO_1_ROW, ER(ER_SUBQUERY_NO_1_ROW), MYF(0));
3070  DBUG_RETURN(1);
3071  }
3072  if (unit->offset_limit_cnt)
3073  { // Using limit offset,count
3074  unit->offset_limit_cnt--;
3075  DBUG_RETURN(0);
3076  }
3077  List_iterator_fast<Item> li(items);
3078  Item *val_item;
3079  for (uint i= 0; (val_item= li++); i++)
3080  it->store(i, val_item);
3081  it->assigned(1);
3082  DBUG_RETURN(0);
3083 }
3084 
3085 
3086 void select_max_min_finder_subselect::cleanup()
3087 {
3088  DBUG_ENTER("select_max_min_finder_subselect::cleanup");
3089  cache= 0;
3090  DBUG_VOID_RETURN;
3091 }
3092 
3093 
3094 bool select_max_min_finder_subselect::send_data(List<Item> &items)
3095 {
3096  DBUG_ENTER("select_max_min_finder_subselect::send_data");
3098  List_iterator_fast<Item> li(items);
3099  Item *val_item= li++;
3100  it->register_value();
3101  if (it->assigned())
3102  {
3103  cache->store(val_item);
3104  if ((this->*op)())
3105  it->store(0, cache);
3106  }
3107  else
3108  {
3109  if (!cache)
3110  {
3111  cache= Item_cache::get_cache(val_item);
3112  switch (val_item->result_type())
3113  {
3114  case REAL_RESULT:
3115  op= &select_max_min_finder_subselect::cmp_real;
3116  break;
3117  case INT_RESULT:
3118  op= &select_max_min_finder_subselect::cmp_int;
3119  break;
3120  case STRING_RESULT:
3121  op= &select_max_min_finder_subselect::cmp_str;
3122  break;
3123  case DECIMAL_RESULT:
3124  op= &select_max_min_finder_subselect::cmp_decimal;
3125  break;
3126  case ROW_RESULT:
3127  // This case should never be choosen
3128  DBUG_ASSERT(0);
3129  op= 0;
3130  }
3131  }
3132  cache->store(val_item);
3133  it->store(0, cache);
3134  }
3135  it->assigned(1);
3136  DBUG_RETURN(0);
3137 }
3138 
3159 bool select_max_min_finder_subselect::cmp_real()
3160 {
3161  Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
3162  double val1= cache->val_real(), val2= maxmin->val_real();
3163  /*
3164  If we're ignoring NULLs and the current maximum/minimum is NULL
3165  (must have been placed there as the first value iterated over) and
3166  the new value is not NULL, return true so that a new, non-NULL
3167  maximum/minimum is set. Otherwise, return false to keep the
3168  current non-NULL maximum/minimum.
3169 
3170  If we're not ignoring NULLs and the current maximum/minimum is not
3171  NULL, return true to store NULL. Otherwise, return false to keep
3172  the NULL we've already got.
3173  */
3174  if (cache->null_value || maxmin->null_value)
3175  return (ignore_nulls) ? !(cache->null_value) : !(maxmin->null_value);
3176  return (fmax) ? (val1 > val2) : (val1 < val2);
3177 }
3178 
3184 bool select_max_min_finder_subselect::cmp_int()
3185 {
3186  Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
3187  longlong val1= cache->val_int(), val2= maxmin->val_int();
3188  if (cache->null_value || maxmin->null_value)
3189  return (ignore_nulls) ? !(cache->null_value) : !(maxmin->null_value);
3190  return (fmax) ? (val1 > val2) : (val1 < val2);
3191 }
3192 
3198 bool select_max_min_finder_subselect::cmp_decimal()
3199 {
3200  Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
3201  my_decimal cval, *cvalue= cache->val_decimal(&cval);
3202  my_decimal mval, *mvalue= maxmin->val_decimal(&mval);
3203  if (cache->null_value || maxmin->null_value)
3204  return (ignore_nulls) ? !(cache->null_value) : !(maxmin->null_value);
3205  return (fmax)
3206  ? (my_decimal_cmp(cvalue,mvalue) > 0)
3207  : (my_decimal_cmp(cvalue,mvalue) < 0);
3208 }
3209 
3215 bool select_max_min_finder_subselect::cmp_str()
3216 {
3217  String *val1, *val2, buf1, buf2;
3218  Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
3219  /*
3220  as far as both operand is Item_cache buf1 & buf2 will not be used,
3221  but added for safety
3222  */
3223  val1= cache->val_str(&buf1);
3224  val2= maxmin->val_str(&buf1);
3225  if (cache->null_value || maxmin->null_value)
3226  return (ignore_nulls) ? !(cache->null_value) : !(maxmin->null_value);
3227  return (fmax)
3228  ? (sortcmp(val1, val2, cache->collation.collation) > 0)
3229  : (sortcmp(val1, val2, cache->collation.collation) < 0);
3230 }
3231 
3232 bool select_exists_subselect::send_data(List<Item> &items)
3233 {
3234  DBUG_ENTER("select_exists_subselect::send_data");
3236  if (unit->offset_limit_cnt)
3237  { // Using limit offset,count
3238  unit->offset_limit_cnt--;
3239  DBUG_RETURN(0);
3240  }
3241  /*
3242  A subquery may be evaluated 1) by executing the JOIN 2) by optimized
3243  functions (index_subquery, subquery materialization).
3244  It's only in (1) that we get here when we find a row. In (2) "value" is
3245  set elsewhere.
3246  */
3247  it->value= 1;
3248  it->assigned(1);
3249  DBUG_RETURN(0);
3250 }
3251 
3252 
3253 /***************************************************************************
3254  Dump of select to variables
3255 ***************************************************************************/
3256 
3257 int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
3258 {
3259  unit= u;
3260 
3261  if (var_list.elements != list.elements)
3262  {
3263  my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
3264  ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT), MYF(0));
3265  return 1;
3266  }
3267 
3268  return 0;
3269 }
3270 
3271 
3273 {
3274  my_error(ER_SP_BAD_CURSOR_SELECT, MYF(0));
3275  return TRUE;
3276 }
3277 
3278 
3279 void select_dumpvar::cleanup()
3280 {
3281  row_count= 0;
3282 }
3283 
3284 
3285 Query_arena::Type Query_arena::type() const
3286 {
3287  DBUG_ASSERT(0); /* Should never be called */
3288  return STATEMENT;
3289 }
3290 
3291 
3292 void Query_arena::free_items()
3293 {
3294  Item *next;
3295  DBUG_ENTER("Query_arena::free_items");
3296  /* This works because items are allocated with sql_alloc() */
3297  for (; free_list; free_list= next)
3298  {
3299  next= free_list->next;
3300  free_list->delete_self();
3301  }
3302  /* Postcondition: free_list is 0 */
3303  DBUG_VOID_RETURN;
3304 }
3305 
3306 
3307 void Query_arena::set_query_arena(Query_arena *set)
3308 {
3309  mem_root= set->mem_root;
3310  free_list= set->free_list;
3311  state= set->state;
3312 }
3313 
3314 
3315 void Query_arena::cleanup_stmt()
3316 {
3317  DBUG_ASSERT(! "Query_arena::cleanup_stmt() not implemented");
3318 }
3319 
3320 /*
3321  Statement functions
3322 */
3323 
3324 Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg,
3325  enum enum_state state_arg, ulong id_arg)
3326  :Query_arena(mem_root_arg, state_arg),
3327  id(id_arg),
3328  mark_used_columns(MARK_COLUMNS_READ),
3329  lex(lex_arg),
3330  db(NULL),
3331  db_length(0)
3332 {
3333  name.str= NULL;
3334 }
3335 
3336 
3337 Query_arena::Type Statement::type() const
3338 {
3339  return STATEMENT;
3340 }
3341 
3342 
3343 void Statement::set_statement(Statement *stmt)
3344 {
3345  id= stmt->id;
3346  mark_used_columns= stmt->mark_used_columns;
3347  lex= stmt->lex;
3348  query_string= stmt->query_string;
3349 }
3350 
3351 
3352 void
3353 Statement::set_n_backup_statement(Statement *stmt, Statement *backup)
3354 {
3355  DBUG_ENTER("Statement::set_n_backup_statement");
3356  backup->set_statement(this);
3357  set_statement(stmt);
3358  DBUG_VOID_RETURN;
3359 }
3360 
3361 
3362 void Statement::restore_backup_statement(Statement *stmt, Statement *backup)
3363 {
3364  DBUG_ENTER("Statement::restore_backup_statement");
3365  stmt->set_statement(this);
3366  set_statement(backup);
3367  DBUG_VOID_RETURN;
3368 }
3369 
3370 
3371 void THD::end_statement()
3372 {
3373  /* Cleanup SQL processing state to reuse this statement in next query. */
3374  lex_end(lex);
3375  delete lex->result;
3376  lex->result= 0;
3377  /* Note that free_list is freed in cleanup_after_query() */
3378 
3379  /*
3380  Don't free mem_root, as mem_root is freed in the end of dispatch_command
3381  (once for any command).
3382  */
3383 }
3384 
3385 
3386 void THD::set_n_backup_active_arena(Query_arena *set, Query_arena *backup)
3387 {
3388  DBUG_ENTER("THD::set_n_backup_active_arena");
3389  DBUG_ASSERT(backup->is_backup_arena == FALSE);
3390 
3391  backup->set_query_arena(this);
3392  set_query_arena(set);
3393 #ifndef DBUG_OFF
3394  backup->is_backup_arena= TRUE;
3395 #endif
3396  DBUG_VOID_RETURN;
3397 }
3398 
3399 
3400 void THD::restore_active_arena(Query_arena *set, Query_arena *backup)
3401 {
3402  DBUG_ENTER("THD::restore_active_arena");
3403  DBUG_ASSERT(backup->is_backup_arena);
3404  set->set_query_arena(this);
3405  set_query_arena(backup);
3406 #ifndef DBUG_OFF
3407  backup->is_backup_arena= FALSE;
3408 #endif
3409  DBUG_VOID_RETURN;
3410 }
3411 
3412 Statement::~Statement()
3413 {
3414 }
3415 
3416 C_MODE_START
3417 
3418 static uchar *
3419 get_statement_id_as_hash_key(const uchar *record, size_t *key_length,
3420  my_bool not_used __attribute__((unused)))
3421 {
3422  const Statement *statement= (const Statement *) record;
3423  *key_length= sizeof(statement->id);
3424  return (uchar *) &((const Statement *) statement)->id;
3425 }
3426 
3427 static void delete_statement_as_hash_key(void *key)
3428 {
3429  delete (Statement *) key;
3430 }
3431 
3432 static uchar *get_stmt_name_hash_key(Statement *entry, size_t *length,
3433  my_bool not_used __attribute__((unused)))
3434 {
3435  *length= entry->name.length;
3436  return (uchar*) entry->name.str;
3437 }
3438 
3439 C_MODE_END
3440 
3441 Statement_map::Statement_map() :
3442  last_found_statement(0)
3443 {
3444  enum
3445  {
3446  START_STMT_HASH_SIZE = 16,
3447  START_NAME_HASH_SIZE = 16
3448  };
3449  my_hash_init(&st_hash, &my_charset_bin, START_STMT_HASH_SIZE, 0, 0,
3450  get_statement_id_as_hash_key,
3451  delete_statement_as_hash_key, MYF(0));
3452  my_hash_init(&names_hash, system_charset_info, START_NAME_HASH_SIZE, 0, 0,
3453  (my_hash_get_key) get_stmt_name_hash_key,
3454  NULL,MYF(0));
3455 }
3456 
3457 
3458 /*
3459  Insert a new statement to the thread-local statement map.
3460 
3461  DESCRIPTION
3462  If there was an old statement with the same name, replace it with the
3463  new one. Otherwise, check if max_prepared_stmt_count is not reached yet,
3464  increase prepared_stmt_count, and insert the new statement. It's okay
3465  to delete an old statement and fail to insert the new one.
3466 
3467  POSTCONDITIONS
3468  All named prepared statements are also present in names_hash.
3469  Statement names in names_hash are unique.
3470  The statement is added only if prepared_stmt_count < max_prepard_stmt_count
3471  last_found_statement always points to a valid statement or is 0
3472 
3473  RETURN VALUE
3474  0 success
3475  1 error: out of resources or max_prepared_stmt_count limit has been
3476  reached. An error is sent to the client, the statement is deleted.
3477 */
3478 
3479 int Statement_map::insert(THD *thd, Statement *statement)
3480 {
3481  if (my_hash_insert(&st_hash, (uchar*) statement))
3482  {
3483  /*
3484  Delete is needed only in case of an insert failure. In all other
3485  cases hash_delete will also delete the statement.
3486  */
3487  delete statement;
3488  my_error(ER_OUT_OF_RESOURCES, MYF(0));
3489  goto err_st_hash;
3490  }
3491  if (statement->name.str && my_hash_insert(&names_hash, (uchar*) statement))
3492  {
3493  my_error(ER_OUT_OF_RESOURCES, MYF(0));
3494  goto err_names_hash;
3495  }
3496  mysql_mutex_lock(&LOCK_prepared_stmt_count);
3497  /*
3498  We don't check that prepared_stmt_count is <= max_prepared_stmt_count
3499  because we would like to allow to lower the total limit
3500  of prepared statements below the current count. In that case
3501  no new statements can be added until prepared_stmt_count drops below
3502  the limit.
3503  */
3504  if (prepared_stmt_count >= max_prepared_stmt_count)
3505  {
3506  mysql_mutex_unlock(&LOCK_prepared_stmt_count);
3507  my_error(ER_MAX_PREPARED_STMT_COUNT_REACHED, MYF(0),
3508  max_prepared_stmt_count);
3509  goto err_max;
3510  }
3511  prepared_stmt_count++;
3512  mysql_mutex_unlock(&LOCK_prepared_stmt_count);
3513 
3514  last_found_statement= statement;
3515  return 0;
3516 
3517 err_max:
3518  if (statement->name.str)
3519  my_hash_delete(&names_hash, (uchar*) statement);
3520 err_names_hash:
3521  my_hash_delete(&st_hash, (uchar*) statement);
3522 err_st_hash:
3523  return 1;
3524 }
3525 
3526 
3527 void Statement_map::close_transient_cursors()
3528 {
3529 #ifdef TO_BE_IMPLEMENTED
3530  Statement *stmt;
3531  while ((stmt= transient_cursor_list.head()))
3532  stmt->close_cursor(); /* deletes itself from the list */
3533 #endif
3534 }
3535 
3536 
3537 void Statement_map::erase(Statement *statement)
3538 {
3539  if (statement == last_found_statement)
3540  last_found_statement= 0;
3541  if (statement->name.str)
3542  my_hash_delete(&names_hash, (uchar *) statement);
3543 
3544  my_hash_delete(&st_hash, (uchar *) statement);
3545  mysql_mutex_lock(&LOCK_prepared_stmt_count);
3546  DBUG_ASSERT(prepared_stmt_count > 0);
3547  prepared_stmt_count--;
3548  mysql_mutex_unlock(&LOCK_prepared_stmt_count);
3549 }
3550 
3551 
3552 void Statement_map::reset()
3553 {
3554  /* Must be first, hash_free will reset st_hash.records */
3555  mysql_mutex_lock(&LOCK_prepared_stmt_count);
3556  DBUG_ASSERT(prepared_stmt_count >= st_hash.records);
3557  prepared_stmt_count-= st_hash.records;
3558  mysql_mutex_unlock(&LOCK_prepared_stmt_count);
3559 
3560  my_hash_reset(&names_hash);
3561  my_hash_reset(&st_hash);
3562  last_found_statement= 0;
3563 }
3564 
3565 
3566 Statement_map::~Statement_map()
3567 {
3568  /*
3569  We do not want to grab the global LOCK_prepared_stmt_count mutex here.
3570  reset() should already have been called to maintain prepared_stmt_count.
3571  */
3572  DBUG_ASSERT(st_hash.records == 0);
3573 
3574  my_hash_free(&names_hash);
3575  my_hash_free(&st_hash);
3576 }
3577 
3578 bool select_dumpvar::send_data(List<Item> &items)
3579 {
3580  List_iterator_fast<my_var> var_li(var_list);
3581  List_iterator<Item> it(items);
3582  Item *item;
3583  my_var *mv;
3584  DBUG_ENTER("select_dumpvar::send_data");
3585 
3586  if (unit->offset_limit_cnt)
3587  { // using limit offset,count
3588  unit->offset_limit_cnt--;
3589  DBUG_RETURN(false);
3590  }
3591  if (row_count++)
3592  {
3593  my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0));
3594  DBUG_RETURN(true);
3595  }
3596  while ((mv= var_li++) && (item= it++))
3597  {
3598  if (mv->local)
3599  {
3600  if (thd->sp_runtime_ctx->set_variable(thd, mv->offset, &item))
3601  DBUG_RETURN(true);
3602  }
3603  else
3604  {
3605  /*
3606  Create Item_func_set_user_vars with delayed non-constness. We
3607  do this so that Item_get_user_var::const_item() will return
3608  the same result during
3609  Item_func_set_user_var::save_item_result() as they did during
3610  optimization and execution.
3611  */
3613  new Item_func_set_user_var(mv->s, item, true);
3614  if (suv->fix_fields(thd, 0))
3615  DBUG_RETURN(true);
3616  suv->save_item_result(item);
3617  if (suv->update())
3618  DBUG_RETURN(true);
3619  }
3620  }
3621  DBUG_RETURN(thd->is_error());
3622 }
3623 
3624 bool select_dumpvar::send_eof()
3625 {
3626  if (! row_count)
3627  push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
3628  ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA));
3629  /*
3630  Don't send EOF if we're in error condition (which implies we've already
3631  sent or are sending an error)
3632  */
3633  if (thd->is_error())
3634  return true;
3635 
3636  ::my_ok(thd,row_count);
3637  return 0;
3638 }
3639 
3640 /****************************************************************************
3641  TMP_TABLE_PARAM
3642 ****************************************************************************/
3643 
3644 void TMP_TABLE_PARAM::init()
3645 {
3646  DBUG_ENTER("TMP_TABLE_PARAM::init");
3647  DBUG_PRINT("enter", ("this: 0x%lx", (ulong)this));
3648  field_count= sum_func_count= func_count= hidden_field_count= 0;
3649  group_parts= group_length= group_null_parts= 0;
3650  quick_group= 1;
3651  table_charset= 0;
3652  precomputed_group_by= 0;
3653  skip_create_table= 0;
3654  bit_fields_as_long= 0;
3655  recinfo= 0;
3656  start_recinfo= 0;
3657  keyinfo= 0;
3658  DBUG_VOID_RETURN;
3659 }
3660 
3661 
3662 void thd_increment_bytes_sent(ulong length)
3663 {
3664  THD *thd=current_thd;
3665  if (likely(thd != 0))
3666  { /* current_thd==0 when close_connection() calls net_send_error() */
3667  thd->status_var.bytes_sent+= length;
3668  }
3669 }
3670 
3671 
3672 void thd_increment_bytes_received(ulong length)
3673 {
3674  current_thd->status_var.bytes_received+= length;
3675 }
3676 
3677 
3678 void THD::set_status_var_init()
3679 {
3680  memset(&status_var, 0, sizeof(status_var));
3681 }
3682 
3683 
3684 void Security_context::init()
3685 {
3686  user= 0;
3687  ip.set("", 0, system_charset_info);
3688  host.set("", 0, system_charset_info);
3689  external_user.set("", 0, system_charset_info);
3690  host_or_ip= "connecting host";
3691  priv_user[0]= priv_host[0]= proxy_user[0]= '\0';
3692  master_access= 0;
3693 #ifndef NO_EMBEDDED_ACCESS_CHECKS
3694  db_access= NO_ACCESS;
3695 #endif
3696  password_expired= false;
3697 }
3698 
3699 void Security_context::destroy()
3700 {
3701  if (host.ptr() != my_localhost && host.length())
3702  {
3703  char *c= (char *) host.ptr();
3704  host.set("", 0, system_charset_info);
3705  my_free(c);
3706  }
3707 
3708  if (user && user != delayed_user)
3709  {
3710  my_free(user);
3711  user= NULL;
3712  }
3713 
3714  if (external_user.length())
3715  {
3716  char *c= (char *) external_user.ptr();
3717  external_user.set("", 0, system_charset_info);
3718  my_free(c);
3719  }
3720 
3721  if (ip.length())
3722  {
3723  char *c= (char *) ip.ptr();
3724  ip.set("", 0, system_charset_info);
3725  my_free(c);
3726  }
3727 
3728 }
3729 
3730 
3731 void Security_context::skip_grants()
3732 {
3733  /* privileges for the user are unknown everything is allowed */
3734  host_or_ip= (char *)"";
3735  master_access= ~NO_ACCESS;
3736  *priv_user= *priv_host= '\0';
3737 }
3738 
3739 
3740 bool Security_context::set_user(char *user_arg)
3741 {
3742  my_free(user);
3743  user= my_strdup(user_arg, MYF(0));
3744  return user == 0;
3745 }
3746 
3747 String *Security_context::get_host()
3748 {
3749  return (&host);
3750 }
3751 
3752 String *Security_context::get_ip()
3753 {
3754  return (&ip);
3755 }
3756 
3757 String *Security_context::get_external_user()
3758 {
3759  return (&external_user);
3760 }
3761 
3762 void Security_context::set_host(const char *str)
3763 {
3764  uint len= str ? strlen(str) : 0;
3765  host.set(str, len, system_charset_info);
3766 }
3767 
3768 void Security_context::set_ip(const char *str)
3769 {
3770  uint len= str ? strlen(str) : 0;
3771  ip.set(str, len, system_charset_info);
3772 }
3773 
3774 void Security_context::set_external_user(const char *str)
3775 {
3776  uint len= str ? strlen(str) : 0;
3777  external_user.set(str, len, system_charset_info);
3778 }
3779 
3780 void Security_context::set_host(const char * str, size_t len)
3781 {
3782  host.set(str, len, system_charset_info);
3783  host.c_ptr_quick();
3784 }
3785 
3786 #ifndef NO_EMBEDDED_ACCESS_CHECKS
3787 
3836 bool
3837 Security_context::
3838 change_security_context(THD *thd,
3839  LEX_STRING *definer_user,
3840  LEX_STRING *definer_host,
3841  LEX_STRING *db,
3842  Security_context **backup)
3843 {
3844  bool needs_change;
3845 
3846  DBUG_ENTER("Security_context::change_security_context");
3847 
3848  DBUG_ASSERT(definer_user->str && definer_host->str);
3849 
3850  *backup= NULL;
3851  needs_change= (strcmp(definer_user->str, thd->security_ctx->priv_user) ||
3852  my_strcasecmp(system_charset_info, definer_host->str,
3853  thd->security_ctx->priv_host));
3854  if (needs_change)
3855  {
3856  if (acl_getroot(this, definer_user->str, definer_host->str,
3857  definer_host->str, db->str))
3858  {
3859  my_error(ER_NO_SUCH_USER, MYF(0), definer_user->str,
3860  definer_host->str);
3861  DBUG_RETURN(TRUE);
3862  }
3863  *backup= thd->security_ctx;
3864  thd->security_ctx= this;
3865  }
3866 
3867  DBUG_RETURN(FALSE);
3868 }
3869 
3870 
3871 void
3872 Security_context::restore_security_context(THD *thd,
3873  Security_context *backup)
3874 {
3875  if (backup)
3876  thd->security_ctx= backup;
3877 }
3878 #endif
3879 
3880 
3881 bool Security_context::user_matches(Security_context *them)
3882 {
3883  return ((user != NULL) && (them->user != NULL) &&
3884  !strcmp(user, them->user));
3885 }
3886 
3887 
3888 void Log_throttle::new_window(ulonglong now)
3889 {
3890  count= 0;
3891  window_end= now + window_size;
3892 }
3893 
3894 
3895 void Slow_log_throttle::new_window(ulonglong now)
3896 {
3897  Log_throttle::new_window(now);
3898  total_exec_time= 0;
3899  total_lock_time= 0;
3900 }
3901 
3902 
3903 Slow_log_throttle::Slow_log_throttle(ulong *threshold, mysql_mutex_t *lock,
3904  ulong window_usecs,
3905  bool (*logger)(THD *, const char *, uint),
3906  const char *msg)
3907  : Log_throttle(window_usecs, msg), total_exec_time(0), total_lock_time(0),
3908  rate(threshold), log_summary(logger), LOCK_log_throttle(lock)
3909 {
3910  aggregate_sctx.init();
3911 }
3912 
3913 
3914 ulong Log_throttle::prepare_summary(ulong rate)
3915 {
3916  ulong ret= 0;
3917  /*
3918  Previous throttling window is over or rate changed.
3919  Return the number of lines we throttled.
3920  */
3921  if (count > rate)
3922  {
3923  ret= count - rate;
3924  count= 0; // prevent writing it again.
3925  }
3926 
3927  return ret;
3928 }
3929 
3930 
3931 void Slow_log_throttle::print_summary(THD *thd, ulong suppressed,
3932  ulonglong print_lock_time,
3933  ulonglong print_exec_time)
3934 {
3935  /*
3936  We synthesize these values so the totals in the log will be
3937  correct (just in case somebody analyses them), even if the
3938  start/stop times won't be (as they're an aggregate which will
3939  usually mostly lie within [ window_end - window_size ; window_end ]
3940  */
3941  ulonglong save_start_utime= thd->start_utime;
3942  ulonglong save_utime_after_lock= thd->utime_after_lock;
3943  Security_context *save_sctx= thd->security_ctx;
3944 
3945  char buf[128];
3946 
3947  snprintf(buf, sizeof(buf), summary_template, suppressed);
3948 
3949  mysql_mutex_lock(&thd->LOCK_thd_data);
3950  thd->start_utime= thd->current_utime() - print_exec_time;
3951  thd->utime_after_lock= thd->start_utime + print_lock_time;
3952  thd->security_ctx= (Security_context *) &aggregate_sctx;
3953  mysql_mutex_unlock(&thd->LOCK_thd_data);
3954 
3955  (*log_summary)(thd, buf, strlen(buf));
3956 
3957  mysql_mutex_lock(&thd->LOCK_thd_data);
3958  thd->security_ctx = save_sctx;
3959  thd->start_utime = save_start_utime;
3960  thd->utime_after_lock= save_utime_after_lock;
3961  mysql_mutex_unlock(&thd->LOCK_thd_data);
3962 }
3963 
3964 
3965 bool Slow_log_throttle::flush(THD *thd)
3966 {
3967  // Write summary if we throttled.
3968  mysql_mutex_lock(LOCK_log_throttle);
3969  ulonglong print_lock_time= total_lock_time;
3970  ulonglong print_exec_time= total_exec_time;
3971  ulong suppressed_count= prepare_summary(*rate);
3972  mysql_mutex_unlock(LOCK_log_throttle);
3973  if (suppressed_count > 0)
3974  {
3975  print_summary(thd, suppressed_count, print_lock_time, print_exec_time);
3976  return true;
3977  }
3978  return false;
3979 }
3980 
3981 
3982 bool Slow_log_throttle::log(THD *thd, bool eligible)
3983 {
3984  bool suppress_current= false;
3985 
3986  /*
3987  If throttling is enabled, we might have to write a summary even if
3988  the current query is not of the type we handle.
3989  */
3990  if (*rate > 0)
3991  {
3992  mysql_mutex_lock(LOCK_log_throttle);
3993 
3994  ulong suppressed_count= 0;
3995  ulonglong print_lock_time= total_lock_time;
3996  ulonglong print_exec_time= total_exec_time;
3997  ulonglong end_utime_of_query= thd->current_utime();
3998 
3999  /*
4000  If the window has expired, we'll try to write a summary line.
4001  The subroutine will know whether we actually need to.
4002  */
4003  if (!in_window(end_utime_of_query))
4004  {
4005  suppressed_count= prepare_summary(*rate);
4006  // start new window only if this is the statement type we handle
4007  if (eligible)
4008  new_window(end_utime_of_query);
4009  }
4010  if (eligible && inc_log_count(*rate))
4011  {
4012  /*
4013  Current query's logging should be suppressed.
4014  Add its execution time and lock time to totals for the current window.
4015  */
4016  total_exec_time += (end_utime_of_query - thd->start_utime);
4017  total_lock_time += (thd->utime_after_lock - thd->start_utime);
4018  suppress_current= true;
4019  }
4020 
4021  mysql_mutex_unlock(LOCK_log_throttle);
4022 
4023  /*
4024  print_summary() is deferred until after we release the locks to
4025  avoid congestion. All variables we hand in are local to the caller,
4026  so things would even be safe if print_summary() hadn't finished by the
4027  time the next one comes around (60s later at the earliest for now).
4028  The current design will produce correct data, but does not guarantee
4029  order (there is a theoretical race condition here where the above
4030  new_window()/unlock() may enable a different thread to print a warning
4031  for the new window before the current thread gets to print_summary().
4032  If the requirements ever change, add a print_lock to the object that
4033  is held during print_summary(), AND that is briefly locked before
4034  returning from this function if(eligible && !suppress_current).
4035  This should ensure correct ordering of summaries with regard to any
4036  follow-up summaries as well as to any (non-suppressed) warnings (of
4037  the type we handle) from the next window.
4038  */
4039  if (suppressed_count > 0)
4040  print_summary(thd, suppressed_count, print_lock_time, print_exec_time);
4041  }
4042 
4043  return suppress_current;
4044 }
4045 
4046 
4047 bool Error_log_throttle::log(THD *thd)
4048 {
4049  ulonglong end_utime_of_query= thd->current_utime();
4050 
4051  /*
4052  If the window has expired, we'll try to write a summary line.
4053  The subroutine will know whether we actually need to.
4054  */
4055  if (!in_window(end_utime_of_query))
4056  {
4057  ulong suppressed_count= prepare_summary(1);
4058 
4059  new_window(end_utime_of_query);
4060 
4061  if (suppressed_count > 0)
4062  print_summary(suppressed_count);
4063  }
4064 
4065  /*
4066  If this is a first error in the current window then do not suppress it.
4067  */
4068  return inc_log_count(1);
4069 }
4070 
4071 
4072 bool Error_log_throttle::flush(THD *thd)
4073 {
4074  // Write summary if we throttled.
4075  ulong suppressed_count= prepare_summary(1);
4076  if (suppressed_count > 0)
4077  {
4078  print_summary(suppressed_count);
4079  return true;
4080  }
4081  return false;
4082 }
4083 
4084 
4085 /****************************************************************************
4086  Handling of open and locked tables states.
4087 
4088  This is used when we want to open/lock (and then close) some tables when
4089  we already have a set of tables open and locked. We use these methods for
4090  access to mysql.proc table to find definitions of stored routines.
4091 ****************************************************************************/
4092 
4093 void THD::reset_n_backup_open_tables_state(Open_tables_backup *backup)
4094 {
4095  DBUG_ENTER("reset_n_backup_open_tables_state");
4096  backup->set_open_tables_state(this);
4097  backup->mdl_system_tables_svp= mdl_context.mdl_savepoint();
4098  reset_open_tables_state();
4099  state_flags|= Open_tables_state::BACKUPS_AVAIL;
4100  DBUG_VOID_RETURN;
4101 }
4102 
4103 
4104 void THD::restore_backup_open_tables_state(Open_tables_backup *backup)
4105 {
4106  DBUG_ENTER("restore_backup_open_tables_state");
4107  mdl_context.rollback_to_savepoint(backup->mdl_system_tables_svp);
4108  /*
4109  Before we will throw away current open tables state we want
4110  to be sure that it was properly cleaned up.
4111  */
4112  DBUG_ASSERT(open_tables == 0 && temporary_tables == 0 &&
4113  derived_tables == 0 &&
4114  lock == 0 &&
4115  locked_tables_mode == LTM_NONE &&
4116  get_reprepare_observer() == NULL);
4117 
4118  set_open_tables_state(backup);
4119  DBUG_VOID_RETURN;
4120 }
4121 
4128 extern "C" int thd_killed(const MYSQL_THD thd)
4129 {
4130  return(thd->killed);
4131 }
4132 
4138 extern "C" unsigned long thd_get_thread_id(const MYSQL_THD thd)
4139 {
4140  return((unsigned long)thd->thread_id);
4141 }
4142 
4149 extern "C" int thd_allow_batch(MYSQL_THD thd)
4150 {
4151  if ((thd->variables.option_bits & OPTION_ALLOW_BATCH) ||
4152  (thd->slave_thread && opt_slave_allow_batching))
4153  return 1;
4154  return 0;
4155 }
4156 
4157 enum_tx_isolation thd_get_trx_isolation(const MYSQL_THD thd)
4158 {
4159  return thd->tx_isolation;
4160 }
4161 
4162 #ifdef INNODB_COMPATIBILITY_HOOKS
4163 extern "C" const struct charset_info_st *thd_charset(MYSQL_THD thd)
4164 {
4165  return(thd->charset());
4166 }
4167 
4172 extern "C" char **thd_query(MYSQL_THD thd)
4173 {
4174  return (&thd->query_string.string.str);
4175 }
4176 
4183 extern "C" LEX_STRING * thd_query_string (MYSQL_THD thd)
4184 {
4185  return(&thd->query_string.string);
4186 }
4187 
4188 extern "C" int thd_slave_thread(const MYSQL_THD thd)
4189 {
4190  return(thd->slave_thread);
4191 }
4192 
4193 extern "C" int thd_non_transactional_update(const MYSQL_THD thd)
4194 {
4195  return thd->transaction.all.has_modified_non_trans_table();
4196 }
4197 
4198 extern "C" int thd_binlog_format(const MYSQL_THD thd)
4199 {
4200  if (mysql_bin_log.is_open() && (thd->variables.option_bits & OPTION_BIN_LOG))
4201  return (int) thd->variables.binlog_format;
4202  else
4203  return BINLOG_FORMAT_UNSPEC;
4204 }
4205 
4206 extern "C" void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all)
4207 {
4208  mark_transaction_to_rollback(thd, all);
4209 }
4210 
4211 extern "C" bool thd_binlog_filter_ok(const MYSQL_THD thd)
4212 {
4213  return binlog_filter->db_ok(thd->db);
4214 }
4215 
4216 extern "C" bool thd_sqlcom_can_generate_row_events(const MYSQL_THD thd)
4217 {
4218  return sqlcom_can_generate_row_events(thd);
4219 }
4220 
4221 extern "C" enum durability_properties thd_get_durability_property(const MYSQL_THD thd)
4222 {
4223  enum durability_properties ret= HA_REGULAR_DURABILITY;
4224 
4225  if (thd != NULL)
4226  ret= thd->durability_property;
4227 
4228  return ret;
4229 }
4230 
4236 extern "C" void thd_get_autoinc(const MYSQL_THD thd, ulong* off, ulong* inc)
4237 {
4238  *off = thd->variables.auto_increment_offset;
4239  *inc = thd->variables.auto_increment_increment;
4240 }
4241 
4242 
4251 extern "C" bool thd_is_strict_mode(const MYSQL_THD thd)
4252 {
4253  return thd->is_strict_mode();
4254 }
4255 
4256 
4257 #ifndef EMBEDDED_LIBRARY
4258 extern "C" void thd_pool_wait_begin(MYSQL_THD thd, int wait_type);
4259 extern "C" void thd_pool_wait_end(MYSQL_THD thd);
4260 
4261 /*
4262  Interface for MySQL Server, plugins and storage engines to report
4263  when they are going to sleep/stall.
4264 
4265  SYNOPSIS
4266  thd_wait_begin()
4267  thd Thread object
4268  wait_type Type of wait
4269  1 -- short wait (e.g. for mutex)
4270  2 -- medium wait (e.g. for disk io)
4271  3 -- large wait (e.g. for locked row/table)
4272  NOTES
4273  This is used by the threadpool to have better knowledge of which
4274  threads that currently are actively running on CPUs. When a thread
4275  reports that it's going to sleep/stall, the threadpool scheduler is
4276  free to start another thread in the pool most likely. The expected wait
4277  time is simply an indication of how long the wait is expected to
4278  become, the real wait time could be very different.
4279 
4280  thd_wait_end MUST be called immediately after waking up again.
4281 */
4282 extern "C" void thd_wait_begin(MYSQL_THD thd, int wait_type)
4283 {
4284  MYSQL_CALLBACK(thread_scheduler, thd_wait_begin, (thd, wait_type));
4285 }
4286 
4293 extern "C" void thd_wait_end(MYSQL_THD thd)
4294 {
4295  MYSQL_CALLBACK(thread_scheduler, thd_wait_end, (thd));
4296 }
4297 #else
4298 extern "C" void thd_wait_begin(MYSQL_THD thd, int wait_type)
4299 {
4300  /* do NOTHING for the embedded library */
4301  return;
4302 }
4303 
4304 extern "C" void thd_wait_end(MYSQL_THD thd)
4305 {
4306  /* do NOTHING for the embedded library */
4307  return;
4308 }
4309 #endif
4310 #endif // INNODB_COMPATIBILITY_HOOKS */
4311 
4312 /****************************************************************************
4313  Handling of statement states in functions and triggers.
4314 
4315  This is used to ensure that the function/trigger gets a clean state
4316  to work with and does not cause any side effects of the calling statement.
4317 
4318  It also allows most stored functions and triggers to replicate even
4319  if they are used items that would normally be stored in the binary
4320  replication (like last_insert_id() etc...)
4321 
4322  The following things is done
4323  - Disable binary logging for the duration of the statement
4324  - Disable multi-result-sets for the duration of the statement
4325  - Value of last_insert_id() is saved and restored
4326  - Value set by 'SET INSERT_ID=#' is reset and restored
4327  - Value for found_rows() is reset and restored
4328  - examined_row_count is added to the total
4329  - cuted_fields is added to the total
4330  - new savepoint level is created and destroyed
4331 
4332  NOTES:
4333  Seed for random() is saved for the first! usage of RAND()
4334  We reset examined_row_count and cuted_fields and add these to the
4335  result to ensure that if we have a bug that would reset these within
4336  a function, we are not loosing any rows from the main statement.
4337 
4338  We do not reset value of last_insert_id().
4339 ****************************************************************************/
4340 
4341 void THD::reset_sub_statement_state(Sub_statement_state *backup,
4342  uint new_state)
4343 {
4344 #ifndef EMBEDDED_LIBRARY
4345  /* BUG#33029, if we are replicating from a buggy master, reset
4346  auto_inc_intervals_forced to prevent substatement
4347  (triggers/functions) from using erroneous INSERT_ID value
4348  */
4349  if (rpl_master_erroneous_autoinc(this))
4350  {
4351  DBUG_ASSERT(backup->auto_inc_intervals_forced.nb_elements() == 0);
4352  auto_inc_intervals_forced.swap(&backup->auto_inc_intervals_forced);
4353  }
4354 #endif
4355 
4356  backup->option_bits= variables.option_bits;
4357  backup->count_cuted_fields= count_cuted_fields;
4358  backup->in_sub_stmt= in_sub_stmt;
4359  backup->enable_slow_log= enable_slow_log;
4360  backup->limit_found_rows= limit_found_rows;
4361  backup->examined_row_count= m_examined_row_count;
4362  backup->sent_row_count= m_sent_row_count;
4363  backup->cuted_fields= cuted_fields;
4364  backup->client_capabilities= client_capabilities;
4365  backup->savepoints= transaction.savepoints;
4366  backup->first_successful_insert_id_in_prev_stmt=
4367  first_successful_insert_id_in_prev_stmt;
4368  backup->first_successful_insert_id_in_cur_stmt=
4369  first_successful_insert_id_in_cur_stmt;
4370 
4371  if ((!lex->requires_prelocking() || is_update_query(lex->sql_command)) &&
4372  !is_current_stmt_binlog_format_row())
4373  {
4374  variables.option_bits&= ~OPTION_BIN_LOG;
4375  }
4376 
4377  if ((backup->option_bits & OPTION_BIN_LOG) &&
4378  is_update_query(lex->sql_command) &&
4379  !is_current_stmt_binlog_format_row())
4380  mysql_bin_log.start_union_events(this, this->query_id);
4381 
4382  /* Disable result sets */
4383  client_capabilities &= ~CLIENT_MULTI_RESULTS;
4384  in_sub_stmt|= new_state;
4385  m_examined_row_count= 0;
4386  m_sent_row_count= 0;
4387  cuted_fields= 0;
4388  transaction.savepoints= 0;
4389  first_successful_insert_id_in_cur_stmt= 0;
4390 }
4391 
4392 
4393 void THD::restore_sub_statement_state(Sub_statement_state *backup)
4394 {
4395  DBUG_ENTER("THD::restore_sub_statement_state");
4396 #ifndef EMBEDDED_LIBRARY
4397  /* BUG#33029, if we are replicating from a buggy master, restore
4398  auto_inc_intervals_forced so that the top statement can use the
4399  INSERT_ID value set before this statement.
4400  */
4401  if (rpl_master_erroneous_autoinc(this))
4402  {
4403  backup->auto_inc_intervals_forced.swap(&auto_inc_intervals_forced);
4404  DBUG_ASSERT(backup->auto_inc_intervals_forced.nb_elements() == 0);
4405  }
4406 #endif
4407 
4408  /*
4409  To save resources we want to release savepoints which were created
4410  during execution of function or trigger before leaving their savepoint
4411  level. It is enough to release first savepoint set on this level since
4412  all later savepoints will be released automatically.
4413  */
4414  if (transaction.savepoints)
4415  {
4416  SAVEPOINT *sv;
4417  for (sv= transaction.savepoints; sv->prev; sv= sv->prev)
4418  {}
4419  /* ha_release_savepoint() never returns error. */
4420  (void)ha_release_savepoint(this, sv);
4421  }
4422  count_cuted_fields= backup->count_cuted_fields;
4423  transaction.savepoints= backup->savepoints;
4424  variables.option_bits= backup->option_bits;
4425  in_sub_stmt= backup->in_sub_stmt;
4426  enable_slow_log= backup->enable_slow_log;
4427  first_successful_insert_id_in_prev_stmt=
4428  backup->first_successful_insert_id_in_prev_stmt;
4429  first_successful_insert_id_in_cur_stmt=
4430  backup->first_successful_insert_id_in_cur_stmt;
4431  limit_found_rows= backup->limit_found_rows;
4432  set_sent_row_count(backup->sent_row_count);
4433  client_capabilities= backup->client_capabilities;
4434  /*
4435  If we've left sub-statement mode, reset the fatal error flag.
4436  Otherwise keep the current value, to propagate it up the sub-statement
4437  stack.
4438  */
4439  if (!in_sub_stmt)
4440  is_fatal_sub_stmt_error= FALSE;
4441 
4442  if ((variables.option_bits & OPTION_BIN_LOG) && is_update_query(lex->sql_command) &&
4443  !is_current_stmt_binlog_format_row())
4444  mysql_bin_log.stop_union_events(this);
4445 
4446  /*
4447  The following is added to the old values as we are interested in the
4448  total complexity of the query
4449  */
4450  inc_examined_row_count(backup->examined_row_count);
4451  cuted_fields+= backup->cuted_fields;
4452  DBUG_VOID_RETURN;
4453 }
4454 
4455 
4456 void THD::set_statement(Statement *stmt)
4457 {
4458  mysql_mutex_lock(&LOCK_thd_data);
4459  Statement::set_statement(stmt);
4460  mysql_mutex_unlock(&LOCK_thd_data);
4461 }
4462 
4463 void THD::set_sent_row_count(ha_rows count)
4464 {
4465  m_sent_row_count= count;
4466  MYSQL_SET_STATEMENT_ROWS_SENT(m_statement_psi, m_sent_row_count);
4467 }
4468 
4469 void THD::set_examined_row_count(ha_rows count)
4470 {
4471  m_examined_row_count= count;
4472  MYSQL_SET_STATEMENT_ROWS_EXAMINED(m_statement_psi, m_examined_row_count);
4473 }
4474 
4475 void THD::inc_sent_row_count(ha_rows count)
4476 {
4477  m_sent_row_count+= count;
4478  MYSQL_SET_STATEMENT_ROWS_SENT(m_statement_psi, m_sent_row_count);
4479 }
4480 
4481 void THD::inc_examined_row_count(ha_rows count)
4482 {
4483  m_examined_row_count+= count;
4484  MYSQL_SET_STATEMENT_ROWS_EXAMINED(m_statement_psi, m_examined_row_count);
4485 }
4486 
4487 void THD::inc_status_created_tmp_disk_tables()
4488 {
4489  status_var_increment(status_var.created_tmp_disk_tables);
4490 #ifdef HAVE_PSI_STATEMENT_INTERFACE
4491  PSI_STATEMENT_CALL(inc_statement_created_tmp_disk_tables)(m_statement_psi, 1);
4492 #endif
4493 }
4494 
4495 void THD::inc_status_created_tmp_tables()
4496 {
4497  status_var_increment(status_var.created_tmp_tables);
4498 #ifdef HAVE_PSI_STATEMENT_INTERFACE
4499  PSI_STATEMENT_CALL(inc_statement_created_tmp_tables)(m_statement_psi, 1);
4500 #endif
4501 }
4502 
4503 void THD::inc_status_select_full_join()
4504 {
4505  status_var_increment(status_var.select_full_join_count);
4506 #ifdef HAVE_PSI_STATEMENT_INTERFACE
4507  PSI_STATEMENT_CALL(inc_statement_select_full_join)(m_statement_psi, 1);
4508 #endif
4509 }
4510 
4511 void THD::inc_status_select_full_range_join()
4512 {
4513  status_var_increment(status_var.select_full_range_join_count);
4514 #ifdef HAVE_PSI_STATEMENT_INTERFACE
4515  PSI_STATEMENT_CALL(inc_statement_select_full_range_join)(m_statement_psi, 1);
4516 #endif
4517 }
4518 
4519 void THD::inc_status_select_range()
4520 {
4521  status_var_increment(status_var.select_range_count);
4522 #ifdef HAVE_PSI_STATEMENT_INTERFACE
4523  PSI_STATEMENT_CALL(inc_statement_select_range)(m_statement_psi, 1);
4524 #endif
4525 }
4526 
4527 void THD::inc_status_select_range_check()
4528 {
4529  status_var_increment(status_var.select_range_check_count);
4530 #ifdef HAVE_PSI_STATEMENT_INTERFACE
4531  PSI_STATEMENT_CALL(inc_statement_select_range_check)(m_statement_psi, 1);
4532 #endif
4533 }
4534 
4535 void THD::inc_status_select_scan()
4536 {
4537  status_var_increment(status_var.select_scan_count);
4538 #ifdef HAVE_PSI_STATEMENT_INTERFACE
4539  PSI_STATEMENT_CALL(inc_statement_select_scan)(m_statement_psi, 1);
4540 #endif
4541 }
4542 
4543 void THD::inc_status_sort_merge_passes()
4544 {
4545  status_var_increment(status_var.filesort_merge_passes);
4546 #ifdef HAVE_PSI_STATEMENT_INTERFACE
4547  PSI_STATEMENT_CALL(inc_statement_sort_merge_passes)(m_statement_psi, 1);
4548 #endif
4549 }
4550 
4551 void THD::inc_status_sort_range()
4552 {
4553  status_var_increment(status_var.filesort_range_count);
4554 #ifdef HAVE_PSI_STATEMENT_INTERFACE
4555  PSI_STATEMENT_CALL(inc_statement_sort_range)(m_statement_psi, 1);
4556 #endif
4557 }
4558 
4559 void THD::inc_status_sort_rows(ha_rows count)
4560 {
4561  statistic_add(status_var.filesort_rows, count, &LOCK_status);
4562 #ifdef HAVE_PSI_STATEMENT_INTERFACE
4563  PSI_STATEMENT_CALL(inc_statement_sort_rows)(m_statement_psi, count);
4564 #endif
4565 }
4566 
4567 void THD::inc_status_sort_scan()
4568 {
4569  status_var_increment(status_var.filesort_scan_count);
4570 #ifdef HAVE_PSI_STATEMENT_INTERFACE
4571  PSI_STATEMENT_CALL(inc_statement_sort_scan)(m_statement_psi, 1);
4572 #endif
4573 }
4574 
4575 void THD::set_status_no_index_used()
4576 {
4577  server_status|= SERVER_QUERY_NO_INDEX_USED;
4578 #ifdef HAVE_PSI_STATEMENT_INTERFACE
4579  PSI_STATEMENT_CALL(set_statement_no_index_used)(m_statement_psi);
4580 #endif
4581 }
4582 
4583 void THD::set_status_no_good_index_used()
4584 {
4585  server_status|= SERVER_QUERY_NO_GOOD_INDEX_USED;
4586 #ifdef HAVE_PSI_STATEMENT_INTERFACE
4587  PSI_STATEMENT_CALL(set_statement_no_good_index_used)(m_statement_psi);
4588 #endif
4589 }
4590 
4591 void THD::set_command(enum enum_server_command command)
4592 {
4593  m_command= command;
4594 #ifdef HAVE_PSI_THREAD_INTERFACE
4595  PSI_STATEMENT_CALL(set_thread_command)(m_command);
4596 #endif
4597 }
4598 
4599 
4602 void THD::set_query(const CSET_STRING &string_arg)
4603 {
4604  mysql_mutex_lock(&LOCK_thd_data);
4605  set_query_inner(string_arg);
4606  mysql_mutex_unlock(&LOCK_thd_data);
4607 
4608 #ifdef HAVE_PSI_THREAD_INTERFACE
4609  PSI_THREAD_CALL(set_thread_info)(query(), query_length());
4610 #endif
4611 }
4612 
4615 void THD::set_query_and_id(char *query_arg, uint32 query_length_arg,
4616  const CHARSET_INFO *cs,
4617  query_id_t new_query_id)
4618 {
4619  mysql_mutex_lock(&LOCK_thd_data);
4620  set_query_inner(query_arg, query_length_arg, cs);
4621  query_id= new_query_id;
4622  mysql_mutex_unlock(&LOCK_thd_data);
4623 }
4624 
4627 void THD::set_query_id(query_id_t new_query_id)
4628 {
4629  mysql_mutex_lock(&LOCK_thd_data);
4630  query_id= new_query_id;
4631  mysql_mutex_unlock(&LOCK_thd_data);
4632 }
4633 
4635 void THD::set_mysys_var(struct st_my_thread_var *new_mysys_var)
4636 {
4637  mysql_mutex_lock(&LOCK_thd_data);
4638  mysys_var= new_mysys_var;
4639  mysql_mutex_unlock(&LOCK_thd_data);
4640 }
4641 
4647 void THD::leave_locked_tables_mode()
4648 {
4649  if (locked_tables_mode == LTM_LOCK_TABLES)
4650  {
4651  /*
4652  When leaving LOCK TABLES mode we have to change the duration of most
4653  of the metadata locks being held, except for HANDLER and GRL locks,
4654  to transactional for them to be properly released at UNLOCK TABLES.
4655  */
4656  mdl_context.set_transaction_duration_for_all_locks();
4657  /*
4658  Make sure we don't release the global read lock and commit blocker
4659  when leaving LTM.
4660  */
4661  global_read_lock.set_explicit_lock_duration(this);
4662  /* Also ensure that we don't release metadata locks for open HANDLERs. */
4663  if (handler_tables_hash.records)
4664  mysql_ha_set_explicit_lock_duration(this);
4665  }
4666  locked_tables_mode= LTM_NONE;
4667 }
4668 
4669 void THD::get_definer(LEX_USER *definer)
4670 {
4671  binlog_invoker();
4672 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
4673  if (slave_thread && has_invoker())
4674  {
4675  definer->user = invoker_user;
4676  definer->host= invoker_host;
4677  definer->password.str= NULL;
4678  definer->password.length= 0;
4679  definer->plugin.str= (char *) "";
4680  definer->plugin.length= 0;
4681  definer->auth.str= (char *) "";
4682  definer->auth.length= 0;
4683  }
4684  else
4685 #endif
4686  get_default_definer(this, definer);
4687 }
4688 
4689 
4697 void mark_transaction_to_rollback(THD *thd, bool all)
4698 {
4699  if (thd)
4700  {
4701  thd->is_fatal_sub_stmt_error= TRUE;
4702  thd->transaction_rollback_request= all;
4703  /*
4704  Aborted transactions can not be IGNOREd.
4705  Switch off the IGNORE flag for the current
4706  SELECT_LEX. This should allow my_error()
4707  to report the error and abort the execution
4708  flow, even in presence
4709  of IGNORE clause.
4710  */
4711  if (thd->lex->current_select)
4712  thd->lex->current_select->no_error= FALSE;
4713  }
4714 }
4715 /***************************************************************************
4716  Handling of XA id cacheing
4717 ***************************************************************************/
4718 
4719 mysql_mutex_t LOCK_xid_cache;
4720 HASH xid_cache;
4721 
4722 extern "C" uchar *xid_get_hash_key(const uchar *, size_t *, my_bool);
4723 extern "C" void xid_free_hash(void *);
4724 
4725 uchar *xid_get_hash_key(const uchar *ptr, size_t *length,
4726  my_bool not_used __attribute__((unused)))
4727 {
4728  *length=((XID_STATE*)ptr)->xid.key_length();
4729  return ((XID_STATE*)ptr)->xid.key();
4730 }
4731 
4732 void xid_free_hash(void *ptr)
4733 {
4734  if (!((XID_STATE*)ptr)->in_thd)
4735  my_free(ptr);
4736 }
4737 
4738 #ifdef HAVE_PSI_INTERFACE
4739 static PSI_mutex_key key_LOCK_xid_cache;
4740 
4741 static PSI_mutex_info all_xid_mutexes[]=
4742 {
4743  { &key_LOCK_xid_cache, "LOCK_xid_cache", PSI_FLAG_GLOBAL}
4744 };
4745 
4746 static void init_xid_psi_keys(void)
4747 {
4748  const char* category= "sql";
4749  int count;
4750 
4751  count= array_elements(all_xid_mutexes);
4752  mysql_mutex_register(category, all_xid_mutexes, count);
4753 }
4754 #endif /* HAVE_PSI_INTERFACE */
4755 
4756 bool xid_cache_init()
4757 {
4758 #ifdef HAVE_PSI_INTERFACE
4759  init_xid_psi_keys();
4760 #endif
4761 
4762  mysql_mutex_init(key_LOCK_xid_cache, &LOCK_xid_cache, MY_MUTEX_INIT_FAST);
4763  return my_hash_init(&xid_cache, &my_charset_bin, 100, 0, 0,
4764  xid_get_hash_key, xid_free_hash, 0) != 0;
4765 }
4766 
4767 void xid_cache_free()
4768 {
4769  if (my_hash_inited(&xid_cache))
4770  {
4771  my_hash_free(&xid_cache);
4772  mysql_mutex_destroy(&LOCK_xid_cache);
4773  }
4774 }
4775 
4776 XID_STATE *xid_cache_search(XID *xid)
4777 {
4778  mysql_mutex_lock(&LOCK_xid_cache);
4779  XID_STATE *res=(XID_STATE *)my_hash_search(&xid_cache, xid->key(),
4780  xid->key_length());
4781  mysql_mutex_unlock(&LOCK_xid_cache);
4782  return res;
4783 }
4784 
4785 
4786 bool xid_cache_insert(XID *xid, enum xa_states xa_state)
4787 {
4788  XID_STATE *xs;
4789  my_bool res;
4790  mysql_mutex_lock(&LOCK_xid_cache);
4791  if (my_hash_search(&xid_cache, xid->key(), xid->key_length()))
4792  res=0;
4793  else if (!(xs=(XID_STATE *)my_malloc(sizeof(*xs), MYF(MY_WME))))
4794  res=1;
4795  else
4796  {
4797  xs->xa_state=xa_state;
4798  xs->xid.set(xid);
4799  xs->in_thd=0;
4800  xs->rm_error=0;
4801  res=my_hash_insert(&xid_cache, (uchar*)xs);
4802  }
4803  mysql_mutex_unlock(&LOCK_xid_cache);
4804  return res;
4805 }
4806 
4807 
4808 bool xid_cache_insert(XID_STATE *xid_state)
4809 {
4810  mysql_mutex_lock(&LOCK_xid_cache);
4811  if (my_hash_search(&xid_cache, xid_state->xid.key(),
4812  xid_state->xid.key_length()))
4813  {
4814  mysql_mutex_unlock(&LOCK_xid_cache);
4815  my_error(ER_XAER_DUPID, MYF(0));
4816  return true;
4817  }
4818  bool res= my_hash_insert(&xid_cache, (uchar*)xid_state);
4819  mysql_mutex_unlock(&LOCK_xid_cache);
4820  return res;
4821 }
4822 
4823 
4824 void xid_cache_delete(XID_STATE *xid_state)
4825 {
4826  mysql_mutex_lock(&LOCK_xid_cache);
4827  my_hash_delete(&xid_cache, (uchar *)xid_state);
4828  mysql_mutex_unlock(&LOCK_xid_cache);
4829 }
4830 
4831 
4832 void THD::set_next_event_pos(const char* _filename, ulonglong _pos)
4833 {
4834  char*& filename= binlog_next_event_pos.file_name;
4835  if (filename == NULL)
4836  {
4837  /* First time, allocate maximal buffer */
4838  filename= (char*) my_malloc(FN_REFLEN+1, MYF(MY_WME));
4839  if (filename == NULL) return;
4840  }
4841 
4842  assert(strlen(_filename) <= FN_REFLEN);
4843  strcpy(filename, _filename);
4844  filename[ FN_REFLEN ]= 0;
4845 
4846  binlog_next_event_pos.pos= _pos;
4847 };
4848 
4849 void THD::clear_next_event_pos()
4850 {
4851  if (binlog_next_event_pos.file_name != NULL)
4852  {
4853  my_free(binlog_next_event_pos.file_name);
4854  }
4855  binlog_next_event_pos.file_name= NULL;
4856  binlog_next_event_pos.pos= 0;
4857 };
4858 
4859 void THD::set_user_connect(USER_CONN *uc)
4860 {
4861  DBUG_ENTER("THD::set_user_connect");
4862 
4863  m_user_connect= uc;
4864 
4865  DBUG_VOID_RETURN;
4866 }
4867 
4868 void THD::increment_user_connections_counter()
4869 {
4870  DBUG_ENTER("THD::increment_user_connections_counter");
4871 
4872  m_user_connect->connections++;
4873 
4874  DBUG_VOID_RETURN;
4875 }
4876 
4877 void THD::decrement_user_connections_counter()
4878 {
4879  DBUG_ENTER("THD::decrement_user_connections_counter");
4880 
4881  DBUG_ASSERT(m_user_connect->connections > 0);
4882  m_user_connect->connections--;
4883 
4884  DBUG_VOID_RETURN;
4885 }
4886 
4887 void THD::increment_con_per_hour_counter()
4888 {
4889  DBUG_ENTER("THD::decrement_conn_per_hour_counter");
4890 
4891  m_user_connect->conn_per_hour++;
4892 
4893  DBUG_VOID_RETURN;
4894 }
4895 
4896 void THD::increment_updates_counter()
4897 {
4898  DBUG_ENTER("THD::increment_updates_counter");
4899 
4900  m_user_connect->updates++;
4901 
4902  DBUG_VOID_RETURN;
4903 }
4904 
4905 void THD::increment_questions_counter()
4906 {
4907  DBUG_ENTER("THD::increment_updates_counter");
4908 
4909  m_user_connect->questions++;
4910 
4911  DBUG_VOID_RETURN;
4912 }
4913 
4914 /*
4915  Reset per-hour user resource limits when it has been more than
4916  an hour since they were last checked
4917 
4918  SYNOPSIS:
4919  time_out_user_resource_limits()
4920 
4921  NOTE:
4922  This assumes that the LOCK_user_conn mutex has been acquired, so it is
4923  safe to test and modify members of the USER_CONN structure.
4924 */
4925 void THD::time_out_user_resource_limits()
4926 {
4927  mysql_mutex_assert_owner(&LOCK_user_conn);
4928  ulonglong check_time= start_utime;
4929  DBUG_ENTER("time_out_user_resource_limits");
4930 
4931  /* If more than a hour since last check, reset resource checking */
4932  if (check_time - m_user_connect->reset_utime >= LL(3600000000))
4933  {
4934  m_user_connect->questions=1;
4935  m_user_connect->updates=0;
4936  m_user_connect->conn_per_hour=0;
4937  m_user_connect->reset_utime= check_time;
4938  }
4939 
4940  DBUG_VOID_RETURN;
4941 }