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