~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzletest.cc

  • Committer: Monty Taylor
  • Date: 2008-10-10 23:04:21 UTC
  • mto: (509.1.1 codestyle)
  • mto: This revision was merged to the branch mainline in revision 511.
  • Revision ID: monty@inaugust.com-20081010230421-zohe1eppxievpw8d
Removed O_NOFOLLOW

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 * 
4
 
 *  Copyright (C) 2010 Vijay Samuel
 
3
 *
5
4
 *  Copyright (C) 2008 MySQL
6
5
 *
7
6
 *  This program is free software; you can redistribute it and/or modify
39
38
 
40
39
#define MTEST_VERSION "3.3"
41
40
 
 
41
#include "config.h"
42
42
#include "client_priv.h"
43
43
 
44
44
#include <queue>
45
45
#include <map>
46
46
#include <string>
47
 
#include <sstream>
48
 
#include <fstream>
49
 
#include <iostream>
50
47
#include <vector>
51
 
#include <algorithm>
52
 
#ifdef HAVE_SYS_WAIT_H
53
 
#include <sys/wait.h>
54
 
#endif
55
 
#include <cassert>
56
 
#include <sys/stat.h>
57
 
#include <sys/types.h>
58
 
#include <fcntl.h>
59
 
#include <boost/program_options.hpp>
60
 
 
61
 
#include PCRE_HEADER
62
 
 
 
48
 
 
49
#include <pcrecpp.h>
 
50
 
 
51
#include <mysys/hash.h>
63
52
#include <stdarg.h>
64
 
#include <boost/unordered_map.hpp>
65
53
 
66
54
#include "errname.h"
67
55
 
68
 
/* Added this for string translation. */
69
 
#include "drizzled/gettext.h"
70
 
#include "drizzled/drizzle_time.h"
71
 
#include "drizzled/charset.h"
72
 
#include <drizzled/configmake.h>
73
 
 
74
 
#ifndef DRIZZLE_RETURN_SERVER_GONE
75
 
#define DRIZZLE_RETURN_HANDSHAKE_FAILED DRIZZLE_RETURN_ERROR_CODE
76
 
#endif
77
 
namespace po= boost::program_options;
78
56
using namespace std;
79
 
using namespace drizzled;
80
 
 
81
 
extern "C"
82
 
unsigned char *get_var_key(const unsigned char* var, size_t *len, bool);
83
 
 
84
 
int get_one_option(int optid, const struct option *, char *argument);
85
57
 
86
58
#define MAX_VAR_NAME_LENGTH    256
87
59
#define MAX_COLUMNS            256
 
60
#define MAX_EMBEDDED_SERVER_ARGS 64
88
61
#define MAX_DELIMITER_LENGTH 16
 
62
 
89
63
/* Flags controlling send and reap */
90
64
#define QUERY_SEND_FLAG  1
91
65
#define QUERY_REAP_FLAG  2
92
66
 
93
 
ErrorCodes global_error_names;
94
 
 
95
67
enum {
96
68
  OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL,
97
 
  OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES,
98
 
  OPT_TESTDIR
 
69
  OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES
99
70
};
100
71
 
101
72
static int record= 0, opt_sleep= -1;
102
 
static char *opt_pass= NULL;
103
 
const char *unix_sock= NULL;
104
 
static uint32_t opt_port= 0;
105
 
static uint32_t opt_max_connect_retries;
106
 
static bool silent= false, verbose= false;
107
 
static bool opt_mark_progress= false;
108
 
static bool parsing_disabled= false;
 
73
static char *opt_db= 0, *opt_pass= 0;
 
74
const char *opt_user= 0, *opt_host= 0, *unix_sock= 0, *opt_basedir= "./";
 
75
const char *opt_logdir= "";
 
76
const char *opt_include= 0, *opt_charsets_dir;
 
77
static int opt_port= 0;
 
78
static int opt_max_connect_retries;
 
79
static bool opt_compress= 0, silent= 0, verbose= 0;
 
80
static bool debug_info_flag= 0, debug_check_flag= 0;
 
81
static bool tty_password= 0;
 
82
static bool opt_mark_progress= 0;
 
83
static bool parsing_disabled= 0;
109
84
static bool display_result_vertically= false,
110
85
  display_metadata= false, display_result_sorted= false;
111
 
static bool disable_query_log= false, disable_result_log= false;
112
 
static bool disable_warnings= false;
113
 
static bool disable_info= true;
114
 
static bool abort_on_error= true;
115
 
static bool server_initialized= false;
116
 
static bool is_windows= false;
117
 
static bool use_drizzle_protocol= false;
 
86
static bool disable_query_log= 0, disable_result_log= 0;
 
87
static bool disable_warnings= 0;
 
88
static bool disable_info= 1;
 
89
static bool abort_on_error= 1;
 
90
static bool server_initialized= 0;
 
91
static bool is_windows= 0;
 
92
static char **default_argv;
 
93
static const char *load_default_groups[]= { "drizzletest", "client", 0 };
118
94
static char line_buffer[MAX_DELIMITER_LENGTH], *line_buffer_pos= line_buffer;
119
95
 
120
 
std::string opt_basedir,
121
 
  opt_charsets_dir,
122
 
  opt_db,
123
 
  opt_host,
124
 
  opt_include,
125
 
  opt_testdir,
126
 
  opt_logdir,
127
 
  password,
128
 
  opt_password,
129
 
  result_file_name,
130
 
  opt_user,
131
 
  opt_protocol;
132
 
 
133
 
static uint32_t start_lineno= 0; /* Start line of current command */
 
96
static uint start_lineno= 0; /* Start line of current command */
 
97
static uint my_end_arg= 0;
134
98
 
135
99
/* Number of lines of the result to include in failure report */
136
 
static uint32_t opt_tail_lines= 0;
 
100
static uint opt_tail_lines= 0;
137
101
 
138
102
static char delimiter[MAX_DELIMITER_LENGTH]= ";";
139
 
static uint32_t delimiter_length= 1;
 
103
static uint delimiter_length= 1;
140
104
 
141
105
static char TMPDIR[FN_REFLEN];
142
106
 
162
126
{
163
127
  FILE* file;
164
128
  const char *file_name;
165
 
  uint32_t lineno; /* Current line in file */
 
129
  uint lineno; /* Current line in file */
166
130
};
167
131
 
168
132
static struct st_test_file file_stack[16];
172
136
 
173
137
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci; /* Default charset */
174
138
 
 
139
static int embedded_server_arg_count=0;
 
140
static char *embedded_server_args[MAX_EMBEDDED_SERVER_ARGS];
 
141
 
175
142
/*
176
143
  Timer related variables
177
144
  See the timer_output() definition for details
199
166
master_pos_st master_pos;
200
167
 
201
168
/* if set, all results are concated and compared against this file */
 
169
const char *result_file_name= 0;
202
170
 
203
171
typedef struct st_var
204
172
{
216
184
/*Perl/shell-like variable registers */
217
185
VAR var_reg[10];
218
186
 
219
 
 
220
 
boost::unordered_map<string, VAR *> var_hash;
 
187
HASH var_hash;
221
188
 
222
189
struct st_connection
223
190
{
224
 
  drizzle_st *drizzle;
225
 
  drizzle_con_st con;
 
191
  DRIZZLE drizzle;
226
192
  /* Used when creating views and sp, to avoid implicit commit */
227
 
  drizzle_con_st *util_con;
 
193
  DRIZZLE *util_drizzle;
228
194
  char *name;
229
195
};
230
196
struct st_connection connections[128];
380
346
  enum match_err_type type;
381
347
  union
382
348
  {
383
 
    uint32_t errnum;
384
 
    char sqlstate[DRIZZLE_MAX_SQLSTATE_SIZE+1];  /* \0 terminated string */
 
349
    uint errnum;
 
350
    char sqlstate[SQLSTATE_LENGTH+1];  /* \0 terminated string */
385
351
  } code;
386
352
};
387
353
 
388
354
struct st_expected_errors
389
355
{
390
356
  struct st_match_err err[10];
391
 
  uint32_t count;
 
357
  uint count;
392
358
};
393
359
static struct st_expected_errors saved_expected_errors;
394
360
 
397
363
  char *query, *query_buf,*first_argument,*last_argument,*end;
398
364
  int first_word_len, query_len;
399
365
  bool abort_on_error;
400
 
  st_expected_errors expected_errors;
401
 
  string require_file;
 
366
  struct st_expected_errors expected_errors;
 
367
  char require_file[FN_REFLEN];
402
368
  enum enum_commands type;
403
 
 
404
 
  st_command()
405
 
    : query(NULL), query_buf(NULL), first_argument(NULL), last_argument(NULL),
406
 
      end(NULL), first_word_len(0), query_len(0), abort_on_error(false),
407
 
      require_file(""), type(Q_CONNECTION)
408
 
  {
409
 
    memset(&expected_errors, 0, sizeof(st_expected_errors));
410
 
  }
411
 
 
412
 
  ~st_command()
413
 
  {
414
 
    if (query_buf != NULL)
415
 
    {
416
 
      free(query_buf);
417
 
    }
418
 
  }
419
369
};
420
370
 
421
371
TYPELIB command_typelib= {array_elements(command_names),"",
439
389
VAR* var_from_env(const char *, const char *);
440
390
VAR* var_init(VAR* v, const char *name, int name_len, const char *val,
441
391
              int val_len);
442
 
void var_free(pair<string, VAR*> v);
 
392
void var_free(void* v);
443
393
VAR* var_get(const char *var_name, const char** var_name_end,
444
394
             bool raw, bool ignore_not_existing);
445
395
void eval_expr(VAR* v, const char *p, const char** p_end);
446
 
bool match_delimiter(int c, const char *delim, uint32_t length);
 
396
bool match_delimiter(int c, const char *delim, uint length);
447
397
void dump_result_to_reject_file(char *buf, int size);
448
398
void dump_result_to_log_file(const char *buf, int size);
449
399
void dump_warning_messages(void);
456
406
 
457
407
/* For replace_column */
458
408
static char *replace_column[MAX_COLUMNS];
459
 
static uint32_t max_replace_column= 0;
 
409
static uint max_replace_column= 0;
460
410
void do_get_replace_column(struct st_command*);
461
411
void free_replace_column(void);
462
412
 
481
431
void replace_append_mem(string *ds, const char *val,
482
432
                        int len);
483
433
void replace_append(string *ds, const char *val);
484
 
void replace_append_uint(string *ds, uint32_t val);
 
434
void replace_append_uint(string *ds, uint val);
485
435
void append_sorted(string* ds, string* ds_input);
486
436
 
487
437
void handle_error(struct st_command*,
490
440
void handle_no_error(struct st_command*);
491
441
 
492
442
 
 
443
#define do_send_query(cn,q,q_len,flags) drizzle_send_query(&cn->drizzle, q, q_len)
 
444
 
493
445
void do_eval(string *query_eval, const char *query,
494
446
             const char *query_end, bool pass_through_escape_chars)
495
447
{
560
512
  options are passed.
561
513
*/
562
514
 
563
 
static void append_os_quoted(string *str, const char *append, ...)
 
515
void append_os_quoted(string *str, const char *append, ...)
564
516
{
565
517
  const char *quote_str= "\'";
566
 
  const uint32_t  quote_len= 1;
 
518
  const uint  quote_len= 1;
567
519
 
568
520
  va_list dirty_text;
569
521
 
603
555
 
604
556
*/
605
557
 
606
 
static void show_query(drizzle_con_st *con, const char* query)
 
558
static void show_query(DRIZZLE *drizzle, const char* query)
607
559
{
608
 
  drizzle_result_st res;
609
 
  drizzle_return_t ret;
610
 
 
611
 
  if (!con)
 
560
  DRIZZLE_RES* res;
 
561
 
 
562
 
 
563
  if (!drizzle)
612
564
    return;
613
565
 
614
 
  if (drizzle_query_str(con, &res, query, &ret) == NULL ||
615
 
      ret != DRIZZLE_RETURN_OK)
 
566
  if (drizzle_query(drizzle, query))
616
567
  {
617
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
618
 
    {
619
 
      log_msg("Error running query '%s': %d %s",
620
 
              query, drizzle_result_error_code(&res),
621
 
              drizzle_result_error(&res));
622
 
      drizzle_result_free(&res);
623
 
    }
624
 
    else
625
 
    {
626
 
      log_msg("Error running query '%s': %d %s",
627
 
              query, ret, drizzle_con_error(con));
628
 
    }
 
568
    log_msg("Error running query '%s': %d %s",
 
569
            query, drizzle_errno(drizzle), drizzle_error(drizzle));
629
570
    return;
630
571
  }
631
572
 
632
 
  if (drizzle_result_column_count(&res) == 0 ||
633
 
      drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
 
573
  if ((res= drizzle_store_result(drizzle)) == NULL)
634
574
  {
635
575
    /* No result set returned */
636
 
    drizzle_result_free(&res);
637
576
    return;
638
577
  }
639
578
 
640
579
  {
641
 
    drizzle_row_t row;
 
580
    DRIZZLE_ROW row;
642
581
    unsigned int i;
643
582
    unsigned int row_num= 0;
644
 
    unsigned int num_fields= drizzle_result_column_count(&res);
645
 
    drizzle_column_st *column;
 
583
    unsigned int num_fields= drizzle_num_fields(res);
 
584
    const DRIZZLE_FIELD *fields= drizzle_fetch_fields(res);
646
585
 
647
586
    fprintf(stderr, "=== %s ===\n", query);
648
 
    while ((row= drizzle_row_next(&res)))
 
587
    while ((row= drizzle_fetch_row(res)))
649
588
    {
650
 
      size_t *lengths= drizzle_row_field_sizes(&res);
 
589
      uint32_t *lengths= drizzle_fetch_lengths(res);
651
590
      row_num++;
652
591
 
653
592
      fprintf(stderr, "---- %d. ----\n", row_num);
654
 
      drizzle_column_seek(&res, 0);
655
593
      for(i= 0; i < num_fields; i++)
656
594
      {
657
 
        column= drizzle_column_next(&res);
658
595
        fprintf(stderr, "%s\t%.*s\n",
659
 
                drizzle_column_name(column),
 
596
                fields[i].name,
660
597
                (int)lengths[i], row[i] ? row[i] : "NULL");
661
598
      }
662
599
    }
664
601
      fprintf(stderr, "=");
665
602
    fprintf(stderr, "\n\n");
666
603
  }
667
 
  drizzle_result_free(&res);
 
604
  drizzle_free_result(res);
668
605
 
669
606
  return;
670
607
}
683
620
 
684
621
*/
685
622
 
686
 
static void show_warnings_before_error(drizzle_con_st *con)
 
623
static void show_warnings_before_error(DRIZZLE *drizzle)
687
624
{
688
 
  drizzle_result_st res;
689
 
  drizzle_return_t ret;
 
625
  DRIZZLE_RES* res;
690
626
  const char* query= "SHOW WARNINGS";
691
627
 
692
 
  if (!con)
 
628
 
 
629
  if (!drizzle)
693
630
    return;
694
631
 
695
 
  if (drizzle_query_str(con, &res, query, &ret) == NULL ||
696
 
      ret != DRIZZLE_RETURN_OK)
 
632
  if (drizzle_query(drizzle, query))
697
633
  {
698
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
699
 
    {
700
 
      log_msg("Error running query '%s': %d %s",
701
 
              query, drizzle_result_error_code(&res),
702
 
              drizzle_result_error(&res));
703
 
      drizzle_result_free(&res);
704
 
    }
705
 
    else
706
 
    {
707
 
      log_msg("Error running query '%s': %d %s",
708
 
              query, ret, drizzle_con_error(con));
709
 
    }
 
634
    log_msg("Error running query '%s': %d %s",
 
635
            query, drizzle_errno(drizzle), drizzle_error(drizzle));
710
636
    return;
711
637
  }
712
638
 
713
 
  if (drizzle_result_column_count(&res) == 0 ||
714
 
      drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
 
639
  if ((res= drizzle_store_result(drizzle)) == NULL)
715
640
  {
716
641
    /* No result set returned */
717
 
    drizzle_result_free(&res);
718
642
    return;
719
643
  }
720
644
 
721
 
  if (drizzle_result_row_count(&res) <= 1)
 
645
  if (drizzle_num_rows(res) <= 1)
722
646
  {
723
647
    /* Don't display the last row, it's "last error" */
724
648
  }
725
649
  else
726
650
  {
727
 
    drizzle_row_t row;
 
651
    DRIZZLE_ROW row;
728
652
    unsigned int row_num= 0;
729
 
    unsigned int num_fields= drizzle_result_column_count(&res);
 
653
    unsigned int num_fields= drizzle_num_fields(res);
730
654
 
731
655
    fprintf(stderr, "\nWarnings from just before the error:\n");
732
 
    while ((row= drizzle_row_next(&res)))
 
656
    while ((row= drizzle_fetch_row(res)))
733
657
    {
734
658
      uint32_t i;
735
 
      size_t *lengths= drizzle_row_field_sizes(&res);
 
659
      uint32_t *lengths= drizzle_fetch_lengths(res);
736
660
 
737
 
      if (++row_num >= drizzle_result_row_count(&res))
 
661
      if (++row_num >= drizzle_num_rows(res))
738
662
      {
739
663
        /* Don't display the last row, it's "last error" */
740
664
        break;
748
672
      fprintf(stderr, "\n");
749
673
    }
750
674
  }
751
 
  drizzle_result_free(&res);
 
675
  drizzle_free_result(res);
752
676
 
753
677
  return;
754
678
}
781
705
  for (i= 0; i < num_args; i++)
782
706
  {
783
707
    const struct command_arg *arg= &args[i];
784
 
    arg->ds->clear();
785
708
 
786
709
    switch (arg->type) {
787
710
      /* A string */
840
763
}
841
764
 
842
765
 
843
 
static void handle_command_error(struct st_command *command, uint32_t error)
 
766
static void handle_command_error(struct st_command *command, uint error)
844
767
{
845
768
 
846
769
  if (error != 0)
847
770
  {
848
 
    uint32_t i;
 
771
    uint i;
849
772
 
850
773
    if (command->abort_on_error)
851
774
      die("command \"%.*s\" failed with error %d",
875
798
 
876
799
static void close_connections(void)
877
800
{
 
801
 
878
802
  for (--next_con; next_con >= connections; --next_con)
879
803
  {
880
 
    if (next_con->drizzle != NULL)
881
 
    {
882
 
      drizzle_free(next_con->drizzle);
883
 
      next_con->drizzle= NULL;
884
 
    }
 
804
    drizzle_close(&next_con->drizzle);
 
805
    if (next_con->util_drizzle)
 
806
      drizzle_close(next_con->util_drizzle);
885
807
    free(next_con->name);
886
808
  }
887
809
  return;
895
817
  {
896
818
    if (cur_file->file && cur_file->file != stdin)
897
819
    {
898
 
      fclose(cur_file->file);
 
820
      my_fclose(cur_file->file, MYF(0));
899
821
    }
900
822
    free((unsigned char*) cur_file->file_name);
901
823
    cur_file->file_name= 0;
906
828
 
907
829
static void free_used_memory(void)
908
830
{
909
 
  uint32_t i;
 
831
  uint i;
910
832
 
911
833
 
912
834
  close_connections();
913
835
  close_files();
914
 
  for_each(var_hash.begin(), var_hash.end(), var_free);
915
 
  var_hash.clear();
 
836
  hash_free(&var_hash);
916
837
 
917
 
  vector<st_command *>::iterator iter;
 
838
  vector<struct st_command *>::iterator iter;
918
839
  for (iter= q_lines.begin() ; iter < q_lines.end() ; iter++)
919
840
  {
920
 
    struct st_command * q_line= *iter;
921
 
    delete q_line;
 
841
    struct st_command * q_line= *(iter.base());
 
842
    if (q_line->query_buf != NULL)
 
843
    {
 
844
      free(q_line->query_buf);
 
845
    }
 
846
    free(q_line);
922
847
  }
923
848
 
924
849
  for (i= 0; i < 10; i++)
926
851
    if (var_reg[i].alloced_len)
927
852
      free(var_reg[i].str_val);
928
853
  }
 
854
  while (embedded_server_arg_count > 1)
 
855
    free(embedded_server_args[--embedded_server_arg_count]);
929
856
 
930
857
  free_all_replace();
931
858
  free(opt_pass);
 
859
  free_defaults(default_argv);
932
860
 
933
861
  return;
934
862
}
937
865
static void cleanup_and_exit(int exit_code)
938
866
{
939
867
  free_used_memory();
940
 
  internal::my_end();
 
868
  my_end(my_end_arg);
941
869
 
942
870
  if (!silent) {
943
871
    switch (exit_code) {
1010
938
  }
1011
939
 
1012
940
  /* Dump the result that has been accumulated so far to .log file */
1013
 
  if (! result_file_name.empty() && ds_res.length())
 
941
  if (result_file_name && ds_res.length())
1014
942
    dump_result_to_log_file(ds_res.c_str(), ds_res.length());
1015
943
 
1016
944
  /* Dump warning messages */
1017
 
  if (! result_file_name.empty() && ds_warning_messages.length())
 
945
  if (result_file_name && ds_warning_messages.length())
1018
946
    dump_warning_messages();
1019
947
 
1020
948
  /*
1022
950
    been produced prior to the error
1023
951
  */
1024
952
  if (cur_con)
1025
 
    show_warnings_before_error(&cur_con->con);
 
953
    show_warnings_before_error(&cur_con->drizzle);
1026
954
 
1027
955
  cleanup_and_exit(1);
1028
956
}
1147
1075
static void cat_file(string* ds, const char* filename)
1148
1076
{
1149
1077
  int fd;
1150
 
  uint32_t len;
 
1078
  uint len;
1151
1079
  char buff[512];
1152
1080
 
1153
 
  if ((fd= internal::my_open(filename, O_RDONLY, MYF(0))) < 0)
 
1081
  if ((fd= my_open(filename, O_RDONLY, MYF(0))) < 0)
1154
1082
    die("Failed to open file '%s'", filename);
1155
 
  while((len= internal::my_read(fd, (unsigned char*)&buff,
 
1083
  while((len= my_read(fd, (unsigned char*)&buff,
1156
1084
                      sizeof(buff), MYF(0))) > 0)
1157
1085
  {
1158
1086
    char *p= buff, *start= buff;
1174
1102
    /* Output any chars that might be left */
1175
1103
    ds->append(start, p-start);
1176
1104
  }
1177
 
  internal::my_close(fd, MYF(0));
 
1105
  my_close(fd, MYF(0));
1178
1106
}
1179
1107
 
1180
1108
 
1279
1207
               "2>&1",
1280
1208
               NULL) > 1) /* Most "diff" tools return >1 if error */
1281
1209
  {
 
1210
    ds_tmp= "";
1282
1211
 
1283
1212
    /* Fallback to context diff with "diff -c" */
1284
1213
    if (run_tool("diff",
1293
1222
        Fallback to dump both files to result file and inform
1294
1223
        about installing "diff"
1295
1224
      */
1296
 
      ds_tmp.clear();
 
1225
      ds_tmp= "";
1297
1226
 
1298
1227
      ds_tmp.append(
1299
1228
                    "\n"
1350
1279
 
1351
1280
*/
1352
1281
 
1353
 
static int compare_files2(int fd, const char* filename2)
 
1282
static int compare_files2(File fd, const char* filename2)
1354
1283
{
1355
1284
  int error= RESULT_OK;
1356
 
  int fd2;
1357
 
  uint32_t len, len2;
 
1285
  File fd2;
 
1286
  uint len, len2;
1358
1287
  char buff[512], buff2[512];
1359
 
  const char *fname= filename2;
1360
 
  string tmpfile;
1361
1288
 
1362
 
  if ((fd2= internal::my_open(fname, O_RDONLY, MYF(0))) < 0)
 
1289
  if ((fd2= my_open(filename2, O_RDONLY, MYF(0))) < 0)
1363
1290
  {
1364
 
    internal::my_close(fd, MYF(0));
1365
 
    if (! opt_testdir.empty())
1366
 
    {
1367
 
      tmpfile= opt_testdir;
1368
 
      if (tmpfile[tmpfile.length()] != '/')
1369
 
        tmpfile.append("/");
1370
 
      tmpfile.append(filename2);
1371
 
      fname= tmpfile.c_str();
1372
 
    }
1373
 
    if ((fd2= internal::my_open(fname, O_RDONLY, MYF(0))) < 0)
1374
 
    {
1375
 
      internal::my_close(fd, MYF(0));
1376
 
    
1377
 
      die("Failed to open second file: '%s'", fname);
1378
 
    }
 
1291
    my_close(fd, MYF(0));
 
1292
    die("Failed to open second file: '%s'", filename2);
1379
1293
  }
1380
 
  while((len= internal::my_read(fd, (unsigned char*)&buff,
 
1294
  while((len= my_read(fd, (unsigned char*)&buff,
1381
1295
                      sizeof(buff), MYF(0))) > 0)
1382
1296
  {
1383
 
    if ((len2= internal::my_read(fd2, (unsigned char*)&buff2,
 
1297
    if ((len2= my_read(fd2, (unsigned char*)&buff2,
1384
1298
                       sizeof(buff2), MYF(0))) < len)
1385
1299
    {
1386
1300
      /* File 2 was smaller */
1400
1314
      break;
1401
1315
    }
1402
1316
  }
1403
 
  if (!error && internal::my_read(fd2, (unsigned char*)&buff2,
 
1317
  if (!error && my_read(fd2, (unsigned char*)&buff2,
1404
1318
                        sizeof(buff2), MYF(0)) > 0)
1405
1319
  {
1406
1320
    /* File 1 was smaller */
1407
1321
    error= RESULT_LENGTH_MISMATCH;
1408
1322
  }
1409
1323
 
1410
 
  internal::my_close(fd2, MYF(0));
 
1324
  my_close(fd2, MYF(0));
1411
1325
 
1412
1326
  return error;
1413
1327
}
1428
1342
 
1429
1343
static int compare_files(const char* filename1, const char* filename2)
1430
1344
{
1431
 
  int fd;
 
1345
  File fd;
1432
1346
  int error;
1433
1347
 
1434
 
  if ((fd= internal::my_open(filename1, O_RDONLY, MYF(0))) < 0)
 
1348
  if ((fd= my_open(filename1, O_RDONLY, MYF(0))) < 0)
1435
1349
    die("Failed to open first file: '%s'", filename1);
1436
1350
 
1437
1351
  error= compare_files2(fd, filename2);
1438
1352
 
1439
 
  internal::my_close(fd, MYF(0));
 
1353
  my_close(fd, MYF(0));
1440
1354
 
1441
1355
  return error;
1442
1356
}
1457
1371
static int string_cmp(string* ds, const char *fname)
1458
1372
{
1459
1373
  int error;
1460
 
  int fd;
 
1374
  File fd;
1461
1375
  char temp_file_path[FN_REFLEN];
1462
1376
 
1463
 
  if ((fd= internal::create_temp_file(temp_file_path, NULL,
1464
 
                            "tmp", MYF(MY_WME))) < 0)
 
1377
  if ((fd= create_temp_file(temp_file_path, NULL,
 
1378
                            "tmp", O_CREAT | O_RDWR,
 
1379
                            MYF(MY_WME))) < 0)
1465
1380
    die("Failed to create temporary file for ds");
1466
1381
 
1467
1382
  /* Write ds to temporary file and set file pos to beginning*/
1468
 
  if (internal::my_write(fd, (unsigned char *) ds->c_str(), ds->length(),
 
1383
  if (my_write(fd, (unsigned char *) ds->c_str(), ds->length(),
1469
1384
               MYF(MY_FNABP | MY_WME)) ||
1470
 
      lseek(fd, 0, SEEK_SET) == MY_FILEPOS_ERROR)
 
1385
      my_seek(fd, 0, SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR)
1471
1386
  {
1472
 
    internal::my_close(fd, MYF(0));
 
1387
    my_close(fd, MYF(0));
1473
1388
    /* Remove the temporary file */
1474
 
    internal::my_delete(temp_file_path, MYF(0));
 
1389
    my_delete(temp_file_path, MYF(0));
1475
1390
    die("Failed to write file '%s'", temp_file_path);
1476
1391
  }
1477
1392
 
1478
1393
  error= compare_files2(fd, fname);
1479
1394
 
1480
 
  internal::my_close(fd, MYF(0));
 
1395
  my_close(fd, MYF(0));
1481
1396
  /* Remove the temporary file */
1482
 
  internal::my_delete(temp_file_path, MYF(0));
 
1397
  my_delete(temp_file_path, MYF(0));
1483
1398
 
1484
1399
  return(error);
1485
1400
}
1502
1417
  const char* mess= "Result content mismatch\n";
1503
1418
 
1504
1419
 
1505
 
  assert(result_file_name.c_str());
1506
 
 
1507
 
  if (access(result_file_name.c_str(), F_OK) != 0)
1508
 
    die("The specified result file does not exist: '%s'", result_file_name.c_str());
1509
 
 
1510
 
  switch (string_cmp(ds, result_file_name.c_str())) {
 
1420
  assert(result_file_name);
 
1421
 
 
1422
  if (access(result_file_name, F_OK) != 0)
 
1423
    die("The specified result file does not exist: '%s'", result_file_name);
 
1424
 
 
1425
  switch (string_cmp(ds, result_file_name)) {
1511
1426
  case RESULT_OK:
1512
1427
    break; /* ok */
1513
1428
  case RESULT_LENGTH_MISMATCH:
1521
1436
    */
1522
1437
    char reject_file[FN_REFLEN];
1523
1438
    size_t reject_length;
1524
 
    internal::dirname_part(reject_file, result_file_name.c_str(), &reject_length);
 
1439
    dirname_part(reject_file, result_file_name, &reject_length);
1525
1440
 
1526
1441
    if (access(reject_file, W_OK) == 0)
1527
1442
    {
1528
1443
      /* Result file directory is writable, save reject file there */
1529
 
      internal::fn_format(reject_file, result_file_name.c_str(), NULL,
 
1444
      fn_format(reject_file, result_file_name, NULL,
1530
1445
                ".reject", MY_REPLACE_EXT);
1531
1446
    }
1532
1447
    else
1533
1448
    {
1534
1449
      /* Put reject file in opt_logdir */
1535
 
      internal::fn_format(reject_file, result_file_name.c_str(), opt_logdir.c_str(),
 
1450
      fn_format(reject_file, result_file_name, opt_logdir,
1536
1451
                ".reject", MY_REPLACE_DIR | MY_REPLACE_EXT);
1537
1452
    }
1538
1453
    str_to_file(reject_file, ds->c_str(), ds->length());
1539
1454
 
1540
1455
    ds->erase(); /* Don't create a .log file */
1541
1456
 
1542
 
    show_diff(NULL, result_file_name.c_str(), reject_file);
1543
 
    die("%s",mess);
 
1457
    show_diff(NULL, result_file_name, reject_file);
 
1458
    die(mess);
1544
1459
    break;
1545
1460
  }
1546
1461
  default: /* impossible */
1566
1481
 
1567
1482
*/
1568
1483
 
1569
 
static void check_require(string* ds, const string &fname)
 
1484
static void check_require(string* ds, const char *fname)
1570
1485
{
1571
1486
 
1572
1487
 
1573
 
  if (string_cmp(ds, fname.c_str()))
 
1488
  if (string_cmp(ds, fname))
1574
1489
  {
1575
1490
    char reason[FN_REFLEN];
1576
 
    internal::fn_format(reason, fname.c_str(), "", "", MY_REPLACE_EXT | MY_REPLACE_DIR);
 
1491
    fn_format(reason, fname, "", "", MY_REPLACE_EXT | MY_REPLACE_DIR);
1577
1492
    abort_not_supported_test("Test requires: '%s'", reason);
1578
1493
  }
1579
1494
  return;
1624
1539
}
1625
1540
 
1626
1541
 
 
1542
static unsigned char *get_var_key(const unsigned char* var, size_t *len,
 
1543
                          bool __attribute__((unused)) t)
 
1544
{
 
1545
  register char* key;
 
1546
  key = ((VAR*)var)->name;
 
1547
  *len = ((VAR*)var)->name_len;
 
1548
  return (unsigned char*)key;
 
1549
}
 
1550
 
1627
1551
 
1628
1552
VAR *var_init(VAR *v, const char *name, int name_len, const char *val,
1629
1553
              int val_len)
1635
1559
  if (!val_len && val)
1636
1560
    val_len = strlen(val) ;
1637
1561
  val_alloc_len = val_len + 16; /* room to grow */
1638
 
  if (!(tmp_var=v) && !(tmp_var = (VAR*)malloc(sizeof(*tmp_var)
1639
 
                                               + name_len+1)))
 
1562
  if (!(tmp_var=v) && !(tmp_var = (VAR*)my_malloc(sizeof(*tmp_var)
 
1563
                                                  + name_len+1, MYF(MY_WME))))
1640
1564
    die("Out of memory");
1641
1565
 
1642
1566
  tmp_var->name = (name) ? (char*) tmp_var + sizeof(*tmp_var) : 0;
1643
1567
  tmp_var->alloced = (v == 0);
1644
1568
 
1645
 
  if (!(tmp_var->str_val = (char *)malloc(val_alloc_len+1)))
 
1569
  if (!(tmp_var->str_val = (char *)my_malloc(val_alloc_len+1, MYF(MY_WME))))
1646
1570
    die("Out of memory");
1647
1571
 
1648
1572
  memcpy(tmp_var->name, name, name_len);
1661
1585
}
1662
1586
 
1663
1587
 
1664
 
void var_free(pair<string, VAR *> v)
 
1588
void var_free(void *v)
1665
1589
{
1666
 
  free(v.second->str_val);
1667
 
  free(v.second->env_s);
1668
 
  if (v.second->alloced)
1669
 
    free(v.second);
 
1590
  free(((VAR*) v)->str_val);
 
1591
  free(((VAR*) v)->env_s);
 
1592
  if (((VAR*)v)->alloced)
 
1593
    free(v);
1670
1594
}
1671
1595
 
1672
1596
 
1678
1602
    tmp = def_val;
1679
1603
 
1680
1604
  v = var_init(0, name, strlen(name), tmp, strlen(tmp));
1681
 
  string var_name(name);
1682
 
  var_hash.insert(make_pair(var_name, v));
 
1605
  my_hash_insert(&var_hash, (unsigned char*)v);
1683
1606
  return v;
1684
1607
}
1685
1608
 
1696
1619
  if (digit < 0 || digit >= 10)
1697
1620
  {
1698
1621
    const char *save_var_name = var_name, *end;
1699
 
    uint32_t length;
 
1622
    uint length;
1700
1623
    end = (var_name_end) ? *var_name_end : 0;
1701
1624
    while (my_isvar(charset_info,*var_name) && var_name != end)
1702
1625
      var_name++;
1706
1629
        return(0);
1707
1630
      die("Empty variable");
1708
1631
    }
1709
 
    length= (uint32_t) (var_name - save_var_name);
 
1632
    length= (uint) (var_name - save_var_name);
1710
1633
    if (length >= MAX_VAR_NAME_LENGTH)
1711
1634
      die("Too long variable name: %s", save_var_name);
1712
1635
 
1713
 
    string save_var_name_str(save_var_name, length);
1714
 
    boost::unordered_map<string, VAR*>::iterator iter=
1715
 
      var_hash.find(save_var_name_str);
1716
 
    if (iter == var_hash.end())
 
1636
    if (!(v = (VAR*) hash_search(&var_hash, (const unsigned char*) save_var_name,
 
1637
                                 length)))
1717
1638
    {
1718
1639
      char buff[MAX_VAR_NAME_LENGTH+1];
1719
 
      strncpy(buff, save_var_name, length);
1720
 
      buff[length]= '\0';
 
1640
      strmake(buff, save_var_name, length);
1721
1641
      v= var_from_env(buff, "");
1722
1642
    }
1723
 
    else
1724
 
    {
1725
 
      v= (*iter).second;
1726
 
    }
1727
1643
    var_name--;  /* Point at last character */
1728
1644
  }
1729
1645
  else
1748
1664
 
1749
1665
static VAR *var_obtain(const char *name, int len)
1750
1666
{
1751
 
  string var_name(name, len);
1752
 
  boost::unordered_map<string, VAR*>::iterator iter=
1753
 
    var_hash.find(var_name);
1754
 
  if (iter != var_hash.end())
1755
 
    return (*iter).second;
1756
 
  VAR *v = var_init(0, name, len, "", 0);
1757
 
  var_hash.insert(make_pair(var_name, v));
 
1667
  VAR* v;
 
1668
  if ((v = (VAR*)hash_search(&var_hash, (const unsigned char *) name, len)))
 
1669
    return v;
 
1670
  v = var_init(0, name, len, "", 0);
 
1671
  my_hash_insert(&var_hash, (unsigned char*)v);
1758
1672
  return v;
1759
1673
}
1760
1674
 
1779
1693
  digit= *var_name - '0';
1780
1694
  if (!(digit < 10 && digit >= 0))
1781
1695
  {
1782
 
    v= var_obtain(var_name, (uint32_t) (var_name_end - var_name));
 
1696
    v= var_obtain(var_name, (uint) (var_name_end - var_name));
1783
1697
  }
1784
1698
  else
1785
1699
    v= var_reg + digit;
1798
1712
    snprintf(buf, sizeof(buf), "%.*s=%.*s",
1799
1713
             v->name_len, v->name,
1800
1714
             v->str_val_len, v->str_val);
1801
 
    if (!(v->env_s= strdup(buf)))
 
1715
    if (!(v->env_s= my_strdup(buf, MYF(MY_WME))))
1802
1716
      die("Out of memory");
1803
1717
    putenv(v->env_s);
1804
1718
    free(old_env_s);
1823
1737
 
1824
1738
/*
1825
1739
  Store an integer (typically the returncode of the last SQL)
1826
 
  statement in the drizzletest builtin variable $drizzleclient_errno
 
1740
  statement in the drizzletest builtin variable $drizzle_errno
1827
1741
*/
1828
1742
 
1829
1743
static void var_set_errno(int sql_errno)
1830
1744
{
1831
 
  var_set_int("$drizzleclient_errno", sql_errno);
 
1745
  var_set_int("$drizzle_errno", sql_errno);
1832
1746
}
1833
1747
 
1834
1748
 
1835
1749
/*
1836
 
  Update $drizzleclient_get_server_version variable with version
 
1750
  Update $drizzle_get_server_version variable with version
1837
1751
  of the currently connected server
1838
1752
*/
1839
1753
 
1840
 
static void var_set_drizzleclient_get_server_version(drizzle_con_st *con)
 
1754
static void var_set_drizzle_get_server_version(DRIZZLE *drizzle)
1841
1755
{
1842
 
  var_set_int("$drizzle_con_server_version", drizzle_con_server_version_number(con));
 
1756
  var_set_int("$drizzle_get_server_version", drizzle_get_server_version(drizzle));
1843
1757
}
1844
1758
 
1845
1759
 
1870
1784
{
1871
1785
  const char *end = (char*)((query_end && *query_end) ?
1872
1786
                            *query_end : query + strlen(query));
1873
 
  drizzle_result_st res;
1874
 
  drizzle_return_t ret;
1875
 
  drizzle_row_t row;
1876
 
  drizzle_con_st *con= &cur_con->con;
 
1787
  DRIZZLE_RES *res;
 
1788
  DRIZZLE_ROW row;
 
1789
  DRIZZLE *drizzle= &cur_con->drizzle;
1877
1790
  string ds_query;
1878
1791
 
1879
1792
 
1886
1799
  /* Eval the query, thus replacing all environment variables */
1887
1800
  do_eval(&ds_query, query, end, false);
1888
1801
 
1889
 
  if (drizzle_query(con, &res, ds_query.c_str(), ds_query.length(),
1890
 
                    &ret) == NULL ||
1891
 
      ret != DRIZZLE_RETURN_OK)
1892
 
  {
1893
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
1894
 
    {
1895
 
      die("Error running query '%s': %d %s", ds_query.c_str(),
1896
 
          drizzle_result_error_code(&res), drizzle_result_error(&res));
1897
 
      drizzle_result_free(&res);
1898
 
    }
1899
 
    else
1900
 
    {
1901
 
      die("Error running query '%s': %d %s", ds_query.c_str(), ret,
1902
 
          drizzle_con_error(con));
1903
 
    }
1904
 
  }
1905
 
  if (drizzle_result_column_count(&res) == 0 ||
1906
 
      drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
 
1802
  if (drizzle_real_query(drizzle, ds_query.c_str(), ds_query.length()))
 
1803
    die("Error running query '%s': %d %s", ds_query.c_str(),
 
1804
        drizzle_errno(drizzle), drizzle_error(drizzle));
 
1805
  if (!(res= drizzle_store_result(drizzle)))
1907
1806
    die("Query '%s' didn't return a result set", ds_query.c_str());
1908
1807
 
1909
 
  if ((row= drizzle_row_next(&res)) && row[0])
 
1808
  if ((row= drizzle_fetch_row(res)) && row[0])
1910
1809
  {
1911
1810
    /*
1912
1811
      Concatenate all fields in the first row with tab in between
1914
1813
    */
1915
1814
    string result;
1916
1815
    uint32_t i;
1917
 
    size_t *lengths;
 
1816
    uint32_t *lengths;
1918
1817
 
1919
 
    lengths= drizzle_row_field_sizes(&res);
1920
 
    for (i= 0; i < drizzle_result_column_count(&res); i++)
 
1818
    lengths= drizzle_fetch_lengths(res);
 
1819
    for (i= 0; i < drizzle_num_fields(res); i++)
1921
1820
    {
1922
1821
      if (row[i])
1923
1822
      {
1932
1831
  else
1933
1832
    eval_expr(var, "", 0);
1934
1833
 
1935
 
  drizzle_result_free(&res);
 
1834
  drizzle_free_result(res);
1936
1835
  return;
1937
1836
}
1938
1837
 
1963
1862
{
1964
1863
  long row_no;
1965
1864
  int col_no= -1;
1966
 
  drizzle_result_st res;
1967
 
  drizzle_return_t ret;
1968
 
  drizzle_con_st *con= &cur_con->con;
 
1865
  DRIZZLE_RES* res;
 
1866
  DRIZZLE *drizzle= &cur_con->drizzle;
1969
1867
 
1970
1868
  string ds_query;
1971
1869
  string ds_col;
1984
1882
                     ',');
1985
1883
 
1986
1884
  /* Convert row number to int */
1987
 
  row_no= atoi(ds_row.c_str());
1988
 
  
1989
 
  istringstream buff(ds_row);
1990
 
  if ((buff >> row_no).fail())
 
1885
  if (!str2int(ds_row.c_str(), 10, (long) 0, (long) INT_MAX, &row_no))
1991
1886
    die("Invalid row number: '%s'", ds_row.c_str());
1992
1887
 
1993
1888
  /* Remove any surrounding "'s from the query - if there is any */
1995
1890
  char * unstripped_query= strdup(ds_query.c_str());
1996
1891
  if (strip_surrounding(unstripped_query, '"', '"'))
1997
1892
    die("Mismatched \"'s around query '%s'", ds_query.c_str());
1998
 
  ds_query.clear();
1999
 
  ds_query.append(unstripped_query);
 
1893
  ds_query= unstripped_query;
2000
1894
 
2001
1895
  /* Run the query */
2002
 
  if (drizzle_query(con, &res, ds_query.c_str(), ds_query.length(),
2003
 
                    &ret) == NULL ||
2004
 
      ret != DRIZZLE_RETURN_OK)
2005
 
  {
2006
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
2007
 
    {
2008
 
      die("Error running query '%s': %d %s", ds_query.c_str(),
2009
 
          drizzle_result_error_code(&res), drizzle_result_error(&res));
2010
 
      drizzle_result_free(&res);
2011
 
    }
2012
 
    else
2013
 
    {
2014
 
      die("Error running query '%s': %d %s", ds_query.c_str(), ret,
2015
 
          drizzle_con_error(con));
2016
 
    }
2017
 
  }
2018
 
  if (drizzle_result_column_count(&res) == 0 ||
2019
 
      drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
 
1896
  if (drizzle_real_query(drizzle, ds_query.c_str(), ds_query.length()))
 
1897
    die("Error running query '%s': %d %s", ds_query.c_str(),
 
1898
        drizzle_errno(drizzle), drizzle_error(drizzle));
 
1899
  if (!(res= drizzle_store_result(drizzle)))
2020
1900
    die("Query '%s' didn't return a result set", ds_query.c_str());
2021
1901
 
2022
1902
  {
2023
1903
    /* Find column number from the given column name */
2024
 
    uint32_t i;
2025
 
    uint32_t num_fields= drizzle_result_column_count(&res);
2026
 
    drizzle_column_st *column;
 
1904
    uint i;
 
1905
    uint num_fields= drizzle_num_fields(res);
 
1906
    const DRIZZLE_FIELD *fields= drizzle_fetch_fields(res);
2027
1907
 
2028
1908
    for (i= 0; i < num_fields; i++)
2029
1909
    {
2030
 
      column= drizzle_column_next(&res);
2031
 
      if (strcmp(drizzle_column_name(column), ds_col.c_str()) == 0 &&
2032
 
          strlen(drizzle_column_name(column)) == ds_col.length())
 
1910
      if (strcmp(fields[i].name, ds_col.c_str()) == 0 &&
 
1911
          strlen(fields[i].name) == ds_col.length())
2033
1912
      {
2034
1913
        col_no= i;
2035
1914
        break;
2037
1916
    }
2038
1917
    if (col_no == -1)
2039
1918
    {
2040
 
      drizzle_result_free(&res);
 
1919
      drizzle_free_result(res);
2041
1920
      die("Could not find column '%s' in the result of '%s'",
2042
1921
          ds_col.c_str(), ds_query.c_str());
2043
1922
    }
2045
1924
 
2046
1925
  {
2047
1926
    /* Get the value */
2048
 
    drizzle_row_t row;
 
1927
    DRIZZLE_ROW row;
2049
1928
    long rows= 0;
2050
1929
    const char* value= "No such row";
2051
1930
 
2052
 
    while ((row= drizzle_row_next(&res)))
 
1931
    while ((row= drizzle_fetch_row(res)))
2053
1932
    {
2054
1933
      if (++rows == row_no)
2055
1934
      {
2065
1944
    }
2066
1945
    eval_expr(var, value, 0);
2067
1946
  }
2068
 
  drizzle_result_free(&res);
 
1947
  drizzle_free_result(res);
2069
1948
 
2070
1949
  return;
2071
1950
}
2077
1956
  dest->int_dirty= src->int_dirty;
2078
1957
 
2079
1958
  /* Alloc/realloc data for str_val in dest */
2080
 
  if (dest->alloced_len < src->alloced_len)
2081
 
  {
2082
 
    char *tmpptr= (char *)realloc(dest->str_val, src->alloced_len);
2083
 
    if (tmpptr == NULL)
2084
 
      die("Out of memory");
2085
 
    dest->str_val= tmpptr;
2086
 
  }
 
1959
  if (dest->alloced_len < src->alloced_len &&
 
1960
      !(dest->str_val= dest->str_val
 
1961
        ? (char *)my_realloc(dest->str_val, src->alloced_len, MYF(MY_WME))
 
1962
        : (char *)my_malloc(src->alloced_len, MYF(MY_WME))))
 
1963
    die("Out of memory");
2087
1964
  else
2088
1965
    dest->alloced_len= src->alloced_len;
2089
1966
 
2116
1993
    const size_t len= strlen(get_value_str);
2117
1994
    if (strncmp(p, get_value_str, len)==0)
2118
1995
    {
2119
 
      st_command command;
 
1996
      struct st_command command;
 
1997
      memset(&command, 0, sizeof(command));
2120
1998
      command.query= (char*)p;
2121
1999
      command.first_word_len= len;
2122
2000
      command.first_argument= command.query + len;
2134
2012
      static int MIN_VAR_ALLOC= 32;
2135
2013
      v->alloced_len = (new_val_len < MIN_VAR_ALLOC - 1) ?
2136
2014
        MIN_VAR_ALLOC : new_val_len + 1;
2137
 
      char *tmpptr= (char *)realloc(v->str_val, v->alloced_len+1);
2138
 
      if (tmpptr == NULL)
 
2015
      if (!(v->str_val =
 
2016
            v->str_val ? (char *)my_realloc(v->str_val, v->alloced_len+1,
 
2017
                                            MYF(MY_WME)) :
 
2018
            (char *)my_malloc(v->alloced_len+1, MYF(MY_WME))))
2139
2019
        die("Out of memory");
2140
 
      v->str_val= tmpptr;
2141
2020
    }
2142
2021
    v->str_val_len = new_val_len;
2143
2022
    memcpy(v->str_val, p, new_val_len);
2153
2032
{
2154
2033
  char buff[FN_REFLEN];
2155
2034
 
2156
 
  if (!internal::test_if_hard_path(name))
 
2035
  if (!test_if_hard_path(name))
2157
2036
  {
2158
 
    snprintf(buff, sizeof(buff), "%s%s",opt_basedir.c_str(),name);
 
2037
    strxmov(buff, opt_basedir, name, NULL);
2159
2038
    name=buff;
2160
2039
  }
2161
 
  internal::fn_format(buff, name, "", "", MY_UNPACK_FILENAME);
 
2040
  fn_format(buff, name, "", "", MY_UNPACK_FILENAME);
2162
2041
 
2163
2042
  if (cur_file == file_stack_end)
2164
2043
    die("Source directives are nesting too deep");
2165
2044
  cur_file++;
2166
 
  if (!(cur_file->file= fopen(buff, "r")))
 
2045
  if (!(cur_file->file = my_fopen(buff, O_RDONLY, MYF(0))))
2167
2046
  {
2168
2047
    cur_file--;
2169
2048
    die("Could not open '%s' for reading", buff);
2170
2049
  }
2171
 
  if (!(cur_file->file_name= strdup(buff)))
2172
 
    die("Out of memory");
 
2050
  cur_file->file_name= my_strdup(buff, MYF(MY_FAE));
2173
2051
  cur_file->lineno=1;
2174
2052
  return(0);
2175
2053
}
2209
2087
    ; /* Do nothing */
2210
2088
  else
2211
2089
  {
2212
 
    if (! opt_testdir.empty())
2213
 
    {
2214
 
      string testdir(opt_testdir);
2215
 
      if (testdir[testdir.length()] != '/')
2216
 
        testdir.append("/");
2217
 
      testdir.append(ds_filename);
2218
 
      ds_filename.swap(testdir);
2219
 
    }
2220
2090
    open_file(ds_filename.c_str());
2221
2091
  }
2222
2092
 
2328
2198
  error= pclose(res_file);
2329
2199
  if (error > 0)
2330
2200
  {
2331
 
    uint32_t status= WEXITSTATUS(error), i;
 
2201
    uint status= WEXITSTATUS(error), i;
2332
2202
    bool ok= 0;
2333
2203
 
2334
2204
    if (command->abort_on_error)
2477
2347
                     rm_args, sizeof(rm_args)/sizeof(struct command_arg),
2478
2348
                     ' ');
2479
2349
 
2480
 
  error= internal::my_delete(ds_filename.c_str(), MYF(0)) != 0;
 
2350
  error= my_delete(ds_filename.c_str(), MYF(0)) != 0;
2481
2351
  handle_command_error(command, error);
2482
2352
  return;
2483
2353
}
2511
2381
                     sizeof(copy_file_args)/sizeof(struct command_arg),
2512
2382
                     ' ');
2513
2383
 
2514
 
  error= (internal::my_copy(ds_from_file.c_str(), ds_to_file.c_str(),
 
2384
  error= (my_copy(ds_from_file.c_str(), ds_to_file.c_str(),
2515
2385
                  MYF(MY_DONT_OVERWRITE_FILE)) != 0);
2516
2386
  handle_command_error(command, error);
2517
2387
  return;
2546
2416
                     ' ');
2547
2417
 
2548
2418
  /* Parse what mode to set */
2549
 
  istringstream buff(ds_mode);
2550
2419
  if (ds_mode.length() != 4 ||
2551
 
      (buff >> oct >> mode).fail())
 
2420
      str2int(ds_mode.c_str(), 8, 0, INT_MAX, &mode) == NULL)
2552
2421
    die("You must write a 4 digit octal number for mode");
2553
2422
 
2554
2423
  handle_command_error(command, chmod(ds_file.c_str(), mode));
2598
2467
 
2599
2468
static void do_mkdir(struct st_command *command)
2600
2469
{
 
2470
  int error;
2601
2471
  string ds_dirname;
2602
 
  int error;
2603
2472
  const struct command_arg mkdir_args[] = {
2604
2473
    {"dirname", ARG_STRING, true, &ds_dirname, "Directory to create"}
2605
2474
  };
2609
2478
                     mkdir_args, sizeof(mkdir_args)/sizeof(struct command_arg),
2610
2479
                     ' ');
2611
2480
 
2612
 
  error= mkdir(ds_dirname.c_str(), (0777 & internal::my_umask_dir)) != 0;
 
2481
  error= my_mkdir(ds_dirname.c_str(), 0777, MYF(0)) != 0;
2613
2482
  handle_command_error(command, error);
2614
2483
  return;
2615
2484
}
2729
2598
 
2730
2599
  /* If no delimiter was provided, use EOF */
2731
2600
  if (ds_delimiter.length() == 0)
2732
 
    ds_delimiter.append("EOF");
 
2601
    ds_delimiter= "EOF";
2733
2602
 
2734
2603
  if (!append && access(ds_filename.c_str(), F_OK) == 0)
2735
2604
  {
2910
2779
{
2911
2780
  char *p= command->first_argument, *name;
2912
2781
  struct st_connection *con;
2913
 
  drizzle_result_st result;
2914
 
  drizzle_return_t ret;
2915
2782
 
2916
2783
  if (!*p)
2917
2784
    die("Missing connection name in send_quit");
2926
2793
  if (!(con= find_connection_by_name(name)))
2927
2794
    die("connection '%s' not found in connection pool", name);
2928
2795
 
2929
 
  if (drizzle_quit(&con->con,&result, &ret))
2930
 
    drizzle_result_free(&result);
 
2796
  simple_command(&con->drizzle,COM_QUIT,0,0,1);
2931
2797
 
2932
2798
  return;
2933
2799
}
2949
2815
 
2950
2816
*/
2951
2817
 
2952
 
static void do_change_user(struct st_command *)
 
2818
static void do_change_user(struct st_command *command)
2953
2819
{
2954
 
  assert(0);
 
2820
  DRIZZLE *drizzle= &cur_con->drizzle;
 
2821
  /* static keyword to make the NetWare compiler happy. */
 
2822
  string ds_user, ds_passwd, ds_db;
 
2823
  const struct command_arg change_user_args[] = {
 
2824
    { "user", ARG_STRING, false, &ds_user, "User to connect as" },
 
2825
    { "password", ARG_STRING, false, &ds_passwd, "Password used when connecting" },
 
2826
    { "database", ARG_STRING, false, &ds_db, "Database to select after connect" },
 
2827
  };
 
2828
 
 
2829
 
 
2830
 
 
2831
  check_command_args(command, command->first_argument,
 
2832
                     change_user_args,
 
2833
                     sizeof(change_user_args)/sizeof(struct command_arg),
 
2834
                     ',');
 
2835
 
 
2836
  if (!ds_user.length())
 
2837
    ds_user= drizzle->user;
 
2838
 
 
2839
  if (!ds_passwd.length())
 
2840
    ds_passwd= drizzle->passwd;
 
2841
 
 
2842
  if (!ds_db.length())
 
2843
    ds_db= drizzle->db;
 
2844
 
 
2845
  if (drizzle_change_user(drizzle, ds_user.c_str(),
 
2846
                          ds_passwd.c_str(), ds_db.c_str()))
 
2847
    die("change user failed: %s", drizzle_error(drizzle));
 
2848
 
 
2849
 
 
2850
  return;
2955
2851
}
2956
2852
 
 
2853
 
2957
2854
/*
2958
2855
  SYNOPSIS
2959
2856
  do_perl
2976
2873
static void do_perl(struct st_command *command)
2977
2874
{
2978
2875
  int error;
2979
 
  int fd;
 
2876
  File fd;
2980
2877
  FILE *res_file;
2981
2878
  char buf[FN_REFLEN];
2982
2879
  char temp_file_path[FN_REFLEN];
2995
2892
 
2996
2893
  /* If no delimiter was provided, use EOF */
2997
2894
  if (ds_delimiter.length() == 0)
2998
 
    ds_delimiter.append("EOF");
 
2895
    ds_delimiter= "EOF";
2999
2896
 
3000
2897
  read_until_delimiter(&ds_script, &ds_delimiter);
3001
2898
 
3002
2899
  /* Create temporary file name */
3003
 
  if ((fd= internal::create_temp_file(temp_file_path, getenv("MYSQLTEST_VARDIR"),
3004
 
                            "tmp", MYF(MY_WME))) < 0)
 
2900
  if ((fd= create_temp_file(temp_file_path, getenv("MYSQLTEST_VARDIR"),
 
2901
                            "tmp", O_CREAT | O_RDWR,
 
2902
                            MYF(MY_WME))) < 0)
3005
2903
    die("Failed to create temporary file for perl command");
3006
 
  internal::my_close(fd, MYF(0));
 
2904
  my_close(fd, MYF(0));
3007
2905
 
3008
2906
  str_to_file(temp_file_path, ds_script.c_str(), ds_script.length());
3009
2907
 
3023
2921
  error= pclose(res_file);
3024
2922
 
3025
2923
  /* Remove the temporary file */
3026
 
  internal::my_delete(temp_file_path, MYF(0));
 
2924
  my_delete(temp_file_path, MYF(0));
3027
2925
 
3028
2926
  handle_command_error(command, WEXITSTATUS(error));
3029
2927
  return;
3068
2966
 
3069
2967
 
3070
2968
static void
3071
 
do_wait_for_slave_to_stop(struct st_command *)
 
2969
do_wait_for_slave_to_stop(struct st_command *c __attribute__((unused)))
3072
2970
{
3073
2971
  static int SLAVE_POLL_INTERVAL= 300000;
3074
 
  drizzle_con_st *con= &cur_con->con;
 
2972
  DRIZZLE *drizzle= &cur_con->drizzle;
3075
2973
  for (;;)
3076
2974
  {
3077
 
    drizzle_result_st res;
3078
 
    drizzle_return_t ret;
3079
 
    drizzle_row_t row;
 
2975
    DRIZZLE_RES *res= NULL;
 
2976
    DRIZZLE_ROW row;
3080
2977
    int done;
3081
2978
 
3082
 
    if (drizzle_query_str(con,&res,"show status like 'Slave_running'",
3083
 
                          &ret) == NULL || ret != DRIZZLE_RETURN_OK)
3084
 
    {
3085
 
      if (ret == DRIZZLE_RETURN_ERROR_CODE)
3086
 
      {
3087
 
        die("Query failed while probing slave for stop: %s",
3088
 
            drizzle_result_error(&res));
3089
 
        drizzle_result_free(&res);
3090
 
      }
3091
 
      else
3092
 
      {
3093
 
        die("Query failed while probing slave for stop: %s",
3094
 
            drizzle_con_error(con));
3095
 
      }
3096
 
    }
3097
 
 
3098
 
    if (drizzle_result_column_count(&res) == 0 ||
3099
 
        drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
3100
 
    {
 
2979
    if (drizzle_query(drizzle,"show status like 'Slave_running'") ||
 
2980
        !(res=drizzle_store_result(drizzle)))
3101
2981
      die("Query failed while probing slave for stop: %s",
3102
 
          drizzle_con_error(con));
3103
 
    }
3104
 
 
3105
 
    if (!(row=drizzle_row_next(&res)) || !row[1])
 
2982
          drizzle_error(drizzle));
 
2983
    if (!(row=drizzle_fetch_row(res)) || !row[1])
3106
2984
    {
3107
 
      drizzle_result_free(&res);
 
2985
      drizzle_free_result(res);
3108
2986
      die("Strange result from query while probing slave for stop");
3109
2987
    }
3110
2988
    done = !strcmp(row[1],"OFF");
3111
 
    drizzle_result_free(&res);
 
2989
    drizzle_free_result(res);
3112
2990
    if (done)
3113
2991
      break;
3114
 
    usleep(SLAVE_POLL_INTERVAL);
 
2992
    my_sleep(SLAVE_POLL_INTERVAL);
3115
2993
  }
3116
2994
  return;
3117
2995
}
3119
2997
 
3120
2998
static void do_sync_with_master2(long offset)
3121
2999
{
3122
 
  drizzle_result_st res;
3123
 
  drizzle_return_t ret;
3124
 
  drizzle_row_t row;
3125
 
  drizzle_con_st *con= &cur_con->con;
 
3000
  DRIZZLE_RES *res;
 
3001
  DRIZZLE_ROW row;
 
3002
  DRIZZLE *drizzle= &cur_con->drizzle;
3126
3003
  char query_buf[FN_REFLEN+128];
3127
3004
  int tries= 0;
3128
3005
 
3129
3006
  if (!master_pos.file[0])
3130
3007
    die("Calling 'sync_with_master' without calling 'save_master_pos'");
3131
3008
 
3132
 
  snprintf(query_buf, sizeof(query_buf), "select master_pos_wait('%s', %ld)", master_pos.file,
 
3009
  sprintf(query_buf, "select master_pos_wait('%s', %ld)", master_pos.file,
3133
3010
          master_pos.pos + offset);
3134
3011
 
3135
3012
wait_for_position:
3136
3013
 
3137
 
  if (drizzle_query_str(con, &res, query_buf, &ret) == NULL ||
3138
 
      ret != DRIZZLE_RETURN_OK)
3139
 
  {
3140
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
3141
 
    {
3142
 
      die("failed in '%s': %d: %s", query_buf, drizzle_result_error_code(&res),
3143
 
           drizzle_result_error(&res));
3144
 
      drizzle_result_free(&res);
3145
 
    }
3146
 
    else
3147
 
      die("failed in '%s': %d: %s", query_buf, ret, drizzle_con_error(con));
3148
 
  }
3149
 
 
3150
 
  if (drizzle_result_column_count(&res) == 0 ||
3151
 
      drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
3152
 
    die("drizzle_result_buffer() returned NULL for '%s'", query_buf);
3153
 
 
3154
 
  if (!(row= drizzle_row_next(&res)))
3155
 
  {
3156
 
    drizzle_result_free(&res);
 
3014
  if (drizzle_query(drizzle, query_buf))
 
3015
    die("failed in '%s': %d: %s", query_buf, drizzle_errno(drizzle),
 
3016
        drizzle_error(drizzle));
 
3017
 
 
3018
  if (!(res= drizzle_store_result(drizzle)))
 
3019
    die("drizzle_store_result() returned NULL for '%s'", query_buf);
 
3020
  if (!(row= drizzle_fetch_row(res)))
 
3021
  {
 
3022
    drizzle_free_result(res);
3157
3023
    die("empty result in %s", query_buf);
3158
3024
  }
3159
3025
  if (!row[0])
3162
3028
      It may be that the slave SQL thread has not started yet, though START
3163
3029
      SLAVE has been issued ?
3164
3030
    */
3165
 
    drizzle_result_free(&res);
 
3031
    drizzle_free_result(res);
3166
3032
    if (tries++ == 30)
3167
3033
    {
3168
 
      show_query(con, "SHOW MASTER STATUS");
3169
 
      show_query(con, "SHOW SLAVE STATUS");
 
3034
      show_query(drizzle, "SHOW MASTER STATUS");
 
3035
      show_query(drizzle, "SHOW SLAVE STATUS");
3170
3036
      die("could not sync with master ('%s' returned NULL)", query_buf);
3171
3037
    }
3172
3038
    sleep(1); /* So at most we will wait 30 seconds and make 31 tries */
3173
3039
    goto wait_for_position;
3174
3040
  }
3175
 
  drizzle_result_free(&res);
 
3041
  drizzle_free_result(res);
3176
3042
  return;
3177
3043
}
3178
3044
 
3202
3068
*/
3203
3069
static int do_save_master_pos(void)
3204
3070
{
3205
 
  drizzle_result_st res;
3206
 
  drizzle_return_t ret;
3207
 
  drizzle_row_t row;
3208
 
  drizzle_con_st *con= &cur_con->con;
 
3071
  DRIZZLE_RES *res;
 
3072
  DRIZZLE_ROW row;
 
3073
  DRIZZLE *drizzle= &cur_con->drizzle;
3209
3074
  const char *query;
3210
3075
 
3211
3076
 
3212
 
  if (drizzle_query_str(con, &res, query= "show master status", &ret) == NULL ||
3213
 
      ret != DRIZZLE_RETURN_OK)
3214
 
  {
3215
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
3216
 
    {
3217
 
      die("failed in '%s': %d: %s", query, drizzle_result_error_code(&res),
3218
 
           drizzle_result_error(&res));
3219
 
      drizzle_result_free(&res);
3220
 
    }
3221
 
    else
3222
 
      die("failed in '%s': %d: %s", query, ret, drizzle_con_error(con));
3223
 
  }
 
3077
  if (drizzle_query(drizzle, query= "show master status"))
 
3078
    die("failed in 'show master status': %d %s",
 
3079
        drizzle_errno(drizzle), drizzle_error(drizzle));
3224
3080
 
3225
 
  if (drizzle_result_column_count(&res) == 0 ||
3226
 
      drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
3227
 
    die("drizzleclient_store_result() retuned NULL for '%s'", query);
3228
 
  if (!(row = drizzle_row_next(&res)))
 
3081
  if (!(res = drizzle_store_result(drizzle)))
 
3082
    die("drizzle_store_result() retuned NULL for '%s'", query);
 
3083
  if (!(row = drizzle_fetch_row(res)))
3229
3084
    die("empty result in show master status");
3230
 
  strncpy(master_pos.file, row[0], sizeof(master_pos.file)-1);
 
3085
  my_stpncpy(master_pos.file, row[0], sizeof(master_pos.file)-1);
3231
3086
  master_pos.pos = strtoul(row[1], (char**) 0, 10);
3232
 
  drizzle_result_free(&res);
 
3087
  drizzle_free_result(res);
3233
3088
  return(0);
3234
3089
}
3235
3090
 
3313
3168
 
3314
3169
static int do_sleep(struct st_command *command, bool real_sleep)
3315
3170
{
3316
 
  bool error= false;
 
3171
  int error= 0;
3317
3172
  char *p= command->first_argument;
3318
3173
  char *sleep_start, *sleep_end= command->end;
3319
3174
  double sleep_val;
3323
3178
  if (!*p)
3324
3179
    die("Missing argument to %.*s", command->first_word_len, command->query);
3325
3180
  sleep_start= p;
3326
 
  /* Check that arg starts with a digit, not handled by internal::my_strtod */
 
3181
  /* Check that arg starts with a digit, not handled by my_strtod */
3327
3182
  if (!my_isdigit(charset_info, *sleep_start))
3328
3183
    die("Invalid argument to %.*s \"%s\"", command->first_word_len,
3329
3184
        command->query,command->first_argument);
3330
 
  string buff_str(sleep_start, sleep_end-sleep_start);
3331
 
  istringstream buff(buff_str);
3332
 
  error= (buff >> sleep_val).fail();
 
3185
  sleep_val= my_strtod(sleep_start, &sleep_end, &error);
3333
3186
  if (error)
3334
3187
    die("Invalid argument to %.*s \"%s\"", command->first_word_len,
3335
3188
        command->query, command->first_argument);
3339
3192
    sleep_val= opt_sleep;
3340
3193
 
3341
3194
  if (sleep_val)
3342
 
    usleep((uint32_t) (sleep_val * 1000000L));
 
3195
    my_sleep((uint32_t) (sleep_val * 1000000L));
3343
3196
  command->last_argument= sleep_end;
3344
3197
  return 0;
3345
3198
}
3346
3199
 
3347
3200
 
3348
 
static void do_get_file_name(struct st_command *command, string &dest)
 
3201
static void do_get_file_name(struct st_command *command,
 
3202
                             char* dest, uint dest_max_len)
3349
3203
{
3350
3204
  char *p= command->first_argument, *name;
3351
3205
  if (!*p)
3356
3210
  if (*p)
3357
3211
    *p++= 0;
3358
3212
  command->last_argument= p;
3359
 
  if (! opt_testdir.empty())
3360
 
  {
3361
 
    dest= opt_testdir;
3362
 
    if (dest[dest.length()] != '/')
3363
 
      dest.append("/");
3364
 
  }
3365
 
  dest.append(name);
 
3213
  strmake(dest, name, dest_max_len - 1);
3366
3214
}
3367
3215
 
3368
3216
 
3380
3228
  if(*p)
3381
3229
    *p++= 0;
3382
3230
  command->last_argument= p;
3383
 
  charset_info= get_charset_by_csname(charset_name, MY_CS_PRIMARY);
 
3231
  charset_info= get_charset_by_csname(charset_name,MY_CS_PRIMARY,MYF(MY_WME));
3384
3232
  if (!charset_info)
3385
3233
    abort_not_supported_test("Test requires charset '%s'", charset_name);
3386
3234
}
3387
3235
 
3388
 
static uint32_t get_errcode_from_name(char *error_name, char *error_end)
 
3236
static uint get_errcode_from_name(char *error_name, char *error_end)
3389
3237
{
3390
 
  size_t err_name_len= error_end - error_name;
3391
 
  string error_name_s(error_name, err_name_len);
3392
 
 
3393
 
  uint32_t code= global_error_names.getErrorCode(error_name_s);
3394
 
 
3395
 
  if (!code)
3396
 
    die("Unknown SQL error name '%s'", error_name_s.c_str());
3397
 
 
3398
 
  return(code);
 
3238
  /* SQL error as string */
 
3239
  st_error *e= global_error_names;
 
3240
 
 
3241
  /* Loop through the array of known error names */
 
3242
  for (; e->name; e++)
 
3243
  {
 
3244
    /*
 
3245
      If we get a match, we need to check the length of the name we
 
3246
      matched against in case it was longer than what we are checking
 
3247
      (as in ER_WRONG_VALUE vs. ER_WRONG_VALUE_COUNT).
 
3248
    */
 
3249
    if (!strncmp(error_name, e->name, (int) (error_end - error_name)) &&
 
3250
        (uint) strlen(e->name) == (uint) (error_end - error_name))
 
3251
    {
 
3252
      return(e->code);
 
3253
    }
 
3254
  }
 
3255
  if (!e->name)
 
3256
    die("Unknown SQL error name '%s'", error_name);
 
3257
  return(0);
3399
3258
}
3400
3259
 
3401
3260
static void do_get_errcodes(struct st_command *command)
3402
3261
{
3403
3262
  struct st_match_err *to= saved_expected_errors.err;
3404
3263
  char *p= command->first_argument;
3405
 
  uint32_t count= 0;
 
3264
  uint count= 0;
3406
3265
 
3407
3266
 
3408
3267
 
3428
3287
 
3429
3288
      /*
3430
3289
        SQLSTATE string
3431
 
        - Must be DRIZZLE_MAX_SQLSTATE_SIZE long
 
3290
        - Must be SQLSTATE_LENGTH long
3432
3291
        - May contain only digits[0-9] and _uppercase_ letters
3433
3292
      */
3434
3293
      p++; /* Step past the S */
3435
 
      if ((end - p) != DRIZZLE_MAX_SQLSTATE_SIZE)
3436
 
        die("The sqlstate must be exactly %d chars long", DRIZZLE_MAX_SQLSTATE_SIZE);
 
3294
      if ((end - p) != SQLSTATE_LENGTH)
 
3295
        die("The sqlstate must be exactly %d chars long", SQLSTATE_LENGTH);
3437
3296
 
3438
3297
      /* Check sqlstate string validity */
3439
3298
      while (*p && p < end)
3478
3337
      }
3479
3338
 
3480
3339
      /* Convert the sting to int */
3481
 
      istringstream buff(start);
3482
 
      if ((buff >> val).fail())
 
3340
      if (!str2int(start, 10, (long) INT_MIN, (long) INT_MAX, &val))
3483
3341
        die("Invalid argument to error: '%s'", command->first_argument);
3484
3342
 
3485
 
      to->code.errnum= (uint32_t) val;
 
3343
      to->code.errnum= (uint) val;
3486
3344
      to->type= ERR_ERRNO;
3487
3345
    }
3488
3346
    to++;
3589
3447
}
3590
3448
 
3591
3449
 
3592
 
static void set_reconnect(drizzle_con_st *con, int val)
 
3450
static void set_reconnect(DRIZZLE *drizzle, int val)
3593
3451
{
3594
 
  (void) con;
3595
 
  (void) val;
3596
 
/* XXX
3597
3452
  bool reconnect= val;
3598
3453
 
3599
 
  drizzleclient_options(drizzle, DRIZZLE_OPT_RECONNECT, (char *)&reconnect);
3600
 
*/
 
3454
  drizzle_options(drizzle, DRIZZLE_OPT_RECONNECT, (char *)&reconnect);
 
3455
 
 
3456
  return;
3601
3457
}
3602
3458
 
3603
3459
 
3606
3462
  if (!(cur_con= find_connection_by_name(name)))
3607
3463
    die("connection '%s' not found in connection pool", name);
3608
3464
 
3609
 
  /* Update $drizzleclient_get_server_version to that of current connection */
3610
 
  var_set_drizzleclient_get_server_version(&cur_con->con);
 
3465
  /* Update $drizzle_get_server_version to that of current connection */
 
3466
  var_set_drizzle_get_server_version(&cur_con->drizzle);
3611
3467
 
3612
3468
  return(0);
3613
3469
}
3649
3505
  if (!(con= find_connection_by_name(name)))
3650
3506
    die("connection '%s' not found in connection pool", name);
3651
3507
 
3652
 
  if (con->drizzle != NULL)
 
3508
  if (command->type == Q_DIRTY_CLOSE)
3653
3509
  {
3654
 
    drizzle_free(con->drizzle);
3655
 
    con->drizzle= NULL;
 
3510
    if (con->drizzle.net.vio)
 
3511
    {
 
3512
      net_close(&(con->drizzle.net));
 
3513
    }
3656
3514
  }
 
3515
 
 
3516
  drizzle_close(&con->drizzle);
 
3517
 
 
3518
  if (con->util_drizzle)
 
3519
    drizzle_close(con->util_drizzle);
 
3520
  con->util_drizzle= 0;
 
3521
 
3657
3522
  free(con->name);
3658
3523
 
3659
3524
  /*
3660
3525
    When the connection is closed set name to "-closed_connection-"
3661
3526
    to make it possible to reuse the connection name.
3662
3527
  */
3663
 
  if (!(con->name = strdup("-closed_connection-")))
 
3528
  if (!(con->name = my_strdup("-closed_connection-", MYF(MY_WME))))
3664
3529
    die("Out of memory");
3665
3530
 
3666
3531
  return;
3692
3557
 
3693
3558
*/
3694
3559
 
3695
 
static void safe_connect(drizzle_con_st *con, const char *name,
3696
 
                         const string host, const string user, const char *pass,
3697
 
                         const string db, uint32_t port)
 
3560
static void safe_connect(DRIZZLE *drizzle, const char *name, const char *host,
 
3561
                         const char *user, const char *pass, const char *db,
 
3562
                         int port)
3698
3563
{
3699
 
  uint32_t failed_attempts= 0;
 
3564
  int failed_attempts= 0;
3700
3565
  static uint32_t connection_retry_sleep= 100000; /* Microseconds */
3701
 
  drizzle_return_t ret;
3702
 
 
3703
 
  drizzle_con_set_tcp(con, host.c_str(), port);
3704
 
  drizzle_con_set_auth(con, user.c_str(), pass);
3705
 
  drizzle_con_set_db(con, db.c_str());
3706
 
  while((ret= drizzle_con_connect(con)) != DRIZZLE_RETURN_OK)
 
3566
 
 
3567
 
 
3568
  while(!drizzle_connect(drizzle, host, user, pass, db, port, NULL,
 
3569
                         CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS))
3707
3570
  {
3708
3571
    /*
3709
3572
      Connect failed
3713
3576
      on protocol/connection type
3714
3577
    */
3715
3578
 
3716
 
    if ((ret == DRIZZLE_RETURN_GETADDRINFO ||
3717
 
         ret == DRIZZLE_RETURN_COULD_NOT_CONNECT) &&
 
3579
    if ((drizzle_errno(drizzle) == CR_CONN_HOST_ERROR ||
 
3580
         drizzle_errno(drizzle) == CR_CONNECTION_ERROR) &&
3718
3581
        failed_attempts < opt_max_connect_retries)
3719
3582
    {
3720
3583
      verbose_msg("Connect attempt %d/%d failed: %d: %s", failed_attempts,
3721
 
                  opt_max_connect_retries, ret, drizzle_con_error(con));
3722
 
      usleep(connection_retry_sleep);
 
3584
                  opt_max_connect_retries, drizzle_errno(drizzle),
 
3585
                  drizzle_error(drizzle));
 
3586
      my_sleep(connection_retry_sleep);
3723
3587
    }
3724
3588
    else
3725
3589
    {
3726
3590
      if (failed_attempts > 0)
3727
3591
        die("Could not open connection '%s' after %d attempts: %d %s", name,
3728
 
            failed_attempts, ret, drizzle_con_error(con));
 
3592
            failed_attempts, drizzle_errno(drizzle), drizzle_error(drizzle));
3729
3593
      else
3730
 
        die("Could not open connection '%s': %d %s", name, ret,
3731
 
            drizzle_con_error(con));
 
3594
        die("Could not open connection '%s': %d %s", name,
 
3595
            drizzle_errno(drizzle), drizzle_error(drizzle));
3732
3596
    }
3733
3597
    failed_attempts++;
3734
3598
  }
3760
3624
*/
3761
3625
 
3762
3626
static int connect_n_handle_errors(struct st_command *command,
3763
 
                                   drizzle_con_st *con, const char* host,
 
3627
                                   DRIZZLE *con, const char* host,
3764
3628
                                   const char* user, const char* pass,
3765
3629
                                   const char* db, int port, const char* sock)
3766
3630
{
3767
 
  drizzle_return_t ret;
3768
3631
 
3769
3632
  /* Only log if an error is expected */
3770
3633
  if (!command->abort_on_error &&
3791
3654
    ds_res.append(delimiter);
3792
3655
    ds_res.append("\n");
3793
3656
  }
3794
 
  drizzle_con_set_tcp(con, host, port);
3795
 
  drizzle_con_set_auth(con, user, pass);
3796
 
  drizzle_con_set_db(con, db);
3797
 
  if ((ret= drizzle_con_connect(con)) != DRIZZLE_RETURN_OK)
 
3657
  if (!drizzle_connect(con, host, user, pass, db, port, 0,
 
3658
                       CLIENT_MULTI_STATEMENTS))
3798
3659
  {
3799
 
    if (ret == DRIZZLE_RETURN_HANDSHAKE_FAILED)
3800
 
    {
3801
 
      var_set_errno(drizzle_con_error_code(con));
3802
 
      handle_error(command, drizzle_con_error_code(con), drizzle_con_error(con),
3803
 
                   drizzle_con_sqlstate(con), &ds_res);
3804
 
    }
3805
 
    else
3806
 
    {
3807
 
      var_set_errno(ret);
3808
 
      handle_error(command, ret, drizzle_con_error(con), "", &ds_res);
3809
 
    }
3810
 
 
 
3660
    var_set_errno(drizzle_errno(con));
 
3661
    handle_error(command, drizzle_errno(con), drizzle_error(con),
 
3662
                 drizzle_sqlstate(con), &ds_res);
3811
3663
    return 0; /* Not connected */
3812
3664
  }
3813
3665
 
3844
3696
 
3845
3697
static void do_connect(struct st_command *command)
3846
3698
{
3847
 
  uint32_t con_port= opt_port;
 
3699
  int con_port= opt_port;
3848
3700
  const char *con_options;
3849
3701
  bool con_ssl= 0, con_compress= 0;
3850
3702
  struct st_connection* con_slot;
3892
3744
    if (*ds_sock.c_str() != FN_LIBCHAR)
3893
3745
    {
3894
3746
      char buff[FN_REFLEN];
3895
 
      internal::fn_format(buff, ds_sock.c_str(), TMPDIR, "", 0);
3896
 
      ds_sock.clear();
3897
 
      ds_sock.append(buff);
 
3747
      fn_format(buff, ds_sock.c_str(), TMPDIR, "", 0);
 
3748
      ds_sock= buff;
3898
3749
    }
3899
3750
  }
3900
3751
 
3935
3786
          (int) (sizeof(connections)/sizeof(struct st_connection)));
3936
3787
  }
3937
3788
 
3938
 
  if ((con_slot->drizzle= drizzle_create(NULL)) == NULL)
 
3789
  if (!drizzle_create(&con_slot->drizzle))
3939
3790
    die("Failed on drizzle_create()");
3940
 
  if (!drizzle_con_create(con_slot->drizzle, &con_slot->con))
3941
 
    die("Failed on drizzle_con_create()");
3942
 
  drizzle_con_add_options(&con_slot->con, use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL);
 
3791
  if (opt_compress || con_compress)
 
3792
    drizzle_options(&con_slot->drizzle, DRIZZLE_OPT_COMPRESS, NULL);
 
3793
  drizzle_options(&con_slot->drizzle, DRIZZLE_OPT_LOCAL_INFILE, 0);
3943
3794
 
3944
3795
  /* Use default db name */
3945
3796
  if (ds_database.length() == 0)
3946
 
    ds_database.append(opt_db);
 
3797
    ds_database= opt_db;
3947
3798
 
3948
3799
  /* Special database to allow one to connect without a database name */
3949
3800
  if (ds_database.length() && !strcmp(ds_database.c_str(),"*NO-ONE*"))
3950
 
    ds_database.clear();
 
3801
    ds_database= "";
3951
3802
 
3952
 
  if (connect_n_handle_errors(command, &con_slot->con,
 
3803
  if (connect_n_handle_errors(command, &con_slot->drizzle,
3953
3804
                              ds_host.c_str(),ds_user.c_str(),
3954
3805
                              ds_password.c_str(), ds_database.c_str(),
3955
3806
                              con_port, ds_sock.c_str()))
3962
3813
      next_con++; /* if we used the next_con slot, advance the pointer */
3963
3814
  }
3964
3815
 
3965
 
  /* Update $drizzleclient_get_server_version to that of current connection */
3966
 
  var_set_drizzleclient_get_server_version(&cur_con->con);
 
3816
  /* Update $drizzle_get_server_version to that of current connection */
 
3817
  var_set_drizzle_get_server_version(&cur_con->drizzle);
3967
3818
 
3968
3819
  return;
3969
3820
}
4080
3931
  if (not_expr)
4081
3932
    cur_block->ok = !cur_block->ok;
4082
3933
 
4083
 
  free(v.str_val);
4084
 
  free(v.env_s);
4085
 
 
 
3934
  var_free(&v);
4086
3935
  return;
4087
3936
}
4088
3937
 
4097
3946
  if (!(*p))
4098
3947
    die("Can't set empty delimiter");
4099
3948
 
4100
 
  strncpy(delimiter, p, sizeof(delimiter) - 1);
 
3949
  strmake(delimiter, p, sizeof(delimiter) - 1);
4101
3950
  delimiter_length= strlen(delimiter);
4102
3951
 
4103
3952
  command->last_argument= p + delimiter_length;
4105
3954
}
4106
3955
 
4107
3956
 
4108
 
bool match_delimiter(int c, const char *delim, uint32_t length)
 
3957
bool match_delimiter(int c, const char *delim, uint length)
4109
3958
{
4110
 
  uint32_t i;
 
3959
  uint i;
4111
3960
  char tmp[MAX_DELIMITER_LENGTH];
4112
3961
 
4113
3962
  if (c != *delim)
4159
4008
 
4160
4009
*/
4161
4010
 
4162
 
 
4163
 
static int my_strnncoll_simple(const CHARSET_INFO * const  cs, const unsigned char *s, size_t slen,
4164
 
                               const unsigned char *t, size_t tlen,
4165
 
                               bool t_is_prefix)
4166
 
{
4167
 
  size_t len = ( slen > tlen ) ? tlen : slen;
4168
 
  unsigned char *map= cs->sort_order;
4169
 
  if (t_is_prefix && slen > tlen)
4170
 
    slen=tlen;
4171
 
  while (len--)
4172
 
  {
4173
 
    if (map[*s++] != map[*t++])
4174
 
      return ((int) map[s[-1]] - (int) map[t[-1]]);
4175
 
  }
4176
 
  /*
4177
 
    We can't use (slen - tlen) here as the result may be outside of the
4178
 
    precision of a signed int
4179
 
  */
4180
 
  return slen > tlen ? 1 : slen < tlen ? -1 : 0 ;
4181
 
}
4182
 
 
4183
4011
static int read_line(char *buf, int size)
4184
4012
{
4185
4013
  char c, last_quote= 0;
4199
4027
  found_eof:
4200
4028
      if (cur_file->file != stdin)
4201
4029
      {
4202
 
        fclose(cur_file->file);
 
4030
        my_fclose(cur_file->file, MYF(0));
4203
4031
        cur_file->file= 0;
4204
4032
      }
4205
4033
      free((unsigned char*) cur_file->file_name);
4239
4067
      }
4240
4068
      else if ((c == '{' &&
4241
4069
                (!my_strnncoll_simple(charset_info, (const unsigned char*) "while", 5,
4242
 
                                      (unsigned char*) buf, min((ptrdiff_t)5, p - buf), 0) ||
 
4070
                                      (unsigned char*) buf, cmin((long)5, p - buf), 0) ||
4243
4071
                 !my_strnncoll_simple(charset_info, (const unsigned char*) "if", 2,
4244
 
                                      (unsigned char*) buf, min((ptrdiff_t)2, p - buf), 0))))
 
4072
                                      (unsigned char*) buf, cmin((long)2, p - buf), 0))))
4245
4073
      {
4246
4074
        /* Only if and while commands can be terminated by { */
4247
4075
        *p++= c;
4318
4146
    {
4319
4147
      /* Could be a multibyte character */
4320
4148
      /* This code is based on the code in "sql_load.cc" */
 
4149
#ifdef USE_MB
4321
4150
      int charlen = my_mbcharlen(charset_info, c);
4322
4151
      /* We give up if multibyte character is started but not */
4323
4152
      /* completed before we pass buf_end */
4344
4173
        }
4345
4174
      }
4346
4175
      else
 
4176
#endif
4347
4177
        *p++= c;
4348
4178
    }
4349
4179
  }
4426
4256
        ptr[2] && ptr[2] == '-' &&
4427
4257
        ptr[3])
4428
4258
    {
4429
 
      uint32_t type;
 
4259
      uint type;
4430
4260
      char save;
4431
4261
      char *end, *start= (char*)ptr+3;
4432
4262
      /* Skip leading spaces */
4503
4333
  return;
4504
4334
}
4505
4335
 
 
4336
 
 
4337
 
4506
4338
/*
4507
4339
  Create a command from a set of lines
4508
4340
 
4520
4352
  terminated by new line '\n' regardless how many "delimiter" it contain.
4521
4353
*/
4522
4354
 
4523
 
#define MAX_QUERY (768*1024*2) /* 256K -- a test in sp-big is >128K */
 
4355
#define MAX_QUERY (256*1024*2) /* 256K -- a test in sp-big is >128K */
4524
4356
static char read_command_buf[MAX_QUERY];
4525
4357
 
4526
4358
static int read_command(struct st_command** command_ptr)
4534
4366
    *command_ptr= q_lines[parser.current_line];
4535
4367
    return(0);
4536
4368
  }
4537
 
  if (!(*command_ptr= command= new st_command))
4538
 
    die("command construction failed");
 
4369
  if (!(*command_ptr= command=
 
4370
        (struct st_command*) my_malloc(sizeof(*command),
 
4371
                                       MYF(MY_WME|MY_ZEROFILL))))
 
4372
    die(NULL);
4539
4373
  q_lines.push_back(command);
4540
4374
  command->type= Q_UNKNOWN;
4541
4375
 
4562
4396
  while (*p && my_isspace(charset_info, *p))
4563
4397
    p++;
4564
4398
 
4565
 
  if (!(command->query_buf= command->query= strdup(p)))
 
4399
  if (!(command->query_buf= command->query= my_strdup(p, MYF(MY_WME))))
4566
4400
    die("Out of memory");
4567
4401
 
4568
4402
  /* Calculate first word length(the command), terminated by space or ( */
4569
4403
  p= command->query;
4570
4404
  while (*p && !my_isspace(charset_info, *p) && *p != '(')
4571
4405
    p++;
4572
 
  command->first_word_len= (uint32_t) (p - command->query);
 
4406
  command->first_word_len= (uint) (p - command->query);
4573
4407
 
4574
4408
  /* Skip spaces between command and first argument */
4575
4409
  while (*p && my_isspace(charset_info, *p))
4582
4416
  return(0);
4583
4417
}
4584
4418
 
 
4419
 
 
4420
static struct my_option my_long_options[] =
 
4421
{
 
4422
  {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
 
4423
   0, 0, 0, 0, 0, 0},
 
4424
  {"basedir", 'b', "Basedir for tests.", (char**) &opt_basedir,
 
4425
   (char**) &opt_basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
4426
  {"character-sets-dir", OPT_CHARSETS_DIR,
 
4427
   "Directory where character sets are.", (char**) &opt_charsets_dir,
 
4428
   (char**) &opt_charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
4429
  {"compress", 'C', "Use the compressed server/client protocol.",
 
4430
   (char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
4431
   0, 0, 0},
 
4432
  {"database", 'D', "Database to use.", (char**) &opt_db, (char**) &opt_db, 0,
 
4433
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
4434
  {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
 
4435
   (char**) &debug_check_flag, (char**) &debug_check_flag, 0,
 
4436
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
4437
  {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
 
4438
   (char**) &debug_info_flag, (char**) &debug_info_flag,
 
4439
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
4440
  {"host", 'h', "Connect to host.", (char**) &opt_host, (char**) &opt_host, 0,
 
4441
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
4442
  {"include", 'i', "Include SQL before each test case.", (char**) &opt_include,
 
4443
   (char**) &opt_include, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
4444
  {"logdir", OPT_LOG_DIR, "Directory for log files", (char**) &opt_logdir,
 
4445
   (char**) &opt_logdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
4446
  {"mark-progress", OPT_MARK_PROGRESS,
 
4447
   "Write linenumber and elapsed time to <testname>.progress ",
 
4448
   (char**) &opt_mark_progress, (char**) &opt_mark_progress, 0,
 
4449
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
4450
  {"max-connect-retries", OPT_MAX_CONNECT_RETRIES,
 
4451
   "Max number of connection attempts when connecting to server",
 
4452
   (char**) &opt_max_connect_retries, (char**) &opt_max_connect_retries, 0,
 
4453
   GET_INT, REQUIRED_ARG, 500, 1, 10000, 0, 0, 0},
 
4454
  {"password", 'p', "Password to use when connecting to server.",
 
4455
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
4456
  {"port", 'P', "Port number to use for connection or 0 for default to, in "
 
4457
   "order of preference, my.cnf, $DRIZZLE_TCP_PORT, "
 
4458
   "built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
 
4459
   (char**) &opt_port,
 
4460
   (char**) &opt_port, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
4461
  {"quiet", 's', "Suppress all normal output.", (char**) &silent,
 
4462
   (char**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
4463
  {"record", 'r', "Record output of test_file into result file.",
 
4464
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
4465
  {"result-file", 'R', "Read/Store result from/in this file.",
 
4466
   (char**) &result_file_name, (char**) &result_file_name, 0,
 
4467
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
4468
  {"server-arg", 'A', "Send option value to embedded server as a parameter.",
 
4469
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
4470
  {"server-file", 'F', "Read embedded server arguments from file.",
 
4471
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
4472
  {"silent", 's', "Suppress all normal output. Synonym for --quiet.",
 
4473
   (char**) &silent, (char**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
4474
  {"sleep", 'T', "Sleep always this many seconds on sleep commands.",
 
4475
   (char**) &opt_sleep, (char**) &opt_sleep, 0, GET_INT, REQUIRED_ARG, -1, -1, 0,
 
4476
   0, 0, 0},
 
4477
  {"tail-lines", OPT_TAIL_LINES,
 
4478
   "Number of lines of the resul to include in a failure report",
 
4479
   (char**) &opt_tail_lines, (char**) &opt_tail_lines, 0,
 
4480
   GET_INT, REQUIRED_ARG, 0, 0, 10000, 0, 0, 0},
 
4481
  {"test-file", 'x', "Read test from/in this file (default stdin).",
 
4482
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
4483
  {"timer-file", 'm', "File where the timing in micro seconds is stored.",
 
4484
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
4485
  {"tmpdir", 't', "Temporary directory where sockets are put.",
 
4486
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
4487
  {"user", 'u', "User for login.", (char**) &opt_user, (char**) &opt_user, 0,
 
4488
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
4489
  {"verbose", 'v', "Write more.", (char**) &verbose, (char**) &verbose, 0,
 
4490
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
4491
  {"version", 'V', "Output version information and exit.",
 
4492
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
4493
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 
4494
};
 
4495
 
 
4496
 
 
4497
static void print_version(void)
 
4498
{
 
4499
  printf("%s  Ver %s Distrib %s, for %s (%s)\n",my_progname,MTEST_VERSION,
 
4500
         drizzle_get_client_info(),SYSTEM_TYPE,MACHINE_TYPE);
 
4501
}
 
4502
 
 
4503
static void usage(void)
 
4504
{
 
4505
  print_version();
 
4506
  printf("MySQL AB, by Sasha, Matt, Monty & Jani\n");
 
4507
  printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
 
4508
  printf("Runs a test against the DRIZZLE server and compares output with a results file.\n\n");
 
4509
  printf("Usage: %s [OPTIONS] [database] < test_file\n", my_progname);
 
4510
  my_print_help(my_long_options);
 
4511
  printf("  --no-defaults       Don't read default options from any options file.\n");
 
4512
  my_print_variables(my_long_options);
 
4513
}
 
4514
 
 
4515
/*
 
4516
  Read arguments for embedded server and put them into
 
4517
  embedded_server_args[]
 
4518
*/
 
4519
 
 
4520
static void read_embedded_server_arguments(const char *name)
 
4521
{
 
4522
  char argument[1024],buff[FN_REFLEN], *str=0;
 
4523
  FILE *file;
 
4524
 
 
4525
  if (!test_if_hard_path(name))
 
4526
  {
 
4527
    strxmov(buff, opt_basedir, name, NULL);
 
4528
    name=buff;
 
4529
  }
 
4530
  fn_format(buff, name, "", "", MY_UNPACK_FILENAME);
 
4531
 
 
4532
  if (!embedded_server_arg_count)
 
4533
  {
 
4534
    embedded_server_arg_count=1;
 
4535
    embedded_server_args[0]= (char*) "";    /* Progname */
 
4536
  }
 
4537
  if (!(file=my_fopen(buff, O_RDONLY, MYF(MY_WME))))
 
4538
    die("Failed to open file '%s'", buff);
 
4539
 
 
4540
  while (embedded_server_arg_count < MAX_EMBEDDED_SERVER_ARGS &&
 
4541
         (str=fgets(argument,sizeof(argument), file)))
 
4542
  {
 
4543
    *(strchr(str, '\0')-1)=0;        /* Remove end newline */
 
4544
    if (!(embedded_server_args[embedded_server_arg_count]=
 
4545
          (char*) my_strdup(str,MYF(MY_WME))))
 
4546
    {
 
4547
      my_fclose(file,MYF(0));
 
4548
      die("Out of memory");
 
4549
 
 
4550
    }
 
4551
    embedded_server_arg_count++;
 
4552
  }
 
4553
  my_fclose(file,MYF(0));
 
4554
  if (str)
 
4555
    die("Too many arguments in option file: %s",name);
 
4556
 
 
4557
  return;
 
4558
}
 
4559
 
 
4560
 
 
4561
static bool
 
4562
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
 
4563
               char *argument)
 
4564
{
 
4565
  switch(optid) {
 
4566
  case 'r':
 
4567
    record = 1;
 
4568
    break;
 
4569
  case 'x':
 
4570
  {
 
4571
    char buff[FN_REFLEN];
 
4572
    if (!test_if_hard_path(argument))
 
4573
    {
 
4574
      strxmov(buff, opt_basedir, argument, NULL);
 
4575
      argument= buff;
 
4576
    }
 
4577
    fn_format(buff, argument, "", "", MY_UNPACK_FILENAME);
 
4578
    assert(cur_file == file_stack && cur_file->file == 0);
 
4579
    if (!(cur_file->file=
 
4580
          my_fopen(buff, O_RDONLY, MYF(0))))
 
4581
      die("Could not open '%s' for reading: errno = %d", buff, errno);
 
4582
    cur_file->file_name= my_strdup(buff, MYF(MY_FAE));
 
4583
    cur_file->lineno= 1;
 
4584
    break;
 
4585
  }
 
4586
  case 'm':
 
4587
  {
 
4588
    static char buff[FN_REFLEN];
 
4589
    if (!test_if_hard_path(argument))
 
4590
    {
 
4591
      strxmov(buff, opt_basedir, argument, NULL);
 
4592
      argument= buff;
 
4593
    }
 
4594
    fn_format(buff, argument, "", "", MY_UNPACK_FILENAME);
 
4595
    timer_file= buff;
 
4596
    unlink(timer_file);       /* Ignore error, may not exist */
 
4597
    break;
 
4598
  }
 
4599
  case 'p':
 
4600
    if (argument)
 
4601
    {
 
4602
      free(opt_pass);
 
4603
      opt_pass= my_strdup(argument, MYF(MY_FAE));
 
4604
      while (*argument) *argument++= 'x';    /* Destroy argument */
 
4605
      tty_password= 0;
 
4606
    }
 
4607
    else
 
4608
      tty_password= 1;
 
4609
    break;
 
4610
  case 't':
 
4611
    my_stpncpy(TMPDIR, argument, sizeof(TMPDIR));
 
4612
    break;
 
4613
  case 'A':
 
4614
    if (!embedded_server_arg_count)
 
4615
    {
 
4616
      embedded_server_arg_count=1;
 
4617
      embedded_server_args[0]= (char*) "";
 
4618
    }
 
4619
    if (embedded_server_arg_count == MAX_EMBEDDED_SERVER_ARGS-1 ||
 
4620
        !(embedded_server_args[embedded_server_arg_count++]=
 
4621
          my_strdup(argument, MYF(MY_FAE))))
 
4622
    {
 
4623
      die("Can't use server argument");
 
4624
    }
 
4625
    break;
 
4626
  case 'F':
 
4627
    read_embedded_server_arguments(argument);
 
4628
    break;
 
4629
  case 'V':
 
4630
    print_version();
 
4631
    exit(0);
 
4632
  case '?':
 
4633
    usage();
 
4634
    exit(0);
 
4635
  }
 
4636
  return 0;
 
4637
}
 
4638
 
 
4639
 
 
4640
static int parse_args(int argc, char **argv)
 
4641
{
 
4642
  load_defaults("my",load_default_groups,&argc,&argv);
 
4643
  default_argv= argv;
 
4644
 
 
4645
  if ((handle_options(&argc, &argv, my_long_options, get_one_option)))
 
4646
    exit(1);
 
4647
 
 
4648
  if (argc > 1)
 
4649
  {
 
4650
    usage();
 
4651
    exit(1);
 
4652
  }
 
4653
  if (argc == 1)
 
4654
    opt_db= *argv;
 
4655
  if (tty_password)
 
4656
    opt_pass= get_tty_password(NULL);          /* purify tested */
 
4657
  if (debug_info_flag)
 
4658
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
 
4659
  if (debug_check_flag)
 
4660
    my_end_arg= MY_CHECK_ERROR;
 
4661
 
 
4662
  return 0;
 
4663
}
 
4664
 
4585
4665
/*
4586
4666
  Write the content of str into file
4587
4667
 
4598
4678
  int fd;
4599
4679
  char buff[FN_REFLEN];
4600
4680
  int flags= O_WRONLY | O_CREAT;
4601
 
  if (!internal::test_if_hard_path(fname))
 
4681
  if (!test_if_hard_path(fname))
4602
4682
  {
4603
 
    snprintf(buff, sizeof(buff), "%s%s",opt_basedir.c_str(),fname);
 
4683
    strxmov(buff, opt_basedir, fname, NULL);
4604
4684
    fname= buff;
4605
4685
  }
4606
 
  internal::fn_format(buff, fname, "", "", MY_UNPACK_FILENAME);
 
4686
  fn_format(buff, fname, "", "", MY_UNPACK_FILENAME);
4607
4687
 
4608
4688
  if (!append)
4609
4689
    flags|= O_TRUNC;
4610
 
  if ((fd= internal::my_open(buff, flags,
 
4690
  if ((fd= my_open(buff, flags,
4611
4691
                   MYF(MY_WME | MY_FFNF))) < 0)
4612
4692
    die("Could not open '%s' for writing: errno = %d", buff, errno);
4613
 
  if (append && lseek(fd, 0, SEEK_END) == MY_FILEPOS_ERROR)
 
4693
  if (append && my_seek(fd, 0, SEEK_END, MYF(0)) == MY_FILEPOS_ERROR)
4614
4694
    die("Could not find end of file '%s': errno = %d", buff, errno);
4615
 
  if (internal::my_write(fd, (unsigned char*)str, size, MYF(MY_WME|MY_FNABP)))
 
4695
  if (my_write(fd, (unsigned char*)str, size, MYF(MY_WME|MY_FNABP)))
4616
4696
    die("write failed");
4617
 
  internal::my_close(fd, MYF(0));
 
4697
  my_close(fd, MYF(0));
4618
4698
}
4619
4699
 
4620
4700
/*
4636
4716
void dump_result_to_log_file(const char *buf, int size)
4637
4717
{
4638
4718
  char log_file[FN_REFLEN];
4639
 
  str_to_file(internal::fn_format(log_file, result_file_name.c_str(), opt_logdir.c_str(), ".log",
4640
 
                        ! opt_logdir.empty() ? MY_REPLACE_DIR | MY_REPLACE_EXT :
 
4719
  str_to_file(fn_format(log_file, result_file_name, opt_logdir, ".log",
 
4720
                        *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
4641
4721
                        MY_REPLACE_EXT),
4642
4722
              buf, size);
4643
4723
  fprintf(stderr, "\nMore results from queries before failure can be found in %s\n",
4647
4727
void dump_progress(void)
4648
4728
{
4649
4729
  char progress_file[FN_REFLEN];
4650
 
  str_to_file(internal::fn_format(progress_file, result_file_name.c_str(),
4651
 
                        opt_logdir.c_str(), ".progress",
4652
 
                        ! opt_logdir.empty() ? MY_REPLACE_DIR | MY_REPLACE_EXT :
 
4730
  str_to_file(fn_format(progress_file, result_file_name,
 
4731
                        opt_logdir, ".progress",
 
4732
                        *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
4653
4733
                        MY_REPLACE_EXT),
4654
4734
              ds_progress.c_str(), ds_progress.length());
4655
4735
}
4658
4738
{
4659
4739
  char warn_file[FN_REFLEN];
4660
4740
 
4661
 
  str_to_file(internal::fn_format(warn_file, result_file_name.c_str(), opt_logdir.c_str(), ".warnings",
4662
 
                        ! opt_logdir.empty() ? MY_REPLACE_DIR | MY_REPLACE_EXT :
 
4741
  str_to_file(fn_format(warn_file, result_file_name, opt_logdir, ".warnings",
 
4742
                        *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
4663
4743
                        MY_REPLACE_EXT),
4664
4744
              ds_warning_messages.c_str(), ds_warning_messages.length());
4665
4745
}
4669
4749
  Append the result for one field to the dynamic string ds
4670
4750
*/
4671
4751
 
4672
 
static void append_field(string *ds, uint32_t col_idx, drizzle_column_st *column,
 
4752
static void append_field(string *ds, uint col_idx, const DRIZZLE_FIELD* field,
4673
4753
                         const char* val, uint64_t len, bool is_null)
4674
4754
{
4675
4755
  if (col_idx < max_replace_column && replace_column[col_idx])
4691
4771
  }
4692
4772
  else
4693
4773
  {
4694
 
    ds->append(drizzle_column_name(column));
 
4774
    ds->append(field->name);
4695
4775
    ds->append("\t");
4696
4776
    replace_append_mem(ds, val, (int)len);
4697
4777
    ds->append("\n");
4704
4784
  Values may be converted with 'replace_column'
4705
4785
*/
4706
4786
 
4707
 
static void append_result(string *ds, drizzle_result_st *res)
 
4787
static void append_result(string *ds, DRIZZLE_RES *res)
4708
4788
{
4709
 
  drizzle_row_t row;
4710
 
  uint32_t num_fields= drizzle_result_column_count(res);
4711
 
  drizzle_column_st *column;
4712
 
  size_t *lengths;
 
4789
  DRIZZLE_ROW row;
 
4790
  uint32_t num_fields= drizzle_num_fields(res);
 
4791
  const DRIZZLE_FIELD *fields= drizzle_fetch_fields(res);
 
4792
  uint32_t *lengths;
4713
4793
 
4714
 
  while ((row = drizzle_row_next(res)))
 
4794
  while ((row = drizzle_fetch_row(res)))
4715
4795
  {
4716
4796
    uint32_t i;
4717
 
    lengths = drizzle_row_field_sizes(res);
4718
 
    drizzle_column_seek(res, 0);
 
4797
    lengths = drizzle_fetch_lengths(res);
4719
4798
    for (i = 0; i < num_fields; i++)
4720
 
    {
4721
 
      column= drizzle_column_next(res);
4722
 
      append_field(ds, i, column,
 
4799
      append_field(ds, i, &fields[i],
4723
4800
                   (const char*)row[i], lengths[i], !row[i]);
4724
 
    }
4725
4801
    if (!display_result_vertically)
4726
4802
      ds->append("\n");
4727
4803
 
4733
4809
  Append metadata for fields to output
4734
4810
*/
4735
4811
 
4736
 
static void append_metadata(string *ds, drizzle_result_st *res)
 
4812
static void append_metadata(string *ds,
 
4813
                            const DRIZZLE_FIELD *field,
 
4814
                            uint num_fields)
4737
4815
{
4738
 
  drizzle_column_st *column;
 
4816
  const DRIZZLE_FIELD *field_end;
4739
4817
  ds->append("Catalog\tDatabase\tTable\tTable_alias\tColumn\t"
4740
4818
             "Column_alias\tType\tLength\tMax length\tIs_null\t"
4741
4819
             "Flags\tDecimals\tCharsetnr\n");
4742
4820
 
4743
 
  drizzle_column_seek(res, 0);
4744
 
  while ((column= drizzle_column_next(res)))
 
4821
  for (field_end= field+num_fields ;
 
4822
       field < field_end ;
 
4823
       field++)
4745
4824
  {
4746
 
    ds->append(drizzle_column_catalog(column),
4747
 
               strlen(drizzle_column_catalog(column)));
4748
 
    ds->append("\t", 1);
4749
 
    ds->append(drizzle_column_db(column), strlen(drizzle_column_db(column)));
4750
 
    ds->append("\t", 1);
4751
 
    ds->append(drizzle_column_orig_table(column),
4752
 
               strlen(drizzle_column_orig_table(column)));
4753
 
    ds->append("\t", 1);
4754
 
    ds->append(drizzle_column_table(column),
4755
 
               strlen(drizzle_column_table(column)));
4756
 
    ds->append("\t", 1);
4757
 
    ds->append(drizzle_column_orig_name(column),
4758
 
               strlen(drizzle_column_orig_name(column)));
4759
 
    ds->append("\t", 1);
4760
 
    ds->append(drizzle_column_name(column),
4761
 
               strlen(drizzle_column_name(column)));
4762
 
    ds->append("\t", 1);
4763
 
    replace_append_uint(ds, drizzle_column_type_drizzle(column));
4764
 
    ds->append("\t", 1);
4765
 
    replace_append_uint(ds, drizzle_column_size(column));
4766
 
    ds->append("\t", 1);
4767
 
    replace_append_uint(ds, drizzle_column_max_size(column));
4768
 
    ds->append("\t", 1);
4769
 
    ds->append((char*) ((drizzle_column_flags(column) & DRIZZLE_COLUMN_FLAGS_NOT_NULL) ? "N" : "Y"), 1);
4770
 
    ds->append("\t", 1);
4771
 
    replace_append_uint(ds, drizzle_column_flags(column));
4772
 
    ds->append("\t", 1);
4773
 
    replace_append_uint(ds, drizzle_column_decimals(column));
4774
 
    ds->append("\t", 1);
4775
 
    replace_append_uint(ds, drizzle_column_charset(column));
 
4825
    ds->append(field->catalog,
 
4826
               field->catalog_length);
 
4827
    ds->append("\t", 1);
 
4828
    ds->append(field->db, field->db_length);
 
4829
    ds->append("\t", 1);
 
4830
    ds->append(field->org_table,
 
4831
               field->org_table_length);
 
4832
    ds->append("\t", 1);
 
4833
    ds->append(field->table,
 
4834
               field->table_length);
 
4835
    ds->append("\t", 1);
 
4836
    ds->append(field->org_name,
 
4837
               field->org_name_length);
 
4838
    ds->append("\t", 1);
 
4839
    ds->append(field->name, field->name_length);
 
4840
    ds->append("\t", 1);
 
4841
    replace_append_uint(ds, field->type);
 
4842
    ds->append("\t", 1);
 
4843
    replace_append_uint(ds, field->length);
 
4844
    ds->append("\t", 1);
 
4845
    replace_append_uint(ds, field->max_length);
 
4846
    ds->append("\t", 1);
 
4847
    ds->append((char*) ((field->flags & NOT_NULL_FLAG) ?
 
4848
                        "N" : "Y"), 1);
 
4849
    ds->append("\t", 1);
 
4850
    replace_append_uint(ds, field->flags);
 
4851
    ds->append("\t", 1);
 
4852
    replace_append_uint(ds, field->decimals);
 
4853
    ds->append("\t", 1);
 
4854
    replace_append_uint(ds, field->charsetnr);
4776
4855
    ds->append("\n", 1);
4777
4856
  }
4778
4857
}
4785
4864
static void append_info(string *ds, uint64_t affected_rows,
4786
4865
                        const char *info)
4787
4866
{
4788
 
  ostringstream buf;
4789
 
  buf << "affected rows: " << affected_rows << endl;
4790
 
  ds->append(buf.str());
4791
 
  if (info && strcmp(info, ""))
 
4867
  char buf[40], buff2[21];
 
4868
  sprintf(buf,"affected rows: %s\n", llstr(affected_rows, buff2));
 
4869
  ds->append(buf);
 
4870
  if (info)
4792
4871
  {
4793
4872
    ds->append("info: ");
4794
4873
    ds->append(info);
4801
4880
  Display the table headings with the names tab separated
4802
4881
*/
4803
4882
 
4804
 
static void append_table_headings(string *ds, drizzle_result_st *res)
 
4883
static void append_table_headings(string *ds,
 
4884
                                  const DRIZZLE_FIELD *field,
 
4885
                                  uint num_fields)
4805
4886
{
4806
 
  uint32_t col_idx= 0;
4807
 
  drizzle_column_st *column;
4808
 
  drizzle_column_seek(res, 0);
4809
 
  while ((column= drizzle_column_next(res)))
 
4887
  uint col_idx;
 
4888
  for (col_idx= 0; col_idx < num_fields; col_idx++)
4810
4889
  {
4811
4890
    if (col_idx)
4812
4891
      ds->append("\t", 1);
4813
 
    replace_append(ds, drizzle_column_name(column));
4814
 
    col_idx++;
 
4892
    replace_append(ds, field[col_idx].name);
4815
4893
  }
4816
4894
  ds->append("\n", 1);
4817
4895
}
4823
4901
  Number of warnings appended to ds
4824
4902
*/
4825
4903
 
4826
 
static int append_warnings(string *ds, drizzle_con_st *con,
4827
 
                           drizzle_result_st *res)
 
4904
static int append_warnings(string *ds, DRIZZLE *drizzle)
4828
4905
{
4829
 
  uint32_t count;
4830
 
  drizzle_result_st warn_res;
4831
 
  drizzle_return_t ret;
4832
 
 
4833
 
 
4834
 
  if (!(count= drizzle_result_warning_count(res)))
 
4906
  uint count;
 
4907
  DRIZZLE_RES *warn_res;
 
4908
 
 
4909
 
 
4910
  if (!(count= drizzle_warning_count(drizzle)))
4835
4911
    return(0);
4836
4912
 
4837
 
  if (drizzle_query_str(con, &warn_res, "SHOW WARNINGS", &ret) == NULL ||
4838
 
      ret != DRIZZLE_RETURN_OK)
4839
 
  {
4840
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
4841
 
      die("Error running query \"SHOW WARNINGS\": %s", drizzle_result_error(&warn_res));
4842
 
    else
4843
 
      die("Error running query \"SHOW WARNINGS\": %s", drizzle_con_error(con));
4844
 
  }
4845
 
 
4846
 
  if (drizzle_result_column_count(&warn_res) == 0 ||
4847
 
      drizzle_result_buffer(&warn_res) != DRIZZLE_RETURN_OK)
4848
 
    die("Warning count is %u but didn't get any warnings", count);
4849
 
 
4850
 
  append_result(ds, &warn_res);
4851
 
  drizzle_result_free(&warn_res);
 
4913
  /*
 
4914
    If one day we will support execution of multi-statements
 
4915
    through PS API we should not issue SHOW WARNINGS until
 
4916
    we have not read all results...
 
4917
  */
 
4918
  assert(!drizzle_more_results(drizzle));
 
4919
 
 
4920
  if (drizzle_real_query(drizzle, "SHOW WARNINGS", 13))
 
4921
    die("Error running query \"SHOW WARNINGS\": %s", drizzle_error(drizzle));
 
4922
 
 
4923
  if (!(warn_res= drizzle_store_result(drizzle)))
 
4924
    die("Warning count is %u but didn't get any warnings",
 
4925
        count);
 
4926
 
 
4927
  append_result(ds, warn_res);
4852
4928
 
4853
4929
  return(count);
4854
4930
}
4872
4948
                             int flags, char *query, int query_len,
4873
4949
                             string *ds, string *ds_warnings)
4874
4950
{
4875
 
  drizzle_result_st res;
4876
 
  drizzle_return_t ret;
4877
 
  drizzle_con_st *con= &cn->con;
4878
 
  int err= 0;
4879
 
 
4880
 
  drizzle_con_add_options(con, DRIZZLE_CON_NO_RESULT_READ);
 
4951
  DRIZZLE_RES *res= 0;
 
4952
  DRIZZLE *drizzle= &cn->drizzle;
 
4953
  int err= 0, counter= 0;
4881
4954
 
4882
4955
  if (flags & QUERY_SEND_FLAG)
4883
4956
  {
4884
4957
    /*
4885
4958
     * Send the query
4886
4959
     */
4887
 
 
4888
 
    (void) drizzle_query(con, &res, query, query_len, &ret);
4889
 
    if (ret != DRIZZLE_RETURN_OK)
 
4960
    if (do_send_query(cn, query, query_len, flags))
4890
4961
    {
4891
 
      if (ret == DRIZZLE_RETURN_ERROR_CODE ||
4892
 
          ret == DRIZZLE_RETURN_HANDSHAKE_FAILED)
4893
 
      {
4894
 
        err= drizzle_result_error_code(&res);
4895
 
        handle_error(command, err, drizzle_result_error(&res),
4896
 
                     drizzle_result_sqlstate(&res), ds);
4897
 
        if (ret == DRIZZLE_RETURN_ERROR_CODE)
4898
 
          drizzle_result_free(&res);
4899
 
      }
4900
 
      else
4901
 
      {
4902
 
        handle_error(command, ret, drizzle_con_error(con), "", ds);
4903
 
        err= ret;
4904
 
      }
 
4962
      handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
 
4963
                   drizzle_sqlstate(drizzle), ds);
4905
4964
      goto end;
4906
4965
    }
4907
4966
  }
4908
4967
  if (!(flags & QUERY_REAP_FLAG))
4909
4968
    return;
4910
4969
 
 
4970
  do
4911
4971
  {
4912
4972
    /*
4913
 
     * Read the result packet
4914
 
     */
4915
 
    if (drizzle_result_read(con, &res, &ret) == NULL ||
4916
 
        ret != DRIZZLE_RETURN_OK)
 
4973
      When  on first result set, call drizzle_read_query_result to retrieve
 
4974
      answer to the query sent earlier
 
4975
    */
 
4976
    if ((counter==0) && drizzle_read_query_result(drizzle))
4917
4977
    {
4918
 
      if (ret == DRIZZLE_RETURN_ERROR_CODE)
4919
 
      {
4920
 
        handle_error(command, drizzle_result_error_code(&res),
4921
 
                     drizzle_result_error(&res), drizzle_result_sqlstate(&res),
4922
 
                     ds);
4923
 
      }
4924
 
      else
4925
 
        handle_error(command, ret, drizzle_con_error(con), "", ds);
4926
 
      drizzle_result_free(&res);
4927
 
      err= ret;
 
4978
      handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
 
4979
                   drizzle_sqlstate(drizzle), ds);
4928
4980
      goto end;
 
4981
 
4929
4982
    }
4930
4983
 
4931
4984
    /*
4932
4985
      Store the result of the query if it will return any fields
4933
4986
    */
4934
 
    if (drizzle_result_column_count(&res) &&
4935
 
        (ret= drizzle_result_buffer(&res)) != DRIZZLE_RETURN_OK)
 
4987
    if (drizzle_field_count(drizzle) && ((res= drizzle_store_result(drizzle)) == 0))
4936
4988
    {
4937
 
      if (ret == DRIZZLE_RETURN_ERROR_CODE)
4938
 
      {
4939
 
        handle_error(command, drizzle_result_error_code(&res),
4940
 
                     drizzle_result_error(&res), drizzle_result_sqlstate(&res),
4941
 
                     ds);
4942
 
      }
4943
 
      else
4944
 
        handle_error(command, ret, drizzle_con_error(con), "", ds);
4945
 
      drizzle_result_free(&res);
4946
 
      err= ret;
 
4989
      handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
 
4990
                   drizzle_sqlstate(drizzle), ds);
4947
4991
      goto end;
4948
4992
    }
4949
4993
 
4951
4995
    {
4952
4996
      uint64_t affected_rows= 0;    /* Ok to be undef if 'disable_info' is set */
4953
4997
 
4954
 
      if (drizzle_result_column_count(&res))
 
4998
      if (res)
4955
4999
      {
 
5000
        const DRIZZLE_FIELD *fields= drizzle_fetch_fields(res);
 
5001
        uint num_fields= drizzle_num_fields(res);
 
5002
 
4956
5003
        if (display_metadata)
4957
 
          append_metadata(ds, &res);
 
5004
          append_metadata(ds, fields, num_fields);
4958
5005
 
4959
5006
        if (!display_result_vertically)
4960
 
          append_table_headings(ds, &res);
 
5007
          append_table_headings(ds, fields, num_fields);
4961
5008
 
4962
 
        append_result(ds, &res);
 
5009
        append_result(ds, res);
4963
5010
      }
4964
5011
 
4965
5012
      /*
4966
 
        Need to call drizzle_result_affected_rows() before the "new"
 
5013
        Need to call drizzle_affected_rows() before the "new"
4967
5014
        query to find the warnings
4968
5015
      */
4969
5016
      if (!disable_info)
4970
 
        affected_rows= drizzle_result_affected_rows(&res);
 
5017
        affected_rows= drizzle_affected_rows(drizzle);
4971
5018
 
4972
5019
      /*
4973
5020
        Add all warnings to the result. We can't do this if we are in
4974
5021
        the middle of processing results from multi-statement, because
4975
5022
        this will break protocol.
4976
5023
      */
4977
 
      if (!disable_warnings)
 
5024
      if (!disable_warnings && !drizzle_more_results(drizzle))
4978
5025
      {
4979
 
        drizzle_con_remove_options(con, DRIZZLE_CON_NO_RESULT_READ);
4980
 
        if (append_warnings(ds_warnings, con, &res) || ds_warnings->length())
 
5026
        if (append_warnings(ds_warnings, drizzle) || ds_warnings->length())
4981
5027
        {
4982
5028
          ds->append("Warnings:\n", 10);
4983
5029
          ds->append(ds_warnings->c_str(), ds_warnings->length());
4985
5031
      }
4986
5032
 
4987
5033
      if (!disable_info)
4988
 
        append_info(ds, affected_rows, drizzle_result_info(&res));
 
5034
        append_info(ds, affected_rows, drizzle_info(drizzle));
4989
5035
    }
4990
5036
 
4991
 
    drizzle_result_free(&res);
 
5037
    if (res)
 
5038
    {
 
5039
      drizzle_free_result(res);
 
5040
      res= 0;
 
5041
    }
 
5042
    counter++;
 
5043
  } while (!(err= drizzle_next_result(drizzle)));
 
5044
  if (err > 0)
 
5045
  {
 
5046
    /* We got an error from drizzle_next_result, maybe expected */
 
5047
    handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
 
5048
                 drizzle_sqlstate(drizzle), ds);
 
5049
    goto end;
4992
5050
  }
 
5051
  assert(err == -1); /* Successful and there are no more results */
4993
5052
 
4994
5053
  /* If we come here the query is both executed and read successfully */
4995
5054
  handle_no_error(command);
4997
5056
end:
4998
5057
 
4999
5058
  /*
5000
 
    We save the return code (drizzleclient_errno(drizzle)) from the last call sent
5001
 
    to the server into the drizzletest builtin variable $drizzleclient_errno. This
 
5059
    We save the return code (drizzle_errno(drizzle)) from the last call sent
 
5060
    to the server into the drizzletest builtin variable $drizzle_errno. This
5002
5061
    variable then can be used from the test case itself.
5003
5062
  */
5004
 
  drizzle_con_remove_options(con, DRIZZLE_CON_NO_RESULT_READ);
5005
 
  var_set_errno(err);
 
5063
  var_set_errno(drizzle_errno(drizzle));
5006
5064
  return;
5007
5065
}
5008
5066
 
5027
5085
                  unsigned int err_errno, const char *err_error,
5028
5086
                  const char *err_sqlstate, string *ds)
5029
5087
{
5030
 
  uint32_t i;
5031
 
 
5032
 
 
5033
 
  if (! command->require_file.empty())
 
5088
  uint i;
 
5089
 
 
5090
 
 
5091
  if (command->require_file[0])
5034
5092
  {
5035
5093
    /*
5036
5094
      The query after a "--require" failed. This is fine as long the server
5037
5095
      returned a valid reponse. Don't allow 2013 or 2006 to trigger an
5038
5096
      abort_not_supported_test
5039
5097
    */
5040
 
    if (err_errno == DRIZZLE_RETURN_SERVER_GONE)
 
5098
    if (err_errno == CR_SERVER_LOST ||
 
5099
        err_errno == CR_SERVER_GONE_ERROR)
5041
5100
      die("require query '%s' failed: %d: %s", command->query,
5042
5101
          err_errno, err_error);
5043
5102
 
5049
5108
  if (command->abort_on_error)
5050
5109
    die("query '%s' failed: %d: %s", command->query, err_errno, err_error);
5051
5110
 
5052
 
  for (i= 0 ; (uint32_t) i < command->expected_errors.count ; i++)
 
5111
  for (i= 0 ; (uint) i < command->expected_errors.count ; i++)
5053
5112
  {
5054
5113
    if (((command->expected_errors.err[i].type == ERR_ERRNO) &&
5055
5114
         (command->expected_errors.err[i].code.errnum == err_errno)) ||
5056
5115
        ((command->expected_errors.err[i].type == ERR_SQLSTATE) &&
5057
5116
         (strncmp(command->expected_errors.err[i].code.sqlstate,
5058
 
                  err_sqlstate, DRIZZLE_MAX_SQLSTATE_SIZE) == 0)))
 
5117
                  err_sqlstate, SQLSTATE_LENGTH) == 0)))
5059
5118
    {
5060
5119
      if (!disable_result_log)
5061
5120
      {
5189
5248
    Create a temporary dynamic string to contain the output from
5190
5249
    this query.
5191
5250
  */
5192
 
  if (! command->require_file.empty())
 
5251
  if (command->require_file[0])
5193
5252
  {
5194
5253
    ds= &ds_result;
5195
5254
  }
5232
5291
    ds= save_ds;
5233
5292
  }
5234
5293
 
5235
 
  if (! command->require_file.empty())
 
5294
  if (command->require_file[0])
5236
5295
  {
5237
5296
    /* A result file was specified for _this_ query
5238
5297
       and the output should be checked against an already
5250
5309
static void get_command_type(struct st_command* command)
5251
5310
{
5252
5311
  char save;
5253
 
  uint32_t type;
 
5312
  uint type;
5254
5313
 
5255
5314
 
5256
5315
  if (*command->query == '}')
5333
5392
 
5334
5393
*/
5335
5394
 
5336
 
static void mark_progress(struct st_command*, int line)
 
5395
static void mark_progress(struct st_command* command __attribute__((unused)),
 
5396
                          int line)
5337
5397
{
 
5398
  char buf[32], *end;
5338
5399
  uint64_t timer= timer_now();
5339
5400
  if (!progress_start)
5340
5401
    progress_start= timer;
5341
5402
  timer-= progress_start;
5342
5403
 
5343
 
  ostringstream buf;
5344
5404
  /* Milliseconds since start */
5345
 
  buf << timer << "\t";
 
5405
  end= int64_t2str(timer, buf, 10);
 
5406
  ds_progress.append(buf, (int)(end-buf));
 
5407
  ds_progress.append("\t", 1);
5346
5408
 
5347
5409
  /* Parser line number */
5348
 
  buf << line << "\t";
 
5410
  end= int10_to_str(line, buf, 10);
 
5411
  ds_progress.append(buf, (int)(end-buf));
 
5412
  ds_progress.append("\t", 1);
5349
5413
 
5350
5414
  /* Filename */
5351
 
  buf << cur_file->file_name << ":";
 
5415
  ds_progress.append(cur_file->file_name);
 
5416
  ds_progress.append(":", 1);
5352
5417
 
5353
5418
  /* Line in file */
5354
 
  buf << cur_file->lineno << endl;
5355
 
 
5356
 
  ds_progress.append(buf.str());
5357
 
 
5358
 
}
5359
 
 
5360
 
static void check_retries(uint32_t in_opt_max_connect_retries)
5361
 
{
5362
 
  if (in_opt_max_connect_retries > 10000 || opt_max_connect_retries<1)
5363
 
  {
5364
 
    cout << N_("Error: Invalid Value for opt_max_connect_retries"); 
5365
 
    exit(-1);
5366
 
  }
5367
 
  opt_max_connect_retries= in_opt_max_connect_retries;
5368
 
}
5369
 
 
5370
 
static void check_tail_lines(uint32_t in_opt_tail_lines)
5371
 
{
5372
 
  if (in_opt_tail_lines > 10000)
5373
 
  {
5374
 
    cout << N_("Error: Invalid Value for opt_tail_lines"); 
5375
 
    exit(-1);
5376
 
  }
5377
 
  opt_tail_lines= in_opt_tail_lines;
5378
 
}
5379
 
 
5380
 
static void check_sleep(int32_t in_opt_sleep)
5381
 
{
5382
 
  if (in_opt_sleep < -1)
5383
 
  {
5384
 
    cout << N_("Error: Invalid Value for opt_sleep"); 
5385
 
    exit(-1);
5386
 
  }
5387
 
  opt_sleep= in_opt_sleep;
5388
 
}
 
5419
  end= int10_to_str(cur_file->lineno, buf, 10);
 
5420
  ds_progress.append(buf, (int)(end-buf));
 
5421
 
 
5422
 
 
5423
  ds_progress.append("\n", 1);
 
5424
 
 
5425
}
 
5426
 
5389
5427
 
5390
5428
int main(int argc, char **argv)
5391
5429
{
5392
 
try
5393
 
{
5394
5430
  struct st_command *command;
5395
5431
  bool q_send_flag= 0, abort_flag= 0;
5396
 
  uint32_t command_executed= 0, last_command_executed= 0;
5397
 
  string save_file("");
 
5432
  uint command_executed= 0, last_command_executed= 0;
 
5433
  char save_file[FN_REFLEN];
5398
5434
  struct stat res_info;
 
5435
  MY_INIT(argv[0]);
5399
5436
 
 
5437
  save_file[0]= 0;
5400
5438
  TMPDIR[0]= 0;
5401
5439
 
5402
 
  internal::my_init();
5403
 
 
5404
 
  po::options_description commandline_options("Options used only in command line");
5405
 
  commandline_options.add_options()
5406
 
  ("help,?", "Display this help and exit.")
5407
 
  ("mark-progress", po::value<bool>(&opt_mark_progress)->default_value(false)->zero_tokens(),
5408
 
  "Write linenumber and elapsed time to <testname>.progress ")
5409
 
  ("sleep,T", po::value<int32_t>(&opt_sleep)->default_value(-1)->notifier(&check_sleep),
5410
 
  "Sleep always this many seconds on sleep commands.")
5411
 
  ("test-file,x", po::value<string>(),
5412
 
  "Read test from/in this file (default stdin).")
5413
 
  ("timer-file,f", po::value<string>(),
5414
 
  "File where the timing in micro seconds is stored.")
5415
 
  ("tmpdir,t", po::value<string>(),
5416
 
  "Temporary directory where sockets are put.")
5417
 
  ("verbose,v", po::value<bool>(&verbose)->default_value(false),
5418
 
  "Write more.")
5419
 
  ("version,V", "Output version information and exit.")
5420
 
  ("no-defaults", po::value<bool>()->default_value(false)->zero_tokens(),
5421
 
  "Configuration file defaults are not used if no-defaults is set")
5422
 
  ;
5423
 
 
5424
 
  po::options_description test_options("Options specific to the drizzleimport");
5425
 
  test_options.add_options()
5426
 
  ("basedir,b", po::value<string>(&opt_basedir)->default_value(""),
5427
 
  "Basedir for tests.")
5428
 
  ("character-sets-dir", po::value<string>(&opt_charsets_dir)->default_value(""),
5429
 
  "Directory where character sets are.")
5430
 
  ("database,D", po::value<string>(&opt_db)->default_value(""),
5431
 
  "Database to use.")
5432
 
  ("include,i", po::value<string>(&opt_include)->default_value(""),
5433
 
  "Include SQL before each test case.")  
5434
 
  ("testdir", po::value<string>(&opt_testdir)->default_value(""),
5435
 
  "Path to use to search for test files")
5436
 
  ("logdir", po::value<string>(&opt_logdir)->default_value(""),
5437
 
  "Directory for log files")
5438
 
  ("max-connect-retries", po::value<uint32_t>(&opt_max_connect_retries)->default_value(500)->notifier(&check_retries),
5439
 
  "Max number of connection attempts when connecting to server")
5440
 
  ("quiet,s", po::value<bool>(&silent)->default_value(false)->zero_tokens(),
5441
 
  "Suppress all normal output.")
5442
 
  ("record,r", "Record output of test_file into result file.")
5443
 
  ("result-file,R", po::value<string>(&result_file_name)->default_value(""),
5444
 
  "Read/Store result from/in this file.")
5445
 
  ("silent,s", po::value<bool>(&silent)->default_value(false)->zero_tokens(),
5446
 
  "Suppress all normal output. Synonym for --quiet.")
5447
 
  ("tail-lines", po::value<uint32_t>(&opt_tail_lines)->default_value(0)->notifier(&check_tail_lines),
5448
 
  "Number of lines of the resul to include in a failure report")
5449
 
  ;
5450
 
 
5451
 
  po::options_description client_options("Options specific to the client");
5452
 
  client_options.add_options()
5453
 
 
5454
 
  ("host,h", po::value<string>(&opt_host)->default_value("localhost"),
5455
 
  "Connect to host.")
5456
 
  ("password,P", po::value<string>(&password)->default_value("PASSWORD_SENTINEL"),
5457
 
  "Password to use when connecting to server.")
5458
 
  ("port,p", po::value<uint32_t>(&opt_port)->default_value(0),
5459
 
  "Port number to use for connection or 0 for default")
5460
 
  ("protocol", po::value<string>(&opt_protocol),
5461
 
  "The protocol of connection (mysql or drizzle).")
5462
 
  ("user,u", po::value<string>(&opt_user)->default_value(""),
5463
 
  "User for login.")
5464
 
  ;
5465
 
 
5466
 
  po::positional_options_description p;
5467
 
  p.add("database", 1);
5468
 
 
5469
 
  po::options_description long_options("Allowed Options");
5470
 
  long_options.add(commandline_options).add(test_options).add(client_options);
5471
 
 
5472
 
  std::string system_config_dir_test(SYSCONFDIR); 
5473
 
  system_config_dir_test.append("/drizzle/drizzletest.cnf");
5474
 
 
5475
 
  std::string system_config_dir_client(SYSCONFDIR); 
5476
 
  system_config_dir_client.append("/drizzle/client.cnf");
5477
 
 
5478
 
  std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
5479
 
 
5480
 
  po::variables_map vm;
5481
 
 
5482
 
  // Disable allow_guessing
5483
 
  int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
5484
 
 
5485
 
  po::store(po::command_line_parser(argc, argv).options(long_options).
5486
 
            style(style).positional(p).extra_parser(parse_password_arg).run(),
5487
 
            vm);
5488
 
 
5489
 
  if (! vm["no-defaults"].as<bool>())
5490
 
  {
5491
 
    std::string user_config_dir_test(user_config_dir);
5492
 
    user_config_dir_test.append("/drizzle/drizzletest.cnf"); 
5493
 
 
5494
 
    std::string user_config_dir_client(user_config_dir);
5495
 
    user_config_dir_client.append("/drizzle/client.cnf");
5496
 
 
5497
 
    ifstream user_test_ifs(user_config_dir_test.c_str());
5498
 
    po::store(parse_config_file(user_test_ifs, test_options), vm);
5499
 
 
5500
 
    ifstream user_client_ifs(user_config_dir_client.c_str());
5501
 
    po::store(parse_config_file(user_client_ifs, client_options), vm);
5502
 
 
5503
 
    ifstream system_test_ifs(system_config_dir_test.c_str());
5504
 
    store(parse_config_file(system_test_ifs, test_options), vm);
5505
 
 
5506
 
    ifstream system_client_ifs(system_config_dir_client.c_str());
5507
 
    po::store(parse_config_file(system_client_ifs, client_options), vm);
5508
 
  }
5509
 
 
5510
 
  po::notify(vm);
5511
 
 
5512
5440
  /* Init expected errors */
5513
5441
  memset(&saved_expected_errors, 0, sizeof(saved_expected_errors));
5514
5442
 
5532
5460
  cur_block->ok= true; /* Outer block should always be executed */
5533
5461
  cur_block->cmd= cmd_none;
5534
5462
 
5535
 
  var_set_string("$DRIZZLE_SERVER_VERSION", drizzle_version());
 
5463
  if (hash_init(&var_hash, charset_info,
 
5464
                1024, 0, 0, get_var_key, var_free, MYF(0)))
 
5465
    die("Variable hash initialization failed");
 
5466
 
 
5467
  var_set_string("$DRIZZLE_SERVER_VERSION", drizzle_get_client_info());
5536
5468
 
5537
5469
  memset(&master_pos, 0, sizeof(master_pos));
5538
5470
 
5545
5477
  ds_progress.reserve(2048);
5546
5478
  ds_warning_messages.reserve(2048);
5547
5479
 
5548
 
 
5549
 
  if (vm.count("record"))
5550
 
  {
5551
 
    record = 1;
5552
 
  }
5553
 
 
5554
 
  if (vm.count("test-file"))
5555
 
  {
5556
 
    string tmp= vm["test-file"].as<string>();
5557
 
    char buff[FN_REFLEN];
5558
 
    if (!internal::test_if_hard_path(tmp.c_str()))
5559
 
    {
5560
 
      snprintf(buff, sizeof(buff), "%s%s",opt_basedir.c_str(),tmp.c_str());
5561
 
      tmp= buff;
5562
 
    }
5563
 
    internal::fn_format(buff, tmp.c_str(), "", "", MY_UNPACK_FILENAME);
5564
 
    assert(cur_file == file_stack && cur_file->file == 0);
5565
 
    if (!(cur_file->file= fopen(buff, "r")))
5566
 
    {
5567
 
      fprintf(stderr, _("Could not open '%s' for reading: errno = %d"), buff, errno);
5568
 
      return EXIT_ARGUMENT_INVALID;
5569
 
    }
5570
 
    if (!(cur_file->file_name= strdup(buff)))
5571
 
    {
5572
 
      fprintf(stderr, _("Out of memory"));
5573
 
      return EXIT_OUT_OF_MEMORY;
5574
 
    }
5575
 
    cur_file->lineno= 1;
5576
 
  }
5577
 
 
5578
 
  if (vm.count("timer-file"))
5579
 
  {
5580
 
    string tmp= vm["timer-file"].as<string>().c_str();
5581
 
    static char buff[FN_REFLEN];
5582
 
    if (!internal::test_if_hard_path(tmp.c_str()))
5583
 
    {
5584
 
      snprintf(buff, sizeof(buff), "%s%s",opt_basedir.c_str(),tmp.c_str());
5585
 
      tmp= buff;
5586
 
    }
5587
 
    internal::fn_format(buff, tmp.c_str(), "", "", MY_UNPACK_FILENAME);
5588
 
    timer_file= buff;
5589
 
    unlink(timer_file);       /* Ignore error, may not exist */
5590
 
  }
5591
 
 
5592
 
  if (vm.count("protocol"))
5593
 
  {
5594
 
    std::transform(opt_protocol.begin(), opt_protocol.end(),
5595
 
      opt_protocol.begin(), ::tolower);
5596
 
 
5597
 
    if (not opt_protocol.compare("mysql"))
5598
 
      use_drizzle_protocol=false;
5599
 
    else if (not opt_protocol.compare("drizzle"))
5600
 
      use_drizzle_protocol=true;
5601
 
    else
5602
 
    {
5603
 
      cout << _("Error: Unknown protocol") << " '" << opt_protocol << "'" << endl;
5604
 
      exit(-1);
5605
 
    }
5606
 
  }
5607
 
 
5608
 
  if (vm.count("port"))
5609
 
  {
5610
 
    /* If the port number is > 65535 it is not a valid port
5611
 
       This also helps with potential data loss casting unsigned long to a
5612
 
       uint32_t. */
5613
 
    if (opt_port > 65535)
5614
 
    {
5615
 
      fprintf(stderr, _("Value supplied for port is not valid.\n"));
5616
 
      exit(EXIT_ARGUMENT_INVALID);
5617
 
    }
5618
 
  }
5619
 
 
5620
 
  if( vm.count("password") )
5621
 
  {
5622
 
    if (!opt_password.empty())
5623
 
      opt_password.erase();
5624
 
    if (password == PASSWORD_SENTINEL)
5625
 
    {
5626
 
      opt_password= "";
5627
 
    }
5628
 
    else
5629
 
    {
5630
 
      opt_password= password;
5631
 
      tty_password= false;
5632
 
    }
5633
 
  }
5634
 
  else
5635
 
  {
5636
 
      tty_password= true;
5637
 
  }
5638
 
 
5639
 
  if (vm.count("tmpdir"))
5640
 
  {
5641
 
    strncpy(TMPDIR, vm["tmpdir"].as<string>().c_str(), sizeof(TMPDIR));
5642
 
  }
5643
 
 
5644
 
  if (vm.count("version"))
5645
 
  {
5646
 
    printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname,MTEST_VERSION,
5647
 
    drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
5648
 
    exit(0);
5649
 
  }
5650
 
  
5651
 
  if (vm.count("help"))
5652
 
  {
5653
 
    printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname,MTEST_VERSION,
5654
 
    drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
5655
 
    printf("MySQL AB, by Sasha, Matt, Monty & Jani\n");
5656
 
    printf("Drizzle version modified by Brian, Jay, Monty Taylor, PatG and Stewart\n");
5657
 
    printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
5658
 
    printf("Runs a test against the DRIZZLE server and compares output with a results file.\n\n");
5659
 
    printf("Usage: %s [OPTIONS] [database] < test_file\n", internal::my_progname);
5660
 
    exit(0);
5661
 
  }
5662
 
 
5663
 
  if (tty_password)
5664
 
  {
5665
 
    opt_pass= client_get_tty_password(NULL);          /* purify tested */
5666
 
  }
 
5480
  parse_args(argc, argv);
5667
5481
 
5668
5482
  server_initialized= 1;
5669
5483
  if (cur_file == file_stack && cur_file->file == 0)
5670
5484
  {
5671
5485
    cur_file->file= stdin;
5672
 
    cur_file->file_name= strdup("<stdin>");
5673
 
    if (cur_file->file_name == NULL)
5674
 
      die("Out of memory");
 
5486
    cur_file->file_name= my_strdup("<stdin>", MYF(MY_WME));
5675
5487
    cur_file->lineno= 1;
5676
5488
  }
5677
5489
  cur_con= connections;
5678
 
  if ((cur_con->drizzle= drizzle_create(NULL)) == NULL)
 
5490
  if (!( drizzle_create(&cur_con->drizzle)))
5679
5491
    die("Failed in drizzle_create()");
5680
 
  if (!( drizzle_con_create(cur_con->drizzle, &cur_con->con)))
5681
 
    die("Failed in drizzle_con_create()");
5682
 
  drizzle_con_add_options(&cur_con->con, use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL);
 
5492
  if (opt_compress)
 
5493
    drizzle_options(&cur_con->drizzle,DRIZZLE_OPT_COMPRESS,NULL);
 
5494
  drizzle_options(&cur_con->drizzle, DRIZZLE_OPT_LOCAL_INFILE, 0);
5683
5495
 
5684
 
  if (!(cur_con->name = strdup("default")))
 
5496
  if (!(cur_con->name = my_strdup("default", MYF(MY_WME))))
5685
5497
    die("Out of memory");
5686
 
  safe_connect(&cur_con->con, cur_con->name, opt_host, opt_user, opt_pass,
 
5498
 
 
5499
  safe_connect(&cur_con->drizzle, cur_con->name, opt_host, opt_user, opt_pass,
5687
5500
               opt_db, opt_port);
5688
5501
 
5689
5502
  /* Use all time until exit if no explicit 'start_timer' */
5690
5503
  timer_start= timer_now();
5691
5504
 
5692
5505
  /*
5693
 
    Initialize $drizzleclient_errno with -1, so we can
 
5506
    Initialize $drizzle_errno with -1, so we can
5694
5507
    - distinguish it from valid values ( >= 0 ) and
5695
5508
    - detect if there was never a command sent to the server
5696
5509
  */
5697
5510
  var_set_errno(-1);
5698
5511
 
5699
 
  /* Update $drizzleclient_get_server_version to that of current connection */
5700
 
  var_set_drizzleclient_get_server_version(&cur_con->con);
 
5512
  /* Update $drizzle_get_server_version to that of current connection */
 
5513
  var_set_drizzle_get_server_version(&cur_con->drizzle);
5701
5514
 
5702
 
  if (! opt_include.empty())
 
5515
  if (opt_include)
5703
5516
  {
5704
 
    open_file(opt_include.c_str());
 
5517
    open_file(opt_include);
5705
5518
  }
5706
5519
 
5707
5520
  while (!read_command(&command) && !abort_flag)
5815
5628
        /* Check for special property for this query */
5816
5629
        display_result_vertically|= (command->type == Q_QUERY_VERTICAL);
5817
5630
 
5818
 
        if (! save_file.empty())
 
5631
        if (save_file[0])
5819
5632
        {
5820
 
          command->require_file= save_file;
5821
 
          save_file.clear();
 
5633
          strmake(command->require_file, save_file, sizeof(save_file) - 1);
 
5634
          save_file[0]= 0;
5822
5635
        }
5823
5636
        run_query(cur_con, command, flags);
5824
5637
        command_executed++;
5855
5668
        command->last_argument= command->end;
5856
5669
        break;
5857
5670
      case Q_REQUIRE:
5858
 
        do_get_file_name(command, save_file);
 
5671
        do_get_file_name(command, save_file, sizeof(save_file));
5859
5672
        break;
5860
5673
      case Q_ERROR:
5861
5674
        do_get_errcodes(command);
5885
5698
        command->last_argument= command->end;
5886
5699
        break;
5887
5700
      case Q_PING:
5888
 
        {
5889
 
          drizzle_result_st result;
5890
 
          drizzle_return_t ret;
5891
 
          (void) drizzle_ping(&cur_con->con, &result, &ret);
5892
 
          if (ret == DRIZZLE_RETURN_OK || ret == DRIZZLE_RETURN_ERROR_CODE)
5893
 
            drizzle_result_free(&result);
5894
 
        }
 
5701
        (void) drizzle_ping(&cur_con->drizzle);
5895
5702
        break;
5896
5703
      case Q_EXEC:
5897
5704
        do_exec(command);
5909
5716
        do_set_charset(command);
5910
5717
        break;
5911
5718
      case Q_DISABLE_RECONNECT:
5912
 
        set_reconnect(&cur_con->con, 0);
 
5719
        set_reconnect(&cur_con->drizzle, 0);
5913
5720
        break;
5914
5721
      case Q_ENABLE_RECONNECT:
5915
 
        set_reconnect(&cur_con->con, 1);
 
5722
        set_reconnect(&cur_con->drizzle, 1);
5916
5723
        break;
5917
5724
      case Q_DISABLE_PARSING:
5918
5725
        if (parsing_disabled == 0)
6005
5812
  */
6006
5813
  if (ds_res.length())
6007
5814
  {
6008
 
    if (! result_file_name.empty())
 
5815
    if (result_file_name)
6009
5816
    {
6010
5817
      /* A result file has been specified */
6011
5818
 
6012
5819
      if (record)
6013
5820
      {
6014
5821
        /* Recording - dump the output from test to result file */
6015
 
        str_to_file(result_file_name.c_str(), ds_res.c_str(), ds_res.length());
 
5822
        str_to_file(result_file_name, ds_res.c_str(), ds_res.length());
6016
5823
      }
6017
5824
      else
6018
5825
      {
6035
5842
  }
6036
5843
 
6037
5844
  if (!command_executed &&
6038
 
      ! result_file_name.empty() && !stat(result_file_name.c_str(), &res_info))
 
5845
      result_file_name && !stat(result_file_name, &res_info))
6039
5846
  {
6040
5847
    /*
6041
5848
      my_stat() successful on result file. Check if we have not run a
6047
5854
    die("No queries executed but result file found!");
6048
5855
  }
6049
5856
 
6050
 
  if ( opt_mark_progress && ! result_file_name.empty() )
 
5857
  if ( opt_mark_progress && result_file_name )
6051
5858
    dump_progress();
6052
5859
 
6053
5860
  /* Dump warning messages */
6054
 
  if (! result_file_name.empty() && ds_warning_messages.length())
 
5861
  if (result_file_name && ds_warning_messages.length())
6055
5862
    dump_warning_messages();
6056
5863
 
6057
5864
  timer_output();
6058
5865
  /* Yes, if we got this far the test has suceeded! Sakila smiles */
6059
5866
  cleanup_and_exit(0);
6060
 
}
6061
 
 
6062
 
  catch(exception &err)
6063
 
  {
6064
 
    cerr<<err.what()<<endl;
6065
 
  }
6066
 
 
6067
5867
  return 0; /* Keep compiler happy too */
6068
5868
}
6069
5869
 
6093
5893
{
6094
5894
  if (timer_file)
6095
5895
  {
6096
 
    ostringstream buf;
 
5896
    char buf[32], *end;
6097
5897
    uint64_t timer= timer_now() - timer_start;
6098
 
    buf << timer;
6099
 
    str_to_file(timer_file,buf.str().c_str(), buf.str().size() );
 
5898
    end= int64_t2str(timer, buf, 10);
 
5899
    str_to_file(timer_file,buf, (int) (end-buf));
6100
5900
    /* Timer has been written to the file, don't use it anymore */
6101
5901
    timer_file= 0;
6102
5902
  }
6105
5905
 
6106
5906
uint64_t timer_now(void)
6107
5907
{
6108
 
#if defined(HAVE_GETHRTIME)
6109
 
  return gethrtime()/1000/1000;
6110
 
#else
6111
 
  uint64_t newtime;
6112
 
  struct timeval t;
6113
 
  /*
6114
 
    The following loop is here because gettimeofday may fail on some systems
6115
 
  */
6116
 
  while (gettimeofday(&t, NULL) != 0)
6117
 
  {}
6118
 
  newtime= (uint64_t)t.tv_sec * 1000000 + t.tv_usec;
6119
 
  return newtime/1000;
6120
 
#endif  /* defined(HAVE_GETHRTIME) */
 
5908
  return my_micro_time() / 1000;
6121
5909
}
6122
5910
 
6123
5911
 
6140
5928
    die("Missing argument in %s", command->query);
6141
5929
 
6142
5930
  /* Allocate a buffer for results */
6143
 
  start= buff= (char *)malloc(strlen(from)+1);
 
5931
  start= buff= (char *)my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE));
6144
5932
  while (*from)
6145
5933
  {
6146
5934
    char *to;
6147
 
    uint32_t column_number;
 
5935
    uint column_number;
6148
5936
 
6149
5937
    to= get_string(&buff, &from, command);
6150
5938
    if (!(column_number= atoi(to)) || column_number > MAX_COLUMNS)
6153
5941
      die("Wrong number of arguments to replace_column in '%s'", command->query);
6154
5942
    to= get_string(&buff, &from, command);
6155
5943
    free(replace_column[column_number-1]);
6156
 
    replace_column[column_number-1]= strdup(to);
6157
 
    if (replace_column[column_number-1] == NULL)
6158
 
      die("Out of memory");
 
5944
    replace_column[column_number-1]= my_strdup(to, MYF(MY_WME | MY_FAE));
6159
5945
    set_if_bigger(max_replace_column, column_number);
6160
5946
  }
6161
5947
  free(start);
6165
5951
 
6166
5952
void free_replace_column()
6167
5953
{
6168
 
  uint32_t i;
 
5954
  uint i;
6169
5955
  for (i=0 ; i < max_replace_column ; i++)
6170
5956
  {
6171
5957
    if (replace_column[i])
6189
5975
  TYPELIB typelib;        /* Pointer to strings */
6190
5976
  unsigned char  *str;          /* Strings is here */
6191
5977
  uint8_t *flag;          /* Flag about each var. */
6192
 
  uint32_t  array_allocs,max_count,length,max_length;
 
5978
  uint  array_allocs,max_count,length,max_length;
6193
5979
} POINTER_ARRAY;
6194
5980
 
6195
5981
struct st_replace;
6196
 
struct st_replace *init_replace(char * *from, char * *to, uint32_t count,
 
5982
struct st_replace *init_replace(char * *from, char * *to, uint count,
6197
5983
                                char * word_end_chars);
6198
5984
int insert_pointer_name(POINTER_ARRAY *pa,char * name);
6199
5985
void replace_strings_append(struct st_replace *rep, string* ds,
6200
5986
                            const char *from, int len);
6201
5987
void free_pointer_array(POINTER_ARRAY *pa);
6202
5988
 
6203
 
struct st_replace *glob_replace= NULL;
 
5989
struct st_replace *glob_replace;
6204
5990
 
6205
5991
/*
6206
5992
  Get arguments for replace. The syntax is:
6212
5998
 
6213
5999
void do_get_replace(struct st_command *command)
6214
6000
{
6215
 
  uint32_t i;
 
6001
  uint i;
6216
6002
  char *from= command->first_argument;
6217
6003
  char *buff, *start;
6218
6004
  char word_end_chars[256], *pos;
6225
6011
  memset(&from_array, 0, sizeof(from_array));
6226
6012
  if (!*from)
6227
6013
    die("Missing argument in %s", command->query);
6228
 
  start= buff= (char *)malloc(strlen(from)+1);
 
6014
  start= buff= (char *)my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE));
6229
6015
  while (*from)
6230
6016
  {
6231
6017
    char *to= buff;
6243
6029
  *pos=0;          /* End pointer */
6244
6030
  if (!(glob_replace= init_replace((char**) from_array.typelib.type_names,
6245
6031
                                   (char**) to_array.typelib.type_names,
6246
 
                                   (uint32_t) from_array.typelib.count,
 
6032
                                   (uint) from_array.typelib.count,
6247
6033
                                   word_end_chars)))
6248
6034
    die("Can't initialize replace from '%s'", command->query);
6249
6035
  free_pointer_array(&from_array);
6274
6060
typedef struct st_replace_found {
6275
6061
  bool found;
6276
6062
  char *replace_string;
6277
 
  uint32_t to_offset;
 
6063
  uint to_offset;
6278
6064
  int from_offset;
6279
6065
} REPLACE_STRING;
6280
6066
 
6332
6118
  char* pattern; /* Pattern to be replaced */
6333
6119
  char* replace; /* String or expression to replace the pattern with */
6334
6120
  int icase; /* true if the match is case insensitive */
6335
 
  int global; /* true if the match should be global -- 
6336
 
                 i.e. repeat the matching until the end of the string */
6337
6121
};
6338
6122
 
6339
6123
struct st_replace_regex
6357
6141
struct st_replace_regex *glob_replace_regex= 0;
6358
6142
 
6359
6143
int reg_replace(char** buf_p, int* buf_len_p, char *pattern, char *replace,
6360
 
                char *string, int icase, int global);
 
6144
                char *string, int icase);
6361
6145
 
6362
6146
 
6363
6147
 
6402
6186
  char* buf,*expr_end;
6403
6187
  char* p;
6404
6188
  char* buf_p;
6405
 
  uint32_t expr_len= strlen(expr);
 
6189
  uint expr_len= strlen(expr);
6406
6190
  char last_c = 0;
6407
6191
  struct st_regex reg;
6408
6192
 
6409
 
  res=(st_replace_regex*)malloc(sizeof(*res)+expr_len);
6410
 
  if (!res)
6411
 
    return NULL;
 
6193
  /* my_malloc() will die on fail with MY_FAE */
 
6194
  res=(struct st_replace_regex*)my_malloc(
 
6195
                                          sizeof(*res)+expr_len ,MYF(MY_FAE+MY_WME));
6412
6196
  my_init_dynamic_array(&res->regex_arr,sizeof(struct st_regex),128,128);
6413
6197
 
6414
6198
  buf= (char*)res + sizeof(*res);
6458
6242
 
6459
6243
    /* Check if we should do matching case insensitive */
6460
6244
    if (p < expr_end && *p == 'i')
6461
 
    {
6462
 
      p++;
6463
6245
      reg.icase= 1;
6464
 
    }
6465
 
 
6466
 
    /* Check if we should do matching globally */
6467
 
    if (p < expr_end && *p == 'g')
6468
 
    {
6469
 
      p++;
6470
 
      reg.global= 1;
6471
 
    }
6472
6246
 
6473
6247
    /* done parsing the statement, now place it in regex_arr */
6474
6248
    if (insert_dynamic(&res->regex_arr,(unsigned char*) &reg))
6475
6249
      die("Out of memory");
6476
6250
  }
6477
6251
  res->odd_buf_len= res->even_buf_len= 8192;
6478
 
  res->even_buf= (char*)malloc(res->even_buf_len);
6479
 
  res->odd_buf= (char*)malloc(res->odd_buf_len);
 
6252
  res->even_buf= (char*)my_malloc(res->even_buf_len,MYF(MY_WME+MY_FAE));
 
6253
  res->odd_buf= (char*)my_malloc(res->odd_buf_len,MYF(MY_WME+MY_FAE));
6480
6254
  res->buf= res->even_buf;
6481
6255
 
6482
6256
  return res;
6508
6282
 
6509
6283
static int multi_reg_replace(struct st_replace_regex* r,char* val)
6510
6284
{
6511
 
  uint32_t i;
 
6285
  uint i;
6512
6286
  char* in_buf, *out_buf;
6513
6287
  int* buf_len_p;
6514
6288
 
6526
6300
    get_dynamic(&r->regex_arr,(unsigned char*)&re,i);
6527
6301
 
6528
6302
    if (!reg_replace(&out_buf, buf_len_p, re.pattern, re.replace,
6529
 
                     in_buf, re.icase, re.global))
 
6303
                     in_buf, re.icase))
6530
6304
    {
6531
6305
      /* if the buffer has been reallocated, make adjustements */
6532
6306
      if (save_out_buf != out_buf)
6584
6358
 
6585
6359
 
6586
6360
/*
 
6361
  auxiluary macro used by reg_replace
 
6362
  makes sure the result buffer has sufficient length
 
6363
*/
 
6364
#define SECURE_REG_BUF   if (buf_len < need_buf_len)                    \
 
6365
  {                                                                     \
 
6366
    int off= res_p - buf;                                               \
 
6367
    buf= (char*)my_realloc(buf,need_buf_len,MYF(MY_WME+MY_FAE));        \
 
6368
    res_p= buf + off;                                                   \
 
6369
    buf_len= need_buf_len;                                              \
 
6370
  }                                                                     \
 
6371
                                                                        \
 
6372
/*
6587
6373
  Performs a regex substitution
6588
6374
 
6589
6375
  IN:
6596
6382
  icase - flag, if set to 1 the match is case insensitive
6597
6383
*/
6598
6384
int reg_replace(char** buf_p, int* buf_len_p, char *pattern,
6599
 
                char *replace, char *in_string, int icase, int global)
 
6385
                char *replace, char *in_string, int icase)
6600
6386
{
6601
 
  const char *error= NULL;
6602
 
  int erroffset;
6603
 
  int ovector[3];
6604
 
  pcre *re= pcre_compile(pattern,
6605
 
                         icase ? PCRE_CASELESS | PCRE_MULTILINE : PCRE_MULTILINE,
6606
 
                         &error, &erroffset, NULL);
6607
 
  if (re == NULL)
6608
 
    return 1;
6609
 
 
6610
 
  if (! global)
6611
 
  {
6612
 
 
6613
 
    int rc= pcre_exec(re, NULL, in_string, (int)strlen(in_string),
6614
 
                      0, 0, ovector, 3);
6615
 
    if (rc < 0)
6616
 
    {
6617
 
      pcre_free(re);
6618
 
      return 1;
6619
 
    }
6620
 
 
6621
 
    char *substring_to_replace= in_string + ovector[0];
6622
 
    int substring_length= ovector[1] - ovector[0];
6623
 
    *buf_len_p= strlen(in_string) - substring_length + strlen(replace);
6624
 
    char * new_buf = (char *)malloc(*buf_len_p+1);
6625
 
    if (new_buf == NULL)
6626
 
    {
6627
 
      pcre_free(re);
6628
 
      return 1;
6629
 
    }
6630
 
 
6631
 
    memset(new_buf, 0, *buf_len_p+1);
6632
 
    strncpy(new_buf, in_string, substring_to_replace-in_string);
6633
 
    strncpy(new_buf+(substring_to_replace-in_string), replace, strlen(replace));
6634
 
    strncpy(new_buf+(substring_to_replace-in_string)+strlen(replace),
6635
 
            substring_to_replace + substring_length,
6636
 
            strlen(in_string)
6637
 
              - substring_length
6638
 
              - (substring_to_replace-in_string));
6639
 
    *buf_p= new_buf;
6640
 
 
6641
 
    pcre_free(re);
6642
 
    return 0;
6643
 
  }
6644
 
  else
6645
 
  {
6646
 
    /* Repeatedly replace the string with the matched regex */
6647
 
    string subject(in_string);
6648
 
    size_t replace_length= strlen(replace);
6649
 
    size_t length_of_replacement= strlen(replace);
6650
 
    size_t current_position= 0;
6651
 
    int rc= 0;
6652
 
 
6653
 
    while (true) 
6654
 
    {
6655
 
      rc= pcre_exec(re, NULL, subject.c_str(), subject.length(), 
6656
 
                    current_position, 0, ovector, 3);
6657
 
      if (rc < 0)
6658
 
      {
6659
 
        break;
6660
 
      }
6661
 
 
6662
 
      current_position= static_cast<size_t>(ovector[0]);
6663
 
      replace_length= static_cast<size_t>(ovector[1] - ovector[0]);
6664
 
      subject.replace(current_position, replace_length, replace, length_of_replacement);
6665
 
      current_position= current_position + length_of_replacement;
6666
 
    }
6667
 
 
6668
 
    char *new_buf = (char *) malloc(subject.length() + 1);
6669
 
    if (new_buf == NULL)
6670
 
    {
6671
 
      pcre_free(re);
6672
 
      return 1;
6673
 
    }
6674
 
    memset(new_buf, 0, subject.length() + 1);
6675
 
    strncpy(new_buf, subject.c_str(), subject.length());
6676
 
    *buf_len_p= subject.length() + 1;
6677
 
    *buf_p= new_buf;
6678
 
          
6679
 
    pcre_free(re);
6680
 
    return 0;
6681
 
  }
 
6387
  string string_to_match(in_string);
 
6388
  pcrecpp::RE_Options opt;
 
6389
 
 
6390
  if (icase)
 
6391
    opt.set_caseless(true);
 
6392
 
 
6393
  if (!pcrecpp::RE(pattern, opt).Replace(replace,&string_to_match)){
 
6394
    return 1;
 
6395
  }
 
6396
 
 
6397
  const char * new_str= string_to_match.c_str();
 
6398
  *buf_len_p= strlen(new_str);
 
6399
  char * new_buf = (char *)malloc(*buf_len_p+1);
 
6400
  if (new_buf == NULL)
 
6401
  {
 
6402
    return 1;
 
6403
  }
 
6404
  strcpy(new_buf, new_str);
 
6405
  *buf_p= new_buf;
 
6406
 
 
6407
  return 0;
6682
6408
}
6683
6409
 
6684
6410
 
6685
6411
#ifndef WORD_BIT
6686
 
#define WORD_BIT (8*sizeof(uint32_t))
 
6412
#define WORD_BIT (8*sizeof(uint))
6687
6413
#endif
6688
6414
 
6689
6415
#define SET_MALLOC_HUNC 64
6690
6416
#define LAST_CHAR_CODE 259
6691
6417
 
6692
6418
typedef struct st_rep_set {
6693
 
  uint32_t  *bits;        /* Pointer to used sets */
 
6419
  uint  *bits;        /* Pointer to used sets */
6694
6420
  short next[LAST_CHAR_CODE];    /* Pointer to next sets */
6695
 
  uint32_t  found_len;      /* Best match to date */
 
6421
  uint  found_len;      /* Best match to date */
6696
6422
  int  found_offset;
6697
 
  uint32_t  table_offset;
6698
 
  uint32_t  size_of_bits;      /* For convinience */
 
6423
  uint  table_offset;
 
6424
  uint  size_of_bits;      /* For convinience */
6699
6425
} REP_SET;
6700
6426
 
6701
6427
typedef struct st_rep_sets {
6702
 
  uint32_t    count;      /* Number of sets */
6703
 
  uint32_t    extra;      /* Extra sets in buffer */
6704
 
  uint32_t    invisible;    /* Sets not chown */
6705
 
  uint32_t    size_of_bits;
 
6428
  uint    count;      /* Number of sets */
 
6429
  uint    extra;      /* Extra sets in buffer */
 
6430
  uint    invisible;    /* Sets not chown */
 
6431
  uint    size_of_bits;
6706
6432
  REP_SET  *set,*set_buffer;
6707
 
  uint32_t    *bit_buffer;
 
6433
  uint    *bit_buffer;
6708
6434
} REP_SETS;
6709
6435
 
6710
6436
typedef struct st_found_set {
6711
 
  uint32_t table_offset;
 
6437
  uint table_offset;
6712
6438
  int found_offset;
6713
6439
} FOUND_SET;
6714
6440
 
6715
6441
typedef struct st_follow {
6716
6442
  int chr;
6717
 
  uint32_t table_offset;
6718
 
  uint32_t len;
 
6443
  uint table_offset;
 
6444
  uint len;
6719
6445
} FOLLOWS;
6720
6446
 
6721
6447
 
6722
 
int init_sets(REP_SETS *sets,uint32_t states);
 
6448
int init_sets(REP_SETS *sets,uint states);
6723
6449
REP_SET *make_new_set(REP_SETS *sets);
6724
6450
void make_sets_invisible(REP_SETS *sets);
6725
6451
void free_last_set(REP_SETS *sets);
6726
6452
void free_sets(REP_SETS *sets);
6727
 
void internal_set_bit(REP_SET *set, uint32_t bit);
6728
 
void internal_clear_bit(REP_SET *set, uint32_t bit);
 
6453
void internal_set_bit(REP_SET *set, uint bit);
 
6454
void internal_clear_bit(REP_SET *set, uint bit);
6729
6455
void or_bits(REP_SET *to,REP_SET *from);
6730
6456
void copy_bits(REP_SET *to,REP_SET *from);
6731
6457
int cmp_bits(REP_SET *set1,REP_SET *set2);
6732
 
int get_next_bit(REP_SET *set,uint32_t lastpos);
 
6458
int get_next_bit(REP_SET *set,uint lastpos);
6733
6459
int find_set(REP_SETS *sets,REP_SET *find);
6734
 
int find_found(FOUND_SET *found_set,uint32_t table_offset,
 
6460
int find_found(FOUND_SET *found_set,uint table_offset,
6735
6461
               int found_offset);
6736
 
uint32_t start_at_word(char * pos);
6737
 
uint32_t end_of_word(char * pos);
6738
 
 
6739
 
static uint32_t found_sets=0;
6740
 
 
6741
 
 
6742
 
static uint32_t replace_len(char * str)
 
6462
uint start_at_word(char * pos);
 
6463
uint end_of_word(char * pos);
 
6464
 
 
6465
static uint found_sets=0;
 
6466
 
 
6467
 
 
6468
static uint replace_len(char * str)
6743
6469
{
6744
 
  uint32_t len=0;
 
6470
  uint len=0;
6745
6471
  while (*str)
6746
6472
  {
6747
6473
    if (str[0] == '\\' && str[1])
6754
6480
 
6755
6481
/* Init a replace structure for further calls */
6756
6482
 
6757
 
REPLACE *init_replace(char * *from, char * *to,uint32_t count,
 
6483
REPLACE *init_replace(char * *from, char * *to,uint count,
6758
6484
                      char * word_end_chars)
6759
6485
{
6760
6486
  static const int SPACE_CHAR= 256;
6761
6487
  static const int START_OF_LINE= 257;
6762
6488
  static const int END_OF_LINE= 258;
6763
6489
 
6764
 
  uint32_t i,j,states,set_nr,len,result_len,max_length,found_end,bits_set,bit_nr;
 
6490
  uint i,j,states,set_nr,len,result_len,max_length,found_end,bits_set,bit_nr;
6765
6491
  int used_sets,chr,default_state;
6766
6492
  char used_chars[LAST_CHAR_CODE],is_word_end[256];
6767
6493
  char * pos, *to_pos, **to_array;
6783
6509
      return(0);
6784
6510
    }
6785
6511
    states+=len+1;
6786
 
    result_len+=(uint32_t) strlen(to[i])+1;
 
6512
    result_len+=(uint) strlen(to[i])+1;
6787
6513
    if (len > max_length)
6788
6514
      max_length=len;
6789
6515
  }
6794
6520
  if (init_sets(&sets,states))
6795
6521
    return(0);
6796
6522
  found_sets=0;
6797
 
  if (!(found_set= (FOUND_SET*) malloc(sizeof(FOUND_SET)*max_length*count)))
6798
 
                                
 
6523
  if (!(found_set= (FOUND_SET*) my_malloc(sizeof(FOUND_SET)*max_length*count,
 
6524
                                          MYF(MY_WME))))
6799
6525
  {
6800
6526
    free_sets(&sets);
6801
6527
    return(0);
6805
6531
  used_sets=-1;
6806
6532
  word_states=make_new_set(&sets);    /* Start of new word */
6807
6533
  start_states=make_new_set(&sets);    /* This is first state */
6808
 
  if (!(follow=(FOLLOWS*) malloc((states+2)*sizeof(FOLLOWS))))
 
6534
  if (!(follow=(FOLLOWS*) my_malloc((states+2)*sizeof(FOLLOWS),MYF(MY_WME))))
6809
6535
  {
6810
6536
    free_sets(&sets);
6811
6537
    free(found_set);
6881
6607
    follow_ptr->table_offset=i;
6882
6608
    follow_ptr->len=len;
6883
6609
    follow_ptr++;
6884
 
    states+=(uint32_t) len+1;
 
6610
    states+=(uint) len+1;
6885
6611
  }
6886
6612
 
6887
6613
 
6997
6723
 
6998
6724
  /* Alloc replace structure for the replace-state-machine */
6999
6725
 
7000
 
  if ((replace=(REPLACE*) malloc(sizeof(REPLACE)*(sets.count)+
7001
 
                                 sizeof(REPLACE_STRING)*(found_sets+1)+
7002
 
                                 sizeof(char *)*count+result_len)))
 
6726
  if ((replace=(REPLACE*) my_malloc(sizeof(REPLACE)*(sets.count)+
 
6727
                                    sizeof(REPLACE_STRING)*(found_sets+1)+
 
6728
                                    sizeof(char *)*count+result_len,
 
6729
                                    MYF(MY_WME | MY_ZEROFILL))))
7003
6730
  {
7004
 
    memset(replace, 0, sizeof(REPLACE)*(sets.count)+
7005
 
                       sizeof(REPLACE_STRING)*(found_sets+1)+
7006
 
                       sizeof(char *)*count+result_len);
7007
6731
    rep_str=(REPLACE_STRING*) (replace+sets.count);
7008
6732
    to_array= (char **) (rep_str+found_sets+1);
7009
6733
    to_pos=(char *) (to_array+count);
7010
6734
    for (i=0 ; i < count ; i++)
7011
6735
    {
7012
6736
      to_array[i]=to_pos;
7013
 
      to_pos=strcpy(to_pos,to[i])+strlen(to[i])+1;
 
6737
      to_pos=my_stpcpy(to_pos,to[i])+1;
7014
6738
    }
7015
6739
    rep_str[0].found=1;
7016
6740
    rep_str[0].replace_string=0;
7039
6763
}
7040
6764
 
7041
6765
 
7042
 
int init_sets(REP_SETS *sets,uint32_t states)
 
6766
int init_sets(REP_SETS *sets,uint states)
7043
6767
{
7044
6768
  memset(sets, 0, sizeof(*sets));
7045
6769
  sets->size_of_bits=((states+7)/8);
7046
 
  if (!(sets->set_buffer=(REP_SET*) malloc(sizeof(REP_SET)*SET_MALLOC_HUNC)))
 
6770
  if (!(sets->set_buffer=(REP_SET*) my_malloc(sizeof(REP_SET)*SET_MALLOC_HUNC,
 
6771
                                              MYF(MY_WME))))
7047
6772
    return 1;
7048
 
  if (!(sets->bit_buffer=(uint*) malloc(sizeof(uint32_t)*sets->size_of_bits*
7049
 
                                        SET_MALLOC_HUNC)))
 
6773
  if (!(sets->bit_buffer=(uint*) my_malloc(sizeof(uint)*sets->size_of_bits*
 
6774
                                           SET_MALLOC_HUNC,MYF(MY_WME))))
7050
6775
  {
7051
6776
    free(sets->set);
7052
6777
    return 1;
7065
6790
 
7066
6791
REP_SET *make_new_set(REP_SETS *sets)
7067
6792
{
7068
 
  uint32_t i,count,*bit_buffer;
 
6793
  uint i,count,*bit_buffer;
7069
6794
  REP_SET *set;
7070
6795
  if (sets->extra)
7071
6796
  {
7072
6797
    sets->extra--;
7073
6798
    set=sets->set+ sets->count++;
7074
 
    memset(set->bits, 0, sizeof(uint32_t)*sets->size_of_bits);
 
6799
    memset(set->bits, 0, sizeof(uint)*sets->size_of_bits);
7075
6800
    memset(&set->next[0], 0, sizeof(set->next[0])*LAST_CHAR_CODE);
7076
6801
    set->found_offset=0;
7077
6802
    set->found_len=0;
7080
6805
    return set;
7081
6806
  }
7082
6807
  count=sets->count+sets->invisible+SET_MALLOC_HUNC;
7083
 
  if (!(set=(REP_SET*) realloc((unsigned char*) sets->set_buffer,
7084
 
                                  sizeof(REP_SET)*count)))
 
6808
  if (!(set=(REP_SET*) my_realloc((unsigned char*) sets->set_buffer,
 
6809
                                  sizeof(REP_SET)*count,
 
6810
                                  MYF(MY_WME))))
7085
6811
    return 0;
7086
6812
  sets->set_buffer=set;
7087
6813
  sets->set=set+sets->invisible;
7088
 
  if (!(bit_buffer=(uint*) realloc((unsigned char*) sets->bit_buffer,
7089
 
                                   (sizeof(uint32_t)*sets->size_of_bits)*count)))
 
6814
  if (!(bit_buffer=(uint*) my_realloc((unsigned char*) sets->bit_buffer,
 
6815
                                      (sizeof(uint)*sets->size_of_bits)*count,
 
6816
                                      MYF(MY_WME))))
7090
6817
    return 0;
7091
6818
  sets->bit_buffer=bit_buffer;
7092
6819
  for (i=0 ; i < count ; i++)
7112
6839
  return;
7113
6840
}
7114
6841
 
7115
 
void internal_set_bit(REP_SET *set, uint32_t bit)
 
6842
void internal_set_bit(REP_SET *set, uint bit)
7116
6843
{
7117
6844
  set->bits[bit / WORD_BIT] |= 1 << (bit % WORD_BIT);
7118
6845
  return;
7119
6846
}
7120
6847
 
7121
 
void internal_clear_bit(REP_SET *set, uint32_t bit)
 
6848
void internal_clear_bit(REP_SET *set, uint bit)
7122
6849
{
7123
6850
  set->bits[bit / WORD_BIT] &= ~ (1 << (bit % WORD_BIT));
7124
6851
  return;
7127
6854
 
7128
6855
void or_bits(REP_SET *to,REP_SET *from)
7129
6856
{
7130
 
  register uint32_t i;
 
6857
  register uint i;
7131
6858
  for (i=0 ; i < to->size_of_bits ; i++)
7132
6859
    to->bits[i]|=from->bits[i];
7133
6860
  return;
7136
6863
void copy_bits(REP_SET *to,REP_SET *from)
7137
6864
{
7138
6865
  memcpy(to->bits,from->bits,
7139
 
         (size_t) (sizeof(uint32_t) * to->size_of_bits));
 
6866
         (size_t) (sizeof(uint) * to->size_of_bits));
7140
6867
}
7141
6868
 
7142
6869
int cmp_bits(REP_SET *set1,REP_SET *set2)
7143
6870
{
7144
 
  return memcmp(set1->bits,set2->bits, sizeof(uint32_t) * set1->size_of_bits);
 
6871
  return memcmp(set1->bits,set2->bits, sizeof(uint) * set1->size_of_bits);
7145
6872
}
7146
6873
 
7147
6874
 
7148
6875
/* Get next set bit from set. */
7149
6876
 
7150
 
int get_next_bit(REP_SET *set,uint32_t lastpos)
 
6877
int get_next_bit(REP_SET *set,uint lastpos)
7151
6878
{
7152
 
  uint32_t pos,*start,*end,bits;
 
6879
  uint pos,*start,*end,bits;
7153
6880
 
7154
6881
  start=set->bits+ ((lastpos+1) / WORD_BIT);
7155
6882
  end=set->bits + set->size_of_bits;
7159
6886
    bits=start[0];
7160
6887
  if (!bits)
7161
6888
    return 0;
7162
 
  pos=(uint32_t) (start-set->bits)*WORD_BIT;
 
6889
  pos=(uint) (start-set->bits)*WORD_BIT;
7163
6890
  while (! (bits & 1))
7164
6891
  {
7165
6892
    bits>>=1;
7174
6901
 
7175
6902
int find_set(REP_SETS *sets,REP_SET *find)
7176
6903
{
7177
 
  uint32_t i;
 
6904
  uint i;
7178
6905
  for (i=0 ; i < sets->count-1 ; i++)
7179
6906
  {
7180
6907
    if (!cmp_bits(sets->set+i,find))
7193
6920
   set->next[] == -1 is reserved for end without replaces.
7194
6921
*/
7195
6922
 
7196
 
int find_found(FOUND_SET *found_set,uint32_t table_offset, int found_offset)
 
6923
int find_found(FOUND_SET *found_set,uint table_offset, int found_offset)
7197
6924
{
7198
6925
  int i;
7199
 
  for (i=0 ; (uint32_t) i < found_sets ; i++)
 
6926
  for (i=0 ; (uint) i < found_sets ; i++)
7200
6927
    if (found_set[i].table_offset == table_offset &&
7201
6928
        found_set[i].found_offset == found_offset)
7202
6929
      return -i-2;
7208
6935
 
7209
6936
/* Return 1 if regexp starts with \b or ends with \b*/
7210
6937
 
7211
 
uint32_t start_at_word(char * pos)
 
6938
uint start_at_word(char * pos)
7212
6939
{
7213
6940
  return (((!memcmp(pos, "\\b",2) && pos[2]) ||
7214
6941
           !memcmp(pos, "\\^", 2)) ? 1 : 0);
7215
6942
}
7216
6943
 
7217
 
uint32_t end_of_word(char * pos)
 
6944
uint end_of_word(char * pos)
7218
6945
{
7219
6946
  char * end= strchr(pos, '\0');
7220
6947
  return ((end > pos+2 && !memcmp(end-2, "\\b", 2)) ||
7230
6957
 
7231
6958
int insert_pointer_name(POINTER_ARRAY *pa,char * name)
7232
6959
{
7233
 
  uint32_t i,length,old_count;
 
6960
  uint i,length,old_count;
7234
6961
  unsigned char *new_pos;
7235
6962
  const char **new_array;
7236
6963
 
7238
6965
  if (! pa->typelib.count)
7239
6966
  {
7240
6967
    if (!(pa->typelib.type_names=(const char **)
7241
 
          malloc(((PC_MALLOC-MALLOC_OVERHEAD)/
 
6968
          my_malloc(((PC_MALLOC-MALLOC_OVERHEAD)/
7242
6969
                     (sizeof(char *)+sizeof(*pa->flag))*
7243
 
                     (sizeof(char *)+sizeof(*pa->flag))))))
 
6970
                     (sizeof(char *)+sizeof(*pa->flag))),MYF(MY_WME))))
7244
6971
      return(-1);
7245
 
    if (!(pa->str= (unsigned char*) malloc(PS_MALLOC-MALLOC_OVERHEAD)))
 
6972
    if (!(pa->str= (unsigned char*) my_malloc((uint) (PS_MALLOC-MALLOC_OVERHEAD),
 
6973
                                      MYF(MY_WME))))
7246
6974
    {
7247
6975
      free((char*) pa->typelib.type_names);
7248
6976
      return (-1);
7254
6982
    pa->max_length=PS_MALLOC-MALLOC_OVERHEAD;
7255
6983
    pa->array_allocs=1;
7256
6984
  }
7257
 
  length=(uint32_t) strlen(name)+1;
 
6985
  length=(uint) strlen(name)+1;
7258
6986
  if (pa->length+length >= pa->max_length)
7259
6987
  {
7260
 
    if (!(new_pos= (unsigned char*)realloc((unsigned char*)pa->str,
7261
 
                                           (size_t)(pa->max_length+PS_MALLOC))))
 
6988
    if (!(new_pos= (unsigned char*) my_realloc((unsigned char*) pa->str,
 
6989
                                       (uint) (pa->max_length+PS_MALLOC),
 
6990
                                       MYF(MY_WME))))
7262
6991
      return(1);
7263
6992
    if (new_pos != pa->str)
7264
6993
    {
7265
 
      ptrdiff_t diff= PTR_BYTE_DIFF(new_pos,pa->str);
 
6994
      my_ptrdiff_t diff=PTR_BYTE_DIFF(new_pos,pa->str);
7266
6995
      for (i=0 ; i < pa->typelib.count ; i++)
7267
6996
        pa->typelib.type_names[i]= ADD_TO_PTR(pa->typelib.type_names[i],diff,
7268
6997
                                              char*);
7272
7001
  }
7273
7002
  if (pa->typelib.count >= pa->max_count-1)
7274
7003
  {
7275
 
    size_t len;
 
7004
    int len;
7276
7005
    pa->array_allocs++;
7277
7006
    len=(PC_MALLOC*pa->array_allocs - MALLOC_OVERHEAD);
7278
 
    if (!(new_array=
7279
 
         (const char **)realloc((unsigned char*) pa->typelib.type_names,
7280
 
                                 len/
7281
 
                                  (sizeof(unsigned char*)+sizeof(*pa->flag))*
7282
 
                                  (sizeof(unsigned char*)+sizeof(*pa->flag)))))
 
7007
    if (!(new_array=(const char **) my_realloc((unsigned char*) pa->typelib.type_names,
 
7008
                                               (uint) len/
 
7009
                                               (sizeof(unsigned char*)+sizeof(*pa->flag))*
 
7010
                                               (sizeof(unsigned char*)+sizeof(*pa->flag)),
 
7011
                                               MYF(MY_WME))))
7283
7012
      return(1);
7284
7013
    pa->typelib.type_names=new_array;
7285
7014
    old_count=pa->max_count;
7291
7020
  pa->flag[pa->typelib.count]=0;      /* Reset flag */
7292
7021
  pa->typelib.type_names[pa->typelib.count++]= (char*) pa->str+pa->length;
7293
7022
  pa->typelib.type_names[pa->typelib.count]= NULL;  /* Put end-mark */
7294
 
  strcpy((char*) pa->str+pa->length,name);
 
7023
  my_stpcpy((char*) pa->str+pa->length,name);
7295
7024
  pa->length+=length;
7296
7025
  return(0);
7297
7026
} /* insert_pointer_name */
7347
7076
  replace_append_mem(ds, val, strlen(val));
7348
7077
}
7349
7078
 
7350
 
/* Append uint32_t to ds, with optional replace */
7351
 
void replace_append_uint(string *ds, uint32_t val)
 
7079
/* Append uint to ds, with optional replace */
 
7080
void replace_append_uint(string *ds, uint val)
7352
7081
{
7353
 
  ostringstream buff;
7354
 
  buff << val;
7355
 
  replace_append_mem(ds, buff.str().c_str(), buff.str().size());
 
7082
  char buff[22]; /* This should be enough for any int */
 
7083
  char *end= int64_t10_to_str(val, buff, 10);
 
7084
  replace_append_mem(ds, buff, end - buff);
7356
7085
 
7357
7086
}
7358
7087