~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzleslap.cc

  • Committer: Monty Taylor
  • Date: 2010-05-24 19:34:46 UTC
  • mto: This revision was merged to the branch mainline in revision 1564.
  • Revision ID: mordred@inaugust.com-20100524193446-j74n0rvylqdnttld
Updated translations to what's in the tree.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2010 Vijay Samuel
5
4
 *  Copyright (C) 2008 MySQL
6
5
 *
7
6
 *  This program is free software; you can redistribute it and/or modify
61
60
  --iterations=5 --query=query.sql --create=create.sql \
62
61
  --delimiter=";"
63
62
 
64
 
  @todo
 
63
  TODO:
65
64
  Add language for better tests
66
65
  String length for files and those put on the command line are not
67
66
  setup to handle binary data.
71
70
 
72
71
*/
73
72
 
74
 
#include "config.h"
 
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
75
78
 
76
79
#include "client_priv.h"
77
80
#include <signal.h>
83
86
#endif
84
87
#include <fcntl.h>
85
88
#include <math.h>
 
89
#include <ctype.h>
86
90
#include <cassert>
87
91
#include <cstdlib>
88
92
#include <string>
89
 
#include <iostream>
90
 
#include <fstream>
 
93
 
91
94
#include <pthread.h>
92
 
#include <drizzled/configmake.h>
 
95
 
93
96
/* Added this for string translation. */
94
97
#include <drizzled/gettext.h>
95
 
#include <boost/program_options.hpp>
96
 
 
97
 
#define SLAP_VERSION "1.5"
98
 
 
99
 
#define HUGE_STRING_LENGTH 8196
100
 
#define RAND_STRING_SIZE 126
101
 
#define DEFAULT_BLOB_SIZE 1024
102
98
 
103
99
using namespace std;
104
100
using namespace drizzled;
105
 
namespace po= boost::program_options;
106
101
 
107
102
#ifdef HAVE_SMEM
108
103
static char *shared_memory_base_name=0;
121
116
pthread_mutex_t timer_alarm_mutex;
122
117
pthread_cond_t timer_alarm_threshold;
123
118
 
124
 
std::vector < std::string > primary_keys;
125
 
 
126
 
static string host, 
127
 
  opt_password, 
128
 
  user,
129
 
  user_supplied_query,
130
 
  user_supplied_pre_statements,
131
 
  user_supplied_post_statements,
132
 
  default_engine,
133
 
  pre_system,
134
 
  post_system;
135
 
 
136
 
static vector<string> user_supplied_queries;
137
 
static string opt_verbose;
138
 
std::string opt_protocol;
139
 
string delimiter;
140
 
 
141
 
string create_schema_string;
142
 
 
143
 
static bool use_drizzle_protocol= false;
 
119
static char **defaults_argv;
 
120
 
 
121
char **primary_keys;
 
122
/* This gets passed to malloc, so lets set it to an arch-dependant size */
 
123
size_t primary_keys_number_of;
 
124
 
 
125
static char *host= NULL, *opt_password= NULL, *user= NULL,
 
126
  *user_supplied_query= NULL,
 
127
  *user_supplied_pre_statements= NULL,
 
128
  *user_supplied_post_statements= NULL,
 
129
  *default_engine= NULL,
 
130
  *pre_system= NULL,
 
131
  *post_system= NULL;
 
132
 
 
133
const char *delimiter= "\n";
 
134
 
 
135
const char *create_schema_string= "drizzleslap";
 
136
 
 
137
static bool opt_mysql= false;
144
138
static bool opt_preserve= true;
145
 
static bool opt_only_print;
146
 
static bool opt_burnin;
 
139
static bool opt_only_print= false;
 
140
static bool opt_burnin= false;
147
141
static bool opt_ignore_sql_errors= false;
148
 
static bool opt_silent,
149
 
  auto_generate_sql_autoincrement,
150
 
  auto_generate_sql_guid_primary,
151
 
  auto_generate_sql;
152
 
std::string opt_auto_generate_sql_type;
 
142
static bool tty_password= false,
 
143
  opt_silent= false,
 
144
  auto_generate_sql_autoincrement= false,
 
145
  auto_generate_sql_guid_primary= false,
 
146
  auto_generate_sql= false;
 
147
const char *opt_auto_generate_sql_type= "mixed";
153
148
 
154
 
static int32_t verbose= 0;
155
 
static uint32_t delimiter_length;
 
149
static int verbose, delimiter_length;
156
150
static uint32_t commit_rate;
157
151
static uint32_t detach_rate;
158
152
static uint32_t opt_timer_length;
159
153
static uint32_t opt_delayed_start;
160
 
string num_blob_cols_opt,
161
 
  num_char_cols_opt,
162
 
  num_int_cols_opt;
163
 
string opt_label;
 
154
const char *num_int_cols_opt;
 
155
const char *num_char_cols_opt;
 
156
const char *num_blob_cols_opt;
 
157
const char *opt_label;
164
158
static unsigned int opt_set_random_seed;
165
159
 
166
 
string auto_generate_selected_columns_opt;
 
160
const char *auto_generate_selected_columns_opt;
167
161
 
168
162
/* Yes, we do set defaults here */
169
163
static unsigned int num_int_cols= 1;
173
167
static unsigned int num_blob_cols_size_min;
174
168
static unsigned int num_int_cols_index= 0;
175
169
static unsigned int num_char_cols_index= 0;
176
 
static uint32_t iterations;
 
170
static unsigned int iterations;
177
171
static uint64_t actual_queries= 0;
178
172
static uint64_t auto_actual_queries;
179
173
static uint64_t auto_generate_sql_unique_write_number;
180
174
static uint64_t auto_generate_sql_unique_query_number;
181
 
static uint32_t auto_generate_sql_secondary_indexes;
 
175
static unsigned int auto_generate_sql_secondary_indexes;
182
176
static uint64_t num_of_query;
183
177
static uint64_t auto_generate_sql_number;
184
 
string concurrency_str;
185
 
string create_string;
186
 
std::vector <uint32_t> concurrency;
 
178
const char *concurrency_str= NULL;
 
179
static char *create_string;
 
180
uint32_t *concurrency;
187
181
 
188
182
const char *default_dbug_option= "d:t:o,/tmp/drizzleslap.trace";
189
 
std::string opt_csv_str;
 
183
const char *opt_csv_str;
190
184
int csv_file;
191
185
 
192
 
static int process_options(void);
 
186
static int get_options(int *argc,char ***argv);
193
187
static uint32_t opt_drizzle_port= 0;
194
188
 
 
189
static const char *load_default_groups[]= { "drizzleslap","client",0 };
195
190
 
196
191
/* Types */
197
 
enum slap_query_t {
 
192
typedef enum {
198
193
  SELECT_TYPE= 0,
199
194
  UPDATE_TYPE= 1,
200
195
  INSERT_TYPE= 2,
202
197
  CREATE_TABLE_TYPE= 4,
203
198
  SELECT_TYPE_REQUIRES_PREFIX= 5,
204
199
  DELETE_TYPE_REQUIRES_PREFIX= 6
205
 
};
 
200
} slap_query_type;
206
201
 
207
202
class Statement;
208
203
 
211
206
public:
212
207
  Statement(char *in_string,
213
208
            size_t in_length,
214
 
            slap_query_t in_type,
215
 
            Statement *in_next) :
 
209
            slap_query_type in_type,
 
210
            char *in_option,
 
211
            size_t in_option_length,
 
212
            Statement *in_next)
 
213
    :
216
214
    string(in_string),
217
215
    length(in_length),
218
216
    type(in_type),
 
217
    option(in_option),
 
218
    option_length(in_option_length),
219
219
    next(in_next)
220
 
  { }
 
220
    {}
221
221
 
222
 
  Statement() :
 
222
  Statement()
 
223
    :
223
224
    string(NULL),
224
225
    length(0),
225
226
    type(),
 
227
    option(NULL),
 
228
    option_length(0),
226
229
    next(NULL)
227
 
  { }
228
 
 
229
 
  ~Statement()
230
 
  {
231
 
    if (string)
232
 
      free(string);
233
 
  }
 
230
    {}
234
231
   
235
232
  char *getString() const
236
233
  {
242
239
    return length;
243
240
  }
244
241
 
245
 
  slap_query_t getType() const
 
242
  slap_query_type getType() const
246
243
  {
247
244
    return type;
248
245
  }
249
246
 
 
247
  char *getOption() const
 
248
  {
 
249
    return option;
 
250
  }
 
251
 
 
252
  size_t getOptionLength() const
 
253
  {
 
254
    return option_length;
 
255
  }
 
256
 
250
257
  Statement *getNext() const
251
258
  {
252
259
    return next;
257
264
    string= in_string;
258
265
  }
259
266
 
260
 
  void setString(size_t length_arg)
261
 
  {
262
 
    string= (char *)calloc(length_arg + 1, sizeof(char));
263
 
    length= length_arg;
264
 
  }
265
 
 
266
267
  void setString(size_t in_length, char in_char)
267
268
  {
268
269
    string[in_length]= in_char;
273
274
    length= in_length;
274
275
  }
275
276
 
276
 
  void setType(slap_query_t in_type)
 
277
  void setType(slap_query_type in_type)
277
278
  {
278
279
    type= in_type;
279
280
  }
280
281
 
 
282
  void setOption(char *in_option)
 
283
  {
 
284
    option= in_option;
 
285
  }
 
286
 
 
287
   void setOptionLength(size_t in_option_length)
 
288
  {
 
289
    option_length= in_option_length;
 
290
  }
 
291
 
281
292
  void setNext(Statement *in_next)
282
293
  {
283
294
    next= in_next;
286
297
private:
287
298
  char *string;
288
299
  size_t length;
289
 
  slap_query_t type;
 
300
  slap_query_type type;
 
301
  char *option;
 
302
  size_t option_length;
290
303
  Statement *next;
291
304
};
292
305
 
299
312
               size_t in_length,
300
313
               char *in_option,
301
314
               size_t in_option_length,
302
 
               OptionString *in_next) :
 
315
               OptionString *in_next)
 
316
    :
303
317
    string(in_string),
304
318
    length(in_length),
305
319
    option(in_option),
306
320
    option_length(in_option_length),
307
321
    next(in_next)
308
 
  { }  
 
322
    {}  
309
323
 
310
 
  OptionString() :
 
324
  OptionString()
 
325
    :
311
326
    string(NULL),
312
327
    length(0),
313
328
    option(NULL),
314
329
    option_length(0),
315
330
    next(NULL)
316
 
  { }
317
 
 
318
 
  ~OptionString()
319
 
  {
320
 
    if (getString())
321
 
      free(getString());
322
 
    if (getOption())
323
 
      free(getOption());
324
 
  }
 
331
    {}
325
332
 
326
333
  char *getString() const
327
334
  {
351
358
  void setString(char *in_string)
352
359
  {
353
360
    string= in_string;
354
 
    length= strlen(in_string);
 
361
  }
 
362
 
 
363
  void setOptionLength(size_t in_option_length)
 
364
  {
 
365
    option_length= in_option_length;
 
366
  }
 
367
 
 
368
  void setLength(size_t in_length)
 
369
  {
 
370
    length= in_length;
355
371
  }
356
372
 
357
373
  void setOption(char *in_option)
358
374
  {
359
 
    option= strdup(in_option);
360
 
    option_length= strlen(in_option);
 
375
    option= in_option;
 
376
  }
 
377
 
 
378
  void setOption(size_t in_option_length, char in_char)
 
379
  {
 
380
    option[in_option_length]= in_char;
361
381
  }
362
382
 
363
383
  void setNext(OptionString *in_next)
383
403
        uint32_t in_real_users,
384
404
        uint32_t in_rows,
385
405
        long int in_create_timing,
386
 
        uint64_t in_create_count) :
 
406
        uint64_t in_create_count)
 
407
    :
387
408
    timing(in_timing),
388
409
    users(in_users),
389
410
    real_users(in_real_users),
390
411
    rows(in_rows),
391
412
    create_timing(in_create_timing),
392
413
    create_count(in_create_count)
393
 
  { }
 
414
    {}
394
415
 
395
 
  Stats() :
 
416
  Stats()
 
417
    :
396
418
    timing(0),
397
419
    users(0),
398
420
    real_users(0),
399
421
    rows(0),
400
422
    create_timing(0),
401
423
    create_count(0)
402
 
  { }
 
424
    {}
403
425
 
404
426
  long int getTiming() const
405
427
  {
476
498
{
477
499
public:
478
500
  ThreadContext(Statement *in_stmt,
479
 
                uint64_t in_limit) :
 
501
                uint64_t in_limit)
 
502
    :
480
503
    stmt(in_stmt),
481
504
    limit(in_limit)
482
 
  { }
 
505
    {}
483
506
 
484
 
  ThreadContext() :
 
507
  ThreadContext()
 
508
    :
485
509
    stmt(),
486
510
    limit(0)
487
 
  { }
 
511
    {}
488
512
 
489
513
  Statement *getStmt() const
490
514
  {
531
555
              long int in_create_min_timing,
532
556
              uint64_t in_create_count,
533
557
              uint64_t in_max_rows,
534
 
              uint64_t in_min_rows) :
 
558
              uint64_t in_min_rows)
 
559
    :
535
560
    engine(in_engine),
536
561
    avg_timing(in_avg_timing),
537
562
    max_timing(in_max_timing),
547
572
    create_count(in_create_count),
548
573
    max_rows(in_max_rows),
549
574
    min_rows(in_min_rows)
550
 
  { }
 
575
    {}
551
576
 
552
 
  Conclusions() :
 
577
  Conclusions()
 
578
    :
553
579
    engine(NULL),
554
580
    avg_timing(0),
555
581
    max_timing(0),
565
591
    create_count(0),
566
592
    max_rows(0),
567
593
    min_rows(0)
568
 
  { }
 
594
    {}
569
595
 
570
596
  char *getEngine() const
571
597
  {
744
770
static Statement *post_statements= NULL;
745
771
static Statement *create_statements= NULL;
746
772
 
747
 
static std::vector <Statement *> query_statements;
 
773
static Statement **query_statements= NULL;
748
774
static unsigned int query_statements_count;
749
775
 
750
776
 
752
778
void print_conclusions(Conclusions *con);
753
779
void print_conclusions_csv(Conclusions *con);
754
780
void generate_stats(Conclusions *con, OptionString *eng, Stats *sptr);
755
 
uint32_t parse_comma(const char *string, std::vector <uint32_t> &range);
 
781
uint32_t parse_comma(const char *string, uint32_t **range);
756
782
uint32_t parse_delimiter(const char *script, Statement **stmt, char delm);
757
783
uint32_t parse_option(const char *origin, OptionString **stmt, char delm);
758
784
static int drop_schema(drizzle_con_st *con, const char *db);
762
788
static Statement *build_update_string(void);
763
789
static Statement * build_select_string(bool key);
764
790
static int generate_primary_key_list(drizzle_con_st *con, OptionString *engine_stmt);
 
791
static int drop_primary_key_list(void);
765
792
static int create_schema(drizzle_con_st *con, const char *db, Statement *stmt,
766
793
                         OptionString *engine_stmt, Stats *sptr);
767
794
static int run_scheduler(Stats *sptr, Statement **stmts, uint32_t concur,
794
821
  return s + us;
795
822
}
796
823
 
797
 
static void combine_queries(vector<string> queries)
798
 
{
799
 
  user_supplied_query.erase();
800
 
  for (vector<string>::iterator it= queries.begin();
801
 
       it != queries.end();
802
 
       ++it)
803
 
  {
804
 
    user_supplied_query.append(*it);
805
 
    user_supplied_query.append(delimiter);
806
 
  }
807
 
}
808
 
/**
809
 
 * commandline_options is the set of all options that can only be called via the command line.
810
 
 
811
 
 * client_options is the set of all options that can be defined via both command line and via
812
 
 * the configuration file client.cnf
813
 
 
814
 
 * slap_options is the set of all drizzleslap specific options which behave in a manner 
815
 
 * similar to that of client_options. It's configuration file is drizzleslap.cnf
816
 
 
817
 
 * long_options is the union of commandline_options, slap_options and client_options.
818
 
 
819
 
 * There are two configuration files per set of options, one which is defined by the user
820
 
 * which is found at either $XDG_CONFIG_HOME/drizzle or ~/.config/drizzle directory and the other which 
821
 
 * is the system configuration file which is found in the SYSCONFDIR/drizzle directory.
822
 
 
823
 
 * The system configuration file is over ridden by the user's configuration file which
824
 
 * in turn is over ridden by the command line.
825
 
 */
826
824
int main(int argc, char **argv)
827
825
{
828
 
  char *password= NULL;
829
 
  try
830
 
  {
831
 
    po::options_description commandline_options("Options used only in command line");
832
 
    commandline_options.add_options()
833
 
      ("help,?","Display this help and exit")
834
 
      ("info,i","Gives information and exit")
835
 
      ("burnin",po::value<bool>(&opt_burnin)->default_value(false)->zero_tokens(),
836
 
       "Run full test case in infinite loop")
837
 
      ("ignore-sql-errors", po::value<bool>(&opt_ignore_sql_errors)->default_value(false)->zero_tokens(),
838
 
       "Ignore SQL errors in query run")
839
 
      ("create-schema",po::value<string>(&create_schema_string)->default_value("drizzleslap"),
840
 
       "Schema to run tests in")
841
 
      ("create",po::value<string>(&create_string)->default_value(""),
842
 
       "File or string to use to create tables")
843
 
      ("detach",po::value<uint32_t>(&detach_rate)->default_value(0),
844
 
       "Detach (close and re open) connections after X number of requests")
845
 
      ("iterations,i",po::value<uint32_t>(&iterations)->default_value(1),
846
 
       "Number of times to run the tests")
847
 
      ("label",po::value<string>(&opt_label)->default_value(""),
848
 
       "Label to use for print and csv")
849
 
      ("number-blob-cols",po::value<string>(&num_blob_cols_opt)->default_value(""),
850
 
       "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. ")
851
 
      ("number-char-cols,x",po::value<string>(&num_char_cols_opt)->default_value(""),
852
 
       "Number of VARCHAR columns to create in table if specifying --auto-generate-sql.")
853
 
      ("number-int-cols,y",po::value<string>(&num_int_cols_opt)->default_value(""),
854
 
       "Number of INT columns to create in table if specifying --auto-generate-sql.")
855
 
      ("number-of-queries",
856
 
       po::value<uint64_t>(&num_of_query)->default_value(0),
857
 
       "Limit each client to this number of queries(this is not exact)") 
858
 
      ("only-print",po::value<bool>(&opt_only_print)->default_value(false)->zero_tokens(),
859
 
       "This causes drizzleslap to not connect to the database instead print out what it would have done instead")
860
 
      ("post-query", po::value<string>(&user_supplied_post_statements)->default_value(""),
861
 
       "Query to run or file containing query to execute after tests have completed.")
862
 
      ("post-system",po::value<string>(&post_system)->default_value(""),
863
 
       "system() string to execute after tests have completed")
864
 
      ("pre-query",
865
 
       po::value<string>(&user_supplied_pre_statements)->default_value(""),
866
 
       "Query to run or file containing query to execute before running tests.")
867
 
      ("pre-system",po::value<string>(&pre_system)->default_value(""),
868
 
       "system() string to execute before running tests.")
869
 
      ("query,q",po::value<vector<string> >(&user_supplied_queries)->composing()->notifier(&combine_queries),
870
 
       "Query to run or file containing query")
871
 
      ("verbose,v", po::value<string>(&opt_verbose)->default_value("v"), "Increase verbosity level by one.")
872
 
      ("version,V","Output version information and exit") 
873
 
      ;
874
 
 
875
 
    po::options_description slap_options("Options specific to drizzleslap");
876
 
    slap_options.add_options()
877
 
      ("auto-generate-sql-select-columns",
878
 
       po::value<string>(&auto_generate_selected_columns_opt)->default_value(""),
879
 
       "Provide a string to use for the select fields used in auto tests")
880
 
      ("auto-generate-sql,a",po::value<bool>(&auto_generate_sql)->default_value(false)->zero_tokens(),
881
 
       "Generate SQL where not supplied by file or command line")  
882
 
      ("auto-generate-sql-add-autoincrement",
883
 
       po::value<bool>(&auto_generate_sql_autoincrement)->default_value(false)->zero_tokens(),
884
 
       "Add an AUTO_INCREMENT column to auto-generated tables")
885
 
      ("auto-generate-sql-execute-number",
886
 
       po::value<uint64_t>(&auto_actual_queries)->default_value(0),
887
 
       "See this number and generate a set of queries to run")
888
 
      ("auto-generate-sql-guid-primary",
889
 
       po::value<bool>(&auto_generate_sql_guid_primary)->default_value(false)->zero_tokens(),
890
 
       "Add GUID based primary keys to auto-generated tables")
891
 
      ("auto-generate-sql-load-type",
892
 
       po::value<string>(&opt_auto_generate_sql_type)->default_value("mixed"),
893
 
       "Specify test load type: mixed, update, write, key or read; default is mixed")  
894
 
      ("auto-generate-sql-secondary-indexes",
895
 
       po::value<uint32_t>(&auto_generate_sql_secondary_indexes)->default_value(0),
896
 
       "Number of secondary indexes to add to auto-generated tables")
897
 
      ("auto-generated-sql-unique-query-number",
898
 
       po::value<uint64_t>(&auto_generate_sql_unique_query_number)->default_value(10),
899
 
       "Number of unique queries to generate for automatic tests")
900
 
      ("auto-generate-sql-unique-write-number",
901
 
       po::value<uint64_t>(&auto_generate_sql_unique_write_number)->default_value(10),
902
 
       "Number of unique queries to generate for auto-generate-sql-write-number")
903
 
      ("auto-generate-sql-write-number",
904
 
       po::value<uint64_t>(&auto_generate_sql_number)->default_value(100),
905
 
       "Number of row inserts to perform for each thread (default is 100).")
906
 
      ("commit",po::value<uint32_t>(&commit_rate)->default_value(0),
907
 
       "Commit records every X number of statements")
908
 
      ("concurrency,c",po::value<string>(&concurrency_str)->default_value(""),
909
 
       "Number of clients to simulate for query to run")
910
 
      ("csv",po::value<std::string>(&opt_csv_str)->default_value(""),
911
 
       "Generate CSV output to named file or to stdout if no file is name.")
912
 
      ("delayed-start",po::value<uint32_t>(&opt_delayed_start)->default_value(0),
913
 
       "Delay the startup of threads by a random number of microsends (the maximum of the delay")
914
 
      ("delimiter,F",po::value<string>(&delimiter)->default_value("\n"),
915
 
       "Delimiter to use in SQL statements supplied in file or command line")
916
 
      ("engine ,e",po::value<string>(&default_engine)->default_value(""),
917
 
       "Storage engien to use for creating the table")
918
 
      ("set-random-seed",
919
 
       po::value<uint32_t>(&opt_set_random_seed)->default_value(0), 
920
 
       "Seed for random number generator (srandom(3)) ") 
921
 
      ("silent,s",po::value<bool>(&opt_silent)->default_value(false)->zero_tokens(),
922
 
       "Run program in silent mode - no output. ") 
923
 
      ("timer-length",po::value<uint32_t>(&opt_timer_length)->default_value(0),
924
 
       "Require drizzleslap to run each specific test a certain amount of time in seconds")  
925
 
      ;
926
 
 
927
 
    po::options_description client_options("Options specific to the client");
928
 
    client_options.add_options()
929
 
      ("host,h",po::value<string>(&host)->default_value("localhost"),"Connect to the host")
930
 
      ("password,P",po::value<char *>(&password),
931
 
       "Password to use when connecting to server. If password is not given it's asked from the tty")
932
 
      ("port,p",po::value<uint32_t>(), "Port number to use for connection")
933
 
      ("protocol",po::value<string>(&opt_protocol)->default_value("mysql"),
934
 
       "The protocol of connection (mysql or drizzle).")
935
 
      ("user,u",po::value<string>(&user)->default_value(""),
936
 
       "User for login if not current user")  
937
 
      ;
938
 
 
939
 
    po::options_description long_options("Allowed Options");
940
 
    long_options.add(commandline_options).add(slap_options).add(client_options);
941
 
 
942
 
    std::string system_config_dir_slap(SYSCONFDIR); 
943
 
    system_config_dir_slap.append("/drizzle/drizzleslap.cnf");
944
 
 
945
 
    std::string system_config_dir_client(SYSCONFDIR); 
946
 
    system_config_dir_client.append("/drizzle/client.cnf");
947
 
 
948
 
    std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
949
 
 
950
 
    uint64_t temp_drizzle_port= 0;
951
 
    drizzle_con_st con;
952
 
    OptionString *eptr;
953
 
 
954
 
 
955
 
    po::variables_map vm;
956
 
    po::store(po::command_line_parser(argc, argv).options(long_options).
957
 
            extra_parser(parse_password_arg).run(), vm);
958
 
 
959
 
    std::string user_config_dir_slap(user_config_dir);
960
 
    user_config_dir_slap.append("/drizzle/drizzleslap.cnf"); 
961
 
 
962
 
    std::string user_config_dir_client(user_config_dir);
963
 
    user_config_dir_client.append("/drizzle/client.cnf");
964
 
 
965
 
    ifstream user_slap_ifs(user_config_dir_slap.c_str());
966
 
    po::store(parse_config_file(user_slap_ifs, slap_options), vm);
967
 
 
968
 
    ifstream user_client_ifs(user_config_dir_client.c_str());
969
 
    po::store(parse_config_file(user_client_ifs, client_options), vm);
970
 
 
971
 
    ifstream system_slap_ifs(system_config_dir_slap.c_str());
972
 
    store(parse_config_file(system_slap_ifs, slap_options), vm);
973
 
 
974
 
    ifstream system_client_ifs(system_config_dir_client.c_str());
975
 
    store(parse_config_file(system_client_ifs, client_options), vm);
976
 
 
977
 
    po::notify(vm);
978
 
 
979
 
    if (process_options())
980
 
      exit(1);
981
 
 
982
 
    if ( vm.count("help") || vm.count("info"))
983
 
    {
984
 
      printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname, SLAP_VERSION,
985
 
          drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
986
 
      puts("Copyright (C) 2008 Sun Microsystems");
987
 
      puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\
988
 
          \nand you are welcome to modify and redistribute it under the GPL \
989
 
          license\n");
990
 
      puts("Run a query multiple times against the server\n");
991
 
      cout << long_options << endl;
992
 
      exit(0);
993
 
    }   
994
 
 
995
 
    if (vm.count("protocol"))
996
 
    {
997
 
      std::transform(opt_protocol.begin(), opt_protocol.end(),
998
 
        opt_protocol.begin(), ::tolower);
999
 
 
1000
 
      if (not opt_protocol.compare("mysql"))
1001
 
        use_drizzle_protocol=false;
1002
 
      else if (not opt_protocol.compare("drizzle"))
1003
 
        use_drizzle_protocol=true;
1004
 
      else
1005
 
      {
1006
 
        cout << _("Error: Unknown protocol") << " '" << opt_protocol << "'" << endl;
1007
 
        exit(-1);
1008
 
      }
1009
 
    }
1010
 
    if (vm.count("port")) 
1011
 
    {
1012
 
      temp_drizzle_port= vm["port"].as<uint32_t>();
1013
 
 
1014
 
      if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
1015
 
      {
1016
 
        fprintf(stderr, _("Value supplied for port is not valid.\n"));
1017
 
        exit(1);
1018
 
      }
1019
 
      else
1020
 
      {
1021
 
        opt_drizzle_port= (uint32_t) temp_drizzle_port;
1022
 
      }
1023
 
    }
1024
 
 
1025
 
  if ( vm.count("password") )
1026
 
  {
1027
 
    if (!opt_password.empty())
1028
 
      opt_password.erase();
1029
 
    if (password == PASSWORD_SENTINEL)
1030
 
    {
1031
 
      opt_password= "";
1032
 
    }
1033
 
    else
1034
 
    {
1035
 
      opt_password= password;
1036
 
      tty_password= false;
1037
 
    }
1038
 
  }
1039
 
  else
1040
 
  {
1041
 
      tty_password= true;
1042
 
  }
1043
 
 
1044
 
 
1045
 
 
1046
 
    if ( vm.count("version") )
1047
 
    {
1048
 
      printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname, SLAP_VERSION,
1049
 
          drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
1050
 
      exit(0);
1051
 
    }
1052
 
 
1053
 
    /* Seed the random number generator if we will be using it. */
1054
 
    if (auto_generate_sql)
1055
 
    {
1056
 
      if (opt_set_random_seed == 0)
1057
 
        opt_set_random_seed= (unsigned int)time(NULL);
1058
 
      srandom(opt_set_random_seed);
1059
 
    }
1060
 
 
1061
 
    /* globals? Yes, so we only have to run strlen once */
1062
 
    delimiter_length= delimiter.length();
1063
 
 
1064
 
    slap_connect(&con, false);
1065
 
 
1066
 
    pthread_mutex_init(&counter_mutex, NULL);
1067
 
    pthread_cond_init(&count_threshhold, NULL);
1068
 
    pthread_mutex_init(&sleeper_mutex, NULL);
1069
 
    pthread_cond_init(&sleep_threshhold, NULL);
1070
 
    pthread_mutex_init(&timer_alarm_mutex, NULL);
1071
 
    pthread_cond_init(&timer_alarm_threshold, NULL);
1072
 
 
1073
 
 
1074
 
    /* Main iterations loop */
 
826
  drizzle_con_st con;
 
827
  OptionString *eptr;
 
828
  unsigned int x;
 
829
 
 
830
  internal::my_init();
 
831
 
 
832
  MY_INIT(argv[0]);
 
833
 
 
834
  internal::load_defaults("drizzle",load_default_groups,&argc,&argv);
 
835
  defaults_argv=argv;
 
836
  if (get_options(&argc,&argv))
 
837
  {
 
838
    internal::free_defaults(defaults_argv);
 
839
    internal::my_end();
 
840
    exit(1);
 
841
  }
 
842
 
 
843
  /* Seed the random number generator if we will be using it. */
 
844
  if (auto_generate_sql)
 
845
  {
 
846
    if (opt_set_random_seed == 0)
 
847
      opt_set_random_seed= (unsigned int)time(NULL);
 
848
    srandom(opt_set_random_seed);
 
849
  }
 
850
 
 
851
  /* globals? Yes, so we only have to run strlen once */
 
852
  delimiter_length= strlen(delimiter);
 
853
 
 
854
  if (argc > 2)
 
855
  {
 
856
    fprintf(stderr,"%s: Too many arguments\n",internal::my_progname);
 
857
    internal::free_defaults(defaults_argv);
 
858
    internal::my_end();
 
859
    exit(1);
 
860
  }
 
861
 
 
862
  slap_connect(&con, false);
 
863
 
 
864
  pthread_mutex_init(&counter_mutex, NULL);
 
865
  pthread_cond_init(&count_threshhold, NULL);
 
866
  pthread_mutex_init(&sleeper_mutex, NULL);
 
867
  pthread_cond_init(&sleep_threshhold, NULL);
 
868
  pthread_mutex_init(&timer_alarm_mutex, NULL);
 
869
  pthread_cond_init(&timer_alarm_threshold, NULL);
 
870
 
 
871
 
 
872
  /* Main iterations loop */
1075
873
burnin:
1076
 
    eptr= engine_options;
1077
 
    do
1078
 
    {
1079
 
      /* For the final stage we run whatever queries we were asked to run */
1080
 
      uint32_t *current;
1081
 
 
1082
 
      if (verbose >= 2)
1083
 
        printf("Starting Concurrency Test\n");
1084
 
 
1085
 
      if (concurrency.size())
1086
 
      {
1087
 
        for (current= &concurrency[0]; current && *current; current++)
1088
 
          concurrency_loop(&con, *current, eptr);
1089
 
      }
1090
 
      else
1091
 
      {
1092
 
        uint32_t infinite= 1;
1093
 
        do {
1094
 
          concurrency_loop(&con, infinite, eptr);
1095
 
        }
1096
 
        while (infinite++);
1097
 
      }
1098
 
 
1099
 
      if (!opt_preserve)
1100
 
        drop_schema(&con, create_schema_string.c_str());
1101
 
 
1102
 
    } while (eptr ? (eptr= eptr->getNext()) : 0);
1103
 
 
1104
 
    if (opt_burnin)
1105
 
      goto burnin;
1106
 
 
1107
 
    pthread_mutex_destroy(&counter_mutex);
1108
 
    pthread_cond_destroy(&count_threshhold);
1109
 
    pthread_mutex_destroy(&sleeper_mutex);
1110
 
    pthread_cond_destroy(&sleep_threshhold);
1111
 
    pthread_mutex_destroy(&timer_alarm_mutex);
1112
 
    pthread_cond_destroy(&timer_alarm_threshold);
1113
 
 
1114
 
    slap_close(&con);
1115
 
 
1116
 
    /* now free all the strings we created */
1117
 
    if (!opt_password.empty())
1118
 
      opt_password.erase();
1119
 
 
1120
 
    concurrency.clear();
1121
 
 
1122
 
    statement_cleanup(create_statements);
1123
 
    for (uint32_t x= 0; x < query_statements_count; x++)
1124
 
      statement_cleanup(query_statements[x]);
1125
 
    query_statements.clear();
1126
 
    statement_cleanup(pre_statements);
1127
 
    statement_cleanup(post_statements);
1128
 
    option_cleanup(engine_options);
1129
 
    option_cleanup(query_options);
 
874
  eptr= engine_options;
 
875
  do
 
876
  {
 
877
    /* For the final stage we run whatever queries we were asked to run */
 
878
    uint32_t *current;
 
879
 
 
880
    if (verbose >= 2)
 
881
      printf("Starting Concurrency Test\n");
 
882
 
 
883
    if (*concurrency)
 
884
    {
 
885
      for (current= concurrency; current && *current; current++)
 
886
        concurrency_loop(&con, *current, eptr);
 
887
    }
 
888
    else
 
889
    {
 
890
      uint32_t infinite= 1;
 
891
      do {
 
892
        concurrency_loop(&con, infinite, eptr);
 
893
      }
 
894
      while (infinite++);
 
895
    }
 
896
 
 
897
    if (!opt_preserve)
 
898
      drop_schema(&con, create_schema_string);
 
899
 
 
900
  } while (eptr ? (eptr= eptr->getNext()) : 0);
 
901
 
 
902
  if (opt_burnin)
 
903
    goto burnin;
 
904
 
 
905
  pthread_mutex_destroy(&counter_mutex);
 
906
  pthread_cond_destroy(&count_threshhold);
 
907
  pthread_mutex_destroy(&sleeper_mutex);
 
908
  pthread_cond_destroy(&sleep_threshhold);
 
909
  pthread_mutex_destroy(&timer_alarm_mutex);
 
910
  pthread_cond_destroy(&timer_alarm_threshold);
 
911
 
 
912
  slap_close(&con);
 
913
 
 
914
  /* now free all the strings we created */
 
915
  if (opt_password)
 
916
    free(opt_password);
 
917
 
 
918
  free(concurrency);
 
919
 
 
920
  statement_cleanup(create_statements);
 
921
  for (x= 0; x < query_statements_count; x++)
 
922
    statement_cleanup(query_statements[x]);
 
923
  free(query_statements);
 
924
  statement_cleanup(pre_statements);
 
925
  statement_cleanup(post_statements);
 
926
  option_cleanup(engine_options);
 
927
  option_cleanup(query_options);
1130
928
 
1131
929
#ifdef HAVE_SMEM
1132
 
    if (shared_memory_base_name)
1133
 
      free(shared_memory_base_name);
 
930
  if (shared_memory_base_name)
 
931
    free(shared_memory_base_name);
1134
932
#endif
1135
 
 
1136
 
  }
1137
 
 
1138
 
  catch(std::exception &err)
1139
 
  {
1140
 
    cerr<<"Error:"<<err.what()<<endl;
1141
 
  }
1142
 
 
1143
 
  if (csv_file != fileno(stdout))
1144
 
    close(csv_file);
 
933
  internal::free_defaults(defaults_argv);
 
934
  internal::my_end();
1145
935
 
1146
936
  return 0;
1147
937
}
1148
938
 
1149
939
void concurrency_loop(drizzle_con_st *con, uint32_t current, OptionString *eptr)
1150
940
{
 
941
  unsigned int x;
1151
942
  Stats *head_sptr;
1152
943
  Stats *sptr;
1153
944
  Conclusions conclusion;
1154
945
  uint64_t client_limit;
1155
946
 
1156
 
  head_sptr= new Stats[iterations];
 
947
  head_sptr= (Stats *)malloc(sizeof(Stats) * iterations);
1157
948
  if (head_sptr == NULL)
1158
949
  {
1159
950
    fprintf(stderr,"Error allocating memory in concurrency_loop\n");
1160
951
    exit(1);
1161
952
  }
 
953
  memset(head_sptr, 0, sizeof(Stats) * iterations);
 
954
 
 
955
  memset(&conclusion, 0, sizeof(Conclusions));
1162
956
 
1163
957
  if (auto_actual_queries)
1164
958
    client_limit= auto_actual_queries;
1167
961
  else
1168
962
    client_limit= actual_queries;
1169
963
 
1170
 
  uint32_t x;
1171
964
  for (x= 0, sptr= head_sptr; x < iterations; x++, sptr++)
1172
965
  {
1173
966
    /*
1176
969
      data in the table.
1177
970
    */
1178
971
    if (opt_preserve == false)
1179
 
      drop_schema(con, create_schema_string.c_str());
 
972
      drop_schema(con, create_schema_string);
1180
973
 
1181
974
    /* First we create */
1182
975
    if (create_statements)
1183
 
      create_schema(con, create_schema_string.c_str(), create_statements, eptr, sptr);
 
976
      create_schema(con, create_schema_string, create_statements, eptr, sptr);
1184
977
 
1185
978
    /*
1186
979
      If we generated GUID we need to build a list of them from creation that
1194
987
    if (commit_rate)
1195
988
      run_query(con, NULL, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
1196
989
 
1197
 
    if (!pre_system.empty())
 
990
    if (pre_system)
1198
991
    {
1199
 
      int ret= system(pre_system.c_str());
 
992
      int ret= system(pre_system);
1200
993
      assert(ret != -1);
1201
994
    }
1202
995
       
1208
1001
    if (pre_statements)
1209
1002
      run_statements(con, pre_statements);
1210
1003
 
1211
 
    run_scheduler(sptr, &query_statements[0], current, client_limit);
 
1004
    run_scheduler(sptr, query_statements, current, client_limit);
1212
1005
 
1213
1006
    if (post_statements)
1214
1007
      run_statements(con, post_statements);
1215
1008
 
1216
 
    if (!post_system.empty())
 
1009
    if (post_system)
1217
1010
    {
1218
 
      int ret=  system(post_system.c_str());
 
1011
      int ret=  system(post_system);
1219
1012
      assert(ret !=-1);
1220
1013
    }
1221
1014
 
1222
1015
    /* We are finished with this run */
1223
1016
    if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
1224
 
      primary_keys.clear();
 
1017
      drop_primary_key_list();
1225
1018
  }
1226
1019
 
1227
1020
  if (verbose >= 2)
1231
1024
 
1232
1025
  if (!opt_silent)
1233
1026
    print_conclusions(&conclusion);
1234
 
  if (!opt_csv_str.empty())
 
1027
  if (opt_csv_str)
1235
1028
    print_conclusions_csv(&conclusion);
1236
1029
 
1237
 
  delete [] head_sptr;
 
1030
  free(head_sptr);
 
1031
 
 
1032
}
 
1033
 
 
1034
 
 
1035
static struct option my_long_options[] =
 
1036
{
 
1037
  {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
 
1038
   0, 0, 0, 0, 0, 0},
 
1039
  {"auto-generate-sql-select-columns", OPT_SLAP_AUTO_GENERATE_SELECT_COLUMNS,
 
1040
   "Provide a string to use for the select fields used in auto tests.",
 
1041
   (char**) &auto_generate_selected_columns_opt,
 
1042
   (char**) &auto_generate_selected_columns_opt,
 
1043
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1044
  {"auto-generate-sql", 'a',
 
1045
   "Generate SQL where not supplied by file or command line.",
 
1046
   (char**) &auto_generate_sql, (char**) &auto_generate_sql,
 
1047
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1048
  {"auto-generate-sql-add-autoincrement", OPT_SLAP_AUTO_GENERATE_ADD_AUTO,
 
1049
   "Add an AUTO_INCREMENT column to auto-generated tables.",
 
1050
   (char**) &auto_generate_sql_autoincrement,
 
1051
   (char**) &auto_generate_sql_autoincrement,
 
1052
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1053
  {"auto-generate-sql-execute-number", OPT_SLAP_AUTO_GENERATE_EXECUTE_QUERIES,
 
1054
   "Set this number to generate a set number of queries to run.",
 
1055
   (char**) &auto_actual_queries, (char**) &auto_actual_queries,
 
1056
   0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1057
  {"auto-generate-sql-guid-primary", OPT_SLAP_AUTO_GENERATE_GUID_PRIMARY,
 
1058
   "Add GUID based primary keys to auto-generated tables.",
 
1059
   (char**) &auto_generate_sql_guid_primary,
 
1060
   (char**) &auto_generate_sql_guid_primary,
 
1061
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1062
  {"auto-generate-sql-load-type", OPT_SLAP_AUTO_GENERATE_SQL_LOAD_TYPE,
 
1063
   "Specify test load type: mixed, update, write, key, or read; default is mixed.",
 
1064
   (char**) &opt_auto_generate_sql_type, (char**) &opt_auto_generate_sql_type,
 
1065
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1066
  {"auto-generate-sql-secondary-indexes",
 
1067
   OPT_SLAP_AUTO_GENERATE_SECONDARY_INDEXES,
 
1068
   "Number of secondary indexes to add to auto-generated tables.",
 
1069
   (char**) &auto_generate_sql_secondary_indexes,
 
1070
   (char**) &auto_generate_sql_secondary_indexes, 0,
 
1071
   GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1072
  {"auto-generate-sql-unique-query-number",
 
1073
   OPT_SLAP_AUTO_GENERATE_UNIQUE_QUERY_NUM,
 
1074
   "Number of unique queries to generate for automatic tests.",
 
1075
   (char**) &auto_generate_sql_unique_query_number,
 
1076
   (char**) &auto_generate_sql_unique_query_number,
 
1077
   0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
 
1078
  {"auto-generate-sql-unique-write-number",
 
1079
   OPT_SLAP_AUTO_GENERATE_UNIQUE_WRITE_NUM,
 
1080
   "Number of unique queries to generate for auto-generate-sql-write-number.",
 
1081
   (char**) &auto_generate_sql_unique_write_number,
 
1082
   (char**) &auto_generate_sql_unique_write_number,
 
1083
   0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
 
1084
  {"auto-generate-sql-write-number", OPT_SLAP_AUTO_GENERATE_WRITE_NUM,
 
1085
   "Number of row inserts to perform for each thread (default is 100).",
 
1086
   (char**) &auto_generate_sql_number, (char**) &auto_generate_sql_number,
 
1087
   0, GET_ULL, REQUIRED_ARG, 100, 0, 0, 0, 0, 0},
 
1088
  {"burnin", OPT_SLAP_BURNIN, "Run full test case in infinite loop.",
 
1089
   (char**) &opt_burnin, (char**) &opt_burnin, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
1090
   0, 0, 0},
 
1091
  {"ignore-sql-errors", OPT_SLAP_IGNORE_SQL_ERRORS,
 
1092
   "Ignore SQL erros in query run.",
 
1093
   (char**) &opt_ignore_sql_errors,
 
1094
   (char**) &opt_ignore_sql_errors,
 
1095
   0, GET_BOOL, NO_ARG, 0, 0, 0,
 
1096
   0, 0, 0},
 
1097
  {"commit", OPT_SLAP_COMMIT, "Commit records every X number of statements.",
 
1098
   (char**) &commit_rate, (char**) &commit_rate, 0, GET_UINT, REQUIRED_ARG,
 
1099
   0, 0, 0, 0, 0, 0},
 
1100
  {"concurrency", 'c', "Number of clients to simulate for query to run.",
 
1101
   (char**) &concurrency_str, (char**) &concurrency_str, 0, GET_STR,
 
1102
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1103
  {"create", OPT_SLAP_CREATE_STRING, "File or string to use create tables.",
 
1104
   (char**) &create_string, (char**) &create_string, 0, GET_STR, REQUIRED_ARG,
 
1105
   0, 0, 0, 0, 0, 0},
 
1106
  {"create-schema", OPT_CREATE_SLAP_SCHEMA, "Schema to run tests in.",
 
1107
   (char**) &create_schema_string, (char**) &create_schema_string, 0, GET_STR,
 
1108
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1109
  {"csv", OPT_SLAP_CSV,
 
1110
   "Generate CSV output to named file or to stdout if no file is named.",
 
1111
   (char**) &opt_csv_str, (char**) &opt_csv_str, 0, GET_STR,
 
1112
   OPT_ARG, 0, 0, 0, 0, 0, 0},
 
1113
  {"delayed-start", OPT_SLAP_DELAYED_START,
 
1114
   "Delay the startup of threads by a random number of microsends (the maximum of the delay)",
 
1115
   (char**) &opt_delayed_start, (char**) &opt_delayed_start, 0, GET_UINT,
 
1116
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1117
  {"delimiter", 'F',
 
1118
   "Delimiter to use in SQL statements supplied in file or command line.",
 
1119
   (char**) &delimiter, (char**) &delimiter, 0, GET_STR, REQUIRED_ARG,
 
1120
   0, 0, 0, 0, 0, 0},
 
1121
  {"detach", OPT_SLAP_DETACH,
 
1122
   "Detach (close and reopen) connections after X number of requests.",
 
1123
   (char**) &detach_rate, (char**) &detach_rate, 0, GET_UINT, REQUIRED_ARG,
 
1124
   0, 0, 0, 0, 0, 0},
 
1125
  {"engine", 'e', "Storage engine to use for creating the table.",
 
1126
   (char**) &default_engine, (char**) &default_engine, 0,
 
1127
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1128
  {"host", 'h', "Connect to host.", (char**) &host, (char**) &host, 0, GET_STR,
 
1129
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1130
  {"iterations", 'i', "Number of times to run the tests.", (char**) &iterations,
 
1131
   (char**) &iterations, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0},
 
1132
  {"label", OPT_SLAP_LABEL, "Label to use for print and csv output.",
 
1133
   (char**) &opt_label, (char**) &opt_label, 0,
 
1134
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1135
  {"mysql", 'm', N_("Use MySQL Protocol."),
 
1136
   (char**) &opt_mysql, (char**) &opt_mysql, 0, GET_BOOL, NO_ARG, 1, 0, 0,
 
1137
   0, 0, 0},
 
1138
  {"number-blob-cols", OPT_SLAP_BLOB_COL,
 
1139
   "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. ",
 
1140
   (char**) &num_blob_cols_opt, (char**) &num_blob_cols_opt, 0, GET_STR, REQUIRED_ARG,
 
1141
   0, 0, 0, 0, 0, 0},
 
1142
  {"number-char-cols", 'x',
 
1143
   "Number of VARCHAR columns to create in table if specifying --auto-generate-sql.",
 
1144
   (char**) &num_char_cols_opt, (char**) &num_char_cols_opt, 0, GET_STR, REQUIRED_ARG,
 
1145
   0, 0, 0, 0, 0, 0},
 
1146
  {"number-int-cols", 'y',
 
1147
   "Number of INT columns to create in table if specifying --auto-generate-sql.",
 
1148
   (char**) &num_int_cols_opt, (char**) &num_int_cols_opt, 0, GET_STR, REQUIRED_ARG,
 
1149
   0, 0, 0, 0, 0, 0},
 
1150
  {"number-of-queries", OPT_DRIZZLE_NUMBER_OF_QUERY,
 
1151
   "Limit each client to this number of queries (this is not exact).",
 
1152
   (char**) &num_of_query, (char**) &num_of_query, 0,
 
1153
   GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1154
  {"only-print", OPT_DRIZZLE_ONLY_PRINT,
 
1155
   "This causes drizzleslap to not connect to the databases, but instead print "
 
1156
   "out what it would have done instead.",
 
1157
   (char**) &opt_only_print, (char**) &opt_only_print, 0, GET_BOOL,  NO_ARG,
 
1158
   0, 0, 0, 0, 0, 0},
 
1159
  {"password", 'P',
 
1160
   "Password to use when connecting to server. If password is not given it's "
 
1161
   "asked from the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
1162
  {"port", 'p', "Port number to use for connection.",
 
1163
   0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1164
  {"post-query", OPT_SLAP_POST_QUERY,
 
1165
   "Query to run or file containing query to execute after tests have completed.",
 
1166
   (char**) &user_supplied_post_statements,
 
1167
   (char**) &user_supplied_post_statements,
 
1168
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1169
  {"post-system", OPT_SLAP_POST_SYSTEM,
 
1170
   "system() string to execute after tests have completed.",
 
1171
   (char**) &post_system,
 
1172
   (char**) &post_system,
 
1173
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1174
  {"pre-query", OPT_SLAP_PRE_QUERY,
 
1175
   "Query to run or file containing query to execute before running tests.",
 
1176
   (char**) &user_supplied_pre_statements,
 
1177
   (char**) &user_supplied_pre_statements,
 
1178
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1179
  {"pre-system", OPT_SLAP_PRE_SYSTEM,
 
1180
   "system() string to execute before running tests.",
 
1181
   (char**) &pre_system,
 
1182
   (char**) &pre_system,
 
1183
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1184
  {"protocol", OPT_DRIZZLE_PROTOCOL,
 
1185
   "The protocol of connection (tcp,socket,pipe,memory).",
 
1186
   0, 0, 0, GET_STR,  REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1187
  {"query", 'q', "Query to run or file containing query to run.",
 
1188
   (char**) &user_supplied_query, (char**) &user_supplied_query,
 
1189
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1190
  {"set-random-seed", OPT_SLAP_SET_RANDOM_SEED,
 
1191
   "Seed for random number generator (srandom(3))",
 
1192
   (char**)&opt_set_random_seed,
 
1193
   (char**)&opt_set_random_seed,0,
 
1194
   GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1195
  {"silent", 's', "Run program in silent mode - no output.",
 
1196
   (char**) &opt_silent, (char**) &opt_silent, 0, GET_BOOL,  NO_ARG,
 
1197
   0, 0, 0, 0, 0, 0},
 
1198
  {"timer-length", OPT_SLAP_TIMER_LENGTH,
 
1199
   "Require drizzleslap to run each specific test a certain amount of time in seconds.",
 
1200
   (char**) &opt_timer_length, (char**) &opt_timer_length, 0, GET_UINT,
 
1201
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1202
  {"user", 'u', "User for login if not current user.", (char**) &user,
 
1203
   (char**) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1204
  {"verbose", 'v',
 
1205
   "More verbose output; you can use this multiple times to get even more "
 
1206
   "verbose output.", (char**) &verbose, (char**) &verbose, 0,
 
1207
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1208
  {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
 
1209
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
1210
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 
1211
};
 
1212
 
 
1213
 
 
1214
static void print_version(void)
 
1215
{
 
1216
  printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname, SLAP_VERSION,
 
1217
         drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
 
1218
}
 
1219
 
 
1220
 
 
1221
static void usage(void)
 
1222
{
 
1223
  print_version();
 
1224
  puts("Copyright (C) 2008 Sun Microsystems");
 
1225
  puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\
 
1226
       \nand you are welcome to modify and redistribute it under the GPL \
 
1227
       license\n");
 
1228
  puts("Run a query multiple times against the server\n");
 
1229
  printf("Usage: %s [OPTIONS]\n",internal::my_progname);
 
1230
  internal::print_defaults("drizzle",load_default_groups);
 
1231
  my_print_help(my_long_options);
 
1232
}
 
1233
 
 
1234
static int get_one_option(int optid, const struct option *, char *argument)
 
1235
{
 
1236
  char *endchar= NULL;
 
1237
  uint64_t temp_drizzle_port= 0;
 
1238
 
 
1239
  switch(optid) {
 
1240
  case 'v':
 
1241
    verbose++;
 
1242
    break;
 
1243
  case 'p':
 
1244
    temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
 
1245
    /* if there is an alpha character this is not a valid port */
 
1246
    if (strlen(endchar) != 0)
 
1247
    {
 
1248
      fprintf(stderr, _("Non-integer value supplied for port.  If you are trying to enter a password please use --password instead.\n"));
 
1249
      exit(1);
 
1250
    }
 
1251
    /* If the port number is > 65535 it is not a valid port
 
1252
       This also helps with potential data loss casting unsigned long to a
 
1253
       uint32_t. */
 
1254
    if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
 
1255
    {
 
1256
      fprintf(stderr, _("Value supplied for port is not valid.\n"));
 
1257
      exit(1);
 
1258
    }
 
1259
    else
 
1260
    {
 
1261
      opt_drizzle_port= (uint32_t) temp_drizzle_port;
 
1262
    }
 
1263
    break;
 
1264
  case 'P':
 
1265
    if (argument)
 
1266
    {
 
1267
      char *start= argument;
 
1268
      if (opt_password)
 
1269
        free(opt_password);
 
1270
      opt_password = strdup(argument);
 
1271
      if (opt_password == NULL)
 
1272
      {
 
1273
        fprintf(stderr, "Memory allocation error while copying password. "
 
1274
                        "Aborting.\n");
 
1275
        exit(ENOMEM);
 
1276
      }
 
1277
      while (*argument)
 
1278
      {
 
1279
        /* Overwriting password with 'x' */
 
1280
        *argument++= 'x';
 
1281
      }
 
1282
      if (*start)
 
1283
      {
 
1284
        /* Cut length of argument */
 
1285
        start[1]= 0;
 
1286
      }
 
1287
      tty_password= 0;
 
1288
    }
 
1289
    else
 
1290
      tty_password= 1;
 
1291
    break;
 
1292
  case 'V':
 
1293
    print_version();
 
1294
    exit(0);
 
1295
  case '?':
 
1296
  case 'I':          /* Info */
 
1297
    usage();
 
1298
    exit(0);
 
1299
  }
 
1300
  return(0);
1238
1301
}
1239
1302
 
1240
1303
 
1242
1305
get_random_string(char *buf, size_t size)
1243
1306
{
1244
1307
  char *buf_ptr= buf;
 
1308
  size_t x;
1245
1309
 
1246
 
  for (size_t x= size; x > 0; x--)
 
1310
  for (x= size; x > 0; x--)
1247
1311
    *buf_ptr++= ALPHANUMERICS[random() % ALPHANUMERICS_SIZE];
1248
1312
  return(buf_ptr - buf);
1249
1313
}
1376
1440
    }
1377
1441
 
1378
1442
  table_string.append(")");
1379
 
  ptr= new Statement;
1380
 
  ptr->setString(table_string.length());
 
1443
  ptr= (Statement *)malloc(sizeof(Statement));
 
1444
  if (ptr == NULL)
 
1445
  {
 
1446
    fprintf(stderr, "Memory Allocation error in creating table\n");
 
1447
    exit(1);
 
1448
  }
 
1449
  memset(ptr, 0, sizeof(Statement));
 
1450
  ptr->setString((char *)malloc(table_string.length()+1));
1381
1451
  if (ptr->getString()==NULL)
1382
1452
  {
1383
1453
    fprintf(stderr, "Memory Allocation error in creating table\n");
1384
1454
    exit(1);
1385
1455
  }
 
1456
  memset(ptr->getString(), 0, table_string.length()+1);
 
1457
  ptr->setLength(table_string.length()+1);
1386
1458
  ptr->setType(CREATE_TABLE_TYPE);
1387
1459
  strcpy(ptr->getString(), table_string.c_str());
1388
1460
  return(ptr);
1444
1516
    update_string.append(" WHERE id = ");
1445
1517
 
1446
1518
 
1447
 
  ptr= new Statement;
 
1519
  ptr= (Statement *)malloc(sizeof(Statement));
 
1520
  if (ptr == NULL)
 
1521
  {
 
1522
    fprintf(stderr, "Memory Allocation error in creating update\n");
 
1523
    exit(1);
 
1524
  }
 
1525
  memset(ptr, 0, sizeof(Statement));
1448
1526
 
1449
 
  ptr->setString(update_string.length());
 
1527
  ptr->setLength(update_string.length()+1);
 
1528
  ptr->setString((char *)malloc(ptr->getLength()));
1450
1529
  if (ptr->getString() == NULL)
1451
1530
  {
1452
1531
    fprintf(stderr, "Memory Allocation error in creating update\n");
1453
1532
    exit(1);
1454
1533
  }
 
1534
  memset(ptr->getString(), 0, ptr->getLength());
1455
1535
  if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
1456
1536
    ptr->setType(UPDATE_TYPE_REQUIRES_PREFIX);
1457
1537
  else
1539
1619
 
1540
1620
  if (num_blob_cols)
1541
1621
  {
1542
 
    vector <char> blob_ptr;
 
1622
    char *blob_ptr;
1543
1623
 
1544
 
    blob_ptr.resize(num_blob_cols_size);
 
1624
    if (num_blob_cols_size > HUGE_STRING_LENGTH)
 
1625
    {
 
1626
      blob_ptr= (char *)malloc(sizeof(char)*num_blob_cols_size);
 
1627
      if (!blob_ptr)
 
1628
      {
 
1629
        fprintf(stderr, "Memory Allocation error in creating select\n");
 
1630
        exit(1);
 
1631
      }
 
1632
      memset(blob_ptr, 0, sizeof(char)*num_blob_cols_size);
 
1633
    }
 
1634
    else
 
1635
    {
 
1636
      blob_ptr= buf;
 
1637
    }
1545
1638
 
1546
1639
    for (col_count= 1; col_count <= num_blob_cols; col_count++)
1547
1640
    {
1552
1645
      size= difference ? (num_blob_cols_size_min + (random() % difference)) :
1553
1646
        num_blob_cols_size;
1554
1647
 
1555
 
      buf_len= get_random_string(&blob_ptr[0], size);
 
1648
      buf_len= get_random_string(blob_ptr, size);
1556
1649
 
1557
1650
      insert_string.append("'", 1);
1558
 
      insert_string.append(&blob_ptr[0], buf_len);
 
1651
      insert_string.append(blob_ptr, buf_len);
1559
1652
      insert_string.append("'", 1);
1560
1653
 
1561
1654
      if (col_count < num_blob_cols)
1562
1655
        insert_string.append(",", 1);
1563
1656
    }
 
1657
 
 
1658
    if (num_blob_cols_size > HUGE_STRING_LENGTH)
 
1659
      free(blob_ptr);
1564
1660
  }
1565
1661
 
1566
1662
  insert_string.append(")", 1);
1567
1663
 
1568
 
  ptr= new Statement;
1569
 
  ptr->setString(insert_string.length());
 
1664
  if (!(ptr= (Statement *)malloc(sizeof(Statement))))
 
1665
  {
 
1666
    fprintf(stderr, "Memory Allocation error in creating select\n");
 
1667
    exit(1);
 
1668
  }
 
1669
  memset(ptr, 0, sizeof(Statement));
 
1670
  ptr->setLength(insert_string.length()+1);
 
1671
  ptr->setString((char *)malloc(ptr->getLength()));
1570
1672
  if (ptr->getString()==NULL)
1571
1673
  {
1572
1674
    fprintf(stderr, "Memory Allocation error in creating select\n");
1573
1675
    exit(1);
1574
1676
  }
 
1677
  memset(ptr->getString(), 0, ptr->getLength());
1575
1678
  ptr->setType(INSERT_TYPE);
1576
1679
  strcpy(ptr->getString(), insert_string.c_str());
1577
1680
  return(ptr);
1595
1698
  query_string.reserve(HUGE_STRING_LENGTH);
1596
1699
 
1597
1700
  query_string.append("SELECT ", 7);
1598
 
  if (!auto_generate_selected_columns_opt.empty())
 
1701
  if (auto_generate_selected_columns_opt)
1599
1702
  {
1600
 
    query_string.append(auto_generate_selected_columns_opt.c_str());
 
1703
    query_string.append(auto_generate_selected_columns_opt);
1601
1704
  }
1602
1705
  else
1603
1706
  {
1649
1752
      (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary))
1650
1753
    query_string.append(" WHERE id = ");
1651
1754
 
1652
 
  ptr= new Statement;
1653
 
  ptr->setString(query_string.length());
 
1755
  ptr= (Statement *)malloc(sizeof(Statement));
 
1756
  if (ptr == NULL)
 
1757
  {
 
1758
    fprintf(stderr, "Memory Allocation error in creating select\n");
 
1759
    exit(1);
 
1760
  }
 
1761
  memset(ptr, 0, sizeof(Statement));
 
1762
  ptr->setLength(query_string.length()+1);
 
1763
  ptr->setString((char *)malloc(ptr->getLength()));
1654
1764
  if (ptr->getString() == NULL)
1655
1765
  {
1656
1766
    fprintf(stderr, "Memory Allocation error in creating select\n");
1657
1767
    exit(1);
1658
1768
  }
 
1769
  memset(ptr->getString(), 0, ptr->getLength());
1659
1770
  if ((key) &&
1660
1771
      (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary))
1661
1772
    ptr->setType(SELECT_TYPE_REQUIRES_PREFIX);
1666
1777
}
1667
1778
 
1668
1779
static int
1669
 
process_options(void)
 
1780
get_options(int *argc,char ***argv)
1670
1781
{
 
1782
  int ho_error;
 
1783
  char *tmp_string;
1671
1784
  struct stat sbuf;
1672
1785
  OptionString *sql_type;
1673
1786
  unsigned int sql_type_count= 0;
1674
1787
  ssize_t bytes_read= 0;
1675
 
  
1676
 
  if (user.empty())
1677
 
    user= "root";
1678
 
 
1679
 
  verbose= opt_verbose.length();
 
1788
 
 
1789
 
 
1790
  if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option)))
 
1791
    exit(ho_error);
 
1792
 
 
1793
  if (!user)
 
1794
    user= (char *)"root";
1680
1795
 
1681
1796
  /* If something is created we clean it up, otherwise we leave schemas alone */
1682
 
  if ( (!create_string.empty()) || auto_generate_sql)
 
1797
  if (create_string || auto_generate_sql)
1683
1798
    opt_preserve= false;
1684
1799
 
1685
 
  if (auto_generate_sql && (!create_string.empty() || !user_supplied_query.empty()))
 
1800
  if (auto_generate_sql && (create_string || user_supplied_query))
1686
1801
  {
1687
1802
    fprintf(stderr,
1688
1803
            "%s: Can't use --auto-generate-sql when create and query strings are specified!\n",
1707
1822
    exit(1);
1708
1823
  }
1709
1824
 
1710
 
  parse_comma(!concurrency_str.empty() ? concurrency_str.c_str() : "1", concurrency);
 
1825
  parse_comma(concurrency_str ? concurrency_str : "1", &concurrency);
1711
1826
 
1712
 
  if (!opt_csv_str.empty())
 
1827
  if (opt_csv_str)
1713
1828
  {
1714
1829
    opt_silent= true;
1715
1830
 
1719
1834
    }
1720
1835
    else
1721
1836
    {
1722
 
      if ((csv_file= open(opt_csv_str.c_str(), O_CREAT|O_WRONLY|O_APPEND, 
 
1837
      if ((csv_file= open(opt_csv_str, O_CREAT|O_WRONLY|O_APPEND, 
1723
1838
                          S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1)
1724
1839
      {
1725
1840
        fprintf(stderr,"%s: Could not open csv file: %sn\n",
1726
 
                internal::my_progname, opt_csv_str.c_str());
 
1841
                internal::my_progname, opt_csv_str);
1727
1842
        exit(1);
1728
1843
      }
1729
1844
    }
1732
1847
  if (opt_only_print)
1733
1848
    opt_silent= true;
1734
1849
 
1735
 
  if (!num_int_cols_opt.empty())
 
1850
  if (num_int_cols_opt)
1736
1851
  {
1737
1852
    OptionString *str;
1738
 
    parse_option(num_int_cols_opt.c_str(), &str, ',');
 
1853
    parse_option(num_int_cols_opt, &str, ',');
1739
1854
    num_int_cols= atoi(str->getString());
1740
1855
    if (str->getOption())
1741
1856
      num_int_cols_index= atoi(str->getOption());
1742
1857
    option_cleanup(str);
1743
1858
  }
1744
1859
 
1745
 
  if (!num_char_cols_opt.empty())
 
1860
  if (num_char_cols_opt)
1746
1861
  {
1747
1862
    OptionString *str;
1748
 
    parse_option(num_char_cols_opt.c_str(), &str, ',');
 
1863
    parse_option(num_char_cols_opt, &str, ',');
1749
1864
    num_char_cols= atoi(str->getString());
1750
1865
    if (str->getOption())
1751
1866
      num_char_cols_index= atoi(str->getOption());
1754
1869
    option_cleanup(str);
1755
1870
  }
1756
1871
 
1757
 
  if (!num_blob_cols_opt.empty())
 
1872
  if (num_blob_cols_opt)
1758
1873
  {
1759
1874
    OptionString *str;
1760
 
    parse_option(num_blob_cols_opt.c_str(), &str, ',');
 
1875
    parse_option(num_blob_cols_opt, &str, ',');
1761
1876
    num_blob_cols= atoi(str->getString());
1762
1877
    if (str->getOption())
1763
1878
    {
1804
1919
    if (verbose >= 2)
1805
1920
      printf("Building Query Statements for Auto\n");
1806
1921
 
1807
 
    if (opt_auto_generate_sql_type.empty())
 
1922
    if (!opt_auto_generate_sql_type)
1808
1923
      opt_auto_generate_sql_type= "mixed";
1809
1924
 
1810
1925
    query_statements_count=
1811
 
      parse_option(opt_auto_generate_sql_type.c_str(), &query_options, ',');
 
1926
      parse_option(opt_auto_generate_sql_type, &query_options, ',');
1812
1927
 
1813
 
    query_statements.resize(query_statements_count);
 
1928
    query_statements= (Statement **)malloc(sizeof(Statement *) * query_statements_count);
 
1929
    if (query_statements == NULL)
 
1930
    {
 
1931
      fprintf(stderr, "Memory Allocation error in Building Query Statements\n");
 
1932
      exit(1);
 
1933
    }
 
1934
    memset(query_statements, 0, sizeof(Statement *) * query_statements_count);
1814
1935
 
1815
1936
    sql_type= query_options;
1816
1937
    do
1916
2037
  }
1917
2038
  else
1918
2039
  {
1919
 
    if (!create_string.empty() && !stat(create_string.c_str(), &sbuf))
 
2040
    if (create_string && !stat(create_string, &sbuf))
1920
2041
    {
1921
2042
      int data_file;
1922
 
      std::vector<char> tmp_string;
1923
2043
      if (!S_ISREG(sbuf.st_mode))
1924
2044
      {
1925
2045
        fprintf(stderr,"%s: Create file was not a regular file\n",
1926
2046
                internal::my_progname);
1927
2047
        exit(1);
1928
2048
      }
1929
 
      if ((data_file= open(create_string.c_str(), O_RDWR)) == -1)
 
2049
      if ((data_file= open(create_string, O_RDWR)) == -1)
1930
2050
      {
1931
2051
        fprintf(stderr,"%s: Could not open create file\n", internal::my_progname);
1932
2052
        exit(1);
1936
2056
        fprintf(stderr, "Request for more memory than architecture supports\n");
1937
2057
        exit(1);
1938
2058
      }
1939
 
      tmp_string.resize(sbuf.st_size + 1);
1940
 
      bytes_read= read(data_file, (unsigned char*) &tmp_string[0],
 
2059
      tmp_string= (char *)malloc((size_t)(sbuf.st_size + 1));
 
2060
      if (tmp_string == NULL)
 
2061
      {
 
2062
        fprintf(stderr, "Memory Allocation error in option processing\n");
 
2063
        exit(1);
 
2064
      }
 
2065
      memset(tmp_string, 0, (size_t)(sbuf.st_size + 1));
 
2066
      bytes_read= read(data_file, (unsigned char*) tmp_string,
1941
2067
                       (size_t)sbuf.st_size);
 
2068
      tmp_string[sbuf.st_size]= '\0';
1942
2069
      close(data_file);
1943
2070
      if (bytes_read != sbuf.st_size)
1944
2071
      {
1945
2072
        fprintf(stderr, "Problem reading file: read less bytes than requested\n");
1946
2073
      }
1947
 
      parse_delimiter(&tmp_string[0], &create_statements, delimiter[0]);
 
2074
      parse_delimiter(tmp_string, &create_statements, delimiter[0]);
 
2075
      free(tmp_string);
1948
2076
    }
1949
 
    else if (!create_string.empty())
 
2077
    else if (create_string)
1950
2078
    {
1951
 
      parse_delimiter(create_string.c_str(), &create_statements, delimiter[0]);
 
2079
      parse_delimiter(create_string, &create_statements, delimiter[0]);
1952
2080
    }
1953
2081
 
1954
2082
    /* Set this up till we fully support options on user generated queries */
1955
 
    if (!user_supplied_query.empty())
 
2083
    if (user_supplied_query)
1956
2084
    {
1957
2085
      query_statements_count=
1958
2086
        parse_option("default", &query_options, ',');
1959
2087
 
1960
 
      query_statements.resize(query_statements_count);
 
2088
      query_statements= (Statement **)malloc(sizeof(Statement *) * query_statements_count);
 
2089
      if (query_statements == NULL)
 
2090
      {
 
2091
        fprintf(stderr, "Memory Allocation error in option processing\n");
 
2092
        exit(1);
 
2093
      }
 
2094
      memset(query_statements, 0, sizeof(Statement *) * query_statements_count); 
1961
2095
    }
1962
2096
 
1963
 
    if (!user_supplied_query.empty() && !stat(user_supplied_query.c_str(), &sbuf))
 
2097
    if (user_supplied_query && !stat(user_supplied_query, &sbuf))
1964
2098
    {
1965
2099
      int data_file;
1966
 
      std::vector<char> tmp_string;
1967
 
 
1968
2100
      if (!S_ISREG(sbuf.st_mode))
1969
2101
      {
1970
2102
        fprintf(stderr,"%s: User query supplied file was not a regular file\n",
1971
2103
                internal::my_progname);
1972
2104
        exit(1);
1973
2105
      }
1974
 
      if ((data_file= open(user_supplied_query.c_str(), O_RDWR)) == -1)
 
2106
      if ((data_file= open(user_supplied_query, O_RDWR)) == -1)
1975
2107
      {
1976
2108
        fprintf(stderr,"%s: Could not open query supplied file\n", internal::my_progname);
1977
2109
        exit(1);
1981
2113
        fprintf(stderr, "Request for more memory than architecture supports\n");
1982
2114
        exit(1);
1983
2115
      }
1984
 
      tmp_string.resize((size_t)(sbuf.st_size + 1));
1985
 
      bytes_read= read(data_file, (unsigned char*) &tmp_string[0],
 
2116
      tmp_string= (char *)malloc((size_t)(sbuf.st_size + 1));
 
2117
      if (tmp_string == NULL)
 
2118
      {
 
2119
        fprintf(stderr, "Memory Allocation error in option processing\n");
 
2120
        exit(1);
 
2121
      }
 
2122
      memset(tmp_string, 0, (size_t)(sbuf.st_size + 1));
 
2123
      bytes_read= read(data_file, (unsigned char*) tmp_string,
1986
2124
                       (size_t)sbuf.st_size);
 
2125
      tmp_string[sbuf.st_size]= '\0';
1987
2126
      close(data_file);
1988
2127
      if (bytes_read != sbuf.st_size)
1989
2128
      {
1990
2129
        fprintf(stderr, "Problem reading file: read less bytes than requested\n");
1991
2130
      }
1992
 
      if (!user_supplied_query.empty())
1993
 
        actual_queries= parse_delimiter(&tmp_string[0], &query_statements[0],
 
2131
      if (user_supplied_query)
 
2132
        actual_queries= parse_delimiter(tmp_string, &query_statements[0],
1994
2133
                                        delimiter[0]);
 
2134
      free(tmp_string);
1995
2135
    }
1996
 
    else if (!user_supplied_query.empty())
 
2136
    else if (user_supplied_query)
1997
2137
    {
1998
 
      actual_queries= parse_delimiter(user_supplied_query.c_str(), &query_statements[0],
 
2138
      actual_queries= parse_delimiter(user_supplied_query, &query_statements[0],
1999
2139
                                      delimiter[0]);
2000
2140
    }
2001
2141
  }
2002
2142
 
2003
 
  if (!user_supplied_pre_statements.empty()
2004
 
      && !stat(user_supplied_pre_statements.c_str(), &sbuf))
 
2143
  if (user_supplied_pre_statements
 
2144
      && !stat(user_supplied_pre_statements, &sbuf))
2005
2145
  {
2006
2146
    int data_file;
2007
 
    std::vector<char> tmp_string;
2008
 
 
2009
2147
    if (!S_ISREG(sbuf.st_mode))
2010
2148
    {
2011
2149
      fprintf(stderr,"%s: User query supplied file was not a regular file\n",
2012
2150
              internal::my_progname);
2013
2151
      exit(1);
2014
2152
    }
2015
 
    if ((data_file= open(user_supplied_pre_statements.c_str(), O_RDWR)) == -1)
 
2153
    if ((data_file= open(user_supplied_pre_statements, O_RDWR)) == -1)
2016
2154
    {
2017
2155
      fprintf(stderr,"%s: Could not open query supplied file\n", internal::my_progname);
2018
2156
      exit(1);
2022
2160
      fprintf(stderr, "Request for more memory than architecture supports\n");
2023
2161
      exit(1);
2024
2162
    }
2025
 
    tmp_string.resize((size_t)(sbuf.st_size + 1));
2026
 
    bytes_read= read(data_file, (unsigned char*) &tmp_string[0],
 
2163
    tmp_string= (char *)malloc((size_t)(sbuf.st_size + 1));
 
2164
    if (tmp_string == NULL)
 
2165
    {
 
2166
      fprintf(stderr, "Memory Allocation error in option processing\n");
 
2167
      exit(1);
 
2168
    }
 
2169
    memset(tmp_string, 0, (size_t)(sbuf.st_size + 1));
 
2170
    bytes_read= read(data_file, (unsigned char*) tmp_string,
2027
2171
                     (size_t)sbuf.st_size);
 
2172
    tmp_string[sbuf.st_size]= '\0';
2028
2173
    close(data_file);
2029
2174
    if (bytes_read != sbuf.st_size)
2030
2175
    {
2031
2176
      fprintf(stderr, "Problem reading file: read less bytes than requested\n");
2032
2177
    }
2033
 
    if (!user_supplied_pre_statements.empty())
2034
 
      (void)parse_delimiter(&tmp_string[0], &pre_statements,
 
2178
    if (user_supplied_pre_statements)
 
2179
      (void)parse_delimiter(tmp_string, &pre_statements,
2035
2180
                            delimiter[0]);
 
2181
    free(tmp_string);
2036
2182
  }
2037
 
  else if (!user_supplied_pre_statements.empty())
 
2183
  else if (user_supplied_pre_statements)
2038
2184
  {
2039
 
    (void)parse_delimiter(user_supplied_pre_statements.c_str(),
 
2185
    (void)parse_delimiter(user_supplied_pre_statements,
2040
2186
                          &pre_statements,
2041
2187
                          delimiter[0]);
2042
2188
  }
2043
2189
 
2044
 
  if (!user_supplied_post_statements.empty()
2045
 
      && !stat(user_supplied_post_statements.c_str(), &sbuf))
 
2190
  if (user_supplied_post_statements
 
2191
      && !stat(user_supplied_post_statements, &sbuf))
2046
2192
  {
2047
2193
    int data_file;
2048
 
    std::vector<char> tmp_string;
2049
 
 
2050
2194
    if (!S_ISREG(sbuf.st_mode))
2051
2195
    {
2052
2196
      fprintf(stderr,"%s: User query supplied file was not a regular file\n",
2053
2197
              internal::my_progname);
2054
2198
      exit(1);
2055
2199
    }
2056
 
    if ((data_file= open(user_supplied_post_statements.c_str(), O_RDWR)) == -1)
 
2200
    if ((data_file= open(user_supplied_post_statements, O_RDWR)) == -1)
2057
2201
    {
2058
2202
      fprintf(stderr,"%s: Could not open query supplied file\n", internal::my_progname);
2059
2203
      exit(1);
2064
2208
      fprintf(stderr, "Request for more memory than architecture supports\n");
2065
2209
      exit(1);
2066
2210
    }
2067
 
    tmp_string.resize((size_t)(sbuf.st_size + 1));
 
2211
    tmp_string= (char *)malloc((size_t)(sbuf.st_size + 1));
 
2212
    if (tmp_string == NULL)
 
2213
    {
 
2214
      fprintf(stderr, "Memory Allocation error in option processing\n");
 
2215
      exit(1);
 
2216
    }
 
2217
    memset(tmp_string, 0, (size_t)(sbuf.st_size+1));
2068
2218
 
2069
 
    bytes_read= read(data_file, (unsigned char*) &tmp_string[0],
 
2219
    bytes_read= read(data_file, (unsigned char*) tmp_string,
2070
2220
                     (size_t)(sbuf.st_size));
 
2221
    tmp_string[sbuf.st_size]= '\0';
2071
2222
    close(data_file);
2072
2223
    if (bytes_read != sbuf.st_size)
2073
2224
    {
2074
2225
      fprintf(stderr, "Problem reading file: read less bytes than requested\n");
2075
2226
    }
2076
 
    if (!user_supplied_post_statements.empty())
2077
 
      (void)parse_delimiter(&tmp_string[0], &post_statements,
 
2227
    if (user_supplied_post_statements)
 
2228
      (void)parse_delimiter(tmp_string, &post_statements,
2078
2229
                            delimiter[0]);
 
2230
    free(tmp_string);
2079
2231
  }
2080
 
  else if (!user_supplied_post_statements.empty())
 
2232
  else if (user_supplied_post_statements)
2081
2233
  {
2082
 
    (void)parse_delimiter(user_supplied_post_statements.c_str(), &post_statements,
 
2234
    (void)parse_delimiter(user_supplied_post_statements, &post_statements,
2083
2235
                          delimiter[0]);
2084
2236
  }
2085
2237
 
2086
2238
  if (verbose >= 2)
2087
2239
    printf("Parsing engines to use.\n");
2088
2240
 
2089
 
  if (!default_engine.empty())
2090
 
    parse_option(default_engine.c_str(), &engine_options, ',');
 
2241
  if (default_engine)
 
2242
    parse_option(default_engine, &engine_options, ',');
2091
2243
 
2092
2244
  if (tty_password)
2093
2245
    opt_password= client_get_tty_password(NULL);
2140
2292
  if (opt_only_print || (engine_stmt &&
2141
2293
                         strstr(engine_stmt->getString(), "blackhole")))
2142
2294
  {
 
2295
    primary_keys_number_of= 1;
 
2296
    primary_keys= (char **)malloc((sizeof(char *) *
 
2297
                                  primary_keys_number_of));
 
2298
    if (primary_keys == NULL)
 
2299
    {
 
2300
      fprintf(stderr, "Memory Allocation error in option processing\n");
 
2301
      exit(1);
 
2302
    }
 
2303
    
 
2304
    memset(primary_keys, 0, (sizeof(char *) * primary_keys_number_of));
2143
2305
    /* Yes, we strdup a const string to simplify the interface */
2144
 
    primary_keys.push_back("796c4422-1d94-102a-9d6d-00e0812d");
 
2306
    primary_keys[0]= strdup("796c4422-1d94-102a-9d6d-00e0812d");
 
2307
    if (primary_keys[0] == NULL)
 
2308
    {
 
2309
      fprintf(stderr, "Memory Allocation error in option processing\n");
 
2310
      exit(1);
 
2311
    }
2145
2312
  }
2146
2313
  else
2147
2314
  {
2158
2325
      fprintf(stderr, "More primary keys than than architecture supports\n");
2159
2326
      exit(1);
2160
2327
    }
2161
 
    size_t primary_keys_number_of;
2162
2328
    primary_keys_number_of= (size_t)num_rows_ret;
2163
2329
 
2164
2330
    /* So why check this? Blackhole :) */
2167
2333
      /*
2168
2334
        We create the structure and loop and create the items.
2169
2335
      */
 
2336
      primary_keys= (char **)malloc(sizeof(char *) *
 
2337
                                    primary_keys_number_of);
 
2338
      if (primary_keys == NULL)
 
2339
      {
 
2340
        fprintf(stderr, "Memory Allocation error in option processing\n");
 
2341
        exit(1);
 
2342
      }
 
2343
      memset(primary_keys, 0, (size_t)(sizeof(char *) * primary_keys_number_of));
2170
2344
      row= drizzle_row_next(&result);
2171
2345
      for (counter= 0; counter < primary_keys_number_of;
2172
2346
           counter++, row= drizzle_row_next(&result))
2173
2347
      {
2174
 
        primary_keys.push_back(row[0]);
 
2348
        primary_keys[counter]= strdup(row[0]);
 
2349
        if (primary_keys[counter] == NULL)
 
2350
        {
 
2351
          fprintf(stderr, "Memory Allocation error in option processing\n");
 
2352
          exit(1);
 
2353
        }
2175
2354
      }
2176
2355
    }
2177
2356
 
2182
2361
}
2183
2362
 
2184
2363
static int
 
2364
drop_primary_key_list(void)
 
2365
{
 
2366
  uint64_t counter;
 
2367
 
 
2368
  if (primary_keys_number_of)
 
2369
  {
 
2370
    for (counter= 0; counter < primary_keys_number_of; counter++)
 
2371
      free(primary_keys[counter]);
 
2372
 
 
2373
    free(primary_keys);
 
2374
  }
 
2375
 
 
2376
  return 0;
 
2377
}
 
2378
 
 
2379
static int
2185
2380
create_schema(drizzle_con_st *con, const char *db, Statement *stmt,
2186
2381
              OptionString *engine_stmt, Stats *sptr)
2187
2382
{
2340
2535
static int
2341
2536
run_scheduler(Stats *sptr, Statement **stmts, uint32_t concur, uint64_t limit)
2342
2537
{
 
2538
  uint32_t x;
2343
2539
  uint32_t y;
2344
2540
  unsigned int real_concurrency;
2345
2541
  struct timeval start_time, end_time;
2346
2542
  OptionString *sql_type;
 
2543
  ThreadContext *con;
2347
2544
  pthread_t mainthread;            /* Thread descriptor */
2348
2545
  pthread_attr_t attr;          /* Thread attributes */
2349
2546
 
2375
2572
    }
2376
2573
 
2377
2574
    while (options_loop--)
2378
 
    {
2379
 
      for (uint32_t x= 0; x < concur; x++)
 
2575
      for (x= 0; x < concur; x++)
2380
2576
      {
2381
 
        ThreadContext *con;
2382
 
        con= new ThreadContext;
 
2577
        con= (ThreadContext *)malloc(sizeof(ThreadContext));
2383
2578
        if (con == NULL)
2384
2579
        {
2385
2580
          fprintf(stderr, "Memory Allocation error in scheduler\n");
2398
2593
        }
2399
2594
        thread_counter++;
2400
2595
      }
2401
 
    }
2402
2596
  }
2403
2597
 
2404
2598
  /*
2531
2725
    {
2532
2726
      int length;
2533
2727
      unsigned int key_val;
 
2728
      char *key;
2534
2729
      char buffer[HUGE_STRING_LENGTH];
2535
2730
 
2536
2731
      /*
2540
2735
        Just in case someone runs this under an experimental engine we don't
2541
2736
        want a crash so the if() is placed here.
2542
2737
      */
2543
 
      assert(primary_keys.size());
2544
 
      if (primary_keys.size())
 
2738
      assert(primary_keys_number_of);
 
2739
      if (primary_keys_number_of)
2545
2740
      {
2546
 
        key_val= (unsigned int)(random() % primary_keys.size());
2547
 
        const char *key;
2548
 
        key= primary_keys[key_val].c_str();
 
2741
        key_val= (unsigned int)(random() % primary_keys_number_of);
 
2742
        key= primary_keys[key_val];
2549
2743
 
2550
2744
        assert(key);
2551
2745
 
2611
2805
  pthread_cond_signal(&count_threshhold);
2612
2806
  pthread_mutex_unlock(&counter_mutex);
2613
2807
 
2614
 
  delete ctx;
 
2808
  free(ctx);
2615
2809
 
2616
2810
  return(0);
2617
2811
}
2626
2820
  char *string;
2627
2821
  char *begin_ptr;
2628
2822
  char *end_ptr;
 
2823
  OptionString **sptr= stmt;
 
2824
  OptionString *tmp;
2629
2825
  uint32_t length= strlen(origin);
2630
2826
  uint32_t count= 0; /* We know that there is always one */
2631
2827
 
2632
2828
  end_ptr= (char *)origin + length;
2633
2829
 
2634
 
  OptionString *tmp;
2635
 
  *stmt= tmp= new OptionString;
 
2830
  tmp= *sptr= (OptionString *)malloc(sizeof(OptionString));
 
2831
  if (tmp == NULL)
 
2832
  {
 
2833
    fprintf(stderr,"Error allocating memory while parsing options\n");
 
2834
    exit(1);
 
2835
  }
 
2836
  memset(tmp, 0, sizeof(OptionString));
2636
2837
 
2637
2838
  for (begin_ptr= (char *)origin;
2638
2839
       begin_ptr != end_ptr;
2664
2865
      buffer_ptr++;
2665
2866
 
2666
2867
      /* Move past the : and the first string */
2667
 
      tmp->setOption(buffer_ptr);
 
2868
      tmp->setOptionLength(strlen(buffer_ptr));
 
2869
      tmp->setOption((char *)malloc(tmp->getOptionLength() + 1));
 
2870
      if (tmp->getOption() == NULL)
 
2871
      {
 
2872
        fprintf(stderr,"Error allocating memory while parsing options\n");
 
2873
        exit(1);
 
2874
      }
 
2875
      memcpy(tmp->getOption(), buffer_ptr, tmp->getOptionLength());
 
2876
      tmp->setOption(tmp->getOptionLength(),0); 
2668
2877
    }
2669
2878
 
 
2879
    tmp->setLength(strlen(buffer));
2670
2880
    tmp->setString(strdup(buffer));
2671
2881
    if (tmp->getString() == NULL)
2672
2882
    {
2681
2891
 
2682
2892
    if (begin_ptr != end_ptr)
2683
2893
    {
2684
 
      tmp->setNext( new OptionString);
 
2894
      tmp->setNext((OptionString *)malloc(sizeof(OptionString)));
 
2895
      if (tmp->getNext() == NULL)
 
2896
      {
 
2897
        fprintf(stderr,"Error allocating memory while parsing options\n");
 
2898
        exit(1);
 
2899
      }
 
2900
      memset(tmp->getNext(), 0, sizeof(OptionString));
2685
2901
    }
2686
2902
    
2687
2903
  }
2704
2920
  uint32_t length= strlen(script);
2705
2921
  uint32_t count= 0; /* We know that there is always one */
2706
2922
 
2707
 
  for (tmp= *sptr= new Statement;
 
2923
  for (tmp= *sptr= (Statement *)calloc(1, sizeof(Statement));
2708
2924
       (retstr= strchr(ptr, delm));
2709
 
       tmp->setNext(new Statement),
 
2925
       tmp->setNext((Statement *)calloc(1, sizeof(Statement))),
2710
2926
       tmp= tmp->getNext())
2711
2927
  {
2712
2928
    if (tmp == NULL)
2716
2932
    }
2717
2933
 
2718
2934
    count++;
2719
 
    tmp->setString((size_t)(retstr - ptr));
 
2935
    tmp->setLength((size_t)(retstr - ptr));
 
2936
    tmp->setString((char *)malloc(tmp->getLength() + 1));
2720
2937
 
2721
2938
    if (tmp->getString() == NULL)
2722
2939
    {
2725
2942
    }
2726
2943
 
2727
2944
    memcpy(tmp->getString(), ptr, tmp->getLength());
 
2945
    tmp->setString(tmp->getLength(), 0);
2728
2946
    ptr+= retstr - ptr + 1;
2729
2947
    if (isspace(*ptr))
2730
2948
      ptr++;
2732
2950
 
2733
2951
  if (ptr != script+length)
2734
2952
  {
2735
 
    tmp->setString((size_t)((script + length) - ptr));
 
2953
    tmp->setLength((size_t)((script + length) - ptr));
 
2954
    tmp->setString((char *)malloc(tmp->getLength() + 1));
2736
2955
    if (tmp->getString() == NULL)
2737
2956
    {
2738
2957
      fprintf(stderr,"Error allocating memory while parsing delimiter\n");
2739
2958
      exit(1);
2740
2959
    }
2741
2960
    memcpy(tmp->getString(), ptr, tmp->getLength());
 
2961
    tmp->setString(tmp->getLength(),0);
2742
2962
    count++;
2743
2963
  }
2744
2964
 
2752
2972
  In restrospect, this is a lousy name from this function.
2753
2973
*/
2754
2974
uint
2755
 
parse_comma(const char *string, std::vector <uint32_t> &range)
 
2975
parse_comma(const char *string, uint32_t **range)
2756
2976
{
2757
2977
  unsigned int count= 1,x; /* We know that there is always one */
2758
2978
  char *retstr;
2763
2983
    if (*ptr == ',') count++;
2764
2984
 
2765
2985
  /* One extra spot for the NULL */
2766
 
  range.resize(count +1);
2767
 
  nptr= &range[0];
 
2986
  nptr= *range= (uint32_t *)malloc(sizeof(unsigned int) * (count + 1));
 
2987
  memset(nptr, 0, sizeof(unsigned int) * (count + 1));
2768
2988
 
2769
2989
  ptr= (char *)string;
2770
2990
  x= 0;
2784
3004
  printf("Benchmark\n");
2785
3005
  if (con->getEngine())
2786
3006
    printf("\tRunning for engine %s\n", con->getEngine());
2787
 
  if (!opt_label.empty() || !opt_auto_generate_sql_type.empty())
 
3007
  if (opt_label || opt_auto_generate_sql_type)
2788
3008
  {
2789
 
    const char *ptr= opt_auto_generate_sql_type.c_str() ? opt_auto_generate_sql_type.c_str() : "query";
2790
 
    printf("\tLoad: %s\n", !opt_label.empty() ? opt_label.c_str() : ptr);
 
3009
    const char *ptr= opt_auto_generate_sql_type ? opt_auto_generate_sql_type : "query";
 
3010
    printf("\tLoad: %s\n", opt_label ? opt_label : ptr);
2791
3011
  }
2792
3012
  printf("\tAverage Time took to generate schema and initial data: %ld.%03ld seconds\n",
2793
3013
         con->getCreateAvgTiming() / 1000, con->getCreateAvgTiming() % 1000);
2815
3035
  char buffer[HUGE_STRING_LENGTH];
2816
3036
  char label_buffer[HUGE_STRING_LENGTH];
2817
3037
  size_t string_len;
2818
 
  const char *temp_label= opt_label.c_str();
2819
 
 
2820
 
  memset(label_buffer, 0, sizeof(label_buffer));
2821
 
 
2822
 
  if (!opt_label.empty())
 
3038
 
 
3039
  memset(label_buffer, 0, HUGE_STRING_LENGTH);
 
3040
 
 
3041
  if (opt_label)
2823
3042
  {
2824
 
    string_len= opt_label.length();
 
3043
    string_len= strlen(opt_label);
2825
3044
 
2826
3045
    for (x= 0; x < string_len; x++)
2827
3046
    {
2828
 
      if (temp_label[x] == ',')
 
3047
      if (opt_label[x] == ',')
2829
3048
        label_buffer[x]= '-';
2830
3049
      else
2831
 
        label_buffer[x]= temp_label[x] ;
 
3050
        label_buffer[x]= opt_label[x] ;
2832
3051
    }
2833
3052
  }
2834
 
  else if (!opt_auto_generate_sql_type.empty())
 
3053
  else if (opt_auto_generate_sql_type)
2835
3054
  {
2836
 
    string_len= opt_auto_generate_sql_type.length();
 
3055
    string_len= strlen(opt_auto_generate_sql_type);
2837
3056
 
2838
3057
    for (x= 0; x < string_len; x++)
2839
3058
    {
2844
3063
    }
2845
3064
  }
2846
3065
  else
2847
 
  {
2848
3066
    snprintf(label_buffer, HUGE_STRING_LENGTH, "query");
2849
 
  }
2850
3067
 
2851
3068
  snprintf(buffer, HUGE_STRING_LENGTH,
2852
3069
           "%s,%s,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,"
2863
3080
           con->getRealUsers(), /* Children used max_timing */
2864
3081
           con->getAvgRows()  /* Queries run */
2865
3082
           );
2866
 
  size_t buff_len= strlen(buffer);
2867
 
  ssize_t write_ret= write(csv_file, (unsigned char*) buffer, buff_len);
2868
 
  if (write_ret != (ssize_t)buff_len)
2869
 
  {
2870
 
    fprintf(stderr, _("Unable to fully write %"PRIu64" bytes. "
2871
 
                      "Could only write %"PRId64"."), (uint64_t)write_ret,
2872
 
                      (int64_t)buff_len);
2873
 
    exit(-1);
2874
 
  }
 
3083
  internal::my_write(csv_file, (unsigned char*) buffer, (uint32_t)strlen(buffer), MYF(0));
2875
3084
}
2876
3085
 
2877
3086
void
2934
3143
option_cleanup(OptionString *stmt)
2935
3144
{
2936
3145
  OptionString *ptr, *nptr;
2937
 
  if (not stmt)
 
3146
  if (!stmt)
2938
3147
    return;
2939
3148
 
2940
3149
  for (ptr= stmt; ptr; ptr= nptr)
2941
3150
  {
2942
3151
    nptr= ptr->getNext();
2943
 
    delete ptr;
 
3152
    if (ptr->getString())
 
3153
      free(ptr->getString());
 
3154
    if (ptr->getOption())
 
3155
      free(ptr->getOption());
 
3156
    free(ptr);
2944
3157
  }
2945
3158
}
2946
3159
 
2954
3167
  for (ptr= stmt; ptr; ptr= nptr)
2955
3168
  {
2956
3169
    nptr= ptr->getNext();
2957
 
    delete ptr;
 
3170
    if (ptr->getString())
 
3171
      free(ptr->getString());
 
3172
    free(ptr);
2958
3173
  }
2959
3174
}
2960
3175
 
2972
3187
{
2973
3188
  /* Connect to server */
2974
3189
  static uint32_t connection_retry_sleep= 100000; /* Microseconds */
2975
 
  int connect_error= 1;
 
3190
  int x, connect_error= 1;
2976
3191
  drizzle_return_t ret;
2977
3192
  drizzle_st *drizzle;
2978
3193
 
2983
3198
    usleep(random()%opt_delayed_start);
2984
3199
 
2985
3200
  if ((drizzle= drizzle_create(NULL)) == NULL ||
2986
 
      drizzle_con_add_tcp(drizzle, con, host.c_str(), opt_drizzle_port,
2987
 
        user.c_str(),
2988
 
        opt_password.c_str(),
2989
 
        connect_to_schema ? create_schema_string.c_str() : NULL,
2990
 
        use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL) == NULL)
 
3201
      drizzle_con_add_tcp(drizzle, con, host, opt_drizzle_port, user,
 
3202
                          opt_password,
 
3203
                          connect_to_schema ? create_schema_string : NULL,
 
3204
                          opt_mysql ? DRIZZLE_CON_MYSQL : DRIZZLE_CON_NONE) == NULL)
2991
3205
  {
2992
3206
    fprintf(stderr,"%s: Error creating drizzle object\n", internal::my_progname);
2993
3207
    exit(1);
2994
3208
  }
2995
3209
 
2996
 
  for (uint32_t x= 0; x < 10; x++)
 
3210
  for (x= 0; x < 10; x++)
2997
3211
  {
2998
3212
    if ((ret= drizzle_con_connect(con)) == DRIZZLE_RETURN_OK)
2999
3213
    {