~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzletest.cc

  • Committer: Monty Taylor
  • Date: 2008-11-16 20:15:33 UTC
  • mto: (584.1.9 devel)
  • mto: This revision was merged to the branch mainline in revision 589.
  • Revision ID: monty@inaugust.com-20081116201533-d0f19s1bk1h95iyw
Removed a big bank of includes from item.h.

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
 
39
39
#define MTEST_VERSION "3.3"
40
40
 
 
41
#include <config.h>
41
42
#include "client_priv.h"
42
43
 
43
44
#include <queue>
44
45
#include <map>
45
46
#include <string>
46
 
#include <sstream>
47
 
#include <iostream>
48
47
#include <vector>
49
 
#include <algorithm>
50
 
#ifdef HAVE_SYS_WAIT_H
51
 
#include <sys/wait.h>
52
 
#endif
53
 
#include <cassert>
54
 
#include <sys/stat.h>
55
 
#include <sys/types.h>
56
 
#include <fcntl.h>
57
 
 
58
 
#include PCRE_HEADER
59
 
 
 
48
 
 
49
#include <pcrecpp.h>
 
50
 
 
51
#include <mysys/hash.h>
60
52
#include <stdarg.h>
61
53
 
62
54
#include "errname.h"
63
55
 
64
 
/* Added this for string translation. */
65
 
#include "drizzled/gettext.h"
66
 
#include "drizzled/hash.h"
67
 
#include "drizzled/drizzle_time.h"
68
 
#include "drizzled/charset.h"
69
 
 
70
 
#ifndef DRIZZLE_RETURN_SERVER_GONE
71
 
#define DRIZZLE_RETURN_HANDSHAKE_FAILED DRIZZLE_RETURN_ERROR_CODE
72
 
#endif
73
 
 
74
56
using namespace std;
75
 
using namespace drizzled;
76
 
 
77
 
extern "C"
78
 
unsigned char *get_var_key(const unsigned char* var, size_t *len, bool);
79
 
 
80
 
int get_one_option(int optid, const struct option *, char *argument);
81
57
 
82
58
#define MAX_VAR_NAME_LENGTH    256
83
59
#define MAX_COLUMNS            256
 
60
#define MAX_EMBEDDED_SERVER_ARGS 64
84
61
#define MAX_DELIMITER_LENGTH 16
85
62
/* Flags controlling send and reap */
86
63
#define QUERY_SEND_FLAG  1
87
64
#define QUERY_REAP_FLAG  2
88
65
 
89
 
ErrorCodes global_error_names;
90
 
 
91
66
enum {
92
67
  OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL,
93
 
  OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES,
94
 
  OPT_TESTDIR
 
68
  OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES
95
69
};
96
70
 
97
71
static int record= 0, opt_sleep= -1;
98
 
static char *opt_db= NULL, *opt_pass= NULL;
99
 
const char *opt_user= NULL, *opt_host= NULL, *unix_sock= NULL,
100
 
           *opt_basedir= "./";
 
72
static char *opt_db= 0, *opt_pass= 0;
 
73
const char *opt_user= 0, *opt_host= 0, *unix_sock= 0, *opt_basedir= "./";
101
74
const char *opt_logdir= "";
102
 
const char *opt_include= NULL, *opt_charsets_dir;
103
 
const char *opt_testdir= NULL;
104
 
static uint32_t opt_port= 0;
 
75
const char *opt_include= 0, *opt_charsets_dir;
 
76
static int opt_port= 0;
105
77
static int opt_max_connect_retries;
106
 
static bool silent= false, verbose= false;
107
 
static bool tty_password= false;
108
 
static bool opt_mark_progress= false;
109
 
static bool parsing_disabled= false;
 
78
static bool opt_compress= 0, silent= 0, verbose= 0;
 
79
static bool debug_info_flag= 0, debug_check_flag= 0;
 
80
static bool tty_password= 0;
 
81
static bool opt_mark_progress= 0;
 
82
static bool parsing_disabled= 0;
110
83
static bool display_result_vertically= false,
111
84
  display_metadata= false, display_result_sorted= false;
112
 
static bool disable_query_log= false, disable_result_log= false;
113
 
static bool disable_warnings= false;
114
 
static bool disable_info= true;
115
 
static bool abort_on_error= true;
116
 
static bool server_initialized= false;
117
 
static bool is_windows= false;
118
 
static bool opt_mysql= false;
 
85
static bool disable_query_log= 0, disable_result_log= 0;
 
86
static bool disable_warnings= 0;
 
87
static bool disable_info= 1;
 
88
static bool abort_on_error= 1;
 
89
static bool server_initialized= 0;
 
90
static bool is_windows= 0;
119
91
static char **default_argv;
120
92
static const char *load_default_groups[]= { "drizzletest", "client", 0 };
121
93
static char line_buffer[MAX_DELIMITER_LENGTH], *line_buffer_pos= line_buffer;
122
94
 
123
 
static uint32_t start_lineno= 0; /* Start line of current command */
 
95
static uint start_lineno= 0; /* Start line of current command */
 
96
static uint my_end_arg= 0;
124
97
 
125
98
/* Number of lines of the result to include in failure report */
126
 
static uint32_t opt_tail_lines= 0;
 
99
static uint opt_tail_lines= 0;
127
100
 
128
101
static char delimiter[MAX_DELIMITER_LENGTH]= ";";
129
 
static uint32_t delimiter_length= 1;
 
102
static uint delimiter_length= 1;
130
103
 
131
104
static char TMPDIR[FN_REFLEN];
132
105
 
152
125
{
153
126
  FILE* file;
154
127
  const char *file_name;
155
 
  uint32_t lineno; /* Current line in file */
 
128
  uint lineno; /* Current line in file */
156
129
};
157
130
 
158
131
static struct st_test_file file_stack[16];
162
135
 
163
136
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci; /* Default charset */
164
137
 
 
138
static int embedded_server_arg_count=0;
 
139
static char *embedded_server_args[MAX_EMBEDDED_SERVER_ARGS];
 
140
 
165
141
/*
166
142
  Timer related variables
167
143
  See the timer_output() definition for details
189
165
master_pos_st master_pos;
190
166
 
191
167
/* if set, all results are concated and compared against this file */
192
 
const char *result_file_name= NULL;
 
168
const char *result_file_name= 0;
193
169
 
194
170
typedef struct st_var
195
171
{
207
183
/*Perl/shell-like variable registers */
208
184
VAR var_reg[10];
209
185
 
210
 
 
211
 
drizzled::hash_map<string, VAR *> var_hash;
 
186
HASH var_hash;
212
187
 
213
188
struct st_connection
214
189
{
215
 
  drizzle_st *drizzle;
216
 
  drizzle_con_st con;
 
190
  DRIZZLE drizzle;
217
191
  /* Used when creating views and sp, to avoid implicit commit */
218
 
  drizzle_con_st *util_con;
 
192
  DRIZZLE *util_drizzle;
219
193
  char *name;
220
194
};
221
195
struct st_connection connections[128];
371
345
  enum match_err_type type;
372
346
  union
373
347
  {
374
 
    uint32_t errnum;
375
 
    char sqlstate[DRIZZLE_MAX_SQLSTATE_SIZE+1];  /* \0 terminated string */
 
348
    uint errnum;
 
349
    char sqlstate[SQLSTATE_LENGTH+1];  /* \0 terminated string */
376
350
  } code;
377
351
};
378
352
 
379
353
struct st_expected_errors
380
354
{
381
355
  struct st_match_err err[10];
382
 
  uint32_t count;
 
356
  uint count;
383
357
};
384
358
static struct st_expected_errors saved_expected_errors;
385
359
 
388
362
  char *query, *query_buf,*first_argument,*last_argument,*end;
389
363
  int first_word_len, query_len;
390
364
  bool abort_on_error;
391
 
  st_expected_errors expected_errors;
392
 
  string require_file;
 
365
  struct st_expected_errors expected_errors;
 
366
  char require_file[FN_REFLEN];
393
367
  enum enum_commands type;
394
 
 
395
 
  st_command()
396
 
    : query(NULL), query_buf(NULL), first_argument(NULL), last_argument(NULL),
397
 
      end(NULL), first_word_len(0), query_len(0), abort_on_error(false),
398
 
      require_file(""), type(Q_CONNECTION)
399
 
  {
400
 
    memset(&expected_errors, 0, sizeof(st_expected_errors));
401
 
  }
402
 
 
403
 
  ~st_command()
404
 
  {
405
 
    if (query_buf != NULL)
406
 
    {
407
 
      free(query_buf);
408
 
    }
409
 
  }
410
368
};
411
369
 
412
370
TYPELIB command_typelib= {array_elements(command_names),"",
430
388
VAR* var_from_env(const char *, const char *);
431
389
VAR* var_init(VAR* v, const char *name, int name_len, const char *val,
432
390
              int val_len);
433
 
void var_free(pair<string, VAR*> v);
 
391
void var_free(void* v);
434
392
VAR* var_get(const char *var_name, const char** var_name_end,
435
393
             bool raw, bool ignore_not_existing);
436
394
void eval_expr(VAR* v, const char *p, const char** p_end);
437
 
bool match_delimiter(int c, const char *delim, uint32_t length);
 
395
bool match_delimiter(int c, const char *delim, uint length);
438
396
void dump_result_to_reject_file(char *buf, int size);
439
397
void dump_result_to_log_file(const char *buf, int size);
440
398
void dump_warning_messages(void);
447
405
 
448
406
/* For replace_column */
449
407
static char *replace_column[MAX_COLUMNS];
450
 
static uint32_t max_replace_column= 0;
 
408
static uint max_replace_column= 0;
451
409
void do_get_replace_column(struct st_command*);
452
410
void free_replace_column(void);
453
411
 
472
430
void replace_append_mem(string *ds, const char *val,
473
431
                        int len);
474
432
void replace_append(string *ds, const char *val);
475
 
void replace_append_uint(string *ds, uint32_t val);
 
433
void replace_append_uint(string *ds, uint val);
476
434
void append_sorted(string* ds, string* ds_input);
477
435
 
478
436
void handle_error(struct st_command*,
481
439
void handle_no_error(struct st_command*);
482
440
 
483
441
 
 
442
#define do_send_query(cn,q,q_len,flags) drizzle_send_query(&cn->drizzle, q, q_len)
 
443
 
484
444
void do_eval(string *query_eval, const char *query,
485
445
             const char *query_end, bool pass_through_escape_chars)
486
446
{
551
511
  options are passed.
552
512
*/
553
513
 
554
 
static void append_os_quoted(string *str, const char *append, ...)
 
514
void append_os_quoted(string *str, const char *append, ...)
555
515
{
556
516
  const char *quote_str= "\'";
557
 
  const uint32_t  quote_len= 1;
 
517
  const uint  quote_len= 1;
558
518
 
559
519
  va_list dirty_text;
560
520
 
594
554
 
595
555
*/
596
556
 
597
 
static void show_query(drizzle_con_st *con, const char* query)
 
557
static void show_query(DRIZZLE *drizzle, const char* query)
598
558
{
599
 
  drizzle_result_st res;
600
 
  drizzle_return_t ret;
601
 
 
602
 
  if (!con)
 
559
  DRIZZLE_RES* res;
 
560
 
 
561
 
 
562
  if (!drizzle)
603
563
    return;
604
564
 
605
 
  if (drizzle_query_str(con, &res, query, &ret) == NULL ||
606
 
      ret != DRIZZLE_RETURN_OK)
 
565
  if (drizzle_query(drizzle, query))
607
566
  {
608
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
609
 
    {
610
 
      log_msg("Error running query '%s': %d %s",
611
 
              query, drizzle_result_error_code(&res),
612
 
              drizzle_result_error(&res));
613
 
      drizzle_result_free(&res);
614
 
    }
615
 
    else
616
 
    {
617
 
      log_msg("Error running query '%s': %d %s",
618
 
              query, ret, drizzle_con_error(con));
619
 
    }
 
567
    log_msg("Error running query '%s': %d %s",
 
568
            query, drizzle_errno(drizzle), drizzle_error(drizzle));
620
569
    return;
621
570
  }
622
571
 
623
 
  if (drizzle_result_column_count(&res) == 0 ||
624
 
      drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
 
572
  if ((res= drizzle_store_result(drizzle)) == NULL)
625
573
  {
626
574
    /* No result set returned */
627
 
    drizzle_result_free(&res);
628
575
    return;
629
576
  }
630
577
 
631
578
  {
632
 
    drizzle_row_t row;
 
579
    DRIZZLE_ROW row;
633
580
    unsigned int i;
634
581
    unsigned int row_num= 0;
635
 
    unsigned int num_fields= drizzle_result_column_count(&res);
636
 
    drizzle_column_st *column;
 
582
    unsigned int num_fields= drizzle_num_fields(res);
 
583
    const DRIZZLE_FIELD *fields= drizzle_fetch_fields(res);
637
584
 
638
585
    fprintf(stderr, "=== %s ===\n", query);
639
 
    while ((row= drizzle_row_next(&res)))
 
586
    while ((row= drizzle_fetch_row(res)))
640
587
    {
641
 
      size_t *lengths= drizzle_row_field_sizes(&res);
 
588
      uint32_t *lengths= drizzle_fetch_lengths(res);
642
589
      row_num++;
643
590
 
644
591
      fprintf(stderr, "---- %d. ----\n", row_num);
645
 
      drizzle_column_seek(&res, 0);
646
592
      for(i= 0; i < num_fields; i++)
647
593
      {
648
 
        column= drizzle_column_next(&res);
649
594
        fprintf(stderr, "%s\t%.*s\n",
650
 
                drizzle_column_name(column),
 
595
                fields[i].name,
651
596
                (int)lengths[i], row[i] ? row[i] : "NULL");
652
597
      }
653
598
    }
655
600
      fprintf(stderr, "=");
656
601
    fprintf(stderr, "\n\n");
657
602
  }
658
 
  drizzle_result_free(&res);
 
603
  drizzle_free_result(res);
659
604
 
660
605
  return;
661
606
}
674
619
 
675
620
*/
676
621
 
677
 
static void show_warnings_before_error(drizzle_con_st *con)
 
622
static void show_warnings_before_error(DRIZZLE *drizzle)
678
623
{
679
 
  drizzle_result_st res;
680
 
  drizzle_return_t ret;
 
624
  DRIZZLE_RES* res;
681
625
  const char* query= "SHOW WARNINGS";
682
626
 
683
 
  if (!con)
 
627
 
 
628
  if (!drizzle)
684
629
    return;
685
630
 
686
 
  if (drizzle_query_str(con, &res, query, &ret) == NULL ||
687
 
      ret != DRIZZLE_RETURN_OK)
 
631
  if (drizzle_query(drizzle, query))
688
632
  {
689
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
690
 
    {
691
 
      log_msg("Error running query '%s': %d %s",
692
 
              query, drizzle_result_error_code(&res),
693
 
              drizzle_result_error(&res));
694
 
      drizzle_result_free(&res);
695
 
    }
696
 
    else
697
 
    {
698
 
      log_msg("Error running query '%s': %d %s",
699
 
              query, ret, drizzle_con_error(con));
700
 
    }
 
633
    log_msg("Error running query '%s': %d %s",
 
634
            query, drizzle_errno(drizzle), drizzle_error(drizzle));
701
635
    return;
702
636
  }
703
637
 
704
 
  if (drizzle_result_column_count(&res) == 0 ||
705
 
      drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
 
638
  if ((res= drizzle_store_result(drizzle)) == NULL)
706
639
  {
707
640
    /* No result set returned */
708
 
    drizzle_result_free(&res);
709
641
    return;
710
642
  }
711
643
 
712
 
  if (drizzle_result_row_count(&res) <= 1)
 
644
  if (drizzle_num_rows(res) <= 1)
713
645
  {
714
646
    /* Don't display the last row, it's "last error" */
715
647
  }
716
648
  else
717
649
  {
718
 
    drizzle_row_t row;
 
650
    DRIZZLE_ROW row;
719
651
    unsigned int row_num= 0;
720
 
    unsigned int num_fields= drizzle_result_column_count(&res);
 
652
    unsigned int num_fields= drizzle_num_fields(res);
721
653
 
722
654
    fprintf(stderr, "\nWarnings from just before the error:\n");
723
 
    while ((row= drizzle_row_next(&res)))
 
655
    while ((row= drizzle_fetch_row(res)))
724
656
    {
725
657
      uint32_t i;
726
 
      size_t *lengths= drizzle_row_field_sizes(&res);
 
658
      uint32_t *lengths= drizzle_fetch_lengths(res);
727
659
 
728
 
      if (++row_num >= drizzle_result_row_count(&res))
 
660
      if (++row_num >= drizzle_num_rows(res))
729
661
      {
730
662
        /* Don't display the last row, it's "last error" */
731
663
        break;
739
671
      fprintf(stderr, "\n");
740
672
    }
741
673
  }
742
 
  drizzle_result_free(&res);
 
674
  drizzle_free_result(res);
743
675
 
744
676
  return;
745
677
}
772
704
  for (i= 0; i < num_args; i++)
773
705
  {
774
706
    const struct command_arg *arg= &args[i];
775
 
    arg->ds->clear();
776
707
 
777
708
    switch (arg->type) {
778
709
      /* A string */
831
762
}
832
763
 
833
764
 
834
 
static void handle_command_error(struct st_command *command, uint32_t error)
 
765
static void handle_command_error(struct st_command *command, uint error)
835
766
{
836
767
 
837
768
  if (error != 0)
838
769
  {
839
 
    uint32_t i;
 
770
    uint i;
840
771
 
841
772
    if (command->abort_on_error)
842
773
      die("command \"%.*s\" failed with error %d",
866
797
 
867
798
static void close_connections(void)
868
799
{
 
800
 
869
801
  for (--next_con; next_con >= connections; --next_con)
870
802
  {
871
 
    if (next_con->drizzle != NULL)
872
 
    {
873
 
      drizzle_free(next_con->drizzle);
874
 
      next_con->drizzle= NULL;
875
 
    }
 
803
    drizzle_close(&next_con->drizzle);
 
804
    if (next_con->util_drizzle)
 
805
      drizzle_close(next_con->util_drizzle);
876
806
    free(next_con->name);
877
807
  }
878
808
  return;
886
816
  {
887
817
    if (cur_file->file && cur_file->file != stdin)
888
818
    {
889
 
      fclose(cur_file->file);
 
819
      my_fclose(cur_file->file, MYF(0));
890
820
    }
891
821
    free((unsigned char*) cur_file->file_name);
892
822
    cur_file->file_name= 0;
897
827
 
898
828
static void free_used_memory(void)
899
829
{
900
 
  uint32_t i;
 
830
  uint i;
901
831
 
902
832
 
903
833
  close_connections();
904
834
  close_files();
905
 
  for_each(var_hash.begin(), var_hash.end(), var_free);
906
 
  var_hash.clear();
 
835
  hash_free(&var_hash);
907
836
 
908
 
  vector<st_command *>::iterator iter;
 
837
  vector<struct st_command *>::iterator iter;
909
838
  for (iter= q_lines.begin() ; iter < q_lines.end() ; iter++)
910
839
  {
911
840
    struct st_command * q_line= *iter;
912
 
    delete q_line;
 
841
    if (q_line->query_buf != NULL)
 
842
    {
 
843
      free(q_line->query_buf);
 
844
    }
 
845
    free(q_line);
913
846
  }
914
847
 
915
848
  for (i= 0; i < 10; i++)
917
850
    if (var_reg[i].alloced_len)
918
851
      free(var_reg[i].str_val);
919
852
  }
 
853
  while (embedded_server_arg_count > 1)
 
854
    free(embedded_server_args[--embedded_server_arg_count]);
920
855
 
921
856
  free_all_replace();
922
857
  free(opt_pass);
923
 
  internal::free_defaults(default_argv);
 
858
  free_defaults(default_argv);
924
859
 
925
860
  return;
926
861
}
929
864
static void cleanup_and_exit(int exit_code)
930
865
{
931
866
  free_used_memory();
932
 
  internal::my_end();
 
867
  my_end(my_end_arg);
933
868
 
934
869
  if (!silent) {
935
870
    switch (exit_code) {
1014
949
    been produced prior to the error
1015
950
  */
1016
951
  if (cur_con)
1017
 
    show_warnings_before_error(&cur_con->con);
 
952
    show_warnings_before_error(&cur_con->drizzle);
1018
953
 
1019
954
  cleanup_and_exit(1);
1020
955
}
1139
1074
static void cat_file(string* ds, const char* filename)
1140
1075
{
1141
1076
  int fd;
1142
 
  uint32_t len;
 
1077
  uint len;
1143
1078
  char buff[512];
1144
1079
 
1145
 
  if ((fd= internal::my_open(filename, O_RDONLY, MYF(0))) < 0)
 
1080
  if ((fd= my_open(filename, O_RDONLY, MYF(0))) < 0)
1146
1081
    die("Failed to open file '%s'", filename);
1147
 
  while((len= internal::my_read(fd, (unsigned char*)&buff,
 
1082
  while((len= my_read(fd, (unsigned char*)&buff,
1148
1083
                      sizeof(buff), MYF(0))) > 0)
1149
1084
  {
1150
1085
    char *p= buff, *start= buff;
1166
1101
    /* Output any chars that might be left */
1167
1102
    ds->append(start, p-start);
1168
1103
  }
1169
 
  internal::my_close(fd, MYF(0));
 
1104
  my_close(fd, MYF(0));
1170
1105
}
1171
1106
 
1172
1107
 
1271
1206
               "2>&1",
1272
1207
               NULL) > 1) /* Most "diff" tools return >1 if error */
1273
1208
  {
 
1209
    ds_tmp= "";
1274
1210
 
1275
1211
    /* Fallback to context diff with "diff -c" */
1276
1212
    if (run_tool("diff",
1285
1221
        Fallback to dump both files to result file and inform
1286
1222
        about installing "diff"
1287
1223
      */
1288
 
      ds_tmp.clear();
 
1224
      ds_tmp= "";
1289
1225
 
1290
1226
      ds_tmp.append(
1291
1227
                    "\n"
1342
1278
 
1343
1279
*/
1344
1280
 
1345
 
static int compare_files2(int fd, const char* filename2)
 
1281
static int compare_files2(File fd, const char* filename2)
1346
1282
{
1347
1283
  int error= RESULT_OK;
1348
 
  int fd2;
1349
 
  uint32_t len, len2;
 
1284
  File fd2;
 
1285
  uint len, len2;
1350
1286
  char buff[512], buff2[512];
1351
 
  const char *fname= filename2;
1352
 
  string tmpfile;
1353
1287
 
1354
 
  if ((fd2= internal::my_open(fname, O_RDONLY, MYF(0))) < 0)
 
1288
  if ((fd2= my_open(filename2, O_RDONLY, MYF(0))) < 0)
1355
1289
  {
1356
 
    internal::my_close(fd, MYF(0));
1357
 
    if (opt_testdir != NULL)
1358
 
    {
1359
 
      tmpfile= opt_testdir;
1360
 
      if (tmpfile[tmpfile.length()] != '/')
1361
 
        tmpfile.append("/");
1362
 
      tmpfile.append(filename2);
1363
 
      fname= tmpfile.c_str();
1364
 
    }
1365
 
    if ((fd2= internal::my_open(fname, O_RDONLY, MYF(0))) < 0)
1366
 
    {
1367
 
      internal::my_close(fd, MYF(0));
1368
 
    
1369
 
      die("Failed to open second file: '%s'", fname);
1370
 
    }
 
1290
    my_close(fd, MYF(0));
 
1291
    die("Failed to open second file: '%s'", filename2);
1371
1292
  }
1372
 
  while((len= internal::my_read(fd, (unsigned char*)&buff,
 
1293
  while((len= my_read(fd, (unsigned char*)&buff,
1373
1294
                      sizeof(buff), MYF(0))) > 0)
1374
1295
  {
1375
 
    if ((len2= internal::my_read(fd2, (unsigned char*)&buff2,
 
1296
    if ((len2= my_read(fd2, (unsigned char*)&buff2,
1376
1297
                       sizeof(buff2), MYF(0))) < len)
1377
1298
    {
1378
1299
      /* File 2 was smaller */
1392
1313
      break;
1393
1314
    }
1394
1315
  }
1395
 
  if (!error && internal::my_read(fd2, (unsigned char*)&buff2,
 
1316
  if (!error && my_read(fd2, (unsigned char*)&buff2,
1396
1317
                        sizeof(buff2), MYF(0)) > 0)
1397
1318
  {
1398
1319
    /* File 1 was smaller */
1399
1320
    error= RESULT_LENGTH_MISMATCH;
1400
1321
  }
1401
1322
 
1402
 
  internal::my_close(fd2, MYF(0));
 
1323
  my_close(fd2, MYF(0));
1403
1324
 
1404
1325
  return error;
1405
1326
}
1420
1341
 
1421
1342
static int compare_files(const char* filename1, const char* filename2)
1422
1343
{
1423
 
  int fd;
 
1344
  File fd;
1424
1345
  int error;
1425
1346
 
1426
 
  if ((fd= internal::my_open(filename1, O_RDONLY, MYF(0))) < 0)
 
1347
  if ((fd= my_open(filename1, O_RDONLY, MYF(0))) < 0)
1427
1348
    die("Failed to open first file: '%s'", filename1);
1428
1349
 
1429
1350
  error= compare_files2(fd, filename2);
1430
1351
 
1431
 
  internal::my_close(fd, MYF(0));
 
1352
  my_close(fd, MYF(0));
1432
1353
 
1433
1354
  return error;
1434
1355
}
1449
1370
static int string_cmp(string* ds, const char *fname)
1450
1371
{
1451
1372
  int error;
1452
 
  int fd;
 
1373
  File fd;
1453
1374
  char temp_file_path[FN_REFLEN];
1454
1375
 
1455
 
  if ((fd= internal::create_temp_file(temp_file_path, NULL,
1456
 
                            "tmp", MYF(MY_WME))) < 0)
 
1376
  if ((fd= create_temp_file(temp_file_path, NULL,
 
1377
                            "tmp", O_CREAT | O_RDWR,
 
1378
                            MYF(MY_WME))) < 0)
1457
1379
    die("Failed to create temporary file for ds");
1458
1380
 
1459
1381
  /* Write ds to temporary file and set file pos to beginning*/
1460
 
  if (internal::my_write(fd, (unsigned char *) ds->c_str(), ds->length(),
 
1382
  if (my_write(fd, (unsigned char *) ds->c_str(), ds->length(),
1461
1383
               MYF(MY_FNABP | MY_WME)) ||
1462
 
      lseek(fd, 0, SEEK_SET) == MY_FILEPOS_ERROR)
 
1384
      my_seek(fd, 0, SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR)
1463
1385
  {
1464
 
    internal::my_close(fd, MYF(0));
 
1386
    my_close(fd, MYF(0));
1465
1387
    /* Remove the temporary file */
1466
 
    internal::my_delete(temp_file_path, MYF(0));
 
1388
    my_delete(temp_file_path, MYF(0));
1467
1389
    die("Failed to write file '%s'", temp_file_path);
1468
1390
  }
1469
1391
 
1470
1392
  error= compare_files2(fd, fname);
1471
1393
 
1472
 
  internal::my_close(fd, MYF(0));
 
1394
  my_close(fd, MYF(0));
1473
1395
  /* Remove the temporary file */
1474
 
  internal::my_delete(temp_file_path, MYF(0));
 
1396
  my_delete(temp_file_path, MYF(0));
1475
1397
 
1476
1398
  return(error);
1477
1399
}
1513
1435
    */
1514
1436
    char reject_file[FN_REFLEN];
1515
1437
    size_t reject_length;
1516
 
    internal::dirname_part(reject_file, result_file_name, &reject_length);
 
1438
    dirname_part(reject_file, result_file_name, &reject_length);
1517
1439
 
1518
1440
    if (access(reject_file, W_OK) == 0)
1519
1441
    {
1520
1442
      /* Result file directory is writable, save reject file there */
1521
 
      internal::fn_format(reject_file, result_file_name, NULL,
 
1443
      fn_format(reject_file, result_file_name, NULL,
1522
1444
                ".reject", MY_REPLACE_EXT);
1523
1445
    }
1524
1446
    else
1525
1447
    {
1526
1448
      /* Put reject file in opt_logdir */
1527
 
      internal::fn_format(reject_file, result_file_name, opt_logdir,
 
1449
      fn_format(reject_file, result_file_name, opt_logdir,
1528
1450
                ".reject", MY_REPLACE_DIR | MY_REPLACE_EXT);
1529
1451
    }
1530
1452
    str_to_file(reject_file, ds->c_str(), ds->length());
1558
1480
 
1559
1481
*/
1560
1482
 
1561
 
static void check_require(string* ds, const string &fname)
 
1483
static void check_require(string* ds, const char *fname)
1562
1484
{
1563
1485
 
1564
1486
 
1565
 
  if (string_cmp(ds, fname.c_str()))
 
1487
  if (string_cmp(ds, fname))
1566
1488
  {
1567
1489
    char reason[FN_REFLEN];
1568
 
    internal::fn_format(reason, fname.c_str(), "", "", MY_REPLACE_EXT | MY_REPLACE_DIR);
 
1490
    fn_format(reason, fname, "", "", MY_REPLACE_EXT | MY_REPLACE_DIR);
1569
1491
    abort_not_supported_test("Test requires: '%s'", reason);
1570
1492
  }
1571
1493
  return;
1616
1538
}
1617
1539
 
1618
1540
 
 
1541
static unsigned char *get_var_key(const unsigned char* var, size_t *len,
 
1542
                          bool __attribute__((unused)) t)
 
1543
{
 
1544
  register char* key;
 
1545
  key = ((VAR*)var)->name;
 
1546
  *len = ((VAR*)var)->name_len;
 
1547
  return (unsigned char*)key;
 
1548
}
 
1549
 
1619
1550
 
1620
1551
VAR *var_init(VAR *v, const char *name, int name_len, const char *val,
1621
1552
              int val_len)
1627
1558
  if (!val_len && val)
1628
1559
    val_len = strlen(val) ;
1629
1560
  val_alloc_len = val_len + 16; /* room to grow */
1630
 
  if (!(tmp_var=v) && !(tmp_var = (VAR*)malloc(sizeof(*tmp_var)
1631
 
                                               + name_len+1)))
 
1561
  if (!(tmp_var=v) && !(tmp_var = (VAR*)my_malloc(sizeof(*tmp_var)
 
1562
                                                  + name_len+1, MYF(MY_WME))))
1632
1563
    die("Out of memory");
1633
1564
 
1634
1565
  tmp_var->name = (name) ? (char*) tmp_var + sizeof(*tmp_var) : 0;
1635
1566
  tmp_var->alloced = (v == 0);
1636
1567
 
1637
 
  if (!(tmp_var->str_val = (char *)malloc(val_alloc_len+1)))
 
1568
  if (!(tmp_var->str_val = (char *)my_malloc(val_alloc_len+1, MYF(MY_WME))))
1638
1569
    die("Out of memory");
1639
1570
 
1640
1571
  memcpy(tmp_var->name, name, name_len);
1653
1584
}
1654
1585
 
1655
1586
 
1656
 
void var_free(pair<string, VAR *> v)
 
1587
void var_free(void *v)
1657
1588
{
1658
 
  free(v.second->str_val);
1659
 
  free(v.second->env_s);
1660
 
  if (v.second->alloced)
1661
 
    free(v.second);
 
1589
  free(((VAR*) v)->str_val);
 
1590
  free(((VAR*) v)->env_s);
 
1591
  if (((VAR*)v)->alloced)
 
1592
    free(v);
1662
1593
}
1663
1594
 
1664
1595
 
1670
1601
    tmp = def_val;
1671
1602
 
1672
1603
  v = var_init(0, name, strlen(name), tmp, strlen(tmp));
1673
 
  string var_name(name);
1674
 
  var_hash.insert(make_pair(var_name, v));
 
1604
  my_hash_insert(&var_hash, (unsigned char*)v);
1675
1605
  return v;
1676
1606
}
1677
1607
 
1688
1618
  if (digit < 0 || digit >= 10)
1689
1619
  {
1690
1620
    const char *save_var_name = var_name, *end;
1691
 
    uint32_t length;
 
1621
    uint length;
1692
1622
    end = (var_name_end) ? *var_name_end : 0;
1693
1623
    while (my_isvar(charset_info,*var_name) && var_name != end)
1694
1624
      var_name++;
1698
1628
        return(0);
1699
1629
      die("Empty variable");
1700
1630
    }
1701
 
    length= (uint32_t) (var_name - save_var_name);
 
1631
    length= (uint) (var_name - save_var_name);
1702
1632
    if (length >= MAX_VAR_NAME_LENGTH)
1703
1633
      die("Too long variable name: %s", save_var_name);
1704
1634
 
1705
 
    string save_var_name_str(save_var_name, length);
1706
 
    drizzled::hash_map<string, VAR*>::iterator iter=
1707
 
      var_hash.find(save_var_name_str);
1708
 
    if (iter == var_hash.end())
 
1635
    if (!(v = (VAR*) hash_search(&var_hash, (const unsigned char*) save_var_name,
 
1636
                                 length)))
1709
1637
    {
1710
1638
      char buff[MAX_VAR_NAME_LENGTH+1];
1711
 
      strncpy(buff, save_var_name, length);
1712
 
      buff[length]= '\0';
 
1639
      strmake(buff, save_var_name, length);
1713
1640
      v= var_from_env(buff, "");
1714
1641
    }
1715
 
    else
1716
 
    {
1717
 
      v= (*iter).second;
1718
 
    }
1719
1642
    var_name--;  /* Point at last character */
1720
1643
  }
1721
1644
  else
1740
1663
 
1741
1664
static VAR *var_obtain(const char *name, int len)
1742
1665
{
1743
 
  string var_name(name, len);
1744
 
  drizzled::hash_map<string, VAR*>::iterator iter=
1745
 
    var_hash.find(var_name);
1746
 
  if (iter != var_hash.end())
1747
 
    return (*iter).second;
1748
 
  VAR *v = var_init(0, name, len, "", 0);
1749
 
  var_hash.insert(make_pair(var_name, v));
 
1666
  VAR* v;
 
1667
  if ((v = (VAR*)hash_search(&var_hash, (const unsigned char *) name, len)))
 
1668
    return v;
 
1669
  v = var_init(0, name, len, "", 0);
 
1670
  my_hash_insert(&var_hash, (unsigned char*)v);
1750
1671
  return v;
1751
1672
}
1752
1673
 
1771
1692
  digit= *var_name - '0';
1772
1693
  if (!(digit < 10 && digit >= 0))
1773
1694
  {
1774
 
    v= var_obtain(var_name, (uint32_t) (var_name_end - var_name));
 
1695
    v= var_obtain(var_name, (uint) (var_name_end - var_name));
1775
1696
  }
1776
1697
  else
1777
1698
    v= var_reg + digit;
1790
1711
    snprintf(buf, sizeof(buf), "%.*s=%.*s",
1791
1712
             v->name_len, v->name,
1792
1713
             v->str_val_len, v->str_val);
1793
 
    if (!(v->env_s= strdup(buf)))
 
1714
    if (!(v->env_s= my_strdup(buf, MYF(MY_WME))))
1794
1715
      die("Out of memory");
1795
1716
    putenv(v->env_s);
1796
1717
    free(old_env_s);
1815
1736
 
1816
1737
/*
1817
1738
  Store an integer (typically the returncode of the last SQL)
1818
 
  statement in the drizzletest builtin variable $drizzleclient_errno
 
1739
  statement in the drizzletest builtin variable $drizzle_errno
1819
1740
*/
1820
1741
 
1821
1742
static void var_set_errno(int sql_errno)
1822
1743
{
1823
 
  var_set_int("$drizzleclient_errno", sql_errno);
 
1744
  var_set_int("$drizzle_errno", sql_errno);
1824
1745
}
1825
1746
 
1826
1747
 
1827
1748
/*
1828
 
  Update $drizzleclient_get_server_version variable with version
 
1749
  Update $drizzle_get_server_version variable with version
1829
1750
  of the currently connected server
1830
1751
*/
1831
1752
 
1832
 
static void var_set_drizzleclient_get_server_version(drizzle_con_st *con)
 
1753
static void var_set_drizzle_get_server_version(DRIZZLE *drizzle)
1833
1754
{
1834
 
  var_set_int("$drizzle_con_server_version", drizzle_con_server_version_number(con));
 
1755
  var_set_int("$drizzle_get_server_version", drizzle_get_server_version(drizzle));
1835
1756
}
1836
1757
 
1837
1758
 
1862
1783
{
1863
1784
  const char *end = (char*)((query_end && *query_end) ?
1864
1785
                            *query_end : query + strlen(query));
1865
 
  drizzle_result_st res;
1866
 
  drizzle_return_t ret;
1867
 
  drizzle_row_t row;
1868
 
  drizzle_con_st *con= &cur_con->con;
 
1786
  DRIZZLE_RES *res;
 
1787
  DRIZZLE_ROW row;
 
1788
  DRIZZLE *drizzle= &cur_con->drizzle;
1869
1789
  string ds_query;
1870
1790
 
1871
1791
 
1878
1798
  /* Eval the query, thus replacing all environment variables */
1879
1799
  do_eval(&ds_query, query, end, false);
1880
1800
 
1881
 
  if (drizzle_query(con, &res, ds_query.c_str(), ds_query.length(),
1882
 
                    &ret) == NULL ||
1883
 
      ret != DRIZZLE_RETURN_OK)
1884
 
  {
1885
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
1886
 
    {
1887
 
      die("Error running query '%s': %d %s", ds_query.c_str(),
1888
 
          drizzle_result_error_code(&res), drizzle_result_error(&res));
1889
 
      drizzle_result_free(&res);
1890
 
    }
1891
 
    else
1892
 
    {
1893
 
      die("Error running query '%s': %d %s", ds_query.c_str(), ret,
1894
 
          drizzle_con_error(con));
1895
 
    }
1896
 
  }
1897
 
  if (drizzle_result_column_count(&res) == 0 ||
1898
 
      drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
 
1801
  if (drizzle_real_query(drizzle, ds_query.c_str(), ds_query.length()))
 
1802
    die("Error running query '%s': %d %s", ds_query.c_str(),
 
1803
        drizzle_errno(drizzle), drizzle_error(drizzle));
 
1804
  if (!(res= drizzle_store_result(drizzle)))
1899
1805
    die("Query '%s' didn't return a result set", ds_query.c_str());
1900
1806
 
1901
 
  if ((row= drizzle_row_next(&res)) && row[0])
 
1807
  if ((row= drizzle_fetch_row(res)) && row[0])
1902
1808
  {
1903
1809
    /*
1904
1810
      Concatenate all fields in the first row with tab in between
1906
1812
    */
1907
1813
    string result;
1908
1814
    uint32_t i;
1909
 
    size_t *lengths;
 
1815
    uint32_t *lengths;
1910
1816
 
1911
 
    lengths= drizzle_row_field_sizes(&res);
1912
 
    for (i= 0; i < drizzle_result_column_count(&res); i++)
 
1817
    lengths= drizzle_fetch_lengths(res);
 
1818
    for (i= 0; i < drizzle_num_fields(res); i++)
1913
1819
    {
1914
1820
      if (row[i])
1915
1821
      {
1924
1830
  else
1925
1831
    eval_expr(var, "", 0);
1926
1832
 
1927
 
  drizzle_result_free(&res);
 
1833
  drizzle_free_result(res);
1928
1834
  return;
1929
1835
}
1930
1836
 
1955
1861
{
1956
1862
  long row_no;
1957
1863
  int col_no= -1;
1958
 
  drizzle_result_st res;
1959
 
  drizzle_return_t ret;
1960
 
  drizzle_con_st *con= &cur_con->con;
 
1864
  DRIZZLE_RES* res;
 
1865
  DRIZZLE *drizzle= &cur_con->drizzle;
1961
1866
 
1962
1867
  string ds_query;
1963
1868
  string ds_col;
1976
1881
                     ',');
1977
1882
 
1978
1883
  /* Convert row number to int */
1979
 
  row_no= atoi(ds_row.c_str());
1980
 
  
1981
 
  istringstream buff(ds_row);
1982
 
  if ((buff >> row_no).fail())
 
1884
  if (!str2int(ds_row.c_str(), 10, (long) 0, (long) INT_MAX, &row_no))
1983
1885
    die("Invalid row number: '%s'", ds_row.c_str());
1984
1886
 
1985
1887
  /* Remove any surrounding "'s from the query - if there is any */
1987
1889
  char * unstripped_query= strdup(ds_query.c_str());
1988
1890
  if (strip_surrounding(unstripped_query, '"', '"'))
1989
1891
    die("Mismatched \"'s around query '%s'", ds_query.c_str());
1990
 
  ds_query.clear();
1991
 
  ds_query.append(unstripped_query);
 
1892
  ds_query= unstripped_query;
1992
1893
 
1993
1894
  /* Run the query */
1994
 
  if (drizzle_query(con, &res, ds_query.c_str(), ds_query.length(),
1995
 
                    &ret) == NULL ||
1996
 
      ret != DRIZZLE_RETURN_OK)
1997
 
  {
1998
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
1999
 
    {
2000
 
      die("Error running query '%s': %d %s", ds_query.c_str(),
2001
 
          drizzle_result_error_code(&res), drizzle_result_error(&res));
2002
 
      drizzle_result_free(&res);
2003
 
    }
2004
 
    else
2005
 
    {
2006
 
      die("Error running query '%s': %d %s", ds_query.c_str(), ret,
2007
 
          drizzle_con_error(con));
2008
 
    }
2009
 
  }
2010
 
  if (drizzle_result_column_count(&res) == 0 ||
2011
 
      drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
 
1895
  if (drizzle_real_query(drizzle, ds_query.c_str(), ds_query.length()))
 
1896
    die("Error running query '%s': %d %s", ds_query.c_str(),
 
1897
        drizzle_errno(drizzle), drizzle_error(drizzle));
 
1898
  if (!(res= drizzle_store_result(drizzle)))
2012
1899
    die("Query '%s' didn't return a result set", ds_query.c_str());
2013
1900
 
2014
1901
  {
2015
1902
    /* Find column number from the given column name */
2016
 
    uint32_t i;
2017
 
    uint32_t num_fields= drizzle_result_column_count(&res);
2018
 
    drizzle_column_st *column;
 
1903
    uint i;
 
1904
    uint num_fields= drizzle_num_fields(res);
 
1905
    const DRIZZLE_FIELD *fields= drizzle_fetch_fields(res);
2019
1906
 
2020
1907
    for (i= 0; i < num_fields; i++)
2021
1908
    {
2022
 
      column= drizzle_column_next(&res);
2023
 
      if (strcmp(drizzle_column_name(column), ds_col.c_str()) == 0 &&
2024
 
          strlen(drizzle_column_name(column)) == ds_col.length())
 
1909
      if (strcmp(fields[i].name, ds_col.c_str()) == 0 &&
 
1910
          strlen(fields[i].name) == ds_col.length())
2025
1911
      {
2026
1912
        col_no= i;
2027
1913
        break;
2029
1915
    }
2030
1916
    if (col_no == -1)
2031
1917
    {
2032
 
      drizzle_result_free(&res);
 
1918
      drizzle_free_result(res);
2033
1919
      die("Could not find column '%s' in the result of '%s'",
2034
1920
          ds_col.c_str(), ds_query.c_str());
2035
1921
    }
2037
1923
 
2038
1924
  {
2039
1925
    /* Get the value */
2040
 
    drizzle_row_t row;
 
1926
    DRIZZLE_ROW row;
2041
1927
    long rows= 0;
2042
1928
    const char* value= "No such row";
2043
1929
 
2044
 
    while ((row= drizzle_row_next(&res)))
 
1930
    while ((row= drizzle_fetch_row(res)))
2045
1931
    {
2046
1932
      if (++rows == row_no)
2047
1933
      {
2057
1943
    }
2058
1944
    eval_expr(var, value, 0);
2059
1945
  }
2060
 
  drizzle_result_free(&res);
 
1946
  drizzle_free_result(res);
2061
1947
 
2062
1948
  return;
2063
1949
}
2069
1955
  dest->int_dirty= src->int_dirty;
2070
1956
 
2071
1957
  /* Alloc/realloc data for str_val in dest */
2072
 
  if (dest->alloced_len < src->alloced_len)
2073
 
  {
2074
 
    char *tmpptr= (char *)realloc(dest->str_val, src->alloced_len);
2075
 
    if (tmpptr == NULL)
2076
 
      die("Out of memory");
2077
 
    dest->str_val= tmpptr;
2078
 
  }
 
1958
  if (dest->alloced_len < src->alloced_len &&
 
1959
      !(dest->str_val= dest->str_val
 
1960
        ? (char *)my_realloc(dest->str_val, src->alloced_len, MYF(MY_WME))
 
1961
        : (char *)my_malloc(src->alloced_len, MYF(MY_WME))))
 
1962
    die("Out of memory");
2079
1963
  else
2080
1964
    dest->alloced_len= src->alloced_len;
2081
1965
 
2108
1992
    const size_t len= strlen(get_value_str);
2109
1993
    if (strncmp(p, get_value_str, len)==0)
2110
1994
    {
2111
 
      st_command command;
 
1995
      struct st_command command;
 
1996
      memset(&command, 0, sizeof(command));
2112
1997
      command.query= (char*)p;
2113
1998
      command.first_word_len= len;
2114
1999
      command.first_argument= command.query + len;
2126
2011
      static int MIN_VAR_ALLOC= 32;
2127
2012
      v->alloced_len = (new_val_len < MIN_VAR_ALLOC - 1) ?
2128
2013
        MIN_VAR_ALLOC : new_val_len + 1;
2129
 
      char *tmpptr= (char *)realloc(v->str_val, v->alloced_len+1);
2130
 
      if (tmpptr == NULL)
 
2014
      if (!(v->str_val =
 
2015
            v->str_val ? (char *)my_realloc(v->str_val, v->alloced_len+1,
 
2016
                                            MYF(MY_WME)) :
 
2017
            (char *)my_malloc(v->alloced_len+1, MYF(MY_WME))))
2131
2018
        die("Out of memory");
2132
 
      v->str_val= tmpptr;
2133
2019
    }
2134
2020
    v->str_val_len = new_val_len;
2135
2021
    memcpy(v->str_val, p, new_val_len);
2145
2031
{
2146
2032
  char buff[FN_REFLEN];
2147
2033
 
2148
 
  if (!internal::test_if_hard_path(name))
 
2034
  if (!test_if_hard_path(name))
2149
2035
  {
2150
 
    snprintf(buff, sizeof(buff), "%s%s",opt_basedir,name);
 
2036
    strxmov(buff, opt_basedir, name, NULL);
2151
2037
    name=buff;
2152
2038
  }
2153
 
  internal::fn_format(buff, name, "", "", MY_UNPACK_FILENAME);
 
2039
  fn_format(buff, name, "", "", MY_UNPACK_FILENAME);
2154
2040
 
2155
2041
  if (cur_file == file_stack_end)
2156
2042
    die("Source directives are nesting too deep");
2157
2043
  cur_file++;
2158
 
  if (!(cur_file->file= fopen(buff, "r")))
 
2044
  if (!(cur_file->file = my_fopen(buff, O_RDONLY, MYF(0))))
2159
2045
  {
2160
2046
    cur_file--;
2161
2047
    die("Could not open '%s' for reading", buff);
2162
2048
  }
2163
 
  if (!(cur_file->file_name= strdup(buff)))
2164
 
    die("Out of memory");
 
2049
  cur_file->file_name= my_strdup(buff, MYF(MY_FAE));
2165
2050
  cur_file->lineno=1;
2166
2051
  return(0);
2167
2052
}
2201
2086
    ; /* Do nothing */
2202
2087
  else
2203
2088
  {
2204
 
    if (opt_testdir != NULL)
2205
 
    {
2206
 
      string testdir(opt_testdir);
2207
 
      if (testdir[testdir.length()] != '/')
2208
 
        testdir.append("/");
2209
 
      testdir.append(ds_filename);
2210
 
      ds_filename.swap(testdir);
2211
 
    }
2212
2089
    open_file(ds_filename.c_str());
2213
2090
  }
2214
2091
 
2320
2197
  error= pclose(res_file);
2321
2198
  if (error > 0)
2322
2199
  {
2323
 
    uint32_t status= WEXITSTATUS(error), i;
 
2200
    uint status= WEXITSTATUS(error), i;
2324
2201
    bool ok= 0;
2325
2202
 
2326
2203
    if (command->abort_on_error)
2469
2346
                     rm_args, sizeof(rm_args)/sizeof(struct command_arg),
2470
2347
                     ' ');
2471
2348
 
2472
 
  error= internal::my_delete(ds_filename.c_str(), MYF(0)) != 0;
 
2349
  error= my_delete(ds_filename.c_str(), MYF(0)) != 0;
2473
2350
  handle_command_error(command, error);
2474
2351
  return;
2475
2352
}
2503
2380
                     sizeof(copy_file_args)/sizeof(struct command_arg),
2504
2381
                     ' ');
2505
2382
 
2506
 
  error= (internal::my_copy(ds_from_file.c_str(), ds_to_file.c_str(),
 
2383
  error= (my_copy(ds_from_file.c_str(), ds_to_file.c_str(),
2507
2384
                  MYF(MY_DONT_OVERWRITE_FILE)) != 0);
2508
2385
  handle_command_error(command, error);
2509
2386
  return;
2538
2415
                     ' ');
2539
2416
 
2540
2417
  /* Parse what mode to set */
2541
 
  istringstream buff(ds_mode);
2542
2418
  if (ds_mode.length() != 4 ||
2543
 
      (buff >> oct >> mode).fail())
 
2419
      str2int(ds_mode.c_str(), 8, 0, INT_MAX, &mode) == NULL)
2544
2420
    die("You must write a 4 digit octal number for mode");
2545
2421
 
2546
2422
  handle_command_error(command, chmod(ds_file.c_str(), mode));
2590
2466
 
2591
2467
static void do_mkdir(struct st_command *command)
2592
2468
{
 
2469
  int error;
2593
2470
  string ds_dirname;
2594
 
  int error;
2595
2471
  const struct command_arg mkdir_args[] = {
2596
2472
    {"dirname", ARG_STRING, true, &ds_dirname, "Directory to create"}
2597
2473
  };
2601
2477
                     mkdir_args, sizeof(mkdir_args)/sizeof(struct command_arg),
2602
2478
                     ' ');
2603
2479
 
2604
 
  error= mkdir(ds_dirname.c_str(), (0777 & internal::my_umask_dir)) != 0;
 
2480
  error= my_mkdir(ds_dirname.c_str(), 0777, MYF(0)) != 0;
2605
2481
  handle_command_error(command, error);
2606
2482
  return;
2607
2483
}
2721
2597
 
2722
2598
  /* If no delimiter was provided, use EOF */
2723
2599
  if (ds_delimiter.length() == 0)
2724
 
    ds_delimiter.append("EOF");
 
2600
    ds_delimiter= "EOF";
2725
2601
 
2726
2602
  if (!append && access(ds_filename.c_str(), F_OK) == 0)
2727
2603
  {
2902
2778
{
2903
2779
  char *p= command->first_argument, *name;
2904
2780
  struct st_connection *con;
2905
 
  drizzle_result_st result;
2906
 
  drizzle_return_t ret;
2907
2781
 
2908
2782
  if (!*p)
2909
2783
    die("Missing connection name in send_quit");
2918
2792
  if (!(con= find_connection_by_name(name)))
2919
2793
    die("connection '%s' not found in connection pool", name);
2920
2794
 
2921
 
  if (drizzle_quit(&con->con,&result, &ret))
2922
 
    drizzle_result_free(&result);
 
2795
  simple_command(&con->drizzle,COM_QUIT,0,0,1);
2923
2796
 
2924
2797
  return;
2925
2798
}
2941
2814
 
2942
2815
*/
2943
2816
 
2944
 
static void do_change_user(struct st_command *)
 
2817
static void do_change_user(struct st_command *command)
2945
2818
{
2946
 
  assert(0);
 
2819
  DRIZZLE *drizzle= &cur_con->drizzle;
 
2820
  /* static keyword to make the NetWare compiler happy. */
 
2821
  string ds_user, ds_passwd, ds_db;
 
2822
  const struct command_arg change_user_args[] = {
 
2823
    { "user", ARG_STRING, false, &ds_user, "User to connect as" },
 
2824
    { "password", ARG_STRING, false, &ds_passwd, "Password used when connecting" },
 
2825
    { "database", ARG_STRING, false, &ds_db, "Database to select after connect" },
 
2826
  };
 
2827
 
 
2828
 
 
2829
 
 
2830
  check_command_args(command, command->first_argument,
 
2831
                     change_user_args,
 
2832
                     sizeof(change_user_args)/sizeof(struct command_arg),
 
2833
                     ',');
 
2834
 
 
2835
  if (!ds_user.length())
 
2836
    ds_user= drizzle->user;
 
2837
 
 
2838
  if (!ds_passwd.length())
 
2839
    ds_passwd= drizzle->passwd;
 
2840
 
 
2841
  if (!ds_db.length())
 
2842
    ds_db= drizzle->db;
 
2843
 
 
2844
  if (drizzle_change_user(drizzle, ds_user.c_str(),
 
2845
                          ds_passwd.c_str(), ds_db.c_str()))
 
2846
    die("change user failed: %s", drizzle_error(drizzle));
 
2847
 
 
2848
 
 
2849
  return;
2947
2850
}
2948
2851
 
 
2852
 
2949
2853
/*
2950
2854
  SYNOPSIS
2951
2855
  do_perl
2968
2872
static void do_perl(struct st_command *command)
2969
2873
{
2970
2874
  int error;
2971
 
  int fd;
 
2875
  File fd;
2972
2876
  FILE *res_file;
2973
2877
  char buf[FN_REFLEN];
2974
2878
  char temp_file_path[FN_REFLEN];
2987
2891
 
2988
2892
  /* If no delimiter was provided, use EOF */
2989
2893
  if (ds_delimiter.length() == 0)
2990
 
    ds_delimiter.append("EOF");
 
2894
    ds_delimiter= "EOF";
2991
2895
 
2992
2896
  read_until_delimiter(&ds_script, &ds_delimiter);
2993
2897
 
2994
2898
  /* Create temporary file name */
2995
 
  if ((fd= internal::create_temp_file(temp_file_path, getenv("MYSQLTEST_VARDIR"),
2996
 
                            "tmp", MYF(MY_WME))) < 0)
 
2899
  if ((fd= create_temp_file(temp_file_path, getenv("MYSQLTEST_VARDIR"),
 
2900
                            "tmp", O_CREAT | O_RDWR,
 
2901
                            MYF(MY_WME))) < 0)
2997
2902
    die("Failed to create temporary file for perl command");
2998
 
  internal::my_close(fd, MYF(0));
 
2903
  my_close(fd, MYF(0));
2999
2904
 
3000
2905
  str_to_file(temp_file_path, ds_script.c_str(), ds_script.length());
3001
2906
 
3015
2920
  error= pclose(res_file);
3016
2921
 
3017
2922
  /* Remove the temporary file */
3018
 
  internal::my_delete(temp_file_path, MYF(0));
 
2923
  my_delete(temp_file_path, MYF(0));
3019
2924
 
3020
2925
  handle_command_error(command, WEXITSTATUS(error));
3021
2926
  return;
3060
2965
 
3061
2966
 
3062
2967
static void
3063
 
do_wait_for_slave_to_stop(struct st_command *)
 
2968
do_wait_for_slave_to_stop(struct st_command *c __attribute__((unused)))
3064
2969
{
3065
2970
  static int SLAVE_POLL_INTERVAL= 300000;
3066
 
  drizzle_con_st *con= &cur_con->con;
 
2971
  DRIZZLE *drizzle= &cur_con->drizzle;
3067
2972
  for (;;)
3068
2973
  {
3069
 
    drizzle_result_st res;
3070
 
    drizzle_return_t ret;
3071
 
    drizzle_row_t row;
 
2974
    DRIZZLE_RES *res= NULL;
 
2975
    DRIZZLE_ROW row;
3072
2976
    int done;
3073
2977
 
3074
 
    if (drizzle_query_str(con,&res,"show status like 'Slave_running'",
3075
 
                          &ret) == NULL || ret != DRIZZLE_RETURN_OK)
3076
 
    {
3077
 
      if (ret == DRIZZLE_RETURN_ERROR_CODE)
3078
 
      {
3079
 
        die("Query failed while probing slave for stop: %s",
3080
 
            drizzle_result_error(&res));
3081
 
        drizzle_result_free(&res);
3082
 
      }
3083
 
      else
3084
 
      {
3085
 
        die("Query failed while probing slave for stop: %s",
3086
 
            drizzle_con_error(con));
3087
 
      }
3088
 
    }
3089
 
 
3090
 
    if (drizzle_result_column_count(&res) == 0 ||
3091
 
        drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
3092
 
    {
 
2978
    if (drizzle_query(drizzle,"show status like 'Slave_running'") ||
 
2979
        !(res=drizzle_store_result(drizzle)))
3093
2980
      die("Query failed while probing slave for stop: %s",
3094
 
          drizzle_con_error(con));
3095
 
    }
3096
 
 
3097
 
    if (!(row=drizzle_row_next(&res)) || !row[1])
 
2981
          drizzle_error(drizzle));
 
2982
    if (!(row=drizzle_fetch_row(res)) || !row[1])
3098
2983
    {
3099
 
      drizzle_result_free(&res);
 
2984
      drizzle_free_result(res);
3100
2985
      die("Strange result from query while probing slave for stop");
3101
2986
    }
3102
2987
    done = !strcmp(row[1],"OFF");
3103
 
    drizzle_result_free(&res);
 
2988
    drizzle_free_result(res);
3104
2989
    if (done)
3105
2990
      break;
3106
 
    usleep(SLAVE_POLL_INTERVAL);
 
2991
    my_sleep(SLAVE_POLL_INTERVAL);
3107
2992
  }
3108
2993
  return;
3109
2994
}
3111
2996
 
3112
2997
static void do_sync_with_master2(long offset)
3113
2998
{
3114
 
  drizzle_result_st res;
3115
 
  drizzle_return_t ret;
3116
 
  drizzle_row_t row;
3117
 
  drizzle_con_st *con= &cur_con->con;
 
2999
  DRIZZLE_RES *res;
 
3000
  DRIZZLE_ROW row;
 
3001
  DRIZZLE *drizzle= &cur_con->drizzle;
3118
3002
  char query_buf[FN_REFLEN+128];
3119
3003
  int tries= 0;
3120
3004
 
3121
3005
  if (!master_pos.file[0])
3122
3006
    die("Calling 'sync_with_master' without calling 'save_master_pos'");
3123
3007
 
3124
 
  snprintf(query_buf, sizeof(query_buf), "select master_pos_wait('%s', %ld)", master_pos.file,
 
3008
  sprintf(query_buf, "select master_pos_wait('%s', %ld)", master_pos.file,
3125
3009
          master_pos.pos + offset);
3126
3010
 
3127
3011
wait_for_position:
3128
3012
 
3129
 
  if (drizzle_query_str(con, &res, query_buf, &ret) == NULL ||
3130
 
      ret != DRIZZLE_RETURN_OK)
3131
 
  {
3132
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
3133
 
    {
3134
 
      die("failed in '%s': %d: %s", query_buf, drizzle_result_error_code(&res),
3135
 
           drizzle_result_error(&res));
3136
 
      drizzle_result_free(&res);
3137
 
    }
3138
 
    else
3139
 
      die("failed in '%s': %d: %s", query_buf, ret, drizzle_con_error(con));
3140
 
  }
3141
 
 
3142
 
  if (drizzle_result_column_count(&res) == 0 ||
3143
 
      drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
3144
 
    die("drizzle_result_buffer() returned NULL for '%s'", query_buf);
3145
 
 
3146
 
  if (!(row= drizzle_row_next(&res)))
3147
 
  {
3148
 
    drizzle_result_free(&res);
 
3013
  if (drizzle_query(drizzle, query_buf))
 
3014
    die("failed in '%s': %d: %s", query_buf, drizzle_errno(drizzle),
 
3015
        drizzle_error(drizzle));
 
3016
 
 
3017
  if (!(res= drizzle_store_result(drizzle)))
 
3018
    die("drizzle_store_result() returned NULL for '%s'", query_buf);
 
3019
  if (!(row= drizzle_fetch_row(res)))
 
3020
  {
 
3021
    drizzle_free_result(res);
3149
3022
    die("empty result in %s", query_buf);
3150
3023
  }
3151
3024
  if (!row[0])
3154
3027
      It may be that the slave SQL thread has not started yet, though START
3155
3028
      SLAVE has been issued ?
3156
3029
    */
3157
 
    drizzle_result_free(&res);
 
3030
    drizzle_free_result(res);
3158
3031
    if (tries++ == 30)
3159
3032
    {
3160
 
      show_query(con, "SHOW MASTER STATUS");
3161
 
      show_query(con, "SHOW SLAVE STATUS");
 
3033
      show_query(drizzle, "SHOW MASTER STATUS");
 
3034
      show_query(drizzle, "SHOW SLAVE STATUS");
3162
3035
      die("could not sync with master ('%s' returned NULL)", query_buf);
3163
3036
    }
3164
3037
    sleep(1); /* So at most we will wait 30 seconds and make 31 tries */
3165
3038
    goto wait_for_position;
3166
3039
  }
3167
 
  drizzle_result_free(&res);
 
3040
  drizzle_free_result(res);
3168
3041
  return;
3169
3042
}
3170
3043
 
3194
3067
*/
3195
3068
static int do_save_master_pos(void)
3196
3069
{
3197
 
  drizzle_result_st res;
3198
 
  drizzle_return_t ret;
3199
 
  drizzle_row_t row;
3200
 
  drizzle_con_st *con= &cur_con->con;
 
3070
  DRIZZLE_RES *res;
 
3071
  DRIZZLE_ROW row;
 
3072
  DRIZZLE *drizzle= &cur_con->drizzle;
3201
3073
  const char *query;
3202
3074
 
3203
3075
 
3204
 
  if (drizzle_query_str(con, &res, query= "show master status", &ret) == NULL ||
3205
 
      ret != DRIZZLE_RETURN_OK)
3206
 
  {
3207
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
3208
 
    {
3209
 
      die("failed in '%s': %d: %s", query, drizzle_result_error_code(&res),
3210
 
           drizzle_result_error(&res));
3211
 
      drizzle_result_free(&res);
3212
 
    }
3213
 
    else
3214
 
      die("failed in '%s': %d: %s", query, ret, drizzle_con_error(con));
3215
 
  }
 
3076
  if (drizzle_query(drizzle, query= "show master status"))
 
3077
    die("failed in 'show master status': %d %s",
 
3078
        drizzle_errno(drizzle), drizzle_error(drizzle));
3216
3079
 
3217
 
  if (drizzle_result_column_count(&res) == 0 ||
3218
 
      drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
3219
 
    die("drizzleclient_store_result() retuned NULL for '%s'", query);
3220
 
  if (!(row = drizzle_row_next(&res)))
 
3080
  if (!(res = drizzle_store_result(drizzle)))
 
3081
    die("drizzle_store_result() retuned NULL for '%s'", query);
 
3082
  if (!(row = drizzle_fetch_row(res)))
3221
3083
    die("empty result in show master status");
3222
 
  strncpy(master_pos.file, row[0], sizeof(master_pos.file)-1);
 
3084
  my_stpncpy(master_pos.file, row[0], sizeof(master_pos.file)-1);
3223
3085
  master_pos.pos = strtoul(row[1], (char**) 0, 10);
3224
 
  drizzle_result_free(&res);
 
3086
  drizzle_free_result(res);
3225
3087
  return(0);
3226
3088
}
3227
3089
 
3305
3167
 
3306
3168
static int do_sleep(struct st_command *command, bool real_sleep)
3307
3169
{
3308
 
  bool error= false;
 
3170
  int error= 0;
3309
3171
  char *p= command->first_argument;
3310
3172
  char *sleep_start, *sleep_end= command->end;
3311
3173
  double sleep_val;
3315
3177
  if (!*p)
3316
3178
    die("Missing argument to %.*s", command->first_word_len, command->query);
3317
3179
  sleep_start= p;
3318
 
  /* Check that arg starts with a digit, not handled by internal::my_strtod */
 
3180
  /* Check that arg starts with a digit, not handled by my_strtod */
3319
3181
  if (!my_isdigit(charset_info, *sleep_start))
3320
3182
    die("Invalid argument to %.*s \"%s\"", command->first_word_len,
3321
3183
        command->query,command->first_argument);
3322
 
  string buff_str(sleep_start, sleep_end-sleep_start);
3323
 
  istringstream buff(buff_str);
3324
 
  error= (buff >> sleep_val).fail();
 
3184
  sleep_val= my_strtod(sleep_start, &sleep_end, &error);
3325
3185
  if (error)
3326
3186
    die("Invalid argument to %.*s \"%s\"", command->first_word_len,
3327
3187
        command->query, command->first_argument);
3331
3191
    sleep_val= opt_sleep;
3332
3192
 
3333
3193
  if (sleep_val)
3334
 
    usleep((uint32_t) (sleep_val * 1000000L));
 
3194
    my_sleep((uint32_t) (sleep_val * 1000000L));
3335
3195
  command->last_argument= sleep_end;
3336
3196
  return 0;
3337
3197
}
3338
3198
 
3339
3199
 
3340
 
static void do_get_file_name(struct st_command *command, string &dest)
 
3200
static void do_get_file_name(struct st_command *command,
 
3201
                             char* dest, uint dest_max_len)
3341
3202
{
3342
3203
  char *p= command->first_argument, *name;
3343
3204
  if (!*p)
3348
3209
  if (*p)
3349
3210
    *p++= 0;
3350
3211
  command->last_argument= p;
3351
 
  if (opt_testdir != NULL)
3352
 
  {
3353
 
    dest= opt_testdir;
3354
 
    if (dest[dest.length()] != '/')
3355
 
      dest.append("/");
3356
 
  }
3357
 
  dest.append(name);
 
3212
  strmake(dest, name, dest_max_len - 1);
3358
3213
}
3359
3214
 
3360
3215
 
3372
3227
  if(*p)
3373
3228
    *p++= 0;
3374
3229
  command->last_argument= p;
3375
 
  charset_info= get_charset_by_csname(charset_name, MY_CS_PRIMARY);
 
3230
  charset_info= get_charset_by_csname(charset_name,MY_CS_PRIMARY,MYF(MY_WME));
3376
3231
  if (!charset_info)
3377
3232
    abort_not_supported_test("Test requires charset '%s'", charset_name);
3378
3233
}
3379
3234
 
3380
 
static uint32_t get_errcode_from_name(char *error_name, char *error_end)
 
3235
static uint get_errcode_from_name(char *error_name, char *error_end)
3381
3236
{
3382
 
  size_t err_name_len= error_end - error_name;
3383
 
  string error_name_s(error_name, err_name_len);
3384
 
 
3385
 
  uint32_t code= global_error_names.getErrorCode(error_name_s);
3386
 
 
3387
 
  if (!code)
3388
 
    die("Unknown SQL error name '%s'", error_name_s.c_str());
3389
 
 
3390
 
  return(code);
 
3237
  /* SQL error as string */
 
3238
  st_error *e= global_error_names;
 
3239
 
 
3240
  /* Loop through the array of known error names */
 
3241
  for (; e->name; e++)
 
3242
  {
 
3243
    /*
 
3244
      If we get a match, we need to check the length of the name we
 
3245
      matched against in case it was longer than what we are checking
 
3246
      (as in ER_WRONG_VALUE vs. ER_WRONG_VALUE_COUNT).
 
3247
    */
 
3248
    if (!strncmp(error_name, e->name, (int) (error_end - error_name)) &&
 
3249
        (uint) strlen(e->name) == (uint) (error_end - error_name))
 
3250
    {
 
3251
      return(e->code);
 
3252
    }
 
3253
  }
 
3254
  if (!e->name)
 
3255
    die("Unknown SQL error name '%s'", error_name);
 
3256
  return(0);
3391
3257
}
3392
3258
 
3393
3259
static void do_get_errcodes(struct st_command *command)
3394
3260
{
3395
3261
  struct st_match_err *to= saved_expected_errors.err;
3396
3262
  char *p= command->first_argument;
3397
 
  uint32_t count= 0;
 
3263
  uint count= 0;
3398
3264
 
3399
3265
 
3400
3266
 
3420
3286
 
3421
3287
      /*
3422
3288
        SQLSTATE string
3423
 
        - Must be DRIZZLE_MAX_SQLSTATE_SIZE long
 
3289
        - Must be SQLSTATE_LENGTH long
3424
3290
        - May contain only digits[0-9] and _uppercase_ letters
3425
3291
      */
3426
3292
      p++; /* Step past the S */
3427
 
      if ((end - p) != DRIZZLE_MAX_SQLSTATE_SIZE)
3428
 
        die("The sqlstate must be exactly %d chars long", DRIZZLE_MAX_SQLSTATE_SIZE);
 
3293
      if ((end - p) != SQLSTATE_LENGTH)
 
3294
        die("The sqlstate must be exactly %d chars long", SQLSTATE_LENGTH);
3429
3295
 
3430
3296
      /* Check sqlstate string validity */
3431
3297
      while (*p && p < end)
3470
3336
      }
3471
3337
 
3472
3338
      /* Convert the sting to int */
3473
 
      istringstream buff(start);
3474
 
      if ((buff >> val).fail())
 
3339
      if (!str2int(start, 10, (long) INT_MIN, (long) INT_MAX, &val))
3475
3340
        die("Invalid argument to error: '%s'", command->first_argument);
3476
3341
 
3477
 
      to->code.errnum= (uint32_t) val;
 
3342
      to->code.errnum= (uint) val;
3478
3343
      to->type= ERR_ERRNO;
3479
3344
    }
3480
3345
    to++;
3581
3446
}
3582
3447
 
3583
3448
 
3584
 
static void set_reconnect(drizzle_con_st *con, int val)
 
3449
static void set_reconnect(DRIZZLE *drizzle, int val)
3585
3450
{
3586
 
  (void) con;
3587
 
  (void) val;
3588
 
/* XXX
3589
3451
  bool reconnect= val;
3590
3452
 
3591
 
  drizzleclient_options(drizzle, DRIZZLE_OPT_RECONNECT, (char *)&reconnect);
3592
 
*/
 
3453
  drizzle_options(drizzle, DRIZZLE_OPT_RECONNECT, (char *)&reconnect);
 
3454
 
 
3455
  return;
3593
3456
}
3594
3457
 
3595
3458
 
3598
3461
  if (!(cur_con= find_connection_by_name(name)))
3599
3462
    die("connection '%s' not found in connection pool", name);
3600
3463
 
3601
 
  /* Update $drizzleclient_get_server_version to that of current connection */
3602
 
  var_set_drizzleclient_get_server_version(&cur_con->con);
 
3464
  /* Update $drizzle_get_server_version to that of current connection */
 
3465
  var_set_drizzle_get_server_version(&cur_con->drizzle);
3603
3466
 
3604
3467
  return(0);
3605
3468
}
3641
3504
  if (!(con= find_connection_by_name(name)))
3642
3505
    die("connection '%s' not found in connection pool", name);
3643
3506
 
3644
 
  if (con->drizzle != NULL)
 
3507
  if (command->type == Q_DIRTY_CLOSE)
3645
3508
  {
3646
 
    drizzle_free(con->drizzle);
3647
 
    con->drizzle= NULL;
 
3509
    if (con->drizzle.net.vio)
 
3510
    {
 
3511
      net_close(&(con->drizzle.net));
 
3512
    }
3648
3513
  }
 
3514
 
 
3515
  drizzle_close(&con->drizzle);
 
3516
 
 
3517
  if (con->util_drizzle)
 
3518
    drizzle_close(con->util_drizzle);
 
3519
  con->util_drizzle= 0;
 
3520
 
3649
3521
  free(con->name);
3650
3522
 
3651
3523
  /*
3652
3524
    When the connection is closed set name to "-closed_connection-"
3653
3525
    to make it possible to reuse the connection name.
3654
3526
  */
3655
 
  if (!(con->name = strdup("-closed_connection-")))
 
3527
  if (!(con->name = my_strdup("-closed_connection-", MYF(MY_WME))))
3656
3528
    die("Out of memory");
3657
3529
 
3658
3530
  return;
3684
3556
 
3685
3557
*/
3686
3558
 
3687
 
static void safe_connect(drizzle_con_st *con, const char *name,
3688
 
                         const char *host, const char *user, const char *pass,
3689
 
                         const char *db, int port)
 
3559
static void safe_connect(DRIZZLE *drizzle, const char *name, const char *host,
 
3560
                         const char *user, const char *pass, const char *db,
 
3561
                         int port)
3690
3562
{
3691
3563
  int failed_attempts= 0;
3692
3564
  static uint32_t connection_retry_sleep= 100000; /* Microseconds */
3693
 
  drizzle_return_t ret;
3694
 
 
3695
 
  drizzle_con_set_tcp(con, host, port);
3696
 
  drizzle_con_set_auth(con, user, pass);
3697
 
  drizzle_con_set_db(con, db);
3698
 
  while((ret= drizzle_con_connect(con)) != DRIZZLE_RETURN_OK)
 
3565
 
 
3566
 
 
3567
  while(!drizzle_connect(drizzle, host, user, pass, db, port, NULL,
 
3568
                         CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS))
3699
3569
  {
3700
3570
    /*
3701
3571
      Connect failed
3705
3575
      on protocol/connection type
3706
3576
    */
3707
3577
 
3708
 
    if ((ret == DRIZZLE_RETURN_GETADDRINFO ||
3709
 
         ret == DRIZZLE_RETURN_COULD_NOT_CONNECT) &&
 
3578
    if ((drizzle_errno(drizzle) == CR_CONN_HOST_ERROR ||
 
3579
         drizzle_errno(drizzle) == CR_CONNECTION_ERROR) &&
3710
3580
        failed_attempts < opt_max_connect_retries)
3711
3581
    {
3712
3582
      verbose_msg("Connect attempt %d/%d failed: %d: %s", failed_attempts,
3713
 
                  opt_max_connect_retries, ret, drizzle_con_error(con));
3714
 
      usleep(connection_retry_sleep);
 
3583
                  opt_max_connect_retries, drizzle_errno(drizzle),
 
3584
                  drizzle_error(drizzle));
 
3585
      my_sleep(connection_retry_sleep);
3715
3586
    }
3716
3587
    else
3717
3588
    {
3718
3589
      if (failed_attempts > 0)
3719
3590
        die("Could not open connection '%s' after %d attempts: %d %s", name,
3720
 
            failed_attempts, ret, drizzle_con_error(con));
 
3591
            failed_attempts, drizzle_errno(drizzle), drizzle_error(drizzle));
3721
3592
      else
3722
 
        die("Could not open connection '%s': %d %s", name, ret,
3723
 
            drizzle_con_error(con));
 
3593
        die("Could not open connection '%s': %d %s", name,
 
3594
            drizzle_errno(drizzle), drizzle_error(drizzle));
3724
3595
    }
3725
3596
    failed_attempts++;
3726
3597
  }
3752
3623
*/
3753
3624
 
3754
3625
static int connect_n_handle_errors(struct st_command *command,
3755
 
                                   drizzle_con_st *con, const char* host,
 
3626
                                   DRIZZLE *con, const char* host,
3756
3627
                                   const char* user, const char* pass,
3757
3628
                                   const char* db, int port, const char* sock)
3758
3629
{
3759
 
  drizzle_return_t ret;
3760
3630
 
3761
3631
  /* Only log if an error is expected */
3762
3632
  if (!command->abort_on_error &&
3783
3653
    ds_res.append(delimiter);
3784
3654
    ds_res.append("\n");
3785
3655
  }
3786
 
  drizzle_con_set_tcp(con, host, port);
3787
 
  drizzle_con_set_auth(con, user, pass);
3788
 
  drizzle_con_set_db(con, db);
3789
 
  if ((ret= drizzle_con_connect(con)) != DRIZZLE_RETURN_OK)
 
3656
  if (!drizzle_connect(con, host, user, pass, db, port, 0,
 
3657
                       CLIENT_MULTI_STATEMENTS))
3790
3658
  {
3791
 
    if (ret == DRIZZLE_RETURN_HANDSHAKE_FAILED)
3792
 
    {
3793
 
      var_set_errno(drizzle_con_error_code(con));
3794
 
      handle_error(command, drizzle_con_error_code(con), drizzle_con_error(con),
3795
 
                   drizzle_con_sqlstate(con), &ds_res);
3796
 
    }
3797
 
    else
3798
 
    {
3799
 
      var_set_errno(ret);
3800
 
      handle_error(command, ret, drizzle_con_error(con), "", &ds_res);
3801
 
    }
3802
 
 
 
3659
    var_set_errno(drizzle_errno(con));
 
3660
    handle_error(command, drizzle_errno(con), drizzle_error(con),
 
3661
                 drizzle_sqlstate(con), &ds_res);
3803
3662
    return 0; /* Not connected */
3804
3663
  }
3805
3664
 
3884
3743
    if (*ds_sock.c_str() != FN_LIBCHAR)
3885
3744
    {
3886
3745
      char buff[FN_REFLEN];
3887
 
      internal::fn_format(buff, ds_sock.c_str(), TMPDIR, "", 0);
3888
 
      ds_sock.clear();
3889
 
      ds_sock.append(buff);
 
3746
      fn_format(buff, ds_sock.c_str(), TMPDIR, "", 0);
 
3747
      ds_sock= buff;
3890
3748
    }
3891
3749
  }
3892
3750
 
3927
3785
          (int) (sizeof(connections)/sizeof(struct st_connection)));
3928
3786
  }
3929
3787
 
3930
 
  if ((con_slot->drizzle= drizzle_create(NULL)) == NULL)
 
3788
  if (!drizzle_create(&con_slot->drizzle))
3931
3789
    die("Failed on drizzle_create()");
3932
 
  if (!drizzle_con_create(con_slot->drizzle, &con_slot->con))
3933
 
    die("Failed on drizzle_con_create()");
3934
 
  if (opt_mysql)
3935
 
    drizzle_con_add_options(&con_slot->con, DRIZZLE_CON_MYSQL);
 
3790
  if (opt_compress || con_compress)
 
3791
    drizzle_options(&con_slot->drizzle, DRIZZLE_OPT_COMPRESS, NULL);
 
3792
  drizzle_options(&con_slot->drizzle, DRIZZLE_OPT_LOCAL_INFILE, 0);
3936
3793
 
3937
3794
  /* Use default db name */
3938
3795
  if (ds_database.length() == 0)
3939
 
    ds_database.append(opt_db);
 
3796
    ds_database= opt_db;
3940
3797
 
3941
3798
  /* Special database to allow one to connect without a database name */
3942
3799
  if (ds_database.length() && !strcmp(ds_database.c_str(),"*NO-ONE*"))
3943
 
    ds_database.clear();
 
3800
    ds_database= "";
3944
3801
 
3945
 
  if (connect_n_handle_errors(command, &con_slot->con,
 
3802
  if (connect_n_handle_errors(command, &con_slot->drizzle,
3946
3803
                              ds_host.c_str(),ds_user.c_str(),
3947
3804
                              ds_password.c_str(), ds_database.c_str(),
3948
3805
                              con_port, ds_sock.c_str()))
3955
3812
      next_con++; /* if we used the next_con slot, advance the pointer */
3956
3813
  }
3957
3814
 
3958
 
  /* Update $drizzleclient_get_server_version to that of current connection */
3959
 
  var_set_drizzleclient_get_server_version(&cur_con->con);
 
3815
  /* Update $drizzle_get_server_version to that of current connection */
 
3816
  var_set_drizzle_get_server_version(&cur_con->drizzle);
3960
3817
 
3961
3818
  return;
3962
3819
}
4073
3930
  if (not_expr)
4074
3931
    cur_block->ok = !cur_block->ok;
4075
3932
 
4076
 
  free(v.str_val);
4077
 
  free(v.env_s);
4078
 
 
 
3933
  var_free(&v);
4079
3934
  return;
4080
3935
}
4081
3936
 
4090
3945
  if (!(*p))
4091
3946
    die("Can't set empty delimiter");
4092
3947
 
4093
 
  strncpy(delimiter, p, sizeof(delimiter) - 1);
 
3948
  strmake(delimiter, p, sizeof(delimiter) - 1);
4094
3949
  delimiter_length= strlen(delimiter);
4095
3950
 
4096
3951
  command->last_argument= p + delimiter_length;
4098
3953
}
4099
3954
 
4100
3955
 
4101
 
bool match_delimiter(int c, const char *delim, uint32_t length)
 
3956
bool match_delimiter(int c, const char *delim, uint length)
4102
3957
{
4103
 
  uint32_t i;
 
3958
  uint i;
4104
3959
  char tmp[MAX_DELIMITER_LENGTH];
4105
3960
 
4106
3961
  if (c != *delim)
4152
4007
 
4153
4008
*/
4154
4009
 
4155
 
 
4156
 
static int my_strnncoll_simple(const CHARSET_INFO * const  cs, const unsigned char *s, size_t slen,
4157
 
                               const unsigned char *t, size_t tlen,
4158
 
                               bool t_is_prefix)
4159
 
{
4160
 
  size_t len = ( slen > tlen ) ? tlen : slen;
4161
 
  unsigned char *map= cs->sort_order;
4162
 
  if (t_is_prefix && slen > tlen)
4163
 
    slen=tlen;
4164
 
  while (len--)
4165
 
  {
4166
 
    if (map[*s++] != map[*t++])
4167
 
      return ((int) map[s[-1]] - (int) map[t[-1]]);
4168
 
  }
4169
 
  /*
4170
 
    We can't use (slen - tlen) here as the result may be outside of the
4171
 
    precision of a signed int
4172
 
  */
4173
 
  return slen > tlen ? 1 : slen < tlen ? -1 : 0 ;
4174
 
}
4175
 
 
4176
4010
static int read_line(char *buf, int size)
4177
4011
{
4178
4012
  char c, last_quote= 0;
4192
4026
  found_eof:
4193
4027
      if (cur_file->file != stdin)
4194
4028
      {
4195
 
        fclose(cur_file->file);
 
4029
        my_fclose(cur_file->file, MYF(0));
4196
4030
        cur_file->file= 0;
4197
4031
      }
4198
4032
      free((unsigned char*) cur_file->file_name);
4232
4066
      }
4233
4067
      else if ((c == '{' &&
4234
4068
                (!my_strnncoll_simple(charset_info, (const unsigned char*) "while", 5,
4235
 
                                      (unsigned char*) buf, min((ptrdiff_t)5, p - buf), 0) ||
 
4069
                                      (unsigned char*) buf, cmin((long)5, p - buf), 0) ||
4236
4070
                 !my_strnncoll_simple(charset_info, (const unsigned char*) "if", 2,
4237
 
                                      (unsigned char*) buf, min((ptrdiff_t)2, p - buf), 0))))
 
4071
                                      (unsigned char*) buf, cmin((long)2, p - buf), 0))))
4238
4072
      {
4239
4073
        /* Only if and while commands can be terminated by { */
4240
4074
        *p++= c;
4311
4145
    {
4312
4146
      /* Could be a multibyte character */
4313
4147
      /* This code is based on the code in "sql_load.cc" */
 
4148
#ifdef USE_MB
4314
4149
      int charlen = my_mbcharlen(charset_info, c);
4315
4150
      /* We give up if multibyte character is started but not */
4316
4151
      /* completed before we pass buf_end */
4337
4172
        }
4338
4173
      }
4339
4174
      else
 
4175
#endif
4340
4176
        *p++= c;
4341
4177
    }
4342
4178
  }
4419
4255
        ptr[2] && ptr[2] == '-' &&
4420
4256
        ptr[3])
4421
4257
    {
4422
 
      uint32_t type;
 
4258
      uint type;
4423
4259
      char save;
4424
4260
      char *end, *start= (char*)ptr+3;
4425
4261
      /* Skip leading spaces */
4529
4365
    *command_ptr= q_lines[parser.current_line];
4530
4366
    return(0);
4531
4367
  }
4532
 
  if (!(*command_ptr= command= new st_command))
4533
 
    die("command construction failed");
 
4368
  if (!(*command_ptr= command=
 
4369
        (struct st_command*) my_malloc(sizeof(*command),
 
4370
                                       MYF(MY_WME|MY_ZEROFILL))))
 
4371
    die(NULL);
4534
4372
  q_lines.push_back(command);
4535
4373
  command->type= Q_UNKNOWN;
4536
4374
 
4557
4395
  while (*p && my_isspace(charset_info, *p))
4558
4396
    p++;
4559
4397
 
4560
 
  if (!(command->query_buf= command->query= strdup(p)))
 
4398
  if (!(command->query_buf= command->query= my_strdup(p, MYF(MY_WME))))
4561
4399
    die("Out of memory");
4562
4400
 
4563
4401
  /* Calculate first word length(the command), terminated by space or ( */
4564
4402
  p= command->query;
4565
4403
  while (*p && !my_isspace(charset_info, *p) && *p != '(')
4566
4404
    p++;
4567
 
  command->first_word_len= (uint32_t) (p - command->query);
 
4405
  command->first_word_len= (uint) (p - command->query);
4568
4406
 
4569
4407
  /* Skip spaces between command and first argument */
4570
4408
  while (*p && my_isspace(charset_info, *p))
4578
4416
}
4579
4417
 
4580
4418
 
4581
 
static struct option my_long_options[] =
 
4419
static struct my_option my_long_options[] =
4582
4420
{
4583
4421
  {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
4584
4422
   0, 0, 0, 0, 0, 0},
4587
4425
  {"character-sets-dir", OPT_CHARSETS_DIR,
4588
4426
   "Directory where character sets are.", (char**) &opt_charsets_dir,
4589
4427
   (char**) &opt_charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
4428
  {"compress", 'C', "Use the compressed server/client protocol.",
 
4429
   (char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
4430
   0, 0, 0},
4590
4431
  {"database", 'D', "Database to use.", (char**) &opt_db, (char**) &opt_db, 0,
4591
4432
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
4433
  {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
 
4434
   (char**) &debug_check_flag, (char**) &debug_check_flag, 0,
 
4435
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
4436
  {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
 
4437
   (char**) &debug_info_flag, (char**) &debug_info_flag,
 
4438
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4592
4439
  {"host", 'h', "Connect to host.", (char**) &opt_host, (char**) &opt_host, 0,
4593
4440
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4594
4441
  {"include", 'i', "Include SQL before each test case.", (char**) &opt_include,
4595
4442
   (char**) &opt_include, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4596
 
  {"testdir", OPT_TESTDIR, "Path to use to search for test files",
4597
 
   (char**) &opt_testdir,
4598
 
   (char**) &opt_testdir, 0,GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4599
4443
  {"logdir", OPT_LOG_DIR, "Directory for log files", (char**) &opt_logdir,
4600
4444
   (char**) &opt_logdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4601
4445
  {"mark-progress", OPT_MARK_PROGRESS,
4606
4450
   "Max number of connection attempts when connecting to server",
4607
4451
   (char**) &opt_max_connect_retries, (char**) &opt_max_connect_retries, 0,
4608
4452
   GET_INT, REQUIRED_ARG, 500, 1, 10000, 0, 0, 0},
4609
 
  {"mysql", 'm', N_("Use MySQL Protocol."),
4610
 
   (char**) &opt_mysql, (char**) &opt_mysql, 0, GET_BOOL, NO_ARG, 1, 0, 0,
4611
 
   0, 0, 0},
4612
 
  {"password", 'P', "Password to use when connecting to server.",
 
4453
  {"password", 'p', "Password to use when connecting to server.",
4613
4454
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
4614
 
  {"port", 'p', "Port number to use for connection or 0 for default to, in "
 
4455
  {"port", 'P', "Port number to use for connection or 0 for default to, in "
4615
4456
   "order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
4616
4457
   "built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
4617
 
   0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
4458
   (char**) &opt_port,
 
4459
   (char**) &opt_port, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4618
4460
  {"quiet", 's', "Suppress all normal output.", (char**) &silent,
4619
4461
   (char**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4620
4462
  {"record", 'r', "Record output of test_file into result file.",
4622
4464
  {"result-file", 'R', "Read/Store result from/in this file.",
4623
4465
   (char**) &result_file_name, (char**) &result_file_name, 0,
4624
4466
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
4467
  {"server-arg", 'A', "Send option value to embedded server as a parameter.",
 
4468
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
4469
  {"server-file", 'F', "Read embedded server arguments from file.",
 
4470
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4625
4471
  {"silent", 's', "Suppress all normal output. Synonym for --quiet.",
4626
4472
   (char**) &silent, (char**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4627
4473
  {"sleep", 'T', "Sleep always this many seconds on sleep commands.",
4649
4495
 
4650
4496
static void print_version(void)
4651
4497
{
4652
 
  printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname,MTEST_VERSION,
4653
 
         drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
 
4498
  printf("%s  Ver %s Distrib %s, for %s (%s)\n",my_progname,MTEST_VERSION,
 
4499
         drizzle_get_client_info(),SYSTEM_TYPE,MACHINE_TYPE);
4654
4500
}
4655
4501
 
4656
4502
static void usage(void)
4657
4503
{
4658
4504
  print_version();
4659
4505
  printf("MySQL AB, by Sasha, Matt, Monty & Jani\n");
4660
 
  printf("Drizzle version modified by Brian, Jay, Monty Taylor, PatG and Stewart\n");
4661
4506
  printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
4662
4507
  printf("Runs a test against the DRIZZLE server and compares output with a results file.\n\n");
4663
 
  printf("Usage: %s [OPTIONS] [database] < test_file\n", internal::my_progname);
 
4508
  printf("Usage: %s [OPTIONS] [database] < test_file\n", my_progname);
4664
4509
  my_print_help(my_long_options);
4665
4510
  printf("  --no-defaults       Don't read default options from any options file.\n");
4666
4511
  my_print_variables(my_long_options);
4667
4512
}
4668
4513
 
4669
 
int get_one_option(int optid, const struct option *, char *argument)
4670
 
{
4671
 
  char *endchar= NULL;
4672
 
  uint64_t temp_drizzle_port= 0;
4673
 
 
 
4514
/*
 
4515
  Read arguments for embedded server and put them into
 
4516
  embedded_server_args[]
 
4517
*/
 
4518
 
 
4519
static void read_embedded_server_arguments(const char *name)
 
4520
{
 
4521
  char argument[1024],buff[FN_REFLEN], *str=0;
 
4522
  FILE *file;
 
4523
 
 
4524
  if (!test_if_hard_path(name))
 
4525
  {
 
4526
    strxmov(buff, opt_basedir, name, NULL);
 
4527
    name=buff;
 
4528
  }
 
4529
  fn_format(buff, name, "", "", MY_UNPACK_FILENAME);
 
4530
 
 
4531
  if (!embedded_server_arg_count)
 
4532
  {
 
4533
    embedded_server_arg_count=1;
 
4534
    embedded_server_args[0]= (char*) "";    /* Progname */
 
4535
  }
 
4536
  if (!(file=my_fopen(buff, O_RDONLY, MYF(MY_WME))))
 
4537
    die("Failed to open file '%s'", buff);
 
4538
 
 
4539
  while (embedded_server_arg_count < MAX_EMBEDDED_SERVER_ARGS &&
 
4540
         (str=fgets(argument,sizeof(argument), file)))
 
4541
  {
 
4542
    *(strchr(str, '\0')-1)=0;        /* Remove end newline */
 
4543
    if (!(embedded_server_args[embedded_server_arg_count]=
 
4544
          (char*) my_strdup(str,MYF(MY_WME))))
 
4545
    {
 
4546
      my_fclose(file,MYF(0));
 
4547
      die("Out of memory");
 
4548
 
 
4549
    }
 
4550
    embedded_server_arg_count++;
 
4551
  }
 
4552
  my_fclose(file,MYF(0));
 
4553
  if (str)
 
4554
    die("Too many arguments in option file: %s",name);
 
4555
 
 
4556
  return;
 
4557
}
 
4558
 
 
4559
 
 
4560
static bool
 
4561
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
 
4562
               char *argument)
 
4563
{
4674
4564
  switch(optid) {
4675
4565
  case 'r':
4676
4566
    record = 1;
4678
4568
  case 'x':
4679
4569
  {
4680
4570
    char buff[FN_REFLEN];
4681
 
    if (!internal::test_if_hard_path(argument))
 
4571
    if (!test_if_hard_path(argument))
4682
4572
    {
4683
 
      snprintf(buff, sizeof(buff), "%s%s",opt_basedir,argument);
 
4573
      strxmov(buff, opt_basedir, argument, NULL);
4684
4574
      argument= buff;
4685
4575
    }
4686
 
    internal::fn_format(buff, argument, "", "", MY_UNPACK_FILENAME);
 
4576
    fn_format(buff, argument, "", "", MY_UNPACK_FILENAME);
4687
4577
    assert(cur_file == file_stack && cur_file->file == 0);
4688
 
    if (!(cur_file->file= fopen(buff, "r")))
4689
 
    {
4690
 
      fprintf(stderr, _("Could not open '%s' for reading: errno = %d"), buff, errno);
4691
 
      return EXIT_ARGUMENT_INVALID;
4692
 
    }
4693
 
    if (!(cur_file->file_name= strdup(buff)))
4694
 
    {
4695
 
      fprintf(stderr, _("Out of memory"));
4696
 
      return EXIT_OUT_OF_MEMORY;
4697
 
    }
 
4578
    if (!(cur_file->file=
 
4579
          my_fopen(buff, O_RDONLY, MYF(0))))
 
4580
      die("Could not open '%s' for reading: errno = %d", buff, errno);
 
4581
    cur_file->file_name= my_strdup(buff, MYF(MY_FAE));
4698
4582
    cur_file->lineno= 1;
4699
4583
    break;
4700
4584
  }
4701
4585
  case 'm':
4702
4586
  {
4703
4587
    static char buff[FN_REFLEN];
4704
 
    if (!internal::test_if_hard_path(argument))
 
4588
    if (!test_if_hard_path(argument))
4705
4589
    {
4706
 
      snprintf(buff, sizeof(buff), "%s%s",opt_basedir,argument);
 
4590
      strxmov(buff, opt_basedir, argument, NULL);
4707
4591
      argument= buff;
4708
4592
    }
4709
 
    internal::fn_format(buff, argument, "", "", MY_UNPACK_FILENAME);
 
4593
    fn_format(buff, argument, "", "", MY_UNPACK_FILENAME);
4710
4594
    timer_file= buff;
4711
4595
    unlink(timer_file);       /* Ignore error, may not exist */
4712
4596
    break;
4713
4597
  }
4714
4598
  case 'p':
4715
 
    temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
4716
 
    /* if there is an alpha character this is not a valid port */
4717
 
    if (strlen(endchar) != 0)
4718
 
    {
4719
 
      fprintf(stderr, _("Non-integer value supplied for port.  If you are trying to enter a password please use --password instead.\n"));
4720
 
      return EXIT_ARGUMENT_INVALID;
4721
 
    }
4722
 
    /* If the port number is > 65535 it is not a valid port
4723
 
       This also helps with potential data loss casting unsigned long to a
4724
 
       uint32_t. */
4725
 
    if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
4726
 
    {
4727
 
      fprintf(stderr, _("Value supplied for port is not valid.\n"));
4728
 
      return EXIT_ARGUMENT_INVALID;
4729
 
    }
4730
 
    else
4731
 
    {
4732
 
      opt_port= (uint32_t) temp_drizzle_port;
4733
 
    }
4734
 
    break;
4735
 
  case 'P':
4736
4599
    if (argument)
4737
4600
    {
4738
 
      if (opt_pass)
4739
 
        free(opt_pass);
4740
 
      opt_pass = strdup(argument);
4741
 
      if (opt_pass == NULL)
4742
 
      {
4743
 
        fprintf(stderr, _("Out of memory"));
4744
 
        return EXIT_OUT_OF_MEMORY;
4745
 
      }
4746
 
      while (*argument)
4747
 
      {
4748
 
        /* Overwriting password with 'x' */
4749
 
        *argument++= 'x';
4750
 
      }
 
4601
      free(opt_pass);
 
4602
      opt_pass= my_strdup(argument, MYF(MY_FAE));
 
4603
      while (*argument) *argument++= 'x';    /* Destroy argument */
4751
4604
      tty_password= 0;
4752
4605
    }
4753
4606
    else
4754
4607
      tty_password= 1;
4755
4608
    break;
4756
4609
  case 't':
4757
 
    strncpy(TMPDIR, argument, sizeof(TMPDIR));
 
4610
    my_stpncpy(TMPDIR, argument, sizeof(TMPDIR));
 
4611
    break;
 
4612
  case 'A':
 
4613
    if (!embedded_server_arg_count)
 
4614
    {
 
4615
      embedded_server_arg_count=1;
 
4616
      embedded_server_args[0]= (char*) "";
 
4617
    }
 
4618
    if (embedded_server_arg_count == MAX_EMBEDDED_SERVER_ARGS-1 ||
 
4619
        !(embedded_server_args[embedded_server_arg_count++]=
 
4620
          my_strdup(argument, MYF(MY_FAE))))
 
4621
    {
 
4622
      die("Can't use server argument");
 
4623
    }
 
4624
    break;
 
4625
  case 'F':
 
4626
    read_embedded_server_arguments(argument);
4758
4627
    break;
4759
4628
  case 'V':
4760
4629
    print_version();
4769
4638
 
4770
4639
static int parse_args(int argc, char **argv)
4771
4640
{
4772
 
  internal::load_defaults("drizzle",load_default_groups,&argc,&argv);
 
4641
  load_defaults("drizzle",load_default_groups,&argc,&argv);
4773
4642
  default_argv= argv;
4774
4643
 
4775
4644
  if ((handle_options(&argc, &argv, my_long_options, get_one_option)))
4783
4652
  if (argc == 1)
4784
4653
    opt_db= *argv;
4785
4654
  if (tty_password)
4786
 
    opt_pass= client_get_tty_password(NULL);          /* purify tested */
 
4655
    opt_pass= get_tty_password(NULL);          /* purify tested */
 
4656
  if (debug_info_flag)
 
4657
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
 
4658
  if (debug_check_flag)
 
4659
    my_end_arg= MY_CHECK_ERROR;
4787
4660
 
4788
4661
  return 0;
4789
4662
}
4804
4677
  int fd;
4805
4678
  char buff[FN_REFLEN];
4806
4679
  int flags= O_WRONLY | O_CREAT;
4807
 
  if (!internal::test_if_hard_path(fname))
 
4680
  if (!test_if_hard_path(fname))
4808
4681
  {
4809
 
    snprintf(buff, sizeof(buff), "%s%s",opt_basedir,fname);
 
4682
    strxmov(buff, opt_basedir, fname, NULL);
4810
4683
    fname= buff;
4811
4684
  }
4812
 
  internal::fn_format(buff, fname, "", "", MY_UNPACK_FILENAME);
 
4685
  fn_format(buff, fname, "", "", MY_UNPACK_FILENAME);
4813
4686
 
4814
4687
  if (!append)
4815
4688
    flags|= O_TRUNC;
4816
 
  if ((fd= internal::my_open(buff, flags,
 
4689
  if ((fd= my_open(buff, flags,
4817
4690
                   MYF(MY_WME | MY_FFNF))) < 0)
4818
4691
    die("Could not open '%s' for writing: errno = %d", buff, errno);
4819
 
  if (append && lseek(fd, 0, SEEK_END) == MY_FILEPOS_ERROR)
 
4692
  if (append && my_seek(fd, 0, SEEK_END, MYF(0)) == MY_FILEPOS_ERROR)
4820
4693
    die("Could not find end of file '%s': errno = %d", buff, errno);
4821
 
  if (internal::my_write(fd, (unsigned char*)str, size, MYF(MY_WME|MY_FNABP)))
 
4694
  if (my_write(fd, (unsigned char*)str, size, MYF(MY_WME|MY_FNABP)))
4822
4695
    die("write failed");
4823
 
  internal::my_close(fd, MYF(0));
 
4696
  my_close(fd, MYF(0));
4824
4697
}
4825
4698
 
4826
4699
/*
4842
4715
void dump_result_to_log_file(const char *buf, int size)
4843
4716
{
4844
4717
  char log_file[FN_REFLEN];
4845
 
  str_to_file(internal::fn_format(log_file, result_file_name, opt_logdir, ".log",
 
4718
  str_to_file(fn_format(log_file, result_file_name, opt_logdir, ".log",
4846
4719
                        *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
4847
4720
                        MY_REPLACE_EXT),
4848
4721
              buf, size);
4853
4726
void dump_progress(void)
4854
4727
{
4855
4728
  char progress_file[FN_REFLEN];
4856
 
  str_to_file(internal::fn_format(progress_file, result_file_name,
 
4729
  str_to_file(fn_format(progress_file, result_file_name,
4857
4730
                        opt_logdir, ".progress",
4858
4731
                        *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
4859
4732
                        MY_REPLACE_EXT),
4864
4737
{
4865
4738
  char warn_file[FN_REFLEN];
4866
4739
 
4867
 
  str_to_file(internal::fn_format(warn_file, result_file_name, opt_logdir, ".warnings",
 
4740
  str_to_file(fn_format(warn_file, result_file_name, opt_logdir, ".warnings",
4868
4741
                        *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
4869
4742
                        MY_REPLACE_EXT),
4870
4743
              ds_warning_messages.c_str(), ds_warning_messages.length());
4875
4748
  Append the result for one field to the dynamic string ds
4876
4749
*/
4877
4750
 
4878
 
static void append_field(string *ds, uint32_t col_idx, drizzle_column_st *column,
 
4751
static void append_field(string *ds, uint col_idx, const DRIZZLE_FIELD* field,
4879
4752
                         const char* val, uint64_t len, bool is_null)
4880
4753
{
4881
4754
  if (col_idx < max_replace_column && replace_column[col_idx])
4897
4770
  }
4898
4771
  else
4899
4772
  {
4900
 
    ds->append(drizzle_column_name(column));
 
4773
    ds->append(field->name);
4901
4774
    ds->append("\t");
4902
4775
    replace_append_mem(ds, val, (int)len);
4903
4776
    ds->append("\n");
4910
4783
  Values may be converted with 'replace_column'
4911
4784
*/
4912
4785
 
4913
 
static void append_result(string *ds, drizzle_result_st *res)
 
4786
static void append_result(string *ds, DRIZZLE_RES *res)
4914
4787
{
4915
 
  drizzle_row_t row;
4916
 
  uint32_t num_fields= drizzle_result_column_count(res);
4917
 
  drizzle_column_st *column;
4918
 
  size_t *lengths;
 
4788
  DRIZZLE_ROW row;
 
4789
  uint32_t num_fields= drizzle_num_fields(res);
 
4790
  const DRIZZLE_FIELD *fields= drizzle_fetch_fields(res);
 
4791
  uint32_t *lengths;
4919
4792
 
4920
 
  while ((row = drizzle_row_next(res)))
 
4793
  while ((row = drizzle_fetch_row(res)))
4921
4794
  {
4922
4795
    uint32_t i;
4923
 
    lengths = drizzle_row_field_sizes(res);
4924
 
    drizzle_column_seek(res, 0);
 
4796
    lengths = drizzle_fetch_lengths(res);
4925
4797
    for (i = 0; i < num_fields; i++)
4926
 
    {
4927
 
      column= drizzle_column_next(res);
4928
 
      append_field(ds, i, column,
 
4798
      append_field(ds, i, &fields[i],
4929
4799
                   (const char*)row[i], lengths[i], !row[i]);
4930
 
    }
4931
4800
    if (!display_result_vertically)
4932
4801
      ds->append("\n");
4933
4802
 
4939
4808
  Append metadata for fields to output
4940
4809
*/
4941
4810
 
4942
 
static void append_metadata(string *ds, drizzle_result_st *res)
 
4811
static void append_metadata(string *ds,
 
4812
                            const DRIZZLE_FIELD *field,
 
4813
                            uint num_fields)
4943
4814
{
4944
 
  drizzle_column_st *column;
 
4815
  const DRIZZLE_FIELD *field_end;
4945
4816
  ds->append("Catalog\tDatabase\tTable\tTable_alias\tColumn\t"
4946
4817
             "Column_alias\tType\tLength\tMax length\tIs_null\t"
4947
4818
             "Flags\tDecimals\tCharsetnr\n");
4948
4819
 
4949
 
  drizzle_column_seek(res, 0);
4950
 
  while ((column= drizzle_column_next(res)))
 
4820
  for (field_end= field+num_fields ;
 
4821
       field < field_end ;
 
4822
       field++)
4951
4823
  {
4952
 
    ds->append(drizzle_column_catalog(column),
4953
 
               strlen(drizzle_column_catalog(column)));
4954
 
    ds->append("\t", 1);
4955
 
    ds->append(drizzle_column_db(column), strlen(drizzle_column_db(column)));
4956
 
    ds->append("\t", 1);
4957
 
    ds->append(drizzle_column_orig_table(column),
4958
 
               strlen(drizzle_column_orig_table(column)));
4959
 
    ds->append("\t", 1);
4960
 
    ds->append(drizzle_column_table(column),
4961
 
               strlen(drizzle_column_table(column)));
4962
 
    ds->append("\t", 1);
4963
 
    ds->append(drizzle_column_orig_name(column),
4964
 
               strlen(drizzle_column_orig_name(column)));
4965
 
    ds->append("\t", 1);
4966
 
    ds->append(drizzle_column_name(column),
4967
 
               strlen(drizzle_column_name(column)));
4968
 
    ds->append("\t", 1);
4969
 
    replace_append_uint(ds, drizzle_column_type_drizzle(column));
4970
 
    ds->append("\t", 1);
4971
 
    replace_append_uint(ds, drizzle_column_size(column));
4972
 
    ds->append("\t", 1);
4973
 
    replace_append_uint(ds, drizzle_column_max_size(column));
4974
 
    ds->append("\t", 1);
4975
 
    ds->append((char*) ((drizzle_column_flags(column) & DRIZZLE_COLUMN_FLAGS_NOT_NULL) ? "N" : "Y"), 1);
4976
 
    ds->append("\t", 1);
4977
 
    replace_append_uint(ds, drizzle_column_flags(column));
4978
 
    ds->append("\t", 1);
4979
 
    replace_append_uint(ds, drizzle_column_decimals(column));
4980
 
    ds->append("\t", 1);
4981
 
    replace_append_uint(ds, drizzle_column_charset(column));
 
4824
    ds->append(field->catalog,
 
4825
               field->catalog_length);
 
4826
    ds->append("\t", 1);
 
4827
    ds->append(field->db, field->db_length);
 
4828
    ds->append("\t", 1);
 
4829
    ds->append(field->org_table,
 
4830
               field->org_table_length);
 
4831
    ds->append("\t", 1);
 
4832
    ds->append(field->table,
 
4833
               field->table_length);
 
4834
    ds->append("\t", 1);
 
4835
    ds->append(field->org_name,
 
4836
               field->org_name_length);
 
4837
    ds->append("\t", 1);
 
4838
    ds->append(field->name, field->name_length);
 
4839
    ds->append("\t", 1);
 
4840
    replace_append_uint(ds, field->type);
 
4841
    ds->append("\t", 1);
 
4842
    replace_append_uint(ds, field->length);
 
4843
    ds->append("\t", 1);
 
4844
    replace_append_uint(ds, field->max_length);
 
4845
    ds->append("\t", 1);
 
4846
    ds->append((char*) ((field->flags & NOT_NULL_FLAG) ?
 
4847
                        "N" : "Y"), 1);
 
4848
    ds->append("\t", 1);
 
4849
    replace_append_uint(ds, field->flags);
 
4850
    ds->append("\t", 1);
 
4851
    replace_append_uint(ds, field->decimals);
 
4852
    ds->append("\t", 1);
 
4853
    replace_append_uint(ds, field->charsetnr);
4982
4854
    ds->append("\n", 1);
4983
4855
  }
4984
4856
}
4991
4863
static void append_info(string *ds, uint64_t affected_rows,
4992
4864
                        const char *info)
4993
4865
{
4994
 
  ostringstream buf;
4995
 
  buf << "affected rows: " << affected_rows << endl;
4996
 
  ds->append(buf.str());
4997
 
  if (info && strcmp(info, ""))
 
4866
  char buf[40], buff2[21];
 
4867
  sprintf(buf,"affected rows: %s\n", llstr(affected_rows, buff2));
 
4868
  ds->append(buf);
 
4869
  if (info)
4998
4870
  {
4999
4871
    ds->append("info: ");
5000
4872
    ds->append(info);
5007
4879
  Display the table headings with the names tab separated
5008
4880
*/
5009
4881
 
5010
 
static void append_table_headings(string *ds, drizzle_result_st *res)
 
4882
static void append_table_headings(string *ds,
 
4883
                                  const DRIZZLE_FIELD *field,
 
4884
                                  uint num_fields)
5011
4885
{
5012
 
  uint32_t col_idx= 0;
5013
 
  drizzle_column_st *column;
5014
 
  drizzle_column_seek(res, 0);
5015
 
  while ((column= drizzle_column_next(res)))
 
4886
  uint col_idx;
 
4887
  for (col_idx= 0; col_idx < num_fields; col_idx++)
5016
4888
  {
5017
4889
    if (col_idx)
5018
4890
      ds->append("\t", 1);
5019
 
    replace_append(ds, drizzle_column_name(column));
5020
 
    col_idx++;
 
4891
    replace_append(ds, field[col_idx].name);
5021
4892
  }
5022
4893
  ds->append("\n", 1);
5023
4894
}
5029
4900
  Number of warnings appended to ds
5030
4901
*/
5031
4902
 
5032
 
static int append_warnings(string *ds, drizzle_con_st *con,
5033
 
                           drizzle_result_st *res)
 
4903
static int append_warnings(string *ds, DRIZZLE *drizzle)
5034
4904
{
5035
 
  uint32_t count;
5036
 
  drizzle_result_st warn_res;
5037
 
  drizzle_return_t ret;
5038
 
 
5039
 
 
5040
 
  if (!(count= drizzle_result_warning_count(res)))
 
4905
  uint count;
 
4906
  DRIZZLE_RES *warn_res;
 
4907
 
 
4908
 
 
4909
  if (!(count= drizzle_warning_count(drizzle)))
5041
4910
    return(0);
5042
4911
 
5043
 
  if (drizzle_query_str(con, &warn_res, "SHOW WARNINGS", &ret) == NULL ||
5044
 
      ret != DRIZZLE_RETURN_OK)
5045
 
  {
5046
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
5047
 
      die("Error running query \"SHOW WARNINGS\": %s", drizzle_result_error(&warn_res));
5048
 
    else
5049
 
      die("Error running query \"SHOW WARNINGS\": %s", drizzle_con_error(con));
5050
 
  }
5051
 
 
5052
 
  if (drizzle_result_column_count(&warn_res) == 0 ||
5053
 
      drizzle_result_buffer(&warn_res) != DRIZZLE_RETURN_OK)
5054
 
    die("Warning count is %u but didn't get any warnings", count);
5055
 
 
5056
 
  append_result(ds, &warn_res);
5057
 
  drizzle_result_free(&warn_res);
 
4912
  /*
 
4913
    If one day we will support execution of multi-statements
 
4914
    through PS API we should not issue SHOW WARNINGS until
 
4915
    we have not read all results...
 
4916
  */
 
4917
  assert(!drizzle_more_results(drizzle));
 
4918
 
 
4919
  if (drizzle_real_query(drizzle, "SHOW WARNINGS", 13))
 
4920
    die("Error running query \"SHOW WARNINGS\": %s", drizzle_error(drizzle));
 
4921
 
 
4922
  if (!(warn_res= drizzle_store_result(drizzle)))
 
4923
    die("Warning count is %u but didn't get any warnings",
 
4924
        count);
 
4925
 
 
4926
  append_result(ds, warn_res);
5058
4927
 
5059
4928
  return(count);
5060
4929
}
5078
4947
                             int flags, char *query, int query_len,
5079
4948
                             string *ds, string *ds_warnings)
5080
4949
{
5081
 
  drizzle_result_st res;
5082
 
  drizzle_return_t ret;
5083
 
  drizzle_con_st *con= &cn->con;
5084
 
  int err= 0;
5085
 
 
5086
 
  drizzle_con_add_options(con, DRIZZLE_CON_NO_RESULT_READ);
 
4950
  DRIZZLE_RES *res= 0;
 
4951
  DRIZZLE *drizzle= &cn->drizzle;
 
4952
  int err= 0, counter= 0;
5087
4953
 
5088
4954
  if (flags & QUERY_SEND_FLAG)
5089
4955
  {
5090
4956
    /*
5091
4957
     * Send the query
5092
4958
     */
5093
 
 
5094
 
    (void) drizzle_query(con, &res, query, query_len, &ret);
5095
 
    if (ret != DRIZZLE_RETURN_OK)
 
4959
    if (do_send_query(cn, query, query_len, flags))
5096
4960
    {
5097
 
      if (ret == DRIZZLE_RETURN_ERROR_CODE ||
5098
 
          ret == DRIZZLE_RETURN_HANDSHAKE_FAILED)
5099
 
      {
5100
 
        err= drizzle_result_error_code(&res);
5101
 
        handle_error(command, err, drizzle_result_error(&res),
5102
 
                     drizzle_result_sqlstate(&res), ds);
5103
 
        if (ret == DRIZZLE_RETURN_ERROR_CODE)
5104
 
          drizzle_result_free(&res);
5105
 
      }
5106
 
      else
5107
 
      {
5108
 
        handle_error(command, ret, drizzle_con_error(con), "", ds);
5109
 
        err= ret;
5110
 
      }
 
4961
      handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
 
4962
                   drizzle_sqlstate(drizzle), ds);
5111
4963
      goto end;
5112
4964
    }
5113
4965
  }
5114
4966
  if (!(flags & QUERY_REAP_FLAG))
5115
4967
    return;
5116
4968
 
 
4969
  do
5117
4970
  {
5118
4971
    /*
5119
 
     * Read the result packet
5120
 
     */
5121
 
    if (drizzle_result_read(con, &res, &ret) == NULL ||
5122
 
        ret != DRIZZLE_RETURN_OK)
 
4972
      When  on first result set, call drizzle_read_query_result to retrieve
 
4973
      answer to the query sent earlier
 
4974
    */
 
4975
    if ((counter==0) && drizzle_read_query_result(drizzle))
5123
4976
    {
5124
 
      if (ret == DRIZZLE_RETURN_ERROR_CODE)
5125
 
      {
5126
 
        handle_error(command, drizzle_result_error_code(&res),
5127
 
                     drizzle_result_error(&res), drizzle_result_sqlstate(&res),
5128
 
                     ds);
5129
 
      }
5130
 
      else
5131
 
        handle_error(command, ret, drizzle_con_error(con), "", ds);
5132
 
      drizzle_result_free(&res);
5133
 
      err= ret;
 
4977
      handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
 
4978
                   drizzle_sqlstate(drizzle), ds);
5134
4979
      goto end;
 
4980
 
5135
4981
    }
5136
4982
 
5137
4983
    /*
5138
4984
      Store the result of the query if it will return any fields
5139
4985
    */
5140
 
    if (drizzle_result_column_count(&res) &&
5141
 
        (ret= drizzle_result_buffer(&res)) != DRIZZLE_RETURN_OK)
 
4986
    if (drizzle_field_count(drizzle) && ((res= drizzle_store_result(drizzle)) == 0))
5142
4987
    {
5143
 
      if (ret == DRIZZLE_RETURN_ERROR_CODE)
5144
 
      {
5145
 
        handle_error(command, drizzle_result_error_code(&res),
5146
 
                     drizzle_result_error(&res), drizzle_result_sqlstate(&res),
5147
 
                     ds);
5148
 
      }
5149
 
      else
5150
 
        handle_error(command, ret, drizzle_con_error(con), "", ds);
5151
 
      drizzle_result_free(&res);
5152
 
      err= ret;
 
4988
      handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
 
4989
                   drizzle_sqlstate(drizzle), ds);
5153
4990
      goto end;
5154
4991
    }
5155
4992
 
5157
4994
    {
5158
4995
      uint64_t affected_rows= 0;    /* Ok to be undef if 'disable_info' is set */
5159
4996
 
5160
 
      if (drizzle_result_column_count(&res))
 
4997
      if (res)
5161
4998
      {
 
4999
        const DRIZZLE_FIELD *fields= drizzle_fetch_fields(res);
 
5000
        uint num_fields= drizzle_num_fields(res);
 
5001
 
5162
5002
        if (display_metadata)
5163
 
          append_metadata(ds, &res);
 
5003
          append_metadata(ds, fields, num_fields);
5164
5004
 
5165
5005
        if (!display_result_vertically)
5166
 
          append_table_headings(ds, &res);
 
5006
          append_table_headings(ds, fields, num_fields);
5167
5007
 
5168
 
        append_result(ds, &res);
 
5008
        append_result(ds, res);
5169
5009
      }
5170
5010
 
5171
5011
      /*
5172
 
        Need to call drizzle_result_affected_rows() before the "new"
 
5012
        Need to call drizzle_affected_rows() before the "new"
5173
5013
        query to find the warnings
5174
5014
      */
5175
5015
      if (!disable_info)
5176
 
        affected_rows= drizzle_result_affected_rows(&res);
 
5016
        affected_rows= drizzle_affected_rows(drizzle);
5177
5017
 
5178
5018
      /*
5179
5019
        Add all warnings to the result. We can't do this if we are in
5180
5020
        the middle of processing results from multi-statement, because
5181
5021
        this will break protocol.
5182
5022
      */
5183
 
      if (!disable_warnings)
 
5023
      if (!disable_warnings && !drizzle_more_results(drizzle))
5184
5024
      {
5185
 
        drizzle_con_remove_options(con, DRIZZLE_CON_NO_RESULT_READ);
5186
 
        if (append_warnings(ds_warnings, con, &res) || ds_warnings->length())
 
5025
        if (append_warnings(ds_warnings, drizzle) || ds_warnings->length())
5187
5026
        {
5188
5027
          ds->append("Warnings:\n", 10);
5189
5028
          ds->append(ds_warnings->c_str(), ds_warnings->length());
5191
5030
      }
5192
5031
 
5193
5032
      if (!disable_info)
5194
 
        append_info(ds, affected_rows, drizzle_result_info(&res));
 
5033
        append_info(ds, affected_rows, drizzle_info(drizzle));
5195
5034
    }
5196
5035
 
5197
 
    drizzle_result_free(&res);
 
5036
    if (res)
 
5037
    {
 
5038
      drizzle_free_result(res);
 
5039
      res= 0;
 
5040
    }
 
5041
    counter++;
 
5042
  } while (!(err= drizzle_next_result(drizzle)));
 
5043
  if (err > 0)
 
5044
  {
 
5045
    /* We got an error from drizzle_next_result, maybe expected */
 
5046
    handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
 
5047
                 drizzle_sqlstate(drizzle), ds);
 
5048
    goto end;
5198
5049
  }
 
5050
  assert(err == -1); /* Successful and there are no more results */
5199
5051
 
5200
5052
  /* If we come here the query is both executed and read successfully */
5201
5053
  handle_no_error(command);
5203
5055
end:
5204
5056
 
5205
5057
  /*
5206
 
    We save the return code (drizzleclient_errno(drizzle)) from the last call sent
5207
 
    to the server into the drizzletest builtin variable $drizzleclient_errno. This
 
5058
    We save the return code (drizzle_errno(drizzle)) from the last call sent
 
5059
    to the server into the drizzletest builtin variable $drizzle_errno. This
5208
5060
    variable then can be used from the test case itself.
5209
5061
  */
5210
 
  drizzle_con_remove_options(con, DRIZZLE_CON_NO_RESULT_READ);
5211
 
  var_set_errno(err);
 
5062
  var_set_errno(drizzle_errno(drizzle));
5212
5063
  return;
5213
5064
}
5214
5065
 
5233
5084
                  unsigned int err_errno, const char *err_error,
5234
5085
                  const char *err_sqlstate, string *ds)
5235
5086
{
5236
 
  uint32_t i;
5237
 
 
5238
 
 
5239
 
  if (! command->require_file.empty())
 
5087
  uint i;
 
5088
 
 
5089
 
 
5090
  if (command->require_file[0])
5240
5091
  {
5241
5092
    /*
5242
5093
      The query after a "--require" failed. This is fine as long the server
5243
5094
      returned a valid reponse. Don't allow 2013 or 2006 to trigger an
5244
5095
      abort_not_supported_test
5245
5096
    */
5246
 
    if (err_errno == DRIZZLE_RETURN_SERVER_GONE)
 
5097
    if (err_errno == CR_SERVER_LOST ||
 
5098
        err_errno == CR_SERVER_GONE_ERROR)
5247
5099
      die("require query '%s' failed: %d: %s", command->query,
5248
5100
          err_errno, err_error);
5249
5101
 
5255
5107
  if (command->abort_on_error)
5256
5108
    die("query '%s' failed: %d: %s", command->query, err_errno, err_error);
5257
5109
 
5258
 
  for (i= 0 ; (uint32_t) i < command->expected_errors.count ; i++)
 
5110
  for (i= 0 ; (uint) i < command->expected_errors.count ; i++)
5259
5111
  {
5260
5112
    if (((command->expected_errors.err[i].type == ERR_ERRNO) &&
5261
5113
         (command->expected_errors.err[i].code.errnum == err_errno)) ||
5262
5114
        ((command->expected_errors.err[i].type == ERR_SQLSTATE) &&
5263
5115
         (strncmp(command->expected_errors.err[i].code.sqlstate,
5264
 
                  err_sqlstate, DRIZZLE_MAX_SQLSTATE_SIZE) == 0)))
 
5116
                  err_sqlstate, SQLSTATE_LENGTH) == 0)))
5265
5117
    {
5266
5118
      if (!disable_result_log)
5267
5119
      {
5395
5247
    Create a temporary dynamic string to contain the output from
5396
5248
    this query.
5397
5249
  */
5398
 
  if (! command->require_file.empty())
 
5250
  if (command->require_file[0])
5399
5251
  {
5400
5252
    ds= &ds_result;
5401
5253
  }
5438
5290
    ds= save_ds;
5439
5291
  }
5440
5292
 
5441
 
  if (! command->require_file.empty())
 
5293
  if (command->require_file[0])
5442
5294
  {
5443
5295
    /* A result file was specified for _this_ query
5444
5296
       and the output should be checked against an already
5456
5308
static void get_command_type(struct st_command* command)
5457
5309
{
5458
5310
  char save;
5459
 
  uint32_t type;
 
5311
  uint type;
5460
5312
 
5461
5313
 
5462
5314
  if (*command->query == '}')
5539
5391
 
5540
5392
*/
5541
5393
 
5542
 
static void mark_progress(struct st_command*, int line)
 
5394
static void mark_progress(struct st_command* command __attribute__((unused)),
 
5395
                          int line)
5543
5396
{
 
5397
  char buf[32], *end;
5544
5398
  uint64_t timer= timer_now();
5545
5399
  if (!progress_start)
5546
5400
    progress_start= timer;
5547
5401
  timer-= progress_start;
5548
5402
 
5549
 
  ostringstream buf;
5550
5403
  /* Milliseconds since start */
5551
 
  buf << timer << "\t";
 
5404
  end= int64_t2str(timer, buf, 10);
 
5405
  ds_progress.append(buf, (int)(end-buf));
 
5406
  ds_progress.append("\t", 1);
5552
5407
 
5553
5408
  /* Parser line number */
5554
 
  buf << line << "\t";
 
5409
  end= int10_to_str(line, buf, 10);
 
5410
  ds_progress.append(buf, (int)(end-buf));
 
5411
  ds_progress.append("\t", 1);
5555
5412
 
5556
5413
  /* Filename */
5557
 
  buf << cur_file->file_name << ":";
 
5414
  ds_progress.append(cur_file->file_name);
 
5415
  ds_progress.append(":", 1);
5558
5416
 
5559
5417
  /* Line in file */
5560
 
  buf << cur_file->lineno << endl;
5561
 
 
5562
 
  ds_progress.append(buf.str());
 
5418
  end= int10_to_str(cur_file->lineno, buf, 10);
 
5419
  ds_progress.append(buf, (int)(end-buf));
 
5420
 
 
5421
 
 
5422
  ds_progress.append("\n", 1);
5563
5423
 
5564
5424
}
5565
5425
 
5568
5428
{
5569
5429
  struct st_command *command;
5570
5430
  bool q_send_flag= 0, abort_flag= 0;
5571
 
  uint32_t command_executed= 0, last_command_executed= 0;
5572
 
  string save_file("");
 
5431
  uint command_executed= 0, last_command_executed= 0;
 
5432
  char save_file[FN_REFLEN];
5573
5433
  struct stat res_info;
5574
5434
  MY_INIT(argv[0]);
5575
5435
 
 
5436
  save_file[0]= 0;
5576
5437
  TMPDIR[0]= 0;
5577
5438
 
5578
5439
  /* Init expected errors */
5598
5459
  cur_block->ok= true; /* Outer block should always be executed */
5599
5460
  cur_block->cmd= cmd_none;
5600
5461
 
5601
 
  var_set_string("$DRIZZLE_SERVER_VERSION", drizzle_version());
 
5462
  if (hash_init(&var_hash, charset_info,
 
5463
                1024, 0, 0, get_var_key, var_free, MYF(0)))
 
5464
    die("Variable hash initialization failed");
 
5465
 
 
5466
  var_set_string("$DRIZZLE_SERVER_VERSION", drizzle_get_client_info());
5602
5467
 
5603
5468
  memset(&master_pos, 0, sizeof(master_pos));
5604
5469
 
5617
5482
  if (cur_file == file_stack && cur_file->file == 0)
5618
5483
  {
5619
5484
    cur_file->file= stdin;
5620
 
    cur_file->file_name= strdup("<stdin>");
5621
 
    if (cur_file->file_name == NULL)
5622
 
      die("Out of memory");
 
5485
    cur_file->file_name= my_strdup("<stdin>", MYF(MY_WME));
5623
5486
    cur_file->lineno= 1;
5624
5487
  }
5625
5488
  cur_con= connections;
5626
 
  if ((cur_con->drizzle= drizzle_create(NULL)) == NULL)
 
5489
  if (!( drizzle_create(&cur_con->drizzle)))
5627
5490
    die("Failed in drizzle_create()");
5628
 
  if (!( drizzle_con_create(cur_con->drizzle, &cur_con->con)))
5629
 
    die("Failed in drizzle_con_create()");
5630
 
  if (opt_mysql)
5631
 
    drizzle_con_add_options(&cur_con->con, DRIZZLE_CON_MYSQL);
 
5491
  if (opt_compress)
 
5492
    drizzle_options(&cur_con->drizzle,DRIZZLE_OPT_COMPRESS,NULL);
 
5493
  drizzle_options(&cur_con->drizzle, DRIZZLE_OPT_LOCAL_INFILE, 0);
5632
5494
 
5633
 
  if (!(cur_con->name = strdup("default")))
 
5495
  if (!(cur_con->name = my_strdup("default", MYF(MY_WME))))
5634
5496
    die("Out of memory");
5635
5497
 
5636
 
  safe_connect(&cur_con->con, cur_con->name, opt_host, opt_user, opt_pass,
 
5498
  safe_connect(&cur_con->drizzle, cur_con->name, opt_host, opt_user, opt_pass,
5637
5499
               opt_db, opt_port);
5638
5500
 
5639
5501
  /* Use all time until exit if no explicit 'start_timer' */
5640
5502
  timer_start= timer_now();
5641
5503
 
5642
5504
  /*
5643
 
    Initialize $drizzleclient_errno with -1, so we can
 
5505
    Initialize $drizzle_errno with -1, so we can
5644
5506
    - distinguish it from valid values ( >= 0 ) and
5645
5507
    - detect if there was never a command sent to the server
5646
5508
  */
5647
5509
  var_set_errno(-1);
5648
5510
 
5649
 
  /* Update $drizzleclient_get_server_version to that of current connection */
5650
 
  var_set_drizzleclient_get_server_version(&cur_con->con);
 
5511
  /* Update $drizzle_get_server_version to that of current connection */
 
5512
  var_set_drizzle_get_server_version(&cur_con->drizzle);
5651
5513
 
5652
5514
  if (opt_include)
5653
5515
  {
5765
5627
        /* Check for special property for this query */
5766
5628
        display_result_vertically|= (command->type == Q_QUERY_VERTICAL);
5767
5629
 
5768
 
        if (! save_file.empty())
 
5630
        if (save_file[0])
5769
5631
        {
5770
 
          command->require_file= save_file;
5771
 
          save_file.clear();
 
5632
          strmake(command->require_file, save_file, sizeof(save_file) - 1);
 
5633
          save_file[0]= 0;
5772
5634
        }
5773
5635
        run_query(cur_con, command, flags);
5774
5636
        command_executed++;
5805
5667
        command->last_argument= command->end;
5806
5668
        break;
5807
5669
      case Q_REQUIRE:
5808
 
        do_get_file_name(command, save_file);
 
5670
        do_get_file_name(command, save_file, sizeof(save_file));
5809
5671
        break;
5810
5672
      case Q_ERROR:
5811
5673
        do_get_errcodes(command);
5835
5697
        command->last_argument= command->end;
5836
5698
        break;
5837
5699
      case Q_PING:
5838
 
        {
5839
 
          drizzle_result_st result;
5840
 
          drizzle_return_t ret;
5841
 
          (void) drizzle_ping(&cur_con->con, &result, &ret);
5842
 
          if (ret == DRIZZLE_RETURN_OK || ret == DRIZZLE_RETURN_ERROR_CODE)
5843
 
            drizzle_result_free(&result);
5844
 
        }
 
5700
        (void) drizzle_ping(&cur_con->drizzle);
5845
5701
        break;
5846
5702
      case Q_EXEC:
5847
5703
        do_exec(command);
5859
5715
        do_set_charset(command);
5860
5716
        break;
5861
5717
      case Q_DISABLE_RECONNECT:
5862
 
        set_reconnect(&cur_con->con, 0);
 
5718
        set_reconnect(&cur_con->drizzle, 0);
5863
5719
        break;
5864
5720
      case Q_ENABLE_RECONNECT:
5865
 
        set_reconnect(&cur_con->con, 1);
 
5721
        set_reconnect(&cur_con->drizzle, 1);
5866
5722
        break;
5867
5723
      case Q_DISABLE_PARSING:
5868
5724
        if (parsing_disabled == 0)
6036
5892
{
6037
5893
  if (timer_file)
6038
5894
  {
6039
 
    ostringstream buf;
 
5895
    char buf[32], *end;
6040
5896
    uint64_t timer= timer_now() - timer_start;
6041
 
    buf << timer;
6042
 
    str_to_file(timer_file,buf.str().c_str(), buf.str().size() );
 
5897
    end= int64_t2str(timer, buf, 10);
 
5898
    str_to_file(timer_file,buf, (int) (end-buf));
6043
5899
    /* Timer has been written to the file, don't use it anymore */
6044
5900
    timer_file= 0;
6045
5901
  }
6048
5904
 
6049
5905
uint64_t timer_now(void)
6050
5906
{
6051
 
#if defined(HAVE_GETHRTIME)
6052
 
  return gethrtime()/1000/1000;
6053
 
#else
6054
 
  uint64_t newtime;
6055
 
  struct timeval t;
6056
 
  /*
6057
 
    The following loop is here because gettimeofday may fail on some systems
6058
 
  */
6059
 
  while (gettimeofday(&t, NULL) != 0)
6060
 
  {}
6061
 
  newtime= (uint64_t)t.tv_sec * 1000000 + t.tv_usec;
6062
 
  return newtime/1000;
6063
 
#endif  /* defined(HAVE_GETHRTIME) */
 
5907
  return my_micro_time() / 1000;
6064
5908
}
6065
5909
 
6066
5910
 
6083
5927
    die("Missing argument in %s", command->query);
6084
5928
 
6085
5929
  /* Allocate a buffer for results */
6086
 
  start= buff= (char *)malloc(strlen(from)+1);
 
5930
  start= buff= (char *)my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE));
6087
5931
  while (*from)
6088
5932
  {
6089
5933
    char *to;
6090
 
    uint32_t column_number;
 
5934
    uint column_number;
6091
5935
 
6092
5936
    to= get_string(&buff, &from, command);
6093
5937
    if (!(column_number= atoi(to)) || column_number > MAX_COLUMNS)
6096
5940
      die("Wrong number of arguments to replace_column in '%s'", command->query);
6097
5941
    to= get_string(&buff, &from, command);
6098
5942
    free(replace_column[column_number-1]);
6099
 
    replace_column[column_number-1]= strdup(to);
6100
 
    if (replace_column[column_number-1] == NULL)
6101
 
      die("Out of memory");
 
5943
    replace_column[column_number-1]= my_strdup(to, MYF(MY_WME | MY_FAE));
6102
5944
    set_if_bigger(max_replace_column, column_number);
6103
5945
  }
6104
5946
  free(start);
6108
5950
 
6109
5951
void free_replace_column()
6110
5952
{
6111
 
  uint32_t i;
 
5953
  uint i;
6112
5954
  for (i=0 ; i < max_replace_column ; i++)
6113
5955
  {
6114
5956
    if (replace_column[i])
6132
5974
  TYPELIB typelib;        /* Pointer to strings */
6133
5975
  unsigned char  *str;          /* Strings is here */
6134
5976
  uint8_t *flag;          /* Flag about each var. */
6135
 
  uint32_t  array_allocs,max_count,length,max_length;
 
5977
  uint  array_allocs,max_count,length,max_length;
6136
5978
} POINTER_ARRAY;
6137
5979
 
6138
5980
struct st_replace;
6139
 
struct st_replace *init_replace(char * *from, char * *to, uint32_t count,
 
5981
struct st_replace *init_replace(char * *from, char * *to, uint count,
6140
5982
                                char * word_end_chars);
6141
5983
int insert_pointer_name(POINTER_ARRAY *pa,char * name);
6142
5984
void replace_strings_append(struct st_replace *rep, string* ds,
6143
5985
                            const char *from, int len);
6144
5986
void free_pointer_array(POINTER_ARRAY *pa);
6145
5987
 
6146
 
struct st_replace *glob_replace= NULL;
 
5988
struct st_replace *glob_replace;
6147
5989
 
6148
5990
/*
6149
5991
  Get arguments for replace. The syntax is:
6155
5997
 
6156
5998
void do_get_replace(struct st_command *command)
6157
5999
{
6158
 
  uint32_t i;
 
6000
  uint i;
6159
6001
  char *from= command->first_argument;
6160
6002
  char *buff, *start;
6161
6003
  char word_end_chars[256], *pos;
6168
6010
  memset(&from_array, 0, sizeof(from_array));
6169
6011
  if (!*from)
6170
6012
    die("Missing argument in %s", command->query);
6171
 
  start= buff= (char *)malloc(strlen(from)+1);
 
6013
  start= buff= (char *)my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE));
6172
6014
  while (*from)
6173
6015
  {
6174
6016
    char *to= buff;
6186
6028
  *pos=0;          /* End pointer */
6187
6029
  if (!(glob_replace= init_replace((char**) from_array.typelib.type_names,
6188
6030
                                   (char**) to_array.typelib.type_names,
6189
 
                                   (uint32_t) from_array.typelib.count,
 
6031
                                   (uint) from_array.typelib.count,
6190
6032
                                   word_end_chars)))
6191
6033
    die("Can't initialize replace from '%s'", command->query);
6192
6034
  free_pointer_array(&from_array);
6217
6059
typedef struct st_replace_found {
6218
6060
  bool found;
6219
6061
  char *replace_string;
6220
 
  uint32_t to_offset;
 
6062
  uint to_offset;
6221
6063
  int from_offset;
6222
6064
} REPLACE_STRING;
6223
6065
 
6275
6117
  char* pattern; /* Pattern to be replaced */
6276
6118
  char* replace; /* String or expression to replace the pattern with */
6277
6119
  int icase; /* true if the match is case insensitive */
6278
 
  int global; /* true if the match should be global -- 
6279
 
                 i.e. repeat the matching until the end of the string */
6280
6120
};
6281
6121
 
6282
6122
struct st_replace_regex
6300
6140
struct st_replace_regex *glob_replace_regex= 0;
6301
6141
 
6302
6142
int reg_replace(char** buf_p, int* buf_len_p, char *pattern, char *replace,
6303
 
                char *string, int icase, int global);
 
6143
                char *string, int icase);
6304
6144
 
6305
6145
 
6306
6146
 
6345
6185
  char* buf,*expr_end;
6346
6186
  char* p;
6347
6187
  char* buf_p;
6348
 
  uint32_t expr_len= strlen(expr);
 
6188
  uint expr_len= strlen(expr);
6349
6189
  char last_c = 0;
6350
6190
  struct st_regex reg;
6351
6191
 
6352
 
  res=(st_replace_regex*)malloc(sizeof(*res)+expr_len);
6353
 
  if (!res)
6354
 
    return NULL;
 
6192
  /* my_malloc() will die on fail with MY_FAE */
 
6193
  res=(struct st_replace_regex*)my_malloc(
 
6194
                                          sizeof(*res)+expr_len ,MYF(MY_FAE+MY_WME));
6355
6195
  my_init_dynamic_array(&res->regex_arr,sizeof(struct st_regex),128,128);
6356
6196
 
6357
6197
  buf= (char*)res + sizeof(*res);
6401
6241
 
6402
6242
    /* Check if we should do matching case insensitive */
6403
6243
    if (p < expr_end && *p == 'i')
6404
 
    {
6405
 
      p++;
6406
6244
      reg.icase= 1;
6407
 
    }
6408
 
 
6409
 
    /* Check if we should do matching globally */
6410
 
    if (p < expr_end && *p == 'g')
6411
 
    {
6412
 
      p++;
6413
 
      reg.global= 1;
6414
 
    }
6415
6245
 
6416
6246
    /* done parsing the statement, now place it in regex_arr */
6417
6247
    if (insert_dynamic(&res->regex_arr,(unsigned char*) &reg))
6418
6248
      die("Out of memory");
6419
6249
  }
6420
6250
  res->odd_buf_len= res->even_buf_len= 8192;
6421
 
  res->even_buf= (char*)malloc(res->even_buf_len);
6422
 
  res->odd_buf= (char*)malloc(res->odd_buf_len);
 
6251
  res->even_buf= (char*)my_malloc(res->even_buf_len,MYF(MY_WME+MY_FAE));
 
6252
  res->odd_buf= (char*)my_malloc(res->odd_buf_len,MYF(MY_WME+MY_FAE));
6423
6253
  res->buf= res->even_buf;
6424
6254
 
6425
6255
  return res;
6451
6281
 
6452
6282
static int multi_reg_replace(struct st_replace_regex* r,char* val)
6453
6283
{
6454
 
  uint32_t i;
 
6284
  uint i;
6455
6285
  char* in_buf, *out_buf;
6456
6286
  int* buf_len_p;
6457
6287
 
6469
6299
    get_dynamic(&r->regex_arr,(unsigned char*)&re,i);
6470
6300
 
6471
6301
    if (!reg_replace(&out_buf, buf_len_p, re.pattern, re.replace,
6472
 
                     in_buf, re.icase, re.global))
 
6302
                     in_buf, re.icase))
6473
6303
    {
6474
6304
      /* if the buffer has been reallocated, make adjustements */
6475
6305
      if (save_out_buf != out_buf)
6539
6369
  icase - flag, if set to 1 the match is case insensitive
6540
6370
*/
6541
6371
int reg_replace(char** buf_p, int* buf_len_p, char *pattern,
6542
 
                char *replace, char *in_string, int icase, int global)
 
6372
                char *replace, char *in_string, int icase)
6543
6373
{
6544
 
  const char *error= NULL;
6545
 
  int erroffset;
6546
 
  int ovector[3];
6547
 
  pcre *re= pcre_compile(pattern,
6548
 
                         icase ? PCRE_CASELESS | PCRE_MULTILINE : PCRE_MULTILINE,
6549
 
                         &error, &erroffset, NULL);
6550
 
  if (re == NULL)
6551
 
    return 1;
6552
 
 
6553
 
  if (! global)
6554
 
  {
6555
 
 
6556
 
    int rc= pcre_exec(re, NULL, in_string, (int)strlen(in_string),
6557
 
                      0, 0, ovector, 3);
6558
 
    if (rc < 0)
6559
 
    {
6560
 
      pcre_free(re);
6561
 
      return 1;
6562
 
    }
6563
 
 
6564
 
    char *substring_to_replace= in_string + ovector[0];
6565
 
    int substring_length= ovector[1] - ovector[0];
6566
 
    *buf_len_p= strlen(in_string) - substring_length + strlen(replace);
6567
 
    char * new_buf = (char *)malloc(*buf_len_p+1);
6568
 
    if (new_buf == NULL)
6569
 
    {
6570
 
      pcre_free(re);
6571
 
      return 1;
6572
 
    }
6573
 
 
6574
 
    memset(new_buf, 0, *buf_len_p+1);
6575
 
    strncpy(new_buf, in_string, substring_to_replace-in_string);
6576
 
    strncpy(new_buf+(substring_to_replace-in_string), replace, strlen(replace));
6577
 
    strncpy(new_buf+(substring_to_replace-in_string)+strlen(replace),
6578
 
            substring_to_replace + substring_length,
6579
 
            strlen(in_string)
6580
 
              - substring_length
6581
 
              - (substring_to_replace-in_string));
6582
 
    *buf_p= new_buf;
6583
 
 
6584
 
    pcre_free(re);
6585
 
    return 0;
6586
 
  }
6587
 
  else
6588
 
  {
6589
 
    /* Repeatedly replace the string with the matched regex */
6590
 
    string subject(in_string);
6591
 
    size_t replace_length= strlen(replace);
6592
 
    size_t current_position= 0;
6593
 
    int rc= 0;
6594
 
    while(0 >= (rc= pcre_exec(re, NULL, subject.c_str() + current_position, subject.length() - current_position,
6595
 
                      0, 0, ovector, 3)))
6596
 
    {
6597
 
      current_position= static_cast<size_t>(ovector[0]);
6598
 
      replace_length= static_cast<size_t>(ovector[1] - ovector[0]);
6599
 
      subject.replace(current_position, replace_length, replace, replace_length);
6600
 
    }
6601
 
 
6602
 
    char *new_buf = (char *) malloc(subject.length() + 1);
6603
 
    if (new_buf == NULL)
6604
 
    {
6605
 
      pcre_free(re);
6606
 
      return 1;
6607
 
    }
6608
 
    memset(new_buf, 0, subject.length() + 1);
6609
 
    strncpy(new_buf, subject.c_str(), subject.length());
6610
 
    *buf_len_p= subject.length() + 1;
6611
 
    *buf_p= new_buf;
6612
 
          
6613
 
    pcre_free(re);
6614
 
    return 0;
6615
 
  }
 
6374
  string string_to_match(in_string);
 
6375
  pcrecpp::RE_Options opt;
 
6376
 
 
6377
  if (icase)
 
6378
    opt.set_caseless(true);
 
6379
 
 
6380
  if (!pcrecpp::RE(pattern, opt).Replace(replace,&string_to_match)){
 
6381
    return 1;
 
6382
  }
 
6383
 
 
6384
  const char * new_str= string_to_match.c_str();
 
6385
  *buf_len_p= strlen(new_str);
 
6386
  char * new_buf = (char *)malloc(*buf_len_p+1);
 
6387
  if (new_buf == NULL)
 
6388
  {
 
6389
    return 1;
 
6390
  }
 
6391
  strcpy(new_buf, new_str);
 
6392
  *buf_p= new_buf;
 
6393
 
 
6394
  return 0;
6616
6395
}
6617
6396
 
6618
6397
 
6619
6398
#ifndef WORD_BIT
6620
 
#define WORD_BIT (8*sizeof(uint32_t))
 
6399
#define WORD_BIT (8*sizeof(uint))
6621
6400
#endif
6622
6401
 
6623
6402
#define SET_MALLOC_HUNC 64
6624
6403
#define LAST_CHAR_CODE 259
6625
6404
 
6626
6405
typedef struct st_rep_set {
6627
 
  uint32_t  *bits;        /* Pointer to used sets */
 
6406
  uint  *bits;        /* Pointer to used sets */
6628
6407
  short next[LAST_CHAR_CODE];    /* Pointer to next sets */
6629
 
  uint32_t  found_len;      /* Best match to date */
 
6408
  uint  found_len;      /* Best match to date */
6630
6409
  int  found_offset;
6631
 
  uint32_t  table_offset;
6632
 
  uint32_t  size_of_bits;      /* For convinience */
 
6410
  uint  table_offset;
 
6411
  uint  size_of_bits;      /* For convinience */
6633
6412
} REP_SET;
6634
6413
 
6635
6414
typedef struct st_rep_sets {
6636
 
  uint32_t    count;      /* Number of sets */
6637
 
  uint32_t    extra;      /* Extra sets in buffer */
6638
 
  uint32_t    invisible;    /* Sets not chown */
6639
 
  uint32_t    size_of_bits;
 
6415
  uint    count;      /* Number of sets */
 
6416
  uint    extra;      /* Extra sets in buffer */
 
6417
  uint    invisible;    /* Sets not chown */
 
6418
  uint    size_of_bits;
6640
6419
  REP_SET  *set,*set_buffer;
6641
 
  uint32_t    *bit_buffer;
 
6420
  uint    *bit_buffer;
6642
6421
} REP_SETS;
6643
6422
 
6644
6423
typedef struct st_found_set {
6645
 
  uint32_t table_offset;
 
6424
  uint table_offset;
6646
6425
  int found_offset;
6647
6426
} FOUND_SET;
6648
6427
 
6649
6428
typedef struct st_follow {
6650
6429
  int chr;
6651
 
  uint32_t table_offset;
6652
 
  uint32_t len;
 
6430
  uint table_offset;
 
6431
  uint len;
6653
6432
} FOLLOWS;
6654
6433
 
6655
6434
 
6656
 
int init_sets(REP_SETS *sets,uint32_t states);
 
6435
int init_sets(REP_SETS *sets,uint states);
6657
6436
REP_SET *make_new_set(REP_SETS *sets);
6658
6437
void make_sets_invisible(REP_SETS *sets);
6659
6438
void free_last_set(REP_SETS *sets);
6660
6439
void free_sets(REP_SETS *sets);
6661
 
void internal_set_bit(REP_SET *set, uint32_t bit);
6662
 
void internal_clear_bit(REP_SET *set, uint32_t bit);
 
6440
void internal_set_bit(REP_SET *set, uint bit);
 
6441
void internal_clear_bit(REP_SET *set, uint bit);
6663
6442
void or_bits(REP_SET *to,REP_SET *from);
6664
6443
void copy_bits(REP_SET *to,REP_SET *from);
6665
6444
int cmp_bits(REP_SET *set1,REP_SET *set2);
6666
 
int get_next_bit(REP_SET *set,uint32_t lastpos);
 
6445
int get_next_bit(REP_SET *set,uint lastpos);
6667
6446
int find_set(REP_SETS *sets,REP_SET *find);
6668
 
int find_found(FOUND_SET *found_set,uint32_t table_offset,
 
6447
int find_found(FOUND_SET *found_set,uint table_offset,
6669
6448
               int found_offset);
6670
 
uint32_t start_at_word(char * pos);
6671
 
uint32_t end_of_word(char * pos);
6672
 
 
6673
 
static uint32_t found_sets=0;
6674
 
 
6675
 
 
6676
 
static uint32_t replace_len(char * str)
 
6449
uint start_at_word(char * pos);
 
6450
uint end_of_word(char * pos);
 
6451
 
 
6452
static uint found_sets=0;
 
6453
 
 
6454
 
 
6455
static uint replace_len(char * str)
6677
6456
{
6678
 
  uint32_t len=0;
 
6457
  uint len=0;
6679
6458
  while (*str)
6680
6459
  {
6681
6460
    if (str[0] == '\\' && str[1])
6688
6467
 
6689
6468
/* Init a replace structure for further calls */
6690
6469
 
6691
 
REPLACE *init_replace(char * *from, char * *to,uint32_t count,
 
6470
REPLACE *init_replace(char * *from, char * *to,uint count,
6692
6471
                      char * word_end_chars)
6693
6472
{
6694
6473
  static const int SPACE_CHAR= 256;
6695
6474
  static const int START_OF_LINE= 257;
6696
6475
  static const int END_OF_LINE= 258;
6697
6476
 
6698
 
  uint32_t i,j,states,set_nr,len,result_len,max_length,found_end,bits_set,bit_nr;
 
6477
  uint i,j,states,set_nr,len,result_len,max_length,found_end,bits_set,bit_nr;
6699
6478
  int used_sets,chr,default_state;
6700
6479
  char used_chars[LAST_CHAR_CODE],is_word_end[256];
6701
6480
  char * pos, *to_pos, **to_array;
6717
6496
      return(0);
6718
6497
    }
6719
6498
    states+=len+1;
6720
 
    result_len+=(uint32_t) strlen(to[i])+1;
 
6499
    result_len+=(uint) strlen(to[i])+1;
6721
6500
    if (len > max_length)
6722
6501
      max_length=len;
6723
6502
  }
6728
6507
  if (init_sets(&sets,states))
6729
6508
    return(0);
6730
6509
  found_sets=0;
6731
 
  if (!(found_set= (FOUND_SET*) malloc(sizeof(FOUND_SET)*max_length*count)))
6732
 
                                
 
6510
  if (!(found_set= (FOUND_SET*) my_malloc(sizeof(FOUND_SET)*max_length*count,
 
6511
                                          MYF(MY_WME))))
6733
6512
  {
6734
6513
    free_sets(&sets);
6735
6514
    return(0);
6739
6518
  used_sets=-1;
6740
6519
  word_states=make_new_set(&sets);    /* Start of new word */
6741
6520
  start_states=make_new_set(&sets);    /* This is first state */
6742
 
  if (!(follow=(FOLLOWS*) malloc((states+2)*sizeof(FOLLOWS))))
 
6521
  if (!(follow=(FOLLOWS*) my_malloc((states+2)*sizeof(FOLLOWS),MYF(MY_WME))))
6743
6522
  {
6744
6523
    free_sets(&sets);
6745
6524
    free(found_set);
6815
6594
    follow_ptr->table_offset=i;
6816
6595
    follow_ptr->len=len;
6817
6596
    follow_ptr++;
6818
 
    states+=(uint32_t) len+1;
 
6597
    states+=(uint) len+1;
6819
6598
  }
6820
6599
 
6821
6600
 
6931
6710
 
6932
6711
  /* Alloc replace structure for the replace-state-machine */
6933
6712
 
6934
 
  if ((replace=(REPLACE*) malloc(sizeof(REPLACE)*(sets.count)+
6935
 
                                 sizeof(REPLACE_STRING)*(found_sets+1)+
6936
 
                                 sizeof(char *)*count+result_len)))
 
6713
  if ((replace=(REPLACE*) my_malloc(sizeof(REPLACE)*(sets.count)+
 
6714
                                    sizeof(REPLACE_STRING)*(found_sets+1)+
 
6715
                                    sizeof(char *)*count+result_len,
 
6716
                                    MYF(MY_WME | MY_ZEROFILL))))
6937
6717
  {
6938
 
    memset(replace, 0, sizeof(REPLACE)*(sets.count)+
6939
 
                       sizeof(REPLACE_STRING)*(found_sets+1)+
6940
 
                       sizeof(char *)*count+result_len);
6941
6718
    rep_str=(REPLACE_STRING*) (replace+sets.count);
6942
6719
    to_array= (char **) (rep_str+found_sets+1);
6943
6720
    to_pos=(char *) (to_array+count);
6944
6721
    for (i=0 ; i < count ; i++)
6945
6722
    {
6946
6723
      to_array[i]=to_pos;
6947
 
      to_pos=strcpy(to_pos,to[i])+strlen(to[i])+1;
 
6724
      to_pos=my_stpcpy(to_pos,to[i])+1;
6948
6725
    }
6949
6726
    rep_str[0].found=1;
6950
6727
    rep_str[0].replace_string=0;
6973
6750
}
6974
6751
 
6975
6752
 
6976
 
int init_sets(REP_SETS *sets,uint32_t states)
 
6753
int init_sets(REP_SETS *sets,uint states)
6977
6754
{
6978
6755
  memset(sets, 0, sizeof(*sets));
6979
6756
  sets->size_of_bits=((states+7)/8);
6980
 
  if (!(sets->set_buffer=(REP_SET*) malloc(sizeof(REP_SET)*SET_MALLOC_HUNC)))
 
6757
  if (!(sets->set_buffer=(REP_SET*) my_malloc(sizeof(REP_SET)*SET_MALLOC_HUNC,
 
6758
                                              MYF(MY_WME))))
6981
6759
    return 1;
6982
 
  if (!(sets->bit_buffer=(uint*) malloc(sizeof(uint32_t)*sets->size_of_bits*
6983
 
                                        SET_MALLOC_HUNC)))
 
6760
  if (!(sets->bit_buffer=(uint*) my_malloc(sizeof(uint)*sets->size_of_bits*
 
6761
                                           SET_MALLOC_HUNC,MYF(MY_WME))))
6984
6762
  {
6985
6763
    free(sets->set);
6986
6764
    return 1;
6999
6777
 
7000
6778
REP_SET *make_new_set(REP_SETS *sets)
7001
6779
{
7002
 
  uint32_t i,count,*bit_buffer;
 
6780
  uint i,count,*bit_buffer;
7003
6781
  REP_SET *set;
7004
6782
  if (sets->extra)
7005
6783
  {
7006
6784
    sets->extra--;
7007
6785
    set=sets->set+ sets->count++;
7008
 
    memset(set->bits, 0, sizeof(uint32_t)*sets->size_of_bits);
 
6786
    memset(set->bits, 0, sizeof(uint)*sets->size_of_bits);
7009
6787
    memset(&set->next[0], 0, sizeof(set->next[0])*LAST_CHAR_CODE);
7010
6788
    set->found_offset=0;
7011
6789
    set->found_len=0;
7014
6792
    return set;
7015
6793
  }
7016
6794
  count=sets->count+sets->invisible+SET_MALLOC_HUNC;
7017
 
  if (!(set=(REP_SET*) realloc((unsigned char*) sets->set_buffer,
7018
 
                                  sizeof(REP_SET)*count)))
 
6795
  if (!(set=(REP_SET*) my_realloc((unsigned char*) sets->set_buffer,
 
6796
                                  sizeof(REP_SET)*count,
 
6797
                                  MYF(MY_WME))))
7019
6798
    return 0;
7020
6799
  sets->set_buffer=set;
7021
6800
  sets->set=set+sets->invisible;
7022
 
  if (!(bit_buffer=(uint*) realloc((unsigned char*) sets->bit_buffer,
7023
 
                                   (sizeof(uint32_t)*sets->size_of_bits)*count)))
 
6801
  if (!(bit_buffer=(uint*) my_realloc((unsigned char*) sets->bit_buffer,
 
6802
                                      (sizeof(uint)*sets->size_of_bits)*count,
 
6803
                                      MYF(MY_WME))))
7024
6804
    return 0;
7025
6805
  sets->bit_buffer=bit_buffer;
7026
6806
  for (i=0 ; i < count ; i++)
7046
6826
  return;
7047
6827
}
7048
6828
 
7049
 
void internal_set_bit(REP_SET *set, uint32_t bit)
 
6829
void internal_set_bit(REP_SET *set, uint bit)
7050
6830
{
7051
6831
  set->bits[bit / WORD_BIT] |= 1 << (bit % WORD_BIT);
7052
6832
  return;
7053
6833
}
7054
6834
 
7055
 
void internal_clear_bit(REP_SET *set, uint32_t bit)
 
6835
void internal_clear_bit(REP_SET *set, uint bit)
7056
6836
{
7057
6837
  set->bits[bit / WORD_BIT] &= ~ (1 << (bit % WORD_BIT));
7058
6838
  return;
7061
6841
 
7062
6842
void or_bits(REP_SET *to,REP_SET *from)
7063
6843
{
7064
 
  register uint32_t i;
 
6844
  register uint i;
7065
6845
  for (i=0 ; i < to->size_of_bits ; i++)
7066
6846
    to->bits[i]|=from->bits[i];
7067
6847
  return;
7070
6850
void copy_bits(REP_SET *to,REP_SET *from)
7071
6851
{
7072
6852
  memcpy(to->bits,from->bits,
7073
 
         (size_t) (sizeof(uint32_t) * to->size_of_bits));
 
6853
         (size_t) (sizeof(uint) * to->size_of_bits));
7074
6854
}
7075
6855
 
7076
6856
int cmp_bits(REP_SET *set1,REP_SET *set2)
7077
6857
{
7078
 
  return memcmp(set1->bits,set2->bits, sizeof(uint32_t) * set1->size_of_bits);
 
6858
  return memcmp(set1->bits,set2->bits, sizeof(uint) * set1->size_of_bits);
7079
6859
}
7080
6860
 
7081
6861
 
7082
6862
/* Get next set bit from set. */
7083
6863
 
7084
 
int get_next_bit(REP_SET *set,uint32_t lastpos)
 
6864
int get_next_bit(REP_SET *set,uint lastpos)
7085
6865
{
7086
 
  uint32_t pos,*start,*end,bits;
 
6866
  uint pos,*start,*end,bits;
7087
6867
 
7088
6868
  start=set->bits+ ((lastpos+1) / WORD_BIT);
7089
6869
  end=set->bits + set->size_of_bits;
7093
6873
    bits=start[0];
7094
6874
  if (!bits)
7095
6875
    return 0;
7096
 
  pos=(uint32_t) (start-set->bits)*WORD_BIT;
 
6876
  pos=(uint) (start-set->bits)*WORD_BIT;
7097
6877
  while (! (bits & 1))
7098
6878
  {
7099
6879
    bits>>=1;
7108
6888
 
7109
6889
int find_set(REP_SETS *sets,REP_SET *find)
7110
6890
{
7111
 
  uint32_t i;
 
6891
  uint i;
7112
6892
  for (i=0 ; i < sets->count-1 ; i++)
7113
6893
  {
7114
6894
    if (!cmp_bits(sets->set+i,find))
7127
6907
   set->next[] == -1 is reserved for end without replaces.
7128
6908
*/
7129
6909
 
7130
 
int find_found(FOUND_SET *found_set,uint32_t table_offset, int found_offset)
 
6910
int find_found(FOUND_SET *found_set,uint table_offset, int found_offset)
7131
6911
{
7132
6912
  int i;
7133
 
  for (i=0 ; (uint32_t) i < found_sets ; i++)
 
6913
  for (i=0 ; (uint) i < found_sets ; i++)
7134
6914
    if (found_set[i].table_offset == table_offset &&
7135
6915
        found_set[i].found_offset == found_offset)
7136
6916
      return -i-2;
7142
6922
 
7143
6923
/* Return 1 if regexp starts with \b or ends with \b*/
7144
6924
 
7145
 
uint32_t start_at_word(char * pos)
 
6925
uint start_at_word(char * pos)
7146
6926
{
7147
6927
  return (((!memcmp(pos, "\\b",2) && pos[2]) ||
7148
6928
           !memcmp(pos, "\\^", 2)) ? 1 : 0);
7149
6929
}
7150
6930
 
7151
 
uint32_t end_of_word(char * pos)
 
6931
uint end_of_word(char * pos)
7152
6932
{
7153
6933
  char * end= strchr(pos, '\0');
7154
6934
  return ((end > pos+2 && !memcmp(end-2, "\\b", 2)) ||
7164
6944
 
7165
6945
int insert_pointer_name(POINTER_ARRAY *pa,char * name)
7166
6946
{
7167
 
  uint32_t i,length,old_count;
 
6947
  uint i,length,old_count;
7168
6948
  unsigned char *new_pos;
7169
6949
  const char **new_array;
7170
6950
 
7172
6952
  if (! pa->typelib.count)
7173
6953
  {
7174
6954
    if (!(pa->typelib.type_names=(const char **)
7175
 
          malloc(((PC_MALLOC-MALLOC_OVERHEAD)/
 
6955
          my_malloc(((PC_MALLOC-MALLOC_OVERHEAD)/
7176
6956
                     (sizeof(char *)+sizeof(*pa->flag))*
7177
 
                     (sizeof(char *)+sizeof(*pa->flag))))))
 
6957
                     (sizeof(char *)+sizeof(*pa->flag))),MYF(MY_WME))))
7178
6958
      return(-1);
7179
 
    if (!(pa->str= (unsigned char*) malloc(PS_MALLOC-MALLOC_OVERHEAD)))
 
6959
    if (!(pa->str= (unsigned char*) my_malloc((uint) (PS_MALLOC-MALLOC_OVERHEAD),
 
6960
                                      MYF(MY_WME))))
7180
6961
    {
7181
6962
      free((char*) pa->typelib.type_names);
7182
6963
      return (-1);
7188
6969
    pa->max_length=PS_MALLOC-MALLOC_OVERHEAD;
7189
6970
    pa->array_allocs=1;
7190
6971
  }
7191
 
  length=(uint32_t) strlen(name)+1;
 
6972
  length=(uint) strlen(name)+1;
7192
6973
  if (pa->length+length >= pa->max_length)
7193
6974
  {
7194
 
    if (!(new_pos= (unsigned char*)realloc((unsigned char*)pa->str,
7195
 
                                           (size_t)(pa->max_length+PS_MALLOC))))
 
6975
    if (!(new_pos= (unsigned char*) my_realloc((unsigned char*) pa->str,
 
6976
                                       (uint) (pa->max_length+PS_MALLOC),
 
6977
                                       MYF(MY_WME))))
7196
6978
      return(1);
7197
6979
    if (new_pos != pa->str)
7198
6980
    {
7199
 
      ptrdiff_t diff= PTR_BYTE_DIFF(new_pos,pa->str);
 
6981
      my_ptrdiff_t diff=PTR_BYTE_DIFF(new_pos,pa->str);
7200
6982
      for (i=0 ; i < pa->typelib.count ; i++)
7201
6983
        pa->typelib.type_names[i]= ADD_TO_PTR(pa->typelib.type_names[i],diff,
7202
6984
                                              char*);
7206
6988
  }
7207
6989
  if (pa->typelib.count >= pa->max_count-1)
7208
6990
  {
7209
 
    size_t len;
 
6991
    int len;
7210
6992
    pa->array_allocs++;
7211
6993
    len=(PC_MALLOC*pa->array_allocs - MALLOC_OVERHEAD);
7212
 
    if (!(new_array=
7213
 
         (const char **)realloc((unsigned char*) pa->typelib.type_names,
7214
 
                                 len/
7215
 
                                  (sizeof(unsigned char*)+sizeof(*pa->flag))*
7216
 
                                  (sizeof(unsigned char*)+sizeof(*pa->flag)))))
 
6994
    if (!(new_array=(const char **) my_realloc((unsigned char*) pa->typelib.type_names,
 
6995
                                               (uint) len/
 
6996
                                               (sizeof(unsigned char*)+sizeof(*pa->flag))*
 
6997
                                               (sizeof(unsigned char*)+sizeof(*pa->flag)),
 
6998
                                               MYF(MY_WME))))
7217
6999
      return(1);
7218
7000
    pa->typelib.type_names=new_array;
7219
7001
    old_count=pa->max_count;
7225
7007
  pa->flag[pa->typelib.count]=0;      /* Reset flag */
7226
7008
  pa->typelib.type_names[pa->typelib.count++]= (char*) pa->str+pa->length;
7227
7009
  pa->typelib.type_names[pa->typelib.count]= NULL;  /* Put end-mark */
7228
 
  strcpy((char*) pa->str+pa->length,name);
 
7010
  my_stpcpy((char*) pa->str+pa->length,name);
7229
7011
  pa->length+=length;
7230
7012
  return(0);
7231
7013
} /* insert_pointer_name */
7281
7063
  replace_append_mem(ds, val, strlen(val));
7282
7064
}
7283
7065
 
7284
 
/* Append uint32_t to ds, with optional replace */
7285
 
void replace_append_uint(string *ds, uint32_t val)
 
7066
/* Append uint to ds, with optional replace */
 
7067
void replace_append_uint(string *ds, uint val)
7286
7068
{
7287
 
  ostringstream buff;
7288
 
  buff << val;
7289
 
  replace_append_mem(ds, buff.str().c_str(), buff.str().size());
 
7069
  char buff[22]; /* This should be enough for any int */
 
7070
  char *end= int64_t10_to_str(val, buff, 10);
 
7071
  replace_append_mem(ds, buff, end - buff);
7290
7072
 
7291
7073
}
7292
7074