363
365
char *query, *query_buf,*first_argument,*last_argument,*end;
364
366
int first_word_len, query_len;
367
my_bool abort_on_error;
366
368
struct st_expected_errors expected_errors;
367
369
char require_file[FN_REFLEN];
368
370
enum enum_commands type;
371
373
TYPELIB command_typelib= {array_elements(command_names),"",
374
string ds_res, ds_progress, ds_warning_messages;
376
DYNAMIC_STRING ds_res, ds_progress, ds_warning_messages;
376
378
char builtin_echo[FN_REFLEN];
378
380
void die(const char *fmt, ...)
379
__attribute__((format(printf, 1, 2)));
381
ATTRIBUTE_FORMAT(printf, 1, 2);
380
382
void abort_not_supported_test(const char *fmt, ...)
381
__attribute__((format(printf, 1, 2)));
383
ATTRIBUTE_FORMAT(printf, 1, 2);
382
384
void verbose_msg(const char *fmt, ...)
383
__attribute__((format(printf, 1, 2)));
385
ATTRIBUTE_FORMAT(printf, 1, 2);
384
386
void warning_msg(const char *fmt, ...)
385
__attribute__((format(printf, 1, 2)));
387
ATTRIBUTE_FORMAT(printf, 1, 2);
386
388
void log_msg(const char *fmt, ...)
387
__attribute__((format(printf, 1, 2)));
389
ATTRIBUTE_FORMAT(printf, 1, 2);
389
391
VAR* var_from_env(const char *, const char *);
390
392
VAR* var_init(VAR* v, const char *name, int name_len, const char *val,
392
394
void var_free(void* v);
393
395
VAR* var_get(const char *var_name, const char** var_name_end,
394
bool raw, bool ignore_not_existing);
396
my_bool raw, my_bool ignore_not_existing);
395
397
void eval_expr(VAR* v, const char *p, const char** p_end);
396
bool match_delimiter(int c, const char *delim, uint length);
398
my_bool match_delimiter(int c, const char *delim, uint length);
397
399
void dump_result_to_reject_file(char *buf, int size);
398
void dump_result_to_log_file(const char *buf, int size);
400
void dump_result_to_log_file(char *buf, int size);
399
401
void dump_warning_messages(void);
400
402
void dump_progress(void);
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);
404
void do_eval(DYNAMIC_STRING *query_eval, const char *query,
405
const char *query_end, my_bool pass_through_escape_chars);
406
void str_to_file(const char *fname, char *str, int size);
407
void str_to_file2(const char *fname, char *str, int size, my_bool append);
407
409
/* For replace_column */
408
410
static char *replace_column[MAX_COLUMNS];
428
430
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);
433
void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
435
void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val);
436
void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val);
437
void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING* ds_input);
437
439
void handle_error(struct st_command*,
438
440
unsigned int err_errno, const char *err_error,
439
const char *err_sqlstate, string *ds);
441
const char *err_sqlstate, DYNAMIC_STRING *ds);
440
442
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)
444
#ifdef EMBEDDED_LIBRARY
446
/* attributes of the query thread */
447
pthread_attr_t cn_thd_attrib;
450
send_one_query executes query in separate thread, which is
451
necessary in embedded library to run 'send' in proper way.
452
This implementation doesn't handle errors returned
453
by mysql_send_query. It's technically possible, though
454
I don't see where it is needed.
456
pthread_handler_t send_one_query(void *arg)
458
struct st_connection *cn= (struct st_connection*)arg;
461
VOID(mysql_send_query(&cn->mysql, cn->cur_query, cn->cur_query_len));
464
pthread_mutex_lock(&cn->mutex);
466
VOID(pthread_cond_signal(&cn->cond));
467
pthread_mutex_unlock(&cn->mutex);
472
static int do_send_query(struct st_connection *cn, const char *q, int q_len,
477
if (flags & QUERY_REAP_FLAG)
478
return mysql_send_query(&cn->mysql, q, q_len);
480
if (pthread_mutex_init(&cn->mutex, NULL) ||
481
pthread_cond_init(&cn->cond, NULL))
482
die("Error in the thread library");
485
cn->cur_query_len= q_len;
487
if (pthread_create(&tid, &cn_thd_attrib, send_one_query, (void*)cn))
488
die("Cannot start new thread for query");
493
static void wait_query_thread_end(struct st_connection *con)
495
if (!con->query_done)
497
pthread_mutex_lock(&con->mutex);
498
while (!con->query_done)
499
pthread_cond_wait(&con->cond, &con->mutex);
500
pthread_mutex_unlock(&con->mutex);
504
#else /*EMBEDDED_LIBRARY*/
506
#define do_send_query(cn,q,q_len,flags) mysql_send_query(&cn->mysql, q, q_len)
508
#endif /*EMBEDDED_LIBRARY*/
510
void do_eval(DYNAMIC_STRING *query_eval, const char *query,
511
const char *query_end, my_bool pass_through_escape_chars)
449
514
register char c, next_c;
450
515
register int escaped = 0;
517
DBUG_ENTER("do_eval");
454
519
for (p= query; (c= *p) && p < query_end; ++p)
1864
1941
int col_no= -1;
1866
DRIZZLE *drizzle= &cur_con->drizzle;
1943
MYSQL* mysql= &cur_con->mysql;
1945
static DYNAMIC_STRING ds_query;
1946
static DYNAMIC_STRING ds_col;
1947
static DYNAMIC_STRING ds_row;
1871
1948
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"}
1949
{"query", ARG_STRING, TRUE, &ds_query, "Query to run"},
1950
{"column name", ARG_STRING, TRUE, &ds_col, "Name of column"},
1951
{"row number", ARG_STRING, TRUE, &ds_row, "Number for row"}
1954
DBUG_ENTER("var_set_query_get_value");
1879
1956
strip_parentheses(command);
1957
DBUG_PRINT("info", ("query: %s", command->query));
1880
1958
check_command_args(command, command->first_argument, query_get_value_args,
1881
1959
sizeof(query_get_value_args)/sizeof(struct command_arg),
1962
DBUG_PRINT("info", ("query: %s", ds_query.str));
1963
DBUG_PRINT("info", ("col: %s", ds_col.str));
1884
1965
/* 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());
1966
if (!str2int(ds_row.str, 10, (long) 0, (long) INT_MAX, &row_no))
1967
die("Invalid row number: '%s'", ds_row.str);
1968
DBUG_PRINT("info", ("row: %s, row_no: %ld", ds_row.str, row_no));
1969
dynstr_free(&ds_row);
1888
1971
/* 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;
1972
if (strip_surrounding(ds_query.str, '"', '"'))
1973
die("Mismatched \"'s around query '%s'", ds_query.str);
1895
1975
/* 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());
1976
if (mysql_real_query(mysql, ds_query.str, ds_query.length))
1977
die("Error running query '%s': %d %s", ds_query.str,
1978
mysql_errno(mysql), mysql_error(mysql));
1979
if (!(res= mysql_store_result(mysql)))
1980
die("Query '%s' didn't return a result set", ds_query.str);
1903
1983
/* 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);
1985
uint num_fields= mysql_num_fields(res);
1986
MYSQL_FIELD *fields= mysql_fetch_fields(res);
1908
1988
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())
1990
if (strcmp(fields[i].name, ds_col.str) == 0 &&
1991
strlen(fields[i].name) == ds_col.length)
3066
3258
when ndb binlog is on, this call will wait until last updated epoch
3067
(locally in the drizzled) has been received into the binlog
3259
(locally in the mysqld) has been received into the binlog
3069
3261
static int do_save_master_pos(void)
3073
DRIZZLE *drizzle= &cur_con->drizzle;
3265
MYSQL *mysql = &cur_con->mysql;
3074
3266
const char *query;
3077
if (drizzle_query(drizzle, query= "show master status"))
3267
DBUG_ENTER("do_save_master_pos");
3269
#ifdef HAVE_NDB_BINLOG
3271
Wait for ndb binlog to be up-to-date with all changes
3272
done on the local mysql server
3275
ulong have_ndbcluster;
3276
if (mysql_query(mysql, query= "show variables like 'have_ndbcluster'"))
3277
die("'%s' failed: %d %s", query,
3278
mysql_errno(mysql), mysql_error(mysql));
3279
if (!(res= mysql_store_result(mysql)))
3280
die("mysql_store_result() returned NULL for '%s'", query);
3281
if (!(row= mysql_fetch_row(res)))
3282
die("Query '%s' returned empty result", query);
3284
have_ndbcluster= strcmp("YES", row[1]) == 0;
3285
mysql_free_result(res);
3287
if (have_ndbcluster)
3289
ulonglong start_epoch= 0, handled_epoch= 0,
3290
latest_epoch=0, latest_trans_epoch=0,
3291
latest_handled_binlog_epoch= 0, latest_received_binlog_epoch= 0,
3292
latest_applied_binlog_epoch= 0;
3297
const char binlog[]= "binlog";
3298
const char latest_epoch_str[]=
3300
const char latest_trans_epoch_str[]=
3301
"latest_trans_epoch=";
3302
const char latest_received_binlog_epoch_str[]=
3303
"latest_received_binlog_epoch";
3304
const char latest_handled_binlog_epoch_str[]=
3305
"latest_handled_binlog_epoch=";
3306
const char latest_applied_binlog_epoch_str[]=
3307
"latest_applied_binlog_epoch=";
3310
if (mysql_query(mysql, query= "show engine ndb status"))
3311
die("failed in '%s': %d %s", query,
3312
mysql_errno(mysql), mysql_error(mysql));
3313
if (!(res= mysql_store_result(mysql)))
3314
die("mysql_store_result() returned NULL for '%s'", query);
3315
while ((row= mysql_fetch_row(res)))
3317
if (strcmp(row[1], binlog) == 0)
3319
const char *status= row[2];
3322
while (*status && strncmp(status, latest_epoch_str,
3323
sizeof(latest_epoch_str)-1))
3327
status+= sizeof(latest_epoch_str)-1;
3328
latest_epoch= strtoull(status, (char**) 0, 10);
3331
die("result does not contain '%s' in '%s'",
3332
latest_epoch_str, query);
3333
/* latest_trans_epoch */
3334
while (*status && strncmp(status, latest_trans_epoch_str,
3335
sizeof(latest_trans_epoch_str)-1))
3339
status+= sizeof(latest_trans_epoch_str)-1;
3340
latest_trans_epoch= strtoull(status, (char**) 0, 10);
3343
die("result does not contain '%s' in '%s'",
3344
latest_trans_epoch_str, query);
3345
/* latest_received_binlog_epoch */
3347
strncmp(status, latest_received_binlog_epoch_str,
3348
sizeof(latest_received_binlog_epoch_str)-1))
3352
status+= sizeof(latest_received_binlog_epoch_str)-1;
3353
latest_received_binlog_epoch= strtoull(status, (char**) 0, 10);
3356
die("result does not contain '%s' in '%s'",
3357
latest_received_binlog_epoch_str, query);
3358
/* latest_handled_binlog */
3360
strncmp(status, latest_handled_binlog_epoch_str,
3361
sizeof(latest_handled_binlog_epoch_str)-1))
3365
status+= sizeof(latest_handled_binlog_epoch_str)-1;
3366
latest_handled_binlog_epoch= strtoull(status, (char**) 0, 10);
3369
die("result does not contain '%s' in '%s'",
3370
latest_handled_binlog_epoch_str, query);
3371
/* latest_applied_binlog_epoch */
3373
strncmp(status, latest_applied_binlog_epoch_str,
3374
sizeof(latest_applied_binlog_epoch_str)-1))
3378
status+= sizeof(latest_applied_binlog_epoch_str)-1;
3379
latest_applied_binlog_epoch= strtoull(status, (char**) 0, 10);
3382
die("result does not contain '%s' in '%s'",
3383
latest_applied_binlog_epoch_str, query);
3385
start_epoch= latest_trans_epoch;
3390
die("result does not contain '%s' in '%s'",
3392
if (latest_handled_binlog_epoch > handled_epoch)
3394
handled_epoch= latest_handled_binlog_epoch;
3396
if (latest_handled_binlog_epoch >= start_epoch)
3398
else if (count > 30)
3402
mysql_free_result(res);
3407
if (mysql_query(mysql, query= "show master status"))
3078
3408
die("failed in 'show master status': %d %s",
3079
drizzle_errno(drizzle), drizzle_error(drizzle));
3409
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)))
3411
if (!(res = mysql_store_result(mysql)))
3412
die("mysql_store_result() retuned NULL for '%s'", query);
3413
if (!(row = mysql_fetch_row(res)))
3084
3414
die("empty result in show master status");
3085
my_stpncpy(master_pos.file, row[0], sizeof(master_pos.file)-1);
3415
strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1);
3086
3416
master_pos.pos = strtoul(row[1], (char**) 0, 10);
3087
drizzle_free_result(res);
3417
mysql_free_result(res);
3637
4022
Log the connect to result log
3639
ds_res.append("connect(");
3640
replace_append(&ds_res, host);
3642
replace_append(&ds_res, user);
3644
replace_append(&ds_res, pass);
4024
dynstr_append_mem(ds, "connect(", 8);
4025
replace_dynstr_append(ds, host);
4026
dynstr_append_mem(ds, ",", 1);
4027
replace_dynstr_append(ds, user);
4028
dynstr_append_mem(ds, ",", 1);
4029
replace_dynstr_append(ds, pass);
4030
dynstr_append_mem(ds, ",", 1);
3647
replace_append(&ds_res, db);
3649
replace_append_uint(&ds_res, port);
4032
replace_dynstr_append(ds, db);
4033
dynstr_append_mem(ds, ",", 1);
4034
replace_dynstr_append_uint(ds, port);
4035
dynstr_append_mem(ds, ",", 1);
3652
replace_append(&ds_res, sock);
3654
ds_res.append(delimiter);
3655
ds_res.append("\n");
4037
replace_dynstr_append(ds, sock);
4038
dynstr_append_mem(ds, ")", 1);
4039
dynstr_append_mem(ds, delimiter, delimiter_length);
4040
dynstr_append_mem(ds, "\n", 1);
3657
if (!drizzle_connect(con, host, user, pass, db, port, 0,
3658
CLIENT_MULTI_STATEMENTS))
4042
if (!mysql_real_connect(con, host, user, pass, db, port, 0,
4043
CLIENT_MULTI_STATEMENTS))
3660
var_set_errno(drizzle_errno(con));
3661
handle_error(command, drizzle_errno(con), drizzle_error(con),
3662
drizzle_sqlstate(con), &ds_res);
4045
var_set_errno(mysql_errno(con));
4046
handle_error(command, mysql_errno(con), mysql_error(con),
4047
mysql_sqlstate(con), ds);
3663
4048
return 0; /* Not connected */
3689
4074
<port> - server port
3690
4075
<sock> - server socket
3691
4076
<opts> - options to use for the connection
3692
* SSL - use SSL if available
3693
* COMPRESS - use compression if available
4077
* SSL - use SSL if available
4078
* COMPRESS - use compression if available
3697
4082
static void do_connect(struct st_command *command)
3699
4084
int con_port= opt_port;
3700
const char *con_options;
3701
bool con_ssl= 0, con_compress= 0;
4086
my_bool con_ssl= 0, con_compress= 0;
3702
4087
struct st_connection* con_slot;
3704
string ds_connection_name;
4089
static DYNAMIC_STRING ds_connection_name;
4090
static DYNAMIC_STRING ds_host;
4091
static DYNAMIC_STRING ds_user;
4092
static DYNAMIC_STRING ds_password;
4093
static DYNAMIC_STRING ds_database;
4094
static DYNAMIC_STRING ds_port;
4095
static DYNAMIC_STRING ds_sock;
4096
static DYNAMIC_STRING ds_options;
3712
4097
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" }
4098
{ "connection name", ARG_STRING, TRUE, &ds_connection_name, "Name of the connection" },
4099
{ "host", ARG_STRING, TRUE, &ds_host, "Host to connect to" },
4100
{ "user", ARG_STRING, FALSE, &ds_user, "User to connect as" },
4101
{ "passsword", ARG_STRING, FALSE, &ds_password, "Password used when connecting" },
4102
{ "database", ARG_STRING, FALSE, &ds_database, "Database to select after connect" },
4103
{ "port", ARG_STRING, FALSE, &ds_port, "Port to connect to" },
4104
{ "socket", ARG_STRING, FALSE, &ds_sock, "Socket to connect with" },
4105
{ "options", ARG_STRING, FALSE, &ds_options, "Options to use while connecting" }
4108
DBUG_ENTER("do_connect");
4109
DBUG_PRINT("enter",("connect: %s", command->first_argument));
3724
4111
strip_parentheses(command);
3725
4112
check_command_args(command, command->first_argument, connect_args,
3786
4178
(int) (sizeof(connections)/sizeof(struct st_connection)));
3789
if (!drizzle_create(&con_slot->drizzle))
3790
die("Failed on drizzle_create()");
4181
#ifdef EMBEDDED_LIBRARY
4182
con_slot->query_done= 1;
4184
if (!mysql_init(&con_slot->mysql))
4185
die("Failed on mysql_init()");
3791
4186
if (opt_compress || con_compress)
3792
drizzle_options(&con_slot->drizzle, DRIZZLE_OPT_COMPRESS, NULL);
3793
drizzle_options(&con_slot->drizzle, DRIZZLE_OPT_LOCAL_INFILE, 0);
4187
mysql_options(&con_slot->mysql, MYSQL_OPT_COMPRESS, NullS);
4188
mysql_options(&con_slot->mysql, MYSQL_OPT_LOCAL_INFILE, 0);
4189
mysql_options(&con_slot->mysql, MYSQL_SET_CHARSET_NAME,
4190
charset_info->csname);
4191
int opt_protocol= MYSQL_PROTOCOL_TCP;
4192
mysql_options(&con_slot->mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
4193
if (opt_charsets_dir)
4194
mysql_options(&con_slot->mysql, MYSQL_SET_CHARSET_DIR,
3795
4197
/* Use default db name */
3796
if (ds_database.length() == 0)
3797
ds_database= opt_db;
4198
if (ds_database.length == 0)
4199
dynstr_set(&ds_database, opt_db);
3799
4201
/* Special database to allow one to connect without a database name */
3800
if (ds_database.length() && !strcmp(ds_database.c_str(),"*NO-ONE*"))
4202
if (ds_database.length && !strcmp(ds_database.str,"*NO-ONE*"))
4203
dynstr_set(&ds_database, "");
3803
if (connect_n_handle_errors(command, &con_slot->drizzle,
3804
ds_host.c_str(),ds_user.c_str(),
3805
ds_password.c_str(), ds_database.c_str(),
3806
con_port, ds_sock.c_str()))
4205
if (connect_n_handle_errors(command, &con_slot->mysql,
4206
ds_host.str,ds_user.str,
4207
ds_password.str, ds_database.str,
4208
con_port, ds_sock.str))
3808
if (!(con_slot->name= strdup(ds_connection_name.c_str())))
4210
DBUG_PRINT("info", ("Inserting connection %s in connection pool",
4211
ds_connection_name.str));
4212
if (!(con_slot->name= my_strdup(ds_connection_name.str, MYF(MY_WME))))
3809
4213
die("Out of memory");
3810
4214
cur_con= con_slot;
3812
4216
if (con_slot == next_con)
3813
4217
next_con++; /* if we used the next_con slot, advance the pointer */
3816
/* Update $drizzle_get_server_version to that of current connection */
3817
var_set_drizzle_get_server_version(&cur_con->drizzle);
4220
/* Update $mysql_get_server_version to that of current connection */
4221
var_set_mysql_get_server_version(&cur_con->mysql);
4223
dynstr_free(&ds_connection_name);
4224
dynstr_free(&ds_host);
4225
dynstr_free(&ds_user);
4226
dynstr_free(&ds_password);
4227
dynstr_free(&ds_database);
4228
dynstr_free(&ds_port);
4229
dynstr_free(&ds_sock);
4230
dynstr_free(&ds_options);
4422
4865
{"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
4423
4866
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},
4867
{"basedir", 'b', "Basedir for tests.", (uchar**) &opt_basedir,
4868
(uchar**) &opt_basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4426
4869
{"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},
4870
"Directory where character sets are.", (uchar**) &opt_charsets_dir,
4871
(uchar**) &opt_charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4429
4872
{"compress", 'C', "Use the compressed server/client protocol.",
4430
(char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
4873
(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,
4875
{"database", 'D', "Database to use.", (uchar**) &opt_db, (uchar**) &opt_db, 0,
4433
4876
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4878
{"debug", '#', "This is a non-debug version. Catch this and exit",
4879
0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0},
4881
{"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",
4882
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
4434
4884
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
4435
(char**) &debug_check_flag, (char**) &debug_check_flag, 0,
4885
(uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0,
4436
4886
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4437
4887
{"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
4438
(char**) &debug_info_flag, (char**) &debug_info_flag,
4888
(uchar**) &debug_info_flag, (uchar**) &debug_info_flag,
4439
4889
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4440
{"host", 'h', "Connect to host.", (char**) &opt_host, (char**) &opt_host, 0,
4890
{"host", 'h', "Connect to host.", (uchar**) &opt_host, (uchar**) &opt_host, 0,
4441
4891
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},
4892
{"include", 'i', "Include SQL before each test case.", (uchar**) &opt_include,
4893
(uchar**) &opt_include, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4894
{"logdir", OPT_LOG_DIR, "Directory for log files", (uchar**) &opt_logdir,
4895
(uchar**) &opt_logdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4446
4896
{"mark-progress", OPT_MARK_PROGRESS,
4447
4897
"Write linenumber and elapsed time to <testname>.progress ",
4448
(char**) &opt_mark_progress, (char**) &opt_mark_progress, 0,
4898
(uchar**) &opt_mark_progress, (uchar**) &opt_mark_progress, 0,
4449
4899
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4450
4900
{"max-connect-retries", OPT_MAX_CONNECT_RETRIES,
4451
4901
"Max number of connection attempts when connecting to server",
4452
(char**) &opt_max_connect_retries, (char**) &opt_max_connect_retries, 0,
4902
(uchar**) &opt_max_connect_retries, (uchar**) &opt_max_connect_retries, 0,
4453
4903
GET_INT, REQUIRED_ARG, 500, 1, 10000, 0, 0, 0},
4454
4904
{"password", 'p', "Password to use when connecting to server.",
4455
4905
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
4456
4906
{"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},
4907
"order of preference, my.cnf, $MYSQL_TCP_PORT, "
4908
#if MYSQL_PORT_DEFAULT == 0
4911
"built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
4912
(uchar**) &opt_port,
4913
(uchar**) &opt_port, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4914
{"quiet", 's', "Suppress all normal output.", (uchar**) &silent,
4915
(uchar**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4463
4916
{"record", 'r', "Record output of test_file into result file.",
4464
4917
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
4465
4918
{"result-file", 'R', "Read/Store result from/in this file.",
4466
(char**) &result_file_name, (char**) &result_file_name, 0,
4919
(uchar**) &result_file_name, (uchar**) &result_file_name, 0,
4467
4920
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4468
4921
{"server-arg", 'A', "Send option value to embedded server as a parameter.",
4469
4922
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4470
4923
{"server-file", 'F', "Read embedded server arguments from file.",
4471
4924
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4472
4925
{"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},
4926
(uchar**) &silent, (uchar**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4474
4927
{"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,
4928
(uchar**) &opt_sleep, (uchar**) &opt_sleep, 0, GET_INT, REQUIRED_ARG, -1, -1, 0,
4477
4930
{"tail-lines", OPT_TAIL_LINES,
4478
4931
"Number of lines of the resul to include in a failure report",
4479
(char**) &opt_tail_lines, (char**) &opt_tail_lines, 0,
4932
(uchar**) &opt_tail_lines, (uchar**) &opt_tail_lines, 0,
4480
4933
GET_INT, REQUIRED_ARG, 0, 0, 10000, 0, 0, 0},
4481
4934
{"test-file", 'x', "Read test from/in this file (default stdin).",
4482
4935
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4809
5272
Append metadata for fields to output
4812
static void append_metadata(string *ds,
4813
const DRIZZLE_FIELD *field,
5275
static void append_metadata(DYNAMIC_STRING *ds,
4814
5277
uint num_fields)
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");
5279
MYSQL_FIELD *field_end;
5280
dynstr_append(ds,"Catalog\tDatabase\tTable\tTable_alias\tColumn\t"
5281
"Column_alias\tType\tLength\tMax length\tIs_null\t"
5282
"Flags\tDecimals\tCharsetnr\n");
4821
5284
for (field_end= field+num_fields ;
4822
5285
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);
5288
dynstr_append_mem(ds, field->catalog,
5289
field->catalog_length);
5290
dynstr_append_mem(ds, "\t", 1);
5291
dynstr_append_mem(ds, field->db, field->db_length);
5292
dynstr_append_mem(ds, "\t", 1);
5293
dynstr_append_mem(ds, field->org_table,
5294
field->org_table_length);
5295
dynstr_append_mem(ds, "\t", 1);
5296
dynstr_append_mem(ds, field->table,
5297
field->table_length);
5298
dynstr_append_mem(ds, "\t", 1);
5299
dynstr_append_mem(ds, field->org_name,
5300
field->org_name_length);
5301
dynstr_append_mem(ds, "\t", 1);
5302
dynstr_append_mem(ds, field->name, field->name_length);
5303
dynstr_append_mem(ds, "\t", 1);
5304
replace_dynstr_append_uint(ds, field->type);
5305
dynstr_append_mem(ds, "\t", 1);
5306
replace_dynstr_append_uint(ds, field->length);
5307
dynstr_append_mem(ds, "\t", 1);
5308
replace_dynstr_append_uint(ds, field->max_length);
5309
dynstr_append_mem(ds, "\t", 1);
5310
dynstr_append_mem(ds, (char*) (IS_NOT_NULL(field->flags) ?
5312
dynstr_append_mem(ds, "\t", 1);
5313
replace_dynstr_append_uint(ds, field->flags);
5314
dynstr_append_mem(ds, "\t", 1);
5315
replace_dynstr_append_uint(ds, field->decimals);
5316
dynstr_append_mem(ds, "\t", 1);
5317
replace_dynstr_append_uint(ds, field->charsetnr);
5318
dynstr_append_mem(ds, "\n", 1);
4901
5364
Number of warnings appended to ds
4904
static int append_warnings(string *ds, DRIZZLE *drizzle)
5367
static int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql)
4907
DRIZZLE_RES *warn_res;
4910
if (!(count= drizzle_warning_count(drizzle)))
5370
MYSQL_RES *warn_res;
5371
DBUG_ENTER("append_warnings");
5373
if (!(count= mysql_warning_count(mysql)))
4914
5377
If one day we will support execution of multi-statements
4915
5378
through PS API we should not issue SHOW WARNINGS until
4916
5379
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)))
5381
DBUG_ASSERT(!mysql_more_results(mysql));
5383
if (mysql_real_query(mysql, "SHOW WARNINGS", 13))
5384
die("Error running query \"SHOW WARNINGS\": %s", mysql_error(mysql));
5386
if (!(warn_res= mysql_store_result(mysql)))
4924
5387
die("Warning count is %u but didn't get any warnings",
4927
5390
append_result(ds, warn_res);
5391
mysql_free_result(warn_res);
5393
DBUG_PRINT("warnings", ("%s", ds->str));
4934
Run query using DRIZZLE C API
5400
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
5405
command current command pointer
5406
flags flags indicating if we should SEND and/or REAP
5407
query query string to execute
5408
query_len length query string to execute
5409
ds output buffer where to store result form query
4946
5412
static void run_query_normal(struct st_connection *cn,
4947
5413
struct st_command *command,
4948
5414
int flags, char *query, int query_len,
4949
string *ds, string *ds_warnings)
5415
DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings)
4951
DRIZZLE_RES *res= 0;
4952
DRIZZLE *drizzle= &cn->drizzle;
5418
MYSQL *mysql= &cn->mysql;
4953
5419
int err= 0, counter= 0;
5420
DBUG_ENTER("run_query_normal");
5421
DBUG_PRINT("enter",("flags: %d", flags));
5422
DBUG_PRINT("enter", ("query: '%-.60s'", query));
4955
5424
if (flags & QUERY_SEND_FLAG)
4960
5429
if (do_send_query(cn, query, query_len, flags))
4962
handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
4963
drizzle_sqlstate(drizzle), ds);
5431
handle_error(command, mysql_errno(mysql), mysql_error(mysql),
5432
mysql_sqlstate(mysql), ds);
5436
#ifdef EMBEDDED_LIBRARY
5438
Here we handle 'reap' command, so we need to check if the
5439
query's thread was finished and probably wait
5441
else if (flags & QUERY_REAP_FLAG)
5442
wait_query_thread_end(cn);
5443
#endif /*EMBEDDED_LIBRARY*/
4967
5444
if (!(flags & QUERY_REAP_FLAG))
4973
When on first result set, call drizzle_read_query_result to retrieve
5450
When on first result set, call mysql_read_query_result to retrieve
4974
5451
answer to the query sent earlier
4976
if ((counter==0) && drizzle_read_query_result(drizzle))
5453
if ((counter==0) && mysql_read_query_result(mysql))
4978
handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
4979
drizzle_sqlstate(drizzle), ds);
5455
handle_error(command, mysql_errno(mysql), mysql_error(mysql),
5456
mysql_sqlstate(mysql), ds);
4985
5462
Store the result of the query if it will return any fields
4987
if (drizzle_field_count(drizzle) && ((res= drizzle_store_result(drizzle)) == 0))
5464
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);
5466
handle_error(command, mysql_errno(mysql), mysql_error(mysql),
5467
mysql_sqlstate(mysql), ds);
4994
5471
if (!disable_result_log)
4996
uint64_t affected_rows= 0; /* Ok to be undef if 'disable_info' is set */
5473
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);
5477
MYSQL_FIELD *fields= mysql_fetch_fields(res);
5478
uint num_fields= mysql_num_fields(res);
5003
if (display_metadata)
5480
if (display_metadata)
5004
5481
append_metadata(ds, fields, num_fields);
5006
if (!display_result_vertically)
5007
append_table_headings(ds, fields, num_fields);
5483
if (!display_result_vertically)
5484
append_table_headings(ds, fields, num_fields);
5009
append_result(ds, res);
5486
append_result(ds, res);
5013
Need to call drizzle_affected_rows() before the "new"
5490
Need to call mysql_affected_rows() before the "new"
5014
5491
query to find the warnings
5016
5493
if (!disable_info)
5017
affected_rows= drizzle_affected_rows(drizzle);
5494
affected_rows= mysql_affected_rows(mysql);
5020
5497
Add all warnings to the result. We can't do this if we are in
5021
5498
the middle of processing results from multi-statement, because
5022
5499
this will break protocol.
5024
if (!disable_warnings && !drizzle_more_results(drizzle))
5501
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());
5503
if (append_warnings(ds_warnings, mysql) || ds_warnings->length)
5505
dynstr_append_mem(ds, "Warnings:\n", 10);
5506
dynstr_append_mem(ds, ds_warnings->str, ds_warnings->length);
5033
5510
if (!disable_info)
5034
append_info(ds, affected_rows, drizzle_info(drizzle));
5511
append_info(ds, affected_rows, mysql_info(mysql));
5039
drizzle_free_result(res);
5516
mysql_free_result(res);
5043
} while (!(err= drizzle_next_result(drizzle)));
5520
} 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);
5523
/* We got an error from mysql_next_result, maybe expected */
5524
handle_error(command, mysql_errno(mysql), mysql_error(mysql),
5525
mysql_sqlstate(mysql), ds);
5051
assert(err == -1); /* Successful and there are no more results */
5528
DBUG_ASSERT(err == -1); /* Successful and there are no more results */
5053
5530
/* If we come here the query is both executed and read successfully */
5054
5531
handle_no_error(command);
6026
6539
for (i= 1,pos= word_end_chars ; i < 256 ; i++)
6027
6540
if (my_isspace(charset_info,i))
6029
*pos=0; /* End pointer */
6542
*pos=0; /* End pointer */
6030
6543
if (!(glob_replace= init_replace((char**) from_array.typelib.type_names,
6031
(char**) to_array.typelib.type_names,
6032
(uint) from_array.typelib.count,
6544
(char**) to_array.typelib.type_names,
6545
(uint) from_array.typelib.count,
6034
6547
die("Can't initialize replace from '%s'", command->query);
6035
6548
free_pointer_array(&from_array);
6036
6549
free_pointer_array(&to_array);
6550
my_free(start, MYF(0));
6038
6551
command->last_argument= command->end;
6043
6556
void free_replace()
6558
DBUG_ENTER("free_replace");
6046
6559
if (glob_replace)
6561
my_free(glob_replace,MYF(0));
6049
6562
glob_replace=0;
6055
6568
typedef struct st_replace {
6057
6570
struct st_replace *next[256];
6060
6573
typedef struct st_replace_found {
6062
6575
char *replace_string;
6063
6576
uint to_offset;
6064
6577
int from_offset;
6065
6578
} REPLACE_STRING;
6068
void replace_strings_append(REPLACE *rep, string* ds,
6069
const char *str, int len)
6581
void replace_strings_append(REPLACE *rep, DYNAMIC_STRING* ds,
6583
int len __attribute__((unused)))
6071
6585
register REPLACE *rep_pos;
6072
6586
register REPLACE_STRING *rep_str;
6073
6587
const char *start, *from;
6588
DBUG_ENTER("replace_strings_append");
6076
6590
start= from= str;
6080
6594
/* Loop through states */
6595
DBUG_PRINT("info", ("Looping through states"));
6081
6596
while (!rep_pos->found)
6082
rep_pos= rep_pos->next[(unsigned char) *from++];
6597
rep_pos= rep_pos->next[(uchar) *from++];
6084
6599
/* Does this state contain a string to be replaced */
6085
6600
if (!(rep_str = ((REPLACE_STRING*) rep_pos))->replace_string)
6087
6602
/* No match found */
6088
ds->append(start, from - start - 1);
6603
dynstr_append_mem(ds, start, from - start - 1);
6604
DBUG_PRINT("exit", ("Found no more string to replace, appended: %s", start));
6608
/* Found a string that needs to be replaced */
6609
DBUG_PRINT("info", ("found: %d, to_offset: %d, from_offset: %d, string: %s",
6610
rep_str->found, rep_str->to_offset,
6611
rep_str->from_offset, rep_str->replace_string));
6092
6613
/* Append part of original string before replace string */
6093
ds->append(start, (from - rep_str->to_offset) - start);
6614
dynstr_append_mem(ds, start, (from - rep_str->to_offset) - start);
6095
6616
/* Append replace string */
6096
ds->append(rep_str->replace_string,
6097
strlen(rep_str->replace_string));
6617
dynstr_append_mem(ds, rep_str->replace_string,
6618
strlen(rep_str->replace_string));
6099
6620
if (!*(from-=rep_str->from_offset) && rep_pos->found != 2)
6102
assert(from <= str+len);
6622
/* End of from string */
6623
DBUG_PRINT("exit", ("Found end of from string"));
6626
DBUG_ASSERT(from <= str+len);
6614
7138
for (set_nr=0,pos=0 ; set_nr < sets.count ; set_nr++)
6616
7140
set=sets.set+set_nr;
6617
default_state= 0; /* Start from beginning */
7141
default_state= 0; /* Start from beginning */
6619
7143
/* If end of found-string not found or start-set with current set */
6621
for (i= UINT32_MAX; (i=get_next_bit(set,i)) ;)
7145
for (i= (uint) ~0; (i=get_next_bit(set,i)) ;)
6623
7147
if (!follow[i].chr)
6625
if (! default_state)
6626
default_state= find_found(found_set,set->table_offset,
6627
set->found_offset+1);
7149
if (! default_state)
7150
default_state= find_found(found_set,set->table_offset,
7151
set->found_offset+1);
6630
copy_bits(sets.set+used_sets,set); /* Save set for changes */
7154
copy_bits(sets.set+used_sets,set); /* Save set for changes */
6631
7155
if (!default_state)
6632
or_bits(sets.set+used_sets,sets.set); /* Can restart from start */
7156
or_bits(sets.set+used_sets,sets.set); /* Can restart from start */
6634
7158
/* 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)) ;)
7159
bzero((char*) used_chars,sizeof(used_chars));
7160
for (i= (uint) ~0; (i=get_next_bit(sets.set+used_sets,i)) ;)
6638
7162
used_chars[follow[i].chr]=1;
6639
7163
if ((follow[i].chr == SPACE_CHAR && !follow[i+1].chr &&
6640
follow[i].len > 1) || follow[i].chr == END_OF_LINE)
7164
follow[i].len > 1) || follow[i].chr == END_OF_LINE)
6644
7168
/* Mark word_chars used if \b is in state */
6645
7169
if (used_chars[SPACE_CHAR])
6646
7170
for (pos= word_end_chars ; *pos ; pos++)
6647
used_chars[(int) (unsigned char) *pos] = 1;
7171
used_chars[(int) (uchar) *pos] = 1;
6649
7173
/* Handle other used characters */
6650
7174
for (chr= 0 ; chr < 256 ; chr++)
6652
7176
if (! used_chars[chr])
6653
set->next[chr]= chr ? default_state : -1;
7177
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;
7180
new_set=make_new_set(&sets);
7181
set=sets.set+set_nr; /* if realloc */
7182
new_set->table_offset=set->table_offset;
7183
new_set->found_len=set->found_len;
7184
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);
7187
for (i= (uint) ~0 ; (i=get_next_bit(sets.set+used_sets,i)) ; )
7189
if (!follow[i].chr || follow[i].chr == chr ||
7190
(follow[i].chr == SPACE_CHAR &&
7191
(is_word_end[chr] ||
7192
(!chr && follow[i].len > 1 && ! follow[i+1].chr))) ||
7193
(follow[i].chr == END_OF_LINE && ! chr))
7195
if ((! chr || (follow[i].chr && !follow[i+1].chr)) &&
7196
follow[i].len > found_end)
7197
found_end=follow[i].len;
7198
if (chr && follow[i].chr)
7199
internal_set_bit(new_set,i+1); /* To next set */
7201
internal_set_bit(new_set,i);
7206
new_set->found_len=0; /* Set for testing if first */
7208
for (i= (uint) ~0; (i=get_next_bit(new_set,i)) ;)
7210
if ((follow[i].chr == SPACE_CHAR ||
7211
follow[i].chr == END_OF_LINE) && ! chr)
7215
if (follow[bit_nr-1].len < found_end ||
7216
(new_set->found_len &&
7217
(chr == 0 || !follow[bit_nr].chr)))
7218
internal_clear_bit(new_set,i);
7221
if (chr == 0 || !follow[bit_nr].chr)
7223
new_set->table_offset=follow[bit_nr].table_offset;
7224
if (chr || (follow[i].chr == SPACE_CHAR ||
7225
follow[i].chr == END_OF_LINE))
7226
new_set->found_offset=found_end; /* New match */
7227
new_set->found_len=found_end;
7234
set->next[chr] = find_found(found_set,
7235
new_set->table_offset,
7236
new_set->found_offset);
7237
free_last_set(&sets);
7240
set->next[chr] = find_set(&sets,new_set);
7243
set->next[chr] = find_set(&sets,new_set);
6926
7453
for (i=0 ; (uint) i < found_sets ; i++)
6927
7454
if (found_set[i].table_offset == table_offset &&
6928
found_set[i].found_offset == found_offset)
7455
found_set[i].found_offset == found_offset)
6930
7457
found_set[i].table_offset=table_offset;
6931
7458
found_set[i].found_offset=found_offset;
6933
return -i-2; /* return new postion */
7460
return -i-2; /* return new postion */
6936
7463
/* Return 1 if regexp starts with \b or ends with \b*/
6938
7465
uint start_at_word(char * pos)
6940
return (((!memcmp(pos, "\\b",2) && pos[2]) ||
6941
!memcmp(pos, "\\^", 2)) ? 1 : 0);
7467
return (((!bcmp((const uchar*) pos, (const uchar*) "\\b",2) && pos[2]) ||
7468
!bcmp((const uchar*) pos, (const uchar*) "\\^", 2)) ? 1 : 0);
6944
7471
uint end_of_word(char * pos)
6946
char * end= strchr(pos, '\0');
6947
return ((end > pos+2 && !memcmp(end-2, "\\b", 2)) ||
6948
(end >= pos+2 && !memcmp(end-2, "\\$",2))) ? 1 : 0;
7473
char * end=strend(pos);
7474
return ((end > pos+2 && !bcmp((const uchar*) end-2,
7475
(const uchar*) "\\b", 2)) ||
7476
(end >= pos+2 && !bcmp((const uchar*) end-2,
7477
(const uchar*) "\\$",2))) ? 1 : 0;
6951
7480
/****************************************************************************
6952
7481
* Handle replacement of strings
6953
7482
****************************************************************************/
6955
#define PC_MALLOC 256 /* Bytes for pointers */
6956
#define PS_MALLOC 512 /* Bytes for data */
7484
#define PC_MALLOC 256 /* Bytes for pointers */
7485
#define PS_MALLOC 512 /* Bytes for data */
6958
7487
int insert_pointer_name(POINTER_ARRAY *pa,char * name)
6960
7489
uint i,length,old_count;
6961
unsigned char *new_pos;
6962
7491
const char **new_array;
7492
DBUG_ENTER("insert_pointer_name");
6965
7494
if (! pa->typelib.count)
6967
7496
if (!(pa->typelib.type_names=(const char **)
6968
my_malloc(((PC_MALLOC-MALLOC_OVERHEAD)/
6969
(sizeof(char *)+sizeof(*pa->flag))*
6970
(sizeof(char *)+sizeof(*pa->flag))),MYF(MY_WME))))
6972
if (!(pa->str= (unsigned char*) my_malloc((uint) (PS_MALLOC-MALLOC_OVERHEAD),
7497
my_malloc(((PC_MALLOC-MALLOC_OVERHEAD)/
7498
(sizeof(char *)+sizeof(*pa->flag))*
7499
(sizeof(char *)+sizeof(*pa->flag))),MYF(MY_WME))))
7501
if (!(pa->str= (uchar*) my_malloc((uint) (PS_MALLOC-MALLOC_OVERHEAD),
6975
free((char*) pa->typelib.type_names);
7504
my_free((char*) pa->typelib.type_names,MYF(0));
6978
pa->max_count=(PC_MALLOC-MALLOC_OVERHEAD)/(sizeof(unsigned char*)+
6980
pa->flag= (uint8_t*) (pa->typelib.type_names+pa->max_count);
7507
pa->max_count=(PC_MALLOC-MALLOC_OVERHEAD)/(sizeof(uchar*)+
7509
pa->flag= (int7*) (pa->typelib.type_names+pa->max_count);
6982
7511
pa->max_length=PS_MALLOC-MALLOC_OVERHEAD;
6983
7512
pa->array_allocs=1;