~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sys_var.cc

  • Committer: Monty Taylor
  • Date: 2011-02-13 17:26:39 UTC
  • mfrom: (2157.2.2 give-in-to-pkg-config)
  • mto: This revision was merged to the branch mainline in revision 2166.
  • Revision ID: mordred@inaugust.com-20110213172639-nhy7i72sfhoq13ms
Merged in pkg-config fixes.

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