~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/set_var.cc

  • Committer: Jay Pipes
  • Date: 2009-02-04 15:44:25 UTC
  • mfrom: (829 drizzle)
  • mto: This revision was merged to the branch mainline in revision 830.
  • Revision ID: jpipes@serialcoder-20090204154425-th8xfk2ujz2y8xwg
Merge with trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
53
53
 
54
54
#include <drizzled/server_includes.h>
55
55
#include <mysys/my_getopt.h>
 
56
#include <mysys/thr_alarm.h>
56
57
#include <storage/myisam/myisam.h>
57
58
#include <drizzled/error.h>
58
59
#include <drizzled/gettext.h>
66
67
#include <drizzled/item/null.h>
67
68
#include <drizzled/item/float.h>
68
69
 
69
 
#include <map>
70
 
#include <algorithm>
71
 
 
72
 
using namespace std;
73
 
 
74
70
extern const CHARSET_INFO *character_set_filesystem;
75
71
extern I_List<NAMED_LIST> key_caches;
76
72
extern size_t my_thread_stack_size;
77
73
 
78
74
static DYNAMIC_ARRAY fixed_show_vars;
79
 
static map<const string, sys_var *> system_variable_hash;
 
75
static HASH system_variable_hash;
80
76
extern char *opt_drizzle_tmpdir;
81
77
 
82
78
const char *bool_type_names[]= { "OFF", "ON", NULL };
92
88
  delay_key_write_type_names, NULL
93
89
};
94
90
 
 
91
static bool sys_update_init_connect(Session*, set_var*);
 
92
static void sys_default_init_connect(Session*, enum_var_type type);
95
93
static bool set_option_bit(Session *session, set_var *var);
96
94
static bool set_option_autocommit(Session *session, set_var *var);
97
95
static int  check_pseudo_thread_id(Session *session, set_var *var);
103
101
static void fix_net_write_timeout(Session *session, enum_var_type type);
104
102
static void fix_net_retry_count(Session *session, enum_var_type type);
105
103
static void fix_max_join_size(Session *session, enum_var_type type);
 
104
static void fix_max_connections(Session *session, enum_var_type type);
106
105
static void fix_session_mem_root(Session *session, enum_var_type type);
107
106
static void fix_trans_mem_root(Session *session, enum_var_type type);
108
107
static void fix_server_id(Session *session, enum_var_type type);
109
108
static uint64_t fix_unsigned(Session *, uint64_t, const struct my_option *);
110
 
static bool get_unsigned32(Session *session, set_var *var);
111
 
static bool get_unsigned64(Session *session, set_var *var);
 
109
static bool get_unsigned(Session *session, set_var *var);
112
110
bool throw_bounds_warning(Session *session, bool fixed, bool unsignd,
113
111
                          const char *name, int64_t val);
114
112
static KEY_CACHE *create_key_cache(const char *name, uint32_t length);
152
150
sys_collation_server(&vars, "collation_server", &SV::collation_server,
153
151
                     &default_charset_info,
154
152
                     sys_var::SESSION_VARIABLE_IN_BINLOG);
155
 
static sys_var_uint32_t_ptr     sys_connect_timeout(&vars, "connect_timeout",
156
 
                                                &connect_timeout);
 
153
static sys_var_long_ptr sys_connect_timeout(&vars, "connect_timeout",
 
154
                                            &connect_timeout);
157
155
static sys_var_const_str       sys_datadir(&vars, "datadir", drizzle_real_data_home);
158
156
static sys_var_enum             sys_delay_key_write(&vars, "delay_key_write",
159
157
                                            &delay_key_write_options,
160
158
                                            &delay_key_write_typelib,
161
159
                                            fix_delay_key_write);
162
160
 
 
161
static sys_var_long_ptr sys_expire_logs_days(&vars, "expire_logs_days",
 
162
                                             &expire_logs_days);
163
163
static sys_var_bool_ptr sys_flush(&vars, "flush", &myisam_flush);
 
164
sys_var_str             sys_init_connect(&vars, "init_connect", 0,
 
165
                                         sys_update_init_connect,
 
166
                                         sys_default_init_connect,0);
 
167
static sys_var_session_uint32_t sys_interactive_timeout(&vars, "interactive_timeout",
 
168
                                                        &SV::net_interactive_timeout);
164
169
static sys_var_session_uint64_t sys_join_buffer_size(&vars, "join_buffer_size",
165
170
                                                     &SV::join_buff_size);
166
171
static sys_var_key_buffer_size  sys_key_buffer_size(&vars, "key_buffer_size");
167
 
static sys_var_key_cache_uint32_t  sys_key_cache_block_size(&vars, "key_cache_block_size",
 
172
static sys_var_key_cache_long  sys_key_cache_block_size(&vars, "key_cache_block_size",
168
173
                                                        offsetof(KEY_CACHE,
169
174
                                                                 param_block_size));
170
 
static sys_var_key_cache_uint32_t       sys_key_cache_division_limit(&vars, "key_cache_division_limit",
 
175
static sys_var_key_cache_long   sys_key_cache_division_limit(&vars, "key_cache_division_limit",
171
176
                                                           offsetof(KEY_CACHE,
172
177
                                                                    param_division_limit));
173
 
static sys_var_key_cache_uint32_t  sys_key_cache_age_threshold(&vars, "key_cache_age_threshold",
 
178
static sys_var_key_cache_long  sys_key_cache_age_threshold(&vars, "key_cache_age_threshold",
174
179
                                                           offsetof(KEY_CACHE,
175
180
                                                                    param_age_threshold));
 
181
static sys_var_bool_ptr sys_local_infile(&vars, "local_infile",
 
182
                                         &opt_local_infile);
176
183
static sys_var_session_uint32_t sys_max_allowed_packet(&vars, "max_allowed_packet",
177
184
                                                       &SV::max_allowed_packet);
178
 
static sys_var_uint64_t_ptr     sys_max_connect_errors(&vars, "max_connect_errors",
 
185
static sys_var_long_ptr sys_max_connections(&vars, "max_connections",
 
186
                                            &max_connections,
 
187
                                            fix_max_connections);
 
188
static sys_var_long_ptr sys_max_connect_errors(&vars, "max_connect_errors",
179
189
                                               &max_connect_errors);
180
190
static sys_var_session_uint64_t sys_max_error_count(&vars, "max_error_count",
181
191
                                                  &SV::max_error_count);
192
202
                                                      &SV::max_seeks_for_key);
193
203
static sys_var_session_uint64_t   sys_max_length_for_sort_data(&vars, "max_length_for_sort_data",
194
204
                                                               &SV::max_length_for_sort_data);
195
 
static sys_var_session_size_t   sys_max_sort_length(&vars, "max_sort_length",
 
205
static sys_var_session_uint64_t sys_max_sort_length(&vars, "max_sort_length",
196
206
                                                    &SV::max_sort_length);
197
207
static sys_var_session_uint64_t sys_max_tmp_tables(&vars, "max_tmp_tables",
198
208
                                                   &SV::max_tmp_tables);
199
 
static sys_var_uint64_t_ptr     sys_max_write_lock_count(&vars, "max_write_lock_count",
 
209
static sys_var_long_ptr sys_max_write_lock_count(&vars, "max_write_lock_count",
200
210
                                                 &max_write_lock_count);
201
211
static sys_var_session_uint64_t sys_min_examined_row_limit(&vars, "min_examined_row_limit",
202
212
                                                           &SV::min_examined_row_limit);
216
226
static sys_var_session_uint32_t sys_net_retry_count(&vars, "net_retry_count",
217
227
                                                    &SV::net_retry_count,
218
228
                                                    0, fix_net_retry_count);
 
229
static sys_var_session_bool     sys_new_mode(&vars, "new", &SV::new_mode);
 
230
static sys_var_bool_ptr_readonly sys_old_mode(&vars, "old",
 
231
                                              &global_system_variables.old_mode);
219
232
/* these two cannot be static */
220
233
sys_var_session_bool sys_old_alter_table(&vars, "old_alter_table",
221
234
                                         &SV::old_alter_table);
265
278
static sys_var_uint32_t_ptr  sys_server_id(&vars, "server_id", &server_id,
266
279
                                           fix_server_id);
267
280
 
 
281
static sys_var_long_ptr sys_slow_launch_time(&vars, "slow_launch_time",
 
282
                                             &slow_launch_time);
268
283
static sys_var_session_size_t   sys_sort_buffer(&vars, "sort_buffer_size",
269
284
                                                &SV::sortbuff_size);
270
285
/*
277
292
                                                               &SV::optimizer_switch);
278
293
 
279
294
static sys_var_session_storage_engine sys_storage_engine(&vars, "storage_engine",
280
 
                                       &SV::storage_engine);
 
295
                                       &SV::table_plugin);
281
296
static sys_var_const_str        sys_system_time_zone(&vars, "system_time_zone",
282
297
                                             system_time_zone);
283
 
static sys_var_uint64_t_ptr     sys_table_def_size(&vars, "table_definition_cache",
 
298
static sys_var_long_ptr sys_table_def_size(&vars, "table_definition_cache",
284
299
                                           &table_def_size);
285
 
static sys_var_uint64_t_ptr     sys_table_cache_size(&vars, "table_open_cache",
 
300
static sys_var_long_ptr sys_table_cache_size(&vars, "table_open_cache",
286
301
                                             &table_cache_size);
287
 
static sys_var_uint64_t_ptr     sys_table_lock_wait_timeout(&vars, "table_lock_wait_timeout",
 
302
static sys_var_long_ptr sys_table_lock_wait_timeout(&vars, "table_lock_wait_timeout",
288
303
                                                    &table_lock_wait_timeout);
289
304
static sys_var_session_enum     sys_tx_isolation(&vars, "tx_isolation",
290
305
                                             &SV::tx_isolation,
309
324
sys_engine_condition_pushdown(&vars, "engine_condition_pushdown",
310
325
                              &SV::engine_condition_pushdown);
311
326
 
 
327
/* Time/date/datetime formats */
 
328
 
 
329
static sys_var_session_date_time_format sys_time_format(&vars, "time_format",
 
330
                                             &SV::time_format,
 
331
                                             DRIZZLE_TIMESTAMP_TIME);
 
332
static sys_var_session_date_time_format sys_date_format(&vars, "date_format",
 
333
                                             &SV::date_format,
 
334
                                             DRIZZLE_TIMESTAMP_DATE);
 
335
static sys_var_session_date_time_format sys_datetime_format(&vars, "datetime_format",
 
336
                                                 &SV::datetime_format,
 
337
                                                 DRIZZLE_TIMESTAMP_DATETIME);
 
338
 
312
339
/* Variables that are bits in Session */
313
340
 
314
341
sys_var_session_bit sys_autocommit(&vars, "autocommit", 0,
379
406
*/
380
407
static sys_var_readonly sys_error_count(&vars, "error_count",
381
408
                                        OPT_SESSION,
382
 
                                        SHOW_INT,
 
409
                                        SHOW_LONG,
383
410
                                        get_error_count);
384
411
static sys_var_readonly sys_warning_count(&vars, "warning_count",
385
412
                                          OPT_SESSION,
386
 
                                          SHOW_INT,
 
413
                                          SHOW_LONG,
387
414
                                          get_warning_count);
388
415
 
389
416
sys_var_session_uint64_t sys_group_concat_max_len(&vars, "group_concat_max_len",
410
437
#define FIXED_VARS_SIZE (sizeof(fixed_vars) / sizeof(SHOW_VAR))
411
438
static SHOW_VAR fixed_vars[]= {
412
439
  {"back_log",                (char*) &back_log,                    SHOW_INT},
 
440
  {"init_file",               (char*) &opt_init_file,               SHOW_CHAR_PTR},
413
441
  {"language",                language,                             SHOW_CHAR},
414
442
#ifdef HAVE_MLOCKALL
415
443
  {"locked_in_memory",        (char*) &locked_in_memory,            SHOW_MY_BOOL},
416
444
#endif
 
445
  {"log_bin",                 (char*) &opt_bin_log,                 SHOW_BOOL},
417
446
  {"myisam_recover_options",  (char*) &myisam_recover_options_str,  SHOW_CHAR_PTR},
 
447
  {"open_files_limit",        (char*) &open_files_limit,                  SHOW_LONGLONG},
418
448
  {"pid_file",                (char*) pidfile_name,                 SHOW_CHAR},
419
449
  {"plugin_dir",              (char*) opt_plugin_dir,               SHOW_CHAR},
420
450
  {"port",                    (char*) &drizzled_port,               SHOW_INT},
422
452
  {"thread_stack",            (char*) &my_thread_stack_size,        SHOW_INT},
423
453
};
424
454
 
 
455
 
425
456
bool sys_var::check(Session *, set_var *var)
426
457
{
427
458
  var->save_result.uint64_t_value= var->value->val_int();
445
476
*/
446
477
 
447
478
 
 
479
/*
 
480
  Update variables 'init_connect, init_slave'.
 
481
 
 
482
  In case of 'DEFAULT' value
 
483
  (for example: 'set GLOBAL init_connect=DEFAULT')
 
484
  'var' parameter is NULL pointer.
 
485
*/
 
486
 
 
487
bool update_sys_var_str(sys_var_str *var_str, pthread_rwlock_t *var_mutex,
 
488
                        set_var *var)
 
489
{
 
490
  char *res= 0, *old_value=(char *)(var ? var->value->str_value.ptr() : 0);
 
491
  uint32_t new_length= (var ? var->value->str_value.length() : 0);
 
492
  if (!old_value)
 
493
    old_value= (char*) "";
 
494
  res= (char *)malloc(new_length + 1);
 
495
  if (res == NULL)
 
496
    return 1;
 
497
  memcpy(res, old_value, new_length);
 
498
  res[new_length]= 0; 
 
499
 
 
500
  /*
 
501
    Replace the old value in such a way that the any thread using
 
502
    the value will work.
 
503
  */
 
504
  pthread_rwlock_wrlock(var_mutex);
 
505
  old_value= var_str->value;
 
506
  var_str->value= res;
 
507
  var_str->value_length= new_length;
 
508
  pthread_rwlock_unlock(var_mutex);
 
509
  free(old_value);
 
510
  return 0;
 
511
}
 
512
 
 
513
 
 
514
static bool sys_update_init_connect(Session *, set_var *var)
 
515
{
 
516
  return update_sys_var_str(&sys_init_connect, &LOCK_sys_init_connect, var);
 
517
}
 
518
 
 
519
 
 
520
static void sys_default_init_connect(Session *, enum_var_type)
 
521
{
 
522
  update_sys_var_str(&sys_init_connect, &LOCK_sys_init_connect, 0);
 
523
}
 
524
 
 
525
 
448
526
/**
449
527
  Set the OPTION_BIG_SELECTS flag if max_join_size == HA_POS_ERROR.
450
528
*/
502
580
 
503
581
 
504
582
/*
505
 
  If we are changing the thread variable, we have to copy it to Protocol too
 
583
  If we are changing the thread variable, we have to copy it to NET too
506
584
*/
507
585
 
508
586
static void fix_net_read_timeout(Session *session, enum_var_type type)
509
587
{
510
588
  if (type != OPT_GLOBAL)
511
 
    session->protocol->setReadTimeout(session->variables.net_read_timeout);
 
589
    my_net_set_read_timeout(&session->net, session->variables.net_read_timeout);
512
590
}
513
591
 
514
592
 
515
593
static void fix_net_write_timeout(Session *session, enum_var_type type)
516
594
{
517
595
  if (type != OPT_GLOBAL)
518
 
    session->protocol->setWriteTimeout(session->variables.net_write_timeout);
 
596
    my_net_set_write_timeout(&session->net, session->variables.net_write_timeout);
519
597
}
520
598
 
521
599
static void fix_net_retry_count(Session *session, enum_var_type type)
522
600
{
523
601
  if (type != OPT_GLOBAL)
524
 
    session->protocol->setRetryCount(session->variables.net_retry_count);
 
602
    session->net.retry_count=session->variables.net_retry_count;
525
603
}
526
604
 
527
605
 
541
619
  }
542
620
}
543
621
 
 
622
static void fix_max_connections(Session *, enum_var_type)
 
623
{
 
624
  resize_thr_alarm(max_connections +  10);
 
625
}
 
626
 
544
627
 
545
628
static void fix_session_mem_root(Session *session, enum_var_type type)
546
629
{
560
643
}
561
644
 
562
645
 
563
 
static void fix_server_id(Session *, enum_var_type)
 
646
static void fix_server_id(Session *session, enum_var_type)
564
647
{
 
648
  server_id_supplied = 1;
 
649
  session->server_id= server_id;
565
650
}
566
651
 
567
652
 
577
662
    else
578
663
      llstr(val, buf);
579
664
 
580
 
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
665
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
581
666
                        ER_TRUNCATED_WRONG_VALUE,
582
667
                        ER(ER_TRUNCATED_WRONG_VALUE), name, buf);
583
668
  }
605
690
  return out;
606
691
}
607
692
 
608
 
static bool get_unsigned32(Session *, set_var *var)
609
 
{
610
 
  if (var->value->unsigned_flag)
611
 
    var->save_result.uint32_t_value= (uint32_t) var->value->val_int();
612
 
  else
613
 
  {
614
 
    int64_t v= var->value->val_int();
615
 
    var->save_result.uint32_t_value= (uint32_t) ((v < 0) ? 0 : v);
616
 
  }
617
 
  return 0;
618
 
}
619
 
 
620
 
static bool get_unsigned64(Session *, set_var *var)
621
 
{
622
 
  if (var->value->unsigned_flag)
623
 
      var->save_result.uint64_t_value=(uint64_t) var->value->val_int();
624
 
  else
625
 
  {
626
 
    int64_t v= var->value->val_int();
627
 
      var->save_result.uint64_t_value= (uint64_t) ((v < 0) ? 0 : v);
 
693
static bool get_unsigned(Session *, set_var *var)
 
694
{
 
695
  if (var->value->unsigned_flag)
 
696
    var->save_result.uint64_t_value= (uint64_t) var->value->val_int();
 
697
  else
 
698
  {
 
699
    int64_t v= var->value->val_int();
 
700
    var->save_result.uint64_t_value= (uint64_t) ((v < 0) ? 0 : v);
628
701
  }
629
702
  return 0;
630
703
}
632
705
static bool get_size_t(Session *, set_var *var)
633
706
{
634
707
  if (var->value->unsigned_flag)
635
 
    var->save_result.size_t_value= (size_t) var->value->val_int();
636
 
  else
637
 
  {
638
 
    ssize_t v= (ssize_t)var->value->val_int();
639
 
    var->save_result.size_t_value= (size_t) ((v < 0) ? 0 : v);
640
 
  }
641
 
  return 0;
642
 
}
643
 
 
644
 
bool sys_var_uint32_t_ptr::check(Session *, set_var *var)
645
 
{
646
 
  var->save_result.uint32_t_value= (uint32_t)var->value->val_int();
647
 
  return 0;
 
708
    var->save_result.uint64_t_value= (size_t) var->value->val_int();
 
709
  else
 
710
  {
 
711
    ssize_t v= var->value->val_int();
 
712
    var->save_result.uint64_t_value= (size_t) ((v < 0) ? 0 : v);
 
713
  }
 
714
  return 0;
 
715
}
 
716
 
 
717
 
 
718
sys_var_long_ptr::
 
719
sys_var_long_ptr(sys_var_chain *chain, const char *name_arg, uint64_t *value_ptr_arg,
 
720
                 sys_after_update_func after_update_arg)
 
721
  :sys_var_long_ptr_global(chain, name_arg, value_ptr_arg,
 
722
                           &LOCK_global_system_variables, after_update_arg)
 
723
{}
 
724
 
 
725
 
 
726
bool sys_var_long_ptr_global::check(Session *session, set_var *var)
 
727
{
 
728
  return get_unsigned(session, var);
 
729
}
 
730
 
 
731
bool sys_var_long_ptr_global::update(Session *session, set_var *var)
 
732
{
 
733
  uint64_t tmp= var->save_result.uint64_t_value;
 
734
  pthread_mutex_lock(guard);
 
735
  if (option_limits)
 
736
    *value= (uint64_t) fix_unsigned(session, tmp, option_limits);
 
737
  else
 
738
  {
 
739
    if (tmp > UINT32_MAX)
 
740
    {
 
741
      tmp= UINT32_MAX;
 
742
      throw_bounds_warning(session, true, true, name,
 
743
                           (int64_t) var->save_result.uint64_t_value);
 
744
    }
 
745
    *value= (uint64_t) tmp;
 
746
  }
 
747
 
 
748
  pthread_mutex_unlock(guard);
 
749
  return 0;
 
750
}
 
751
 
 
752
 
 
753
void sys_var_long_ptr_global::set_default(Session *, enum_var_type)
 
754
{
 
755
  bool not_used;
 
756
  pthread_mutex_lock(guard);
 
757
  *value= (uint64_t) getopt_ull_limit_value((uint64_t) option_limits->def_value,
 
758
                                         option_limits, &not_used);
 
759
  pthread_mutex_unlock(guard);
648
760
}
649
761
 
650
762
bool sys_var_uint32_t_ptr::update(Session *session, set_var *var)
652
764
  uint32_t tmp= var->save_result.uint32_t_value;
653
765
  pthread_mutex_lock(&LOCK_global_system_variables);
654
766
  if (option_limits)
655
 
  {
656
 
    uint32_t newvalue= (uint32_t) fix_unsigned(session, tmp, option_limits);
657
 
    if(newvalue==tmp)
658
 
      *value= newvalue;
659
 
  }
 
767
    *value= (uint32_t) fix_unsigned(session, tmp, option_limits);
660
768
  else
661
769
    *value= (uint32_t) tmp;
662
770
  pthread_mutex_unlock(&LOCK_global_system_variables);
668
776
{
669
777
  bool not_used;
670
778
  pthread_mutex_lock(&LOCK_global_system_variables);
671
 
  *value= (uint32_t)getopt_ull_limit_value((uint32_t) option_limits->def_value,
672
 
                                           option_limits, &not_used);
 
779
  *value= getopt_ull_limit_value((uint32_t) option_limits->def_value,
 
780
                                 option_limits, &not_used);
673
781
  pthread_mutex_unlock(&LOCK_global_system_variables);
674
782
}
675
783
 
679
787
  uint64_t tmp= var->save_result.uint64_t_value;
680
788
  pthread_mutex_lock(&LOCK_global_system_variables);
681
789
  if (option_limits)
682
 
  {
683
 
    uint64_t newvalue= (uint64_t) fix_unsigned(session, tmp, option_limits);
684
 
    if(newvalue==tmp)
685
 
      *value= newvalue;
686
 
  }
 
790
    *value= (uint64_t) fix_unsigned(session, tmp, option_limits);
687
791
  else
688
792
    *value= (uint64_t) tmp;
689
793
  pthread_mutex_unlock(&LOCK_global_system_variables);
738
842
 
739
843
bool sys_var_enum::update(Session *, set_var *var)
740
844
{
741
 
  *value= (uint32_t) var->save_result.uint32_t_value;
 
845
  *value= (uint) var->save_result.uint32_t_value;
742
846
  return 0;
743
847
}
744
848
 
760
864
*/
761
865
bool sys_var_session_uint32_t::check(Session *session, set_var *var)
762
866
{
763
 
  return (get_unsigned32(session, var) ||
 
867
  return (get_unsigned(session, var) ||
764
868
          (check_func && (*check_func)(session, var)));
765
869
}
766
870
 
767
871
bool sys_var_session_uint32_t::update(Session *session, set_var *var)
768
872
{
769
 
  uint64_t tmp= (uint64_t) var->save_result.uint32_t_value;
 
873
  uint64_t tmp= var->save_result.uint64_t_value;
770
874
 
771
875
  /* Don't use bigger value than given with --maximum-variable-name=.. */
772
876
  if ((uint32_t) tmp > max_system_variables.*offset)
868
972
 
869
973
bool sys_var_session_uint64_t::check(Session *session, set_var *var)
870
974
{
871
 
  return (get_unsigned64(session, var) ||
 
975
  return (get_unsigned(session, var) ||
872
976
          (check_func && (*check_func)(session, var)));
873
977
}
874
978
 
954
1058
    bool not_used;
955
1059
    pthread_mutex_lock(&LOCK_global_system_variables);
956
1060
    global_system_variables.*offset=
957
 
      (size_t)getopt_ull_limit_value((size_t) option_limits->def_value,
958
 
                                     option_limits, &not_used);
 
1061
      getopt_ull_limit_value((size_t) option_limits->def_value,
 
1062
                             option_limits, &not_used);
959
1063
    pthread_mutex_unlock(&LOCK_global_system_variables);
960
1064
  }
961
1065
  else
1011
1115
 
1012
1116
  if (var->value->result_type() == STRING_RESULT)
1013
1117
  {
1014
 
    if (!(res=var->value->val_str(&str)) ||
1015
 
        (var->save_result.uint32_t_value= find_type(enum_names, res->ptr(),
1016
 
                                                    res->length(),1)) == 0)
 
1118
    if (!(res=var->value->val_str(&str)))
1017
1119
    {
1018
1120
      value= res ? res->c_ptr() : "NULL";
1019
1121
      goto err;
1020
1122
    }
1021
 
 
1022
 
    var->save_result.uint32_t_value--;
1023
1123
  }
1024
1124
  else
1025
1125
  {
1277
1377
}
1278
1378
 
1279
1379
 
 
1380
/** Update a date_time format variable based on given value. */
 
1381
 
 
1382
void sys_var_session_date_time_format::update2(Session *session, enum_var_type type,
 
1383
                                           DATE_TIME_FORMAT *new_value)
 
1384
{
 
1385
  DATE_TIME_FORMAT *old;
 
1386
 
 
1387
  if (type == OPT_GLOBAL)
 
1388
  {
 
1389
    pthread_mutex_lock(&LOCK_global_system_variables);
 
1390
    old= (global_system_variables.*offset);
 
1391
    (global_system_variables.*offset)= new_value;
 
1392
    pthread_mutex_unlock(&LOCK_global_system_variables);
 
1393
  }
 
1394
  else
 
1395
  {
 
1396
    old= (session->variables.*offset);
 
1397
    (session->variables.*offset)= new_value;
 
1398
  }
 
1399
  free((char*) old);
 
1400
  return;
 
1401
}
 
1402
 
 
1403
 
 
1404
bool sys_var_session_date_time_format::update(Session *session, set_var *var)
 
1405
{
 
1406
  DATE_TIME_FORMAT *new_value;
 
1407
  /* We must make a copy of the last value to get it into normal memory */
 
1408
  new_value= date_time_format_copy((Session*) 0,
 
1409
                                   var->save_result.date_time_format);
 
1410
  if (!new_value)
 
1411
    return 1;                                   // Out of memory
 
1412
  update2(session, var->type, new_value);               // Can't fail
 
1413
  return 0;
 
1414
}
 
1415
 
 
1416
 
 
1417
bool sys_var_session_date_time_format::check(Session *session, set_var *var)
 
1418
{
 
1419
  char buff[STRING_BUFFER_USUAL_SIZE];
 
1420
  String str(buff,sizeof(buff), system_charset_info), *res;
 
1421
  DATE_TIME_FORMAT *format;
 
1422
 
 
1423
  if (!(res=var->value->val_str(&str)))
 
1424
    res= &my_empty_string;
 
1425
 
 
1426
  if (!(format= date_time_format_make(date_time_type,
 
1427
                                      res->ptr(), res->length())))
 
1428
  {
 
1429
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, res->c_ptr());
 
1430
    return 1;
 
1431
  }
 
1432
 
 
1433
  /*
 
1434
    We must copy result to thread space to not get a memory leak if
 
1435
    update is aborted
 
1436
  */
 
1437
  var->save_result.date_time_format= date_time_format_copy(session, format);
 
1438
  free((char*) format);
 
1439
  return var->save_result.date_time_format == 0;
 
1440
}
 
1441
 
 
1442
 
 
1443
void sys_var_session_date_time_format::set_default(Session *session, enum_var_type type)
 
1444
{
 
1445
  DATE_TIME_FORMAT *res= 0;
 
1446
 
 
1447
  if (type == OPT_GLOBAL)
 
1448
  {
 
1449
    const char *format;
 
1450
    if ((format= opt_date_time_formats[date_time_type]))
 
1451
      res= date_time_format_make(date_time_type, format, strlen(format));
 
1452
  }
 
1453
  else
 
1454
  {
 
1455
    /* Make copy with malloc */
 
1456
    res= date_time_format_copy((Session *) 0, global_system_variables.*offset);
 
1457
  }
 
1458
 
 
1459
  if (res)                                      // Should always be true
 
1460
    update2(session, type, res);
 
1461
}
 
1462
 
 
1463
 
 
1464
unsigned char *sys_var_session_date_time_format::value_ptr(Session *session,
 
1465
                                                           enum_var_type type,
 
1466
                                                           const LEX_STRING *)
 
1467
{
 
1468
  if (type == OPT_GLOBAL)
 
1469
  {
 
1470
    char *res;
 
1471
    /*
 
1472
      We do a copy here just to be sure things will work even if someone
 
1473
      is modifying the original string while the copy is accessed
 
1474
      (Can't happen now in SQL SHOW, but this is a good safety for the future)
 
1475
    */
 
1476
    res= session->strmake((global_system_variables.*offset)->format.str,
 
1477
                      (global_system_variables.*offset)->format.length);
 
1478
    return (unsigned char*) res;
 
1479
  }
 
1480
  return (unsigned char*) (session->variables.*offset)->format.str;
 
1481
}
 
1482
 
 
1483
 
1280
1484
typedef struct old_names_map_st
1281
1485
{
1282
1486
  const char *old_name;
1296
1500
      my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
1297
1501
      return 1;
1298
1502
    }
1299
 
    if (!(tmp=get_charset_by_name(res->c_ptr())))
 
1503
    if (!(tmp=get_charset_by_name(res->c_ptr(),MYF(0))))
1300
1504
    {
1301
1505
      my_error(ER_UNKNOWN_COLLATION, MYF(0), res->c_ptr());
1302
1506
      return 1;
1304
1508
  }
1305
1509
  else // INT_RESULT
1306
1510
  {
1307
 
    if (!(tmp=get_charset((int) var->value->val_int())))
 
1511
    if (!(tmp=get_charset((int) var->value->val_int(),MYF(0))))
1308
1512
    {
1309
1513
      char buf[20];
1310
1514
      int10_to_str((int) var->value->val_int(), buf, -10);
1470
1674
  This should be changed so that we wait until the previous
1471
1675
  assignment is done and then do the new assign
1472
1676
*/
1473
 
bool sys_var_key_cache_uint32_t::update(Session *session, set_var *var)
 
1677
bool sys_var_key_cache_long::update(Session *session, set_var *var)
1474
1678
{
1475
1679
  uint64_t tmp= (uint64_t) var->value->val_int();
1476
1680
  LEX_STRING *base_name= &var->base;
1497
1701
  if (key_cache->in_init)
1498
1702
    goto end;
1499
1703
 
1500
 
  *((uint32_t*) (((char*) key_cache) + offset))=
1501
 
    (uint32_t) fix_unsigned(session, tmp, option_limits);
 
1704
  *((uint64_t*) (((char*) key_cache) + offset))=
 
1705
    (uint64_t) fix_unsigned(session, tmp, option_limits);
1502
1706
 
1503
1707
  /*
1504
1708
    Don't create a new key cache if it didn't exist
1648
1852
 
1649
1853
  if (var->value->result_type() == INT_RESULT)
1650
1854
  {
1651
 
    if (!(locale_match= my_locale_by_number((uint32_t) var->value->val_int())))
 
1855
    if (!(locale_match= my_locale_by_number((uint) var->value->val_int())))
1652
1856
    {
1653
1857
      char buf[20];
1654
1858
      int10_to_str((int) var->value->val_int(), buf, -10);
1816
2020
 
1817
2021
static unsigned char *get_warning_count(Session *session)
1818
2022
{
1819
 
  session->sys_var_tmp.uint32_t_value=
 
2023
  session->sys_var_tmp.long_value=
1820
2024
    (session->warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_NOTE] +
1821
2025
     session->warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR] +
1822
2026
     session->warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_WARN]);
1823
 
  return (unsigned char*) &session->sys_var_tmp.uint32_t_value;
 
2027
  return (unsigned char*) &session->sys_var_tmp.long_value;
1824
2028
}
1825
2029
 
1826
2030
static unsigned char *get_error_count(Session *session)
1827
2031
{
1828
 
  session->sys_var_tmp.uint32_t_value=
 
2032
  session->sys_var_tmp.long_value=
1829
2033
    session->warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR];
1830
 
  return (unsigned char*) &session->sys_var_tmp.uint32_t_value;
 
2034
  return (unsigned char*) &session->sys_var_tmp.long_value;
1831
2035
}
1832
2036
 
1833
2037
 
1890
2094
}
1891
2095
 
1892
2096
 
 
2097
/**
 
2098
  Return variable name and length for hashing of variables.
 
2099
*/
 
2100
 
 
2101
static unsigned char *get_sys_var_length(const sys_var *var, size_t *length,
 
2102
                                         bool)
 
2103
{
 
2104
  *length= var->name_length;
 
2105
  return (unsigned char*) var->name;
 
2106
}
 
2107
 
 
2108
 
1893
2109
/*
1894
2110
  Add variables to the dynamic hash of system variables
1895
2111
 
1907
2123
int mysql_add_sys_var_chain(sys_var *first, struct my_option *long_options)
1908
2124
{
1909
2125
  sys_var *var;
 
2126
 
1910
2127
  /* A write lock should be held on LOCK_system_variables_hash */
1911
2128
 
1912
2129
  for (var= first; var; var= var->next)
1913
2130
  {
1914
 
    /* Make a temp string to hold this and then make it lower so that matching
1915
 
     * happens case-insensitive.
1916
 
     */
1917
 
    string var_name(var->name);
1918
 
    transform(var_name.begin(), var_name.end(), var_name.begin(), ::tolower);
1919
 
    var->name_length= var_name.length();
1920
 
 
1921
 
    /* this fails if there is a conflicting variable name. */
1922
 
    if (system_variable_hash.count(var_name) == 0)
1923
 
    {
1924
 
      system_variable_hash[var_name]= var;
1925
 
    } 
1926
 
    else
1927
 
    {
1928
 
      for (; first != var; first= first->next)
1929
 
      {
1930
 
        /*
1931
 
         * This is slightly expensive, since we have to do the transform 
1932
 
         * _again_ but should rarely happen unless there is a pretty
1933
 
         * major problem in the code
1934
 
         */
1935
 
        var_name= first->name;
1936
 
        transform(var_name.begin(), var_name.end(),
1937
 
                  var_name.begin(), ::tolower);
1938
 
        system_variable_hash.erase(var_name);
1939
 
      }
1940
 
      return 1;
1941
 
    }
 
2131
    var->name_length= strlen(var->name);
 
2132
    /* this fails if there is a conflicting variable name. see HASH_UNIQUE */
 
2133
    if (my_hash_insert(&system_variable_hash, (unsigned char*) var))
 
2134
      goto error;
1942
2135
    if (long_options)
1943
2136
      var->option_limits= find_option(long_options, var->name);
1944
2137
  }
1945
2138
  return 0;
1946
2139
 
 
2140
error:
 
2141
  for (; first != var; first= first->next)
 
2142
    hash_delete(&system_variable_hash, (unsigned char*) first);
 
2143
  return 1;
1947
2144
}
1948
2145
 
1949
2146
 
1962
2159
int mysql_del_sys_var_chain(sys_var *first)
1963
2160
{
1964
2161
  int result= 0;
1965
 
  string var_name;
1966
2162
 
1967
2163
  /* A write lock should be held on LOCK_system_variables_hash */
 
2164
 
1968
2165
  for (sys_var *var= first; var; var= var->next)
1969
 
  {
1970
 
    var_name= var->name;
1971
 
    transform(var_name.begin(), var_name.end(),
1972
 
              var_name.begin(), ::tolower);
1973
 
    result|= system_variable_hash.erase(var_name);
1974
 
  }
 
2166
    result|= hash_delete(&system_variable_hash, (unsigned char*) var);
1975
2167
 
1976
2168
  return result;
1977
2169
}
1978
2170
 
1979
2171
 
 
2172
static int show_cmp(SHOW_VAR *a, SHOW_VAR *b)
 
2173
{
 
2174
  return strcmp(a->name, b->name);
 
2175
}
 
2176
 
1980
2177
 
1981
2178
/*
1982
2179
  Constructs an array of system variables for display to the user.
1991
2188
    NULL        FAILURE
1992
2189
*/
1993
2190
 
1994
 
SHOW_VAR* enumerate_sys_vars(Session *session, bool)
 
2191
SHOW_VAR* enumerate_sys_vars(Session *session, bool sorted)
1995
2192
{
 
2193
  int count= system_variable_hash.records, i;
1996
2194
  int fixed_count= fixed_show_vars.elements;
1997
 
  int size= sizeof(SHOW_VAR) * (system_variable_hash.size() + fixed_count + 1);
 
2195
  int size= sizeof(SHOW_VAR) * (count + fixed_count + 1);
1998
2196
  SHOW_VAR *result= (SHOW_VAR*) session->alloc(size);
1999
2197
 
2000
2198
  if (result)
2002
2200
    SHOW_VAR *show= result + fixed_count;
2003
2201
    memcpy(result, fixed_show_vars.buffer, fixed_count * sizeof(SHOW_VAR));
2004
2202
 
2005
 
    map<string, sys_var *>::iterator iter;
2006
 
    for(iter= system_variable_hash.begin();
2007
 
        iter != system_variable_hash.end();
2008
 
        iter++)
 
2203
    for (i= 0; i < count; i++)
2009
2204
    {
2010
 
      sys_var *var= (*iter).second;
 
2205
      sys_var *var= (sys_var*) hash_element(&system_variable_hash, i);
2011
2206
      show->name= var->name;
2012
2207
      show->value= (char*) var;
2013
2208
      show->type= SHOW_SYS;
2014
2209
      show++;
2015
2210
    }
2016
2211
 
 
2212
    /* sort into order */
 
2213
    if (sorted)
 
2214
      my_qsort(result, count + fixed_count, sizeof(SHOW_VAR),
 
2215
               (qsort_cmp) show_cmp);
 
2216
 
2017
2217
    /* make last element empty */
2018
2218
    memset(show, 0, sizeof(SHOW_VAR));
2019
2219
  }
2060
2260
  fixed_show_vars.elements= FIXED_VARS_SIZE;
2061
2261
  memcpy(fixed_show_vars.buffer, fixed_vars, sizeof(fixed_vars));
2062
2262
 
 
2263
  if (hash_init(&system_variable_hash, system_charset_info, count, 0,
 
2264
                0, (hash_get_key) get_sys_var_length, 0, HASH_UNIQUE))
 
2265
    goto error;
 
2266
 
2063
2267
  vars.last->next= NULL;
2064
2268
  if (mysql_add_sys_var_chain(vars.first, my_long_options))
2065
2269
    goto error;
2074
2278
 
2075
2279
void set_var_free()
2076
2280
{
 
2281
  hash_free(&system_variable_hash);
2077
2282
  delete_dynamic(&fixed_show_vars);
2078
2283
}
2079
2284
 
2113
2318
    0           Unknown variable (error message is given)
2114
2319
*/
2115
2320
 
2116
 
sys_var *intern_find_sys_var(const char *str, uint32_t, bool no_error)
 
2321
sys_var *intern_find_sys_var(const char *str, uint32_t length, bool no_error)
2117
2322
{
 
2323
  sys_var *var;
 
2324
 
2118
2325
  /*
2119
2326
    This function is only called from the sql_plugin.cc.
2120
2327
    A lock on LOCK_system_variable_hash should be held
2121
2328
  */
2122
 
  string lower_var(str);
2123
 
  transform(lower_var.begin(), lower_var.end(), lower_var.begin(), ::tolower);
2124
 
  map<string, sys_var *>::iterator result_iter=
2125
 
    system_variable_hash.find(lower_var);
2126
 
  if (result_iter == system_variable_hash.end())
2127
 
  {
2128
 
    if (no_error)
2129
 
    {
2130
 
      return NULL;
2131
 
    }
2132
 
    else
2133
 
    {
2134
 
      my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
2135
 
      return NULL;
2136
 
    }
2137
 
  }
 
2329
  var= (sys_var*) hash_search(&system_variable_hash,
 
2330
                              (unsigned char*) str, length ? length : strlen(str));
 
2331
  if (!(var || no_error))
 
2332
    my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
2138
2333
 
2139
 
  return (*result_iter).second;
 
2334
  return var;
2140
2335
}
2141
2336
 
2142
2337
 
2285
2480
  const char *value;
2286
2481
  String str(buff, sizeof(buff), &my_charset_utf8_general_ci), *res;
2287
2482
 
2288
 
  var->save_result.storage_engine= NULL;
 
2483
  var->save_result.plugin= NULL;
2289
2484
  if (var->value->result_type() == STRING_RESULT)
2290
2485
  {
2291
2486
    LEX_STRING engine_name;
2292
 
    StorageEngine *engine;
 
2487
    handlerton *hton;
2293
2488
    if (!(res=var->value->val_str(&str)) ||
2294
2489
        !(engine_name.str= (char *)res->ptr()) ||
2295
2490
        !(engine_name.length= res->length()) ||
2296
 
              !(var->save_result.storage_engine=
2297
 
            ha_resolve_by_name(session, &engine_name)) ||
2298
 
        !(engine= var->save_result.storage_engine))
 
2491
        !(var->save_result.plugin= ha_resolve_by_name(session, &engine_name)) ||
 
2492
        !(hton= plugin_data(var->save_result.plugin, handlerton *)))
2299
2493
    {
2300
2494
      value= res ? res->c_ptr() : "NULL";
2301
2495
      goto err;
2315
2509
                                                         const LEX_STRING *)
2316
2510
{
2317
2511
  unsigned char* result;
2318
 
  string engine_name;
2319
 
  StorageEngine *engine= session->variables.*offset;
2320
 
  if (type == OPT_GLOBAL)
2321
 
    engine= global_system_variables.*offset;
2322
 
  engine_name= engine->getName();
2323
 
  result= (unsigned char *) session->strmake(engine_name.c_str(),
2324
 
                                             engine_name.size());
 
2512
  handlerton *hton;
 
2513
  LEX_STRING *engine_name;
 
2514
  plugin_ref plugin= session->variables.*offset;
 
2515
  if (type == OPT_GLOBAL)
 
2516
    plugin= my_plugin_lock(session, &(global_system_variables.*offset));
 
2517
  hton= plugin_data(plugin, handlerton*);
 
2518
  engine_name= ha_storage_engine_name(hton);
 
2519
  result= (unsigned char *) session->strmake(engine_name->str, engine_name->length);
 
2520
  if (type == OPT_GLOBAL)
 
2521
    plugin_unlock(session, plugin);
2325
2522
  return result;
2326
2523
}
2327
2524
 
2328
2525
 
2329
2526
void sys_var_session_storage_engine::set_default(Session *session, enum_var_type type)
2330
2527
{
2331
 
  StorageEngine *old_value, *new_value, **value;
 
2528
  plugin_ref old_value, new_value, *value;
2332
2529
  if (type == OPT_GLOBAL)
2333
2530
  {
2334
2531
    value= &(global_system_variables.*offset);
2335
 
    new_value= myisam_engine;
 
2532
    new_value= ha_lock_engine(NULL, myisam_hton);
2336
2533
  }
2337
2534
  else
2338
2535
  {
2339
2536
    value= &(session->variables.*offset);
2340
 
    new_value= global_system_variables.*offset;
 
2537
    new_value= my_plugin_lock(NULL, &(global_system_variables.*offset));
2341
2538
  }
2342
2539
  assert(new_value);
2343
2540
  old_value= *value;
2344
2541
  *value= new_value;
 
2542
  plugin_unlock(NULL, old_value);
2345
2543
}
2346
2544
 
2347
2545
 
2348
2546
bool sys_var_session_storage_engine::update(Session *session, set_var *var)
2349
2547
{
2350
 
  StorageEngine **value= &(global_system_variables.*offset), *old_value;
 
2548
  plugin_ref *value= &(global_system_variables.*offset), old_value;
2351
2549
   if (var->type != OPT_GLOBAL)
2352
2550
     value= &(session->variables.*offset);
2353
2551
  old_value= *value;
2354
 
  if (old_value != var->save_result.storage_engine)
 
2552
  if (old_value != var->save_result.plugin)
2355
2553
  {
2356
 
    *value= var->save_result.storage_engine;
 
2554
    *value= my_plugin_lock(NULL, &var->save_result.plugin);
 
2555
    plugin_unlock(NULL, old_value);
2357
2556
  }
2358
2557
  return 0;
2359
2558
}
2393
2592
                                                           const LEX_STRING *)
2394
2593
{
2395
2594
  LEX_STRING opts;
2396
 
  uint32_t val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
 
2595
  uint64_t val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
2397
2596
                  session->variables.*offset);
2398
2597
  (void) symbolic_mode_representation(session, val, &opts);
2399
2598
  return (unsigned char *) opts.str;