~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sys_var.cc

  • Committer: Brian Aker
  • Date: 2011-02-17 10:09:00 UTC
  • mfrom: (2173.2.1 clean-include-usuage)
  • Revision ID: brian@tangent.org-20110217100900-4tpuxxzdl1sj00sh
Merge Monty for headers.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems
 
4
 *  Copyright (C) 2008 Sun Microsystems, Inc.
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
36
36
  @todo
37
37
    Add full support for the variable character_set (for 4.1)
38
38
 
39
 
  @note
40
 
    Be careful with var->save_result: sys_var::check() only updates
41
 
    uint64_t_value; so other members of the union are garbage then; to use
42
 
    them you must first assign a value to them (in specific ::check() for
43
 
    example).
44
39
*/
45
40
 
46
 
#include "config.h"
47
 
#include "drizzled/option.h"
48
 
#include "drizzled/error.h"
49
 
#include "drizzled/gettext.h"
50
 
#include "drizzled/tztime.h"
51
 
#include "drizzled/data_home.h"
52
 
#include "drizzled/set_var.h"
53
 
#include "drizzled/session.h"
54
 
#include "drizzled/sql_base.h"
55
 
#include "drizzled/lock.h"
56
 
#include "drizzled/item/uint.h"
57
 
#include "drizzled/item/null.h"
58
 
#include "drizzled/item/float.h"
59
 
#include "drizzled/item/string.h"
60
 
#include "drizzled/plugin.h"
61
 
#include "drizzled/version.h"
62
 
#include "drizzled/strfunc.h"
63
 
#include "drizzled/internal/m_string.h"
64
 
#include "drizzled/pthread_globals.h"
65
 
#include "drizzled/charset.h"
66
 
#include "drizzled/transaction_services.h"
67
 
#include "drizzled/constrained_value.h"
 
41
#include <config.h>
 
42
#include <drizzled/option.h>
 
43
#include <drizzled/error.h>
 
44
#include <drizzled/gettext.h>
 
45
#include <drizzled/tztime.h>
 
46
#include <drizzled/data_home.h>
 
47
#include <drizzled/set_var.h>
 
48
#include <drizzled/session.h>
 
49
#include <drizzled/sql_base.h>
 
50
#include <drizzled/lock.h>
 
51
#include <drizzled/item/uint.h>
 
52
#include <drizzled/item/null.h>
 
53
#include <drizzled/item/float.h>
 
54
#include <drizzled/item/string.h>
 
55
#include <drizzled/plugin.h>
 
56
#include <drizzled/version.h>
 
57
#include <drizzled/strfunc.h>
 
58
#include <drizzled/internal/m_string.h>
 
59
#include <drizzled/pthread_globals.h>
 
60
#include <drizzled/charset.h>
 
61
#include <drizzled/transaction_services.h>
 
62
#include <drizzled/constrained_value.h>
 
63
#include <drizzled/visibility.h>
 
64
#include <drizzled/typelib.h>
 
65
#include <drizzled/plugin/storage_engine.h>
68
66
 
69
67
#include <cstdio>
70
68
#include <map>
110
108
static void fix_max_join_size(Session *session, sql_var_t type);
111
109
static void fix_session_mem_root(Session *session, sql_var_t type);
112
110
static void fix_server_id(Session *session, sql_var_t type);
113
 
static bool get_unsigned32(Session *session, set_var *var);
114
 
static bool get_unsigned64(Session *session, set_var *var);
115
111
bool throw_bounds_warning(Session *session, bool fixed, bool unsignd,
116
112
                          const std::string &name, int64_t val);
117
113
static unsigned char *get_error_count(Session *session);
156
152
                                                     &drizzle_system_variables::join_buff_size);
157
153
static sys_var_session_uint32_t sys_max_allowed_packet("max_allowed_packet",
158
154
                                                       &drizzle_system_variables::max_allowed_packet);
159
 
static sys_var_uint64_t_ptr     sys_max_connect_errors("max_connect_errors",
160
 
                                               &max_connect_errors);
161
155
static sys_var_session_uint64_t sys_max_error_count("max_error_count",
162
156
                                                  &drizzle_system_variables::max_error_count);
163
157
static sys_var_session_uint64_t sys_max_heap_table_size("max_heap_table_size",
220
214
static sys_var_session_size_t   sys_sort_buffer("sort_buffer_size",
221
215
                                                &drizzle_system_variables::sortbuff_size);
222
216
 
223
 
static sys_var_session_size_t sys_transaction_message_threshold("transaction_message_threshold",
224
 
                                                                &drizzle_system_variables::transaction_message_threshold);
 
217
static sys_var_size_t_ptr_readonly sys_transaction_message_threshold("transaction_message_threshold",
 
218
                                                                &transaction_message_threshold);
225
219
 
226
220
static sys_var_session_storage_engine sys_storage_engine("storage_engine",
227
221
                                       &drizzle_system_variables::storage_engine);
228
 
static sys_var_const_str        sys_system_time_zone("system_time_zone",
229
 
                                             system_time_zone);
230
222
static sys_var_size_t_ptr       sys_table_def_size("table_definition_cache",
231
223
                                             &table_def_size);
232
224
static sys_var_uint64_t_ptr     sys_table_cache_size("table_open_cache",
315
307
sys_var_session_uint64_t sys_group_concat_max_len("group_concat_max_len",
316
308
                                                  &drizzle_system_variables::group_concat_max_len);
317
309
 
318
 
sys_var_session_time_zone sys_time_zone("time_zone");
319
 
 
320
310
/* Global read-only variable containing hostname */
321
311
static sys_var_const_str        sys_hostname("hostname", glob_hostname);
322
312
 
329
319
      my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), getName().c_str(), var->value->str_value.ptr());
330
320
    return res;
331
321
  }
332
 
  var->save_result.uint64_t_value= var->value->val_int();
 
322
  var->updateValue();
333
323
  return 0;
334
324
}
335
325
 
439
429
{
440
430
  if (fixed)
441
431
  {
442
 
    char buf[22];
 
432
    char buf[DECIMAL_LONGLONG_DIGITS];
443
433
 
444
434
    if (unsignd)
445
435
      internal::ullstr((uint64_t) val, buf);
474
464
  return out;
475
465
}
476
466
 
477
 
static bool get_unsigned32(Session *session, set_var *var)
478
 
{
479
 
  if (var->value->unsigned_flag)
480
 
    var->save_result.uint32_t_value= 
481
 
      static_cast<uint32_t>(var->value->val_int());
482
 
  else
483
 
  {
484
 
    int64_t v= var->value->val_int();
485
 
    if (v > UINT32_MAX)
486
 
      throw_bounds_warning(session, true, true,var->var->getName().c_str(), v);
487
 
    
488
 
    var->save_result.uint32_t_value= 
489
 
      static_cast<uint32_t>((v > UINT32_MAX) ? UINT32_MAX : (v < 0) ? 0 : v);
490
 
  }
491
 
  return false;
492
 
}
493
 
 
494
 
static bool get_unsigned64(Session *, set_var *var)
495
 
{
496
 
  if (var->value->unsigned_flag)
497
 
      var->save_result.uint64_t_value=(uint64_t) var->value->val_int();
498
 
  else
499
 
  {
500
 
    int64_t v= var->value->val_int();
501
 
      var->save_result.uint64_t_value= (uint64_t) ((v < 0) ? 0 : v);
502
 
  }
503
 
  return 0;
504
 
}
505
 
 
506
 
static bool get_size_t(Session *, set_var *var)
507
 
{
508
 
  if (var->value->unsigned_flag)
509
 
    var->save_result.size_t_value= (size_t) var->value->val_int();
510
 
  else
511
 
  {
512
 
    ssize_t v= (ssize_t)var->value->val_int();
513
 
    var->save_result.size_t_value= (size_t) ((v < 0) ? 0 : v);
514
 
  }
515
 
  return 0;
516
 
}
517
 
 
518
467
bool sys_var_uint32_t_ptr::check(Session *, set_var *var)
519
468
{
520
 
  var->save_result.uint32_t_value= (uint32_t)var->value->val_int();
 
469
  var->updateValue();
521
470
  return 0;
522
471
}
523
472
 
524
473
bool sys_var_uint32_t_ptr::update(Session *session, set_var *var)
525
474
{
526
 
  uint32_t tmp= var->save_result.uint32_t_value;
527
 
  LOCK_global_system_variables.lock();
 
475
  uint64_t tmp= var->getInteger();
 
476
  boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
477
 
528
478
  if (option_limits)
529
479
  {
530
480
    uint32_t newvalue= (uint32_t) fix_unsigned(session, tmp, option_limits);
531
 
    if(newvalue==tmp)
 
481
    if(static_cast<uint64_t>(newvalue) == tmp)
532
482
      *value= newvalue;
533
483
  }
534
484
  else
535
 
    *value= (uint32_t) tmp;
536
 
  LOCK_global_system_variables.unlock();
 
485
  {
 
486
    *value= static_cast<uint32_t>(tmp);
 
487
  }
 
488
 
537
489
  return 0;
538
490
}
539
491
 
540
492
 
541
 
void sys_var_uint32_t_ptr::set_default(Session *, sql_var_t)
 
493
void sys_var_uint32_t_ptr::set_default(Session *session, sql_var_t)
542
494
{
543
495
  bool not_used;
544
 
  LOCK_global_system_variables.lock();
 
496
  boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
545
497
  *value= (uint32_t)getopt_ull_limit_value((uint32_t) option_limits->def_value,
546
498
                                           option_limits, &not_used);
547
 
  LOCK_global_system_variables.unlock();
548
499
}
549
500
 
550
501
 
551
502
bool sys_var_uint64_t_ptr::update(Session *session, set_var *var)
552
503
{
553
 
  uint64_t tmp= var->save_result.uint64_t_value;
554
 
  LOCK_global_system_variables.lock();
 
504
  uint64_t tmp= var->getInteger();
 
505
  boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
506
 
555
507
  if (option_limits)
556
508
  {
557
 
    uint64_t newvalue= (uint64_t) fix_unsigned(session, tmp, option_limits);
 
509
    uint64_t newvalue= fix_unsigned(session, tmp, option_limits);
558
510
    if(newvalue==tmp)
559
511
      *value= newvalue;
560
512
  }
561
513
  else
562
 
    *value= (uint64_t) tmp;
563
 
  LOCK_global_system_variables.unlock();
 
514
  {
 
515
    *value= tmp;
 
516
  }
 
517
 
564
518
  return 0;
565
519
}
566
520
 
567
521
 
568
 
void sys_var_uint64_t_ptr::set_default(Session *, sql_var_t)
 
522
void sys_var_uint64_t_ptr::set_default(Session *session, sql_var_t)
569
523
{
570
524
  if (have_default_value)
571
525
  {
574
528
  else
575
529
  {
576
530
    bool not_used;
577
 
    LOCK_global_system_variables.lock();
 
531
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
578
532
    *value= getopt_ull_limit_value((uint64_t) option_limits->def_value,
579
533
                                   option_limits, &not_used);
580
 
    LOCK_global_system_variables.unlock();
581
534
  }
582
535
}
583
536
 
584
537
 
585
538
bool sys_var_size_t_ptr::update(Session *session, set_var *var)
586
539
{
587
 
  size_t tmp= var->save_result.size_t_value;
588
 
  LOCK_global_system_variables.lock();
 
540
  size_t tmp= size_t(var->getInteger());
 
541
 
 
542
  boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
543
 
589
544
  if (option_limits)
590
545
    *value= fix_size_t(session, tmp, option_limits);
591
546
  else
592
547
    *value= tmp;
593
 
  LOCK_global_system_variables.unlock();
 
548
 
594
549
  return 0;
595
550
}
596
551
 
597
552
 
598
 
void sys_var_size_t_ptr::set_default(Session *, sql_var_t)
 
553
void sys_var_size_t_ptr::set_default(Session *session, sql_var_t)
599
554
{
600
555
  bool not_used;
601
 
  LOCK_global_system_variables.lock();
 
556
  boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
602
557
  *value= (size_t)getopt_ull_limit_value((size_t) option_limits->def_value,
603
558
                                         option_limits, &not_used);
604
 
  LOCK_global_system_variables.unlock();
 
559
}
 
560
 
 
561
bool sys_var_bool_ptr::check(Session *session, set_var *var)
 
562
{
 
563
  return check_enum(session, var, &bool_typelib);
605
564
}
606
565
 
607
566
bool sys_var_bool_ptr::update(Session *, set_var *var)
608
567
{
609
 
  *value= (bool) var->save_result.uint32_t_value;
 
568
  *value= bool(var->getInteger());
610
569
  return 0;
611
570
}
612
571
 
622
581
*/
623
582
bool sys_var_session_uint32_t::check(Session *session, set_var *var)
624
583
{
625
 
  return (get_unsigned32(session, var) ||
626
 
          (check_func && (*check_func)(session, var)));
 
584
  var->updateValue();
 
585
  return (check_func && (*check_func)(session, var));
627
586
}
628
587
 
629
588
bool sys_var_session_uint32_t::update(Session *session, set_var *var)
630
589
{
631
 
  uint64_t tmp= (uint64_t) var->save_result.uint32_t_value;
 
590
  uint64_t tmp= var->getInteger();
632
591
 
633
592
  /* Don't use bigger value than given with --maximum-variable-name=.. */
634
593
  if ((uint32_t) tmp > max_system_variables.*offset)
642
601
  else if (tmp > UINT32_MAX)
643
602
  {
644
603
    tmp= UINT32_MAX;
645
 
    throw_bounds_warning(session, true, true, getName(), (int64_t) var->save_result.uint64_t_value);
 
604
    throw_bounds_warning(session, true, true, getName(), int64_t(var->getInteger()));
646
605
  }
647
606
 
648
607
  if (var->type == OPT_GLOBAL)
681
640
 
682
641
bool sys_var_session_ha_rows::update(Session *session, set_var *var)
683
642
{
684
 
  uint64_t tmp= var->save_result.uint64_t_value;
 
643
  uint64_t tmp= var->getInteger();
685
644
 
686
645
  /* Don't use bigger value than given with --maximum-variable-name=.. */
687
646
  if ((ha_rows) tmp > max_system_variables.*offset)
692
651
  if (var->type == OPT_GLOBAL)
693
652
  {
694
653
    /* Lock is needed to make things safe on 32 bit systems */
695
 
    LOCK_global_system_variables.lock();
 
654
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
696
655
    global_system_variables.*offset= (ha_rows) tmp;
697
 
    LOCK_global_system_variables.unlock();
698
656
  }
699
657
  else
 
658
  {
700
659
    session->variables.*offset= (ha_rows) tmp;
 
660
  }
 
661
 
701
662
  return 0;
702
663
}
703
664
 
708
669
  {
709
670
    bool not_used;
710
671
    /* We will not come here if option_limits is not set */
711
 
    LOCK_global_system_variables.lock();
 
672
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
712
673
    global_system_variables.*offset=
713
674
      (ha_rows) getopt_ull_limit_value((ha_rows) option_limits->def_value,
714
675
                                       option_limits, &not_used);
715
 
    LOCK_global_system_variables.unlock();
716
676
  }
717
677
  else
 
678
  {
718
679
    session->variables.*offset= global_system_variables.*offset;
 
680
  }
719
681
}
720
682
 
721
683
 
730
692
 
731
693
bool sys_var_session_uint64_t::check(Session *session, set_var *var)
732
694
{
733
 
  return (get_unsigned64(session, var) ||
734
 
          (check_func && (*check_func)(session, var)));
 
695
  var->updateValue();
 
696
  return (check_func && (*check_func)(session, var));
735
697
}
736
698
 
737
699
bool sys_var_session_uint64_t::update(Session *session,  set_var *var)
738
700
{
739
 
  uint64_t tmp= var->save_result.uint64_t_value;
 
701
  uint64_t tmp= var->getInteger();
740
702
 
741
703
  if (tmp > max_system_variables.*offset)
742
704
  {
749
711
  if (var->type == OPT_GLOBAL)
750
712
  {
751
713
    /* Lock is needed to make things safe on 32 bit systems */
752
 
    LOCK_global_system_variables.lock();
 
714
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
753
715
    global_system_variables.*offset= (uint64_t) tmp;
754
 
    LOCK_global_system_variables.unlock();
755
716
  }
756
717
  else
 
718
  {
757
719
    session->variables.*offset= (uint64_t) tmp;
 
720
  }
 
721
 
758
722
  return 0;
759
723
}
760
724
 
764
728
  if (type == OPT_GLOBAL)
765
729
  {
766
730
    bool not_used;
767
 
    LOCK_global_system_variables.lock();
 
731
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
768
732
    global_system_variables.*offset=
769
733
      getopt_ull_limit_value((uint64_t) option_limits->def_value,
770
734
                             option_limits, &not_used);
771
 
    LOCK_global_system_variables.unlock();
772
735
  }
773
736
  else
 
737
  {
774
738
    session->variables.*offset= global_system_variables.*offset;
 
739
  }
775
740
}
776
741
 
777
742
 
786
751
 
787
752
bool sys_var_session_size_t::check(Session *session, set_var *var)
788
753
{
789
 
  return (get_size_t(session, var) ||
790
 
          (check_func && (*check_func)(session, var)));
 
754
  var->updateValue();
 
755
  return (check_func && (*check_func)(session, var));
791
756
}
792
757
 
793
758
bool sys_var_session_size_t::update(Session *session,  set_var *var)
794
759
{
795
 
  size_t tmp= var->save_result.size_t_value;
 
760
  size_t tmp= size_t(var->getInteger());
796
761
 
797
762
  if (tmp > max_system_variables.*offset)
798
763
    tmp= max_system_variables.*offset;
802
767
  if (var->type == OPT_GLOBAL)
803
768
  {
804
769
    /* Lock is needed to make things safe on 32 bit systems */
805
 
    LOCK_global_system_variables.lock();
 
770
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
806
771
    global_system_variables.*offset= tmp;
807
 
    LOCK_global_system_variables.unlock();
808
772
  }
809
773
  else
 
774
  {
810
775
    session->variables.*offset= tmp;
 
776
  }
 
777
 
811
778
  return 0;
812
779
}
813
780
 
817
784
  if (type == OPT_GLOBAL)
818
785
  {
819
786
    bool not_used;
820
 
    LOCK_global_system_variables.lock();
 
787
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
821
788
    global_system_variables.*offset=
822
789
      (size_t)getopt_ull_limit_value((size_t) option_limits->def_value,
823
790
                                     option_limits, &not_used);
824
 
    LOCK_global_system_variables.unlock();
825
791
  }
826
792
  else
 
793
  {
827
794
    session->variables.*offset= global_system_variables.*offset;
 
795
  }
828
796
}
829
797
 
830
798
 
837
805
  return (unsigned char*) &(session->variables.*offset);
838
806
}
839
807
 
 
808
bool sys_var_session_bool::check(Session *session, set_var *var)
 
809
{
 
810
  return check_enum(session, var, &bool_typelib);
 
811
}
840
812
 
841
813
bool sys_var_session_bool::update(Session *session,  set_var *var)
842
814
{
843
815
  if (var->type == OPT_GLOBAL)
844
 
    global_system_variables.*offset= (bool) var->save_result.uint32_t_value;
 
816
    global_system_variables.*offset= bool(var->getInteger());
845
817
  else
846
 
    session->variables.*offset= (bool) var->save_result.uint32_t_value;
 
818
    session->variables.*offset= bool(var->getInteger());
 
819
 
847
820
  return 0;
848
821
}
849
822
 
876
849
 
877
850
  if (var->value->result_type() == STRING_RESULT)
878
851
  {
879
 
    if (!(res=var->value->val_str(&str)) ||
880
 
        (var->save_result.uint32_t_value= find_type(enum_names, res->ptr(),
881
 
                                                    res->length(),1)) == 0)
 
852
    res= var->value->val_str(&str);
 
853
    if (res == NULL)
882
854
    {
883
 
      value= res ? res->c_ptr() : "NULL";
 
855
      value= "NULL";
884
856
      goto err;
885
857
    }
886
858
 
887
 
    var->save_result.uint32_t_value--;
 
859
    uint64_t tmp_val= enum_names->find_type(res->ptr(), res->length(), true);
 
860
    if (tmp_val == 0)
 
861
    {
 
862
      value= res->c_ptr();
 
863
      goto err;
 
864
    }
 
865
    var->setValue(tmp_val-1);
888
866
  }
889
867
  else
890
868
  {
891
 
    uint64_t tmp=var->value->val_int();
 
869
    uint64_t tmp= var->value->val_int();
892
870
    if (tmp >= enum_names->count)
893
871
    {
894
872
      internal::llstr(tmp,buff);
895
873
      value=buff;                               // Wrong value is here
896
874
      goto err;
897
875
    }
898
 
    var->save_result.uint32_t_value= (uint32_t) tmp;    // Save for update
 
876
    var->setValue(tmp); // Save for update
899
877
  }
900
878
  return 0;
901
879
 
931
909
  case SHOW_INT:
932
910
  {
933
911
    uint32_t value;
934
 
    LOCK_global_system_variables.lock();
 
912
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
935
913
    value= *(uint*) value_ptr(session, var_type, base);
936
 
    LOCK_global_system_variables.unlock();
 
914
 
937
915
    return new Item_uint((uint64_t) value);
938
916
  }
939
917
  case SHOW_LONGLONG:
940
918
  {
941
919
    int64_t value;
942
 
    LOCK_global_system_variables.lock();
 
920
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
943
921
    value= *(int64_t*) value_ptr(session, var_type, base);
944
 
    LOCK_global_system_variables.unlock();
 
922
 
945
923
    return new Item_int(value);
946
924
  }
947
925
  case SHOW_DOUBLE:
948
926
  {
949
927
    double value;
950
 
    LOCK_global_system_variables.lock();
951
 
    value= *(double*) value_ptr(session, var_type, base);
952
 
    LOCK_global_system_variables.unlock();
 
928
    {
 
929
      boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
930
      value= *(double*) value_ptr(session, var_type, base);
 
931
    }
 
932
 
953
933
    /* 6, as this is for now only used with microseconds */
954
934
    return new Item_float(value, 6);
955
935
  }
956
936
  case SHOW_HA_ROWS:
957
937
  {
958
938
    ha_rows value;
959
 
    LOCK_global_system_variables.lock();
 
939
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
960
940
    value= *(ha_rows*) value_ptr(session, var_type, base);
961
 
    LOCK_global_system_variables.unlock();
 
941
 
962
942
    return new Item_int((uint64_t) value);
963
943
  }
964
944
  case SHOW_SIZE:
965
945
  {
966
946
    size_t value;
967
 
    LOCK_global_system_variables.lock();
 
947
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
968
948
    value= *(size_t*) value_ptr(session, var_type, base);
969
 
    LOCK_global_system_variables.unlock();
 
949
 
970
950
    return new Item_int((uint64_t) value);
971
951
  }
972
952
  case SHOW_MY_BOOL:
973
953
  {
974
954
    int32_t value;
975
 
    LOCK_global_system_variables.lock();
 
955
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
976
956
    value= *(bool*) value_ptr(session, var_type, base);
977
 
    LOCK_global_system_variables.unlock();
978
957
    return new Item_int(value,1);
979
958
  }
980
959
  case SHOW_CHAR_PTR:
981
960
  {
982
961
    Item *tmp;
983
 
    LOCK_global_system_variables.lock();
 
962
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
984
963
    char *str= *(char**) value_ptr(session, var_type, base);
985
964
    if (str)
986
965
    {
993
972
      tmp= new Item_null();
994
973
      tmp->collation.set(system_charset_info, DERIVATION_SYSCONST);
995
974
    }
996
 
    LOCK_global_system_variables.unlock();
 
975
 
997
976
    return tmp;
998
977
  }
999
978
  case SHOW_CHAR:
1000
979
  {
1001
980
    Item *tmp;
1002
 
    LOCK_global_system_variables.lock();
 
981
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
1003
982
    char *str= (char*) value_ptr(session, var_type, base);
1004
983
    if (str)
1005
984
      tmp= new Item_string(str, strlen(str),
1009
988
      tmp= new Item_null();
1010
989
      tmp->collation.set(system_charset_info, DERIVATION_SYSCONST);
1011
990
    }
1012
 
    LOCK_global_system_variables.unlock();
 
991
 
1013
992
    return tmp;
1014
993
  }
1015
994
  default:
1022
1001
bool sys_var_session_enum::update(Session *session, set_var *var)
1023
1002
{
1024
1003
  if (var->type == OPT_GLOBAL)
1025
 
    global_system_variables.*offset= var->save_result.uint32_t_value;
 
1004
    global_system_variables.*offset= var->getInteger();
1026
1005
  else
1027
 
    session->variables.*offset= var->save_result.uint32_t_value;
 
1006
    session->variables.*offset= var->getInteger();
1028
1007
  return 0;
1029
1008
}
1030
1009
 
1074
1053
}
1075
1054
 
1076
1055
 
1077
 
typedef struct old_names_map_st
1078
 
{
1079
 
  const char *old_name;
1080
 
  const char *new_name;
1081
 
} my_old_conv;
1082
 
 
1083
 
bool sys_var_collation::check(Session *, set_var *var)
 
1056
bool sys_var_collation_sv::update(Session *session, set_var *var)
1084
1057
{
1085
1058
  const CHARSET_INFO *tmp;
1086
1059
 
1090
1063
    String str(buff,sizeof(buff), system_charset_info), *res;
1091
1064
    if (!(res=var->value->val_str(&str)))
1092
1065
    {
1093
 
      my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.c_str(), "NULL");
 
1066
      boost::throw_exception(invalid_option_value(var->var->getName()) << invalid_value(std::string("NULL")));
1094
1067
      return 1;
1095
1068
    }
1096
1069
    if (!(tmp=get_charset_by_name(res->c_ptr())))
1097
1070
    {
1098
1071
      my_error(ER_UNKNOWN_COLLATION, MYF(0), res->c_ptr());
 
1072
      boost::throw_exception(invalid_option_value(var->var->getName()) << invalid_value(std::string(res->c_ptr())));
1099
1073
      return 1;
1100
1074
    }
1101
1075
  }
1106
1080
      char buf[20];
1107
1081
      internal::int10_to_str((int) var->value->val_int(), buf, -10);
1108
1082
      my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
 
1083
      boost::throw_exception(invalid_option_value(var->var->getName()) << invalid_value(boost::lexical_cast<std::string>(var->value->val_int())));
1109
1084
      return 1;
1110
1085
    }
1111
1086
  }
1112
 
  var->save_result.charset= tmp;        // Save for update
1113
 
  return 0;
1114
 
}
1115
 
 
1116
 
 
1117
 
bool sys_var_collation_sv::update(Session *session, set_var *var)
1118
 
{
1119
1087
  if (var->type == OPT_GLOBAL)
1120
 
    global_system_variables.*offset= var->save_result.charset;
 
1088
    global_system_variables.*offset= tmp;
1121
1089
  else
1122
1090
  {
1123
 
    session->variables.*offset= var->save_result.charset;
 
1091
    session->variables.*offset= tmp;
1124
1092
  }
1125
1093
  return 0;
1126
1094
}
1151
1119
 
1152
1120
bool sys_var_timestamp::update(Session *session,  set_var *var)
1153
1121
{
1154
 
  session->set_time((time_t) var->save_result.uint64_t_value);
 
1122
  session->set_time(time_t(var->getInteger()));
1155
1123
  return 0;
1156
1124
}
1157
1125
 
1158
1126
 
1159
1127
void sys_var_timestamp::set_default(Session *session, sql_var_t)
1160
1128
{
1161
 
  session->user_time=0;
 
1129
  session->resetUserTime();
1162
1130
}
1163
1131
 
1164
1132
 
1165
1133
unsigned char *sys_var_timestamp::value_ptr(Session *session, sql_var_t,
1166
1134
                                            const LEX_STRING *)
1167
1135
{
1168
 
  session->sys_var_tmp.int32_t_value= (int32_t) session->start_time;
 
1136
  session->sys_var_tmp.int32_t_value= (int32_t) session->getCurrentTimestampEpoch();
1169
1137
  return (unsigned char*) &session->sys_var_tmp.int32_t_value;
1170
1138
}
1171
1139
 
1172
1140
 
1173
1141
bool sys_var_last_insert_id::update(Session *session, set_var *var)
1174
1142
{
1175
 
  session->first_successful_insert_id_in_prev_stmt=
1176
 
    var->save_result.uint64_t_value;
 
1143
  session->first_successful_insert_id_in_prev_stmt= var->getInteger();
1177
1144
  return 0;
1178
1145
}
1179
1146
 
1191
1158
  return (unsigned char*) &session->sys_var_tmp.uint64_t_value;
1192
1159
}
1193
1160
 
1194
 
 
1195
 
bool sys_var_session_time_zone::check(Session *session, set_var *var)
1196
 
{
1197
 
  char buff[MAX_TIME_ZONE_NAME_LENGTH];
1198
 
  String str(buff, sizeof(buff), &my_charset_utf8_general_ci);
1199
 
  String *res= var->value->val_str(&str);
1200
 
 
1201
 
  if (!(var->save_result.time_zone= my_tz_find(session, res)))
1202
 
  {
1203
 
    my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), res ? res->c_ptr() : "NULL");
1204
 
    return 1;
1205
 
  }
1206
 
  return 0;
1207
 
}
1208
 
 
1209
 
 
1210
 
bool sys_var_session_time_zone::update(Session *session, set_var *var)
1211
 
{
1212
 
  /* We are using Time_zone object found during check() phase. */
1213
 
  if (var->type == OPT_GLOBAL)
1214
 
  {
1215
 
    LOCK_global_system_variables.lock();
1216
 
    global_system_variables.time_zone= var->save_result.time_zone;
1217
 
    LOCK_global_system_variables.unlock();
1218
 
  }
1219
 
  else
1220
 
    session->variables.time_zone= var->save_result.time_zone;
1221
 
  return 0;
1222
 
}
1223
 
 
1224
 
 
1225
 
unsigned char *sys_var_session_time_zone::value_ptr(Session *session,
1226
 
                                                    sql_var_t type,
1227
 
                                                    const LEX_STRING *)
1228
 
{
1229
 
  /*
1230
 
    We can use ptr() instead of c_ptr() here because String contaning
1231
 
    time zone name is guaranteed to be zero ended.
1232
 
  */
1233
 
  if (type == OPT_GLOBAL)
1234
 
    return (unsigned char *)(global_system_variables.time_zone->get_name()->ptr());
1235
 
  else
1236
 
  {
1237
 
    /*
1238
 
      This is an ugly fix for replication: we don't replicate properly queries
1239
 
      invoking system variables' values to update tables; but
1240
 
      CONVERT_TZ(,,@@session.time_zone) is so popular that we make it
1241
 
      replicable (i.e. we tell the binlog code to store the session
1242
 
      timezone). If it's the global value which was used we can't replicate
1243
 
      (binlog code stores session value only).
1244
 
    */
1245
 
    return (unsigned char *)(session->variables.time_zone->get_name()->ptr());
1246
 
  }
1247
 
}
1248
 
 
1249
 
 
1250
 
void sys_var_session_time_zone::set_default(Session *session, sql_var_t type)
1251
 
{
1252
 
 LOCK_global_system_variables.lock();
1253
 
 if (type == OPT_GLOBAL)
1254
 
 {
1255
 
   if (default_tz_name)
1256
 
   {
1257
 
     String str(default_tz_name, &my_charset_utf8_general_ci);
1258
 
     /*
1259
 
       We are guaranteed to find this time zone since its existence
1260
 
       is checked during start-up.
1261
 
     */
1262
 
     global_system_variables.time_zone= my_tz_find(session, &str);
1263
 
   }
1264
 
   else
1265
 
     global_system_variables.time_zone= my_tz_SYSTEM;
1266
 
 }
1267
 
 else
1268
 
   session->variables.time_zone= global_system_variables.time_zone;
1269
 
 LOCK_global_system_variables.unlock();
1270
 
}
1271
 
 
1272
 
 
1273
 
bool sys_var_session_lc_time_names::check(Session *, set_var *var)
 
1161
bool sys_var_session_lc_time_names::update(Session *session, set_var *var)
1274
1162
{
1275
1163
  MY_LOCALE *locale_match;
1276
1164
 
1278
1166
  {
1279
1167
    if (!(locale_match= my_locale_by_number((uint32_t) var->value->val_int())))
1280
1168
    {
1281
 
      char buf[20];
 
1169
      char buf[DECIMAL_LONGLONG_DIGITS];
1282
1170
      internal::int10_to_str((int) var->value->val_int(), buf, -10);
1283
1171
      my_printf_error(ER_UNKNOWN_ERROR, "Unknown locale: '%s'", MYF(0), buf);
1284
1172
      return 1;
1302
1190
    }
1303
1191
  }
1304
1192
 
1305
 
  var->save_result.locale_value= locale_match;
1306
 
  return 0;
1307
 
}
1308
 
 
1309
 
 
1310
 
bool sys_var_session_lc_time_names::update(Session *session, set_var *var)
1311
 
{
1312
1193
  if (var->type == OPT_GLOBAL)
1313
 
    global_system_variables.lc_time_names= var->save_result.locale_value;
 
1194
    global_system_variables.lc_time_names= locale_match;
1314
1195
  else
1315
 
    session->variables.lc_time_names= var->save_result.locale_value;
 
1196
    session->variables.lc_time_names= locale_match;
1316
1197
  return 0;
1317
1198
}
1318
1199
 
1355
1236
  microseconds= (int64_t) (num * 1000000.0 + 0.5);
1356
1237
  if (var->type == OPT_GLOBAL)
1357
1238
  {
1358
 
    LOCK_global_system_variables.lock();
 
1239
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
1359
1240
    (global_system_variables.*offset)= microseconds;
1360
 
    LOCK_global_system_variables.unlock();
1361
1241
  }
1362
1242
  else
1363
1243
    session->variables.*offset= microseconds;
1370
1250
  int64_t microseconds= (int64_t) (option_limits->def_value * 1000000.0);
1371
1251
  if (type == OPT_GLOBAL)
1372
1252
  {
1373
 
    LOCK_global_system_variables.lock();
 
1253
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
1374
1254
    global_system_variables.*offset= microseconds;
1375
 
    LOCK_global_system_variables.unlock();
1376
1255
  }
1377
1256
  else
1378
1257
    session->variables.*offset= microseconds;
1385
1264
static bool set_option_bit(Session *session, set_var *var)
1386
1265
{
1387
1266
  sys_var_session_bit *sys_var= ((sys_var_session_bit*) var->var);
1388
 
  if ((var->save_result.uint32_t_value != 0) == sys_var->reverse)
 
1267
  if ((var->getInteger() != 0) == sys_var->reverse)
1389
1268
    session->options&= ~sys_var->bit_flag;
1390
1269
  else
1391
1270
    session->options|= sys_var->bit_flag;
1395
1274
 
1396
1275
static bool set_option_autocommit(Session *session, set_var *var)
1397
1276
{
 
1277
  bool success= true;
1398
1278
  /* The test is negative as the flag we use is NOT autocommit */
1399
1279
 
1400
1280
  uint64_t org_options= session->options;
 
1281
  uint64_t new_options= session->options;
1401
1282
 
1402
 
  if (var->save_result.uint32_t_value != 0)
1403
 
    session->options&= ~((sys_var_session_bit*) var->var)->bit_flag;
 
1283
  if (var->getInteger() != 0)
 
1284
    new_options&= ~((sys_var_session_bit*) var->var)->bit_flag;
1404
1285
  else
1405
 
    session->options|= ((sys_var_session_bit*) var->var)->bit_flag;
 
1286
    new_options|= ((sys_var_session_bit*) var->var)->bit_flag;
1406
1287
 
1407
 
  if ((org_options ^ session->options) & OPTION_NOT_AUTOCOMMIT)
 
1288
  if ((org_options ^ new_options) & OPTION_NOT_AUTOCOMMIT)
1408
1289
  {
1409
1290
    if ((org_options & OPTION_NOT_AUTOCOMMIT))
1410
1291
    {
 
1292
      success= session->endActiveTransaction();
1411
1293
      /* We changed to auto_commit mode */
1412
1294
      session->options&= ~(uint64_t) (OPTION_BEGIN);
1413
1295
      session->server_status|= SERVER_STATUS_AUTOCOMMIT;
1414
 
      TransactionServices &transaction_services= TransactionServices::singleton();
1415
 
      if (transaction_services.commitTransaction(session, true))
1416
 
        return 1;
1417
1296
    }
1418
1297
    else
1419
1298
    {
1420
1299
      session->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
1421
1300
    }
1422
1301
  }
 
1302
 
 
1303
  if (var->getInteger() != 0)
 
1304
    session->options&= ~((sys_var_session_bit*) var->var)->bit_flag;
 
1305
  else
 
1306
    session->options|= ((sys_var_session_bit*) var->var)->bit_flag;
 
1307
 
 
1308
  if (not success)
 
1309
    return true;
 
1310
 
1423
1311
  return 0;
1424
1312
}
1425
1313
 
1426
1314
static int check_pseudo_thread_id(Session *, set_var *var)
1427
1315
{
1428
 
  var->save_result.uint64_t_value= var->value->val_int();
 
1316
  var->updateValue();
1429
1317
  return 0;
1430
1318
}
1431
1319
 
1523
1411
drizzle_show_var* enumerate_sys_vars(Session *session)
1524
1412
{
1525
1413
  int size= sizeof(drizzle_show_var) * (system_variable_map.size() + 1);
1526
 
  drizzle_show_var *result= (drizzle_show_var*) session->alloc(size);
 
1414
  drizzle_show_var *result= (drizzle_show_var*) session->getMemRoot()->allocate(size);
1527
1415
 
1528
1416
  if (result)
1529
1417
  {
1557
1445
  /* this fails if there is a conflicting variable name. */
1558
1446
  if (system_variable_map.find(lower_name) != system_variable_map.end())
1559
1447
  {
1560
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Variable named %s already exists!\n"),
 
1448
    errmsg_printf(error::ERROR, _("Variable named %s already exists!\n"),
1561
1449
                  var->getName().c_str());
1562
1450
    throw exception();
1563
1451
  } 
1566
1454
    system_variable_map.insert(make_pair(lower_name, var));
1567
1455
  if (ret.second == false)
1568
1456
  {
1569
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Could not add Variable: %s\n"),
 
1457
    errmsg_printf(error::ERROR, _("Could not add Variable: %s\n"),
1570
1458
                  var->getName().c_str());
1571
1459
    throw exception();
1572
1460
  }
1614
1502
    add_sys_var_to_list(&sys_last_insert_id, my_long_options);
1615
1503
    add_sys_var_to_list(&sys_lc_time_names, my_long_options);
1616
1504
    add_sys_var_to_list(&sys_max_allowed_packet, my_long_options);
1617
 
    add_sys_var_to_list(&sys_max_connect_errors, my_long_options);
1618
1505
    add_sys_var_to_list(&sys_max_error_count, my_long_options);
1619
1506
    add_sys_var_to_list(&sys_max_heap_table_size, my_long_options);
1620
1507
    add_sys_var_to_list(&sys_max_join_size, my_long_options);
1643
1530
    add_sys_var_to_list(&sys_sql_notes, my_long_options);
1644
1531
    add_sys_var_to_list(&sys_sql_warnings, my_long_options);
1645
1532
    add_sys_var_to_list(&sys_storage_engine, my_long_options);
1646
 
    add_sys_var_to_list(&sys_system_time_zone, my_long_options);
1647
1533
    add_sys_var_to_list(&sys_table_cache_size, my_long_options);
1648
1534
    add_sys_var_to_list(&sys_table_def_size, my_long_options);
1649
1535
    add_sys_var_to_list(&sys_table_lock_wait_timeout, my_long_options);
1650
1536
    add_sys_var_to_list(&sys_thread_stack_size, my_long_options);
1651
 
    add_sys_var_to_list(&sys_time_zone, my_long_options);
1652
1537
    add_sys_var_to_list(&sys_timed_mutexes, my_long_options);
1653
1538
    add_sys_var_to_list(&sys_timestamp, my_long_options);
1654
1539
    add_sys_var_to_list(&sys_tmp_table_size, my_long_options);
1665
1550
  }
1666
1551
  catch (std::exception&)
1667
1552
  {
1668
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize system variables"));
 
1553
    errmsg_printf(error::ERROR, _("Failed to initialize system variables"));
1669
1554
    return(1);
1670
1555
  }
1671
1556
  return(0);
1675
1560
/**
1676
1561
  Find a user set-table variable.
1677
1562
 
1678
 
  @param str       Name of system variable to find
1679
 
  @param length    Length of variable.  zero means that we should use strlen()
1680
 
                   on the variable
1681
 
  @param no_error  Refuse to emit an error, even if one occurred.
 
1563
  @param name      Name of system variable to find
1682
1564
 
1683
1565
  @retval
1684
1566
    pointer     pointer to variable definitions
1686
1568
    0           Unknown variable (error message is given)
1687
1569
*/
1688
1570
 
1689
 
sys_var *intern_find_sys_var(const char *str, uint32_t, bool no_error)
 
1571
sys_var *find_sys_var(const std::string &name)
1690
1572
{
1691
 
  string lower_name(str);
 
1573
  string lower_name(name);
1692
1574
  transform(lower_name.begin(), lower_name.end(),
1693
1575
            lower_name.begin(), ::tolower);
1694
1576
 
1700
1582
    result= (*iter).second;
1701
1583
  } 
1702
1584
 
1703
 
  /*
1704
 
    This function is only called from the sql_plugin.cc.
1705
 
    A lock on LOCK_system_variable_hash should be held
1706
 
  */
1707
1585
  if (result == NULL)
1708
1586
  {
1709
 
    if (no_error)
1710
 
    {
1711
 
      return NULL;
1712
 
    }
1713
 
    else
1714
 
    {
1715
 
      my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
1716
 
      return NULL;
1717
 
    }
 
1587
    my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), name.c_str());
 
1588
    return NULL;
1718
1589
  }
1719
1590
 
1720
1591
  return result;
1725
1596
 Functions to handle table_type
1726
1597
****************************************************************************/
1727
1598
 
1728
 
/* Based upon sys_var::check_enum() */
1729
 
 
1730
 
bool sys_var_session_storage_engine::check(Session *session, set_var *var)
1731
 
{
1732
 
  char buff[STRING_BUFFER_USUAL_SIZE];
1733
 
  const char *value;
1734
 
  String str(buff, sizeof(buff), &my_charset_utf8_general_ci), *res;
1735
 
 
1736
 
  var->save_result.storage_engine= NULL;
1737
 
  if (var->value->result_type() == STRING_RESULT)
1738
 
  {
1739
 
    res= var->value->val_str(&str);
1740
 
    if (res == NULL || res->ptr() == NULL)
1741
 
    {
1742
 
      value= "NULL";
1743
 
      goto err;
1744
 
    }
1745
 
    else
1746
 
    {
1747
 
      const std::string engine_name(res->ptr());
1748
 
      plugin::StorageEngine *engine;
1749
 
      var->save_result.storage_engine= plugin::StorageEngine::findByName(*session, engine_name);
1750
 
      if (var->save_result.storage_engine == NULL)
1751
 
      {
1752
 
        value= res->c_ptr();
1753
 
        goto err;
1754
 
      }
1755
 
      engine= var->save_result.storage_engine;
1756
 
    }
1757
 
    return 0;
1758
 
  }
1759
 
  value= "unknown";
1760
 
 
1761
 
err:
1762
 
  my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), value);
1763
 
  return 1;
1764
 
}
1765
 
 
1766
 
 
1767
1599
unsigned char *sys_var_session_storage_engine::value_ptr(Session *session,
1768
1600
                                                         sql_var_t type,
1769
1601
                                                         const LEX_STRING *)
1801
1633
 
1802
1634
bool sys_var_session_storage_engine::update(Session *session, set_var *var)
1803
1635
{
1804
 
  plugin::StorageEngine **value= &(global_system_variables.*offset), *old_value;
 
1636
  char buff[STRING_BUFFER_USUAL_SIZE];
 
1637
  const char *name_value;
 
1638
  String str(buff, sizeof(buff), &my_charset_utf8_general_ci), *res;
 
1639
 
 
1640
  plugin::StorageEngine *tmp= NULL;
 
1641
  plugin::StorageEngine **value= NULL;
 
1642
    
 
1643
  if (var->value->result_type() == STRING_RESULT)
 
1644
  {
 
1645
    res= var->value->val_str(&str);
 
1646
    if (res == NULL || res->ptr() == NULL)
 
1647
    {
 
1648
      name_value= "NULL";
 
1649
      goto err;
 
1650
    }
 
1651
    else
 
1652
    {
 
1653
      const std::string engine_name(res->ptr());
 
1654
      tmp= plugin::StorageEngine::findByName(*session, engine_name);
 
1655
      if (tmp == NULL)
 
1656
      {
 
1657
        name_value= res->c_ptr();
 
1658
        goto err;
 
1659
      }
 
1660
    }
 
1661
  }
 
1662
  else
 
1663
  {
 
1664
    name_value= "unknown";
 
1665
  }
 
1666
 
 
1667
  value= &(global_system_variables.*offset);
1805
1668
   if (var->type != OPT_GLOBAL)
1806
1669
     value= &(session->variables.*offset);
1807
 
  old_value= *value;
1808
 
  if (old_value != var->save_result.storage_engine)
 
1670
  if (*value != tmp)
1809
1671
  {
1810
 
    *value= var->save_result.storage_engine;
 
1672
    *value= tmp;
1811
1673
  }
1812
1674
  return 0;
 
1675
err:
 
1676
  my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name_value);
 
1677
  return 1;
1813
1678
}
1814
1679
 
1815
1680
} /* namespace drizzled */