~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzleslap.cc

MErgeĀ VJ

Show diffs side-by-side

added added

removed removed

Lines of Context:
70
70
 
71
71
*/
72
72
 
73
 
#define SLAP_VERSION "1.5"
74
 
 
75
 
#define HUGE_STRING_LENGTH 8196
76
 
#define RAND_STRING_SIZE 126
77
 
#define DEFAULT_BLOB_SIZE 1024
 
73
#include "config.h"
78
74
 
79
75
#include "client_priv.h"
80
76
#include <signal.h>
86
82
#endif
87
83
#include <fcntl.h>
88
84
#include <math.h>
89
 
#include <ctype.h>
90
85
#include <cassert>
91
86
#include <cstdlib>
92
87
#include <string>
93
 
 
 
88
#include <iostream>
 
89
#include <fstream>
94
90
#include <pthread.h>
95
 
 
 
91
#include <drizzled/configmake.h>
96
92
/* Added this for string translation. */
97
93
#include <drizzled/gettext.h>
 
94
#include <boost/program_options.hpp>
 
95
 
 
96
#define SLAP_VERSION "1.5"
 
97
 
 
98
#define HUGE_STRING_LENGTH 8196
 
99
#define RAND_STRING_SIZE 126
 
100
#define DEFAULT_BLOB_SIZE 1024
98
101
 
99
102
using namespace std;
100
103
using namespace drizzled;
 
104
namespace po= boost::program_options;
101
105
 
102
106
#ifdef HAVE_SMEM
103
107
static char *shared_memory_base_name=0;
116
120
pthread_mutex_t timer_alarm_mutex;
117
121
pthread_cond_t timer_alarm_threshold;
118
122
 
119
 
static char **defaults_argv;
120
 
 
121
123
char **primary_keys;
122
124
/* This gets passed to malloc, so lets set it to an arch-dependant size */
123
125
size_t primary_keys_number_of;
124
126
 
125
 
static char *host= NULL, *opt_password= NULL, *user= NULL,
126
 
  *user_supplied_query= NULL,
127
 
  *user_supplied_pre_statements= NULL,
128
 
  *user_supplied_post_statements= NULL,
129
 
  *default_engine= NULL,
130
 
  *pre_system= NULL,
131
 
  *post_system= NULL;
132
 
 
133
 
const char *delimiter= "\n";
134
 
 
135
 
const char *create_schema_string= "drizzleslap";
136
 
 
137
 
static bool opt_mysql= false;
 
127
static string host, 
 
128
  opt_password, 
 
129
  user,
 
130
  user_supplied_query,
 
131
  user_supplied_pre_statements,
 
132
  user_supplied_post_statements,
 
133
  default_engine,
 
134
  pre_system,
 
135
  post_system;
 
136
 
 
137
static vector<string> user_supplied_queries;
 
138
static string opt_verbose;
 
139
string delimiter;
 
140
 
 
141
string create_schema_string;
 
142
 
 
143
static bool opt_mysql;
138
144
static bool opt_preserve= true;
139
 
static bool opt_only_print= false;
140
 
static bool opt_burnin= false;
 
145
static bool opt_only_print;
 
146
static bool opt_burnin;
141
147
static bool opt_ignore_sql_errors= false;
142
148
static bool tty_password= false,
143
 
  opt_silent= false,
144
 
  auto_generate_sql_autoincrement= false,
145
 
  auto_generate_sql_guid_primary= false,
146
 
  auto_generate_sql= false;
147
 
const char *opt_auto_generate_sql_type= "mixed";
 
149
  opt_silent,
 
150
  auto_generate_sql_autoincrement,
 
151
  auto_generate_sql_guid_primary,
 
152
  auto_generate_sql;
 
153
std::string opt_auto_generate_sql_type;
148
154
 
149
 
static int verbose, delimiter_length;
 
155
static int32_t verbose= 0;
 
156
static uint32_t delimiter_length;
150
157
static uint32_t commit_rate;
151
158
static uint32_t detach_rate;
152
159
static uint32_t opt_timer_length;
153
160
static uint32_t opt_delayed_start;
154
 
const char *num_int_cols_opt;
155
 
const char *num_char_cols_opt;
156
 
const char *num_blob_cols_opt;
157
 
const char *opt_label;
 
161
string num_blob_cols_opt,
 
162
  num_char_cols_opt,
 
163
  num_int_cols_opt;
 
164
string opt_label;
158
165
static unsigned int opt_set_random_seed;
159
166
 
160
 
const char *auto_generate_selected_columns_opt;
 
167
string auto_generate_selected_columns_opt;
161
168
 
162
169
/* Yes, we do set defaults here */
163
170
static unsigned int num_int_cols= 1;
167
174
static unsigned int num_blob_cols_size_min;
168
175
static unsigned int num_int_cols_index= 0;
169
176
static unsigned int num_char_cols_index= 0;
170
 
static unsigned int iterations;
 
177
static uint32_t iterations;
171
178
static uint64_t actual_queries= 0;
172
179
static uint64_t auto_actual_queries;
173
180
static uint64_t auto_generate_sql_unique_write_number;
174
181
static uint64_t auto_generate_sql_unique_query_number;
175
 
static unsigned int auto_generate_sql_secondary_indexes;
 
182
static uint32_t auto_generate_sql_secondary_indexes;
176
183
static uint64_t num_of_query;
177
184
static uint64_t auto_generate_sql_number;
178
 
const char *concurrency_str= NULL;
179
 
static char *create_string;
 
185
string concurrency_str;
 
186
string create_string;
180
187
uint32_t *concurrency;
181
188
 
182
189
const char *default_dbug_option= "d:t:o,/tmp/drizzleslap.trace";
183
 
const char *opt_csv_str;
 
190
std::string opt_csv_str;
184
191
int csv_file;
185
192
 
186
 
static int get_options(int *argc,char ***argv);
 
193
static int process_options(void);
187
194
static uint32_t opt_drizzle_port= 0;
188
195
 
189
 
static const char *load_default_groups[]= { "drizzleslap","client",0 };
190
196
 
191
197
/* Types */
192
198
typedef enum {
821
827
  return s + us;
822
828
}
823
829
 
 
830
static void combine_queries(vector<string> queries)
 
831
{
 
832
  user_supplied_query.erase();
 
833
  for (vector<string>::iterator it= queries.begin();
 
834
       it != queries.end();
 
835
       ++it)
 
836
  {
 
837
    user_supplied_query.append(*it);
 
838
    user_supplied_query.append(delimiter);
 
839
  }
 
840
}
 
841
/**
 
842
 * commandline_options is the set of all options that can only be called via the command line.
 
843
 
 
844
 * client_options is the set of all options that can be defined via both command line and via
 
845
 * the configuration file client.cnf
 
846
 
 
847
 * slap_options is the set of all drizzleslap specific options which behave in a manner 
 
848
 * similar to that of client_options. It's configuration file is drizzleslap.cnf
 
849
 
 
850
 * long_options is the union of commandline_options, slap_options and client_options.
 
851
 
 
852
 * There are two configuration files per set of options, one which is defined by the user and
 
853
 * which is found at ~/.drizzle directory and the other which is the system configuration
 
854
 * file which is found in the SYSCONFDIR/drizzle directory.
 
855
 
 
856
 * The system configuration file is over ridden by the user's configuration file which
 
857
 * in turn is over ridden by the command line.
 
858
 */
824
859
int main(int argc, char **argv)
825
860
{
 
861
  char *password= NULL;
 
862
  try
 
863
  {
 
864
  po::options_description commandline_options("Options used only in command line");
 
865
  commandline_options.add_options()
 
866
  ("help,?","Display this help and exit")
 
867
  ("info,i","Gives information and exit")
 
868
  ("burnin",po::value<bool>(&opt_burnin)->default_value(false)->zero_tokens(),
 
869
  "Run full test case in infinite loop")
 
870
  ("ignore-sql-errors", po::value<bool>(&opt_ignore_sql_errors)->default_value(false)->zero_tokens(),
 
871
  "Ignore SQL errors in query run")
 
872
  ("create-schema",po::value<string>(&create_schema_string)->default_value("drizzleslap"),
 
873
  "Schema to run tests in")
 
874
  ("create",po::value<string>(&create_string)->default_value(""),
 
875
  "File or string to use to create tables")
 
876
  ("detach",po::value<uint32_t>(&detach_rate)->default_value(0),
 
877
  "Detach (close and re open) connections after X number of requests")
 
878
  ("iterations,i",po::value<uint32_t>(&iterations)->default_value(1),
 
879
  "Number of times to run the tests")
 
880
  ("label",po::value<string>(&opt_label)->default_value(""),
 
881
  "Label to use for print and csv")
 
882
  ("number-blob-cols",po::value<string>(&num_blob_cols_opt)->default_value(""),
 
883
  "Number of BLOB columns to create table with if specifying --auto-generate-sql. Example --number-blob-cols=3:1024/2048 would give you 3 blobs with a random size between 1024 and 2048. ")
 
884
  ("number-char-cols,x",po::value<string>(&num_char_cols_opt)->default_value(""),
 
885
  "Number of VARCHAR columns to create in table if specifying --auto-generate-sql.")
 
886
  ("number-int-cols,y",po::value<string>(&num_int_cols_opt)->default_value(""),
 
887
  "Number of INT columns to create in table if specifying --auto-generate-sql.")
 
888
  ("number-of-queries",
 
889
  po::value<uint64_t>(&num_of_query)->default_value(0),
 
890
  "Limit each client to this number of queries(this is not exact)") 
 
891
  ("only-print",po::value<bool>(&opt_only_print)->default_value(false)->zero_tokens(),
 
892
  "This causes drizzleslap to not connect to the database instead print out what it would have done instead")
 
893
  ("post-query", po::value<string>(&user_supplied_post_statements)->default_value(""),
 
894
  "Query to run or file containing query to execute after tests have completed.")
 
895
  ("post-system",po::value<string>(&post_system)->default_value(""),
 
896
  "system() string to execute after tests have completed")
 
897
  ("pre-query",
 
898
  po::value<string>(&user_supplied_pre_statements)->default_value(""),
 
899
  "Query to run or file containing query to execute before running tests.")
 
900
  ("pre-system",po::value<string>(&pre_system)->default_value(""),
 
901
  "system() string to execute before running tests.")
 
902
  ("query,q",po::value<vector<string> >(&user_supplied_queries)->composing()->notifier(&combine_queries),
 
903
  "Query to run or file containing query")
 
904
  ("verbose,v", po::value<string>(&opt_verbose)->default_value("v"), "Increase verbosity level by one.")
 
905
  ("version,V","Output version information and exit") 
 
906
  ;
 
907
 
 
908
  po::options_description slap_options("Options specific to drizzleslap");
 
909
  slap_options.add_options()
 
910
  ("auto-generate-sql-select-columns",
 
911
  po::value<string>(&auto_generate_selected_columns_opt)->default_value(""),
 
912
  "Provide a string to use for the select fields used in auto tests")
 
913
  ("auto-generate-sql,a",po::value<bool>(&auto_generate_sql)->default_value(false)->zero_tokens(),
 
914
  "Generate SQL where not supplied by file or command line")  
 
915
  ("auto-generate-sql-add-autoincrement",
 
916
  po::value<bool>(&auto_generate_sql_autoincrement)->default_value(false)->zero_tokens(),
 
917
  "Add an AUTO_INCREMENT column to auto-generated tables")
 
918
  ("auto-generate-sql-execute-number",
 
919
  po::value<uint64_t>(&auto_actual_queries)->default_value(0),
 
920
  "See this number and generate a set of queries to run")
 
921
  ("auto-generate-sql-guid-primary",
 
922
  po::value<bool>(&auto_generate_sql_guid_primary)->default_value(false)->zero_tokens(),
 
923
  "Add GUID based primary keys to auto-generated tables")
 
924
  ("auto-generate-sql-load-type",
 
925
  po::value<string>(&opt_auto_generate_sql_type)->default_value("mixed"),
 
926
  "Specify test load type: mixed, update, write, key or read; default is mixed")  
 
927
  ("auto-generate-sql-secondary-indexes",
 
928
  po::value<uint32_t>(&auto_generate_sql_secondary_indexes)->default_value(0),
 
929
  "Number of secondary indexes to add to auto-generated tables")
 
930
  ("auto-generated-sql-unique-query-number",
 
931
  po::value<uint64_t>(&auto_generate_sql_unique_query_number)->default_value(10),
 
932
  "Number of unique queries to generate for automatic tests")
 
933
  ("auto-generate-sql-unique-write-number",
 
934
  po::value<uint64_t>(&auto_generate_sql_unique_write_number)->default_value(10),
 
935
  "Number of unique queries to generate for auto-generate-sql-write-number")
 
936
  ("auto-generate-sql-write-number",
 
937
  po::value<uint64_t>(&auto_generate_sql_number)->default_value(100),
 
938
  "Number of row inserts to perform for each thread (default is 100).")
 
939
  ("commit",po::value<uint32_t>(&commit_rate)->default_value(0),
 
940
  "Commit records every X number of statements")
 
941
  ("concurrency,c",po::value<string>(&concurrency_str)->default_value(""),
 
942
  "Number of clients to simulate for query to run")
 
943
  ("csv",po::value<std::string>(&opt_csv_str)->default_value(""),
 
944
  "Generate CSV output to named file or to stdout if no file is name.")
 
945
  ("delayed-start",po::value<uint32_t>(&opt_delayed_start)->default_value(0),
 
946
  "Delay the startup of threads by a random number of microsends (the maximum of the delay")
 
947
  ("delimiter,F",po::value<string>(&delimiter)->default_value("\n"),
 
948
  "Delimiter to use in SQL statements supplied in file or command line")
 
949
  ("engine ,e",po::value<string>(&default_engine)->default_value(""),
 
950
  "Storage engien to use for creating the table")
 
951
  ("set-random-seed",
 
952
  po::value<uint32_t>(&opt_set_random_seed)->default_value(0), 
 
953
  "Seed for random number generator (srandom(3)) ") 
 
954
  ("silent,s",po::value<bool>(&opt_silent)->default_value(false)->zero_tokens(),
 
955
  "Run program in silent mode - no output. ") 
 
956
  ("timer-length",po::value<uint32_t>(&opt_timer_length)->default_value(0),
 
957
  "Require drizzleslap to run each specific test a certain amount of time in seconds")  
 
958
  ;
 
959
 
 
960
  po::options_description client_options("Options specific to the client");
 
961
  client_options.add_options()
 
962
  ("mysql,m", po::value<bool>(&opt_mysql)->default_value(true)->zero_tokens(),
 
963
  N_("Use MySQL Protocol."))
 
964
  ("host,h",po::value<string>(&host)->default_value("localhost"),"Connect to the host")
 
965
  ("password,P",po::value<char *>(&password),
 
966
  "Password to use when connecting to server. If password is not given it's asked from the tty")
 
967
  ("port,p",po::value<uint32_t>(), "Port number to use for connection")
 
968
  ("protocol",po::value<string>(),
 
969
  "The protocol of connection (tcp,socket,pipe,memory).")
 
970
  ("user,u",po::value<string>(&user)->default_value(""),
 
971
  "User for login if not current user")  
 
972
  ;
 
973
 
 
974
  po::options_description long_options("Allowed Options");
 
975
  long_options.add(commandline_options).add(slap_options).add(client_options);
 
976
 
 
977
  std::string system_config_dir_slap(SYSCONFDIR); 
 
978
  system_config_dir_slap.append("/drizzle/drizzleslap.cnf");
 
979
 
 
980
  std::string system_config_dir_client(SYSCONFDIR); 
 
981
  system_config_dir_client.append("/drizzle/client.cnf");
 
982
 
 
983
  uint64_t temp_drizzle_port= 0;
826
984
  drizzle_con_st con;
827
985
  OptionString *eptr;
828
 
  unsigned int x;
829
 
 
830
 
  internal::my_init();
831
 
 
832
 
  MY_INIT(argv[0]);
833
 
 
834
 
  internal::load_defaults("drizzle",load_default_groups,&argc,&argv);
835
 
  defaults_argv=argv;
836
 
  if (get_options(&argc,&argv))
837
 
  {
838
 
    internal::free_defaults(defaults_argv);
839
 
    internal::my_end();
 
986
  uint32_t x;
 
987
 
 
988
  
 
989
  po::variables_map vm;
 
990
  po::store(po::parse_command_line(argc,argv,long_options),vm);
 
991
 
 
992
  ifstream user_slap_ifs("~/.drizzle/drizzleslap.cnf");
 
993
  po::store(parse_config_file(user_slap_ifs, slap_options), vm);
 
994
 
 
995
  ifstream system_slap_ifs(system_config_dir_slap.c_str());
 
996
  store(parse_config_file(system_slap_ifs, slap_options), vm);
 
997
 
 
998
  ifstream user_client_ifs("~/.drizzle/client.cnf");
 
999
  po::store(parse_config_file(user_client_ifs, client_options), vm);
 
1000
 
 
1001
  ifstream system_client_ifs(system_config_dir_client.c_str());
 
1002
  store(parse_config_file(system_client_ifs, client_options), vm);
 
1003
 
 
1004
  po::notify(vm);
 
1005
 
 
1006
  if (process_options())
840
1007
    exit(1);
 
1008
 
 
1009
  if( vm.count("help") || vm.count("info"))
 
1010
  {
 
1011
     printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname, SLAP_VERSION,
 
1012
       drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
 
1013
     puts("Copyright (C) 2008 Sun Microsystems");
 
1014
     puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\
 
1015
      \nand you are welcome to modify and redistribute it under the GPL \
 
1016
      license\n");
 
1017
    puts("Run a query multiple times against the server\n");
 
1018
    cout<<long_options<<endl;
 
1019
    exit(0);
 
1020
  }   
 
1021
 
 
1022
  if(vm.count("port")) 
 
1023
  {
 
1024
    temp_drizzle_port= vm["port"].as<uint32_t>();
 
1025
    
 
1026
    if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
 
1027
    {
 
1028
      fprintf(stderr, _("Value supplied for port is not valid.\n"));
 
1029
      exit(1);
 
1030
    }
 
1031
    else
 
1032
    {
 
1033
      opt_drizzle_port= (uint32_t) temp_drizzle_port;
 
1034
    }
 
1035
  }
 
1036
 
 
1037
  if( vm.count("password") )
 
1038
  {
 
1039
    char *start= vm["password"].as<char *>();
 
1040
    if (!opt_password.empty())
 
1041
      opt_password.erase();
 
1042
    opt_password = strdup(vm["password"].as<char *>());
 
1043
  if (opt_password.c_str() == NULL)
 
1044
  {
 
1045
    fprintf(stderr, "Memory allocation error while copying password. "
 
1046
                    "Aborting.\n");
 
1047
    exit(ENOMEM);
 
1048
  }
 
1049
  
 
1050
  while (*password)
 
1051
  {
 
1052
    /* Overwriting password with 'x' */
 
1053
    *password++= 'x';
 
1054
  }
 
1055
  
 
1056
  if (*start)
 
1057
  {
 
1058
    /* Cut length of argument */
 
1059
    start[1]= 0;
 
1060
  }
 
1061
  tty_password= 0;
 
1062
  }
 
1063
  else
 
1064
    tty_password= 1;
 
1065
  
 
1066
 
 
1067
  if( vm.count("version") )
 
1068
  {
 
1069
    printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname, SLAP_VERSION,
 
1070
           drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
 
1071
    exit(0);
841
1072
  }
842
1073
 
843
1074
  /* Seed the random number generator if we will be using it. */
849
1080
  }
850
1081
 
851
1082
  /* globals? Yes, so we only have to run strlen once */
852
 
  delimiter_length= strlen(delimiter);
853
 
 
854
 
  if (argc > 2)
855
 
  {
856
 
    fprintf(stderr,"%s: Too many arguments\n",internal::my_progname);
857
 
    internal::free_defaults(defaults_argv);
858
 
    internal::my_end();
859
 
    exit(1);
860
 
  }
 
1083
  delimiter_length= delimiter.length();
861
1084
 
862
1085
  slap_connect(&con, false);
863
1086
 
895
1118
    }
896
1119
 
897
1120
    if (!opt_preserve)
898
 
      drop_schema(&con, create_schema_string);
 
1121
      drop_schema(&con, create_schema_string.c_str());
899
1122
 
900
1123
  } while (eptr ? (eptr= eptr->getNext()) : 0);
901
1124
 
912
1135
  slap_close(&con);
913
1136
 
914
1137
  /* now free all the strings we created */
915
 
  if (opt_password)
916
 
    free(opt_password);
 
1138
  if (!opt_password.empty())
 
1139
    opt_password.erase();
917
1140
 
918
1141
  free(concurrency);
919
1142
 
930
1153
  if (shared_memory_base_name)
931
1154
    free(shared_memory_base_name);
932
1155
#endif
933
 
  internal::free_defaults(defaults_argv);
934
 
  internal::my_end();
935
 
 
 
1156
 
 
1157
  }
 
1158
 
 
1159
  catch(exception &err)
 
1160
  {
 
1161
  cerr<<"Error:"<<err.what()<<endl;
 
1162
  }
936
1163
  return 0;
937
1164
}
938
1165
 
969
1196
      data in the table.
970
1197
    */
971
1198
    if (opt_preserve == false)
972
 
      drop_schema(con, create_schema_string);
 
1199
      drop_schema(con, create_schema_string.c_str());
973
1200
 
974
1201
    /* First we create */
975
1202
    if (create_statements)
976
 
      create_schema(con, create_schema_string, create_statements, eptr, sptr);
 
1203
      create_schema(con, create_schema_string.c_str(), create_statements, eptr, sptr);
977
1204
 
978
1205
    /*
979
1206
      If we generated GUID we need to build a list of them from creation that
987
1214
    if (commit_rate)
988
1215
      run_query(con, NULL, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
989
1216
 
990
 
    if (pre_system)
 
1217
    if (!pre_system.empty())
991
1218
    {
992
 
      int ret= system(pre_system);
 
1219
      int ret= system(pre_system.c_str());
993
1220
      assert(ret != -1);
994
1221
    }
995
1222
       
1006
1233
    if (post_statements)
1007
1234
      run_statements(con, post_statements);
1008
1235
 
1009
 
    if (post_system)
 
1236
    if (!post_system.empty())
1010
1237
    {
1011
 
      int ret=  system(post_system);
 
1238
      int ret=  system(post_system.c_str());
1012
1239
      assert(ret !=-1);
1013
1240
    }
1014
1241
 
1024
1251
 
1025
1252
  if (!opt_silent)
1026
1253
    print_conclusions(&conclusion);
1027
 
  if (opt_csv_str)
 
1254
  if (!opt_csv_str.empty())
1028
1255
    print_conclusions_csv(&conclusion);
1029
1256
 
1030
1257
  free(head_sptr);
1032
1259
}
1033
1260
 
1034
1261
 
1035
 
static struct option my_long_options[] =
1036
 
{
1037
 
  {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
1038
 
   0, 0, 0, 0, 0, 0},
1039
 
  {"auto-generate-sql-select-columns", OPT_SLAP_AUTO_GENERATE_SELECT_COLUMNS,
1040
 
   "Provide a string to use for the select fields used in auto tests.",
1041
 
   (char**) &auto_generate_selected_columns_opt,
1042
 
   (char**) &auto_generate_selected_columns_opt,
1043
 
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1044
 
  {"auto-generate-sql", 'a',
1045
 
   "Generate SQL where not supplied by file or command line.",
1046
 
   (char**) &auto_generate_sql, (char**) &auto_generate_sql,
1047
 
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1048
 
  {"auto-generate-sql-add-autoincrement", OPT_SLAP_AUTO_GENERATE_ADD_AUTO,
1049
 
   "Add an AUTO_INCREMENT column to auto-generated tables.",
1050
 
   (char**) &auto_generate_sql_autoincrement,
1051
 
   (char**) &auto_generate_sql_autoincrement,
1052
 
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1053
 
  {"auto-generate-sql-execute-number", OPT_SLAP_AUTO_GENERATE_EXECUTE_QUERIES,
1054
 
   "Set this number to generate a set number of queries to run.",
1055
 
   (char**) &auto_actual_queries, (char**) &auto_actual_queries,
1056
 
   0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1057
 
  {"auto-generate-sql-guid-primary", OPT_SLAP_AUTO_GENERATE_GUID_PRIMARY,
1058
 
   "Add GUID based primary keys to auto-generated tables.",
1059
 
   (char**) &auto_generate_sql_guid_primary,
1060
 
   (char**) &auto_generate_sql_guid_primary,
1061
 
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1062
 
  {"auto-generate-sql-load-type", OPT_SLAP_AUTO_GENERATE_SQL_LOAD_TYPE,
1063
 
   "Specify test load type: mixed, update, write, key, or read; default is mixed.",
1064
 
   (char**) &opt_auto_generate_sql_type, (char**) &opt_auto_generate_sql_type,
1065
 
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1066
 
  {"auto-generate-sql-secondary-indexes",
1067
 
   OPT_SLAP_AUTO_GENERATE_SECONDARY_INDEXES,
1068
 
   "Number of secondary indexes to add to auto-generated tables.",
1069
 
   (char**) &auto_generate_sql_secondary_indexes,
1070
 
   (char**) &auto_generate_sql_secondary_indexes, 0,
1071
 
   GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1072
 
  {"auto-generate-sql-unique-query-number",
1073
 
   OPT_SLAP_AUTO_GENERATE_UNIQUE_QUERY_NUM,
1074
 
   "Number of unique queries to generate for automatic tests.",
1075
 
   (char**) &auto_generate_sql_unique_query_number,
1076
 
   (char**) &auto_generate_sql_unique_query_number,
1077
 
   0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
1078
 
  {"auto-generate-sql-unique-write-number",
1079
 
   OPT_SLAP_AUTO_GENERATE_UNIQUE_WRITE_NUM,
1080
 
   "Number of unique queries to generate for auto-generate-sql-write-number.",
1081
 
   (char**) &auto_generate_sql_unique_write_number,
1082
 
   (char**) &auto_generate_sql_unique_write_number,
1083
 
   0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
1084
 
  {"auto-generate-sql-write-number", OPT_SLAP_AUTO_GENERATE_WRITE_NUM,
1085
 
   "Number of row inserts to perform for each thread (default is 100).",
1086
 
   (char**) &auto_generate_sql_number, (char**) &auto_generate_sql_number,
1087
 
   0, GET_ULL, REQUIRED_ARG, 100, 0, 0, 0, 0, 0},
1088
 
  {"burnin", OPT_SLAP_BURNIN, "Run full test case in infinite loop.",
1089
 
   (char**) &opt_burnin, (char**) &opt_burnin, 0, GET_BOOL, NO_ARG, 0, 0, 0,
1090
 
   0, 0, 0},
1091
 
  {"ignore-sql-errors", OPT_SLAP_IGNORE_SQL_ERRORS,
1092
 
   "Ignore SQL erros in query run.",
1093
 
   (char**) &opt_ignore_sql_errors,
1094
 
   (char**) &opt_ignore_sql_errors,
1095
 
   0, GET_BOOL, NO_ARG, 0, 0, 0,
1096
 
   0, 0, 0},
1097
 
  {"commit", OPT_SLAP_COMMIT, "Commit records every X number of statements.",
1098
 
   (char**) &commit_rate, (char**) &commit_rate, 0, GET_UINT, REQUIRED_ARG,
1099
 
   0, 0, 0, 0, 0, 0},
1100
 
  {"concurrency", 'c', "Number of clients to simulate for query to run.",
1101
 
   (char**) &concurrency_str, (char**) &concurrency_str, 0, GET_STR,
1102
 
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1103
 
  {"create", OPT_SLAP_CREATE_STRING, "File or string to use create tables.",
1104
 
   (char**) &create_string, (char**) &create_string, 0, GET_STR, REQUIRED_ARG,
1105
 
   0, 0, 0, 0, 0, 0},
1106
 
  {"create-schema", OPT_CREATE_SLAP_SCHEMA, "Schema to run tests in.",
1107
 
   (char**) &create_schema_string, (char**) &create_schema_string, 0, GET_STR,
1108
 
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1109
 
  {"csv", OPT_SLAP_CSV,
1110
 
   "Generate CSV output to named file or to stdout if no file is named.",
1111
 
   (char**) &opt_csv_str, (char**) &opt_csv_str, 0, GET_STR,
1112
 
   OPT_ARG, 0, 0, 0, 0, 0, 0},
1113
 
  {"delayed-start", OPT_SLAP_DELAYED_START,
1114
 
   "Delay the startup of threads by a random number of microsends (the maximum of the delay)",
1115
 
   (char**) &opt_delayed_start, (char**) &opt_delayed_start, 0, GET_UINT,
1116
 
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1117
 
  {"delimiter", 'F',
1118
 
   "Delimiter to use in SQL statements supplied in file or command line.",
1119
 
   (char**) &delimiter, (char**) &delimiter, 0, GET_STR, REQUIRED_ARG,
1120
 
   0, 0, 0, 0, 0, 0},
1121
 
  {"detach", OPT_SLAP_DETACH,
1122
 
   "Detach (close and reopen) connections after X number of requests.",
1123
 
   (char**) &detach_rate, (char**) &detach_rate, 0, GET_UINT, REQUIRED_ARG,
1124
 
   0, 0, 0, 0, 0, 0},
1125
 
  {"engine", 'e', "Storage engine to use for creating the table.",
1126
 
   (char**) &default_engine, (char**) &default_engine, 0,
1127
 
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1128
 
  {"host", 'h', "Connect to host.", (char**) &host, (char**) &host, 0, GET_STR,
1129
 
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1130
 
  {"iterations", 'i', "Number of times to run the tests.", (char**) &iterations,
1131
 
   (char**) &iterations, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0},
1132
 
  {"label", OPT_SLAP_LABEL, "Label to use for print and csv output.",
1133
 
   (char**) &opt_label, (char**) &opt_label, 0,
1134
 
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1135
 
  {"mysql", 'm', N_("Use MySQL Protocol."),
1136
 
   (char**) &opt_mysql, (char**) &opt_mysql, 0, GET_BOOL, NO_ARG, 1, 0, 0,
1137
 
   0, 0, 0},
1138
 
  {"number-blob-cols", OPT_SLAP_BLOB_COL,
1139
 
   "Number of BLOB columns to create table with if specifying --auto-generate-sql. Example --number-blob-cols=3:1024/2048 would give you 3 blobs with a random size between 1024 and 2048. ",
1140
 
   (char**) &num_blob_cols_opt, (char**) &num_blob_cols_opt, 0, GET_STR, REQUIRED_ARG,
1141
 
   0, 0, 0, 0, 0, 0},
1142
 
  {"number-char-cols", 'x',
1143
 
   "Number of VARCHAR columns to create in table if specifying --auto-generate-sql.",
1144
 
   (char**) &num_char_cols_opt, (char**) &num_char_cols_opt, 0, GET_STR, REQUIRED_ARG,
1145
 
   0, 0, 0, 0, 0, 0},
1146
 
  {"number-int-cols", 'y',
1147
 
   "Number of INT columns to create in table if specifying --auto-generate-sql.",
1148
 
   (char**) &num_int_cols_opt, (char**) &num_int_cols_opt, 0, GET_STR, REQUIRED_ARG,
1149
 
   0, 0, 0, 0, 0, 0},
1150
 
  {"number-of-queries", OPT_DRIZZLE_NUMBER_OF_QUERY,
1151
 
   "Limit each client to this number of queries (this is not exact).",
1152
 
   (char**) &num_of_query, (char**) &num_of_query, 0,
1153
 
   GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1154
 
  {"only-print", OPT_DRIZZLE_ONLY_PRINT,
1155
 
   "This causes drizzleslap to not connect to the databases, but instead print "
1156
 
   "out what it would have done instead.",
1157
 
   (char**) &opt_only_print, (char**) &opt_only_print, 0, GET_BOOL,  NO_ARG,
1158
 
   0, 0, 0, 0, 0, 0},
1159
 
  {"password", 'P',
1160
 
   "Password to use when connecting to server. If password is not given it's "
1161
 
   "asked from the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
1162
 
  {"port", 'p', "Port number to use for connection.",
1163
 
   0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1164
 
  {"post-query", OPT_SLAP_POST_QUERY,
1165
 
   "Query to run or file containing query to execute after tests have completed.",
1166
 
   (char**) &user_supplied_post_statements,
1167
 
   (char**) &user_supplied_post_statements,
1168
 
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1169
 
  {"post-system", OPT_SLAP_POST_SYSTEM,
1170
 
   "system() string to execute after tests have completed.",
1171
 
   (char**) &post_system,
1172
 
   (char**) &post_system,
1173
 
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1174
 
  {"pre-query", OPT_SLAP_PRE_QUERY,
1175
 
   "Query to run or file containing query to execute before running tests.",
1176
 
   (char**) &user_supplied_pre_statements,
1177
 
   (char**) &user_supplied_pre_statements,
1178
 
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1179
 
  {"pre-system", OPT_SLAP_PRE_SYSTEM,
1180
 
   "system() string to execute before running tests.",
1181
 
   (char**) &pre_system,
1182
 
   (char**) &pre_system,
1183
 
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1184
 
  {"protocol", OPT_DRIZZLE_PROTOCOL,
1185
 
   "The protocol of connection (tcp,socket,pipe,memory).",
1186
 
   0, 0, 0, GET_STR,  REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1187
 
  {"query", 'q', "Query to run or file containing query to run.",
1188
 
   (char**) &user_supplied_query, (char**) &user_supplied_query,
1189
 
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1190
 
  {"set-random-seed", OPT_SLAP_SET_RANDOM_SEED,
1191
 
   "Seed for random number generator (srandom(3))",
1192
 
   (char**)&opt_set_random_seed,
1193
 
   (char**)&opt_set_random_seed,0,
1194
 
   GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1195
 
  {"silent", 's', "Run program in silent mode - no output.",
1196
 
   (char**) &opt_silent, (char**) &opt_silent, 0, GET_BOOL,  NO_ARG,
1197
 
   0, 0, 0, 0, 0, 0},
1198
 
  {"timer-length", OPT_SLAP_TIMER_LENGTH,
1199
 
   "Require drizzleslap to run each specific test a certain amount of time in seconds.",
1200
 
   (char**) &opt_timer_length, (char**) &opt_timer_length, 0, GET_UINT,
1201
 
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1202
 
  {"user", 'u', "User for login if not current user.", (char**) &user,
1203
 
   (char**) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1204
 
  {"verbose", 'v',
1205
 
   "More verbose output; you can use this multiple times to get even more "
1206
 
   "verbose output.", (char**) &verbose, (char**) &verbose, 0,
1207
 
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1208
 
  {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
1209
 
   NO_ARG, 0, 0, 0, 0, 0, 0},
1210
 
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
1211
 
};
1212
 
 
1213
 
 
1214
 
static void print_version(void)
1215
 
{
1216
 
  printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname, SLAP_VERSION,
1217
 
         drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
1218
 
}
1219
 
 
1220
 
 
1221
 
static void usage(void)
1222
 
{
1223
 
  print_version();
1224
 
  puts("Copyright (C) 2008 Sun Microsystems");
1225
 
  puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\
1226
 
       \nand you are welcome to modify and redistribute it under the GPL \
1227
 
       license\n");
1228
 
  puts("Run a query multiple times against the server\n");
1229
 
  printf("Usage: %s [OPTIONS]\n",internal::my_progname);
1230
 
  internal::print_defaults("drizzle",load_default_groups);
1231
 
  my_print_help(my_long_options);
1232
 
}
1233
 
 
1234
 
static int get_one_option(int optid, const struct option *, char *argument)
1235
 
{
1236
 
  char *endchar= NULL;
1237
 
  uint64_t temp_drizzle_port= 0;
1238
 
 
1239
 
  switch(optid) {
1240
 
  case 'v':
1241
 
    verbose++;
1242
 
    break;
1243
 
  case 'p':
1244
 
    temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
1245
 
    /* if there is an alpha character this is not a valid port */
1246
 
    if (strlen(endchar) != 0)
1247
 
    {
1248
 
      fprintf(stderr, _("Non-integer value supplied for port.  If you are trying to enter a password please use --password instead.\n"));
1249
 
      exit(1);
1250
 
    }
1251
 
    /* If the port number is > 65535 it is not a valid port
1252
 
       This also helps with potential data loss casting unsigned long to a
1253
 
       uint32_t. */
1254
 
    if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
1255
 
    {
1256
 
      fprintf(stderr, _("Value supplied for port is not valid.\n"));
1257
 
      exit(1);
1258
 
    }
1259
 
    else
1260
 
    {
1261
 
      opt_drizzle_port= (uint32_t) temp_drizzle_port;
1262
 
    }
1263
 
    break;
1264
 
  case 'P':
1265
 
    if (argument)
1266
 
    {
1267
 
      char *start= argument;
1268
 
      if (opt_password)
1269
 
        free(opt_password);
1270
 
      opt_password = strdup(argument);
1271
 
      if (opt_password == NULL)
1272
 
      {
1273
 
        fprintf(stderr, "Memory allocation error while copying password. "
1274
 
                        "Aborting.\n");
1275
 
        exit(ENOMEM);
1276
 
      }
1277
 
      while (*argument)
1278
 
      {
1279
 
        /* Overwriting password with 'x' */
1280
 
        *argument++= 'x';
1281
 
      }
1282
 
      if (*start)
1283
 
      {
1284
 
        /* Cut length of argument */
1285
 
        start[1]= 0;
1286
 
      }
1287
 
      tty_password= 0;
1288
 
    }
1289
 
    else
1290
 
      tty_password= 1;
1291
 
    break;
1292
 
  case 'V':
1293
 
    print_version();
1294
 
    exit(0);
1295
 
  case '?':
1296
 
  case 'I':          /* Info */
1297
 
    usage();
1298
 
    exit(0);
1299
 
  }
1300
 
  return(0);
1301
 
}
1302
 
 
1303
1262
 
1304
1263
uint
1305
1264
get_random_string(char *buf, size_t size)
1698
1657
  query_string.reserve(HUGE_STRING_LENGTH);
1699
1658
 
1700
1659
  query_string.append("SELECT ", 7);
1701
 
  if (auto_generate_selected_columns_opt)
 
1660
  if (!auto_generate_selected_columns_opt.empty())
1702
1661
  {
1703
 
    query_string.append(auto_generate_selected_columns_opt);
 
1662
    query_string.append(auto_generate_selected_columns_opt.c_str());
1704
1663
  }
1705
1664
  else
1706
1665
  {
1777
1736
}
1778
1737
 
1779
1738
static int
1780
 
get_options(int *argc,char ***argv)
 
1739
process_options(void)
1781
1740
{
1782
 
  int ho_error;
1783
1741
  char *tmp_string;
1784
1742
  struct stat sbuf;
1785
1743
  OptionString *sql_type;
1786
1744
  unsigned int sql_type_count= 0;
1787
1745
  ssize_t bytes_read= 0;
1788
 
 
1789
 
 
1790
 
  if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option)))
1791
 
    exit(ho_error);
1792
 
 
1793
 
  if (!user)
1794
 
    user= (char *)"root";
 
1746
  
 
1747
  if (user.empty())
 
1748
    user= "root";
 
1749
 
 
1750
  verbose= opt_verbose.length();
1795
1751
 
1796
1752
  /* If something is created we clean it up, otherwise we leave schemas alone */
1797
 
  if (create_string || auto_generate_sql)
 
1753
  if ( (!create_string.empty()) || auto_generate_sql)
1798
1754
    opt_preserve= false;
1799
1755
 
1800
 
  if (auto_generate_sql && (create_string || user_supplied_query))
 
1756
  if (auto_generate_sql && (!create_string.empty() || !user_supplied_query.empty()))
1801
1757
  {
1802
1758
    fprintf(stderr,
1803
1759
            "%s: Can't use --auto-generate-sql when create and query strings are specified!\n",
1822
1778
    exit(1);
1823
1779
  }
1824
1780
 
1825
 
  parse_comma(concurrency_str ? concurrency_str : "1", &concurrency);
 
1781
  parse_comma(!concurrency_str.empty() ? concurrency_str.c_str() : "1", &concurrency);
1826
1782
 
1827
 
  if (opt_csv_str)
 
1783
  if (!opt_csv_str.empty())
1828
1784
  {
1829
1785
    opt_silent= true;
1830
1786
 
1834
1790
    }
1835
1791
    else
1836
1792
    {
1837
 
      if ((csv_file= open(opt_csv_str, O_CREAT|O_WRONLY|O_APPEND, 
 
1793
      if ((csv_file= open(opt_csv_str.c_str(), O_CREAT|O_WRONLY|O_APPEND, 
1838
1794
                          S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1)
1839
1795
      {
1840
1796
        fprintf(stderr,"%s: Could not open csv file: %sn\n",
1841
 
                internal::my_progname, opt_csv_str);
 
1797
                internal::my_progname, opt_csv_str.c_str());
1842
1798
        exit(1);
1843
1799
      }
1844
1800
    }
1847
1803
  if (opt_only_print)
1848
1804
    opt_silent= true;
1849
1805
 
1850
 
  if (num_int_cols_opt)
 
1806
  if (!num_int_cols_opt.empty())
1851
1807
  {
1852
1808
    OptionString *str;
1853
 
    parse_option(num_int_cols_opt, &str, ',');
 
1809
    parse_option(num_int_cols_opt.c_str(), &str, ',');
1854
1810
    num_int_cols= atoi(str->getString());
1855
1811
    if (str->getOption())
1856
1812
      num_int_cols_index= atoi(str->getOption());
1857
1813
    option_cleanup(str);
1858
1814
  }
1859
1815
 
1860
 
  if (num_char_cols_opt)
 
1816
  if (!num_char_cols_opt.empty())
1861
1817
  {
1862
1818
    OptionString *str;
1863
 
    parse_option(num_char_cols_opt, &str, ',');
 
1819
    parse_option(num_char_cols_opt.c_str(), &str, ',');
1864
1820
    num_char_cols= atoi(str->getString());
1865
1821
    if (str->getOption())
1866
1822
      num_char_cols_index= atoi(str->getOption());
1869
1825
    option_cleanup(str);
1870
1826
  }
1871
1827
 
1872
 
  if (num_blob_cols_opt)
 
1828
  if (!num_blob_cols_opt.empty())
1873
1829
  {
1874
1830
    OptionString *str;
1875
 
    parse_option(num_blob_cols_opt, &str, ',');
 
1831
    parse_option(num_blob_cols_opt.c_str(), &str, ',');
1876
1832
    num_blob_cols= atoi(str->getString());
1877
1833
    if (str->getOption())
1878
1834
    {
1919
1875
    if (verbose >= 2)
1920
1876
      printf("Building Query Statements for Auto\n");
1921
1877
 
1922
 
    if (!opt_auto_generate_sql_type)
 
1878
    if (opt_auto_generate_sql_type.empty())
1923
1879
      opt_auto_generate_sql_type= "mixed";
1924
1880
 
1925
1881
    query_statements_count=
1926
 
      parse_option(opt_auto_generate_sql_type, &query_options, ',');
 
1882
      parse_option(opt_auto_generate_sql_type.c_str(), &query_options, ',');
1927
1883
 
1928
1884
    query_statements= (Statement **)malloc(sizeof(Statement *) * query_statements_count);
1929
1885
    if (query_statements == NULL)
2037
1993
  }
2038
1994
  else
2039
1995
  {
2040
 
    if (create_string && !stat(create_string, &sbuf))
 
1996
    if (!create_string.empty() && !stat(create_string.c_str(), &sbuf))
2041
1997
    {
2042
1998
      int data_file;
2043
1999
      if (!S_ISREG(sbuf.st_mode))
2046
2002
                internal::my_progname);
2047
2003
        exit(1);
2048
2004
      }
2049
 
      if ((data_file= open(create_string, O_RDWR)) == -1)
 
2005
      if ((data_file= open(create_string.c_str(), O_RDWR)) == -1)
2050
2006
      {
2051
2007
        fprintf(stderr,"%s: Could not open create file\n", internal::my_progname);
2052
2008
        exit(1);
2074
2030
      parse_delimiter(tmp_string, &create_statements, delimiter[0]);
2075
2031
      free(tmp_string);
2076
2032
    }
2077
 
    else if (create_string)
 
2033
    else if (!create_string.empty())
2078
2034
    {
2079
 
      parse_delimiter(create_string, &create_statements, delimiter[0]);
 
2035
      parse_delimiter(create_string.c_str(), &create_statements, delimiter[0]);
2080
2036
    }
2081
2037
 
2082
2038
    /* Set this up till we fully support options on user generated queries */
2083
 
    if (user_supplied_query)
 
2039
    if (!user_supplied_query.empty())
2084
2040
    {
2085
2041
      query_statements_count=
2086
2042
        parse_option("default", &query_options, ',');
2094
2050
      memset(query_statements, 0, sizeof(Statement *) * query_statements_count); 
2095
2051
    }
2096
2052
 
2097
 
    if (user_supplied_query && !stat(user_supplied_query, &sbuf))
 
2053
    if (!user_supplied_query.empty() && !stat(user_supplied_query.c_str(), &sbuf))
2098
2054
    {
2099
2055
      int data_file;
2100
2056
      if (!S_ISREG(sbuf.st_mode))
2103
2059
                internal::my_progname);
2104
2060
        exit(1);
2105
2061
      }
2106
 
      if ((data_file= open(user_supplied_query, O_RDWR)) == -1)
 
2062
      if ((data_file= open(user_supplied_query.c_str(), O_RDWR)) == -1)
2107
2063
      {
2108
2064
        fprintf(stderr,"%s: Could not open query supplied file\n", internal::my_progname);
2109
2065
        exit(1);
2128
2084
      {
2129
2085
        fprintf(stderr, "Problem reading file: read less bytes than requested\n");
2130
2086
      }
2131
 
      if (user_supplied_query)
 
2087
      if (!user_supplied_query.empty())
2132
2088
        actual_queries= parse_delimiter(tmp_string, &query_statements[0],
2133
2089
                                        delimiter[0]);
2134
2090
      free(tmp_string);
2135
2091
    }
2136
 
    else if (user_supplied_query)
 
2092
    else if (!user_supplied_query.empty())
2137
2093
    {
2138
 
      actual_queries= parse_delimiter(user_supplied_query, &query_statements[0],
 
2094
      actual_queries= parse_delimiter(user_supplied_query.c_str(), &query_statements[0],
2139
2095
                                      delimiter[0]);
2140
2096
    }
2141
2097
  }
2142
2098
 
2143
 
  if (user_supplied_pre_statements
2144
 
      && !stat(user_supplied_pre_statements, &sbuf))
 
2099
  if (!user_supplied_pre_statements.empty()
 
2100
      && !stat(user_supplied_pre_statements.c_str(), &sbuf))
2145
2101
  {
2146
2102
    int data_file;
2147
2103
    if (!S_ISREG(sbuf.st_mode))
2150
2106
              internal::my_progname);
2151
2107
      exit(1);
2152
2108
    }
2153
 
    if ((data_file= open(user_supplied_pre_statements, O_RDWR)) == -1)
 
2109
    if ((data_file= open(user_supplied_pre_statements.c_str(), O_RDWR)) == -1)
2154
2110
    {
2155
2111
      fprintf(stderr,"%s: Could not open query supplied file\n", internal::my_progname);
2156
2112
      exit(1);
2175
2131
    {
2176
2132
      fprintf(stderr, "Problem reading file: read less bytes than requested\n");
2177
2133
    }
2178
 
    if (user_supplied_pre_statements)
 
2134
    if (!user_supplied_pre_statements.empty())
2179
2135
      (void)parse_delimiter(tmp_string, &pre_statements,
2180
2136
                            delimiter[0]);
2181
2137
    free(tmp_string);
2182
2138
  }
2183
 
  else if (user_supplied_pre_statements)
 
2139
  else if (!user_supplied_pre_statements.empty())
2184
2140
  {
2185
 
    (void)parse_delimiter(user_supplied_pre_statements,
 
2141
    (void)parse_delimiter(user_supplied_pre_statements.c_str(),
2186
2142
                          &pre_statements,
2187
2143
                          delimiter[0]);
2188
2144
  }
2189
2145
 
2190
 
  if (user_supplied_post_statements
2191
 
      && !stat(user_supplied_post_statements, &sbuf))
 
2146
  if (!user_supplied_post_statements.empty()
 
2147
      && !stat(user_supplied_post_statements.c_str(), &sbuf))
2192
2148
  {
2193
2149
    int data_file;
2194
2150
    if (!S_ISREG(sbuf.st_mode))
2197
2153
              internal::my_progname);
2198
2154
      exit(1);
2199
2155
    }
2200
 
    if ((data_file= open(user_supplied_post_statements, O_RDWR)) == -1)
 
2156
    if ((data_file= open(user_supplied_post_statements.c_str(), O_RDWR)) == -1)
2201
2157
    {
2202
2158
      fprintf(stderr,"%s: Could not open query supplied file\n", internal::my_progname);
2203
2159
      exit(1);
2224
2180
    {
2225
2181
      fprintf(stderr, "Problem reading file: read less bytes than requested\n");
2226
2182
    }
2227
 
    if (user_supplied_post_statements)
 
2183
    if (!user_supplied_post_statements.empty())
2228
2184
      (void)parse_delimiter(tmp_string, &post_statements,
2229
2185
                            delimiter[0]);
2230
2186
    free(tmp_string);
2231
2187
  }
2232
 
  else if (user_supplied_post_statements)
 
2188
  else if (!user_supplied_post_statements.empty())
2233
2189
  {
2234
 
    (void)parse_delimiter(user_supplied_post_statements, &post_statements,
 
2190
    (void)parse_delimiter(user_supplied_post_statements.c_str(), &post_statements,
2235
2191
                          delimiter[0]);
2236
2192
  }
2237
2193
 
2238
2194
  if (verbose >= 2)
2239
2195
    printf("Parsing engines to use.\n");
2240
2196
 
2241
 
  if (default_engine)
2242
 
    parse_option(default_engine, &engine_options, ',');
 
2197
  if (!default_engine.empty())
 
2198
    parse_option(default_engine.c_str(), &engine_options, ',');
2243
2199
 
2244
2200
  if (tty_password)
2245
2201
    opt_password= client_get_tty_password(NULL);
3004
2960
  printf("Benchmark\n");
3005
2961
  if (con->getEngine())
3006
2962
    printf("\tRunning for engine %s\n", con->getEngine());
3007
 
  if (opt_label || opt_auto_generate_sql_type)
 
2963
  if (!opt_label.empty() || !opt_auto_generate_sql_type.empty())
3008
2964
  {
3009
 
    const char *ptr= opt_auto_generate_sql_type ? opt_auto_generate_sql_type : "query";
3010
 
    printf("\tLoad: %s\n", opt_label ? opt_label : ptr);
 
2965
    const char *ptr= opt_auto_generate_sql_type.c_str() ? opt_auto_generate_sql_type.c_str() : "query";
 
2966
    printf("\tLoad: %s\n", !opt_label.empty() ? opt_label.c_str() : ptr);
3011
2967
  }
3012
2968
  printf("\tAverage Time took to generate schema and initial data: %ld.%03ld seconds\n",
3013
2969
         con->getCreateAvgTiming() / 1000, con->getCreateAvgTiming() % 1000);
3035
2991
  char buffer[HUGE_STRING_LENGTH];
3036
2992
  char label_buffer[HUGE_STRING_LENGTH];
3037
2993
  size_t string_len;
 
2994
  const char *temp_label= opt_label.c_str();
3038
2995
 
3039
2996
  memset(label_buffer, 0, HUGE_STRING_LENGTH);
3040
2997
 
3041
 
  if (opt_label)
 
2998
  if (!opt_label.empty())
3042
2999
  {
3043
 
    string_len= strlen(opt_label);
 
3000
    string_len= opt_label.length();
3044
3001
 
3045
3002
    for (x= 0; x < string_len; x++)
3046
3003
    {
3047
 
      if (opt_label[x] == ',')
 
3004
      if (temp_label[x] == ',')
3048
3005
        label_buffer[x]= '-';
3049
3006
      else
3050
 
        label_buffer[x]= opt_label[x] ;
 
3007
        label_buffer[x]= temp_label[x] ;
3051
3008
    }
3052
3009
  }
3053
 
  else if (opt_auto_generate_sql_type)
 
3010
  else if (!opt_auto_generate_sql_type.empty())
3054
3011
  {
3055
 
    string_len= strlen(opt_auto_generate_sql_type);
 
3012
    string_len= opt_auto_generate_sql_type.length();
3056
3013
 
3057
3014
    for (x= 0; x < string_len; x++)
3058
3015
    {
3198
3155
    usleep(random()%opt_delayed_start);
3199
3156
 
3200
3157
  if ((drizzle= drizzle_create(NULL)) == NULL ||
3201
 
      drizzle_con_add_tcp(drizzle, con, host, opt_drizzle_port, user,
3202
 
                          opt_password,
3203
 
                          connect_to_schema ? create_schema_string : NULL,
 
3158
      drizzle_con_add_tcp(drizzle, con, host.c_str(), opt_drizzle_port, user.c_str(),
 
3159
                          opt_password.c_str(),
 
3160
                          connect_to_schema ? create_schema_string.c_str() : NULL,
3204
3161
                          opt_mysql ? DRIZZLE_CON_MYSQL : DRIZZLE_CON_NONE) == NULL)
3205
3162
  {
3206
3163
    fprintf(stderr,"%s: Error creating drizzle object\n", internal::my_progname);