~mdcallag/+junk/5.1-map

« back to all changes in this revision

Viewing changes to client/mysqltest.c

  • Committer: msvensson at pilot
  • Date: 2007-04-24 09:11:45 UTC
  • mfrom: (2469.1.106)
  • Revision ID: sp1r-msvensson@pilot.blaudden-20070424091145-10463
Merge pilot.blaudden:/home/msvensson/mysql/my51-m-mysql_upgrade
into  pilot.blaudden:/home/msvensson/mysql/mysql-5.1-maint

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
 
34
34
#define MTEST_VERSION "3.2"
35
35
 
36
 
#include <my_global.h>
37
 
#include <mysql_embed.h>
38
 
#include <my_sys.h>
39
 
#include <m_string.h>
40
 
#include <mysql.h>
 
36
#include "client_priv.h"
41
37
#include <mysql_version.h>
42
38
#include <mysqld_error.h>
43
 
#include <errmsg.h>
44
39
#include <m_ctype.h>
45
40
#include <my_dir.h>
46
41
#include <hash.h>
47
 
#include <my_getopt.h>
48
42
#include <stdarg.h>
49
43
#include <violite.h>
50
44
#include "my_regex.h" /* Our own version of regex */
52
46
#include <sys/wait.h>
53
47
#endif
54
48
 
55
 
#ifndef WEXITSTATUS
56
 
# ifdef __WIN__
57
 
#  define WEXITSTATUS(stat_val) (stat_val)
58
 
# else
59
 
#  define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
60
 
# endif
61
 
#endif
62
 
 
63
49
/* Use cygwin for --exec and --system before 5.0 */
64
50
#if MYSQL_VERSION_ID < 50000
65
51
#define USE_CYGWIN
81
67
 };
82
68
 
83
69
enum {
84
 
  OPT_SKIP_SAFEMALLOC=256, OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT,
85
 
  OPT_SSL_CA, OPT_SSL_CAPATH, OPT_SSL_CIPHER, OPT_PS_PROTOCOL,
86
 
  OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL,
87
 
  OPT_SSL_VERIFY_SERVER_CERT, OPT_MAX_CONNECT_RETRIES,
88
 
  OPT_MARK_PROGRESS, OPT_CHARSETS_DIR, OPT_LOG_DIR, OPT_DEBUG_INFO
 
70
  OPT_SKIP_SAFEMALLOC=OPT_MAX_CLIENT_OPTION,
 
71
  OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL,
 
72
  OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR
89
73
};
90
74
 
91
75
static int record= 0, opt_sleep= -1;
103
87
static my_bool view_protocol= 0, view_protocol_enabled= 0;
104
88
static my_bool cursor_protocol= 0, cursor_protocol_enabled= 0;
105
89
static my_bool parsing_disabled= 0;
106
 
static my_bool info_flag;
107
 
static my_bool display_result_vertically= FALSE, display_metadata= FALSE;
 
90
static my_bool display_result_vertically= FALSE,
 
91
  display_metadata= FALSE, display_result_sorted= FALSE;
108
92
static my_bool disable_query_log= 0, disable_result_log= 0;
109
 
static my_bool disable_warnings= 0, disable_ps_warnings= 0;
 
93
static my_bool disable_warnings= 0;
110
94
static my_bool disable_info= 1;
111
95
static my_bool abort_on_error= 1;
112
96
static my_bool server_initialized= 0;
266
250
  Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG,
267
251
  Q_WAIT_FOR_SLAVE_TO_STOP,
268
252
  Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS,
269
 
  Q_ENABLE_PS_WARNINGS, Q_DISABLE_PS_WARNINGS,
270
253
  Q_ENABLE_INFO, Q_DISABLE_INFO,
271
254
  Q_ENABLE_METADATA, Q_DISABLE_METADATA,
272
255
  Q_EXEC, Q_DELIMITER,
273
256
  Q_DISABLE_ABORT_ON_ERROR, Q_ENABLE_ABORT_ON_ERROR,
274
257
  Q_DISPLAY_VERTICAL_RESULTS, Q_DISPLAY_HORIZONTAL_RESULTS,
275
 
  Q_QUERY_VERTICAL, Q_QUERY_HORIZONTAL,
 
258
  Q_QUERY_VERTICAL, Q_QUERY_HORIZONTAL, Q_QUERY_SORTED,
276
259
  Q_START_TIMER, Q_END_TIMER,
277
260
  Q_CHARACTER_SET, Q_DISABLE_PS_PROTOCOL, Q_ENABLE_PS_PROTOCOL,
278
261
  Q_DISABLE_RECONNECT, Q_ENABLE_RECONNECT,
279
262
  Q_IF,
280
263
  Q_DISABLE_PARSING, Q_ENABLE_PARSING,
281
264
  Q_REPLACE_REGEX, Q_REMOVE_FILE, Q_FILE_EXIST,
282
 
  Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT,
 
265
  Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT, Q_SKIP,
283
266
  Q_CHMOD_FILE, Q_APPEND_FILE, Q_CAT_FILE, Q_DIFF_FILES,
284
267
 
285
268
  Q_UNKNOWN,                           /* Unknown command.   */
330
313
  "wait_for_slave_to_stop",
331
314
  "enable_warnings",
332
315
  "disable_warnings",
333
 
  "enable_ps_warnings",
334
 
  "disable_ps_warnings",
335
316
  "enable_info",
336
317
  "disable_info",
337
318
  "enable_metadata",
344
325
  "horizontal_results",
345
326
  "query_vertical",
346
327
  "query_horizontal",
 
328
  "query_sorted",
347
329
  "start_timer",
348
330
  "end_timer",
349
331
  "character_set",
361
343
  "copy_file",
362
344
  "perl",
363
345
  "die",
 
346
               
364
347
  /* Don't execute any more commands, compare result */
365
348
  "exit",
 
349
  "skip",
366
350
  "chmod",
367
351
  "append_file",
368
352
  "cat_file",
415
399
TYPELIB command_typelib= {array_elements(command_names),"",
416
400
                          command_names, 0};
417
401
 
418
 
static DYNAMIC_STRING ds_res, ds_progress, ds_warning_messages;
419
 
static DYNAMIC_STRING global_ds_warnings, global_eval_query;
 
402
DYNAMIC_STRING ds_res, ds_progress, ds_warning_messages;
420
403
 
421
404
char builtin_echo[FN_REFLEN];
422
405
 
423
 
 
424
406
void die(const char *fmt, ...)
425
407
  ATTRIBUTE_FORMAT(printf, 1, 2);
426
408
void abort_not_supported_test(const char *fmt, ...)
490
472
                               int len);
491
473
void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val);
492
474
void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val);
 
475
void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING* ds_input);
493
476
 
494
477
void handle_error(struct st_command*,
495
478
                  unsigned int err_errno, const char *err_error,
797
780
  dynstr_free(&ds_res);
798
781
  dynstr_free(&ds_progress);
799
782
  dynstr_free(&ds_warning_messages);
800
 
  dynstr_free(&global_ds_warnings);
801
 
  dynstr_free(&global_eval_query);
802
 
 
803
783
  free_all_replace();
804
784
  my_free(opt_pass,MYF(MY_ALLOW_ZERO_PTR));
805
785
  free_defaults(default_argv);
818
798
}
819
799
 
820
800
 
 
801
static void cleanup_and_exit(int exit_code)
 
802
{
 
803
  free_used_memory();
 
804
  my_end(MY_CHECK_ERROR);
 
805
 
 
806
  if (!silent)
 
807
  {
 
808
    switch (exit_code)
 
809
    {
 
810
    case 1:
 
811
      printf("not ok\n");
 
812
      break;
 
813
    case 0:
 
814
      printf("ok\n");
 
815
      break;
 
816
    case 62:
 
817
      printf("skipped\n");
 
818
    break;
 
819
    default:
 
820
      printf("unknown exit code: %d\n", exit_code);
 
821
      DBUG_ASSERT(0);
 
822
    }
 
823
  }
 
824
 
 
825
  exit(exit_code);
 
826
}
 
827
 
821
828
void die(const char *fmt, ...)
822
829
{
 
830
  static int dying= 0;
823
831
  va_list args;
824
832
  DBUG_ENTER("die");
825
833
  DBUG_PRINT("enter", ("start_lineno: %d", start_lineno));
826
834
 
 
835
  /*
 
836
    Protect against dying twice
 
837
    first time 'die' is called, try to write log files
 
838
    second time, just exit
 
839
  */
 
840
  if (dying)
 
841
    cleanup_and_exit(1);
 
842
  dying= 1;
 
843
 
827
844
  /* Print the error message */
828
 
  va_start(args, fmt);
 
845
  fprintf(stderr, "mysqltest: ");
 
846
  if (cur_file && cur_file != file_stack)
 
847
    fprintf(stderr, "In included file \"%s\": ",
 
848
            cur_file->file_name);
 
849
  if (start_lineno > 0)
 
850
    fprintf(stderr, "At line %u: ", start_lineno);
829
851
  if (fmt)
830
852
  {
831
 
    fprintf(stderr, "mysqltest: ");
832
 
    if (cur_file && cur_file != file_stack)
833
 
      fprintf(stderr, "In included file \"%s\": ",
834
 
              cur_file->file_name);
835
 
    if (start_lineno > 0)
836
 
      fprintf(stderr, "At line %u: ", start_lineno);
 
853
    va_start(args, fmt);
837
854
    vfprintf(stderr, fmt, args);
838
 
    fprintf(stderr, "\n");
839
 
    fflush(stderr);
 
855
    va_end(args);
840
856
  }
841
 
  va_end(args);
 
857
  else
 
858
    fprintf(stderr, "unknown error");
 
859
  fprintf(stderr, "\n");
 
860
  fflush(stderr);
842
861
 
843
862
  /* Dump the result that has been accumulated so far to .log file */
844
863
  if (result_file_name && ds_res.length)
848
867
  if (result_file_name && ds_warning_messages.length)
849
868
    dump_warning_messages();
850
869
 
851
 
  /* Clean up and exit */
852
 
  free_used_memory();
853
 
  my_end(info_flag ? MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR);
854
 
 
855
 
  if (!silent)
856
 
    printf("not ok\n");
857
 
 
858
 
  exit(1);
 
870
  cleanup_and_exit(1);
859
871
}
860
872
 
861
873
 
888
900
  }
889
901
  va_end(args);
890
902
 
891
 
  /* Clean up and exit */
892
 
  free_used_memory();
893
 
  my_end(info_flag ? MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR);
894
 
 
895
 
  if (!silent)
896
 
    printf("skipped\n");
897
 
 
898
 
  exit(62);
 
903
  cleanup_and_exit(62);
899
904
}
900
905
 
901
906
 
1308
1313
  DBUG_VOID_RETURN;
1309
1314
}
1310
1315
 
 
1316
 
 
1317
void var_set_string(const char* name, const char* value)
 
1318
{
 
1319
  var_set(name, name + strlen(name), value, value + strlen(value));
 
1320
}
 
1321
 
 
1322
 
 
1323
void var_set_int(const char* name, int value)
 
1324
{
 
1325
  char buf[21];
 
1326
  my_snprintf(buf, sizeof(buf), "%d", value);
 
1327
  var_set_string(name, buf);
 
1328
}
 
1329
 
 
1330
 
1311
1331
/*
1312
1332
  Store an integer (typically the returncode of the last SQL)
1313
 
  statement in the mysqltest builtin variable $mysql_errno, by
1314
 
  simulating of a user statement "let $mysql_errno= <integer>"
 
1333
  statement in the mysqltest builtin variable $mysql_errno
1315
1334
*/
1316
1335
 
1317
1336
void var_set_errno(int sql_errno)
1318
1337
{
1319
 
  /* TODO MASV make easier */
1320
 
  const char *var_name= "$mysql_errno";
1321
 
  char var_val[21];
1322
 
  uint length= my_sprintf(var_val, (var_val, "%d", sql_errno));
1323
 
  var_set(var_name, var_name + 12, var_val, var_val + length);
1324
 
  return;
 
1338
  var_set_int("$mysql_errno", sql_errno);
1325
1339
}
1326
1340
 
1327
 
 
1328
1341
/*
1329
1342
  Set variable from the result of a query
1330
1343
 
1355
1368
  MYSQL_RES *res;
1356
1369
  MYSQL_ROW row;
1357
1370
  MYSQL* mysql = &cur_con->mysql;
 
1371
  DYNAMIC_STRING ds_query;
1358
1372
  DBUG_ENTER("var_query_set");
1359
1373
  LINT_INIT(res);
1360
1374
 
1364
1378
    die("Syntax error in query, missing '`'");
1365
1379
  ++query;
1366
1380
 
1367
 
  if (mysql_real_query(mysql, query, (int)(end - query)) ||
 
1381
  /* Eval the query, thus replacing all environment variables */
 
1382
  init_dynamic_string(&ds_query, 0, (end - query) + 32, 256);
 
1383
  do_eval(&ds_query, query, end, FALSE);
 
1384
 
 
1385
  if (mysql_real_query(mysql, ds_query.str, ds_query.length) ||
1368
1386
      !(res = mysql_store_result(mysql)))
1369
1387
  {
1370
 
    *end = 0;
1371
 
    die("Error running query '%s': %d %s", query,
 
1388
    die("Error running query '%s': %d %s", ds_query.str,
1372
1389
        mysql_errno(mysql), mysql_error(mysql));
1373
1390
  }
 
1391
  dynstr_free(&ds_query);
1374
1392
 
1375
1393
  if ((row = mysql_fetch_row(res)) && row[0])
1376
1394
  {
2501
2519
  if (!(res= mysql_store_result(mysql)))
2502
2520
    die("mysql_store_result() returned NULL for '%s'", query_buf);
2503
2521
  if (!(row= mysql_fetch_row(res)))
 
2522
  {
 
2523
    mysql_free_result(res);
2504
2524
    die("empty result in %s", query_buf);
 
2525
  }
2505
2526
  if (!row[0])
2506
2527
  {
2507
2528
    /*
2508
2529
      It may be that the slave SQL thread has not started yet, though START
2509
2530
      SLAVE has been issued ?
2510
2531
    */
 
2532
    mysql_free_result(res);
2511
2533
    if (tries++ == 30)
2512
2534
      die("could not sync with master ('%s' returned NULL)", query_buf);
2513
2535
    sleep(1); /* So at most we will wait 30 seconds and make 31 tries */
2514
 
    mysql_free_result(res);
2515
2536
    goto wait_for_position;
2516
2537
  }
2517
2538
  mysql_free_result(res);
2552
2573
  MYSQL *mysql = &cur_con->mysql;
2553
2574
  const char *query;
2554
2575
  int rpl_parse;
 
2576
  DBUG_ENTER("do_save_master_pos");
2555
2577
 
2556
2578
  rpl_parse = mysql_rpl_parse_enabled(mysql);
2557
2579
  mysql_disable_rpl_parse(mysql);
2576
2598
 
2577
2599
    if (have_ndbcluster)
2578
2600
    {
2579
 
      ulonglong start_epoch= 0, applied_epoch= 0,
 
2601
      ulonglong start_epoch= 0, handled_epoch= 0,
2580
2602
        latest_epoch=0, latest_trans_epoch=0,
2581
2603
        latest_handled_binlog_epoch= 0, latest_received_binlog_epoch= 0,
2582
2604
        latest_applied_binlog_epoch= 0;
2679
2701
        if (!row)
2680
2702
          die("result does not contain '%s' in '%s'",
2681
2703
              binlog, query);
2682
 
        if (latest_applied_binlog_epoch > applied_epoch)
 
2704
        if (latest_handled_binlog_epoch > handled_epoch)
2683
2705
          count= 0;
2684
 
        applied_epoch= latest_applied_binlog_epoch;
 
2706
        handled_epoch= latest_handled_binlog_epoch;
2685
2707
        count++;
2686
2708
        if (latest_handled_binlog_epoch >= start_epoch)
2687
2709
          do_continue= 0;
2709
2731
  if (rpl_parse)
2710
2732
    mysql_enable_rpl_parse(mysql);
2711
2733
 
2712
 
  return 0;
 
2734
  DBUG_RETURN(0);
2713
2735
}
2714
2736
 
2715
2737
 
3164
3186
 
3165
3187
int select_connection_name(const char *name)
3166
3188
{
3167
 
  DBUG_ENTER("select_connection2");
 
3189
  DBUG_ENTER("select_connection_name");
3168
3190
  DBUG_PRINT("enter",("name: '%s'", name));
3169
3191
 
3170
3192
  if (!(cur_con= find_connection_by_name(name)))
3187
3209
  if (*p)
3188
3210
    *p++= 0;
3189
3211
  command->last_argument= p;
3190
 
  return select_connection_name(name);
 
3212
  DBUG_RETURN(select_connection_name(name));
3191
3213
}
3192
3214
 
3193
3215
 
3543
3565
                  opt_ssl_capath, opt_ssl_cipher);
3544
3566
#if MYSQL_VERSION_ID >= 50000
3545
3567
    /* Turn on ssl_verify_server_cert only if host is "localhost" */
3546
 
    opt_ssl_verify_server_cert= !strcmp(ds_connection_name.str, "localhost");
 
3568
    opt_ssl_verify_server_cert= !strcmp(ds_host.str, "localhost");
3547
3569
    mysql_options(&next_con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
3548
3570
                  &opt_ssl_verify_server_cert);
3549
3571
#endif
4235
4257
  {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",
4236
4258
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
4237
4259
#endif
4238
 
  {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", (gptr*) &info_flag,
4239
 
   (gptr*) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4240
4260
  {"host", 'h', "Connect to host.", (gptr*) &opt_host, (gptr*) &opt_host, 0,
4241
4261
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4242
4262
  {"include", 'i', "Include SQL before each test case.", (gptr*) &opt_include,
4244
4264
  {"logdir", OPT_LOG_DIR, "Directory for log files", (gptr*) &opt_logdir,
4245
4265
   (gptr*) &opt_logdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4246
4266
  {"mark-progress", OPT_MARK_PROGRESS,
4247
 
   "Write linenumber and elapsed time to <testname>.progress",
 
4267
   "Write linenumber and elapsed time to <testname>.progress ",
4248
4268
   (gptr*) &opt_mark_progress, (gptr*) &opt_mark_progress, 0,
4249
4269
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4250
4270
  {"max-connect-retries", OPT_MAX_CONNECT_RETRIES,
4546
4566
{
4547
4567
  char log_file[FN_REFLEN];
4548
4568
  str_to_file(fn_format(log_file, result_file_name, opt_logdir, ".log",
4549
 
                        *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT:
 
4569
                        *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
4550
4570
                        MY_REPLACE_EXT),
4551
4571
              buf, size);
4552
4572
}
4553
4573
 
4554
4574
void dump_progress(void)
4555
4575
{
4556
 
  char log_file[FN_REFLEN];
4557
 
  str_to_file(fn_format(log_file, result_file_name, opt_logdir, ".progress",
4558
 
                        *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT:
4559
 
                          MY_REPLACE_EXT),
 
4576
  char progress_file[FN_REFLEN];
 
4577
  str_to_file(fn_format(progress_file, result_file_name,
 
4578
                        opt_logdir, ".progress",
 
4579
                        *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
 
4580
                        MY_REPLACE_EXT),
4560
4581
              ds_progress.str, ds_progress.length);
4561
4582
}
4562
4583
 
4564
4585
{
4565
4586
  char warn_file[FN_REFLEN];
4566
4587
 
4567
 
  str_to_file(fn_format(warn_file, result_file_name, "", ".warnings",
 
4588
  str_to_file(fn_format(warn_file, result_file_name, opt_logdir, ".warnings",
 
4589
                        *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
4568
4590
                        MY_REPLACE_EXT),
4569
4591
              ds_warning_messages.str, ds_warning_messages.length);
4570
4592
}
5517
5539
{
5518
5540
  MYSQL *mysql= &cn->mysql;
5519
5541
  DYNAMIC_STRING *ds;
 
5542
  DYNAMIC_STRING *save_ds= NULL;
5520
5543
  DYNAMIC_STRING ds_result;
 
5544
  DYNAMIC_STRING ds_sorted;
 
5545
  DYNAMIC_STRING ds_warnings;
 
5546
  DYNAMIC_STRING eval_query;
5521
5547
  char *query;
5522
5548
  int query_len;
5523
5549
  my_bool view_created= 0, sp_created= 0;
5525
5551
                           (flags & QUERY_REAP_FLAG));
5526
5552
  DBUG_ENTER("run_query");
5527
5553
 
5528
 
  init_dynamic_string(&global_ds_warnings, NULL, 0, 256);
 
5554
  init_dynamic_string(&ds_warnings, NULL, 0, 256);
5529
5555
 
5530
5556
  /* Scan for warning before sendign to server */
5531
5557
  scan_command_for_warnings(command);
5535
5561
  */
5536
5562
  if (command->type == Q_EVAL)
5537
5563
  {
5538
 
    init_dynamic_string(&global_eval_query, "", command->query_len+256, 1024);
5539
 
    do_eval(&global_eval_query, command->query, command->end, FALSE);
5540
 
    query = global_eval_query.str;
5541
 
    query_len = global_eval_query.length;
 
5564
    init_dynamic_string(&eval_query, "", command->query_len+256, 1024);
 
5565
    do_eval(&eval_query, command->query, command->end, FALSE);
 
5566
    query = eval_query.str;
 
5567
    query_len = eval_query.length;
5542
5568
  }
5543
5569
  else
5544
5570
  {
5610
5636
        Collect warnings from create of the view that should otherwise
5611
5637
        have been produced when the SELECT was executed
5612
5638
      */
5613
 
      append_warnings(&global_ds_warnings, cur_con->util_mysql);
 
5639
      append_warnings(&ds_warnings, cur_con->util_mysql);
5614
5640
    }
5615
5641
 
5616
5642
    dynstr_free(&query_str);
5657
5683
    dynstr_free(&query_str);
5658
5684
  }
5659
5685
 
 
5686
  if (display_result_sorted)
 
5687
  {
 
5688
    /*
 
5689
       Collect the query output in a separate string
 
5690
       that can be sorted before it's added to the
 
5691
       global result string
 
5692
    */
 
5693
    init_dynamic_string(&ds_sorted, "", 1024, 1024);
 
5694
    save_ds= ds; /* Remember original ds */
 
5695
    ds= &ds_sorted;
 
5696
  }
 
5697
 
5660
5698
  /*
5661
5699
    Find out how to run this query
5662
5700
 
5669
5707
  if (ps_protocol_enabled &&
5670
5708
      complete_query &&
5671
5709
      match_re(&ps_re, query))
5672
 
    run_query_stmt(mysql, command, query, query_len, ds, &global_ds_warnings);
 
5710
    run_query_stmt(mysql, command, query, query_len, ds, &ds_warnings);
5673
5711
  else
5674
5712
    run_query_normal(cn, command, flags, query, query_len,
5675
 
                     ds, &global_ds_warnings);
 
5713
                     ds, &ds_warnings);
 
5714
 
 
5715
  if (display_result_sorted)
 
5716
  {
 
5717
    /* Sort the result set and append it to result */
 
5718
    dynstr_append_sorted(save_ds, &ds_sorted);
 
5719
    ds= save_ds;
 
5720
    dynstr_free(&ds_sorted);
 
5721
  }
5676
5722
 
5677
5723
  if (sp_created)
5678
5724
  {
5696
5742
    check_require(ds, command->require_file);
5697
5743
  }
5698
5744
 
5699
 
  dynstr_free(&global_ds_warnings);
 
5745
  dynstr_free(&ds_warnings);
5700
5746
  if (ds == &ds_result)
5701
5747
    dynstr_free(&ds_result);
5702
5748
  if (command->type == Q_EVAL)
5703
 
    dynstr_free(&global_eval_query);
 
5749
    dynstr_free(&eval_query);
5704
5750
  DBUG_VOID_RETURN;
5705
5751
}
5706
5752
 
5961
6007
                1024, 0, 0, get_var_key, var_free, MYF(0)))
5962
6008
    die("Variable hash initialization failed");
5963
6009
 
 
6010
  var_set_string("$MYSQL_SERVER_VERSION", MYSQL_SERVER_VERSION);
 
6011
 
5964
6012
  memset(&master_pos, 0, sizeof(master_pos));
5965
6013
 
5966
6014
  parser.current_line= parser.read_lines= 0;
6015
6063
 
6016
6064
#ifdef HAVE_OPENSSL
6017
6065
 
6018
 
#if MYSQL_VERSION_ID >= 50000
6019
 
  opt_ssl_verify_server_cert= TRUE; /* Always on in mysqltest */
6020
 
#endif
6021
 
 
6022
6066
  if (opt_use_ssl)
6023
6067
  {
6024
6068
    mysql_ssl_set(&cur_con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
6025
6069
                  opt_ssl_capath, opt_ssl_cipher);
6026
6070
#if MYSQL_VERSION_ID >= 50000
 
6071
    /* Turn on ssl_verify_server_cert only if host is "localhost" */
 
6072
    opt_ssl_verify_server_cert= opt_host && !strcmp(opt_host, "localhost");
6027
6073
    mysql_options(&cur_con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
6028
6074
                  &opt_ssl_verify_server_cert);
6029
6075
#endif
6088
6134
      case Q_DISABLE_RESULT_LOG: disable_result_log=1; break;
6089
6135
      case Q_ENABLE_WARNINGS:    disable_warnings=0; break;
6090
6136
      case Q_DISABLE_WARNINGS:   disable_warnings=1; break;
6091
 
      case Q_ENABLE_PS_WARNINGS:    disable_ps_warnings=0; break;
6092
 
      case Q_DISABLE_PS_WARNINGS:   disable_ps_warnings=1; break;
6093
6137
      case Q_ENABLE_INFO:        disable_info=0; break;
6094
6138
      case Q_DISABLE_INFO:       disable_info=1; break;
6095
6139
      case Q_ENABLE_METADATA:    display_metadata=1; break;
6124
6168
      case Q_EVAL_RESULT:
6125
6169
        eval_result = 1; break;
6126
6170
      case Q_EVAL:
 
6171
      case Q_QUERY_VERTICAL:
 
6172
      case Q_QUERY_HORIZONTAL:
 
6173
      case Q_QUERY_SORTED:
6127
6174
        if (command->query == command->query_buf)
6128
6175
        {
 
6176
          /* Skip the first part of command, i.e query_xxx */
6129
6177
          command->query= command->first_argument;
6130
6178
          command->first_word_len= 0;
6131
6179
        }
6132
6180
        /* fall through */
6133
 
      case Q_QUERY_VERTICAL:
6134
 
      case Q_QUERY_HORIZONTAL:
6135
 
      {
6136
 
        my_bool old_display_result_vertically= display_result_vertically;
6137
 
 
6138
 
        /* Remove "query_*" if this is first iteration */
6139
 
        if (command->query == command->query_buf)
6140
 
          command->query= command->first_argument;
6141
 
 
6142
 
        display_result_vertically= (command->type == Q_QUERY_VERTICAL);
6143
 
        if (save_file[0])
6144
 
        {
6145
 
          strmake(command->require_file, save_file, sizeof(save_file));
6146
 
          save_file[0]= 0;
6147
 
        }
6148
 
        run_query(cur_con, command, QUERY_REAP_FLAG|QUERY_SEND_FLAG);
6149
 
        display_result_vertically= old_display_result_vertically;
6150
 
        command->last_argument= command->end;
6151
 
        command_executed++;
6152
 
        break;
6153
 
      }
6154
6181
      case Q_QUERY:
6155
6182
      case Q_REAP:
6156
6183
      {
6157
 
        int flags;
 
6184
        my_bool old_display_result_vertically= display_result_vertically;
 
6185
        my_bool old_display_result_sorted= display_result_sorted;
 
6186
        /* Default is full query, both reap and send  */
 
6187
        int flags= QUERY_REAP_FLAG | QUERY_SEND_FLAG;
 
6188
 
6158
6189
        if (q_send_flag)
6159
6190
        {
6160
6191
          /* Last command was an empty 'send' */
6165
6196
        {
6166
6197
          flags= QUERY_REAP_FLAG;
6167
6198
        }
6168
 
        else
6169
 
        {
6170
 
          /* full query, both reap and send  */
6171
 
          flags= QUERY_REAP_FLAG | QUERY_SEND_FLAG;
6172
 
        }
 
6199
 
 
6200
        /* Check for special property for this query */
 
6201
        display_result_vertically|= (command->type == Q_QUERY_VERTICAL);
 
6202
        display_result_sorted= (command->type == Q_QUERY_SORTED);
6173
6203
 
6174
6204
        if (save_file[0])
6175
6205
        {
6179
6209
        run_query(cur_con, command, flags);
6180
6210
        command_executed++;
6181
6211
        command->last_argument= command->end;
 
6212
 
 
6213
        /* Restore settings */
 
6214
        display_result_vertically= old_display_result_vertically;
 
6215
        display_result_sorted= old_display_result_sorted;
 
6216
 
6182
6217
        break;
6183
6218
      }
6184
6219
      case Q_SEND:
6294
6329
        /* Stop processing any more commands */
6295
6330
        abort_flag= 1;
6296
6331
        break;
 
6332
      case Q_SKIP:
 
6333
        abort_not_supported_test("%s", command->first_argument);
 
6334
        break;
6297
6335
 
6298
6336
      case Q_RESULT:
6299
6337
        die("result, deprecated command");
6405
6443
    dump_warning_messages();
6406
6444
 
6407
6445
  timer_output();
6408
 
  free_used_memory();
6409
 
  my_end(info_flag ? MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR);
6410
 
 
6411
6446
  /* Yes, if we got this far the test has suceeded! Sakila smiles */
6412
 
  if (!silent)
6413
 
    printf("ok\n");
6414
 
  exit(0);
6415
 
  return 0;                             /* Keep compiler happy */
 
6447
  cleanup_and_exit(0);
 
6448
  return 0; /* Keep compiler happy too */
6416
6449
}
6417
6450
 
6418
6451
 
7066
7099
        if (back_ref_num >= 0 && back_ref_num <= (int)r.re_nsub)
7067
7100
        {
7068
7101
          regoff_t start_off, end_off;
7069
 
          if ((start_off= subs[back_ref_num].rm_so) > -1 &&
 
7102
          if ((start_off=subs[back_ref_num].rm_so) > -1 &&
7070
7103
              (end_off=subs[back_ref_num].rm_eo) > -1)
7071
7104
          {
7072
7105
            int block_len= (int) (end_off - start_off);
7791
7824
  char *end= longlong10_to_str(val, buff, 10);
7792
7825
  replace_dynstr_append_mem(ds, buff, end - buff);
7793
7826
}
 
7827
 
 
7828
 
 
7829
 
 
7830
/*
 
7831
  Build a list of pointer to each line in ds_input, sort
 
7832
  the list and use the sorted list to append the strings
 
7833
  sorted to the output ds
 
7834
 
 
7835
  SYNOPSIS
 
7836
  dynstr_append_sorted
 
7837
  ds - string where the sorted output will be appended
 
7838
  ds_input - string to be sorted
 
7839
 
 
7840
*/
 
7841
 
 
7842
static int comp_lines(const char **a, const char **b)
 
7843
{
 
7844
  return (strcmp(*a,*b));
 
7845
}
 
7846
 
 
7847
void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input)
 
7848
{
 
7849
  unsigned i;
 
7850
  char *start= ds_input->str;
 
7851
  DYNAMIC_ARRAY lines;
 
7852
  DBUG_ENTER("dynstr_append_sorted");
 
7853
 
 
7854
  if (!*start)
 
7855
    DBUG_VOID_RETURN;  /* No input */
 
7856
 
 
7857
  my_init_dynamic_array(&lines, sizeof(const char*), 32, 32);
 
7858
 
 
7859
  /* First line is result header, skip past it */
 
7860
  while (*start && *start != '\n')
 
7861
    start++;
 
7862
  start++; /* Skip past \n */
 
7863
  dynstr_append_mem(ds, ds_input->str, start - ds_input->str);
 
7864
 
 
7865
  /* Insert line(s) in array */
 
7866
  while (*start)
 
7867
  {
 
7868
    char* line_end= (char*)start;
 
7869
 
 
7870
    /* Find end of line */
 
7871
    while (*line_end && *line_end != '\n')
 
7872
      line_end++;
 
7873
    *line_end= 0;
 
7874
 
 
7875
    /* Insert pointer to the line in array */
 
7876
    if (insert_dynamic(&lines, (gptr) &start))
 
7877
      die("Out of memory inserting lines to sort");
 
7878
 
 
7879
    start= line_end+1;
 
7880
  }
 
7881
 
 
7882
  /* Sort array */
 
7883
  qsort(lines.buffer, lines.elements,
 
7884
        sizeof(char**), (qsort_cmp)comp_lines);
 
7885
 
 
7886
  /* Create new result */
 
7887
  for (i= 0; i < lines.elements ; i++)
 
7888
  {
 
7889
    const char **line= dynamic_element(&lines, i, const char**);
 
7890
    dynstr_append(ds, *line);
 
7891
    dynstr_append(ds, "\n");
 
7892
  }
 
7893
 
 
7894
  delete_dynamic(&lines);
 
7895
  DBUG_VOID_RETURN;
 
7896
}