~drizzle-trunk/drizzle/development

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