~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzleslap.cc

  • Committer: LinuxJedi
  • Date: 2010-08-12 23:56:35 UTC
  • mto: (1723.1.4 build)
  • mto: This revision was merged to the branch mainline in revision 1724.
  • Revision ID: linuxjedi@linuxjedi-laptop-20100812235635-0dd1nuryjb43k9nj
Migrate the rest of strerror to strerror_r

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
 
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
      ;
552
981
 
553
982
    std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
554
983
 
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
984
    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();
 
985
    drizzle_con_st con;
566
986
    OptionString *eptr;
 
987
    uint32_t x;
567
988
 
568
 
    // Disable allow_guessing
569
 
    int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
570
989
 
571
990
    po::variables_map vm;
572
991
    po::store(po::command_line_parser(argc, argv).options(long_options).
573
 
              style(style).extra_parser(parse_password_arg).run(), vm);
 
992
            extra_parser(parse_password_arg).run(), vm);
574
993
 
575
994
    std::string user_config_dir_slap(user_config_dir);
576
995
    user_config_dir_slap.append("/drizzle/drizzleslap.cnf"); 
593
1012
    po::notify(vm);
594
1013
 
595
1014
    if (process_options())
596
 
      abort();
 
1015
      exit(1);
597
1016
 
598
1017
    if ( vm.count("help") || vm.count("info"))
599
1018
    {
600
 
      printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",SLAP_NAME, SLAP_VERSION,
 
1019
      printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname, SLAP_VERSION,
601
1020
          drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
602
1021
      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");
 
1022
      puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\
 
1023
          \nand you are welcome to modify and redistribute it under the GPL \
 
1024
          license\n");
607
1025
      puts("Run a query multiple times against the server\n");
608
1026
      cout << long_options << endl;
609
 
      abort();
 
1027
      exit(0);
610
1028
    }   
611
1029
 
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
1030
    if (vm.count("port")) 
628
1031
    {
629
1032
      temp_drizzle_port= vm["port"].as<uint32_t>();
631
1034
      if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
632
1035
      {
633
1036
        fprintf(stderr, _("Value supplied for port is not valid.\n"));
634
 
        abort();
 
1037
        exit(1);
635
1038
      }
636
1039
      else
637
1040
      {
641
1044
 
642
1045
  if ( vm.count("password") )
643
1046
  {
644
 
    if (not opt_password.empty())
 
1047
    if (!opt_password.empty())
645
1048
      opt_password.erase();
646
1049
    if (password == PASSWORD_SENTINEL)
647
1050
    {
662
1065
 
663
1066
    if ( vm.count("version") )
664
1067
    {
665
 
      printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",SLAP_NAME, SLAP_VERSION,
 
1068
      printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname, SLAP_VERSION,
666
1069
          drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
667
 
      abort();
 
1070
      exit(0);
668
1071
    }
669
1072
 
670
1073
    /* Seed the random number generator if we will be using it. */
671
1074
    if (auto_generate_sql)
672
1075
    {
673
1076
      if (opt_set_random_seed == 0)
674
 
        opt_set_random_seed= (uint32_t)time(NULL);
 
1077
        opt_set_random_seed= (unsigned int)time(NULL);
675
1078
      srandom(opt_set_random_seed);
676
1079
    }
677
1080
 
678
1081
    /* globals? Yes, so we only have to run strlen once */
679
1082
    delimiter_length= delimiter.length();
680
1083
 
681
 
    slap_connect(con, false);
 
1084
    slap_connect(&con, false);
 
1085
 
 
1086
    pthread_mutex_init(&counter_mutex, NULL);
 
1087
    pthread_cond_init(&count_threshhold, NULL);
 
1088
    pthread_mutex_init(&sleeper_mutex, NULL);
 
1089
    pthread_cond_init(&sleep_threshhold, NULL);
 
1090
    pthread_mutex_init(&timer_alarm_mutex, NULL);
 
1091
    pthread_cond_init(&timer_alarm_threshold, NULL);
 
1092
 
682
1093
 
683
1094
    /* Main iterations loop */
684
1095
burnin:
691
1102
      if (verbose >= 2)
692
1103
        printf("Starting Concurrency Test\n");
693
1104
 
694
 
      if (concurrency.size())
 
1105
      if (*concurrency)
695
1106
      {
696
 
        for (current= &concurrency[0]; current && *current; current++)
697
 
          concurrency_loop(con, *current, eptr);
 
1107
        for (current= concurrency; current && *current; current++)
 
1108
          concurrency_loop(&con, *current, eptr);
698
1109
      }
699
1110
      else
700
1111
      {
701
1112
        uint32_t infinite= 1;
702
1113
        do {
703
 
          concurrency_loop(con, infinite, eptr);
 
1114
          concurrency_loop(&con, infinite, eptr);
704
1115
        }
705
1116
        while (infinite++);
706
1117
      }
707
1118
 
708
 
      if (not opt_preserve)
709
 
        drop_schema(con, create_schema_string.c_str());
 
1119
      if (!opt_preserve)
 
1120
        drop_schema(&con, create_schema_string.c_str());
710
1121
 
711
1122
    } while (eptr ? (eptr= eptr->getNext()) : 0);
712
1123
 
713
1124
    if (opt_burnin)
714
1125
      goto burnin;
715
1126
 
716
 
    slap_close(con);
 
1127
    pthread_mutex_destroy(&counter_mutex);
 
1128
    pthread_cond_destroy(&count_threshhold);
 
1129
    pthread_mutex_destroy(&sleeper_mutex);
 
1130
    pthread_cond_destroy(&sleep_threshhold);
 
1131
    pthread_mutex_destroy(&timer_alarm_mutex);
 
1132
    pthread_cond_destroy(&timer_alarm_threshold);
 
1133
 
 
1134
    slap_close(&con);
717
1135
 
718
1136
    /* now free all the strings we created */
719
 
    if (not opt_password.empty())
 
1137
    if (!opt_password.empty())
720
1138
      opt_password.erase();
721
1139
 
722
 
    concurrency.clear();
 
1140
    free(concurrency);
723
1141
 
724
1142
    statement_cleanup(create_statements);
725
 
    for (uint32_t x= 0; x < query_statements_count; x++)
 
1143
    for (x= 0; x < query_statements_count; x++)
726
1144
      statement_cleanup(query_statements[x]);
727
 
    query_statements.clear();
 
1145
    free(query_statements);
728
1146
    statement_cleanup(pre_statements);
729
1147
    statement_cleanup(post_statements);
730
1148
    option_cleanup(engine_options);
741
1159
  {
742
1160
    cerr<<"Error:"<<err.what()<<endl;
743
1161
  }
744
 
 
745
 
  if (csv_file != fileno(stdout))
746
 
    close(csv_file);
747
 
 
748
1162
  return 0;
749
1163
}
750
1164
 
751
 
void concurrency_loop(drizzle_con_st &con, uint32_t current, OptionString *eptr)
 
1165
void concurrency_loop(drizzle_con_st *con, uint32_t current, OptionString *eptr)
752
1166
{
 
1167
  unsigned int x;
753
1168
  Stats *head_sptr;
754
1169
  Stats *sptr;
755
1170
  Conclusions conclusion;
756
1171
  uint64_t client_limit;
757
1172
 
758
 
  head_sptr= new Stats[iterations];
 
1173
  head_sptr= (Stats *)malloc(sizeof(Stats) * iterations);
759
1174
  if (head_sptr == NULL)
760
1175
  {
761
1176
    fprintf(stderr,"Error allocating memory in concurrency_loop\n");
762
 
    abort();
 
1177
    exit(1);
763
1178
  }
 
1179
  memset(head_sptr, 0, sizeof(Stats) * iterations);
 
1180
 
 
1181
  memset(&conclusion, 0, sizeof(Conclusions));
764
1182
 
765
1183
  if (auto_actual_queries)
766
1184
    client_limit= auto_actual_queries;
769
1187
  else
770
1188
    client_limit= actual_queries;
771
1189
 
772
 
  uint32_t x;
773
1190
  for (x= 0, sptr= head_sptr; x < iterations; x++, sptr++)
774
1191
  {
775
1192
    /*
793
1210
    if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
794
1211
      generate_primary_key_list(con, eptr);
795
1212
 
796
 
    if (not pre_system.empty())
 
1213
    if (commit_rate)
 
1214
      run_query(con, NULL, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
 
1215
 
 
1216
    if (!pre_system.empty())
797
1217
    {
798
1218
      int ret= system(pre_system.c_str());
799
1219
      assert(ret != -1);
800
1220
    }
 
1221
       
801
1222
 
802
1223
    /*
803
1224
      Pre statements are always run after all other logic so they can
806
1227
    if (pre_statements)
807
1228
      run_statements(con, pre_statements);
808
1229
 
809
 
    run_scheduler(sptr, &query_statements[0], current, client_limit);
 
1230
    run_scheduler(sptr, query_statements, current, client_limit);
810
1231
 
811
1232
    if (post_statements)
812
1233
      run_statements(con, post_statements);
813
1234
 
814
 
    if (not post_system.empty())
 
1235
    if (!post_system.empty())
815
1236
    {
816
1237
      int ret=  system(post_system.c_str());
817
1238
      assert(ret !=-1);
819
1240
 
820
1241
    /* We are finished with this run */
821
1242
    if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
822
 
      primary_keys.clear();
 
1243
      drop_primary_key_list();
823
1244
  }
824
1245
 
825
1246
  if (verbose >= 2)
827
1248
 
828
1249
  generate_stats(&conclusion, eptr, head_sptr);
829
1250
 
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;
 
1251
  if (!opt_silent)
 
1252
    print_conclusions(&conclusion);
 
1253
  if (!opt_csv_str.empty())
 
1254
    print_conclusions_csv(&conclusion);
 
1255
 
 
1256
  free(head_sptr);
 
1257
 
836
1258
}
837
1259
 
838
1260
 
839
 
uint32_t get_random_string(char *buf, size_t size)
 
1261
 
 
1262
uint
 
1263
get_random_string(char *buf, size_t size)
840
1264
{
841
1265
  char *buf_ptr= buf;
 
1266
  size_t x;
842
1267
 
843
 
  for (size_t x= size; x > 0; x--)
 
1268
  for (x= size; x > 0; x--)
844
1269
    *buf_ptr++= ALPHANUMERICS[random() % ALPHANUMERICS_SIZE];
845
1270
  return(buf_ptr - buf);
846
1271
}
856
1281
build_table_string(void)
857
1282
{
858
1283
  char       buf[HUGE_STRING_LENGTH];
859
 
  uint32_t        col_count;
 
1284
  unsigned int        col_count;
860
1285
  Statement *ptr;
861
1286
  string table_string;
862
1287
 
882
1307
 
883
1308
  if (auto_generate_sql_secondary_indexes)
884
1309
  {
885
 
    for (uint32_t count= 0; count < auto_generate_sql_secondary_indexes; count++)
 
1310
    unsigned int count;
 
1311
 
 
1312
    for (count= 0; count < auto_generate_sql_secondary_indexes; count++)
886
1313
    {
887
1314
      if (count) /* Except for the first pass we add a comma */
888
1315
        table_string.append(",");
891
1318
          > HUGE_STRING_LENGTH)
892
1319
      {
893
1320
        fprintf(stderr, "Memory Allocation error in create table\n");
894
 
        abort();
 
1321
        exit(1);
895
1322
      }
896
1323
      table_string.append(buf);
897
1324
    }
909
1336
                     col_count, col_count) > HUGE_STRING_LENGTH)
910
1337
        {
911
1338
          fprintf(stderr, "Memory Allocation error in create table\n");
912
 
          abort();
 
1339
          exit(1);
913
1340
        }
914
1341
      }
915
1342
      else
918
1345
            > HUGE_STRING_LENGTH)
919
1346
        {
920
1347
          fprintf(stderr, "Memory Allocation error in create table\n");
921
 
          abort();
 
1348
          exit(1);
922
1349
        }
923
1350
      }
924
1351
      table_string.append(buf);
937
1364
                     col_count, col_count) > HUGE_STRING_LENGTH)
938
1365
        {
939
1366
          fprintf(stderr, "Memory Allocation error in creating table\n");
940
 
          abort();
 
1367
          exit(1);
941
1368
        }
942
1369
      }
943
1370
      else
946
1373
                     col_count) > HUGE_STRING_LENGTH)
947
1374
        {
948
1375
          fprintf(stderr, "Memory Allocation error in creating table\n");
949
 
          abort();
 
1376
          exit(1);
950
1377
        }
951
1378
      }
952
1379
      table_string.append(buf);
962
1389
                   col_count) > HUGE_STRING_LENGTH)
963
1390
      {
964
1391
        fprintf(stderr, "Memory Allocation error in creating table\n");
965
 
        abort();
 
1392
        exit(1);
966
1393
      }
967
1394
      table_string.append(buf);
968
1395
 
971
1398
    }
972
1399
 
973
1400
  table_string.append(")");
974
 
  ptr= new Statement;
975
 
  ptr->setString(table_string.length());
 
1401
  ptr= (Statement *)malloc(sizeof(Statement));
 
1402
  if (ptr == NULL)
 
1403
  {
 
1404
    fprintf(stderr, "Memory Allocation error in creating table\n");
 
1405
    exit(1);
 
1406
  }
 
1407
  memset(ptr, 0, sizeof(Statement));
 
1408
  ptr->setString((char *)malloc(table_string.length()+1));
976
1409
  if (ptr->getString()==NULL)
977
1410
  {
978
1411
    fprintf(stderr, "Memory Allocation error in creating table\n");
979
 
    abort();
 
1412
    exit(1);
980
1413
  }
 
1414
  memset(ptr->getString(), 0, table_string.length()+1);
 
1415
  ptr->setLength(table_string.length()+1);
981
1416
  ptr->setType(CREATE_TABLE_TYPE);
982
1417
  strcpy(ptr->getString(), table_string.c_str());
983
1418
  return(ptr);
993
1428
build_update_string(void)
994
1429
{
995
1430
  char       buf[HUGE_STRING_LENGTH];
996
 
  uint32_t        col_count;
 
1431
  unsigned int        col_count;
997
1432
  Statement *ptr;
998
1433
  string update_string;
999
1434
 
1008
1443
                   random()) > HUGE_STRING_LENGTH)
1009
1444
      {
1010
1445
        fprintf(stderr, "Memory Allocation error in creating update\n");
1011
 
        abort();
 
1446
        exit(1);
1012
1447
      }
1013
1448
      update_string.append(buf);
1014
1449
 
1027
1462
          > HUGE_STRING_LENGTH)
1028
1463
      {
1029
1464
        fprintf(stderr, "Memory Allocation error in creating update\n");
1030
 
        abort();
 
1465
        exit(1);
1031
1466
      }
1032
1467
      update_string.append(buf);
1033
1468
 
1039
1474
    update_string.append(" WHERE id = ");
1040
1475
 
1041
1476
 
1042
 
  ptr= new Statement;
 
1477
  ptr= (Statement *)malloc(sizeof(Statement));
 
1478
  if (ptr == NULL)
 
1479
  {
 
1480
    fprintf(stderr, "Memory Allocation error in creating update\n");
 
1481
    exit(1);
 
1482
  }
 
1483
  memset(ptr, 0, sizeof(Statement));
1043
1484
 
1044
 
  ptr->setString(update_string.length());
 
1485
  ptr->setLength(update_string.length()+1);
 
1486
  ptr->setString((char *)malloc(ptr->getLength()));
1045
1487
  if (ptr->getString() == NULL)
1046
1488
  {
1047
1489
    fprintf(stderr, "Memory Allocation error in creating update\n");
1048
 
    abort();
 
1490
    exit(1);
1049
1491
  }
 
1492
  memset(ptr->getString(), 0, ptr->getLength());
1050
1493
  if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
1051
1494
    ptr->setType(UPDATE_TYPE_REQUIRES_PREFIX);
1052
1495
  else
1066
1509
build_insert_string(void)
1067
1510
{
1068
1511
  char       buf[HUGE_STRING_LENGTH];
1069
 
  uint32_t        col_count;
 
1512
  unsigned int        col_count;
1070
1513
  Statement *ptr;
1071
1514
  string insert_string;
1072
1515
 
1092
1535
 
1093
1536
  if (auto_generate_sql_secondary_indexes)
1094
1537
  {
1095
 
    uint32_t count;
 
1538
    unsigned int count;
1096
1539
 
1097
1540
    for (count= 0; count < auto_generate_sql_secondary_indexes; count++)
1098
1541
    {
1112
1555
      if (snprintf(buf, HUGE_STRING_LENGTH, "%ld", random()) > HUGE_STRING_LENGTH)
1113
1556
      {
1114
1557
        fprintf(stderr, "Memory Allocation error in creating insert\n");
1115
 
        abort();
 
1558
        exit(1);
1116
1559
      }
1117
1560
      insert_string.append(buf);
1118
1561
 
1134
1577
 
1135
1578
  if (num_blob_cols)
1136
1579
  {
1137
 
    vector <char> blob_ptr;
 
1580
    char *blob_ptr;
1138
1581
 
1139
 
    blob_ptr.resize(num_blob_cols_size);
 
1582
    if (num_blob_cols_size > HUGE_STRING_LENGTH)
 
1583
    {
 
1584
      blob_ptr= (char *)malloc(sizeof(char)*num_blob_cols_size);
 
1585
      if (!blob_ptr)
 
1586
      {
 
1587
        fprintf(stderr, "Memory Allocation error in creating select\n");
 
1588
        exit(1);
 
1589
      }
 
1590
      memset(blob_ptr, 0, sizeof(char)*num_blob_cols_size);
 
1591
    }
 
1592
    else
 
1593
    {
 
1594
      blob_ptr= buf;
 
1595
    }
1140
1596
 
1141
1597
    for (col_count= 1; col_count <= num_blob_cols; col_count++)
1142
1598
    {
1143
 
      uint32_t buf_len;
1144
 
      uint32_t size;
1145
 
      uint32_t difference= num_blob_cols_size - num_blob_cols_size_min;
 
1599
      unsigned int buf_len;
 
1600
      unsigned int size;
 
1601
      unsigned int difference= num_blob_cols_size - num_blob_cols_size_min;
1146
1602
 
1147
1603
      size= difference ? (num_blob_cols_size_min + (random() % difference)) :
1148
1604
        num_blob_cols_size;
1149
1605
 
1150
 
      buf_len= get_random_string(&blob_ptr[0], size);
 
1606
      buf_len= get_random_string(blob_ptr, size);
1151
1607
 
1152
1608
      insert_string.append("'", 1);
1153
 
      insert_string.append(&blob_ptr[0], buf_len);
 
1609
      insert_string.append(blob_ptr, buf_len);
1154
1610
      insert_string.append("'", 1);
1155
1611
 
1156
1612
      if (col_count < num_blob_cols)
1157
1613
        insert_string.append(",", 1);
1158
1614
    }
 
1615
 
 
1616
    if (num_blob_cols_size > HUGE_STRING_LENGTH)
 
1617
      free(blob_ptr);
1159
1618
  }
1160
1619
 
1161
1620
  insert_string.append(")", 1);
1162
1621
 
1163
 
  ptr= new Statement;
1164
 
  ptr->setString(insert_string.length());
 
1622
  if (!(ptr= (Statement *)malloc(sizeof(Statement))))
 
1623
  {
 
1624
    fprintf(stderr, "Memory Allocation error in creating select\n");
 
1625
    exit(1);
 
1626
  }
 
1627
  memset(ptr, 0, sizeof(Statement));
 
1628
  ptr->setLength(insert_string.length()+1);
 
1629
  ptr->setString((char *)malloc(ptr->getLength()));
1165
1630
  if (ptr->getString()==NULL)
1166
1631
  {
1167
1632
    fprintf(stderr, "Memory Allocation error in creating select\n");
1168
 
    abort();
 
1633
    exit(1);
1169
1634
  }
 
1635
  memset(ptr->getString(), 0, ptr->getLength());
1170
1636
  ptr->setType(INSERT_TYPE);
1171
1637
  strcpy(ptr->getString(), insert_string.c_str());
1172
1638
  return(ptr);
1183
1649
build_select_string(bool key)
1184
1650
{
1185
1651
  char       buf[HUGE_STRING_LENGTH];
1186
 
  uint32_t        col_count;
 
1652
  unsigned int        col_count;
1187
1653
  Statement *ptr;
1188
1654
  string query_string;
1189
1655
 
1190
1656
  query_string.reserve(HUGE_STRING_LENGTH);
1191
1657
 
1192
1658
  query_string.append("SELECT ", 7);
1193
 
  if (not auto_generate_selected_columns_opt.empty())
 
1659
  if (!auto_generate_selected_columns_opt.empty())
1194
1660
  {
1195
1661
    query_string.append(auto_generate_selected_columns_opt.c_str());
1196
1662
  }
1202
1668
          > HUGE_STRING_LENGTH)
1203
1669
      {
1204
1670
        fprintf(stderr, "Memory Allocation error in creating select\n");
1205
 
        abort();
 
1671
        exit(1);
1206
1672
      }
1207
1673
      query_string.append(buf);
1208
1674
 
1216
1682
          > HUGE_STRING_LENGTH)
1217
1683
      {
1218
1684
        fprintf(stderr, "Memory Allocation error in creating select\n");
1219
 
        abort();
 
1685
        exit(1);
1220
1686
      }
1221
1687
      query_string.append(buf);
1222
1688
 
1230
1696
          > HUGE_STRING_LENGTH)
1231
1697
      {
1232
1698
        fprintf(stderr, "Memory Allocation error in creating select\n");
1233
 
        abort();
 
1699
        exit(1);
1234
1700
      }
1235
1701
      query_string.append(buf);
1236
1702
 
1244
1710
      (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary))
1245
1711
    query_string.append(" WHERE id = ");
1246
1712
 
1247
 
  ptr= new Statement;
1248
 
  ptr->setString(query_string.length());
 
1713
  ptr= (Statement *)malloc(sizeof(Statement));
 
1714
  if (ptr == NULL)
 
1715
  {
 
1716
    fprintf(stderr, "Memory Allocation error in creating select\n");
 
1717
    exit(1);
 
1718
  }
 
1719
  memset(ptr, 0, sizeof(Statement));
 
1720
  ptr->setLength(query_string.length()+1);
 
1721
  ptr->setString((char *)malloc(ptr->getLength()));
1249
1722
  if (ptr->getString() == NULL)
1250
1723
  {
1251
1724
    fprintf(stderr, "Memory Allocation error in creating select\n");
1252
 
    abort();
 
1725
    exit(1);
1253
1726
  }
 
1727
  memset(ptr->getString(), 0, ptr->getLength());
1254
1728
  if ((key) &&
1255
1729
      (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary))
1256
1730
    ptr->setType(SELECT_TYPE_REQUIRES_PREFIX);
1263
1737
static int
1264
1738
process_options(void)
1265
1739
{
 
1740
  char *tmp_string;
1266
1741
  struct stat sbuf;
1267
1742
  OptionString *sql_type;
1268
 
  uint32_t sql_type_count= 0;
 
1743
  unsigned int sql_type_count= 0;
1269
1744
  ssize_t bytes_read= 0;
1270
1745
  
1271
1746
  if (user.empty())
1274
1749
  verbose= opt_verbose.length();
1275
1750
 
1276
1751
  /* If something is created we clean it up, otherwise we leave schemas alone */
1277
 
  if ( (not create_string.empty()) || auto_generate_sql)
 
1752
  if ( (!create_string.empty()) || auto_generate_sql)
1278
1753
    opt_preserve= false;
1279
1754
 
1280
 
  if (auto_generate_sql && (not create_string.empty() || !user_supplied_query.empty()))
 
1755
  if (auto_generate_sql && (!create_string.empty() || !user_supplied_query.empty()))
1281
1756
  {
1282
1757
    fprintf(stderr,
1283
1758
            "%s: Can't use --auto-generate-sql when create and query strings are specified!\n",
1284
 
            SLAP_NAME);
1285
 
    abort();
 
1759
            internal::my_progname);
 
1760
    exit(1);
1286
1761
  }
1287
1762
 
1288
1763
  if (auto_generate_sql && auto_generate_sql_guid_primary &&
1290
1765
  {
1291
1766
    fprintf(stderr,
1292
1767
            "%s: Either auto-generate-sql-guid-primary or auto-generate-sql-add-autoincrement can be used!\n",
1293
 
            SLAP_NAME);
1294
 
    abort();
 
1768
            internal::my_progname);
 
1769
    exit(1);
1295
1770
  }
1296
1771
 
1297
1772
  if (auto_generate_sql && num_of_query && auto_actual_queries)
1298
1773
  {
1299
1774
    fprintf(stderr,
1300
1775
            "%s: Either auto-generate-sql-execute-number or number-of-queries can be used!\n",
1301
 
            SLAP_NAME);
1302
 
    abort();
 
1776
            internal::my_progname);
 
1777
    exit(1);
1303
1778
  }
1304
1779
 
1305
 
  parse_comma(not concurrency_str.empty() ? concurrency_str.c_str() : "1", concurrency);
 
1780
  parse_comma(!concurrency_str.empty() ? concurrency_str.c_str() : "1", &concurrency);
1306
1781
 
1307
 
  if (not opt_csv_str.empty())
 
1782
  if (!opt_csv_str.empty())
1308
1783
  {
1309
1784
    opt_silent= true;
1310
1785
 
1318
1793
                          S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1)
1319
1794
      {
1320
1795
        fprintf(stderr,"%s: Could not open csv file: %sn\n",
1321
 
                SLAP_NAME, opt_csv_str.c_str());
1322
 
        abort();
 
1796
                internal::my_progname, opt_csv_str.c_str());
 
1797
        exit(1);
1323
1798
      }
1324
1799
    }
1325
1800
  }
1327
1802
  if (opt_only_print)
1328
1803
    opt_silent= true;
1329
1804
 
1330
 
  if (not num_int_cols_opt.empty())
 
1805
  if (!num_int_cols_opt.empty())
1331
1806
  {
1332
1807
    OptionString *str;
1333
1808
    parse_option(num_int_cols_opt.c_str(), &str, ',');
1337
1812
    option_cleanup(str);
1338
1813
  }
1339
1814
 
1340
 
  if (not num_char_cols_opt.empty())
 
1815
  if (!num_char_cols_opt.empty())
1341
1816
  {
1342
1817
    OptionString *str;
1343
1818
    parse_option(num_char_cols_opt.c_str(), &str, ',');
1349
1824
    option_cleanup(str);
1350
1825
  }
1351
1826
 
1352
 
  if (not num_blob_cols_opt.empty())
 
1827
  if (!num_blob_cols_opt.empty())
1353
1828
  {
1354
1829
    OptionString *str;
1355
1830
    parse_option(num_blob_cols_opt.c_str(), &str, ',');
1405
1880
    query_statements_count=
1406
1881
      parse_option(opt_auto_generate_sql_type.c_str(), &query_options, ',');
1407
1882
 
1408
 
    query_statements.resize(query_statements_count);
 
1883
    query_statements= (Statement **)malloc(sizeof(Statement *) * query_statements_count);
 
1884
    if (query_statements == NULL)
 
1885
    {
 
1886
      fprintf(stderr, "Memory Allocation error in Building Query Statements\n");
 
1887
      exit(1);
 
1888
    }
 
1889
    memset(query_statements, 0, sizeof(Statement *) * query_statements_count);
1409
1890
 
1410
1891
    sql_type= query_options;
1411
1892
    do
1433
1914
        {
1434
1915
          fprintf(stderr,
1435
1916
                  "%s: Can't perform key test without a primary key!\n",
1436
 
                  SLAP_NAME);
1437
 
          abort();
 
1917
                  internal::my_progname);
 
1918
          exit(1);
1438
1919
        }
1439
1920
 
1440
1921
        query_statements[sql_type_count]= build_select_string(true);
1469
1950
        {
1470
1951
          fprintf(stderr,
1471
1952
                  "%s: Can't perform update test without a primary key!\n",
1472
 
                  SLAP_NAME);
1473
 
          abort();
 
1953
                  internal::my_progname);
 
1954
          exit(1);
1474
1955
        }
1475
1956
 
1476
1957
        query_statements[sql_type_count]= build_update_string();
1511
1992
  }
1512
1993
  else
1513
1994
  {
1514
 
    if (not create_string.empty() && !stat(create_string.c_str(), &sbuf))
 
1995
    if (!create_string.empty() && !stat(create_string.c_str(), &sbuf))
1515
1996
    {
1516
1997
      int data_file;
1517
 
      std::vector<char> tmp_string;
1518
 
      if (not S_ISREG(sbuf.st_mode))
 
1998
      if (!S_ISREG(sbuf.st_mode))
1519
1999
      {
1520
2000
        fprintf(stderr,"%s: Create file was not a regular file\n",
1521
 
                SLAP_NAME);
1522
 
        abort();
 
2001
                internal::my_progname);
 
2002
        exit(1);
1523
2003
      }
1524
2004
      if ((data_file= open(create_string.c_str(), O_RDWR)) == -1)
1525
2005
      {
1526
 
        fprintf(stderr,"%s: Could not open create file\n", SLAP_NAME);
1527
 
        abort();
 
2006
        fprintf(stderr,"%s: Could not open create file\n", internal::my_progname);
 
2007
        exit(1);
1528
2008
      }
1529
2009
      if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1530
2010
      {
1531
2011
        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],
 
2012
        exit(1);
 
2013
      }
 
2014
      tmp_string= (char *)malloc((size_t)(sbuf.st_size + 1));
 
2015
      if (tmp_string == NULL)
 
2016
      {
 
2017
        fprintf(stderr, "Memory Allocation error in option processing\n");
 
2018
        exit(1);
 
2019
      }
 
2020
      memset(tmp_string, 0, (size_t)(sbuf.st_size + 1));
 
2021
      bytes_read= read(data_file, (unsigned char*) tmp_string,
1536
2022
                       (size_t)sbuf.st_size);
 
2023
      tmp_string[sbuf.st_size]= '\0';
1537
2024
      close(data_file);
1538
2025
      if (bytes_read != sbuf.st_size)
1539
2026
      {
1540
2027
        fprintf(stderr, "Problem reading file: read less bytes than requested\n");
1541
2028
      }
1542
 
      parse_delimiter(&tmp_string[0], &create_statements, delimiter[0]);
 
2029
      parse_delimiter(tmp_string, &create_statements, delimiter[0]);
 
2030
      free(tmp_string);
1543
2031
    }
1544
 
    else if (not create_string.empty())
 
2032
    else if (!create_string.empty())
1545
2033
    {
1546
2034
      parse_delimiter(create_string.c_str(), &create_statements, delimiter[0]);
1547
2035
    }
1548
2036
 
1549
2037
    /* Set this up till we fully support options on user generated queries */
1550
 
    if (not user_supplied_query.empty())
 
2038
    if (!user_supplied_query.empty())
1551
2039
    {
1552
2040
      query_statements_count=
1553
2041
        parse_option("default", &query_options, ',');
1554
2042
 
1555
 
      query_statements.resize(query_statements_count);
 
2043
      query_statements= (Statement **)malloc(sizeof(Statement *) * query_statements_count);
 
2044
      if (query_statements == NULL)
 
2045
      {
 
2046
        fprintf(stderr, "Memory Allocation error in option processing\n");
 
2047
        exit(1);
 
2048
      }
 
2049
      memset(query_statements, 0, sizeof(Statement *) * query_statements_count); 
1556
2050
    }
1557
2051
 
1558
 
    if (not user_supplied_query.empty() && !stat(user_supplied_query.c_str(), &sbuf))
 
2052
    if (!user_supplied_query.empty() && !stat(user_supplied_query.c_str(), &sbuf))
1559
2053
    {
1560
2054
      int data_file;
1561
 
      std::vector<char> tmp_string;
1562
 
 
1563
 
      if (not S_ISREG(sbuf.st_mode))
 
2055
      if (!S_ISREG(sbuf.st_mode))
1564
2056
      {
1565
2057
        fprintf(stderr,"%s: User query supplied file was not a regular file\n",
1566
 
                SLAP_NAME);
1567
 
        abort();
 
2058
                internal::my_progname);
 
2059
        exit(1);
1568
2060
      }
1569
2061
      if ((data_file= open(user_supplied_query.c_str(), O_RDWR)) == -1)
1570
2062
      {
1571
 
        fprintf(stderr,"%s: Could not open query supplied file\n", SLAP_NAME);
1572
 
        abort();
 
2063
        fprintf(stderr,"%s: Could not open query supplied file\n", internal::my_progname);
 
2064
        exit(1);
1573
2065
      }
1574
2066
      if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1575
2067
      {
1576
2068
        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],
 
2069
        exit(1);
 
2070
      }
 
2071
      tmp_string= (char *)malloc((size_t)(sbuf.st_size + 1));
 
2072
      if (tmp_string == NULL)
 
2073
      {
 
2074
        fprintf(stderr, "Memory Allocation error in option processing\n");
 
2075
        exit(1);
 
2076
      }
 
2077
      memset(tmp_string, 0, (size_t)(sbuf.st_size + 1));
 
2078
      bytes_read= read(data_file, (unsigned char*) tmp_string,
1581
2079
                       (size_t)sbuf.st_size);
 
2080
      tmp_string[sbuf.st_size]= '\0';
1582
2081
      close(data_file);
1583
2082
      if (bytes_read != sbuf.st_size)
1584
2083
      {
1585
2084
        fprintf(stderr, "Problem reading file: read less bytes than requested\n");
1586
2085
      }
1587
 
      if (not user_supplied_query.empty())
1588
 
        actual_queries= parse_delimiter(&tmp_string[0], &query_statements[0],
 
2086
      if (!user_supplied_query.empty())
 
2087
        actual_queries= parse_delimiter(tmp_string, &query_statements[0],
1589
2088
                                        delimiter[0]);
 
2089
      free(tmp_string);
1590
2090
    }
1591
 
    else if (not user_supplied_query.empty())
 
2091
    else if (!user_supplied_query.empty())
1592
2092
    {
1593
2093
      actual_queries= parse_delimiter(user_supplied_query.c_str(), &query_statements[0],
1594
2094
                                      delimiter[0]);
1595
2095
    }
1596
2096
  }
1597
2097
 
1598
 
  if (not user_supplied_pre_statements.empty()
 
2098
  if (!user_supplied_pre_statements.empty()
1599
2099
      && !stat(user_supplied_pre_statements.c_str(), &sbuf))
1600
2100
  {
1601
2101
    int data_file;
1602
 
    std::vector<char> tmp_string;
1603
 
 
1604
 
    if (not S_ISREG(sbuf.st_mode))
 
2102
    if (!S_ISREG(sbuf.st_mode))
1605
2103
    {
1606
2104
      fprintf(stderr,"%s: User query supplied file was not a regular file\n",
1607
 
              SLAP_NAME);
1608
 
      abort();
 
2105
              internal::my_progname);
 
2106
      exit(1);
1609
2107
    }
1610
2108
    if ((data_file= open(user_supplied_pre_statements.c_str(), O_RDWR)) == -1)
1611
2109
    {
1612
 
      fprintf(stderr,"%s: Could not open query supplied file\n", SLAP_NAME);
1613
 
      abort();
 
2110
      fprintf(stderr,"%s: Could not open query supplied file\n", internal::my_progname);
 
2111
      exit(1);
1614
2112
    }
1615
2113
    if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1616
2114
    {
1617
2115
      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],
 
2116
      exit(1);
 
2117
    }
 
2118
    tmp_string= (char *)malloc((size_t)(sbuf.st_size + 1));
 
2119
    if (tmp_string == NULL)
 
2120
    {
 
2121
      fprintf(stderr, "Memory Allocation error in option processing\n");
 
2122
      exit(1);
 
2123
    }
 
2124
    memset(tmp_string, 0, (size_t)(sbuf.st_size + 1));
 
2125
    bytes_read= read(data_file, (unsigned char*) tmp_string,
1622
2126
                     (size_t)sbuf.st_size);
 
2127
    tmp_string[sbuf.st_size]= '\0';
1623
2128
    close(data_file);
1624
2129
    if (bytes_read != sbuf.st_size)
1625
2130
    {
1626
2131
      fprintf(stderr, "Problem reading file: read less bytes than requested\n");
1627
2132
    }
1628
 
    if (not user_supplied_pre_statements.empty())
1629
 
      (void)parse_delimiter(&tmp_string[0], &pre_statements,
 
2133
    if (!user_supplied_pre_statements.empty())
 
2134
      (void)parse_delimiter(tmp_string, &pre_statements,
1630
2135
                            delimiter[0]);
 
2136
    free(tmp_string);
1631
2137
  }
1632
 
  else if (not user_supplied_pre_statements.empty())
 
2138
  else if (!user_supplied_pre_statements.empty())
1633
2139
  {
1634
2140
    (void)parse_delimiter(user_supplied_pre_statements.c_str(),
1635
2141
                          &pre_statements,
1636
2142
                          delimiter[0]);
1637
2143
  }
1638
2144
 
1639
 
  if (not user_supplied_post_statements.empty()
 
2145
  if (!user_supplied_post_statements.empty()
1640
2146
      && !stat(user_supplied_post_statements.c_str(), &sbuf))
1641
2147
  {
1642
2148
    int data_file;
1643
 
    std::vector<char> tmp_string;
1644
 
 
1645
 
    if (not S_ISREG(sbuf.st_mode))
 
2149
    if (!S_ISREG(sbuf.st_mode))
1646
2150
    {
1647
2151
      fprintf(stderr,"%s: User query supplied file was not a regular file\n",
1648
 
              SLAP_NAME);
1649
 
      abort();
 
2152
              internal::my_progname);
 
2153
      exit(1);
1650
2154
    }
1651
2155
    if ((data_file= open(user_supplied_post_statements.c_str(), O_RDWR)) == -1)
1652
2156
    {
1653
 
      fprintf(stderr,"%s: Could not open query supplied file\n", SLAP_NAME);
1654
 
      abort();
 
2157
      fprintf(stderr,"%s: Could not open query supplied file\n", internal::my_progname);
 
2158
      exit(1);
1655
2159
    }
1656
2160
 
1657
2161
    if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1658
2162
    {
1659
2163
      fprintf(stderr, "Request for more memory than architecture supports\n");
1660
 
      abort();
1661
 
    }
1662
 
    tmp_string.resize((size_t)(sbuf.st_size + 1));
 
2164
      exit(1);
 
2165
    }
 
2166
    tmp_string= (char *)malloc((size_t)(sbuf.st_size + 1));
 
2167
    if (tmp_string == NULL)
 
2168
    {
 
2169
      fprintf(stderr, "Memory Allocation error in option processing\n");
 
2170
      exit(1);
 
2171
    }
 
2172
    memset(tmp_string, 0, (size_t)(sbuf.st_size+1));
1663
2173
 
1664
 
    bytes_read= read(data_file, (unsigned char*) &tmp_string[0],
 
2174
    bytes_read= read(data_file, (unsigned char*) tmp_string,
1665
2175
                     (size_t)(sbuf.st_size));
 
2176
    tmp_string[sbuf.st_size]= '\0';
1666
2177
    close(data_file);
1667
2178
    if (bytes_read != sbuf.st_size)
1668
2179
    {
1669
2180
      fprintf(stderr, "Problem reading file: read less bytes than requested\n");
1670
2181
    }
1671
 
    if (not user_supplied_post_statements.empty())
1672
 
      (void)parse_delimiter(&tmp_string[0], &post_statements,
 
2182
    if (!user_supplied_post_statements.empty())
 
2183
      (void)parse_delimiter(tmp_string, &post_statements,
1673
2184
                            delimiter[0]);
 
2185
    free(tmp_string);
1674
2186
  }
1675
 
  else if (not user_supplied_post_statements.empty())
 
2187
  else if (!user_supplied_post_statements.empty())
1676
2188
  {
1677
2189
    (void)parse_delimiter(user_supplied_post_statements.c_str(), &post_statements,
1678
2190
                          delimiter[0]);
1681
2193
  if (verbose >= 2)
1682
2194
    printf("Parsing engines to use.\n");
1683
2195
 
1684
 
  if (not default_engine.empty())
 
2196
  if (!default_engine.empty())
1685
2197
    parse_option(default_engine.c_str(), &engine_options, ',');
1686
2198
 
1687
2199
  if (tty_password)
1690
2202
}
1691
2203
 
1692
2204
 
1693
 
static int run_query(drizzle_con_st &con, drizzle_result_st *result,
 
2205
static int run_query(drizzle_con_st *con, drizzle_result_st *result,
1694
2206
                     const char *query, int len)
1695
2207
{
1696
2208
  drizzle_return_t ret;
1698
2210
 
1699
2211
  if (opt_only_print)
1700
2212
  {
1701
 
    printf("/* CON: %" PRIu64 " */ %.*s;\n",
1702
 
           (uint64_t)drizzle_context(drizzle_con_drizzle(&con)),
1703
 
           len, query);
 
2213
    printf("%.*s;\n", len, query);
1704
2214
    return 0;
1705
2215
  }
1706
2216
 
1710
2220
  if (result == NULL)
1711
2221
    result= &result_buffer;
1712
2222
 
1713
 
  result= drizzle_query(&con, result, query, len, &ret);
 
2223
  result= drizzle_query(con, result, query, len, &ret);
1714
2224
 
1715
2225
  if (ret == DRIZZLE_RETURN_OK)
1716
2226
    ret= drizzle_result_buffer(result);
1723
2233
 
1724
2234
 
1725
2235
static int
1726
 
generate_primary_key_list(drizzle_con_st &con, OptionString *engine_stmt)
 
2236
generate_primary_key_list(drizzle_con_st *con, OptionString *engine_stmt)
1727
2237
{
1728
2238
  drizzle_result_st result;
1729
2239
  drizzle_row_t row;
1737
2247
  if (opt_only_print || (engine_stmt &&
1738
2248
                         strstr(engine_stmt->getString(), "blackhole")))
1739
2249
  {
 
2250
    primary_keys_number_of= 1;
 
2251
    primary_keys= (char **)malloc((sizeof(char *) *
 
2252
                                  primary_keys_number_of));
 
2253
    if (primary_keys == NULL)
 
2254
    {
 
2255
      fprintf(stderr, "Memory Allocation error in option processing\n");
 
2256
      exit(1);
 
2257
    }
 
2258
    
 
2259
    memset(primary_keys, 0, (sizeof(char *) * primary_keys_number_of));
1740
2260
    /* Yes, we strdup a const string to simplify the interface */
1741
 
    primary_keys.push_back("796c4422-1d94-102a-9d6d-00e0812d");
 
2261
    primary_keys[0]= strdup("796c4422-1d94-102a-9d6d-00e0812d");
 
2262
    if (primary_keys[0] == NULL)
 
2263
    {
 
2264
      fprintf(stderr, "Memory Allocation error in option processing\n");
 
2265
      exit(1);
 
2266
    }
1742
2267
  }
1743
2268
  else
1744
2269
  {
1745
2270
    if (run_query(con, &result, "SELECT id from t1", strlen("SELECT id from t1")))
1746
2271
    {
1747
 
      fprintf(stderr,"%s: Cannot select GUID primary keys. (%s)\n", SLAP_NAME,
1748
 
              drizzle_con_error(&con));
1749
 
      abort();
 
2272
      fprintf(stderr,"%s: Cannot select GUID primary keys. (%s)\n", internal::my_progname,
 
2273
              drizzle_con_error(con));
 
2274
      exit(1);
1750
2275
    }
1751
2276
 
1752
2277
    uint64_t num_rows_ret= drizzle_result_row_count(&result);
1753
2278
    if (num_rows_ret > SIZE_MAX)
1754
2279
    {
1755
2280
      fprintf(stderr, "More primary keys than than architecture supports\n");
1756
 
      abort();
 
2281
      exit(1);
1757
2282
    }
1758
 
    size_t primary_keys_number_of;
1759
2283
    primary_keys_number_of= (size_t)num_rows_ret;
1760
2284
 
1761
2285
    /* So why check this? Blackhole :) */
1764
2288
      /*
1765
2289
        We create the structure and loop and create the items.
1766
2290
      */
 
2291
      primary_keys= (char **)malloc(sizeof(char *) *
 
2292
                                    primary_keys_number_of);
 
2293
      if (primary_keys == NULL)
 
2294
      {
 
2295
        fprintf(stderr, "Memory Allocation error in option processing\n");
 
2296
        exit(1);
 
2297
      }
 
2298
      memset(primary_keys, 0, (size_t)(sizeof(char *) * primary_keys_number_of));
1767
2299
      row= drizzle_row_next(&result);
1768
2300
      for (counter= 0; counter < primary_keys_number_of;
1769
2301
           counter++, row= drizzle_row_next(&result))
1770
2302
      {
1771
 
        primary_keys.push_back(row[0]);
 
2303
        primary_keys[counter]= strdup(row[0]);
 
2304
        if (primary_keys[counter] == NULL)
 
2305
        {
 
2306
          fprintf(stderr, "Memory Allocation error in option processing\n");
 
2307
          exit(1);
 
2308
        }
1772
2309
      }
1773
2310
    }
1774
2311
 
1778
2315
  return(0);
1779
2316
}
1780
2317
 
1781
 
static void create_schema(drizzle_con_st &con, const char *db, Statement *stmt, OptionString *engine_stmt, Stats *sptr)
 
2318
static int
 
2319
drop_primary_key_list(void)
 
2320
{
 
2321
  uint64_t counter;
 
2322
 
 
2323
  if (primary_keys_number_of)
 
2324
  {
 
2325
    for (counter= 0; counter < primary_keys_number_of; counter++)
 
2326
      free(primary_keys[counter]);
 
2327
 
 
2328
    free(primary_keys);
 
2329
  }
 
2330
 
 
2331
  return 0;
 
2332
}
 
2333
 
 
2334
static int
 
2335
create_schema(drizzle_con_st *con, const char *db, Statement *stmt,
 
2336
              OptionString *engine_stmt, Stats *sptr)
1782
2337
{
1783
2338
  char query[HUGE_STRING_LENGTH];
1784
2339
  Statement *ptr;
1785
2340
  Statement *after_create;
1786
2341
  int len;
 
2342
  uint64_t count;
1787
2343
  struct timeval start_time, end_time;
1788
2344
 
1789
2345
 
1796
2352
 
1797
2353
  if (run_query(con, NULL, query, len))
1798
2354
  {
1799
 
    fprintf(stderr,"%s: Cannot create schema %s : %s\n", SLAP_NAME, db,
1800
 
            drizzle_con_error(&con));
1801
 
    abort();
 
2355
    fprintf(stderr,"%s: Cannot create schema %s : %s\n", internal::my_progname, db,
 
2356
            drizzle_con_error(con));
 
2357
    exit(1);
1802
2358
  }
1803
2359
  else
1804
2360
  {
1807
2363
 
1808
2364
  if (opt_only_print)
1809
2365
  {
1810
 
    printf("/* CON: %" PRIu64 " */ use %s;\n",
1811
 
           (uint64_t)drizzle_context(drizzle_con_drizzle(&con)),
1812
 
           db);
 
2366
    printf("use %s;\n", db);
1813
2367
  }
1814
2368
  else
1815
2369
  {
1819
2373
    if (verbose >= 3)
1820
2374
      printf("%s;\n", query);
1821
2375
 
1822
 
    if (drizzle_select_db(&con,  &result, db, &ret) == NULL ||
 
2376
    if (drizzle_select_db(con,  &result, db, &ret) == NULL ||
1823
2377
        ret != DRIZZLE_RETURN_OK)
1824
2378
    {
1825
 
      fprintf(stderr,"%s: Cannot select schema '%s': %s\n",SLAP_NAME, db,
 
2379
      fprintf(stderr,"%s: Cannot select schema '%s': %s\n",internal::my_progname, db,
1826
2380
              ret == DRIZZLE_RETURN_ERROR_CODE ?
1827
 
              drizzle_result_error(&result) : drizzle_con_error(&con));
1828
 
      abort();
 
2381
              drizzle_result_error(&result) : drizzle_con_error(con));
 
2382
      exit(1);
1829
2383
    }
1830
2384
    drizzle_result_free(&result);
1831
2385
    sptr->setCreateCount(sptr->getCreateCount()+1);
1837
2391
                  engine_stmt->getString());
1838
2392
    if (run_query(con, NULL, query, len))
1839
2393
    {
1840
 
      fprintf(stderr,"%s: Cannot set default engine: %s\n", SLAP_NAME,
1841
 
              drizzle_con_error(&con));
1842
 
      abort();
 
2394
      fprintf(stderr,"%s: Cannot set default engine: %s\n", internal::my_progname,
 
2395
              drizzle_con_error(con));
 
2396
      exit(1);
1843
2397
    }
1844
2398
    sptr->setCreateCount(sptr->getCreateCount()+1);
1845
2399
  }
1846
2400
 
1847
 
  uint64_t count= 0;
 
2401
  count= 0;
1848
2402
  after_create= stmt;
1849
2403
 
1850
2404
limit_not_met:
1862
2416
      if (run_query(con, NULL, buffer, strlen(buffer)))
1863
2417
      {
1864
2418
        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();
 
2419
                internal::my_progname, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(con));
 
2420
        if (!opt_ignore_sql_errors)
 
2421
          exit(1);
1868
2422
      }
1869
2423
      sptr->setCreateCount(sptr->getCreateCount()+1);
1870
2424
    }
1873
2427
      if (run_query(con, NULL, ptr->getString(), ptr->getLength()))
1874
2428
      {
1875
2429
        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();
 
2430
                internal::my_progname, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(con));
 
2431
        if (!opt_ignore_sql_errors)
 
2432
          exit(1);
1879
2433
      }
1880
2434
      sptr->setCreateCount(sptr->getCreateCount()+1);
1881
2435
    }
1891
2445
  gettimeofday(&end_time, NULL);
1892
2446
 
1893
2447
  sptr->setCreateTiming(timedif(end_time, start_time));
 
2448
 
 
2449
  return(0);
1894
2450
}
1895
2451
 
1896
 
static void drop_schema(drizzle_con_st &con, const char *db)
 
2452
static int
 
2453
drop_schema(drizzle_con_st *con, const char *db)
1897
2454
{
1898
2455
  char query[HUGE_STRING_LENGTH];
1899
2456
  int len;
1903
2460
  if (run_query(con, NULL, query, len))
1904
2461
  {
1905
2462
    fprintf(stderr,"%s: Cannot drop database '%s' ERROR : %s\n",
1906
 
            SLAP_NAME, db, drizzle_con_error(&con));
1907
 
    abort();
 
2463
            internal::my_progname, db, drizzle_con_error(con));
 
2464
    exit(1);
1908
2465
  }
 
2466
 
 
2467
 
 
2468
 
 
2469
  return(0);
1909
2470
}
1910
2471
 
1911
 
static void run_statements(drizzle_con_st &con, Statement *stmt)
 
2472
static int
 
2473
run_statements(drizzle_con_st *con, Statement *stmt)
1912
2474
{
1913
 
  for (Statement *ptr= stmt; ptr && ptr->getLength(); ptr= ptr->getNext())
 
2475
  Statement *ptr;
 
2476
 
 
2477
  for (ptr= stmt; ptr && ptr->getLength(); ptr= ptr->getNext())
1914
2478
  {
1915
2479
    if (run_query(con, NULL, ptr->getString(), ptr->getLength()))
1916
2480
    {
1917
2481
      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();
 
2482
              internal::my_progname, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(con));
 
2483
      exit(1);
1920
2484
    }
1921
2485
  }
 
2486
 
 
2487
  return(0);
1922
2488
}
1923
2489
 
1924
 
 
1925
 
static void timer_thread()
 
2490
static int
 
2491
run_scheduler(Stats *sptr, Statement **stmts, uint32_t concur, uint64_t limit)
1926
2492
{
 
2493
  uint32_t x;
 
2494
  uint32_t y;
 
2495
  unsigned int real_concurrency;
 
2496
  struct timeval start_time, end_time;
 
2497
  OptionString *sql_type;
 
2498
  ThreadContext *con;
 
2499
  pthread_t mainthread;            /* Thread descriptor */
 
2500
  pthread_attr_t attr;          /* Thread attributes */
 
2501
 
 
2502
 
 
2503
  pthread_attr_init(&attr);
 
2504
  pthread_attr_setdetachstate(&attr,
 
2505
                              PTHREAD_CREATE_DETACHED);
 
2506
 
 
2507
  pthread_mutex_lock(&counter_mutex);
 
2508
  thread_counter= 0;
 
2509
 
 
2510
  pthread_mutex_lock(&sleeper_mutex);
 
2511
  master_wakeup= 1;
 
2512
  pthread_mutex_unlock(&sleeper_mutex);
 
2513
 
 
2514
  real_concurrency= 0;
 
2515
 
 
2516
  for (y= 0, sql_type= query_options;
 
2517
       y < query_statements_count;
 
2518
       y++, sql_type= sql_type->getNext())
 
2519
  {
 
2520
    unsigned int options_loop= 1;
 
2521
 
 
2522
    if (sql_type->getOption())
 
2523
    {
 
2524
      options_loop= strtol(sql_type->getOption(),
 
2525
                           (char **)NULL, 10);
 
2526
      options_loop= options_loop ? options_loop : 1;
 
2527
    }
 
2528
 
 
2529
    while (options_loop--)
 
2530
      for (x= 0; x < concur; x++)
 
2531
      {
 
2532
        con= (ThreadContext *)malloc(sizeof(ThreadContext));
 
2533
        if (con == NULL)
 
2534
        {
 
2535
          fprintf(stderr, "Memory Allocation error in scheduler\n");
 
2536
          exit(1);
 
2537
        }
 
2538
        con->setStmt(stmts[y]);
 
2539
        con->setLimit(limit);
 
2540
 
 
2541
        real_concurrency++;
 
2542
        /* now you create the thread */
 
2543
        if (pthread_create(&mainthread, &attr, run_task,
 
2544
                           (void *)con) != 0)
 
2545
        {
 
2546
          fprintf(stderr,"%s: Could not create thread\n", internal::my_progname);
 
2547
          exit(1);
 
2548
        }
 
2549
        thread_counter++;
 
2550
      }
 
2551
  }
 
2552
 
1927
2553
  /*
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.
 
2554
    The timer_thread belongs to all threads so it too obeys the wakeup
 
2555
    call that run tasks obey.
1930
2556
  */
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();
 
2557
  if (opt_timer_length)
 
2558
  {
 
2559
    pthread_mutex_lock(&timer_alarm_mutex);
 
2560
    timer_alarm= true;
 
2561
    pthread_mutex_unlock(&timer_alarm_mutex);
 
2562
 
 
2563
    if (pthread_create(&mainthread, &attr, timer_thread,
 
2564
                       (void *)&opt_timer_length) != 0)
 
2565
    {
 
2566
      fprintf(stderr,"%s: Could not create timer thread\n", internal::my_progname);
 
2567
      exit(1);
 
2568
    }
 
2569
  }
 
2570
 
 
2571
  pthread_mutex_unlock(&counter_mutex);
 
2572
  pthread_attr_destroy(&attr);
 
2573
 
 
2574
  pthread_mutex_lock(&sleeper_mutex);
 
2575
  master_wakeup= 0;
 
2576
  pthread_mutex_unlock(&sleeper_mutex);
 
2577
  pthread_cond_broadcast(&sleep_threshhold);
2022
2578
 
2023
2579
  gettimeofday(&start_time, NULL);
2024
2580
 
2025
2581
  /*
2026
2582
    We loop until we know that all children have cleaned up.
2027
2583
  */
2028
 
  for (Threads::iterator iter= threads.begin(); iter != threads.end(); iter++)
 
2584
  pthread_mutex_lock(&counter_mutex);
 
2585
  while (thread_counter)
2029
2586
  {
2030
 
    (*iter)->join();
 
2587
    struct timespec abstime;
 
2588
 
 
2589
    set_timespec(abstime, 3);
 
2590
    pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
2031
2591
  }
 
2592
  pthread_mutex_unlock(&counter_mutex);
2032
2593
 
2033
2594
  gettimeofday(&end_time, NULL);
2034
2595
 
 
2596
 
2035
2597
  sptr->setTiming(timedif(end_time, start_time));
2036
2598
  sptr->setUsers(concur);
2037
2599
  sptr->setRealUsers(real_concurrency);
2038
2600
  sptr->setRows(limit);
 
2601
 
 
2602
  return(0);
 
2603
}
 
2604
 
 
2605
 
 
2606
pthread_handler_t timer_thread(void *p)
 
2607
{
 
2608
  uint32_t *timer_length= (uint32_t *)p;
 
2609
  struct timespec abstime;
 
2610
 
 
2611
 
 
2612
  /*
 
2613
    We lock around the initial call in case were we in a loop. This
 
2614
    also keeps the value properly syncronized across call threads.
 
2615
  */
 
2616
  pthread_mutex_lock(&sleeper_mutex);
 
2617
  while (master_wakeup)
 
2618
  {
 
2619
    pthread_cond_wait(&sleep_threshhold, &sleeper_mutex);
 
2620
  }
 
2621
  pthread_mutex_unlock(&sleeper_mutex);
 
2622
 
 
2623
  set_timespec(abstime, *timer_length);
 
2624
 
 
2625
  pthread_mutex_lock(&timer_alarm_mutex);
 
2626
  pthread_cond_timedwait(&timer_alarm_threshold, &timer_alarm_mutex, &abstime);
 
2627
  pthread_mutex_unlock(&timer_alarm_mutex);
 
2628
 
 
2629
  pthread_mutex_lock(&timer_alarm_mutex);
 
2630
  timer_alarm= false;
 
2631
  pthread_mutex_unlock(&timer_alarm_mutex);
 
2632
 
 
2633
  return(0);
 
2634
}
 
2635
 
 
2636
pthread_handler_t run_task(void *p)
 
2637
{
 
2638
  uint64_t counter= 0, queries;
 
2639
  uint64_t detach_counter;
 
2640
  unsigned int commit_counter;
 
2641
  drizzle_con_st con;
 
2642
  drizzle_result_st result;
 
2643
  drizzle_row_t row;
 
2644
  Statement *ptr;
 
2645
  ThreadContext *ctx= (ThreadContext *)p;
 
2646
 
 
2647
  pthread_mutex_lock(&sleeper_mutex);
 
2648
  while (master_wakeup)
 
2649
  {
 
2650
    pthread_cond_wait(&sleep_threshhold, &sleeper_mutex);
 
2651
  }
 
2652
  pthread_mutex_unlock(&sleeper_mutex);
 
2653
 
 
2654
  slap_connect(&con, true);
 
2655
 
 
2656
  if (verbose >= 3)
 
2657
    printf("connected!\n");
 
2658
  queries= 0;
 
2659
 
 
2660
  commit_counter= 0;
 
2661
  if (commit_rate)
 
2662
    run_query(&con, NULL, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
 
2663
 
 
2664
limit_not_met:
 
2665
  for (ptr= ctx->getStmt(), detach_counter= 0;
 
2666
       ptr && ptr->getLength();
 
2667
       ptr= ptr->getNext(), detach_counter++)
 
2668
  {
 
2669
    if (!opt_only_print && detach_rate && !(detach_counter % detach_rate))
 
2670
    {
 
2671
      slap_close(&con);
 
2672
      slap_connect(&con, true);
 
2673
    }
 
2674
 
 
2675
    /*
 
2676
      We have to execute differently based on query type. This should become a function.
 
2677
    */
 
2678
    if ((ptr->getType() == UPDATE_TYPE_REQUIRES_PREFIX) ||
 
2679
        (ptr->getType() == SELECT_TYPE_REQUIRES_PREFIX))
 
2680
    {
 
2681
      int length;
 
2682
      unsigned int key_val;
 
2683
      char *key;
 
2684
      char buffer[HUGE_STRING_LENGTH];
 
2685
 
 
2686
      /*
 
2687
        This should only happen if some sort of new engine was
 
2688
        implemented that didn't properly handle UPDATEs.
 
2689
 
 
2690
        Just in case someone runs this under an experimental engine we don't
 
2691
        want a crash so the if() is placed here.
 
2692
      */
 
2693
      assert(primary_keys_number_of);
 
2694
      if (primary_keys_number_of)
 
2695
      {
 
2696
        key_val= (unsigned int)(random() % primary_keys_number_of);
 
2697
        key= primary_keys[key_val];
 
2698
 
 
2699
        assert(key);
 
2700
 
 
2701
        length= snprintf(buffer, HUGE_STRING_LENGTH, "%.*s '%s'",
 
2702
                         (int)ptr->getLength(), ptr->getString(), key);
 
2703
 
 
2704
        if (run_query(&con, &result, buffer, length))
 
2705
        {
 
2706
          fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
 
2707
                  internal::my_progname, (uint32_t)length, buffer, drizzle_con_error(&con));
 
2708
          exit(1);
 
2709
        }
 
2710
      }
 
2711
    }
 
2712
    else
 
2713
    {
 
2714
      if (run_query(&con, &result, ptr->getString(), ptr->getLength()))
 
2715
      {
 
2716
        fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
 
2717
                internal::my_progname, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(&con));
 
2718
        exit(1);
 
2719
      }
 
2720
    }
 
2721
 
 
2722
    if (!opt_only_print)
 
2723
    {
 
2724
      while ((row = drizzle_row_next(&result)))
 
2725
        counter++;
 
2726
      drizzle_result_free(&result);
 
2727
    }
 
2728
    queries++;
 
2729
 
 
2730
    if (commit_rate && (++commit_counter == commit_rate))
 
2731
    {
 
2732
      commit_counter= 0;
 
2733
      run_query(&con, NULL, "COMMIT", strlen("COMMIT"));
 
2734
    }
 
2735
 
 
2736
    /* If the timer is set, and the alarm is not active then end */
 
2737
    if (opt_timer_length && timer_alarm == false)
 
2738
      goto end;
 
2739
 
 
2740
    /* If limit has been reached, and we are not in a timer_alarm just end */
 
2741
    if (ctx->getLimit() && queries == ctx->getLimit() && timer_alarm == false)
 
2742
      goto end;
 
2743
  }
 
2744
 
 
2745
  if (opt_timer_length && timer_alarm == true)
 
2746
    goto limit_not_met;
 
2747
 
 
2748
  if (ctx->getLimit() && queries < ctx->getLimit())
 
2749
    goto limit_not_met;
 
2750
 
 
2751
 
 
2752
end:
 
2753
  if (commit_rate)
 
2754
    run_query(&con, NULL, "COMMIT", strlen("COMMIT"));
 
2755
 
 
2756
  slap_close(&con);
 
2757
 
 
2758
  pthread_mutex_lock(&counter_mutex);
 
2759
  thread_counter--;
 
2760
  pthread_cond_signal(&count_threshhold);
 
2761
  pthread_mutex_unlock(&counter_mutex);
 
2762
 
 
2763
  free(ctx);
 
2764
 
 
2765
  return(0);
2039
2766
}
2040
2767
 
2041
2768
/*
2042
2769
  Parse records from comma seperated string. : is a reserved character and is used for options
2043
2770
  on variables.
2044
2771
*/
2045
 
uint32_t parse_option(const char *origin, OptionString **stmt, char delm)
 
2772
uint
 
2773
parse_option(const char *origin, OptionString **stmt, char delm)
2046
2774
{
2047
2775
  char *string;
2048
2776
  char *begin_ptr;
2049
2777
  char *end_ptr;
 
2778
  OptionString **sptr= stmt;
 
2779
  OptionString *tmp;
2050
2780
  uint32_t length= strlen(origin);
2051
2781
  uint32_t count= 0; /* We know that there is always one */
2052
2782
 
2053
2783
  end_ptr= (char *)origin + length;
2054
2784
 
2055
 
  OptionString *tmp;
2056
 
  *stmt= tmp= new OptionString;
 
2785
  tmp= *sptr= (OptionString *)malloc(sizeof(OptionString));
 
2786
  if (tmp == NULL)
 
2787
  {
 
2788
    fprintf(stderr,"Error allocating memory while parsing options\n");
 
2789
    exit(1);
 
2790
  }
 
2791
  memset(tmp, 0, sizeof(OptionString));
2057
2792
 
2058
2793
  for (begin_ptr= (char *)origin;
2059
2794
       begin_ptr != end_ptr;
2085
2820
      buffer_ptr++;
2086
2821
 
2087
2822
      /* Move past the : and the first string */
2088
 
      tmp->setOption(buffer_ptr);
 
2823
      tmp->setOptionLength(strlen(buffer_ptr));
 
2824
      tmp->setOption((char *)malloc(tmp->getOptionLength() + 1));
 
2825
      if (tmp->getOption() == NULL)
 
2826
      {
 
2827
        fprintf(stderr,"Error allocating memory while parsing options\n");
 
2828
        exit(1);
 
2829
      }
 
2830
      memcpy(tmp->getOption(), buffer_ptr, tmp->getOptionLength());
 
2831
      tmp->setOption(tmp->getOptionLength(),0); 
2089
2832
    }
2090
2833
 
 
2834
    tmp->setLength(strlen(buffer));
2091
2835
    tmp->setString(strdup(buffer));
2092
2836
    if (tmp->getString() == NULL)
2093
2837
    {
2094
2838
      fprintf(stderr,"Error allocating memory while parsing options\n");
2095
 
      abort();
 
2839
      exit(1);
2096
2840
    }
2097
2841
 
2098
2842
    if (isspace(*begin_ptr))
2102
2846
 
2103
2847
    if (begin_ptr != end_ptr)
2104
2848
    {
2105
 
      tmp->setNext( new OptionString);
 
2849
      tmp->setNext((OptionString *)malloc(sizeof(OptionString)));
 
2850
      if (tmp->getNext() == NULL)
 
2851
      {
 
2852
        fprintf(stderr,"Error allocating memory while parsing options\n");
 
2853
        exit(1);
 
2854
      }
 
2855
      memset(tmp->getNext(), 0, sizeof(OptionString));
2106
2856
    }
2107
2857
    
2108
2858
  }
2115
2865
  Raw parsing interface. If you want the slap specific parser look at
2116
2866
  parse_option.
2117
2867
*/
2118
 
uint32_t parse_delimiter(const char *script, Statement **stmt, char delm)
 
2868
uint
 
2869
parse_delimiter(const char *script, Statement **stmt, char delm)
2119
2870
{
2120
2871
  char *retstr;
2121
2872
  char *ptr= (char *)script;
2124
2875
  uint32_t length= strlen(script);
2125
2876
  uint32_t count= 0; /* We know that there is always one */
2126
2877
 
2127
 
  for (tmp= *sptr= new Statement;
 
2878
  for (tmp= *sptr= (Statement *)calloc(1, sizeof(Statement));
2128
2879
       (retstr= strchr(ptr, delm));
2129
 
       tmp->setNext(new Statement),
 
2880
       tmp->setNext((Statement *)calloc(1, sizeof(Statement))),
2130
2881
       tmp= tmp->getNext())
2131
2882
  {
2132
2883
    if (tmp == NULL)
2133
2884
    {
2134
2885
      fprintf(stderr,"Error allocating memory while parsing delimiter\n");
2135
 
      abort();
 
2886
      exit(1);
2136
2887
    }
2137
2888
 
2138
2889
    count++;
2139
 
    tmp->setString((size_t)(retstr - ptr));
 
2890
    tmp->setLength((size_t)(retstr - ptr));
 
2891
    tmp->setString((char *)malloc(tmp->getLength() + 1));
2140
2892
 
2141
2893
    if (tmp->getString() == NULL)
2142
2894
    {
2143
2895
      fprintf(stderr,"Error allocating memory while parsing delimiter\n");
2144
 
      abort();
 
2896
      exit(1);
2145
2897
    }
2146
2898
 
2147
2899
    memcpy(tmp->getString(), ptr, tmp->getLength());
 
2900
    tmp->setString(tmp->getLength(), 0);
2148
2901
    ptr+= retstr - ptr + 1;
2149
2902
    if (isspace(*ptr))
2150
2903
      ptr++;
2152
2905
 
2153
2906
  if (ptr != script+length)
2154
2907
  {
2155
 
    tmp->setString((size_t)((script + length) - ptr));
 
2908
    tmp->setLength((size_t)((script + length) - ptr));
 
2909
    tmp->setString((char *)malloc(tmp->getLength() + 1));
2156
2910
    if (tmp->getString() == NULL)
2157
2911
    {
2158
2912
      fprintf(stderr,"Error allocating memory while parsing delimiter\n");
2159
 
      abort();
 
2913
      exit(1);
2160
2914
    }
2161
2915
    memcpy(tmp->getString(), ptr, tmp->getLength());
 
2916
    tmp->setString(tmp->getLength(),0);
2162
2917
    count++;
2163
2918
  }
2164
2919
 
2171
2926
  number ranges from a comma seperated string.
2172
2927
  In restrospect, this is a lousy name from this function.
2173
2928
*/
2174
 
uint32_t parse_comma(const char *string, std::vector <uint32_t> &range)
 
2929
uint
 
2930
parse_comma(const char *string, uint32_t **range)
2175
2931
{
2176
 
  uint32_t count= 1; /* We know that there is always one */
 
2932
  unsigned int count= 1,x; /* We know that there is always one */
2177
2933
  char *retstr;
2178
2934
  char *ptr= (char *)string;
2179
 
  uint32_t *nptr;
 
2935
  unsigned int *nptr;
2180
2936
 
2181
2937
  for (;*ptr; ptr++)
2182
2938
    if (*ptr == ',') count++;
2183
2939
 
2184
2940
  /* One extra spot for the NULL */
2185
 
  range.resize(count +1);
2186
 
  nptr= &range[0];
 
2941
  nptr= *range= (uint32_t *)malloc(sizeof(unsigned int) * (count + 1));
 
2942
  memset(nptr, 0, sizeof(unsigned int) * (count + 1));
2187
2943
 
2188
2944
  ptr= (char *)string;
2189
 
  uint32_t x= 0;
 
2945
  x= 0;
2190
2946
  while ((retstr= strchr(ptr,',')))
2191
2947
  {
2192
2948
    nptr[x++]= atoi(ptr);
2197
2953
  return count;
2198
2954
}
2199
2955
 
2200
 
void print_conclusions(Conclusions &con)
 
2956
void
 
2957
print_conclusions(Conclusions *con)
2201
2958
{
2202
2959
  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())
 
2960
  if (con->getEngine())
 
2961
    printf("\tRunning for engine %s\n", con->getEngine());
 
2962
  if (!opt_label.empty() || !opt_auto_generate_sql_type.empty())
2207
2963
  {
2208
2964
    const char *ptr= opt_auto_generate_sql_type.c_str() ? opt_auto_generate_sql_type.c_str() : "query";
2209
2965
    printf("\tLoad: %s\n", !opt_label.empty() ? opt_label.c_str() : ptr);
2210
2966
  }
2211
2967
  printf("\tAverage Time took to generate schema and initial data: %ld.%03ld seconds\n",
2212
 
         con.getCreateAvgTiming() / 1000, con.getCreateAvgTiming() % 1000);
 
2968
         con->getCreateAvgTiming() / 1000, con->getCreateAvgTiming() % 1000);
2213
2969
  printf("\tAverage number of seconds to run all queries: %ld.%03ld seconds\n",
2214
 
         con.getAvgTiming() / 1000, con.getAvgTiming() % 1000);
 
2970
         con->getAvgTiming() / 1000, con->getAvgTiming() % 1000);
2215
2971
  printf("\tMinimum number of seconds to run all queries: %ld.%03ld seconds\n",
2216
 
         con.getMinTiming() / 1000, con.getMinTiming() % 1000);
 
2972
         con->getMinTiming() / 1000, con->getMinTiming() % 1000);
2217
2973
  printf("\tMaximum number of seconds to run all queries: %ld.%03ld seconds\n",
2218
 
         con.getMaxTiming() / 1000, con.getMaxTiming() % 1000);
 
2974
         con->getMaxTiming() / 1000, con->getMaxTiming() % 1000);
2219
2975
  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());
 
2976
         con->getSumOfTime() / 1000, con->getSumOfTime() % 1000);
 
2977
  printf("\tStandard Deviation: %ld.%03ld\n", con->getStdDev() / 1000, con->getStdDev() % 1000);
 
2978
  printf("\tNumber of queries in create queries: %"PRIu64"\n", con->getCreateCount());
2223
2979
  printf("\tNumber of clients running queries: %u/%u\n",
2224
 
         con.getUsers(), con.getRealUsers());
 
2980
         con->getUsers(), con->getRealUsers());
2225
2981
  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
 
 
 
2982
  printf("\tAverage number of queries per client: %"PRIu64"\n", con->getAvgRows());
2232
2983
  printf("\n");
2233
2984
}
2234
2985
 
2235
 
void print_conclusions_csv(Conclusions &con)
 
2986
void
 
2987
print_conclusions_csv(Conclusions *con)
2236
2988
{
 
2989
  unsigned int x;
2237
2990
  char buffer[HUGE_STRING_LENGTH];
2238
2991
  char label_buffer[HUGE_STRING_LENGTH];
2239
2992
  size_t string_len;
2240
2993
  const char *temp_label= opt_label.c_str();
2241
2994
 
2242
 
  memset(label_buffer, 0, sizeof(label_buffer));
 
2995
  memset(label_buffer, 0, HUGE_STRING_LENGTH);
2243
2996
 
2244
 
  if (not opt_label.empty())
 
2997
  if (!opt_label.empty())
2245
2998
  {
2246
2999
    string_len= opt_label.length();
2247
3000
 
2248
 
    for (uint32_t x= 0; x < string_len; x++)
 
3001
    for (x= 0; x < string_len; x++)
2249
3002
    {
2250
3003
      if (temp_label[x] == ',')
2251
3004
        label_buffer[x]= '-';
2253
3006
        label_buffer[x]= temp_label[x] ;
2254
3007
    }
2255
3008
  }
2256
 
  else if (not opt_auto_generate_sql_type.empty())
 
3009
  else if (!opt_auto_generate_sql_type.empty())
2257
3010
  {
2258
3011
    string_len= opt_auto_generate_sql_type.length();
2259
3012
 
2260
 
    for (uint32_t x= 0; x < string_len; x++)
 
3013
    for (x= 0; x < string_len; x++)
2261
3014
    {
2262
3015
      if (opt_auto_generate_sql_type[x] == ',')
2263
3016
        label_buffer[x]= '-';
2266
3019
    }
2267
3020
  }
2268
3021
  else
2269
 
  {
2270
3022
    snprintf(label_buffer, HUGE_STRING_LENGTH, "query");
2271
 
  }
2272
3023
 
2273
3024
  snprintf(buffer, HUGE_STRING_LENGTH,
2274
3025
           "%s,%s,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,"
2275
3026
           "%u,%u,%u,%"PRIu64"\n",
2276
 
           con.getEngine() ? con.getEngine() : "", /* Storage engine we ran against */
 
3027
           con->getEngine() ? con->getEngine() : "", /* Storage engine we ran against */
2277
3028
           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 */
 
3029
           con->getAvgTiming() / 1000, con->getAvgTiming() % 1000, /* Time to load */
 
3030
           con->getMinTiming() / 1000, con->getMinTiming() % 1000, /* Min time */
 
3031
           con->getMaxTiming() / 1000, con->getMaxTiming() % 1000, /* Max time */
 
3032
           con->getSumOfTime() / 1000, con->getSumOfTime() % 1000, /* Total time */
 
3033
           con->getStdDev() / 1000, con->getStdDev() % 1000, /* Standard Deviation */
2283
3034
           iterations, /* Iterations */
2284
 
           con.getUsers(), /* Children used max_timing */
2285
 
           con.getRealUsers(), /* Children used max_timing */
2286
 
           con.getAvgRows()  /* Queries run */
 
3035
           con->getUsers(), /* Children used max_timing */
 
3036
           con->getRealUsers(), /* Children used max_timing */
 
3037
           con->getAvgRows()  /* Queries run */
2287
3038
           );
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
 
  }
 
3039
  internal::my_write(csv_file, (unsigned char*) buffer, (uint32_t)strlen(buffer), MYF(0));
2297
3040
}
2298
3041
 
2299
 
void generate_stats(Conclusions *con, OptionString *eng, Stats *sptr)
 
3042
void
 
3043
generate_stats(Conclusions *con, OptionString *eng, Stats *sptr)
2300
3044
{
2301
3045
  Stats *ptr;
2302
 
  uint32_t x;
 
3046
  unsigned int x;
2303
3047
 
2304
3048
  con->setMinTiming(sptr->getTiming());
2305
3049
  con->setMaxTiming(sptr->getTiming());
2329
3073
  else
2330
3074
    con->setEngine(NULL);
2331
3075
 
2332
 
  standard_deviation(*con, sptr);
 
3076
  standard_deviation(con, sptr);
2333
3077
 
2334
3078
  /* Now we do the create time operations */
2335
3079
  con->setCreateMinTiming(sptr->getCreateTiming());
2355
3099
option_cleanup(OptionString *stmt)
2356
3100
{
2357
3101
  OptionString *ptr, *nptr;
2358
 
  if (not stmt)
 
3102
  if (!stmt)
2359
3103
    return;
2360
3104
 
2361
3105
  for (ptr= stmt; ptr; ptr= nptr)
2362
3106
  {
2363
3107
    nptr= ptr->getNext();
2364
 
    delete ptr;
 
3108
    if (ptr->getString())
 
3109
      free(ptr->getString());
 
3110
    if (ptr->getOption())
 
3111
      free(ptr->getOption());
 
3112
    free(ptr);
2365
3113
  }
2366
3114
}
2367
3115
 
2368
 
void statement_cleanup(Statement *stmt)
 
3116
void
 
3117
statement_cleanup(Statement *stmt)
2369
3118
{
2370
3119
  Statement *ptr, *nptr;
2371
 
  if (not stmt)
 
3120
  if (!stmt)
2372
3121
    return;
2373
3122
 
2374
3123
  for (ptr= stmt; ptr; ptr= nptr)
2375
3124
  {
2376
3125
    nptr= ptr->getNext();
2377
 
    delete ptr;
 
3126
    if (ptr->getString())
 
3127
      free(ptr->getString());
 
3128
    free(ptr);
2378
3129
  }
2379
3130
}
2380
3131
 
2381
 
void slap_close(drizzle_con_st &con)
 
3132
void
 
3133
slap_close(drizzle_con_st *con)
2382
3134
{
2383
 
  drizzle_free(drizzle_con_drizzle(&con));
 
3135
  if (opt_only_print)
 
3136
    return;
 
3137
 
 
3138
  drizzle_free(drizzle_con_drizzle(con));
2384
3139
}
2385
3140
 
2386
 
void slap_connect(drizzle_con_st &con, bool connect_to_schema)
 
3141
void
 
3142
slap_connect(drizzle_con_st *con, bool connect_to_schema)
2387
3143
{
2388
3144
  /* Connect to server */
2389
3145
  static uint32_t connection_retry_sleep= 100000; /* Microseconds */
2390
 
  int connect_error= 1;
 
3146
  int x, connect_error= 1;
2391
3147
  drizzle_return_t ret;
2392
3148
  drizzle_st *drizzle;
2393
3149
 
 
3150
  if (opt_only_print)
 
3151
    return;
 
3152
 
2394
3153
  if (opt_delayed_start)
2395
3154
    usleep(random()%opt_delayed_start);
2396
3155
 
2397
3156
  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)
 
3157
      drizzle_con_add_tcp(drizzle, con, host.c_str(), opt_drizzle_port, user.c_str(),
 
3158
                          opt_password.c_str(),
 
3159
                          connect_to_schema ? create_schema_string.c_str() : NULL,
 
3160
                          opt_mysql ? DRIZZLE_CON_MYSQL : DRIZZLE_CON_NONE) == NULL)
2403
3161
  {
2404
 
    fprintf(stderr,"%s: Error creating drizzle object\n", SLAP_NAME);
2405
 
    abort();
 
3162
    fprintf(stderr,"%s: Error creating drizzle object\n", internal::my_progname);
 
3163
    exit(1);
2406
3164
  }
2407
3165
 
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++)
 
3166
  for (x= 0; x < 10; x++)
2414
3167
  {
2415
 
    if ((ret= drizzle_con_connect(&con)) == DRIZZLE_RETURN_OK)
 
3168
    if ((ret= drizzle_con_connect(con)) == DRIZZLE_RETURN_OK)
2416
3169
    {
2417
3170
      /* Connect suceeded */
2418
3171
      connect_error= 0;
2422
3175
  }
2423
3176
  if (connect_error)
2424
3177
  {
2425
 
    fprintf(stderr,"%s: Error when connecting to server: %d %s\n", SLAP_NAME,
2426
 
            ret, drizzle_con_error(&con));
2427
 
    abort();
 
3178
    fprintf(stderr,"%s: Error when connecting to server: %d %s\n", internal::my_progname,
 
3179
            ret, drizzle_con_error(con));
 
3180
    exit(1);
2428
3181
  }
 
3182
 
 
3183
  return;
2429
3184
}
2430
3185
 
2431
 
void standard_deviation(Conclusions &con, Stats *sptr)
 
3186
void
 
3187
standard_deviation (Conclusions *con, Stats *sptr)
2432
3188
{
 
3189
  unsigned int x;
2433
3190
  long int sum_of_squares;
2434
3191
  double the_catch;
2435
3192
  Stats *ptr;
2436
3193
 
2437
3194
  if (iterations == 1 || iterations == 0)
2438
3195
  {
2439
 
    con.setStdDev(0);
 
3196
    con->setStdDev(0);
2440
3197
    return;
2441
3198
  }
2442
3199
 
2443
 
  uint32_t x;
2444
3200
  for (ptr= sptr, x= 0, sum_of_squares= 0; x < iterations; ptr++, x++)
2445
3201
  {
2446
3202
    long int deviation;
2447
3203
 
2448
 
    deviation= ptr->getTiming() - con.getAvgTiming();
 
3204
    deviation= ptr->getTiming() - con->getAvgTiming();
2449
3205
    sum_of_squares+= deviation*deviation;
2450
3206
  }
2451
3207
 
2452
3208
  the_catch= sqrt((double)(sum_of_squares/(iterations -1)));
2453
 
  con.setStdDev((long int)the_catch);
 
3209
  con->setStdDev((long int)the_catch);
2454
3210
}