363
387
char *query, *query_buf,*first_argument,*last_argument,*end;
364
388
int first_word_len, query_len;
389
my_bool abort_on_error;
366
390
struct st_expected_errors expected_errors;
367
391
char require_file[FN_REFLEN];
368
392
enum enum_commands type;
371
395
TYPELIB command_typelib= {array_elements(command_names),"",
374
string ds_res, ds_progress, ds_warning_messages;
398
DYNAMIC_STRING ds_res, ds_progress, ds_warning_messages;
376
400
char builtin_echo[FN_REFLEN];
378
402
void die(const char *fmt, ...)
379
__attribute__((format(printf, 1, 2)));
403
ATTRIBUTE_FORMAT(printf, 1, 2);
380
404
void abort_not_supported_test(const char *fmt, ...)
381
__attribute__((format(printf, 1, 2)));
405
ATTRIBUTE_FORMAT(printf, 1, 2);
382
406
void verbose_msg(const char *fmt, ...)
383
__attribute__((format(printf, 1, 2)));
407
ATTRIBUTE_FORMAT(printf, 1, 2);
384
408
void warning_msg(const char *fmt, ...)
385
__attribute__((format(printf, 1, 2)));
409
ATTRIBUTE_FORMAT(printf, 1, 2);
386
410
void log_msg(const char *fmt, ...)
387
__attribute__((format(printf, 1, 2)));
411
ATTRIBUTE_FORMAT(printf, 1, 2);
389
413
VAR* var_from_env(const char *, const char *);
390
414
VAR* var_init(VAR* v, const char *name, int name_len, const char *val,
392
416
void var_free(void* v);
393
417
VAR* var_get(const char *var_name, const char** var_name_end,
394
bool raw, bool ignore_not_existing);
418
my_bool raw, my_bool ignore_not_existing);
395
419
void eval_expr(VAR* v, const char *p, const char** p_end);
396
bool match_delimiter(int c, const char *delim, uint length);
420
my_bool match_delimiter(int c, const char *delim, uint length);
397
421
void dump_result_to_reject_file(char *buf, int size);
398
void dump_result_to_log_file(const char *buf, int size);
399
void dump_warning_messages(void);
400
void dump_progress(void);
422
void dump_result_to_log_file(char *buf, int size);
423
void dump_warning_messages();
424
void dump_progress();
402
void do_eval(string *query_eval, const char *query,
403
const char *query_end, bool pass_through_escape_chars);
404
void str_to_file(const char *fname, const char *str, int size);
405
void str_to_file2(const char *fname, const char *str, int size, bool append);
426
void do_eval(DYNAMIC_STRING *query_eval, const char *query,
427
const char *query_end, my_bool pass_through_escape_chars);
428
void str_to_file(const char *fname, char *str, int size);
429
void str_to_file2(const char *fname, char *str, int size, my_bool append);
407
431
/* For replace_column */
408
432
static char *replace_column[MAX_COLUMNS];
409
433
static uint max_replace_column= 0;
410
434
void do_get_replace_column(struct st_command*);
411
void free_replace_column(void);
435
void free_replace_column();
413
437
/* For replace */
414
438
void do_get_replace(struct st_command *command);
415
void free_replace(void);
417
441
/* For replace_regex */
418
442
void do_get_replace_regex(struct st_command *command);
419
void free_replace_regex(void);
422
void free_all_replace(void);
425
void free_all_replace(void){
443
void free_replace_regex();
446
void free_all_replace(){
427
448
free_replace_regex();
428
449
free_replace_column();
431
void replace_append_mem(string *ds, const char *val,
433
void replace_append(string *ds, const char *val);
434
void replace_append_uint(string *ds, uint val);
435
void append_sorted(string* ds, string* ds_input);
452
void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
454
void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val);
455
void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val);
456
void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING* ds_input);
437
458
void handle_error(struct st_command*,
438
459
unsigned int err_errno, const char *err_error,
439
const char *err_sqlstate, string *ds);
460
const char *err_sqlstate, DYNAMIC_STRING *ds);
440
461
void handle_no_error(struct st_command*);
443
#define do_send_query(cn,q,q_len,flags) drizzle_send_query(&cn->drizzle, q, q_len)
445
void do_eval(string *query_eval, const char *query,
446
const char *query_end, bool pass_through_escape_chars)
463
#ifdef EMBEDDED_LIBRARY
465
/* attributes of the query thread */
466
pthread_attr_t cn_thd_attrib;
469
send_one_query executes query in separate thread, which is
470
necessary in embedded library to run 'send' in proper way.
471
This implementation doesn't handle errors returned
472
by mysql_send_query. It's technically possible, though
473
I don't see where it is needed.
475
pthread_handler_t send_one_query(void *arg)
477
struct st_connection *cn= (struct st_connection*)arg;
480
VOID(mysql_send_query(&cn->mysql, cn->cur_query, cn->cur_query_len));
483
pthread_mutex_lock(&cn->mutex);
485
VOID(pthread_cond_signal(&cn->cond));
486
pthread_mutex_unlock(&cn->mutex);
491
static int do_send_query(struct st_connection *cn, const char *q, int q_len,
496
if (flags & QUERY_REAP_FLAG)
497
return mysql_send_query(&cn->mysql, q, q_len);
499
if (pthread_mutex_init(&cn->mutex, NULL) ||
500
pthread_cond_init(&cn->cond, NULL))
501
die("Error in the thread library");
504
cn->cur_query_len= q_len;
506
if (pthread_create(&tid, &cn_thd_attrib, send_one_query, (void*)cn))
507
die("Cannot start new thread for query");
512
static void wait_query_thread_end(struct st_connection *con)
514
if (!con->query_done)
516
pthread_mutex_lock(&con->mutex);
517
while (!con->query_done)
518
pthread_cond_wait(&con->cond, &con->mutex);
519
pthread_mutex_unlock(&con->mutex);
523
#else /*EMBEDDED_LIBRARY*/
525
#define do_send_query(cn,q,q_len,flags) mysql_send_query(&cn->mysql, q, q_len)
527
#endif /*EMBEDDED_LIBRARY*/
529
void do_eval(DYNAMIC_STRING *query_eval, const char *query,
530
const char *query_end, my_bool pass_through_escape_chars)
449
533
register char c, next_c;
450
534
register int escaped = 0;
536
DBUG_ENTER("do_eval");
454
538
for (p= query; (c= *p) && p < query_end; ++p)
1853
1980
<query to run> - The query that should be sent to the server
1854
1981
<column name> - Name of the column that holds the field be compared
1855
against the expected value
1982
against the expected value
1856
1983
<row no> - Number of the row that holds the field to be
1857
compared against the expected value
1984
compared against the expected value
1861
static void var_set_query_get_value(struct st_command *command, VAR *var)
1988
void var_set_query_get_value(struct st_command *command, VAR *var)
1864
1991
int col_no= -1;
1866
DRIZZLE *drizzle= &cur_con->drizzle;
1993
MYSQL* mysql= &cur_con->mysql;
1995
static DYNAMIC_STRING ds_query;
1996
static DYNAMIC_STRING ds_col;
1997
static DYNAMIC_STRING ds_row;
1871
1998
const struct command_arg query_get_value_args[] = {
1872
{"query", ARG_STRING, true, &ds_query, "Query to run"},
1873
{"column name", ARG_STRING, true, &ds_col, "Name of column"},
1874
{"row number", ARG_STRING, true, &ds_row, "Number for row"}
1999
"query", ARG_STRING, TRUE, &ds_query, "Query to run",
2000
"column name", ARG_STRING, TRUE, &ds_col, "Name of column",
2001
"row number", ARG_STRING, TRUE, &ds_row, "Number for row"
2004
DBUG_ENTER("var_set_query_get_value");
1879
2006
strip_parentheses(command);
2007
DBUG_PRINT("info", ("query: %s", command->query));
1880
2008
check_command_args(command, command->first_argument, query_get_value_args,
1881
2009
sizeof(query_get_value_args)/sizeof(struct command_arg),
2012
DBUG_PRINT("info", ("query: %s", ds_query.str));
2013
DBUG_PRINT("info", ("col: %s", ds_col.str));
1884
2015
/* Convert row number to int */
1885
if (!str2int(ds_row.c_str(), 10, (long) 0, (long) INT_MAX, &row_no))
1886
die("Invalid row number: '%s'", ds_row.c_str());
2016
if (!str2int(ds_row.str, 10, (long) 0, (long) INT_MAX, &row_no))
2017
die("Invalid row number: '%s'", ds_row.str);
2018
DBUG_PRINT("info", ("row: %s, row_no: %ld", ds_row.str, row_no));
2019
dynstr_free(&ds_row);
1888
2021
/* Remove any surrounding "'s from the query - if there is any */
1889
// (Don't get me started on this)
1890
char * unstripped_query= strdup(ds_query.c_str());
1891
if (strip_surrounding(unstripped_query, '"', '"'))
1892
die("Mismatched \"'s around query '%s'", ds_query.c_str());
1893
ds_query= unstripped_query;
2022
if (strip_surrounding(ds_query.str, '"', '"'))
2023
die("Mismatched \"'s around query '%s'", ds_query.str);
1895
2025
/* Run the query */
1896
if (drizzle_real_query(drizzle, ds_query.c_str(), ds_query.length()))
1897
die("Error running query '%s': %d %s", ds_query.c_str(),
1898
drizzle_errno(drizzle), drizzle_error(drizzle));
1899
if (!(res= drizzle_store_result(drizzle)))
1900
die("Query '%s' didn't return a result set", ds_query.c_str());
2026
if (mysql_real_query(mysql, ds_query.str, ds_query.length))
2027
die("Error running query '%s': %d %s", ds_query.str,
2028
mysql_errno(mysql), mysql_error(mysql));
2029
if (!(res= mysql_store_result(mysql)))
2030
die("Query '%s' didn't return a result set", ds_query.str);
1903
2033
/* Find column number from the given column name */
1905
uint num_fields= drizzle_num_fields(res);
1906
const DRIZZLE_FIELD *fields= drizzle_fetch_fields(res);
2035
uint num_fields= mysql_num_fields(res);
2036
MYSQL_FIELD *fields= mysql_fetch_fields(res);
1908
2038
for (i= 0; i < num_fields; i++)
1910
if (strcmp(fields[i].name, ds_col.c_str()) == 0 &&
1911
strlen(fields[i].name) == ds_col.length())
2040
if (strcmp(fields[i].name, ds_col.str) == 0 &&
2041
strlen(fields[i].name) == ds_col.length)
2418
2616
/* Parse what mode to set */
2419
if (ds_mode.length() != 4 ||
2420
str2int(ds_mode.c_str(), 8, 0, INT_MAX, &mode) == NULL)
2617
if (ds_mode.length != 4 ||
2618
str2int(ds_mode.str, 8, 0, INT_MAX, &mode) == NullS)
2421
2619
die("You must write a 4 digit octal number for mode");
2423
handle_command_error(command, chmod(ds_file.c_str(), mode));
2621
DBUG_PRINT("info", ("chmod %o %s", (uint)mode, ds_file.str));
2622
handle_command_error(command, chmod(ds_file.str, mode));
2623
dynstr_free(&ds_mode);
2624
dynstr_free(&ds_file);
2431
command called command
2632
command called command
2434
2635
fiile_exist <file_name>
2435
2636
Check if file <file_name> exists
2438
static void do_file_exist(struct st_command *command)
2639
void do_file_exist(struct st_command *command)
2642
static DYNAMIC_STRING ds_filename;
2442
2643
const struct command_arg file_exist_args[] = {
2443
{ "filename", ARG_STRING, true, &ds_filename, "File to check if it exist" }
2644
{ "filename", ARG_STRING, TRUE, &ds_filename, "File to check if it exist" }
2646
DBUG_ENTER("do_file_exist");
2447
2648
check_command_args(command, command->first_argument,
2448
2649
file_exist_args,
2449
2650
sizeof(file_exist_args)/sizeof(struct command_arg),
2452
error= (access(ds_filename.c_str(), F_OK) != 0);
2653
DBUG_PRINT("info", ("Checking for existence of file: %s", ds_filename.str));
2654
error= (access(ds_filename.str, F_OK) != 0);
2453
2655
handle_command_error(command, error);
2656
dynstr_free(&ds_filename);
2461
command called command
2664
command called command
2464
2667
mkdir <dir_name>
2465
2668
Create the directory <dir_name>
2468
static void do_mkdir(struct st_command *command)
2671
void do_mkdir(struct st_command *command)
2674
static DYNAMIC_STRING ds_dirname;
2472
2675
const struct command_arg mkdir_args[] = {
2473
{"dirname", ARG_STRING, true, &ds_dirname, "Directory to create"}
2676
"dirname", ARG_STRING, TRUE, &ds_dirname, "Directory to create"
2678
DBUG_ENTER("do_mkdir");
2477
2680
check_command_args(command, command->first_argument,
2478
2681
mkdir_args, sizeof(mkdir_args)/sizeof(struct command_arg),
2481
error= my_mkdir(ds_dirname.c_str(), 0777, MYF(0)) != 0;
2684
DBUG_PRINT("info", ("creating directory: %s", ds_dirname.str));
2685
error= my_mkdir(ds_dirname.str, 0777, MYF(0)) != 0;
2482
2686
handle_command_error(command, error);
2687
dynstr_free(&ds_dirname);
2489
command called command
2694
command called command
2492
2697
rmdir <dir_name>
2493
2698
Remove the empty directory <dir_name>
2496
static void do_rmdir(struct st_command *command)
2701
void do_rmdir(struct st_command *command)
2704
static DYNAMIC_STRING ds_dirname;
2500
2705
const struct command_arg rmdir_args[] = {
2501
{"dirname", ARG_STRING, true, &ds_dirname, "Directory to remove"}
2706
"dirname", ARG_STRING, TRUE, &ds_dirname, "Directory to remove"
2708
DBUG_ENTER("do_rmdir");
2505
2710
check_command_args(command, command->first_argument,
2506
2711
rmdir_args, sizeof(rmdir_args)/sizeof(struct command_arg),
2509
error= rmdir(ds_dirname.c_str()) != 0;
2714
DBUG_PRINT("info", ("removing directory: %s", ds_dirname.str));
2715
error= rmdir(ds_dirname.str) != 0;
2510
2716
handle_command_error(command, error);
2717
dynstr_free(&ds_dirname);
3066
3313
when ndb binlog is on, this call will wait until last updated epoch
3067
(locally in the drizzled) has been received into the binlog
3314
(locally in the mysqld) has been received into the binlog
3069
static int do_save_master_pos(void)
3316
int do_save_master_pos()
3073
DRIZZLE *drizzle= &cur_con->drizzle;
3320
MYSQL *mysql = &cur_con->mysql;
3074
3321
const char *query;
3077
if (drizzle_query(drizzle, query= "show master status"))
3322
DBUG_ENTER("do_save_master_pos");
3324
#ifdef HAVE_NDB_BINLOG
3326
Wait for ndb binlog to be up-to-date with all changes
3327
done on the local mysql server
3330
ulong have_ndbcluster;
3331
if (mysql_query(mysql, query= "show variables like 'have_ndbcluster'"))
3332
die("'%s' failed: %d %s", query,
3333
mysql_errno(mysql), mysql_error(mysql));
3334
if (!(res= mysql_store_result(mysql)))
3335
die("mysql_store_result() returned NULL for '%s'", query);
3336
if (!(row= mysql_fetch_row(res)))
3337
die("Query '%s' returned empty result", query);
3339
have_ndbcluster= strcmp("YES", row[1]) == 0;
3340
mysql_free_result(res);
3342
if (have_ndbcluster)
3344
ulonglong start_epoch= 0, handled_epoch= 0,
3345
latest_epoch=0, latest_trans_epoch=0,
3346
latest_handled_binlog_epoch= 0, latest_received_binlog_epoch= 0,
3347
latest_applied_binlog_epoch= 0;
3352
const char binlog[]= "binlog";
3353
const char latest_epoch_str[]=
3355
const char latest_trans_epoch_str[]=
3356
"latest_trans_epoch=";
3357
const char latest_received_binlog_epoch_str[]=
3358
"latest_received_binlog_epoch";
3359
const char latest_handled_binlog_epoch_str[]=
3360
"latest_handled_binlog_epoch=";
3361
const char latest_applied_binlog_epoch_str[]=
3362
"latest_applied_binlog_epoch=";
3365
if (mysql_query(mysql, query= "show engine ndb status"))
3366
die("failed in '%s': %d %s", query,
3367
mysql_errno(mysql), mysql_error(mysql));
3368
if (!(res= mysql_store_result(mysql)))
3369
die("mysql_store_result() returned NULL for '%s'", query);
3370
while ((row= mysql_fetch_row(res)))
3372
if (strcmp(row[1], binlog) == 0)
3374
const char *status= row[2];
3377
while (*status && strncmp(status, latest_epoch_str,
3378
sizeof(latest_epoch_str)-1))
3382
status+= sizeof(latest_epoch_str)-1;
3383
latest_epoch= strtoull(status, (char**) 0, 10);
3386
die("result does not contain '%s' in '%s'",
3387
latest_epoch_str, query);
3388
/* latest_trans_epoch */
3389
while (*status && strncmp(status, latest_trans_epoch_str,
3390
sizeof(latest_trans_epoch_str)-1))
3394
status+= sizeof(latest_trans_epoch_str)-1;
3395
latest_trans_epoch= strtoull(status, (char**) 0, 10);
3398
die("result does not contain '%s' in '%s'",
3399
latest_trans_epoch_str, query);
3400
/* latest_received_binlog_epoch */
3402
strncmp(status, latest_received_binlog_epoch_str,
3403
sizeof(latest_received_binlog_epoch_str)-1))
3407
status+= sizeof(latest_received_binlog_epoch_str)-1;
3408
latest_received_binlog_epoch= strtoull(status, (char**) 0, 10);
3411
die("result does not contain '%s' in '%s'",
3412
latest_received_binlog_epoch_str, query);
3413
/* latest_handled_binlog */
3415
strncmp(status, latest_handled_binlog_epoch_str,
3416
sizeof(latest_handled_binlog_epoch_str)-1))
3420
status+= sizeof(latest_handled_binlog_epoch_str)-1;
3421
latest_handled_binlog_epoch= strtoull(status, (char**) 0, 10);
3424
die("result does not contain '%s' in '%s'",
3425
latest_handled_binlog_epoch_str, query);
3426
/* latest_applied_binlog_epoch */
3428
strncmp(status, latest_applied_binlog_epoch_str,
3429
sizeof(latest_applied_binlog_epoch_str)-1))
3433
status+= sizeof(latest_applied_binlog_epoch_str)-1;
3434
latest_applied_binlog_epoch= strtoull(status, (char**) 0, 10);
3437
die("result does not contain '%s' in '%s'",
3438
latest_applied_binlog_epoch_str, query);
3440
start_epoch= latest_trans_epoch;
3445
die("result does not contain '%s' in '%s'",
3447
if (latest_handled_binlog_epoch > handled_epoch)
3449
handled_epoch= latest_handled_binlog_epoch;
3451
if (latest_handled_binlog_epoch >= start_epoch)
3453
else if (count > 30)
3457
mysql_free_result(res);
3462
if (mysql_query(mysql, query= "show master status"))
3078
3463
die("failed in 'show master status': %d %s",
3079
drizzle_errno(drizzle), drizzle_error(drizzle));
3464
mysql_errno(mysql), mysql_error(mysql));
3081
if (!(res = drizzle_store_result(drizzle)))
3082
die("drizzle_store_result() retuned NULL for '%s'", query);
3083
if (!(row = drizzle_fetch_row(res)))
3466
if (!(res = mysql_store_result(mysql)))
3467
die("mysql_store_result() retuned NULL for '%s'", query);
3468
if (!(row = mysql_fetch_row(res)))
3084
3469
die("empty result in show master status");
3085
my_stpncpy(master_pos.file, row[0], sizeof(master_pos.file)-1);
3470
strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1);
3086
3471
master_pos.pos = strtoul(row[1], (char**) 0, 10);
3087
drizzle_free_result(res);
3472
mysql_free_result(res);
3689
4141
<port> - server port
3690
4142
<sock> - server socket
3691
4143
<opts> - options to use for the connection
3692
* SSL - use SSL if available
3693
* COMPRESS - use compression if available
3697
static void do_connect(struct st_command *command)
4144
* SSL - use SSL if available
4145
* COMPRESS - use compression if available
4149
void do_connect(struct st_command *command)
3699
4151
int con_port= opt_port;
3700
const char *con_options;
3701
bool con_ssl= 0, con_compress= 0;
4153
my_bool con_ssl= 0, con_compress= 0;
3702
4154
struct st_connection* con_slot;
3704
string ds_connection_name;
4156
static DYNAMIC_STRING ds_connection_name;
4157
static DYNAMIC_STRING ds_host;
4158
static DYNAMIC_STRING ds_user;
4159
static DYNAMIC_STRING ds_password;
4160
static DYNAMIC_STRING ds_database;
4161
static DYNAMIC_STRING ds_port;
4162
static DYNAMIC_STRING ds_sock;
4163
static DYNAMIC_STRING ds_options;
3712
4164
const struct command_arg connect_args[] = {
3713
{ "connection name", ARG_STRING, true, &ds_connection_name, "Name of the connection" },
3714
{ "host", ARG_STRING, true, &ds_host, "Host to connect to" },
3715
{ "user", ARG_STRING, false, &ds_user, "User to connect as" },
3716
{ "passsword", ARG_STRING, false, &ds_password, "Password used when connecting" },
3717
{ "database", ARG_STRING, false, &ds_database, "Database to select after connect" },
3718
{ "port", ARG_STRING, false, &ds_port, "Port to connect to" },
3719
{ "socket", ARG_STRING, false, &ds_sock, "Socket to connect with" },
3720
{ "options", ARG_STRING, false, &ds_options, "Options to use while connecting" }
4165
{ "connection name", ARG_STRING, TRUE, &ds_connection_name, "Name of the connection" },
4166
{ "host", ARG_STRING, TRUE, &ds_host, "Host to connect to" },
4167
{ "user", ARG_STRING, FALSE, &ds_user, "User to connect as" },
4168
{ "passsword", ARG_STRING, FALSE, &ds_password, "Password used when connecting" },
4169
{ "database", ARG_STRING, FALSE, &ds_database, "Database to select after connect" },
4170
{ "port", ARG_STRING, FALSE, &ds_port, "Port to connect to" },
4171
{ "socket", ARG_STRING, FALSE, &ds_sock, "Socket to connect with" },
4172
{ "options", ARG_STRING, FALSE, &ds_options, "Options to use while connecting" }
4175
DBUG_ENTER("do_connect");
4176
DBUG_PRINT("enter",("connect: %s", command->first_argument));
3724
4178
strip_parentheses(command);
3725
4179
check_command_args(command, command->first_argument, connect_args,
4422
4932
{"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
4423
4933
0, 0, 0, 0, 0, 0},
4424
{"basedir", 'b', "Basedir for tests.", (char**) &opt_basedir,
4425
(char**) &opt_basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4934
{"basedir", 'b', "Basedir for tests.", (uchar**) &opt_basedir,
4935
(uchar**) &opt_basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4426
4936
{"character-sets-dir", OPT_CHARSETS_DIR,
4427
"Directory where character sets are.", (char**) &opt_charsets_dir,
4428
(char**) &opt_charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4937
"Directory where character sets are.", (uchar**) &opt_charsets_dir,
4938
(uchar**) &opt_charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4429
4939
{"compress", 'C', "Use the compressed server/client protocol.",
4430
(char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
4940
(uchar**) &opt_compress, (uchar**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
4432
{"database", 'D', "Database to use.", (char**) &opt_db, (char**) &opt_db, 0,
4942
{"cursor-protocol", OPT_CURSOR_PROTOCOL, "Use cursors for prepared statements.",
4943
(uchar**) &cursor_protocol, (uchar**) &cursor_protocol, 0,
4944
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4945
{"database", 'D', "Database to use.", (uchar**) &opt_db, (uchar**) &opt_db, 0,
4433
4946
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4948
{"debug", '#', "This is a non-debug version. Catch this and exit",
4949
0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0},
4951
{"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",
4952
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
4434
4954
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
4435
(char**) &debug_check_flag, (char**) &debug_check_flag, 0,
4955
(uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0,
4436
4956
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4437
4957
{"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
4438
(char**) &debug_info_flag, (char**) &debug_info_flag,
4958
(uchar**) &debug_info_flag, (uchar**) &debug_info_flag,
4439
4959
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4440
{"host", 'h', "Connect to host.", (char**) &opt_host, (char**) &opt_host, 0,
4960
{"host", 'h', "Connect to host.", (uchar**) &opt_host, (uchar**) &opt_host, 0,
4441
4961
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4442
{"include", 'i', "Include SQL before each test case.", (char**) &opt_include,
4443
(char**) &opt_include, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4444
{"logdir", OPT_LOG_DIR, "Directory for log files", (char**) &opt_logdir,
4445
(char**) &opt_logdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4962
{"include", 'i', "Include SQL before each test case.", (uchar**) &opt_include,
4963
(uchar**) &opt_include, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4964
{"logdir", OPT_LOG_DIR, "Directory for log files", (uchar**) &opt_logdir,
4965
(uchar**) &opt_logdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4446
4966
{"mark-progress", OPT_MARK_PROGRESS,
4447
4967
"Write linenumber and elapsed time to <testname>.progress ",
4448
(char**) &opt_mark_progress, (char**) &opt_mark_progress, 0,
4968
(uchar**) &opt_mark_progress, (uchar**) &opt_mark_progress, 0,
4449
4969
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4450
4970
{"max-connect-retries", OPT_MAX_CONNECT_RETRIES,
4451
4971
"Max number of connection attempts when connecting to server",
4452
(char**) &opt_max_connect_retries, (char**) &opt_max_connect_retries, 0,
4972
(uchar**) &opt_max_connect_retries, (uchar**) &opt_max_connect_retries, 0,
4453
4973
GET_INT, REQUIRED_ARG, 500, 1, 10000, 0, 0, 0},
4454
4974
{"password", 'p', "Password to use when connecting to server.",
4455
4975
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
4456
4976
{"port", 'P', "Port number to use for connection or 0 for default to, in "
4457
"order of preference, my.cnf, $DRIZZLE_TCP_PORT, "
4458
"built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
4460
(char**) &opt_port, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4461
{"quiet", 's', "Suppress all normal output.", (char**) &silent,
4462
(char**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4977
"order of preference, my.cnf, $MYSQL_TCP_PORT, "
4978
#if MYSQL_PORT_DEFAULT == 0
4981
"built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
4982
(uchar**) &opt_port,
4983
(uchar**) &opt_port, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4984
{"protocol", OPT_MYSQL_PROTOCOL,
4985
"The protocol of connection (tcp,socket,pipe,memory).",
4986
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4987
{"ps-protocol", OPT_PS_PROTOCOL, "Use prepared statements protocol for communication",
4988
(uchar**) &ps_protocol, (uchar**) &ps_protocol, 0,
4989
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4990
{"quiet", 's', "Suppress all normal output.", (uchar**) &silent,
4991
(uchar**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4463
4992
{"record", 'r', "Record output of test_file into result file.",
4464
4993
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
4465
4994
{"result-file", 'R', "Read/Store result from/in this file.",
4466
(char**) &result_file_name, (char**) &result_file_name, 0,
4995
(uchar**) &result_file_name, (uchar**) &result_file_name, 0,
4467
4996
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4468
4997
{"server-arg", 'A', "Send option value to embedded server as a parameter.",
4469
4998
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4470
4999
{"server-file", 'F', "Read embedded server arguments from file.",
4471
5000
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4472
5001
{"silent", 's', "Suppress all normal output. Synonym for --quiet.",
4473
(char**) &silent, (char**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
5002
(uchar**) &silent, (uchar**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4474
5003
{"sleep", 'T', "Sleep always this many seconds on sleep commands.",
4475
(char**) &opt_sleep, (char**) &opt_sleep, 0, GET_INT, REQUIRED_ARG, -1, -1, 0,
5004
(uchar**) &opt_sleep, (uchar**) &opt_sleep, 0, GET_INT, REQUIRED_ARG, -1, -1, 0,
5006
{"socket", 'S', "Socket file to use for connection.",
5007
(uchar**) &unix_sock, (uchar**) &unix_sock, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
5009
{"sp-protocol", OPT_SP_PROTOCOL, "Use stored procedures for select",
5010
(uchar**) &sp_protocol, (uchar**) &sp_protocol, 0,
5011
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4477
5012
{"tail-lines", OPT_TAIL_LINES,
4478
5013
"Number of lines of the resul to include in a failure report",
4479
(char**) &opt_tail_lines, (char**) &opt_tail_lines, 0,
5014
(uchar**) &opt_tail_lines, (uchar**) &opt_tail_lines, 0,
4480
5015
GET_INT, REQUIRED_ARG, 0, 0, 10000, 0, 0, 0},
4481
5016
{"test-file", 'x', "Read test from/in this file (default stdin).",
4482
5017
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4484
5019
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4485
5020
{"tmpdir", 't', "Temporary directory where sockets are put.",
4486
5021
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4487
{"user", 'u', "User for login.", (char**) &opt_user, (char**) &opt_user, 0,
5022
{"user", 'u', "User for login.", (uchar**) &opt_user, (uchar**) &opt_user, 0,
4488
5023
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4489
{"verbose", 'v', "Write more.", (char**) &verbose, (char**) &verbose, 0,
5024
{"verbose", 'v', "Write more.", (uchar**) &verbose, (uchar**) &verbose, 0,
4490
5025
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4491
5026
{"version", 'V', "Output version information and exit.",
4492
5027
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
5028
{"view-protocol", OPT_VIEW_PROTOCOL, "Use views for select",
5029
(uchar**) &view_protocol, (uchar**) &view_protocol, 0,
5030
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4493
5031
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
4497
static void print_version(void)
5035
#include <help_start.h>
5037
void print_version(void)
4499
5039
printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,MTEST_VERSION,
4500
drizzle_get_client_info(),SYSTEM_TYPE,MACHINE_TYPE);
5040
MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
4503
static void usage(void)
4505
5045
print_version();
4506
5046
printf("MySQL AB, by Sasha, Matt, Monty & Jani\n");
4507
5047
printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
4508
printf("Runs a test against the DRIZZLE server and compares output with a results file.\n\n");
5048
printf("Runs a test against the mysql server and compares output with a results file.\n\n");
4509
5049
printf("Usage: %s [OPTIONS] [database] < test_file\n", my_progname);
4510
5050
my_print_help(my_long_options);
4511
5051
printf(" --no-defaults Don't read default options from any options file.\n");
4512
5052
my_print_variables(my_long_options);
5055
#include <help_end.h>
4516
5059
Read arguments for embedded server and put them into
4517
5060
embedded_server_args[]
4520
static void read_embedded_server_arguments(const char *name)
5063
void read_embedded_server_arguments(const char *name)
4522
5065
char argument[1024],buff[FN_REFLEN], *str=0;
4525
5068
if (!test_if_hard_path(name))
4527
strxmov(buff, opt_basedir, name, NULL);
5070
strxmov(buff, opt_basedir, name, NullS);
4530
5073
fn_format(buff, name, "", "", MY_UNPACK_FILENAME);
4784
5343
Values may be converted with 'replace_column'
4787
static void append_result(string *ds, DRIZZLE_RES *res)
5346
void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res)
4790
uint32_t num_fields= drizzle_num_fields(res);
4791
const DRIZZLE_FIELD *fields= drizzle_fetch_fields(res);
5349
uint num_fields= mysql_num_fields(res);
5350
MYSQL_FIELD *fields= mysql_fetch_fields(res);
4794
while ((row = drizzle_fetch_row(res)))
5353
while ((row = mysql_fetch_row(res)))
4797
lengths = drizzle_fetch_lengths(res);
5356
lengths = mysql_fetch_lengths(res);
4798
5357
for (i = 0; i < num_fields; i++)
4799
5358
append_field(ds, i, &fields[i],
4800
5359
(const char*)row[i], lengths[i], !row[i]);
4801
5360
if (!display_result_vertically)
5361
dynstr_append_mem(ds, "\n", 1);
5367
Append all results from ps execution to the dynamic string separated
5368
with '\t'. Values may be converted with 'replace_column'
5371
void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt,
5372
MYSQL_FIELD *fields, uint num_fields)
5374
MYSQL_BIND *my_bind;
5379
/* Allocate array with bind structs, lengths and NULL flags */
5380
my_bind= (MYSQL_BIND*) my_malloc(num_fields * sizeof(MYSQL_BIND),
5381
MYF(MY_WME | MY_FAE | MY_ZEROFILL));
5382
length= (ulong*) my_malloc(num_fields * sizeof(ulong),
5383
MYF(MY_WME | MY_FAE));
5384
is_null= (my_bool*) my_malloc(num_fields * sizeof(my_bool),
5385
MYF(MY_WME | MY_FAE));
5387
/* Allocate data for the result of each field */
5388
for (i= 0; i < num_fields; i++)
5390
uint max_length= fields[i].max_length + 1;
5391
my_bind[i].buffer_type= MYSQL_TYPE_STRING;
5392
my_bind[i].buffer= (char *)my_malloc(max_length, MYF(MY_WME | MY_FAE));
5393
my_bind[i].buffer_length= max_length;
5394
my_bind[i].is_null= &is_null[i];
5395
my_bind[i].length= &length[i];
5397
DBUG_PRINT("bind", ("col[%d]: buffer_type: %d, buffer_length: %lu",
5398
i, my_bind[i].buffer_type, my_bind[i].buffer_length));
5401
if (mysql_stmt_bind_result(stmt, my_bind))
5402
die("mysql_stmt_bind_result failed: %d: %s",
5403
mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
5405
while (mysql_stmt_fetch(stmt) == 0)
5407
for (i= 0; i < num_fields; i++)
5408
append_field(ds, i, &fields[i], (const char *) my_bind[i].buffer,
5409
*my_bind[i].length, *my_bind[i].is_null);
5410
if (!display_result_vertically)
5411
dynstr_append_mem(ds, "\n", 1);
5414
if (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
5415
die("fetch didn't end with MYSQL_NO_DATA from statement: %d %s",
5416
mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
5418
for (i= 0; i < num_fields; i++)
5420
/* Free data for output */
5421
my_free(my_bind[i].buffer, MYF(MY_WME | MY_FAE));
5423
/* Free array with bind structs, lengths and NULL flags */
5424
my_free(my_bind , MYF(MY_WME | MY_FAE));
5425
my_free(length , MYF(MY_WME | MY_FAE));
5426
my_free(is_null , MYF(MY_WME | MY_FAE));
4809
5431
Append metadata for fields to output
4812
static void append_metadata(string *ds,
4813
const DRIZZLE_FIELD *field,
5434
void append_metadata(DYNAMIC_STRING *ds,
4816
const DRIZZLE_FIELD *field_end;
4817
ds->append("Catalog\tDatabase\tTable\tTable_alias\tColumn\t"
4818
"Column_alias\tType\tLength\tMax length\tIs_null\t"
4819
"Flags\tDecimals\tCharsetnr\n");
5438
MYSQL_FIELD *field_end;
5439
dynstr_append(ds,"Catalog\tDatabase\tTable\tTable_alias\tColumn\t"
5440
"Column_alias\tType\tLength\tMax length\tIs_null\t"
5441
"Flags\tDecimals\tCharsetnr\n");
4821
5443
for (field_end= field+num_fields ;
4822
5444
field < field_end ;
4825
ds->append(field->catalog,
4826
field->catalog_length);
4827
ds->append("\t", 1);
4828
ds->append(field->db, field->db_length);
4829
ds->append("\t", 1);
4830
ds->append(field->org_table,
4831
field->org_table_length);
4832
ds->append("\t", 1);
4833
ds->append(field->table,
4834
field->table_length);
4835
ds->append("\t", 1);
4836
ds->append(field->org_name,
4837
field->org_name_length);
4838
ds->append("\t", 1);
4839
ds->append(field->name, field->name_length);
4840
ds->append("\t", 1);
4841
replace_append_uint(ds, field->type);
4842
ds->append("\t", 1);
4843
replace_append_uint(ds, field->length);
4844
ds->append("\t", 1);
4845
replace_append_uint(ds, field->max_length);
4846
ds->append("\t", 1);
4847
ds->append((char*) ((field->flags & NOT_NULL_FLAG) ?
4849
ds->append("\t", 1);
4850
replace_append_uint(ds, field->flags);
4851
ds->append("\t", 1);
4852
replace_append_uint(ds, field->decimals);
4853
ds->append("\t", 1);
4854
replace_append_uint(ds, field->charsetnr);
4855
ds->append("\n", 1);
5447
dynstr_append_mem(ds, field->catalog,
5448
field->catalog_length);
5449
dynstr_append_mem(ds, "\t", 1);
5450
dynstr_append_mem(ds, field->db, field->db_length);
5451
dynstr_append_mem(ds, "\t", 1);
5452
dynstr_append_mem(ds, field->org_table,
5453
field->org_table_length);
5454
dynstr_append_mem(ds, "\t", 1);
5455
dynstr_append_mem(ds, field->table,
5456
field->table_length);
5457
dynstr_append_mem(ds, "\t", 1);
5458
dynstr_append_mem(ds, field->org_name,
5459
field->org_name_length);
5460
dynstr_append_mem(ds, "\t", 1);
5461
dynstr_append_mem(ds, field->name, field->name_length);
5462
dynstr_append_mem(ds, "\t", 1);
5463
replace_dynstr_append_uint(ds, field->type);
5464
dynstr_append_mem(ds, "\t", 1);
5465
replace_dynstr_append_uint(ds, field->length);
5466
dynstr_append_mem(ds, "\t", 1);
5467
replace_dynstr_append_uint(ds, field->max_length);
5468
dynstr_append_mem(ds, "\t", 1);
5469
dynstr_append_mem(ds, (char*) (IS_NOT_NULL(field->flags) ?
5471
dynstr_append_mem(ds, "\t", 1);
5472
replace_dynstr_append_uint(ds, field->flags);
5473
dynstr_append_mem(ds, "\t", 1);
5474
replace_dynstr_append_uint(ds, field->decimals);
5475
dynstr_append_mem(ds, "\t", 1);
5476
replace_dynstr_append_uint(ds, field->charsetnr);
5477
dynstr_append_mem(ds, "\n", 1);
4901
5523
Number of warnings appended to ds
4904
static int append_warnings(string *ds, DRIZZLE *drizzle)
5526
int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql)
4907
DRIZZLE_RES *warn_res;
4910
if (!(count= drizzle_warning_count(drizzle)))
5529
MYSQL_RES *warn_res;
5530
DBUG_ENTER("append_warnings");
5532
if (!(count= mysql_warning_count(mysql)))
4914
5536
If one day we will support execution of multi-statements
4915
5537
through PS API we should not issue SHOW WARNINGS until
4916
5538
we have not read all results...
4918
assert(!drizzle_more_results(drizzle));
4920
if (drizzle_real_query(drizzle, "SHOW WARNINGS", 13))
4921
die("Error running query \"SHOW WARNINGS\": %s", drizzle_error(drizzle));
4923
if (!(warn_res= drizzle_store_result(drizzle)))
5540
DBUG_ASSERT(!mysql_more_results(mysql));
5542
if (mysql_real_query(mysql, "SHOW WARNINGS", 13))
5543
die("Error running query \"SHOW WARNINGS\": %s", mysql_error(mysql));
5545
if (!(warn_res= mysql_store_result(mysql)))
4924
5546
die("Warning count is %u but didn't get any warnings",
4927
5549
append_result(ds, warn_res);
5550
mysql_free_result(warn_res);
5552
DBUG_PRINT("warnings", ("%s", ds->str));
4934
Run query using DRIZZLE C API
5559
Run query using MySQL C API
4938
drizzle DRIZZLE handle
4939
command current command pointer
4940
flags flags indicating if we should SEND and/or REAP
4941
query query string to execute
4942
query_len length query string to execute
4943
ds output buffer where to store result form query
5564
command current command pointer
5565
flags flags indicating if we should SEND and/or REAP
5566
query query string to execute
5567
query_len length query string to execute
5568
ds output buffer where to store result form query
4946
static void run_query_normal(struct st_connection *cn,
4947
struct st_command *command,
4948
int flags, char *query, int query_len,
4949
string *ds, string *ds_warnings)
5571
void run_query_normal(struct st_connection *cn, struct st_command *command,
5572
int flags, char *query, int query_len,
5573
DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings)
4951
DRIZZLE_RES *res= 0;
4952
DRIZZLE *drizzle= &cn->drizzle;
5576
MYSQL *mysql= &cn->mysql;
4953
5577
int err= 0, counter= 0;
5578
DBUG_ENTER("run_query_normal");
5579
DBUG_PRINT("enter",("flags: %d", flags));
5580
DBUG_PRINT("enter", ("query: '%-.60s'", query));
4955
5582
if (flags & QUERY_SEND_FLAG)
4960
5587
if (do_send_query(cn, query, query_len, flags))
4962
handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
4963
drizzle_sqlstate(drizzle), ds);
5589
handle_error(command, mysql_errno(mysql), mysql_error(mysql),
5590
mysql_sqlstate(mysql), ds);
5594
#ifdef EMBEDDED_LIBRARY
5596
Here we handle 'reap' command, so we need to check if the
5597
query's thread was finished and probably wait
5599
else if (flags & QUERY_REAP_FLAG)
5600
wait_query_thread_end(cn);
5601
#endif /*EMBEDDED_LIBRARY*/
4967
5602
if (!(flags & QUERY_REAP_FLAG))
4973
When on first result set, call drizzle_read_query_result to retrieve
5608
When on first result set, call mysql_read_query_result to retrieve
4974
5609
answer to the query sent earlier
4976
if ((counter==0) && drizzle_read_query_result(drizzle))
5611
if ((counter==0) && mysql_read_query_result(mysql))
4978
handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
4979
drizzle_sqlstate(drizzle), ds);
5613
handle_error(command, mysql_errno(mysql), mysql_error(mysql),
5614
mysql_sqlstate(mysql), ds);
4985
5620
Store the result of the query if it will return any fields
4987
if (drizzle_field_count(drizzle) && ((res= drizzle_store_result(drizzle)) == 0))
5622
if (mysql_field_count(mysql) && ((res= mysql_store_result(mysql)) == 0))
4989
handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
4990
drizzle_sqlstate(drizzle), ds);
5624
handle_error(command, mysql_errno(mysql), mysql_error(mysql),
5625
mysql_sqlstate(mysql), ds);
4994
5629
if (!disable_result_log)
4996
uint64_t affected_rows= 0; /* Ok to be undef if 'disable_info' is set */
5631
ulonglong affected_rows= 0; /* Ok to be undef if 'disable_info' is set */
5000
const DRIZZLE_FIELD *fields= drizzle_fetch_fields(res);
5001
uint num_fields= drizzle_num_fields(res);
5635
MYSQL_FIELD *fields= mysql_fetch_fields(res);
5636
uint num_fields= mysql_num_fields(res);
5003
if (display_metadata)
5638
if (display_metadata)
5004
5639
append_metadata(ds, fields, num_fields);
5006
if (!display_result_vertically)
5007
append_table_headings(ds, fields, num_fields);
5641
if (!display_result_vertically)
5642
append_table_headings(ds, fields, num_fields);
5009
append_result(ds, res);
5644
append_result(ds, res);
5013
Need to call drizzle_affected_rows() before the "new"
5648
Need to call mysql_affected_rows() before the "new"
5014
5649
query to find the warnings
5016
5651
if (!disable_info)
5017
affected_rows= drizzle_affected_rows(drizzle);
5652
affected_rows= mysql_affected_rows(mysql);
5020
5655
Add all warnings to the result. We can't do this if we are in
5021
5656
the middle of processing results from multi-statement, because
5022
5657
this will break protocol.
5024
if (!disable_warnings && !drizzle_more_results(drizzle))
5659
if (!disable_warnings && !mysql_more_results(mysql))
5026
if (append_warnings(ds_warnings, drizzle) || ds_warnings->length())
5028
ds->append("Warnings:\n", 10);
5029
ds->append(ds_warnings->c_str(), ds_warnings->length());
5661
if (append_warnings(ds_warnings, mysql) || ds_warnings->length)
5663
dynstr_append_mem(ds, "Warnings:\n", 10);
5664
dynstr_append_mem(ds, ds_warnings->str, ds_warnings->length);
5033
5668
if (!disable_info)
5034
append_info(ds, affected_rows, drizzle_info(drizzle));
5669
append_info(ds, affected_rows, mysql_info(mysql));
5039
drizzle_free_result(res);
5674
mysql_free_result(res);
5043
} while (!(err= drizzle_next_result(drizzle)));
5678
} while (!(err= mysql_next_result(mysql)));
5046
/* We got an error from drizzle_next_result, maybe expected */
5047
handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
5048
drizzle_sqlstate(drizzle), ds);
5681
/* We got an error from mysql_next_result, maybe expected */
5682
handle_error(command, mysql_errno(mysql), mysql_error(mysql),
5683
mysql_sqlstate(mysql), ds);
5051
assert(err == -1); /* Successful and there are no more results */
5686
DBUG_ASSERT(err == -1); /* Successful and there are no more results */
5053
5688
/* If we come here the query is both executed and read successfully */
5054
5689
handle_no_error(command);
5193
5834
command->query, command->expected_errors.err[0].code.sqlstate);
5842
Run query using prepared statement C API
5846
mysql - mysql handle
5847
command - currrent command pointer
5848
query - query string to execute
5849
query_len - length query string to execute
5850
ds - output buffer where to store result form query
5853
error - function will not return
5856
void run_query_stmt(MYSQL *mysql, struct st_command *command,
5857
char *query, int query_len, DYNAMIC_STRING *ds,
5858
DYNAMIC_STRING *ds_warnings)
5860
MYSQL_RES *res= NULL; /* Note that here 'res' is meta data result set */
5862
DYNAMIC_STRING ds_prepare_warnings;
5863
DYNAMIC_STRING ds_execute_warnings;
5864
DBUG_ENTER("run_query_stmt");
5865
DBUG_PRINT("query", ("'%-.60s'", query));
5868
Init a new stmt if it's not already one created for this connection
5870
if(!(stmt= cur_con->stmt))
5872
if (!(stmt= mysql_stmt_init(mysql)))
5873
die("unable to init stmt structure");
5874
cur_con->stmt= stmt;
5877
/* Init dynamic strings for warnings */
5878
if (!disable_warnings)
5880
init_dynamic_string(&ds_prepare_warnings, NULL, 0, 256);
5881
init_dynamic_string(&ds_execute_warnings, NULL, 0, 256);
5887
if (mysql_stmt_prepare(stmt, query, query_len))
5889
handle_error(command, mysql_stmt_errno(stmt),
5890
mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
5895
Get the warnings from mysql_stmt_prepare and keep them in a
5898
if (!disable_warnings)
5899
append_warnings(&ds_prepare_warnings, mysql);
5902
No need to call mysql_stmt_bind_param() because we have no
5906
#if MYSQL_VERSION_ID >= 50000
5907
if (cursor_protocol_enabled)
5910
Use cursor when retrieving result
5912
ulong type= CURSOR_TYPE_READ_ONLY;
5913
if (mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type))
5914
die("mysql_stmt_attr_set(STMT_ATTR_CURSOR_TYPE) failed': %d %s",
5915
mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
5922
if (mysql_stmt_execute(stmt))
5924
handle_error(command, mysql_stmt_errno(stmt),
5925
mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
5930
When running in cursor_protocol get the warnings from execute here
5931
and keep them in a separate string for later.
5933
if (cursor_protocol_enabled && !disable_warnings)
5934
append_warnings(&ds_execute_warnings, mysql);
5937
We instruct that we want to update the "max_length" field in
5938
mysql_stmt_store_result(), this is our only way to know how much
5939
buffer to allocate for result data
5943
if (mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &one))
5944
die("mysql_stmt_attr_set(STMT_ATTR_UPDATE_MAX_LENGTH) failed': %d %s",
5945
mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
5949
If we got here the statement succeeded and was expected to do so,
5950
get data. Note that this can still give errors found during execution!
5951
Store the result of the query if if will return any fields
5953
if (mysql_stmt_field_count(stmt) && mysql_stmt_store_result(stmt))
5955
handle_error(command, mysql_stmt_errno(stmt),
5956
mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
5960
/* If we got here the statement was both executed and read successfully */
5961
handle_no_error(command);
5962
if (!disable_result_log)
5965
Not all statements creates a result set. If there is one we can
5966
now create another normal result set that contains the meta
5967
data. This set can be handled almost like any other non prepared
5968
statement result set.
5970
if ((res= mysql_stmt_result_metadata(stmt)) != NULL)
5972
/* Take the column count from meta info */
5973
MYSQL_FIELD *fields= mysql_fetch_fields(res);
5974
uint num_fields= mysql_num_fields(res);
5976
if (display_metadata)
5977
append_metadata(ds, fields, num_fields);
5979
if (!display_result_vertically)
5980
append_table_headings(ds, fields, num_fields);
5982
append_stmt_result(ds, stmt, fields, num_fields);
5984
mysql_free_result(res); /* Free normal result set with meta data */
5986
/* Clear prepare warnings */
5987
dynstr_set(&ds_prepare_warnings, NULL);
5992
This is a query without resultset
5996
if (!disable_warnings)
5998
/* Get the warnings from execute */
6000
/* Append warnings to ds - if there are any */
6001
if (append_warnings(&ds_execute_warnings, mysql) ||
6002
ds_execute_warnings.length ||
6003
ds_prepare_warnings.length ||
6004
ds_warnings->length)
6006
dynstr_append_mem(ds, "Warnings:\n", 10);
6007
if (ds_warnings->length)
6008
dynstr_append_mem(ds, ds_warnings->str,
6009
ds_warnings->length);
6010
if (ds_prepare_warnings.length)
6011
dynstr_append_mem(ds, ds_prepare_warnings.str,
6012
ds_prepare_warnings.length);
6013
if (ds_execute_warnings.length)
6014
dynstr_append_mem(ds, ds_execute_warnings.str,
6015
ds_execute_warnings.length);
6020
append_info(ds, mysql_affected_rows(mysql), mysql_info(mysql));
6025
if (!disable_warnings)
6027
dynstr_free(&ds_prepare_warnings);
6028
dynstr_free(&ds_execute_warnings);
6032
/* Close the statement if - no reconnect, need new prepare */
6033
if (mysql->reconnect)
6035
mysql_stmt_close(stmt);
6036
cur_con->stmt= NULL;
6040
We save the return code (mysql_stmt_errno(stmt)) from the last call sent
6041
to the server into the mysqltest builtin variable $mysql_errno. This
6042
variable then can be used from the test case itself.
6045
var_set_errno(mysql_stmt_errno(stmt));
6053
Create a util connection if one does not already exists
6054
and use that to run the query
6055
This is done to avoid implict commit when creating/dropping objects such
6059
int util_query(MYSQL* org_mysql, const char* query){
6062
DBUG_ENTER("util_query");
6064
if(!(mysql= cur_con->util_mysql))
6066
int opt_protocol= MYSQL_PROTOCOL_TCP;
6067
DBUG_PRINT("info", ("Creating util_mysql"));
6068
if (!(mysql= mysql_init(mysql)))
6069
die("Failed in mysql_init()");
6070
mysql_options(mysql, MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
6072
/* enable local infile, in non-binary builds often disabled by default */
6073
mysql_options(mysql, MYSQL_OPT_LOCAL_INFILE, 0);
6074
safe_connect(mysql, "util", org_mysql->host, org_mysql->user,
6075
org_mysql->passwd, org_mysql->db, org_mysql->port);
6077
cur_con->util_mysql= mysql;
6080
return mysql_query(mysql, query);
5205
drizzle DRIZZLE handle
5206
command currrent command pointer
6091
command currrent command pointer
5208
6093
flags control the phased/stages of query execution to be performed
5209
6094
if QUERY_SEND_FLAG bit is on, the query will be sent. If QUERY_REAP_FLAG
5210
6095
is on the result will be read - for regular query, both bits must be on
5213
static void run_query(struct st_connection *cn,
5214
struct st_command *command,
6098
void run_query(struct st_connection *cn, struct st_command *command, int flags)
5218
string *save_ds= NULL;
6100
MYSQL *mysql= &cn->mysql;
6102
DYNAMIC_STRING *save_ds= NULL;
6103
DYNAMIC_STRING ds_result;
6104
DYNAMIC_STRING ds_sorted;
6105
DYNAMIC_STRING ds_warnings;
6106
DYNAMIC_STRING eval_query;
6109
my_bool view_created= 0, sp_created= 0;
6110
my_bool complete_query= ((flags & QUERY_SEND_FLAG) &&
6111
(flags & QUERY_REAP_FLAG));
6112
DBUG_ENTER("run_query");
6114
init_dynamic_string(&ds_warnings, NULL, 0, 256);
5227
6116
/* Scan for warning before sending to server */
5228
6117
scan_command_for_warnings(command);
5251
6141
if (command->require_file[0])
6143
init_dynamic_string(&ds_result, "", 1024, 1024);
5253
6144
ds= &ds_result;
5260
6150
Log the query into the output buffer
5262
6152
if (!disable_query_log && (flags & QUERY_SEND_FLAG))
5264
replace_append_mem(ds, query, query_len);
5265
ds->append(delimiter, delimiter_length);
6154
replace_dynstr_append_mem(ds, query, query_len);
6155
dynstr_append_mem(ds, delimiter, delimiter_length);
6156
dynstr_append_mem(ds, "\n", 1);
6159
if (view_protocol_enabled &&
6161
match_re(&view_re, query))
6164
Create the query as a view.
6165
Use replace since view can exist from a failed mysqltest run
6167
DYNAMIC_STRING query_str;
6168
init_dynamic_string(&query_str,
6169
"CREATE OR REPLACE VIEW mysqltest_tmp_v AS ",
6171
dynstr_append_mem(&query_str, query, query_len);
6172
if (util_query(mysql, query_str.str))
6175
Failed to create the view, this is not fatal
6176
just run the query the normal way
6178
DBUG_PRINT("view_create_error",
6179
("Failed to create view '%s': %d: %s", query_str.str,
6180
mysql_errno(mysql), mysql_error(mysql)));
6182
/* Log error to create view */
6183
verbose_msg("Failed to create view '%s' %d: %s", query_str.str,
6184
mysql_errno(mysql), mysql_error(mysql));
6189
Yes, it was possible to create this query as a view
6192
query= (char*)"SELECT * FROM mysqltest_tmp_v";
6193
query_len = strlen(query);
6196
Collect warnings from create of the view that should otherwise
6197
have been produced when the SELECT was executed
6199
append_warnings(&ds_warnings, cur_con->util_mysql);
6202
dynstr_free(&query_str);
6206
if (sp_protocol_enabled &&
6208
match_re(&sp_re, query))
6211
Create the query as a stored procedure
6212
Drop first since sp can exist from a failed mysqltest run
6214
DYNAMIC_STRING query_str;
6215
init_dynamic_string(&query_str,
6216
"DROP PROCEDURE IF EXISTS mysqltest_tmp_sp;",
6218
util_query(mysql, query_str.str);
6219
dynstr_set(&query_str, "CREATE PROCEDURE mysqltest_tmp_sp()\n");
6220
dynstr_append_mem(&query_str, query, query_len);
6221
if (util_query(mysql, query_str.str))
6224
Failed to create the stored procedure for this query,
6225
this is not fatal just run the query the normal way
6227
DBUG_PRINT("sp_create_error",
6228
("Failed to create sp '%s': %d: %s", query_str.str,
6229
mysql_errno(mysql), mysql_error(mysql)));
6231
/* Log error to create sp */
6232
verbose_msg("Failed to create sp '%s' %d: %s", query_str.str,
6233
mysql_errno(mysql), mysql_error(mysql));
6240
query= (char*)"CALL mysqltest_tmp_sp()";
6241
query_len = strlen(query);
6243
dynstr_free(&query_str);
5269
6246
if (display_result_sorted)
5272
Collect the query output in a separate string
5273
that can be sorted before it's added to the
5274
global result string
6249
Collect the query output in a separate string
6250
that can be sorted before it's added to the
6251
global result string
6253
init_dynamic_string(&ds_sorted, "", 1024, 1024);
5276
6254
save_ds= ds; /* Remember original ds */
5277
6255
ds= &ds_sorted;
6259
Find out how to run this query
5281
6261
Always run with normal C API if it's not a complete
6264
If it is a '?' in the query it may be a SQL level prepared
6265
statement already and we can't do it twice
5284
run_query_normal(cn, command, flags, query, query_len,
6267
if (ps_protocol_enabled &&
6269
match_re(&ps_re, query))
6270
run_query_stmt(mysql, command, query, query_len, ds, &ds_warnings);
6272
run_query_normal(cn, command, flags, query, query_len,
5287
6275
if (display_result_sorted)
5289
6277
/* Sort the result set and append it to result */
5290
append_sorted(save_ds, &ds_sorted);
6278
dynstr_append_sorted(save_ds, &ds_sorted);
6280
dynstr_free(&ds_sorted);
6285
if (util_query(mysql, "DROP PROCEDURE mysqltest_tmp_sp "))
6286
die("Failed to drop sp: %d: %s", mysql_errno(mysql), mysql_error(mysql));
6291
if (util_query(mysql, "DROP VIEW mysqltest_tmp_v "))
6292
die("Failed to drop view: %d: %s",
6293
mysql_errno(mysql), mysql_error(mysql));
5294
6296
if (command->require_file[0])
6026
7183
for (i= 1,pos= word_end_chars ; i < 256 ; i++)
6027
7184
if (my_isspace(charset_info,i))
6029
*pos=0; /* End pointer */
7186
*pos=0; /* End pointer */
6030
7187
if (!(glob_replace= init_replace((char**) from_array.typelib.type_names,
6031
(char**) to_array.typelib.type_names,
6032
(uint) from_array.typelib.count,
7188
(char**) to_array.typelib.type_names,
7189
(uint) from_array.typelib.count,
6034
7191
die("Can't initialize replace from '%s'", command->query);
6035
7192
free_pointer_array(&from_array);
6036
7193
free_pointer_array(&to_array);
7194
my_free(start, MYF(0));
6038
7195
command->last_argument= command->end;
6043
7200
void free_replace()
7202
DBUG_ENTER("free_replace");
6046
7203
if (glob_replace)
7205
my_free(glob_replace,MYF(0));
6049
7206
glob_replace=0;
6055
7212
typedef struct st_replace {
6057
7214
struct st_replace *next[256];
6060
7217
typedef struct st_replace_found {
6062
7219
char *replace_string;
6063
7220
uint to_offset;
6064
7221
int from_offset;
6065
7222
} REPLACE_STRING;
6068
void replace_strings_append(REPLACE *rep, string* ds,
6069
const char *str, int len)
7225
void replace_strings_append(REPLACE *rep, DYNAMIC_STRING* ds,
7227
int len __attribute__((unused)))
6071
7229
register REPLACE *rep_pos;
6072
7230
register REPLACE_STRING *rep_str;
6073
7231
const char *start, *from;
7232
DBUG_ENTER("replace_strings_append");
6076
7234
start= from= str;
6080
7238
/* Loop through states */
7239
DBUG_PRINT("info", ("Looping through states"));
6081
7240
while (!rep_pos->found)
6082
rep_pos= rep_pos->next[(unsigned char) *from++];
7241
rep_pos= rep_pos->next[(uchar) *from++];
6084
7243
/* Does this state contain a string to be replaced */
6085
7244
if (!(rep_str = ((REPLACE_STRING*) rep_pos))->replace_string)
6087
7246
/* No match found */
6088
ds->append(start, from - start - 1);
7247
dynstr_append_mem(ds, start, from - start - 1);
7248
DBUG_PRINT("exit", ("Found no more string to replace, appended: %s", start));
7252
/* Found a string that needs to be replaced */
7253
DBUG_PRINT("info", ("found: %d, to_offset: %d, from_offset: %d, string: %s",
7254
rep_str->found, rep_str->to_offset,
7255
rep_str->from_offset, rep_str->replace_string));
6092
7257
/* Append part of original string before replace string */
6093
ds->append(start, (from - rep_str->to_offset) - start);
7258
dynstr_append_mem(ds, start, (from - rep_str->to_offset) - start);
6095
7260
/* Append replace string */
6096
ds->append(rep_str->replace_string,
6097
strlen(rep_str->replace_string));
7261
dynstr_append_mem(ds, rep_str->replace_string,
7262
strlen(rep_str->replace_string));
6099
7264
if (!*(from-=rep_str->from_offset) && rep_pos->found != 2)
6102
assert(from <= str+len);
7266
/* End of from string */
7267
DBUG_PRINT("exit", ("Found end of from string"));
7270
DBUG_ASSERT(from <= str+len);
6382
7550
icase - flag, if set to 1 the match is case insensitive
6384
7552
int reg_replace(char** buf_p, int* buf_len_p, char *pattern,
6385
char *replace, char *in_string, int icase)
7553
char *replace, char *string, int icase)
6387
string string_to_match(in_string);
6388
pcrecpp::RE_Options opt;
7556
my_regmatch_t *subs;
7560
int buf_len, need_buf_len;
7561
int cflags= REG_EXTENDED;
7563
char *res_p,*str_p,*str_end;
7565
buf_len= *buf_len_p;
7566
len= strlen(string);
7567
str_end= string + len;
7569
/* start with a buffer of a reasonable size that hopefully will not
7570
need to be reallocated
7572
need_buf_len= len * 2 + 1;
6391
opt.set_caseless(true);
6393
if (!pcrecpp::RE(pattern, opt).Replace(replace,&string_to_match)){
6397
const char * new_str= string_to_match.c_str();
6398
*buf_len_p= strlen(new_str);
6399
char * new_buf = (char *)malloc(*buf_len_p+1);
6400
if (new_buf == NULL)
6404
strcpy(new_buf, new_str);
7580
if ((err_code= my_regcomp(&r,pattern,cflags,&my_charset_latin1)))
7582
check_regerr(&r,err_code);
7586
subs= (my_regmatch_t*)my_malloc(sizeof(my_regmatch_t) * (r.re_nsub+1),
7587
MYF(MY_WME+MY_FAE));
7591
replace_end= replace + strlen(replace);
7593
/* for each pattern match instance perform a replacement */
7596
/* find the match */
7597
err_code= my_regexec(&r,str_p, r.re_nsub+1, subs,
7598
(str_p == string) ? REG_NOTBOL : 0);
7600
/* if regular expression error (eg. bad syntax, or out of memory) */
7601
if (err_code && err_code != REG_NOMATCH)
7603
check_regerr(&r,err_code);
7608
/* if match found */
7611
char* expr_p= replace;
7615
we need at least what we have so far in the buffer + the part
7618
need_buf_len= (res_p - buf) + (int) subs[0].rm_so;
7620
/* on this pass, calculate the memory for the result buffer */
7621
while (expr_p < replace_end)
7623
int back_ref_num= -1;
7626
if (c == '\\' && expr_p + 1 < replace_end)
7628
back_ref_num= (int) (expr_p[1] - '0');
7631
/* found a valid back_ref (eg. \1)*/
7632
if (back_ref_num >= 0 && back_ref_num <= (int)r.re_nsub)
7634
regoff_t start_off, end_off;
7635
if ((start_off=subs[back_ref_num].rm_so) > -1 &&
7636
(end_off=subs[back_ref_num].rm_eo) > -1)
7638
need_buf_len += (int) (end_off - start_off);
7650
now that we know the size of the buffer,
7651
make sure it is big enough
7655
/* copy the pre-match part */
7658
memcpy(res_p, str_p, (size_t) subs[0].rm_so);
7659
res_p+= subs[0].rm_so;
7664
/* copy the match and expand back_refs */
7665
while (expr_p < replace_end)
7667
int back_ref_num= -1;
7670
if (c == '\\' && expr_p + 1 < replace_end)
7672
back_ref_num= expr_p[1] - '0';
7675
if (back_ref_num >= 0 && back_ref_num <= (int)r.re_nsub)
7677
regoff_t start_off, end_off;
7678
if ((start_off=subs[back_ref_num].rm_so) > -1 &&
7679
(end_off=subs[back_ref_num].rm_eo) > -1)
7681
int block_len= (int) (end_off - start_off);
7682
memcpy(res_p,str_p + start_off, block_len);
7689
*res_p++ = *expr_p++;
7693
/* handle the post-match part */
7694
if (subs[0].rm_so == subs[0].rm_eo)
7696
if (str_p + subs[0].rm_so >= str_end)
7698
str_p += subs[0].rm_eo ;
7699
*res_p++ = *str_p++;
7703
str_p += subs[0].rm_eo;
7706
else /* no match this time, just copy the string as is */
7708
int left_in_str= str_end-str_p;
7709
need_buf_len= (res_p-buf) + left_in_str;
7711
memcpy(res_p,str_p,left_in_str);
7712
res_p += left_in_str;
7716
my_free(subs, MYF(0));
7720
*buf_len_p= buf_len;
6614
7928
for (set_nr=0,pos=0 ; set_nr < sets.count ; set_nr++)
6616
7930
set=sets.set+set_nr;
6617
default_state= 0; /* Start from beginning */
7931
default_state= 0; /* Start from beginning */
6619
7933
/* If end of found-string not found or start-set with current set */
6621
for (i= UINT32_MAX; (i=get_next_bit(set,i)) ;)
7935
for (i= (uint) ~0; (i=get_next_bit(set,i)) ;)
6623
7937
if (!follow[i].chr)
6625
if (! default_state)
6626
default_state= find_found(found_set,set->table_offset,
6627
set->found_offset+1);
7939
if (! default_state)
7940
default_state= find_found(found_set,set->table_offset,
7941
set->found_offset+1);
6630
copy_bits(sets.set+used_sets,set); /* Save set for changes */
7944
copy_bits(sets.set+used_sets,set); /* Save set for changes */
6631
7945
if (!default_state)
6632
or_bits(sets.set+used_sets,sets.set); /* Can restart from start */
7946
or_bits(sets.set+used_sets,sets.set); /* Can restart from start */
6634
7948
/* Find all chars that follows current sets */
6635
memset(used_chars, 0, sizeof(used_chars));
6636
for (i= UINT32_MAX; (i=get_next_bit(sets.set+used_sets,i)) ;)
7949
bzero((char*) used_chars,sizeof(used_chars));
7950
for (i= (uint) ~0; (i=get_next_bit(sets.set+used_sets,i)) ;)
6638
7952
used_chars[follow[i].chr]=1;
6639
7953
if ((follow[i].chr == SPACE_CHAR && !follow[i+1].chr &&
6640
follow[i].len > 1) || follow[i].chr == END_OF_LINE)
7954
follow[i].len > 1) || follow[i].chr == END_OF_LINE)
6644
7958
/* Mark word_chars used if \b is in state */
6645
7959
if (used_chars[SPACE_CHAR])
6646
7960
for (pos= word_end_chars ; *pos ; pos++)
6647
used_chars[(int) (unsigned char) *pos] = 1;
7961
used_chars[(int) (uchar) *pos] = 1;
6649
7963
/* Handle other used characters */
6650
7964
for (chr= 0 ; chr < 256 ; chr++)
6652
7966
if (! used_chars[chr])
6653
set->next[chr]= chr ? default_state : -1;
7967
set->next[chr]= chr ? default_state : -1;
6656
new_set=make_new_set(&sets);
6657
set=sets.set+set_nr; /* if realloc */
6658
new_set->table_offset=set->table_offset;
6659
new_set->found_len=set->found_len;
6660
new_set->found_offset=set->found_offset+1;
7970
new_set=make_new_set(&sets);
7971
set=sets.set+set_nr; /* if realloc */
7972
new_set->table_offset=set->table_offset;
7973
new_set->found_len=set->found_len;
7974
new_set->found_offset=set->found_offset+1;
6663
for (i= UINT32_MAX ; (i=get_next_bit(sets.set+used_sets,i)) ; )
6665
if (!follow[i].chr || follow[i].chr == chr ||
6666
(follow[i].chr == SPACE_CHAR &&
6667
(is_word_end[chr] ||
6668
(!chr && follow[i].len > 1 && ! follow[i+1].chr))) ||
6669
(follow[i].chr == END_OF_LINE && ! chr))
6671
if ((! chr || (follow[i].chr && !follow[i+1].chr)) &&
6672
follow[i].len > found_end)
6673
found_end=follow[i].len;
6674
if (chr && follow[i].chr)
6675
internal_set_bit(new_set,i+1); /* To next set */
6677
internal_set_bit(new_set,i);
6682
new_set->found_len=0; /* Set for testing if first */
6684
for (i= UINT32_MAX; (i=get_next_bit(new_set,i)) ;)
6686
if ((follow[i].chr == SPACE_CHAR ||
6687
follow[i].chr == END_OF_LINE) && ! chr)
6691
if (follow[bit_nr-1].len < found_end ||
6692
(new_set->found_len &&
6693
(chr == 0 || !follow[bit_nr].chr)))
6694
internal_clear_bit(new_set,i);
6697
if (chr == 0 || !follow[bit_nr].chr)
6699
new_set->table_offset=follow[bit_nr].table_offset;
6700
if (chr || (follow[i].chr == SPACE_CHAR ||
6701
follow[i].chr == END_OF_LINE))
6702
new_set->found_offset=found_end; /* New match */
6703
new_set->found_len=found_end;
6710
set->next[chr] = find_found(found_set,
6711
new_set->table_offset,
6712
new_set->found_offset);
6713
free_last_set(&sets);
6716
set->next[chr] = find_set(&sets,new_set);
6719
set->next[chr] = find_set(&sets,new_set);
7977
for (i= (uint) ~0 ; (i=get_next_bit(sets.set+used_sets,i)) ; )
7979
if (!follow[i].chr || follow[i].chr == chr ||
7980
(follow[i].chr == SPACE_CHAR &&
7981
(is_word_end[chr] ||
7982
(!chr && follow[i].len > 1 && ! follow[i+1].chr))) ||
7983
(follow[i].chr == END_OF_LINE && ! chr))
7985
if ((! chr || (follow[i].chr && !follow[i+1].chr)) &&
7986
follow[i].len > found_end)
7987
found_end=follow[i].len;
7988
if (chr && follow[i].chr)
7989
internal_set_bit(new_set,i+1); /* To next set */
7991
internal_set_bit(new_set,i);
7996
new_set->found_len=0; /* Set for testing if first */
7998
for (i= (uint) ~0; (i=get_next_bit(new_set,i)) ;)
8000
if ((follow[i].chr == SPACE_CHAR ||
8001
follow[i].chr == END_OF_LINE) && ! chr)
8005
if (follow[bit_nr-1].len < found_end ||
8006
(new_set->found_len &&
8007
(chr == 0 || !follow[bit_nr].chr)))
8008
internal_clear_bit(new_set,i);
8011
if (chr == 0 || !follow[bit_nr].chr)
8013
new_set->table_offset=follow[bit_nr].table_offset;
8014
if (chr || (follow[i].chr == SPACE_CHAR ||
8015
follow[i].chr == END_OF_LINE))
8016
new_set->found_offset=found_end; /* New match */
8017
new_set->found_len=found_end;
8024
set->next[chr] = find_found(found_set,
8025
new_set->table_offset,
8026
new_set->found_offset);
8027
free_last_set(&sets);
8030
set->next[chr] = find_set(&sets,new_set);
8033
set->next[chr] = find_set(&sets,new_set);