~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/mysqlslap.c

Merged build changes from Antony.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2005 MySQL AB
 
1
/* Copyright (C) 2008 Drizzle Open Source Development Team
2
2
 
3
3
   This program is free software; you can redistribute it and/or modify
4
4
   it under the terms of the GNU General Public License as published by
19
19
 
20
20
 
21
21
/*
22
 
  MySQL Slap
 
22
  Drizzle Slap
23
23
 
24
24
  A simple program designed to work as if multiple clients querying the database,
25
25
  then reporting the timing of each stage.
26
26
 
27
 
  MySQL slap runs three stages:
 
27
  Drizzle slap runs three stages:
28
28
  1) Create schema,table, and optionally any SP or data you want to beign
29
29
     the test with. (single client)
30
30
  2) Load test (many clients)
32
32
 
33
33
  Examples:
34
34
 
35
 
  Supply your own create and query SQL statements, with 50 clients 
 
35
  Supply your own create and query SQL statements, with 50 clients
36
36
  querying (200 selects for each):
37
37
 
38
 
    mysqlslap --delimiter=";" \
 
38
    drizzleslap --delimiter=";" \
39
39
              --create="CREATE TABLE A (a int);INSERT INTO A VALUES (23)" \
40
40
              --query="SELECT * FROM A" --concurrency=50 --iterations=200
41
41
 
44
44
  don't create the table or insert the data (using the previous test's
45
45
  schema and data):
46
46
 
47
 
    mysqlslap --concurrency=5 --iterations=20 \
 
47
    drizzleslap --concurrency=5 --iterations=20 \
48
48
              --number-int-cols=2 --number-char-cols=3 \
49
49
              --auto-generate-sql
50
50
 
51
51
  Tell the program to load the create, insert and query SQL statements from
52
52
  the specified files, where the create.sql file has multiple table creation
53
53
  statements delimited by ';' and multiple insert statements delimited by ';'.
54
 
  The --query file will have multiple queries delimited by ';', run all the 
 
54
  The --query file will have multiple queries delimited by ';', run all the
55
55
  load statements, and then run all the queries in the query file
56
56
  with five clients (five times each):
57
57
 
58
 
    mysqlslap --concurrency=5 \
 
58
    drizzleslap --concurrency=5 \
59
59
              --iterations=5 --query=query.sql --create=create.sql \
60
60
              --delimiter=";"
61
61
 
76
76
#define DEFAULT_BLOB_SIZE 1024
77
77
 
78
78
#include "client_priv.h"
79
 
#include <mysqld_error.h>
80
 
#include <my_dir.h>
81
79
#include <signal.h>
82
80
#include <stdarg.h>
83
81
#include <sys/types.h>
84
82
#include <sys/wait.h>
85
83
#include <ctype.h>
86
84
 
87
 
#ifdef HAVE_SMEM 
 
85
#ifdef HAVE_SMEM
88
86
static char *shared_memory_base_name=0;
89
87
#endif
90
88
 
113
111
            *default_engine= NULL,
114
112
            *pre_system= NULL,
115
113
            *post_system= NULL,
116
 
            *opt_mysql_unix_port= NULL;
 
114
            *opt_drizzle_unix_port= NULL;
117
115
 
118
116
const char *delimiter= "\n";
119
117
 
153
151
static unsigned int num_blob_cols= 0;
154
152
static unsigned int num_blob_cols_size;
155
153
static unsigned int num_blob_cols_size_min;
156
 
static unsigned int num_int_cols_index= 0; 
 
154
static unsigned int num_int_cols_index= 0;
157
155
static unsigned int num_char_cols_index= 0;
158
156
static unsigned int iterations;
159
157
static uint my_end_arg= 0;
173
171
const char *opt_csv_str;
174
172
File csv_file;
175
173
 
176
 
static uint opt_protocol= MYSQL_PROTOCOL_TCP;
 
174
static uint opt_protocol= DRIZZLE_PROTOCOL_TCP;
177
175
 
178
176
static int get_options(int *argc,char ***argv);
179
 
static uint opt_mysql_port= 0;
 
177
static uint opt_drizzle_port= 0;
180
178
 
181
179
static const char *load_default_groups[]= { "mysqlslap","client",0 };
182
180
 
253
251
};
254
252
 
255
253
static option_string *engine_options= NULL;
256
 
static option_string *query_options= NULL; 
257
 
static statement *pre_statements= NULL; 
258
 
static statement *post_statements= NULL; 
 
254
static option_string *query_options= NULL;
 
255
static statement *pre_statements= NULL;
 
256
static statement *post_statements= NULL;
259
257
static statement *create_statements= NULL;
260
258
 
261
259
static statement **query_statements= NULL;
269
267
uint parse_comma(const char *string, uint **range);
270
268
uint parse_delimiter(const char *script, statement **stmt, char delm);
271
269
uint parse_option(const char *origin, option_string **stmt, char delm);
272
 
static int drop_schema(MYSQL *mysql, const char *db);
 
270
static int drop_schema(DRIZZLE *drizzle, const char *db);
273
271
uint get_random_string(char *buf, size_t size);
274
272
static statement *build_table_string(void);
275
273
static statement *build_insert_string(void);
276
274
static statement *build_update_string(void);
277
275
static statement * build_select_string(bool key);
278
 
static int generate_primary_key_list(MYSQL *mysql, option_string *engine_stmt);
 
276
static int generate_primary_key_list(DRIZZLE *drizzle, option_string *engine_stmt);
279
277
static int drop_primary_key_list(void);
280
 
static int create_schema(MYSQL *mysql, const char *db, statement *stmt, 
 
278
static int create_schema(DRIZZLE *drizzle, const char *db, statement *stmt,
281
279
                         option_string *engine_stmt, stats *sptr);
282
 
static int run_scheduler(stats *sptr, statement **stmts, uint concur, 
 
280
static int run_scheduler(stats *sptr, statement **stmts, uint concur,
283
281
                         uint64_t limit);
284
282
pthread_handler_t run_task(void *p);
285
283
pthread_handler_t timer_thread(void *p);
286
284
void statement_cleanup(statement *stmt);
287
285
void option_cleanup(option_string *stmt);
288
 
void concurrency_loop(MYSQL *mysql, uint current, option_string *eptr);
289
 
static int run_statements(MYSQL *mysql, statement *stmt);
290
 
void slap_connect(MYSQL *mysql, bool connect_to_schema);
291
 
void slap_close(MYSQL *mysql);
292
 
static int run_query(MYSQL *mysql, const char *query, int len);
 
286
void concurrency_loop(DRIZZLE *drizzle, uint current, option_string *eptr);
 
287
static int run_statements(DRIZZLE *drizzle, statement *stmt);
 
288
void slap_connect(DRIZZLE *drizzle, bool connect_to_schema);
 
289
void slap_close(DRIZZLE *drizzle);
 
290
static int run_query(DRIZZLE *drizzle, const char *query, int len);
293
291
void standard_deviation (conclusions *con, stats *sptr);
294
292
 
295
293
static const char ALPHANUMERICS[]=
301
299
static long int timedif(struct timeval a, struct timeval b)
302
300
{
303
301
    register int us, s;
304
 
 
 
302
 
305
303
    us = a.tv_usec - b.tv_usec;
306
304
    us /= 1000;
307
305
    s = a.tv_sec - b.tv_sec;
311
309
 
312
310
int main(int argc, char **argv)
313
311
{
314
 
  MYSQL mysql;
 
312
  DRIZZLE drizzle;
315
313
  option_string *eptr;
316
314
  unsigned int x;
317
315
 
319
317
 
320
318
  MY_INIT(argv[0]);
321
319
 
322
 
  if (!(mysql_thread_safe()))
 
320
  if (!(drizzle_thread_safe()))
323
321
      fprintf(stderr, "This application was compiled incorrectly. Please recompile with thread support.\n");
324
322
 
325
323
  load_defaults("my",load_default_groups,&argc,&argv);
350
348
    exit(1);
351
349
  }
352
350
 
353
 
  slap_connect(&mysql, false);
 
351
  slap_connect(&drizzle, false);
354
352
 
355
353
  VOID(pthread_mutex_init(&counter_mutex, NULL));
356
354
  VOID(pthread_cond_init(&count_threshhold, NULL));
374
372
    if (*concurrency)
375
373
    {
376
374
      for (current= concurrency; current && *current; current++)
377
 
        concurrency_loop(&mysql, *current, eptr);
 
375
        concurrency_loop(&drizzle, *current, eptr);
378
376
    }
379
377
    else
380
378
    {
381
379
      uint infinite= 1;
382
380
      do {
383
 
        concurrency_loop(&mysql, infinite, eptr);
 
381
        concurrency_loop(&drizzle, infinite, eptr);
384
382
      }
385
383
      while (infinite++);
386
384
    }
387
385
 
388
386
    if (!opt_preserve)
389
 
      drop_schema(&mysql, create_schema_string);
 
387
      drop_schema(&drizzle, create_schema_string);
390
388
 
391
389
  } while (eptr ? (eptr= eptr->next) : 0);
392
 
  
 
390
 
393
391
  if (opt_burnin)
394
392
    goto burnin;
395
393
 
400
398
  VOID(pthread_mutex_destroy(&timer_alarm_mutex));
401
399
  VOID(pthread_cond_destroy(&timer_alarm_threshold));
402
400
 
403
 
  slap_close(&mysql);
 
401
  slap_close(&drizzle);
404
402
 
405
403
  /* now free all the strings we created */
406
404
  if (opt_password)
427
425
  return 0;
428
426
}
429
427
 
430
 
void concurrency_loop(MYSQL *mysql, uint current, option_string *eptr)
 
428
void concurrency_loop(DRIZZLE *drizzle, uint current, option_string *eptr)
431
429
{
432
430
  unsigned int x;
433
431
  stats *head_sptr;
435
433
  conclusions conclusion;
436
434
  unsigned long long client_limit;
437
435
 
438
 
  head_sptr= (stats *)my_malloc(sizeof(stats) * iterations, 
 
436
  head_sptr= (stats *)my_malloc(sizeof(stats) * iterations,
439
437
                                MYF(MY_ZEROFILL|MY_FAE|MY_WME));
440
438
 
441
 
  bzero(&conclusion, sizeof(conclusions));
 
439
  memset(&conclusion, 0, sizeof(conclusions));
442
440
 
443
441
  if (auto_actual_queries)
444
442
    client_limit= auto_actual_queries;
455
453
      data in the table.
456
454
    */
457
455
    if (opt_preserve == false)
458
 
      drop_schema(mysql, create_schema_string);
 
456
      drop_schema(drizzle, create_schema_string);
459
457
 
460
458
    /* First we create */
461
459
    if (create_statements)
462
 
      create_schema(mysql, create_schema_string, create_statements, eptr, sptr);
 
460
      create_schema(drizzle, create_schema_string, create_statements, eptr, sptr);
463
461
 
464
462
    /*
465
463
      If we generated GUID we need to build a list of them from creation that
468
466
    if (verbose >= 2)
469
467
      printf("Generating primary key list\n");
470
468
    if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
471
 
      generate_primary_key_list(mysql, eptr);
 
469
      generate_primary_key_list(drizzle, eptr);
472
470
 
473
471
    if (commit_rate)
474
 
      run_query(mysql, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
 
472
      run_query(drizzle, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
475
473
 
476
474
    if (pre_system)
477
475
      system(pre_system);
478
476
 
479
 
    /* 
480
 
      Pre statements are always run after all other logic so they can 
481
 
      correct/adjust any item that they want. 
 
477
    /*
 
478
      Pre statements are always run after all other logic so they can
 
479
      correct/adjust any item that they want.
482
480
    */
483
481
    if (pre_statements)
484
 
      run_statements(mysql, pre_statements);
 
482
      run_statements(drizzle, pre_statements);
485
483
 
486
 
    run_scheduler(sptr, query_statements, current, client_limit); 
487
 
    
 
484
    run_scheduler(sptr, query_statements, current, client_limit);
 
485
   
488
486
    if (post_statements)
489
 
      run_statements(mysql, post_statements);
 
487
      run_statements(drizzle, post_statements);
490
488
 
491
489
    if (post_system)
492
490
      system(post_system);
517
515
    0, 0, 0, 0, 0, 0},
518
516
  {"auto-generate-sql-select-columns", OPT_SLAP_AUTO_GENERATE_SELECT_COLUMNS,
519
517
    "Provide a string to use for the select fields used in auto tests.",
520
 
    (char**) &auto_generate_selected_columns_opt, 
 
518
    (char**) &auto_generate_selected_columns_opt,
521
519
    (char**) &auto_generate_selected_columns_opt,
522
520
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
523
521
  {"auto-generate-sql", 'a',
526
524
    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
527
525
  {"auto-generate-sql-add-autoincrement", OPT_SLAP_AUTO_GENERATE_ADD_AUTO,
528
526
    "Add an AUTO_INCREMENT column to auto-generated tables.",
529
 
    (char**) &auto_generate_sql_autoincrement, 
 
527
    (char**) &auto_generate_sql_autoincrement,
530
528
    (char**) &auto_generate_sql_autoincrement,
531
529
    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
532
530
  {"auto-generate-sql-execute-number", OPT_SLAP_AUTO_GENERATE_EXECUTE_QUERIES,
535
533
    0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
536
534
  {"auto-generate-sql-guid-primary", OPT_SLAP_AUTO_GENERATE_GUID_PRIMARY,
537
535
    "Add GUID based primary keys to auto-generated tables.",
538
 
    (char**) &auto_generate_sql_guid_primary, 
 
536
    (char**) &auto_generate_sql_guid_primary,
539
537
    (char**) &auto_generate_sql_guid_primary,
540
538
    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
541
539
  {"auto-generate-sql-load-type", OPT_SLAP_AUTO_GENERATE_SQL_LOAD_TYPE,
542
540
    "Specify test load type: mixed, update, write, key, or read; default is mixed.",
543
541
    (char**) &opt_auto_generate_sql_type, (char**) &opt_auto_generate_sql_type,
544
542
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
545
 
  {"auto-generate-sql-secondary-indexes", 
546
 
    OPT_SLAP_AUTO_GENERATE_SECONDARY_INDEXES, 
 
543
  {"auto-generate-sql-secondary-indexes",
 
544
    OPT_SLAP_AUTO_GENERATE_SECONDARY_INDEXES,
547
545
    "Number of secondary indexes to add to auto-generated tables.",
548
 
    (char**) &auto_generate_sql_secondary_indexes, 
 
546
    (char**) &auto_generate_sql_secondary_indexes,
549
547
    (char**) &auto_generate_sql_secondary_indexes, 0,
550
548
    GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
551
 
  {"auto-generate-sql-unique-query-number", 
 
549
  {"auto-generate-sql-unique-query-number",
552
550
    OPT_SLAP_AUTO_GENERATE_UNIQUE_QUERY_NUM,
553
551
    "Number of unique queries to generate for automatic tests.",
554
 
    (char**) &auto_generate_sql_unique_query_number, 
 
552
    (char**) &auto_generate_sql_unique_query_number,
555
553
    (char**) &auto_generate_sql_unique_query_number,
556
554
    0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
557
 
  {"auto-generate-sql-unique-write-number", 
 
555
  {"auto-generate-sql-unique-write-number",
558
556
    OPT_SLAP_AUTO_GENERATE_UNIQUE_WRITE_NUM,
559
557
    "Number of unique queries to generate for auto-generate-sql-write-number.",
560
 
    (char**) &auto_generate_sql_unique_write_number, 
 
558
    (char**) &auto_generate_sql_unique_write_number,
561
559
    (char**) &auto_generate_sql_unique_write_number,
562
560
    0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
563
561
  {"auto-generate-sql-write-number", OPT_SLAP_AUTO_GENERATE_WRITE_NUM,
567
565
  {"burnin", OPT_SLAP_BURNIN, "Run full test case in infinite loop.",
568
566
    (char**) &opt_burnin, (char**) &opt_burnin, 0, GET_BOOL, NO_ARG, 0, 0, 0,
569
567
    0, 0, 0},
570
 
  {"ignore-sql-errors", OPT_SLAP_IGNORE_SQL_ERRORS, 
 
568
  {"ignore-sql-errors", OPT_SLAP_IGNORE_SQL_ERRORS,
571
569
    "Ignore SQL erros in query run.",
572
 
    (char**) &opt_ignore_sql_errors, 
573
 
    (char**) &opt_ignore_sql_errors, 
 
570
    (char**) &opt_ignore_sql_errors,
 
571
    (char**) &opt_ignore_sql_errors,
574
572
    0, GET_BOOL, NO_ARG, 0, 0, 0,
575
573
    0, 0, 0},
576
574
  {"commit", OPT_SLAP_COMMIT, "Commit records every X number of statements.",
586
584
    (char**) &create_string, (char**) &create_string, 0, GET_STR, REQUIRED_ARG,
587
585
    0, 0, 0, 0, 0, 0},
588
586
  {"create-schema", OPT_CREATE_SLAP_SCHEMA, "Schema to run tests in.",
589
 
    (char**) &create_schema_string, (char**) &create_schema_string, 0, GET_STR, 
 
587
    (char**) &create_schema_string, (char**) &create_schema_string, 0, GET_STR,
590
588
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
591
589
  {"csv", OPT_SLAP_CSV,
592
 
        "Generate CSV output to named file or to stdout if no file is named.",
593
 
    (char**) &opt_csv_str, (char**) &opt_csv_str, 0, GET_STR, 
 
590
  "Generate CSV output to named file or to stdout if no file is named.",
 
591
    (char**) &opt_csv_str, (char**) &opt_csv_str, 0, GET_STR,
594
592
    OPT_ARG, 0, 0, 0, 0, 0, 0},
595
593
  {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
596
594
   (char**) &debug_check_flag, (char**) &debug_check_flag, 0,
597
595
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
598
596
  {"debug-info", 'T', "Print some debug info at exit.", (char**) &debug_info_flag,
599
597
   (char**) &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
600
 
  {"delayed-start", OPT_SLAP_DELAYED_START, 
 
598
  {"delayed-start", OPT_SLAP_DELAYED_START,
601
599
    "Delay the startup of threads by a random number of microsends (the maximum of the delay)",
602
 
    (char**) &opt_delayed_start, (char**) &opt_delayed_start, 0, GET_UINT, 
 
600
    (char**) &opt_delayed_start, (char**) &opt_delayed_start, 0, GET_UINT,
603
601
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
604
602
  {"delimiter", 'F',
605
603
    "Delimiter to use in SQL statements supplied in file or command line.",
607
605
    0, 0, 0, 0, 0, 0},
608
606
  {"detach", OPT_SLAP_DETACH,
609
607
    "Detach (close and reopen) connections after X number of requests.",
610
 
    (char**) &detach_rate, (char**) &detach_rate, 0, GET_UINT, REQUIRED_ARG, 
 
608
    (char**) &detach_rate, (char**) &detach_rate, 0, GET_UINT, REQUIRED_ARG,
611
609
    0, 0, 0, 0, 0, 0},
612
610
  {"engine", 'e', "Storage engine to use for creating the table.",
613
611
    (char**) &default_engine, (char**) &default_engine, 0,
619
617
  {"label", OPT_SLAP_LABEL, "Label to use for print and csv output.",
620
618
    (char**) &opt_label, (char**) &opt_label, 0,
621
619
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
622
 
  {"number-blob-cols", OPT_SLAP_BLOB_COL, 
 
620
  {"number-blob-cols", OPT_SLAP_BLOB_COL,
623
621
    "Number of BLOB columns to create table with if specifying --auto-generate-sql. Example --number-blob-cols=3:1024/2048 would give you 3 blobs with a random size between 1024 and 2048. ",
624
622
    (char**) &num_blob_cols_opt, (char**) &num_blob_cols_opt, 0, GET_STR, REQUIRED_ARG,
625
623
    0, 0, 0, 0, 0, 0},
626
 
  {"number-char-cols", 'x', 
 
624
  {"number-char-cols", 'x',
627
625
    "Number of VARCHAR columns to create in table if specifying --auto-generate-sql.",
628
626
    (char**) &num_char_cols_opt, (char**) &num_char_cols_opt, 0, GET_STR, REQUIRED_ARG,
629
627
    0, 0, 0, 0, 0, 0},
630
 
  {"number-int-cols", 'y', 
 
628
  {"number-int-cols", 'y',
631
629
    "Number of INT columns to create in table if specifying --auto-generate-sql.",
632
 
    (char**) &num_int_cols_opt, (char**) &num_int_cols_opt, 0, GET_STR, REQUIRED_ARG, 
 
630
    (char**) &num_int_cols_opt, (char**) &num_int_cols_opt, 0, GET_STR, REQUIRED_ARG,
633
631
    0, 0, 0, 0, 0, 0},
634
 
  {"number-of-queries", OPT_MYSQL_NUMBER_OF_QUERY, 
 
632
  {"number-of-queries", OPT_DRIZZLE_NUMBER_OF_QUERY,
635
633
    "Limit each client to this number of queries (this is not exact).",
636
634
    (char**) &num_of_query, (char**) &num_of_query, 0,
637
635
    GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
638
 
  {"only-print", OPT_MYSQL_ONLY_PRINT,
639
 
    "This causes mysqlslap to not connect to the databases, but instead print "
 
636
  {"only-print", OPT_DRIZZLE_ONLY_PRINT,
 
637
    "This causes drizzleslap to not connect to the databases, but instead print "
640
638
      "out what it would have done instead.",
641
639
    (char**) &opt_only_print, (char**) &opt_only_print, 0, GET_BOOL,  NO_ARG,
642
640
    0, 0, 0, 0, 0, 0},
643
641
  {"password", 'p',
644
642
    "Password to use when connecting to server. If password is not given it's "
645
643
      "asked from the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
646
 
  {"port", 'P', "Port number to use for connection.", (char**) &opt_mysql_port,
647
 
    (char**) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
 
644
  {"port", 'P', "Port number to use for connection.", (char**) &opt_drizzle_port,
 
645
    (char**) &opt_drizzle_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
648
646
    0},
649
647
  {"post-query", OPT_SLAP_POST_QUERY,
650
648
    "Query to run or file containing query to execute after tests have completed.",
651
 
    (char**) &user_supplied_post_statements, 
 
649
    (char**) &user_supplied_post_statements,
652
650
    (char**) &user_supplied_post_statements,
653
651
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
654
652
  {"post-system", OPT_SLAP_POST_SYSTEM,
655
653
    "system() string to execute after tests have completed.",
656
 
    (char**) &post_system, 
 
654
    (char**) &post_system,
657
655
    (char**) &post_system,
658
656
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
659
 
  {"pre-query", OPT_SLAP_PRE_QUERY, 
 
657
  {"pre-query", OPT_SLAP_PRE_QUERY,
660
658
    "Query to run or file containing query to execute before running tests.",
661
 
    (char**) &user_supplied_pre_statements, 
 
659
    (char**) &user_supplied_pre_statements,
662
660
    (char**) &user_supplied_pre_statements,
663
661
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
664
 
  {"pre-system", OPT_SLAP_PRE_SYSTEM, 
 
662
  {"pre-system", OPT_SLAP_PRE_SYSTEM,
665
663
    "system() string to execute before running tests.",
666
 
    (char**) &pre_system, 
 
664
    (char**) &pre_system,
667
665
    (char**) &pre_system,
668
666
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
669
 
  {"protocol", OPT_MYSQL_PROTOCOL,
 
667
  {"protocol", OPT_DRIZZLE_PROTOCOL,
670
668
    "The protocol of connection (tcp,socket,pipe,memory).",
671
669
    0, 0, 0, GET_STR,  REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
672
670
  {"query", 'q', "Query to run or file containing query to run.",
673
671
    (char**) &user_supplied_query, (char**) &user_supplied_query,
674
672
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
675
 
  {"set-random-seed", OPT_SLAP_SET_RANDOM_SEED, 
 
673
  {"set-random-seed", OPT_SLAP_SET_RANDOM_SEED,
676
674
    "Seed for random number generator (srandom(3))",
677
675
    (char**)&opt_set_random_seed,
678
676
    (char**)&opt_set_random_seed,0,
681
679
    (char**) &opt_silent, (char**) &opt_silent, 0, GET_BOOL,  NO_ARG,
682
680
    0, 0, 0, 0, 0, 0},
683
681
  {"socket", 'S', "Socket file to use for connection.",
684
 
    (char**) &opt_mysql_unix_port, (char**) &opt_mysql_unix_port, 0, GET_STR,
 
682
    (char**) &opt_drizzle_unix_port, (char**) &opt_drizzle_unix_port, 0, GET_STR,
685
683
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
686
 
  {"timer-length", OPT_SLAP_TIMER_LENGTH, 
687
 
    "Require mysqlslap to run each specific test a certain amount of time in seconds.", 
688
 
    (char**) &opt_timer_length, (char**) &opt_timer_length, 0, GET_UINT, 
 
684
  {"timer-length", OPT_SLAP_TIMER_LENGTH,
 
685
    "Require drizzleslap to run each specific test a certain amount of time in seconds.",
 
686
    (char**) &opt_timer_length, (char**) &opt_timer_length, 0, GET_UINT,
689
687
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
690
688
#ifndef DONT_ALLOW_USER_CHANGE
691
689
  {"user", 'u', "User for login if not current user.", (char**) &user,
693
691
#endif
694
692
  {"verbose", 'v',
695
693
    "More verbose output; you can use this multiple times to get even more "
696
 
      "verbose output.", (char**) &verbose, (char**) &verbose, 0, 
 
694
      "verbose output.", (char**) &verbose, (char**) &verbose, 0,
697
695
      GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
698
696
  {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
699
697
    NO_ARG, 0, 0, 0, 0, 0, 0},
701
699
};
702
700
 
703
701
 
704
 
#include <help_start.h>
705
 
 
706
702
static void print_version(void)
707
703
{
708
704
  printf("%s  Ver %s Distrib %s, for %s (%s)\n",my_progname, SLAP_VERSION,
713
709
static void usage(void)
714
710
{
715
711
  print_version();
716
 
  puts("Copyright (C) 2005 MySQL AB");
 
712
  puts("Copyright (C) 2005 DRIZZLE AB");
717
713
  puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\
718
714
       \nand you are welcome to modify and redistribute it under the GPL \
719
715
       license\n");
723
719
  my_print_help(my_long_options);
724
720
}
725
721
 
726
 
#include <help_end.h>
727
 
 
728
722
static bool
729
723
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
730
724
               char *argument)
740
734
      char *start= argument;
741
735
      my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
742
736
      opt_password= my_strdup(argument,MYF(MY_FAE));
743
 
      while (*argument) *argument++= 'x';               /* Destroy argument */
 
737
      while (*argument) *argument++= 'x';    /* Destroy argument */
744
738
      if (*start)
745
 
        start[1]= 0;                            /* Cut length of argument */
 
739
        start[1]= 0;        /* Cut length of argument */
746
740
      tty_password= 0;
747
741
    }
748
742
    else
753
747
    exit(0);
754
748
    break;
755
749
  case '?':
756
 
  case 'I':                                     /* Info */
 
750
  case 'I':          /* Info */
757
751
    usage();
758
752
    exit(0);
759
753
  }
816
810
      if (count) /* Except for the first pass we add a comma */
817
811
        dynstr_append(&table_string, ",");
818
812
 
819
 
      if (snprintf(buf, HUGE_STRING_LENGTH, "id%d varchar(32) unique key", count) 
 
813
      if (snprintf(buf, HUGE_STRING_LENGTH, "id%d varchar(32) unique key", count)
820
814
          > HUGE_STRING_LENGTH)
821
815
      {
822
816
        fprintf(stderr, "Memory Allocation error in create table\n");
834
828
    {
835
829
      if (num_int_cols_index)
836
830
      {
837
 
        if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d INT(32), INDEX(intcol%d)", 
 
831
        if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d INT, INDEX(intcol%d)",
838
832
                     col_count, col_count) > HUGE_STRING_LENGTH)
839
833
        {
840
834
          fprintf(stderr, "Memory Allocation error in create table\n");
843
837
      }
844
838
      else
845
839
      {
846
 
        if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d INT(32) ", col_count) 
 
840
        if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d INT ", col_count)
847
841
            > HUGE_STRING_LENGTH)
848
842
        {
849
843
          fprintf(stderr, "Memory Allocation error in create table\n");
861
855
    {
862
856
      if (num_char_cols_index)
863
857
      {
864
 
        if (snprintf(buf, HUGE_STRING_LENGTH, 
865
 
                     "charcol%d VARCHAR(128), INDEX(charcol%d) ", 
 
858
        if (snprintf(buf, HUGE_STRING_LENGTH,
 
859
                     "charcol%d VARCHAR(128), INDEX(charcol%d) ",
866
860
                     col_count, col_count) > HUGE_STRING_LENGTH)
867
861
        {
868
862
          fprintf(stderr, "Memory Allocation error in creating table\n");
871
865
      }
872
866
      else
873
867
      {
874
 
        if (snprintf(buf, HUGE_STRING_LENGTH, "charcol%d VARCHAR(128)", 
 
868
        if (snprintf(buf, HUGE_STRING_LENGTH, "charcol%d VARCHAR(128)",
875
869
                     col_count) > HUGE_STRING_LENGTH)
876
870
        {
877
871
          fprintf(stderr, "Memory Allocation error in creating table\n");
887
881
  if (num_blob_cols)
888
882
    for (col_count= 1; col_count <= num_blob_cols; col_count++)
889
883
    {
890
 
      if (snprintf(buf, HUGE_STRING_LENGTH, "blobcol%d blob", 
 
884
      if (snprintf(buf, HUGE_STRING_LENGTH, "blobcol%d blob",
891
885
                   col_count) > HUGE_STRING_LENGTH)
892
886
      {
893
887
        fprintf(stderr, "Memory Allocation error in creating table\n");
900
894
    }
901
895
 
902
896
  dynstr_append(&table_string, ")");
903
 
  ptr= (statement *)my_malloc(sizeof(statement), 
 
897
  ptr= (statement *)my_malloc(sizeof(statement),
904
898
                              MYF(MY_ZEROFILL|MY_FAE|MY_WME));
905
899
  ptr->string = (char *)my_malloc(table_string.length+1,
906
900
                                  MYF(MY_ZEROFILL|MY_FAE|MY_WME));
933
927
  if (num_int_cols)
934
928
    for (col_count= 1; col_count <= num_int_cols; col_count++)
935
929
    {
936
 
      if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d = %ld", col_count, 
 
930
      if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d = %ld", col_count,
937
931
                   random()) > HUGE_STRING_LENGTH)
938
932
      {
939
933
        fprintf(stderr, "Memory Allocation error in creating update\n");
951
945
      char rand_buffer[RAND_STRING_SIZE];
952
946
      int buf_len= get_random_string(rand_buffer, RAND_STRING_SIZE);
953
947
 
954
 
      if (snprintf(buf, HUGE_STRING_LENGTH, "charcol%d = '%.*s'", col_count, 
955
 
                   buf_len, rand_buffer) 
 
948
      if (snprintf(buf, HUGE_STRING_LENGTH, "charcol%d = '%.*s'", col_count,
 
949
                   buf_len, rand_buffer)
956
950
          > HUGE_STRING_LENGTH)
957
951
      {
958
952
        fprintf(stderr, "Memory Allocation error in creating update\n");
968
962
    dynstr_append(&update_string, " WHERE id = ");
969
963
 
970
964
 
971
 
  ptr= (statement *)my_malloc(sizeof(statement), 
 
965
  ptr= (statement *)my_malloc(sizeof(statement),
972
966
                              MYF(MY_ZEROFILL|MY_FAE|MY_WME));
973
967
 
974
968
  ptr->string= (char *)my_malloc(update_string.length + 1,
1086
1080
      unsigned int size;
1087
1081
      unsigned int difference= num_blob_cols_size - num_blob_cols_size_min;
1088
1082
 
1089
 
      size= difference ? (num_blob_cols_size_min + (random() % difference)) : 
 
1083
      size= difference ? (num_blob_cols_size_min + (random() % difference)) :
1090
1084
                          num_blob_cols_size;
1091
1085
 
1092
1086
      buf_len= get_random_string(blob_ptr, size);
1150
1144
  {
1151
1145
    for (col_count= 1; col_count <= num_int_cols; col_count++)
1152
1146
    {
1153
 
      if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d", col_count) 
 
1147
      if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d", col_count)
1154
1148
          > HUGE_STRING_LENGTH)
1155
1149
      {
1156
1150
        fprintf(stderr, "Memory Allocation error in creating select\n");
1192
1186
  }
1193
1187
  dynstr_append(&query_string, " FROM t1");
1194
1188
 
1195
 
  if ((key) && 
 
1189
  if ((key) &&
1196
1190
      (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary))
1197
1191
    dynstr_append(&query_string, " WHERE id = ");
1198
1192
 
1201
1195
  ptr->string= (char *)my_malloc(query_string.length + 1,
1202
1196
                              MYF(MY_ZEROFILL|MY_FAE|MY_WME));
1203
1197
  ptr->length= query_string.length+1;
1204
 
  if ((key) && 
 
1198
  if ((key) &&
1205
1199
      (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary))
1206
1200
    ptr->type= SELECT_TYPE_REQUIRES_PREFIX;
1207
1201
  else
1243
1237
      exit(1);
1244
1238
  }
1245
1239
 
1246
 
  if (auto_generate_sql && auto_generate_sql_guid_primary && 
 
1240
  if (auto_generate_sql && auto_generate_sql_guid_primary &&
1247
1241
      auto_generate_sql_autoincrement)
1248
1242
  {
1249
1243
      fprintf(stderr,
1265
1259
  if (opt_csv_str)
1266
1260
  {
1267
1261
    opt_silent= true;
1268
 
    
 
1262
   
1269
1263
    if (opt_csv_str[0] == '-')
1270
1264
    {
1271
1265
      csv_file= fileno(stdout);
1344
1338
      printf("Building Create Statements for Auto\n");
1345
1339
 
1346
1340
    create_statements= build_table_string();
1347
 
    /* 
1348
 
      Pre-populate table 
 
1341
    /*
 
1342
      Pre-populate table
1349
1343
    */
1350
 
    for (ptr_statement= create_statements, x= 0; 
1351
 
         x < auto_generate_sql_unique_write_number; 
 
1344
    for (ptr_statement= create_statements, x= 0;
 
1345
         x < auto_generate_sql_unique_write_number;
1352
1346
         x++, ptr_statement= ptr_statement->next)
1353
1347
    {
1354
1348
      ptr_statement->next= build_insert_string();
1360
1354
    if (!opt_auto_generate_sql_type)
1361
1355
      opt_auto_generate_sql_type= "mixed";
1362
1356
 
1363
 
    query_statements_count= 
 
1357
    query_statements_count=
1364
1358
      parse_option(opt_auto_generate_sql_type, &query_options, ',');
1365
1359
 
1366
1360
    query_statements= (statement **)my_malloc(sizeof(statement *) * query_statements_count,
1375
1369
          printf("Generating SELECT Statements for Auto\n");
1376
1370
 
1377
1371
        query_statements[sql_type_count]= build_select_string(false);
1378
 
        for (ptr_statement= query_statements[sql_type_count], x= 0; 
1379
 
             x < auto_generate_sql_unique_query_number; 
 
1372
        for (ptr_statement= query_statements[sql_type_count], x= 0;
 
1373
             x < auto_generate_sql_unique_query_number;
1380
1374
             x++, ptr_statement= ptr_statement->next)
1381
1375
        {
1382
1376
          ptr_statement->next= build_select_string(false);
1397
1391
        }
1398
1392
 
1399
1393
        query_statements[sql_type_count]= build_select_string(true);
1400
 
        for (ptr_statement= query_statements[sql_type_count], x= 0; 
1401
 
             x < auto_generate_sql_unique_query_number; 
 
1394
        for (ptr_statement= query_statements[sql_type_count], x= 0;
 
1395
             x < auto_generate_sql_unique_query_number;
1402
1396
             x++, ptr_statement= ptr_statement->next)
1403
1397
        {
1404
1398
          ptr_statement->next= build_select_string(true);
1407
1401
      else if (sql_type->string[0] == 'w')
1408
1402
      {
1409
1403
        /*
1410
 
          We generate a number of strings in case the engine is 
 
1404
          We generate a number of strings in case the engine is
1411
1405
          Archive (since strings which were identical one after another
1412
1406
          would be too easily optimized).
1413
1407
        */
1414
1408
        if (verbose >= 2)
1415
1409
          printf("Generating INSERT Statements for Auto\n");
1416
1410
        query_statements[sql_type_count]= build_insert_string();
1417
 
        for (ptr_statement= query_statements[sql_type_count], x= 0; 
1418
 
             x < auto_generate_sql_unique_query_number; 
 
1411
        for (ptr_statement= query_statements[sql_type_count], x= 0;
 
1412
             x < auto_generate_sql_unique_query_number;
1419
1413
             x++, ptr_statement= ptr_statement->next)
1420
1414
        {
1421
1415
          ptr_statement->next= build_insert_string();
1433
1427
        }
1434
1428
 
1435
1429
        query_statements[sql_type_count]= build_update_string();
1436
 
        for (ptr_statement= query_statements[sql_type_count], x= 0; 
1437
 
             x < auto_generate_sql_unique_query_number; 
 
1430
        for (ptr_statement= query_statements[sql_type_count], x= 0;
 
1431
             x < auto_generate_sql_unique_query_number;
1438
1432
             x++, ptr_statement= ptr_statement->next)
1439
1433
        {
1440
1434
          ptr_statement->next= build_update_string();
1445
1439
        int coin= 0;
1446
1440
 
1447
1441
        query_statements[sql_type_count]= build_insert_string();
1448
 
        /* 
 
1442
        /*
1449
1443
          This logic should be extended to do a more mixed load,
1450
1444
          at the moment it results in "every other".
1451
1445
        */
1452
 
        for (ptr_statement= query_statements[sql_type_count], x= 0; 
1453
 
             x < auto_generate_sql_unique_query_number; 
 
1446
        for (ptr_statement= query_statements[sql_type_count], x= 0;
 
1447
             x < auto_generate_sql_unique_query_number;
1454
1448
             x++, ptr_statement= ptr_statement->next)
1455
1449
        {
1456
1450
          if (coin)
1473
1467
    if (create_string && !stat(create_string, &sbuf))
1474
1468
    {
1475
1469
      File data_file;
1476
 
      if (!MY_S_ISREG(sbuf.st_mode))
 
1470
      if (!S_ISREG(sbuf.st_mode))
1477
1471
      {
1478
1472
        fprintf(stderr,"%s: Create file was not a regular file\n",
1479
1473
                my_progname);
1500
1494
    /* Set this up till we fully support options on user generated queries */
1501
1495
    if (user_supplied_query)
1502
1496
    {
1503
 
      query_statements_count= 
 
1497
      query_statements_count=
1504
1498
        parse_option("default", &query_options, ',');
1505
1499
 
1506
1500
      query_statements= (statement **)my_malloc(sizeof(statement *),
1510
1504
    if (user_supplied_query && !stat(user_supplied_query, &sbuf))
1511
1505
    {
1512
1506
      File data_file;
1513
 
      if (!MY_S_ISREG(sbuf.st_mode))
 
1507
      if (!S_ISREG(sbuf.st_mode))
1514
1508
      {
1515
1509
        fprintf(stderr,"%s: User query supplied file was not a regular file\n",
1516
1510
                my_progname);
1530
1524
        actual_queries= parse_delimiter(tmp_string, &query_statements[0],
1531
1525
                                        delimiter[0]);
1532
1526
      my_free(tmp_string, MYF(0));
1533
 
    } 
 
1527
    }
1534
1528
    else if (user_supplied_query)
1535
1529
    {
1536
1530
      actual_queries= parse_delimiter(user_supplied_query, &query_statements[0],
1542
1536
      && !stat(user_supplied_pre_statements, &sbuf))
1543
1537
  {
1544
1538
    File data_file;
1545
 
    if (!MY_S_ISREG(sbuf.st_mode))
 
1539
    if (!S_ISREG(sbuf.st_mode))
1546
1540
    {
1547
1541
      fprintf(stderr,"%s: User query supplied file was not a regular file\n",
1548
1542
              my_progname);
1562
1556
      (void)parse_delimiter(tmp_string, &pre_statements,
1563
1557
                            delimiter[0]);
1564
1558
    my_free(tmp_string, MYF(0));
1565
 
  } 
 
1559
  }
1566
1560
  else if (user_supplied_pre_statements)
1567
1561
  {
1568
1562
    (void)parse_delimiter(user_supplied_pre_statements,
1574
1568
      && !stat(user_supplied_post_statements, &sbuf))
1575
1569
  {
1576
1570
    File data_file;
1577
 
    if (!MY_S_ISREG(sbuf.st_mode))
 
1571
    if (!S_ISREG(sbuf.st_mode))
1578
1572
    {
1579
1573
      fprintf(stderr,"%s: User query supplied file was not a regular file\n",
1580
1574
              my_progname);
1594
1588
      (void)parse_delimiter(tmp_string, &post_statements,
1595
1589
                            delimiter[0]);
1596
1590
    my_free(tmp_string, MYF(0));
1597
 
  } 
 
1591
  }
1598
1592
  else if (user_supplied_post_statements)
1599
1593
  {
1600
1594
    (void)parse_delimiter(user_supplied_post_statements, &post_statements,
1613
1607
}
1614
1608
 
1615
1609
 
1616
 
static int run_query(MYSQL *mysql, const char *query, int len)
 
1610
static int run_query(DRIZZLE *drizzle, const char *query, int len)
1617
1611
{
1618
1612
  if (opt_only_print)
1619
1613
  {
1623
1617
 
1624
1618
  if (verbose >= 3)
1625
1619
    printf("%.*s;\n", len, query);
1626
 
  return mysql_real_query(mysql, query, len);
 
1620
  return drizzle_real_query(drizzle, query, len);
1627
1621
}
1628
1622
 
1629
1623
 
1630
1624
static int
1631
 
generate_primary_key_list(MYSQL *mysql, option_string *engine_stmt)
 
1625
generate_primary_key_list(DRIZZLE *drizzle, option_string *engine_stmt)
1632
1626
{
1633
 
  MYSQL_RES *result;
1634
 
  MYSQL_ROW row;
 
1627
  DRIZZLE_RES *result;
 
1628
  DRIZZLE_ROW row;
1635
1629
  unsigned long long counter;
1636
1630
 
1637
1631
 
1638
 
  /* 
1639
 
    Blackhole is a special case, this allows us to test the upper end 
 
1632
  /*
 
1633
    Blackhole is a special case, this allows us to test the upper end
1640
1634
    of the server during load runs.
1641
1635
  */
1642
 
  if (opt_only_print || (engine_stmt && 
 
1636
  if (opt_only_print || (engine_stmt &&
1643
1637
                         strstr(engine_stmt->string, "blackhole")))
1644
1638
  {
1645
1639
    primary_keys_number_of= 1;
1646
 
    primary_keys= (char **)my_malloc((uint)(sizeof(char *) * 
1647
 
                                            primary_keys_number_of), 
 
1640
    primary_keys= (char **)my_malloc((uint)(sizeof(char *) *
 
1641
                                            primary_keys_number_of),
1648
1642
                                    MYF(MY_ZEROFILL|MY_FAE|MY_WME));
1649
1643
    /* Yes, we strdup a const string to simplify the interface */
1650
 
    primary_keys[0]= my_strdup("796c4422-1d94-102a-9d6d-00e0812d", MYF(0)); 
 
1644
    primary_keys[0]= my_strdup("796c4422-1d94-102a-9d6d-00e0812d", MYF(0));
1651
1645
  }
1652
1646
  else
1653
1647
  {
1654
 
    if (run_query(mysql, "SELECT id from t1", strlen("SELECT id from t1")))
 
1648
    if (run_query(drizzle, "SELECT id from t1", strlen("SELECT id from t1")))
1655
1649
    {
1656
1650
      fprintf(stderr,"%s: Cannot select GUID primary keys. (%s)\n", my_progname,
1657
 
              mysql_error(mysql));
 
1651
              drizzle_error(drizzle));
1658
1652
      exit(1);
1659
1653
    }
1660
1654
 
1661
 
    result= mysql_store_result(mysql);
1662
 
    primary_keys_number_of= mysql_num_rows(result);
 
1655
    result= drizzle_store_result(drizzle);
 
1656
    primary_keys_number_of= drizzle_num_rows(result);
1663
1657
 
1664
1658
    /* So why check this? Blackhole :) */
1665
1659
    if (primary_keys_number_of)
1667
1661
      /*
1668
1662
        We create the structure and loop and create the items.
1669
1663
      */
1670
 
      primary_keys= (char **)my_malloc((uint)(sizeof(char *) * 
1671
 
                                              primary_keys_number_of), 
 
1664
      primary_keys= (char **)my_malloc((uint)(sizeof(char *) *
 
1665
                                              primary_keys_number_of),
1672
1666
                                       MYF(MY_ZEROFILL|MY_FAE|MY_WME));
1673
 
      row= mysql_fetch_row(result);
1674
 
      for (counter= 0; counter < primary_keys_number_of; 
1675
 
           counter++, row= mysql_fetch_row(result))
 
1667
      row= drizzle_fetch_row(result);
 
1668
      for (counter= 0; counter < primary_keys_number_of;
 
1669
           counter++, row= drizzle_fetch_row(result))
1676
1670
        primary_keys[counter]= my_strdup(row[0], MYF(0));
1677
1671
    }
1678
1672
 
1679
 
    mysql_free_result(result);
 
1673
    drizzle_free_result(result);
1680
1674
  }
1681
1675
 
1682
1676
  return(0);
1699
1693
}
1700
1694
 
1701
1695
static int
1702
 
create_schema(MYSQL *mysql, const char *db, statement *stmt, 
 
1696
create_schema(DRIZZLE *drizzle, const char *db, statement *stmt,
1703
1697
              option_string *engine_stmt, stats *sptr)
1704
1698
{
1705
1699
  char query[HUGE_STRING_LENGTH];
1717
1711
  if (verbose >= 2)
1718
1712
    printf("Loading Pre-data\n");
1719
1713
 
1720
 
  if (run_query(mysql, query, len))
 
1714
  if (run_query(drizzle, query, len))
1721
1715
  {
1722
1716
    fprintf(stderr,"%s: Cannot create schema %s : %s\n", my_progname, db,
1723
 
            mysql_error(mysql));
 
1717
            drizzle_error(drizzle));
1724
1718
    exit(1);
1725
1719
  }
1726
1720
  else
1737
1731
    if (verbose >= 3)
1738
1732
      printf("%s;\n", query);
1739
1733
 
1740
 
    if (mysql_select_db(mysql,  db))
 
1734
    if (drizzle_select_db(drizzle,  db))
1741
1735
    {
1742
1736
      fprintf(stderr,"%s: Cannot select schema '%s': %s\n",my_progname, db,
1743
 
              mysql_error(mysql));
 
1737
              drizzle_error(drizzle));
1744
1738
      exit(1);
1745
1739
    }
1746
1740
    sptr->create_count++;
1750
1744
  {
1751
1745
    len= snprintf(query, HUGE_STRING_LENGTH, "set storage_engine=`%s`",
1752
1746
                  engine_stmt->string);
1753
 
    if (run_query(mysql, query, len))
 
1747
    if (run_query(drizzle, query, len))
1754
1748
    {
1755
1749
      fprintf(stderr,"%s: Cannot set default engine: %s\n", my_progname,
1756
 
              mysql_error(mysql));
 
1750
              drizzle_error(drizzle));
1757
1751
      exit(1);
1758
1752
    }
1759
1753
    sptr->create_count++;
1772
1766
    {
1773
1767
      char buffer[HUGE_STRING_LENGTH];
1774
1768
 
1775
 
      snprintf(buffer, HUGE_STRING_LENGTH, "%s %s", ptr->string, 
 
1769
      snprintf(buffer, HUGE_STRING_LENGTH, "%s %s", ptr->string,
1776
1770
               engine_stmt->option);
1777
 
      if (run_query(mysql, buffer, strlen(buffer)))
 
1771
      if (run_query(drizzle, buffer, strlen(buffer)))
1778
1772
      {
1779
1773
        fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
1780
 
                my_progname, (uint)ptr->length, ptr->string, mysql_error(mysql));
 
1774
                my_progname, (uint)ptr->length, ptr->string, drizzle_error(drizzle));
1781
1775
        if (!opt_ignore_sql_errors)
1782
1776
          exit(1);
1783
1777
      }
1785
1779
    }
1786
1780
    else
1787
1781
    {
1788
 
      if (run_query(mysql, ptr->string, ptr->length))
 
1782
      if (run_query(drizzle, ptr->string, ptr->length))
1789
1783
      {
1790
1784
        fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
1791
 
                my_progname, (uint)ptr->length, ptr->string, mysql_error(mysql));
 
1785
                my_progname, (uint)ptr->length, ptr->string, drizzle_error(drizzle));
1792
1786
        if (!opt_ignore_sql_errors)
1793
1787
          exit(1);
1794
1788
      }
1811
1805
}
1812
1806
 
1813
1807
static int
1814
 
drop_schema(MYSQL *mysql, const char *db)
 
1808
drop_schema(DRIZZLE *drizzle, const char *db)
1815
1809
{
1816
1810
  char query[HUGE_STRING_LENGTH];
1817
1811
  int len;
1818
1812
 
1819
1813
  len= snprintf(query, HUGE_STRING_LENGTH, "DROP SCHEMA IF EXISTS `%s`", db);
1820
1814
 
1821
 
  if (run_query(mysql, query, len))
 
1815
  if (run_query(drizzle, query, len))
1822
1816
  {
1823
1817
    fprintf(stderr,"%s: Cannot drop database '%s' ERROR : %s\n",
1824
 
            my_progname, db, mysql_error(mysql));
 
1818
            my_progname, db, drizzle_error(drizzle));
1825
1819
    exit(1);
1826
1820
  }
1827
1821
 
1831
1825
}
1832
1826
 
1833
1827
static int
1834
 
run_statements(MYSQL *mysql, statement *stmt) 
 
1828
run_statements(DRIZZLE *drizzle, statement *stmt)
1835
1829
{
1836
1830
  statement *ptr;
1837
 
  MYSQL_RES *result;
 
1831
  DRIZZLE_RES *result;
1838
1832
 
1839
1833
 
1840
1834
  for (ptr= stmt; ptr && ptr->length; ptr= ptr->next)
1841
1835
  {
1842
 
    if (run_query(mysql, ptr->string, ptr->length))
 
1836
    if (run_query(drizzle, ptr->string, ptr->length))
1843
1837
    {
1844
1838
      fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
1845
 
              my_progname, (uint)ptr->length, ptr->string, mysql_error(mysql));
 
1839
              my_progname, (uint)ptr->length, ptr->string, drizzle_error(drizzle));
1846
1840
      exit(1);
1847
1841
    }
1848
1842
    if (!opt_only_print)
1849
1843
    {
1850
 
      if (mysql_field_count(mysql))
 
1844
      if (drizzle_field_count(drizzle))
1851
1845
      {
1852
 
        result= mysql_store_result(mysql);
1853
 
        mysql_free_result(result);
 
1846
        result= drizzle_store_result(drizzle);
 
1847
        drizzle_free_result(result);
1854
1848
      }
1855
1849
    }
1856
1850
  }
1873
1867
 
1874
1868
  pthread_attr_init(&attr);
1875
1869
  pthread_attr_setdetachstate(&attr,
1876
 
                  PTHREAD_CREATE_DETACHED);
 
1870
      PTHREAD_CREATE_DETACHED);
1877
1871
 
1878
1872
  pthread_mutex_lock(&counter_mutex);
1879
1873
  thread_counter= 0;
1884
1878
 
1885
1879
  real_concurrency= 0;
1886
1880
 
1887
 
  for (y= 0, sql_type= query_options; 
1888
 
       y < query_statements_count; 
 
1881
  for (y= 0, sql_type= query_options;
 
1882
       y < query_statements_count;
1889
1883
       y++, sql_type= sql_type->next)
1890
1884
  {
1891
1885
    unsigned int options_loop= 1;
1892
1886
 
1893
1887
    if (sql_type->option)
1894
1888
    {
1895
 
      options_loop= strtol(sql_type->option, 
 
1889
      options_loop= strtol(sql_type->option,
1896
1890
                           (char **)NULL, 10);
1897
1891
      options_loop= options_loop ? options_loop : 1;
1898
1892
    }
1906
1900
 
1907
1901
        real_concurrency++;
1908
1902
        /* now you create the thread */
1909
 
        if (pthread_create(&mainthread, &attr, run_task, 
 
1903
        if (pthread_create(&mainthread, &attr, run_task,
1910
1904
                           (void *)con) != 0)
1911
1905
        {
1912
1906
          fprintf(stderr,"%s: Could not create thread\n", my_progname);
1916
1910
      }
1917
1911
  }
1918
1912
 
1919
 
  /* 
1920
 
    The timer_thread belongs to all threads so it too obeys the wakeup 
 
1913
  /*
 
1914
    The timer_thread belongs to all threads so it too obeys the wakeup
1921
1915
    call that run tasks obey.
1922
1916
  */
1923
1917
  if (opt_timer_length)
1926
1920
    timer_alarm= true;
1927
1921
    pthread_mutex_unlock(&timer_alarm_mutex);
1928
1922
 
1929
 
    if (pthread_create(&mainthread, &attr, timer_thread, 
 
1923
    if (pthread_create(&mainthread, &attr, timer_thread,
1930
1924
                       (void *)&opt_timer_length) != 0)
1931
1925
    {
1932
1926
      fprintf(stderr,"%s: Could not create timer thread\n", my_progname);
1976
1970
 
1977
1971
 
1978
1972
 
1979
 
  if (mysql_thread_init())
 
1973
  if (drizzle_thread_init())
1980
1974
  {
1981
 
    fprintf(stderr,"%s: mysql_thread_init() failed.\n",
 
1975
    fprintf(stderr,"%s: drizzle_thread_init() failed.\n",
1982
1976
            my_progname);
1983
1977
    exit(1);
1984
1978
  }
1985
1979
 
1986
 
  /* 
1987
 
    We lock around the initial call in case were we in a loop. This 
 
1980
  /*
 
1981
    We lock around the initial call in case were we in a loop. This
1988
1982
    also keeps the value properly syncronized across call threads.
1989
1983
  */
1990
1984
  pthread_mutex_lock(&sleeper_mutex);
2004
1998
  timer_alarm= false;
2005
1999
  pthread_mutex_unlock(&timer_alarm_mutex);
2006
2000
 
2007
 
  mysql_thread_end();
 
2001
  drizzle_thread_end();
2008
2002
  return(0);
2009
2003
}
2010
2004
 
2013
2007
  uint64_t counter= 0, queries;
2014
2008
  uint64_t detach_counter;
2015
2009
  unsigned int commit_counter;
2016
 
  MYSQL mysql;
2017
 
  MYSQL_RES *result;
2018
 
  MYSQL_ROW row;
 
2010
  DRIZZLE drizzle;
 
2011
  DRIZZLE_RES *result;
 
2012
  DRIZZLE_ROW row;
2019
2013
  statement *ptr;
2020
2014
  thread_context *con= (thread_context *)p;
2021
2015
 
2022
 
  if (mysql_thread_init())
 
2016
  if (drizzle_thread_init())
2023
2017
  {
2024
 
    fprintf(stderr,"%s: mysql_thread_init() failed.\n",
 
2018
    fprintf(stderr,"%s: drizzle_thread_init() failed.\n",
2025
2019
            my_progname);
2026
2020
    exit(1);
2027
2021
  }
2033
2027
  }
2034
2028
  pthread_mutex_unlock(&sleeper_mutex);
2035
2029
 
2036
 
  slap_connect(&mysql, true);
 
2030
  slap_connect(&drizzle, true);
2037
2031
 
2038
2032
  if (verbose >= 3)
2039
2033
    printf("connected!\n");
2041
2035
 
2042
2036
  commit_counter= 0;
2043
2037
  if (commit_rate)
2044
 
    run_query(&mysql, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
 
2038
    run_query(&drizzle, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
2045
2039
 
2046
2040
limit_not_met:
2047
 
    for (ptr= con->stmt, detach_counter= 0; 
2048
 
         ptr && ptr->length; 
 
2041
    for (ptr= con->stmt, detach_counter= 0;
 
2042
         ptr && ptr->length;
2049
2043
         ptr= ptr->next, detach_counter++)
2050
2044
    {
2051
2045
      if (!opt_only_print && detach_rate && !(detach_counter % detach_rate))
2052
2046
      {
2053
 
        slap_close(&mysql);
2054
 
        slap_connect(&mysql, true);
 
2047
        slap_close(&drizzle);
 
2048
        slap_connect(&drizzle, true);
2055
2049
      }
2056
2050
 
2057
 
      /* 
 
2051
      /*
2058
2052
        We have to execute differently based on query type. This should become a function.
2059
2053
      */
2060
2054
      if ((ptr->type == UPDATE_TYPE_REQUIRES_PREFIX) ||
2065
2059
        char *key;
2066
2060
        char buffer[HUGE_STRING_LENGTH];
2067
2061
 
2068
 
        /* 
 
2062
        /*
2069
2063
          This should only happen if some sort of new engine was
2070
2064
          implemented that didn't properly handle UPDATEs.
2071
2065
 
2080
2074
 
2081
2075
          assert(key);
2082
2076
 
2083
 
          length= snprintf(buffer, HUGE_STRING_LENGTH, "%.*s '%s'", 
 
2077
          length= snprintf(buffer, HUGE_STRING_LENGTH, "%.*s '%s'",
2084
2078
                           (int)ptr->length, ptr->string, key);
2085
2079
 
2086
 
          if (run_query(&mysql, buffer, length))
 
2080
          if (run_query(&drizzle, buffer, length))
2087
2081
          {
2088
2082
            fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
2089
 
                    my_progname, (uint)length, buffer, mysql_error(&mysql));
 
2083
                    my_progname, (uint)length, buffer, drizzle_error(&drizzle));
2090
2084
            exit(1);
2091
2085
          }
2092
2086
        }
2093
2087
      }
2094
2088
      else
2095
2089
      {
2096
 
        if (run_query(&mysql, ptr->string, ptr->length))
 
2090
        if (run_query(&drizzle, ptr->string, ptr->length))
2097
2091
        {
2098
2092
          fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
2099
 
                  my_progname, (uint)ptr->length, ptr->string, mysql_error(&mysql));
 
2093
                  my_progname, (uint)ptr->length, ptr->string, drizzle_error(&drizzle));
2100
2094
          exit(1);
2101
2095
        }
2102
2096
      }
2105
2099
      {
2106
2100
        do
2107
2101
        {
2108
 
          if (mysql_field_count(&mysql))
 
2102
          if (drizzle_field_count(&drizzle))
2109
2103
          {
2110
 
            result= mysql_store_result(&mysql);
2111
 
            while ((row = mysql_fetch_row(result)))
 
2104
            result= drizzle_store_result(&drizzle);
 
2105
            while ((row = drizzle_fetch_row(result)))
2112
2106
              counter++;
2113
 
            mysql_free_result(result);
 
2107
            drizzle_free_result(result);
2114
2108
          }
2115
 
        } while(mysql_next_result(&mysql) == 0);
 
2109
        } while(drizzle_next_result(&drizzle) == 0);
2116
2110
      }
2117
2111
      queries++;
2118
2112
 
2119
2113
      if (commit_rate && (++commit_counter == commit_rate))
2120
2114
      {
2121
2115
        commit_counter= 0;
2122
 
        run_query(&mysql, "COMMIT", strlen("COMMIT"));
 
2116
        run_query(&drizzle, "COMMIT", strlen("COMMIT"));
2123
2117
      }
2124
2118
 
2125
2119
      /* If the timer is set, and the alarm is not active then end */
2140
2134
 
2141
2135
end:
2142
2136
  if (commit_rate)
2143
 
    run_query(&mysql, "COMMIT", strlen("COMMIT"));
 
2137
    run_query(&drizzle, "COMMIT", strlen("COMMIT"));
2144
2138
 
2145
 
  slap_close(&mysql);
 
2139
  slap_close(&drizzle);
2146
2140
 
2147
2141
  pthread_mutex_lock(&counter_mutex);
2148
2142
  thread_counter--;
2151
2145
 
2152
2146
  my_free(con, MYF(0));
2153
2147
 
2154
 
  mysql_thread_end();
 
2148
  drizzle_thread_end();
2155
2149
  return(0);
2156
2150
}
2157
2151
 
2182
2176
    char buffer[HUGE_STRING_LENGTH];
2183
2177
    char *buffer_ptr;
2184
2178
 
2185
 
    bzero(buffer, HUGE_STRING_LENGTH);
 
2179
    memset(buffer, 0, HUGE_STRING_LENGTH);
2186
2180
 
2187
 
    string= strchr(begin_ptr, delm); 
 
2181
    string= strchr(begin_ptr, delm);
2188
2182
 
2189
2183
    if (string)
2190
2184
    {
2243
2237
 
2244
2238
  for (tmp= *sptr= (statement *)my_malloc(sizeof(statement),
2245
2239
                                          MYF(MY_ZEROFILL|MY_FAE|MY_WME));
2246
 
       (retstr= strchr(ptr, delm)); 
 
2240
       (retstr= strchr(ptr, delm));
2247
2241
       tmp->next=  (statement *)my_malloc(sizeof(statement),
2248
2242
                                          MYF(MY_ZEROFILL|MY_FAE|MY_WME)),
2249
2243
       tmp= tmp->next)
2258
2252
 
2259
2253
  if (ptr != script+length)
2260
2254
  {
2261
 
    tmp->string= my_strndup(ptr, (uint)((script + length) - ptr), 
 
2255
    tmp->string= my_strndup(ptr, (uint)((script + length) - ptr),
2262
2256
                                       MYF(MY_FAE));
2263
2257
    tmp->length= (size_t)((script + length) - ptr);
2264
2258
    count++;
2283
2277
 
2284
2278
  for (;*ptr; ptr++)
2285
2279
    if (*ptr == ',') count++;
2286
 
  
 
2280
 
2287
2281
  /* One extra spot for the NULL */
2288
 
  nptr= *range= (uint *)my_malloc(sizeof(uint) * (count + 1), 
 
2282
  nptr= *range= (uint *)my_malloc(sizeof(uint) * (count + 1),
2289
2283
                                  MYF(MY_ZEROFILL|MY_FAE|MY_WME));
2290
2284
 
2291
2285
  ptr= (char *)string;
2319
2313
         con->min_timing / 1000, con->min_timing % 1000);
2320
2314
  printf("\tMaximum number of seconds to run all queries: %ld.%03ld seconds\n",
2321
2315
         con->max_timing / 1000, con->max_timing % 1000);
2322
 
  printf("\tTotal time for tests: %ld.%03ld seconds\n", 
 
2316
  printf("\tTotal time for tests: %ld.%03ld seconds\n",
2323
2317
         con->sum_of_time / 1000, con->sum_of_time % 1000);
2324
2318
  printf("\tStandard Deviation: %ld.%03ld\n", con->std_dev / 1000, con->std_dev % 1000);
2325
2319
  printf("\tNumber of queries in create queries: %llu\n", con->create_count);
2326
 
  printf("\tNumber of clients running queries: %u/%u\n", 
 
2320
  printf("\tNumber of clients running queries: %u/%u\n",
2327
2321
         con->users, con->real_users);
2328
2322
  printf("\tNumber of times test was run: %u\n", iterations);
2329
 
  printf("\tAverage number of queries per client: %llu\n", con->avg_rows); 
 
2323
  printf("\tAverage number of queries per client: %llu\n", con->avg_rows);
2330
2324
  printf("\n");
2331
2325
}
2332
2326
 
2338
2332
  char label_buffer[HUGE_STRING_LENGTH];
2339
2333
  size_t string_len;
2340
2334
 
2341
 
  bzero(label_buffer, HUGE_STRING_LENGTH);
 
2335
  memset(label_buffer, 0, HUGE_STRING_LENGTH);
2342
2336
 
2343
2337
  if (opt_label)
2344
2338
  {
2351
2345
      else
2352
2346
        label_buffer[x]= opt_label[x] ;
2353
2347
    }
2354
 
  } 
 
2348
  }
2355
2349
  else if (opt_auto_generate_sql_type)
2356
2350
  {
2357
2351
    string_len= strlen(opt_auto_generate_sql_type);
2367
2361
  else
2368
2362
    snprintf(label_buffer, HUGE_STRING_LENGTH, "query");
2369
2363
 
2370
 
  snprintf(buffer, HUGE_STRING_LENGTH, 
 
2364
  snprintf(buffer, HUGE_STRING_LENGTH,
2371
2365
           "%s,%s,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,%u,%u,%u,%llu\n",
2372
2366
           con->engine ? con->engine : "", /* Storage engine we ran against */
2373
2367
           label_buffer, /* Load type */
2390
2384
  stats *ptr;
2391
2385
  unsigned int x;
2392
2386
 
2393
 
  con->min_timing= sptr->timing; 
 
2387
  con->min_timing= sptr->timing;
2394
2388
  con->max_timing= sptr->timing;
2395
2389
  con->min_rows= sptr->rows;
2396
2390
  con->max_rows= sptr->rows;
2397
 
  
 
2391
 
2398
2392
  /* At the moment we assume uniform */
2399
2393
  con->users= sptr->users;
2400
2394
  con->real_users= sptr->real_users;
2401
2395
  con->avg_rows= sptr->rows;
2402
 
  
 
2396
 
2403
2397
  /* With no next, we know it is the last element that was malloced */
2404
2398
  for (ptr= sptr, x= 0; x < iterations; ptr++, x++)
2405
2399
  {
2421
2415
  standard_deviation(con, sptr);
2422
2416
 
2423
2417
  /* Now we do the create time operations */
2424
 
  con->create_min_timing= sptr->create_timing; 
 
2418
  con->create_min_timing= sptr->create_timing;
2425
2419
  con->create_max_timing= sptr->create_timing;
2426
 
  
 
2420
 
2427
2421
  /* At the moment we assume uniform */
2428
2422
  con->create_count= sptr->create_count;
2429
 
  
 
2423
 
2430
2424
  /* With no next, we know it is the last element that was malloced */
2431
2425
  for (ptr= sptr, x= 0; x < iterations; ptr++, x++)
2432
2426
  {
2451
2445
  {
2452
2446
    nptr= ptr->next;
2453
2447
    if (ptr->string)
2454
 
      my_free(ptr->string, MYF(0)); 
 
2448
      my_free(ptr->string, MYF(0));
2455
2449
    if (ptr->option)
2456
 
      my_free(ptr->option, MYF(0)); 
 
2450
      my_free(ptr->option, MYF(0));
2457
2451
    my_free(ptr, MYF(0));
2458
2452
  }
2459
2453
}
2469
2463
  {
2470
2464
    nptr= ptr->next;
2471
2465
    if (ptr->string)
2472
 
      my_free(ptr->string, MYF(0)); 
 
2466
      my_free(ptr->string, MYF(0));
2473
2467
    my_free(ptr, MYF(0));
2474
2468
  }
2475
2469
}
2476
2470
 
2477
 
void 
2478
 
slap_close(MYSQL *mysql)
 
2471
void
 
2472
slap_close(DRIZZLE *drizzle)
2479
2473
{
2480
 
  if (opt_only_print) 
 
2474
  if (opt_only_print)
2481
2475
    return;
2482
2476
 
2483
 
  mysql_close(mysql);
 
2477
  drizzle_close(drizzle);
2484
2478
}
2485
2479
 
2486
 
void 
2487
 
slap_connect(MYSQL *mysql, bool connect_to_schema)
 
2480
void
 
2481
slap_connect(DRIZZLE *drizzle, bool connect_to_schema)
2488
2482
{
2489
2483
  /* Connect to server */
2490
2484
  static ulong connection_retry_sleep= 100000; /* Microseconds */
2491
2485
  int x, connect_error= 1;
2492
2486
 
2493
 
  if (opt_only_print) 
 
2487
  if (opt_only_print)
2494
2488
    return;
2495
2489
 
2496
2490
  if (opt_delayed_start)
2497
2491
    my_sleep(random()%opt_delayed_start);
2498
2492
 
2499
 
  mysql_init(mysql);
 
2493
  drizzle_create(drizzle);
2500
2494
 
2501
2495
  if (opt_compress)
2502
 
    mysql_options(mysql,MYSQL_OPT_COMPRESS,NullS);
 
2496
    drizzle_options(drizzle,DRIZZLE_OPT_COMPRESS,NullS);
2503
2497
  /* We always do opt_protocol to TCP/IP */
2504
 
  mysql_options(mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
2505
 
  mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset);
 
2498
  drizzle_options(drizzle,DRIZZLE_OPT_PROTOCOL,(char*)&opt_protocol);
 
2499
  drizzle_options(drizzle, DRIZZLE_SET_CHARSET_NAME, default_charset);
2506
2500
 
2507
2501
  for (x= 0; x < 10; x++)
2508
2502
  {
2509
2503
 
2510
2504
 
2511
 
    if (mysql_real_connect(mysql, host, user, opt_password,
 
2505
    if (drizzle_connect(drizzle, host, user, opt_password,
2512
2506
                           connect_to_schema ? create_schema_string : NULL,
2513
 
                           opt_mysql_port,
2514
 
                           opt_mysql_unix_port,
 
2507
                           opt_drizzle_port,
 
2508
                           opt_drizzle_unix_port,
2515
2509
                           connect_flags))
2516
2510
    {
2517
2511
      /* Connect suceeded */
2523
2517
  if (connect_error)
2524
2518
  {
2525
2519
    fprintf(stderr,"%s: Error when connecting to server: %d %s\n",
2526
 
            my_progname, mysql_errno(mysql), mysql_error(mysql));
 
2520
            my_progname, drizzle_errno(drizzle), drizzle_error(drizzle));
2527
2521
    exit(1);
2528
2522
  }
2529
2523
 
2530
2524
  return;
2531
2525
}
2532
2526
 
2533
 
void 
 
2527
void
2534
2528
standard_deviation (conclusions *con, stats *sptr)
2535
2529
{
2536
2530
  unsigned int x;