~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/drizzled.cc

  • Committer: Brian Aker
  • Date: 2009-02-27 21:38:40 UTC
  • Revision ID: brian@tangent.org-20090227213840-r9hq3sfk8d8qrg72
Code cleanup in signal_handler.cc

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
 
20
 
 
21
#include <drizzled/configmake.h>
20
22
#include <drizzled/server_includes.h>
21
 
#include <drizzled/configmake.h>
22
 
#include <drizzled/atomics.h>
23
23
 
24
24
#include <netdb.h>
 
25
#include <sys/poll.h>
25
26
#include <netinet/tcp.h>
26
 
#include <netinet/in.h>
27
27
#include <signal.h>
28
28
 
29
29
#include <mysys/my_bit.h>
 
30
#include <libdrizzleclient/libdrizzle.h>
30
31
#include <mysys/hash.h>
31
32
#include <drizzled/stacktrace.h>
32
33
#include <mysys/mysys_err.h>
40
41
#include <drizzled/session.h>
41
42
#include <drizzled/db.h>
42
43
#include <drizzled/item/create.h>
 
44
#include <drizzled/function/time/get_format.h>
 
45
#include <drizzled/errmsg.h>
43
46
#include <drizzled/unireg.h>
 
47
#include <drizzled/plugin_scheduling.h>
44
48
#include "drizzled/temporal_format.h" /* For init_temporal_formats() */
45
 
#include "drizzled/plugin/listen.h"
46
 
#include "drizzled/plugin/error_message.h"
47
 
#include "drizzled/plugin/client.h"
48
 
#include "drizzled/plugin/scheduler.h"
49
 
#include "drizzled/probes.h"
50
 
 
51
 
#include <google/protobuf/stubs/common.h>
52
49
 
53
50
#if TIME_WITH_SYS_TIME
54
51
# include <sys/time.h>
61
58
# endif
62
59
#endif
63
60
 
 
61
#include <storage/myisam/ha_myisam.h>
 
62
 
64
63
#ifdef HAVE_SYS_PRCTL_H
65
64
#include <sys/prctl.h>
66
65
#endif
67
66
 
 
67
#ifndef DEFAULT_SKIP_THREAD_PRIORITY
 
68
#define DEFAULT_SKIP_THREAD_PRIORITY 0
 
69
#endif
 
70
 
 
71
#include <libdrizzleclient/errmsg.h>
68
72
#include <locale.h>
69
73
 
70
74
#define mysqld_charset &my_charset_utf8_general_ci
77
81
 
78
82
#define MAX_MEM_TABLE_SIZE SIZE_MAX
79
83
 
 
84
/* We have HAVE_purify below as this speeds up the shutdown of MySQL */
 
85
 
 
86
#if defined(HAVE_DEC_3_2_THREADS) || defined(SIGNALS_DONT_BREAK_READ) || defined(HAVE_purify) && defined(__linux__)
 
87
#define HAVE_CLOSE_SERVER_SOCK 1
 
88
#endif
 
89
 
80
90
extern "C" {                                    // Because of SCO 3.2V4.2
81
91
#include <errno.h>
82
92
#include <sys/stat.h>
107
117
#include <sys/mman.h>
108
118
#endif
109
119
 
 
120
#define SIGNAL_FMT "signal %d"
 
121
 
 
122
 
110
123
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
111
124
#include <ieeefp.h>
112
125
#ifdef HAVE_FP_EXCEPT                           // Fix type conflict
123
136
#include <sys/fpu.h>
124
137
#endif
125
138
 
 
139
 
126
140
inline void setup_fpu()
127
141
{
128
142
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
162
176
extern "C" int gethostname(char *name, int namelen);
163
177
#endif
164
178
 
 
179
extern "C" void handle_segfault(int sig);
 
180
 
165
181
using namespace std;
166
 
using namespace drizzled;
167
182
 
168
183
/* Constants */
169
184
 
170
185
const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"};
 
186
/*
 
187
  WARNING: When adding new SQL modes don't forget to update the
 
188
           tables definitions that stores it's value.
 
189
           (ie: mysql.event, mysql.proc)
 
190
*/
171
191
static const char *optimizer_switch_names[]=
172
192
{
173
193
  "no_materialization", "no_semijoin",
195
215
  tc_heuristic_recover_names, NULL
196
216
};
197
217
 
198
 
const char *first_keyword= "first";
199
 
const char *binary_keyword= "BINARY";
 
218
const char *first_keyword= "first", *binary_keyword= "BINARY";
 
219
const char *my_localhost= "localhost";
200
220
const char * const DRIZZLE_CONFIG_NAME= "drizzled";
201
221
#define GET_HA_ROWS GET_ULL
202
222
 
204
224
  Used with --help for detailed option
205
225
*/
206
226
static bool opt_help= false;
207
 
static bool opt_help_extended= false;
208
227
 
209
228
arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
210
229
{{&Arg_comparator::compare_string,     &Arg_comparator::compare_e_string},
215
234
 
216
235
/* static variables */
217
236
 
 
237
/* the default log output is log tables */
218
238
static bool volatile select_thread_in_use;
219
239
static bool volatile ready_to_exit;
220
240
static bool opt_debugging= 0;
221
241
static uint32_t wake_thread;
222
 
static uint32_t killed_threads;
 
242
static uint32_t killed_threads, thread_created;
223
243
static char *drizzled_user, *drizzled_chroot;
224
 
static char *language_ptr;
225
 
static const char *default_character_set_name;
226
 
static const char *character_set_filesystem_name;
 
244
static char *language_ptr, *opt_init_connect;
 
245
static char *default_character_set_name;
 
246
static char *character_set_filesystem_name;
227
247
static char *lc_time_names_name;
 
248
static char *my_bind_addr_str;
228
249
static char *default_collation_name;
229
250
static char *default_storage_engine_str;
230
 
static const char *compiled_default_collation_name= "utf8_general_ci";
 
251
static char compiled_default_collation_name[]= DRIZZLE_DEFAULT_COLLATION_NAME;
 
252
static struct pollfd fds[UINT8_MAX];
 
253
static uint8_t pollfd_count= 0;
231
254
 
232
255
/* Global variables */
233
256
 
 
257
bool opt_bin_log;
 
258
bool opt_log_queries_not_using_indexes= false;
 
259
bool opt_skip_show_db= false;
 
260
bool server_id_supplied = 0;
 
261
bool opt_endinfo, using_udf_functions;
234
262
bool locked_in_memory;
 
263
bool opt_using_transactions;
235
264
bool volatile abort_loop;
236
265
bool volatile shutdown_in_progress;
 
266
bool opt_skip_slave_start = 0; ///< If set, slave is not autostarted
 
267
bool opt_reckless_slave = 0;
 
268
bool opt_enable_named_pipe= 0;
 
269
bool opt_local_infile;
 
270
bool opt_safe_user_create = 0;
 
271
bool opt_show_slave_auth_info, opt_sql_bin_update = 0;
 
272
bool opt_log_slave_updates= 0;
237
273
uint32_t max_used_connections;
238
 
const string opt_scheduler_default("multi_thread");
239
 
char *opt_scheduler= NULL;
 
274
const char *opt_scheduler= "pool_of_threads";
240
275
 
241
276
size_t my_thread_stack_size= 65536;
242
277
 
243
278
/*
244
 
  Legacy global plugin::StorageEngine. These will be removed (please do not add more).
 
279
  Legacy global handlerton. These will be removed (please do not add more).
245
280
*/
246
 
plugin::StorageEngine *heap_engine;
247
 
plugin::StorageEngine *myisam_engine;
 
281
handlerton *heap_hton;
 
282
handlerton *myisam_hton;
248
283
 
 
284
bool use_temp_pool;
249
285
char* opt_secure_file_priv= 0;
 
286
/*
 
287
  True if there is at least one per-hour limit for some user, so we should
 
288
  check them before each query (and possibly reset counters when hour is
 
289
  changed). False otherwise.
 
290
*/
 
291
bool opt_noacl;
250
292
 
251
293
#ifdef HAVE_INITGROUPS
252
294
static bool calling_initgroups= false; /**< Used in SIGSEGV handler. */
253
295
#endif
254
 
 
255
 
uint32_t drizzled_bind_timeout;
256
 
std::bitset<12> test_flags;
257
 
uint32_t dropping_tables, ha_open_options;
 
296
uint32_t drizzled_port, test_flags, select_errors, dropping_tables, ha_open_options;
 
297
uint32_t drizzled_port_timeout;
 
298
uint32_t delay_key_write_options, protocol_version= PROTOCOL_VERSION;
 
299
uint32_t lower_case_table_names= 1;
258
300
uint32_t tc_heuristic_recover= 0;
 
301
uint32_t volatile thread_count, thread_running;
259
302
uint64_t session_startup_options;
260
303
uint32_t back_log;
 
304
uint32_t connect_timeout;
261
305
uint32_t server_id;
262
306
uint64_t table_cache_size;
263
 
size_t table_def_size;
 
307
uint64_t table_def_size;
 
308
ulong what_to_log;
 
309
uint64_t slow_launch_time;
 
310
uint64_t slave_open_temp_tables;
 
311
uint32_t refresh_version;  /* Increments on each reload */
264
312
uint64_t aborted_threads;
265
313
uint64_t aborted_connects;
266
314
uint64_t max_connect_errors;
267
 
uint32_t global_thread_id= 1UL;
 
315
ulong thread_id=1L;
268
316
pid_t current_pid;
 
317
uint64_t slow_launch_threads= 0;
 
318
uint64_t expire_logs_days= 0;
269
319
 
270
320
const double log_10[] = {
271
321
  1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009,
309
359
char glob_hostname[FN_REFLEN];
310
360
char drizzle_real_data_home[FN_REFLEN],
311
361
     language[FN_REFLEN], 
 
362
     reg_ext[FN_EXTLEN],
 
363
     *opt_init_file, 
312
364
     *opt_tc_log_file;
313
365
char drizzle_unpacked_real_data_home[FN_REFLEN];
 
366
uint32_t reg_ext_length;
314
367
const key_map key_map_empty(0);
315
368
key_map key_map_full(0);                        // Will be initialized later
316
369
 
 
370
const char *opt_date_time_formats[3];
 
371
 
317
372
uint32_t drizzle_data_home_len;
318
373
char drizzle_data_home_buff[2], *drizzle_data_home=drizzle_real_data_home;
 
374
char server_version[SERVER_VERSION_LENGTH];
319
375
char *drizzle_tmpdir= NULL;
320
376
char *opt_drizzle_tmpdir= NULL;
 
377
const char *myisam_recover_options_str="OFF";
 
378
const char *myisam_stats_method_str="nulls_unequal";
321
379
 
322
380
/** name of reference on left espression in rewritten IN subquery */
323
381
const char *in_left_expr_name= "<left expr>";
330
388
 
331
389
FILE *stderror_file=0;
332
390
 
333
 
vector<Session*> session_list;
 
391
I_List<Session> threads;
 
392
I_List<NAMED_LIST> key_caches;
334
393
 
335
394
struct system_variables global_system_variables;
336
395
struct system_variables max_system_variables;
337
396
struct system_status_var global_status_var;
338
397
 
 
398
MY_BITMAP temp_pool;
 
399
 
339
400
const CHARSET_INFO *system_charset_info, *files_charset_info ;
340
 
const CHARSET_INFO *table_alias_charset;
 
401
const CHARSET_INFO *national_charset_info, *table_alias_charset;
341
402
const CHARSET_INFO *character_set_filesystem;
342
403
 
343
404
MY_LOCALE *my_default_lc_time_names;
348
409
 
349
410
pthread_key_t THR_Mem_root;
350
411
pthread_key_t THR_Session;
351
 
pthread_mutex_t LOCK_create_db;
352
 
pthread_mutex_t LOCK_open;
353
 
pthread_mutex_t LOCK_thread_count;
354
 
pthread_mutex_t LOCK_status;
355
 
pthread_mutex_t LOCK_global_read_lock;
356
 
pthread_mutex_t LOCK_global_system_variables;
 
412
pthread_mutex_t LOCK_drizzleclient_create_db, 
 
413
                LOCK_open, 
 
414
                LOCK_thread_count,
 
415
                LOCK_status,
 
416
                LOCK_global_read_lock,
 
417
                LOCK_global_system_variables;
357
418
 
 
419
pthread_rwlock_t        LOCK_sys_init_connect;
358
420
pthread_rwlock_t        LOCK_system_variables_hash;
359
421
pthread_cond_t COND_refresh, COND_thread_count, COND_global_read_lock;
360
422
pthread_t signal_thread;
361
 
pthread_cond_t  COND_server_end;
 
423
pthread_attr_t connection_attrib;
 
424
pthread_cond_t  COND_server_started;
 
425
 
 
426
/* replication parameters, if master_host is not NULL, we are a slave */
 
427
uint32_t report_port= DRIZZLE_PORT;
 
428
uint32_t master_retry_count= 0;
 
429
char *master_info_file;
 
430
char *report_host;
 
431
char *opt_logname;
362
432
 
363
433
/* Static variables */
364
434
 
370
440
static char *drizzle_home_ptr, *pidfile_name_ptr;
371
441
static int defaults_argc;
372
442
static char **defaults_argv;
 
443
static char *opt_bin_logname;
 
444
 
 
445
struct rand_struct sql_rand; ///< used by sql_class.cc:Session::Session()
373
446
 
374
447
struct passwd *user_info;
375
448
static pthread_t select_thread;
376
449
static uint32_t thr_kill_signal;
377
450
 
 
451
extern scheduling_st thread_scheduler;
 
452
 
378
453
/**
379
454
  Number of currently active user connections. The variable is protected by
380
455
  LOCK_thread_count.
381
456
*/
382
 
drizzled::atomic<uint32_t> connection_count;
383
 
 
384
 
/** 
385
 
  Refresh value. We use to test this to find out if a refresh even has happened recently.
386
 
*/
387
 
uint64_t refresh_version;  /* Increments on each reload */
 
457
uint32_t connection_count= 0;
388
458
 
389
459
/* Function declarations */
390
 
bool drizzle_rm_tmp_tables();
391
460
 
392
461
extern "C" pthread_handler_t signal_hand(void *arg);
393
462
static void drizzle_init_variables(void);
394
463
static void get_options(int *argc,char **argv);
395
464
extern "C" bool drizzled_get_one_option(int, const struct my_option *, char *);
 
465
static void set_server_version(void);
396
466
static int init_thread_environment();
397
467
static const char *get_relative_path(const char *path);
398
 
static void fix_paths(string &progname);
 
468
static void fix_paths(void);
 
469
void handle_connections_sockets();
399
470
extern "C" pthread_handler_t handle_slave(void *arg);
 
471
static uint32_t find_bit_type(const char *x, TYPELIB *bit_lib);
 
472
static uint32_t find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
 
473
                                   const char *option);
400
474
static void clean_up(bool print_message);
401
475
 
402
476
static void usage(void);
 
477
static void close_server_sock();
403
478
static void clean_up_mutexes(void);
404
 
void close_connections(void);
405
 
 
 
479
static void drizzled_exit(int exit_code) __attribute__((noreturn));
 
480
extern "C" bool safe_read_error_impl(NET *net);
 
481
 
406
482
/****************************************************************************
407
483
** Code to end drizzled
408
484
****************************************************************************/
409
485
 
410
486
void close_connections(void)
411
487
{
412
 
  /* Abort listening to new connections */
413
 
  plugin::Listen::shutdown();
414
488
 
415
489
  /* kill connection thread */
416
490
  (void) pthread_mutex_lock(&LOCK_thread_count);
423
497
    set_timespec(abstime, 2);
424
498
    for (uint32_t tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
425
499
    {
426
 
      error=pthread_cond_timedwait(&COND_thread_count,&LOCK_thread_count, &abstime);
 
500
      error=pthread_cond_timedwait(&COND_thread_count,&LOCK_thread_count,
 
501
                                   &abstime);
427
502
      if (error != EINTR)
428
 
        break;
 
503
        break;
429
504
    }
 
505
    close_server_sock();
430
506
  }
431
507
  (void) pthread_mutex_unlock(&LOCK_thread_count);
432
508
 
433
509
 
 
510
  /* Abort listening to new connections */
 
511
  {
 
512
    int x;
 
513
 
 
514
    for (x= 0; x < pollfd_count; x++)
 
515
    {
 
516
      if (fds[x].fd != -1)
 
517
      {
 
518
        (void) shutdown(fds[x].fd, SHUT_RDWR);
 
519
        (void) close(fds[x].fd);
 
520
        fds[x].fd= -1;
 
521
      }
 
522
    }
 
523
  }
 
524
 
434
525
  /*
435
526
    First signal all threads that it's time to die
436
527
    This will give the threads some time to gracefully abort their
438
529
  */
439
530
 
440
531
  Session *tmp;
441
 
 
442
532
  (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
443
533
 
444
 
  for( vector<Session*>::iterator it= session_list.begin(); it != session_list.end(); ++it )
 
534
  I_List_iterator<Session> it(threads);
 
535
  while ((tmp=it++))
445
536
  {
446
 
    tmp= *it;
447
537
    tmp->killed= Session::KILL_CONNECTION;
448
 
    tmp->scheduler->killSession(tmp);
449
 
    DRIZZLE_CONNECTION_DONE(tmp->thread_id);
 
538
    thread_scheduler.post_kill_notification(tmp);
450
539
    if (tmp->mysys_var)
451
540
    {
452
541
      tmp->mysys_var->abort=1;
462
551
  }
463
552
  (void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list
464
553
 
465
 
  if (connection_count)
466
 
    sleep(2);                                   // Give threads time to die
 
554
  /* TODO This is a crappy way to handle this. Fix for proper shutdown. */
 
555
  if (thread_count)
 
556
    sleep(2);                                   // Give threads time to die
467
557
 
468
558
  /*
469
559
    Force remaining threads to die by closing the connection to the client
470
560
    This will ensure that threads that are waiting for a command from the
471
561
    client on a blocking read call are aborted.
472
562
  */
 
563
 
473
564
  for (;;)
474
565
  {
475
566
    (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
476
 
    if (session_list.empty())
 
567
    if (!(tmp=threads.get()))
477
568
    {
478
569
      (void) pthread_mutex_unlock(&LOCK_thread_count);
479
570
      break;
480
571
    }
481
 
    tmp= session_list.front();
482
 
    /* Close before unlock, avoiding crash. See LP bug#436685 */
483
 
    tmp->client->close();
 
572
    if (tmp->drizzleclient_vio_ok())
 
573
    {
 
574
      if (global_system_variables.log_warnings)
 
575
            errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),my_progname,
 
576
                          tmp->thread_id,
 
577
                          (tmp->security_ctx.user.c_str() ?
 
578
                           tmp->security_ctx.user.c_str() : ""));
 
579
      tmp->close_connection(0,0);
 
580
    }
484
581
    (void) pthread_mutex_unlock(&LOCK_thread_count);
485
582
  }
486
 
}
487
 
 
488
 
extern "C" void print_signal_warning(int sig);
 
583
  /* All threads has now been aborted */
 
584
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
585
  while (thread_count)
 
586
  {
 
587
    (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
 
588
  }
 
589
  (void) pthread_mutex_unlock(&LOCK_thread_count);
 
590
}
 
591
 
 
592
 
 
593
static void close_server_sock()
 
594
{
 
595
#ifdef HAVE_CLOSE_SERVER_SOCK
 
596
  {
 
597
    int x;
 
598
 
 
599
    for (x= 0; x < pollfd_count; x++)
 
600
    {
 
601
      if (fds[x].fd != -1)
 
602
      {
 
603
        (void) shutdown(fds[x].fd, SHUT_RDWR);
 
604
        (void) close(fds[x].fd);
 
605
        fds[x].fd= -1;
 
606
      }
 
607
    }
 
608
  }
 
609
#endif
 
610
}
 
611
 
489
612
 
490
613
extern "C" void print_signal_warning(int sig)
491
614
{
498
621
    alarm(2);                                   /* reschedule alarm */
499
622
}
500
623
 
 
624
 
 
625
void unireg_init()
 
626
{
 
627
  abort_loop=0;
 
628
 
 
629
  my_disable_async_io=1;                /* aioread is only in shared library */
 
630
  wild_many='%'; wild_one='_'; wild_prefix='\\'; /* Change to sql syntax */
 
631
 
 
632
  current_pid=(ulong) getpid();         /* Save for later ref */
 
633
  init_time();                          /* Init time-functions (read zone) */
 
634
  my_abort_hook=unireg_abort;           /* Abort with close of databases */
 
635
 
 
636
  strcpy(reg_ext,".frm");
 
637
  reg_ext_length= 4;
 
638
 
 
639
  return;
 
640
}
 
641
 
 
642
 
501
643
/**
502
644
  cleanup all memory and end program nicely.
503
645
 
508
650
  @note
509
651
    This function never returns.
510
652
*/
511
 
void unireg_end(void)
 
653
extern "C" void unireg_end(void)
512
654
{
513
655
  clean_up(1);
514
656
  my_thread_end();
520
662
}
521
663
 
522
664
 
523
 
void unireg_abort(int exit_code)
 
665
extern "C" void unireg_abort(int exit_code)
524
666
{
525
667
 
526
668
  if (exit_code)
527
669
    errmsg_printf(ERRMSG_LVL_ERROR, _("Aborting\n"));
528
 
  else if (opt_help || opt_help_extended)
 
670
  else if (opt_help)
529
671
    usage();
530
 
  clean_up(!opt_help && (exit_code));
 
672
  clean_up(!opt_help && (exit_code)); /* purecov: inspected */
 
673
  drizzled_exit(exit_code);
 
674
}
 
675
 
 
676
 
 
677
static void drizzled_exit(int exit_code)
 
678
{
531
679
  clean_up_mutexes();
532
 
  my_end();
533
 
  exit(exit_code);
 
680
  my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
 
681
  exit(exit_code); /* purecov: inspected */
534
682
}
535
683
 
536
684
 
537
 
static void clean_up(bool print_message)
 
685
void clean_up(bool print_message)
538
686
{
539
 
  plugin::Registry &plugins= plugin::Registry::singleton();
540
687
  if (cleanup_done++)
541
 
    return;
 
688
    return; /* purecov: inspected */
542
689
 
543
690
  table_cache_free();
544
 
  TableShare::cacheStop();
 
691
  table_def_free();
545
692
  set_var_free();
546
693
  free_charsets();
547
 
  plugin_shutdown(plugins);
 
694
  udf_free();
 
695
  plugin_shutdown();
548
696
  ha_end();
549
697
  xid_cache_free();
 
698
  delete_elements(&key_caches, (void (*)(const char*, unsigned char*)) free_key_cache);
 
699
  multi_keycache_free();
550
700
  free_status_vars();
 
701
  my_free_open_file_info();
 
702
  free((char*) global_system_variables.date_format);
 
703
  free((char*) global_system_variables.time_format);
 
704
  free((char*) global_system_variables.datetime_format);
551
705
  if (defaults_argv)
552
706
    free_defaults(defaults_argv);
 
707
  free(sys_init_connect.value);
553
708
  free(drizzle_tmpdir);
 
709
  if (opt_bin_logname)
 
710
    free(opt_bin_logname);
554
711
  if (opt_secure_file_priv)
555
712
    free(opt_secure_file_priv);
556
 
 
557
 
  deinit_temporal_formats();
558
 
 
559
 
#if GOOGLE_PROTOBUF_VERSION >= 2001000
560
 
  google::protobuf::ShutdownProtobufLibrary();
561
 
#endif
562
 
 
563
 
  (void) unlink(pidfile_name);  // This may not always exist
 
713
  bitmap_free(&temp_pool);
 
714
 
 
715
  (void) my_delete(pidfile_name,MYF(0));        // This may not always exist
564
716
 
565
717
  if (print_message && server_start_time)
566
718
    errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_SHUTDOWN_COMPLETE)),my_progname);
573
725
  (void) pthread_mutex_lock(&LOCK_thread_count);
574
726
  ready_to_exit=1;
575
727
  /* do the broadcast inside the lock to ensure that my_end() is not called */
576
 
  (void) pthread_cond_broadcast(&COND_server_end);
 
728
  (void) pthread_cond_broadcast(&COND_thread_count);
577
729
  (void) pthread_mutex_unlock(&LOCK_thread_count);
578
730
 
579
731
  /*
585
737
 
586
738
static void clean_up_mutexes()
587
739
{
588
 
  (void) pthread_mutex_destroy(&LOCK_create_db);
 
740
  (void) pthread_mutex_destroy(&LOCK_drizzleclient_create_db);
 
741
  (void) pthread_mutex_destroy(&LOCK_lock_db);
589
742
  (void) pthread_mutex_destroy(&LOCK_open);
590
743
  (void) pthread_mutex_destroy(&LOCK_thread_count);
591
744
  (void) pthread_mutex_destroy(&LOCK_status);
 
745
  (void) pthread_rwlock_destroy(&LOCK_sys_init_connect);
592
746
  (void) pthread_mutex_destroy(&LOCK_global_system_variables);
593
747
  (void) pthread_rwlock_destroy(&LOCK_system_variables_hash);
594
748
  (void) pthread_mutex_destroy(&LOCK_global_read_lock);
595
749
  (void) pthread_cond_destroy(&COND_thread_count);
596
 
  (void) pthread_cond_destroy(&COND_server_end);
597
750
  (void) pthread_cond_destroy(&COND_refresh);
598
751
  (void) pthread_cond_destroy(&COND_global_read_lock);
599
752
}
600
753
 
601
754
 
 
755
/****************************************************************************
 
756
** Init IP and UNIX socket
 
757
****************************************************************************/
 
758
 
 
759
static void set_ports()
 
760
{
 
761
  char  *env;
 
762
  if (!drizzled_port)
 
763
  {                                     // Get port if not from commandline
 
764
    drizzled_port= DRIZZLE_PORT;
 
765
 
 
766
    /*
 
767
      if builder specifically requested a default port, use that
 
768
      (even if it coincides with our factory default).
 
769
      only if they didn't do we check /etc/services (and, failing
 
770
      on that, fall back to the factory default of 4427).
 
771
      either default can be overridden by the environment variable
 
772
      DRIZZLE_TCP_PORT, which in turn can be overridden with command
 
773
      line options.
 
774
    */
 
775
 
 
776
    struct  servent *serv_ptr;
 
777
    if ((serv_ptr= getservbyname("drizzle", "tcp")))
 
778
      drizzled_port= ntohs((u_short) serv_ptr->s_port); /* purecov: inspected */
 
779
 
 
780
    if ((env = getenv("DRIZZLE_TCP_PORT")))
 
781
      drizzled_port= (uint32_t) atoi(env);              /* purecov: inspected */
 
782
 
 
783
    assert(drizzled_port);
 
784
  }
 
785
}
 
786
 
602
787
/* Change to run as another user if started with --user */
603
788
 
604
789
static struct passwd *check_user(const char *user)
612
797
    if (user)
613
798
    {
614
799
      /* Don't give a warning, if real user is same as given with --user */
 
800
      /* purecov: begin tested */
615
801
      tmp_user_info= getpwnam(user);
616
802
      if ((!tmp_user_info || user_id != tmp_user_info->pw_uid) &&
617
803
          global_system_variables.log_warnings)
618
804
            errmsg_printf(ERRMSG_LVL_WARN, _("One can only use the --user switch "
619
805
                            "if running as root\n"));
 
806
      /* purecov: end */
620
807
    }
621
808
    return NULL;
622
809
  }
625
812
      errmsg_printf(ERRMSG_LVL_ERROR, _("Fatal error: Please read \"Security\" section of "
626
813
                      "the manual to find out how to run drizzled as root!\n"));
627
814
    unireg_abort(1);
 
815
 
 
816
    return NULL;
628
817
  }
 
818
  /* purecov: begin tested */
629
819
  if (!strcmp(user,"root"))
630
820
    return NULL;                        // Avoid problem with dynamic libraries
631
821
 
640
830
      goto err;
641
831
  }
642
832
  return tmp_user_info;
 
833
  /* purecov: end */
643
834
 
644
835
err:
645
836
  errmsg_printf(ERRMSG_LVL_ERROR, _("Fatal error: Can't change to run as user '%s' ;  "
647
838
  unireg_abort(1);
648
839
 
649
840
#ifdef PR_SET_DUMPABLE
650
 
  if (test_flags.test(TEST_CORE_ON_SIGNAL))
 
841
  if (test_flags & TEST_CORE_ON_SIGNAL)
651
842
  {
652
843
    /* inform kernel that process is dumpable */
653
844
    (void) prctl(PR_SET_DUMPABLE, 1);
654
845
  }
655
846
#endif
656
847
 
657
 
/* Sun Studio 5.10 doesn't like this line.  5.9 requires it */
658
 
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x590)
659
848
  return NULL;
660
 
#endif
661
 
 
662
849
}
663
850
 
664
851
static void set_user(const char *user, struct passwd *user_info_arg)
665
852
{
 
853
  /* purecov: begin tested */
666
854
  assert(user_info_arg != 0);
667
855
#ifdef HAVE_INITGROUPS
668
856
  /*
685
873
    sql_perror("setuid");
686
874
    unireg_abort(1);
687
875
  }
 
876
  /* purecov: end */
688
877
}
689
878
 
690
879
 
714
903
  }
715
904
}
716
905
 
717
 
extern "C" void end_thread_signal(int );
 
906
 
 
907
static void network_init(void)
 
908
{
 
909
  int   ret;
 
910
  uint32_t  waited;
 
911
  uint32_t  this_wait;
 
912
  uint32_t  retry;
 
913
  char port_buf[NI_MAXSERV];
 
914
  struct addrinfo *ai;
 
915
  struct addrinfo *next;
 
916
  struct addrinfo hints;
 
917
  int error;
 
918
 
 
919
  set_ports();
 
920
 
 
921
  memset(fds, 0, sizeof(struct pollfd) * UINT8_MAX);
 
922
  memset(&hints, 0, sizeof (hints));
 
923
  hints.ai_flags= AI_PASSIVE;
 
924
  hints.ai_socktype= SOCK_STREAM;
 
925
 
 
926
  snprintf(port_buf, NI_MAXSERV, "%d", drizzled_port);
 
927
  error= getaddrinfo(my_bind_addr_str, port_buf, &hints, &ai);
 
928
  if (error != 0)
 
929
  {
 
930
    sql_perror(ER(ER_IPSOCK_ERROR));            /* purecov: tested */
 
931
    unireg_abort(1);                            /* purecov: tested */
 
932
  }
 
933
 
 
934
  for (next= ai, pollfd_count= 0; next; next= next->ai_next, pollfd_count++)
 
935
  {
 
936
    int ip_sock;
 
937
 
 
938
    ip_sock= socket(next->ai_family, next->ai_socktype, next->ai_protocol);
 
939
 
 
940
    if (ip_sock == -1)
 
941
    {
 
942
      sql_perror(ER(ER_IPSOCK_ERROR));          /* purecov: tested */
 
943
      unireg_abort(1);                          /* purecov: tested */
 
944
    }
 
945
 
 
946
    fds[pollfd_count].fd= ip_sock;
 
947
    fds[pollfd_count].events= POLLIN | POLLERR;
 
948
 
 
949
    /* Add options for our listening socket */
 
950
    {
 
951
      struct linger ling = {0, 0};
 
952
      int flags =1;
 
953
 
 
954
#ifdef IPV6_V6ONLY
 
955
      if (next->ai_family == AF_INET6)
 
956
      {
 
957
        error= setsockopt(ip_sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &flags, sizeof(flags));
 
958
        if (error != 0)
 
959
        {
 
960
          perror("setsockopt");
 
961
          assert(error == 0);
 
962
        }
 
963
      }
 
964
#endif
 
965
      error= setsockopt(ip_sock, SOL_SOCKET, SO_REUSEADDR, (char*)&flags, sizeof(flags));
 
966
      if (error != 0)
 
967
      {
 
968
        perror("setsockopt");
 
969
        assert(error == 0);
 
970
      }
 
971
      error= setsockopt(ip_sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, sizeof(flags));
 
972
      if (error != 0)
 
973
      {
 
974
        perror("setsockopt");
 
975
        assert(error == 0);
 
976
      }
 
977
      error= setsockopt(ip_sock, SOL_SOCKET, SO_LINGER, (void *)&ling, sizeof(ling));
 
978
      if (error != 0)
 
979
      {
 
980
        perror("setsockopt");
 
981
        assert(error == 0);
 
982
      }
 
983
      error= setsockopt(ip_sock, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags));
 
984
      if (error != 0)
 
985
      {
 
986
        perror("setsockopt");
 
987
        assert(error == 0);
 
988
      }
 
989
    }
 
990
 
 
991
 
 
992
    /*
 
993
      Sometimes the port is not released fast enough when stopping and
 
994
      restarting the server. This happens quite often with the test suite
 
995
      on busy Linux systems. Retry to bind the address at these intervals:
 
996
      Sleep intervals: 1, 2, 4,  6,  9, 13, 17, 22, ...
 
997
      Retry at second: 1, 3, 7, 13, 22, 35, 52, 74, ...
 
998
      Limit the sequence by drizzled_port_timeout (set --port-open-timeout=#).
 
999
    */
 
1000
    for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
 
1001
    {
 
1002
      if (((ret= bind(ip_sock, next->ai_addr, next->ai_addrlen)) >= 0 ) ||
 
1003
          (errno != EADDRINUSE) ||
 
1004
          (waited >= drizzled_port_timeout))
 
1005
        break;
 
1006
          errmsg_printf(ERRMSG_LVL_INFO, _("Retrying bind on TCP/IP port %u"), drizzled_port);
 
1007
      this_wait= retry * retry / 3 + 1;
 
1008
      sleep(this_wait);
 
1009
    }
 
1010
    if (ret < 0)
 
1011
    {
 
1012
      sql_perror(_("Can't start server: Bind on TCP/IP port"));
 
1013
          errmsg_printf(ERRMSG_LVL_ERROR, _("Do you already have another drizzled server running "
 
1014
                        "on port: %d ?"),drizzled_port);
 
1015
      unireg_abort(1);
 
1016
    }
 
1017
    if (listen(ip_sock,(int) back_log) < 0)
 
1018
    {
 
1019
      sql_perror(_("Can't start server: listen() on TCP/IP port"));
 
1020
          errmsg_printf(ERRMSG_LVL_ERROR, _("listen() on TCP/IP failed with error %d"),
 
1021
                      errno);
 
1022
      unireg_abort(1);
 
1023
    }
 
1024
  }
 
1025
 
 
1026
  freeaddrinfo(ai);
 
1027
  return;
 
1028
}
 
1029
 
 
1030
 
718
1031
 
719
1032
/** Called when a thread is aborted. */
 
1033
/* ARGSUSED */
720
1034
extern "C" void end_thread_signal(int )
721
1035
{
722
1036
  Session *session=current_session;
723
1037
  if (session)
724
1038
  {
725
1039
    statistic_increment(killed_threads, &LOCK_status);
726
 
    session->scheduler->killSessionNow(session);
727
 
    DRIZZLE_CONNECTION_DONE(session->thread_id);
 
1040
    (void)thread_scheduler.end_thread(session, 0);              /* purecov: inspected */
728
1041
  }
729
 
  return;
 
1042
  return;;                              /* purecov: deadcode */
730
1043
}
731
1044
 
732
1045
 
743
1056
 
744
1057
void unlink_session(Session *session)
745
1058
{
 
1059
  session->cleanup();
 
1060
 
 
1061
  (void) pthread_mutex_lock(&LOCK_thread_count);
746
1062
  connection_count--;
747
 
 
748
 
  session->cleanup();
749
 
 
750
 
  (void) pthread_mutex_lock(&LOCK_thread_count);
751
 
  pthread_mutex_lock(&session->LOCK_delete);
752
 
 
753
 
  session_list.erase(remove(session_list.begin(),
754
 
                     session_list.end(),
755
 
                     session));
756
 
 
 
1063
  thread_count--;
757
1064
  delete session;
758
 
  (void) pthread_mutex_unlock(&LOCK_thread_count);
759
 
 
 
1065
  pthread_mutex_unlock(&LOCK_thread_count);
760
1066
  return;
761
1067
}
762
1068
 
785
1091
}
786
1092
#endif
787
1093
 
788
 
extern "C" void handle_segfault(int sig);
789
1094
 
790
1095
extern "C" void handle_segfault(int sig)
791
1096
{
800
1105
  */
801
1106
  if (segfaulted)
802
1107
  {
803
 
    fprintf(stderr, _("Fatal signal %d while backtracing\n"), sig);
 
1108
    fprintf(stderr, _("Fatal " SIGNAL_FMT " while backtracing\n"), sig);
804
1109
    exit(1);
805
1110
  }
806
1111
 
814
1119
  }
815
1120
 
816
1121
  localtime_r(&curr_time, &tm);
817
 
  
818
 
  fprintf(stderr,"%02d%02d%02d %2d:%02d:%02d - drizzled got signal %d;\n"
 
1122
 
 
1123
  fprintf(stderr,"%02d%02d%02d %2d:%02d:%02d - drizzled got "
 
1124
          SIGNAL_FMT " ;\n"
819
1125
          "This could be because you hit a bug. It is also possible that "
820
1126
          "this binary\n or one of the libraries it was linked against is "
821
1127
          "corrupt, improperly built,\n or misconfigured. This error can "
831
1137
          (uint32_t) dflt_key_cache->key_cache_mem_size);
832
1138
  fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
833
1139
  fprintf(stderr, "max_used_connections=%u\n", max_used_connections);
834
 
  fprintf(stderr, "connection_count=%u\n", uint32_t(connection_count));
 
1140
  fprintf(stderr, "max_threads=%u\n", thread_scheduler.max_threads);
 
1141
  fprintf(stderr, "thread_count=%u\n", thread_count);
 
1142
  fprintf(stderr, "connection_count=%u\n", connection_count);
835
1143
  fprintf(stderr, _("It is possible that drizzled could use up to \n"
836
1144
                    "key_buffer_size + (read_buffer_size + "
837
 
                    "sort_buffer_size)*thread_count\n"
 
1145
                    "sort_buffer_size)*max_threads = %"PRIu64" K\n"
838
1146
                    "bytes of memory\n"
839
1147
                    "Hope that's ok; if not, decrease some variables in the "
840
 
                    "equation.\n\n"));
 
1148
                    "equation.\n\n"),
 
1149
          (uint64_t)(((uint32_t) dflt_key_cache->key_cache_mem_size +
 
1150
                     (global_system_variables.read_buff_size +
 
1151
                      global_system_variables.sortbuff_size) *
 
1152
                     thread_scheduler.max_threads) / 1024));
841
1153
 
842
1154
#ifdef HAVE_STACKTRACE
843
1155
  Session *session= current_session;
844
1156
 
845
 
  if (! (test_flags.test(TEST_NO_STACKTRACE)))
 
1157
  if (!(test_flags & TEST_NO_STACKTRACE))
846
1158
  {
847
1159
    fprintf(stderr,"session: 0x%lx\n",(long) session);
848
1160
    fprintf(stderr,_("Attempting backtrace. You can use the following "
926
1238
  }
927
1239
 
928
1240
#ifdef HAVE_WRITE_CORE
929
 
  if (test_flags.test(TEST_CORE_ON_SIGNAL))
 
1241
  if (test_flags & TEST_CORE_ON_SIGNAL)
930
1242
  {
931
1243
    fprintf(stderr, _("Writing a core file\n"));
932
1244
    fflush(stderr);
949
1261
  sigset_t set;
950
1262
  struct sigaction sa;
951
1263
 
952
 
  if (!(test_flags.test(TEST_NO_STACKTRACE) || 
953
 
        test_flags.test(TEST_CORE_ON_SIGNAL)))
 
1264
  if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL))
954
1265
  {
955
1266
    sa.sa_flags = SA_RESETHAND | SA_NODEFER;
956
1267
    sigemptyset(&sa.sa_mask);
968
1279
  }
969
1280
 
970
1281
#ifdef HAVE_GETRLIMIT
971
 
  if (test_flags.test(TEST_CORE_ON_SIGNAL))
 
1282
  if (test_flags & TEST_CORE_ON_SIGNAL)
972
1283
  {
973
1284
    /* Change limits so that we will get a core file */
974
 
    struct rlimit rl;
 
1285
    STRUCT_RLIMIT rl;
975
1286
    rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
976
1287
    if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
977
1288
        errmsg_printf(ERRMSG_LVL_WARN, _("setrlimit could not change the size of core files "
999
1310
#ifdef SIGTSTP
1000
1311
  sigaddset(&set,SIGTSTP);
1001
1312
#endif
1002
 
  if (test_flags.test(TEST_SIGINT))
 
1313
  if (test_flags & TEST_SIGINT)
1003
1314
  {
1004
1315
    my_sigset(thr_kill_signal, end_thread_signal);
1005
1316
    // May be SIGINT
1012
1323
  return;;
1013
1324
}
1014
1325
 
1015
 
extern "C" void my_message_sql(uint32_t error, const char *str, myf MyFlags);
 
1326
static void check_data_home(const char *)
 
1327
{}
 
1328
 
1016
1329
 
1017
1330
/**
1018
1331
  All global error messages are sent here where the first one is stored
1019
1332
  for the client.
1020
1333
*/
1021
 
extern "C" void my_message_sql(uint32_t error, const char *str, myf MyFlags)
 
1334
/* ARGSUSED */
 
1335
extern "C" void my_message_sql(uint32_t error, const char *str, myf MyFlags);
 
1336
 
 
1337
void my_message_sql(uint32_t error, const char *str, myf MyFlags)
1022
1338
{
1023
1339
  Session *session;
1024
1340
  /*
1051
1367
          error= ER_UNKNOWN_ERROR;
1052
1368
        if (str == NULL)
1053
1369
          str= ER(error);
1054
 
        session->main_da.set_error_status(error, str);
 
1370
        session->main_da.set_error_status(session, error, str);
1055
1371
      }
1056
1372
    }
1057
1373
 
1067
1383
    }
1068
1384
  }
1069
1385
  if (!session || MyFlags & ME_NOREFRESH)
1070
 
    errmsg_printf(ERRMSG_LVL_ERROR, "%s: %s",my_progname,str);
 
1386
    errmsg_printf(ERRMSG_LVL_ERROR, "%s: %s",my_progname,str); /* purecov: inspected */
 
1387
  return;;
1071
1388
}
1072
1389
 
1073
1390
 
1074
1391
static const char *load_default_groups[]= {
1075
 
DRIZZLE_CONFIG_NAME, "server", 0, 0};
1076
 
 
1077
 
static int show_starttime(SHOW_VAR *var, char *buff)
1078
 
{
1079
 
  var->type= SHOW_LONG;
1080
 
  var->value= buff;
1081
 
  *((long *)buff)= (long) (time(NULL) - server_start_time);
1082
 
  return 0;
1083
 
}
1084
 
 
1085
 
static int show_flushstatustime(SHOW_VAR *var, char *buff)
1086
 
{
1087
 
  var->type= SHOW_LONG;
1088
 
  var->value= buff;
1089
 
  *((long *)buff)= (long) (time(NULL) - flush_status_time);
1090
 
  return 0;
1091
 
}
1092
 
 
1093
 
static int show_open_tables(SHOW_VAR *var, char *buff)
1094
 
{
1095
 
  var->type= SHOW_LONG;
1096
 
  var->value= buff;
1097
 
  *((long *)buff)= (long)cached_open_tables();
1098
 
  return 0;
1099
 
}
1100
 
 
1101
 
static int show_table_definitions(SHOW_VAR *var, char *buff)
1102
 
{
1103
 
  var->type= SHOW_LONG;
1104
 
  var->value= buff;
1105
 
  *((long *)buff)= (long)cached_table_definitions();
1106
 
  return 0;
1107
 
}
1108
 
 
1109
 
static st_show_var_func_container
1110
 
show_open_tables_cont= { &show_open_tables };
1111
 
static st_show_var_func_container
1112
 
show_table_definitions_cont= { &show_table_definitions };
1113
 
static st_show_var_func_container
1114
 
show_starttime_cont= { &show_starttime };
1115
 
static st_show_var_func_container
1116
 
show_flushstatustime_cont= { &show_flushstatustime };
1117
 
 
1118
 
/*
1119
 
  Variables shown by SHOW STATUS in alphabetical order
 
1392
DRIZZLE_CONFIG_NAME,"server", DRIZZLE_BASE_VERSION, 0, 0};
 
1393
 
 
1394
 
 
1395
/**
 
1396
  Initialize one of the global date/time format variables.
 
1397
 
 
1398
  @param format_type            What kind of format should be supported
 
1399
  @param var_ptr                Pointer to variable that should be updated
 
1400
 
 
1401
  @note
 
1402
    The default value is taken from either opt_date_time_formats[] or
 
1403
    the ISO format (ANSI SQL)
 
1404
 
 
1405
  @retval
 
1406
    0 ok
 
1407
  @retval
 
1408
    1 error
1120
1409
*/
1121
 
static SHOW_VAR com_status_vars[]= {
 
1410
 
 
1411
static bool init_global_datetime_format(enum enum_drizzle_timestamp_type format_type,
 
1412
                                        DATE_TIME_FORMAT **var_ptr)
 
1413
{
 
1414
  /* Get command line option */
 
1415
  const char *str= opt_date_time_formats[format_type];
 
1416
 
 
1417
  if (!str)                                     // No specified format
 
1418
  {
 
1419
    str= get_date_time_format_str(&known_date_time_formats[ISO_FORMAT],
 
1420
                                  format_type);
 
1421
    /*
 
1422
      Set the "command line" option to point to the generated string so
 
1423
      that we can set global formats back to default
 
1424
    */
 
1425
    opt_date_time_formats[format_type]= str;
 
1426
  }
 
1427
  if (!(*var_ptr= date_time_format_make(format_type, str, strlen(str))))
 
1428
  {
 
1429
    fprintf(stderr, _("Wrong date/time format specifier: %s\n"), str);
 
1430
    return 1;
 
1431
  }
 
1432
  return 0;
 
1433
}
 
1434
 
 
1435
SHOW_VAR com_status_vars[]= {
1122
1436
  {"admin_commands",       (char*) offsetof(STATUS_VAR, com_other), SHOW_LONG_STATUS},
 
1437
  {"assign_to_keycache",   (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ASSIGN_TO_KEYCACHE]), SHOW_LONG_STATUS},
1123
1438
  {"alter_db",             (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ALTER_DB]), SHOW_LONG_STATUS},
1124
1439
  {"alter_table",          (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ALTER_TABLE]), SHOW_LONG_STATUS},
1125
1440
  {"analyze",              (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ANALYZE]), SHOW_LONG_STATUS},
1132
1447
  {"create_index",         (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_CREATE_INDEX]), SHOW_LONG_STATUS},
1133
1448
  {"create_table",         (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_CREATE_TABLE]), SHOW_LONG_STATUS},
1134
1449
  {"delete",               (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_DELETE]), SHOW_LONG_STATUS},
 
1450
  {"delete_multi",         (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_DELETE_MULTI]), SHOW_LONG_STATUS},
1135
1451
  {"drop_db",              (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_DROP_DB]), SHOW_LONG_STATUS},
1136
1452
  {"drop_index",           (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_DROP_INDEX]), SHOW_LONG_STATUS},
1137
1453
  {"drop_table",           (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_DROP_TABLE]), SHOW_LONG_STATUS},
1141
1457
  {"insert_select",        (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_INSERT_SELECT]), SHOW_LONG_STATUS},
1142
1458
  {"kill",                 (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_KILL]), SHOW_LONG_STATUS},
1143
1459
  {"load",                 (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_LOAD]), SHOW_LONG_STATUS},
 
1460
  {"lock_tables",          (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_LOCK_TABLES]), SHOW_LONG_STATUS},
 
1461
  {"optimize",             (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_OPTIMIZE]), SHOW_LONG_STATUS},
1144
1462
  {"release_savepoint",    (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_RELEASE_SAVEPOINT]), SHOW_LONG_STATUS},
1145
1463
  {"rename_table",         (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_RENAME_TABLE]), SHOW_LONG_STATUS},
 
1464
  {"repair",               (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_REPAIR]), SHOW_LONG_STATUS},
1146
1465
  {"replace",              (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_REPLACE]), SHOW_LONG_STATUS},
1147
1466
  {"replace_select",       (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_REPLACE_SELECT]), SHOW_LONG_STATUS},
1148
1467
  {"rollback",             (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ROLLBACK]), SHOW_LONG_STATUS},
1158
1477
  {"show_fields",          (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_FIELDS]), SHOW_LONG_STATUS},
1159
1478
  {"show_keys",            (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS},
1160
1479
  {"show_open_tables",     (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_OPEN_TABLES]), SHOW_LONG_STATUS},
 
1480
  {"show_plugins",         (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_PLUGINS]), SHOW_LONG_STATUS},
1161
1481
  {"show_processlist",     (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_PROCESSLIST]), SHOW_LONG_STATUS},
1162
1482
  {"show_status",          (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
1163
1483
  {"show_table_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS},
1167
1487
  {"truncate",             (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_TRUNCATE]), SHOW_LONG_STATUS},
1168
1488
  {"unlock_tables",        (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_UNLOCK_TABLES]), SHOW_LONG_STATUS},
1169
1489
  {"update",               (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_UPDATE]), SHOW_LONG_STATUS},
1170
 
  {NULL, NULL, SHOW_LONGLONG}
1171
 
};
1172
 
 
1173
 
static SHOW_VAR status_vars[]= {
1174
 
  {"Aborted_clients",          (char*) &aborted_threads,        SHOW_LONGLONG},
1175
 
  {"Aborted_connects",         (char*) &aborted_connects,       SHOW_LONGLONG},
1176
 
  {"Bytes_received",           (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS},
1177
 
  {"Bytes_sent",               (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS},
1178
 
  {"Com",                      (char*) com_status_vars, SHOW_ARRAY},
1179
 
  {"Connections",              (char*) &global_thread_id, SHOW_INT_NOFLUSH},
1180
 
  {"Created_tmp_disk_tables",  (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS},
1181
 
  {"Created_tmp_files",        (char*) &my_tmp_file_created,SHOW_INT},
1182
 
  {"Created_tmp_tables",       (char*) offsetof(STATUS_VAR, created_tmp_tables), SHOW_LONG_STATUS},
1183
 
  {"Flush_commands",           (char*) &refresh_version,    SHOW_INT_NOFLUSH},
1184
 
  {"Handler_commit",           (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
1185
 
  {"Handler_delete",           (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
1186
 
  {"Handler_prepare",          (char*) offsetof(STATUS_VAR, ha_prepare_count),  SHOW_LONG_STATUS},
1187
 
  {"Handler_read_first",       (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS},
1188
 
  {"Handler_read_key",         (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS},
1189
 
  {"Handler_read_next",        (char*) offsetof(STATUS_VAR, ha_read_next_count), SHOW_LONG_STATUS},
1190
 
  {"Handler_read_prev",        (char*) offsetof(STATUS_VAR, ha_read_prev_count), SHOW_LONG_STATUS},
1191
 
  {"Handler_read_rnd",         (char*) offsetof(STATUS_VAR, ha_read_rnd_count), SHOW_LONG_STATUS},
1192
 
  {"Handler_read_rnd_next",    (char*) offsetof(STATUS_VAR, ha_read_rnd_next_count), SHOW_LONG_STATUS},
1193
 
  {"Handler_rollback",         (char*) offsetof(STATUS_VAR, ha_rollback_count), SHOW_LONG_STATUS},
1194
 
  {"Handler_savepoint",        (char*) offsetof(STATUS_VAR, ha_savepoint_count), SHOW_LONG_STATUS},
1195
 
  {"Handler_savepoint_rollback",(char*) offsetof(STATUS_VAR, ha_savepoint_rollback_count), SHOW_LONG_STATUS},
1196
 
  {"Handler_update",           (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS},
1197
 
  {"Handler_write",            (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS},
1198
 
  {"Key_blocks_not_flushed",   (char*) offsetof(KEY_CACHE, global_blocks_changed), SHOW_KEY_CACHE_LONG},
1199
 
  {"Key_blocks_unused",        (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_LONG},
1200
 
  {"Key_blocks_used",          (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_LONG},
1201
 
  {"Key_read_requests",        (char*) offsetof(KEY_CACHE, global_cache_r_requests), SHOW_KEY_CACHE_LONGLONG},
1202
 
  {"Key_reads",                (char*) offsetof(KEY_CACHE, global_cache_read), SHOW_KEY_CACHE_LONGLONG},
1203
 
  {"Key_write_requests",       (char*) offsetof(KEY_CACHE, global_cache_w_requests), SHOW_KEY_CACHE_LONGLONG},
1204
 
  {"Key_writes",               (char*) offsetof(KEY_CACHE, global_cache_write), SHOW_KEY_CACHE_LONGLONG},
1205
 
  {"Last_query_cost",          (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS},
1206
 
  {"Max_used_connections",     (char*) &max_used_connections,  SHOW_INT},
1207
 
  {"Open_files",               (char*) &my_file_opened,    SHOW_INT_NOFLUSH},
1208
 
  {"Open_streams",             (char*) &my_stream_opened,  SHOW_INT_NOFLUSH},
1209
 
  {"Open_table_definitions",   (char*) &show_table_definitions_cont, SHOW_FUNC},
1210
 
  {"Open_tables",              (char*) &show_open_tables_cont,       SHOW_FUNC},
1211
 
  {"Opened_files",             (char*) &my_file_total_opened, SHOW_INT_NOFLUSH},
1212
 
  {"Opened_tables",            (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS},
1213
 
  {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS},
1214
 
  {"Questions",                (char*) offsetof(STATUS_VAR, questions), SHOW_LONG_STATUS},
1215
 
  {"Select_full_join",         (char*) offsetof(STATUS_VAR, select_full_join_count), SHOW_LONG_STATUS},
1216
 
  {"Select_full_range_join",   (char*) offsetof(STATUS_VAR, select_full_range_join_count), SHOW_LONG_STATUS},
1217
 
  {"Select_range",             (char*) offsetof(STATUS_VAR, select_range_count), SHOW_LONG_STATUS},
1218
 
  {"Select_range_check",       (char*) offsetof(STATUS_VAR, select_range_check_count), SHOW_LONG_STATUS},
1219
 
  {"Select_scan",              (char*) offsetof(STATUS_VAR, select_scan_count), SHOW_LONG_STATUS},
1220
 
  {"Slow_queries",             (char*) offsetof(STATUS_VAR, long_query_count), SHOW_LONG_STATUS},
1221
 
  {"Sort_merge_passes",        (char*) offsetof(STATUS_VAR, filesort_merge_passes), SHOW_LONG_STATUS},
1222
 
  {"Sort_range",               (char*) offsetof(STATUS_VAR, filesort_range_count), SHOW_LONG_STATUS},
1223
 
  {"Sort_rows",                (char*) offsetof(STATUS_VAR, filesort_rows), SHOW_LONG_STATUS},
1224
 
  {"Sort_scan",                (char*) offsetof(STATUS_VAR, filesort_scan_count), SHOW_LONG_STATUS},
1225
 
  {"Table_locks_immediate",    (char*) &locks_immediate,        SHOW_INT},
1226
 
  {"Table_locks_waited",       (char*) &locks_waited,           SHOW_INT},
1227
 
  {"Threads_connected",        (char*) &connection_count,       SHOW_INT},
1228
 
  {"Uptime",                   (char*) &show_starttime_cont,         SHOW_FUNC},
1229
 
  {"Uptime_since_flush_status",(char*) &show_flushstatustime_cont,   SHOW_FUNC},
 
1490
  {"update_multi",         (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_UPDATE_MULTI]), SHOW_LONG_STATUS},
1230
1491
  {NULL, NULL, SHOW_LONGLONG}
1231
1492
};
1232
1493
 
1249
1510
    return 1;
1250
1511
  drizzle_init_variables();
1251
1512
 
 
1513
#ifdef HAVE_TZNAME
1252
1514
  {
1253
1515
    struct tm tm_tmp;
1254
1516
    localtime_r(&server_start_time,&tm_tmp);
1256
1518
            sizeof(system_time_zone)-1);
1257
1519
 
1258
1520
 }
 
1521
#endif
1259
1522
  /*
1260
1523
    We set SYSTEM time zone as reasonable default and
1261
1524
    also for failure of my_tz_init() and bootstrap mode.
1269
1532
    strncpy(glob_hostname, STRING_WITH_LEN("localhost"));
1270
1533
      errmsg_printf(ERRMSG_LVL_WARN, _("gethostname failed, using '%s' as hostname"),
1271
1534
                      glob_hostname);
1272
 
    strncpy(pidfile_name, STRING_WITH_LEN("drizzle"));
 
1535
    strncpy(pidfile_name, STRING_WITH_LEN("mysql"));
1273
1536
  }
1274
1537
  else
1275
1538
    strncpy(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
1288
1551
  defaults_argv=argv;
1289
1552
  defaults_argc=argc;
1290
1553
  get_options(&defaults_argc, defaults_argv);
1291
 
 
1292
 
  current_pid= getpid();                /* Save for later ref */
1293
 
  init_time();                          /* Init time-functions (read zone) */
1294
 
 
 
1554
  set_server_version();
 
1555
 
 
1556
 
 
1557
  /* connections and databases needs lots of files */
 
1558
  (void) my_set_max_open_files(0xFFFFFFFF);
 
1559
 
 
1560
  unireg_init(); /* Set up extern variabels */
1295
1561
  if (init_errmessage())        /* Read error messages from file */
1296
1562
    return 1;
1297
1563
  if (item_create_init())
1301
1567
  /* Creates static regex matching for temporal values */
1302
1568
  if (! init_temporal_formats())
1303
1569
    return 1;
1304
 
 
1305
 
  if (!(default_charset_info=
1306
 
        get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
 
1570
  /*
 
1571
    Process a comma-separated character set list and choose
 
1572
    the first available character set. This is mostly for
 
1573
    test purposes, to be able to start "mysqld" even if
 
1574
    the requested character set is not available (see bug#18743).
 
1575
  */
 
1576
  for (;;)
1307
1577
  {
1308
 
    return 1;                           // Eof of the list
 
1578
    char *next_character_set_name= strchr(default_character_set_name, ',');
 
1579
    if (next_character_set_name)
 
1580
      *next_character_set_name++= '\0';
 
1581
    if (!(default_charset_info=
 
1582
          get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
 
1583
    {
 
1584
      if (next_character_set_name)
 
1585
      {
 
1586
        default_character_set_name= next_character_set_name;
 
1587
        default_collation_name= 0;          // Ignore collation
 
1588
      }
 
1589
      else
 
1590
        return 1;                           // Eof of the list
 
1591
    }
 
1592
    else
 
1593
      break;
1309
1594
  }
1310
1595
 
1311
1596
  if (default_collation_name)
1327
1612
  }
1328
1613
  /* Set collactions that depends on the default collation */
1329
1614
  global_system_variables.collation_server=      default_charset_info;
 
1615
  global_system_variables.collation_database=    default_charset_info;
1330
1616
 
 
1617
  global_system_variables.optimizer_use_mrr= 1;
1331
1618
  global_system_variables.optimizer_switch= 0;
1332
1619
 
1333
1620
  if (!(character_set_filesystem=
1343
1630
  }
1344
1631
  global_system_variables.lc_time_names= my_default_lc_time_names;
1345
1632
 
1346
 
  /* Reset table_alias_charset */
 
1633
  sys_init_connect.value_length= 0;
 
1634
  if ((sys_init_connect.value= opt_init_connect))
 
1635
    sys_init_connect.value_length= strlen(opt_init_connect);
 
1636
  else
 
1637
    sys_init_connect.value=strdup("");
 
1638
  if (sys_init_connect.value == NULL)
 
1639
    return 1;
 
1640
 
 
1641
  if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
 
1642
    return 1;
 
1643
 
 
1644
  /* Reset table_alias_charset, now that lower_case_table_names is set. */
 
1645
  lower_case_table_names= 1; /* This we need to look at */
1347
1646
  table_alias_charset= files_charset_info;
1348
1647
 
1349
1648
  return 0;
1352
1651
 
1353
1652
static int init_thread_environment()
1354
1653
{
1355
 
  (void) pthread_mutex_init(&LOCK_create_db, NULL);
 
1654
  (void) pthread_mutex_init(&LOCK_drizzleclient_create_db,MY_MUTEX_INIT_SLOW);
 
1655
  (void) pthread_mutex_init(&LOCK_lock_db,MY_MUTEX_INIT_SLOW);
1356
1656
  (void) pthread_mutex_init(&LOCK_open, NULL);
1357
1657
  (void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
1358
1658
  (void) pthread_mutex_init(&LOCK_status,MY_MUTEX_INIT_FAST);
1359
1659
  (void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
1360
1660
  (void) pthread_rwlock_init(&LOCK_system_variables_hash, NULL);
1361
1661
  (void) pthread_mutex_init(&LOCK_global_read_lock, MY_MUTEX_INIT_FAST);
 
1662
  (void) pthread_rwlock_init(&LOCK_sys_init_connect, NULL);
1362
1663
  (void) pthread_cond_init(&COND_thread_count,NULL);
1363
 
  (void) pthread_cond_init(&COND_server_end,NULL);
1364
1664
  (void) pthread_cond_init(&COND_refresh,NULL);
1365
1665
  (void) pthread_cond_init(&COND_global_read_lock,NULL);
1366
1666
 
 
1667
  /* Parameter for threads created for connections */
 
1668
  (void) pthread_attr_init(&connection_attrib);
 
1669
  (void) pthread_attr_setdetachstate(&connection_attrib,
 
1670
                                     PTHREAD_CREATE_DETACHED);
 
1671
  pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM);
 
1672
  {
 
1673
    struct sched_param tmp_sched_param;
 
1674
 
 
1675
    memset(&tmp_sched_param, 0, sizeof(tmp_sched_param));
 
1676
    tmp_sched_param.sched_priority= WAIT_PRIOR;
 
1677
    (void)pthread_attr_setschedparam(&connection_attrib, &tmp_sched_param);
 
1678
  }
 
1679
 
1367
1680
  if (pthread_key_create(&THR_Session,NULL) ||
1368
1681
      pthread_key_create(&THR_Mem_root,NULL))
1369
1682
  {
1374
1687
}
1375
1688
 
1376
1689
 
1377
 
static int init_server_components(plugin::Registry &plugins)
 
1690
static int init_server_components()
1378
1691
{
1379
1692
  /*
1380
1693
    We need to call each of these following functions to ensure that
1381
1694
    all things are initialized so that unireg_abort() doesn't fail
1382
1695
  */
1383
 
  if (table_cache_init())
 
1696
  if (table_cache_init() | table_def_init())
1384
1697
    unireg_abort(1);
1385
 
  TableShare::cacheStart();
1386
1698
 
 
1699
  drizzleclient_randominit(&sql_rand,
 
1700
                           (uint64_t) server_start_time,
 
1701
                           (uint64_t) server_start_time/2);
1387
1702
  setup_fpu();
1388
1703
  init_thr_lock();
1389
1704
 
1395
1710
    unireg_abort(1);
1396
1711
  }
1397
1712
 
 
1713
  /* call ha_init_key_cache() on all key caches to init them */
 
1714
  process_key_caches(&ha_init_key_cache);
 
1715
 
1398
1716
  /* Allow storage engine to give real error messages */
1399
1717
  if (ha_init_errors())
1400
1718
    return(1);
1401
1719
 
1402
 
  if (plugin_init(plugins, &defaults_argc, defaults_argv,
1403
 
                  ((opt_help) ? PLUGIN_INIT_SKIP_INITIALIZATION : 0)))
 
1720
  if (plugin_init(&defaults_argc, defaults_argv,
 
1721
                  (opt_noacl ? PLUGIN_INIT_SKIP_PLUGIN_TABLE : 0) |
 
1722
                  (opt_help ? PLUGIN_INIT_SKIP_INITIALIZATION : 0)))
1404
1723
  {
1405
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize plugins."));
 
1724
      errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize plugins."));
1406
1725
    unireg_abort(1);
1407
1726
  }
1408
1727
 
1409
 
  if (opt_help || opt_help_extended)
 
1728
  if (opt_help)
1410
1729
    unireg_abort(0);
1411
1730
 
1412
1731
  /* we do want to exit if there are any other unknown options */
1440
1759
    }
1441
1760
  }
1442
1761
 
1443
 
  string scheduler_name;
1444
 
  if (opt_scheduler)
1445
 
  {
1446
 
    scheduler_name= opt_scheduler;
1447
 
  }
1448
 
  else
1449
 
  {
1450
 
    scheduler_name= opt_scheduler_default;
1451
 
  }
1452
 
 
1453
 
  if (plugin::Scheduler::setPlugin(scheduler_name))
1454
 
  {
1455
 
      errmsg_printf(ERRMSG_LVL_ERROR,
1456
 
                   _("No scheduler found, cannot continue!\n"));
1457
 
      unireg_abort(1);
1458
 
  }
1459
 
 
1460
1762
  /* We have to initialize the storage engines before CSV logging */
1461
1763
  if (ha_init())
1462
1764
  {
1465
1767
  }
1466
1768
 
1467
1769
  /*
1468
 
    This is entirely for legacy. We will create a new "disk based" engine and a
1469
 
    "memory" engine which will be configurable longterm.
1470
 
  */
1471
 
  const std::string myisam_engine_name("MyISAM");
1472
 
  const std::string heap_engine_name("MEMORY");
1473
 
  myisam_engine= plugin::StorageEngine::findByName(myisam_engine_name);
1474
 
  heap_engine= plugin::StorageEngine::findByName(heap_engine_name);
1475
 
 
1476
 
  /*
1477
1770
    Check that the default storage engine is actually available.
1478
1771
  */
1479
1772
  if (default_storage_engine_str)
1480
1773
  {
1481
 
    const std::string name(default_storage_engine_str);
1482
 
    plugin::StorageEngine *engine;
 
1774
    LEX_STRING name= { default_storage_engine_str,
 
1775
                       strlen(default_storage_engine_str) };
 
1776
    plugin_ref plugin;
 
1777
    handlerton *hton;
1483
1778
 
1484
 
    engine= plugin::StorageEngine::findByName(name);
1485
 
    if (engine == NULL)
1486
 
    {
1487
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown/unsupported table type: %s"),
1488
 
                    default_storage_engine_str);
1489
 
      unireg_abort(1);
1490
 
    }
1491
 
    if (!engine->is_enabled())
1492
 
    {
1493
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Default storage engine (%s) is not available"),
1494
 
                    default_storage_engine_str);
1495
 
      unireg_abort(1);
1496
 
      //assert(global_system_variables.storage_engine);
 
1779
    if ((plugin= ha_resolve_by_name(0, &name)))
 
1780
    {
 
1781
      hton= plugin_data(plugin,handlerton *);
 
1782
    }
 
1783
    else
 
1784
    {
 
1785
          errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown/unsupported table type: %s"),
 
1786
                      default_storage_engine_str);
 
1787
      unireg_abort(1);
 
1788
    }
 
1789
    if (!ha_storage_engine_is_enabled(hton))
 
1790
    {
 
1791
          errmsg_printf(ERRMSG_LVL_ERROR, _("Default storage engine (%s) is not available"),
 
1792
                      default_storage_engine_str);
 
1793
      unireg_abort(1);
 
1794
      assert(global_system_variables.table_plugin);
1497
1795
    }
1498
1796
    else
1499
1797
    {
1500
1798
      /*
1501
 
        Need to unlock as global_system_variables.storage_engine
 
1799
        Need to unlock as global_system_variables.table_plugin
1502
1800
        was acquired during plugin_init()
1503
1801
      */
1504
 
      global_system_variables.storage_engine= engine;
 
1802
      plugin_unlock(0, global_system_variables.table_plugin);
 
1803
      global_system_variables.table_plugin= plugin;
1505
1804
    }
1506
1805
  }
1507
1806
 
1508
 
  if (plugin::StorageEngine::recover(0))
 
1807
  if (ha_recover(0))
1509
1808
  {
1510
1809
    unireg_abort(1);
1511
1810
  }
1546
1845
  textdomain("drizzle");
1547
1846
#endif
1548
1847
 
1549
 
  plugin::Registry &plugins= plugin::Registry::singleton();
1550
 
  plugin::Client *client;
1551
 
  Session *session;
1552
 
 
1553
1848
  MY_INIT(argv[0]);             // init my_sys library & pthreads
1554
1849
  /* nothing should come before this line ^^^ */
1555
1850
 
1560
1855
  thr_kill_signal= SIGINT;
1561
1856
#endif
1562
1857
 
 
1858
#ifdef _CUSTOMSTARTUPCONFIG_
 
1859
  if (_cust_check_startup())
 
1860
  {
 
1861
    / * _cust_check_startup will report startup failure error * /
 
1862
    exit(1);
 
1863
  }
 
1864
#endif
 
1865
 
1563
1866
  if (init_common_variables(DRIZZLE_CONFIG_NAME,
1564
1867
                            argc, argv, load_default_groups))
1565
1868
    unireg_abort(1);                            // Will do exit
1566
1869
 
1567
1870
  init_signals();
1568
1871
 
 
1872
  pthread_attr_setstacksize(&connection_attrib, my_thread_stack_size);
 
1873
 
 
1874
#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
 
1875
  {
 
1876
    /* Retrieve used stack size;  Needed for checking stack overflows */
 
1877
    size_t stack_size= 0;
 
1878
    pthread_attr_getstacksize(&connection_attrib, &stack_size);
 
1879
    /* We must check if stack_size = 0 as Solaris 2.9 can return 0 here */
 
1880
    if (stack_size && stack_size < my_thread_stack_size)
 
1881
    {
 
1882
      if (global_system_variables.log_warnings)
 
1883
      {
 
1884
            errmsg_printf(ERRMSG_LVL_WARN, _("Asked for %"PRIu64" thread stack, "
 
1885
                            "but got %"PRIu64),
 
1886
                          (uint64_t)my_thread_stack_size,
 
1887
                          (uint64_t)stack_size);
 
1888
      }
 
1889
      my_thread_stack_size= stack_size;
 
1890
    }
 
1891
  }
 
1892
#endif
1569
1893
 
1570
1894
  select_thread=pthread_self();
1571
1895
  select_thread_in_use=1;
1572
1896
 
 
1897
  /*
 
1898
    We have enough space for fiddling with the argv, continue
 
1899
  */
 
1900
  check_data_home(drizzle_real_data_home);
1573
1901
  if (chdir(drizzle_real_data_home) && !opt_help)
1574
 
    unireg_abort(1);
 
1902
    unireg_abort(1);                            /* purecov: inspected */
1575
1903
  drizzle_data_home= drizzle_data_home_buff;
1576
1904
  drizzle_data_home[0]=FN_CURLIB;               // all paths are relative from here
1577
1905
  drizzle_data_home[1]=0;
1592
1920
    server_id= 1;
1593
1921
  }
1594
1922
 
1595
 
  if (init_server_components(plugins))
1596
 
    unireg_abort(1);
1597
 
 
1598
 
  if (plugin::Listen::setup())
1599
 
    unireg_abort(1);
 
1923
  if (init_server_components())
 
1924
    unireg_abort(1);
 
1925
 
 
1926
  network_init();
 
1927
 
 
1928
  safe_read_error_hook= safe_read_error_impl; 
1600
1929
 
1601
1930
  /*
1602
1931
    init signals & alarm
1604
1933
  */
1605
1934
  error_handler_hook= my_message_sql;
1606
1935
 
1607
 
  if (drizzle_rm_tmp_tables() ||
1608
 
      my_tz_init((Session *)0, default_tz_name))
 
1936
  if (drizzle_rm_tmp_tables() || my_tz_init((Session *)0, default_tz_name))
1609
1937
  {
1610
 
    abort_loop= true;
 
1938
    abort_loop=1;
1611
1939
    select_thread_in_use=0;
1612
1940
    (void) pthread_kill(signal_thread, SIGTERM);
1613
1941
 
1614
 
    (void) unlink(pidfile_name);        // Not needed anymore
 
1942
    (void) my_delete(pidfile_name,MYF(MY_WME)); // Not needed anymore
1615
1943
 
1616
1944
    exit(1);
1617
1945
  }
1618
1946
 
1619
1947
  init_status_vars();
1620
 
 
1621
 
  errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)), my_progname,
1622
 
                PANDORA_RELEASE_VERSION, COMPILATION_COMMENT);
1623
 
 
1624
 
 
1625
 
  /* Listen for new connections and start new session for each connection
1626
 
     accepted. The listen.getClient() method will return NULL when the server
1627
 
     should be shutdown. */
1628
 
  while ((client= plugin::Listen::getClient()) != NULL)
1629
 
  {
1630
 
    if (!(session= new Session(client)))
1631
 
    {
1632
 
      delete client;
1633
 
      continue;
1634
 
    }
1635
 
 
1636
 
    /* If we error on creation we drop the connection and delete the session. */
1637
 
    if (session->schedule())
1638
 
      unlink_session(session);
1639
 
  }
1640
 
 
 
1948
  /*
 
1949
    init_slave() must be called after the thread keys are created.
 
1950
    Some parts of the code (e.g. SHOW STATUS LIKE 'slave_running' and other
 
1951
    places) assume that active_mi != 0, so let's fail if it's 0 (out of
 
1952
    memory); a message has already been printed.
 
1953
  */
 
1954
 
 
1955
  errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)),my_progname,server_version,
 
1956
                        "", drizzled_port, COMPILATION_COMMENT);
 
1957
 
 
1958
 
 
1959
  handle_connections_sockets();
1641
1960
  /* (void) pthread_attr_destroy(&connection_attrib); */
1642
1961
 
1643
1962
 
1649
1968
  /* Wait until cleanup is done */
1650
1969
  (void) pthread_mutex_lock(&LOCK_thread_count);
1651
1970
  while (!ready_to_exit)
1652
 
    pthread_cond_wait(&COND_server_end,&LOCK_thread_count);
 
1971
    pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
1653
1972
  (void) pthread_mutex_unlock(&LOCK_thread_count);
1654
1973
 
1655
1974
  clean_up(1);
1656
 
  plugin::Registry::shutdown();
1657
 
  clean_up_mutexes();
1658
 
  my_end();
1659
 
  return 0;
 
1975
  drizzled_exit(0);
 
1976
}
 
1977
 
 
1978
 
 
1979
/**
 
1980
  Create new thread to handle incoming connection.
 
1981
 
 
1982
    This function will create new thread to handle the incoming
 
1983
    connection.  If there are idle cached threads one will be used.
 
1984
    'session' will be pushed into 'threads'.
 
1985
 
 
1986
    In single-threaded mode (\#define ONE_THREAD) connection will be
 
1987
    handled inside this function.
 
1988
 
 
1989
  @param[in,out] session    Thread handle of future thread.
 
1990
*/
 
1991
 
 
1992
static void create_new_thread(Session *session)
 
1993
{
 
1994
  pthread_mutex_lock(&LOCK_thread_count);
 
1995
 
 
1996
  ++connection_count;
 
1997
 
 
1998
  if (connection_count > max_used_connections)
 
1999
    max_used_connections= connection_count;
 
2000
 
 
2001
  /*
 
2002
    The initialization of thread_id is done in create_embedded_session() for
 
2003
    the embedded library.
 
2004
    TODO: refactor this to avoid code duplication there
 
2005
  */
 
2006
  session->thread_id= session->variables.pseudo_thread_id= thread_id++;
 
2007
 
 
2008
  thread_count++;
 
2009
 
 
2010
  /* 
 
2011
    If we error on creation we drop the connection and delete the session.
 
2012
  */
 
2013
  if (thread_scheduler.add_connection(session))
 
2014
  {
 
2015
    char error_message_buff[DRIZZLE_ERRMSG_SIZE];
 
2016
 
 
2017
    session->killed= Session::KILL_CONNECTION;                        // Safety
 
2018
 
 
2019
    statistic_increment(aborted_connects, &LOCK_status);
 
2020
 
 
2021
    /* Can't use my_error() since store_globals has not been called. */
 
2022
    snprintf(error_message_buff, sizeof(error_message_buff), ER(ER_CANT_CREATE_THREAD), 1); /* TODO replace will better error message */
 
2023
    net_send_error(session, ER_CANT_CREATE_THREAD, error_message_buff);
 
2024
    (void) pthread_mutex_lock(&LOCK_thread_count);
 
2025
    --connection_count;
 
2026
    session->close_connection(0, 0);
 
2027
    delete session;
 
2028
    (void) pthread_mutex_unlock(&LOCK_thread_count);
 
2029
  }
 
2030
}
 
2031
 
 
2032
 
 
2033
        /* Handle new connections and spawn new process to handle them */
 
2034
 
 
2035
void handle_connections_sockets()
 
2036
{
 
2037
  int x;
 
2038
  int sock,new_sock;
 
2039
  uint32_t error_count=0;
 
2040
  Session *session;
 
2041
  struct sockaddr_storage cAddr;
 
2042
 
 
2043
  while (!abort_loop)
 
2044
  {
 
2045
    int number_of;
 
2046
 
 
2047
    if ((number_of= poll(fds, pollfd_count, -1)) == -1)
 
2048
    {
 
2049
      if (errno != EINTR)
 
2050
      {
 
2051
        if (!select_errors++ && !abort_loop)    /* purecov: inspected */
 
2052
                errmsg_printf(ERRMSG_LVL_ERROR, _("drizzled: Got error %d from select"),
 
2053
                          errno); /* purecov: inspected */
 
2054
      }
 
2055
      continue;
 
2056
    }
 
2057
    if (number_of == 0)
 
2058
      continue;
 
2059
 
 
2060
#ifdef FIXME_IF_WE_WERE_KEEPING_THIS
 
2061
    assert(number_of > 1); /* Not handling this at the moment */
 
2062
#endif
 
2063
 
 
2064
    if (abort_loop)
 
2065
    {
 
2066
      break;
 
2067
    }
 
2068
 
 
2069
    for (x= 0, sock= -1; x < pollfd_count; x++)
 
2070
    {
 
2071
      if (fds[x].revents == POLLIN)
 
2072
      {
 
2073
        sock= fds[x].fd;
 
2074
        break;
 
2075
      }
 
2076
    }
 
2077
    assert(sock != -1);
 
2078
 
 
2079
    for (uint32_t retry=0; retry < MAX_ACCEPT_RETRY; retry++)
 
2080
    {
 
2081
      SOCKET_SIZE_TYPE length= sizeof(struct sockaddr_storage);
 
2082
      new_sock= accept(sock, (struct sockaddr *)(&cAddr),
 
2083
                       &length);
 
2084
      if (new_sock != -1 || (errno != EINTR && errno != EAGAIN))
 
2085
        break;
 
2086
    }
 
2087
 
 
2088
 
 
2089
    if (new_sock == -1)
 
2090
    {
 
2091
      if ((error_count++ & 255) == 0)           // This can happen often
 
2092
        sql_perror("Error in accept");
 
2093
      if (errno == ENFILE || errno == EMFILE)
 
2094
        sleep(1);                               // Give other threads some time
 
2095
      continue;
 
2096
    }
 
2097
 
 
2098
    {
 
2099
      SOCKET_SIZE_TYPE dummyLen;
 
2100
      struct sockaddr_storage dummy;
 
2101
      dummyLen = sizeof(dummy);
 
2102
      if (  getsockname(new_sock,(struct sockaddr *)&dummy,
 
2103
                        (socklen_t *)&dummyLen) < 0  )
 
2104
      {
 
2105
        sql_perror("Error on new connection socket");
 
2106
        (void) shutdown(new_sock, SHUT_RDWR);
 
2107
        (void) close(new_sock);
 
2108
        continue;
 
2109
      }
 
2110
      dummyLen = sizeof(dummy);
 
2111
      if ( getpeername(new_sock, (struct sockaddr *)&dummy,
 
2112
                       (socklen_t *)&dummyLen) < 0)
 
2113
      {
 
2114
        sql_perror("Error on new connection socket");
 
2115
        (void) shutdown(new_sock, SHUT_RDWR);
 
2116
        (void) close(new_sock);
 
2117
         continue;
 
2118
      }
 
2119
    }
 
2120
 
 
2121
    /*
 
2122
    ** Don't allow too many connections
 
2123
    */
 
2124
 
 
2125
    if (!(session= new Session))
 
2126
    {
 
2127
      (void) shutdown(new_sock, SHUT_RDWR);
 
2128
      close(new_sock);
 
2129
      continue;
 
2130
    }
 
2131
    if (drizzleclient_net_init_sock(&session->net, new_sock, sock == 0))
 
2132
    {
 
2133
      delete session;
 
2134
      continue;
 
2135
    }
 
2136
 
 
2137
    create_new_thread(session);
 
2138
  }
1660
2139
}
1661
2140
 
1662
2141
 
1666
2145
 
1667
2146
enum options_drizzled
1668
2147
{
1669
 
  OPT_SOCKET=256,
1670
 
  OPT_BIND_ADDRESS,            
1671
 
  OPT_PID_FILE,
 
2148
  OPT_ISAM_LOG=256,
 
2149
  OPT_SKIP_NEW,
 
2150
  OPT_SOCKET,
 
2151
  OPT_BIN_LOG,
 
2152
  OPT_BIND_ADDRESS,            OPT_PID_FILE,
 
2153
  OPT_SKIP_PRIOR,
 
2154
  OPT_FLUSH,                   OPT_SAFE,
1672
2155
  OPT_STORAGE_ENGINE,          
1673
2156
  OPT_INIT_FILE,
 
2157
  OPT_DELAY_KEY_WRITE_ALL,
 
2158
  OPT_DELAY_KEY_WRITE,
1674
2159
  OPT_WANT_CORE,
1675
2160
  OPT_MEMLOCK,
 
2161
  OPT_MYISAM_RECOVER,
1676
2162
  OPT_SERVER_ID,
1677
2163
  OPT_TC_HEURISTIC_RECOVER,
 
2164
  OPT_ENGINE_CONDITION_PUSHDOWN,
1678
2165
  OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
1679
2166
  OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
1680
2167
  OPT_DO_PSTACK,
1681
2168
  OPT_LOCAL_INFILE,
1682
2169
  OPT_BACK_LOG,
1683
 
  OPT_JOIN_BUFF_SIZE,
 
2170
  OPT_CONNECT_TIMEOUT,
 
2171
  OPT_FLUSH_TIME,
 
2172
  OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE,
1684
2173
  OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE,
1685
2174
  OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD,
1686
 
  OPT_MAX_ALLOWED_PACKET,
 
2175
  OPT_LONG_QUERY_TIME,
 
2176
  OPT_LOWER_CASE_TABLE_NAMES, OPT_MAX_ALLOWED_PACKET,
1687
2177
  OPT_MAX_CONNECT_ERRORS,
1688
2178
  OPT_MAX_HEP_TABLE_SIZE,
1689
2179
  OPT_MAX_JOIN_SIZE,
1690
 
  OPT_MAX_SORT_LENGTH,
 
2180
  OPT_MAX_RELAY_LOG_SIZE, OPT_MAX_SORT_LENGTH,
1691
2181
  OPT_MAX_SEEKS_FOR_KEY, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS,
1692
2182
  OPT_MAX_LENGTH_FOR_SORT_DATA,
1693
2183
  OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE,
1695
2185
  OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
1696
2186
  OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
1697
2187
  OPT_MYISAM_USE_MMAP, OPT_MYISAM_REPAIR_THREADS,
1698
 
  OPT_NET_BUFFER_LENGTH,
 
2188
  OPT_MYISAM_STATS_METHOD,
 
2189
  OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT,
 
2190
  OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT,
1699
2191
  OPT_PRELOAD_BUFFER_SIZE,
1700
2192
  OPT_RECORD_BUFFER,
1701
2193
  OPT_RECORD_RND_BUFFER, OPT_DIV_PRECINCREMENT,
1703
2195
  OPT_SORT_BUFFER, OPT_TABLE_OPEN_CACHE, OPT_TABLE_DEF_CACHE,
1704
2196
  OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK,
1705
2197
  OPT_WAIT_TIMEOUT,
 
2198
  OPT_DEFAULT_WEEK_FORMAT,
1706
2199
  OPT_RANGE_ALLOC_BLOCK_SIZE,
1707
2200
  OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE,
1708
2201
  OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE,
1712
2205
  OPT_CHARACTER_SET_FILESYSTEM,
1713
2206
  OPT_LC_TIME_NAMES,
1714
2207
  OPT_INIT_CONNECT,
 
2208
  OPT_DATE_FORMAT,
 
2209
  OPT_TIME_FORMAT,
 
2210
  OPT_DATETIME_FORMAT,
1715
2211
  OPT_DEFAULT_TIME_ZONE,
 
2212
  OPT_SYSDATE_IS_NOW,
1716
2213
  OPT_OPTIMIZER_SEARCH_DEPTH,
1717
2214
  OPT_SCHEDULER,
1718
 
  OPT_PROTOCOL,
1719
2215
  OPT_OPTIMIZER_PRUNE_LEVEL,
 
2216
  OPT_UPDATABLE_VIEWS_WITH_LIMIT,
1720
2217
  OPT_AUTO_INCREMENT, OPT_AUTO_INCREMENT_OFFSET,
1721
2218
  OPT_ENABLE_LARGE_PAGES,
1722
2219
  OPT_TIMED_MUTEXES,
1723
2220
  OPT_TABLE_LOCK_WAIT_TIMEOUT,
1724
 
  OPT_PLUGIN_ADD,
1725
2221
  OPT_PLUGIN_LOAD,
1726
2222
  OPT_PLUGIN_DIR,
1727
2223
  OPT_PORT_OPEN_TIMEOUT,
 
2224
  OPT_KEEP_FILES_ON_CREATE,
1728
2225
  OPT_SECURE_FILE_PRIV,
1729
 
  OPT_MIN_EXAMINED_ROW_LIMIT
 
2226
  OPT_MIN_EXAMINED_ROW_LIMIT,
 
2227
  OPT_OLD_MODE
1730
2228
};
1731
2229
 
1732
2230
 
 
2231
#define LONG_TIMEOUT ((uint32_t) 3600L*24L*365L)
 
2232
 
1733
2233
struct my_option my_long_options[] =
1734
2234
{
1735
2235
  {"help", '?', N_("Display this help and exit."),
1736
2236
   (char**) &opt_help, (char**) &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
1737
2237
   0, 0},
1738
 
  {"help-extended", '?',
1739
 
   N_("Display this help and exit after initializing plugins."),
1740
 
   (char**) &opt_help_extended, (char**) &opt_help_extended,
1741
 
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1742
2238
  {"auto-increment-increment", OPT_AUTO_INCREMENT,
1743
2239
   N_("Auto-increment columns are incremented by this"),
1744
2240
   (char**) &global_system_variables.auto_increment_increment,
1755
2251
      "relative to this."),
1756
2252
   (char**) &drizzle_home_ptr, (char**) &drizzle_home_ptr, 0, GET_STR, REQUIRED_ARG,
1757
2253
   0, 0, 0, 0, 0, 0},
 
2254
  {"bind-address", OPT_BIND_ADDRESS, N_("IP address to bind to."),
 
2255
   (char**) &my_bind_addr_str, (char**) &my_bind_addr_str, 0, GET_STR,
 
2256
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
2257
  {"character-set-filesystem", OPT_CHARACTER_SET_FILESYSTEM,
 
2258
   N_("Set the filesystem character set."),
 
2259
   (char**) &character_set_filesystem_name,
 
2260
   (char**) &character_set_filesystem_name,
 
2261
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
 
2262
  {"character-set-server", 'C',
 
2263
   N_("Set the default character set."),
 
2264
   (char**) &default_character_set_name, (char**) &default_character_set_name,
 
2265
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
1758
2266
  {"chroot", 'r',
1759
2267
   N_("Chroot drizzled daemon during startup."),
1760
2268
   (char**) &drizzled_chroot, (char**) &drizzled_chroot, 0, GET_STR, REQUIRED_ARG,
1784
2292
   N_("Set the default time zone."),
1785
2293
   (char**) &default_tz_name, (char**) &default_tz_name,
1786
2294
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
 
2295
  {"delay-key-write", OPT_DELAY_KEY_WRITE,
 
2296
   N_("Type of DELAY_KEY_WRITE."),
 
2297
   0,0,0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
1787
2298
#ifdef HAVE_STACK_TRACE_ON_SEGV
1788
2299
  {"enable-pstack", OPT_DO_PSTACK,
1789
2300
   N_("Print a symbolic stack trace on failure."),
1790
2301
   (char**) &opt_do_pstack, (char**) &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0,
1791
2302
   0, 0, 0, 0},
1792
2303
#endif /* HAVE_STACK_TRACE_ON_SEGV */
 
2304
  {"engine-condition-pushdown",
 
2305
   OPT_ENGINE_CONDITION_PUSHDOWN,
 
2306
   N_("Push supported query conditions to the storage engine."),
 
2307
   (char**) &global_system_variables.engine_condition_pushdown,
 
2308
   (char**) &global_system_variables.engine_condition_pushdown,
 
2309
   0, GET_BOOL, NO_ARG, false, 0, 0, 0, 0, 0},
1793
2310
  /* See how it's handled in get_one_option() */
1794
2311
  {"exit-info", 'T',
1795
2312
   N_("Used for debugging;  Use at your own risk!"),
1796
2313
   0, 0, 0, GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
2314
  {"flush", OPT_FLUSH,
 
2315
   N_("Flush tables to disk between SQL commands."),
 
2316
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1797
2317
  /* We must always support the next option to make scripts like mysqltest
1798
2318
     easier to do */
1799
2319
  {"gdb", OPT_DEBUGGING,
1800
2320
   N_("Set up signals usable for debugging"),
1801
2321
   (char**) &opt_debugging, (char**) &opt_debugging,
1802
2322
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
2323
  {"init-connect", OPT_INIT_CONNECT,
 
2324
   N_("Command(s) that are executed for each new connection"),
 
2325
   (char**) &opt_init_connect, (char**) &opt_init_connect, 0, GET_STR_ALLOC,
 
2326
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
2327
  {"init-file", OPT_INIT_FILE,
 
2328
   N_("Read SQL commands from this file at startup."),
 
2329
   (char**) &opt_init_file, (char**) &opt_init_file, 0, GET_STR, REQUIRED_ARG,
 
2330
   0, 0, 0, 0, 0, 0},
1803
2331
  {"language", 'L',
1804
2332
   N_("(IGNORED)"),
1805
2333
   (char**) &language_ptr, (char**) &language_ptr, 0, GET_STR, REQUIRED_ARG,
1809
2337
   (char**) &lc_time_names_name,
1810
2338
   (char**) &lc_time_names_name,
1811
2339
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
 
2340
  {"local-infile", OPT_LOCAL_INFILE,
 
2341
   N_("Enable/disable LOAD DATA LOCAL INFILE (takes values 1|0)."),
 
2342
   (char**) &opt_local_infile,
 
2343
   (char**) &opt_local_infile, 0, GET_BOOL, OPT_ARG,
 
2344
   1, 0, 0, 0, 0, 0},
 
2345
  {"log", 'l',
 
2346
   N_("Log connections and queries to file."),
 
2347
   (char**) &opt_logname,
 
2348
   (char**) &opt_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
2349
  {"log-isam", OPT_ISAM_LOG,
 
2350
   N_("Log all MyISAM changes to file."),
 
2351
   (char**) &myisam_log_filename, (char**) &myisam_log_filename, 0, GET_STR,
 
2352
   OPT_ARG, 0, 0, 0, 0, 0, 0},
1812
2353
  {"log-warnings", 'W',
1813
2354
   N_("Log some not critical warnings to the log file."),
1814
2355
   (char**) &global_system_variables.log_warnings,
1815
 
   (char**) &max_system_variables.log_warnings, 0, GET_BOOL, OPT_ARG, 1, 0, 0,
 
2356
   (char**) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0,
1816
2357
   0, 0, 0},
1817
2358
  {"memlock", OPT_MEMLOCK,
1818
2359
   N_("Lock drizzled in memory."),
1819
2360
   (char**) &locked_in_memory,
1820
2361
   (char**) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
2362
  {"myisam-recover", OPT_MYISAM_RECOVER,
 
2363
   N_("Syntax: myisam-recover[=option[,option...]], where option can be "
 
2364
      "DEFAULT, BACKUP, FORCE or QUICK."),
 
2365
   (char**) &myisam_recover_options_str, (char**) &myisam_recover_options_str, 0,
 
2366
   GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
2367
  {"new", 'n',
 
2368
   N_("Use very new possible 'unsafe' functions."),
 
2369
   (char**) &global_system_variables.new_mode,
 
2370
   (char**) &max_system_variables.new_mode,
 
2371
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
2372
  {"old-alter-table", OPT_OLD_ALTER_TABLE,
 
2373
   N_("Use old, non-optimized alter table."),
 
2374
   (char**) &global_system_variables.old_alter_table,
 
2375
   (char**) &max_system_variables.old_alter_table, 0, GET_BOOL, NO_ARG,
 
2376
   0, 0, 0, 0, 0, 0},
1821
2377
  {"pid-file", OPT_PID_FILE,
1822
2378
   N_("Pid file used by safe_mysqld."),
1823
2379
   (char**) &pidfile_name_ptr, (char**) &pidfile_name_ptr, 0, GET_STR,
1824
2380
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
2381
  {"port", 'P',
 
2382
   N_("Port number to use for connection or 0 for default to, in "
 
2383
      "order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
 
2384
      "built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ")."),
 
2385
   (char**) &drizzled_port,
 
2386
   (char**) &drizzled_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1825
2387
  {"port-open-timeout", OPT_PORT_OPEN_TIMEOUT,
1826
2388
   N_("Maximum time in seconds to wait for the port to become free. "
1827
2389
      "(Default: no wait)"),
1828
 
   (char**) &drizzled_bind_timeout,
1829
 
   (char**) &drizzled_bind_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
2390
   (char**) &drizzled_port_timeout,
 
2391
   (char**) &drizzled_port_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
2392
  {"safe-mode", OPT_SAFE,
 
2393
   N_("Skip some optimize stages (for testing)."),
 
2394
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1830
2395
  {"secure-file-priv", OPT_SECURE_FILE_PRIV,
1831
2396
   N_("Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
1832
2397
      "within specified directory"),
1835
2400
  {"server-id", OPT_SERVER_ID,
1836
2401
   N_("Uniquely identifies the server instance in the community of "
1837
2402
      "replication partners."),
1838
 
   (char**) &server_id, (char**) &server_id, 0, GET_UINT32, REQUIRED_ARG, 0, 0, 0,
 
2403
   (char**) &server_id, (char**) &server_id, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 0,
1839
2404
   0, 0, 0},
 
2405
  {"skip-new", OPT_SKIP_NEW,
 
2406
   N_("Don't use new, possible wrong routines."),
 
2407
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1840
2408
  {"skip-stack-trace", OPT_SKIP_STACK_TRACE,
1841
2409
   N_("Don't print a stack trace on failure."),
1842
2410
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
1843
2411
   0, 0, 0, 0},
 
2412
  {"skip-thread-priority", OPT_SKIP_PRIOR,
 
2413
   N_("Don't give threads different priorities."),
 
2414
   0, 0, 0, GET_NO_ARG, NO_ARG,
 
2415
   DEFAULT_SKIP_THREAD_PRIORITY, 0, 0, 0, 0, 0},
1844
2416
  {"symbolic-links", 's',
1845
2417
   N_("Enable symbolic link support."),
1846
2418
   (char**) &my_use_symdir, (char**) &my_use_symdir, 0, GET_BOOL, NO_ARG,
1850
2422
     option if compiled with valgrind support.
1851
2423
   */
1852
2424
   IF_PURIFY(0,1), 0, 0, 0, 0, 0},
 
2425
  {"sysdate-is-now", OPT_SYSDATE_IS_NOW,
 
2426
   N_("Non-default option to alias SYSDATE() to NOW() to make it "
 
2427
      "safe-replicable."),
 
2428
   (char**) &global_system_variables.sysdate_is_now,
 
2429
   0, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
 
2430
  {"temp-pool", OPT_TEMP_POOL,
 
2431
   N_("Using this option will cause most temporary files created to use a "
 
2432
      "small set of names, rather than a unique name for each new file."),
 
2433
   (char**) &use_temp_pool, (char**) &use_temp_pool, 0, GET_BOOL, NO_ARG, 1,
 
2434
   0, 0, 0, 0, 0},
1853
2435
  {"timed_mutexes", OPT_TIMED_MUTEXES,
1854
2436
   N_("Specify whether to time mutexes (only InnoDB mutexes are currently "
1855
2437
      "supported)"),
1883
2465
    (char**) &global_system_variables.bulk_insert_buff_size,
1884
2466
    (char**) &max_system_variables.bulk_insert_buff_size,
1885
2467
    0, GET_ULL, REQUIRED_ARG, 8192*1024, 0, ULONG_MAX, 0, 1, 0},
 
2468
  { "connect_timeout", OPT_CONNECT_TIMEOUT,
 
2469
    N_("The number of seconds the drizzled server is waiting for a connect "
 
2470
       "packet before responding with 'Bad handshake'."),
 
2471
    (char**) &connect_timeout, (char**) &connect_timeout,
 
2472
    0, GET_ULONG, REQUIRED_ARG, CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1, 0 },
 
2473
  { "date_format", OPT_DATE_FORMAT,
 
2474
    N_("The DATE format (For future)."),
 
2475
    (char**) &opt_date_time_formats[DRIZZLE_TIMESTAMP_DATE],
 
2476
    (char**) &opt_date_time_formats[DRIZZLE_TIMESTAMP_DATE],
 
2477
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
2478
  { "datetime_format", OPT_DATETIME_FORMAT,
 
2479
    N_("The DATETIME/TIMESTAMP format (for future)."),
 
2480
    (char**) &opt_date_time_formats[DRIZZLE_TIMESTAMP_DATETIME],
 
2481
    (char**) &opt_date_time_formats[DRIZZLE_TIMESTAMP_DATETIME],
 
2482
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1886
2483
  { "div_precision_increment", OPT_DIV_PRECINCREMENT,
1887
2484
   N_("Precision of the result of '/' operator will be increased on that "
1888
2485
      "value."),
1892
2489
  { "group_concat_max_len", OPT_GROUP_CONCAT_MAX_LEN,
1893
2490
    N_("The maximum length of the result of function  group_concat."),
1894
2491
    (char**) &global_system_variables.group_concat_max_len,
1895
 
    (char**) &max_system_variables.group_concat_max_len, 0, GET_UINT64,
 
2492
    (char**) &max_system_variables.group_concat_max_len, 0, GET_ULONG,
1896
2493
    REQUIRED_ARG, 1024, 4, ULONG_MAX, 0, 1, 0},
 
2494
  { "interactive_timeout", OPT_INTERACTIVE_TIMEOUT,
 
2495
    N_("The number of seconds the server waits for activity on an interactive "
 
2496
       "connection before closing it."),
 
2497
   (char**) &global_system_variables.net_interactive_timeout,
 
2498
   (char**) &max_system_variables.net_interactive_timeout, 0,
 
2499
   GET_ULONG, REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
1897
2500
  { "join_buffer_size", OPT_JOIN_BUFF_SIZE,
1898
2501
    N_("The size of the buffer that is used for full joins."),
1899
2502
   (char**) &global_system_variables.join_buff_size,
1900
 
   (char**) &max_system_variables.join_buff_size, 0, GET_UINT64,
 
2503
   (char**) &max_system_variables.join_buff_size, 0, GET_ULONG,
1901
2504
   REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ULONG_MAX,
1902
2505
   MALLOC_OVERHEAD, IO_SIZE, 0},
 
2506
  {"keep_files_on_create", OPT_KEEP_FILES_ON_CREATE,
 
2507
   N_("Don't overwrite stale .MYD and .MYI even if no directory is specified."),
 
2508
   (char**) &global_system_variables.keep_files_on_create,
 
2509
   (char**) &max_system_variables.keep_files_on_create,
 
2510
   0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
1903
2511
  {"key_buffer_size", OPT_KEY_BUFFER_SIZE,
1904
2512
   N_("The size of the buffer used for index blocks for MyISAM tables. "
1905
2513
      "Increase this to get better index handling (for all reads and multiple "
1906
2514
      "writes) to as much as you can afford;"),
1907
2515
   (char**) &dflt_key_cache_var.param_buff_size,
1908
2516
   (char**) 0,
1909
 
   0, (GET_ULL),
 
2517
   0, (GET_ULL | GET_ASK_ADDR),
1910
2518
   REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, SIZE_T_MAX, MALLOC_OVERHEAD,
1911
2519
   IO_SIZE, 0},
1912
2520
  {"key_cache_age_threshold", OPT_KEY_CACHE_AGE_THRESHOLD,
1916
2524
      "total number of blocks in key cache"),
1917
2525
   (char**) &dflt_key_cache_var.param_age_threshold,
1918
2526
   (char**) 0,
1919
 
   0, (GET_UINT32), REQUIRED_ARG,
 
2527
   0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG,
1920
2528
   300, 100, ULONG_MAX, 0, 100, 0},
1921
2529
  {"key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE,
1922
2530
   N_("The default size of key cache blocks"),
1923
2531
   (char**) &dflt_key_cache_var.param_block_size,
1924
2532
   (char**) 0,
1925
 
   0, (GET_UINT32), REQUIRED_ARG,
 
2533
   0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG,
1926
2534
   KEY_CACHE_BLOCK_SIZE, 512, 1024 * 16, 0, 512, 0},
1927
2535
  {"key_cache_division_limit", OPT_KEY_CACHE_DIVISION_LIMIT,
1928
2536
   N_("The minimum percentage of warm blocks in key cache"),
1929
2537
   (char**) &dflt_key_cache_var.param_division_limit,
1930
2538
   (char**) 0,
1931
 
   0, (GET_UINT32) , REQUIRED_ARG, 100,
 
2539
   0, (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100,
1932
2540
   1, 100, 0, 1, 0},
1933
2541
  {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
1934
2542
   N_("Max packetlength to send/receive from to server."),
1935
2543
   (char**) &global_system_variables.max_allowed_packet,
1936
 
   (char**) &max_system_variables.max_allowed_packet, 0, GET_UINT32,
 
2544
   (char**) &max_system_variables.max_allowed_packet, 0, GET_ULONG,
1937
2545
   REQUIRED_ARG, 1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
1938
2546
  {"max_connect_errors", OPT_MAX_CONNECT_ERRORS,
1939
2547
   N_("If there is more than this number of interrupted connections from a "
1940
2548
      "host this host will be blocked from further connections."),
1941
 
   (char**) &max_connect_errors, (char**) &max_connect_errors, 0, GET_UINT64,
 
2549
   (char**) &max_connect_errors, (char**) &max_connect_errors, 0, GET_ULONG,
1942
2550
   REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ULONG_MAX, 0, 1, 0},
1943
2551
  {"max_error_count", OPT_MAX_ERROR_COUNT,
1944
2552
   N_("Max number of errors/warnings to store for a statement."),
1945
2553
   (char**) &global_system_variables.max_error_count,
1946
2554
   (char**) &max_system_variables.max_error_count,
1947
 
   0, GET_UINT64, REQUIRED_ARG, DEFAULT_ERROR_COUNT, 0, 65535, 0, 1, 0},
 
2555
   0, GET_ULONG, REQUIRED_ARG, DEFAULT_ERROR_COUNT, 0, 65535, 0, 1, 0},
1948
2556
  {"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
1949
2557
   N_("Don't allow creation of heap tables bigger than this."),
1950
2558
   (char**) &global_system_variables.max_heap_table_size,
1965
2573
  { "max_seeks_for_key", OPT_MAX_SEEKS_FOR_KEY,
1966
2574
    N_("Limit assumed max number of seeks when looking up rows based on a key"),
1967
2575
    (char**) &global_system_variables.max_seeks_for_key,
1968
 
    (char**) &max_system_variables.max_seeks_for_key, 0, GET_UINT64,
 
2576
    (char**) &max_system_variables.max_seeks_for_key, 0, GET_ULONG,
1969
2577
    REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0 },
1970
2578
  {"max_sort_length", OPT_MAX_SORT_LENGTH,
1971
2579
   N_("The number of bytes to use when sorting BLOB or TEXT values "
1972
2580
      "(only the first max_sort_length bytes of each value are used; the "
1973
2581
      "rest are ignored)."),
1974
2582
   (char**) &global_system_variables.max_sort_length,
1975
 
   (char**) &max_system_variables.max_sort_length, 0, GET_SIZE,
 
2583
   (char**) &max_system_variables.max_sort_length, 0, GET_UINT,
1976
2584
   REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
 
2585
  {"max_tmp_tables", OPT_MAX_TMP_TABLES,
 
2586
   N_("Maximum number of temporary tables a client can keep open at a time."),
 
2587
   (char**) &global_system_variables.max_tmp_tables,
 
2588
   (char**) &max_system_variables.max_tmp_tables, 0, GET_ULONG,
 
2589
   REQUIRED_ARG, 32, 1, ULONG_MAX, 0, 1, 0},
1977
2590
  {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
1978
2591
   N_("After this many write locks, allow some read locks to run in between."),
1979
2592
   (char**) &max_write_lock_count, (char**) &max_write_lock_count, 0, GET_ULL,
1984
2597
   (char**) &global_system_variables.min_examined_row_limit,
1985
2598
   (char**) &max_system_variables.min_examined_row_limit, 0, GET_ULL,
1986
2599
   REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1L, 0},
 
2600
  {"myisam_stats_method", OPT_MYISAM_STATS_METHOD,
 
2601
   N_("Specifies how MyISAM index statistics collection code should threat "
 
2602
      "NULLs. Possible values of name are 'nulls_unequal' "
 
2603
      "(default behavior), "
 
2604
      "'nulls_equal' (emulate MySQL 4.0 behavior), and 'nulls_ignored'."),
 
2605
   (char**) &myisam_stats_method_str, (char**) &myisam_stats_method_str, 0,
 
2606
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
2607
  {"net_buffer_length", OPT_NET_BUFFER_LENGTH,
 
2608
   N_("Buffer length for TCP/IP and socket communication."),
 
2609
   (char**) &global_system_variables.net_buffer_length,
 
2610
   (char**) &max_system_variables.net_buffer_length, 0, GET_ULONG,
 
2611
   REQUIRED_ARG, 16384, 1024, 1024*1024L, 0, 1024, 0},
 
2612
  {"net_read_timeout", OPT_NET_READ_TIMEOUT,
 
2613
   N_("Number of seconds to wait for more data from a connection before "
 
2614
      "aborting the read."),
 
2615
   (char**) &global_system_variables.net_read_timeout,
 
2616
   (char**) &max_system_variables.net_read_timeout, 0, GET_ULONG,
 
2617
   REQUIRED_ARG, NET_READ_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
 
2618
  {"net_retry_count", OPT_NET_RETRY_COUNT,
 
2619
   N_("If a read on a communication port is interrupted, retry this many "
 
2620
      "times before giving up."),
 
2621
   (char**) &global_system_variables.net_retry_count,
 
2622
   (char**) &max_system_variables.net_retry_count,0,
 
2623
   GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, ULONG_MAX, 0, 1, 0},
 
2624
  {"net_write_timeout", OPT_NET_WRITE_TIMEOUT,
 
2625
   N_("Number of seconds to wait for a block to be written to a connection "
 
2626
      "before aborting the write."),
 
2627
   (char**) &global_system_variables.net_write_timeout,
 
2628
   (char**) &max_system_variables.net_write_timeout, 0, GET_ULONG,
 
2629
   REQUIRED_ARG, NET_WRITE_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
 
2630
  { "old", OPT_OLD_MODE,
 
2631
    N_("Use compatible behavior."),
 
2632
    (char**) &global_system_variables.old_mode,
 
2633
    (char**) &max_system_variables.old_mode, 0, GET_BOOL, NO_ARG,
 
2634
    0, 0, 0, 0, 0, 0},
1987
2635
  {"optimizer_prune_level", OPT_OPTIMIZER_PRUNE_LEVEL,
1988
2636
    N_("Controls the heuristic(s) applied during query optimization to prune "
1989
2637
       "less-promising partial plans from the optimizer search space. Meaning: "
2003
2651
      "testing/comparison)."),
2004
2652
   (char**) &global_system_variables.optimizer_search_depth,
2005
2653
   (char**) &max_system_variables.optimizer_search_depth,
2006
 
   0, GET_UINT, OPT_ARG, 0, 0, MAX_TABLES+2, 0, 1, 0},
 
2654
   0, GET_UINT, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0},
2007
2655
  {"plugin_dir", OPT_PLUGIN_DIR,
2008
2656
   N_("Directory for plugins."),
2009
2657
   (char**) &opt_plugin_dir_ptr, (char**) &opt_plugin_dir_ptr, 0,
2010
2658
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
2011
 
  {"plugin_add", OPT_PLUGIN_ADD,
2012
 
   N_("Optional comma separated list of plugins to load at startup in addition "
2013
 
      "to the default list of plugins. "
2014
 
      "[for example: --plugin_add=crc32,logger_gearman]"),
2015
 
   (char**) &opt_plugin_add, (char**) &opt_plugin_add, 0,
2016
 
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
2017
2659
  {"plugin_load", OPT_PLUGIN_LOAD,
2018
 
   N_("Optional comma separated list of plugins to load at starup instead of "
2019
 
      "the default plugin load list. "
2020
 
      "[for example: --plugin_load=crc32,logger_gearman]"),
 
2660
   N_("Optional colon (or semicolon) separated list of plugins to load,"
 
2661
      "where each plugin is identified by the name of the shared library. "
 
2662
      "[for example: --plugin_load=libmd5udf.so:libauth_pam.so]"),
2021
2663
   (char**) &opt_plugin_load, (char**) &opt_plugin_load, 0,
2022
2664
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
2023
2665
  {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
2039
2681
  {"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE,
2040
2682
   N_("Allocation block size for storing ranges during optimization"),
2041
2683
   (char**) &global_system_variables.range_alloc_block_size,
2042
 
   (char**) &max_system_variables.range_alloc_block_size, 0, GET_SIZE,
 
2684
   (char**) &max_system_variables.range_alloc_block_size, 0, GET_ULONG,
2043
2685
   REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, SIZE_MAX,
2044
2686
   0, 1024, 0},
2045
2687
  {"read_buffer_size", OPT_RECORD_BUFFER,
2059
2701
   GET_UINT, REQUIRED_ARG, 256*1024L, 64 /*IO_SIZE*2+MALLOC_OVERHEAD*/ ,
2060
2702
   UINT32_MAX, MALLOC_OVERHEAD, 1 /* Small lower limit to be able to test MRR */, 0},
2061
2703
  {"scheduler", OPT_SCHEDULER,
2062
 
   N_("Select scheduler to be used (by default multi-thread)."),
2063
 
   (char**)&opt_scheduler, (char**)&opt_scheduler,
2064
 
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
2065
 
  /* x8 compared to MySQL's x2. We have UTF8 to consider. */
 
2704
   N_("Select scheduler to be used (by default pool-of-threads)."),
 
2705
   (char**) &opt_scheduler, (char**) &opt_scheduler, 0,
 
2706
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
2066
2707
  {"sort_buffer_size", OPT_SORT_BUFFER,
2067
2708
   N_("Each thread that needs to do a sort allocates a buffer of this size."),
2068
2709
   (char**) &global_system_variables.sortbuff_size,
2069
 
   (char**) &max_system_variables.sortbuff_size, 0, GET_SIZE, REQUIRED_ARG,
2070
 
   MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*8, SIZE_MAX,
 
2710
   (char**) &max_system_variables.sortbuff_size, 0, GET_ULONG, REQUIRED_ARG,
 
2711
   MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, SIZE_MAX,
2071
2712
   MALLOC_OVERHEAD, 1, 0},
2072
2713
  {"table_definition_cache", OPT_TABLE_DEF_CACHE,
2073
2714
   N_("The number of cached table definitions."),
2074
2715
   (char**) &table_def_size, (char**) &table_def_size,
2075
 
   0, GET_SIZE, REQUIRED_ARG, 128, 1, 512*1024L, 0, 1, 0},
 
2716
   0, GET_ULL, REQUIRED_ARG, 128, 1, 512*1024L, 0, 1, 0},
2076
2717
  {"table_open_cache", OPT_TABLE_OPEN_CACHE,
2077
2718
   N_("The number of cached open tables."),
2078
 
   (char**) &table_cache_size, (char**) &table_cache_size, 0, GET_UINT64,
 
2719
   (char**) &table_cache_size, (char**) &table_cache_size, 0, GET_ULONG,
2079
2720
   REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
2080
2721
  {"table_lock_wait_timeout", OPT_TABLE_LOCK_WAIT_TIMEOUT,
2081
2722
   N_("Timeout in seconds to wait for a table level lock before returning an "
2085
2726
  {"thread_stack", OPT_THREAD_STACK,
2086
2727
   N_("The stack size for each thread."),
2087
2728
   (char**) &my_thread_stack_size,
2088
 
   (char**) &my_thread_stack_size, 0, GET_SIZE,
 
2729
   (char**) &my_thread_stack_size, 0, GET_ULONG,
2089
2730
   REQUIRED_ARG,DEFAULT_THREAD_STACK,
2090
 
   UINT32_C(1024*512), SIZE_MAX, 0, 1024, 0},
 
2731
   UINT32_C(1024*128), SIZE_MAX, 0, 1024, 0},
 
2732
  { "time_format", OPT_TIME_FORMAT,
 
2733
    N_("The TIME format (for future)."),
 
2734
    (char**) &opt_date_time_formats[DRIZZLE_TIMESTAMP_TIME],
 
2735
    (char**) &opt_date_time_formats[DRIZZLE_TIMESTAMP_TIME],
 
2736
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
2091
2737
  {"tmp_table_size", OPT_TMP_TABLE_SIZE,
2092
2738
   N_("If an internal in-memory temporary table exceeds this size, Drizzle will"
2093
2739
      " automatically convert it to an on-disk MyISAM table."),
2104
2750
   (char**) &global_system_variables.trans_prealloc_size,
2105
2751
   (char**) &max_system_variables.trans_prealloc_size, 0, GET_UINT,
2106
2752
   REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
 
2753
  {"wait_timeout", OPT_WAIT_TIMEOUT,
 
2754
   N_("The number of seconds the server waits for activity on a connection "
 
2755
      "before closing it."),
 
2756
   (char**) &global_system_variables.net_wait_timeout,
 
2757
   (char**) &max_system_variables.net_wait_timeout, 0, GET_UINT,
 
2758
   REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT,
 
2759
   0, 1, 0},
2107
2760
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
2108
2761
};
2109
2762
 
 
2763
static int show_net_compression(Session *session,
 
2764
                                SHOW_VAR *var,
 
2765
                                char *)
 
2766
{
 
2767
  var->type= SHOW_MY_BOOL;
 
2768
  var->value= (char *)&session->net.compress;
 
2769
  return 0;
 
2770
}
 
2771
 
 
2772
static st_show_var_func_container
 
2773
show_net_compression_cont= { &show_net_compression };
 
2774
 
 
2775
static int show_starttime(Session *session, SHOW_VAR *var, char *buff)
 
2776
{
 
2777
  var->type= SHOW_LONG;
 
2778
  var->value= buff;
 
2779
  *((long *)buff)= (long) (session->query_start() - server_start_time);
 
2780
  return 0;
 
2781
}
 
2782
 
 
2783
static st_show_var_func_container
 
2784
show_starttime_cont= { &show_starttime };
 
2785
 
 
2786
static int show_flushstatustime(Session *session, SHOW_VAR *var, char *buff)
 
2787
{
 
2788
  var->type= SHOW_LONG;
 
2789
  var->value= buff;
 
2790
  *((long *)buff)= (long) (session->query_start() - flush_status_time);
 
2791
  return 0;
 
2792
}
 
2793
 
 
2794
static st_show_var_func_container
 
2795
show_flushstatustime_cont= { &show_flushstatustime };
 
2796
 
 
2797
static int show_open_tables(Session *, SHOW_VAR *var, char *buff)
 
2798
{
 
2799
  var->type= SHOW_LONG;
 
2800
  var->value= buff;
 
2801
  *((long *)buff)= (long)cached_open_tables();
 
2802
  return 0;
 
2803
}
 
2804
 
 
2805
static int show_table_definitions(Session *,
 
2806
                                  SHOW_VAR *var, char *buff)
 
2807
{
 
2808
  var->type= SHOW_LONG;
 
2809
  var->value= buff;
 
2810
  *((long *)buff)= (long)cached_table_definitions();
 
2811
  return 0;
 
2812
}
 
2813
 
 
2814
static st_show_var_func_container
 
2815
show_open_tables_cont= { &show_open_tables };
 
2816
static st_show_var_func_container
 
2817
show_table_definitions_cont= { &show_table_definitions };
 
2818
 
 
2819
/*
 
2820
  Variables shown by SHOW STATUS in alphabetical order
 
2821
*/
 
2822
 
 
2823
SHOW_VAR status_vars[]= {
 
2824
  {"Aborted_clients",          (char*) &aborted_threads,        SHOW_LONGLONG},
 
2825
  {"Aborted_connects",         (char*) &aborted_connects,       SHOW_LONGLONG},
 
2826
  {"Bytes_received",           (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS},
 
2827
  {"Bytes_sent",               (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS},
 
2828
  {"Com",                      (char*) com_status_vars, SHOW_ARRAY},
 
2829
  {"Compression",              (char*) &show_net_compression_cont, SHOW_FUNC},
 
2830
  {"Connections",              (char*) &thread_id,              SHOW_LONG_NOFLUSH},
 
2831
  {"Created_tmp_disk_tables",  (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS},
 
2832
  {"Created_tmp_files",        (char*) &my_tmp_file_created,    SHOW_INT},
 
2833
  {"Created_tmp_tables",       (char*) offsetof(STATUS_VAR, created_tmp_tables), SHOW_LONG_STATUS},
 
2834
  {"Flush_commands",           (char*) &refresh_version,        SHOW_LONG_NOFLUSH},
 
2835
  {"Handler_commit",           (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
 
2836
  {"Handler_delete",           (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
 
2837
  {"Handler_prepare",          (char*) offsetof(STATUS_VAR, ha_prepare_count),  SHOW_LONG_STATUS},
 
2838
  {"Handler_read_first",       (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS},
 
2839
  {"Handler_read_key",         (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS},
 
2840
  {"Handler_read_next",        (char*) offsetof(STATUS_VAR, ha_read_next_count), SHOW_LONG_STATUS},
 
2841
  {"Handler_read_prev",        (char*) offsetof(STATUS_VAR, ha_read_prev_count), SHOW_LONG_STATUS},
 
2842
  {"Handler_read_rnd",         (char*) offsetof(STATUS_VAR, ha_read_rnd_count), SHOW_LONG_STATUS},
 
2843
  {"Handler_read_rnd_next",    (char*) offsetof(STATUS_VAR, ha_read_rnd_next_count), SHOW_LONG_STATUS},
 
2844
  {"Handler_rollback",         (char*) offsetof(STATUS_VAR, ha_rollback_count), SHOW_LONG_STATUS},
 
2845
  {"Handler_savepoint",        (char*) offsetof(STATUS_VAR, ha_savepoint_count), SHOW_LONG_STATUS},
 
2846
  {"Handler_savepoint_rollback",(char*) offsetof(STATUS_VAR, ha_savepoint_rollback_count), SHOW_LONG_STATUS},
 
2847
  {"Handler_update",           (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS},
 
2848
  {"Handler_write",            (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS},
 
2849
  {"Key_blocks_not_flushed",   (char*) offsetof(KEY_CACHE, global_blocks_changed), SHOW_KEY_CACHE_LONG},
 
2850
  {"Key_blocks_unused",        (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_LONG},
 
2851
  {"Key_blocks_used",          (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_LONG},
 
2852
  {"Key_read_requests",        (char*) offsetof(KEY_CACHE, global_cache_r_requests), SHOW_KEY_CACHE_LONGLONG},
 
2853
  {"Key_reads",                (char*) offsetof(KEY_CACHE, global_cache_read), SHOW_KEY_CACHE_LONGLONG},
 
2854
  {"Key_write_requests",       (char*) offsetof(KEY_CACHE, global_cache_w_requests), SHOW_KEY_CACHE_LONGLONG},
 
2855
  {"Key_writes",               (char*) offsetof(KEY_CACHE, global_cache_write), SHOW_KEY_CACHE_LONGLONG},
 
2856
  {"Last_query_cost",          (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS},
 
2857
  {"Max_used_connections",     (char*) &max_used_connections,  SHOW_INT},
 
2858
  {"Open_files",               (char*) &my_file_opened,         SHOW_LONG_NOFLUSH},
 
2859
  {"Open_streams",             (char*) &my_stream_opened,       SHOW_LONG_NOFLUSH},
 
2860
  {"Open_table_definitions",   (char*) &show_table_definitions_cont, SHOW_FUNC},
 
2861
  {"Open_tables",              (char*) &show_open_tables_cont,       SHOW_FUNC},
 
2862
  {"Opened_files",             (char*) &my_file_total_opened, SHOW_LONG_NOFLUSH},
 
2863
  {"Opened_tables",            (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS},
 
2864
  {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS},
 
2865
  {"Questions",                (char*) offsetof(STATUS_VAR, questions), SHOW_LONG_STATUS},
 
2866
  {"Select_full_join",         (char*) offsetof(STATUS_VAR, select_full_join_count), SHOW_LONG_STATUS},
 
2867
  {"Select_full_range_join",   (char*) offsetof(STATUS_VAR, select_full_range_join_count), SHOW_LONG_STATUS},
 
2868
  {"Select_range",             (char*) offsetof(STATUS_VAR, select_range_count), SHOW_LONG_STATUS},
 
2869
  {"Select_range_check",       (char*) offsetof(STATUS_VAR, select_range_check_count), SHOW_LONG_STATUS},
 
2870
  {"Select_scan",              (char*) offsetof(STATUS_VAR, select_scan_count), SHOW_LONG_STATUS},
 
2871
  {"Slow_launch_threads",      (char*) &slow_launch_threads,    SHOW_LONGLONG},
 
2872
  {"Slow_queries",             (char*) offsetof(STATUS_VAR, long_query_count), SHOW_LONG_STATUS},
 
2873
  {"Sort_merge_passes",        (char*) offsetof(STATUS_VAR, filesort_merge_passes), SHOW_LONG_STATUS},
 
2874
  {"Sort_range",               (char*) offsetof(STATUS_VAR, filesort_range_count), SHOW_LONG_STATUS},
 
2875
  {"Sort_rows",                (char*) offsetof(STATUS_VAR, filesort_rows), SHOW_LONG_STATUS},
 
2876
  {"Sort_scan",                (char*) offsetof(STATUS_VAR, filesort_scan_count), SHOW_LONG_STATUS},
 
2877
  {"Table_locks_immediate",    (char*) &locks_immediate,        SHOW_INT},
 
2878
  {"Table_locks_waited",       (char*) &locks_waited,           SHOW_INT},
 
2879
  {"Threads_connected",        (char*) &connection_count,       SHOW_INT},
 
2880
  {"Threads_created",          (char*) &thread_created,         SHOW_LONG_NOFLUSH},
 
2881
  {"Threads_running",          (char*) &thread_running,         SHOW_INT},
 
2882
  {"Uptime",                   (char*) &show_starttime_cont,         SHOW_FUNC},
 
2883
  {"Uptime_since_flush_status",(char*) &show_flushstatustime_cont,   SHOW_FUNC},
 
2884
  {NULL, NULL, SHOW_LONGLONG}
 
2885
};
 
2886
 
2110
2887
static void print_version(void)
2111
2888
{
 
2889
  set_server_version();
2112
2890
  /*
2113
2891
    Note: the instance manager keys off the string 'Ver' so it can find the
2114
2892
    version from the output of 'drizzled --version', so don't change it!
2115
2893
  */
2116
 
  printf("%s  Ver %s for %s-%s on %s (%s)\n",my_progname,
2117
 
         PANDORA_RELEASE_VERSION, HOST_VENDOR, HOST_OS, HOST_CPU,
2118
 
         COMPILATION_COMMENT);
 
2894
  printf("%s  Ver %s for %s on %s (%s)\n",my_progname,
 
2895
         server_version,SYSTEM_TYPE,MACHINE_TYPE, COMPILATION_COMMENT);
2119
2896
}
2120
2897
 
2121
2898
static void usage(void)
2134
2911
 
2135
2912
  printf(_("Usage: %s [OPTIONS]\n"), my_progname);
2136
2913
  {
2137
 
     print_defaults(DRIZZLE_CONFIG_NAME,load_default_groups);
2138
 
     puts("");
2139
 
 
2140
 
     /* Print out all the options including plugin supplied options */
2141
 
     my_print_help_inc_plugins(my_long_options);
 
2914
#ifdef FOO
 
2915
  print_defaults(DRIZZLE_CONFIG_NAME,load_default_groups);
 
2916
  puts("");
 
2917
  set_ports();
 
2918
#endif
 
2919
 
 
2920
  /* Print out all the options including plugin supplied options */
 
2921
  my_print_help_inc_plugins(my_long_options, sizeof(my_long_options)/sizeof(my_option));
 
2922
 
 
2923
  puts(_("\nTo see what values a running Drizzle server is using, type\n"
 
2924
         "'drizzleadmin variables' instead of 'drizzled --help'."));
2142
2925
  }
2143
2926
}
2144
2927
 
2162
2945
static void drizzle_init_variables(void)
2163
2946
{
2164
2947
  /* Things reset to zero */
 
2948
  opt_skip_slave_start= opt_reckless_slave = 0;
2165
2949
  drizzle_home[0]= pidfile_name[0]= 0;
 
2950
  opt_bin_log= 0;
 
2951
  opt_skip_show_db=0;
 
2952
  opt_logname= 0;
2166
2953
  opt_tc_log_file= (char *)"tc.log";      // no hostname in tc_log file name !
2167
2954
  opt_secure_file_priv= 0;
2168
2955
  segfaulted= 0;
2169
2956
  cleanup_done= 0;
2170
2957
  defaults_argc= 0;
2171
2958
  defaults_argv= 0;
2172
 
  dropping_tables= ha_open_options=0;
2173
 
  test_flags.reset();
2174
 
  wake_thread=0;
2175
 
  abort_loop= select_thread_in_use= false;
 
2959
  server_id_supplied= 0;
 
2960
  test_flags= select_errors= dropping_tables= ha_open_options=0;
 
2961
  thread_count= thread_running= wake_thread=0;
 
2962
  slave_open_temp_tables= 0;
 
2963
  opt_endinfo= using_udf_functions= 0;
 
2964
  opt_using_transactions= false;
 
2965
  abort_loop= select_thread_in_use= 0;
2176
2966
  ready_to_exit= shutdown_in_progress= 0;
2177
2967
  aborted_threads= aborted_connects= 0;
2178
2968
  max_used_connections= 0;
2179
 
  drizzled_user= drizzled_chroot= 0;
 
2969
  slow_launch_threads= 0;
 
2970
  drizzled_user= drizzled_chroot= opt_init_file= opt_bin_logname = 0;
 
2971
  my_bind_addr_str= NULL;
2180
2972
  memset(&global_status_var, 0, sizeof(global_status_var));
2181
 
  key_map_full.set();
 
2973
  key_map_full.set_all();
2182
2974
 
2183
2975
  /* Character sets */
2184
2976
  system_charset_info= &my_charset_utf8_general_ci;
2185
2977
  files_charset_info= &my_charset_utf8_general_ci;
 
2978
  national_charset_info= &my_charset_utf8_general_ci;
2186
2979
  table_alias_charset= &my_charset_bin;
2187
2980
  character_set_filesystem= &my_charset_bin;
2188
2981
 
 
2982
  opt_date_time_formats[0]= opt_date_time_formats[1]= opt_date_time_formats[2]= 0;
 
2983
 
2189
2984
  /* Things with default values that are not zero */
 
2985
  delay_key_write_options= (uint32_t) DELAY_KEY_WRITE_ON;
2190
2986
  drizzle_home_ptr= drizzle_home;
2191
2987
  pidfile_name_ptr= pidfile_name;
2192
2988
  language_ptr= language;
2193
2989
  drizzle_data_home= drizzle_real_data_home;
2194
2990
  session_startup_options= (OPTION_AUTO_IS_NULL | OPTION_SQL_NOTES);
 
2991
  what_to_log= ~ (1L << (uint32_t) COM_TIME);
2195
2992
  refresh_version= 1L;  /* Increments on each reload */
2196
 
  global_thread_id= 1UL;
2197
 
  session_list.clear();
 
2993
  thread_id= 1;
 
2994
  strcpy(server_version, VERSION);
 
2995
  myisam_recover_options_str= "OFF";
 
2996
  myisam_stats_method_str= "nulls_unequal";
 
2997
  threads.empty();
 
2998
  key_caches.empty();
 
2999
  if (!(dflt_key_cache= get_or_create_key_cache(default_key_cache_base.str,
 
3000
                                                default_key_cache_base.length)))
 
3001
    exit(1);
 
3002
  /* set key_cache_hash.default_value = dflt_key_cache */
 
3003
  multi_keycache_init();
2198
3004
 
2199
3005
  /* Set directory paths */
2200
3006
  strncpy(language, LANGUAGE, sizeof(language)-1);
2205
3011
  drizzle_data_home_len= 2;
2206
3012
 
2207
3013
  /* Variables in libraries */
2208
 
  default_character_set_name= "utf8";
2209
 
  default_collation_name= (char *)compiled_default_collation_name;
2210
 
  character_set_filesystem_name= "binary";
 
3014
  default_character_set_name= (char*) DRIZZLE_DEFAULT_CHARSET_NAME;
 
3015
  default_collation_name= compiled_default_collation_name;
 
3016
  character_set_filesystem_name= (char*) "binary";
2211
3017
  lc_time_names_name= (char*) "en_US";
2212
3018
  /* Set default values for some option variables */
2213
3019
  default_storage_engine_str= (char*) "innodb";
2214
 
  global_system_variables.storage_engine= NULL;
 
3020
  global_system_variables.table_plugin= NULL;
2215
3021
  global_system_variables.tx_isolation= ISO_REPEATABLE_READ;
2216
3022
  global_system_variables.select_limit= (uint64_t) HA_POS_ERROR;
2217
3023
  max_system_variables.select_limit=    (uint64_t) HA_POS_ERROR;
2218
3024
  global_system_variables.max_join_size= (uint64_t) HA_POS_ERROR;
2219
3025
  max_system_variables.max_join_size=   (uint64_t) HA_POS_ERROR;
 
3026
  global_system_variables.old_alter_table= 0;
 
3027
  /*
 
3028
    Default behavior for 4.1 and 5.0 is to treat NULL values as unequal
 
3029
    when collecting index statistics for MyISAM tables.
 
3030
  */
 
3031
  global_system_variables.myisam_stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
2220
3032
 
2221
3033
  /* Variables that depends on compile options */
2222
3034
#ifdef HAVE_BROKEN_REALPATH
2229
3041
  if (!(tmpenv = getenv("MY_BASEDIR_VERSION")))
2230
3042
    tmpenv = PREFIX;
2231
3043
  (void) strncpy(drizzle_home, tmpenv, sizeof(drizzle_home)-1);
2232
 
  
2233
 
  connection_count= 0;
2234
3044
}
2235
3045
 
2236
3046
 
2237
 
extern "C" bool
 
3047
bool
2238
3048
drizzled_get_one_option(int optid, const struct my_option *opt,
2239
3049
                        char *argument)
2240
3050
{
2241
3051
  switch(optid) {
 
3052
  case '#':
 
3053
    opt_endinfo=1;                              /* unireg: memory allocation */
 
3054
    break;
2242
3055
  case 'a':
2243
3056
    global_system_variables.tx_isolation= ISO_SERIALIZABLE;
2244
3057
    break;
2278
3091
      global_system_variables.log_warnings= atoi(argument);
2279
3092
    break;
2280
3093
  case 'T':
2281
 
    if (argument)
2282
 
    {
2283
 
      test_flags.set((uint32_t) atoi(argument));
2284
 
    }
 
3094
    test_flags= argument ? (uint32_t) atoi(argument) : 0;
 
3095
    opt_endinfo=1;
 
3096
    break;
 
3097
  case (int) OPT_BIN_LOG:
 
3098
    opt_bin_log= test(argument != disabled_my_option);
2285
3099
    break;
2286
3100
  case (int) OPT_WANT_CORE:
2287
 
    test_flags.set(TEST_CORE_ON_SIGNAL);
 
3101
    test_flags |= TEST_CORE_ON_SIGNAL;
2288
3102
    break;
2289
3103
  case (int) OPT_SKIP_STACK_TRACE:
2290
 
    test_flags.set(TEST_NO_STACKTRACE);
 
3104
    test_flags|=TEST_NO_STACKTRACE;
2291
3105
    break;
2292
3106
  case (int) OPT_SKIP_SYMLINKS:
2293
3107
    my_use_symdir=0;
2319
3133
    strncpy(pidfile_name, argument, sizeof(pidfile_name)-1);
2320
3134
    break;
2321
3135
  case OPT_SERVER_ID:
 
3136
    server_id_supplied = 1;
 
3137
    break;
 
3138
  case OPT_DELAY_KEY_WRITE_ALL:
 
3139
    if (argument != disabled_my_option)
 
3140
      argument= (char*) "ALL";
 
3141
    /* Fall through */
 
3142
  case OPT_DELAY_KEY_WRITE:
 
3143
    if (argument == disabled_my_option)
 
3144
      delay_key_write_options= (uint32_t) DELAY_KEY_WRITE_NONE;
 
3145
    else if (! argument)
 
3146
      delay_key_write_options= (uint32_t) DELAY_KEY_WRITE_ON;
 
3147
    else
 
3148
    {
 
3149
      int type;
 
3150
      type= find_type_or_exit(argument, &delay_key_write_typelib, opt->name);
 
3151
      delay_key_write_options= (uint32_t) type-1;
 
3152
    }
2322
3153
    break;
2323
3154
  case OPT_TX_ISOLATION:
2324
3155
    {
2327
3158
      global_system_variables.tx_isolation= (type-1);
2328
3159
      break;
2329
3160
    }
 
3161
  case OPT_MYISAM_RECOVER:
 
3162
    {
 
3163
      if (!argument)
 
3164
      {
 
3165
        myisam_recover_options=    HA_RECOVER_DEFAULT;
 
3166
        myisam_recover_options_str= myisam_recover_typelib.type_names[0];
 
3167
      }
 
3168
      else if (!argument[0])
 
3169
      {
 
3170
        myisam_recover_options= HA_RECOVER_NONE;
 
3171
        myisam_recover_options_str= "OFF";
 
3172
      }
 
3173
      else
 
3174
      {
 
3175
        myisam_recover_options_str=argument;
 
3176
        myisam_recover_options=
 
3177
          find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name);
 
3178
      }
 
3179
      ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
 
3180
      break;
 
3181
    }
2330
3182
  case OPT_TC_HEURISTIC_RECOVER:
2331
3183
    tc_heuristic_recover= find_type_or_exit(argument,
2332
3184
                                            &tc_heuristic_recover_typelib,
2333
3185
                                            opt->name);
2334
3186
    break;
 
3187
  case OPT_MYISAM_STATS_METHOD:
 
3188
    {
 
3189
      uint32_t method_conv;
 
3190
      int method;
 
3191
 
 
3192
      myisam_stats_method_str= argument;
 
3193
      method= find_type_or_exit(argument, &myisam_stats_method_typelib,
 
3194
                                opt->name);
 
3195
      switch (method-1) {
 
3196
      case 2:
 
3197
        method_conv= MI_STATS_METHOD_IGNORE_NULLS;
 
3198
        break;
 
3199
      case 1:
 
3200
        method_conv= MI_STATS_METHOD_NULLS_EQUAL;
 
3201
        break;
 
3202
      case 0:
 
3203
      default:
 
3204
        method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
 
3205
        break;
 
3206
      }
 
3207
      global_system_variables.myisam_stats_method= method_conv;
 
3208
      break;
 
3209
    }
2335
3210
  }
2336
 
 
2337
3211
  return 0;
2338
3212
}
2339
3213
 
 
3214
 
 
3215
/** Handle arguments for multiple key caches. */
 
3216
 
 
3217
extern "C" char **drizzle_getopt_value(const char *keyname, uint32_t key_length,
 
3218
                                       const struct my_option *option);
 
3219
 
 
3220
char**
 
3221
drizzle_getopt_value(const char *keyname, uint32_t key_length,
 
3222
                    const struct my_option *option)
 
3223
{
 
3224
  switch (option->id) {
 
3225
  case OPT_KEY_BUFFER_SIZE:
 
3226
  case OPT_KEY_CACHE_BLOCK_SIZE:
 
3227
  case OPT_KEY_CACHE_DIVISION_LIMIT:
 
3228
  case OPT_KEY_CACHE_AGE_THRESHOLD:
 
3229
  {
 
3230
    KEY_CACHE *key_cache;
 
3231
    if (!(key_cache= get_or_create_key_cache(keyname, key_length)))
 
3232
      exit(1);
 
3233
    switch (option->id) {
 
3234
    case OPT_KEY_BUFFER_SIZE:
 
3235
      return (char**) &key_cache->param_buff_size;
 
3236
    case OPT_KEY_CACHE_BLOCK_SIZE:
 
3237
      return (char**) &key_cache->param_block_size;
 
3238
    case OPT_KEY_CACHE_DIVISION_LIMIT:
 
3239
      return (char**) &key_cache->param_division_limit;
 
3240
    case OPT_KEY_CACHE_AGE_THRESHOLD:
 
3241
      return (char**) &key_cache->param_age_threshold;
 
3242
    }
 
3243
  }
 
3244
  }
 
3245
  return (char **)option->value;
 
3246
}
 
3247
 
 
3248
 
2340
3249
extern "C" void option_error_reporter(enum loglevel level, const char *format, ...);
2341
3250
 
2342
 
extern "C" void option_error_reporter(enum loglevel level, const char *format, ...)
 
3251
void option_error_reporter(enum loglevel level, const char *format, ...)
2343
3252
{
2344
3253
  va_list args;
2345
3254
  va_start(args, format);
2347
3256
  /* Don't print warnings for --loose options during bootstrap */
2348
3257
  if (level == ERROR_LEVEL || global_system_variables.log_warnings)
2349
3258
  {
2350
 
    plugin::ErrorMessage::vprintf(current_session, ERROR_LEVEL, format, args);
 
3259
    errmsg_vprintf (current_session, ERROR_LEVEL, format, args);
2351
3260
  }
2352
3261
  va_end(args);
2353
3262
}
2355
3264
 
2356
3265
/**
2357
3266
  @todo
2358
 
  - FIXME add EXIT_TOO_MANY_ARGUMENTS to "mysys/mysys_err.h" and return that code?
 
3267
  - FIXME add EXIT_TOO_MANY_ARGUMENTS to "mysys_err.h" and return that code?
2359
3268
*/
2360
3269
static void get_options(int *argc,char **argv)
2361
3270
{
2362
3271
  int ho_error;
2363
3272
 
 
3273
  my_getopt_register_get_addr(drizzle_getopt_value);
2364
3274
  my_getopt_error_reporter= option_error_reporter;
2365
3275
 
2366
 
  string progname(argv[0]);
2367
 
 
2368
3276
  /* Skip unknown options so that they may be processed later by plugins */
2369
3277
  my_getopt_skip_unknown= true;
2370
3278
 
2388
3296
  if (opt_debugging)
2389
3297
  {
2390
3298
    /* Allow break with SIGINT, no core or stack trace */
2391
 
    test_flags.set(TEST_SIGINT);
2392
 
    test_flags.set(TEST_NO_STACKTRACE);
2393
 
    test_flags.reset(TEST_CORE_ON_SIGNAL);
 
3299
    test_flags|= TEST_SIGINT | TEST_NO_STACKTRACE;
 
3300
    test_flags&= ~TEST_CORE_ON_SIGNAL;
2394
3301
  }
 
3302
  /* Set global MyISAM variables from delay_key_write_options */
 
3303
  fix_delay_key_write((Session*) 0, OPT_GLOBAL);
2395
3304
 
2396
3305
  if (drizzled_chroot)
2397
3306
    set_root(drizzled_chroot);
2398
 
  fix_paths(progname);
 
3307
  fix_paths();
2399
3308
 
2400
3309
  /*
2401
3310
    Set some global variables from the global_system_variables
2402
3311
    In most cases the global variables will not be used
2403
3312
  */
2404
3313
  my_default_record_cache_size=global_system_variables.read_buff_size;
 
3314
  myisam_max_temp_length= INT32_MAX;
 
3315
 
 
3316
  if (init_global_datetime_format(DRIZZLE_TIMESTAMP_DATE,
 
3317
                                  &global_system_variables.date_format) ||
 
3318
      init_global_datetime_format(DRIZZLE_TIMESTAMP_TIME,
 
3319
                                  &global_system_variables.time_format) ||
 
3320
      init_global_datetime_format(DRIZZLE_TIMESTAMP_DATETIME,
 
3321
                                  &global_system_variables.datetime_format))
 
3322
    exit(1);
 
3323
}
 
3324
 
 
3325
 
 
3326
/*
 
3327
  Create version name for running drizzled version
 
3328
  We automaticly add suffixes -debug, -embedded and -log to the version
 
3329
  name to make the version more descriptive.
 
3330
  (DRIZZLE_SERVER_SUFFIX is set by the compilation environment)
 
3331
*/
 
3332
 
 
3333
#ifdef DRIZZLE_SERVER_SUFFIX
 
3334
#define DRIZZLE_SERVER_SUFFIX_STR STRINGIFY_ARG(DRIZZLE_SERVER_SUFFIX)
 
3335
#else
 
3336
#define DRIZZLE_SERVER_SUFFIX_STR ""
 
3337
#endif
 
3338
 
 
3339
static void set_server_version(void)
 
3340
{
 
3341
  char *end= server_version;
 
3342
  end+= sprintf(server_version, "%s%s", VERSION, 
 
3343
                DRIZZLE_SERVER_SUFFIX_STR);
 
3344
  if (opt_bin_log)
 
3345
    strcpy(end, "-log"); // This may slow down system
2405
3346
}
2406
3347
 
2407
3348
 
2420
3361
}
2421
3362
 
2422
3363
 
2423
 
static void fix_paths(string &progname)
 
3364
static void fix_paths(void)
2424
3365
{
2425
 
  char buff[FN_REFLEN],*pos,rp_buff[PATH_MAX];
 
3366
  char buff[FN_REFLEN],*pos;
2426
3367
  convert_dirname(drizzle_home,drizzle_home,NULL);
2427
3368
  /* Resolve symlinks to allow 'drizzle_home' to be a relative symlink */
2428
 
#if defined(HAVE_BROKEN_REALPATH)
2429
 
   my_load_path(drizzle_home, drizzle_home, NULL);
2430
 
#else
2431
 
  if (!realpath(drizzle_home,rp_buff))
2432
 
    my_load_path(rp_buff, drizzle_home, NULL);
2433
 
  rp_buff[FN_REFLEN-1]= '\0';
2434
 
  strcpy(drizzle_home,rp_buff);
 
3369
  my_realpath(drizzle_home,drizzle_home,MYF(0));
2435
3370
  /* Ensure that drizzle_home ends in FN_LIBCHAR */
2436
3371
  pos= strchr(drizzle_home, '\0');
2437
 
#endif
2438
3372
  if (pos[-1] != FN_LIBCHAR)
2439
3373
  {
2440
3374
    pos[0]= FN_LIBCHAR;
2448
3382
  (void) my_load_path(drizzle_home, drizzle_home,""); // Resolve current dir
2449
3383
  (void) my_load_path(drizzle_real_data_home, drizzle_real_data_home,drizzle_home);
2450
3384
  (void) my_load_path(pidfile_name, pidfile_name,drizzle_real_data_home);
2451
 
 
2452
 
  if (opt_plugin_dir_ptr == NULL)
2453
 
  {
2454
 
    /* No plugin dir has been specified. Figure out where the plugins are */
2455
 
    if (progname[0] != FN_LIBCHAR)
2456
 
    {
2457
 
      /* We have a relative path and need to find the absolute */
2458
 
      char working_dir[FN_REFLEN];
2459
 
      char *working_dir_ptr= working_dir;
2460
 
      working_dir_ptr= getcwd(working_dir_ptr, FN_REFLEN);
2461
 
      string new_path(working_dir);
2462
 
      if (*(new_path.end()-1) != '/')
2463
 
        new_path.push_back('/');
2464
 
      if (progname[0] == '.' && progname[1] == '/')
2465
 
        new_path.append(progname.substr(2));
2466
 
      else
2467
 
        new_path.append(progname);
2468
 
      progname.swap(new_path);
2469
 
    }
2470
 
 
2471
 
    /* Now, trim off the exe name */
2472
 
    string progdir(progname.substr(0, progname.rfind(FN_LIBCHAR)+1));
2473
 
    if (progdir.rfind(".libs/") != string::npos)
2474
 
    {
2475
 
      progdir.assign(progdir.substr(0, progdir.rfind(".libs/")));
2476
 
    }
2477
 
    string testfile(progdir);
2478
 
    testfile.append("drizzled.o");
2479
 
    struct stat testfile_stat;
2480
 
    if (stat(testfile.c_str(), &testfile_stat))
2481
 
    {
2482
 
      /* drizzled.o doesn't exist - we are not in a source dir.
2483
 
       * Go on as usual
2484
 
       */
2485
 
      (void) my_load_path(opt_plugin_dir, get_relative_path(PKGPLUGINDIR),
2486
 
                                          drizzle_home);
2487
 
    }
2488
 
    else
2489
 
    {
2490
 
      /* We are in a source dir! Plugin dir is ../plugin/.libs */
2491
 
      size_t last_libchar_pos= progdir.rfind(FN_LIBCHAR,progdir.size()-2)+1;
2492
 
      string source_plugindir(progdir.substr(0,last_libchar_pos));
2493
 
      source_plugindir.append("plugin/.libs");
2494
 
      (void) my_load_path(opt_plugin_dir, source_plugindir.c_str(), "");
2495
 
    }
2496
 
  }
2497
 
  else
2498
 
  {
2499
 
    (void) my_load_path(opt_plugin_dir, opt_plugin_dir_ptr, drizzle_home);
2500
 
  }
 
3385
  (void) my_load_path(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr :
 
3386
                                      get_relative_path(PKGPLUGINDIR),
 
3387
                                      drizzle_home);
2501
3388
  opt_plugin_dir_ptr= opt_plugin_dir;
2502
3389
 
2503
3390
  const char *sharedir= get_relative_path(PKGDATADIR);
2504
3391
  if (test_if_hard_path(sharedir))
2505
 
    strncpy(buff,sharedir,sizeof(buff)-1);
 
3392
    strncpy(buff,sharedir,sizeof(buff)-1);              /* purecov: tested */
2506
3393
  else
2507
3394
  {
2508
3395
    strcpy(buff, drizzle_home);
2546
3433
  }
2547
3434
}
2548
3435
 
 
3436
 
 
3437
static uint32_t find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
 
3438
                                   const char *option)
 
3439
{
 
3440
  uint32_t res;
 
3441
 
 
3442
  const char **ptr;
 
3443
 
 
3444
  if ((res= find_bit_type(x, bit_lib)) == ~(uint32_t) 0)
 
3445
  {
 
3446
    ptr= bit_lib->type_names;
 
3447
    if (!*x)
 
3448
      fprintf(stderr, _("No option given to %s\n"), option);
 
3449
    else
 
3450
      fprintf(stderr, _("Wrong option to %s. Option(s) given: %s\n"),
 
3451
              option, x);
 
3452
    fprintf(stderr, _("Alternatives are: '%s'"), *ptr);
 
3453
    while (*++ptr)
 
3454
      fprintf(stderr, ",'%s'", *ptr);
 
3455
    fprintf(stderr, "\n");
 
3456
    exit(1);
 
3457
  }
 
3458
  return res;
 
3459
}
 
3460
 
 
3461
 
 
3462
/**
 
3463
  @return
 
3464
    a bitfield from a string of substrings separated by ','
 
3465
    or
 
3466
    ~(uint32_t) 0 on error.
 
3467
*/
 
3468
 
 
3469
static uint32_t find_bit_type(const char *x, TYPELIB *bit_lib)
 
3470
{
 
3471
  bool found_end;
 
3472
  int  found_count;
 
3473
  const char *end,*i,*j;
 
3474
  const char **array, *pos;
 
3475
  uint32_t found,found_int,bit;
 
3476
 
 
3477
  found=0;
 
3478
  found_end= 0;
 
3479
  pos=(char *) x;
 
3480
  while (*pos == ' ') pos++;
 
3481
  found_end= *pos == 0;
 
3482
  while (!found_end)
 
3483
  {
 
3484
    if ((end=strrchr(pos,',')) != NULL)         /* Let end point at fieldend */
 
3485
    {
 
3486
      while (end > pos && end[-1] == ' ')
 
3487
        end--;                                  /* Skip end-space */
 
3488
      found_end=1;
 
3489
    }
 
3490
    else
 
3491
    {
 
3492
        end=pos+strlen(pos);
 
3493
        found_end=1;
 
3494
    }
 
3495
    found_int=0; found_count=0;
 
3496
    for (array=bit_lib->type_names, bit=1 ; (i= *array++) ; bit<<=1)
 
3497
    {
 
3498
      j=pos;
 
3499
      while (j != end)
 
3500
      {
 
3501
        if (my_toupper(mysqld_charset,*i++) !=
 
3502
            my_toupper(mysqld_charset,*j++))
 
3503
          goto skip;
 
3504
      }
 
3505
      found_int=bit;
 
3506
      if (! *i)
 
3507
      {
 
3508
        found_count=1;
 
3509
        break;
 
3510
      }
 
3511
      else if (j != pos)                        // Half field found
 
3512
      {
 
3513
        found_count++;                          // Could be one of two values
 
3514
      }
 
3515
skip: ;
 
3516
    }
 
3517
    if (found_count != 1)
 
3518
      return(~(uint32_t) 0);                            // No unique value
 
3519
    found|=found_int;
 
3520
    pos=end+1;
 
3521
  }
 
3522
 
 
3523
  return(found);
 
3524
} /* find_bit_type */
 
3525
 
 
3526
 
 
3527
bool safe_read_error_impl(NET *net)
 
3528
{
 
3529
  if (net->vio)
 
3530
    return drizzleclient_vio_was_interrupted(net->vio);
 
3531
  return false;
 
3532
}
 
3533
 
 
3534
 
2549
3535
/*****************************************************************************
2550
3536
  Instantiate templates
2551
3537
*****************************************************************************/
2552
3538
 
2553
3539
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
2554
3540
/* Used templates */
 
3541
template class I_List<Session>;
 
3542
template class I_List_iterator<Session>;
2555
3543
template class I_List<i_string>;
2556
3544
template class I_List<i_string_pair>;
 
3545
template class I_List<NAMED_LIST>;
2557
3546
template class I_List<Statement>;
2558
3547
template class I_List_iterator<Statement>;
2559
3548
#endif