~drizzle-trunk/drizzle/development

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