~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sys_var.cc

  • Committer: Lee Bieber
  • Date: 2010-12-03 01:16:19 UTC
  • mfrom: (1819.9.81 update-innobase)
  • Revision ID: kalebral@gmail.com-20101203011619-n6v584rijwdet05b
Merge Stewart - update Innobase plugin based on InnoDB 1.1.2

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, Inc.
 
4
 *  Copyright (C) 2008 Sun Microsystems
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).
39
44
*/
40
45
 
41
46
#include "config.h"
60
65
#include "drizzled/charset.h"
61
66
#include "drizzled/transaction_services.h"
62
67
#include "drizzled/constrained_value.h"
63
 
#include "drizzled/visibility.h"
64
 
#include "drizzled/plugin/storage_engine.h"
65
68
 
66
69
#include <cstdio>
67
70
#include <map>
85
88
extern const CHARSET_INFO *character_set_filesystem;
86
89
extern size_t my_thread_stack_size;
87
90
 
 
91
class sys_var_pluginvar;
88
92
typedef map<string, sys_var *> SystemVariableMap;
89
93
static SystemVariableMap system_variable_map;
90
94
extern char *opt_drizzle_tmpdir;
107
111
static void fix_max_join_size(Session *session, sql_var_t type);
108
112
static void fix_session_mem_root(Session *session, sql_var_t type);
109
113
static void fix_server_id(Session *session, sql_var_t type);
 
114
static bool get_unsigned32(Session *session, set_var *var);
 
115
static bool get_unsigned64(Session *session, set_var *var);
110
116
bool throw_bounds_warning(Session *session, bool fixed, bool unsignd,
111
117
                          const std::string &name, int64_t val);
112
118
static unsigned char *get_error_count(Session *session);
151
157
                                                     &drizzle_system_variables::join_buff_size);
152
158
static sys_var_session_uint32_t sys_max_allowed_packet("max_allowed_packet",
153
159
                                                       &drizzle_system_variables::max_allowed_packet);
 
160
static sys_var_uint64_t_ptr     sys_max_connect_errors("max_connect_errors",
 
161
                                               &max_connect_errors);
154
162
static sys_var_session_uint64_t sys_max_error_count("max_error_count",
155
163
                                                  &drizzle_system_variables::max_error_count);
156
164
static sys_var_session_uint64_t sys_max_heap_table_size("max_heap_table_size",
213
221
static sys_var_session_size_t   sys_sort_buffer("sort_buffer_size",
214
222
                                                &drizzle_system_variables::sortbuff_size);
215
223
 
216
 
static sys_var_size_t_ptr_readonly sys_transaction_message_threshold("transaction_message_threshold",
217
 
                                                                &transaction_message_threshold);
 
224
static sys_var_session_size_t sys_transaction_message_threshold("transaction_message_threshold",
 
225
                                                                &drizzle_system_variables::transaction_message_threshold);
218
226
 
219
227
static sys_var_session_storage_engine sys_storage_engine("storage_engine",
220
228
                                       &drizzle_system_variables::storage_engine);
313
321
/* Global read-only variable containing hostname */
314
322
static sys_var_const_str        sys_hostname("hostname", glob_hostname);
315
323
 
316
 
bool sys_var::check(Session *session, set_var *var)
 
324
bool sys_var::check(Session *, set_var *var)
317
325
{
318
 
  if (check_func)
319
 
  {
320
 
    int res;
321
 
    if ((res=(*check_func)(session, var)) < 0)
322
 
      my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), getName().c_str(), var->value->str_value.ptr());
323
 
    return res;
324
 
  }
325
 
  var->updateValue();
 
326
  var->save_result.uint64_t_value= var->value->val_int();
326
327
  return 0;
327
328
}
328
329
 
329
330
bool sys_var_str::check(Session *session, set_var *var)
330
331
{
 
332
  int res;
331
333
  if (!check_func)
332
334
    return 0;
333
335
 
334
 
  int res;
335
336
  if ((res=(*check_func)(session, var)) < 0)
336
337
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), getName().c_str(), var->value->str_value.ptr());
337
338
  return res;
432
433
{
433
434
  if (fixed)
434
435
  {
435
 
    char buf[DECIMAL_LONGLONG_DIGITS];
 
436
    char buf[22];
436
437
 
437
438
    if (unsignd)
438
439
      internal::ullstr((uint64_t) val, buf);
467
468
  return out;
468
469
}
469
470
 
 
471
static bool get_unsigned32(Session *session, set_var *var)
 
472
{
 
473
  if (var->value->unsigned_flag)
 
474
    var->save_result.uint32_t_value= 
 
475
      static_cast<uint32_t>(var->value->val_int());
 
476
  else
 
477
  {
 
478
    int64_t v= var->value->val_int();
 
479
    if (v > UINT32_MAX)
 
480
      throw_bounds_warning(session, true, true,var->var->getName().c_str(), v);
 
481
    
 
482
    var->save_result.uint32_t_value= 
 
483
      static_cast<uint32_t>((v > UINT32_MAX) ? UINT32_MAX : (v < 0) ? 0 : v);
 
484
  }
 
485
  return false;
 
486
}
 
487
 
 
488
static bool get_unsigned64(Session *, set_var *var)
 
489
{
 
490
  if (var->value->unsigned_flag)
 
491
      var->save_result.uint64_t_value=(uint64_t) var->value->val_int();
 
492
  else
 
493
  {
 
494
    int64_t v= var->value->val_int();
 
495
      var->save_result.uint64_t_value= (uint64_t) ((v < 0) ? 0 : v);
 
496
  }
 
497
  return 0;
 
498
}
 
499
 
 
500
static bool get_size_t(Session *, set_var *var)
 
501
{
 
502
  if (var->value->unsigned_flag)
 
503
    var->save_result.size_t_value= (size_t) var->value->val_int();
 
504
  else
 
505
  {
 
506
    ssize_t v= (ssize_t)var->value->val_int();
 
507
    var->save_result.size_t_value= (size_t) ((v < 0) ? 0 : v);
 
508
  }
 
509
  return 0;
 
510
}
 
511
 
470
512
bool sys_var_uint32_t_ptr::check(Session *, set_var *var)
471
513
{
472
 
  var->updateValue();
 
514
  var->save_result.uint32_t_value= (uint32_t)var->value->val_int();
473
515
  return 0;
474
516
}
475
517
 
476
518
bool sys_var_uint32_t_ptr::update(Session *session, set_var *var)
477
519
{
478
 
  uint64_t tmp= var->getInteger();
479
 
  boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
480
 
 
 
520
  uint32_t tmp= var->save_result.uint32_t_value;
 
521
  LOCK_global_system_variables.lock();
481
522
  if (option_limits)
482
523
  {
483
524
    uint32_t newvalue= (uint32_t) fix_unsigned(session, tmp, option_limits);
484
 
    if(static_cast<uint64_t>(newvalue) == tmp)
 
525
    if(newvalue==tmp)
485
526
      *value= newvalue;
486
527
  }
487
528
  else
488
 
  {
489
 
    *value= static_cast<uint32_t>(tmp);
490
 
  }
491
 
 
 
529
    *value= (uint32_t) tmp;
 
530
  LOCK_global_system_variables.unlock();
492
531
  return 0;
493
532
}
494
533
 
495
534
 
496
 
void sys_var_uint32_t_ptr::set_default(Session *session, sql_var_t)
 
535
void sys_var_uint32_t_ptr::set_default(Session *, sql_var_t)
497
536
{
498
537
  bool not_used;
499
 
  boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
538
  LOCK_global_system_variables.lock();
500
539
  *value= (uint32_t)getopt_ull_limit_value((uint32_t) option_limits->def_value,
501
540
                                           option_limits, &not_used);
 
541
  LOCK_global_system_variables.unlock();
502
542
}
503
543
 
504
544
 
505
545
bool sys_var_uint64_t_ptr::update(Session *session, set_var *var)
506
546
{
507
 
  uint64_t tmp= var->getInteger();
508
 
  boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
509
 
 
 
547
  uint64_t tmp= var->save_result.uint64_t_value;
 
548
  LOCK_global_system_variables.lock();
510
549
  if (option_limits)
511
550
  {
512
 
    uint64_t newvalue= fix_unsigned(session, tmp, option_limits);
 
551
    uint64_t newvalue= (uint64_t) fix_unsigned(session, tmp, option_limits);
513
552
    if(newvalue==tmp)
514
553
      *value= newvalue;
515
554
  }
516
555
  else
517
 
  {
518
 
    *value= tmp;
519
 
  }
520
 
 
 
556
    *value= (uint64_t) tmp;
 
557
  LOCK_global_system_variables.unlock();
521
558
  return 0;
522
559
}
523
560
 
524
561
 
525
 
void sys_var_uint64_t_ptr::set_default(Session *session, sql_var_t)
 
562
void sys_var_uint64_t_ptr::set_default(Session *, sql_var_t)
526
563
{
527
564
  if (have_default_value)
528
565
  {
531
568
  else
532
569
  {
533
570
    bool not_used;
534
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
571
    LOCK_global_system_variables.lock();
535
572
    *value= getopt_ull_limit_value((uint64_t) option_limits->def_value,
536
573
                                   option_limits, &not_used);
 
574
    LOCK_global_system_variables.unlock();
537
575
  }
538
576
}
539
577
 
540
578
 
541
579
bool sys_var_size_t_ptr::update(Session *session, set_var *var)
542
580
{
543
 
  size_t tmp= size_t(var->getInteger());
544
 
 
545
 
  boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
546
 
 
 
581
  size_t tmp= var->save_result.size_t_value;
 
582
  LOCK_global_system_variables.lock();
547
583
  if (option_limits)
548
584
    *value= fix_size_t(session, tmp, option_limits);
549
585
  else
550
586
    *value= tmp;
551
 
 
 
587
  LOCK_global_system_variables.unlock();
552
588
  return 0;
553
589
}
554
590
 
555
591
 
556
 
void sys_var_size_t_ptr::set_default(Session *session, sql_var_t)
 
592
void sys_var_size_t_ptr::set_default(Session *, sql_var_t)
557
593
{
558
594
  bool not_used;
559
 
  boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
595
  LOCK_global_system_variables.lock();
560
596
  *value= (size_t)getopt_ull_limit_value((size_t) option_limits->def_value,
561
597
                                         option_limits, &not_used);
562
 
}
563
 
 
564
 
bool sys_var_bool_ptr::check(Session *session, set_var *var)
565
 
{
566
 
  return check_enum(session, var, &bool_typelib);
 
598
  LOCK_global_system_variables.unlock();
567
599
}
568
600
 
569
601
bool sys_var_bool_ptr::update(Session *, set_var *var)
570
602
{
571
 
  *value= bool(var->getInteger());
 
603
  *value= (bool) var->save_result.uint32_t_value;
572
604
  return 0;
573
605
}
574
606
 
575
607
 
576
608
void sys_var_bool_ptr::set_default(Session *, sql_var_t)
577
609
{
578
 
  *value= default_value;
 
610
  *value= (bool) option_limits->def_value;
579
611
}
580
612
 
581
613
 
584
616
*/
585
617
bool sys_var_session_uint32_t::check(Session *session, set_var *var)
586
618
{
587
 
  var->updateValue();
588
 
  return (check_func && (*check_func)(session, var));
 
619
  return (get_unsigned32(session, var) ||
 
620
          (check_func && (*check_func)(session, var)));
589
621
}
590
622
 
591
623
bool sys_var_session_uint32_t::update(Session *session, set_var *var)
592
624
{
593
 
  uint64_t tmp= var->getInteger();
 
625
  uint64_t tmp= (uint64_t) var->save_result.uint32_t_value;
594
626
 
595
627
  /* Don't use bigger value than given with --maximum-variable-name=.. */
596
628
  if ((uint32_t) tmp > max_system_variables.*offset)
604
636
  else if (tmp > UINT32_MAX)
605
637
  {
606
638
    tmp= UINT32_MAX;
607
 
    throw_bounds_warning(session, true, true, getName(), int64_t(var->getInteger()));
 
639
    throw_bounds_warning(session, true, true, getName(), (int64_t) var->save_result.uint64_t_value);
608
640
  }
609
641
 
610
642
  if (var->type == OPT_GLOBAL)
643
675
 
644
676
bool sys_var_session_ha_rows::update(Session *session, set_var *var)
645
677
{
646
 
  uint64_t tmp= var->getInteger();
 
678
  uint64_t tmp= var->save_result.uint64_t_value;
647
679
 
648
680
  /* Don't use bigger value than given with --maximum-variable-name=.. */
649
681
  if ((ha_rows) tmp > max_system_variables.*offset)
654
686
  if (var->type == OPT_GLOBAL)
655
687
  {
656
688
    /* Lock is needed to make things safe on 32 bit systems */
657
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
689
    LOCK_global_system_variables.lock();
658
690
    global_system_variables.*offset= (ha_rows) tmp;
 
691
    LOCK_global_system_variables.unlock();
659
692
  }
660
693
  else
661
 
  {
662
694
    session->variables.*offset= (ha_rows) tmp;
663
 
  }
664
 
 
665
695
  return 0;
666
696
}
667
697
 
672
702
  {
673
703
    bool not_used;
674
704
    /* We will not come here if option_limits is not set */
675
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
705
    LOCK_global_system_variables.lock();
676
706
    global_system_variables.*offset=
677
707
      (ha_rows) getopt_ull_limit_value((ha_rows) option_limits->def_value,
678
708
                                       option_limits, &not_used);
 
709
    LOCK_global_system_variables.unlock();
679
710
  }
680
711
  else
681
 
  {
682
712
    session->variables.*offset= global_system_variables.*offset;
683
 
  }
684
713
}
685
714
 
686
715
 
695
724
 
696
725
bool sys_var_session_uint64_t::check(Session *session, set_var *var)
697
726
{
698
 
  var->updateValue();
699
 
  return (check_func && (*check_func)(session, var));
 
727
  return (get_unsigned64(session, var) ||
 
728
          (check_func && (*check_func)(session, var)));
700
729
}
701
730
 
702
731
bool sys_var_session_uint64_t::update(Session *session,  set_var *var)
703
732
{
704
 
  uint64_t tmp= var->getInteger();
 
733
  uint64_t tmp= var->save_result.uint64_t_value;
705
734
 
706
735
  if (tmp > max_system_variables.*offset)
707
736
  {
714
743
  if (var->type == OPT_GLOBAL)
715
744
  {
716
745
    /* Lock is needed to make things safe on 32 bit systems */
717
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
746
    LOCK_global_system_variables.lock();
718
747
    global_system_variables.*offset= (uint64_t) tmp;
 
748
    LOCK_global_system_variables.unlock();
719
749
  }
720
750
  else
721
 
  {
722
751
    session->variables.*offset= (uint64_t) tmp;
723
 
  }
724
 
 
725
752
  return 0;
726
753
}
727
754
 
731
758
  if (type == OPT_GLOBAL)
732
759
  {
733
760
    bool not_used;
734
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
761
    LOCK_global_system_variables.lock();
735
762
    global_system_variables.*offset=
736
763
      getopt_ull_limit_value((uint64_t) option_limits->def_value,
737
764
                             option_limits, &not_used);
 
765
    LOCK_global_system_variables.unlock();
738
766
  }
739
767
  else
740
 
  {
741
768
    session->variables.*offset= global_system_variables.*offset;
742
 
  }
743
769
}
744
770
 
745
771
 
754
780
 
755
781
bool sys_var_session_size_t::check(Session *session, set_var *var)
756
782
{
757
 
  var->updateValue();
758
 
  return (check_func && (*check_func)(session, var));
 
783
  return (get_size_t(session, var) ||
 
784
          (check_func && (*check_func)(session, var)));
759
785
}
760
786
 
761
787
bool sys_var_session_size_t::update(Session *session,  set_var *var)
762
788
{
763
 
  size_t tmp= size_t(var->getInteger());
 
789
  size_t tmp= var->save_result.size_t_value;
764
790
 
765
791
  if (tmp > max_system_variables.*offset)
766
792
    tmp= max_system_variables.*offset;
770
796
  if (var->type == OPT_GLOBAL)
771
797
  {
772
798
    /* Lock is needed to make things safe on 32 bit systems */
773
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
799
    LOCK_global_system_variables.lock();
774
800
    global_system_variables.*offset= tmp;
 
801
    LOCK_global_system_variables.unlock();
775
802
  }
776
803
  else
777
 
  {
778
804
    session->variables.*offset= tmp;
779
 
  }
780
 
 
781
805
  return 0;
782
806
}
783
807
 
787
811
  if (type == OPT_GLOBAL)
788
812
  {
789
813
    bool not_used;
790
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
814
    LOCK_global_system_variables.lock();
791
815
    global_system_variables.*offset=
792
816
      (size_t)getopt_ull_limit_value((size_t) option_limits->def_value,
793
817
                                     option_limits, &not_used);
 
818
    LOCK_global_system_variables.unlock();
794
819
  }
795
820
  else
796
 
  {
797
821
    session->variables.*offset= global_system_variables.*offset;
798
 
  }
799
822
}
800
823
 
801
824
 
808
831
  return (unsigned char*) &(session->variables.*offset);
809
832
}
810
833
 
811
 
bool sys_var_session_bool::check(Session *session, set_var *var)
812
 
{
813
 
  return check_enum(session, var, &bool_typelib);
814
 
}
815
834
 
816
835
bool sys_var_session_bool::update(Session *session,  set_var *var)
817
836
{
818
837
  if (var->type == OPT_GLOBAL)
819
 
    global_system_variables.*offset= bool(var->getInteger());
 
838
    global_system_variables.*offset= (bool) var->save_result.uint32_t_value;
820
839
  else
821
 
    session->variables.*offset= bool(var->getInteger());
822
 
 
 
840
    session->variables.*offset= (bool) var->save_result.uint32_t_value;
823
841
  return 0;
824
842
}
825
843
 
852
870
 
853
871
  if (var->value->result_type() == STRING_RESULT)
854
872
  {
855
 
    res= var->value->val_str(&str);
856
 
    if (res == NULL)
 
873
    if (!(res=var->value->val_str(&str)) ||
 
874
        (var->save_result.uint32_t_value= find_type(enum_names, res->ptr(),
 
875
                                                    res->length(),1)) == 0)
857
876
    {
858
 
      value= "NULL";
 
877
      value= res ? res->c_ptr() : "NULL";
859
878
      goto err;
860
879
    }
861
880
 
862
 
    uint64_t tmp_val= find_type(enum_names, res->ptr(), res->length(),1);
863
 
    if (tmp_val == 0)
864
 
    {
865
 
      value= res->c_ptr();
866
 
      goto err;
867
 
    }
868
 
    var->setValue(tmp_val-1);
 
881
    var->save_result.uint32_t_value--;
869
882
  }
870
883
  else
871
884
  {
872
 
    uint64_t tmp= var->value->val_int();
 
885
    uint64_t tmp=var->value->val_int();
873
886
    if (tmp >= enum_names->count)
874
887
    {
875
888
      internal::llstr(tmp,buff);
876
889
      value=buff;                               // Wrong value is here
877
890
      goto err;
878
891
    }
879
 
    var->setValue(tmp); // Save for update
 
892
    var->save_result.uint32_t_value= (uint32_t) tmp;    // Save for update
880
893
  }
881
894
  return 0;
882
895
 
912
925
  case SHOW_INT:
913
926
  {
914
927
    uint32_t value;
915
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
928
    LOCK_global_system_variables.lock();
916
929
    value= *(uint*) value_ptr(session, var_type, base);
917
 
 
 
930
    LOCK_global_system_variables.unlock();
918
931
    return new Item_uint((uint64_t) value);
919
932
  }
920
933
  case SHOW_LONGLONG:
921
934
  {
922
935
    int64_t value;
923
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
936
    LOCK_global_system_variables.lock();
924
937
    value= *(int64_t*) value_ptr(session, var_type, base);
925
 
 
 
938
    LOCK_global_system_variables.unlock();
926
939
    return new Item_int(value);
927
940
  }
928
941
  case SHOW_DOUBLE:
929
942
  {
930
943
    double value;
931
 
    {
932
 
      boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
933
 
      value= *(double*) value_ptr(session, var_type, base);
934
 
    }
935
 
 
 
944
    LOCK_global_system_variables.lock();
 
945
    value= *(double*) value_ptr(session, var_type, base);
 
946
    LOCK_global_system_variables.unlock();
936
947
    /* 6, as this is for now only used with microseconds */
937
948
    return new Item_float(value, 6);
938
949
  }
939
950
  case SHOW_HA_ROWS:
940
951
  {
941
952
    ha_rows value;
942
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
953
    LOCK_global_system_variables.lock();
943
954
    value= *(ha_rows*) value_ptr(session, var_type, base);
944
 
 
 
955
    LOCK_global_system_variables.unlock();
945
956
    return new Item_int((uint64_t) value);
946
957
  }
947
958
  case SHOW_SIZE:
948
959
  {
949
960
    size_t value;
950
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
961
    LOCK_global_system_variables.lock();
951
962
    value= *(size_t*) value_ptr(session, var_type, base);
952
 
 
 
963
    LOCK_global_system_variables.unlock();
953
964
    return new Item_int((uint64_t) value);
954
965
  }
955
966
  case SHOW_MY_BOOL:
956
967
  {
957
968
    int32_t value;
958
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
969
    LOCK_global_system_variables.lock();
959
970
    value= *(bool*) value_ptr(session, var_type, base);
 
971
    LOCK_global_system_variables.unlock();
960
972
    return new Item_int(value,1);
961
973
  }
962
974
  case SHOW_CHAR_PTR:
963
975
  {
964
976
    Item *tmp;
965
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
977
    LOCK_global_system_variables.lock();
966
978
    char *str= *(char**) value_ptr(session, var_type, base);
967
979
    if (str)
968
980
    {
975
987
      tmp= new Item_null();
976
988
      tmp->collation.set(system_charset_info, DERIVATION_SYSCONST);
977
989
    }
978
 
 
 
990
    LOCK_global_system_variables.unlock();
979
991
    return tmp;
980
992
  }
981
993
  case SHOW_CHAR:
982
994
  {
983
995
    Item *tmp;
984
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
996
    LOCK_global_system_variables.lock();
985
997
    char *str= (char*) value_ptr(session, var_type, base);
986
998
    if (str)
987
999
      tmp= new Item_string(str, strlen(str),
991
1003
      tmp= new Item_null();
992
1004
      tmp->collation.set(system_charset_info, DERIVATION_SYSCONST);
993
1005
    }
994
 
 
 
1006
    LOCK_global_system_variables.unlock();
995
1007
    return tmp;
996
1008
  }
997
1009
  default:
1004
1016
bool sys_var_session_enum::update(Session *session, set_var *var)
1005
1017
{
1006
1018
  if (var->type == OPT_GLOBAL)
1007
 
    global_system_variables.*offset= var->getInteger();
 
1019
    global_system_variables.*offset= var->save_result.uint32_t_value;
1008
1020
  else
1009
 
    session->variables.*offset= var->getInteger();
 
1021
    session->variables.*offset= var->save_result.uint32_t_value;
1010
1022
  return 0;
1011
1023
}
1012
1024
 
1056
1068
}
1057
1069
 
1058
1070
 
1059
 
bool sys_var_collation_sv::update(Session *session, set_var *var)
 
1071
typedef struct old_names_map_st
 
1072
{
 
1073
  const char *old_name;
 
1074
  const char *new_name;
 
1075
} my_old_conv;
 
1076
 
 
1077
bool sys_var_collation::check(Session *, set_var *var)
1060
1078
{
1061
1079
  const CHARSET_INFO *tmp;
1062
1080
 
1066
1084
    String str(buff,sizeof(buff), system_charset_info), *res;
1067
1085
    if (!(res=var->value->val_str(&str)))
1068
1086
    {
1069
 
      boost::throw_exception(invalid_option_value(var->var->getName()) << invalid_value(std::string("NULL")));
 
1087
      my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.c_str(), "NULL");
1070
1088
      return 1;
1071
1089
    }
1072
1090
    if (!(tmp=get_charset_by_name(res->c_ptr())))
1073
1091
    {
1074
1092
      my_error(ER_UNKNOWN_COLLATION, MYF(0), res->c_ptr());
1075
 
      boost::throw_exception(invalid_option_value(var->var->getName()) << invalid_value(std::string(res->c_ptr())));
1076
1093
      return 1;
1077
1094
    }
1078
1095
  }
1083
1100
      char buf[20];
1084
1101
      internal::int10_to_str((int) var->value->val_int(), buf, -10);
1085
1102
      my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
1086
 
      boost::throw_exception(invalid_option_value(var->var->getName()) << invalid_value(boost::lexical_cast<std::string>(var->value->val_int())));
1087
1103
      return 1;
1088
1104
    }
1089
1105
  }
 
1106
  var->save_result.charset= tmp;        // Save for update
 
1107
  return 0;
 
1108
}
 
1109
 
 
1110
 
 
1111
bool sys_var_collation_sv::update(Session *session, set_var *var)
 
1112
{
1090
1113
  if (var->type == OPT_GLOBAL)
1091
 
    global_system_variables.*offset= tmp;
 
1114
    global_system_variables.*offset= var->save_result.charset;
1092
1115
  else
1093
1116
  {
1094
 
    session->variables.*offset= tmp;
 
1117
    session->variables.*offset= var->save_result.charset;
1095
1118
  }
1096
1119
  return 0;
1097
1120
}
1122
1145
 
1123
1146
bool sys_var_timestamp::update(Session *session,  set_var *var)
1124
1147
{
1125
 
  session->set_time(time_t(var->getInteger()));
 
1148
  session->set_time((time_t) var->save_result.uint64_t_value);
1126
1149
  return 0;
1127
1150
}
1128
1151
 
1129
1152
 
1130
1153
void sys_var_timestamp::set_default(Session *session, sql_var_t)
1131
1154
{
1132
 
  session->resetUserTime();
 
1155
  session->user_time=0;
1133
1156
}
1134
1157
 
1135
1158
 
1136
1159
unsigned char *sys_var_timestamp::value_ptr(Session *session, sql_var_t,
1137
1160
                                            const LEX_STRING *)
1138
1161
{
1139
 
  session->sys_var_tmp.int32_t_value= (int32_t) session->getCurrentTimestampEpoch();
 
1162
  session->sys_var_tmp.int32_t_value= (int32_t) session->start_time;
1140
1163
  return (unsigned char*) &session->sys_var_tmp.int32_t_value;
1141
1164
}
1142
1165
 
1143
1166
 
1144
1167
bool sys_var_last_insert_id::update(Session *session, set_var *var)
1145
1168
{
1146
 
  session->first_successful_insert_id_in_prev_stmt= var->getInteger();
 
1169
  session->first_successful_insert_id_in_prev_stmt=
 
1170
    var->save_result.uint64_t_value;
1147
1171
  return 0;
1148
1172
}
1149
1173
 
1162
1186
}
1163
1187
 
1164
1188
 
1165
 
bool sys_var_session_time_zone::update(Session *session, set_var *var)
 
1189
bool sys_var_session_time_zone::check(Session *session, set_var *var)
1166
1190
{
1167
1191
  char buff[MAX_TIME_ZONE_NAME_LENGTH];
1168
1192
  String str(buff, sizeof(buff), &my_charset_utf8_general_ci);
1169
1193
  String *res= var->value->val_str(&str);
1170
1194
 
1171
 
  Time_zone *tmp= my_tz_find(session, res);
1172
 
  if (tmp == NULL)
 
1195
  if (!(var->save_result.time_zone= my_tz_find(session, res)))
1173
1196
  {
1174
 
    boost::throw_exception(invalid_option_value(var->var->getName()) << invalid_value(std::string(res ? res->c_ptr() : "NULL")));
 
1197
    my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), res ? res->c_ptr() : "NULL");
1175
1198
    return 1;
1176
1199
  }
 
1200
  return 0;
 
1201
}
 
1202
 
 
1203
 
 
1204
bool sys_var_session_time_zone::update(Session *session, set_var *var)
 
1205
{
1177
1206
  /* We are using Time_zone object found during check() phase. */
1178
1207
  if (var->type == OPT_GLOBAL)
1179
1208
  {
1180
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
1181
 
    global_system_variables.time_zone= tmp;
 
1209
    LOCK_global_system_variables.lock();
 
1210
    global_system_variables.time_zone= var->save_result.time_zone;
 
1211
    LOCK_global_system_variables.unlock();
1182
1212
  }
1183
1213
  else
1184
 
  {
1185
 
    session->variables.time_zone= tmp;
1186
 
  }
1187
 
 
 
1214
    session->variables.time_zone= var->save_result.time_zone;
1188
1215
  return 0;
1189
1216
}
1190
1217
 
1216
1243
 
1217
1244
void sys_var_session_time_zone::set_default(Session *session, sql_var_t type)
1218
1245
{
1219
 
  boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
1220
 
  if (type == OPT_GLOBAL)
1221
 
  {
1222
 
    if (default_tz_name)
1223
 
    {
1224
 
      String str(default_tz_name, &my_charset_utf8_general_ci);
1225
 
      /*
1226
 
        We are guaranteed to find this time zone since its existence
1227
 
        is checked during start-up.
1228
 
      */
1229
 
      global_system_variables.time_zone= my_tz_find(session, &str);
1230
 
    }
1231
 
    else
1232
 
      global_system_variables.time_zone= my_tz_SYSTEM;
1233
 
  }
1234
 
  else
1235
 
    session->variables.time_zone= global_system_variables.time_zone;
 
1246
 LOCK_global_system_variables.lock();
 
1247
 if (type == OPT_GLOBAL)
 
1248
 {
 
1249
   if (default_tz_name)
 
1250
   {
 
1251
     String str(default_tz_name, &my_charset_utf8_general_ci);
 
1252
     /*
 
1253
       We are guaranteed to find this time zone since its existence
 
1254
       is checked during start-up.
 
1255
     */
 
1256
     global_system_variables.time_zone= my_tz_find(session, &str);
 
1257
   }
 
1258
   else
 
1259
     global_system_variables.time_zone= my_tz_SYSTEM;
 
1260
 }
 
1261
 else
 
1262
   session->variables.time_zone= global_system_variables.time_zone;
 
1263
 LOCK_global_system_variables.unlock();
1236
1264
}
1237
1265
 
1238
1266
 
1239
 
 
1240
 
bool sys_var_session_lc_time_names::update(Session *session, set_var *var)
 
1267
bool sys_var_session_lc_time_names::check(Session *, set_var *var)
1241
1268
{
1242
1269
  MY_LOCALE *locale_match;
1243
1270
 
1245
1272
  {
1246
1273
    if (!(locale_match= my_locale_by_number((uint32_t) var->value->val_int())))
1247
1274
    {
1248
 
      char buf[DECIMAL_LONGLONG_DIGITS];
 
1275
      char buf[20];
1249
1276
      internal::int10_to_str((int) var->value->val_int(), buf, -10);
1250
1277
      my_printf_error(ER_UNKNOWN_ERROR, "Unknown locale: '%s'", MYF(0), buf);
1251
1278
      return 1;
1269
1296
    }
1270
1297
  }
1271
1298
 
 
1299
  var->save_result.locale_value= locale_match;
 
1300
  return 0;
 
1301
}
 
1302
 
 
1303
 
 
1304
bool sys_var_session_lc_time_names::update(Session *session, set_var *var)
 
1305
{
1272
1306
  if (var->type == OPT_GLOBAL)
1273
 
    global_system_variables.lc_time_names= locale_match;
 
1307
    global_system_variables.lc_time_names= var->save_result.locale_value;
1274
1308
  else
1275
 
    session->variables.lc_time_names= locale_match;
 
1309
    session->variables.lc_time_names= var->save_result.locale_value;
1276
1310
  return 0;
1277
1311
}
1278
1312
 
1315
1349
  microseconds= (int64_t) (num * 1000000.0 + 0.5);
1316
1350
  if (var->type == OPT_GLOBAL)
1317
1351
  {
1318
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
1352
    LOCK_global_system_variables.lock();
1319
1353
    (global_system_variables.*offset)= microseconds;
 
1354
    LOCK_global_system_variables.unlock();
1320
1355
  }
1321
1356
  else
1322
1357
    session->variables.*offset= microseconds;
1329
1364
  int64_t microseconds= (int64_t) (option_limits->def_value * 1000000.0);
1330
1365
  if (type == OPT_GLOBAL)
1331
1366
  {
1332
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
1367
    LOCK_global_system_variables.lock();
1333
1368
    global_system_variables.*offset= microseconds;
 
1369
    LOCK_global_system_variables.unlock();
1334
1370
  }
1335
1371
  else
1336
1372
    session->variables.*offset= microseconds;
1343
1379
static bool set_option_bit(Session *session, set_var *var)
1344
1380
{
1345
1381
  sys_var_session_bit *sys_var= ((sys_var_session_bit*) var->var);
1346
 
  if ((var->getInteger() != 0) == sys_var->reverse)
 
1382
  if ((var->save_result.uint32_t_value != 0) == sys_var->reverse)
1347
1383
    session->options&= ~sys_var->bit_flag;
1348
1384
  else
1349
1385
    session->options|= sys_var->bit_flag;
1353
1389
 
1354
1390
static bool set_option_autocommit(Session *session, set_var *var)
1355
1391
{
1356
 
  bool success= true;
1357
1392
  /* The test is negative as the flag we use is NOT autocommit */
1358
1393
 
1359
1394
  uint64_t org_options= session->options;
1360
 
  uint64_t new_options= session->options;
1361
1395
 
1362
 
  if (var->getInteger() != 0)
1363
 
    new_options&= ~((sys_var_session_bit*) var->var)->bit_flag;
 
1396
  if (var->save_result.uint32_t_value != 0)
 
1397
    session->options&= ~((sys_var_session_bit*) var->var)->bit_flag;
1364
1398
  else
1365
 
    new_options|= ((sys_var_session_bit*) var->var)->bit_flag;
 
1399
    session->options|= ((sys_var_session_bit*) var->var)->bit_flag;
1366
1400
 
1367
 
  if ((org_options ^ new_options) & OPTION_NOT_AUTOCOMMIT)
 
1401
  if ((org_options ^ session->options) & OPTION_NOT_AUTOCOMMIT)
1368
1402
  {
1369
1403
    if ((org_options & OPTION_NOT_AUTOCOMMIT))
1370
1404
    {
1371
 
      success= session->endActiveTransaction();
1372
1405
      /* We changed to auto_commit mode */
1373
1406
      session->options&= ~(uint64_t) (OPTION_BEGIN);
1374
1407
      session->server_status|= SERVER_STATUS_AUTOCOMMIT;
 
1408
      TransactionServices &transaction_services= TransactionServices::singleton();
 
1409
      if (transaction_services.commitTransaction(session, true))
 
1410
        return 1;
1375
1411
    }
1376
1412
    else
1377
1413
    {
1378
1414
      session->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
1379
1415
    }
1380
1416
  }
1381
 
 
1382
 
  if (var->getInteger() != 0)
1383
 
    session->options&= ~((sys_var_session_bit*) var->var)->bit_flag;
1384
 
  else
1385
 
    session->options|= ((sys_var_session_bit*) var->var)->bit_flag;
1386
 
 
1387
 
  if (not success)
1388
 
    return true;
1389
 
 
1390
1417
  return 0;
1391
1418
}
1392
1419
 
1393
1420
static int check_pseudo_thread_id(Session *, set_var *var)
1394
1421
{
1395
 
  var->updateValue();
 
1422
  var->save_result.uint64_t_value= var->value->val_int();
1396
1423
  return 0;
1397
1424
}
1398
1425
 
1490
1517
drizzle_show_var* enumerate_sys_vars(Session *session)
1491
1518
{
1492
1519
  int size= sizeof(drizzle_show_var) * (system_variable_map.size() + 1);
1493
 
  drizzle_show_var *result= (drizzle_show_var*) session->getMemRoot()->allocate(size);
 
1520
  drizzle_show_var *result= (drizzle_show_var*) session->alloc(size);
1494
1521
 
1495
1522
  if (result)
1496
1523
  {
1524
1551
  /* this fails if there is a conflicting variable name. */
1525
1552
  if (system_variable_map.find(lower_name) != system_variable_map.end())
1526
1553
  {
1527
 
    errmsg_printf(error::ERROR, _("Variable named %s already exists!\n"),
 
1554
    errmsg_printf(ERRMSG_LVL_ERROR, _("Variable named %s already exists!\n"),
1528
1555
                  var->getName().c_str());
1529
1556
    throw exception();
1530
1557
  } 
1533
1560
    system_variable_map.insert(make_pair(lower_name, var));
1534
1561
  if (ret.second == false)
1535
1562
  {
1536
 
    errmsg_printf(error::ERROR, _("Could not add Variable: %s\n"),
 
1563
    errmsg_printf(ERRMSG_LVL_ERROR, _("Could not add Variable: %s\n"),
1537
1564
                  var->getName().c_str());
1538
1565
    throw exception();
1539
1566
  }
1581
1608
    add_sys_var_to_list(&sys_last_insert_id, my_long_options);
1582
1609
    add_sys_var_to_list(&sys_lc_time_names, my_long_options);
1583
1610
    add_sys_var_to_list(&sys_max_allowed_packet, my_long_options);
 
1611
    add_sys_var_to_list(&sys_max_connect_errors, my_long_options);
1584
1612
    add_sys_var_to_list(&sys_max_error_count, my_long_options);
1585
1613
    add_sys_var_to_list(&sys_max_heap_table_size, my_long_options);
1586
1614
    add_sys_var_to_list(&sys_max_join_size, my_long_options);
1631
1659
  }
1632
1660
  catch (std::exception&)
1633
1661
  {
1634
 
    errmsg_printf(error::ERROR, _("Failed to initialize system variables"));
 
1662
    errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize system variables"));
1635
1663
    return(1);
1636
1664
  }
1637
1665
  return(0);
1641
1669
/**
1642
1670
  Find a user set-table variable.
1643
1671
 
1644
 
  @param name      Name of system variable to find
 
1672
  @param str       Name of system variable to find
 
1673
  @param length    Length of variable.  zero means that we should use strlen()
 
1674
                   on the variable
 
1675
  @param no_error  Refuse to emit an error, even if one occurred.
1645
1676
 
1646
1677
  @retval
1647
1678
    pointer     pointer to variable definitions
1649
1680
    0           Unknown variable (error message is given)
1650
1681
*/
1651
1682
 
1652
 
sys_var *find_sys_var(const std::string &name)
 
1683
sys_var *intern_find_sys_var(const char *str, uint32_t, bool no_error)
1653
1684
{
1654
 
  string lower_name(name);
 
1685
  string lower_name(str);
1655
1686
  transform(lower_name.begin(), lower_name.end(),
1656
1687
            lower_name.begin(), ::tolower);
1657
1688
 
1663
1694
    result= (*iter).second;
1664
1695
  } 
1665
1696
 
 
1697
  /*
 
1698
    This function is only called from the sql_plugin.cc.
 
1699
    A lock on LOCK_system_variable_hash should be held
 
1700
  */
1666
1701
  if (result == NULL)
1667
1702
  {
1668
 
    my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), name.c_str());
1669
 
    return NULL;
 
1703
    if (no_error)
 
1704
    {
 
1705
      return NULL;
 
1706
    }
 
1707
    else
 
1708
    {
 
1709
      my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
 
1710
      return NULL;
 
1711
    }
1670
1712
  }
1671
1713
 
1672
1714
  return result;
1677
1719
 Functions to handle table_type
1678
1720
****************************************************************************/
1679
1721
 
 
1722
/* Based upon sys_var::check_enum() */
 
1723
 
 
1724
bool sys_var_session_storage_engine::check(Session *session, set_var *var)
 
1725
{
 
1726
  char buff[STRING_BUFFER_USUAL_SIZE];
 
1727
  const char *value;
 
1728
  String str(buff, sizeof(buff), &my_charset_utf8_general_ci), *res;
 
1729
 
 
1730
  var->save_result.storage_engine= NULL;
 
1731
  if (var->value->result_type() == STRING_RESULT)
 
1732
  {
 
1733
    res= var->value->val_str(&str);
 
1734
    if (res == NULL || res->ptr() == NULL)
 
1735
    {
 
1736
      value= "NULL";
 
1737
      goto err;
 
1738
    }
 
1739
    else
 
1740
    {
 
1741
      const std::string engine_name(res->ptr());
 
1742
      plugin::StorageEngine *engine;
 
1743
      var->save_result.storage_engine= plugin::StorageEngine::findByName(*session, engine_name);
 
1744
      if (var->save_result.storage_engine == NULL)
 
1745
      {
 
1746
        value= res->c_ptr();
 
1747
        goto err;
 
1748
      }
 
1749
      engine= var->save_result.storage_engine;
 
1750
    }
 
1751
    return 0;
 
1752
  }
 
1753
  value= "unknown";
 
1754
 
 
1755
err:
 
1756
  my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), value);
 
1757
  return 1;
 
1758
}
 
1759
 
 
1760
 
1680
1761
unsigned char *sys_var_session_storage_engine::value_ptr(Session *session,
1681
1762
                                                         sql_var_t type,
1682
1763
                                                         const LEX_STRING *)
1714
1795
 
1715
1796
bool sys_var_session_storage_engine::update(Session *session, set_var *var)
1716
1797
{
1717
 
  char buff[STRING_BUFFER_USUAL_SIZE];
1718
 
  const char *name_value;
1719
 
  String str(buff, sizeof(buff), &my_charset_utf8_general_ci), *res;
1720
 
 
1721
 
  plugin::StorageEngine *tmp= NULL;
1722
 
  plugin::StorageEngine **value= NULL;
1723
 
    
1724
 
  if (var->value->result_type() == STRING_RESULT)
1725
 
  {
1726
 
    res= var->value->val_str(&str);
1727
 
    if (res == NULL || res->ptr() == NULL)
1728
 
    {
1729
 
      name_value= "NULL";
1730
 
      goto err;
1731
 
    }
1732
 
    else
1733
 
    {
1734
 
      const std::string engine_name(res->ptr());
1735
 
      tmp= plugin::StorageEngine::findByName(*session, engine_name);
1736
 
      if (tmp == NULL)
1737
 
      {
1738
 
        name_value= res->c_ptr();
1739
 
        goto err;
1740
 
      }
1741
 
    }
1742
 
  }
1743
 
  else
1744
 
  {
1745
 
    name_value= "unknown";
1746
 
  }
1747
 
 
1748
 
  value= &(global_system_variables.*offset);
 
1798
  plugin::StorageEngine **value= &(global_system_variables.*offset), *old_value;
1749
1799
   if (var->type != OPT_GLOBAL)
1750
1800
     value= &(session->variables.*offset);
1751
 
  if (*value != tmp)
 
1801
  old_value= *value;
 
1802
  if (old_value != var->save_result.storage_engine)
1752
1803
  {
1753
 
    *value= tmp;
 
1804
    *value= var->save_result.storage_engine;
1754
1805
  }
1755
1806
  return 0;
1756
 
err:
1757
 
  my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name_value);
1758
 
  return 1;
1759
1807
}
1760
1808
 
1761
1809
} /* namespace drizzled */