~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/mysqlslap.c

Removed dead variable, sorted authors file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2008 MySQL
5
 
 *
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; either version 2 of the License, or
9
 
 *  (at your option) any later version.
10
 
 *
11
 
 *  This program is distributed in the hope that it will be useful,
12
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 *  GNU General Public License for more details.
15
 
 *
16
 
 *  You should have received a copy of the GNU General Public License
17
 
 *  along with this program; if not, write to the Free Software
18
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
 
 */
 
1
/* Copyright (C) 2005 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
 
 
16
   original idea: Brian Aker via playing with ab for too many years
 
17
   coded by: Patrick Galbraith
 
18
*/
20
19
 
21
20
 
22
21
/*
23
 
  Drizzle Slap
 
22
  MySQL Slap
24
23
 
25
24
  A simple program designed to work as if multiple clients querying the database,
26
25
  then reporting the timing of each stage.
27
26
 
28
 
  Drizzle slap runs three stages:
 
27
  MySQL slap runs three stages:
29
28
  1) Create schema,table, and optionally any SP or data you want to beign
30
 
  the test with. (single client)
 
29
     the test with. (single client)
31
30
  2) Load test (many clients)
32
31
  3) Cleanup (disconnection, drop table if specified, single client)
33
32
 
34
33
  Examples:
35
34
 
36
 
  Supply your own create and query SQL statements, with 50 clients
 
35
  Supply your own create and query SQL statements, with 50 clients 
37
36
  querying (200 selects for each):
38
37
 
39
 
  drizzleslap --delimiter=";" \
40
 
  --create="CREATE TABLE A (a int);INSERT INTO A VALUES (23)" \
41
 
  --query="SELECT * FROM A" --concurrency=50 --iterations=200
 
38
    mysqlslap --delimiter=";" \
 
39
              --create="CREATE TABLE A (a int);INSERT INTO A VALUES (23)" \
 
40
              --query="SELECT * FROM A" --concurrency=50 --iterations=200
42
41
 
43
42
  Let the program build the query SQL statement with a table of two int
44
43
  columns, three varchar columns, five clients querying (20 times each),
45
44
  don't create the table or insert the data (using the previous test's
46
45
  schema and data):
47
46
 
48
 
  drizzleslap --concurrency=5 --iterations=20 \
49
 
  --number-int-cols=2 --number-char-cols=3 \
50
 
  --auto-generate-sql
 
47
    mysqlslap --concurrency=5 --iterations=20 \
 
48
              --number-int-cols=2 --number-char-cols=3 \
 
49
              --auto-generate-sql
51
50
 
52
51
  Tell the program to load the create, insert and query SQL statements from
53
52
  the specified files, where the create.sql file has multiple table creation
54
53
  statements delimited by ';' and multiple insert statements delimited by ';'.
55
 
  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 
56
55
  load statements, and then run all the queries in the query file
57
56
  with five clients (five times each):
58
57
 
59
 
  drizzleslap --concurrency=5 \
60
 
  --iterations=5 --query=query.sql --create=create.sql \
61
 
  --delimiter=";"
 
58
    mysqlslap --concurrency=5 \
 
59
              --iterations=5 --query=query.sql --create=create.sql \
 
60
              --delimiter=";"
62
61
 
63
 
  TODO:
 
62
TODO:
64
63
  Add language for better tests
65
64
  String length for files and those put on the command line are not
66
 
  setup to handle binary data.
 
65
    setup to handle binary data.
67
66
  More stats
68
67
  Break up tests and run them on multiple hosts at once.
69
68
  Allow output to be fed into a database directly.
77
76
#define DEFAULT_BLOB_SIZE 1024
78
77
 
79
78
#include "client_priv.h"
 
79
#include <mysqld_error.h>
 
80
#include <my_dir.h>
80
81
#include <signal.h>
81
82
#include <stdarg.h>
82
83
#include <sys/types.h>
83
84
#include <sys/wait.h>
84
85
#include <ctype.h>
85
 
#include <string>
86
 
 
87
 
using namespace std;
88
 
 
89
 
#ifdef HAVE_SMEM
 
86
 
 
87
#ifdef HAVE_SMEM 
90
88
static char *shared_memory_base_name=0;
91
89
#endif
92
90
 
106
104
static char **defaults_argv;
107
105
 
108
106
char **primary_keys;
109
 
uint64_t primary_keys_number_of;
 
107
unsigned long long primary_keys_number_of;
110
108
 
111
109
static char *host= NULL, *opt_password= NULL, *user= NULL,
112
 
  *user_supplied_query= NULL,
113
 
  *user_supplied_pre_statements= NULL,
114
 
  *user_supplied_post_statements= NULL,
115
 
  *default_engine= NULL,
116
 
  *pre_system= NULL,
117
 
  *post_system= NULL,
118
 
  *opt_drizzle_unix_port= NULL;
 
110
            *user_supplied_query= NULL,
 
111
            *user_supplied_pre_statements= NULL,
 
112
            *user_supplied_post_statements= NULL,
 
113
            *default_engine= NULL,
 
114
            *pre_system= NULL,
 
115
            *post_system= NULL,
 
116
            *opt_mysql_unix_port= NULL;
119
117
 
120
118
const char *delimiter= "\n";
121
119
 
122
 
const char *create_schema_string= "drizzleslap";
 
120
const char *create_schema_string= "mysqlslap";
123
121
 
124
122
static bool opt_preserve= true;
125
123
static bool debug_info_flag= 0, debug_check_flag= 0;
127
125
static bool opt_burnin= false;
128
126
static bool opt_ignore_sql_errors= false;
129
127
static bool opt_compress= false, tty_password= false,
130
 
  opt_silent= false,
131
 
  auto_generate_sql_autoincrement= false,
132
 
  auto_generate_sql_guid_primary= false,
133
 
  auto_generate_sql= false;
 
128
               opt_silent= false,
 
129
               auto_generate_sql_autoincrement= false,
 
130
               auto_generate_sql_guid_primary= false,
 
131
               auto_generate_sql= false;
134
132
const char *opt_auto_generate_sql_type= "mixed";
135
133
 
136
134
static unsigned long connect_flags= CLIENT_MULTI_RESULTS |
137
 
  CLIENT_MULTI_STATEMENTS;
 
135
                                    CLIENT_MULTI_STATEMENTS;
138
136
 
139
137
static int verbose, delimiter_length;
140
138
static uint commit_rate;
155
153
static unsigned int num_blob_cols= 0;
156
154
static unsigned int num_blob_cols_size;
157
155
static unsigned int num_blob_cols_size_min;
158
 
static unsigned int num_int_cols_index= 0;
 
156
static unsigned int num_int_cols_index= 0; 
159
157
static unsigned int num_char_cols_index= 0;
160
158
static unsigned int iterations;
161
159
static uint my_end_arg= 0;
 
160
static char *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
162
161
static uint64_t actual_queries= 0;
163
162
static uint64_t auto_actual_queries;
164
163
static uint64_t auto_generate_sql_unique_write_number;
170
169
static char *create_string;
171
170
uint *concurrency;
172
171
 
173
 
const char *default_dbug_option="d:t:o,/tmp/drizzleslap.trace";
 
172
const char *default_dbug_option="d:t:o,/tmp/mysqlslap.trace";
174
173
const char *opt_csv_str;
175
174
File csv_file;
176
175
 
 
176
static uint opt_protocol= MYSQL_PROTOCOL_TCP;
 
177
 
177
178
static int get_options(int *argc,char ***argv);
178
 
static uint opt_drizzle_port= 0;
 
179
static uint opt_mysql_port= 0;
179
180
 
180
 
static const char *load_default_groups[]= { "drizzleslap","client",0 };
 
181
static const char *load_default_groups[]= { "mysqlslap","client",0 };
181
182
 
182
183
/* Types */
183
184
typedef enum {
217
218
  long int timing;
218
219
  uint users;
219
220
  uint real_users;
220
 
  uint64_t rows;
 
221
  unsigned long long rows;
221
222
  long int create_timing;
222
 
  uint64_t create_count;
 
223
  unsigned long long create_count;
223
224
};
224
225
 
225
226
typedef struct thread_context thread_context;
238
239
  long int min_timing;
239
240
  uint users;
240
241
  uint real_users;
241
 
  uint64_t avg_rows;
 
242
  unsigned long long avg_rows;
242
243
  long int sum_of_time;
243
244
  long int std_dev;
244
245
  /* These are just for create time stats */
245
246
  long int create_avg_timing;
246
247
  long int create_max_timing;
247
248
  long int create_min_timing;
248
 
  uint64_t create_count;
 
249
  unsigned long long create_count;
249
250
  /* The following are not used yet */
250
 
  uint64_t max_rows;
251
 
  uint64_t min_rows;
 
251
  unsigned long long max_rows;
 
252
  unsigned long long min_rows;
252
253
};
253
254
 
254
255
static option_string *engine_options= NULL;
255
 
static option_string *query_options= NULL;
256
 
static statement *pre_statements= NULL;
257
 
static statement *post_statements= NULL;
 
256
static option_string *query_options= NULL; 
 
257
static statement *pre_statements= NULL; 
 
258
static statement *post_statements= NULL; 
258
259
static statement *create_statements= NULL;
259
260
 
260
261
static statement **query_statements= NULL;
268
269
uint parse_comma(const char *string, uint **range);
269
270
uint parse_delimiter(const char *script, statement **stmt, char delm);
270
271
uint parse_option(const char *origin, option_string **stmt, char delm);
271
 
static int drop_schema(DRIZZLE *drizzle, const char *db);
 
272
static int drop_schema(MYSQL *mysql, const char *db);
272
273
uint get_random_string(char *buf, size_t size);
273
274
static statement *build_table_string(void);
274
275
static statement *build_insert_string(void);
275
276
static statement *build_update_string(void);
276
277
static statement * build_select_string(bool key);
277
 
static int generate_primary_key_list(DRIZZLE *drizzle, option_string *engine_stmt);
 
278
static int generate_primary_key_list(MYSQL *mysql, option_string *engine_stmt);
278
279
static int drop_primary_key_list(void);
279
 
static int create_schema(DRIZZLE *drizzle, const char *db, statement *stmt,
 
280
static int create_schema(MYSQL *mysql, const char *db, statement *stmt, 
280
281
                         option_string *engine_stmt, stats *sptr);
281
 
static int run_scheduler(stats *sptr, statement **stmts, uint concur,
 
282
static int run_scheduler(stats *sptr, statement **stmts, uint concur, 
282
283
                         uint64_t limit);
283
284
pthread_handler_t run_task(void *p);
284
285
pthread_handler_t timer_thread(void *p);
285
286
void statement_cleanup(statement *stmt);
286
287
void option_cleanup(option_string *stmt);
287
 
void concurrency_loop(DRIZZLE *drizzle, uint current, option_string *eptr);
288
 
static int run_statements(DRIZZLE *drizzle, statement *stmt);
289
 
void slap_connect(DRIZZLE *drizzle, bool connect_to_schema);
290
 
void slap_close(DRIZZLE *drizzle);
291
 
static int run_query(DRIZZLE *drizzle, const char *query, int len);
 
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);
292
293
void standard_deviation (conclusions *con, stats *sptr);
293
294
 
294
295
static const char ALPHANUMERICS[]=
295
 
"0123456789ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstuvwxyz";
 
296
  "0123456789ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstuvwxyz";
296
297
 
297
298
#define ALPHANUMERICS_SIZE (sizeof(ALPHANUMERICS)-1)
298
299
 
299
300
 
300
301
static long int timedif(struct timeval a, struct timeval b)
301
302
{
302
 
  register int us, s;
303
 
 
304
 
  us = a.tv_usec - b.tv_usec;
305
 
  us /= 1000;
306
 
  s = a.tv_sec - b.tv_sec;
307
 
  s *= 1000;
308
 
  return s + us;
 
303
    register int us, s;
 
304
 
 
305
    us = a.tv_usec - b.tv_usec;
 
306
    us /= 1000;
 
307
    s = a.tv_sec - b.tv_sec;
 
308
    s *= 1000;
 
309
    return s + us;
309
310
}
310
311
 
311
312
int main(int argc, char **argv)
312
313
{
313
 
  DRIZZLE drizzle;
 
314
  MYSQL mysql;
314
315
  option_string *eptr;
315
316
  unsigned int x;
316
317
 
318
319
 
319
320
  MY_INIT(argv[0]);
320
321
 
 
322
  if (!(mysql_thread_safe()))
 
323
      fprintf(stderr, "This application was compiled incorrectly. Please recompile with thread support.\n");
 
324
 
321
325
  load_defaults("my",load_default_groups,&argc,&argv);
322
326
  defaults_argv=argv;
323
327
  if (get_options(&argc,&argv))
346
350
    exit(1);
347
351
  }
348
352
 
349
 
  slap_connect(&drizzle, false);
 
353
  slap_connect(&mysql, false);
350
354
 
351
 
  pthread_mutex_init(&counter_mutex, NULL);
352
 
  pthread_cond_init(&count_threshhold, NULL);
353
 
  pthread_mutex_init(&sleeper_mutex, NULL);
354
 
  pthread_cond_init(&sleep_threshhold, NULL);
355
 
  pthread_mutex_init(&timer_alarm_mutex, NULL);
356
 
  pthread_cond_init(&timer_alarm_threshold, NULL);
 
355
  VOID(pthread_mutex_init(&counter_mutex, NULL));
 
356
  VOID(pthread_cond_init(&count_threshhold, NULL));
 
357
  VOID(pthread_mutex_init(&sleeper_mutex, NULL));
 
358
  VOID(pthread_cond_init(&sleep_threshhold, NULL));
 
359
  VOID(pthread_mutex_init(&timer_alarm_mutex, NULL));
 
360
  VOID(pthread_cond_init(&timer_alarm_threshold, NULL));
357
361
 
358
362
 
359
363
  /* Main iterations loop */
370
374
    if (*concurrency)
371
375
    {
372
376
      for (current= concurrency; current && *current; current++)
373
 
        concurrency_loop(&drizzle, *current, eptr);
 
377
        concurrency_loop(&mysql, *current, eptr);
374
378
    }
375
379
    else
376
380
    {
377
381
      uint infinite= 1;
378
382
      do {
379
 
        concurrency_loop(&drizzle, infinite, eptr);
 
383
        concurrency_loop(&mysql, infinite, eptr);
380
384
      }
381
385
      while (infinite++);
382
386
    }
383
387
 
384
388
    if (!opt_preserve)
385
 
      drop_schema(&drizzle, create_schema_string);
 
389
      drop_schema(&mysql, create_schema_string);
386
390
 
387
391
  } while (eptr ? (eptr= eptr->next) : 0);
388
 
 
 
392
  
389
393
  if (opt_burnin)
390
394
    goto burnin;
391
395
 
392
 
  pthread_mutex_destroy(&counter_mutex);
393
 
  pthread_cond_destroy(&count_threshhold);
394
 
  pthread_mutex_destroy(&sleeper_mutex);
395
 
  pthread_cond_destroy(&sleep_threshhold);
396
 
  pthread_mutex_destroy(&timer_alarm_mutex);
397
 
  pthread_cond_destroy(&timer_alarm_threshold);
 
396
  VOID(pthread_mutex_destroy(&counter_mutex));
 
397
  VOID(pthread_cond_destroy(&count_threshhold));
 
398
  VOID(pthread_mutex_destroy(&sleeper_mutex));
 
399
  VOID(pthread_cond_destroy(&sleep_threshhold));
 
400
  VOID(pthread_mutex_destroy(&timer_alarm_mutex));
 
401
  VOID(pthread_cond_destroy(&timer_alarm_threshold));
398
402
 
399
 
  slap_close(&drizzle);
 
403
  slap_close(&mysql);
400
404
 
401
405
  /* now free all the strings we created */
402
406
  if (opt_password)
403
 
    free(opt_password);
 
407
    my_free(opt_password, MYF(0));
404
408
 
405
 
  free(concurrency);
 
409
  my_free(concurrency, MYF(0));
406
410
 
407
411
  statement_cleanup(create_statements);
408
412
  for (x= 0; x < query_statements_count; x++)
409
413
    statement_cleanup(query_statements[x]);
410
 
  free(query_statements);
 
414
  my_free(query_statements, MYF(0));
411
415
  statement_cleanup(pre_statements);
412
416
  statement_cleanup(post_statements);
413
417
  option_cleanup(engine_options);
415
419
 
416
420
#ifdef HAVE_SMEM
417
421
  if (shared_memory_base_name)
418
 
    free(shared_memory_base_name);
 
422
    my_free(shared_memory_base_name, MYF(MY_ALLOW_ZERO_PTR));
419
423
#endif
420
424
  free_defaults(defaults_argv);
421
425
  my_end(my_end_arg);
423
427
  return 0;
424
428
}
425
429
 
426
 
void concurrency_loop(DRIZZLE *drizzle, uint current, option_string *eptr)
 
430
void concurrency_loop(MYSQL *mysql, uint current, option_string *eptr)
427
431
{
428
432
  unsigned int x;
429
433
  stats *head_sptr;
430
434
  stats *sptr;
431
435
  conclusions conclusion;
432
 
  uint64_t client_limit;
 
436
  unsigned long long client_limit;
433
437
 
434
 
  head_sptr= (stats *)my_malloc(sizeof(stats) * iterations,
 
438
  head_sptr= (stats *)my_malloc(sizeof(stats) * iterations, 
435
439
                                MYF(MY_ZEROFILL|MY_FAE|MY_WME));
436
440
 
437
 
  memset(&conclusion, 0, sizeof(conclusions));
 
441
  bzero(&conclusion, sizeof(conclusions));
438
442
 
439
443
  if (auto_actual_queries)
440
444
    client_limit= auto_actual_queries;
451
455
      data in the table.
452
456
    */
453
457
    if (opt_preserve == false)
454
 
      drop_schema(drizzle, create_schema_string);
 
458
      drop_schema(mysql, create_schema_string);
455
459
 
456
460
    /* First we create */
457
461
    if (create_statements)
458
 
      create_schema(drizzle, create_schema_string, create_statements, eptr, sptr);
 
462
      create_schema(mysql, create_schema_string, create_statements, eptr, sptr);
459
463
 
460
464
    /*
461
465
      If we generated GUID we need to build a list of them from creation that
464
468
    if (verbose >= 2)
465
469
      printf("Generating primary key list\n");
466
470
    if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
467
 
      generate_primary_key_list(drizzle, eptr);
 
471
      generate_primary_key_list(mysql, eptr);
468
472
 
469
473
    if (commit_rate)
470
 
      run_query(drizzle, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
 
474
      run_query(mysql, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
471
475
 
472
476
    if (pre_system)
473
477
      system(pre_system);
474
478
 
475
 
    /*
476
 
      Pre statements are always run after all other logic so they can
477
 
      correct/adjust any item that they want.
 
479
    /* 
 
480
      Pre statements are always run after all other logic so they can 
 
481
      correct/adjust any item that they want. 
478
482
    */
479
483
    if (pre_statements)
480
 
      run_statements(drizzle, pre_statements);
481
 
 
482
 
    run_scheduler(sptr, query_statements, current, client_limit);
483
 
 
 
484
      run_statements(mysql, pre_statements);
 
485
 
 
486
    run_scheduler(sptr, query_statements, current, client_limit); 
 
487
    
484
488
    if (post_statements)
485
 
      run_statements(drizzle, post_statements);
 
489
      run_statements(mysql, post_statements);
486
490
 
487
491
    if (post_system)
488
492
      system(post_system);
502
506
  if (opt_csv_str)
503
507
    print_conclusions_csv(&conclusion);
504
508
 
505
 
  free(head_sptr);
 
509
  my_free(head_sptr, MYF(0));
506
510
 
507
511
}
508
512
 
510
514
static struct my_option my_long_options[] =
511
515
{
512
516
  {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
513
 
   0, 0, 0, 0, 0, 0},
 
517
    0, 0, 0, 0, 0, 0},
514
518
  {"auto-generate-sql-select-columns", OPT_SLAP_AUTO_GENERATE_SELECT_COLUMNS,
515
 
   "Provide a string to use for the select fields used in auto tests.",
516
 
   (char**) &auto_generate_selected_columns_opt,
517
 
   (char**) &auto_generate_selected_columns_opt,
518
 
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
519
    "Provide a string to use for the select fields used in auto tests.",
 
520
    (char**) &auto_generate_selected_columns_opt, 
 
521
    (char**) &auto_generate_selected_columns_opt,
 
522
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
519
523
  {"auto-generate-sql", 'a',
520
 
   "Generate SQL where not supplied by file or command line.",
521
 
   (char**) &auto_generate_sql, (char**) &auto_generate_sql,
522
 
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
524
    "Generate SQL where not supplied by file or command line.",
 
525
    (char**) &auto_generate_sql, (char**) &auto_generate_sql,
 
526
    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
523
527
  {"auto-generate-sql-add-autoincrement", OPT_SLAP_AUTO_GENERATE_ADD_AUTO,
524
 
   "Add an AUTO_INCREMENT column to auto-generated tables.",
525
 
   (char**) &auto_generate_sql_autoincrement,
526
 
   (char**) &auto_generate_sql_autoincrement,
527
 
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
528
    "Add an AUTO_INCREMENT column to auto-generated tables.",
 
529
    (char**) &auto_generate_sql_autoincrement, 
 
530
    (char**) &auto_generate_sql_autoincrement,
 
531
    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
528
532
  {"auto-generate-sql-execute-number", OPT_SLAP_AUTO_GENERATE_EXECUTE_QUERIES,
529
 
   "Set this number to generate a set number of queries to run.",
530
 
   (char**) &auto_actual_queries, (char**) &auto_actual_queries,
531
 
   0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
533
    "Set this number to generate a set number of queries to run.",
 
534
    (char**) &auto_actual_queries, (char**) &auto_actual_queries,
 
535
    0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
532
536
  {"auto-generate-sql-guid-primary", OPT_SLAP_AUTO_GENERATE_GUID_PRIMARY,
533
 
   "Add GUID based primary keys to auto-generated tables.",
534
 
   (char**) &auto_generate_sql_guid_primary,
535
 
   (char**) &auto_generate_sql_guid_primary,
536
 
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
537
    "Add GUID based primary keys to auto-generated tables.",
 
538
    (char**) &auto_generate_sql_guid_primary, 
 
539
    (char**) &auto_generate_sql_guid_primary,
 
540
    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
537
541
  {"auto-generate-sql-load-type", OPT_SLAP_AUTO_GENERATE_SQL_LOAD_TYPE,
538
 
   "Specify test load type: mixed, update, write, key, or read; default is mixed.",
539
 
   (char**) &opt_auto_generate_sql_type, (char**) &opt_auto_generate_sql_type,
540
 
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
541
 
  {"auto-generate-sql-secondary-indexes",
542
 
   OPT_SLAP_AUTO_GENERATE_SECONDARY_INDEXES,
543
 
   "Number of secondary indexes to add to auto-generated tables.",
544
 
   (char**) &auto_generate_sql_secondary_indexes,
545
 
   (char**) &auto_generate_sql_secondary_indexes, 0,
546
 
   GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
547
 
  {"auto-generate-sql-unique-query-number",
548
 
   OPT_SLAP_AUTO_GENERATE_UNIQUE_QUERY_NUM,
549
 
   "Number of unique queries to generate for automatic tests.",
550
 
   (char**) &auto_generate_sql_unique_query_number,
551
 
   (char**) &auto_generate_sql_unique_query_number,
552
 
   0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
553
 
  {"auto-generate-sql-unique-write-number",
554
 
   OPT_SLAP_AUTO_GENERATE_UNIQUE_WRITE_NUM,
555
 
   "Number of unique queries to generate for auto-generate-sql-write-number.",
556
 
   (char**) &auto_generate_sql_unique_write_number,
557
 
   (char**) &auto_generate_sql_unique_write_number,
558
 
   0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
 
542
    "Specify test load type: mixed, update, write, key, or read; default is mixed.",
 
543
    (char**) &opt_auto_generate_sql_type, (char**) &opt_auto_generate_sql_type,
 
544
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
545
  {"auto-generate-sql-secondary-indexes", 
 
546
    OPT_SLAP_AUTO_GENERATE_SECONDARY_INDEXES, 
 
547
    "Number of secondary indexes to add to auto-generated tables.",
 
548
    (char**) &auto_generate_sql_secondary_indexes, 
 
549
    (char**) &auto_generate_sql_secondary_indexes, 0,
 
550
    GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
551
  {"auto-generate-sql-unique-query-number", 
 
552
    OPT_SLAP_AUTO_GENERATE_UNIQUE_QUERY_NUM,
 
553
    "Number of unique queries to generate for automatic tests.",
 
554
    (char**) &auto_generate_sql_unique_query_number, 
 
555
    (char**) &auto_generate_sql_unique_query_number,
 
556
    0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
 
557
  {"auto-generate-sql-unique-write-number", 
 
558
    OPT_SLAP_AUTO_GENERATE_UNIQUE_WRITE_NUM,
 
559
    "Number of unique queries to generate for auto-generate-sql-write-number.",
 
560
    (char**) &auto_generate_sql_unique_write_number, 
 
561
    (char**) &auto_generate_sql_unique_write_number,
 
562
    0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
559
563
  {"auto-generate-sql-write-number", OPT_SLAP_AUTO_GENERATE_WRITE_NUM,
560
 
   "Number of row inserts to perform for each thread (default is 100).",
561
 
   (char**) &auto_generate_sql_number, (char**) &auto_generate_sql_number,
562
 
   0, GET_ULL, REQUIRED_ARG, 100, 0, 0, 0, 0, 0},
 
564
    "Number of row inserts to perform for each thread (default is 100).",
 
565
    (char**) &auto_generate_sql_number, (char**) &auto_generate_sql_number,
 
566
    0, GET_ULL, REQUIRED_ARG, 100, 0, 0, 0, 0, 0},
563
567
  {"burnin", OPT_SLAP_BURNIN, "Run full test case in infinite loop.",
564
 
   (char**) &opt_burnin, (char**) &opt_burnin, 0, GET_BOOL, NO_ARG, 0, 0, 0,
565
 
   0, 0, 0},
566
 
  {"ignore-sql-errors", OPT_SLAP_IGNORE_SQL_ERRORS,
567
 
   "Ignore SQL erros in query run.",
568
 
   (char**) &opt_ignore_sql_errors,
569
 
   (char**) &opt_ignore_sql_errors,
570
 
   0, GET_BOOL, NO_ARG, 0, 0, 0,
571
 
   0, 0, 0},
 
568
    (char**) &opt_burnin, (char**) &opt_burnin, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
569
    0, 0, 0},
 
570
  {"ignore-sql-errors", OPT_SLAP_IGNORE_SQL_ERRORS, 
 
571
    "Ignore SQL erros in query run.",
 
572
    (char**) &opt_ignore_sql_errors, 
 
573
    (char**) &opt_ignore_sql_errors, 
 
574
    0, GET_BOOL, NO_ARG, 0, 0, 0,
 
575
    0, 0, 0},
572
576
  {"commit", OPT_SLAP_COMMIT, "Commit records every X number of statements.",
573
 
   (char**) &commit_rate, (char**) &commit_rate, 0, GET_UINT, REQUIRED_ARG,
574
 
   0, 0, 0, 0, 0, 0},
 
577
    (char**) &commit_rate, (char**) &commit_rate, 0, GET_UINT, REQUIRED_ARG,
 
578
    0, 0, 0, 0, 0, 0},
575
579
  {"compress", 'C', "Use compression in server/client protocol.",
576
 
   (char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
577
 
   0, 0, 0},
 
580
    (char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
581
    0, 0, 0},
578
582
  {"concurrency", 'c', "Number of clients to simulate for query to run.",
579
 
   (char**) &concurrency_str, (char**) &concurrency_str, 0, GET_STR,
580
 
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
583
    (char**) &concurrency_str, (char**) &concurrency_str, 0, GET_STR,
 
584
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
581
585
  {"create", OPT_SLAP_CREATE_STRING, "File or string to use create tables.",
582
 
   (char**) &create_string, (char**) &create_string, 0, GET_STR, REQUIRED_ARG,
583
 
   0, 0, 0, 0, 0, 0},
 
586
    (char**) &create_string, (char**) &create_string, 0, GET_STR, REQUIRED_ARG,
 
587
    0, 0, 0, 0, 0, 0},
584
588
  {"create-schema", OPT_CREATE_SLAP_SCHEMA, "Schema to run tests in.",
585
 
   (char**) &create_schema_string, (char**) &create_schema_string, 0, GET_STR,
586
 
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
589
    (char**) &create_schema_string, (char**) &create_schema_string, 0, GET_STR, 
 
590
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
587
591
  {"csv", OPT_SLAP_CSV,
588
 
   "Generate CSV output to named file or to stdout if no file is named.",
589
 
   (char**) &opt_csv_str, (char**) &opt_csv_str, 0, GET_STR,
590
 
   OPT_ARG, 0, 0, 0, 0, 0, 0},
 
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, 
 
594
    OPT_ARG, 0, 0, 0, 0, 0, 0},
591
595
  {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
592
 
    (char**) &debug_check_flag, (char**) &debug_check_flag, 0,
593
 
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
596
   (char**) &debug_check_flag, (char**) &debug_check_flag, 0,
 
597
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
594
598
  {"debug-info", 'T', "Print some debug info at exit.", (char**) &debug_info_flag,
595
 
    (char**) &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
596
 
  {"delayed-start", OPT_SLAP_DELAYED_START,
597
 
   "Delay the startup of threads by a random number of microsends (the maximum of the delay)",
598
 
   (char**) &opt_delayed_start, (char**) &opt_delayed_start, 0, GET_UINT,
599
 
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
599
   (char**) &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
600
  {"delayed-start", OPT_SLAP_DELAYED_START, 
 
601
    "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, 
 
603
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
600
604
  {"delimiter", 'F',
601
 
   "Delimiter to use in SQL statements supplied in file or command line.",
602
 
   (char**) &delimiter, (char**) &delimiter, 0, GET_STR, REQUIRED_ARG,
603
 
   0, 0, 0, 0, 0, 0},
 
605
    "Delimiter to use in SQL statements supplied in file or command line.",
 
606
    (char**) &delimiter, (char**) &delimiter, 0, GET_STR, REQUIRED_ARG,
 
607
    0, 0, 0, 0, 0, 0},
604
608
  {"detach", OPT_SLAP_DETACH,
605
 
   "Detach (close and reopen) connections after X number of requests.",
606
 
   (char**) &detach_rate, (char**) &detach_rate, 0, GET_UINT, REQUIRED_ARG,
607
 
   0, 0, 0, 0, 0, 0},
 
609
    "Detach (close and reopen) connections after X number of requests.",
 
610
    (char**) &detach_rate, (char**) &detach_rate, 0, GET_UINT, REQUIRED_ARG, 
 
611
    0, 0, 0, 0, 0, 0},
608
612
  {"engine", 'e', "Storage engine to use for creating the table.",
609
 
   (char**) &default_engine, (char**) &default_engine, 0,
610
 
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
613
    (char**) &default_engine, (char**) &default_engine, 0,
 
614
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
611
615
  {"host", 'h', "Connect to host.", (char**) &host, (char**) &host, 0, GET_STR,
612
 
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
616
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
613
617
  {"iterations", 'i', "Number of times to run the tests.", (char**) &iterations,
614
 
   (char**) &iterations, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0},
 
618
    (char**) &iterations, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0},
615
619
  {"label", OPT_SLAP_LABEL, "Label to use for print and csv output.",
616
 
   (char**) &opt_label, (char**) &opt_label, 0,
617
 
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
618
 
  {"number-blob-cols", OPT_SLAP_BLOB_COL,
619
 
   "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. ",
620
 
   (char**) &num_blob_cols_opt, (char**) &num_blob_cols_opt, 0, GET_STR, REQUIRED_ARG,
621
 
   0, 0, 0, 0, 0, 0},
622
 
  {"number-char-cols", 'x',
623
 
   "Number of VARCHAR columns to create in table if specifying --auto-generate-sql.",
624
 
   (char**) &num_char_cols_opt, (char**) &num_char_cols_opt, 0, GET_STR, REQUIRED_ARG,
625
 
   0, 0, 0, 0, 0, 0},
626
 
  {"number-int-cols", 'y',
627
 
   "Number of INT columns to create in table if specifying --auto-generate-sql.",
628
 
   (char**) &num_int_cols_opt, (char**) &num_int_cols_opt, 0, GET_STR, REQUIRED_ARG,
629
 
   0, 0, 0, 0, 0, 0},
630
 
  {"number-of-queries", OPT_DRIZZLE_NUMBER_OF_QUERY,
631
 
   "Limit each client to this number of queries (this is not exact).",
632
 
   (char**) &num_of_query, (char**) &num_of_query, 0,
633
 
   GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
634
 
  {"only-print", OPT_DRIZZLE_ONLY_PRINT,
635
 
   "This causes drizzleslap to not connect to the databases, but instead print "
636
 
   "out what it would have done instead.",
637
 
   (char**) &opt_only_print, (char**) &opt_only_print, 0, GET_BOOL,  NO_ARG,
638
 
   0, 0, 0, 0, 0, 0},
 
620
    (char**) &opt_label, (char**) &opt_label, 0,
 
621
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
622
  {"number-blob-cols", OPT_SLAP_BLOB_COL, 
 
623
    "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
    (char**) &num_blob_cols_opt, (char**) &num_blob_cols_opt, 0, GET_STR, REQUIRED_ARG,
 
625
    0, 0, 0, 0, 0, 0},
 
626
  {"number-char-cols", 'x', 
 
627
    "Number of VARCHAR columns to create in table if specifying --auto-generate-sql.",
 
628
    (char**) &num_char_cols_opt, (char**) &num_char_cols_opt, 0, GET_STR, REQUIRED_ARG,
 
629
    0, 0, 0, 0, 0, 0},
 
630
  {"number-int-cols", 'y', 
 
631
    "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, 
 
633
    0, 0, 0, 0, 0, 0},
 
634
  {"number-of-queries", OPT_MYSQL_NUMBER_OF_QUERY, 
 
635
    "Limit each client to this number of queries (this is not exact).",
 
636
    (char**) &num_of_query, (char**) &num_of_query, 0,
 
637
    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 "
 
640
      "out what it would have done instead.",
 
641
    (char**) &opt_only_print, (char**) &opt_only_print, 0, GET_BOOL,  NO_ARG,
 
642
    0, 0, 0, 0, 0, 0},
639
643
  {"password", 'p',
640
 
   "Password to use when connecting to server. If password is not given it's "
641
 
   "asked from the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
642
 
  {"port", 'P', "Port number to use for connection.", (char**) &opt_drizzle_port,
643
 
   (char**) &opt_drizzle_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
644
 
   0},
 
644
    "Password to use when connecting to server. If password is not given it's "
 
645
      "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,
 
648
    0},
645
649
  {"post-query", OPT_SLAP_POST_QUERY,
646
 
   "Query to run or file containing query to execute after tests have completed.",
647
 
   (char**) &user_supplied_post_statements,
648
 
   (char**) &user_supplied_post_statements,
649
 
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
650
    "Query to run or file containing query to execute after tests have completed.",
 
651
    (char**) &user_supplied_post_statements, 
 
652
    (char**) &user_supplied_post_statements,
 
653
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
650
654
  {"post-system", OPT_SLAP_POST_SYSTEM,
651
 
   "system() string to execute after tests have completed.",
652
 
   (char**) &post_system,
653
 
   (char**) &post_system,
654
 
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
655
 
  {"pre-query", OPT_SLAP_PRE_QUERY,
656
 
   "Query to run or file containing query to execute before running tests.",
657
 
   (char**) &user_supplied_pre_statements,
658
 
   (char**) &user_supplied_pre_statements,
659
 
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
660
 
  {"pre-system", OPT_SLAP_PRE_SYSTEM,
661
 
   "system() string to execute before running tests.",
662
 
   (char**) &pre_system,
663
 
   (char**) &pre_system,
664
 
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
665
 
  {"protocol", OPT_DRIZZLE_PROTOCOL,
666
 
   "The protocol of connection (tcp,socket,pipe,memory).",
667
 
   0, 0, 0, GET_STR,  REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
655
    "system() string to execute after tests have completed.",
 
656
    (char**) &post_system, 
 
657
    (char**) &post_system,
 
658
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
659
  {"pre-query", OPT_SLAP_PRE_QUERY, 
 
660
    "Query to run or file containing query to execute before running tests.",
 
661
    (char**) &user_supplied_pre_statements, 
 
662
    (char**) &user_supplied_pre_statements,
 
663
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
664
  {"pre-system", OPT_SLAP_PRE_SYSTEM, 
 
665
    "system() string to execute before running tests.",
 
666
    (char**) &pre_system, 
 
667
    (char**) &pre_system,
 
668
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
669
  {"protocol", OPT_MYSQL_PROTOCOL,
 
670
    "The protocol of connection (tcp,socket,pipe,memory).",
 
671
    0, 0, 0, GET_STR,  REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
668
672
  {"query", 'q', "Query to run or file containing query to run.",
669
 
   (char**) &user_supplied_query, (char**) &user_supplied_query,
670
 
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
671
 
  {"set-random-seed", OPT_SLAP_SET_RANDOM_SEED,
672
 
   "Seed for random number generator (srandom(3))",
673
 
   (char**)&opt_set_random_seed,
674
 
   (char**)&opt_set_random_seed,0,
675
 
   GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
673
    (char**) &user_supplied_query, (char**) &user_supplied_query,
 
674
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
675
  {"set-random-seed", OPT_SLAP_SET_RANDOM_SEED, 
 
676
    "Seed for random number generator (srandom(3))",
 
677
    (char**)&opt_set_random_seed,
 
678
    (char**)&opt_set_random_seed,0,
 
679
    GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
680
#ifdef HAVE_SMEM
 
681
  {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
 
682
    "Base name of shared memory.", (char**) &shared_memory_base_name,
 
683
    (char**) &shared_memory_base_name, 0, GET_STR_ALLOC, REQUIRED_ARG,
 
684
    0, 0, 0, 0, 0, 0},
 
685
#endif
676
686
  {"silent", 's', "Run program in silent mode - no output.",
677
 
   (char**) &opt_silent, (char**) &opt_silent, 0, GET_BOOL,  NO_ARG,
678
 
   0, 0, 0, 0, 0, 0},
 
687
    (char**) &opt_silent, (char**) &opt_silent, 0, GET_BOOL,  NO_ARG,
 
688
    0, 0, 0, 0, 0, 0},
679
689
  {"socket", 'S', "Socket file to use for connection.",
680
 
   (char**) &opt_drizzle_unix_port, (char**) &opt_drizzle_unix_port, 0, GET_STR,
681
 
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
682
 
  {"timer-length", OPT_SLAP_TIMER_LENGTH,
683
 
   "Require drizzleslap to run each specific test a certain amount of time in seconds.",
684
 
   (char**) &opt_timer_length, (char**) &opt_timer_length, 0, GET_UINT,
685
 
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
690
    (char**) &opt_mysql_unix_port, (char**) &opt_mysql_unix_port, 0, GET_STR,
 
691
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
692
  {"timer-length", OPT_SLAP_TIMER_LENGTH, 
 
693
    "Require mysqlslap to run each specific test a certain amount of time in seconds.", 
 
694
    (char**) &opt_timer_length, (char**) &opt_timer_length, 0, GET_UINT, 
 
695
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
686
696
#ifndef DONT_ALLOW_USER_CHANGE
687
697
  {"user", 'u', "User for login if not current user.", (char**) &user,
688
 
   (char**) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
698
    (char**) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
689
699
#endif
690
700
  {"verbose", 'v',
691
 
   "More verbose output; you can use this multiple times to get even more "
692
 
   "verbose output.", (char**) &verbose, (char**) &verbose, 0,
693
 
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
701
    "More verbose output; you can use this multiple times to get even more "
 
702
      "verbose output.", (char**) &verbose, (char**) &verbose, 0, 
 
703
      GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
694
704
  {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
695
 
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
705
    NO_ARG, 0, 0, 0, 0, 0, 0},
696
706
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
697
707
};
698
708
 
699
709
 
 
710
#include <help_start.h>
 
711
 
700
712
static void print_version(void)
701
713
{
702
714
  printf("%s  Ver %s Distrib %s, for %s (%s)\n",my_progname, SLAP_VERSION,
703
 
         drizzle_get_client_info(),SYSTEM_TYPE,MACHINE_TYPE);
 
715
         MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
704
716
}
705
717
 
706
718
 
707
719
static void usage(void)
708
720
{
709
721
  print_version();
710
 
  puts("Copyright (C) 2005 DRIZZLE AB");
 
722
  puts("Copyright (C) 2005 MySQL AB");
711
723
  puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\
712
724
       \nand you are welcome to modify and redistribute it under the GPL \
713
725
       license\n");
717
729
  my_print_help(my_long_options);
718
730
}
719
731
 
 
732
#include <help_end.h>
 
733
 
720
734
static bool
721
735
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
722
736
               char *argument)
730
744
    if (argument)
731
745
    {
732
746
      char *start= argument;
733
 
      free(opt_password);
 
747
      my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
734
748
      opt_password= my_strdup(argument,MYF(MY_FAE));
735
 
      while (*argument) *argument++= 'x';    /* Destroy argument */
 
749
      while (*argument) *argument++= 'x';               /* Destroy argument */
736
750
      if (*start)
737
 
        start[1]= 0;        /* Cut length of argument */
 
751
        start[1]= 0;                            /* Cut length of argument */
738
752
      tty_password= 0;
739
753
    }
740
754
    else
745
759
    exit(0);
746
760
    break;
747
761
  case '?':
748
 
  case 'I':          /* Info */
 
762
  case 'I':                                     /* Info */
749
763
    usage();
750
764
    exit(0);
751
765
  }
777
791
  char       buf[HUGE_STRING_LENGTH];
778
792
  unsigned int        col_count;
779
793
  statement *ptr;
780
 
  string table_string;
781
 
 
782
 
  table_string.reserve(HUGE_STRING_LENGTH);
783
 
 
784
 
  table_string= "CREATE TABLE `t1` (";
 
794
  DYNAMIC_STRING table_string;
 
795
 
 
796
  init_dynamic_string(&table_string, "", HUGE_STRING_LENGTH, HUGE_STRING_LENGTH);
 
797
 
 
798
  dynstr_append(&table_string, "CREATE TABLE `t1` (");
785
799
 
786
800
  if (auto_generate_sql_autoincrement)
787
801
  {
788
 
    table_string.append("id serial");
 
802
    dynstr_append(&table_string, "id serial");
789
803
 
790
804
    if (num_int_cols || num_char_cols)
791
 
      table_string.append(",");
 
805
      dynstr_append(&table_string, ",");
792
806
  }
793
807
 
794
808
  if (auto_generate_sql_guid_primary)
795
809
  {
796
 
    table_string.append("id varchar(128) primary key");
 
810
    dynstr_append(&table_string, "id varchar(128) primary key");
797
811
 
798
812
    if (num_int_cols || num_char_cols || auto_generate_sql_guid_primary)
799
 
      table_string.append(",");
 
813
      dynstr_append(&table_string, ",");
800
814
  }
801
815
 
802
816
  if (auto_generate_sql_secondary_indexes)
806
820
    for (count= 0; count < auto_generate_sql_secondary_indexes; count++)
807
821
    {
808
822
      if (count) /* Except for the first pass we add a comma */
809
 
        table_string.append(",");
 
823
        dynstr_append(&table_string, ",");
810
824
 
811
 
      if (snprintf(buf, HUGE_STRING_LENGTH, "id%d varchar(32) unique key", count)
 
825
      if (snprintf(buf, HUGE_STRING_LENGTH, "id%d varchar(32) unique key", count) 
812
826
          > HUGE_STRING_LENGTH)
813
827
      {
814
828
        fprintf(stderr, "Memory Allocation error in create table\n");
815
829
        exit(1);
816
830
      }
817
 
      table_string.append(buf);
 
831
      dynstr_append(&table_string, buf);
818
832
    }
819
833
 
820
834
    if (num_int_cols || num_char_cols)
821
 
      table_string.append(",");
 
835
      dynstr_append(&table_string, ",");
822
836
  }
823
837
 
824
838
  if (num_int_cols)
826
840
    {
827
841
      if (num_int_cols_index)
828
842
      {
829
 
        if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d INT, INDEX(intcol%d)",
 
843
        if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d INT(32), INDEX(intcol%d)", 
830
844
                     col_count, col_count) > HUGE_STRING_LENGTH)
831
845
        {
832
846
          fprintf(stderr, "Memory Allocation error in create table\n");
835
849
      }
836
850
      else
837
851
      {
838
 
        if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d INT ", col_count)
 
852
        if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d INT(32) ", col_count) 
839
853
            > HUGE_STRING_LENGTH)
840
854
        {
841
855
          fprintf(stderr, "Memory Allocation error in create table\n");
842
856
          exit(1);
843
857
        }
844
858
      }
845
 
      table_string.append(buf);
 
859
      dynstr_append(&table_string, buf);
846
860
 
847
861
      if (col_count < num_int_cols || num_char_cols > 0)
848
 
        table_string.append(",");
 
862
        dynstr_append(&table_string, ",");
849
863
    }
850
864
 
851
865
  if (num_char_cols)
853
867
    {
854
868
      if (num_char_cols_index)
855
869
      {
856
 
        if (snprintf(buf, HUGE_STRING_LENGTH,
857
 
                     "charcol%d VARCHAR(128), INDEX(charcol%d) ",
 
870
        if (snprintf(buf, HUGE_STRING_LENGTH, 
 
871
                     "charcol%d VARCHAR(128), INDEX(charcol%d) ", 
858
872
                     col_count, col_count) > HUGE_STRING_LENGTH)
859
873
        {
860
874
          fprintf(stderr, "Memory Allocation error in creating table\n");
863
877
      }
864
878
      else
865
879
      {
866
 
        if (snprintf(buf, HUGE_STRING_LENGTH, "charcol%d VARCHAR(128)",
 
880
        if (snprintf(buf, HUGE_STRING_LENGTH, "charcol%d VARCHAR(128)", 
867
881
                     col_count) > HUGE_STRING_LENGTH)
868
882
        {
869
883
          fprintf(stderr, "Memory Allocation error in creating table\n");
870
884
          exit(1);
871
885
        }
872
886
      }
873
 
      table_string.append(buf);
 
887
      dynstr_append(&table_string, buf);
874
888
 
875
889
      if (col_count < num_char_cols || num_blob_cols > 0)
876
 
        table_string.append(",");
 
890
        dynstr_append(&table_string, ",");
877
891
    }
878
892
 
879
893
  if (num_blob_cols)
880
894
    for (col_count= 1; col_count <= num_blob_cols; col_count++)
881
895
    {
882
 
      if (snprintf(buf, HUGE_STRING_LENGTH, "blobcol%d blob",
 
896
      if (snprintf(buf, HUGE_STRING_LENGTH, "blobcol%d blob", 
883
897
                   col_count) > HUGE_STRING_LENGTH)
884
898
      {
885
899
        fprintf(stderr, "Memory Allocation error in creating table\n");
886
900
        exit(1);
887
901
      }
888
 
      table_string.append(buf);
 
902
      dynstr_append(&table_string, buf);
889
903
 
890
904
      if (col_count < num_blob_cols)
891
 
        table_string.append(",");
 
905
        dynstr_append(&table_string, ",");
892
906
    }
893
907
 
894
 
  table_string.append(")");
895
 
  ptr= (statement *)my_malloc(sizeof(statement),
 
908
  dynstr_append(&table_string, ")");
 
909
  ptr= (statement *)my_malloc(sizeof(statement), 
896
910
                              MYF(MY_ZEROFILL|MY_FAE|MY_WME));
897
 
  ptr->string = (char *)my_malloc(table_string.length()+1,
 
911
  ptr->string = (char *)my_malloc(table_string.length+1,
898
912
                                  MYF(MY_ZEROFILL|MY_FAE|MY_WME));
899
 
  ptr->length= table_string.length()+1;
 
913
  ptr->length= table_string.length+1;
900
914
  ptr->type= CREATE_TABLE_TYPE;
901
 
  my_stpcpy(ptr->string, table_string.c_str());
 
915
  strmov(ptr->string, table_string.str);
 
916
  dynstr_free(&table_string);
902
917
  return(ptr);
903
918
}
904
919
 
914
929
  char       buf[HUGE_STRING_LENGTH];
915
930
  unsigned int        col_count;
916
931
  statement *ptr;
917
 
  string update_string;
918
 
 
919
 
  update_string.reserve(HUGE_STRING_LENGTH);
920
 
 
921
 
  update_string= "UPDATE t1 SET ";
 
932
  DYNAMIC_STRING update_string;
 
933
 
 
934
 
 
935
  init_dynamic_string(&update_string, "", HUGE_STRING_LENGTH, HUGE_STRING_LENGTH);
 
936
 
 
937
  dynstr_append(&update_string, "UPDATE t1 SET ");
922
938
 
923
939
  if (num_int_cols)
924
940
    for (col_count= 1; col_count <= num_int_cols; col_count++)
925
941
    {
926
 
      if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d = %ld", col_count,
 
942
      if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d = %ld", col_count, 
927
943
                   random()) > HUGE_STRING_LENGTH)
928
944
      {
929
945
        fprintf(stderr, "Memory Allocation error in creating update\n");
930
946
        exit(1);
931
947
      }
932
 
      update_string.append(buf);
 
948
      dynstr_append(&update_string, buf);
933
949
 
934
950
      if (col_count < num_int_cols || num_char_cols > 0)
935
 
        update_string.append(",", 1);
 
951
        dynstr_append_mem(&update_string, ",", 1);
936
952
    }
937
953
 
938
954
  if (num_char_cols)
941
957
      char rand_buffer[RAND_STRING_SIZE];
942
958
      int buf_len= get_random_string(rand_buffer, RAND_STRING_SIZE);
943
959
 
944
 
      if (snprintf(buf, HUGE_STRING_LENGTH, "charcol%d = '%.*s'", col_count,
945
 
                   buf_len, rand_buffer)
 
960
      if (snprintf(buf, HUGE_STRING_LENGTH, "charcol%d = '%.*s'", col_count, 
 
961
                   buf_len, rand_buffer) 
946
962
          > HUGE_STRING_LENGTH)
947
963
      {
948
964
        fprintf(stderr, "Memory Allocation error in creating update\n");
949
965
        exit(1);
950
966
      }
951
 
      update_string.append(buf);
 
967
      dynstr_append(&update_string, buf);
952
968
 
953
969
      if (col_count < num_char_cols)
954
 
        update_string.append(",", 1);
 
970
        dynstr_append_mem(&update_string, ",", 1);
955
971
    }
956
972
 
957
973
  if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
958
 
    update_string.append(" WHERE id = ");
959
 
 
960
 
 
961
 
  ptr= (statement *)my_malloc(sizeof(statement),
 
974
    dynstr_append(&update_string, " WHERE id = ");
 
975
 
 
976
 
 
977
  ptr= (statement *)my_malloc(sizeof(statement), 
962
978
                              MYF(MY_ZEROFILL|MY_FAE|MY_WME));
963
979
 
964
 
  ptr->string= (char *)my_malloc(update_string.length() + 1,
965
 
                                 MYF(MY_ZEROFILL|MY_FAE|MY_WME));
966
 
  ptr->length= update_string.length()+1;
 
980
  ptr->string= (char *)my_malloc(update_string.length + 1,
 
981
                                  MYF(MY_ZEROFILL|MY_FAE|MY_WME));
 
982
  ptr->length= update_string.length+1;
967
983
  if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
968
984
    ptr->type= UPDATE_TYPE_REQUIRES_PREFIX ;
969
985
  else
970
986
    ptr->type= UPDATE_TYPE;
971
 
  my_stpcpy(ptr->string, update_string.c_str());
 
987
  strmov(ptr->string, update_string.str);
 
988
  dynstr_free(&update_string);
972
989
  return(ptr);
973
990
}
974
991
 
985
1002
  char       buf[HUGE_STRING_LENGTH];
986
1003
  unsigned int        col_count;
987
1004
  statement *ptr;
988
 
  string insert_string;
989
 
 
990
 
  insert_string.reserve(HUGE_STRING_LENGTH);
991
 
 
992
 
  insert_string= "INSERT INTO t1 VALUES (";
 
1005
  DYNAMIC_STRING insert_string;
 
1006
 
 
1007
 
 
1008
  init_dynamic_string(&insert_string, "", HUGE_STRING_LENGTH, HUGE_STRING_LENGTH);
 
1009
 
 
1010
  dynstr_append(&insert_string, "INSERT INTO t1 VALUES (");
993
1011
 
994
1012
  if (auto_generate_sql_autoincrement)
995
1013
  {
996
 
    insert_string.append("NULL");
 
1014
    dynstr_append(&insert_string, "NULL");
997
1015
 
998
1016
    if (num_int_cols || num_char_cols)
999
 
      insert_string.append(",");
 
1017
      dynstr_append(&insert_string, ",");
1000
1018
  }
1001
1019
 
1002
1020
  if (auto_generate_sql_guid_primary)
1003
1021
  {
1004
 
    insert_string.append("uuid()");
 
1022
    dynstr_append(&insert_string, "uuid()");
1005
1023
 
1006
1024
    if (num_int_cols || num_char_cols)
1007
 
      insert_string.append(",");
 
1025
      dynstr_append(&insert_string, ",");
1008
1026
  }
1009
1027
 
1010
1028
  if (auto_generate_sql_secondary_indexes)
1014
1032
    for (count= 0; count < auto_generate_sql_secondary_indexes; count++)
1015
1033
    {
1016
1034
      if (count) /* Except for the first pass we add a comma */
1017
 
        insert_string.append(",");
 
1035
        dynstr_append(&insert_string, ",");
1018
1036
 
1019
 
      insert_string.append("uuid()");
 
1037
      dynstr_append(&insert_string, "uuid()");
1020
1038
    }
1021
1039
 
1022
1040
    if (num_int_cols || num_char_cols)
1023
 
      insert_string.append(",");
 
1041
      dynstr_append(&insert_string, ",");
1024
1042
  }
1025
1043
 
1026
1044
  if (num_int_cols)
1031
1049
        fprintf(stderr, "Memory Allocation error in creating insert\n");
1032
1050
        exit(1);
1033
1051
      }
1034
 
      insert_string.append(buf);
 
1052
      dynstr_append(&insert_string, buf);
1035
1053
 
1036
1054
      if (col_count < num_int_cols || num_char_cols > 0)
1037
 
        insert_string.append(",");
 
1055
        dynstr_append_mem(&insert_string, ",", 1);
1038
1056
    }
1039
1057
 
1040
1058
  if (num_char_cols)
1041
1059
    for (col_count= 1; col_count <= num_char_cols; col_count++)
1042
1060
    {
1043
1061
      int buf_len= get_random_string(buf, RAND_STRING_SIZE);
1044
 
      insert_string.append("'", 1);
1045
 
      insert_string.append(buf, buf_len);
1046
 
      insert_string.append("'", 1);
 
1062
      dynstr_append_mem(&insert_string, "'", 1);
 
1063
      dynstr_append_mem(&insert_string, buf, buf_len);
 
1064
      dynstr_append_mem(&insert_string, "'", 1);
1047
1065
 
1048
1066
      if (col_count < num_char_cols || num_blob_cols > 0)
1049
 
        insert_string.append(",", 1);
 
1067
        dynstr_append_mem(&insert_string, ",", 1);
1050
1068
    }
1051
1069
 
1052
1070
  if (num_blob_cols)
1056
1074
    if (num_blob_cols_size > HUGE_STRING_LENGTH)
1057
1075
    {
1058
1076
      blob_ptr= (char *)my_malloc(sizeof(char)*num_blob_cols_size,
1059
 
                                  MYF(MY_ZEROFILL|MY_FAE|MY_WME));
 
1077
                             MYF(MY_ZEROFILL|MY_FAE|MY_WME));
1060
1078
      if (!blob_ptr)
1061
1079
      {
1062
1080
        fprintf(stderr, "Memory Allocation error in creating select\n");
1074
1092
      unsigned int size;
1075
1093
      unsigned int difference= num_blob_cols_size - num_blob_cols_size_min;
1076
1094
 
1077
 
      size= difference ? (num_blob_cols_size_min + (random() % difference)) :
1078
 
        num_blob_cols_size;
 
1095
      size= difference ? (num_blob_cols_size_min + (random() % difference)) : 
 
1096
                          num_blob_cols_size;
1079
1097
 
1080
1098
      buf_len= get_random_string(blob_ptr, size);
1081
1099
 
1082
 
      insert_string.append("'", 1);
1083
 
      insert_string.append(blob_ptr, buf_len);
1084
 
      insert_string.append("'", 1);
 
1100
      dynstr_append_mem(&insert_string, "'", 1);
 
1101
      dynstr_append_mem(&insert_string, blob_ptr, buf_len);
 
1102
      dynstr_append_mem(&insert_string, "'", 1);
1085
1103
 
1086
1104
      if (col_count < num_blob_cols)
1087
 
        insert_string.append(",", 1);
 
1105
        dynstr_append_mem(&insert_string, ",", 1);
1088
1106
    }
1089
1107
 
1090
1108
    if (num_blob_cols_size > HUGE_STRING_LENGTH)
1091
 
      free(blob_ptr);
 
1109
      my_free(blob_ptr, MYF(0));
1092
1110
  }
1093
1111
 
1094
 
  insert_string.append(")", 1);
 
1112
  dynstr_append_mem(&insert_string, ")", 1);
1095
1113
 
1096
1114
  if (!(ptr= (statement *)my_malloc(sizeof(statement), MYF(MY_ZEROFILL|MY_FAE|MY_WME))))
1097
1115
  {
1098
1116
    fprintf(stderr, "Memory Allocation error in creating select\n");
1099
1117
    exit(1);
1100
1118
  }
1101
 
  if (!(ptr->string= (char *)my_malloc(insert_string.length() + 1, MYF(MY_ZEROFILL|MY_FAE|MY_WME))))
 
1119
  if (!(ptr->string= (char *)my_malloc(insert_string.length + 1, MYF(MY_ZEROFILL|MY_FAE|MY_WME))))
1102
1120
  {
1103
1121
    fprintf(stderr, "Memory Allocation error in creating select\n");
1104
1122
    exit(1);
1105
1123
  }
1106
 
  ptr->length= insert_string.length()+1;
 
1124
  ptr->length= insert_string.length+1;
1107
1125
  ptr->type= INSERT_TYPE;
1108
 
  my_stpcpy(ptr->string, insert_string.c_str());
 
1126
  strmov(ptr->string, insert_string.str);
 
1127
  dynstr_free(&insert_string);
 
1128
 
1109
1129
  return(ptr);
1110
1130
}
1111
1131
 
1122
1142
  char       buf[HUGE_STRING_LENGTH];
1123
1143
  unsigned int        col_count;
1124
1144
  statement *ptr;
1125
 
  string query_string;
1126
 
 
1127
 
  query_string.reserve(HUGE_STRING_LENGTH);
1128
 
 
1129
 
  query_string.append("SELECT ", 7);
 
1145
  static DYNAMIC_STRING query_string;
 
1146
 
 
1147
 
 
1148
  init_dynamic_string(&query_string, "", HUGE_STRING_LENGTH, HUGE_STRING_LENGTH);
 
1149
 
 
1150
  dynstr_append_mem(&query_string, "SELECT ", 7);
1130
1151
  if (auto_generate_selected_columns_opt)
1131
1152
  {
1132
 
    query_string.append(auto_generate_selected_columns_opt);
 
1153
    dynstr_append(&query_string, auto_generate_selected_columns_opt);
1133
1154
  }
1134
1155
  else
1135
1156
  {
1136
1157
    for (col_count= 1; col_count <= num_int_cols; col_count++)
1137
1158
    {
1138
 
      if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d", col_count)
 
1159
      if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d", col_count) 
1139
1160
          > HUGE_STRING_LENGTH)
1140
1161
      {
1141
1162
        fprintf(stderr, "Memory Allocation error in creating select\n");
1142
1163
        exit(1);
1143
1164
      }
1144
 
      query_string.append(buf);
 
1165
      dynstr_append(&query_string, buf);
1145
1166
 
1146
1167
      if (col_count < num_int_cols || num_char_cols > 0)
1147
 
        query_string.append(",", 1);
 
1168
        dynstr_append_mem(&query_string, ",", 1);
1148
1169
 
1149
1170
    }
1150
1171
    for (col_count= 1; col_count <= num_char_cols; col_count++)
1155
1176
        fprintf(stderr, "Memory Allocation error in creating select\n");
1156
1177
        exit(1);
1157
1178
      }
1158
 
      query_string.append(buf);
 
1179
      dynstr_append(&query_string, buf);
1159
1180
 
1160
1181
      if (col_count < num_char_cols || num_blob_cols > 0)
1161
 
        query_string.append(",", 1);
 
1182
        dynstr_append_mem(&query_string, ",", 1);
1162
1183
 
1163
1184
    }
1164
1185
    for (col_count= 1; col_count <= num_blob_cols; col_count++)
1169
1190
        fprintf(stderr, "Memory Allocation error in creating select\n");
1170
1191
        exit(1);
1171
1192
      }
1172
 
      query_string.append(buf);
 
1193
      dynstr_append(&query_string, buf);
1173
1194
 
1174
1195
      if (col_count < num_blob_cols)
1175
 
        query_string.append(",", 1);
 
1196
        dynstr_append_mem(&query_string, ",", 1);
1176
1197
    }
1177
1198
  }
1178
 
  query_string.append(" FROM t1");
 
1199
  dynstr_append(&query_string, " FROM t1");
1179
1200
 
1180
 
  if ((key) &&
 
1201
  if ((key) && 
1181
1202
      (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary))
1182
 
    query_string.append(" WHERE id = ");
 
1203
    dynstr_append(&query_string, " WHERE id = ");
1183
1204
 
1184
1205
  ptr= (statement *)my_malloc(sizeof(statement),
1185
1206
                              MYF(MY_ZEROFILL|MY_FAE|MY_WME));
1186
 
  ptr->string= (char *)my_malloc(query_string.length() + 1,
1187
 
                                 MYF(MY_ZEROFILL|MY_FAE|MY_WME));
1188
 
  ptr->length= query_string.length()+1;
1189
 
  if ((key) &&
 
1207
  ptr->string= (char *)my_malloc(query_string.length + 1,
 
1208
                              MYF(MY_ZEROFILL|MY_FAE|MY_WME));
 
1209
  ptr->length= query_string.length+1;
 
1210
  if ((key) && 
1190
1211
      (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary))
1191
1212
    ptr->type= SELECT_TYPE_REQUIRES_PREFIX;
1192
1213
  else
1193
1214
    ptr->type= SELECT_TYPE;
1194
 
  my_stpcpy(ptr->string, query_string.c_str());
 
1215
  strmov(ptr->string, query_string.str);
 
1216
  dynstr_free(&query_string);
1195
1217
  return(ptr);
1196
1218
}
1197
1219
 
1221
1243
 
1222
1244
  if (auto_generate_sql && (create_string || user_supplied_query))
1223
1245
  {
1224
 
    fprintf(stderr,
1225
 
            "%s: Can't use --auto-generate-sql when create and query strings are specified!\n",
1226
 
            my_progname);
1227
 
    exit(1);
 
1246
      fprintf(stderr,
 
1247
              "%s: Can't use --auto-generate-sql when create and query strings are specified!\n",
 
1248
              my_progname);
 
1249
      exit(1);
1228
1250
  }
1229
1251
 
1230
 
  if (auto_generate_sql && auto_generate_sql_guid_primary &&
 
1252
  if (auto_generate_sql && auto_generate_sql_guid_primary && 
1231
1253
      auto_generate_sql_autoincrement)
1232
1254
  {
1233
 
    fprintf(stderr,
1234
 
            "%s: Either auto-generate-sql-guid-primary or auto-generate-sql-add-autoincrement can be used!\n",
1235
 
            my_progname);
1236
 
    exit(1);
 
1255
      fprintf(stderr,
 
1256
              "%s: Either auto-generate-sql-guid-primary or auto-generate-sql-add-autoincrement can be used!\n",
 
1257
              my_progname);
 
1258
      exit(1);
1237
1259
  }
1238
1260
 
1239
1261
  if (auto_generate_sql && num_of_query && auto_actual_queries)
1240
1262
  {
1241
 
    fprintf(stderr,
1242
 
            "%s: Either auto-generate-sql-execute-number or number-of-queries can be used!\n",
1243
 
            my_progname);
1244
 
    exit(1);
 
1263
      fprintf(stderr,
 
1264
              "%s: Either auto-generate-sql-execute-number or number-of-queries can be used!\n",
 
1265
              my_progname);
 
1266
      exit(1);
1245
1267
  }
1246
1268
 
1247
1269
  parse_comma(concurrency_str ? concurrency_str : "1", &concurrency);
1249
1271
  if (opt_csv_str)
1250
1272
  {
1251
1273
    opt_silent= true;
1252
 
 
 
1274
    
1253
1275
    if (opt_csv_str[0] == '-')
1254
1276
    {
1255
1277
      csv_file= fileno(stdout);
1321
1343
 
1322
1344
  if (auto_generate_sql)
1323
1345
  {
1324
 
    uint64_t x= 0;
 
1346
    unsigned long long x= 0;
1325
1347
    statement *ptr_statement;
1326
1348
 
1327
1349
    if (verbose >= 2)
1328
1350
      printf("Building Create Statements for Auto\n");
1329
1351
 
1330
1352
    create_statements= build_table_string();
1331
 
    /*
1332
 
      Pre-populate table
 
1353
    /* 
 
1354
      Pre-populate table 
1333
1355
    */
1334
 
    for (ptr_statement= create_statements, x= 0;
1335
 
         x < auto_generate_sql_unique_write_number;
 
1356
    for (ptr_statement= create_statements, x= 0; 
 
1357
         x < auto_generate_sql_unique_write_number; 
1336
1358
         x++, ptr_statement= ptr_statement->next)
1337
1359
    {
1338
1360
      ptr_statement->next= build_insert_string();
1344
1366
    if (!opt_auto_generate_sql_type)
1345
1367
      opt_auto_generate_sql_type= "mixed";
1346
1368
 
1347
 
    query_statements_count=
 
1369
    query_statements_count= 
1348
1370
      parse_option(opt_auto_generate_sql_type, &query_options, ',');
1349
1371
 
1350
1372
    query_statements= (statement **)my_malloc(sizeof(statement *) * query_statements_count,
1359
1381
          printf("Generating SELECT Statements for Auto\n");
1360
1382
 
1361
1383
        query_statements[sql_type_count]= build_select_string(false);
1362
 
        for (ptr_statement= query_statements[sql_type_count], x= 0;
1363
 
             x < auto_generate_sql_unique_query_number;
 
1384
        for (ptr_statement= query_statements[sql_type_count], x= 0; 
 
1385
             x < auto_generate_sql_unique_query_number; 
1364
1386
             x++, ptr_statement= ptr_statement->next)
1365
1387
        {
1366
1388
          ptr_statement->next= build_select_string(false);
1381
1403
        }
1382
1404
 
1383
1405
        query_statements[sql_type_count]= build_select_string(true);
1384
 
        for (ptr_statement= query_statements[sql_type_count], x= 0;
1385
 
             x < auto_generate_sql_unique_query_number;
 
1406
        for (ptr_statement= query_statements[sql_type_count], x= 0; 
 
1407
             x < auto_generate_sql_unique_query_number; 
1386
1408
             x++, ptr_statement= ptr_statement->next)
1387
1409
        {
1388
1410
          ptr_statement->next= build_select_string(true);
1391
1413
      else if (sql_type->string[0] == 'w')
1392
1414
      {
1393
1415
        /*
1394
 
          We generate a number of strings in case the engine is
 
1416
          We generate a number of strings in case the engine is 
1395
1417
          Archive (since strings which were identical one after another
1396
1418
          would be too easily optimized).
1397
1419
        */
1398
1420
        if (verbose >= 2)
1399
1421
          printf("Generating INSERT Statements for Auto\n");
1400
1422
        query_statements[sql_type_count]= build_insert_string();
1401
 
        for (ptr_statement= query_statements[sql_type_count], x= 0;
1402
 
             x < auto_generate_sql_unique_query_number;
 
1423
        for (ptr_statement= query_statements[sql_type_count], x= 0; 
 
1424
             x < auto_generate_sql_unique_query_number; 
1403
1425
             x++, ptr_statement= ptr_statement->next)
1404
1426
        {
1405
1427
          ptr_statement->next= build_insert_string();
1417
1439
        }
1418
1440
 
1419
1441
        query_statements[sql_type_count]= build_update_string();
1420
 
        for (ptr_statement= query_statements[sql_type_count], x= 0;
1421
 
             x < auto_generate_sql_unique_query_number;
 
1442
        for (ptr_statement= query_statements[sql_type_count], x= 0; 
 
1443
             x < auto_generate_sql_unique_query_number; 
1422
1444
             x++, ptr_statement= ptr_statement->next)
1423
1445
        {
1424
1446
          ptr_statement->next= build_update_string();
1429
1451
        int coin= 0;
1430
1452
 
1431
1453
        query_statements[sql_type_count]= build_insert_string();
1432
 
        /*
 
1454
        /* 
1433
1455
          This logic should be extended to do a more mixed load,
1434
1456
          at the moment it results in "every other".
1435
1457
        */
1436
 
        for (ptr_statement= query_statements[sql_type_count], x= 0;
1437
 
             x < auto_generate_sql_unique_query_number;
 
1458
        for (ptr_statement= query_statements[sql_type_count], x= 0; 
 
1459
             x < auto_generate_sql_unique_query_number; 
1438
1460
             x++, ptr_statement= ptr_statement->next)
1439
1461
        {
1440
1462
          if (coin)
1457
1479
    if (create_string && !stat(create_string, &sbuf))
1458
1480
    {
1459
1481
      File data_file;
1460
 
      if (!S_ISREG(sbuf.st_mode))
 
1482
      if (!MY_S_ISREG(sbuf.st_mode))
1461
1483
      {
1462
1484
        fprintf(stderr,"%s: Create file was not a regular file\n",
1463
1485
                my_progname);
1469
1491
        exit(1);
1470
1492
      }
1471
1493
      tmp_string= (char *)my_malloc(sbuf.st_size + 1,
1472
 
                                    MYF(MY_ZEROFILL|MY_FAE|MY_WME));
1473
 
      my_read(data_file, (unsigned char*) tmp_string, sbuf.st_size, MYF(0));
 
1494
                              MYF(MY_ZEROFILL|MY_FAE|MY_WME));
 
1495
      my_read(data_file, (uchar*) tmp_string, sbuf.st_size, MYF(0));
1474
1496
      tmp_string[sbuf.st_size]= '\0';
1475
1497
      my_close(data_file,MYF(0));
1476
1498
      parse_delimiter(tmp_string, &create_statements, delimiter[0]);
1477
 
      free(tmp_string);
 
1499
      my_free(tmp_string, MYF(0));
1478
1500
    }
1479
1501
    else if (create_string)
1480
1502
    {
1481
 
      parse_delimiter(create_string, &create_statements, delimiter[0]);
 
1503
        parse_delimiter(create_string, &create_statements, delimiter[0]);
1482
1504
    }
1483
1505
 
1484
1506
    /* Set this up till we fully support options on user generated queries */
1485
1507
    if (user_supplied_query)
1486
1508
    {
1487
 
      query_statements_count=
 
1509
      query_statements_count= 
1488
1510
        parse_option("default", &query_options, ',');
1489
1511
 
1490
1512
      query_statements= (statement **)my_malloc(sizeof(statement *),
1494
1516
    if (user_supplied_query && !stat(user_supplied_query, &sbuf))
1495
1517
    {
1496
1518
      File data_file;
1497
 
      if (!S_ISREG(sbuf.st_mode))
 
1519
      if (!MY_S_ISREG(sbuf.st_mode))
1498
1520
      {
1499
1521
        fprintf(stderr,"%s: User query supplied file was not a regular file\n",
1500
1522
                my_progname);
1507
1529
      }
1508
1530
      tmp_string= (char *)my_malloc(sbuf.st_size + 1,
1509
1531
                                    MYF(MY_ZEROFILL|MY_FAE|MY_WME));
1510
 
      my_read(data_file, (unsigned char*) tmp_string, sbuf.st_size, MYF(0));
 
1532
      my_read(data_file, (uchar*) tmp_string, sbuf.st_size, MYF(0));
1511
1533
      tmp_string[sbuf.st_size]= '\0';
1512
1534
      my_close(data_file,MYF(0));
1513
1535
      if (user_supplied_query)
1514
1536
        actual_queries= parse_delimiter(tmp_string, &query_statements[0],
1515
1537
                                        delimiter[0]);
1516
 
      free(tmp_string);
1517
 
    }
 
1538
      my_free(tmp_string, MYF(0));
 
1539
    } 
1518
1540
    else if (user_supplied_query)
1519
1541
    {
1520
1542
      actual_queries= parse_delimiter(user_supplied_query, &query_statements[0],
1526
1548
      && !stat(user_supplied_pre_statements, &sbuf))
1527
1549
  {
1528
1550
    File data_file;
1529
 
    if (!S_ISREG(sbuf.st_mode))
 
1551
    if (!MY_S_ISREG(sbuf.st_mode))
1530
1552
    {
1531
1553
      fprintf(stderr,"%s: User query supplied file was not a regular file\n",
1532
1554
              my_progname);
1539
1561
    }
1540
1562
    tmp_string= (char *)my_malloc(sbuf.st_size + 1,
1541
1563
                                  MYF(MY_ZEROFILL|MY_FAE|MY_WME));
1542
 
    my_read(data_file, (unsigned char*) tmp_string, sbuf.st_size, MYF(0));
 
1564
    my_read(data_file, (uchar*) tmp_string, sbuf.st_size, MYF(0));
1543
1565
    tmp_string[sbuf.st_size]= '\0';
1544
1566
    my_close(data_file,MYF(0));
1545
1567
    if (user_supplied_pre_statements)
1546
1568
      (void)parse_delimiter(tmp_string, &pre_statements,
1547
1569
                            delimiter[0]);
1548
 
    free(tmp_string);
1549
 
  }
 
1570
    my_free(tmp_string, MYF(0));
 
1571
  } 
1550
1572
  else if (user_supplied_pre_statements)
1551
1573
  {
1552
1574
    (void)parse_delimiter(user_supplied_pre_statements,
1558
1580
      && !stat(user_supplied_post_statements, &sbuf))
1559
1581
  {
1560
1582
    File data_file;
1561
 
    if (!S_ISREG(sbuf.st_mode))
 
1583
    if (!MY_S_ISREG(sbuf.st_mode))
1562
1584
    {
1563
1585
      fprintf(stderr,"%s: User query supplied file was not a regular file\n",
1564
1586
              my_progname);
1571
1593
    }
1572
1594
    tmp_string= (char *)my_malloc(sbuf.st_size + 1,
1573
1595
                                  MYF(MY_ZEROFILL|MY_FAE|MY_WME));
1574
 
    my_read(data_file, (unsigned char*) tmp_string, sbuf.st_size, MYF(0));
 
1596
    my_read(data_file, (uchar*) tmp_string, sbuf.st_size, MYF(0));
1575
1597
    tmp_string[sbuf.st_size]= '\0';
1576
1598
    my_close(data_file,MYF(0));
1577
1599
    if (user_supplied_post_statements)
1578
1600
      (void)parse_delimiter(tmp_string, &post_statements,
1579
1601
                            delimiter[0]);
1580
 
    free(tmp_string);
1581
 
  }
 
1602
    my_free(tmp_string, MYF(0));
 
1603
  } 
1582
1604
  else if (user_supplied_post_statements)
1583
1605
  {
1584
1606
    (void)parse_delimiter(user_supplied_post_statements, &post_statements,
1592
1614
    parse_option(default_engine, &engine_options, ',');
1593
1615
 
1594
1616
  if (tty_password)
1595
 
    opt_password= get_tty_password(NULL);
 
1617
    opt_password= get_tty_password(NullS);
1596
1618
  return(0);
1597
1619
}
1598
1620
 
1599
1621
 
1600
 
static int run_query(DRIZZLE *drizzle, const char *query, int len)
 
1622
static int run_query(MYSQL *mysql, const char *query, int len)
1601
1623
{
1602
1624
  if (opt_only_print)
1603
1625
  {
1607
1629
 
1608
1630
  if (verbose >= 3)
1609
1631
    printf("%.*s;\n", len, query);
1610
 
  return drizzle_real_query(drizzle, query, len);
 
1632
  return mysql_real_query(mysql, query, len);
1611
1633
}
1612
1634
 
1613
1635
 
1614
1636
static int
1615
 
generate_primary_key_list(DRIZZLE *drizzle, option_string *engine_stmt)
 
1637
generate_primary_key_list(MYSQL *mysql, option_string *engine_stmt)
1616
1638
{
1617
 
  DRIZZLE_RES *result;
1618
 
  DRIZZLE_ROW row;
1619
 
  uint64_t counter;
1620
 
 
1621
 
 
1622
 
  /*
1623
 
    Blackhole is a special case, this allows us to test the upper end
 
1639
  MYSQL_RES *result;
 
1640
  MYSQL_ROW row;
 
1641
  unsigned long long counter;
 
1642
 
 
1643
 
 
1644
  /* 
 
1645
    Blackhole is a special case, this allows us to test the upper end 
1624
1646
    of the server during load runs.
1625
1647
  */
1626
 
  if (opt_only_print || (engine_stmt &&
 
1648
  if (opt_only_print || (engine_stmt && 
1627
1649
                         strstr(engine_stmt->string, "blackhole")))
1628
1650
  {
1629
1651
    primary_keys_number_of= 1;
1630
 
    primary_keys= (char **)my_malloc((uint)(sizeof(char *) *
1631
 
                                            primary_keys_number_of),
1632
 
                                     MYF(MY_ZEROFILL|MY_FAE|MY_WME));
 
1652
    primary_keys= (char **)my_malloc((uint)(sizeof(char *) * 
 
1653
                                            primary_keys_number_of), 
 
1654
                                    MYF(MY_ZEROFILL|MY_FAE|MY_WME));
1633
1655
    /* Yes, we strdup a const string to simplify the interface */
1634
 
    primary_keys[0]= my_strdup("796c4422-1d94-102a-9d6d-00e0812d", MYF(0));
 
1656
    primary_keys[0]= my_strdup("796c4422-1d94-102a-9d6d-00e0812d", MYF(0)); 
1635
1657
  }
1636
1658
  else
1637
1659
  {
1638
 
    if (run_query(drizzle, "SELECT id from t1", strlen("SELECT id from t1")))
 
1660
    if (run_query(mysql, "SELECT id from t1", strlen("SELECT id from t1")))
1639
1661
    {
1640
1662
      fprintf(stderr,"%s: Cannot select GUID primary keys. (%s)\n", my_progname,
1641
 
              drizzle_error(drizzle));
 
1663
              mysql_error(mysql));
1642
1664
      exit(1);
1643
1665
    }
1644
1666
 
1645
 
    result= drizzle_store_result(drizzle);
1646
 
    primary_keys_number_of= drizzle_num_rows(result);
 
1667
    result= mysql_store_result(mysql);
 
1668
    primary_keys_number_of= mysql_num_rows(result);
1647
1669
 
1648
1670
    /* So why check this? Blackhole :) */
1649
1671
    if (primary_keys_number_of)
1651
1673
      /*
1652
1674
        We create the structure and loop and create the items.
1653
1675
      */
1654
 
      primary_keys= (char **)my_malloc((uint)(sizeof(char *) *
1655
 
                                              primary_keys_number_of),
 
1676
      primary_keys= (char **)my_malloc((uint)(sizeof(char *) * 
 
1677
                                              primary_keys_number_of), 
1656
1678
                                       MYF(MY_ZEROFILL|MY_FAE|MY_WME));
1657
 
      row= drizzle_fetch_row(result);
1658
 
      for (counter= 0; counter < primary_keys_number_of;
1659
 
           counter++, row= drizzle_fetch_row(result))
 
1679
      row= mysql_fetch_row(result);
 
1680
      for (counter= 0; counter < primary_keys_number_of; 
 
1681
           counter++, row= mysql_fetch_row(result))
1660
1682
        primary_keys[counter]= my_strdup(row[0], MYF(0));
1661
1683
    }
1662
1684
 
1663
 
    drizzle_free_result(result);
 
1685
    mysql_free_result(result);
1664
1686
  }
1665
1687
 
1666
1688
  return(0);
1669
1691
static int
1670
1692
drop_primary_key_list(void)
1671
1693
{
1672
 
  uint64_t counter;
 
1694
  unsigned long long counter;
1673
1695
 
1674
1696
  if (primary_keys_number_of)
1675
1697
  {
1676
1698
    for (counter= 0; counter < primary_keys_number_of; counter++)
1677
 
      free(primary_keys[counter]);
 
1699
      my_free(primary_keys[counter], MYF(0));
1678
1700
 
1679
 
    free(primary_keys);
 
1701
    my_free(primary_keys, MYF(0));
1680
1702
  }
1681
1703
 
1682
1704
  return 0;
1683
1705
}
1684
1706
 
1685
1707
static int
1686
 
create_schema(DRIZZLE *drizzle, const char *db, statement *stmt,
 
1708
create_schema(MYSQL *mysql, const char *db, statement *stmt, 
1687
1709
              option_string *engine_stmt, stats *sptr)
1688
1710
{
1689
1711
  char query[HUGE_STRING_LENGTH];
1701
1723
  if (verbose >= 2)
1702
1724
    printf("Loading Pre-data\n");
1703
1725
 
1704
 
  if (run_query(drizzle, query, len))
 
1726
  if (run_query(mysql, query, len))
1705
1727
  {
1706
1728
    fprintf(stderr,"%s: Cannot create schema %s : %s\n", my_progname, db,
1707
 
            drizzle_error(drizzle));
 
1729
            mysql_error(mysql));
1708
1730
    exit(1);
1709
1731
  }
1710
1732
  else
1721
1743
    if (verbose >= 3)
1722
1744
      printf("%s;\n", query);
1723
1745
 
1724
 
    if (drizzle_select_db(drizzle,  db))
 
1746
    if (mysql_select_db(mysql,  db))
1725
1747
    {
1726
1748
      fprintf(stderr,"%s: Cannot select schema '%s': %s\n",my_progname, db,
1727
 
              drizzle_error(drizzle));
 
1749
              mysql_error(mysql));
1728
1750
      exit(1);
1729
1751
    }
1730
1752
    sptr->create_count++;
1734
1756
  {
1735
1757
    len= snprintf(query, HUGE_STRING_LENGTH, "set storage_engine=`%s`",
1736
1758
                  engine_stmt->string);
1737
 
    if (run_query(drizzle, query, len))
 
1759
    if (run_query(mysql, query, len))
1738
1760
    {
1739
1761
      fprintf(stderr,"%s: Cannot set default engine: %s\n", my_progname,
1740
 
              drizzle_error(drizzle));
 
1762
              mysql_error(mysql));
1741
1763
      exit(1);
1742
1764
    }
1743
1765
    sptr->create_count++;
1756
1778
    {
1757
1779
      char buffer[HUGE_STRING_LENGTH];
1758
1780
 
1759
 
      snprintf(buffer, HUGE_STRING_LENGTH, "%s %s", ptr->string,
 
1781
      snprintf(buffer, HUGE_STRING_LENGTH, "%s %s", ptr->string, 
1760
1782
               engine_stmt->option);
1761
 
      if (run_query(drizzle, buffer, strlen(buffer)))
 
1783
      if (run_query(mysql, buffer, strlen(buffer)))
1762
1784
      {
1763
1785
        fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
1764
 
                my_progname, (uint)ptr->length, ptr->string, drizzle_error(drizzle));
 
1786
                my_progname, (uint)ptr->length, ptr->string, mysql_error(mysql));
1765
1787
        if (!opt_ignore_sql_errors)
1766
1788
          exit(1);
1767
1789
      }
1769
1791
    }
1770
1792
    else
1771
1793
    {
1772
 
      if (run_query(drizzle, ptr->string, ptr->length))
 
1794
      if (run_query(mysql, ptr->string, ptr->length))
1773
1795
      {
1774
1796
        fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
1775
 
                my_progname, (uint)ptr->length, ptr->string, drizzle_error(drizzle));
 
1797
                my_progname, (uint)ptr->length, ptr->string, mysql_error(mysql));
1776
1798
        if (!opt_ignore_sql_errors)
1777
1799
          exit(1);
1778
1800
      }
1795
1817
}
1796
1818
 
1797
1819
static int
1798
 
drop_schema(DRIZZLE *drizzle, const char *db)
 
1820
drop_schema(MYSQL *mysql, const char *db)
1799
1821
{
1800
1822
  char query[HUGE_STRING_LENGTH];
1801
1823
  int len;
1802
1824
 
1803
1825
  len= snprintf(query, HUGE_STRING_LENGTH, "DROP SCHEMA IF EXISTS `%s`", db);
1804
1826
 
1805
 
  if (run_query(drizzle, query, len))
 
1827
  if (run_query(mysql, query, len))
1806
1828
  {
1807
1829
    fprintf(stderr,"%s: Cannot drop database '%s' ERROR : %s\n",
1808
 
            my_progname, db, drizzle_error(drizzle));
 
1830
            my_progname, db, mysql_error(mysql));
1809
1831
    exit(1);
1810
1832
  }
1811
1833
 
1815
1837
}
1816
1838
 
1817
1839
static int
1818
 
run_statements(DRIZZLE *drizzle, statement *stmt)
 
1840
run_statements(MYSQL *mysql, statement *stmt) 
1819
1841
{
1820
1842
  statement *ptr;
1821
 
  DRIZZLE_RES *result;
 
1843
  MYSQL_RES *result;
1822
1844
 
1823
1845
 
1824
1846
  for (ptr= stmt; ptr && ptr->length; ptr= ptr->next)
1825
1847
  {
1826
 
    if (run_query(drizzle, ptr->string, ptr->length))
 
1848
    if (run_query(mysql, ptr->string, ptr->length))
1827
1849
    {
1828
1850
      fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
1829
 
              my_progname, (uint)ptr->length, ptr->string, drizzle_error(drizzle));
 
1851
              my_progname, (uint)ptr->length, ptr->string, mysql_error(mysql));
1830
1852
      exit(1);
1831
1853
    }
1832
1854
    if (!opt_only_print)
1833
1855
    {
1834
 
      if (drizzle_field_count(drizzle))
 
1856
      if (mysql_field_count(mysql))
1835
1857
      {
1836
 
        result= drizzle_store_result(drizzle);
1837
 
        drizzle_free_result(result);
 
1858
        result= mysql_store_result(mysql);
 
1859
        mysql_free_result(result);
1838
1860
      }
1839
1861
    }
1840
1862
  }
1857
1879
 
1858
1880
  pthread_attr_init(&attr);
1859
1881
  pthread_attr_setdetachstate(&attr,
1860
 
                              PTHREAD_CREATE_DETACHED);
 
1882
                  PTHREAD_CREATE_DETACHED);
1861
1883
 
1862
1884
  pthread_mutex_lock(&counter_mutex);
1863
1885
  thread_counter= 0;
1868
1890
 
1869
1891
  real_concurrency= 0;
1870
1892
 
1871
 
  for (y= 0, sql_type= query_options;
1872
 
       y < query_statements_count;
 
1893
  for (y= 0, sql_type= query_options; 
 
1894
       y < query_statements_count; 
1873
1895
       y++, sql_type= sql_type->next)
1874
1896
  {
1875
1897
    unsigned int options_loop= 1;
1876
1898
 
1877
1899
    if (sql_type->option)
1878
1900
    {
1879
 
      options_loop= strtol(sql_type->option,
 
1901
      options_loop= strtol(sql_type->option, 
1880
1902
                           (char **)NULL, 10);
1881
1903
      options_loop= options_loop ? options_loop : 1;
1882
1904
    }
1890
1912
 
1891
1913
        real_concurrency++;
1892
1914
        /* now you create the thread */
1893
 
        if (pthread_create(&mainthread, &attr, run_task,
 
1915
        if (pthread_create(&mainthread, &attr, run_task, 
1894
1916
                           (void *)con) != 0)
1895
1917
        {
1896
1918
          fprintf(stderr,"%s: Could not create thread\n", my_progname);
1900
1922
      }
1901
1923
  }
1902
1924
 
1903
 
  /*
1904
 
    The timer_thread belongs to all threads so it too obeys the wakeup
 
1925
  /* 
 
1926
    The timer_thread belongs to all threads so it too obeys the wakeup 
1905
1927
    call that run tasks obey.
1906
1928
  */
1907
1929
  if (opt_timer_length)
1910
1932
    timer_alarm= true;
1911
1933
    pthread_mutex_unlock(&timer_alarm_mutex);
1912
1934
 
1913
 
    if (pthread_create(&mainthread, &attr, timer_thread,
 
1935
    if (pthread_create(&mainthread, &attr, timer_thread, 
1914
1936
                       (void *)&opt_timer_length) != 0)
1915
1937
    {
1916
1938
      fprintf(stderr,"%s: Could not create timer thread\n", my_progname);
1959
1981
  struct timespec abstime;
1960
1982
 
1961
1983
 
1962
 
  /*
1963
 
    We lock around the initial call in case were we in a loop. This
 
1984
 
 
1985
  if (mysql_thread_init())
 
1986
  {
 
1987
    fprintf(stderr,"%s: mysql_thread_init() failed.\n",
 
1988
            my_progname);
 
1989
    exit(1);
 
1990
  }
 
1991
 
 
1992
  /* 
 
1993
    We lock around the initial call in case were we in a loop. This 
1964
1994
    also keeps the value properly syncronized across call threads.
1965
1995
  */
1966
1996
  pthread_mutex_lock(&sleeper_mutex);
1980
2010
  timer_alarm= false;
1981
2011
  pthread_mutex_unlock(&timer_alarm_mutex);
1982
2012
 
 
2013
  mysql_thread_end();
1983
2014
  return(0);
1984
2015
}
1985
2016
 
1988
2019
  uint64_t counter= 0, queries;
1989
2020
  uint64_t detach_counter;
1990
2021
  unsigned int commit_counter;
1991
 
  DRIZZLE drizzle;
1992
 
  DRIZZLE_RES *result;
1993
 
  DRIZZLE_ROW row;
 
2022
  MYSQL mysql;
 
2023
  MYSQL_RES *result;
 
2024
  MYSQL_ROW row;
1994
2025
  statement *ptr;
1995
2026
  thread_context *con= (thread_context *)p;
1996
2027
 
 
2028
  if (mysql_thread_init())
 
2029
  {
 
2030
    fprintf(stderr,"%s: mysql_thread_init() failed.\n",
 
2031
            my_progname);
 
2032
    exit(1);
 
2033
  }
 
2034
 
1997
2035
  pthread_mutex_lock(&sleeper_mutex);
1998
2036
  while (master_wakeup)
1999
2037
  {
2001
2039
  }
2002
2040
  pthread_mutex_unlock(&sleeper_mutex);
2003
2041
 
2004
 
  slap_connect(&drizzle, true);
 
2042
  slap_connect(&mysql, true);
2005
2043
 
2006
2044
  if (verbose >= 3)
2007
2045
    printf("connected!\n");
2009
2047
 
2010
2048
  commit_counter= 0;
2011
2049
  if (commit_rate)
2012
 
    run_query(&drizzle, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
 
2050
    run_query(&mysql, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
2013
2051
 
2014
2052
limit_not_met:
2015
 
  for (ptr= con->stmt, detach_counter= 0;
2016
 
       ptr && ptr->length;
2017
 
       ptr= ptr->next, detach_counter++)
2018
 
  {
2019
 
    if (!opt_only_print && detach_rate && !(detach_counter % detach_rate))
2020
 
    {
2021
 
      slap_close(&drizzle);
2022
 
      slap_connect(&drizzle, true);
2023
 
    }
2024
 
 
2025
 
    /*
2026
 
      We have to execute differently based on query type. This should become a function.
2027
 
    */
2028
 
    if ((ptr->type == UPDATE_TYPE_REQUIRES_PREFIX) ||
2029
 
        (ptr->type == SELECT_TYPE_REQUIRES_PREFIX))
2030
 
    {
2031
 
      int length;
2032
 
      unsigned int key_val;
2033
 
      char *key;
2034
 
      char buffer[HUGE_STRING_LENGTH];
2035
 
 
2036
 
      /*
2037
 
        This should only happen if some sort of new engine was
2038
 
        implemented that didn't properly handle UPDATEs.
2039
 
 
2040
 
        Just in case someone runs this under an experimental engine we don't
2041
 
        want a crash so the if() is placed here.
 
2053
    for (ptr= con->stmt, detach_counter= 0; 
 
2054
         ptr && ptr->length; 
 
2055
         ptr= ptr->next, detach_counter++)
 
2056
    {
 
2057
      if (!opt_only_print && detach_rate && !(detach_counter % detach_rate))
 
2058
      {
 
2059
        slap_close(&mysql);
 
2060
        slap_connect(&mysql, true);
 
2061
      }
 
2062
 
 
2063
      /* 
 
2064
        We have to execute differently based on query type. This should become a function.
2042
2065
      */
2043
 
      assert(primary_keys_number_of);
2044
 
      if (primary_keys_number_of)
2045
 
      {
2046
 
        key_val= (unsigned int)(random() % primary_keys_number_of);
2047
 
        key= primary_keys[key_val];
2048
 
 
2049
 
        assert(key);
2050
 
 
2051
 
        length= snprintf(buffer, HUGE_STRING_LENGTH, "%.*s '%s'",
2052
 
                         (int)ptr->length, ptr->string, key);
2053
 
 
2054
 
        if (run_query(&drizzle, buffer, length))
 
2066
      if ((ptr->type == UPDATE_TYPE_REQUIRES_PREFIX) ||
 
2067
          (ptr->type == SELECT_TYPE_REQUIRES_PREFIX))
 
2068
      {
 
2069
        int length;
 
2070
        unsigned int key_val;
 
2071
        char *key;
 
2072
        char buffer[HUGE_STRING_LENGTH];
 
2073
 
 
2074
        /* 
 
2075
          This should only happen if some sort of new engine was
 
2076
          implemented that didn't properly handle UPDATEs.
 
2077
 
 
2078
          Just in case someone runs this under an experimental engine we don't
 
2079
          want a crash so the if() is placed here.
 
2080
        */
 
2081
        assert(primary_keys_number_of);
 
2082
        if (primary_keys_number_of)
 
2083
        {
 
2084
          key_val= (unsigned int)(random() % primary_keys_number_of);
 
2085
          key= primary_keys[key_val];
 
2086
 
 
2087
          assert(key);
 
2088
 
 
2089
          length= snprintf(buffer, HUGE_STRING_LENGTH, "%.*s '%s'", 
 
2090
                           (int)ptr->length, ptr->string, key);
 
2091
 
 
2092
          if (run_query(&mysql, buffer, length))
 
2093
          {
 
2094
            fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
 
2095
                    my_progname, (uint)length, buffer, mysql_error(&mysql));
 
2096
            exit(1);
 
2097
          }
 
2098
        }
 
2099
      }
 
2100
      else
 
2101
      {
 
2102
        if (run_query(&mysql, ptr->string, ptr->length))
2055
2103
        {
2056
2104
          fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
2057
 
                  my_progname, (uint)length, buffer, drizzle_error(&drizzle));
 
2105
                  my_progname, (uint)ptr->length, ptr->string, mysql_error(&mysql));
2058
2106
          exit(1);
2059
2107
        }
2060
2108
      }
2061
 
    }
2062
 
    else
2063
 
    {
2064
 
      if (run_query(&drizzle, ptr->string, ptr->length))
2065
 
      {
2066
 
        fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
2067
 
                my_progname, (uint)ptr->length, ptr->string, drizzle_error(&drizzle));
2068
 
        exit(1);
2069
 
      }
2070
 
    }
2071
2109
 
2072
 
    if (!opt_only_print)
2073
 
    {
2074
 
      do
 
2110
      if (!opt_only_print)
2075
2111
      {
2076
 
        if (drizzle_field_count(&drizzle))
 
2112
        do
2077
2113
        {
2078
 
          result= drizzle_store_result(&drizzle);
2079
 
          while ((row = drizzle_fetch_row(result)))
2080
 
            counter++;
2081
 
          drizzle_free_result(result);
2082
 
        }
2083
 
      } while(drizzle_next_result(&drizzle) == 0);
2084
 
    }
2085
 
    queries++;
2086
 
 
2087
 
    if (commit_rate && (++commit_counter == commit_rate))
2088
 
    {
2089
 
      commit_counter= 0;
2090
 
      run_query(&drizzle, "COMMIT", strlen("COMMIT"));
2091
 
    }
2092
 
 
2093
 
    /* If the timer is set, and the alarm is not active then end */
2094
 
    if (opt_timer_length && timer_alarm == false)
2095
 
      goto end;
2096
 
 
2097
 
    /* If limit has been reached, and we are not in a timer_alarm just end */
2098
 
    if (con->limit && queries == con->limit && timer_alarm == false)
2099
 
      goto end;
2100
 
  }
2101
 
 
2102
 
  if (opt_timer_length && timer_alarm == true)
2103
 
    goto limit_not_met;
2104
 
 
2105
 
  if (con->limit && queries < con->limit)
2106
 
    goto limit_not_met;
 
2114
          if (mysql_field_count(&mysql))
 
2115
          {
 
2116
            result= mysql_store_result(&mysql);
 
2117
            while ((row = mysql_fetch_row(result)))
 
2118
              counter++;
 
2119
            mysql_free_result(result);
 
2120
          }
 
2121
        } while(mysql_next_result(&mysql) == 0);
 
2122
      }
 
2123
      queries++;
 
2124
 
 
2125
      if (commit_rate && (++commit_counter == commit_rate))
 
2126
      {
 
2127
        commit_counter= 0;
 
2128
        run_query(&mysql, "COMMIT", strlen("COMMIT"));
 
2129
      }
 
2130
 
 
2131
      /* If the timer is set, and the alarm is not active then end */
 
2132
      if (opt_timer_length && timer_alarm == false)
 
2133
        goto end;
 
2134
 
 
2135
      /* If limit has been reached, and we are not in a timer_alarm just end */
 
2136
      if (con->limit && queries == con->limit && timer_alarm == false)
 
2137
        goto end;
 
2138
    }
 
2139
 
 
2140
    if (opt_timer_length && timer_alarm == true)
 
2141
      goto limit_not_met;
 
2142
 
 
2143
    if (con->limit && queries < con->limit)
 
2144
      goto limit_not_met;
2107
2145
 
2108
2146
 
2109
2147
end:
2110
2148
  if (commit_rate)
2111
 
    run_query(&drizzle, "COMMIT", strlen("COMMIT"));
 
2149
    run_query(&mysql, "COMMIT", strlen("COMMIT"));
2112
2150
 
2113
 
  slap_close(&drizzle);
 
2151
  slap_close(&mysql);
2114
2152
 
2115
2153
  pthread_mutex_lock(&counter_mutex);
2116
2154
  thread_counter--;
2117
2155
  pthread_cond_signal(&count_threshhold);
2118
2156
  pthread_mutex_unlock(&counter_mutex);
2119
2157
 
2120
 
  free(con);
 
2158
  my_free(con, MYF(0));
2121
2159
 
 
2160
  mysql_thread_end();
2122
2161
  return(0);
2123
2162
}
2124
2163
 
2149
2188
    char buffer[HUGE_STRING_LENGTH];
2150
2189
    char *buffer_ptr;
2151
2190
 
2152
 
    memset(buffer, 0, HUGE_STRING_LENGTH);
 
2191
    bzero(buffer, HUGE_STRING_LENGTH);
2153
2192
 
2154
 
    string= strchr(begin_ptr, delm);
 
2193
    string= strchr(begin_ptr, delm); 
2155
2194
 
2156
2195
    if (string)
2157
2196
    {
2210
2249
 
2211
2250
  for (tmp= *sptr= (statement *)my_malloc(sizeof(statement),
2212
2251
                                          MYF(MY_ZEROFILL|MY_FAE|MY_WME));
2213
 
       (retstr= strchr(ptr, delm));
 
2252
       (retstr= strchr(ptr, delm)); 
2214
2253
       tmp->next=  (statement *)my_malloc(sizeof(statement),
2215
2254
                                          MYF(MY_ZEROFILL|MY_FAE|MY_WME)),
2216
 
         tmp= tmp->next)
 
2255
       tmp= tmp->next)
2217
2256
  {
2218
2257
    count++;
2219
2258
    tmp->string= my_strndup(ptr, (uint)(retstr - ptr), MYF(MY_FAE));
2225
2264
 
2226
2265
  if (ptr != script+length)
2227
2266
  {
2228
 
    tmp->string= my_strndup(ptr, (uint)((script + length) - ptr),
2229
 
                            MYF(MY_FAE));
 
2267
    tmp->string= my_strndup(ptr, (uint)((script + length) - ptr), 
 
2268
                                       MYF(MY_FAE));
2230
2269
    tmp->length= (size_t)((script + length) - ptr);
2231
2270
    count++;
2232
2271
  }
2250
2289
 
2251
2290
  for (;*ptr; ptr++)
2252
2291
    if (*ptr == ',') count++;
2253
 
 
 
2292
  
2254
2293
  /* One extra spot for the NULL */
2255
 
  nptr= *range= (uint *)my_malloc(sizeof(uint) * (count + 1),
 
2294
  nptr= *range= (uint *)my_malloc(sizeof(uint) * (count + 1), 
2256
2295
                                  MYF(MY_ZEROFILL|MY_FAE|MY_WME));
2257
2296
 
2258
2297
  ptr= (char *)string;
2272
2311
{
2273
2312
  printf("Benchmark\n");
2274
2313
  if (con->engine)
2275
 
    printf("\tRunning for engine %s\n", con->engine);
 
2314
      printf("\tRunning for engine %s\n", con->engine);
2276
2315
  if (opt_label || opt_auto_generate_sql_type)
2277
2316
  {
2278
2317
    const char *ptr= opt_auto_generate_sql_type ? opt_auto_generate_sql_type : "query";
2286
2325
         con->min_timing / 1000, con->min_timing % 1000);
2287
2326
  printf("\tMaximum number of seconds to run all queries: %ld.%03ld seconds\n",
2288
2327
         con->max_timing / 1000, con->max_timing % 1000);
2289
 
  printf("\tTotal time for tests: %ld.%03ld seconds\n",
 
2328
  printf("\tTotal time for tests: %ld.%03ld seconds\n", 
2290
2329
         con->sum_of_time / 1000, con->sum_of_time % 1000);
2291
2330
  printf("\tStandard Deviation: %ld.%03ld\n", con->std_dev / 1000, con->std_dev % 1000);
2292
 
  printf("\tNumber of queries in create queries: %"PRIu64"\n", con->create_count);
2293
 
  printf("\tNumber of clients running queries: %u/%u\n",
 
2331
  printf("\tNumber of queries in create queries: %llu\n", con->create_count);
 
2332
  printf("\tNumber of clients running queries: %u/%u\n", 
2294
2333
         con->users, con->real_users);
2295
2334
  printf("\tNumber of times test was run: %u\n", iterations);
2296
 
  printf("\tAverage number of queries per client: %"PRIu64"\n", con->avg_rows);
 
2335
  printf("\tAverage number of queries per client: %llu\n", con->avg_rows); 
2297
2336
  printf("\n");
2298
2337
}
2299
2338
 
2305
2344
  char label_buffer[HUGE_STRING_LENGTH];
2306
2345
  size_t string_len;
2307
2346
 
2308
 
  memset(label_buffer, 0, HUGE_STRING_LENGTH);
 
2347
  bzero(label_buffer, HUGE_STRING_LENGTH);
2309
2348
 
2310
2349
  if (opt_label)
2311
2350
  {
2318
2357
      else
2319
2358
        label_buffer[x]= opt_label[x] ;
2320
2359
    }
2321
 
  }
 
2360
  } 
2322
2361
  else if (opt_auto_generate_sql_type)
2323
2362
  {
2324
2363
    string_len= strlen(opt_auto_generate_sql_type);
2334
2373
  else
2335
2374
    snprintf(label_buffer, HUGE_STRING_LENGTH, "query");
2336
2375
 
2337
 
  snprintf(buffer, HUGE_STRING_LENGTH,
2338
 
           "%s,%s,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,"
2339
 
           "%u,%u,%u,%"PRIu64"\n",
 
2376
  snprintf(buffer, HUGE_STRING_LENGTH, 
 
2377
           "%s,%s,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,%u,%u,%u,%llu\n",
2340
2378
           con->engine ? con->engine : "", /* Storage engine we ran against */
2341
2379
           label_buffer, /* Load type */
2342
2380
           con->avg_timing / 1000, con->avg_timing % 1000, /* Time to load */
2348
2386
           con->users, /* Children used max_timing */
2349
2387
           con->real_users, /* Children used max_timing */
2350
2388
           con->avg_rows  /* Queries run */
2351
 
           );
2352
 
  my_write(csv_file, (unsigned char*) buffer, (uint)strlen(buffer), MYF(0));
 
2389
          );
 
2390
  my_write(csv_file, (uchar*) buffer, (uint)strlen(buffer), MYF(0));
2353
2391
}
2354
2392
 
2355
2393
void
2358
2396
  stats *ptr;
2359
2397
  unsigned int x;
2360
2398
 
2361
 
  con->min_timing= sptr->timing;
 
2399
  con->min_timing= sptr->timing; 
2362
2400
  con->max_timing= sptr->timing;
2363
2401
  con->min_rows= sptr->rows;
2364
2402
  con->max_rows= sptr->rows;
2365
 
 
 
2403
  
2366
2404
  /* At the moment we assume uniform */
2367
2405
  con->users= sptr->users;
2368
2406
  con->real_users= sptr->real_users;
2369
2407
  con->avg_rows= sptr->rows;
2370
 
 
 
2408
  
2371
2409
  /* With no next, we know it is the last element that was malloced */
2372
2410
  for (ptr= sptr, x= 0; x < iterations; ptr++, x++)
2373
2411
  {
2389
2427
  standard_deviation(con, sptr);
2390
2428
 
2391
2429
  /* Now we do the create time operations */
2392
 
  con->create_min_timing= sptr->create_timing;
 
2430
  con->create_min_timing= sptr->create_timing; 
2393
2431
  con->create_max_timing= sptr->create_timing;
2394
 
 
 
2432
  
2395
2433
  /* At the moment we assume uniform */
2396
2434
  con->create_count= sptr->create_count;
2397
 
 
 
2435
  
2398
2436
  /* With no next, we know it is the last element that was malloced */
2399
2437
  for (ptr= sptr, x= 0; x < iterations; ptr++, x++)
2400
2438
  {
2419
2457
  {
2420
2458
    nptr= ptr->next;
2421
2459
    if (ptr->string)
2422
 
      free(ptr->string);
 
2460
      my_free(ptr->string, MYF(0)); 
2423
2461
    if (ptr->option)
2424
 
      free(ptr->option);
2425
 
    free(ptr);
 
2462
      my_free(ptr->option, MYF(0)); 
 
2463
    my_free(ptr, MYF(0));
2426
2464
  }
2427
2465
}
2428
2466
 
2437
2475
  {
2438
2476
    nptr= ptr->next;
2439
2477
    if (ptr->string)
2440
 
      free(ptr->string);
2441
 
    free(ptr);
 
2478
      my_free(ptr->string, MYF(0)); 
 
2479
    my_free(ptr, MYF(0));
2442
2480
  }
2443
2481
}
2444
2482
 
2445
 
void
2446
 
slap_close(DRIZZLE *drizzle)
 
2483
void 
 
2484
slap_close(MYSQL *mysql)
2447
2485
{
2448
 
  if (opt_only_print)
 
2486
  if (opt_only_print) 
2449
2487
    return;
2450
2488
 
2451
 
  drizzle_close(drizzle);
 
2489
  mysql_close(mysql);
2452
2490
}
2453
2491
 
2454
 
void
2455
 
slap_connect(DRIZZLE *drizzle, bool connect_to_schema)
 
2492
void 
 
2493
slap_connect(MYSQL *mysql, bool connect_to_schema)
2456
2494
{
2457
2495
  /* Connect to server */
2458
 
  static uint32_t connection_retry_sleep= 100000; /* Microseconds */
 
2496
  static ulong connection_retry_sleep= 100000; /* Microseconds */
2459
2497
  int x, connect_error= 1;
2460
2498
 
2461
 
  if (opt_only_print)
 
2499
  if (opt_only_print) 
2462
2500
    return;
2463
2501
 
2464
2502
  if (opt_delayed_start)
2465
2503
    my_sleep(random()%opt_delayed_start);
2466
2504
 
2467
 
  drizzle_create(drizzle);
 
2505
  mysql_init(mysql);
2468
2506
 
2469
2507
  if (opt_compress)
2470
 
    drizzle_options(drizzle,DRIZZLE_OPT_COMPRESS,NULL);
 
2508
    mysql_options(mysql,MYSQL_OPT_COMPRESS,NullS);
 
2509
  /* We always do opt_protocol to TCP/IP */
 
2510
  mysql_options(mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
 
2511
  mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset);
2471
2512
 
2472
2513
  for (x= 0; x < 10; x++)
2473
2514
  {
2474
2515
 
2475
2516
 
2476
 
    if (drizzle_connect(drizzle, host, user, opt_password,
2477
 
                        connect_to_schema ? create_schema_string : NULL,
2478
 
                        opt_drizzle_port,
2479
 
                        opt_drizzle_unix_port,
2480
 
                        connect_flags))
 
2517
    if (mysql_real_connect(mysql, host, user, opt_password,
 
2518
                           connect_to_schema ? create_schema_string : NULL,
 
2519
                           opt_mysql_port,
 
2520
                           opt_mysql_unix_port,
 
2521
                           connect_flags))
2481
2522
    {
2482
2523
      /* Connect suceeded */
2483
2524
      connect_error= 0;
2488
2529
  if (connect_error)
2489
2530
  {
2490
2531
    fprintf(stderr,"%s: Error when connecting to server: %d %s\n",
2491
 
            my_progname, drizzle_errno(drizzle), drizzle_error(drizzle));
 
2532
            my_progname, mysql_errno(mysql), mysql_error(mysql));
2492
2533
    exit(1);
2493
2534
  }
2494
2535
 
2495
2536
  return;
2496
2537
}
2497
2538
 
2498
 
void
 
2539
void 
2499
2540
standard_deviation (conclusions *con, stats *sptr)
2500
2541
{
2501
2542
  unsigned int x;
2502
2543
  long int sum_of_squares;
2503
 
  double the_catch;
 
2544
  double catch;
2504
2545
  stats *ptr;
2505
2546
 
2506
2547
  if (iterations == 1 || iterations == 0)
2517
2558
    sum_of_squares+= deviation*deviation;
2518
2559
  }
2519
2560
 
2520
 
  the_catch= sqrt((double)(sum_of_squares/(iterations -1)));
2521
 
  con->std_dev= (long int)the_catch;
 
2561
  catch= sqrt((double)(sum_of_squares/(iterations -1)));
 
2562
  con->std_dev= (long int)catch;
2522
2563
}