~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/mysqltest.cc

  • Committer: Toru Maesaka
  • Date: 2008-07-17 05:59:20 UTC
  • mto: (202.1.1 toru)
  • mto: This revision was merged to the branch mainline in revision 204.
  • Revision ID: dev@torum.net-20080717055920-10okif50x6nh7b1d
forgot to bzr-add new files in the previous push

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2008 MySQL
5
 
 *
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; either version 2 of the License, or
9
 
 *  (at your option) any later version.
10
 
 *
11
 
 *  This program is distributed in the hope that it will be useful,
12
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 *  GNU General Public License for more details.
15
 
 *
16
 
 *  You should have received a copy of the GNU General Public License
17
 
 *  along with this program; if not, write to the Free Software
18
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
 
 */
 
1
/* Copyright (C) 2000 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
20
15
 
21
16
/*
22
 
  drizzletest
 
17
  mysqltest
23
18
 
24
19
  Tool used for executing a .test file
25
20
 
26
 
  See the "DRIZZLE Test framework manual" for more information
27
 
  http://dev.mysql.com/doc/drizzletest/en/index.html
 
21
  See the "MySQL Test framework manual" for more information
 
22
  http://dev.mysql.com/doc/mysqltest/en/index.html
28
23
 
29
24
  Please keep the test framework tools identical in all versions!
30
25
 
37
32
*/
38
33
 
39
34
#define MTEST_VERSION "3.3"
40
 
 
41
 
#include "config.h"
42
 
 
43
 
#include <queue>
44
 
#include <map>
45
 
#include <string>
46
 
 
47
35
#include <pcrecpp.h>
48
36
 
49
37
#include "client_priv.h"
50
 
#include <mysys/hash.h>
 
38
#include <drizzle_version.h>
 
39
#include <mysqld_error.h>
 
40
#include <m_ctype.h>
 
41
#include <my_dir.h>
 
42
#include <hash.h>
51
43
#include <stdarg.h>
52
 
 
53
 
#include "errname.h"
54
 
 
55
 
using namespace std;
 
44
#include <violite.h>
 
45
 
56
46
 
57
47
#define MAX_VAR_NAME_LENGTH    256
58
48
#define MAX_COLUMNS            256
64
54
#define QUERY_REAP_FLAG  2
65
55
 
66
56
enum {
 
57
  OPT_SKIP_SAFEMALLOC=OPT_MAX_CLIENT_OPTION,
67
58
  OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL,
68
59
  OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES
69
60
};
89
80
static bool server_initialized= 0;
90
81
static bool is_windows= 0;
91
82
static char **default_argv;
92
 
static const char *load_default_groups[]= { "drizzletest", "client", 0 };
 
83
static const char *load_default_groups[]= { "mysqltest", "client", 0 };
93
84
static char line_buffer[MAX_DELIMITER_LENGTH], *line_buffer_pos= line_buffer;
94
85
 
95
86
static uint start_lineno= 0; /* Start line of current command */
133
124
static struct st_test_file* file_stack_end;
134
125
 
135
126
 
136
 
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci; /* Default charset */
 
127
static CHARSET_INFO *charset_info= &my_charset_latin1; /* Default charset */
 
128
 
 
129
static const char *embedded_server_groups[]=
 
130
{
 
131
  "server",
 
132
  "embedded",
 
133
  "mysqltest_SERVER",
 
134
  NullS
 
135
};
137
136
 
138
137
static int embedded_server_arg_count=0;
139
138
static char *embedded_server_args[MAX_EMBEDDED_SERVER_ARGS];
149
148
 
150
149
static uint64_t progress_start= 0;
151
150
 
152
 
vector<struct st_command*> q_lines;
 
151
DYNAMIC_ARRAY q_lines;
153
152
 
154
153
typedef struct {
155
154
  int read_lines,current_line;
159
158
typedef struct
160
159
{
161
160
  char file[FN_REFLEN];
162
 
  uint32_t pos;
 
161
  ulong pos;
163
162
} master_pos_st;
164
163
 
165
164
master_pos_st master_pos;
187
186
 
188
187
struct st_connection
189
188
{
190
 
  DRIZZLE drizzle;
 
189
  MYSQL mysql;
191
190
  /* Used when creating views and sp, to avoid implicit commit */
192
 
  DRIZZLE *util_drizzle;
 
191
  MYSQL* util_mysql;
193
192
  char *name;
194
193
};
195
194
struct st_connection connections[128];
196
195
struct st_connection* cur_con= NULL, *next_con, *connections_end;
197
196
 
198
197
/*
199
 
  List of commands in drizzletest
 
198
  List of commands in mysqltest
200
199
  Must match the "command_names" array
201
200
  Add new commands before Q_UNKNOWN!
202
201
*/
203
202
enum enum_commands {
204
203
  Q_CONNECTION=1,     Q_QUERY,
205
 
  Q_CONNECT,      Q_SLEEP, Q_REAL_SLEEP,
206
 
  Q_INC,        Q_DEC,
207
 
  Q_SOURCE,      Q_DISCONNECT,
208
 
  Q_LET,        Q_ECHO,
209
 
  Q_WHILE,      Q_END_BLOCK,
210
 
  Q_SYSTEM,      Q_RESULT,
211
 
  Q_REQUIRE,      Q_SAVE_MASTER_POS,
 
204
  Q_CONNECT,        Q_SLEEP, Q_REAL_SLEEP,
 
205
  Q_INC,                    Q_DEC,
 
206
  Q_SOURCE,         Q_DISCONNECT,
 
207
  Q_LET,                    Q_ECHO,
 
208
  Q_WHILE,          Q_END_BLOCK,
 
209
  Q_SYSTEM,         Q_RESULT,
 
210
  Q_REQUIRE,        Q_SAVE_MASTER_POS,
212
211
  Q_SYNC_WITH_MASTER,
213
212
  Q_SYNC_SLAVE_WITH_MASTER,
214
213
  Q_ERROR,
215
 
  Q_SEND,        Q_REAP,
216
 
  Q_DIRTY_CLOSE,      Q_REPLACE, Q_REPLACE_COLUMN,
217
 
  Q_PING,        Q_EVAL,
 
214
  Q_SEND,                   Q_REAP,
 
215
  Q_DIRTY_CLOSE,            Q_REPLACE, Q_REPLACE_COLUMN,
 
216
  Q_PING,                   Q_EVAL,
218
217
  Q_EVAL_RESULT,
219
218
  Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG,
220
219
  Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG,
236
235
  Q_CHMOD_FILE, Q_APPEND_FILE, Q_CAT_FILE, Q_DIFF_FILES,
237
236
  Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR,
238
237
 
239
 
  Q_UNKNOWN,             /* Unknown command.   */
240
 
  Q_COMMENT,             /* Comments, ignored. */
 
238
  Q_UNKNOWN,                           /* Unknown command.   */
 
239
  Q_COMMENT,                           /* Comments, ignored. */
241
240
  Q_COMMENT_WITH_COMMAND
242
241
};
243
242
 
309
308
  "copy_file",
310
309
  "perl",
311
310
  "die",
312
 
 
 
311
               
313
312
  /* Don't execute any more commands, compare result */
314
313
  "exit",
315
314
  "skip",
368
367
};
369
368
 
370
369
TYPELIB command_typelib= {array_elements(command_names),"",
371
 
                          command_names, 0};
 
370
                          command_names, 0};
372
371
 
373
 
string ds_res, ds_progress, ds_warning_messages;
 
372
DYNAMIC_STRING ds_res, ds_progress, ds_warning_messages;
374
373
 
375
374
char builtin_echo[FN_REFLEN];
376
375
 
377
376
void die(const char *fmt, ...)
378
 
  __attribute__((format(printf, 1, 2)));
 
377
  ATTRIBUTE_FORMAT(printf, 1, 2);
379
378
void abort_not_supported_test(const char *fmt, ...)
380
 
  __attribute__((format(printf, 1, 2)));
 
379
  ATTRIBUTE_FORMAT(printf, 1, 2);
381
380
void verbose_msg(const char *fmt, ...)
382
 
  __attribute__((format(printf, 1, 2)));
 
381
  ATTRIBUTE_FORMAT(printf, 1, 2);
383
382
void warning_msg(const char *fmt, ...)
384
 
  __attribute__((format(printf, 1, 2)));
 
383
  ATTRIBUTE_FORMAT(printf, 1, 2);
385
384
void log_msg(const char *fmt, ...)
386
 
  __attribute__((format(printf, 1, 2)));
 
385
  ATTRIBUTE_FORMAT(printf, 1, 2);
387
386
 
388
387
VAR* var_from_env(const char *, const char *);
389
388
VAR* var_init(VAR* v, const char *name, int name_len, const char *val,
394
393
void eval_expr(VAR* v, const char *p, const char** p_end);
395
394
bool match_delimiter(int c, const char *delim, uint length);
396
395
void dump_result_to_reject_file(char *buf, int size);
397
 
void dump_result_to_log_file(const char *buf, int size);
 
396
void dump_result_to_log_file(char *buf, int size);
398
397
void dump_warning_messages(void);
399
398
void dump_progress(void);
400
399
 
401
 
void do_eval(string *query_eval, const char *query,
 
400
void do_eval(DYNAMIC_STRING *query_eval, const char *query,
402
401
             const char *query_end, bool pass_through_escape_chars);
403
 
void str_to_file(const char *fname, const char *str, int size);
404
 
void str_to_file2(const char *fname, const char *str, int size, bool append);
 
402
void str_to_file(const char *fname, char *str, int size);
 
403
void str_to_file2(const char *fname, char *str, int size, bool append);
405
404
 
406
405
/* For replace_column */
407
406
static char *replace_column[MAX_COLUMNS];
427
426
  free_replace_column();
428
427
}
429
428
 
430
 
void replace_append_mem(string *ds, const char *val,
431
 
                        int len);
432
 
void replace_append(string *ds, const char *val);
433
 
void replace_append_uint(string *ds, uint val);
434
 
void append_sorted(string* ds, string* ds_input);
 
429
void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
 
430
                               int len);
 
431
void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val);
 
432
void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val);
 
433
void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING* ds_input);
435
434
 
436
435
void handle_error(struct st_command*,
437
436
                  unsigned int err_errno, const char *err_error,
438
 
                  const char *err_sqlstate, string *ds);
 
437
                  const char *err_sqlstate, DYNAMIC_STRING *ds);
439
438
void handle_no_error(struct st_command*);
440
439
 
441
 
 
442
 
#define do_send_query(cn,q,q_len,flags) drizzle_send_query(&cn->drizzle, q, q_len)
443
 
 
444
 
void do_eval(string *query_eval, const char *query,
 
440
#ifdef EMBEDDED_LIBRARY
 
441
 
 
442
/* attributes of the query thread */
 
443
pthread_attr_t cn_thd_attrib;
 
444
 
 
445
/*
 
446
  send_one_query executes query in separate thread, which is
 
447
  necessary in embedded library to run 'send' in proper way.
 
448
  This implementation doesn't handle errors returned
 
449
  by mysql_send_query. It's technically possible, though
 
450
  I don't see where it is needed.
 
451
*/
 
452
pthread_handler_t send_one_query(void *arg)
 
453
{
 
454
  struct st_connection *cn= (struct st_connection*)arg;
 
455
 
 
456
  mysql_thread_init();
 
457
  VOID(mysql_send_query(&cn->mysql, cn->cur_query, cn->cur_query_len));
 
458
 
 
459
  mysql_thread_end();
 
460
  pthread_mutex_lock(&cn->mutex);
 
461
  cn->query_done= 1;
 
462
  VOID(pthread_cond_signal(&cn->cond));
 
463
  pthread_mutex_unlock(&cn->mutex);
 
464
  pthread_exit(0);
 
465
  return 0;
 
466
}
 
467
 
 
468
static int do_send_query(struct st_connection *cn, const char *q, int q_len,
 
469
                         int flags)
 
470
{
 
471
  pthread_t tid;
 
472
 
 
473
  if (flags & QUERY_REAP_FLAG)
 
474
    return mysql_send_query(&cn->mysql, q, q_len);
 
475
 
 
476
  if (pthread_mutex_init(&cn->mutex, NULL) ||
 
477
      pthread_cond_init(&cn->cond, NULL))
 
478
    die("Error in the thread library");
 
479
 
 
480
  cn->cur_query= q;
 
481
  cn->cur_query_len= q_len;
 
482
  cn->query_done= 0;
 
483
  if (pthread_create(&tid, &cn_thd_attrib, send_one_query, (void*)cn))
 
484
    die("Cannot start new thread for query");
 
485
 
 
486
  return 0;
 
487
}
 
488
 
 
489
static void wait_query_thread_end(struct st_connection *con)
 
490
{
 
491
  if (!con->query_done)
 
492
  {
 
493
    pthread_mutex_lock(&con->mutex);
 
494
    while (!con->query_done)
 
495
      pthread_cond_wait(&con->cond, &con->mutex);
 
496
    pthread_mutex_unlock(&con->mutex);
 
497
  }
 
498
}
 
499
 
 
500
#else /*EMBEDDED_LIBRARY*/
 
501
 
 
502
#define do_send_query(cn,q,q_len,flags) mysql_send_query(&cn->mysql, q, q_len)
 
503
 
 
504
#endif /*EMBEDDED_LIBRARY*/
 
505
 
 
506
void do_eval(DYNAMIC_STRING *query_eval, const char *query,
445
507
             const char *query_end, bool pass_through_escape_chars)
446
508
{
447
509
  const char *p;
456
518
    case '$':
457
519
      if (escaped)
458
520
      {
459
 
        escaped= 0;
460
 
        query_eval->append(p, 1);
 
521
        escaped= 0;
 
522
        dynstr_append_mem(query_eval, p, 1);
461
523
      }
462
524
      else
463
525
      {
464
 
        if (!(v= var_get(p, &p, 0, 0)))
465
 
          die("Bad variable in eval");
466
 
        query_eval->append(v->str_val, v->str_val_len);
 
526
        if (!(v= var_get(p, &p, 0, 0)))
 
527
          die("Bad variable in eval");
 
528
        dynstr_append_mem(query_eval, v->str_val, v->str_val_len);
467
529
      }
468
530
      break;
469
531
    case '\\':
470
532
      next_c= *(p+1);
471
533
      if (escaped)
472
534
      {
473
 
        escaped= 0;
474
 
        query_eval->append(p, 1);
 
535
        escaped= 0;
 
536
        dynstr_append_mem(query_eval, p, 1);
475
537
      }
476
538
      else if (next_c == '\\' || next_c == '$' || next_c == '"')
477
539
      {
478
540
        /* Set escaped only if next char is \, " or $ */
479
 
        escaped= 1;
 
541
        escaped= 1;
480
542
 
481
543
        if (pass_through_escape_chars)
482
544
        {
483
545
          /* The escape char should be added to the output string. */
484
 
          query_eval->append(p, 1);
 
546
          dynstr_append_mem(query_eval, p, 1);
485
547
        }
486
548
      }
487
549
      else
488
 
        query_eval->append(p, 1);
 
550
        dynstr_append_mem(query_eval, p, 1);
489
551
      break;
490
552
    default:
491
553
      escaped= 0;
492
 
      query_eval->append(p, 1);
 
554
      dynstr_append_mem(query_eval, p, 1);
493
555
      break;
494
556
    }
495
557
  }
498
560
 
499
561
 
500
562
/*
501
 
  Concatenates any number of strings, escapes any OS quote in the result then
502
 
  surround the whole affair in another set of quotes which is finally appended
503
 
  to specified string.  This function is especially useful when
504
 
  building strings to be executed with the system() function.
505
 
 
506
 
  @param str string which will have addtional strings appended.
507
 
  @param append string to be appended.
508
 
  @param ... Optional. Additional string(s) to be appended.
509
 
 
510
 
  @note The final argument in the list must be NULL even if no additional
511
 
  options are passed.
512
 
*/
513
 
 
514
 
void append_os_quoted(string *str, const char *append, ...)
515
 
{
516
 
  const char *quote_str= "\'";
517
 
  const uint  quote_len= 1;
518
 
 
519
 
  va_list dirty_text;
520
 
 
521
 
  str->append(quote_str, quote_len); /* Leading quote */
522
 
  va_start(dirty_text, append);
523
 
  while (append != NULL)
524
 
  {
525
 
    const char  *cur_pos= append;
526
 
    const char *next_pos= cur_pos;
527
 
 
528
 
    /* Search for quote in each string and replace with escaped quote */
529
 
    while((next_pos= strrchr(cur_pos, quote_str[0])) != NULL)
530
 
    {
531
 
      str->append(cur_pos, next_pos - cur_pos);
532
 
      str->append("\\", 1);
533
 
      str->append(quote_str, quote_len);
534
 
      cur_pos= next_pos + 1;
535
 
    }
536
 
    str->append(cur_pos, next_pos - cur_pos);
537
 
    append= va_arg(dirty_text, char *);
538
 
  }
539
 
  va_end(dirty_text);
540
 
  str->append(quote_str, quote_len); /* Trailing quote */
541
 
}
542
 
 
543
 
 
544
 
/*
545
563
  Run query and dump the result to stdout in vertical format
546
564
 
547
565
  NOTE! This function should be safe to call when an error
549
567
 
550
568
  SYNOPSIS
551
569
  show_query
552
 
  drizzle - connection to use
 
570
  mysql - connection to use
553
571
  query - query to run
554
572
 
555
573
*/
556
574
 
557
 
static void show_query(DRIZZLE *drizzle, const char* query)
 
575
static void show_query(MYSQL* mysql, const char* query)
558
576
{
559
 
  DRIZZLE_RES* res;
560
 
 
561
 
 
562
 
  if (!drizzle)
 
577
  MYSQL_RES* res;
 
578
 
 
579
 
 
580
  if (!mysql)
563
581
    return;
564
582
 
565
 
  if (drizzle_query(drizzle, query))
 
583
  if (mysql_query(mysql, query))
566
584
  {
567
585
    log_msg("Error running query '%s': %d %s",
568
 
            query, drizzle_errno(drizzle), drizzle_error(drizzle));
 
586
            query, mysql_errno(mysql), mysql_error(mysql));
569
587
    return;
570
588
  }
571
589
 
572
 
  if ((res= drizzle_store_result(drizzle)) == NULL)
 
590
  if ((res= mysql_store_result(mysql)) == NULL)
573
591
  {
574
592
    /* No result set returned */
575
593
    return;
576
594
  }
577
595
 
578
596
  {
579
 
    DRIZZLE_ROW row;
 
597
    MYSQL_ROW row;
580
598
    unsigned int i;
581
599
    unsigned int row_num= 0;
582
 
    unsigned int num_fields= drizzle_num_fields(res);
583
 
    const DRIZZLE_FIELD *fields= drizzle_fetch_fields(res);
 
600
    unsigned int num_fields= mysql_num_fields(res);
 
601
    MYSQL_FIELD *fields= mysql_fetch_fields(res);
584
602
 
585
603
    fprintf(stderr, "=== %s ===\n", query);
586
 
    while ((row= drizzle_fetch_row(res)))
 
604
    while ((row= mysql_fetch_row(res)))
587
605
    {
588
 
      uint32_t *lengths= drizzle_fetch_lengths(res);
 
606
      uint32_t *lengths= mysql_fetch_lengths(res);
589
607
      row_num++;
590
608
 
591
609
      fprintf(stderr, "---- %d. ----\n", row_num);
600
618
      fprintf(stderr, "=");
601
619
    fprintf(stderr, "\n\n");
602
620
  }
603
 
  drizzle_free_result(res);
 
621
  mysql_free_result(res);
604
622
 
605
623
  return;
606
624
}
615
633
 
616
634
  SYNOPSIS
617
635
  show_warnings_before_error
618
 
  drizzle - connection to use
 
636
  mysql - connection to use
619
637
 
620
638
*/
621
639
 
622
 
static void show_warnings_before_error(DRIZZLE *drizzle)
 
640
static void show_warnings_before_error(MYSQL* mysql)
623
641
{
624
 
  DRIZZLE_RES* res;
 
642
  MYSQL_RES* res;
625
643
  const char* query= "SHOW WARNINGS";
626
644
 
627
645
 
628
 
  if (!drizzle)
 
646
  if (!mysql)
629
647
    return;
630
648
 
631
 
  if (drizzle_query(drizzle, query))
 
649
  if (mysql_query(mysql, query))
632
650
  {
633
651
    log_msg("Error running query '%s': %d %s",
634
 
            query, drizzle_errno(drizzle), drizzle_error(drizzle));
 
652
            query, mysql_errno(mysql), mysql_error(mysql));
635
653
    return;
636
654
  }
637
655
 
638
 
  if ((res= drizzle_store_result(drizzle)) == NULL)
 
656
  if ((res= mysql_store_result(mysql)) == NULL)
639
657
  {
640
658
    /* No result set returned */
641
659
    return;
642
660
  }
643
661
 
644
 
  if (drizzle_num_rows(res) <= 1)
 
662
  if (mysql_num_rows(res) <= 1)
645
663
  {
646
664
    /* Don't display the last row, it's "last error" */
647
665
  }
648
666
  else
649
667
  {
650
 
    DRIZZLE_ROW row;
 
668
    MYSQL_ROW row;
651
669
    unsigned int row_num= 0;
652
 
    unsigned int num_fields= drizzle_num_fields(res);
 
670
    unsigned int num_fields= mysql_num_fields(res);
653
671
 
654
672
    fprintf(stderr, "\nWarnings from just before the error:\n");
655
 
    while ((row= drizzle_fetch_row(res)))
 
673
    while ((row= mysql_fetch_row(res)))
656
674
    {
657
675
      uint32_t i;
658
 
      uint32_t *lengths= drizzle_fetch_lengths(res);
 
676
      uint32_t *lengths= mysql_fetch_lengths(res);
659
677
 
660
 
      if (++row_num >= drizzle_num_rows(res))
 
678
      if (++row_num >= mysql_num_rows(res))
661
679
      {
662
680
        /* Don't display the last row, it's "last error" */
663
681
        break;
671
689
      fprintf(stderr, "\n");
672
690
    }
673
691
  }
674
 
  drizzle_free_result(res);
 
692
  mysql_free_result(res);
675
693
 
676
694
  return;
677
695
}
687
705
  const char *argname;       /* Name of argument   */
688
706
  enum arg_type type;        /* Type of argument   */
689
707
  bool required;          /* Argument required  */
690
 
  string *ds;        /* Storage for argument */
 
708
  DYNAMIC_STRING *ds;        /* Storage for argument */
691
709
  const char *description;   /* Description of the argument */
692
710
};
693
711
 
717
735
        ptr++;
718
736
      if (ptr > start)
719
737
      {
 
738
        init_dynamic_string(arg->ds, 0, ptr-start, 32);
720
739
        do_eval(arg->ds, start, ptr, false);
721
740
      }
722
741
      else
723
742
      {
724
743
        /* Empty string */
725
 
        arg->ds->erase();
 
744
        init_dynamic_string(arg->ds, "", 0, 0);
726
745
      }
727
746
      command->last_argument= (char*)ptr;
728
747
 
734
753
      /* Rest of line */
735
754
    case ARG_REST:
736
755
      start= ptr;
 
756
      init_dynamic_string(arg->ds, 0, command->query_len, 256);
737
757
      do_eval(arg->ds, start, command->end, false);
738
758
      command->last_argument= command->end;
739
759
      break;
744
764
    }
745
765
 
746
766
    /* Check required arg */
747
 
    if (arg->ds->length() == 0 && arg->required)
 
767
    if (arg->ds->length == 0 && arg->required)
748
768
      die("Missing required argument '%s' to command '%.*s'", arg->argname,
749
769
          command->first_word_len, command->query);
750
770
 
800
820
 
801
821
  for (--next_con; next_con >= connections; --next_con)
802
822
  {
803
 
    drizzle_close(&next_con->drizzle);
804
 
    if (next_con->util_drizzle)
805
 
      drizzle_close(next_con->util_drizzle);
806
 
    free(next_con->name);
 
823
    mysql_close(&next_con->mysql);
 
824
    if (next_con->util_mysql)
 
825
      mysql_close(next_con->util_mysql);
 
826
    my_free(next_con->name, MYF(MY_ALLOW_ZERO_PTR));
807
827
  }
808
828
  return;
809
829
}
818
838
    {
819
839
      my_fclose(cur_file->file, MYF(0));
820
840
    }
821
 
    free((unsigned char*) cur_file->file_name);
 
841
    my_free((uchar*) cur_file->file_name, MYF(MY_ALLOW_ZERO_PTR));
822
842
    cur_file->file_name= 0;
823
843
  }
824
844
  return;
834
854
  close_files();
835
855
  hash_free(&var_hash);
836
856
 
837
 
  vector<struct st_command *>::iterator iter;
838
 
  for (iter= q_lines.begin() ; iter < q_lines.end() ; iter++)
 
857
  for (i= 0 ; i < q_lines.elements ; i++)
839
858
  {
840
 
    struct st_command * q_line= *(iter.base());
841
 
    if (q_line->query_buf != NULL)
842
 
    {
843
 
      free(q_line->query_buf);
844
 
    }
845
 
    free(q_line);
 
859
    struct st_command **q= dynamic_element(&q_lines, i, struct st_command**);
 
860
    my_free((*q)->query_buf,MYF(MY_ALLOW_ZERO_PTR));
 
861
    my_free((*q),MYF(0));
846
862
  }
847
 
 
848
863
  for (i= 0; i < 10; i++)
849
864
  {
850
865
    if (var_reg[i].alloced_len)
851
 
      free(var_reg[i].str_val);
 
866
      my_free(var_reg[i].str_val, MYF(MY_WME));
852
867
  }
853
868
  while (embedded_server_arg_count > 1)
854
 
    free(embedded_server_args[--embedded_server_arg_count]);
855
 
 
 
869
    my_free(embedded_server_args[--embedded_server_arg_count],MYF(0));
 
870
  delete_dynamic(&q_lines);
 
871
  dynstr_free(&ds_res);
 
872
  dynstr_free(&ds_progress);
 
873
  dynstr_free(&ds_warning_messages);
856
874
  free_all_replace();
857
 
  free(opt_pass);
 
875
  my_free(opt_pass,MYF(MY_ALLOW_ZERO_PTR));
858
876
  free_defaults(default_argv);
859
877
 
 
878
  /* Only call mysql_server_end if mysql_server_init has been called */
 
879
  if (server_initialized)
 
880
    mysql_server_end();
 
881
 
860
882
  return;
861
883
}
862
884
 
876
898
      break;
877
899
    case 62:
878
900
      printf("skipped\n");
879
 
      break;
 
901
    break;
880
902
    default:
881
903
      printf("unknown exit code: %d\n", exit_code);
882
904
      assert(0);
901
923
  dying= 1;
902
924
 
903
925
  /* Print the error message */
904
 
  fprintf(stderr, "drizzletest: ");
 
926
  fprintf(stderr, "mysqltest: ");
905
927
  if (cur_file && cur_file != file_stack)
906
928
    fprintf(stderr, "In included file \"%s\": ",
907
929
            cur_file->file_name);
919
941
  fflush(stderr);
920
942
 
921
943
  /* Show results from queries just before failure */
922
 
  if (ds_res.length() && opt_tail_lines)
 
944
  if (ds_res.length && opt_tail_lines)
923
945
  {
924
946
    int tail_lines= opt_tail_lines;
925
 
    const char* show_from= ds_res.c_str() + ds_res.length() - 1;
926
 
    while(show_from > ds_res.c_str() && tail_lines > 0 )
 
947
    char* show_from= ds_res.str + ds_res.length - 1;
 
948
    while(show_from > ds_res.str && tail_lines > 0 )
927
949
    {
928
950
      show_from--;
929
951
      if (*show_from == '\n')
930
952
        tail_lines--;
931
953
    }
932
954
    fprintf(stderr, "\nThe result from queries just before the failure was:\n");
933
 
    if (show_from > ds_res.c_str())
 
955
    if (show_from > ds_res.str)
934
956
      fprintf(stderr, "< snip >");
935
957
    fprintf(stderr, "%s", show_from);
936
958
    fflush(stderr);
937
959
  }
938
960
 
939
961
  /* Dump the result that has been accumulated so far to .log file */
940
 
  if (result_file_name && ds_res.length())
941
 
    dump_result_to_log_file(ds_res.c_str(), ds_res.length());
 
962
  if (result_file_name && ds_res.length)
 
963
    dump_result_to_log_file(ds_res.str, ds_res.length);
942
964
 
943
965
  /* Dump warning messages */
944
 
  if (result_file_name && ds_warning_messages.length())
 
966
  if (result_file_name && ds_warning_messages.length)
945
967
    dump_warning_messages();
946
968
 
947
969
  /*
949
971
    been produced prior to the error
950
972
  */
951
973
  if (cur_con)
952
 
    show_warnings_before_error(&cur_con->drizzle);
 
974
    show_warnings_before_error(&cur_con->mysql);
953
975
 
954
976
  cleanup_and_exit(1);
955
977
}
996
1018
    return;
997
1019
 
998
1020
  va_start(args, fmt);
999
 
  fprintf(stderr, "drizzletest: ");
 
1021
  fprintf(stderr, "mysqltest: ");
1000
1022
  if (cur_file && cur_file != file_stack)
1001
1023
    fprintf(stderr, "In included file \"%s\": ",
1002
1024
            cur_file->file_name);
1018
1040
 
1019
1041
 
1020
1042
  va_start(args, fmt);
1021
 
  ds_warning_messages.append("drizzletest: ");
 
1043
  dynstr_append(&ds_warning_messages, "mysqltest: ");
1022
1044
  if (start_lineno != 0)
1023
1045
  {
1024
 
    ds_warning_messages.append("Warning detected ");
 
1046
    dynstr_append(&ds_warning_messages, "Warning detected ");
1025
1047
    if (cur_file && cur_file != file_stack)
1026
1048
    {
1027
1049
      len= snprintf(buff, sizeof(buff), "in included file %s ",
1028
 
                    cur_file->file_name);
1029
 
      ds_warning_messages.append(buff, len);
 
1050
                       cur_file->file_name);
 
1051
      dynstr_append_mem(&ds_warning_messages,
 
1052
                        buff, len);
1030
1053
    }
1031
1054
    len= snprintf(buff, sizeof(buff), "at line %d: ",
1032
 
                  start_lineno);
1033
 
    ds_warning_messages.append(buff, len);
 
1055
                     start_lineno);
 
1056
    dynstr_append_mem(&ds_warning_messages,
 
1057
                      buff, len);
1034
1058
  }
1035
1059
 
1036
1060
  len= vsnprintf(buff, sizeof(buff), fmt, args);
1037
 
  ds_warning_messages.append(buff, len);
 
1061
  dynstr_append_mem(&ds_warning_messages, buff, len);
1038
1062
 
1039
 
  ds_warning_messages.append("\n");
 
1063
  dynstr_append(&ds_warning_messages, "\n");
1040
1064
  va_end(args);
1041
1065
 
1042
1066
  return;
1054
1078
  len= vsnprintf(buff, sizeof(buff)-1, fmt, args);
1055
1079
  va_end(args);
1056
1080
 
1057
 
  ds_res.append(buff, len);
1058
 
  ds_res.append("\n");
 
1081
  dynstr_append_mem(&ds_res, buff, len);
 
1082
  dynstr_append(&ds_res, "\n");
1059
1083
 
1060
1084
  return;
1061
1085
}
1071
1095
 
1072
1096
*/
1073
1097
 
1074
 
static void cat_file(string* ds, const char* filename)
 
1098
static void cat_file(DYNAMIC_STRING* ds, const char* filename)
1075
1099
{
1076
1100
  int fd;
1077
1101
  uint len;
1079
1103
 
1080
1104
  if ((fd= my_open(filename, O_RDONLY, MYF(0))) < 0)
1081
1105
    die("Failed to open file '%s'", filename);
1082
 
  while((len= my_read(fd, (unsigned char*)&buff,
 
1106
  while((len= my_read(fd, (uchar*)&buff,
1083
1107
                      sizeof(buff), MYF(0))) > 0)
1084
1108
  {
1085
1109
    char *p= buff, *start= buff;
1091
1115
        /* Add fake newline instead of cr and output the line */
1092
1116
        *p= '\n';
1093
1117
        p++; /* Step past the "fake" newline */
1094
 
        ds->append(start, p-start);
 
1118
        dynstr_append_mem(ds, start, p-start);
1095
1119
        p++; /* Step past the "fake" newline */
1096
1120
        start= p;
1097
1121
      }
1098
1122
      else
1099
1123
        p++;
1100
1124
    }
1101
 
    /* Output any chars that might be left */
1102
 
    ds->append(start, p-start);
 
1125
    /* Output any chars that migh be left */
 
1126
    dynstr_append_mem(ds, start, p-start);
1103
1127
  }
1104
1128
  my_close(fd, MYF(0));
1105
1129
}
1111
1135
  SYNOPSIS
1112
1136
  run_command
1113
1137
  cmd - command to execute(should be properly quoted
1114
 
  result - pointer to string where to store the result
 
1138
  ds_res- pointer to dynamic string where to store the result
1115
1139
 
1116
1140
*/
1117
1141
 
1118
 
static int run_command(const char * cmd, string * result)
 
1142
static int run_command(char* cmd,
 
1143
                       DYNAMIC_STRING *ds_res)
1119
1144
{
1120
 
  assert(result!=NULL);
1121
1145
  char buf[512]= {0};
1122
1146
  FILE *res_file;
1123
1147
  int error;
1127
1151
 
1128
1152
  while (fgets(buf, sizeof(buf), res_file))
1129
1153
  {
1130
 
    /* Save the output of this command in the supplied string */
1131
 
    result->append(buf);
 
1154
    if(ds_res)
 
1155
    {
 
1156
      /* Save the output of this command in the supplied string */
 
1157
      dynstr_append(ds_res, buf);
 
1158
    }
 
1159
    else
 
1160
    {
 
1161
      /* Print it directly on screen */
 
1162
      fprintf(stdout, "%s", buf);
 
1163
    }
1132
1164
  }
1133
1165
 
1134
1166
  error= pclose(res_file);
1142
1174
  SYNOPSIS
1143
1175
  run_tool
1144
1176
  tool_path - the name of the tool to run
1145
 
  result - pointer to dynamic string where to store the result
 
1177
  ds_res - pointer to dynamic string where to store the result
1146
1178
  ... - variable number of arguments that will be properly
1147
 
  quoted and appended after the tool's name
 
1179
        quoted and appended after the tool's name
1148
1180
 
1149
1181
*/
1150
1182
 
1151
 
static int run_tool(const char *tool_path, string * result, ...)
 
1183
static int run_tool(const char *tool_path, DYNAMIC_STRING *ds_res, ...)
1152
1184
{
1153
1185
  int ret;
1154
1186
  const char* arg;
1155
1187
  va_list args;
1156
 
  string ds_cmdline;
1157
 
 
1158
 
 
1159
 
  append_os_quoted(&ds_cmdline, tool_path);
1160
 
  ds_cmdline.append(" ");
1161
 
 
1162
 
  va_start(args, result);
 
1188
  DYNAMIC_STRING ds_cmdline;
 
1189
 
 
1190
  if (init_dynamic_string(&ds_cmdline, "", FN_REFLEN, FN_REFLEN))
 
1191
    die("Out of memory");
 
1192
 
 
1193
  dynstr_append_os_quoted(&ds_cmdline, tool_path, NullS);
 
1194
  dynstr_append(&ds_cmdline, " ");
 
1195
 
 
1196
  va_start(args, ds_res);
1163
1197
 
1164
1198
  while ((arg= va_arg(args, char *)))
1165
1199
  {
1166
1200
    /* Options should be os quoted */
1167
1201
    if (strncmp(arg, "--", 2) == 0)
1168
 
      append_os_quoted(&ds_cmdline, arg, NULL);
 
1202
      dynstr_append_os_quoted(&ds_cmdline, arg, NullS);
1169
1203
    else
1170
 
      ds_cmdline.append(arg);
1171
 
    ds_cmdline.append(" ");
 
1204
      dynstr_append(&ds_cmdline, arg);
 
1205
    dynstr_append(&ds_cmdline, " ");
1172
1206
  }
1173
1207
 
1174
1208
  va_end(args);
1175
1209
 
1176
 
  ret= run_command(ds_cmdline.c_str(), result);
 
1210
  ret= run_command(ds_cmdline.str, ds_res);
 
1211
  dynstr_free(&ds_cmdline);
1177
1212
  return(ret);
1178
1213
}
1179
1214
 
1191
1226
 
1192
1227
*/
1193
1228
 
1194
 
static void show_diff(string* ds,
 
1229
static void show_diff(DYNAMIC_STRING* ds,
1195
1230
                      const char* filename1, const char* filename2)
1196
1231
{
1197
1232
 
1198
 
  string ds_tmp;
 
1233
  DYNAMIC_STRING ds_tmp;
 
1234
 
 
1235
  if (init_dynamic_string(&ds_tmp, "", 256, 256))
 
1236
    die("Out of memory");
1199
1237
 
1200
1238
  /* First try with unified diff */
1201
1239
  if (run_tool("diff",
1206
1244
               "2>&1",
1207
1245
               NULL) > 1) /* Most "diff" tools return >1 if error */
1208
1246
  {
1209
 
    ds_tmp= "";
 
1247
    dynstr_set(&ds_tmp, "");
1210
1248
 
1211
1249
    /* Fallback to context diff with "diff -c" */
1212
1250
    if (run_tool("diff",
1221
1259
        Fallback to dump both files to result file and inform
1222
1260
        about installing "diff"
1223
1261
      */
1224
 
      ds_tmp= "";
1225
 
 
1226
 
      ds_tmp.append(
1227
 
                    "\n"
1228
 
                    "The two files differ but it was not possible to execute 'diff' in\n"
1229
 
                    "order to show only the difference, tried both 'diff -u' or 'diff -c'.\n"
1230
 
                    "Instead the whole content of the two files was shown for you to diff manually. ;)\n\n"
1231
 
                    "To get a better report you should install 'diff' on your system, which you\n"
1232
 
                    "for example can get from http://www.gnu.org/software/diffutils/diffutils.html\n"
1233
 
                    "\n");
1234
 
 
1235
 
      ds_tmp.append(" --- ");
1236
 
      ds_tmp.append(filename1);
1237
 
      ds_tmp.append(" >>>\n");
 
1262
      dynstr_set(&ds_tmp, "");
 
1263
 
 
1264
      dynstr_append(&ds_tmp,
 
1265
"\n"
 
1266
"The two files differ but it was not possible to execute 'diff' in\n"
 
1267
"order to show only the difference, tried both 'diff -u' or 'diff -c'.\n"
 
1268
"Instead the whole content of the two files was shown for you to diff manually. ;)\n\n"
 
1269
"To get a better report you should install 'diff' on your system, which you\n"
 
1270
"for example can get from http://www.gnu.org/software/diffutils/diffutils.html\n"
 
1271
"\n");
 
1272
 
 
1273
      dynstr_append(&ds_tmp, " --- ");
 
1274
      dynstr_append(&ds_tmp, filename1);
 
1275
      dynstr_append(&ds_tmp, " >>>\n");
1238
1276
      cat_file(&ds_tmp, filename1);
1239
 
      ds_tmp.append("<<<\n --- ");
1240
 
      ds_tmp.append(filename1);
1241
 
      ds_tmp.append(" >>>\n");
 
1277
      dynstr_append(&ds_tmp, "<<<\n --- ");
 
1278
      dynstr_append(&ds_tmp, filename1);
 
1279
      dynstr_append(&ds_tmp, " >>>\n");
1242
1280
      cat_file(&ds_tmp, filename2);
1243
 
      ds_tmp.append("<<<<\n");
 
1281
      dynstr_append(&ds_tmp, "<<<<\n");
1244
1282
    }
1245
1283
  }
1246
1284
 
1247
1285
  if (ds)
1248
1286
  {
1249
1287
    /* Add the diff to output */
1250
 
    ds->append(ds_tmp.c_str(), ds_tmp.length());
 
1288
    dynstr_append_mem(ds, ds_tmp.str, ds_tmp.length);
1251
1289
  }
1252
1290
  else
1253
1291
  {
1254
1292
    /* Print diff directly to stdout */
1255
 
    fprintf(stderr, "%s\n", ds_tmp.c_str());
 
1293
    fprintf(stderr, "%s\n", ds_tmp.str);
1256
1294
  }
 
1295
 
 
1296
  dynstr_free(&ds_tmp);
1257
1297
 
1258
1298
}
1259
1299
 
1260
1300
 
1261
1301
enum compare_files_result_enum {
1262
 
  RESULT_OK= 0,
1263
 
  RESULT_CONTENT_MISMATCH= 1,
1264
 
  RESULT_LENGTH_MISMATCH= 2
 
1302
   RESULT_OK= 0,
 
1303
   RESULT_CONTENT_MISMATCH= 1,
 
1304
   RESULT_LENGTH_MISMATCH= 2
1265
1305
};
1266
1306
 
1267
1307
/*
1290
1330
    my_close(fd, MYF(0));
1291
1331
    die("Failed to open second file: '%s'", filename2);
1292
1332
  }
1293
 
  while((len= my_read(fd, (unsigned char*)&buff,
 
1333
  while((len= my_read(fd, (uchar*)&buff,
1294
1334
                      sizeof(buff), MYF(0))) > 0)
1295
1335
  {
1296
 
    if ((len2= my_read(fd2, (unsigned char*)&buff2,
 
1336
    if ((len2= my_read(fd2, (uchar*)&buff2,
1297
1337
                       sizeof(buff2), MYF(0))) < len)
1298
1338
    {
1299
1339
      /* File 2 was smaller */
1313
1353
      break;
1314
1354
    }
1315
1355
  }
1316
 
  if (!error && my_read(fd2, (unsigned char*)&buff2,
 
1356
  if (!error && my_read(fd2, (uchar*)&buff2,
1317
1357
                        sizeof(buff2), MYF(0)) > 0)
1318
1358
  {
1319
1359
    /* File 1 was smaller */
1359
1399
  Compare content of the string in ds to content of file fname
1360
1400
 
1361
1401
  SYNOPSIS
1362
 
  string_cmp
 
1402
  dyn_string_cmp
1363
1403
  ds - Dynamic string containing the string o be compared
1364
1404
  fname - Name of file to compare with
1365
1405
 
1367
1407
  See 'compare_files2'
1368
1408
*/
1369
1409
 
1370
 
static int string_cmp(string* ds, const char *fname)
 
1410
static int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname)
1371
1411
{
1372
1412
  int error;
1373
1413
  File fd;
1379
1419
    die("Failed to create temporary file for ds");
1380
1420
 
1381
1421
  /* Write ds to temporary file and set file pos to beginning*/
1382
 
  if (my_write(fd, (unsigned char *) ds->c_str(), ds->length(),
 
1422
  if (my_write(fd, (uchar *) ds->str, ds->length,
1383
1423
               MYF(MY_FNABP | MY_WME)) ||
1384
1424
      my_seek(fd, 0, SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR)
1385
1425
  {
1411
1451
 
1412
1452
*/
1413
1453
 
1414
 
static void check_result(string* ds)
 
1454
static void check_result(DYNAMIC_STRING* ds)
1415
1455
{
1416
1456
  const char* mess= "Result content mismatch\n";
1417
1457
 
1421
1461
  if (access(result_file_name, F_OK) != 0)
1422
1462
    die("The specified result file does not exist: '%s'", result_file_name);
1423
1463
 
1424
 
  switch (string_cmp(ds, result_file_name)) {
 
1464
  switch (dyn_string_cmp(ds, result_file_name)) {
1425
1465
  case RESULT_OK:
1426
1466
    break; /* ok */
1427
1467
  case RESULT_LENGTH_MISMATCH:
1449
1489
      fn_format(reject_file, result_file_name, opt_logdir,
1450
1490
                ".reject", MY_REPLACE_DIR | MY_REPLACE_EXT);
1451
1491
    }
1452
 
    str_to_file(reject_file, ds->c_str(), ds->length());
 
1492
    str_to_file(reject_file, ds->str, ds->length);
1453
1493
 
1454
 
    ds->erase(); /* Don't create a .log file */
 
1494
    dynstr_set(ds, NULL); /* Don't create a .log file */
1455
1495
 
1456
1496
    show_diff(NULL, result_file_name, reject_file);
1457
1497
    die(mess);
1480
1520
 
1481
1521
*/
1482
1522
 
1483
 
static void check_require(string* ds, const char *fname)
 
1523
static void check_require(DYNAMIC_STRING* ds, const char *fname)
1484
1524
{
1485
1525
 
1486
1526
 
1487
 
  if (string_cmp(ds, fname))
 
1527
  if (dyn_string_cmp(ds, fname))
1488
1528
  {
1489
1529
    char reason[FN_REFLEN];
1490
1530
    fn_format(reason, fname, "", "", MY_REPLACE_EXT | MY_REPLACE_DIR);
1495
1535
 
1496
1536
 
1497
1537
/*
1498
 
  Remove surrounding chars from string
 
1538
   Remove surrounding chars from string
1499
1539
 
1500
 
  Return 1 if first character is found but not last
 
1540
   Return 1 if first character is found but not last
1501
1541
*/
1502
1542
static int strip_surrounding(char* str, char c1, char c2)
1503
1543
{
1512
1552
    *ptr= ' ';
1513
1553
 
1514
1554
    /* Last non space charecter should be c2 */
1515
 
    ptr= strchr(str, '\0')-1;
 
1555
    ptr= strend(str)-1;
1516
1556
    while(*ptr && my_isspace(charset_info, *ptr))
1517
1557
      ptr--;
1518
1558
    if (*ptr == c2)
1533
1573
static void strip_parentheses(struct st_command *command)
1534
1574
{
1535
1575
  if (strip_surrounding(command->first_argument, '(', ')'))
1536
 
    die("%.*s - argument list started with '%c' must be ended with '%c'",
1537
 
        command->first_word_len, command->query, '(', ')');
 
1576
      die("%.*s - argument list started with '%c' must be ended with '%c'",
 
1577
          command->first_word_len, command->query, '(', ')');
1538
1578
}
1539
1579
 
1540
1580
 
1541
 
static unsigned char *get_var_key(const unsigned char* var, size_t *len,
 
1581
static uchar *get_var_key(const uchar* var, size_t *len,
1542
1582
                          bool __attribute__((unused)) t)
1543
1583
{
1544
1584
  register char* key;
1545
1585
  key = ((VAR*)var)->name;
1546
1586
  *len = ((VAR*)var)->name_len;
1547
 
  return (unsigned char*)key;
 
1587
  return (uchar*)key;
1548
1588
}
1549
1589
 
1550
1590
 
1586
1626
 
1587
1627
void var_free(void *v)
1588
1628
{
1589
 
  free(((VAR*) v)->str_val);
1590
 
  free(((VAR*) v)->env_s);
 
1629
  my_free(((VAR*) v)->str_val, MYF(MY_WME));
 
1630
  my_free(((VAR*) v)->env_s, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
1591
1631
  if (((VAR*)v)->alloced)
1592
 
    free(v);
 
1632
    my_free(v, MYF(MY_WME));
1593
1633
}
1594
1634
 
1595
1635
 
1601
1641
    tmp = def_val;
1602
1642
 
1603
1643
  v = var_init(0, name, strlen(name), tmp, strlen(tmp));
1604
 
  my_hash_insert(&var_hash, (unsigned char*)v);
 
1644
  my_hash_insert(&var_hash, (uchar*)v);
1605
1645
  return v;
1606
1646
}
1607
1647
 
1608
1648
 
1609
1649
VAR* var_get(const char *var_name, const char **var_name_end, bool raw,
1610
 
             bool ignore_not_existing)
 
1650
             bool ignore_not_existing)
1611
1651
{
1612
1652
  int digit;
1613
1653
  VAR *v;
1625
1665
    if (var_name == save_var_name)
1626
1666
    {
1627
1667
      if (ignore_not_existing)
1628
 
        return(0);
 
1668
        return(0);
1629
1669
      die("Empty variable");
1630
1670
    }
1631
1671
    length= (uint) (var_name - save_var_name);
1632
1672
    if (length >= MAX_VAR_NAME_LENGTH)
1633
1673
      die("Too long variable name: %s", save_var_name);
1634
1674
 
1635
 
    if (!(v = (VAR*) hash_search(&var_hash, (const unsigned char*) save_var_name,
1636
 
                                 length)))
 
1675
    if (!(v = (VAR*) hash_search(&var_hash, (const uchar*) save_var_name,
 
1676
                                            length)))
1637
1677
    {
1638
1678
      char buff[MAX_VAR_NAME_LENGTH+1];
1639
1679
      strmake(buff, save_var_name, length);
1640
1680
      v= var_from_env(buff, "");
1641
1681
    }
1642
 
    var_name--;  /* Point at last character */
 
1682
    var_name--; /* Point at last character */
1643
1683
  }
1644
1684
  else
1645
1685
    v = var_reg + digit;
1664
1704
static VAR *var_obtain(const char *name, int len)
1665
1705
{
1666
1706
  VAR* v;
1667
 
  if ((v = (VAR*)hash_search(&var_hash, (const unsigned char *) name, len)))
 
1707
  if ((v = (VAR*)hash_search(&var_hash, (const uchar *) name, len)))
1668
1708
    return v;
1669
1709
  v = var_init(0, name, len, "", 0);
1670
 
  my_hash_insert(&var_hash, (unsigned char*)v);
 
1710
  my_hash_insert(&var_hash, (uchar*)v);
1671
1711
  return v;
1672
1712
}
1673
1713
 
1709
1749
      v->str_val_len= strlen(v->str_val);
1710
1750
    }
1711
1751
    snprintf(buf, sizeof(buf), "%.*s=%.*s",
1712
 
             v->name_len, v->name,
1713
 
             v->str_val_len, v->str_val);
 
1752
                v->name_len, v->name,
 
1753
                v->str_val_len, v->str_val);
1714
1754
    if (!(v->env_s= my_strdup(buf, MYF(MY_WME))))
1715
1755
      die("Out of memory");
1716
1756
    putenv(v->env_s);
1717
 
    free(old_env_s);
 
1757
    my_free(old_env_s, MYF(MY_ALLOW_ZERO_PTR));
1718
1758
  }
1719
1759
  return;
1720
1760
}
1736
1776
 
1737
1777
/*
1738
1778
  Store an integer (typically the returncode of the last SQL)
1739
 
  statement in the drizzletest builtin variable $drizzle_errno
 
1779
  statement in the mysqltest builtin variable $mysql_errno
1740
1780
*/
1741
1781
 
1742
1782
static void var_set_errno(int sql_errno)
1743
1783
{
1744
 
  var_set_int("$drizzle_errno", sql_errno);
 
1784
  var_set_int("$mysql_errno", sql_errno);
1745
1785
}
1746
1786
 
1747
1787
 
1748
1788
/*
1749
 
  Update $drizzle_get_server_version variable with version
 
1789
  Update $mysql_get_server_version variable with version
1750
1790
  of the currently connected server
1751
1791
*/
1752
1792
 
1753
 
static void var_set_drizzle_get_server_version(DRIZZLE *drizzle)
 
1793
static void var_set_mysql_get_server_version(MYSQL* mysql)
1754
1794
{
1755
 
  var_set_int("$drizzle_get_server_version", drizzle_get_server_version(drizzle));
 
1795
  var_set_int("$mysql_get_server_version", mysql_get_server_version(mysql));
1756
1796
}
1757
1797
 
1758
1798
 
1761
1801
 
1762
1802
  SYNOPSIS
1763
1803
  var_query_set()
1764
 
  var          variable to set from query
 
1804
  var           variable to set from query
1765
1805
  query       start of query string to execute
1766
1806
  query_end   end of the query string to execute
1767
1807
 
1781
1821
 
1782
1822
static void var_query_set(VAR *var, const char *query, const char** query_end)
1783
1823
{
1784
 
  const char *end = (char*)((query_end && *query_end) ?
1785
 
                            *query_end : query + strlen(query));
1786
 
  DRIZZLE_RES *res;
1787
 
  DRIZZLE_ROW row;
1788
 
  DRIZZLE *drizzle= &cur_con->drizzle;
1789
 
  string ds_query;
 
1824
  char *end = (char*)((query_end && *query_end) ?
 
1825
                      *query_end : query + strlen(query));
 
1826
  MYSQL_RES *res;
 
1827
  MYSQL_ROW row;
 
1828
  MYSQL* mysql = &cur_con->mysql;
 
1829
  DYNAMIC_STRING ds_query;
1790
1830
 
1791
1831
 
1792
1832
  while (end > query && *end != '`')
1796
1836
  ++query;
1797
1837
 
1798
1838
  /* Eval the query, thus replacing all environment variables */
 
1839
  init_dynamic_string(&ds_query, 0, (end - query) + 32, 256);
1799
1840
  do_eval(&ds_query, query, end, false);
1800
1841
 
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)))
1805
 
    die("Query '%s' didn't return a result set", ds_query.c_str());
 
1842
  if (mysql_real_query(mysql, ds_query.str, ds_query.length))
 
1843
    die("Error running query '%s': %d %s", ds_query.str,
 
1844
        mysql_errno(mysql), mysql_error(mysql));
 
1845
  if (!(res= mysql_store_result(mysql)))
 
1846
    die("Query '%s' didn't return a result set", ds_query.str);
 
1847
  dynstr_free(&ds_query);
1806
1848
 
1807
 
  if ((row= drizzle_fetch_row(res)) && row[0])
 
1849
  if ((row= mysql_fetch_row(res)) && row[0])
1808
1850
  {
1809
1851
    /*
1810
1852
      Concatenate all fields in the first row with tab in between
1811
1853
      and assign that string to the $variable
1812
1854
    */
1813
 
    string result;
 
1855
    DYNAMIC_STRING result;
1814
1856
    uint32_t i;
1815
1857
    uint32_t *lengths;
1816
1858
 
1817
 
    lengths= drizzle_fetch_lengths(res);
1818
 
    for (i= 0; i < drizzle_num_fields(res); i++)
 
1859
    init_dynamic_string(&result, "", 512, 512);
 
1860
    lengths= mysql_fetch_lengths(res);
 
1861
    for (i= 0; i < mysql_num_fields(res); i++)
1819
1862
    {
1820
1863
      if (row[i])
1821
1864
      {
1822
1865
        /* Add column to tab separated string */
1823
 
        result.append(row[i], lengths[i]);
 
1866
        dynstr_append_mem(&result, row[i], lengths[i]);
1824
1867
      }
1825
 
      result.append("\t", 1);
 
1868
      dynstr_append_mem(&result, "\t", 1);
1826
1869
    }
1827
 
    end= result.c_str() + result.length()-1;
1828
 
    eval_expr(var, result.c_str(), (const char**) &end);
 
1870
    end= result.str + result.length-1;
 
1871
    eval_expr(var, result.str, (const char**) &end);
 
1872
    dynstr_free(&result);
1829
1873
  }
1830
1874
  else
1831
1875
    eval_expr(var, "", 0);
1832
1876
 
1833
 
  drizzle_free_result(res);
 
1877
  mysql_free_result(res);
1834
1878
  return;
1835
1879
}
1836
1880
 
1851
1895
 
1852
1896
  <query to run> -    The query that should be sent to the server
1853
1897
  <column name> -     Name of the column that holds the field be compared
1854
 
  against the expected value
 
1898
                      against the expected value
1855
1899
  <row no> -          Number of the row that holds the field to be
1856
 
  compared against the expected value
 
1900
                      compared against the expected value
1857
1901
 
1858
1902
*/
1859
1903
 
1861
1905
{
1862
1906
  long row_no;
1863
1907
  int col_no= -1;
1864
 
  DRIZZLE_RES* res;
1865
 
  DRIZZLE *drizzle= &cur_con->drizzle;
 
1908
  MYSQL_RES* res;
 
1909
  MYSQL* mysql= &cur_con->mysql;
1866
1910
 
1867
 
  string ds_query;
1868
 
  string ds_col;
1869
 
  string ds_row;
 
1911
  static DYNAMIC_STRING ds_query;
 
1912
  static DYNAMIC_STRING ds_col;
 
1913
  static DYNAMIC_STRING ds_row;
1870
1914
  const struct command_arg query_get_value_args[] = {
1871
1915
    {"query", ARG_STRING, true, &ds_query, "Query to run"},
1872
1916
    {"column name", ARG_STRING, true, &ds_col, "Name of column"},
1881
1925
                     ',');
1882
1926
 
1883
1927
  /* Convert row number to int */
1884
 
  if (!str2int(ds_row.c_str(), 10, (long) 0, (long) INT_MAX, &row_no))
1885
 
    die("Invalid row number: '%s'", ds_row.c_str());
 
1928
  if (!str2int(ds_row.str, 10, (long) 0, (long) INT_MAX, &row_no))
 
1929
    die("Invalid row number: '%s'", ds_row.str);
 
1930
  dynstr_free(&ds_row);
1886
1931
 
1887
1932
  /* Remove any surrounding "'s from the query - if there is any */
1888
 
  // (Don't get me started on this)
1889
 
  char * unstripped_query= strdup(ds_query.c_str());
1890
 
  if (strip_surrounding(unstripped_query, '"', '"'))
1891
 
    die("Mismatched \"'s around query '%s'", ds_query.c_str());
1892
 
  ds_query= unstripped_query;
 
1933
  if (strip_surrounding(ds_query.str, '"', '"'))
 
1934
    die("Mismatched \"'s around query '%s'", ds_query.str);
1893
1935
 
1894
1936
  /* Run the query */
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)))
1899
 
    die("Query '%s' didn't return a result set", ds_query.c_str());
 
1937
  if (mysql_real_query(mysql, ds_query.str, ds_query.length))
 
1938
    die("Error running query '%s': %d %s", ds_query.str,
 
1939
        mysql_errno(mysql), mysql_error(mysql));
 
1940
  if (!(res= mysql_store_result(mysql)))
 
1941
    die("Query '%s' didn't return a result set", ds_query.str);
1900
1942
 
1901
1943
  {
1902
1944
    /* Find column number from the given column name */
1903
1945
    uint i;
1904
 
    uint num_fields= drizzle_num_fields(res);
1905
 
    const DRIZZLE_FIELD *fields= drizzle_fetch_fields(res);
 
1946
    uint num_fields= mysql_num_fields(res);
 
1947
    MYSQL_FIELD *fields= mysql_fetch_fields(res);
1906
1948
 
1907
1949
    for (i= 0; i < num_fields; i++)
1908
1950
    {
1909
 
      if (strcmp(fields[i].name, ds_col.c_str()) == 0 &&
1910
 
          strlen(fields[i].name) == ds_col.length())
 
1951
      if (strcmp(fields[i].name, ds_col.str) == 0 &&
 
1952
          strlen(fields[i].name) == ds_col.length)
1911
1953
      {
1912
1954
        col_no= i;
1913
1955
        break;
1915
1957
    }
1916
1958
    if (col_no == -1)
1917
1959
    {
1918
 
      drizzle_free_result(res);
 
1960
      mysql_free_result(res);
1919
1961
      die("Could not find column '%s' in the result of '%s'",
1920
 
          ds_col.c_str(), ds_query.c_str());
 
1962
          ds_col.str, ds_query.str);
1921
1963
    }
1922
1964
  }
 
1965
  dynstr_free(&ds_col);
1923
1966
 
1924
1967
  {
1925
1968
    /* Get the value */
1926
 
    DRIZZLE_ROW row;
 
1969
    MYSQL_ROW row;
1927
1970
    long rows= 0;
1928
1971
    const char* value= "No such row";
1929
1972
 
1930
 
    while ((row= drizzle_fetch_row(res)))
 
1973
    while ((row= mysql_fetch_row(res)))
1931
1974
    {
1932
1975
      if (++rows == row_no)
1933
1976
      {
1943
1986
    }
1944
1987
    eval_expr(var, value, 0);
1945
1988
  }
1946
 
  drizzle_free_result(res);
 
1989
  dynstr_free(&ds_query);
 
1990
  mysql_free_result(res);
1947
1991
 
1948
1992
  return;
1949
1993
}
2013
2057
        MIN_VAR_ALLOC : new_val_len + 1;
2014
2058
      if (!(v->str_val =
2015
2059
            v->str_val ? (char *)my_realloc(v->str_val, v->alloced_len+1,
2016
 
                                            MYF(MY_WME)) :
 
2060
                                    MYF(MY_WME)) :
2017
2061
            (char *)my_malloc(v->alloced_len+1, MYF(MY_WME))))
2018
2062
        die("Out of memory");
2019
2063
    }
2033
2077
 
2034
2078
  if (!test_if_hard_path(name))
2035
2079
  {
2036
 
    strxmov(buff, opt_basedir, name, NULL);
 
2080
    strxmov(buff, opt_basedir, name, NullS);
2037
2081
    name=buff;
2038
2082
  }
2039
2083
  fn_format(buff, name, "", "", MY_UNPACK_FILENAME);
2057
2101
 
2058
2102
  SYNOPSIS
2059
2103
  do_source()
2060
 
  query  called command
 
2104
  query called command
2061
2105
 
2062
2106
  DESCRIPTION
2063
2107
  source <file_name>
2068
2112
 
2069
2113
static void do_source(struct st_command *command)
2070
2114
{
2071
 
  string ds_filename;
 
2115
  static DYNAMIC_STRING ds_filename;
2072
2116
  const struct command_arg source_args[] = {
2073
2117
    { "filename", ARG_STRING, true, &ds_filename, "File to source" }
2074
2118
  };
2086
2130
    ; /* Do nothing */
2087
2131
  else
2088
2132
  {
2089
 
    open_file(ds_filename.c_str());
 
2133
    open_file(ds_filename.str);
2090
2134
  }
2091
2135
 
 
2136
  dynstr_free(&ds_filename);
2092
2137
  return;
2093
2138
}
2094
2139
 
2095
2140
 
 
2141
static FILE* my_popen(DYNAMIC_STRING *ds_cmd, const char *mode)
 
2142
{
 
2143
  return popen(ds_cmd->str, mode);
 
2144
}
 
2145
 
 
2146
 
2096
2147
static void init_builtin_echo(void)
2097
2148
{
2098
2149
  builtin_echo[0]= 0;
2104
2155
  Replace a substring
2105
2156
 
2106
2157
  SYNOPSIS
2107
 
  replace
2108
 
  ds_str      The string to search and perform the replace in
2109
 
  search_str  The string to search for
2110
 
  search_len  Length of the string to search for
2111
 
  replace_str The string to replace with
2112
 
  replace_len Length of the string to replace with
 
2158
    replace
 
2159
    ds_str      The string to search and perform the replace in
 
2160
    search_str  The string to search for
 
2161
    search_len  Length of the string to search for
 
2162
    replace_str The string to replace with
 
2163
    replace_len Length of the string to replace with
2113
2164
 
2114
2165
  RETURN
2115
 
  0 String replaced
2116
 
  1 Could not find search_str in str
 
2166
    0 String replaced
 
2167
    1 Could not find search_str in str
2117
2168
*/
2118
2169
 
2119
 
static int replace(string *ds_str,
2120
 
                   const char *search_str, uint32_t search_len,
2121
 
                   const char *replace_str, uint32_t replace_len)
 
2170
static int replace(DYNAMIC_STRING *ds_str,
 
2171
                   const char *search_str, ulong search_len,
 
2172
                   const char *replace_str, ulong replace_len)
2122
2173
{
2123
 
  string ds_tmp;
2124
 
  const char *start= strstr(ds_str->c_str(), search_str);
 
2174
  DYNAMIC_STRING ds_tmp;
 
2175
  const char *start= strstr(ds_str->str, search_str);
2125
2176
  if (!start)
2126
2177
    return 1;
2127
 
  ds_tmp.append(ds_str->c_str(), start - ds_str->c_str());
2128
 
  ds_tmp.append(replace_str, replace_len);
2129
 
  ds_tmp.append(start + search_len);
2130
 
  *ds_str= ds_tmp;
 
2178
  init_dynamic_string(&ds_tmp, "",
 
2179
                      ds_str->length + replace_len, 256);
 
2180
  dynstr_append_mem(&ds_tmp, ds_str->str, start - ds_str->str);
 
2181
  dynstr_append_mem(&ds_tmp, replace_str, replace_len);
 
2182
  dynstr_append(&ds_tmp, start + search_len);
 
2183
  dynstr_set(ds_str, ds_tmp.str);
 
2184
  dynstr_free(&ds_tmp);
2131
2185
  return 0;
2132
2186
}
2133
2187
 
2137
2191
 
2138
2192
  SYNOPSIS
2139
2193
  do_exec()
2140
 
  query  called command
 
2194
  query called command
2141
2195
 
2142
2196
  DESCRIPTION
2143
2197
  exec <command>
2148
2202
  It can thus be used to execute a command that shall fail.
2149
2203
 
2150
2204
  NOTE
2151
 
  Although drizzletest is executed from cygwin shell, the command will be
 
2205
  Although mysqltest is executed from cygwin shell, the command will be
2152
2206
  executed in "cmd.exe". Thus commands like "rm" etc can NOT be used, use
2153
 
  drizzletest commmand(s) like "remove_file" for that
 
2207
  mysqltest commmand(s) like "remove_file" for that
2154
2208
*/
2155
2209
 
2156
2210
static void do_exec(struct st_command *command)
2159
2213
  char buf[512];
2160
2214
  FILE *res_file;
2161
2215
  char *cmd= command->first_argument;
2162
 
  string ds_cmd;
 
2216
  DYNAMIC_STRING ds_cmd;
2163
2217
 
2164
2218
  /* Skip leading space */
2165
2219
  while (*cmd && my_isspace(charset_info, *cmd))
2168
2222
    die("Missing argument in exec");
2169
2223
  command->last_argument= command->end;
2170
2224
 
 
2225
  init_dynamic_string(&ds_cmd, 0, command->query_len+256, 256);
2171
2226
  /* Eval the command, thus replacing all environment variables */
2172
2227
  do_eval(&ds_cmd, cmd, command->end, !is_windows);
2173
2228
 
2178
2233
    replace(&ds_cmd, "echo", 4, builtin_echo, strlen(builtin_echo));
2179
2234
  }
2180
2235
 
2181
 
  if (!(res_file= popen(ds_cmd.c_str(), "r")) && command->abort_on_error)
 
2236
  if (!(res_file= my_popen(&ds_cmd, "r")) && command->abort_on_error)
2182
2237
  {
 
2238
    dynstr_free(&ds_cmd);
2183
2239
    die("popen(\"%s\", \"r\") failed", command->first_argument);
2184
2240
  }
2185
2241
 
2191
2247
    }
2192
2248
    else
2193
2249
    {
2194
 
      replace_append(&ds_res, buf);
 
2250
      replace_dynstr_append(&ds_res, buf);
2195
2251
    }
2196
2252
  }
2197
2253
  error= pclose(res_file);
2203
2259
    if (command->abort_on_error)
2204
2260
    {
2205
2261
      log_msg("exec of '%s' failed, error: %d, status: %d, errno: %d",
2206
 
              ds_cmd.c_str(), error, status, errno);
 
2262
              ds_cmd.str, error, status, errno);
 
2263
      dynstr_free(&ds_cmd);
2207
2264
      die("command \"%s\" failed", command->first_argument);
2208
2265
    }
2209
2266
 
2217
2274
    }
2218
2275
    if (!ok)
2219
2276
    {
 
2277
      dynstr_free(&ds_cmd);
2220
2278
      die("command \"%s\" failed with wrong error: %d",
2221
2279
          command->first_argument, status);
2222
2280
    }
2226
2284
  {
2227
2285
    /* Error code we wanted was != 0, i.e. not an expected success */
2228
2286
    log_msg("exec of '%s failed, error: %d, errno: %d",
2229
 
            ds_cmd.c_str(), error, errno);
 
2287
            ds_cmd.str, error, errno);
 
2288
    dynstr_free(&ds_cmd);
2230
2289
    die("command \"%s\" succeeded - should have failed with errno %d...",
2231
2290
        command->first_argument, command->expected_errors.err[0].code.errnum);
2232
2291
  }
2233
2292
 
 
2293
  dynstr_free(&ds_cmd);
2234
2294
  return;
2235
2295
}
2236
2296
 
2246
2306
 
2247
2307
  SYNOPSIS
2248
2308
  do_modify_var()
2249
 
  query  called command
 
2309
  query called command
2250
2310
  operator    operation to perform on the var
2251
2311
 
2252
2312
  DESCRIPTION
2284
2344
 
2285
2345
 
2286
2346
/*
 
2347
  Wrapper for 'system' function
 
2348
 
 
2349
  NOTE
 
2350
  If mysqltest is executed from cygwin shell, the command will be
 
2351
  executed in the "windows command interpreter" cmd.exe and we prepend "sh"
 
2352
  to make it be executed by cygwins "bash". Thus commands like "rm",
 
2353
  "mkdir" as well as shellscripts can executed by "system" in Windows.
 
2354
 
 
2355
*/
 
2356
 
 
2357
static int my_system(DYNAMIC_STRING* ds_cmd)
 
2358
{
 
2359
  return system(ds_cmd->str);
 
2360
}
 
2361
 
 
2362
 
 
2363
/*
2287
2364
  SYNOPSIS
2288
2365
  do_system
2289
 
  command  called command
 
2366
  command       called command
2290
2367
 
2291
2368
  DESCRIPTION
2292
2369
  system <command>
2298
2375
 
2299
2376
static void do_system(struct st_command *command)
2300
2377
{
2301
 
  string ds_cmd;
 
2378
  DYNAMIC_STRING ds_cmd;
2302
2379
 
2303
2380
 
2304
2381
  if (strlen(command->first_argument) == 0)
2305
2382
    die("Missing arguments to system, nothing to do!");
2306
2383
 
 
2384
  init_dynamic_string(&ds_cmd, 0, command->query_len + 64, 256);
 
2385
 
2307
2386
  /* Eval the system command, thus replacing all environment variables */
2308
2387
  do_eval(&ds_cmd, command->first_argument, command->end, !is_windows);
2309
2388
 
2310
 
  if (system(ds_cmd.c_str()))
 
2389
  if (my_system(&ds_cmd))
2311
2390
  {
2312
2391
    if (command->abort_on_error)
2313
2392
      die("system command '%s' failed", command->first_argument);
2314
2393
 
2315
2394
    /* If ! abort_on_error, log message and continue */
2316
 
    ds_res.append("system command '");
2317
 
    replace_append(&ds_res, command->first_argument);
2318
 
    ds_res.append("' failed\n");
 
2395
    dynstr_append(&ds_res, "system command '");
 
2396
    replace_dynstr_append(&ds_res, command->first_argument);
 
2397
    dynstr_append(&ds_res, "' failed\n");
2319
2398
  }
2320
2399
 
2321
2400
  command->last_argument= command->end;
 
2401
  dynstr_free(&ds_cmd);
2322
2402
  return;
2323
2403
}
2324
2404
 
2326
2406
/*
2327
2407
  SYNOPSIS
2328
2408
  do_remove_file
2329
 
  command  called command
 
2409
  command       called command
2330
2410
 
2331
2411
  DESCRIPTION
2332
2412
  remove_file <file_name>
2336
2416
static void do_remove_file(struct st_command *command)
2337
2417
{
2338
2418
  int error;
2339
 
  string ds_filename;
 
2419
  static DYNAMIC_STRING ds_filename;
2340
2420
  const struct command_arg rm_args[] = {
2341
2421
    { "filename", ARG_STRING, true, &ds_filename, "File to delete" }
2342
2422
  };
2346
2426
                     rm_args, sizeof(rm_args)/sizeof(struct command_arg),
2347
2427
                     ' ');
2348
2428
 
2349
 
  error= my_delete(ds_filename.c_str(), MYF(0)) != 0;
 
2429
  error= my_delete(ds_filename.str, MYF(0)) != 0;
2350
2430
  handle_command_error(command, error);
 
2431
  dynstr_free(&ds_filename);
2351
2432
  return;
2352
2433
}
2353
2434
 
2355
2436
/*
2356
2437
  SYNOPSIS
2357
2438
  do_copy_file
2358
 
  command  command handle
 
2439
  command       command handle
2359
2440
 
2360
2441
  DESCRIPTION
2361
2442
  copy_file <from_file> <to_file>
2367
2448
static void do_copy_file(struct st_command *command)
2368
2449
{
2369
2450
  int error;
2370
 
  string ds_from_file;
2371
 
  string ds_to_file;
 
2451
  static DYNAMIC_STRING ds_from_file;
 
2452
  static DYNAMIC_STRING ds_to_file;
2372
2453
  const struct command_arg copy_file_args[] = {
2373
2454
    { "from_file", ARG_STRING, true, &ds_from_file, "Filename to copy from" },
2374
2455
    { "to_file", ARG_STRING, true, &ds_to_file, "Filename to copy to" }
2380
2461
                     sizeof(copy_file_args)/sizeof(struct command_arg),
2381
2462
                     ' ');
2382
2463
 
2383
 
  error= (my_copy(ds_from_file.c_str(), ds_to_file.c_str(),
 
2464
  error= (my_copy(ds_from_file.str, ds_to_file.str,
2384
2465
                  MYF(MY_DONT_OVERWRITE_FILE)) != 0);
2385
2466
  handle_command_error(command, error);
 
2467
  dynstr_free(&ds_from_file);
 
2468
  dynstr_free(&ds_to_file);
2386
2469
  return;
2387
2470
}
2388
2471
 
2390
2473
/*
2391
2474
  SYNOPSIS
2392
2475
  do_chmod_file
2393
 
  command  command handle
 
2476
  command       command handle
2394
2477
 
2395
2478
  DESCRIPTION
2396
2479
  chmod <octal> <file_name>
2401
2484
static void do_chmod_file(struct st_command *command)
2402
2485
{
2403
2486
  long mode= 0;
2404
 
  string ds_mode;
2405
 
  string ds_file;
 
2487
  static DYNAMIC_STRING ds_mode;
 
2488
  static DYNAMIC_STRING ds_file;
2406
2489
  const struct command_arg chmod_file_args[] = {
2407
 
    { "mode", ARG_STRING, true, &ds_mode, "Mode of file(octal) ex. 0660"},
 
2490
    { "mode", ARG_STRING, true, &ds_mode, "Mode of file(octal) ex. 0660"}, 
2408
2491
    { "filename", ARG_STRING, true, &ds_file, "Filename of file to modify" }
2409
2492
  };
2410
2493
 
2415
2498
                     ' ');
2416
2499
 
2417
2500
  /* Parse what mode to set */
2418
 
  if (ds_mode.length() != 4 ||
2419
 
      str2int(ds_mode.c_str(), 8, 0, INT_MAX, &mode) == NULL)
 
2501
  if (ds_mode.length != 4 ||
 
2502
      str2int(ds_mode.str, 8, 0, INT_MAX, &mode) == NullS)
2420
2503
    die("You must write a 4 digit octal number for mode");
2421
2504
 
2422
 
  handle_command_error(command, chmod(ds_file.c_str(), mode));
 
2505
  handle_command_error(command, chmod(ds_file.str, mode));
 
2506
  dynstr_free(&ds_mode);
 
2507
  dynstr_free(&ds_file);
2423
2508
  return;
2424
2509
}
2425
2510
 
2427
2512
/*
2428
2513
  SYNOPSIS
2429
2514
  do_file_exists
2430
 
  command  called command
 
2515
  command       called command
2431
2516
 
2432
2517
  DESCRIPTION
2433
2518
  fiile_exist <file_name>
2437
2522
static void do_file_exist(struct st_command *command)
2438
2523
{
2439
2524
  int error;
2440
 
  string ds_filename;
 
2525
  static DYNAMIC_STRING ds_filename;
2441
2526
  const struct command_arg file_exist_args[] = {
2442
2527
    { "filename", ARG_STRING, true, &ds_filename, "File to check if it exist" }
2443
2528
  };
2448
2533
                     sizeof(file_exist_args)/sizeof(struct command_arg),
2449
2534
                     ' ');
2450
2535
 
2451
 
  error= (access(ds_filename.c_str(), F_OK) != 0);
 
2536
  error= (access(ds_filename.str, F_OK) != 0);
2452
2537
  handle_command_error(command, error);
 
2538
  dynstr_free(&ds_filename);
2453
2539
  return;
2454
2540
}
2455
2541
 
2457
2543
/*
2458
2544
  SYNOPSIS
2459
2545
  do_mkdir
2460
 
  command  called command
 
2546
  command       called command
2461
2547
 
2462
2548
  DESCRIPTION
2463
2549
  mkdir <dir_name>
2467
2553
static void do_mkdir(struct st_command *command)
2468
2554
{
2469
2555
  int error;
2470
 
  string ds_dirname;
 
2556
  static DYNAMIC_STRING ds_dirname;
2471
2557
  const struct command_arg mkdir_args[] = {
2472
2558
    {"dirname", ARG_STRING, true, &ds_dirname, "Directory to create"}
2473
2559
  };
2477
2563
                     mkdir_args, sizeof(mkdir_args)/sizeof(struct command_arg),
2478
2564
                     ' ');
2479
2565
 
2480
 
  error= my_mkdir(ds_dirname.c_str(), 0777, MYF(0)) != 0;
 
2566
  error= my_mkdir(ds_dirname.str, 0777, MYF(0)) != 0;
2481
2567
  handle_command_error(command, error);
 
2568
  dynstr_free(&ds_dirname);
2482
2569
  return;
2483
2570
}
2484
2571
 
2485
2572
/*
2486
2573
  SYNOPSIS
2487
2574
  do_rmdir
2488
 
  command  called command
 
2575
  command       called command
2489
2576
 
2490
2577
  DESCRIPTION
2491
2578
  rmdir <dir_name>
2495
2582
static void do_rmdir(struct st_command *command)
2496
2583
{
2497
2584
  int error;
2498
 
  string ds_dirname;
 
2585
  static DYNAMIC_STRING ds_dirname;
2499
2586
  const struct command_arg rmdir_args[] = {
2500
2587
    {"dirname", ARG_STRING, true, &ds_dirname, "Directory to remove"}
2501
2588
  };
2505
2592
                     rmdir_args, sizeof(rmdir_args)/sizeof(struct command_arg),
2506
2593
                     ' ');
2507
2594
 
2508
 
  error= rmdir(ds_dirname.c_str()) != 0;
 
2595
  error= rmdir(ds_dirname.str) != 0;
2509
2596
  handle_command_error(command, error);
 
2597
  dynstr_free(&ds_dirname);
2510
2598
  return;
2511
2599
}
2512
2600
 
2535
2623
}
2536
2624
 
2537
2625
 
2538
 
static void read_until_delimiter(string *ds,
2539
 
                                 string *ds_delimiter)
 
2626
static void read_until_delimiter(DYNAMIC_STRING *ds,
 
2627
                                 DYNAMIC_STRING *ds_delimiter)
2540
2628
{
2541
2629
  char c;
2542
2630
 
2543
 
  if (ds_delimiter->length() > MAX_DELIMITER_LENGTH)
 
2631
  if (ds_delimiter->length > MAX_DELIMITER_LENGTH)
2544
2632
    die("Max delimiter length(%d) exceeded", MAX_DELIMITER_LENGTH);
2545
2633
 
2546
2634
  /* Read from file until delimiter is found */
2567
2655
 
2568
2656
    if (feof(cur_file->file))
2569
2657
      die("End of file encountered before '%s' delimiter was found",
2570
 
          ds_delimiter->c_str());
 
2658
          ds_delimiter->str);
2571
2659
 
2572
 
    if (match_delimiter(c, ds_delimiter->c_str(), ds_delimiter->length()))
 
2660
    if (match_delimiter(c, ds_delimiter->str, ds_delimiter->length))
2573
2661
      break;
2574
2662
 
2575
 
    ds->push_back(c);
 
2663
    dynstr_append_mem(ds, (const char*)&c, 1);
2576
2664
  }
2577
2665
  return;
2578
2666
}
2580
2668
 
2581
2669
static void do_write_file_command(struct st_command *command, bool append)
2582
2670
{
2583
 
  string ds_content;
2584
 
  string ds_filename;
2585
 
  string ds_delimiter;
 
2671
  static DYNAMIC_STRING ds_content;
 
2672
  static DYNAMIC_STRING ds_filename;
 
2673
  static DYNAMIC_STRING ds_delimiter;
2586
2674
  const struct command_arg write_file_args[] = {
2587
2675
    { "filename", ARG_STRING, true, &ds_filename, "File to write to" },
2588
2676
    { "delimiter", ARG_STRING, false, &ds_delimiter, "Delimiter to read until" }
2596
2684
                     ' ');
2597
2685
 
2598
2686
  /* If no delimiter was provided, use EOF */
2599
 
  if (ds_delimiter.length() == 0)
2600
 
    ds_delimiter= "EOF";
 
2687
  if (ds_delimiter.length == 0)
 
2688
    dynstr_set(&ds_delimiter, "EOF");
2601
2689
 
2602
 
  if (!append && access(ds_filename.c_str(), F_OK) == 0)
 
2690
  if (!append && access(ds_filename.str, F_OK) == 0)
2603
2691
  {
2604
2692
    /* The file should not be overwritten */
2605
 
    die("File already exist: '%s'", ds_filename.c_str());
 
2693
    die("File already exist: '%s'", ds_filename.str);
2606
2694
  }
2607
2695
 
 
2696
  init_dynamic_string(&ds_content, "", 1024, 1024);
2608
2697
  read_until_delimiter(&ds_content, &ds_delimiter);
2609
 
  str_to_file2(ds_filename.c_str(), ds_content.c_str(),
2610
 
               ds_content.length(), append);
 
2698
  str_to_file2(ds_filename.str, ds_content.str, ds_content.length, append);
 
2699
  dynstr_free(&ds_content);
 
2700
  dynstr_free(&ds_filename);
 
2701
  dynstr_free(&ds_delimiter);
2611
2702
  return;
2612
2703
}
2613
2704
 
2615
2706
/*
2616
2707
  SYNOPSIS
2617
2708
  do_write_file
2618
 
  command  called command
 
2709
  command       called command
2619
2710
 
2620
2711
  DESCRIPTION
2621
2712
  write_file <file_name> [<delimiter>];
2648
2739
/*
2649
2740
  SYNOPSIS
2650
2741
  do_append_file
2651
 
  command  called command
 
2742
  command       called command
2652
2743
 
2653
2744
  DESCRIPTION
2654
2745
  append_file <file_name> [<delimiter>];
2679
2770
/*
2680
2771
  SYNOPSIS
2681
2772
  do_cat_file
2682
 
  command  called command
 
2773
  command       called command
2683
2774
 
2684
2775
  DESCRIPTION
2685
2776
  cat_file <file_name>;
2690
2781
 
2691
2782
static void do_cat_file(struct st_command *command)
2692
2783
{
2693
 
  static string ds_filename;
 
2784
  static DYNAMIC_STRING ds_filename;
2694
2785
  const struct command_arg cat_file_args[] = {
2695
2786
    { "filename", ARG_STRING, true, &ds_filename, "File to read from" }
2696
2787
  };
2702
2793
                     sizeof(cat_file_args)/sizeof(struct command_arg),
2703
2794
                     ' ');
2704
2795
 
2705
 
  cat_file(&ds_res, ds_filename.c_str());
 
2796
  cat_file(&ds_res, ds_filename.str);
2706
2797
 
 
2798
  dynstr_free(&ds_filename);
2707
2799
  return;
2708
2800
}
2709
2801
 
2711
2803
/*
2712
2804
  SYNOPSIS
2713
2805
  do_diff_files
2714
 
  command  called command
 
2806
  command       called command
2715
2807
 
2716
2808
  DESCRIPTION
2717
2809
  diff_files <file1> <file2>;
2723
2815
static void do_diff_files(struct st_command *command)
2724
2816
{
2725
2817
  int error= 0;
2726
 
  string ds_filename;
2727
 
  string ds_filename2;
 
2818
  static DYNAMIC_STRING ds_filename;
 
2819
  static DYNAMIC_STRING ds_filename2;
2728
2820
  const struct command_arg diff_file_args[] = {
2729
2821
    { "file1", ARG_STRING, true, &ds_filename, "First file to diff" },
2730
2822
    { "file2", ARG_STRING, true, &ds_filename2, "Second file to diff" }
2737
2829
                     sizeof(diff_file_args)/sizeof(struct command_arg),
2738
2830
                     ' ');
2739
2831
 
2740
 
  if ((error= compare_files(ds_filename.c_str(), ds_filename2.c_str())))
 
2832
  if ((error= compare_files(ds_filename.str, ds_filename2.str)))
2741
2833
  {
2742
2834
    /* Compare of the two files failed, append them to output
2743
2835
       so the failure can be analyzed
2744
2836
    */
2745
 
    show_diff(&ds_res, ds_filename.c_str(), ds_filename2.c_str());
 
2837
    show_diff(&ds_res, ds_filename.str, ds_filename2.str);
2746
2838
  }
2747
2839
 
 
2840
  dynstr_free(&ds_filename);
 
2841
  dynstr_free(&ds_filename2);
2748
2842
  handle_command_error(command, error);
2749
2843
  return;
2750
2844
}
2767
2861
/*
2768
2862
  SYNOPSIS
2769
2863
  do_send_quit
2770
 
  command  called command
 
2864
  command       called command
2771
2865
 
2772
2866
  DESCRIPTION
2773
2867
  Sends a simple quit command to the server for the named connection.
2792
2886
  if (!(con= find_connection_by_name(name)))
2793
2887
    die("connection '%s' not found in connection pool", name);
2794
2888
 
2795
 
  simple_command(&con->drizzle,COM_QUIT,0,0,1);
 
2889
  simple_command(&con->mysql,COM_QUIT,0,0,1);
2796
2890
 
2797
2891
  return;
2798
2892
}
2816
2910
 
2817
2911
static void do_change_user(struct st_command *command)
2818
2912
{
2819
 
  DRIZZLE *drizzle= &cur_con->drizzle;
 
2913
  MYSQL *mysql = &cur_con->mysql;
2820
2914
  /* static keyword to make the NetWare compiler happy. */
2821
 
  string ds_user, ds_passwd, ds_db;
 
2915
  static DYNAMIC_STRING ds_user, ds_passwd, ds_db;
2822
2916
  const struct command_arg change_user_args[] = {
2823
2917
    { "user", ARG_STRING, false, &ds_user, "User to connect as" },
2824
2918
    { "password", ARG_STRING, false, &ds_passwd, "Password used when connecting" },
2832
2926
                     sizeof(change_user_args)/sizeof(struct command_arg),
2833
2927
                     ',');
2834
2928
 
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
 
 
 
2929
  if (!ds_user.length)
 
2930
    dynstr_set(&ds_user, mysql->user);
 
2931
 
 
2932
  if (!ds_passwd.length)
 
2933
    dynstr_set(&ds_passwd, mysql->passwd);
 
2934
 
 
2935
  if (!ds_db.length)
 
2936
    dynstr_set(&ds_db, mysql->db);
 
2937
 
 
2938
  if (mysql_change_user(mysql, ds_user.str, ds_passwd.str, ds_db.str))
 
2939
    die("change user failed: %s", mysql_error(mysql));
 
2940
 
 
2941
  dynstr_free(&ds_user);
 
2942
  dynstr_free(&ds_passwd);
 
2943
  dynstr_free(&ds_db);
2848
2944
 
2849
2945
  return;
2850
2946
}
2853
2949
/*
2854
2950
  SYNOPSIS
2855
2951
  do_perl
2856
 
  command  command handle
 
2952
  command       command handle
2857
2953
 
2858
2954
  DESCRIPTION
2859
2955
  perl [<delimiter>];
2876
2972
  FILE *res_file;
2877
2973
  char buf[FN_REFLEN];
2878
2974
  char temp_file_path[FN_REFLEN];
2879
 
  string ds_script;
2880
 
  string ds_delimiter;
 
2975
  static DYNAMIC_STRING ds_script;
 
2976
  static DYNAMIC_STRING ds_delimiter;
2881
2977
  const struct command_arg perl_args[] = {
2882
2978
    { "delimiter", ARG_STRING, false, &ds_delimiter, "Delimiter to read until" }
2883
2979
  };
2890
2986
                     ' ');
2891
2987
 
2892
2988
  /* If no delimiter was provided, use EOF */
2893
 
  if (ds_delimiter.length() == 0)
2894
 
    ds_delimiter= "EOF";
 
2989
  if (ds_delimiter.length == 0)
 
2990
    dynstr_set(&ds_delimiter, "EOF");
2895
2991
 
 
2992
  init_dynamic_string(&ds_script, "", 1024, 1024);
2896
2993
  read_until_delimiter(&ds_script, &ds_delimiter);
2897
2994
 
2898
2995
  /* Create temporary file name */
2902
2999
    die("Failed to create temporary file for perl command");
2903
3000
  my_close(fd, MYF(0));
2904
3001
 
2905
 
  str_to_file(temp_file_path, ds_script.c_str(), ds_script.length());
 
3002
  str_to_file(temp_file_path, ds_script.str, ds_script.length);
2906
3003
 
2907
3004
  /* Format the "perl <filename>" command */
2908
3005
  snprintf(buf, sizeof(buf), "perl %s", temp_file_path);
2915
3012
    if (disable_result_log)
2916
3013
      buf[strlen(buf)-1]=0;
2917
3014
    else
2918
 
      replace_append(&ds_res, buf);
 
3015
      replace_dynstr_append(&ds_res, buf);
2919
3016
  }
2920
3017
  error= pclose(res_file);
2921
3018
 
2923
3020
  my_delete(temp_file_path, MYF(0));
2924
3021
 
2925
3022
  handle_command_error(command, WEXITSTATUS(error));
 
3023
  dynstr_free(&ds_script);
 
3024
  dynstr_free(&ds_delimiter);
2926
3025
  return;
2927
3026
}
2928
3027
 
2930
3029
/*
2931
3030
  Print the content between echo and <delimiter> to result file.
2932
3031
  Evaluate all variables in the string before printing, allow
2933
 
  for variable names to be escaped using        \
 
3032
  for variable names to be escaped using \
2934
3033
 
2935
3034
  SYNOPSIS
2936
3035
  do_echo()
2953
3052
 
2954
3053
static int do_echo(struct st_command *command)
2955
3054
{
2956
 
  string ds_echo;
2957
 
 
2958
 
 
 
3055
  DYNAMIC_STRING ds_echo;
 
3056
 
 
3057
 
 
3058
  init_dynamic_string(&ds_echo, "", command->query_len, 256);
2959
3059
  do_eval(&ds_echo, command->first_argument, command->end, false);
2960
 
  ds_res.append(ds_echo.c_str(), ds_echo.length());
2961
 
  ds_res.append("\n");
 
3060
  dynstr_append_mem(&ds_res, ds_echo.str, ds_echo.length);
 
3061
  dynstr_append_mem(&ds_res, "\n", 1);
 
3062
  dynstr_free(&ds_echo);
2962
3063
  command->last_argument= command->end;
2963
3064
  return(0);
2964
3065
}
2968
3069
do_wait_for_slave_to_stop(struct st_command *c __attribute__((unused)))
2969
3070
{
2970
3071
  static int SLAVE_POLL_INTERVAL= 300000;
2971
 
  DRIZZLE *drizzle= &cur_con->drizzle;
 
3072
  MYSQL* mysql = &cur_con->mysql;
2972
3073
  for (;;)
2973
3074
  {
2974
 
    DRIZZLE_RES *res= NULL;
2975
 
    DRIZZLE_ROW row;
 
3075
    MYSQL_RES *res= NULL;
 
3076
    MYSQL_ROW row;
2976
3077
    int done;
2977
3078
 
2978
 
    if (drizzle_query(drizzle,"show status like 'Slave_running'") ||
2979
 
        !(res=drizzle_store_result(drizzle)))
 
3079
    if (mysql_query(mysql,"show status like 'Slave_running'") ||
 
3080
        !(res=mysql_store_result(mysql)))
2980
3081
      die("Query failed while probing slave for stop: %s",
2981
 
          drizzle_error(drizzle));
2982
 
    if (!(row=drizzle_fetch_row(res)) || !row[1])
 
3082
          mysql_error(mysql));
 
3083
    if (!(row=mysql_fetch_row(res)) || !row[1])
2983
3084
    {
2984
 
      drizzle_free_result(res);
 
3085
      mysql_free_result(res);
2985
3086
      die("Strange result from query while probing slave for stop");
2986
3087
    }
2987
3088
    done = !strcmp(row[1],"OFF");
2988
 
    drizzle_free_result(res);
 
3089
    mysql_free_result(res);
2989
3090
    if (done)
2990
3091
      break;
2991
3092
    my_sleep(SLAVE_POLL_INTERVAL);
2996
3097
 
2997
3098
static void do_sync_with_master2(long offset)
2998
3099
{
2999
 
  DRIZZLE_RES *res;
3000
 
  DRIZZLE_ROW row;
3001
 
  DRIZZLE *drizzle= &cur_con->drizzle;
 
3100
  MYSQL_RES *res;
 
3101
  MYSQL_ROW row;
 
3102
  MYSQL *mysql= &cur_con->mysql;
3002
3103
  char query_buf[FN_REFLEN+128];
3003
3104
  int tries= 0;
3004
3105
 
3006
3107
    die("Calling 'sync_with_master' without calling 'save_master_pos'");
3007
3108
 
3008
3109
  sprintf(query_buf, "select master_pos_wait('%s', %ld)", master_pos.file,
3009
 
          master_pos.pos + offset);
 
3110
          master_pos.pos + offset);
3010
3111
 
3011
3112
wait_for_position:
3012
3113
 
3013
 
  if (drizzle_query(drizzle, query_buf))
3014
 
    die("failed in '%s': %d: %s", query_buf, drizzle_errno(drizzle),
3015
 
        drizzle_error(drizzle));
 
3114
  if (mysql_query(mysql, query_buf))
 
3115
    die("failed in '%s': %d: %s", query_buf, mysql_errno(mysql),
 
3116
        mysql_error(mysql));
3016
3117
 
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)))
 
3118
  if (!(res= mysql_store_result(mysql)))
 
3119
    die("mysql_store_result() returned NULL for '%s'", query_buf);
 
3120
  if (!(row= mysql_fetch_row(res)))
3020
3121
  {
3021
 
    drizzle_free_result(res);
 
3122
    mysql_free_result(res);
3022
3123
    die("empty result in %s", query_buf);
3023
3124
  }
3024
3125
  if (!row[0])
3027
3128
      It may be that the slave SQL thread has not started yet, though START
3028
3129
      SLAVE has been issued ?
3029
3130
    */
3030
 
    drizzle_free_result(res);
 
3131
    mysql_free_result(res);
3031
3132
    if (tries++ == 30)
3032
3133
    {
3033
 
      show_query(drizzle, "SHOW MASTER STATUS");
3034
 
      show_query(drizzle, "SHOW SLAVE STATUS");
 
3134
      show_query(mysql, "SHOW MASTER STATUS");
 
3135
      show_query(mysql, "SHOW SLAVE STATUS");
3035
3136
      die("could not sync with master ('%s' returned NULL)", query_buf);
3036
3137
    }
3037
3138
    sleep(1); /* So at most we will wait 30 seconds and make 31 tries */
3038
3139
    goto wait_for_position;
3039
3140
  }
3040
 
  drizzle_free_result(res);
 
3141
  mysql_free_result(res);
3041
3142
  return;
3042
3143
}
3043
3144
 
3063
3164
 
3064
3165
/*
3065
3166
  when ndb binlog is on, this call will wait until last updated epoch
3066
 
  (locally in the drizzled) has been received into the binlog
 
3167
  (locally in the mysqld) has been received into the binlog
3067
3168
*/
3068
3169
static int do_save_master_pos(void)
3069
3170
{
3070
 
  DRIZZLE_RES *res;
3071
 
  DRIZZLE_ROW row;
3072
 
  DRIZZLE *drizzle= &cur_con->drizzle;
 
3171
  MYSQL_RES *res;
 
3172
  MYSQL_ROW row;
 
3173
  MYSQL *mysql = &cur_con->mysql;
3073
3174
  const char *query;
3074
3175
 
3075
3176
 
3076
 
  if (drizzle_query(drizzle, query= "show master status"))
 
3177
  if (mysql_query(mysql, query= "show master status"))
3077
3178
    die("failed in 'show master status': %d %s",
3078
 
        drizzle_errno(drizzle), drizzle_error(drizzle));
 
3179
        mysql_errno(mysql), mysql_error(mysql));
3079
3180
 
3080
 
  if (!(res = drizzle_store_result(drizzle)))
3081
 
    die("drizzle_store_result() retuned NULL for '%s'", query);
3082
 
  if (!(row = drizzle_fetch_row(res)))
 
3181
  if (!(res = mysql_store_result(mysql)))
 
3182
    die("mysql_store_result() retuned NULL for '%s'", query);
 
3183
  if (!(row = mysql_fetch_row(res)))
3083
3184
    die("empty result in show master status");
3084
 
  my_stpncpy(master_pos.file, row[0], sizeof(master_pos.file)-1);
 
3185
  strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1);
3085
3186
  master_pos.pos = strtoul(row[1], (char**) 0, 10);
3086
 
  drizzle_free_result(res);
 
3187
  mysql_free_result(res);
3087
3188
  return(0);
3088
3189
}
3089
3190
 
3093
3194
 
3094
3195
  SYNOPSIS
3095
3196
  do_let()
3096
 
  query  called command
 
3197
  query called command
3097
3198
 
3098
3199
  DESCRIPTION
3099
3200
  let $<var_name>=<var_val><delimiter>
3111
3212
{
3112
3213
  char *p= command->first_argument;
3113
3214
  char *var_name, *var_name_end;
3114
 
  string let_rhs_expr;
3115
 
 
 
3215
  DYNAMIC_STRING let_rhs_expr;
 
3216
 
 
3217
 
 
3218
  init_dynamic_string(&let_rhs_expr, "", 512, 2048);
3116
3219
 
3117
3220
  /* Find <var_name> */
3118
3221
  if (!*p)
3137
3240
 
3138
3241
  command->last_argument= command->end;
3139
3242
  /* Assign var_val to var_name */
3140
 
  var_set(var_name, var_name_end, let_rhs_expr.c_str(),
3141
 
          (let_rhs_expr.c_str() + let_rhs_expr.length()));
 
3243
  var_set(var_name, var_name_end, let_rhs_expr.str,
 
3244
          (let_rhs_expr.str + let_rhs_expr.length));
 
3245
  dynstr_free(&let_rhs_expr);
3142
3246
  return;
3143
3247
}
3144
3248
 
3148
3252
 
3149
3253
  SYNOPSIS
3150
3254
  do_sleep()
3151
 
  q         called command
 
3255
  q            called command
3152
3256
  real_sleep   use the value from opt_sleep as number of seconds to sleep
3153
 
  if real_sleep is false
 
3257
               if real_sleep is false
3154
3258
 
3155
3259
  DESCRIPTION
3156
3260
  sleep <seconds>
3191
3295
    sleep_val= opt_sleep;
3192
3296
 
3193
3297
  if (sleep_val)
3194
 
    my_sleep((uint32_t) (sleep_val * 1000000L));
 
3298
    my_sleep((ulong) (sleep_val * 1000000L));
3195
3299
  command->last_argument= sleep_end;
3196
3300
  return 0;
3197
3301
}
3198
3302
 
3199
3303
 
3200
3304
static void do_get_file_name(struct st_command *command,
3201
 
                             char* dest, uint dest_max_len)
 
3305
                      char* dest, uint dest_max_len)
3202
3306
{
3203
3307
  char *p= command->first_argument, *name;
3204
3308
  if (!*p)
3232
3336
    abort_not_supported_test("Test requires charset '%s'", charset_name);
3233
3337
}
3234
3338
 
 
3339
 
 
3340
#if MYSQL_VERSION_ID >= 50000
 
3341
/* List of error names to error codes, available from 5.0 */
 
3342
typedef struct
 
3343
{
 
3344
  const char *name;
 
3345
  uint        code;
 
3346
} st_error;
 
3347
 
 
3348
static st_error global_error_names[] =
 
3349
{
 
3350
#include <mysqld_ername.h>
 
3351
  { 0, 0 }
 
3352
};
 
3353
 
3235
3354
static uint get_errcode_from_name(char *error_name, char *error_end)
3236
3355
{
3237
3356
  /* SQL error as string */
3255
3374
    die("Unknown SQL error name '%s'", error_name);
3256
3375
  return(0);
3257
3376
}
 
3377
#else
 
3378
uint get_errcode_from_name(char *error_name __attribute__((unused)),
 
3379
                           char *error_end __attribute__((unused)))
 
3380
{
 
3381
  abort_not_in_this_version();
 
3382
  return 0; /* Never reached */
 
3383
}
 
3384
#endif
 
3385
 
 
3386
 
3258
3387
 
3259
3388
static void do_get_errcodes(struct st_command *command)
3260
3389
{
3299
3428
        if (my_isdigit(charset_info, *p) || my_isupper(charset_info, *p))
3300
3429
          *to_ptr++= *p++;
3301
3430
        else
3302
 
          die("The sqlstate may only consist of digits[0-9] "   \
 
3431
          die("The sqlstate may only consist of digits[0-9] " \
3303
3432
              "and _uppercase_ letters");
3304
3433
      }
3305
3434
 
3329
3458
      while (*p && p != end)
3330
3459
      {
3331
3460
        if (!my_isdigit(charset_info, *p))
3332
 
          die("Invalid argument to error: '%s' - "              \
 
3461
          die("Invalid argument to error: '%s' - "\
3333
3462
              "the errno may only consist of digits[0-9]",
3334
3463
              command->first_argument);
3335
3464
        p++;
3337
3466
 
3338
3467
      /* Convert the sting to int */
3339
3468
      if (!str2int(start, 10, (long) INT_MIN, (long) INT_MAX, &val))
3340
 
        die("Invalid argument to error: '%s'", command->first_argument);
 
3469
        die("Invalid argument to error: '%s'", command->first_argument);
3341
3470
 
3342
3471
      to->code.errnum= (uint) val;
3343
3472
      to->type= ERR_ERRNO;
3387
3516
  if (*from == '"' || *from == '\'')
3388
3517
    sep= *from++;
3389
3518
  else
3390
 
    sep=' ';        /* Separated with space */
 
3519
    sep=' ';                            /* Separated with space */
3391
3520
 
3392
3521
  for ( ; (c=*from) ; from++)
3393
3522
  {
3394
3523
    if (c == '\\' && from[1])
3395
 
    {          /* Escaped character */
 
3524
    {                                   /* Escaped character */
3396
3525
      /* We can't translate \0 -> ASCII 0 as replace can't handle ASCII 0 */
3397
3526
      switch (*++from) {
3398
3527
      case 'n':
3399
 
        *to++= '\n';
3400
 
        break;
 
3528
        *to++= '\n';
 
3529
        break;
3401
3530
      case 't':
3402
 
        *to++= '\t';
3403
 
        break;
 
3531
        *to++= '\t';
 
3532
        break;
3404
3533
      case 'r':
3405
 
        *to++ = '\r';
3406
 
        break;
 
3534
        *to++ = '\r';
 
3535
        break;
3407
3536
      case 'b':
3408
 
        *to++ = '\b';
3409
 
        break;
3410
 
      case 'Z':        /* ^Z must be escaped on Win32 */
3411
 
        *to++='\032';
3412
 
        break;
 
3537
        *to++ = '\b';
 
3538
        break;
 
3539
      case 'Z':                         /* ^Z must be escaped on Win32 */
 
3540
        *to++='\032';
 
3541
        break;
3413
3542
      default:
3414
 
        *to++ = *from;
3415
 
        break;
 
3543
        *to++ = *from;
 
3544
        break;
3416
3545
      }
3417
3546
    }
3418
3547
    else if (c == sep)
3419
3548
    {
3420
3549
      if (c == ' ' || c != *++from)
3421
 
        break;        /* Found end of string */
3422
 
      *to++=c;        /* Copy duplicated separator */
 
3550
        break;                          /* Found end of string */
 
3551
      *to++=c;                          /* Copy duplicated separator */
3423
3552
    }
3424
3553
    else
3425
3554
      *to++=c;
3427
3556
  if (*from != ' ' && *from)
3428
3557
    die("Wrong string argument in %s", command->query);
3429
3558
 
3430
 
  while (my_isspace(charset_info,*from))  /* Point to next string */
 
3559
  while (my_isspace(charset_info,*from))        /* Point to next string */
3431
3560
    from++;
3432
3561
 
3433
 
  *to =0;        /* End of string marker */
3434
 
  *to_ptr= to+1;      /* Store pointer to end */
 
3562
  *to =0;                               /* End of string marker */
 
3563
  *to_ptr= to+1;                        /* Store pointer to end */
3435
3564
  *from_ptr= from;
3436
3565
 
3437
3566
  /* Check if this was a variable */
3440
3569
    const char *end= to;
3441
3570
    VAR *var=var_get(start, &end, 0, 1);
3442
3571
    if (var && to == (char*) end+1)
3443
 
      return(var->str_val);  /* return found variable value */
 
3572
      return(var->str_val);     /* return found variable value */
3444
3573
  }
3445
3574
  return(start);
3446
3575
}
3447
3576
 
3448
3577
 
3449
 
static void set_reconnect(DRIZZLE *drizzle, int val)
 
3578
static void set_reconnect(MYSQL* mysql, int val)
3450
3579
{
3451
3580
  bool reconnect= val;
3452
3581
 
3453
 
  drizzle_options(drizzle, DRIZZLE_OPT_RECONNECT, (char *)&reconnect);
 
3582
  mysql_options(mysql, MYSQL_OPT_RECONNECT, (char *)&reconnect);
3454
3583
 
3455
3584
  return;
3456
3585
}
3461
3590
  if (!(cur_con= find_connection_by_name(name)))
3462
3591
    die("connection '%s' not found in connection pool", name);
3463
3592
 
3464
 
  /* Update $drizzle_get_server_version to that of current connection */
3465
 
  var_set_drizzle_get_server_version(&cur_con->drizzle);
 
3593
  /* Update $mysql_get_server_version to that of current connection */
 
3594
  var_set_mysql_get_server_version(&cur_con->mysql);
3466
3595
 
3467
3596
  return(0);
3468
3597
}
3506
3635
 
3507
3636
  if (command->type == Q_DIRTY_CLOSE)
3508
3637
  {
3509
 
    if (con->drizzle.net.vio)
 
3638
    if (con->mysql.net.vio)
3510
3639
    {
3511
 
      net_close(&(con->drizzle.net));
 
3640
      vio_delete(con->mysql.net.vio);
 
3641
      con->mysql.net.vio = 0;
3512
3642
    }
3513
3643
  }
3514
3644
 
3515
 
  drizzle_close(&con->drizzle);
3516
 
 
3517
 
  if (con->util_drizzle)
3518
 
    drizzle_close(con->util_drizzle);
3519
 
  con->util_drizzle= 0;
3520
 
 
3521
 
  free(con->name);
 
3645
  mysql_close(&con->mysql);
 
3646
 
 
3647
  if (con->util_mysql)
 
3648
    mysql_close(con->util_mysql);
 
3649
  con->util_mysql= 0;
 
3650
 
 
3651
  my_free(con->name, MYF(0));
3522
3652
 
3523
3653
  /*
3524
3654
    When the connection is closed set name to "-closed_connection-"
3556
3686
 
3557
3687
*/
3558
3688
 
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)
 
3689
static void safe_connect(MYSQL* mysql, const char *name, const char *host,
 
3690
                  const char *user, const char *pass, const char *db,
 
3691
                  int port)
3562
3692
{
3563
3693
  int failed_attempts= 0;
3564
 
  static uint32_t connection_retry_sleep= 100000; /* Microseconds */
3565
 
 
3566
 
 
3567
 
  while(!drizzle_connect(drizzle, host, user, pass, db, port, NULL,
3568
 
                         CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS))
 
3694
  static ulong connection_retry_sleep= 100000; /* Microseconds */
 
3695
 
 
3696
 
 
3697
  while(!mysql_real_connect(mysql, host, user, pass, db, port, NULL,
 
3698
                            CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS))
3569
3699
  {
3570
3700
    /*
3571
3701
      Connect failed
3575
3705
      on protocol/connection type
3576
3706
    */
3577
3707
 
3578
 
    if ((drizzle_errno(drizzle) == CR_CONN_HOST_ERROR ||
3579
 
         drizzle_errno(drizzle) == CR_CONNECTION_ERROR) &&
 
3708
    if ((mysql_errno(mysql) == CR_CONN_HOST_ERROR ||
 
3709
         mysql_errno(mysql) == CR_CONNECTION_ERROR) &&
3580
3710
        failed_attempts < opt_max_connect_retries)
3581
3711
    {
3582
3712
      verbose_msg("Connect attempt %d/%d failed: %d: %s", failed_attempts,
3583
 
                  opt_max_connect_retries, drizzle_errno(drizzle),
3584
 
                  drizzle_error(drizzle));
 
3713
                  opt_max_connect_retries, mysql_errno(mysql),
 
3714
                  mysql_error(mysql));
3585
3715
      my_sleep(connection_retry_sleep);
3586
3716
    }
3587
3717
    else
3588
3718
    {
3589
3719
      if (failed_attempts > 0)
3590
3720
        die("Could not open connection '%s' after %d attempts: %d %s", name,
3591
 
            failed_attempts, drizzle_errno(drizzle), drizzle_error(drizzle));
 
3721
            failed_attempts, mysql_errno(mysql), mysql_error(mysql));
3592
3722
      else
3593
3723
        die("Could not open connection '%s': %d %s", name,
3594
 
            drizzle_errno(drizzle), drizzle_error(drizzle));
 
3724
            mysql_errno(mysql), mysql_error(mysql));
3595
3725
    }
3596
3726
    failed_attempts++;
3597
3727
  }
3623
3753
*/
3624
3754
 
3625
3755
static int connect_n_handle_errors(struct st_command *command,
3626
 
                                   DRIZZLE *con, const char* host,
3627
 
                                   const char* user, const char* pass,
3628
 
                                   const char* db, int port, const char* sock)
 
3756
                            MYSQL* con, const char* host,
 
3757
                            const char* user, const char* pass,
 
3758
                            const char* db, int port, const char* sock)
3629
3759
{
 
3760
  DYNAMIC_STRING *ds;
 
3761
 
 
3762
  ds= &ds_res;
3630
3763
 
3631
3764
  /* Only log if an error is expected */
3632
3765
  if (!command->abort_on_error &&
3635
3768
    /*
3636
3769
      Log the connect to result log
3637
3770
    */
3638
 
    ds_res.append("connect(");
3639
 
    replace_append(&ds_res, host);
3640
 
    ds_res.append(",");
3641
 
    replace_append(&ds_res, user);
3642
 
    ds_res.append(",");
3643
 
    replace_append(&ds_res, pass);
3644
 
    ds_res.append(",");
 
3771
    dynstr_append_mem(ds, "connect(", 8);
 
3772
    replace_dynstr_append(ds, host);
 
3773
    dynstr_append_mem(ds, ",", 1);
 
3774
    replace_dynstr_append(ds, user);
 
3775
    dynstr_append_mem(ds, ",", 1);
 
3776
    replace_dynstr_append(ds, pass);
 
3777
    dynstr_append_mem(ds, ",", 1);
3645
3778
    if (db)
3646
 
      replace_append(&ds_res, db);
3647
 
    ds_res.append(",");
3648
 
    replace_append_uint(&ds_res, port);
3649
 
    ds_res.append(",");
 
3779
      replace_dynstr_append(ds, db);
 
3780
    dynstr_append_mem(ds, ",", 1);
 
3781
    replace_dynstr_append_uint(ds, port);
 
3782
    dynstr_append_mem(ds, ",", 1);
3650
3783
    if (sock)
3651
 
      replace_append(&ds_res, sock);
3652
 
    ds_res.append(")");
3653
 
    ds_res.append(delimiter);
3654
 
    ds_res.append("\n");
 
3784
      replace_dynstr_append(ds, sock);
 
3785
    dynstr_append_mem(ds, ")", 1);
 
3786
    dynstr_append_mem(ds, delimiter, delimiter_length);
 
3787
    dynstr_append_mem(ds, "\n", 1);
3655
3788
  }
3656
 
  if (!drizzle_connect(con, host, user, pass, db, port, 0,
3657
 
                       CLIENT_MULTI_STATEMENTS))
 
3789
  if (!mysql_real_connect(con, host, user, pass, db, port, 0,
 
3790
                          CLIENT_MULTI_STATEMENTS))
3658
3791
  {
3659
 
    var_set_errno(drizzle_errno(con));
3660
 
    handle_error(command, drizzle_errno(con), drizzle_error(con),
3661
 
                 drizzle_sqlstate(con), &ds_res);
 
3792
    var_set_errno(mysql_errno(con));
 
3793
    handle_error(command, mysql_errno(con), mysql_error(con),
 
3794
                 mysql_sqlstate(con), ds);
3662
3795
    return 0; /* Not connected */
3663
3796
  }
3664
3797
 
3669
3802
 
3670
3803
 
3671
3804
/*
3672
 
  Open a new connection to DRIZZLE Server with the parameters
 
3805
  Open a new connection to MySQL Server with the parameters
3673
3806
  specified. Make the new connection the current connection.
3674
3807
 
3675
3808
  SYNOPSIS
3676
3809
  do_connect()
3677
 
  q         called command
 
3810
  q            called command
3678
3811
 
3679
3812
  DESCRIPTION
3680
3813
  connect(<name>,<host>,<user>,[<pass>,[<db>,[<port>,<sock>[<opts>]]]]);
3688
3821
  <port> - server port
3689
3822
  <sock> - server socket
3690
3823
  <opts> - options to use for the connection
3691
 
  * SSL - use SSL if available
3692
 
  * COMPRESS - use compression if available
 
3824
   * SSL - use SSL if available
 
3825
   * COMPRESS - use compression if available
3693
3826
 
3694
 
  */
 
3827
*/
3695
3828
 
3696
3829
static void do_connect(struct st_command *command)
3697
3830
{
3698
3831
  int con_port= opt_port;
3699
 
  const char *con_options;
 
3832
  char *con_options;
3700
3833
  bool con_ssl= 0, con_compress= 0;
3701
3834
  struct st_connection* con_slot;
3702
3835
 
3703
 
  string ds_connection_name;
3704
 
  string ds_host;
3705
 
  string ds_user;
3706
 
  string ds_password;
3707
 
  string ds_database;
3708
 
  string ds_port;
3709
 
  string ds_sock;
3710
 
  string ds_options;
 
3836
  static DYNAMIC_STRING ds_connection_name;
 
3837
  static DYNAMIC_STRING ds_host;
 
3838
  static DYNAMIC_STRING ds_user;
 
3839
  static DYNAMIC_STRING ds_password;
 
3840
  static DYNAMIC_STRING ds_database;
 
3841
  static DYNAMIC_STRING ds_port;
 
3842
  static DYNAMIC_STRING ds_sock;
 
3843
  static DYNAMIC_STRING ds_options;
3711
3844
  const struct command_arg connect_args[] = {
3712
3845
    { "connection name", ARG_STRING, true, &ds_connection_name, "Name of the connection" },
3713
3846
    { "host", ARG_STRING, true, &ds_host, "Host to connect to" },
3726
3859
                     ',');
3727
3860
 
3728
3861
  /* Port */
3729
 
  if (ds_port.length())
 
3862
  if (ds_port.length)
3730
3863
  {
3731
 
    con_port= atoi(ds_port.c_str());
 
3864
    con_port= atoi(ds_port.str);
3732
3865
    if (con_port == 0)
3733
 
      die("Illegal argument for port: '%s'", ds_port.c_str());
 
3866
      die("Illegal argument for port: '%s'", ds_port.str);
3734
3867
  }
3735
3868
 
3736
3869
  /* Sock */
3737
 
  if (!ds_sock.empty())
 
3870
  if (ds_sock.length)
3738
3871
  {
3739
3872
    /*
3740
3873
      If the socket is specified just as a name without path
3741
3874
      append tmpdir in front
3742
3875
    */
3743
 
    if (*ds_sock.c_str() != FN_LIBCHAR)
 
3876
    if (*ds_sock.str != FN_LIBCHAR)
3744
3877
    {
3745
3878
      char buff[FN_REFLEN];
3746
 
      fn_format(buff, ds_sock.c_str(), TMPDIR, "", 0);
3747
 
      ds_sock= buff;
 
3879
      fn_format(buff, ds_sock.str, TMPDIR, "", 0);
 
3880
      dynstr_set(&ds_sock, buff);
3748
3881
    }
3749
3882
  }
 
3883
  else
 
3884
  {
 
3885
    /* No socket specified, use default */
 
3886
    dynstr_set(&ds_sock, unix_sock);
 
3887
  }
3750
3888
 
3751
3889
  /* Options */
3752
 
  con_options= ds_options.c_str();
 
3890
  con_options= ds_options.str;
3753
3891
  while (*con_options)
3754
3892
  {
3755
 
    const char* end;
 
3893
    char* end;
3756
3894
    /* Step past any spaces in beginning of option*/
3757
3895
    while (*con_options && my_isspace(charset_info, *con_options))
3758
 
      con_options++;
 
3896
     con_options++;
3759
3897
    /* Find end of this option */
3760
3898
    end= con_options;
3761
3899
    while (*end && !my_isspace(charset_info, *end))
3765
3903
    else if (!strncmp(con_options, "COMPRESS", 8))
3766
3904
      con_compress= 1;
3767
3905
    else
3768
 
      die("Illegal option to connect: %.*s",
 
3906
      die("Illegal option to connect: %.*s", 
3769
3907
          (int) (end - con_options), con_options);
3770
3908
    /* Process next option */
3771
3909
    con_options= end;
3772
3910
  }
3773
3911
 
3774
 
  if (find_connection_by_name(ds_connection_name.c_str()))
3775
 
    die("Connection %s already exists", ds_connection_name.c_str());
3776
 
 
 
3912
  if (find_connection_by_name(ds_connection_name.str))
 
3913
    die("Connection %s already exists", ds_connection_name.str);
 
3914
    
3777
3915
  if (next_con != connections_end)
3778
 
  {
3779
3916
    con_slot= next_con;
3780
 
  }
3781
3917
  else
3782
3918
  {
3783
3919
    if (!(con_slot= find_connection_by_name("-closed_connection-")))
3785
3921
          (int) (sizeof(connections)/sizeof(struct st_connection)));
3786
3922
  }
3787
3923
 
3788
 
  if (!drizzle_create(&con_slot->drizzle))
3789
 
    die("Failed on drizzle_create()");
 
3924
#ifdef EMBEDDED_LIBRARY
 
3925
  con_slot->query_done= 1;
 
3926
#endif
 
3927
  if (!mysql_init(&con_slot->mysql))
 
3928
    die("Failed on mysql_init()");
3790
3929
  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);
 
3930
    mysql_options(&con_slot->mysql, MYSQL_OPT_COMPRESS, NullS);
 
3931
  mysql_options(&con_slot->mysql, MYSQL_OPT_LOCAL_INFILE, 0);
 
3932
  mysql_options(&con_slot->mysql, MYSQL_SET_CHARSET_NAME,
 
3933
                charset_info->csname);
 
3934
  int opt_protocol= MYSQL_PROTOCOL_TCP;
 
3935
  mysql_options(&con_slot->mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
 
3936
  if (opt_charsets_dir)
 
3937
    mysql_options(&con_slot->mysql, MYSQL_SET_CHARSET_DIR,
 
3938
                  opt_charsets_dir);
3793
3939
 
3794
3940
  /* Use default db name */
3795
 
  if (ds_database.length() == 0)
3796
 
    ds_database= opt_db;
 
3941
  if (ds_database.length == 0)
 
3942
    dynstr_set(&ds_database, opt_db);
3797
3943
 
3798
3944
  /* Special database to allow one to connect without a database name */
3799
 
  if (ds_database.length() && !strcmp(ds_database.c_str(),"*NO-ONE*"))
3800
 
    ds_database= "";
 
3945
  if (ds_database.length && !strcmp(ds_database.str,"*NO-ONE*"))
 
3946
    dynstr_set(&ds_database, "");
3801
3947
 
3802
 
  if (connect_n_handle_errors(command, &con_slot->drizzle,
3803
 
                              ds_host.c_str(),ds_user.c_str(),
3804
 
                              ds_password.c_str(), ds_database.c_str(),
3805
 
                              con_port, ds_sock.c_str()))
 
3948
  if (connect_n_handle_errors(command, &con_slot->mysql,
 
3949
                              ds_host.str,ds_user.str,
 
3950
                              ds_password.str, ds_database.str,
 
3951
                              con_port, ds_sock.str))
3806
3952
  {
3807
 
    if (!(con_slot->name= strdup(ds_connection_name.c_str())))
 
3953
    if (!(con_slot->name= my_strdup(ds_connection_name.str, MYF(MY_WME))))
3808
3954
      die("Out of memory");
3809
3955
    cur_con= con_slot;
3810
 
 
 
3956
    
3811
3957
    if (con_slot == next_con)
3812
3958
      next_con++; /* if we used the next_con slot, advance the pointer */
3813
3959
  }
3814
3960
 
3815
 
  /* Update $drizzle_get_server_version to that of current connection */
3816
 
  var_set_drizzle_get_server_version(&cur_con->drizzle);
 
3961
  /* Update $mysql_get_server_version to that of current connection */
 
3962
  var_set_mysql_get_server_version(&cur_con->mysql);
3817
3963
 
 
3964
  dynstr_free(&ds_connection_name);
 
3965
  dynstr_free(&ds_host);
 
3966
  dynstr_free(&ds_user);
 
3967
  dynstr_free(&ds_password);
 
3968
  dynstr_free(&ds_database);
 
3969
  dynstr_free(&ds_port);
 
3970
  dynstr_free(&ds_sock);
 
3971
  dynstr_free(&ds_options);
3818
3972
  return;
3819
3973
}
3820
3974
 
3852
4006
  SYNOPSIS
3853
4007
  do_block()
3854
4008
  cmd        Type of block
3855
 
  q         called command
 
4009
  q            called command
3856
4010
 
3857
4011
  DESCRIPTION
3858
4012
  if ([!]<expr>)
3962
4116
    return 0;
3963
4117
 
3964
4118
  for (i= 1; i < length &&
3965
 
         (c= my_getc(cur_file->file)) == *(delim + i);
 
4119
         (c= my_getc(cur_file->file)) == *(delim + i);
3966
4120
       i++)
3967
4121
    tmp[i]= c;
3968
4122
 
3969
4123
  if (i == length)
3970
 
    return 1;          /* Found delimiter */
 
4124
    return 1;                                   /* Found delimiter */
3971
4125
 
3972
4126
  /* didn't find delimiter, push back things that we read */
3973
4127
  my_ungetc(c);
4026
4180
  found_eof:
4027
4181
      if (cur_file->file != stdin)
4028
4182
      {
4029
 
        my_fclose(cur_file->file, MYF(0));
 
4183
        my_fclose(cur_file->file, MYF(0));
4030
4184
        cur_file->file= 0;
4031
4185
      }
4032
 
      free((unsigned char*) cur_file->file_name);
 
4186
      my_free((uchar*) cur_file->file_name, MYF(MY_ALLOW_ZERO_PTR));
4033
4187
      cur_file->file_name= 0;
4034
4188
      if (cur_file == file_stack)
4035
4189
      {
4061
4215
    case R_NORMAL:
4062
4216
      if (end_of_query(c))
4063
4217
      {
4064
 
        *p= 0;
4065
 
        return(0);
 
4218
        *p= 0;
 
4219
        return(0);
4066
4220
      }
4067
4221
      else if ((c == '{' &&
4068
 
                (!my_strnncoll_simple(charset_info, (const unsigned char*) "while", 5,
4069
 
                                      (unsigned char*) buf, cmin((long)5, p - buf), 0) ||
4070
 
                 !my_strnncoll_simple(charset_info, (const unsigned char*) "if", 2,
4071
 
                                      (unsigned char*) buf, cmin((long)2, p - buf), 0))))
 
4222
                (!my_strnncoll_simple(charset_info, (const uchar*) "while", 5,
 
4223
                                      (uchar*) buf, min(5, p - buf), 0) ||
 
4224
                 !my_strnncoll_simple(charset_info, (const uchar*) "if", 2,
 
4225
                                      (uchar*) buf, min(2, p - buf), 0))))
4072
4226
      {
4073
4227
        /* Only if and while commands can be terminated by { */
4074
4228
        *p++= c;
4075
 
        *p= 0;
4076
 
        return(0);
 
4229
        *p= 0;
 
4230
        return(0);
4077
4231
      }
4078
4232
      else if (c == '\'' || c == '"' || c == '`')
4079
4233
      {
4080
4234
        last_quote= c;
4081
 
        state= R_Q;
 
4235
        state= R_Q;
4082
4236
      }
4083
4237
      break;
4084
4238
 
4086
4240
      if (c == '\n')
4087
4241
      {
4088
4242
        /* Comments are terminated by newline */
4089
 
        *p= 0;
4090
 
        return(0);
 
4243
        *p= 0;
 
4244
        return(0);
4091
4245
      }
4092
4246
      break;
4093
4247
 
4095
4249
      if (c == '#' || c == '-')
4096
4250
      {
4097
4251
        /* A # or - in the first position of the line - this is a comment */
4098
 
        state = R_COMMENT;
 
4252
        state = R_COMMENT;
4099
4253
      }
4100
4254
      else if (my_isspace(charset_info, c))
4101
4255
      {
4102
4256
        /* Skip all space at begining of line */
4103
 
        if (c == '\n')
 
4257
        if (c == '\n')
4104
4258
        {
4105
4259
          /* Query hasn't started yet */
4106
 
          start_lineno= cur_file->lineno;
 
4260
          start_lineno= cur_file->lineno;
4107
4261
        }
4108
 
        skip_char= 1;
 
4262
        skip_char= 1;
4109
4263
      }
4110
4264
      else if (end_of_query(c))
4111
4265
      {
4112
 
        *p= 0;
4113
 
        return(0);
 
4266
        *p= 0;
 
4267
        return(0);
4114
4268
      }
4115
4269
      else if (c == '}')
4116
4270
      {
4117
4271
        /* A "}" need to be by itself in the begining of a line to terminate */
4118
4272
        *p++= c;
4119
 
        *p= 0;
4120
 
        return(0);
 
4273
        *p= 0;
 
4274
        return(0);
4121
4275
      }
4122
4276
      else if (c == '\'' || c == '"' || c == '`')
4123
4277
      {
4124
4278
        last_quote= c;
4125
 
        state= R_Q;
 
4279
        state= R_Q;
4126
4280
      }
4127
4281
      else
4128
 
        state= R_NORMAL;
 
4282
        state= R_NORMAL;
4129
4283
      break;
4130
4284
 
4131
4285
    case R_Q:
4132
4286
      if (c == last_quote)
4133
 
        state= R_NORMAL;
 
4287
        state= R_NORMAL;
4134
4288
      else if (c == '\\')
4135
 
        state= R_SLASH_IN_Q;
 
4289
        state= R_SLASH_IN_Q;
4136
4290
      break;
4137
4291
 
4138
4292
    case R_SLASH_IN_Q:
4151
4305
      /* completed before we pass buf_end */
4152
4306
      if ((charlen > 1) && (p + charlen) <= buf_end)
4153
4307
      {
4154
 
        int i;
4155
 
        char* mb_start = p;
4156
 
 
4157
 
        *p++ = c;
4158
 
 
4159
 
        for (i= 1; i < charlen; i++)
4160
 
        {
4161
 
          if (feof(cur_file->file))
4162
 
            goto found_eof;
4163
 
          c= my_getc(cur_file->file);
4164
 
          *p++ = c;
4165
 
        }
4166
 
        if (! my_ismbchar(charset_info, mb_start, p))
4167
 
        {
4168
 
          /* It was not a multiline char, push back the characters */
4169
 
          /* We leave first 'c', i.e. pretend it was a normal char */
4170
 
          while (p > mb_start)
4171
 
            my_ungetc(*--p);
4172
 
        }
 
4308
        int i;
 
4309
        char* mb_start = p;
 
4310
 
 
4311
        *p++ = c;
 
4312
 
 
4313
        for (i= 1; i < charlen; i++)
 
4314
        {
 
4315
          if (feof(cur_file->file))
 
4316
            goto found_eof;
 
4317
          c= my_getc(cur_file->file);
 
4318
          *p++ = c;
 
4319
        }
 
4320
        if (! my_ismbchar(charset_info, mb_start, p))
 
4321
        {
 
4322
          /* It was not a multiline char, push back the characters */
 
4323
          /* We leave first 'c', i.e. pretend it was a normal char */
 
4324
          while (p > mb_start)
 
4325
            my_ungetc(*--p);
 
4326
        }
4173
4327
      }
4174
4328
      else
4175
4329
#endif
4176
 
        *p++= c;
 
4330
        *p++= c;
4177
4331
    }
4178
4332
  }
4179
 
  die("The input buffer is too small for this query.x\n"        \
 
4333
  die("The input buffer is too small for this query.x\n" \
4180
4334
      "check your query or increase MAX_QUERY and recompile");
4181
4335
  return(0);
4182
4336
}
4197
4351
{
4198
4352
  int last_c_was_quote= 0;
4199
4353
  char *p= query, *to= query;
4200
 
  char *end= strchr(query, '\0');
 
4354
  char *end= strend(query);
4201
4355
  char last_c;
4202
4356
 
4203
4357
  while (p <= end)
4236
4390
 
4237
4391
/*
4238
4392
  Check a command that is about to be sent (or should have been
4239
 
  sent if parsing was enabled) to DRIZZLE server for
 
4393
  sent if parsing was enabled) to mysql server for
4240
4394
  suspicious things and generate warnings.
4241
4395
*/
4242
4396
 
4248
4402
  {
4249
4403
    /*
4250
4404
      Look for query's that lines that start with a -- comment
4251
 
      and has a drizzletest command
 
4405
      and has a mysqltest command
4252
4406
    */
4253
4407
    if (ptr[0] == '\n' &&
4254
4408
        ptr[1] && ptr[1] == '-' &&
4269
4423
      *end= 0;
4270
4424
      type= find_type(start, &command_typelib, 1+2);
4271
4425
      if (type)
4272
 
        warning_msg("Embedded drizzletest command '--%s' detected in "
 
4426
        warning_msg("Embedded mysqltest command '--%s' detected in "
4273
4427
                    "query '%s' was this intentional? ",
4274
4428
                    start, command->query);
4275
4429
      *end= save;
4338
4492
  Create a command from a set of lines
4339
4493
 
4340
4494
  SYNOPSIS
4341
 
  read_command()
4342
 
  command_ptr pointer where to return the new query
 
4495
    read_command()
 
4496
    command_ptr pointer where to return the new query
4343
4497
 
4344
4498
  DESCRIPTION
4345
 
  Converts lines returned by read_line into a command, this involves
4346
 
  parsing the first word in the read line to find the command type.
 
4499
    Converts lines returned by read_line into a command, this involves
 
4500
    parsing the first word in the read line to find the command type.
4347
4501
 
4348
4502
  A -- comment may contain a valid query as the first word after the
4349
4503
  comment start. Thus it's always checked to see if that is the case.
4362
4516
 
4363
4517
  if (parser.current_line < parser.read_lines)
4364
4518
  {
4365
 
    *command_ptr= q_lines[parser.current_line];
 
4519
    get_dynamic(&q_lines, (uchar*) command_ptr, parser.current_line) ;
4366
4520
    return(0);
4367
4521
  }
4368
4522
  if (!(*command_ptr= command=
4369
4523
        (struct st_command*) my_malloc(sizeof(*command),
4370
 
                                       MYF(MY_WME|MY_ZEROFILL))))
4371
 
    die(NULL);
4372
 
  q_lines.push_back(command);
 
4524
                                       MYF(MY_WME|MY_ZEROFILL))) ||
 
4525
      insert_dynamic(&q_lines, (uchar*) &command))
 
4526
    die(NullS);
4373
4527
  command->type= Q_UNKNOWN;
4374
4528
 
4375
4529
  read_command_buf[0]= 0;
4409
4563
    p++;
4410
4564
  command->first_argument= p;
4411
4565
 
4412
 
  command->end= strchr(command->query, '\0');
 
4566
  command->end= strend(command->query);
4413
4567
  command->query_len= (command->end - command->query);
4414
4568
  parser.read_lines++;
4415
4569
  return(0);
4453
4607
  {"password", 'p', "Password to use when connecting to server.",
4454
4608
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
4455
4609
  {"port", 'P', "Port number to use for connection or 0 for default to, in "
4456
 
   "order of preference, my.cnf, $DRIZZLE_TCP_PORT, "
4457
 
   "built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
 
4610
   "order of preference, my.cnf, $MYSQL_TCP_PORT, "
 
4611
#if MYSQL_PORT_DEFAULT == 0
 
4612
   "/etc/services, "
 
4613
#endif
 
4614
   "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
4458
4615
   (char**) &opt_port,
4459
4616
   (char**) &opt_port, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4460
4617
  {"quiet", 's', "Suppress all normal output.", (char**) &silent,
4493
4650
};
4494
4651
 
4495
4652
 
 
4653
#include <help_start.h>
 
4654
 
4496
4655
static void print_version(void)
4497
4656
{
4498
4657
  printf("%s  Ver %s Distrib %s, for %s (%s)\n",my_progname,MTEST_VERSION,
4499
 
         drizzle_get_client_info(),SYSTEM_TYPE,MACHINE_TYPE);
 
4658
         MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
4500
4659
}
4501
4660
 
4502
4661
static void usage(void)
4504
4663
  print_version();
4505
4664
  printf("MySQL AB, by Sasha, Matt, Monty & Jani\n");
4506
4665
  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");
 
4666
  printf("Runs a test against the mysql server and compares output with a results file.\n\n");
4508
4667
  printf("Usage: %s [OPTIONS] [database] < test_file\n", my_progname);
4509
4668
  my_print_help(my_long_options);
4510
4669
  printf("  --no-defaults       Don't read default options from any options file.\n");
4511
4670
  my_print_variables(my_long_options);
4512
4671
}
4513
4672
 
 
4673
#include <help_end.h>
 
4674
 
 
4675
 
4514
4676
/*
4515
4677
  Read arguments for embedded server and put them into
4516
4678
  embedded_server_args[]
4523
4685
 
4524
4686
  if (!test_if_hard_path(name))
4525
4687
  {
4526
 
    strxmov(buff, opt_basedir, name, NULL);
 
4688
    strxmov(buff, opt_basedir, name, NullS);
4527
4689
    name=buff;
4528
4690
  }
4529
4691
  fn_format(buff, name, "", "", MY_UNPACK_FILENAME);
4531
4693
  if (!embedded_server_arg_count)
4532
4694
  {
4533
4695
    embedded_server_arg_count=1;
4534
 
    embedded_server_args[0]= (char*) "";    /* Progname */
 
4696
    embedded_server_args[0]= (char*) "";                /* Progname */
4535
4697
  }
4536
4698
  if (!(file=my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(MY_WME))))
4537
4699
    die("Failed to open file '%s'", buff);
4538
4700
 
4539
4701
  while (embedded_server_arg_count < MAX_EMBEDDED_SERVER_ARGS &&
4540
 
         (str=fgets(argument,sizeof(argument), file)))
 
4702
         (str=fgets(argument,sizeof(argument), file)))
4541
4703
  {
4542
 
    *(strchr(str, '\0')-1)=0;        /* Remove end newline */
 
4704
    *(strend(str)-1)=0;                         /* Remove end newline */
4543
4705
    if (!(embedded_server_args[embedded_server_arg_count]=
4544
 
          (char*) my_strdup(str,MYF(MY_WME))))
 
4706
          (char*) my_strdup(str,MYF(MY_WME))))
4545
4707
    {
4546
4708
      my_fclose(file,MYF(0));
4547
4709
      die("Out of memory");
4559
4721
 
4560
4722
static bool
4561
4723
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
4562
 
               char *argument)
 
4724
               char *argument)
4563
4725
{
4564
4726
  switch(optid) {
4565
4727
  case 'r':
4570
4732
    char buff[FN_REFLEN];
4571
4733
    if (!test_if_hard_path(argument))
4572
4734
    {
4573
 
      strxmov(buff, opt_basedir, argument, NULL);
 
4735
      strxmov(buff, opt_basedir, argument, NullS);
4574
4736
      argument= buff;
4575
4737
    }
4576
4738
    fn_format(buff, argument, "", "", MY_UNPACK_FILENAME);
4587
4749
    static char buff[FN_REFLEN];
4588
4750
    if (!test_if_hard_path(argument))
4589
4751
    {
4590
 
      strxmov(buff, opt_basedir, argument, NULL);
 
4752
      strxmov(buff, opt_basedir, argument, NullS);
4591
4753
      argument= buff;
4592
4754
    }
4593
4755
    fn_format(buff, argument, "", "", MY_UNPACK_FILENAME);
4594
4756
    timer_file= buff;
4595
 
    unlink(timer_file);       /* Ignore error, may not exist */
 
4757
    unlink(timer_file);      /* Ignore error, may not exist */
4596
4758
    break;
4597
4759
  }
4598
4760
  case 'p':
4599
4761
    if (argument)
4600
4762
    {
4601
 
      free(opt_pass);
 
4763
      my_free(opt_pass, MYF(MY_ALLOW_ZERO_PTR));
4602
4764
      opt_pass= my_strdup(argument, MYF(MY_FAE));
4603
 
      while (*argument) *argument++= 'x';    /* Destroy argument */
 
4765
      while (*argument) *argument++= 'x';               /* Destroy argument */
4604
4766
      tty_password= 0;
4605
4767
    }
4606
4768
    else
4607
4769
      tty_password= 1;
4608
4770
    break;
4609
4771
  case 't':
4610
 
    my_stpncpy(TMPDIR, argument, sizeof(TMPDIR));
 
4772
    strnmov(TMPDIR, argument, sizeof(TMPDIR));
4611
4773
    break;
4612
4774
  case 'A':
4613
4775
    if (!embedded_server_arg_count)
4652
4814
  if (argc == 1)
4653
4815
    opt_db= *argv;
4654
4816
  if (tty_password)
4655
 
    opt_pass= get_tty_password(NULL);          /* purify tested */
 
4817
    opt_pass= get_tty_password(NullS);          /* purify tested */
4656
4818
  if (debug_info_flag)
4657
4819
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
4658
4820
  if (debug_check_flag)
4672
4834
  append - append to file instead of overwriting old file
4673
4835
*/
4674
4836
 
4675
 
void str_to_file2(const char *fname, const char *str, int size, bool append)
 
4837
void str_to_file2(const char *fname, char *str, int size, bool append)
4676
4838
{
4677
4839
  int fd;
4678
4840
  char buff[FN_REFLEN];
4679
4841
  int flags= O_WRONLY | O_CREAT;
4680
4842
  if (!test_if_hard_path(fname))
4681
4843
  {
4682
 
    strxmov(buff, opt_basedir, fname, NULL);
 
4844
    strxmov(buff, opt_basedir, fname, NullS);
4683
4845
    fname= buff;
4684
4846
  }
4685
4847
  fn_format(buff, fname, "", "", MY_UNPACK_FILENAME);
4691
4853
    die("Could not open '%s' for writing: errno = %d", buff, errno);
4692
4854
  if (append && my_seek(fd, 0, SEEK_END, MYF(0)) == MY_FILEPOS_ERROR)
4693
4855
    die("Could not find end of file '%s': errno = %d", buff, errno);
4694
 
  if (my_write(fd, (unsigned char*)str, size, MYF(MY_WME|MY_FNABP)))
 
4856
  if (my_write(fd, (uchar*)str, size, MYF(MY_WME|MY_FNABP)))
4695
4857
    die("write failed");
4696
4858
  my_close(fd, MYF(0));
4697
4859
}
4706
4868
  size - size of content witten to file
4707
4869
*/
4708
4870
 
4709
 
void str_to_file(const char *fname, const char *str, int size)
 
4871
void str_to_file(const char *fname, char *str, int size)
4710
4872
{
4711
4873
  str_to_file2(fname, str, size, false);
4712
4874
}
4713
4875
 
4714
4876
 
4715
 
void dump_result_to_log_file(const char *buf, int size)
 
4877
void dump_result_to_log_file(char *buf, int size)
4716
4878
{
4717
4879
  char log_file[FN_REFLEN];
4718
4880
  str_to_file(fn_format(log_file, result_file_name, opt_logdir, ".log",
4730
4892
                        opt_logdir, ".progress",
4731
4893
                        *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
4732
4894
                        MY_REPLACE_EXT),
4733
 
              ds_progress.c_str(), ds_progress.length());
 
4895
              ds_progress.str, ds_progress.length);
4734
4896
}
4735
4897
 
4736
4898
void dump_warning_messages(void)
4740
4902
  str_to_file(fn_format(warn_file, result_file_name, opt_logdir, ".warnings",
4741
4903
                        *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
4742
4904
                        MY_REPLACE_EXT),
4743
 
              ds_warning_messages.c_str(), ds_warning_messages.length());
 
4905
              ds_warning_messages.str, ds_warning_messages.length);
4744
4906
}
4745
4907
 
4746
4908
 
4748
4910
  Append the result for one field to the dynamic string ds
4749
4911
*/
4750
4912
 
4751
 
static void append_field(string *ds, uint col_idx, const DRIZZLE_FIELD* field,
 
4913
static void append_field(DYNAMIC_STRING *ds, uint col_idx, MYSQL_FIELD* field,
4752
4914
                         const char* val, uint64_t len, bool is_null)
4753
4915
{
4754
4916
  if (col_idx < max_replace_column && replace_column[col_idx])
4765
4927
  if (!display_result_vertically)
4766
4928
  {
4767
4929
    if (col_idx)
4768
 
      ds->append("\t");
4769
 
    replace_append_mem(ds, val, (int)len);
 
4930
      dynstr_append_mem(ds, "\t", 1);
 
4931
    replace_dynstr_append_mem(ds, val, (int)len);
4770
4932
  }
4771
4933
  else
4772
4934
  {
4773
 
    ds->append(field->name);
4774
 
    ds->append("\t");
4775
 
    replace_append_mem(ds, val, (int)len);
4776
 
    ds->append("\n");
 
4935
    dynstr_append(ds, field->name);
 
4936
    dynstr_append_mem(ds, "\t", 1);
 
4937
    replace_dynstr_append_mem(ds, val, (int)len);
 
4938
    dynstr_append_mem(ds, "\n", 1);
4777
4939
  }
4778
4940
}
4779
4941
 
4783
4945
  Values may be converted with 'replace_column'
4784
4946
*/
4785
4947
 
4786
 
static void append_result(string *ds, DRIZZLE_RES *res)
 
4948
static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res)
4787
4949
{
4788
 
  DRIZZLE_ROW row;
4789
 
  uint32_t num_fields= drizzle_num_fields(res);
4790
 
  const DRIZZLE_FIELD *fields= drizzle_fetch_fields(res);
 
4950
  MYSQL_ROW row;
 
4951
  uint32_t num_fields= mysql_num_fields(res);
 
4952
  MYSQL_FIELD *fields= mysql_fetch_fields(res);
4791
4953
  uint32_t *lengths;
4792
4954
 
4793
 
  while ((row = drizzle_fetch_row(res)))
 
4955
  while ((row = mysql_fetch_row(res)))
4794
4956
  {
4795
4957
    uint32_t i;
4796
 
    lengths = drizzle_fetch_lengths(res);
 
4958
    lengths = mysql_fetch_lengths(res);
4797
4959
    for (i = 0; i < num_fields; i++)
4798
4960
      append_field(ds, i, &fields[i],
4799
4961
                   (const char*)row[i], lengths[i], !row[i]);
4800
4962
    if (!display_result_vertically)
4801
 
      ds->append("\n");
4802
 
 
 
4963
      dynstr_append_mem(ds, "\n", 1);
4803
4964
  }
4804
4965
}
4805
4966
 
4808
4969
  Append metadata for fields to output
4809
4970
*/
4810
4971
 
4811
 
static void append_metadata(string *ds,
4812
 
                            const DRIZZLE_FIELD *field,
 
4972
static void append_metadata(DYNAMIC_STRING *ds,
 
4973
                            MYSQL_FIELD *field,
4813
4974
                            uint num_fields)
4814
4975
{
4815
 
  const DRIZZLE_FIELD *field_end;
4816
 
  ds->append("Catalog\tDatabase\tTable\tTable_alias\tColumn\t"
4817
 
             "Column_alias\tType\tLength\tMax length\tIs_null\t"
4818
 
             "Flags\tDecimals\tCharsetnr\n");
 
4976
  MYSQL_FIELD *field_end;
 
4977
  dynstr_append(ds,"Catalog\tDatabase\tTable\tTable_alias\tColumn\t"
 
4978
                "Column_alias\tType\tLength\tMax length\tIs_null\t"
 
4979
                "Flags\tDecimals\tCharsetnr\n");
4819
4980
 
4820
4981
  for (field_end= field+num_fields ;
4821
4982
       field < field_end ;
4822
4983
       field++)
4823
4984
  {
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);
4854
 
    ds->append("\n", 1);
 
4985
    dynstr_append_mem(ds, field->catalog,
 
4986
                      field->catalog_length);
 
4987
    dynstr_append_mem(ds, "\t", 1);
 
4988
    dynstr_append_mem(ds, field->db, field->db_length);
 
4989
    dynstr_append_mem(ds, "\t", 1);
 
4990
    dynstr_append_mem(ds, field->org_table,
 
4991
                      field->org_table_length);
 
4992
    dynstr_append_mem(ds, "\t", 1);
 
4993
    dynstr_append_mem(ds, field->table,
 
4994
                      field->table_length);
 
4995
    dynstr_append_mem(ds, "\t", 1);
 
4996
    dynstr_append_mem(ds, field->org_name,
 
4997
                      field->org_name_length);
 
4998
    dynstr_append_mem(ds, "\t", 1);
 
4999
    dynstr_append_mem(ds, field->name, field->name_length);
 
5000
    dynstr_append_mem(ds, "\t", 1);
 
5001
    replace_dynstr_append_uint(ds, field->type);
 
5002
    dynstr_append_mem(ds, "\t", 1);
 
5003
    replace_dynstr_append_uint(ds, field->length);
 
5004
    dynstr_append_mem(ds, "\t", 1);
 
5005
    replace_dynstr_append_uint(ds, field->max_length);
 
5006
    dynstr_append_mem(ds, "\t", 1);
 
5007
    dynstr_append_mem(ds, (char*) (IS_NOT_NULL(field->flags) ?
 
5008
                                   "N" : "Y"), 1);
 
5009
    dynstr_append_mem(ds, "\t", 1);
 
5010
    replace_dynstr_append_uint(ds, field->flags);
 
5011
    dynstr_append_mem(ds, "\t", 1);
 
5012
    replace_dynstr_append_uint(ds, field->decimals);
 
5013
    dynstr_append_mem(ds, "\t", 1);
 
5014
    replace_dynstr_append_uint(ds, field->charsetnr);
 
5015
    dynstr_append_mem(ds, "\n", 1);
4855
5016
  }
4856
5017
}
4857
5018
 
4860
5021
  Append affected row count and other info to output
4861
5022
*/
4862
5023
 
4863
 
static void append_info(string *ds, uint64_t affected_rows,
 
5024
static void append_info(DYNAMIC_STRING *ds, uint64_t affected_rows,
4864
5025
                        const char *info)
4865
5026
{
4866
5027
  char buf[40], buff2[21];
4867
5028
  sprintf(buf,"affected rows: %s\n", llstr(affected_rows, buff2));
4868
 
  ds->append(buf);
 
5029
  dynstr_append(ds, buf);
4869
5030
  if (info)
4870
5031
  {
4871
 
    ds->append("info: ");
4872
 
    ds->append(info);
4873
 
    ds->append("\n", 1);
 
5032
    dynstr_append(ds, "info: ");
 
5033
    dynstr_append(ds, info);
 
5034
    dynstr_append_mem(ds, "\n", 1);
4874
5035
  }
4875
5036
}
4876
5037
 
4879
5040
  Display the table headings with the names tab separated
4880
5041
*/
4881
5042
 
4882
 
static void append_table_headings(string *ds,
4883
 
                                  const DRIZZLE_FIELD *field,
 
5043
static void append_table_headings(DYNAMIC_STRING *ds,
 
5044
                                  MYSQL_FIELD *field,
4884
5045
                                  uint num_fields)
4885
5046
{
4886
5047
  uint col_idx;
4887
5048
  for (col_idx= 0; col_idx < num_fields; col_idx++)
4888
5049
  {
4889
5050
    if (col_idx)
4890
 
      ds->append("\t", 1);
4891
 
    replace_append(ds, field[col_idx].name);
 
5051
      dynstr_append_mem(ds, "\t", 1);
 
5052
    replace_dynstr_append(ds, field[col_idx].name);
4892
5053
  }
4893
 
  ds->append("\n", 1);
 
5054
  dynstr_append_mem(ds, "\n", 1);
4894
5055
}
4895
5056
 
4896
5057
/*
4900
5061
  Number of warnings appended to ds
4901
5062
*/
4902
5063
 
4903
 
static int append_warnings(string *ds, DRIZZLE *drizzle)
 
5064
static int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql)
4904
5065
{
4905
5066
  uint count;
4906
 
  DRIZZLE_RES *warn_res;
4907
 
 
4908
 
 
4909
 
  if (!(count= drizzle_warning_count(drizzle)))
 
5067
  MYSQL_RES *warn_res;
 
5068
 
 
5069
 
 
5070
  if (!(count= mysql_warning_count(mysql)))
4910
5071
    return(0);
4911
5072
 
4912
5073
  /*
4914
5075
    through PS API we should not issue SHOW WARNINGS until
4915
5076
    we have not read all results...
4916
5077
  */
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)))
 
5078
  assert(!mysql_more_results(mysql));
 
5079
 
 
5080
  if (mysql_real_query(mysql, "SHOW WARNINGS", 13))
 
5081
    die("Error running query \"SHOW WARNINGS\": %s", mysql_error(mysql));
 
5082
 
 
5083
  if (!(warn_res= mysql_store_result(mysql)))
4923
5084
    die("Warning count is %u but didn't get any warnings",
4924
 
        count);
 
5085
        count);
4925
5086
 
4926
5087
  append_result(ds, warn_res);
 
5088
  mysql_free_result(warn_res);
4927
5089
 
4928
5090
  return(count);
4929
5091
}
4930
5092
 
4931
5093
 
4932
5094
/*
4933
 
  Run query using DRIZZLE C API
 
5095
  Run query using MySQL C API
4934
5096
 
4935
5097
  SYNOPSIS
4936
 
  run_query_normal()
4937
 
  drizzle  DRIZZLE handle
4938
 
  command  current command pointer
4939
 
  flags  flags indicating if we should SEND and/or REAP
4940
 
  query  query string to execute
4941
 
  query_len  length query string to execute
4942
 
  ds    output buffer where to store result form query
 
5098
    run_query_normal()
 
5099
    mysql       mysql handle
 
5100
    command     current command pointer
 
5101
    flags       flags indicating if we should SEND and/or REAP
 
5102
    query       query string to execute
 
5103
    query_len   length query string to execute
 
5104
    ds          output buffer where to store result form query
4943
5105
*/
4944
5106
 
4945
5107
static void run_query_normal(struct st_connection *cn,
4946
5108
                             struct st_command *command,
4947
5109
                             int flags, char *query, int query_len,
4948
 
                             string *ds, string *ds_warnings)
 
5110
                             DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings)
4949
5111
{
4950
 
  DRIZZLE_RES *res= 0;
4951
 
  DRIZZLE *drizzle= &cn->drizzle;
 
5112
  MYSQL_RES *res= 0;
 
5113
  MYSQL *mysql= &cn->mysql;
4952
5114
  int err= 0, counter= 0;
4953
5115
 
4954
5116
  if (flags & QUERY_SEND_FLAG)
4955
5117
  {
4956
5118
    /*
4957
 
     * Send the query
4958
 
     */
 
5119
      Send the query
 
5120
    */
4959
5121
    if (do_send_query(cn, query, query_len, flags))
4960
5122
    {
4961
 
      handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
4962
 
                   drizzle_sqlstate(drizzle), ds);
 
5123
      handle_error(command, mysql_errno(mysql), mysql_error(mysql),
 
5124
                   mysql_sqlstate(mysql), ds);
4963
5125
      goto end;
4964
5126
    }
4965
5127
  }
 
5128
#ifdef EMBEDDED_LIBRARY
 
5129
  /*
 
5130
    Here we handle 'reap' command, so we need to check if the
 
5131
    query's thread was finished and probably wait
 
5132
  */
 
5133
  else if (flags & QUERY_REAP_FLAG)
 
5134
    wait_query_thread_end(cn);
 
5135
#endif /*EMBEDDED_LIBRARY*/
4966
5136
  if (!(flags & QUERY_REAP_FLAG))
4967
5137
    return;
4968
5138
 
4969
5139
  do
4970
5140
  {
4971
5141
    /*
4972
 
      When  on first result set, call drizzle_read_query_result to retrieve
 
5142
      When  on first result set, call mysql_read_query_result to retrieve
4973
5143
      answer to the query sent earlier
4974
5144
    */
4975
 
    if ((counter==0) && drizzle_read_query_result(drizzle))
 
5145
    if ((counter==0) && mysql_read_query_result(mysql))
4976
5146
    {
4977
 
      handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
4978
 
                   drizzle_sqlstate(drizzle), ds);
 
5147
      handle_error(command, mysql_errno(mysql), mysql_error(mysql),
 
5148
                   mysql_sqlstate(mysql), ds);
4979
5149
      goto end;
4980
5150
 
4981
5151
    }
4983
5153
    /*
4984
5154
      Store the result of the query if it will return any fields
4985
5155
    */
4986
 
    if (drizzle_field_count(drizzle) && ((res= drizzle_store_result(drizzle)) == 0))
 
5156
    if (mysql_field_count(mysql) && ((res= mysql_store_result(mysql)) == 0))
4987
5157
    {
4988
 
      handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
4989
 
                   drizzle_sqlstate(drizzle), ds);
 
5158
      handle_error(command, mysql_errno(mysql), mysql_error(mysql),
 
5159
                   mysql_sqlstate(mysql), ds);
4990
5160
      goto end;
4991
5161
    }
4992
5162
 
4996
5166
 
4997
5167
      if (res)
4998
5168
      {
4999
 
        const DRIZZLE_FIELD *fields= drizzle_fetch_fields(res);
5000
 
        uint num_fields= drizzle_num_fields(res);
 
5169
        MYSQL_FIELD *fields= mysql_fetch_fields(res);
 
5170
        uint num_fields= mysql_num_fields(res);
5001
5171
 
5002
 
        if (display_metadata)
 
5172
        if (display_metadata)
5003
5173
          append_metadata(ds, fields, num_fields);
5004
5174
 
5005
 
        if (!display_result_vertically)
5006
 
          append_table_headings(ds, fields, num_fields);
 
5175
        if (!display_result_vertically)
 
5176
          append_table_headings(ds, fields, num_fields);
5007
5177
 
5008
 
        append_result(ds, res);
 
5178
        append_result(ds, res);
5009
5179
      }
5010
5180
 
5011
5181
      /*
5012
 
        Need to call drizzle_affected_rows() before the "new"
 
5182
        Need to call mysql_affected_rows() before the "new"
5013
5183
        query to find the warnings
5014
5184
      */
5015
5185
      if (!disable_info)
5016
 
        affected_rows= drizzle_affected_rows(drizzle);
 
5186
        affected_rows= mysql_affected_rows(mysql);
5017
5187
 
5018
5188
      /*
5019
5189
        Add all warnings to the result. We can't do this if we are in
5020
5190
        the middle of processing results from multi-statement, because
5021
5191
        this will break protocol.
5022
5192
      */
5023
 
      if (!disable_warnings && !drizzle_more_results(drizzle))
 
5193
      if (!disable_warnings && !mysql_more_results(mysql))
5024
5194
      {
5025
 
        if (append_warnings(ds_warnings, drizzle) || ds_warnings->length())
5026
 
        {
5027
 
          ds->append("Warnings:\n", 10);
5028
 
          ds->append(ds_warnings->c_str(), ds_warnings->length());
5029
 
        }
 
5195
        if (append_warnings(ds_warnings, mysql) || ds_warnings->length)
 
5196
        {
 
5197
          dynstr_append_mem(ds, "Warnings:\n", 10);
 
5198
          dynstr_append_mem(ds, ds_warnings->str, ds_warnings->length);
 
5199
        }
5030
5200
      }
5031
5201
 
5032
5202
      if (!disable_info)
5033
 
        append_info(ds, affected_rows, drizzle_info(drizzle));
 
5203
        append_info(ds, affected_rows, mysql_info(mysql));
5034
5204
    }
5035
5205
 
5036
5206
    if (res)
5037
5207
    {
5038
 
      drizzle_free_result(res);
 
5208
      mysql_free_result(res);
5039
5209
      res= 0;
5040
5210
    }
5041
5211
    counter++;
5042
 
  } while (!(err= drizzle_next_result(drizzle)));
 
5212
  } while (!(err= mysql_next_result(mysql)));
5043
5213
  if (err > 0)
5044
5214
  {
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);
 
5215
    /* We got an error from mysql_next_result, maybe expected */
 
5216
    handle_error(command, mysql_errno(mysql), mysql_error(mysql),
 
5217
                 mysql_sqlstate(mysql), ds);
5048
5218
    goto end;
5049
5219
  }
5050
5220
  assert(err == -1); /* Successful and there are no more results */
5055
5225
end:
5056
5226
 
5057
5227
  /*
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
 
5228
    We save the return code (mysql_errno(mysql)) from the last call sent
 
5229
    to the server into the mysqltest builtin variable $mysql_errno. This
5060
5230
    variable then can be used from the test case itself.
5061
5231
  */
5062
 
  var_set_errno(drizzle_errno(drizzle));
 
5232
  var_set_errno(mysql_errno(mysql));
5063
5233
  return;
5064
5234
}
5065
5235
 
5076
5246
  ds    - dynamic string which is used for output buffer
5077
5247
 
5078
5248
  NOTE
5079
 
  If there is an unexpected error this function will abort drizzletest
5080
 
  immediately.
 
5249
    If there is an unexpected error this function will abort mysqltest
 
5250
    immediately.
5081
5251
*/
5082
5252
 
5083
5253
void handle_error(struct st_command *command,
5084
5254
                  unsigned int err_errno, const char *err_error,
5085
 
                  const char *err_sqlstate, string *ds)
 
5255
                  const char *err_sqlstate, DYNAMIC_STRING *ds)
5086
5256
{
5087
5257
  uint i;
5088
5258
 
5089
5259
 
 
5260
 
5090
5261
  if (command->require_file[0])
5091
5262
  {
5092
5263
    /*
5120
5291
        if (command->expected_errors.count == 1)
5121
5292
        {
5122
5293
          /* Only log error if there is one possible error */
5123
 
          ds->append("ERROR ", 6);
5124
 
          replace_append(ds, err_sqlstate);
5125
 
          ds->append(": ", 2);
5126
 
          replace_append(ds, err_error);
5127
 
          ds->append("\n",1);
 
5294
          dynstr_append_mem(ds, "ERROR ", 6);
 
5295
          replace_dynstr_append(ds, err_sqlstate);
 
5296
          dynstr_append_mem(ds, ": ", 2);
 
5297
          replace_dynstr_append(ds, err_error);
 
5298
          dynstr_append_mem(ds,"\n",1);
5128
5299
        }
5129
5300
        /* Don't log error if we may not get an error */
5130
5301
        else if (command->expected_errors.err[0].type == ERR_SQLSTATE ||
5131
5302
                 (command->expected_errors.err[0].type == ERR_ERRNO &&
5132
5303
                  command->expected_errors.err[0].code.errnum != 0))
5133
 
          ds->append("Got one of the listed errors\n");
 
5304
          dynstr_append(ds,"Got one of the listed errors\n");
5134
5305
      }
5135
5306
      /* OK */
5136
5307
      return;
5139
5310
 
5140
5311
  if (!disable_result_log)
5141
5312
  {
5142
 
    ds->append("ERROR ",6);
5143
 
    replace_append(ds, err_sqlstate);
5144
 
    ds->append(": ", 2);
5145
 
    replace_append(ds, err_error);
5146
 
    ds->append("\n", 1);
 
5313
    dynstr_append_mem(ds, "ERROR ",6);
 
5314
    replace_dynstr_append(ds, err_sqlstate);
 
5315
    dynstr_append_mem(ds, ": ", 2);
 
5316
    replace_dynstr_append(ds, err_error);
 
5317
    dynstr_append_mem(ds, "\n", 1);
5147
5318
  }
5148
5319
 
5149
5320
  if (i)
5155
5326
    else
5156
5327
      die("query '%s' failed with wrong sqlstate %s: '%s', instead of %s...",
5157
5328
          command->query, err_sqlstate, err_error,
5158
 
          command->expected_errors.err[0].code.sqlstate);
 
5329
          command->expected_errors.err[0].code.sqlstate);
5159
5330
  }
5160
5331
 
5161
5332
  return;
5200
5371
  Run query
5201
5372
 
5202
5373
  SYNPOSIS
5203
 
  run_query()
5204
 
  drizzle  DRIZZLE handle
5205
 
  command  currrent command pointer
 
5374
    run_query()
 
5375
     mysql      mysql handle
 
5376
     command    currrent command pointer
5206
5377
 
5207
5378
  flags control the phased/stages of query execution to be performed
5208
5379
  if QUERY_SEND_FLAG bit is on, the query will be sent. If QUERY_REAP_FLAG
5209
5380
  is on the result will be read - for regular query, both bits must be on
5210
5381
*/
5211
5382
 
5212
 
static void run_query(struct st_connection *cn,
 
5383
static void run_query(struct st_connection *cn, 
5213
5384
                      struct st_command *command,
5214
5385
                      int flags)
5215
5386
{
5216
 
  string *ds= NULL;
5217
 
  string *save_ds= NULL;
5218
 
  string ds_result;
5219
 
  string ds_sorted;
5220
 
  string ds_warnings;
5221
 
  string eval_query;
 
5387
  DYNAMIC_STRING *ds;
 
5388
  DYNAMIC_STRING *save_ds= NULL;
 
5389
  DYNAMIC_STRING ds_result;
 
5390
  DYNAMIC_STRING ds_sorted;
 
5391
  DYNAMIC_STRING ds_warnings;
 
5392
  DYNAMIC_STRING eval_query;
5222
5393
  char *query;
5223
5394
  int query_len;
5224
5395
 
5225
5396
 
 
5397
  init_dynamic_string(&ds_warnings, NULL, 0, 256);
 
5398
 
5226
5399
  /* Scan for warning before sending to server */
5227
5400
  scan_command_for_warnings(command);
5228
5401
 
5231
5404
  */
5232
5405
  if (command->type == Q_EVAL)
5233
5406
  {
 
5407
    init_dynamic_string(&eval_query, "", command->query_len+256, 1024);
5234
5408
    do_eval(&eval_query, command->query, command->end, false);
5235
 
    query = strdup(eval_query.c_str());
5236
 
    query_len = eval_query.length();
 
5409
    query = eval_query.str;
 
5410
    query_len = eval_query.length;
5237
5411
  }
5238
5412
  else
5239
5413
  {
5249
5423
  */
5250
5424
  if (command->require_file[0])
5251
5425
  {
 
5426
    init_dynamic_string(&ds_result, "", 1024, 1024);
5252
5427
    ds= &ds_result;
5253
5428
  }
5254
5429
  else
5255
 
  {
5256
5430
    ds= &ds_res;
5257
 
  }
 
5431
 
5258
5432
  /*
5259
5433
    Log the query into the output buffer
5260
5434
  */
5261
5435
  if (!disable_query_log && (flags & QUERY_SEND_FLAG))
5262
5436
  {
5263
 
    replace_append_mem(ds, query, query_len);
5264
 
    ds->append(delimiter, delimiter_length);
5265
 
    ds->append("\n");
 
5437
    replace_dynstr_append_mem(ds, query, query_len);
 
5438
    dynstr_append_mem(ds, delimiter, delimiter_length);
 
5439
    dynstr_append_mem(ds, "\n", 1);
5266
5440
  }
5267
5441
 
5268
5442
  if (display_result_sorted)
5269
5443
  {
5270
5444
    /*
5271
 
      Collect the query output in a separate string
5272
 
      that can be sorted before it's added to the
5273
 
      global result string
 
5445
       Collect the query output in a separate string
 
5446
       that can be sorted before it's added to the
 
5447
       global result string
5274
5448
    */
 
5449
    init_dynamic_string(&ds_sorted, "", 1024, 1024);
5275
5450
    save_ds= ds; /* Remember original ds */
5276
5451
    ds= &ds_sorted;
5277
5452
  }
5286
5461
  if (display_result_sorted)
5287
5462
  {
5288
5463
    /* Sort the result set and append it to result */
5289
 
    append_sorted(save_ds, &ds_sorted);
 
5464
    dynstr_append_sorted(save_ds, &ds_sorted);
5290
5465
    ds= save_ds;
 
5466
    dynstr_free(&ds_sorted);
5291
5467
  }
5292
5468
 
5293
5469
  if (command->require_file[0])
5299
5475
    check_require(ds, command->require_file);
5300
5476
  }
5301
5477
 
 
5478
  dynstr_free(&ds_warnings);
 
5479
  if (ds == &ds_result)
 
5480
    dynstr_free(&ds_result);
 
5481
  if (command->type == Q_EVAL)
 
5482
    dynstr_free(&eval_query);
5302
5483
  return;
5303
5484
}
5304
5485
 
5323
5504
  command->query[command->first_word_len]= save;
5324
5505
  if (type > 0)
5325
5506
  {
5326
 
    command->type=(enum enum_commands) type;    /* Found command */
 
5507
    command->type=(enum enum_commands) type;            /* Found command */
5327
5508
 
5328
5509
    /*
5329
5510
      Look for case where "query" was explicitly specified to
5337
5518
  }
5338
5519
  else
5339
5520
  {
5340
 
    /* No drizzletest command matched */
 
5521
    /* No mysqltest command matched */
5341
5522
 
5342
5523
    if (command->type != Q_COMMENT_WITH_COMMAND)
5343
5524
    {
5344
 
      /* A query that will sent to drizzled */
 
5525
      /* A query that will sent to mysqld */
5345
5526
      command->type= Q_QUERY;
5346
5527
    }
5347
5528
    else
5348
5529
    {
5349
 
      /* -- comment that didn't contain a drizzletest command */
 
5530
      /* -- comment that didn't contain a mysqltest command */
5350
5531
      command->type= Q_COMMENT;
5351
 
      warning_msg("Suspicious command '--%s' detected, was this intentional? " \
 
5532
      warning_msg("Suspicious command '--%s' detected, was this intentional? "\
5352
5533
                  "Use # instead of -- to avoid this warning",
5353
5534
                  command->query);
5354
5535
 
5402
5583
 
5403
5584
  /* Milliseconds since start */
5404
5585
  end= int64_t2str(timer, buf, 10);
5405
 
  ds_progress.append(buf, (int)(end-buf));
5406
 
  ds_progress.append("\t", 1);
 
5586
  dynstr_append_mem(&ds_progress, buf, (int)(end-buf));
 
5587
  dynstr_append_mem(&ds_progress, "\t", 1);
5407
5588
 
5408
5589
  /* Parser line number */
5409
5590
  end= int10_to_str(line, buf, 10);
5410
 
  ds_progress.append(buf, (int)(end-buf));
5411
 
  ds_progress.append("\t", 1);
 
5591
  dynstr_append_mem(&ds_progress, buf, (int)(end-buf));
 
5592
  dynstr_append_mem(&ds_progress, "\t", 1);
5412
5593
 
5413
5594
  /* Filename */
5414
 
  ds_progress.append(cur_file->file_name);
5415
 
  ds_progress.append(":", 1);
 
5595
  dynstr_append(&ds_progress, cur_file->file_name);
 
5596
  dynstr_append_mem(&ds_progress, ":", 1);
5416
5597
 
5417
5598
  /* Line in file */
5418
5599
  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);
 
5600
  dynstr_append_mem(&ds_progress, buf, (int)(end-buf));
 
5601
 
 
5602
 
 
5603
  dynstr_append_mem(&ds_progress, "\n", 1);
5423
5604
 
5424
5605
}
5425
5606
 
5445
5626
    (sizeof(connections)/sizeof(struct st_connection)) - 1;
5446
5627
  next_con= connections + 1;
5447
5628
 
 
5629
#ifdef EMBEDDED_LIBRARY
 
5630
  /* set appropriate stack for the 'query' threads */
 
5631
  (void) pthread_attr_init(&cn_thd_attrib);
 
5632
  pthread_attr_setstacksize(&cn_thd_attrib, DEFAULT_THREAD_STACK);
 
5633
#endif /*EMBEDDED_LIBRARY*/
 
5634
 
5448
5635
  /* Init file stack */
5449
5636
  memset(file_stack, 0, sizeof(file_stack));
5450
5637
  file_stack_end=
5459
5646
  cur_block->ok= true; /* Outer block should always be executed */
5460
5647
  cur_block->cmd= cmd_none;
5461
5648
 
 
5649
  my_init_dynamic_array(&q_lines, sizeof(struct st_command*), 1024, 1024);
 
5650
 
5462
5651
  if (hash_init(&var_hash, charset_info,
5463
5652
                1024, 0, 0, get_var_key, var_free, MYF(0)))
5464
5653
    die("Variable hash initialization failed");
5465
5654
 
5466
 
  var_set_string("$DRIZZLE_SERVER_VERSION", drizzle_get_client_info());
 
5655
  var_set_string("$MYSQL_SERVER_VERSION", MYSQL_SERVER_VERSION);
5467
5656
 
5468
5657
  memset(&master_pos, 0, sizeof(master_pos));
5469
5658
 
5472
5661
 
5473
5662
  init_builtin_echo();
5474
5663
 
5475
 
  ds_res.reserve(65536);
5476
 
  ds_progress.reserve(2048);
5477
 
  ds_warning_messages.reserve(2048);
5478
 
 
 
5664
  init_dynamic_string(&ds_res, "", 65536, 65536);
 
5665
  init_dynamic_string(&ds_progress, "", 0, 2048);
 
5666
  init_dynamic_string(&ds_warning_messages, "", 0, 2048);
5479
5667
  parse_args(argc, argv);
5480
5668
 
 
5669
  if (mysql_server_init(embedded_server_arg_count,
 
5670
                        embedded_server_args,
 
5671
                        (char**) embedded_server_groups))
 
5672
    die("Can't initialize MySQL server");
5481
5673
  server_initialized= 1;
5482
5674
  if (cur_file == file_stack && cur_file->file == 0)
5483
5675
  {
5486
5678
    cur_file->lineno= 1;
5487
5679
  }
5488
5680
  cur_con= connections;
5489
 
  if (!( drizzle_create(&cur_con->drizzle)))
5490
 
    die("Failed in drizzle_create()");
 
5681
  if (!( mysql_init(&cur_con->mysql)))
 
5682
    die("Failed in mysql_init()");
5491
5683
  if (opt_compress)
5492
 
    drizzle_options(&cur_con->drizzle,DRIZZLE_OPT_COMPRESS,NULL);
5493
 
  drizzle_options(&cur_con->drizzle, DRIZZLE_OPT_LOCAL_INFILE, 0);
 
5684
    mysql_options(&cur_con->mysql,MYSQL_OPT_COMPRESS,NullS);
 
5685
  mysql_options(&cur_con->mysql, MYSQL_OPT_LOCAL_INFILE, 0);
 
5686
  mysql_options(&cur_con->mysql, MYSQL_SET_CHARSET_NAME,
 
5687
                charset_info->csname);
 
5688
  int opt_protocol= MYSQL_PROTOCOL_TCP;
 
5689
  mysql_options(&cur_con->mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
 
5690
  if (opt_charsets_dir)
 
5691
    mysql_options(&cur_con->mysql, MYSQL_SET_CHARSET_DIR,
 
5692
                  opt_charsets_dir);
5494
5693
 
5495
5694
  if (!(cur_con->name = my_strdup("default", MYF(MY_WME))))
5496
5695
    die("Out of memory");
5497
5696
 
5498
 
  safe_connect(&cur_con->drizzle, cur_con->name, opt_host, opt_user, opt_pass,
 
5697
  safe_connect(&cur_con->mysql, cur_con->name, opt_host, opt_user, opt_pass,
5499
5698
               opt_db, opt_port);
5500
5699
 
5501
5700
  /* Use all time until exit if no explicit 'start_timer' */
5502
5701
  timer_start= timer_now();
5503
5702
 
5504
5703
  /*
5505
 
    Initialize $drizzle_errno with -1, so we can
 
5704
    Initialize $mysql_errno with -1, so we can
5506
5705
    - distinguish it from valid values ( >= 0 ) and
5507
5706
    - detect if there was never a command sent to the server
5508
5707
  */
5509
5708
  var_set_errno(-1);
5510
5709
 
5511
 
  /* Update $drizzle_get_server_version to that of current connection */
5512
 
  var_set_drizzle_get_server_version(&cur_con->drizzle);
 
5710
  /* Update $mysql_get_server_version to that of current connection */
 
5711
  var_set_mysql_get_server_version(&cur_con->mysql);
5513
5712
 
5514
5713
  if (opt_include)
5515
5714
  {
5538
5737
      case Q_CONNECT:
5539
5738
        do_connect(command);
5540
5739
        break;
5541
 
      case Q_CONNECTION:
5542
 
        select_connection(command);
5543
 
        break;
 
5740
      case Q_CONNECTION: select_connection(command); break;
5544
5741
      case Q_DISCONNECT:
5545
5742
      case Q_DIRTY_CLOSE:
5546
 
        do_close_connection(command); break;
 
5743
        do_close_connection(command); break;
5547
5744
      case Q_ENABLE_QUERY_LOG:   disable_query_log=0; break;
5548
5745
      case Q_DISABLE_QUERY_LOG:  disable_query_log=1; break;
5549
5746
      case Q_ENABLE_ABORT_ON_ERROR:  abort_on_error=1; break;
5579
5776
      case Q_PERL: do_perl(command); break;
5580
5777
      case Q_DELIMITER:
5581
5778
        do_delimiter(command);
5582
 
        break;
 
5779
        break;
5583
5780
      case Q_DISPLAY_VERTICAL_RESULTS:
5584
5781
        display_result_vertically= true;
5585
5782
        break;
5586
5783
      case Q_DISPLAY_HORIZONTAL_RESULTS:
5587
 
        display_result_vertically= false;
 
5784
        display_result_vertically= false;
5588
5785
        break;
5589
5786
      case Q_SORTED_RESULT:
5590
5787
        /*
5591
5788
          Turn on sorting of result set, will be reset after next
5592
5789
          command
5593
5790
        */
5594
 
        display_result_sorted= true;
 
5791
        display_result_sorted= true;
5595
5792
        break;
5596
5793
      case Q_LET: do_let(command); break;
5597
5794
      case Q_EVAL_RESULT:
5599
5796
      case Q_EVAL:
5600
5797
      case Q_QUERY_VERTICAL:
5601
5798
      case Q_QUERY_HORIZONTAL:
5602
 
        if (command->query == command->query_buf)
 
5799
        if (command->query == command->query_buf)
5603
5800
        {
5604
5801
          /* Skip the first part of command, i.e query_xxx */
5605
 
          command->query= command->first_argument;
 
5802
          command->query= command->first_argument;
5606
5803
          command->first_word_len= 0;
5607
5804
        }
5608
 
        /* fall through */
 
5805
        /* fall through */
5609
5806
      case Q_QUERY:
5610
5807
      case Q_REAP:
5611
5808
      {
5612
 
        bool old_display_result_vertically= display_result_vertically;
 
5809
        bool old_display_result_vertically= display_result_vertically;
5613
5810
        /* Default is full query, both reap and send  */
5614
5811
        int flags= QUERY_REAP_FLAG | QUERY_SEND_FLAG;
5615
5812
 
5627
5824
        /* Check for special property for this query */
5628
5825
        display_result_vertically|= (command->type == Q_QUERY_VERTICAL);
5629
5826
 
5630
 
        if (save_file[0])
5631
 
        {
5632
 
          strmake(command->require_file, save_file, sizeof(save_file) - 1);
5633
 
          save_file[0]= 0;
5634
 
        }
5635
 
        run_query(cur_con, command, flags);
5636
 
        command_executed++;
 
5827
        if (save_file[0])
 
5828
        {
 
5829
          strmake(command->require_file, save_file, sizeof(save_file) - 1);
 
5830
          save_file[0]= 0;
 
5831
        }
 
5832
        run_query(cur_con, command, flags);
 
5833
        command_executed++;
5637
5834
        command->last_argument= command->end;
5638
5835
 
5639
5836
        /* Restore settings */
5640
 
        display_result_vertically= old_display_result_vertically;
 
5837
        display_result_vertically= old_display_result_vertically;
5641
5838
 
5642
 
        break;
 
5839
        break;
5643
5840
      }
5644
5841
      case Q_SEND:
5645
5842
        if (!*command->first_argument)
5653
5850
        }
5654
5851
 
5655
5852
        /* Remove "send" if this is first iteration */
5656
 
        if (command->query == command->query_buf)
5657
 
          command->query= command->first_argument;
 
5853
        if (command->query == command->query_buf)
 
5854
          command->query= command->first_argument;
5658
5855
 
5659
 
        /*
5660
 
          run_query() can execute a query partially, depending on the flags.
5661
 
          QUERY_SEND_FLAG flag without QUERY_REAP_FLAG tells it to just send
 
5856
        /*
 
5857
          run_query() can execute a query partially, depending on the flags.
 
5858
          QUERY_SEND_FLAG flag without QUERY_REAP_FLAG tells it to just send
5662
5859
          the query and read the result some time later when reap instruction
5663
 
          is given on this connection.
 
5860
          is given on this connection.
5664
5861
        */
5665
 
        run_query(cur_con, command, QUERY_SEND_FLAG);
5666
 
        command_executed++;
 
5862
        run_query(cur_con, command, QUERY_SEND_FLAG);
 
5863
        command_executed++;
5667
5864
        command->last_argument= command->end;
5668
 
        break;
 
5865
        break;
5669
5866
      case Q_REQUIRE:
5670
 
        do_get_file_name(command, save_file, sizeof(save_file));
5671
 
        break;
 
5867
        do_get_file_name(command, save_file, sizeof(save_file));
 
5868
        break;
5672
5869
      case Q_ERROR:
5673
5870
        do_get_errcodes(command);
5674
 
        break;
 
5871
        break;
5675
5872
      case Q_REPLACE:
5676
 
        do_get_replace(command);
5677
 
        break;
 
5873
        do_get_replace(command);
 
5874
        break;
5678
5875
      case Q_REPLACE_REGEX:
5679
5876
        do_get_replace_regex(command);
5680
5877
        break;
5681
5878
      case Q_REPLACE_COLUMN:
5682
 
        do_get_replace_column(command);
5683
 
        break;
 
5879
        do_get_replace_column(command);
 
5880
        break;
5684
5881
      case Q_SAVE_MASTER_POS: do_save_master_pos(); break;
5685
5882
      case Q_SYNC_WITH_MASTER: do_sync_with_master(command); break;
5686
5883
      case Q_SYNC_SLAVE_WITH_MASTER:
5687
5884
      {
5688
 
        do_save_master_pos();
5689
 
        if (*command->first_argument)
5690
 
          select_connection(command);
5691
 
        else
5692
 
          select_connection_name("slave");
5693
 
        do_sync_with_master2(0);
5694
 
        break;
 
5885
        do_save_master_pos();
 
5886
        if (*command->first_argument)
 
5887
          select_connection(command);
 
5888
        else
 
5889
          select_connection_name("slave");
 
5890
        do_sync_with_master2(0);
 
5891
        break;
5695
5892
      }
5696
 
      case Q_COMMENT:        /* Ignore row */
 
5893
      case Q_COMMENT:                           /* Ignore row */
5697
5894
        command->last_argument= command->end;
5698
 
        break;
 
5895
        break;
5699
5896
      case Q_PING:
5700
 
        (void) drizzle_ping(&cur_con->drizzle);
5701
 
        break;
 
5897
        (void) mysql_ping(&cur_con->mysql);
 
5898
        break;
5702
5899
      case Q_EXEC:
5703
 
        do_exec(command);
5704
 
        command_executed++;
5705
 
        break;
 
5900
        do_exec(command);
 
5901
        command_executed++;
 
5902
        break;
5706
5903
      case Q_START_TIMER:
5707
 
        /* Overwrite possible earlier start of timer */
5708
 
        timer_start= timer_now();
5709
 
        break;
 
5904
        /* Overwrite possible earlier start of timer */
 
5905
        timer_start= timer_now();
 
5906
        break;
5710
5907
      case Q_END_TIMER:
5711
 
        /* End timer before ending drizzletest */
5712
 
        timer_output();
5713
 
        break;
 
5908
        /* End timer before ending mysqltest */
 
5909
        timer_output();
 
5910
        break;
5714
5911
      case Q_CHARACTER_SET:
5715
 
        do_set_charset(command);
5716
 
        break;
 
5912
        do_set_charset(command);
 
5913
        break;
5717
5914
      case Q_DISABLE_RECONNECT:
5718
 
        set_reconnect(&cur_con->drizzle, 0);
 
5915
        set_reconnect(&cur_con->mysql, 0);
5719
5916
        break;
5720
5917
      case Q_ENABLE_RECONNECT:
5721
 
        set_reconnect(&cur_con->drizzle, 1);
 
5918
        set_reconnect(&cur_con->mysql, 1);
5722
5919
        break;
5723
5920
      case Q_DISABLE_PARSING:
5724
5921
        if (parsing_disabled == 0)
5809
6006
    Time to compare result or save it to record file.
5810
6007
    The entire output from test is now kept in ds_res.
5811
6008
  */
5812
 
  if (ds_res.length())
 
6009
  if (ds_res.length)
5813
6010
  {
5814
6011
    if (result_file_name)
5815
6012
    {
5817
6014
 
5818
6015
      if (record)
5819
6016
      {
5820
 
        /* Recording - dump the output from test to result file */
5821
 
        str_to_file(result_file_name, ds_res.c_str(), ds_res.length());
 
6017
        /* Recording - dump the output from test to result file */
 
6018
        str_to_file(result_file_name, ds_res.str, ds_res.length);
5822
6019
      }
5823
6020
      else
5824
6021
      {
5825
 
        /* Check that the output from test is equal to result file
5826
 
           - detect missing result file
5827
 
           - detect zero size result file
 
6022
        /* Check that the output from test is equal to result file
 
6023
           - detect missing result file
 
6024
           - detect zero size result file
5828
6025
        */
5829
 
        check_result(&ds_res);
 
6026
        check_result(&ds_res);
5830
6027
      }
5831
6028
    }
5832
6029
    else
5833
6030
    {
5834
6031
      /* No result_file_name specified to compare with, print to stdout */
5835
 
      printf("%s", ds_res.c_str());
 
6032
      printf("%s", ds_res.str);
5836
6033
    }
5837
6034
  }
5838
6035
  else
5857
6054
    dump_progress();
5858
6055
 
5859
6056
  /* Dump warning messages */
5860
 
  if (result_file_name && ds_warning_messages.length())
 
6057
  if (result_file_name && ds_warning_messages.length)
5861
6058
    dump_warning_messages();
5862
6059
 
5863
6060
  timer_output();
5875
6072
  before executing any commands. The time we measure is
5876
6073
 
5877
6074
  - If no explicit 'start_timer' or 'end_timer' is given in the
5878
 
  test case, the timer measure how long we execute in drizzletest.
 
6075
  test case, the timer measure how long we execute in mysqltest.
5879
6076
 
5880
6077
  - If only 'start_timer' is given we measure how long we execute
5881
 
  from that point until we terminate drizzletest.
 
6078
  from that point until we terminate mysqltest.
5882
6079
 
5883
6080
  - If only 'end_timer' is given we measure how long we execute
5884
 
  from that we enter drizzletest to the 'end_timer' is command is
 
6081
  from that we enter mysqltest to the 'end_timer' is command is
5885
6082
  executed.
5886
6083
 
5887
6084
  - If both 'start_timer' and 'end_timer' are given we measure
5939
6136
    if (!*from)
5940
6137
      die("Wrong number of arguments to replace_column in '%s'", command->query);
5941
6138
    to= get_string(&buff, &from, command);
5942
 
    free(replace_column[column_number-1]);
 
6139
    my_free(replace_column[column_number-1], MY_ALLOW_ZERO_PTR);
5943
6140
    replace_column[column_number-1]= my_strdup(to, MYF(MY_WME | MY_FAE));
5944
6141
    set_if_bigger(max_replace_column, column_number);
5945
6142
  }
5946
 
  free(start);
 
6143
  my_free(start, MYF(0));
5947
6144
  command->last_argument= command->end;
5948
6145
}
5949
6146
 
5955
6152
  {
5956
6153
    if (replace_column[i])
5957
6154
    {
5958
 
      free(replace_column[i]);
 
6155
      my_free(replace_column[i], 0);
5959
6156
      replace_column[i]= 0;
5960
6157
    }
5961
6158
  }
5970
6167
 
5971
6168
/* Definitions for replace result */
5972
6169
 
5973
 
typedef struct st_pointer_array {    /* when using array-strings */
5974
 
  TYPELIB typelib;        /* Pointer to strings */
5975
 
  unsigned char  *str;          /* Strings is here */
5976
 
  uint8_t *flag;          /* Flag about each var. */
5977
 
  uint  array_allocs,max_count,length,max_length;
 
6170
typedef struct st_pointer_array {               /* when using array-strings */
 
6171
  TYPELIB typelib;                              /* Pointer to strings */
 
6172
  uchar *str;                                   /* Strings is here */
 
6173
  int7  *flag;                                  /* Flag about each var. */
 
6174
  uint  array_allocs,max_count,length,max_length;
5978
6175
} POINTER_ARRAY;
5979
6176
 
5980
6177
struct st_replace;
5981
6178
struct st_replace *init_replace(char * *from, char * *to, uint count,
5982
 
                                char * word_end_chars);
 
6179
                                char * word_end_chars);
5983
6180
int insert_pointer_name(POINTER_ARRAY *pa,char * name);
5984
 
void replace_strings_append(struct st_replace *rep, string* ds,
 
6181
void replace_strings_append(struct st_replace *rep, DYNAMIC_STRING* ds,
5985
6182
                            const char *from, int len);
5986
6183
void free_pointer_array(POINTER_ARRAY *pa);
5987
6184
 
6006
6203
 
6007
6204
  free_replace();
6008
6205
 
6009
 
  memset(&to_array, 0, sizeof(to_array));
6010
 
  memset(&from_array, 0, sizeof(from_array));
 
6206
  bzero((char*) &to_array,sizeof(to_array));
 
6207
  bzero((char*) &from_array,sizeof(from_array));
6011
6208
  if (!*from)
6012
6209
    die("Missing argument in %s", command->query);
6013
6210
  start= buff= (char *)my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE));
6025
6222
  for (i= 1,pos= word_end_chars ; i < 256 ; i++)
6026
6223
    if (my_isspace(charset_info,i))
6027
6224
      *pos++= i;
6028
 
  *pos=0;          /* End pointer */
 
6225
  *pos=0;                                       /* End pointer */
6029
6226
  if (!(glob_replace= init_replace((char**) from_array.typelib.type_names,
6030
 
                                   (char**) to_array.typelib.type_names,
6031
 
                                   (uint) from_array.typelib.count,
6032
 
                                   word_end_chars)))
 
6227
                                  (char**) to_array.typelib.type_names,
 
6228
                                  (uint) from_array.typelib.count,
 
6229
                                  word_end_chars)))
6033
6230
    die("Can't initialize replace from '%s'", command->query);
6034
6231
  free_pointer_array(&from_array);
6035
6232
  free_pointer_array(&to_array);
6036
 
  free(start);
 
6233
  my_free(start, MYF(0));
6037
6234
  command->last_argument= command->end;
6038
6235
  return;
6039
6236
}
6044
6241
 
6045
6242
  if (glob_replace)
6046
6243
  {
6047
 
    free(glob_replace);
 
6244
    my_free(glob_replace,MYF(0));
6048
6245
    glob_replace=0;
6049
6246
  }
6050
6247
  return;
6064
6261
} REPLACE_STRING;
6065
6262
 
6066
6263
 
6067
 
void replace_strings_append(REPLACE *rep, string* ds,
6068
 
                            const char *str, int len)
 
6264
void replace_strings_append(REPLACE *rep, DYNAMIC_STRING* ds,
 
6265
                            const char *str,
 
6266
                            int len __attribute__((unused)))
6069
6267
{
6070
6268
  register REPLACE *rep_pos;
6071
6269
  register REPLACE_STRING *rep_str;
6078
6276
  {
6079
6277
    /* Loop through states */
6080
6278
    while (!rep_pos->found)
6081
 
      rep_pos= rep_pos->next[(unsigned char) *from++];
 
6279
      rep_pos= rep_pos->next[(uchar) *from++];
6082
6280
 
6083
6281
    /* Does this state contain a string to be replaced */
6084
6282
    if (!(rep_str = ((REPLACE_STRING*) rep_pos))->replace_string)
6085
6283
    {
6086
6284
      /* No match found */
6087
 
      ds->append(start, from - start - 1);
 
6285
      dynstr_append_mem(ds, start, from - start - 1);
6088
6286
      return;
6089
6287
    }
6090
6288
 
6091
6289
    /* Append part of original string before replace string */
6092
 
    ds->append(start, (from - rep_str->to_offset) - start);
 
6290
    dynstr_append_mem(ds, start, (from - rep_str->to_offset) - start);
6093
6291
 
6094
6292
    /* Append replace string */
6095
 
    ds->append(rep_str->replace_string,
6096
 
               strlen(rep_str->replace_string));
 
6293
    dynstr_append_mem(ds, rep_str->replace_string,
 
6294
                      strlen(rep_str->replace_string));
6097
6295
 
6098
6296
    if (!*(from-=rep_str->from_offset) && rep_pos->found != 2)
6099
6297
      return;
6202
6400
  /* for each regexp substitution statement */
6203
6401
  while (p < expr_end)
6204
6402
  {
6205
 
    memset(&reg, 0, sizeof(reg));
 
6403
    bzero(&reg,sizeof(reg));
6206
6404
    /* find the start of the statement */
6207
6405
    while (p < expr_end)
6208
6406
    {
6244
6442
      reg.icase= 1;
6245
6443
 
6246
6444
    /* done parsing the statement, now place it in regex_arr */
6247
 
    if (insert_dynamic(&res->regex_arr,(unsigned char*) &reg))
 
6445
    if (insert_dynamic(&res->regex_arr,(uchar*) &reg))
6248
6446
      die("Out of memory");
6249
6447
  }
6250
6448
  res->odd_buf_len= res->even_buf_len= 8192;
6255
6453
  return res;
6256
6454
 
6257
6455
err:
6258
 
  free(res);
 
6456
  my_free(res,0);
6259
6457
  die("Error parsing replace_regex \"%s\"", expr);
6260
6458
  return 0;
6261
6459
}
6296
6494
    struct st_regex re;
6297
6495
    char* save_out_buf= out_buf;
6298
6496
 
6299
 
    get_dynamic(&r->regex_arr,(unsigned char*)&re,i);
 
6497
    get_dynamic(&r->regex_arr,(uchar*)&re,i);
6300
6498
 
6301
6499
    if (!reg_replace(&out_buf, buf_len_p, re.pattern, re.replace,
6302
6500
                     in_buf, re.icase))
6314
6512
      if (in_buf == val)
6315
6513
        in_buf= r->odd_buf;
6316
6514
 
6317
 
      std::swap(in_buf,out_buf);
 
6515
      swap_variables(char*,in_buf,out_buf);
6318
6516
 
6319
6517
      buf_len_p= (out_buf == r->even_buf) ? &r->even_buf_len :
6320
6518
        &r->odd_buf_len;
6347
6545
  if (glob_replace_regex)
6348
6546
  {
6349
6547
    delete_dynamic(&glob_replace_regex->regex_arr);
6350
 
    free(glob_replace_regex->even_buf);
6351
 
    free(glob_replace_regex->odd_buf);
6352
 
    free(glob_replace_regex);
 
6548
    my_free(glob_replace_regex->even_buf,MYF(MY_ALLOW_ZERO_PTR));
 
6549
    my_free(glob_replace_regex->odd_buf,MYF(MY_ALLOW_ZERO_PTR));
 
6550
    my_free(glob_replace_regex,MYF(0));
6353
6551
    glob_replace_regex=0;
6354
6552
  }
6355
6553
}
6415
6613
#define LAST_CHAR_CODE 259
6416
6614
 
6417
6615
typedef struct st_rep_set {
6418
 
  uint  *bits;        /* Pointer to used sets */
6419
 
  short next[LAST_CHAR_CODE];    /* Pointer to next sets */
6420
 
  uint  found_len;      /* Best match to date */
6421
 
  int  found_offset;
6422
 
  uint  table_offset;
6423
 
  uint  size_of_bits;      /* For convinience */
 
6616
  uint  *bits;                          /* Pointer to used sets */
 
6617
  short next[LAST_CHAR_CODE];           /* Pointer to next sets */
 
6618
  uint  found_len;                      /* Best match to date */
 
6619
  int   found_offset;
 
6620
  uint  table_offset;
 
6621
  uint  size_of_bits;                   /* For convinience */
6424
6622
} REP_SET;
6425
6623
 
6426
6624
typedef struct st_rep_sets {
6427
 
  uint    count;      /* Number of sets */
6428
 
  uint    extra;      /* Extra sets in buffer */
6429
 
  uint    invisible;    /* Sets not chown */
6430
 
  uint    size_of_bits;
6431
 
  REP_SET  *set,*set_buffer;
6432
 
  uint    *bit_buffer;
 
6625
  uint          count;                  /* Number of sets */
 
6626
  uint          extra;                  /* Extra sets in buffer */
 
6627
  uint          invisible;              /* Sets not chown */
 
6628
  uint          size_of_bits;
 
6629
  REP_SET       *set,*set_buffer;
 
6630
  uint          *bit_buffer;
6433
6631
} REP_SETS;
6434
6632
 
6435
6633
typedef struct st_found_set {
6480
6678
/* Init a replace structure for further calls */
6481
6679
 
6482
6680
REPLACE *init_replace(char * *from, char * *to,uint count,
6483
 
                      char * word_end_chars)
 
6681
                      char * word_end_chars)
6484
6682
{
6485
6683
  static const int SPACE_CHAR= 256;
6486
6684
  static const int START_OF_LINE= 257;
6512
6710
    if (len > max_length)
6513
6711
      max_length=len;
6514
6712
  }
6515
 
  memset(is_word_end, 0, sizeof(is_word_end));
 
6713
  bzero((char*) is_word_end,sizeof(is_word_end));
6516
6714
  for (i=0 ; word_end_chars[i] ; i++)
6517
 
    is_word_end[(unsigned char) word_end_chars[i]]=1;
 
6715
    is_word_end[(uchar) word_end_chars[i]]=1;
6518
6716
 
6519
6717
  if (init_sets(&sets,states))
6520
6718
    return(0);
6521
6719
  found_sets=0;
6522
6720
  if (!(found_set= (FOUND_SET*) my_malloc(sizeof(FOUND_SET)*max_length*count,
6523
 
                                          MYF(MY_WME))))
 
6721
                                          MYF(MY_WME))))
6524
6722
  {
6525
6723
    free_sets(&sets);
6526
6724
    return(0);
6527
6725
  }
6528
 
  make_new_set(&sets);      /* Set starting set */
6529
 
  make_sets_invisible(&sets);      /* Hide previus sets */
 
6726
  VOID(make_new_set(&sets));                    /* Set starting set */
 
6727
  make_sets_invisible(&sets);                   /* Hide previus sets */
6530
6728
  used_sets=-1;
6531
 
  word_states=make_new_set(&sets);    /* Start of new word */
6532
 
  start_states=make_new_set(&sets);    /* This is first state */
 
6729
  word_states=make_new_set(&sets);              /* Start of new word */
 
6730
  start_states=make_new_set(&sets);             /* This is first state */
6533
6731
  if (!(follow=(FOLLOWS*) my_malloc((states+2)*sizeof(FOLLOWS),MYF(MY_WME))))
6534
6732
  {
6535
6733
    free_sets(&sets);
6536
 
    free(found_set);
 
6734
    my_free(found_set,MYF(0));
6537
6735
    return(0);
6538
6736
  }
6539
6737
 
6545
6743
      internal_set_bit(start_states,states+1);
6546
6744
      if (!from[i][2])
6547
6745
      {
6548
 
        start_states->table_offset=i;
6549
 
        start_states->found_offset=1;
 
6746
        start_states->table_offset=i;
 
6747
        start_states->found_offset=1;
6550
6748
      }
6551
6749
    }
6552
6750
    else if (from[i][0] == '\\' && from[i][1] == '$')
6553
6751
    {
6554
6752
      internal_set_bit(start_states,states);
6555
6753
      internal_set_bit(word_states,states);
6556
 
      if (!from[i][2] && start_states->table_offset == UINT32_MAX)
 
6754
      if (!from[i][2] && start_states->table_offset == (uint) ~0)
6557
6755
      {
6558
 
        start_states->table_offset=i;
6559
 
        start_states->found_offset=0;
 
6756
        start_states->table_offset=i;
 
6757
        start_states->found_offset=0;
6560
6758
      }
6561
6759
    }
6562
6760
    else
6563
6761
    {
6564
6762
      internal_set_bit(word_states,states);
6565
6763
      if (from[i][0] == '\\' && (from[i][1] == 'b' && from[i][2]))
6566
 
        internal_set_bit(start_states,states+1);
 
6764
        internal_set_bit(start_states,states+1);
6567
6765
      else
6568
 
        internal_set_bit(start_states,states);
 
6766
        internal_set_bit(start_states,states);
6569
6767
    }
6570
6768
    for (pos=from[i], len=0; *pos ; pos++)
6571
6769
    {
6572
6770
      if (*pos == '\\' && *(pos+1))
6573
6771
      {
6574
 
        pos++;
6575
 
        switch (*pos) {
6576
 
        case 'b':
6577
 
          follow_ptr->chr = SPACE_CHAR;
6578
 
          break;
6579
 
        case '^':
6580
 
          follow_ptr->chr = START_OF_LINE;
6581
 
          break;
6582
 
        case '$':
6583
 
          follow_ptr->chr = END_OF_LINE;
6584
 
          break;
6585
 
        case 'r':
6586
 
          follow_ptr->chr = '\r';
6587
 
          break;
6588
 
        case 't':
6589
 
          follow_ptr->chr = '\t';
6590
 
          break;
6591
 
        case 'v':
6592
 
          follow_ptr->chr = '\v';
6593
 
          break;
6594
 
        default:
6595
 
          follow_ptr->chr = (unsigned char) *pos;
6596
 
          break;
6597
 
        }
 
6772
        pos++;
 
6773
        switch (*pos) {
 
6774
        case 'b':
 
6775
          follow_ptr->chr = SPACE_CHAR;
 
6776
          break;
 
6777
        case '^':
 
6778
          follow_ptr->chr = START_OF_LINE;
 
6779
          break;
 
6780
        case '$':
 
6781
          follow_ptr->chr = END_OF_LINE;
 
6782
          break;
 
6783
        case 'r':
 
6784
          follow_ptr->chr = '\r';
 
6785
          break;
 
6786
        case 't':
 
6787
          follow_ptr->chr = '\t';
 
6788
          break;
 
6789
        case 'v':
 
6790
          follow_ptr->chr = '\v';
 
6791
          break;
 
6792
        default:
 
6793
          follow_ptr->chr = (uchar) *pos;
 
6794
          break;
 
6795
        }
6598
6796
      }
6599
6797
      else
6600
 
        follow_ptr->chr= (unsigned char) *pos;
 
6798
        follow_ptr->chr= (uchar) *pos;
6601
6799
      follow_ptr->table_offset=i;
6602
6800
      follow_ptr->len= ++len;
6603
6801
      follow_ptr++;
6613
6811
  for (set_nr=0,pos=0 ; set_nr < sets.count ; set_nr++)
6614
6812
  {
6615
6813
    set=sets.set+set_nr;
6616
 
    default_state= 0;        /* Start from beginning */
 
6814
    default_state= 0;                           /* Start from beginning */
6617
6815
 
6618
6816
    /* If end of found-string not found or start-set with current set */
6619
6817
 
6620
 
    for (i= UINT32_MAX; (i=get_next_bit(set,i)) ;)
 
6818
    for (i= (uint) ~0; (i=get_next_bit(set,i)) ;)
6621
6819
    {
6622
6820
      if (!follow[i].chr)
6623
6821
      {
6624
 
        if (! default_state)
6625
 
          default_state= find_found(found_set,set->table_offset,
6626
 
                                    set->found_offset+1);
 
6822
        if (! default_state)
 
6823
          default_state= find_found(found_set,set->table_offset,
 
6824
                                    set->found_offset+1);
6627
6825
      }
6628
6826
    }
6629
 
    copy_bits(sets.set+used_sets,set);    /* Save set for changes */
 
6827
    copy_bits(sets.set+used_sets,set);          /* Save set for changes */
6630
6828
    if (!default_state)
6631
 
      or_bits(sets.set+used_sets,sets.set);  /* Can restart from start */
 
6829
      or_bits(sets.set+used_sets,sets.set);     /* Can restart from start */
6632
6830
 
6633
6831
    /* Find all chars that follows current sets */
6634
 
    memset(used_chars, 0, sizeof(used_chars));
6635
 
    for (i= UINT32_MAX; (i=get_next_bit(sets.set+used_sets,i)) ;)
 
6832
    bzero((char*) used_chars,sizeof(used_chars));
 
6833
    for (i= (uint) ~0; (i=get_next_bit(sets.set+used_sets,i)) ;)
6636
6834
    {
6637
6835
      used_chars[follow[i].chr]=1;
6638
6836
      if ((follow[i].chr == SPACE_CHAR && !follow[i+1].chr &&
6639
 
           follow[i].len > 1) || follow[i].chr == END_OF_LINE)
6640
 
        used_chars[0]=1;
 
6837
           follow[i].len > 1) || follow[i].chr == END_OF_LINE)
 
6838
        used_chars[0]=1;
6641
6839
    }
6642
6840
 
6643
6841
    /* Mark word_chars used if \b is in state */
6644
6842
    if (used_chars[SPACE_CHAR])
6645
6843
      for (pos= word_end_chars ; *pos ; pos++)
6646
 
        used_chars[(int) (unsigned char) *pos] = 1;
 
6844
        used_chars[(int) (uchar) *pos] = 1;
6647
6845
 
6648
6846
    /* Handle other used characters */
6649
6847
    for (chr= 0 ; chr < 256 ; chr++)
6650
6848
    {
6651
6849
      if (! used_chars[chr])
6652
 
        set->next[chr]= chr ? default_state : -1;
 
6850
        set->next[chr]= chr ? default_state : -1;
6653
6851
      else
6654
6852
      {
6655
 
        new_set=make_new_set(&sets);
6656
 
        set=sets.set+set_nr;      /* if realloc */
6657
 
        new_set->table_offset=set->table_offset;
6658
 
        new_set->found_len=set->found_len;
6659
 
        new_set->found_offset=set->found_offset+1;
6660
 
        found_end=0;
 
6853
        new_set=make_new_set(&sets);
 
6854
        set=sets.set+set_nr;                    /* if realloc */
 
6855
        new_set->table_offset=set->table_offset;
 
6856
        new_set->found_len=set->found_len;
 
6857
        new_set->found_offset=set->found_offset+1;
 
6858
        found_end=0;
6661
6859
 
6662
 
        for (i= UINT32_MAX ; (i=get_next_bit(sets.set+used_sets,i)) ; )
6663
 
        {
6664
 
          if (!follow[i].chr || follow[i].chr == chr ||
6665
 
              (follow[i].chr == SPACE_CHAR &&
6666
 
               (is_word_end[chr] ||
6667
 
                (!chr && follow[i].len > 1 && ! follow[i+1].chr))) ||
6668
 
              (follow[i].chr == END_OF_LINE && ! chr))
6669
 
          {
6670
 
            if ((! chr || (follow[i].chr && !follow[i+1].chr)) &&
6671
 
                follow[i].len > found_end)
6672
 
              found_end=follow[i].len;
6673
 
            if (chr && follow[i].chr)
6674
 
              internal_set_bit(new_set,i+1);    /* To next set */
6675
 
            else
6676
 
              internal_set_bit(new_set,i);
6677
 
          }
6678
 
        }
6679
 
        if (found_end)
6680
 
        {
6681
 
          new_set->found_len=0;      /* Set for testing if first */
6682
 
          bits_set=0;
6683
 
          for (i= UINT32_MAX; (i=get_next_bit(new_set,i)) ;)
6684
 
          {
6685
 
            if ((follow[i].chr == SPACE_CHAR ||
6686
 
                 follow[i].chr == END_OF_LINE) && ! chr)
6687
 
              bit_nr=i+1;
6688
 
            else
6689
 
              bit_nr=i;
6690
 
            if (follow[bit_nr-1].len < found_end ||
6691
 
                (new_set->found_len &&
6692
 
                 (chr == 0 || !follow[bit_nr].chr)))
6693
 
              internal_clear_bit(new_set,i);
6694
 
            else
6695
 
            {
6696
 
              if (chr == 0 || !follow[bit_nr].chr)
6697
 
              {          /* best match  */
6698
 
                new_set->table_offset=follow[bit_nr].table_offset;
6699
 
                if (chr || (follow[i].chr == SPACE_CHAR ||
6700
 
                            follow[i].chr == END_OF_LINE))
6701
 
                  new_set->found_offset=found_end;  /* New match */
6702
 
                new_set->found_len=found_end;
6703
 
              }
6704
 
              bits_set++;
6705
 
            }
6706
 
          }
6707
 
          if (bits_set == 1)
6708
 
          {
6709
 
            set->next[chr] = find_found(found_set,
6710
 
                                        new_set->table_offset,
6711
 
                                        new_set->found_offset);
6712
 
            free_last_set(&sets);
6713
 
          }
6714
 
          else
6715
 
            set->next[chr] = find_set(&sets,new_set);
6716
 
        }
6717
 
        else
6718
 
          set->next[chr] = find_set(&sets,new_set);
 
6860
        for (i= (uint) ~0 ; (i=get_next_bit(sets.set+used_sets,i)) ; )
 
6861
        {
 
6862
          if (!follow[i].chr || follow[i].chr == chr ||
 
6863
              (follow[i].chr == SPACE_CHAR &&
 
6864
               (is_word_end[chr] ||
 
6865
                (!chr && follow[i].len > 1 && ! follow[i+1].chr))) ||
 
6866
              (follow[i].chr == END_OF_LINE && ! chr))
 
6867
          {
 
6868
            if ((! chr || (follow[i].chr && !follow[i+1].chr)) &&
 
6869
                follow[i].len > found_end)
 
6870
              found_end=follow[i].len;
 
6871
            if (chr && follow[i].chr)
 
6872
              internal_set_bit(new_set,i+1);            /* To next set */
 
6873
            else
 
6874
              internal_set_bit(new_set,i);
 
6875
          }
 
6876
        }
 
6877
        if (found_end)
 
6878
        {
 
6879
          new_set->found_len=0;                 /* Set for testing if first */
 
6880
          bits_set=0;
 
6881
          for (i= (uint) ~0; (i=get_next_bit(new_set,i)) ;)
 
6882
          {
 
6883
            if ((follow[i].chr == SPACE_CHAR ||
 
6884
                 follow[i].chr == END_OF_LINE) && ! chr)
 
6885
              bit_nr=i+1;
 
6886
            else
 
6887
              bit_nr=i;
 
6888
            if (follow[bit_nr-1].len < found_end ||
 
6889
                (new_set->found_len &&
 
6890
                 (chr == 0 || !follow[bit_nr].chr)))
 
6891
              internal_clear_bit(new_set,i);
 
6892
            else
 
6893
            {
 
6894
              if (chr == 0 || !follow[bit_nr].chr)
 
6895
              {                                 /* best match  */
 
6896
                new_set->table_offset=follow[bit_nr].table_offset;
 
6897
                if (chr || (follow[i].chr == SPACE_CHAR ||
 
6898
                            follow[i].chr == END_OF_LINE))
 
6899
                  new_set->found_offset=found_end;      /* New match */
 
6900
                new_set->found_len=found_end;
 
6901
              }
 
6902
              bits_set++;
 
6903
            }
 
6904
          }
 
6905
          if (bits_set == 1)
 
6906
          {
 
6907
            set->next[chr] = find_found(found_set,
 
6908
                                        new_set->table_offset,
 
6909
                                        new_set->found_offset);
 
6910
            free_last_set(&sets);
 
6911
          }
 
6912
          else
 
6913
            set->next[chr] = find_set(&sets,new_set);
 
6914
        }
 
6915
        else
 
6916
          set->next[chr] = find_set(&sets,new_set);
6719
6917
      }
6720
6918
    }
6721
6919
  }
6723
6921
  /* Alloc replace structure for the replace-state-machine */
6724
6922
 
6725
6923
  if ((replace=(REPLACE*) my_malloc(sizeof(REPLACE)*(sets.count)+
6726
 
                                    sizeof(REPLACE_STRING)*(found_sets+1)+
6727
 
                                    sizeof(char *)*count+result_len,
6728
 
                                    MYF(MY_WME | MY_ZEROFILL))))
 
6924
                                    sizeof(REPLACE_STRING)*(found_sets+1)+
 
6925
                                    sizeof(char *)*count+result_len,
 
6926
                                    MYF(MY_WME | MY_ZEROFILL))))
6729
6927
  {
6730
6928
    rep_str=(REPLACE_STRING*) (replace+sets.count);
6731
6929
    to_array= (char **) (rep_str+found_sets+1);
6733
6931
    for (i=0 ; i < count ; i++)
6734
6932
    {
6735
6933
      to_array[i]=to_pos;
6736
 
      to_pos=my_stpcpy(to_pos,to[i])+1;
 
6934
      to_pos=strmov(to_pos,to[i])+1;
6737
6935
    }
6738
6936
    rep_str[0].found=1;
6739
6937
    rep_str[0].replace_string=0;
6740
6938
    for (i=1 ; i <= found_sets ; i++)
6741
6939
    {
6742
6940
      pos=from[found_set[i-1].table_offset];
6743
 
      rep_str[i].found= !memcmp(pos, "\\^", 3) ? 2 : 1;
 
6941
      rep_str[i].found= !bcmp((const uchar*) pos,
 
6942
                              (const uchar*) "\\^", 3) ? 2 : 1;
6744
6943
      rep_str[i].replace_string=to_array[found_set[i-1].table_offset];
6745
6944
      rep_str[i].to_offset=found_set[i-1].found_offset-start_at_word(pos);
6746
6945
      rep_str[i].from_offset=found_set[i-1].found_offset-replace_len(pos)+
6747
 
        end_of_word(pos);
 
6946
        end_of_word(pos);
6748
6947
    }
6749
6948
    for (i=0 ; i < sets.count ; i++)
6750
6949
    {
6751
6950
      for (j=0 ; j < 256 ; j++)
6752
 
        if (sets.set[i].next[j] >= 0)
6753
 
          replace[i].next[j]=replace+sets.set[i].next[j];
6754
 
        else
6755
 
          replace[i].next[j]=(REPLACE*) (rep_str+(-sets.set[i].next[j]-1));
 
6951
        if (sets.set[i].next[j] >= 0)
 
6952
          replace[i].next[j]=replace+sets.set[i].next[j];
 
6953
        else
 
6954
          replace[i].next[j]=(REPLACE*) (rep_str+(-sets.set[i].next[j]-1));
6756
6955
    }
6757
6956
  }
6758
 
  free(follow);
 
6957
  my_free(follow,MYF(0));
6759
6958
  free_sets(&sets);
6760
 
  free(found_set);
 
6959
  my_free(found_set,MYF(0));
6761
6960
  return(replace);
6762
6961
}
6763
6962
 
6764
6963
 
6765
6964
int init_sets(REP_SETS *sets,uint states)
6766
6965
{
6767
 
  memset(sets, 0, sizeof(*sets));
 
6966
  bzero((char*) sets,sizeof(*sets));
6768
6967
  sets->size_of_bits=((states+7)/8);
6769
6968
  if (!(sets->set_buffer=(REP_SET*) my_malloc(sizeof(REP_SET)*SET_MALLOC_HUNC,
6770
 
                                              MYF(MY_WME))))
 
6969
                                              MYF(MY_WME))))
6771
6970
    return 1;
6772
6971
  if (!(sets->bit_buffer=(uint*) my_malloc(sizeof(uint)*sets->size_of_bits*
6773
 
                                           SET_MALLOC_HUNC,MYF(MY_WME))))
 
6972
                                           SET_MALLOC_HUNC,MYF(MY_WME))))
6774
6973
  {
6775
 
    free(sets->set);
 
6974
    my_free(sets->set,MYF(0));
6776
6975
    return 1;
6777
6976
  }
6778
6977
  return 0;
6795
6994
  {
6796
6995
    sets->extra--;
6797
6996
    set=sets->set+ sets->count++;
6798
 
    memset(set->bits, 0, sizeof(uint)*sets->size_of_bits);
6799
 
    memset(&set->next[0], 0, sizeof(set->next[0])*LAST_CHAR_CODE);
 
6997
    bzero((char*) set->bits,sizeof(uint)*sets->size_of_bits);
 
6998
    bzero((char*) &set->next[0],sizeof(set->next[0])*LAST_CHAR_CODE);
6800
6999
    set->found_offset=0;
6801
7000
    set->found_len=0;
6802
 
    set->table_offset= UINT32_MAX;
 
7001
    set->table_offset= (uint) ~0;
6803
7002
    set->size_of_bits=sets->size_of_bits;
6804
7003
    return set;
6805
7004
  }
6806
7005
  count=sets->count+sets->invisible+SET_MALLOC_HUNC;
6807
 
  if (!(set=(REP_SET*) my_realloc((unsigned char*) sets->set_buffer,
 
7006
  if (!(set=(REP_SET*) my_realloc((uchar*) sets->set_buffer,
6808
7007
                                  sizeof(REP_SET)*count,
6809
 
                                  MYF(MY_WME))))
 
7008
                                  MYF(MY_WME))))
6810
7009
    return 0;
6811
7010
  sets->set_buffer=set;
6812
7011
  sets->set=set+sets->invisible;
6813
 
  if (!(bit_buffer=(uint*) my_realloc((unsigned char*) sets->bit_buffer,
6814
 
                                      (sizeof(uint)*sets->size_of_bits)*count,
6815
 
                                      MYF(MY_WME))))
 
7012
  if (!(bit_buffer=(uint*) my_realloc((uchar*) sets->bit_buffer,
 
7013
                                      (sizeof(uint)*sets->size_of_bits)*count,
 
7014
                                      MYF(MY_WME))))
6816
7015
    return 0;
6817
7016
  sets->bit_buffer=bit_buffer;
6818
7017
  for (i=0 ; i < count ; i++)
6833
7032
 
6834
7033
void free_sets(REP_SETS *sets)
6835
7034
{
6836
 
  free(sets->set_buffer);
6837
 
  free(sets->bit_buffer);
 
7035
  my_free(sets->set_buffer,MYF(0));
 
7036
  my_free(sets->bit_buffer,MYF(0));
6838
7037
  return;
6839
7038
}
6840
7039
 
6861
7060
 
6862
7061
void copy_bits(REP_SET *to,REP_SET *from)
6863
7062
{
6864
 
  memcpy(to->bits,from->bits,
6865
 
         (size_t) (sizeof(uint) * to->size_of_bits));
 
7063
  memcpy((uchar*) to->bits,(uchar*) from->bits,
 
7064
         (size_t) (sizeof(uint) * to->size_of_bits));
6866
7065
}
6867
7066
 
6868
7067
int cmp_bits(REP_SET *set1,REP_SET *set2)
6869
7068
{
6870
 
  return memcmp(set1->bits,set2->bits, sizeof(uint) * set1->size_of_bits);
 
7069
  return bcmp((uchar*) set1->bits,(uchar*) set2->bits,
 
7070
              sizeof(uint) * set1->size_of_bits);
6871
7071
}
6872
7072
 
6873
7073
 
6909
7109
      return i;
6910
7110
    }
6911
7111
  }
6912
 
  return i;        /* return new postion */
 
7112
  return i;                             /* return new postion */
6913
7113
}
6914
7114
 
6915
7115
/* find if there is a found_set with same table_offset & found_offset
6924
7124
  int i;
6925
7125
  for (i=0 ; (uint) i < found_sets ; i++)
6926
7126
    if (found_set[i].table_offset == table_offset &&
6927
 
        found_set[i].found_offset == found_offset)
 
7127
        found_set[i].found_offset == found_offset)
6928
7128
      return -i-2;
6929
7129
  found_set[i].table_offset=table_offset;
6930
7130
  found_set[i].found_offset=found_offset;
6931
7131
  found_sets++;
6932
 
  return -i-2;        /* return new postion */
 
7132
  return -i-2;                          /* return new postion */
6933
7133
}
6934
7134
 
6935
7135
/* Return 1 if regexp starts with \b or ends with \b*/
6936
7136
 
6937
7137
uint start_at_word(char * pos)
6938
7138
{
6939
 
  return (((!memcmp(pos, "\\b",2) && pos[2]) ||
6940
 
           !memcmp(pos, "\\^", 2)) ? 1 : 0);
 
7139
  return (((!bcmp((const uchar*) pos, (const uchar*) "\\b",2) && pos[2]) ||
 
7140
           !bcmp((const uchar*) pos, (const uchar*) "\\^", 2)) ? 1 : 0);
6941
7141
}
6942
7142
 
6943
7143
uint end_of_word(char * pos)
6944
7144
{
6945
 
  char * end= strchr(pos, '\0');
6946
 
  return ((end > pos+2 && !memcmp(end-2, "\\b", 2)) ||
6947
 
          (end >= pos+2 && !memcmp(end-2, "\\$",2))) ? 1 : 0;
 
7145
  char * end=strend(pos);
 
7146
  return ((end > pos+2 && !bcmp((const uchar*) end-2,
 
7147
                                (const uchar*) "\\b", 2)) ||
 
7148
          (end >= pos+2 && !bcmp((const uchar*) end-2,
 
7149
                                (const uchar*) "\\$",2))) ? 1 : 0;
6948
7150
}
6949
7151
 
6950
7152
/****************************************************************************
6951
7153
 * Handle replacement of strings
6952
7154
 ****************************************************************************/
6953
7155
 
6954
 
#define PC_MALLOC    256  /* Bytes for pointers */
6955
 
#define PS_MALLOC    512  /* Bytes for data */
 
7156
#define PC_MALLOC               256     /* Bytes for pointers */
 
7157
#define PS_MALLOC               512     /* Bytes for data */
6956
7158
 
6957
7159
int insert_pointer_name(POINTER_ARRAY *pa,char * name)
6958
7160
{
6959
7161
  uint i,length,old_count;
6960
 
  unsigned char *new_pos;
 
7162
  uchar *new_pos;
6961
7163
  const char **new_array;
6962
7164
 
6963
7165
 
6964
7166
  if (! pa->typelib.count)
6965
7167
  {
6966
7168
    if (!(pa->typelib.type_names=(const char **)
6967
 
          my_malloc(((PC_MALLOC-MALLOC_OVERHEAD)/
6968
 
                     (sizeof(char *)+sizeof(*pa->flag))*
6969
 
                     (sizeof(char *)+sizeof(*pa->flag))),MYF(MY_WME))))
 
7169
          my_malloc(((PC_MALLOC-MALLOC_OVERHEAD)/
 
7170
                     (sizeof(char *)+sizeof(*pa->flag))*
 
7171
                     (sizeof(char *)+sizeof(*pa->flag))),MYF(MY_WME))))
6970
7172
      return(-1);
6971
 
    if (!(pa->str= (unsigned char*) my_malloc((uint) (PS_MALLOC-MALLOC_OVERHEAD),
6972
 
                                      MYF(MY_WME))))
 
7173
    if (!(pa->str= (uchar*) my_malloc((uint) (PS_MALLOC-MALLOC_OVERHEAD),
 
7174
                                     MYF(MY_WME))))
6973
7175
    {
6974
 
      free((char*) pa->typelib.type_names);
 
7176
      my_free((char*) pa->typelib.type_names,MYF(0));
6975
7177
      return (-1);
6976
7178
    }
6977
 
    pa->max_count=(PC_MALLOC-MALLOC_OVERHEAD)/(sizeof(unsigned char*)+
6978
 
                                               sizeof(*pa->flag));
6979
 
    pa->flag= (uint8_t*) (pa->typelib.type_names+pa->max_count);
 
7179
    pa->max_count=(PC_MALLOC-MALLOC_OVERHEAD)/(sizeof(uchar*)+
 
7180
                                               sizeof(*pa->flag));
 
7181
    pa->flag= (int7*) (pa->typelib.type_names+pa->max_count);
6980
7182
    pa->length=0;
6981
7183
    pa->max_length=PS_MALLOC-MALLOC_OVERHEAD;
6982
7184
    pa->array_allocs=1;
6984
7186
  length=(uint) strlen(name)+1;
6985
7187
  if (pa->length+length >= pa->max_length)
6986
7188
  {
6987
 
    if (!(new_pos= (unsigned char*) my_realloc((unsigned char*) pa->str,
6988
 
                                       (uint) (pa->max_length+PS_MALLOC),
6989
 
                                       MYF(MY_WME))))
 
7189
    if (!(new_pos= (uchar*) my_realloc((uchar*) pa->str,
 
7190
                                      (uint) (pa->max_length+PS_MALLOC),
 
7191
                                      MYF(MY_WME))))
6990
7192
      return(1);
6991
7193
    if (new_pos != pa->str)
6992
7194
    {
6993
7195
      my_ptrdiff_t diff=PTR_BYTE_DIFF(new_pos,pa->str);
6994
7196
      for (i=0 ; i < pa->typelib.count ; i++)
6995
 
        pa->typelib.type_names[i]= ADD_TO_PTR(pa->typelib.type_names[i],diff,
6996
 
                                              char*);
 
7197
        pa->typelib.type_names[i]= ADD_TO_PTR(pa->typelib.type_names[i],diff,
 
7198
                                              char*);
6997
7199
      pa->str=new_pos;
6998
7200
    }
6999
7201
    pa->max_length+=PS_MALLOC;
7003
7205
    int len;
7004
7206
    pa->array_allocs++;
7005
7207
    len=(PC_MALLOC*pa->array_allocs - MALLOC_OVERHEAD);
7006
 
    if (!(new_array=(const char **) my_realloc((unsigned char*) pa->typelib.type_names,
7007
 
                                               (uint) len/
7008
 
                                               (sizeof(unsigned char*)+sizeof(*pa->flag))*
7009
 
                                               (sizeof(unsigned char*)+sizeof(*pa->flag)),
 
7208
    if (!(new_array=(const char **) my_realloc((uchar*) pa->typelib.type_names,
 
7209
                                               (uint) len/
 
7210
                                               (sizeof(uchar*)+sizeof(*pa->flag))*
 
7211
                                               (sizeof(uchar*)+sizeof(*pa->flag)),
7010
7212
                                               MYF(MY_WME))))
7011
7213
      return(1);
7012
7214
    pa->typelib.type_names=new_array;
7013
7215
    old_count=pa->max_count;
7014
 
    pa->max_count=len/(sizeof(unsigned char*) + sizeof(*pa->flag));
7015
 
    pa->flag= (uint8_t*) (pa->typelib.type_names+pa->max_count);
7016
 
    memcpy(pa->flag, pa->typelib.type_names+old_count,
7017
 
           old_count*sizeof(*pa->flag));
 
7216
    pa->max_count=len/(sizeof(uchar*) + sizeof(*pa->flag));
 
7217
    pa->flag= (int7*) (pa->typelib.type_names+pa->max_count);
 
7218
    memcpy((uchar*) pa->flag,(char *) (pa->typelib.type_names+old_count),
 
7219
           old_count*sizeof(*pa->flag));
7018
7220
  }
7019
 
  pa->flag[pa->typelib.count]=0;      /* Reset flag */
 
7221
  pa->flag[pa->typelib.count]=0;                        /* Reset flag */
7020
7222
  pa->typelib.type_names[pa->typelib.count++]= (char*) pa->str+pa->length;
7021
 
  pa->typelib.type_names[pa->typelib.count]= NULL;  /* Put end-mark */
7022
 
  my_stpcpy((char*) pa->str+pa->length,name);
 
7223
  pa->typelib.type_names[pa->typelib.count]= NullS;     /* Put end-mark */
 
7224
  VOID(strmov((char*) pa->str+pa->length,name));
7023
7225
  pa->length+=length;
7024
7226
  return(0);
7025
7227
} /* insert_pointer_name */
7032
7234
  if (pa->typelib.count)
7033
7235
  {
7034
7236
    pa->typelib.count=0;
7035
 
    free((char*) pa->typelib.type_names);
 
7237
    my_free((char*) pa->typelib.type_names,MYF(0));
7036
7238
    pa->typelib.type_names=0;
7037
 
    free(pa->str);
 
7239
    my_free(pa->str,MYF(0));
7038
7240
  }
7039
7241
} /* free_pointer_array */
7040
7242
 
7042
7244
/* Functions that uses replace and replace_regex */
7043
7245
 
7044
7246
/* Append the string to ds, with optional replace */
7045
 
void replace_append_mem(string *ds,
7046
 
                        const char *val, int len)
 
7247
void replace_dynstr_append_mem(DYNAMIC_STRING *ds,
 
7248
                               const char *val, int len)
7047
7249
{
7048
 
  char *v= strdup(val);
7049
 
 
7050
7250
  if (glob_replace_regex)
7051
7251
  {
7052
7252
    /* Regex replace */
7053
 
    if (!multi_reg_replace(glob_replace_regex, v))
 
7253
    if (!multi_reg_replace(glob_replace_regex, (char*)val))
7054
7254
    {
7055
 
      v= glob_replace_regex->buf;
7056
 
      len= strlen(v);
 
7255
      val= glob_replace_regex->buf;
 
7256
      len= strlen(val);
7057
7257
    }
7058
7258
  }
7059
7259
 
7060
7260
  if (glob_replace)
7061
7261
  {
7062
7262
    /* Normal replace */
7063
 
    replace_strings_append(glob_replace, ds, v, len);
 
7263
    replace_strings_append(glob_replace, ds, val, len);
7064
7264
  }
7065
7265
  else
7066
 
  {
7067
 
    ds->append(v, len);
7068
 
  }
 
7266
    dynstr_append_mem(ds, val, len);
7069
7267
}
7070
7268
 
7071
7269
 
7072
7270
/* Append zero-terminated string to ds, with optional replace */
7073
 
void replace_append(string *ds, const char *val)
 
7271
void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val)
7074
7272
{
7075
 
  replace_append_mem(ds, val, strlen(val));
 
7273
  replace_dynstr_append_mem(ds, val, strlen(val));
7076
7274
}
7077
7275
 
7078
7276
/* Append uint to ds, with optional replace */
7079
 
void replace_append_uint(string *ds, uint val)
 
7277
void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val)
7080
7278
{
7081
7279
  char buff[22]; /* This should be enough for any int */
7082
7280
  char *end= int64_t10_to_str(val, buff, 10);
7083
 
  replace_append_mem(ds, buff, end - buff);
7084
 
 
 
7281
  replace_dynstr_append_mem(ds, buff, end - buff);
7085
7282
}
7086
7283
 
7087
7284
 
7098
7295
 
7099
7296
*/
7100
7297
 
7101
 
 
7102
 
void append_sorted(string* ds, string *ds_input)
7103
 
{
7104
 
  priority_queue<string> lines;
7105
 
 
7106
 
  if (ds_input->empty())
 
7298
static int comp_lines(const char **a, const char **b)
 
7299
{
 
7300
  return (strcmp(*a,*b));
 
7301
}
 
7302
 
 
7303
void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input)
 
7304
{
 
7305
  unsigned i;
 
7306
  char *start= ds_input->str;
 
7307
  DYNAMIC_ARRAY lines;
 
7308
 
 
7309
 
 
7310
  if (!*start)
7107
7311
    return;  /* No input */
7108
7312
 
7109
 
  unsigned long eol_pos= 0;
7110
 
 
7111
 
  eol_pos= ds_input->find_first_of('\n', 0);
7112
 
  if (eol_pos == string::npos)
7113
 
    return; // We should have at least one header here
7114
 
 
7115
 
  ds->append(ds_input->substr(0, eol_pos));
7116
 
 
7117
 
  unsigned long start_pos= eol_pos+1;
 
7313
  my_init_dynamic_array(&lines, sizeof(const char*), 32, 32);
 
7314
 
 
7315
  /* First line is result header, skip past it */
 
7316
  while (*start && *start != '\n')
 
7317
    start++;
 
7318
  start++; /* Skip past \n */
 
7319
  dynstr_append_mem(ds, ds_input->str, start - ds_input->str);
7118
7320
 
7119
7321
  /* Insert line(s) in array */
7120
 
  do {
 
7322
  while (*start)
 
7323
  {
 
7324
    char* line_end= (char*)start;
7121
7325
 
7122
 
    eol_pos= ds_input->find_first_of('\n', start_pos);
7123
7326
    /* Find end of line */
7124
 
    lines.push(ds_input->substr(start_pos, eol_pos-start_pos));
7125
 
    start_pos= eol_pos+1;
7126
 
 
7127
 
  } while ( eol_pos != string::npos);
 
7327
    while (*line_end && *line_end != '\n')
 
7328
      line_end++;
 
7329
    *line_end= 0;
 
7330
 
 
7331
    /* Insert pointer to the line in array */
 
7332
    if (insert_dynamic(&lines, (uchar*) &start))
 
7333
      die("Out of memory inserting lines to sort");
 
7334
 
 
7335
    start= line_end+1;
 
7336
  }
 
7337
 
 
7338
  /* Sort array */
 
7339
  qsort(lines.buffer, lines.elements,
 
7340
        sizeof(char**), (qsort_cmp)comp_lines);
7128
7341
 
7129
7342
  /* Create new result */
7130
 
  while (!lines.empty()) {
7131
 
    ds->append(lines.top());
7132
 
    lines.pop();
 
7343
  for (i= 0; i < lines.elements ; i++)
 
7344
  {
 
7345
    const char **line= dynamic_element(&lines, i, const char**);
 
7346
    dynstr_append(ds, *line);
 
7347
    dynstr_append(ds, "\n");
7133
7348
  }
7134
7349
 
 
7350
  delete_dynamic(&lines);
7135
7351
  return;
7136
7352
}