~drizzle-pbxt/drizzle/drizzle-pbxt-2

« back to all changes in this revision

Viewing changes to client/drizzletest.cc

  • Committer: Paul McCullagh
  • Date: 2009-11-10 14:18:39 UTC
  • mfrom: (1038.1.7 drizzle-pbxt-pre-merge)
  • Revision ID: paul.mccullagh@primebase.org-20091110141839-2j3k43b17ag6f605
Merged Drizzle trunk and PBXT 1.0.09

Show diffs side-by-side

added added

removed removed

Lines of Context:
46
46
#include <sstream>
47
47
#include <iostream>
48
48
#include <vector>
 
49
#include <algorithm>
 
50
#ifdef HAVE_SYS_WAIT_H
 
51
#include <sys/wait.h>
 
52
#endif
49
53
 
50
54
#include PCRE_HEADER
51
55
 
57
61
/* Added this for string translation. */
58
62
#include <drizzled/gettext.h>
59
63
 
 
64
#ifndef DRIZZLE_RETURN_SERVER_GONE
 
65
#define DRIZZLE_RETURN_HANDSHAKE_FAILED DRIZZLE_RETURN_ERROR_CODE
 
66
#endif
 
67
 
60
68
using namespace std;
61
69
 
 
70
extern "C"
 
71
{
 
72
  unsigned char *get_var_key(const unsigned char* var, size_t *len, bool);
 
73
  bool get_one_option(int optid, const struct my_option *, char *argument);
 
74
}
 
75
 
62
76
#define MAX_VAR_NAME_LENGTH    256
63
77
#define MAX_COLUMNS            256
64
78
#define MAX_EMBEDDED_SERVER_ARGS 64
67
81
#define QUERY_SEND_FLAG  1
68
82
#define QUERY_REAP_FLAG  2
69
83
 
 
84
ErrorCodes global_error_names;
 
85
 
70
86
enum {
71
87
  OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL,
72
88
  OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES,
370
386
  char *query, *query_buf,*first_argument,*last_argument,*end;
371
387
  int first_word_len, query_len;
372
388
  bool abort_on_error;
373
 
  struct st_expected_errors expected_errors;
374
 
  char require_file[FN_REFLEN];
 
389
  st_expected_errors expected_errors;
 
390
  string require_file;
375
391
  enum enum_commands type;
 
392
 
 
393
  st_command()
 
394
    : query(NULL), query_buf(NULL), first_argument(NULL), last_argument(NULL),
 
395
      end(NULL), first_word_len(0), query_len(0), abort_on_error(false),
 
396
      require_file(""), type(Q_CONNECTION)
 
397
  {
 
398
    memset(&expected_errors, 0, sizeof(st_expected_errors));
 
399
  }
 
400
 
 
401
  ~st_command()
 
402
  {
 
403
    if (query_buf != NULL)
 
404
    {
 
405
      free(query_buf);
 
406
    }
 
407
  }
376
408
};
377
409
 
378
410
TYPELIB command_typelib= {array_elements(command_names),"",
517
549
  options are passed.
518
550
*/
519
551
 
520
 
void append_os_quoted(string *str, const char *append, ...)
 
552
static void append_os_quoted(string *str, const char *append, ...)
521
553
{
522
554
  const char *quote_str= "\'";
523
555
  const uint32_t  quote_len= 1;
874
906
  for (iter= q_lines.begin() ; iter < q_lines.end() ; iter++)
875
907
  {
876
908
    struct st_command * q_line= *iter;
877
 
    if (q_line->query_buf != NULL)
878
 
    {
879
 
      free(q_line->query_buf);
880
 
    }
881
 
    free(q_line);
 
909
    delete q_line;
882
910
  }
883
911
 
884
912
  for (i= 0; i < 10; i++)
1529
1557
 
1530
1558
*/
1531
1559
 
1532
 
static void check_require(string* ds, const char *fname)
 
1560
static void check_require(string* ds, const string &fname)
1533
1561
{
1534
1562
 
1535
1563
 
1536
 
  if (string_cmp(ds, fname))
 
1564
  if (string_cmp(ds, fname.c_str()))
1537
1565
  {
1538
1566
    char reason[FN_REFLEN];
1539
 
    fn_format(reason, fname, "", "", MY_REPLACE_EXT | MY_REPLACE_DIR);
 
1567
    fn_format(reason, fname.c_str(), "", "", MY_REPLACE_EXT | MY_REPLACE_DIR);
1540
1568
    abort_not_supported_test("Test requires: '%s'", reason);
1541
1569
  }
1542
1570
  return;
1587
1615
}
1588
1616
 
1589
1617
 
1590
 
extern "C"
1591
1618
unsigned char *get_var_key(const unsigned char* var, size_t *len, bool)
1592
1619
{
1593
1620
  register char* key;
2079
2106
    const size_t len= strlen(get_value_str);
2080
2107
    if (strncmp(p, get_value_str, len)==0)
2081
2108
    {
2082
 
      struct st_command command;
2083
 
      memset(&command, 0, sizeof(command));
 
2109
      st_command command;
2084
2110
      command.query= (char*)p;
2085
2111
      command.first_word_len= len;
2086
2112
      command.first_argument= command.query + len;
2512
2538
  /* Parse what mode to set */
2513
2539
  istringstream buff(ds_mode);
2514
2540
  if (ds_mode.length() != 4 ||
2515
 
      (buff >> mode).fail())
 
2541
      (buff >> oct >> mode).fail())
2516
2542
    die("You must write a 4 digit octal number for mode");
2517
2543
 
2518
2544
  handle_command_error(command, chmod(ds_file.c_str(), mode));
3309
3335
}
3310
3336
 
3311
3337
 
3312
 
static void do_get_file_name(struct st_command *command,
3313
 
                             char* dest, uint32_t dest_max_len)
 
3338
static void do_get_file_name(struct st_command *command, string &dest)
3314
3339
{
3315
3340
  char *p= command->first_argument, *name;
3316
3341
  if (!*p)
3321
3346
  if (*p)
3322
3347
    *p++= 0;
3323
3348
  command->last_argument= p;
3324
 
  strncpy(dest, name, dest_max_len - 1);
 
3349
  if (opt_testdir != NULL)
 
3350
  {
 
3351
    dest= opt_testdir;
 
3352
    if (dest[dest.length()] != '/')
 
3353
      dest.append("/");
 
3354
  }
 
3355
  dest.append(name);
3325
3356
}
3326
3357
 
3327
3358
 
3346
3377
 
3347
3378
static uint32_t get_errcode_from_name(char *error_name, char *error_end)
3348
3379
{
3349
 
  /* SQL error as string */
3350
 
  st_error *e= global_error_names;
3351
 
 
3352
 
  /* Loop through the array of known error names */
3353
 
  for (; e->name; e++)
3354
 
  {
3355
 
    /*
3356
 
      If we get a match, we need to check the length of the name we
3357
 
      matched against in case it was longer than what we are checking
3358
 
      (as in ER_WRONG_VALUE vs. ER_WRONG_VALUE_COUNT).
3359
 
    */
3360
 
    if (!strncmp(error_name, e->name, (int) (error_end - error_name)) &&
3361
 
        (uint32_t) strlen(e->name) == (uint32_t) (error_end - error_name))
3362
 
    {
3363
 
      return(e->code);
3364
 
    }
3365
 
  }
3366
 
  if (!e->name)
3367
 
    die("Unknown SQL error name '%s'", error_name);
3368
 
  return(0);
 
3380
  size_t err_name_len= error_end - error_name;
 
3381
  string error_name_s(error_name, err_name_len);
 
3382
 
 
3383
  uint32_t code= global_error_names.getErrorCode(error_name_s);
 
3384
 
 
3385
  if (!code)
 
3386
    die("Unknown SQL error name '%s'", error_name_s.c_str());
 
3387
 
 
3388
  return(code);
3369
3389
}
3370
3390
 
3371
3391
static void do_get_errcodes(struct st_command *command)
3766
3786
  drizzle_con_set_db(con, db);
3767
3787
  if ((ret= drizzle_con_connect(con)) != DRIZZLE_RETURN_OK)
3768
3788
  {
3769
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
 
3789
    if (ret == DRIZZLE_RETURN_HANDSHAKE_FAILED)
3770
3790
    {
3771
3791
      var_set_errno(drizzle_con_error_code(con));
3772
3792
      handle_error(command, drizzle_con_error_code(con), drizzle_con_error(con),
4187
4207
      }
4188
4208
      else if ((c == '{' &&
4189
4209
                (!my_strnncoll_simple(charset_info, (const unsigned char*) "while", 5,
4190
 
                                      (unsigned char*) buf, cmin((long)5, p - buf), 0) ||
 
4210
                                      (unsigned char*) buf, min((ptrdiff_t)5, p - buf), 0) ||
4191
4211
                 !my_strnncoll_simple(charset_info, (const unsigned char*) "if", 2,
4192
 
                                      (unsigned char*) buf, cmin((long)2, p - buf), 0))))
 
4212
                                      (unsigned char*) buf, min((ptrdiff_t)2, p - buf), 0))))
4193
4213
      {
4194
4214
        /* Only if and while commands can be terminated by { */
4195
4215
        *p++= c;
4266
4286
    {
4267
4287
      /* Could be a multibyte character */
4268
4288
      /* This code is based on the code in "sql_load.cc" */
4269
 
#ifdef USE_MB
4270
4289
      int charlen = my_mbcharlen(charset_info, c);
4271
4290
      /* We give up if multibyte character is started but not */
4272
4291
      /* completed before we pass buf_end */
4293
4312
        }
4294
4313
      }
4295
4314
      else
4296
 
#endif
4297
4315
        *p++= c;
4298
4316
    }
4299
4317
  }
4486
4504
    *command_ptr= q_lines[parser.current_line];
4487
4505
    return(0);
4488
4506
  }
4489
 
  if (!(*command_ptr= command=
4490
 
        (struct st_command*) malloc(sizeof(*command))))
4491
 
    die(NULL);
4492
 
  memset(command, 0, sizeof(*command));
 
4507
  if (!(*command_ptr= command= new st_command))
 
4508
    die("command construction failed");
4493
4509
  q_lines.push_back(command);
4494
4510
  command->type= Q_UNKNOWN;
4495
4511
 
4618
4634
 
4619
4635
static void print_version(void)
4620
4636
{
4621
 
  printf("%s  Ver %s Distrib %s, for %s (%s)\n",my_progname,MTEST_VERSION,
4622
 
         drizzle_version(),SYSTEM_TYPE,MACHINE_TYPE);
 
4637
  printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",my_progname,MTEST_VERSION,
 
4638
         drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
4623
4639
}
4624
4640
 
4625
4641
static void usage(void)
4680
4696
}
4681
4697
 
4682
4698
 
4683
 
extern "C" bool
4684
 
get_one_option(int optid, const struct my_option *, char *argument)
 
4699
bool get_one_option(int optid, const struct my_option *, char *argument)
4685
4700
{
4686
4701
  char *endchar= NULL;
4687
4702
  uint64_t temp_drizzle_port= 0;
5120
5135
    (void) drizzle_query(con, &res, query, query_len, &ret);
5121
5136
    if (ret != DRIZZLE_RETURN_OK)
5122
5137
    {
5123
 
      if (ret == DRIZZLE_RETURN_ERROR_CODE)
 
5138
      if (ret == DRIZZLE_RETURN_ERROR_CODE ||
 
5139
          ret == DRIZZLE_RETURN_HANDSHAKE_FAILED)
5124
5140
      {
5125
5141
        err= drizzle_result_error_code(&res);
5126
5142
        handle_error(command, err, drizzle_result_error(&res),
5127
5143
                     drizzle_result_sqlstate(&res), ds);
5128
 
        drizzle_result_free(&res);
 
5144
        if (ret == DRIZZLE_RETURN_ERROR_CODE)
 
5145
          drizzle_result_free(&res);
5129
5146
      }
5130
5147
      else
5131
5148
      {
5193
5210
      }
5194
5211
 
5195
5212
      /*
5196
 
        Need to call drizzleclient_affected_rows() before the "new"
 
5213
        Need to call drizzle_result_affected_rows() before the "new"
5197
5214
        query to find the warnings
5198
5215
      */
5199
5216
      if (!disable_info)
5260
5277
  uint32_t i;
5261
5278
 
5262
5279
 
5263
 
  if (command->require_file[0])
 
5280
  if (! command->require_file.empty())
5264
5281
  {
5265
5282
    /*
5266
5283
      The query after a "--require" failed. This is fine as long the server
5419
5436
    Create a temporary dynamic string to contain the output from
5420
5437
    this query.
5421
5438
  */
5422
 
  if (command->require_file[0])
 
5439
  if (! command->require_file.empty())
5423
5440
  {
5424
5441
    ds= &ds_result;
5425
5442
  }
5462
5479
    ds= save_ds;
5463
5480
  }
5464
5481
 
5465
 
  if (command->require_file[0])
 
5482
  if (! command->require_file.empty())
5466
5483
  {
5467
5484
    /* A result file was specified for _this_ query
5468
5485
       and the output should be checked against an already
5593
5610
  struct st_command *command;
5594
5611
  bool q_send_flag= 0, abort_flag= 0;
5595
5612
  uint32_t command_executed= 0, last_command_executed= 0;
5596
 
  char save_file[FN_REFLEN];
 
5613
  string save_file("");
5597
5614
  struct stat res_info;
5598
5615
  MY_INIT(argv[0]);
5599
5616
 
5600
 
  save_file[0]= 0;
5601
5617
  TMPDIR[0]= 0;
5602
5618
 
5603
5619
  /* Init expected errors */
5792
5808
        /* Check for special property for this query */
5793
5809
        display_result_vertically|= (command->type == Q_QUERY_VERTICAL);
5794
5810
 
5795
 
        if (save_file[0])
 
5811
        if (! save_file.empty())
5796
5812
        {
5797
 
          strncpy(command->require_file, save_file, sizeof(save_file) - 1);
5798
 
          save_file[0]= 0;
 
5813
          command->require_file= save_file;
 
5814
          save_file.clear();
5799
5815
        }
5800
5816
        run_query(cur_con, command, flags);
5801
5817
        command_executed++;
5832
5848
        command->last_argument= command->end;
5833
5849
        break;
5834
5850
      case Q_REQUIRE:
5835
 
        do_get_file_name(command, save_file, sizeof(save_file));
 
5851
        do_get_file_name(command, save_file);
5836
5852
        break;
5837
5853
      case Q_ERROR:
5838
5854
        do_get_errcodes(command);
7167
7183
      return(1);
7168
7184
    if (new_pos != pa->str)
7169
7185
    {
7170
 
      my_ptrdiff_t diff=PTR_BYTE_DIFF(new_pos,pa->str);
 
7186
      ptrdiff_t diff= PTR_BYTE_DIFF(new_pos,pa->str);
7171
7187
      for (i=0 ; i < pa->typelib.count ; i++)
7172
7188
        pa->typelib.type_names[i]= ADD_TO_PTR(pa->typelib.type_names[i],diff,
7173
7189
                                              char*);