~jlukas79/+junk/mysql-server

« back to all changes in this revision

Viewing changes to sql/sql_class.cc

manual merge 6.0-main --> 6.0-bka-review

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
#include "mysql_priv.h"
29
29
#include "rpl_rli.h"
30
30
#include "rpl_record.h"
 
31
#include "slave.h"
31
32
#include <my_bitmap.h>
32
33
#include "log_event.h"
33
34
#include "sql_audit.h"
200
201
** Thread specific functions
201
202
****************************************************************************/
202
203
 
203
 
Open_tables_state::Open_tables_state(ulong version_arg)
204
 
  :version(version_arg), state_flags(0U)
 
204
/** Push an error to the error stack and return TRUE for now. */
 
205
 
 
206
bool
 
207
Reprepare_observer::report_error(THD *thd)
205
208
{
206
 
  reset_open_tables_state();
 
209
  my_error(ER_NEED_REPREPARE, MYF(ME_NO_WARNING_FOR_ERROR|ME_NO_SP_HANDLER));
 
210
 
 
211
  m_invalidated= TRUE;
 
212
 
 
213
  return TRUE;
207
214
}
208
215
 
 
216
 
209
217
/*
210
218
  The following functions form part of the C plugin API
211
219
*/
371
379
void
372
380
Diagnostics_area::reset_diagnostics_area()
373
381
{
 
382
  DBUG_ENTER("reset_diagnostics_area");
374
383
#ifdef DBUG_OFF
375
384
  can_overwrite_status= FALSE;
376
385
  /** Don't take chances in production */
384
393
  is_sent= FALSE;
385
394
  /** Tiny reset in debug mode to see garbage right away */
386
395
  m_status= DA_EMPTY;
 
396
  DBUG_VOID_RETURN;
387
397
}
388
398
 
389
399
 
397
407
                                ulonglong last_insert_id_arg,
398
408
                                const char *message_arg)
399
409
{
 
410
  DBUG_ENTER("set_ok_status");
400
411
  DBUG_ASSERT(! is_set());
401
 
#ifdef DBUG_OFF
402
412
  /*
403
413
    In production, refuse to overwrite an error or a custom response
404
414
    with an OK packet.
405
415
  */
406
416
  if (is_error() || is_disabled())
407
417
    return;
408
 
#endif
409
 
  /** Only allowed to report success if has not yet reported an error */
410
418
 
411
419
  m_server_status= thd->server_status;
412
420
  m_total_warn_count= thd->total_warn_count;
417
425
  else
418
426
    m_message[0]= '\0';
419
427
  m_status= DA_OK;
 
428
  DBUG_VOID_RETURN;
420
429
}
421
430
 
422
431
 
427
436
void
428
437
Diagnostics_area::set_eof_status(THD *thd)
429
438
{
430
 
  /** Only allowed to report eof if has not yet reported an error */
431
 
 
 
439
  DBUG_ENTER("set_eof_status");
 
440
  /* Only allowed to report eof if has not yet reported an error */
432
441
  DBUG_ASSERT(! is_set());
433
 
#ifdef DBUG_OFF
434
442
  /*
435
443
    In production, refuse to overwrite an error or a custom response
436
444
    with an EOF packet.
437
445
  */
438
446
  if (is_error() || is_disabled())
439
447
    return;
440
 
#endif
441
448
 
442
449
  m_server_status= thd->server_status;
443
450
  /*
448
455
  m_total_warn_count= thd->spcont ? 0 : thd->total_warn_count;
449
456
 
450
457
  m_status= DA_EOF;
 
458
  DBUG_VOID_RETURN;
451
459
}
452
460
 
453
461
/**
458
466
Diagnostics_area::set_error_status(THD *thd, uint sql_errno_arg,
459
467
                                   const char *message_arg)
460
468
{
 
469
  DBUG_ENTER("set_error_status");
461
470
  /*
462
471
    Only allowed to report error if has not yet reported a success
463
472
    The only exception is when we flush the message to the client,
474
483
#endif
475
484
 
476
485
  m_sql_errno= sql_errno_arg;
477
 
  strmake(m_message, message_arg, sizeof(m_message) - 1);
 
486
  strmake(m_message, message_arg, sizeof(m_message)-1);
478
487
 
479
488
  m_status= DA_ERROR;
 
489
  DBUG_VOID_RETURN;
480
490
}
481
491
 
482
492
 
499
509
THD::THD()
500
510
   :Statement(&main_lex, &main_mem_root, CONVENTIONAL_EXECUTION,
501
511
              /* statement id */ 0),
502
 
   Open_tables_state(refresh_version), rli_fake(0),
 
512
   rli_fake(0),
503
513
   lock_id(&main_lock_id),
504
514
   user_time(0), in_sub_stmt(0),
505
515
   binlog_table_maps(0), binlog_flags(0UL),
525
535
          This is needed to ensure the restore (which uses DDL) is not blocked
526
536
          when the DDL blocker is engaged.
527
537
  */
528
 
   DDL_exception(FALSE)
 
538
   DDL_exception(FALSE),
 
539
#if defined(ENABLED_DEBUG_SYNC)
 
540
   debug_sync_control(0),
 
541
#endif /* defined(ENABLED_DEBUG_SYNC) */
 
542
   locked_tables_root(NULL)
529
543
{
530
544
  ulong tmp;
531
545
 
587
601
  cleanup_done= abort_on_warning= no_warnings_for_error= 0;
588
602
  peer_port= 0;                                 // For SHOW PROCESSLIST
589
603
  transaction.m_pending_rows_event= 0;
 
604
  transaction.on= 1;
590
605
#ifdef SIGNAL_WITH_VIO_CLOSE
591
606
  active_vio = 0;
592
607
#endif
600
615
  command=COM_CONNECT;
601
616
  *scramble= '\0';
602
617
 
 
618
  /* Call to init() below requires fully initialized Open_tables_state. */
 
619
  init_open_tables_state(this, refresh_version);
 
620
 
603
621
  init();
604
622
  /* Initialize sub structures */
605
623
  init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
628
646
 
629
647
  tablespace_op=FALSE;
630
648
  tmp= sql_rnd_with_mutex();
631
 
  randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id);
 
649
  my_rnd_init(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id);
632
650
  substitute_null_with_insert_id = FALSE;
633
651
  thr_lock_info_init(&lock_info); /* safety: will be reset after start */
634
652
  thr_lock_owner_init(&main_lock_id, &lock_info);
754
772
  update_charset();
755
773
  reset_current_stmt_binlog_row_based();
756
774
  bzero((char *) &status_var, sizeof(status_var));
 
775
 
 
776
#if defined(ENABLED_DEBUG_SYNC)
 
777
  /* Initialize the Debug Sync Facility. See debug_sync.cc. */
 
778
  debug_sync_init_thread(this);
 
779
#endif /* defined(ENABLED_DEBUG_SYNC) */
757
780
}
758
781
 
759
782
 
828
851
    ha_rollback(this);
829
852
    xid_cache_delete(&transaction.xid_state);
830
853
  }
831
 
  if (locked_tables)
832
 
  {
833
 
    lock=locked_tables; locked_tables=0;
834
 
    close_thread_tables(this);
835
 
  }
 
854
  locked_tables_list.unlock_locked_tables(this);
 
855
 
 
856
#if defined(ENABLED_DEBUG_SYNC)
 
857
  /* End the Debug Sync Facility. See debug_sync.cc. */
 
858
  debug_sync_end_thread(this);
 
859
#endif /* defined(ENABLED_DEBUG_SYNC) */
 
860
 
836
861
  mysql_ha_cleanup(this);
837
862
  delete_dynamic(&user_var_events);
838
863
  hash_free(&user_vars);
903
928
  if (!cleanup_done)
904
929
    cleanup();
905
930
 
 
931
  mdl_context_destroy(&mdl_context);
 
932
  mdl_context_destroy(&handler_mdl_context);
 
933
 
906
934
  ha_close_connection(this);
907
935
  mysql_audit_release(this);
908
936
  plugin_thdvar_cleanup(this);
988
1016
void THD::awake(THD::killed_state state_to_set)
989
1017
{
990
1018
  DBUG_ENTER("THD::awake");
991
 
  DBUG_PRINT("enter", ("this: 0x%lx", (long) this));
 
1019
  DBUG_PRINT("enter", ("this: %p", this));
992
1020
  THD_CHECK_SENTRY(this);
993
1021
  safe_mutex_assert_owner(&LOCK_delete); 
994
1022
 
1018
1046
  if (mysys_var)
1019
1047
  {
1020
1048
    pthread_mutex_lock(&mysys_var->mutex);
1021
 
    if (!system_thread)         // Don't abort locks
1022
 
      mysys_var->abort=1;
 
1049
    if (system_thread == NON_SYSTEM_THREAD ||
 
1050
        system_thread == SYSTEM_THREAD_BACKUP)
 
1051
      mysys_var->abort= 1; // abort locks
1023
1052
    /*
1024
1053
      This broadcast could be up in the air if the victim thread
1025
1054
      exits the cond in the time between read and broadcast, but that is
1457
1486
}
1458
1487
 
1459
1488
 
 
1489
#ifndef EMBEDDED_LIBRARY
 
1490
 
 
1491
/**
 
1492
  Check that the endpoint is still available.
 
1493
*/
 
1494
 
 
1495
bool THD::vio_is_connected()
 
1496
{
 
1497
  uint bytes= 0;
 
1498
 
 
1499
  /* End of input is signaled by poll if the socket is aborted. */
 
1500
  if (vio_poll_read(net.vio, 0))
 
1501
    return TRUE;
 
1502
 
 
1503
  /* Socket is aborted if signaled but no data is available. */
 
1504
  if (vio_peek_read(net.vio, &bytes))
 
1505
    return TRUE;
 
1506
 
 
1507
  return bytes ? TRUE : FALSE;
 
1508
}
 
1509
 
 
1510
#endif
 
1511
 
 
1512
 
1460
1513
/*****************************************************************************
1461
1514
** Functions to provide a interface to select results
1462
1515
*****************************************************************************/
1571
1624
  Item *item;
1572
1625
  while ((item=li++))
1573
1626
  {
1574
 
    if (item->send(protocol, &buffer))
 
1627
    if (item->send(protocol, &buffer) || thd->is_error())
1575
1628
    {
1576
1629
      protocol->free();                         // Free used buffer
1577
1630
      my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
1578
1631
      break;
1579
1632
    }
1580
1633
  }
1581
 
  thd->sent_row_count++;
1582
1634
  if (thd->is_error())
1583
1635
  {
1584
1636
    protocol->remove_last_row();
1585
1637
    DBUG_RETURN(1);
1586
1638
  }
 
1639
  thd->sent_row_count++;
1587
1640
  if (thd->vio_ok())
1588
1641
    DBUG_RETURN(protocol->write());
1589
1642
  DBUG_RETURN(0);
1599
1652
  ha_release_temporary_latches(thd);
1600
1653
 
1601
1654
  /* Unlock tables before sending packet to gain some speed */
1602
 
  if (thd->lock)
 
1655
  if (thd->lock && ! thd->locked_tables_mode)
1603
1656
  {
1604
1657
    mysql_unlock_tables(thd, thd->lock);
1605
1658
    thd->lock=0;
2113
2166
    if (!cache)
2114
2167
    {
2115
2168
      cache= Item_cache::get_cache(val_item);
2116
 
      switch (val_item->result_type())
2117
 
      {
 
2169
      switch (val_item->result_type()) {
2118
2170
      case REAL_RESULT:
2119
2171
        op= &select_max_min_finder_subselect::cmp_real;
2120
2172
        break;
2128
2180
        op= &select_max_min_finder_subselect::cmp_decimal;
2129
2181
        break;
2130
2182
      case ROW_RESULT:
 
2183
      case IMPOSSIBLE_RESULT:
2131
2184
        // This case should never be choosen
2132
2185
        DBUG_ASSERT(0);
2133
2186
        op= 0;
2602
2655
void TMP_TABLE_PARAM::init()
2603
2656
{
2604
2657
  DBUG_ENTER("TMP_TABLE_PARAM::init");
2605
 
  DBUG_PRINT("enter", ("this: 0x%lx", (ulong)this));
 
2658
  DBUG_PRINT("enter", ("this: %p", this));
2606
2659
  field_count= sum_func_count= func_count= hidden_field_count= 0;
2607
2660
  group_parts= group_length= group_null_parts= 0;
2608
2661
  quick_group= 1;
2794
2847
{
2795
2848
  DBUG_ENTER("reset_n_backup_open_tables_state");
2796
2849
  backup->set_open_tables_state(this);
2797
 
  reset_open_tables_state();
 
2850
  reset_open_tables_state(this);
2798
2851
  state_flags|= Open_tables_state::BACKUPS_AVAIL;
2799
2852
  DBUG_VOID_RETURN;
2800
2853
}
2809
2862
  */
2810
2863
  DBUG_ASSERT(open_tables == 0 && temporary_tables == 0 &&
2811
2864
              handler_tables == 0 && derived_tables == 0 &&
2812
 
              lock == 0 && locked_tables == 0 &&
2813
 
              prelocked_mode == NON_PRELOCKED);
 
2865
              lock == 0 &&
 
2866
              locked_tables_mode == LTM_NONE &&
 
2867
              m_reprepare_observer == NULL);
 
2868
  mdl_context_destroy(&mdl_context);
 
2869
  mdl_context_destroy(&handler_mdl_context);
 
2870
 
2814
2871
  set_open_tables_state(backup);
2815
2872
  DBUG_VOID_RETURN;
2816
2873
}
2901
2958
void THD::reset_sub_statement_state(Sub_statement_state *backup,
2902
2959
                                    uint new_state)
2903
2960
{
 
2961
#ifndef EMBEDDED_LIBRARY
 
2962
  /* BUG#33029, if we are replicating from a buggy master, reset
 
2963
     auto_inc_intervals_forced to prevent substatement
 
2964
     (triggers/functions) from using erroneous INSERT_ID value
 
2965
   */
 
2966
  if (rpl_master_erroneous_autoinc(this))
 
2967
  {
 
2968
    DBUG_ASSERT(backup->auto_inc_intervals_forced.nb_elements() == 0);
 
2969
    auto_inc_intervals_forced.swap(&backup->auto_inc_intervals_forced);
 
2970
  }
 
2971
#endif
 
2972
  
2904
2973
  backup->options=         options;
2905
2974
  backup->in_sub_stmt=     in_sub_stmt;
2906
2975
  backup->enable_slow_log= enable_slow_log;
2938
3007
 
2939
3008
void THD::restore_sub_statement_state(Sub_statement_state *backup)
2940
3009
{
 
3010
#ifndef EMBEDDED_LIBRARY
 
3011
  /* BUG#33029, if we are replicating from a buggy master, restore
 
3012
     auto_inc_intervals_forced so that the top statement can use the
 
3013
     INSERT_ID value set before this statement.
 
3014
   */
 
3015
  if (rpl_master_erroneous_autoinc(this))
 
3016
  {
 
3017
    backup->auto_inc_intervals_forced.swap(&auto_inc_intervals_forced);
 
3018
    DBUG_ASSERT(backup->auto_inc_intervals_forced.nb_elements() == 0);
 
3019
  }
 
3020
#endif
 
3021
 
2941
3022
  /*
2942
3023
    To save resources we want to release savepoints which were created
2943
3024
    during execution of function or trigger before leaving their savepoint
3565
3646
    If we are in prelocked mode, the flushing will be done inside the
3566
3647
    top-most close_thread_tables().
3567
3648
  */
3568
 
  if (this->prelocked_mode == NON_PRELOCKED)
 
3649
  if (this->locked_tables_mode <= LTM_LOCK_TABLES)
3569
3650
    if (int error= binlog_flush_pending_rows_event(TRUE))
3570
3651
      DBUG_RETURN(error);
3571
3652
 
3623
3704
      binlog_table_maps= 0;
3624
3705
      DBUG_RETURN(error);
3625
3706
    }
3626
 
    break;
3627
3707
 
3628
3708
  case THD::QUERY_TYPE_COUNT:
3629
3709
  default:
3630
 
    DBUG_ASSERT(0 <= qtype && qtype < QUERY_TYPE_COUNT);
 
3710
    DBUG_ASSERT(qtype < QUERY_TYPE_COUNT);
3631
3711
  }
3632
3712
  DBUG_RETURN(0);
3633
3713
}
3641
3721
  {
3642
3722
    /* it cannot, so need to add a new interval */
3643
3723
    Discrete_interval *new_interval= new Discrete_interval(start, val, incr);
3644
 
    if (unlikely(new_interval == NULL)) // out of memory
3645
 
      DBUG_RETURN(1);
3646
 
    DBUG_PRINT("info",("adding new auto_increment interval"));
3647
 
    if (head == NULL)
3648
 
      head= current= new_interval;
3649
 
    else
3650
 
      tail->next= new_interval;
3651
 
    tail= new_interval;
3652
 
    elements++;
 
3724
    DBUG_RETURN(append(new_interval));
3653
3725
  }
3654
3726
  DBUG_RETURN(0);
3655
3727
}
3656
3728
 
 
3729
bool Discrete_intervals_list::append(Discrete_interval *new_interval)
 
3730
{
 
3731
  DBUG_ENTER("Discrete_intervals_list::append");
 
3732
  if (unlikely(new_interval == NULL))
 
3733
    DBUG_RETURN(1);
 
3734
  DBUG_PRINT("info",("adding new auto_increment interval"));
 
3735
  if (head == NULL)
 
3736
    head= current= new_interval;
 
3737
  else
 
3738
    tail->next= new_interval;
 
3739
  tail= new_interval;
 
3740
  elements++;
 
3741
  DBUG_RETURN(0);
 
3742
}
 
3743
 
3657
3744
#endif /* !defined(MYSQL_CLIENT) */