~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sys_var.cc

  • Committer: Stewart Smith
  • Author(s): Marko Mäkelä, Stewart Smith
  • Date: 2010-11-17 05:52:09 UTC
  • mto: (2021.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 1971.
  • Revision ID: stewart@flamingspork.com-20101117055209-69m035q6h7e1txrc
Merge Revision revid:marko.makela@oracle.com-20100629113248-fvl48lnzr44z94gg from MySQL InnoDB

Original revid:marko.makela@oracle.com-20100629113248-fvl48lnzr44z94gg

Original Authors: Marko Mkel <marko.makela@oracle.com>
Original commit message:
Bug#52199 utf32: mbminlen=4, mbmaxlen=4, type->mbminlen=0, type->mbmaxlen=4

Merge and adjust a forgotten change to fix this bug.
rb://393 approved by Jimmy Yang
  ------------------------------------------------------------------------
  r3794 | marko | 2009-01-07 14:14:53 +0000 (Wed, 07 Jan 2009) | 18 lines

  branches/6.0: Allow the minimum length of a multi-byte character to be
  up to 4 bytes. (Bug #35391)

  dtype_t, dict_col_t: Replace mbminlen:2, mbmaxlen:3 with mbminmaxlen:5.
  In this way, the 5 bits can hold two values of 0..4, and the storage size
  of the fields will not cross the 64-bit boundary.  Encode the values as
  DATA_MBMAX * mbmaxlen + mbminlen.  Define the auxiliary macros
  DB_MBMINLEN(mbminmaxlen), DB_MBMAXLEN(mbminmaxlen), and
  DB_MINMAXLEN(mbminlen, mbmaxlen).

  Try to trim and pad UTF-16 and UTF-32 with spaces as appropriate.

  Alexander Barkov suggested the use of cs->cset->fill(cs, buff, len, 0x20).
  ha_innobase::store_key_val_for_row() now does that, but the added function
  row_mysql_pad_col() does not, because it doesn't have the MySQL TABLE object.

  rb://49 approved by Heikki Tuuri
  ------------------------------------------------------------------------

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