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