~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzleslap.cc

  • Committer: Monty Taylor
  • Date: 2010-07-19 05:06:59 UTC
  • mto: (1662.1.2 rollup)
  • mto: This revision was merged to the branch mainline in revision 1663.
  • Revision ID: mordred@inaugust.com-20100719050659-if3thz0k66m1jkaf
Backed out two bits that snuck in to the merge.

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
#include "config.h"
 
74
 
75
75
#include "client_priv.h"
76
 
 
77
 
#include "option_string.h"
78
 
#include "stats.h"
79
 
#include "thread_context.h"
80
 
#include "conclusions.h"
81
 
#include "wakeup.h"
82
 
 
83
76
#include <signal.h>
84
77
#include <stdarg.h>
85
78
#include <sys/types.h>
94
87
#include <string>
95
88
#include <iostream>
96
89
#include <fstream>
 
90
#include <pthread.h>
97
91
#include <drizzled/configmake.h>
98
 
#include <memory>
99
 
 
100
92
/* Added this for string translation. */
101
93
#include <drizzled/gettext.h>
102
 
 
103
 
#include <boost/thread.hpp>
104
 
#include <boost/thread/mutex.hpp>
105
 
#include <boost/thread/condition_variable.hpp>
106
94
#include <boost/program_options.hpp>
107
 
#include <boost/scoped_ptr.hpp>
108
 
#include <drizzled/atomics.h>
109
95
 
110
 
#define SLAP_NAME "drizzleslap"
111
96
#define SLAP_VERSION "1.5"
112
97
 
113
98
#define HUGE_STRING_LENGTH 8196
122
107
static char *shared_memory_base_name=0;
123
108
#endif
124
109
 
125
 
client::Wakeup master_wakeup;
 
110
/* Global Thread counter */
 
111
uint32_t thread_counter;
 
112
pthread_mutex_t counter_mutex;
 
113
pthread_cond_t count_threshhold;
 
114
uint32_t master_wakeup;
 
115
pthread_mutex_t sleeper_mutex;
 
116
pthread_cond_t sleep_threshhold;
126
117
 
127
118
/* Global Thread timer */
128
119
static bool timer_alarm= false;
129
 
boost::mutex timer_alarm_mutex;
130
 
boost::condition_variable_any timer_alarm_threshold;
131
 
 
132
 
std::vector < std::string > primary_keys;
133
 
 
134
 
drizzled::atomic<size_t> connection_count;
135
 
drizzled::atomic<uint64_t> failed_update_for_transaction;
 
120
pthread_mutex_t timer_alarm_mutex;
 
121
pthread_cond_t timer_alarm_threshold;
 
122
 
 
123
char **primary_keys;
 
124
/* This gets passed to malloc, so lets set it to an arch-dependant size */
 
125
size_t primary_keys_number_of;
136
126
 
137
127
static string host, 
138
128
  opt_password, 
146
136
 
147
137
static vector<string> user_supplied_queries;
148
138
static string opt_verbose;
149
 
std::string opt_protocol;
150
139
string delimiter;
151
140
 
152
141
string create_schema_string;
153
142
 
154
 
static bool use_drizzle_protocol= false;
 
143
static bool opt_mysql;
155
144
static bool opt_preserve= true;
156
145
static bool opt_only_print;
157
146
static bool opt_burnin;
172
161
  num_char_cols_opt,
173
162
  num_int_cols_opt;
174
163
string opt_label;
175
 
static uint32_t opt_set_random_seed;
 
164
static unsigned int opt_set_random_seed;
176
165
 
177
166
string auto_generate_selected_columns_opt;
178
167
 
179
168
/* Yes, we do set defaults here */
180
 
static uint32_t num_int_cols= 1;
181
 
static uint32_t num_char_cols= 1;
182
 
static uint32_t num_blob_cols= 0;
183
 
static uint32_t num_blob_cols_size;
184
 
static uint32_t num_blob_cols_size_min;
185
 
static uint32_t num_int_cols_index= 0;
186
 
static uint32_t num_char_cols_index= 0;
 
169
static unsigned int num_int_cols= 1;
 
170
static unsigned int num_char_cols= 1;
 
171
static unsigned int num_blob_cols= 0;
 
172
static unsigned int num_blob_cols_size;
 
173
static unsigned int num_blob_cols_size_min;
 
174
static unsigned int num_int_cols_index= 0;
 
175
static unsigned int num_char_cols_index= 0;
187
176
static uint32_t iterations;
188
177
static uint64_t actual_queries= 0;
189
178
static uint64_t auto_actual_queries;
194
183
static uint64_t auto_generate_sql_number;
195
184
string concurrency_str;
196
185
string create_string;
197
 
std::vector <uint32_t> concurrency;
 
186
uint32_t *concurrency;
198
187
 
 
188
const char *default_dbug_option= "d:t:o,/tmp/drizzleslap.trace";
199
189
std::string opt_csv_str;
200
190
int csv_file;
201
191
 
202
192
static int process_options(void);
203
193
static uint32_t opt_drizzle_port= 0;
204
194
 
 
195
 
 
196
/* Types */
 
197
typedef enum {
 
198
  SELECT_TYPE= 0,
 
199
  UPDATE_TYPE= 1,
 
200
  INSERT_TYPE= 2,
 
201
  UPDATE_TYPE_REQUIRES_PREFIX= 3,
 
202
  CREATE_TABLE_TYPE= 4,
 
203
  SELECT_TYPE_REQUIRES_PREFIX= 5,
 
204
  DELETE_TYPE_REQUIRES_PREFIX= 6
 
205
} slap_query_type;
 
206
 
 
207
class Statement;
 
208
 
 
209
class Statement 
 
210
{
 
211
public:
 
212
  Statement(char *in_string,
 
213
            size_t in_length,
 
214
            slap_query_type in_type,
 
215
            char *in_option,
 
216
            size_t in_option_length,
 
217
            Statement *in_next)
 
218
    :
 
219
    string(in_string),
 
220
    length(in_length),
 
221
    type(in_type),
 
222
    option(in_option),
 
223
    option_length(in_option_length),
 
224
    next(in_next)
 
225
    {}
 
226
 
 
227
  Statement()
 
228
    :
 
229
    string(NULL),
 
230
    length(0),
 
231
    type(),
 
232
    option(NULL),
 
233
    option_length(0),
 
234
    next(NULL)
 
235
    {}
 
236
   
 
237
  char *getString() const
 
238
  {
 
239
    return string;
 
240
  }
 
241
 
 
242
  size_t getLength() const
 
243
  {
 
244
    return length;
 
245
  }
 
246
 
 
247
  slap_query_type getType() const
 
248
  {
 
249
    return type;
 
250
  }
 
251
 
 
252
  char *getOption() const
 
253
  {
 
254
    return option;
 
255
  }
 
256
 
 
257
  size_t getOptionLength() const
 
258
  {
 
259
    return option_length;
 
260
  }
 
261
 
 
262
  Statement *getNext() const
 
263
  {
 
264
    return next;
 
265
  }
 
266
 
 
267
  void setString(char *in_string)
 
268
  {
 
269
    string= in_string;
 
270
  }
 
271
 
 
272
  void setString(size_t in_length, char in_char)
 
273
  {
 
274
    string[in_length]= in_char;
 
275
  }
 
276
 
 
277
  void setLength(size_t in_length)
 
278
  {
 
279
    length= in_length;
 
280
  }
 
281
 
 
282
  void setType(slap_query_type in_type)
 
283
  {
 
284
    type= in_type;
 
285
  }
 
286
 
 
287
  void setOption(char *in_option)
 
288
  {
 
289
    option= in_option;
 
290
  }
 
291
 
 
292
   void setOptionLength(size_t in_option_length)
 
293
  {
 
294
    option_length= in_option_length;
 
295
  }
 
296
 
 
297
  void setNext(Statement *in_next)
 
298
  {
 
299
    next= in_next;
 
300
  }
 
301
 
 
302
private:
 
303
  char *string;
 
304
  size_t length;
 
305
  slap_query_type type;
 
306
  char *option;
 
307
  size_t option_length;
 
308
  Statement *next;
 
309
};
 
310
 
 
311
class OptionString;
 
312
 
 
313
class OptionString 
 
314
{
 
315
public:
 
316
  OptionString(char *in_string,
 
317
               size_t in_length,
 
318
               char *in_option,
 
319
               size_t in_option_length,
 
320
               OptionString *in_next)
 
321
    :
 
322
    string(in_string),
 
323
    length(in_length),
 
324
    option(in_option),
 
325
    option_length(in_option_length),
 
326
    next(in_next)
 
327
    {}  
 
328
 
 
329
  OptionString()
 
330
    :
 
331
    string(NULL),
 
332
    length(0),
 
333
    option(NULL),
 
334
    option_length(0),
 
335
    next(NULL)
 
336
    {}
 
337
 
 
338
  char *getString() const
 
339
  {
 
340
    return string;
 
341
  }
 
342
 
 
343
  size_t getLength() const
 
344
  {
 
345
    return length;
 
346
  }
 
347
 
 
348
  char *getOption() const
 
349
  {
 
350
  return option;
 
351
  }
 
352
 
 
353
  size_t getOptionLength() const
 
354
  {
 
355
    return option_length;
 
356
  }
 
357
 
 
358
  OptionString *getNext() const
 
359
  {
 
360
    return next;
 
361
  }
 
362
 
 
363
  void setString(char *in_string)
 
364
  {
 
365
    string= in_string;
 
366
  }
 
367
 
 
368
  void setOptionLength(size_t in_option_length)
 
369
  {
 
370
    option_length= in_option_length;
 
371
  }
 
372
 
 
373
  void setLength(size_t in_length)
 
374
  {
 
375
    length= in_length;
 
376
  }
 
377
 
 
378
  void setOption(char *in_option)
 
379
  {
 
380
    option= in_option;
 
381
  }
 
382
 
 
383
  void setOption(size_t in_option_length, char in_char)
 
384
  {
 
385
    option[in_option_length]= in_char;
 
386
  }
 
387
 
 
388
  void setNext(OptionString *in_next)
 
389
  {
 
390
    next= in_next;
 
391
  }
 
392
  
 
393
private:
 
394
  char *string;
 
395
  size_t length;
 
396
  char *option;
 
397
  size_t option_length;
 
398
  OptionString *next;
 
399
};
 
400
 
 
401
class Stats;
 
402
 
 
403
class Stats 
 
404
{
 
405
public:
 
406
  Stats(long int in_timing,
 
407
        uint32_t in_users,
 
408
        uint32_t in_real_users,
 
409
        uint32_t in_rows,
 
410
        long int in_create_timing,
 
411
        uint64_t in_create_count)
 
412
    :
 
413
    timing(in_timing),
 
414
    users(in_users),
 
415
    real_users(in_real_users),
 
416
    rows(in_rows),
 
417
    create_timing(in_create_timing),
 
418
    create_count(in_create_count)
 
419
    {}
 
420
 
 
421
  Stats()
 
422
    :
 
423
    timing(0),
 
424
    users(0),
 
425
    real_users(0),
 
426
    rows(0),
 
427
    create_timing(0),
 
428
    create_count(0)
 
429
    {}
 
430
 
 
431
  long int getTiming() const
 
432
  {
 
433
    return timing;
 
434
  }
 
435
 
 
436
  uint32_t getUsers() const
 
437
  {
 
438
    return users;
 
439
  }   
 
440
 
 
441
  uint32_t getRealUsers() const
 
442
  {
 
443
    return real_users;
 
444
  }
 
445
 
 
446
  uint64_t getRows() const
 
447
  {
 
448
    return rows;
 
449
  }
 
450
 
 
451
  long int getCreateTiming() const
 
452
  {
 
453
    return create_timing;
 
454
  }
 
455
 
 
456
  uint64_t getCreateCount() const
 
457
  {
 
458
    return create_count;
 
459
  }
 
460
 
 
461
  void setTiming(long int in_timing)
 
462
  {
 
463
  timing= in_timing;
 
464
  }
 
465
 
 
466
  void setUsers(uint32_t in_users)
 
467
  {
 
468
    users= in_users;
 
469
  }
 
470
 
 
471
  void setRealUsers(uint32_t in_real_users)
 
472
  {
 
473
    real_users= in_real_users;
 
474
  }
 
475
 
 
476
  void setRows(uint64_t in_rows)
 
477
  {
 
478
    rows= in_rows;
 
479
  }
 
480
   
 
481
  void setCreateTiming(long int in_create_timing)
 
482
  {
 
483
    create_timing= in_create_timing;
 
484
  }
 
485
 
 
486
  void setCreateCount(uint64_t in_create_count)
 
487
  {
 
488
  create_count= in_create_count;
 
489
  }
 
490
  
 
491
private:
 
492
  long int timing;
 
493
  uint32_t users;
 
494
  uint32_t real_users;
 
495
  uint64_t rows;
 
496
  long int create_timing;
 
497
  uint64_t create_count;
 
498
};
 
499
 
 
500
class ThreadContext;
 
501
 
 
502
class ThreadContext 
 
503
{
 
504
public:
 
505
  ThreadContext(Statement *in_stmt,
 
506
                uint64_t in_limit)
 
507
    :
 
508
    stmt(in_stmt),
 
509
    limit(in_limit)
 
510
    {}
 
511
 
 
512
  ThreadContext()
 
513
    :
 
514
    stmt(),
 
515
    limit(0)
 
516
    {}
 
517
 
 
518
  Statement *getStmt() const
 
519
  {
 
520
    return stmt;
 
521
  }
 
522
 
 
523
  uint64_t getLimit() const
 
524
  {
 
525
    return limit;
 
526
  }
 
527
 
 
528
  void setStmt(Statement *in_stmt)
 
529
  {
 
530
    stmt= in_stmt;
 
531
  }
 
532
 
 
533
  void setLimit(uint64_t in_limit)
 
534
  {
 
535
    limit= in_limit;
 
536
  }  
 
537
 
 
538
private:
 
539
  Statement *stmt;
 
540
  uint64_t limit;
 
541
};
 
542
 
 
543
class Conclusions;
 
544
 
 
545
class Conclusions 
 
546
{
 
547
 
 
548
public:
 
549
  Conclusions(char *in_engine,
 
550
              long int in_avg_timing,
 
551
              long int in_max_timing,
 
552
              long int in_min_timing,
 
553
              uint32_t in_users,
 
554
              uint32_t in_real_users,
 
555
              uint64_t in_avg_rows,
 
556
              long int in_sum_of_time,
 
557
              long int in_std_dev,
 
558
              long int in_create_avg_timing,
 
559
              long int in_create_max_timing,
 
560
              long int in_create_min_timing,
 
561
              uint64_t in_create_count,
 
562
              uint64_t in_max_rows,
 
563
              uint64_t in_min_rows)
 
564
    :
 
565
    engine(in_engine),
 
566
    avg_timing(in_avg_timing),
 
567
    max_timing(in_max_timing),
 
568
    min_timing(in_min_timing),
 
569
    users(in_users),
 
570
    real_users(in_real_users),
 
571
    avg_rows(in_avg_rows),
 
572
    sum_of_time(in_sum_of_time),
 
573
    std_dev(in_std_dev),
 
574
    create_avg_timing(in_create_avg_timing),
 
575
    create_max_timing(in_create_max_timing),
 
576
    create_min_timing(in_create_min_timing),
 
577
    create_count(in_create_count),
 
578
    max_rows(in_max_rows),
 
579
    min_rows(in_min_rows)
 
580
    {}
 
581
 
 
582
  Conclusions()
 
583
    :
 
584
    engine(NULL),
 
585
    avg_timing(0),
 
586
    max_timing(0),
 
587
    min_timing(0),
 
588
    users(0),
 
589
    real_users(0),
 
590
    avg_rows(0),
 
591
    sum_of_time(0),
 
592
    std_dev(0),
 
593
    create_avg_timing(0),
 
594
    create_max_timing(0),
 
595
    create_min_timing(0),
 
596
    create_count(0),
 
597
    max_rows(0),
 
598
    min_rows(0)
 
599
    {}
 
600
 
 
601
  char *getEngine() const
 
602
  {
 
603
    return engine;
 
604
  }
 
605
  
 
606
  long int getAvgTiming() const
 
607
  {
 
608
    return avg_timing;
 
609
  }
 
610
 
 
611
  long int getMaxTiming() const
 
612
  {
 
613
    return max_timing;
 
614
  }
 
615
 
 
616
  long int getMinTiming() const
 
617
  {
 
618
    return min_timing;
 
619
  }
 
620
 
 
621
  uint32_t getUsers() const
 
622
  {
 
623
    return users;
 
624
  }
 
625
 
 
626
  uint32_t getRealUsers() const
 
627
  {
 
628
    return real_users;
 
629
  }
 
630
 
 
631
  uint64_t getAvgRows() const
 
632
  {
 
633
    return avg_rows;
 
634
  }   
 
635
 
 
636
  long int getSumOfTime() const
 
637
  {
 
638
    return sum_of_time;
 
639
  }
 
640
 
 
641
  long int getStdDev() const
 
642
  {
 
643
    return std_dev;
 
644
  }
 
645
 
 
646
  long int getCreateAvgTiming() const
 
647
  {
 
648
    return create_avg_timing;
 
649
  }
 
650
 
 
651
  long int getCreateMaxTiming() const
 
652
  {
 
653
    return create_max_timing;
 
654
  }
 
655
 
 
656
  long int getCreateMinTiming() const
 
657
  {
 
658
    return create_min_timing;
 
659
  }
 
660
   
 
661
  uint64_t getCreateCount() const
 
662
  {
 
663
    return create_count;
 
664
  }
 
665
 
 
666
  uint64_t getMinRows() const
 
667
  {
 
668
    return min_rows;
 
669
  }
 
670
 
 
671
  uint64_t getMaxRows() const
 
672
  {
 
673
    return max_rows;
 
674
  }
 
675
 
 
676
  void setEngine(char *in_engine) 
 
677
  {
 
678
    engine= in_engine;
 
679
  }
 
680
  
 
681
  void setAvgTiming(long int in_avg_timing) 
 
682
  {
 
683
    avg_timing= in_avg_timing;
 
684
  }
 
685
 
 
686
  void setMaxTiming(long int in_max_timing) 
 
687
  {
 
688
    max_timing= in_max_timing;
 
689
  }
 
690
 
 
691
  void setMinTiming(long int in_min_timing) 
 
692
  {
 
693
    min_timing= in_min_timing;
 
694
  }
 
695
 
 
696
  void setUsers(uint32_t in_users) 
 
697
  {
 
698
    users= in_users;
 
699
  }
 
700
 
 
701
  void setRealUsers(uint32_t in_real_users) 
 
702
  {
 
703
    real_users= in_real_users;
 
704
  }
 
705
 
 
706
  void setAvgRows(uint64_t in_avg_rows) 
 
707
  {
 
708
    avg_rows= in_avg_rows;
 
709
  }   
 
710
 
 
711
  void setSumOfTime(long int in_sum_of_time) 
 
712
  {
 
713
    sum_of_time= in_sum_of_time;
 
714
  }
 
715
 
 
716
  void setStdDev(long int in_std_dev) 
 
717
  {
 
718
    std_dev= in_std_dev;
 
719
  }
 
720
 
 
721
  void setCreateAvgTiming(long int in_create_avg_timing) 
 
722
  {
 
723
    create_avg_timing= in_create_avg_timing;
 
724
  }
 
725
 
 
726
  void setCreateMaxTiming(long int in_create_max_timing) 
 
727
  {
 
728
    create_max_timing= in_create_max_timing;
 
729
  }
 
730
 
 
731
  void setCreateMinTiming(long int in_create_min_timing) 
 
732
  {
 
733
    create_min_timing= in_create_min_timing;
 
734
  }
 
735
   
 
736
  void setCreateCount(uint64_t in_create_count) 
 
737
  {
 
738
    create_count= in_create_count;
 
739
  }
 
740
 
 
741
  void setMinRows(uint64_t in_min_rows) 
 
742
  {
 
743
    min_rows= in_min_rows;
 
744
  }
 
745
 
 
746
  void setMaxRows(uint64_t in_max_rows) 
 
747
  {
 
748
    max_rows= in_max_rows;
 
749
  }
 
750
 
 
751
private:
 
752
  char *engine;
 
753
  long int avg_timing;
 
754
  long int max_timing;
 
755
  long int min_timing;
 
756
  uint32_t users;
 
757
  uint32_t real_users;
 
758
  uint64_t avg_rows;
 
759
  long int sum_of_time;
 
760
  long int std_dev;
 
761
  /* These are just for create time stats */
 
762
  long int create_avg_timing;
 
763
  long int create_max_timing;
 
764
  long int create_min_timing;
 
765
  uint64_t create_count;
 
766
  /* The following are not used yet */
 
767
  uint64_t max_rows;
 
768
  uint64_t min_rows;
 
769
};
 
770
 
 
771
 
205
772
static OptionString *engine_options= NULL;
206
773
static OptionString *query_options= NULL;
207
774
static Statement *pre_statements= NULL;
208
775
static Statement *post_statements= NULL;
209
776
static Statement *create_statements= NULL;
210
777
 
211
 
static std::vector <Statement *> query_statements;
212
 
static uint32_t query_statements_count;
 
778
static Statement **query_statements= NULL;
 
779
static unsigned int query_statements_count;
213
780
 
214
781
 
215
782
/* Prototypes */
216
 
void print_conclusions(Conclusions &con);
217
 
void print_conclusions_csv(Conclusions &con);
 
783
void print_conclusions(Conclusions *con);
 
784
void print_conclusions_csv(Conclusions *con);
218
785
void generate_stats(Conclusions *con, OptionString *eng, Stats *sptr);
219
 
uint32_t parse_comma(const char *string, std::vector <uint32_t> &range);
 
786
uint32_t parse_comma(const char *string, uint32_t **range);
220
787
uint32_t parse_delimiter(const char *script, Statement **stmt, char delm);
221
788
uint32_t parse_option(const char *origin, OptionString **stmt, char delm);
222
 
static void drop_schema(drizzle_con_st &con, const char *db);
 
789
static int drop_schema(drizzle_con_st *con, const char *db);
223
790
uint32_t get_random_string(char *buf, size_t size);
224
791
static Statement *build_table_string(void);
225
792
static Statement *build_insert_string(void);
226
793
static Statement *build_update_string(void);
227
794
static Statement * build_select_string(bool key);
228
 
static int generate_primary_key_list(drizzle_con_st &con, OptionString *engine_stmt);
229
 
static void create_schema(drizzle_con_st &con, const char *db, Statement *stmt, OptionString *engine_stmt, Stats *sptr);
230
 
static void run_scheduler(Stats *sptr, Statement **stmts, uint32_t concur, uint64_t limit);
 
795
static int generate_primary_key_list(drizzle_con_st *con, OptionString *engine_stmt);
 
796
static int drop_primary_key_list(void);
 
797
static int create_schema(drizzle_con_st *con, const char *db, Statement *stmt,
 
798
                         OptionString *engine_stmt, Stats *sptr);
 
799
static int run_scheduler(Stats *sptr, Statement **stmts, uint32_t concur,
 
800
                         uint64_t limit);
 
801
extern "C" pthread_handler_t run_task(void *p);
 
802
extern "C" pthread_handler_t timer_thread(void *p);
231
803
void statement_cleanup(Statement *stmt);
232
804
void option_cleanup(OptionString *stmt);
233
 
void concurrency_loop(drizzle_con_st &con, uint32_t current, OptionString *eptr);
234
 
static void run_statements(drizzle_con_st &con, Statement *stmt);
235
 
void slap_connect(drizzle_con_st &con, bool connect_to_schema);
236
 
void slap_close(drizzle_con_st &con);
237
 
static int run_query(drizzle_con_st &con, drizzle_result_st *result, const char *query, int len);
238
 
void standard_deviation(Conclusions &con, Stats *sptr);
 
805
void concurrency_loop(drizzle_con_st *con, uint32_t current, OptionString *eptr);
 
806
static int run_statements(drizzle_con_st *con, Statement *stmt);
 
807
void slap_connect(drizzle_con_st *con, bool connect_to_schema);
 
808
void slap_close(drizzle_con_st *con);
 
809
static int run_query(drizzle_con_st *con, drizzle_result_st *result, const char *query, int len);
 
810
void standard_deviation (Conclusions *con, Stats *sptr);
239
811
 
240
812
static const char ALPHANUMERICS[]=
241
813
"0123456789ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstuvwxyz";
245
817
 
246
818
static long int timedif(struct timeval a, struct timeval b)
247
819
{
248
 
  int us, s;
 
820
  register int us, s;
249
821
 
250
822
  us = a.tv_usec - b.tv_usec;
251
823
  us /= 1000;
265
837
    user_supplied_query.append(delimiter);
266
838
  }
267
839
}
268
 
 
269
 
 
270
 
static void run_task(ThreadContext *ctx)
271
 
{
272
 
  uint64_t counter= 0, queries;
273
 
  uint64_t detach_counter;
274
 
  uint32_t commit_counter;
275
 
  boost::scoped_ptr<drizzle_con_st> con_ap(new drizzle_con_st);
276
 
  drizzle_con_st &con= *con_ap.get();
277
 
  drizzle_result_st result;
278
 
  drizzle_row_t row;
279
 
  Statement *ptr;
280
 
 
281
 
  master_wakeup.wait();
282
 
 
283
 
  slap_connect(con, true);
284
 
 
285
 
  if (verbose >= 3)
286
 
    printf("connected!\n");
287
 
  queries= 0;
288
 
 
289
 
  commit_counter= 0;
290
 
  if (commit_rate)
291
 
    run_query(con, NULL, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
292
 
 
293
 
limit_not_met:
294
 
  for (ptr= ctx->getStmt(), detach_counter= 0;
295
 
       ptr && ptr->getLength();
296
 
       ptr= ptr->getNext(), detach_counter++)
297
 
  {
298
 
    if (not opt_only_print && detach_rate && !(detach_counter % detach_rate))
299
 
    {
300
 
      slap_close(con);
301
 
      slap_connect(con, true);
302
 
    }
303
 
 
304
 
    /*
305
 
      We have to execute differently based on query type. This should become a function.
306
 
    */
307
 
    bool is_failed_update= false;
308
 
    if ((ptr->getType() == UPDATE_TYPE_REQUIRES_PREFIX) ||
309
 
        (ptr->getType() == SELECT_TYPE_REQUIRES_PREFIX))
310
 
    {
311
 
      int length;
312
 
      uint32_t key_val;
313
 
      char buffer[HUGE_STRING_LENGTH];
314
 
 
315
 
      /*
316
 
        This should only happen if some sort of new engine was
317
 
        implemented that didn't properly handle UPDATEs.
318
 
 
319
 
        Just in case someone runs this under an experimental engine we don't
320
 
        want a crash so the if() is placed here.
321
 
      */
322
 
      assert(primary_keys.size());
323
 
      if (primary_keys.size())
324
 
      {
325
 
        key_val= (uint32_t)(random() % primary_keys.size());
326
 
        const char *key;
327
 
        key= primary_keys[key_val].c_str();
328
 
 
329
 
        assert(key);
330
 
 
331
 
        length= snprintf(buffer, HUGE_STRING_LENGTH, "%.*s '%s'",
332
 
                         (int)ptr->getLength(), ptr->getString(), key);
333
 
 
334
 
        if (run_query(con, &result, buffer, length))
335
 
        {
336
 
          if ((ptr->getType() == UPDATE_TYPE_REQUIRES_PREFIX) and commit_rate)
337
 
          {
338
 
            // Expand to check to see if Innodb, if so we should restart the
339
 
            // transaction.  
340
 
 
341
 
            is_failed_update= true;
342
 
            failed_update_for_transaction.fetch_and_increment();
343
 
          }
344
 
          else
345
 
          {
346
 
            fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
347
 
                    SLAP_NAME, (uint32_t)length, buffer, drizzle_con_error(&con));
348
 
            abort();
349
 
          }
350
 
        }
351
 
      }
352
 
    }
353
 
    else
354
 
    {
355
 
      if (run_query(con, &result, ptr->getString(), ptr->getLength()))
356
 
      {
357
 
        if ((ptr->getType() == UPDATE_TYPE_REQUIRES_PREFIX) and commit_rate)
358
 
        {
359
 
          // Expand to check to see if Innodb, if so we should restart the
360
 
          // transaction.
361
 
 
362
 
          is_failed_update= true;
363
 
          failed_update_for_transaction.fetch_and_increment();
364
 
        }
365
 
        else
366
 
        {
367
 
          fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
368
 
                  SLAP_NAME, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(&con));
369
 
          abort();
370
 
        }
371
 
      }
372
 
    }
373
 
 
374
 
    if (not opt_only_print and not is_failed_update)
375
 
    {
376
 
      while ((row = drizzle_row_next(&result)))
377
 
        counter++;
378
 
      drizzle_result_free(&result);
379
 
    }
380
 
    queries++;
381
 
 
382
 
    if (commit_rate && (++commit_counter == commit_rate) and not is_failed_update)
383
 
    {
384
 
      commit_counter= 0;
385
 
      run_query(con, NULL, "COMMIT", strlen("COMMIT"));
386
 
    }
387
 
 
388
 
    /* If the timer is set, and the alarm is not active then end */
389
 
    if (opt_timer_length && timer_alarm == false)
390
 
      goto end;
391
 
 
392
 
    /* If limit has been reached, and we are not in a timer_alarm just end */
393
 
    if (ctx->getLimit() && queries == ctx->getLimit() && timer_alarm == false)
394
 
      goto end;
395
 
  }
396
 
 
397
 
  if (opt_timer_length && timer_alarm == true)
398
 
    goto limit_not_met;
399
 
 
400
 
  if (ctx->getLimit() && queries < ctx->getLimit())
401
 
    goto limit_not_met;
402
 
 
403
 
 
404
 
end:
405
 
  if (commit_rate)
406
 
    run_query(con, NULL, "COMMIT", strlen("COMMIT"));
407
 
 
408
 
  slap_close(con);
409
 
 
410
 
  delete ctx;
411
 
}
412
 
 
413
840
/**
414
841
 * commandline_options is the set of all options that can only be called via the command line.
415
842
 
421
848
 
422
849
 * long_options is the union of commandline_options, slap_options and client_options.
423
850
 
424
 
 * There are two configuration files per set of options, one which is defined by the user
425
 
 * which is found at either $XDG_CONFIG_HOME/drizzle or ~/.config/drizzle directory and the other which 
426
 
 * is the system configuration file which is found in the SYSCONFDIR/drizzle directory.
 
851
 * There are two configuration files per set of options, one which is defined by the user and
 
852
 * which is found at ~/.drizzle directory and the other which is the system configuration
 
853
 * file which is found in the SYSCONFDIR/drizzle directory.
427
854
 
428
855
 * The system configuration file is over ridden by the user's configuration file which
429
856
 * in turn is over ridden by the command line.
436
863
    po::options_description commandline_options("Options used only in command line");
437
864
    commandline_options.add_options()
438
865
      ("help,?","Display this help and exit")
439
 
      ("info","Gives information and exit")
 
866
      ("info,i","Gives information and exit")
440
867
      ("burnin",po::value<bool>(&opt_burnin)->default_value(false)->zero_tokens(),
441
868
       "Run full test case in infinite loop")
442
869
      ("ignore-sql-errors", po::value<bool>(&opt_ignore_sql_errors)->default_value(false)->zero_tokens(),
518
945
       "Delay the startup of threads by a random number of microsends (the maximum of the delay")
519
946
      ("delimiter,F",po::value<string>(&delimiter)->default_value("\n"),
520
947
       "Delimiter to use in SQL statements supplied in file or command line")
521
 
      ("engine,e",po::value<string>(&default_engine)->default_value(""),
522
 
       "Storage engine to use for creating the table")
 
948
      ("engine ,e",po::value<string>(&default_engine)->default_value(""),
 
949
       "Storage engien to use for creating the table")
523
950
      ("set-random-seed",
524
951
       po::value<uint32_t>(&opt_set_random_seed)->default_value(0), 
525
952
       "Seed for random number generator (srandom(3)) ") 
531
958
 
532
959
    po::options_description client_options("Options specific to the client");
533
960
    client_options.add_options()
 
961
      ("mysql,m", po::value<bool>(&opt_mysql)->default_value(true)->zero_tokens(),
 
962
       N_("Use MySQL Protocol."))
534
963
      ("host,h",po::value<string>(&host)->default_value("localhost"),"Connect to the host")
535
964
      ("password,P",po::value<char *>(&password),
536
965
       "Password to use when connecting to server. If password is not given it's asked from the tty")
537
966
      ("port,p",po::value<uint32_t>(), "Port number to use for connection")
538
 
      ("protocol",po::value<string>(&opt_protocol)->default_value("mysql"),
539
 
       "The protocol of connection (mysql or drizzle).")
 
967
      ("protocol",po::value<string>(),
 
968
       "The protocol of connection (tcp,socket,pipe,memory).")
540
969
      ("user,u",po::value<string>(&user)->default_value(""),
541
970
       "User for login if not current user")  
542
971
      ;
550
979
    std::string system_config_dir_client(SYSCONFDIR); 
551
980
    system_config_dir_client.append("/drizzle/client.cnf");
552
981
 
553
 
    std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
554
 
 
555
 
    if (user_config_dir.compare(0, 2, "~/") == 0)
556
 
    {
557
 
      char *homedir;
558
 
      homedir= getenv("HOME");
559
 
      if (homedir != NULL)
560
 
        user_config_dir.replace(0, 1, homedir);
561
 
    }
562
 
 
563
982
    uint64_t temp_drizzle_port= 0;
564
 
    boost::scoped_ptr<drizzle_con_st> con_ap(new drizzle_con_st);
565
 
    drizzle_con_st &con= *con_ap.get();
 
983
    drizzle_con_st con;
566
984
    OptionString *eptr;
 
985
    uint32_t x;
567
986
 
568
 
    // Disable allow_guessing
569
 
    int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
570
987
 
571
988
    po::variables_map vm;
572
989
    po::store(po::command_line_parser(argc, argv).options(long_options).
573
 
              style(style).extra_parser(parse_password_arg).run(), vm);
574
 
 
575
 
    std::string user_config_dir_slap(user_config_dir);
576
 
    user_config_dir_slap.append("/drizzle/drizzleslap.cnf"); 
577
 
 
578
 
    std::string user_config_dir_client(user_config_dir);
579
 
    user_config_dir_client.append("/drizzle/client.cnf");
580
 
 
581
 
    ifstream user_slap_ifs(user_config_dir_slap.c_str());
 
990
            extra_parser(parse_password_arg).run(), vm);
 
991
 
 
992
    ifstream user_slap_ifs("~/.drizzle/drizzleslap.cnf");
582
993
    po::store(parse_config_file(user_slap_ifs, slap_options), vm);
583
994
 
584
 
    ifstream user_client_ifs(user_config_dir_client.c_str());
585
 
    po::store(parse_config_file(user_client_ifs, client_options), vm);
586
 
 
587
995
    ifstream system_slap_ifs(system_config_dir_slap.c_str());
588
996
    store(parse_config_file(system_slap_ifs, slap_options), vm);
589
997
 
 
998
    ifstream user_client_ifs("~/.drizzle/client.cnf");
 
999
    po::store(parse_config_file(user_client_ifs, client_options), vm);
 
1000
 
590
1001
    ifstream system_client_ifs(system_config_dir_client.c_str());
591
1002
    store(parse_config_file(system_client_ifs, client_options), vm);
592
1003
 
593
1004
    po::notify(vm);
594
1005
 
595
1006
    if (process_options())
596
 
      abort();
 
1007
      exit(1);
597
1008
 
598
 
    if ( vm.count("help") || vm.count("info"))
 
1009
    if( vm.count("help") || vm.count("info"))
599
1010
    {
600
 
      printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",SLAP_NAME, SLAP_VERSION,
 
1011
      printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname, SLAP_VERSION,
601
1012
          drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
602
1013
      puts("Copyright (C) 2008 Sun Microsystems");
603
 
      puts("This software comes with ABSOLUTELY NO WARRANTY. "
604
 
           "This is free software,\n"
605
 
           "and you are welcome to modify and redistribute it under the GPL "
606
 
           "license\n");
 
1014
      puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\
 
1015
          \nand you are welcome to modify and redistribute it under the GPL \
 
1016
          license\n");
607
1017
      puts("Run a query multiple times against the server\n");
608
 
      cout << long_options << endl;
609
 
      abort();
 
1018
      cout<<long_options<<endl;
 
1019
      exit(0);
610
1020
    }   
611
1021
 
612
 
    if (vm.count("protocol"))
613
 
    {
614
 
      std::transform(opt_protocol.begin(), opt_protocol.end(),
615
 
        opt_protocol.begin(), ::tolower);
616
 
 
617
 
      if (not opt_protocol.compare("mysql"))
618
 
        use_drizzle_protocol=false;
619
 
      else if (not opt_protocol.compare("drizzle"))
620
 
        use_drizzle_protocol=true;
621
 
      else
622
 
      {
623
 
        cout << _("Error: Unknown protocol") << " '" << opt_protocol << "'" << endl;
624
 
        abort();
625
 
      }
626
 
    }
627
 
    if (vm.count("port")) 
 
1022
    if(vm.count("port")) 
628
1023
    {
629
1024
      temp_drizzle_port= vm["port"].as<uint32_t>();
630
1025
 
631
1026
      if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
632
1027
      {
633
1028
        fprintf(stderr, _("Value supplied for port is not valid.\n"));
634
 
        abort();
 
1029
        exit(1);
635
1030
      }
636
1031
      else
637
1032
      {
639
1034
      }
640
1035
    }
641
1036
 
642
 
  if ( vm.count("password") )
 
1037
  if( vm.count("password") )
643
1038
  {
644
 
    if (not opt_password.empty())
 
1039
    if (!opt_password.empty())
645
1040
      opt_password.erase();
646
1041
    if (password == PASSWORD_SENTINEL)
647
1042
    {
660
1055
 
661
1056
 
662
1057
 
663
 
    if ( vm.count("version") )
 
1058
    if( vm.count("version") )
664
1059
    {
665
 
      printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",SLAP_NAME, SLAP_VERSION,
 
1060
      printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname, SLAP_VERSION,
666
1061
          drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
667
 
      abort();
 
1062
      exit(0);
668
1063
    }
669
1064
 
670
1065
    /* Seed the random number generator if we will be using it. */
671
1066
    if (auto_generate_sql)
672
1067
    {
673
1068
      if (opt_set_random_seed == 0)
674
 
        opt_set_random_seed= (uint32_t)time(NULL);
 
1069
        opt_set_random_seed= (unsigned int)time(NULL);
675
1070
      srandom(opt_set_random_seed);
676
1071
    }
677
1072
 
678
1073
    /* globals? Yes, so we only have to run strlen once */
679
1074
    delimiter_length= delimiter.length();
680
1075
 
681
 
    slap_connect(con, false);
 
1076
    slap_connect(&con, false);
 
1077
 
 
1078
    pthread_mutex_init(&counter_mutex, NULL);
 
1079
    pthread_cond_init(&count_threshhold, NULL);
 
1080
    pthread_mutex_init(&sleeper_mutex, NULL);
 
1081
    pthread_cond_init(&sleep_threshhold, NULL);
 
1082
    pthread_mutex_init(&timer_alarm_mutex, NULL);
 
1083
    pthread_cond_init(&timer_alarm_threshold, NULL);
 
1084
 
682
1085
 
683
1086
    /* Main iterations loop */
684
1087
burnin:
691
1094
      if (verbose >= 2)
692
1095
        printf("Starting Concurrency Test\n");
693
1096
 
694
 
      if (concurrency.size())
 
1097
      if (*concurrency)
695
1098
      {
696
 
        for (current= &concurrency[0]; current && *current; current++)
697
 
          concurrency_loop(con, *current, eptr);
 
1099
        for (current= concurrency; current && *current; current++)
 
1100
          concurrency_loop(&con, *current, eptr);
698
1101
      }
699
1102
      else
700
1103
      {
701
1104
        uint32_t infinite= 1;
702
1105
        do {
703
 
          concurrency_loop(con, infinite, eptr);
 
1106
          concurrency_loop(&con, infinite, eptr);
704
1107
        }
705
1108
        while (infinite++);
706
1109
      }
707
1110
 
708
 
      if (not opt_preserve)
709
 
        drop_schema(con, create_schema_string.c_str());
 
1111
      if (!opt_preserve)
 
1112
        drop_schema(&con, create_schema_string.c_str());
710
1113
 
711
1114
    } while (eptr ? (eptr= eptr->getNext()) : 0);
712
1115
 
713
1116
    if (opt_burnin)
714
1117
      goto burnin;
715
1118
 
716
 
    slap_close(con);
 
1119
    pthread_mutex_destroy(&counter_mutex);
 
1120
    pthread_cond_destroy(&count_threshhold);
 
1121
    pthread_mutex_destroy(&sleeper_mutex);
 
1122
    pthread_cond_destroy(&sleep_threshhold);
 
1123
    pthread_mutex_destroy(&timer_alarm_mutex);
 
1124
    pthread_cond_destroy(&timer_alarm_threshold);
 
1125
 
 
1126
    slap_close(&con);
717
1127
 
718
1128
    /* now free all the strings we created */
719
 
    if (not opt_password.empty())
 
1129
    if (!opt_password.empty())
720
1130
      opt_password.erase();
721
1131
 
722
 
    concurrency.clear();
 
1132
    free(concurrency);
723
1133
 
724
1134
    statement_cleanup(create_statements);
725
 
    for (uint32_t x= 0; x < query_statements_count; x++)
 
1135
    for (x= 0; x < query_statements_count; x++)
726
1136
      statement_cleanup(query_statements[x]);
727
 
    query_statements.clear();
 
1137
    free(query_statements);
728
1138
    statement_cleanup(pre_statements);
729
1139
    statement_cleanup(post_statements);
730
1140
    option_cleanup(engine_options);
741
1151
  {
742
1152
    cerr<<"Error:"<<err.what()<<endl;
743
1153
  }
744
 
 
745
 
  if (csv_file != fileno(stdout))
746
 
    close(csv_file);
747
 
 
748
1154
  return 0;
749
1155
}
750
1156
 
751
 
void concurrency_loop(drizzle_con_st &con, uint32_t current, OptionString *eptr)
 
1157
void concurrency_loop(drizzle_con_st *con, uint32_t current, OptionString *eptr)
752
1158
{
 
1159
  unsigned int x;
753
1160
  Stats *head_sptr;
754
1161
  Stats *sptr;
755
1162
  Conclusions conclusion;
756
1163
  uint64_t client_limit;
757
1164
 
758
 
  head_sptr= new Stats[iterations];
 
1165
  head_sptr= (Stats *)malloc(sizeof(Stats) * iterations);
759
1166
  if (head_sptr == NULL)
760
1167
  {
761
1168
    fprintf(stderr,"Error allocating memory in concurrency_loop\n");
762
 
    abort();
 
1169
    exit(1);
763
1170
  }
 
1171
  memset(head_sptr, 0, sizeof(Stats) * iterations);
 
1172
 
 
1173
  memset(&conclusion, 0, sizeof(Conclusions));
764
1174
 
765
1175
  if (auto_actual_queries)
766
1176
    client_limit= auto_actual_queries;
769
1179
  else
770
1180
    client_limit= actual_queries;
771
1181
 
772
 
  uint32_t x;
773
1182
  for (x= 0, sptr= head_sptr; x < iterations; x++, sptr++)
774
1183
  {
775
1184
    /*
793
1202
    if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
794
1203
      generate_primary_key_list(con, eptr);
795
1204
 
796
 
    if (not pre_system.empty())
 
1205
    if (commit_rate)
 
1206
      run_query(con, NULL, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
 
1207
 
 
1208
    if (!pre_system.empty())
797
1209
    {
798
1210
      int ret= system(pre_system.c_str());
799
1211
      assert(ret != -1);
800
1212
    }
 
1213
       
801
1214
 
802
1215
    /*
803
1216
      Pre statements are always run after all other logic so they can
806
1219
    if (pre_statements)
807
1220
      run_statements(con, pre_statements);
808
1221
 
809
 
    run_scheduler(sptr, &query_statements[0], current, client_limit);
 
1222
    run_scheduler(sptr, query_statements, current, client_limit);
810
1223
 
811
1224
    if (post_statements)
812
1225
      run_statements(con, post_statements);
813
1226
 
814
 
    if (not post_system.empty())
 
1227
    if (!post_system.empty())
815
1228
    {
816
1229
      int ret=  system(post_system.c_str());
817
1230
      assert(ret !=-1);
819
1232
 
820
1233
    /* We are finished with this run */
821
1234
    if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
822
 
      primary_keys.clear();
 
1235
      drop_primary_key_list();
823
1236
  }
824
1237
 
825
1238
  if (verbose >= 2)
827
1240
 
828
1241
  generate_stats(&conclusion, eptr, head_sptr);
829
1242
 
830
 
  if (not opt_silent)
831
 
    print_conclusions(conclusion);
832
 
  if (not opt_csv_str.empty())
833
 
    print_conclusions_csv(conclusion);
834
 
 
835
 
  delete [] head_sptr;
 
1243
  if (!opt_silent)
 
1244
    print_conclusions(&conclusion);
 
1245
  if (!opt_csv_str.empty())
 
1246
    print_conclusions_csv(&conclusion);
 
1247
 
 
1248
  free(head_sptr);
 
1249
 
836
1250
}
837
1251
 
838
1252
 
839
 
uint32_t get_random_string(char *buf, size_t size)
 
1253
 
 
1254
uint
 
1255
get_random_string(char *buf, size_t size)
840
1256
{
841
1257
  char *buf_ptr= buf;
 
1258
  size_t x;
842
1259
 
843
 
  for (size_t x= size; x > 0; x--)
 
1260
  for (x= size; x > 0; x--)
844
1261
    *buf_ptr++= ALPHANUMERICS[random() % ALPHANUMERICS_SIZE];
845
1262
  return(buf_ptr - buf);
846
1263
}
856
1273
build_table_string(void)
857
1274
{
858
1275
  char       buf[HUGE_STRING_LENGTH];
859
 
  uint32_t        col_count;
 
1276
  unsigned int        col_count;
860
1277
  Statement *ptr;
861
1278
  string table_string;
862
1279
 
882
1299
 
883
1300
  if (auto_generate_sql_secondary_indexes)
884
1301
  {
885
 
    for (uint32_t count= 0; count < auto_generate_sql_secondary_indexes; count++)
 
1302
    unsigned int count;
 
1303
 
 
1304
    for (count= 0; count < auto_generate_sql_secondary_indexes; count++)
886
1305
    {
887
1306
      if (count) /* Except for the first pass we add a comma */
888
1307
        table_string.append(",");
891
1310
          > HUGE_STRING_LENGTH)
892
1311
      {
893
1312
        fprintf(stderr, "Memory Allocation error in create table\n");
894
 
        abort();
 
1313
        exit(1);
895
1314
      }
896
1315
      table_string.append(buf);
897
1316
    }
909
1328
                     col_count, col_count) > HUGE_STRING_LENGTH)
910
1329
        {
911
1330
          fprintf(stderr, "Memory Allocation error in create table\n");
912
 
          abort();
 
1331
          exit(1);
913
1332
        }
914
1333
      }
915
1334
      else
918
1337
            > HUGE_STRING_LENGTH)
919
1338
        {
920
1339
          fprintf(stderr, "Memory Allocation error in create table\n");
921
 
          abort();
 
1340
          exit(1);
922
1341
        }
923
1342
      }
924
1343
      table_string.append(buf);
937
1356
                     col_count, col_count) > HUGE_STRING_LENGTH)
938
1357
        {
939
1358
          fprintf(stderr, "Memory Allocation error in creating table\n");
940
 
          abort();
 
1359
          exit(1);
941
1360
        }
942
1361
      }
943
1362
      else
946
1365
                     col_count) > HUGE_STRING_LENGTH)
947
1366
        {
948
1367
          fprintf(stderr, "Memory Allocation error in creating table\n");
949
 
          abort();
 
1368
          exit(1);
950
1369
        }
951
1370
      }
952
1371
      table_string.append(buf);
962
1381
                   col_count) > HUGE_STRING_LENGTH)
963
1382
      {
964
1383
        fprintf(stderr, "Memory Allocation error in creating table\n");
965
 
        abort();
 
1384
        exit(1);
966
1385
      }
967
1386
      table_string.append(buf);
968
1387
 
971
1390
    }
972
1391
 
973
1392
  table_string.append(")");
974
 
  ptr= new Statement;
975
 
  ptr->setString(table_string.length());
 
1393
  ptr= (Statement *)malloc(sizeof(Statement));
 
1394
  if (ptr == NULL)
 
1395
  {
 
1396
    fprintf(stderr, "Memory Allocation error in creating table\n");
 
1397
    exit(1);
 
1398
  }
 
1399
  memset(ptr, 0, sizeof(Statement));
 
1400
  ptr->setString((char *)malloc(table_string.length()+1));
976
1401
  if (ptr->getString()==NULL)
977
1402
  {
978
1403
    fprintf(stderr, "Memory Allocation error in creating table\n");
979
 
    abort();
 
1404
    exit(1);
980
1405
  }
 
1406
  memset(ptr->getString(), 0, table_string.length()+1);
 
1407
  ptr->setLength(table_string.length()+1);
981
1408
  ptr->setType(CREATE_TABLE_TYPE);
982
1409
  strcpy(ptr->getString(), table_string.c_str());
983
1410
  return(ptr);
993
1420
build_update_string(void)
994
1421
{
995
1422
  char       buf[HUGE_STRING_LENGTH];
996
 
  uint32_t        col_count;
 
1423
  unsigned int        col_count;
997
1424
  Statement *ptr;
998
1425
  string update_string;
999
1426
 
1008
1435
                   random()) > HUGE_STRING_LENGTH)
1009
1436
      {
1010
1437
        fprintf(stderr, "Memory Allocation error in creating update\n");
1011
 
        abort();
 
1438
        exit(1);
1012
1439
      }
1013
1440
      update_string.append(buf);
1014
1441
 
1027
1454
          > HUGE_STRING_LENGTH)
1028
1455
      {
1029
1456
        fprintf(stderr, "Memory Allocation error in creating update\n");
1030
 
        abort();
 
1457
        exit(1);
1031
1458
      }
1032
1459
      update_string.append(buf);
1033
1460
 
1039
1466
    update_string.append(" WHERE id = ");
1040
1467
 
1041
1468
 
1042
 
  ptr= new Statement;
 
1469
  ptr= (Statement *)malloc(sizeof(Statement));
 
1470
  if (ptr == NULL)
 
1471
  {
 
1472
    fprintf(stderr, "Memory Allocation error in creating update\n");
 
1473
    exit(1);
 
1474
  }
 
1475
  memset(ptr, 0, sizeof(Statement));
1043
1476
 
1044
 
  ptr->setString(update_string.length());
 
1477
  ptr->setLength(update_string.length()+1);
 
1478
  ptr->setString((char *)malloc(ptr->getLength()));
1045
1479
  if (ptr->getString() == NULL)
1046
1480
  {
1047
1481
    fprintf(stderr, "Memory Allocation error in creating update\n");
1048
 
    abort();
 
1482
    exit(1);
1049
1483
  }
 
1484
  memset(ptr->getString(), 0, ptr->getLength());
1050
1485
  if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
1051
1486
    ptr->setType(UPDATE_TYPE_REQUIRES_PREFIX);
1052
1487
  else
1066
1501
build_insert_string(void)
1067
1502
{
1068
1503
  char       buf[HUGE_STRING_LENGTH];
1069
 
  uint32_t        col_count;
 
1504
  unsigned int        col_count;
1070
1505
  Statement *ptr;
1071
1506
  string insert_string;
1072
1507
 
1092
1527
 
1093
1528
  if (auto_generate_sql_secondary_indexes)
1094
1529
  {
1095
 
    uint32_t count;
 
1530
    unsigned int count;
1096
1531
 
1097
1532
    for (count= 0; count < auto_generate_sql_secondary_indexes; count++)
1098
1533
    {
1112
1547
      if (snprintf(buf, HUGE_STRING_LENGTH, "%ld", random()) > HUGE_STRING_LENGTH)
1113
1548
      {
1114
1549
        fprintf(stderr, "Memory Allocation error in creating insert\n");
1115
 
        abort();
 
1550
        exit(1);
1116
1551
      }
1117
1552
      insert_string.append(buf);
1118
1553
 
1134
1569
 
1135
1570
  if (num_blob_cols)
1136
1571
  {
1137
 
    vector <char> blob_ptr;
 
1572
    char *blob_ptr;
1138
1573
 
1139
 
    blob_ptr.resize(num_blob_cols_size);
 
1574
    if (num_blob_cols_size > HUGE_STRING_LENGTH)
 
1575
    {
 
1576
      blob_ptr= (char *)malloc(sizeof(char)*num_blob_cols_size);
 
1577
      if (!blob_ptr)
 
1578
      {
 
1579
        fprintf(stderr, "Memory Allocation error in creating select\n");
 
1580
        exit(1);
 
1581
      }
 
1582
      memset(blob_ptr, 0, sizeof(char)*num_blob_cols_size);
 
1583
    }
 
1584
    else
 
1585
    {
 
1586
      blob_ptr= buf;
 
1587
    }
1140
1588
 
1141
1589
    for (col_count= 1; col_count <= num_blob_cols; col_count++)
1142
1590
    {
1143
 
      uint32_t buf_len;
1144
 
      uint32_t size;
1145
 
      uint32_t difference= num_blob_cols_size - num_blob_cols_size_min;
 
1591
      unsigned int buf_len;
 
1592
      unsigned int size;
 
1593
      unsigned int difference= num_blob_cols_size - num_blob_cols_size_min;
1146
1594
 
1147
1595
      size= difference ? (num_blob_cols_size_min + (random() % difference)) :
1148
1596
        num_blob_cols_size;
1149
1597
 
1150
 
      buf_len= get_random_string(&blob_ptr[0], size);
 
1598
      buf_len= get_random_string(blob_ptr, size);
1151
1599
 
1152
1600
      insert_string.append("'", 1);
1153
 
      insert_string.append(&blob_ptr[0], buf_len);
 
1601
      insert_string.append(blob_ptr, buf_len);
1154
1602
      insert_string.append("'", 1);
1155
1603
 
1156
1604
      if (col_count < num_blob_cols)
1157
1605
        insert_string.append(",", 1);
1158
1606
    }
 
1607
 
 
1608
    if (num_blob_cols_size > HUGE_STRING_LENGTH)
 
1609
      free(blob_ptr);
1159
1610
  }
1160
1611
 
1161
1612
  insert_string.append(")", 1);
1162
1613
 
1163
 
  ptr= new Statement;
1164
 
  ptr->setString(insert_string.length());
 
1614
  if (!(ptr= (Statement *)malloc(sizeof(Statement))))
 
1615
  {
 
1616
    fprintf(stderr, "Memory Allocation error in creating select\n");
 
1617
    exit(1);
 
1618
  }
 
1619
  memset(ptr, 0, sizeof(Statement));
 
1620
  ptr->setLength(insert_string.length()+1);
 
1621
  ptr->setString((char *)malloc(ptr->getLength()));
1165
1622
  if (ptr->getString()==NULL)
1166
1623
  {
1167
1624
    fprintf(stderr, "Memory Allocation error in creating select\n");
1168
 
    abort();
 
1625
    exit(1);
1169
1626
  }
 
1627
  memset(ptr->getString(), 0, ptr->getLength());
1170
1628
  ptr->setType(INSERT_TYPE);
1171
1629
  strcpy(ptr->getString(), insert_string.c_str());
1172
1630
  return(ptr);
1183
1641
build_select_string(bool key)
1184
1642
{
1185
1643
  char       buf[HUGE_STRING_LENGTH];
1186
 
  uint32_t        col_count;
 
1644
  unsigned int        col_count;
1187
1645
  Statement *ptr;
1188
1646
  string query_string;
1189
1647
 
1190
1648
  query_string.reserve(HUGE_STRING_LENGTH);
1191
1649
 
1192
1650
  query_string.append("SELECT ", 7);
1193
 
  if (not auto_generate_selected_columns_opt.empty())
 
1651
  if (!auto_generate_selected_columns_opt.empty())
1194
1652
  {
1195
1653
    query_string.append(auto_generate_selected_columns_opt.c_str());
1196
1654
  }
1202
1660
          > HUGE_STRING_LENGTH)
1203
1661
      {
1204
1662
        fprintf(stderr, "Memory Allocation error in creating select\n");
1205
 
        abort();
 
1663
        exit(1);
1206
1664
      }
1207
1665
      query_string.append(buf);
1208
1666
 
1216
1674
          > HUGE_STRING_LENGTH)
1217
1675
      {
1218
1676
        fprintf(stderr, "Memory Allocation error in creating select\n");
1219
 
        abort();
 
1677
        exit(1);
1220
1678
      }
1221
1679
      query_string.append(buf);
1222
1680
 
1230
1688
          > HUGE_STRING_LENGTH)
1231
1689
      {
1232
1690
        fprintf(stderr, "Memory Allocation error in creating select\n");
1233
 
        abort();
 
1691
        exit(1);
1234
1692
      }
1235
1693
      query_string.append(buf);
1236
1694
 
1244
1702
      (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary))
1245
1703
    query_string.append(" WHERE id = ");
1246
1704
 
1247
 
  ptr= new Statement;
1248
 
  ptr->setString(query_string.length());
 
1705
  ptr= (Statement *)malloc(sizeof(Statement));
 
1706
  if (ptr == NULL)
 
1707
  {
 
1708
    fprintf(stderr, "Memory Allocation error in creating select\n");
 
1709
    exit(1);
 
1710
  }
 
1711
  memset(ptr, 0, sizeof(Statement));
 
1712
  ptr->setLength(query_string.length()+1);
 
1713
  ptr->setString((char *)malloc(ptr->getLength()));
1249
1714
  if (ptr->getString() == NULL)
1250
1715
  {
1251
1716
    fprintf(stderr, "Memory Allocation error in creating select\n");
1252
 
    abort();
 
1717
    exit(1);
1253
1718
  }
 
1719
  memset(ptr->getString(), 0, ptr->getLength());
1254
1720
  if ((key) &&
1255
1721
      (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary))
1256
1722
    ptr->setType(SELECT_TYPE_REQUIRES_PREFIX);
1263
1729
static int
1264
1730
process_options(void)
1265
1731
{
 
1732
  char *tmp_string;
1266
1733
  struct stat sbuf;
1267
1734
  OptionString *sql_type;
1268
 
  uint32_t sql_type_count= 0;
 
1735
  unsigned int sql_type_count= 0;
1269
1736
  ssize_t bytes_read= 0;
1270
1737
  
1271
1738
  if (user.empty())
1274
1741
  verbose= opt_verbose.length();
1275
1742
 
1276
1743
  /* If something is created we clean it up, otherwise we leave schemas alone */
1277
 
  if ( (not create_string.empty()) || auto_generate_sql)
 
1744
  if ( (!create_string.empty()) || auto_generate_sql)
1278
1745
    opt_preserve= false;
1279
1746
 
1280
 
  if (auto_generate_sql && (not create_string.empty() || !user_supplied_query.empty()))
 
1747
  if (auto_generate_sql && (!create_string.empty() || !user_supplied_query.empty()))
1281
1748
  {
1282
1749
    fprintf(stderr,
1283
1750
            "%s: Can't use --auto-generate-sql when create and query strings are specified!\n",
1284
 
            SLAP_NAME);
1285
 
    abort();
 
1751
            internal::my_progname);
 
1752
    exit(1);
1286
1753
  }
1287
1754
 
1288
1755
  if (auto_generate_sql && auto_generate_sql_guid_primary &&
1290
1757
  {
1291
1758
    fprintf(stderr,
1292
1759
            "%s: Either auto-generate-sql-guid-primary or auto-generate-sql-add-autoincrement can be used!\n",
1293
 
            SLAP_NAME);
1294
 
    abort();
 
1760
            internal::my_progname);
 
1761
    exit(1);
1295
1762
  }
1296
1763
 
1297
1764
  if (auto_generate_sql && num_of_query && auto_actual_queries)
1298
1765
  {
1299
1766
    fprintf(stderr,
1300
1767
            "%s: Either auto-generate-sql-execute-number or number-of-queries can be used!\n",
1301
 
            SLAP_NAME);
1302
 
    abort();
 
1768
            internal::my_progname);
 
1769
    exit(1);
1303
1770
  }
1304
1771
 
1305
 
  parse_comma(not concurrency_str.empty() ? concurrency_str.c_str() : "1", concurrency);
 
1772
  parse_comma(!concurrency_str.empty() ? concurrency_str.c_str() : "1", &concurrency);
1306
1773
 
1307
 
  if (not opt_csv_str.empty())
 
1774
  if (!opt_csv_str.empty())
1308
1775
  {
1309
1776
    opt_silent= true;
1310
1777
 
1318
1785
                          S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1)
1319
1786
      {
1320
1787
        fprintf(stderr,"%s: Could not open csv file: %sn\n",
1321
 
                SLAP_NAME, opt_csv_str.c_str());
1322
 
        abort();
 
1788
                internal::my_progname, opt_csv_str.c_str());
 
1789
        exit(1);
1323
1790
      }
1324
1791
    }
1325
1792
  }
1327
1794
  if (opt_only_print)
1328
1795
    opt_silent= true;
1329
1796
 
1330
 
  if (not num_int_cols_opt.empty())
 
1797
  if (!num_int_cols_opt.empty())
1331
1798
  {
1332
1799
    OptionString *str;
1333
1800
    parse_option(num_int_cols_opt.c_str(), &str, ',');
1337
1804
    option_cleanup(str);
1338
1805
  }
1339
1806
 
1340
 
  if (not num_char_cols_opt.empty())
 
1807
  if (!num_char_cols_opt.empty())
1341
1808
  {
1342
1809
    OptionString *str;
1343
1810
    parse_option(num_char_cols_opt.c_str(), &str, ',');
1349
1816
    option_cleanup(str);
1350
1817
  }
1351
1818
 
1352
 
  if (not num_blob_cols_opt.empty())
 
1819
  if (!num_blob_cols_opt.empty())
1353
1820
  {
1354
1821
    OptionString *str;
1355
1822
    parse_option(num_blob_cols_opt.c_str(), &str, ',');
1405
1872
    query_statements_count=
1406
1873
      parse_option(opt_auto_generate_sql_type.c_str(), &query_options, ',');
1407
1874
 
1408
 
    query_statements.resize(query_statements_count);
 
1875
    query_statements= (Statement **)malloc(sizeof(Statement *) * query_statements_count);
 
1876
    if (query_statements == NULL)
 
1877
    {
 
1878
      fprintf(stderr, "Memory Allocation error in Building Query Statements\n");
 
1879
      exit(1);
 
1880
    }
 
1881
    memset(query_statements, 0, sizeof(Statement *) * query_statements_count);
1409
1882
 
1410
1883
    sql_type= query_options;
1411
1884
    do
1433
1906
        {
1434
1907
          fprintf(stderr,
1435
1908
                  "%s: Can't perform key test without a primary key!\n",
1436
 
                  SLAP_NAME);
1437
 
          abort();
 
1909
                  internal::my_progname);
 
1910
          exit(1);
1438
1911
        }
1439
1912
 
1440
1913
        query_statements[sql_type_count]= build_select_string(true);
1469
1942
        {
1470
1943
          fprintf(stderr,
1471
1944
                  "%s: Can't perform update test without a primary key!\n",
1472
 
                  SLAP_NAME);
1473
 
          abort();
 
1945
                  internal::my_progname);
 
1946
          exit(1);
1474
1947
        }
1475
1948
 
1476
1949
        query_statements[sql_type_count]= build_update_string();
1511
1984
  }
1512
1985
  else
1513
1986
  {
1514
 
    if (not create_string.empty() && !stat(create_string.c_str(), &sbuf))
 
1987
    if (!create_string.empty() && !stat(create_string.c_str(), &sbuf))
1515
1988
    {
1516
1989
      int data_file;
1517
 
      std::vector<char> tmp_string;
1518
 
      if (not S_ISREG(sbuf.st_mode))
 
1990
      if (!S_ISREG(sbuf.st_mode))
1519
1991
      {
1520
1992
        fprintf(stderr,"%s: Create file was not a regular file\n",
1521
 
                SLAP_NAME);
1522
 
        abort();
 
1993
                internal::my_progname);
 
1994
        exit(1);
1523
1995
      }
1524
1996
      if ((data_file= open(create_string.c_str(), O_RDWR)) == -1)
1525
1997
      {
1526
 
        fprintf(stderr,"%s: Could not open create file\n", SLAP_NAME);
1527
 
        abort();
 
1998
        fprintf(stderr,"%s: Could not open create file\n", internal::my_progname);
 
1999
        exit(1);
1528
2000
      }
1529
2001
      if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1530
2002
      {
1531
2003
        fprintf(stderr, "Request for more memory than architecture supports\n");
1532
 
        abort();
1533
 
      }
1534
 
      tmp_string.resize(sbuf.st_size + 1);
1535
 
      bytes_read= read(data_file, (unsigned char*) &tmp_string[0],
 
2004
        exit(1);
 
2005
      }
 
2006
      tmp_string= (char *)malloc((size_t)(sbuf.st_size + 1));
 
2007
      if (tmp_string == NULL)
 
2008
      {
 
2009
        fprintf(stderr, "Memory Allocation error in option processing\n");
 
2010
        exit(1);
 
2011
      }
 
2012
      memset(tmp_string, 0, (size_t)(sbuf.st_size + 1));
 
2013
      bytes_read= read(data_file, (unsigned char*) tmp_string,
1536
2014
                       (size_t)sbuf.st_size);
 
2015
      tmp_string[sbuf.st_size]= '\0';
1537
2016
      close(data_file);
1538
2017
      if (bytes_read != sbuf.st_size)
1539
2018
      {
1540
2019
        fprintf(stderr, "Problem reading file: read less bytes than requested\n");
1541
2020
      }
1542
 
      parse_delimiter(&tmp_string[0], &create_statements, delimiter[0]);
 
2021
      parse_delimiter(tmp_string, &create_statements, delimiter[0]);
 
2022
      free(tmp_string);
1543
2023
    }
1544
 
    else if (not create_string.empty())
 
2024
    else if (!create_string.empty())
1545
2025
    {
1546
2026
      parse_delimiter(create_string.c_str(), &create_statements, delimiter[0]);
1547
2027
    }
1548
2028
 
1549
2029
    /* Set this up till we fully support options on user generated queries */
1550
 
    if (not user_supplied_query.empty())
 
2030
    if (!user_supplied_query.empty())
1551
2031
    {
1552
2032
      query_statements_count=
1553
2033
        parse_option("default", &query_options, ',');
1554
2034
 
1555
 
      query_statements.resize(query_statements_count);
 
2035
      query_statements= (Statement **)malloc(sizeof(Statement *) * query_statements_count);
 
2036
      if (query_statements == NULL)
 
2037
      {
 
2038
        fprintf(stderr, "Memory Allocation error in option processing\n");
 
2039
        exit(1);
 
2040
      }
 
2041
      memset(query_statements, 0, sizeof(Statement *) * query_statements_count); 
1556
2042
    }
1557
2043
 
1558
 
    if (not user_supplied_query.empty() && !stat(user_supplied_query.c_str(), &sbuf))
 
2044
    if (!user_supplied_query.empty() && !stat(user_supplied_query.c_str(), &sbuf))
1559
2045
    {
1560
2046
      int data_file;
1561
 
      std::vector<char> tmp_string;
1562
 
 
1563
 
      if (not S_ISREG(sbuf.st_mode))
 
2047
      if (!S_ISREG(sbuf.st_mode))
1564
2048
      {
1565
2049
        fprintf(stderr,"%s: User query supplied file was not a regular file\n",
1566
 
                SLAP_NAME);
1567
 
        abort();
 
2050
                internal::my_progname);
 
2051
        exit(1);
1568
2052
      }
1569
2053
      if ((data_file= open(user_supplied_query.c_str(), O_RDWR)) == -1)
1570
2054
      {
1571
 
        fprintf(stderr,"%s: Could not open query supplied file\n", SLAP_NAME);
1572
 
        abort();
 
2055
        fprintf(stderr,"%s: Could not open query supplied file\n", internal::my_progname);
 
2056
        exit(1);
1573
2057
      }
1574
2058
      if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1575
2059
      {
1576
2060
        fprintf(stderr, "Request for more memory than architecture supports\n");
1577
 
        abort();
1578
 
      }
1579
 
      tmp_string.resize((size_t)(sbuf.st_size + 1));
1580
 
      bytes_read= read(data_file, (unsigned char*) &tmp_string[0],
 
2061
        exit(1);
 
2062
      }
 
2063
      tmp_string= (char *)malloc((size_t)(sbuf.st_size + 1));
 
2064
      if (tmp_string == NULL)
 
2065
      {
 
2066
        fprintf(stderr, "Memory Allocation error in option processing\n");
 
2067
        exit(1);
 
2068
      }
 
2069
      memset(tmp_string, 0, (size_t)(sbuf.st_size + 1));
 
2070
      bytes_read= read(data_file, (unsigned char*) tmp_string,
1581
2071
                       (size_t)sbuf.st_size);
 
2072
      tmp_string[sbuf.st_size]= '\0';
1582
2073
      close(data_file);
1583
2074
      if (bytes_read != sbuf.st_size)
1584
2075
      {
1585
2076
        fprintf(stderr, "Problem reading file: read less bytes than requested\n");
1586
2077
      }
1587
 
      if (not user_supplied_query.empty())
1588
 
        actual_queries= parse_delimiter(&tmp_string[0], &query_statements[0],
 
2078
      if (!user_supplied_query.empty())
 
2079
        actual_queries= parse_delimiter(tmp_string, &query_statements[0],
1589
2080
                                        delimiter[0]);
 
2081
      free(tmp_string);
1590
2082
    }
1591
 
    else if (not user_supplied_query.empty())
 
2083
    else if (!user_supplied_query.empty())
1592
2084
    {
1593
2085
      actual_queries= parse_delimiter(user_supplied_query.c_str(), &query_statements[0],
1594
2086
                                      delimiter[0]);
1595
2087
    }
1596
2088
  }
1597
2089
 
1598
 
  if (not user_supplied_pre_statements.empty()
 
2090
  if (!user_supplied_pre_statements.empty()
1599
2091
      && !stat(user_supplied_pre_statements.c_str(), &sbuf))
1600
2092
  {
1601
2093
    int data_file;
1602
 
    std::vector<char> tmp_string;
1603
 
 
1604
 
    if (not S_ISREG(sbuf.st_mode))
 
2094
    if (!S_ISREG(sbuf.st_mode))
1605
2095
    {
1606
2096
      fprintf(stderr,"%s: User query supplied file was not a regular file\n",
1607
 
              SLAP_NAME);
1608
 
      abort();
 
2097
              internal::my_progname);
 
2098
      exit(1);
1609
2099
    }
1610
2100
    if ((data_file= open(user_supplied_pre_statements.c_str(), O_RDWR)) == -1)
1611
2101
    {
1612
 
      fprintf(stderr,"%s: Could not open query supplied file\n", SLAP_NAME);
1613
 
      abort();
 
2102
      fprintf(stderr,"%s: Could not open query supplied file\n", internal::my_progname);
 
2103
      exit(1);
1614
2104
    }
1615
2105
    if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1616
2106
    {
1617
2107
      fprintf(stderr, "Request for more memory than architecture supports\n");
1618
 
      abort();
1619
 
    }
1620
 
    tmp_string.resize((size_t)(sbuf.st_size + 1));
1621
 
    bytes_read= read(data_file, (unsigned char*) &tmp_string[0],
 
2108
      exit(1);
 
2109
    }
 
2110
    tmp_string= (char *)malloc((size_t)(sbuf.st_size + 1));
 
2111
    if (tmp_string == NULL)
 
2112
    {
 
2113
      fprintf(stderr, "Memory Allocation error in option processing\n");
 
2114
      exit(1);
 
2115
    }
 
2116
    memset(tmp_string, 0, (size_t)(sbuf.st_size + 1));
 
2117
    bytes_read= read(data_file, (unsigned char*) tmp_string,
1622
2118
                     (size_t)sbuf.st_size);
 
2119
    tmp_string[sbuf.st_size]= '\0';
1623
2120
    close(data_file);
1624
2121
    if (bytes_read != sbuf.st_size)
1625
2122
    {
1626
2123
      fprintf(stderr, "Problem reading file: read less bytes than requested\n");
1627
2124
    }
1628
 
    if (not user_supplied_pre_statements.empty())
1629
 
      (void)parse_delimiter(&tmp_string[0], &pre_statements,
 
2125
    if (!user_supplied_pre_statements.empty())
 
2126
      (void)parse_delimiter(tmp_string, &pre_statements,
1630
2127
                            delimiter[0]);
 
2128
    free(tmp_string);
1631
2129
  }
1632
 
  else if (not user_supplied_pre_statements.empty())
 
2130
  else if (!user_supplied_pre_statements.empty())
1633
2131
  {
1634
2132
    (void)parse_delimiter(user_supplied_pre_statements.c_str(),
1635
2133
                          &pre_statements,
1636
2134
                          delimiter[0]);
1637
2135
  }
1638
2136
 
1639
 
  if (not user_supplied_post_statements.empty()
 
2137
  if (!user_supplied_post_statements.empty()
1640
2138
      && !stat(user_supplied_post_statements.c_str(), &sbuf))
1641
2139
  {
1642
2140
    int data_file;
1643
 
    std::vector<char> tmp_string;
1644
 
 
1645
 
    if (not S_ISREG(sbuf.st_mode))
 
2141
    if (!S_ISREG(sbuf.st_mode))
1646
2142
    {
1647
2143
      fprintf(stderr,"%s: User query supplied file was not a regular file\n",
1648
 
              SLAP_NAME);
1649
 
      abort();
 
2144
              internal::my_progname);
 
2145
      exit(1);
1650
2146
    }
1651
2147
    if ((data_file= open(user_supplied_post_statements.c_str(), O_RDWR)) == -1)
1652
2148
    {
1653
 
      fprintf(stderr,"%s: Could not open query supplied file\n", SLAP_NAME);
1654
 
      abort();
 
2149
      fprintf(stderr,"%s: Could not open query supplied file\n", internal::my_progname);
 
2150
      exit(1);
1655
2151
    }
1656
2152
 
1657
2153
    if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1658
2154
    {
1659
2155
      fprintf(stderr, "Request for more memory than architecture supports\n");
1660
 
      abort();
1661
 
    }
1662
 
    tmp_string.resize((size_t)(sbuf.st_size + 1));
 
2156
      exit(1);
 
2157
    }
 
2158
    tmp_string= (char *)malloc((size_t)(sbuf.st_size + 1));
 
2159
    if (tmp_string == NULL)
 
2160
    {
 
2161
      fprintf(stderr, "Memory Allocation error in option processing\n");
 
2162
      exit(1);
 
2163
    }
 
2164
    memset(tmp_string, 0, (size_t)(sbuf.st_size+1));
1663
2165
 
1664
 
    bytes_read= read(data_file, (unsigned char*) &tmp_string[0],
 
2166
    bytes_read= read(data_file, (unsigned char*) tmp_string,
1665
2167
                     (size_t)(sbuf.st_size));
 
2168
    tmp_string[sbuf.st_size]= '\0';
1666
2169
    close(data_file);
1667
2170
    if (bytes_read != sbuf.st_size)
1668
2171
    {
1669
2172
      fprintf(stderr, "Problem reading file: read less bytes than requested\n");
1670
2173
    }
1671
 
    if (not user_supplied_post_statements.empty())
1672
 
      (void)parse_delimiter(&tmp_string[0], &post_statements,
 
2174
    if (!user_supplied_post_statements.empty())
 
2175
      (void)parse_delimiter(tmp_string, &post_statements,
1673
2176
                            delimiter[0]);
 
2177
    free(tmp_string);
1674
2178
  }
1675
 
  else if (not user_supplied_post_statements.empty())
 
2179
  else if (!user_supplied_post_statements.empty())
1676
2180
  {
1677
2181
    (void)parse_delimiter(user_supplied_post_statements.c_str(), &post_statements,
1678
2182
                          delimiter[0]);
1681
2185
  if (verbose >= 2)
1682
2186
    printf("Parsing engines to use.\n");
1683
2187
 
1684
 
  if (not default_engine.empty())
 
2188
  if (!default_engine.empty())
1685
2189
    parse_option(default_engine.c_str(), &engine_options, ',');
1686
2190
 
1687
2191
  if (tty_password)
1690
2194
}
1691
2195
 
1692
2196
 
1693
 
static int run_query(drizzle_con_st &con, drizzle_result_st *result,
 
2197
static int run_query(drizzle_con_st *con, drizzle_result_st *result,
1694
2198
                     const char *query, int len)
1695
2199
{
1696
2200
  drizzle_return_t ret;
1698
2202
 
1699
2203
  if (opt_only_print)
1700
2204
  {
1701
 
    printf("/* CON: %" PRIu64 " */ %.*s;\n",
1702
 
           (uint64_t)drizzle_context(drizzle_con_drizzle(&con)),
1703
 
           len, query);
 
2205
    printf("%.*s;\n", len, query);
1704
2206
    return 0;
1705
2207
  }
1706
2208
 
1710
2212
  if (result == NULL)
1711
2213
    result= &result_buffer;
1712
2214
 
1713
 
  result= drizzle_query(&con, result, query, len, &ret);
 
2215
  result= drizzle_query(con, result, query, len, &ret);
1714
2216
 
1715
2217
  if (ret == DRIZZLE_RETURN_OK)
1716
2218
    ret= drizzle_result_buffer(result);
1723
2225
 
1724
2226
 
1725
2227
static int
1726
 
generate_primary_key_list(drizzle_con_st &con, OptionString *engine_stmt)
 
2228
generate_primary_key_list(drizzle_con_st *con, OptionString *engine_stmt)
1727
2229
{
1728
2230
  drizzle_result_st result;
1729
2231
  drizzle_row_t row;
1737
2239
  if (opt_only_print || (engine_stmt &&
1738
2240
                         strstr(engine_stmt->getString(), "blackhole")))
1739
2241
  {
 
2242
    primary_keys_number_of= 1;
 
2243
    primary_keys= (char **)malloc((sizeof(char *) *
 
2244
                                  primary_keys_number_of));
 
2245
    if (primary_keys == NULL)
 
2246
    {
 
2247
      fprintf(stderr, "Memory Allocation error in option processing\n");
 
2248
      exit(1);
 
2249
    }
 
2250
    
 
2251
    memset(primary_keys, 0, (sizeof(char *) * primary_keys_number_of));
1740
2252
    /* Yes, we strdup a const string to simplify the interface */
1741
 
    primary_keys.push_back("796c4422-1d94-102a-9d6d-00e0812d");
 
2253
    primary_keys[0]= strdup("796c4422-1d94-102a-9d6d-00e0812d");
 
2254
    if (primary_keys[0] == NULL)
 
2255
    {
 
2256
      fprintf(stderr, "Memory Allocation error in option processing\n");
 
2257
      exit(1);
 
2258
    }
1742
2259
  }
1743
2260
  else
1744
2261
  {
1745
2262
    if (run_query(con, &result, "SELECT id from t1", strlen("SELECT id from t1")))
1746
2263
    {
1747
 
      fprintf(stderr,"%s: Cannot select GUID primary keys. (%s)\n", SLAP_NAME,
1748
 
              drizzle_con_error(&con));
1749
 
      abort();
 
2264
      fprintf(stderr,"%s: Cannot select GUID primary keys. (%s)\n", internal::my_progname,
 
2265
              drizzle_con_error(con));
 
2266
      exit(1);
1750
2267
    }
1751
2268
 
1752
2269
    uint64_t num_rows_ret= drizzle_result_row_count(&result);
1753
2270
    if (num_rows_ret > SIZE_MAX)
1754
2271
    {
1755
2272
      fprintf(stderr, "More primary keys than than architecture supports\n");
1756
 
      abort();
 
2273
      exit(1);
1757
2274
    }
1758
 
    size_t primary_keys_number_of;
1759
2275
    primary_keys_number_of= (size_t)num_rows_ret;
1760
2276
 
1761
2277
    /* So why check this? Blackhole :) */
1764
2280
      /*
1765
2281
        We create the structure and loop and create the items.
1766
2282
      */
 
2283
      primary_keys= (char **)malloc(sizeof(char *) *
 
2284
                                    primary_keys_number_of);
 
2285
      if (primary_keys == NULL)
 
2286
      {
 
2287
        fprintf(stderr, "Memory Allocation error in option processing\n");
 
2288
        exit(1);
 
2289
      }
 
2290
      memset(primary_keys, 0, (size_t)(sizeof(char *) * primary_keys_number_of));
1767
2291
      row= drizzle_row_next(&result);
1768
2292
      for (counter= 0; counter < primary_keys_number_of;
1769
2293
           counter++, row= drizzle_row_next(&result))
1770
2294
      {
1771
 
        primary_keys.push_back(row[0]);
 
2295
        primary_keys[counter]= strdup(row[0]);
 
2296
        if (primary_keys[counter] == NULL)
 
2297
        {
 
2298
          fprintf(stderr, "Memory Allocation error in option processing\n");
 
2299
          exit(1);
 
2300
        }
1772
2301
      }
1773
2302
    }
1774
2303
 
1778
2307
  return(0);
1779
2308
}
1780
2309
 
1781
 
static void create_schema(drizzle_con_st &con, const char *db, Statement *stmt, OptionString *engine_stmt, Stats *sptr)
 
2310
static int
 
2311
drop_primary_key_list(void)
 
2312
{
 
2313
  uint64_t counter;
 
2314
 
 
2315
  if (primary_keys_number_of)
 
2316
  {
 
2317
    for (counter= 0; counter < primary_keys_number_of; counter++)
 
2318
      free(primary_keys[counter]);
 
2319
 
 
2320
    free(primary_keys);
 
2321
  }
 
2322
 
 
2323
  return 0;
 
2324
}
 
2325
 
 
2326
static int
 
2327
create_schema(drizzle_con_st *con, const char *db, Statement *stmt,
 
2328
              OptionString *engine_stmt, Stats *sptr)
1782
2329
{
1783
2330
  char query[HUGE_STRING_LENGTH];
1784
2331
  Statement *ptr;
1785
2332
  Statement *after_create;
1786
2333
  int len;
 
2334
  uint64_t count;
1787
2335
  struct timeval start_time, end_time;
1788
2336
 
1789
2337
 
1796
2344
 
1797
2345
  if (run_query(con, NULL, query, len))
1798
2346
  {
1799
 
    fprintf(stderr,"%s: Cannot create schema %s : %s\n", SLAP_NAME, db,
1800
 
            drizzle_con_error(&con));
1801
 
    abort();
 
2347
    fprintf(stderr,"%s: Cannot create schema %s : %s\n", internal::my_progname, db,
 
2348
            drizzle_con_error(con));
 
2349
    exit(1);
1802
2350
  }
1803
2351
  else
1804
2352
  {
1807
2355
 
1808
2356
  if (opt_only_print)
1809
2357
  {
1810
 
    printf("/* CON: %" PRIu64 " */ use %s;\n",
1811
 
           (uint64_t)drizzle_context(drizzle_con_drizzle(&con)),
1812
 
           db);
 
2358
    printf("use %s;\n", db);
1813
2359
  }
1814
2360
  else
1815
2361
  {
1819
2365
    if (verbose >= 3)
1820
2366
      printf("%s;\n", query);
1821
2367
 
1822
 
    if (drizzle_select_db(&con,  &result, db, &ret) == NULL ||
 
2368
    if (drizzle_select_db(con,  &result, db, &ret) == NULL ||
1823
2369
        ret != DRIZZLE_RETURN_OK)
1824
2370
    {
1825
 
      fprintf(stderr,"%s: Cannot select schema '%s': %s\n",SLAP_NAME, db,
 
2371
      fprintf(stderr,"%s: Cannot select schema '%s': %s\n",internal::my_progname, db,
1826
2372
              ret == DRIZZLE_RETURN_ERROR_CODE ?
1827
 
              drizzle_result_error(&result) : drizzle_con_error(&con));
1828
 
      abort();
 
2373
              drizzle_result_error(&result) : drizzle_con_error(con));
 
2374
      exit(1);
1829
2375
    }
1830
2376
    drizzle_result_free(&result);
1831
2377
    sptr->setCreateCount(sptr->getCreateCount()+1);
1837
2383
                  engine_stmt->getString());
1838
2384
    if (run_query(con, NULL, query, len))
1839
2385
    {
1840
 
      fprintf(stderr,"%s: Cannot set default engine: %s\n", SLAP_NAME,
1841
 
              drizzle_con_error(&con));
1842
 
      abort();
 
2386
      fprintf(stderr,"%s: Cannot set default engine: %s\n", internal::my_progname,
 
2387
              drizzle_con_error(con));
 
2388
      exit(1);
1843
2389
    }
1844
2390
    sptr->setCreateCount(sptr->getCreateCount()+1);
1845
2391
  }
1846
2392
 
1847
 
  uint64_t count= 0;
 
2393
  count= 0;
1848
2394
  after_create= stmt;
1849
2395
 
1850
2396
limit_not_met:
1862
2408
      if (run_query(con, NULL, buffer, strlen(buffer)))
1863
2409
      {
1864
2410
        fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
1865
 
                SLAP_NAME, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(&con));
1866
 
        if (not opt_ignore_sql_errors)
1867
 
          abort();
 
2411
                internal::my_progname, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(con));
 
2412
        if (!opt_ignore_sql_errors)
 
2413
          exit(1);
1868
2414
      }
1869
2415
      sptr->setCreateCount(sptr->getCreateCount()+1);
1870
2416
    }
1873
2419
      if (run_query(con, NULL, ptr->getString(), ptr->getLength()))
1874
2420
      {
1875
2421
        fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
1876
 
                SLAP_NAME, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(&con));
1877
 
        if (not opt_ignore_sql_errors)
1878
 
          abort();
 
2422
                internal::my_progname, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(con));
 
2423
        if (!opt_ignore_sql_errors)
 
2424
          exit(1);
1879
2425
      }
1880
2426
      sptr->setCreateCount(sptr->getCreateCount()+1);
1881
2427
    }
1891
2437
  gettimeofday(&end_time, NULL);
1892
2438
 
1893
2439
  sptr->setCreateTiming(timedif(end_time, start_time));
 
2440
 
 
2441
  return(0);
1894
2442
}
1895
2443
 
1896
 
static void drop_schema(drizzle_con_st &con, const char *db)
 
2444
static int
 
2445
drop_schema(drizzle_con_st *con, const char *db)
1897
2446
{
1898
2447
  char query[HUGE_STRING_LENGTH];
1899
2448
  int len;
1903
2452
  if (run_query(con, NULL, query, len))
1904
2453
  {
1905
2454
    fprintf(stderr,"%s: Cannot drop database '%s' ERROR : %s\n",
1906
 
            SLAP_NAME, db, drizzle_con_error(&con));
1907
 
    abort();
 
2455
            internal::my_progname, db, drizzle_con_error(con));
 
2456
    exit(1);
1908
2457
  }
 
2458
 
 
2459
 
 
2460
 
 
2461
  return(0);
1909
2462
}
1910
2463
 
1911
 
static void run_statements(drizzle_con_st &con, Statement *stmt)
 
2464
static int
 
2465
run_statements(drizzle_con_st *con, Statement *stmt)
1912
2466
{
1913
 
  for (Statement *ptr= stmt; ptr && ptr->getLength(); ptr= ptr->getNext())
 
2467
  Statement *ptr;
 
2468
 
 
2469
  for (ptr= stmt; ptr && ptr->getLength(); ptr= ptr->getNext())
1914
2470
  {
1915
2471
    if (run_query(con, NULL, ptr->getString(), ptr->getLength()))
1916
2472
    {
1917
2473
      fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
1918
 
              SLAP_NAME, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(&con));
1919
 
      abort();
 
2474
              internal::my_progname, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(con));
 
2475
      exit(1);
1920
2476
    }
1921
2477
  }
 
2478
 
 
2479
  return(0);
1922
2480
}
1923
2481
 
1924
 
 
1925
 
static void timer_thread()
 
2482
static int
 
2483
run_scheduler(Stats *sptr, Statement **stmts, uint32_t concur, uint64_t limit)
1926
2484
{
 
2485
  uint32_t x;
 
2486
  uint32_t y;
 
2487
  unsigned int real_concurrency;
 
2488
  struct timeval start_time, end_time;
 
2489
  OptionString *sql_type;
 
2490
  ThreadContext *con;
 
2491
  pthread_t mainthread;            /* Thread descriptor */
 
2492
  pthread_attr_t attr;          /* Thread attributes */
 
2493
 
 
2494
 
 
2495
  pthread_attr_init(&attr);
 
2496
  pthread_attr_setdetachstate(&attr,
 
2497
                              PTHREAD_CREATE_DETACHED);
 
2498
 
 
2499
  pthread_mutex_lock(&counter_mutex);
 
2500
  thread_counter= 0;
 
2501
 
 
2502
  pthread_mutex_lock(&sleeper_mutex);
 
2503
  master_wakeup= 1;
 
2504
  pthread_mutex_unlock(&sleeper_mutex);
 
2505
 
 
2506
  real_concurrency= 0;
 
2507
 
 
2508
  for (y= 0, sql_type= query_options;
 
2509
       y < query_statements_count;
 
2510
       y++, sql_type= sql_type->getNext())
 
2511
  {
 
2512
    unsigned int options_loop= 1;
 
2513
 
 
2514
    if (sql_type->getOption())
 
2515
    {
 
2516
      options_loop= strtol(sql_type->getOption(),
 
2517
                           (char **)NULL, 10);
 
2518
      options_loop= options_loop ? options_loop : 1;
 
2519
    }
 
2520
 
 
2521
    while (options_loop--)
 
2522
      for (x= 0; x < concur; x++)
 
2523
      {
 
2524
        con= (ThreadContext *)malloc(sizeof(ThreadContext));
 
2525
        if (con == NULL)
 
2526
        {
 
2527
          fprintf(stderr, "Memory Allocation error in scheduler\n");
 
2528
          exit(1);
 
2529
        }
 
2530
        con->setStmt(stmts[y]);
 
2531
        con->setLimit(limit);
 
2532
 
 
2533
        real_concurrency++;
 
2534
        /* now you create the thread */
 
2535
        if (pthread_create(&mainthread, &attr, run_task,
 
2536
                           (void *)con) != 0)
 
2537
        {
 
2538
          fprintf(stderr,"%s: Could not create thread\n", internal::my_progname);
 
2539
          exit(1);
 
2540
        }
 
2541
        thread_counter++;
 
2542
      }
 
2543
  }
 
2544
 
1927
2545
  /*
1928
 
    We lock around the initial call in case were we in a loop. This
1929
 
    also keeps the value properly syncronized across call threads.
 
2546
    The timer_thread belongs to all threads so it too obeys the wakeup
 
2547
    call that run tasks obey.
1930
2548
  */
1931
 
  master_wakeup.wait();
1932
 
 
1933
 
  {
1934
 
    boost::mutex::scoped_lock scopedLock(timer_alarm_mutex);
1935
 
 
1936
 
    boost::xtime xt; 
1937
 
    xtime_get(&xt, boost::TIME_UTC); 
1938
 
    xt.sec += opt_timer_length; 
1939
 
 
1940
 
    (void)timer_alarm_threshold.timed_wait(scopedLock, xt);
1941
 
  }
1942
 
 
1943
 
  {
1944
 
    boost::mutex::scoped_lock scopedLock(timer_alarm_mutex);
1945
 
    timer_alarm= false;
1946
 
  }
1947
 
}
1948
 
 
1949
 
typedef boost::shared_ptr<boost::thread> Thread;
1950
 
typedef std::vector <Thread> Threads;
1951
 
static void run_scheduler(Stats *sptr, Statement **stmts, uint32_t concur, uint64_t limit)
1952
 
{
1953
 
  uint32_t real_concurrency;
1954
 
  struct timeval start_time, end_time;
1955
 
 
1956
 
  Threads threads;
1957
 
 
1958
 
  {
1959
 
    OptionString *sql_type;
1960
 
 
1961
 
    master_wakeup.reset();
1962
 
 
1963
 
    real_concurrency= 0;
1964
 
 
1965
 
    uint32_t y;
1966
 
    for (y= 0, sql_type= query_options;
1967
 
         y < query_statements_count;
1968
 
         y++, sql_type= sql_type->getNext())
1969
 
    {
1970
 
      uint32_t options_loop= 1;
1971
 
 
1972
 
      if (sql_type->getOption())
1973
 
      {
1974
 
        options_loop= strtol(sql_type->getOption(),
1975
 
                             (char **)NULL, 10);
1976
 
        options_loop= options_loop ? options_loop : 1;
1977
 
      }
1978
 
 
1979
 
      while (options_loop--)
1980
 
      {
1981
 
        for (uint32_t x= 0; x < concur; x++)
1982
 
        {
1983
 
          ThreadContext *con;
1984
 
          con= new ThreadContext;
1985
 
          if (con == NULL)
1986
 
          {
1987
 
            fprintf(stderr, "Memory Allocation error in scheduler\n");
1988
 
            abort();
1989
 
          }
1990
 
          con->setStmt(stmts[y]);
1991
 
          con->setLimit(limit);
1992
 
 
1993
 
          real_concurrency++;
1994
 
 
1995
 
          /* now you create the thread */
1996
 
          Thread thread;
1997
 
          thread= Thread(new boost::thread(boost::bind(&run_task, con)));
1998
 
          threads.push_back(thread);
1999
 
 
2000
 
        }
2001
 
      }
2002
 
    }
2003
 
 
2004
 
    /*
2005
 
      The timer_thread belongs to all threads so it too obeys the wakeup
2006
 
      call that run tasks obey.
2007
 
    */
2008
 
    if (opt_timer_length)
2009
 
    {
2010
 
      {
2011
 
        boost::mutex::scoped_lock alarmLock(timer_alarm_mutex);
2012
 
        timer_alarm= true;
2013
 
      }
2014
 
 
2015
 
      Thread thread;
2016
 
      thread= Thread(new boost::thread(&timer_thread));
2017
 
      threads.push_back(thread);
2018
 
    }
2019
 
  }
2020
 
 
2021
 
  master_wakeup.start();
 
2549
  if (opt_timer_length)
 
2550
  {
 
2551
    pthread_mutex_lock(&timer_alarm_mutex);
 
2552
    timer_alarm= true;
 
2553
    pthread_mutex_unlock(&timer_alarm_mutex);
 
2554
 
 
2555
    if (pthread_create(&mainthread, &attr, timer_thread,
 
2556
                       (void *)&opt_timer_length) != 0)
 
2557
    {
 
2558
      fprintf(stderr,"%s: Could not create timer thread\n", internal::my_progname);
 
2559
      exit(1);
 
2560
    }
 
2561
  }
 
2562
 
 
2563
  pthread_mutex_unlock(&counter_mutex);
 
2564
  pthread_attr_destroy(&attr);
 
2565
 
 
2566
  pthread_mutex_lock(&sleeper_mutex);
 
2567
  master_wakeup= 0;
 
2568
  pthread_mutex_unlock(&sleeper_mutex);
 
2569
  pthread_cond_broadcast(&sleep_threshhold);
2022
2570
 
2023
2571
  gettimeofday(&start_time, NULL);
2024
2572
 
2025
2573
  /*
2026
2574
    We loop until we know that all children have cleaned up.
2027
2575
  */
2028
 
  for (Threads::iterator iter= threads.begin(); iter != threads.end(); iter++)
 
2576
  pthread_mutex_lock(&counter_mutex);
 
2577
  while (thread_counter)
2029
2578
  {
2030
 
    (*iter)->join();
 
2579
    struct timespec abstime;
 
2580
 
 
2581
    set_timespec(abstime, 3);
 
2582
    pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
2031
2583
  }
 
2584
  pthread_mutex_unlock(&counter_mutex);
2032
2585
 
2033
2586
  gettimeofday(&end_time, NULL);
2034
2587
 
 
2588
 
2035
2589
  sptr->setTiming(timedif(end_time, start_time));
2036
2590
  sptr->setUsers(concur);
2037
2591
  sptr->setRealUsers(real_concurrency);
2038
2592
  sptr->setRows(limit);
 
2593
 
 
2594
  return(0);
 
2595
}
 
2596
 
 
2597
 
 
2598
pthread_handler_t timer_thread(void *p)
 
2599
{
 
2600
  uint32_t *timer_length= (uint32_t *)p;
 
2601
  struct timespec abstime;
 
2602
 
 
2603
 
 
2604
  /*
 
2605
    We lock around the initial call in case were we in a loop. This
 
2606
    also keeps the value properly syncronized across call threads.
 
2607
  */
 
2608
  pthread_mutex_lock(&sleeper_mutex);
 
2609
  while (master_wakeup)
 
2610
  {
 
2611
    pthread_cond_wait(&sleep_threshhold, &sleeper_mutex);
 
2612
  }
 
2613
  pthread_mutex_unlock(&sleeper_mutex);
 
2614
 
 
2615
  set_timespec(abstime, *timer_length);
 
2616
 
 
2617
  pthread_mutex_lock(&timer_alarm_mutex);
 
2618
  pthread_cond_timedwait(&timer_alarm_threshold, &timer_alarm_mutex, &abstime);
 
2619
  pthread_mutex_unlock(&timer_alarm_mutex);
 
2620
 
 
2621
  pthread_mutex_lock(&timer_alarm_mutex);
 
2622
  timer_alarm= false;
 
2623
  pthread_mutex_unlock(&timer_alarm_mutex);
 
2624
 
 
2625
  return(0);
 
2626
}
 
2627
 
 
2628
pthread_handler_t run_task(void *p)
 
2629
{
 
2630
  uint64_t counter= 0, queries;
 
2631
  uint64_t detach_counter;
 
2632
  unsigned int commit_counter;
 
2633
  drizzle_con_st con;
 
2634
  drizzle_result_st result;
 
2635
  drizzle_row_t row;
 
2636
  Statement *ptr;
 
2637
  ThreadContext *ctx= (ThreadContext *)p;
 
2638
 
 
2639
  pthread_mutex_lock(&sleeper_mutex);
 
2640
  while (master_wakeup)
 
2641
  {
 
2642
    pthread_cond_wait(&sleep_threshhold, &sleeper_mutex);
 
2643
  }
 
2644
  pthread_mutex_unlock(&sleeper_mutex);
 
2645
 
 
2646
  slap_connect(&con, true);
 
2647
 
 
2648
  if (verbose >= 3)
 
2649
    printf("connected!\n");
 
2650
  queries= 0;
 
2651
 
 
2652
  commit_counter= 0;
 
2653
  if (commit_rate)
 
2654
    run_query(&con, NULL, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
 
2655
 
 
2656
limit_not_met:
 
2657
  for (ptr= ctx->getStmt(), detach_counter= 0;
 
2658
       ptr && ptr->getLength();
 
2659
       ptr= ptr->getNext(), detach_counter++)
 
2660
  {
 
2661
    if (!opt_only_print && detach_rate && !(detach_counter % detach_rate))
 
2662
    {
 
2663
      slap_close(&con);
 
2664
      slap_connect(&con, true);
 
2665
    }
 
2666
 
 
2667
    /*
 
2668
      We have to execute differently based on query type. This should become a function.
 
2669
    */
 
2670
    if ((ptr->getType() == UPDATE_TYPE_REQUIRES_PREFIX) ||
 
2671
        (ptr->getType() == SELECT_TYPE_REQUIRES_PREFIX))
 
2672
    {
 
2673
      int length;
 
2674
      unsigned int key_val;
 
2675
      char *key;
 
2676
      char buffer[HUGE_STRING_LENGTH];
 
2677
 
 
2678
      /*
 
2679
        This should only happen if some sort of new engine was
 
2680
        implemented that didn't properly handle UPDATEs.
 
2681
 
 
2682
        Just in case someone runs this under an experimental engine we don't
 
2683
        want a crash so the if() is placed here.
 
2684
      */
 
2685
      assert(primary_keys_number_of);
 
2686
      if (primary_keys_number_of)
 
2687
      {
 
2688
        key_val= (unsigned int)(random() % primary_keys_number_of);
 
2689
        key= primary_keys[key_val];
 
2690
 
 
2691
        assert(key);
 
2692
 
 
2693
        length= snprintf(buffer, HUGE_STRING_LENGTH, "%.*s '%s'",
 
2694
                         (int)ptr->getLength(), ptr->getString(), key);
 
2695
 
 
2696
        if (run_query(&con, &result, buffer, length))
 
2697
        {
 
2698
          fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
 
2699
                  internal::my_progname, (uint32_t)length, buffer, drizzle_con_error(&con));
 
2700
          exit(1);
 
2701
        }
 
2702
      }
 
2703
    }
 
2704
    else
 
2705
    {
 
2706
      if (run_query(&con, &result, ptr->getString(), ptr->getLength()))
 
2707
      {
 
2708
        fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
 
2709
                internal::my_progname, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(&con));
 
2710
        exit(1);
 
2711
      }
 
2712
    }
 
2713
 
 
2714
    if (!opt_only_print)
 
2715
    {
 
2716
      while ((row = drizzle_row_next(&result)))
 
2717
        counter++;
 
2718
      drizzle_result_free(&result);
 
2719
    }
 
2720
    queries++;
 
2721
 
 
2722
    if (commit_rate && (++commit_counter == commit_rate))
 
2723
    {
 
2724
      commit_counter= 0;
 
2725
      run_query(&con, NULL, "COMMIT", strlen("COMMIT"));
 
2726
    }
 
2727
 
 
2728
    /* If the timer is set, and the alarm is not active then end */
 
2729
    if (opt_timer_length && timer_alarm == false)
 
2730
      goto end;
 
2731
 
 
2732
    /* If limit has been reached, and we are not in a timer_alarm just end */
 
2733
    if (ctx->getLimit() && queries == ctx->getLimit() && timer_alarm == false)
 
2734
      goto end;
 
2735
  }
 
2736
 
 
2737
  if (opt_timer_length && timer_alarm == true)
 
2738
    goto limit_not_met;
 
2739
 
 
2740
  if (ctx->getLimit() && queries < ctx->getLimit())
 
2741
    goto limit_not_met;
 
2742
 
 
2743
 
 
2744
end:
 
2745
  if (commit_rate)
 
2746
    run_query(&con, NULL, "COMMIT", strlen("COMMIT"));
 
2747
 
 
2748
  slap_close(&con);
 
2749
 
 
2750
  pthread_mutex_lock(&counter_mutex);
 
2751
  thread_counter--;
 
2752
  pthread_cond_signal(&count_threshhold);
 
2753
  pthread_mutex_unlock(&counter_mutex);
 
2754
 
 
2755
  free(ctx);
 
2756
 
 
2757
  return(0);
2039
2758
}
2040
2759
 
2041
2760
/*
2042
2761
  Parse records from comma seperated string. : is a reserved character and is used for options
2043
2762
  on variables.
2044
2763
*/
2045
 
uint32_t parse_option(const char *origin, OptionString **stmt, char delm)
 
2764
uint
 
2765
parse_option(const char *origin, OptionString **stmt, char delm)
2046
2766
{
2047
2767
  char *string;
2048
2768
  char *begin_ptr;
2049
2769
  char *end_ptr;
 
2770
  OptionString **sptr= stmt;
 
2771
  OptionString *tmp;
2050
2772
  uint32_t length= strlen(origin);
2051
2773
  uint32_t count= 0; /* We know that there is always one */
2052
2774
 
2053
2775
  end_ptr= (char *)origin + length;
2054
2776
 
2055
 
  OptionString *tmp;
2056
 
  *stmt= tmp= new OptionString;
 
2777
  tmp= *sptr= (OptionString *)malloc(sizeof(OptionString));
 
2778
  if (tmp == NULL)
 
2779
  {
 
2780
    fprintf(stderr,"Error allocating memory while parsing options\n");
 
2781
    exit(1);
 
2782
  }
 
2783
  memset(tmp, 0, sizeof(OptionString));
2057
2784
 
2058
2785
  for (begin_ptr= (char *)origin;
2059
2786
       begin_ptr != end_ptr;
2085
2812
      buffer_ptr++;
2086
2813
 
2087
2814
      /* Move past the : and the first string */
2088
 
      tmp->setOption(buffer_ptr);
 
2815
      tmp->setOptionLength(strlen(buffer_ptr));
 
2816
      tmp->setOption((char *)malloc(tmp->getOptionLength() + 1));
 
2817
      if (tmp->getOption() == NULL)
 
2818
      {
 
2819
        fprintf(stderr,"Error allocating memory while parsing options\n");
 
2820
        exit(1);
 
2821
      }
 
2822
      memcpy(tmp->getOption(), buffer_ptr, tmp->getOptionLength());
 
2823
      tmp->setOption(tmp->getOptionLength(),0); 
2089
2824
    }
2090
2825
 
 
2826
    tmp->setLength(strlen(buffer));
2091
2827
    tmp->setString(strdup(buffer));
2092
2828
    if (tmp->getString() == NULL)
2093
2829
    {
2094
2830
      fprintf(stderr,"Error allocating memory while parsing options\n");
2095
 
      abort();
 
2831
      exit(1);
2096
2832
    }
2097
2833
 
2098
2834
    if (isspace(*begin_ptr))
2102
2838
 
2103
2839
    if (begin_ptr != end_ptr)
2104
2840
    {
2105
 
      tmp->setNext( new OptionString);
 
2841
      tmp->setNext((OptionString *)malloc(sizeof(OptionString)));
 
2842
      if (tmp->getNext() == NULL)
 
2843
      {
 
2844
        fprintf(stderr,"Error allocating memory while parsing options\n");
 
2845
        exit(1);
 
2846
      }
 
2847
      memset(tmp->getNext(), 0, sizeof(OptionString));
2106
2848
    }
2107
2849
    
2108
2850
  }
2115
2857
  Raw parsing interface. If you want the slap specific parser look at
2116
2858
  parse_option.
2117
2859
*/
2118
 
uint32_t parse_delimiter(const char *script, Statement **stmt, char delm)
 
2860
uint
 
2861
parse_delimiter(const char *script, Statement **stmt, char delm)
2119
2862
{
2120
2863
  char *retstr;
2121
2864
  char *ptr= (char *)script;
2124
2867
  uint32_t length= strlen(script);
2125
2868
  uint32_t count= 0; /* We know that there is always one */
2126
2869
 
2127
 
  for (tmp= *sptr= new Statement;
 
2870
  for (tmp= *sptr= (Statement *)calloc(1, sizeof(Statement));
2128
2871
       (retstr= strchr(ptr, delm));
2129
 
       tmp->setNext(new Statement),
 
2872
       tmp->setNext((Statement *)calloc(1, sizeof(Statement))),
2130
2873
       tmp= tmp->getNext())
2131
2874
  {
2132
2875
    if (tmp == NULL)
2133
2876
    {
2134
2877
      fprintf(stderr,"Error allocating memory while parsing delimiter\n");
2135
 
      abort();
 
2878
      exit(1);
2136
2879
    }
2137
2880
 
2138
2881
    count++;
2139
 
    tmp->setString((size_t)(retstr - ptr));
 
2882
    tmp->setLength((size_t)(retstr - ptr));
 
2883
    tmp->setString((char *)malloc(tmp->getLength() + 1));
2140
2884
 
2141
2885
    if (tmp->getString() == NULL)
2142
2886
    {
2143
2887
      fprintf(stderr,"Error allocating memory while parsing delimiter\n");
2144
 
      abort();
 
2888
      exit(1);
2145
2889
    }
2146
2890
 
2147
2891
    memcpy(tmp->getString(), ptr, tmp->getLength());
 
2892
    tmp->setString(tmp->getLength(), 0);
2148
2893
    ptr+= retstr - ptr + 1;
2149
2894
    if (isspace(*ptr))
2150
2895
      ptr++;
2152
2897
 
2153
2898
  if (ptr != script+length)
2154
2899
  {
2155
 
    tmp->setString((size_t)((script + length) - ptr));
 
2900
    tmp->setLength((size_t)((script + length) - ptr));
 
2901
    tmp->setString((char *)malloc(tmp->getLength() + 1));
2156
2902
    if (tmp->getString() == NULL)
2157
2903
    {
2158
2904
      fprintf(stderr,"Error allocating memory while parsing delimiter\n");
2159
 
      abort();
 
2905
      exit(1);
2160
2906
    }
2161
2907
    memcpy(tmp->getString(), ptr, tmp->getLength());
 
2908
    tmp->setString(tmp->getLength(),0);
2162
2909
    count++;
2163
2910
  }
2164
2911
 
2171
2918
  number ranges from a comma seperated string.
2172
2919
  In restrospect, this is a lousy name from this function.
2173
2920
*/
2174
 
uint32_t parse_comma(const char *string, std::vector <uint32_t> &range)
 
2921
uint
 
2922
parse_comma(const char *string, uint32_t **range)
2175
2923
{
2176
 
  uint32_t count= 1; /* We know that there is always one */
 
2924
  unsigned int count= 1,x; /* We know that there is always one */
2177
2925
  char *retstr;
2178
2926
  char *ptr= (char *)string;
2179
 
  uint32_t *nptr;
 
2927
  unsigned int *nptr;
2180
2928
 
2181
2929
  for (;*ptr; ptr++)
2182
2930
    if (*ptr == ',') count++;
2183
2931
 
2184
2932
  /* One extra spot for the NULL */
2185
 
  range.resize(count +1);
2186
 
  nptr= &range[0];
 
2933
  nptr= *range= (uint32_t *)malloc(sizeof(unsigned int) * (count + 1));
 
2934
  memset(nptr, 0, sizeof(unsigned int) * (count + 1));
2187
2935
 
2188
2936
  ptr= (char *)string;
2189
 
  uint32_t x= 0;
 
2937
  x= 0;
2190
2938
  while ((retstr= strchr(ptr,',')))
2191
2939
  {
2192
2940
    nptr[x++]= atoi(ptr);
2197
2945
  return count;
2198
2946
}
2199
2947
 
2200
 
void print_conclusions(Conclusions &con)
 
2948
void
 
2949
print_conclusions(Conclusions *con)
2201
2950
{
2202
2951
  printf("Benchmark\n");
2203
 
  if (con.getEngine())
2204
 
    printf("\tRunning for engine %s\n", con.getEngine());
2205
 
 
2206
 
  if (not opt_label.empty() || !opt_auto_generate_sql_type.empty())
 
2952
  if (con->getEngine())
 
2953
    printf("\tRunning for engine %s\n", con->getEngine());
 
2954
  if (!opt_label.empty() || !opt_auto_generate_sql_type.empty())
2207
2955
  {
2208
2956
    const char *ptr= opt_auto_generate_sql_type.c_str() ? opt_auto_generate_sql_type.c_str() : "query";
2209
2957
    printf("\tLoad: %s\n", !opt_label.empty() ? opt_label.c_str() : ptr);
2210
2958
  }
2211
2959
  printf("\tAverage Time took to generate schema and initial data: %ld.%03ld seconds\n",
2212
 
         con.getCreateAvgTiming() / 1000, con.getCreateAvgTiming() % 1000);
 
2960
         con->getCreateAvgTiming() / 1000, con->getCreateAvgTiming() % 1000);
2213
2961
  printf("\tAverage number of seconds to run all queries: %ld.%03ld seconds\n",
2214
 
         con.getAvgTiming() / 1000, con.getAvgTiming() % 1000);
 
2962
         con->getAvgTiming() / 1000, con->getAvgTiming() % 1000);
2215
2963
  printf("\tMinimum number of seconds to run all queries: %ld.%03ld seconds\n",
2216
 
         con.getMinTiming() / 1000, con.getMinTiming() % 1000);
 
2964
         con->getMinTiming() / 1000, con->getMinTiming() % 1000);
2217
2965
  printf("\tMaximum number of seconds to run all queries: %ld.%03ld seconds\n",
2218
 
         con.getMaxTiming() / 1000, con.getMaxTiming() % 1000);
 
2966
         con->getMaxTiming() / 1000, con->getMaxTiming() % 1000);
2219
2967
  printf("\tTotal time for tests: %ld.%03ld seconds\n",
2220
 
         con.getSumOfTime() / 1000, con.getSumOfTime() % 1000);
2221
 
  printf("\tStandard Deviation: %ld.%03ld\n", con.getStdDev() / 1000, con.getStdDev() % 1000);
2222
 
  printf("\tNumber of queries in create queries: %"PRIu64"\n", con.getCreateCount());
 
2968
         con->getSumOfTime() / 1000, con->getSumOfTime() % 1000);
 
2969
  printf("\tStandard Deviation: %ld.%03ld\n", con->getStdDev() / 1000, con->getStdDev() % 1000);
 
2970
  printf("\tNumber of queries in create queries: %"PRIu64"\n", con->getCreateCount());
2223
2971
  printf("\tNumber of clients running queries: %u/%u\n",
2224
 
         con.getUsers(), con.getRealUsers());
 
2972
         con->getUsers(), con->getRealUsers());
2225
2973
  printf("\tNumber of times test was run: %u\n", iterations);
2226
 
  printf("\tAverage number of queries per client: %"PRIu64"\n", con.getAvgRows());
2227
 
 
2228
 
  uint64_t temp_val= failed_update_for_transaction; 
2229
 
  if (temp_val)
2230
 
    printf("\tFailed number of updates %"PRIu64"\n", temp_val);
2231
 
 
 
2974
  printf("\tAverage number of queries per client: %"PRIu64"\n", con->getAvgRows());
2232
2975
  printf("\n");
2233
2976
}
2234
2977
 
2235
 
void print_conclusions_csv(Conclusions &con)
 
2978
void
 
2979
print_conclusions_csv(Conclusions *con)
2236
2980
{
 
2981
  unsigned int x;
2237
2982
  char buffer[HUGE_STRING_LENGTH];
2238
2983
  char label_buffer[HUGE_STRING_LENGTH];
2239
2984
  size_t string_len;
2240
2985
  const char *temp_label= opt_label.c_str();
2241
2986
 
2242
 
  memset(label_buffer, 0, sizeof(label_buffer));
 
2987
  memset(label_buffer, 0, HUGE_STRING_LENGTH);
2243
2988
 
2244
 
  if (not opt_label.empty())
 
2989
  if (!opt_label.empty())
2245
2990
  {
2246
2991
    string_len= opt_label.length();
2247
2992
 
2248
 
    for (uint32_t x= 0; x < string_len; x++)
 
2993
    for (x= 0; x < string_len; x++)
2249
2994
    {
2250
2995
      if (temp_label[x] == ',')
2251
2996
        label_buffer[x]= '-';
2253
2998
        label_buffer[x]= temp_label[x] ;
2254
2999
    }
2255
3000
  }
2256
 
  else if (not opt_auto_generate_sql_type.empty())
 
3001
  else if (!opt_auto_generate_sql_type.empty())
2257
3002
  {
2258
3003
    string_len= opt_auto_generate_sql_type.length();
2259
3004
 
2260
 
    for (uint32_t x= 0; x < string_len; x++)
 
3005
    for (x= 0; x < string_len; x++)
2261
3006
    {
2262
3007
      if (opt_auto_generate_sql_type[x] == ',')
2263
3008
        label_buffer[x]= '-';
2266
3011
    }
2267
3012
  }
2268
3013
  else
2269
 
  {
2270
3014
    snprintf(label_buffer, HUGE_STRING_LENGTH, "query");
2271
 
  }
2272
3015
 
2273
3016
  snprintf(buffer, HUGE_STRING_LENGTH,
2274
3017
           "%s,%s,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,"
2275
3018
           "%u,%u,%u,%"PRIu64"\n",
2276
 
           con.getEngine() ? con.getEngine() : "", /* Storage engine we ran against */
 
3019
           con->getEngine() ? con->getEngine() : "", /* Storage engine we ran against */
2277
3020
           label_buffer, /* Load type */
2278
 
           con.getAvgTiming() / 1000, con.getAvgTiming() % 1000, /* Time to load */
2279
 
           con.getMinTiming() / 1000, con.getMinTiming() % 1000, /* Min time */
2280
 
           con.getMaxTiming() / 1000, con.getMaxTiming() % 1000, /* Max time */
2281
 
           con.getSumOfTime() / 1000, con.getSumOfTime() % 1000, /* Total time */
2282
 
           con.getStdDev() / 1000, con.getStdDev() % 1000, /* Standard Deviation */
 
3021
           con->getAvgTiming() / 1000, con->getAvgTiming() % 1000, /* Time to load */
 
3022
           con->getMinTiming() / 1000, con->getMinTiming() % 1000, /* Min time */
 
3023
           con->getMaxTiming() / 1000, con->getMaxTiming() % 1000, /* Max time */
 
3024
           con->getSumOfTime() / 1000, con->getSumOfTime() % 1000, /* Total time */
 
3025
           con->getStdDev() / 1000, con->getStdDev() % 1000, /* Standard Deviation */
2283
3026
           iterations, /* Iterations */
2284
 
           con.getUsers(), /* Children used max_timing */
2285
 
           con.getRealUsers(), /* Children used max_timing */
2286
 
           con.getAvgRows()  /* Queries run */
 
3027
           con->getUsers(), /* Children used max_timing */
 
3028
           con->getRealUsers(), /* Children used max_timing */
 
3029
           con->getAvgRows()  /* Queries run */
2287
3030
           );
2288
 
  size_t buff_len= strlen(buffer);
2289
 
  ssize_t write_ret= write(csv_file, (unsigned char*) buffer, buff_len);
2290
 
  if (write_ret != (ssize_t)buff_len)
2291
 
  {
2292
 
    fprintf(stderr, _("Unable to fully write %"PRIu64" bytes. "
2293
 
                      "Could only write %"PRId64"."), (uint64_t)write_ret,
2294
 
                      (int64_t)buff_len);
2295
 
    exit(-1);
2296
 
  }
 
3031
  internal::my_write(csv_file, (unsigned char*) buffer, (uint32_t)strlen(buffer), MYF(0));
2297
3032
}
2298
3033
 
2299
 
void generate_stats(Conclusions *con, OptionString *eng, Stats *sptr)
 
3034
void
 
3035
generate_stats(Conclusions *con, OptionString *eng, Stats *sptr)
2300
3036
{
2301
3037
  Stats *ptr;
2302
 
  uint32_t x;
 
3038
  unsigned int x;
2303
3039
 
2304
3040
  con->setMinTiming(sptr->getTiming());
2305
3041
  con->setMaxTiming(sptr->getTiming());
2329
3065
  else
2330
3066
    con->setEngine(NULL);
2331
3067
 
2332
 
  standard_deviation(*con, sptr);
 
3068
  standard_deviation(con, sptr);
2333
3069
 
2334
3070
  /* Now we do the create time operations */
2335
3071
  con->setCreateMinTiming(sptr->getCreateTiming());
2355
3091
option_cleanup(OptionString *stmt)
2356
3092
{
2357
3093
  OptionString *ptr, *nptr;
2358
 
  if (not stmt)
 
3094
  if (!stmt)
2359
3095
    return;
2360
3096
 
2361
3097
  for (ptr= stmt; ptr; ptr= nptr)
2362
3098
  {
2363
3099
    nptr= ptr->getNext();
2364
 
    delete ptr;
 
3100
    if (ptr->getString())
 
3101
      free(ptr->getString());
 
3102
    if (ptr->getOption())
 
3103
      free(ptr->getOption());
 
3104
    free(ptr);
2365
3105
  }
2366
3106
}
2367
3107
 
2368
 
void statement_cleanup(Statement *stmt)
 
3108
void
 
3109
statement_cleanup(Statement *stmt)
2369
3110
{
2370
3111
  Statement *ptr, *nptr;
2371
 
  if (not stmt)
 
3112
  if (!stmt)
2372
3113
    return;
2373
3114
 
2374
3115
  for (ptr= stmt; ptr; ptr= nptr)
2375
3116
  {
2376
3117
    nptr= ptr->getNext();
2377
 
    delete ptr;
 
3118
    if (ptr->getString())
 
3119
      free(ptr->getString());
 
3120
    free(ptr);
2378
3121
  }
2379
3122
}
2380
3123
 
2381
 
void slap_close(drizzle_con_st &con)
 
3124
void
 
3125
slap_close(drizzle_con_st *con)
2382
3126
{
2383
 
  drizzle_free(drizzle_con_drizzle(&con));
 
3127
  if (opt_only_print)
 
3128
    return;
 
3129
 
 
3130
  drizzle_free(drizzle_con_drizzle(con));
2384
3131
}
2385
3132
 
2386
 
void slap_connect(drizzle_con_st &con, bool connect_to_schema)
 
3133
void
 
3134
slap_connect(drizzle_con_st *con, bool connect_to_schema)
2387
3135
{
2388
3136
  /* Connect to server */
2389
3137
  static uint32_t connection_retry_sleep= 100000; /* Microseconds */
2390
 
  int connect_error= 1;
 
3138
  int x, connect_error= 1;
2391
3139
  drizzle_return_t ret;
2392
3140
  drizzle_st *drizzle;
2393
3141
 
 
3142
  if (opt_only_print)
 
3143
    return;
 
3144
 
2394
3145
  if (opt_delayed_start)
2395
3146
    usleep(random()%opt_delayed_start);
2396
3147
 
2397
3148
  if ((drizzle= drizzle_create(NULL)) == NULL ||
2398
 
      drizzle_con_add_tcp(drizzle, &con, host.c_str(), opt_drizzle_port,
2399
 
        user.c_str(),
2400
 
        opt_password.c_str(),
2401
 
        connect_to_schema ? create_schema_string.c_str() : NULL,
2402
 
        use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL) == NULL)
 
3149
      drizzle_con_add_tcp(drizzle, con, host.c_str(), opt_drizzle_port, user.c_str(),
 
3150
                          opt_password.c_str(),
 
3151
                          connect_to_schema ? create_schema_string.c_str() : NULL,
 
3152
                          opt_mysql ? DRIZZLE_CON_MYSQL : DRIZZLE_CON_NONE) == NULL)
2403
3153
  {
2404
 
    fprintf(stderr,"%s: Error creating drizzle object\n", SLAP_NAME);
2405
 
    abort();
 
3154
    fprintf(stderr,"%s: Error creating drizzle object\n", internal::my_progname);
 
3155
    exit(1);
2406
3156
  }
2407
3157
 
2408
 
  drizzle_set_context(drizzle, (void*)(connection_count.fetch_and_increment()));
2409
 
 
2410
 
  if (opt_only_print)
2411
 
    return;
2412
 
 
2413
 
  for (uint32_t x= 0; x < 10; x++)
 
3158
  for (x= 0; x < 10; x++)
2414
3159
  {
2415
 
    if ((ret= drizzle_con_connect(&con)) == DRIZZLE_RETURN_OK)
 
3160
    if ((ret= drizzle_con_connect(con)) == DRIZZLE_RETURN_OK)
2416
3161
    {
2417
3162
      /* Connect suceeded */
2418
3163
      connect_error= 0;
2422
3167
  }
2423
3168
  if (connect_error)
2424
3169
  {
2425
 
    fprintf(stderr,"%s: Error when connecting to server: %d %s\n", SLAP_NAME,
2426
 
            ret, drizzle_con_error(&con));
2427
 
    abort();
 
3170
    fprintf(stderr,"%s: Error when connecting to server: %d %s\n", internal::my_progname,
 
3171
            ret, drizzle_con_error(con));
 
3172
    exit(1);
2428
3173
  }
 
3174
 
 
3175
  return;
2429
3176
}
2430
3177
 
2431
 
void standard_deviation(Conclusions &con, Stats *sptr)
 
3178
void
 
3179
standard_deviation (Conclusions *con, Stats *sptr)
2432
3180
{
 
3181
  unsigned int x;
2433
3182
  long int sum_of_squares;
2434
3183
  double the_catch;
2435
3184
  Stats *ptr;
2436
3185
 
2437
3186
  if (iterations == 1 || iterations == 0)
2438
3187
  {
2439
 
    con.setStdDev(0);
 
3188
    con->setStdDev(0);
2440
3189
    return;
2441
3190
  }
2442
3191
 
2443
 
  uint32_t x;
2444
3192
  for (ptr= sptr, x= 0, sum_of_squares= 0; x < iterations; ptr++, x++)
2445
3193
  {
2446
3194
    long int deviation;
2447
3195
 
2448
 
    deviation= ptr->getTiming() - con.getAvgTiming();
 
3196
    deviation= ptr->getTiming() - con->getAvgTiming();
2449
3197
    sum_of_squares+= deviation*deviation;
2450
3198
  }
2451
3199
 
2452
3200
  the_catch= sqrt((double)(sum_of_squares/(iterations -1)));
2453
 
  con.setStdDev((long int)the_catch);
 
3201
  con->setStdDev((long int)the_catch);
2454
3202
}