~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzletest.cc

  • Committer: Stewart Smith
  • Date: 2008-11-21 16:06:07 UTC
  • mto: This revision was merged to the branch mainline in revision 593.
  • Revision ID: stewart@flamingspork.com-20081121160607-n6gdlt013spuo54r
remove mysql_frm_type
and fix engines to return correct value from delete_table when table doesn't exist.
(it should be ENOENT).

Also fix up some tests that manipulated frm files by hand. These tests are no longer valid and will need to be rewritten in the not too distant future.

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