summaryrefslogtreecommitdiff
path: root/client/mysqltest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'client/mysqltest.cc')
-rw-r--r--client/mysqltest.cc350
1 files changed, 221 insertions, 129 deletions
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 842bde3b99e..7ec2a62dcf7 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -44,7 +44,8 @@
#include <hash.h>
#include <stdarg.h>
#include <violite.h>
-#include "my_regex.h" /* Our own version of regex */
+#define PCRE_STATIC 1 /* Important on Windows */
+#include "pcreposix.h" /* pcreposix regex library */
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
@@ -87,6 +88,8 @@ static my_bool non_blocking_api_enabled= 0;
#define QUERY_SEND_FLAG 1
#define QUERY_REAP_FLAG 2
+#define QUERY_PRINT_ORIGINAL_FLAG 4
+
#ifndef HAVE_SETENV
static int setenv(const char *name, const char *value, int overwrite);
#endif
@@ -178,6 +181,7 @@ static uint my_end_arg= 0;
static uint opt_tail_lines= 0;
static uint opt_connect_timeout= 0;
+static uint opt_wait_for_pos_timeout= 0;
static char delimiter[MAX_DELIMITER_LENGTH]= ";";
static uint delimiter_length= 1;
@@ -248,14 +252,16 @@ static const char *opt_suite_dir, *opt_overlay_dir;
static size_t suite_dir_len, overlay_dir_len;
/* Precompiled re's */
-static my_regex_t ps_re; /* the query can be run using PS protocol */
-static my_regex_t sp_re; /* the query can be run as a SP */
-static my_regex_t view_re; /* the query can be run as a view*/
+static regex_t ps_re; /* the query can be run using PS protocol */
+static regex_t sp_re; /* the query can be run as a SP */
+static regex_t view_re; /* the query can be run as a view*/
static void init_re(void);
-static int match_re(my_regex_t *, char *);
+static int match_re(regex_t *, char *);
static void free_re(void);
+static char *get_string(char **to_ptr, char **from_ptr,
+ struct st_command *command);
static int replace(DYNAMIC_STRING *ds_str,
const char *search_str, ulong search_len,
const char *replace_str, ulong replace_len);
@@ -345,7 +351,8 @@ enum enum_commands {
Q_ERROR,
Q_SEND, Q_REAP,
Q_DIRTY_CLOSE, Q_REPLACE, Q_REPLACE_COLUMN,
- Q_PING, Q_EVAL,
+ Q_PING, Q_EVAL,
+ Q_EVALP,
Q_EVAL_RESULT,
Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG,
Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG,
@@ -411,6 +418,7 @@ const char *command_names[]=
"replace_column",
"ping",
"eval",
+ "evalp",
"eval_result",
/* Enable/disable that the _query_ is logged to result file */
"enable_query_log",
@@ -592,7 +600,7 @@ void do_eval(DYNAMIC_STRING *query_eval, const char *query,
void str_to_file(const char *fname, char *str, int size);
void str_to_file2(const char *fname, char *str, int size, my_bool append);
-void fix_win_paths(const char *val, int len);
+void fix_win_paths(const char *val, size_t len);
const char *get_errname_from_code (uint error_code);
int multi_reg_replace(struct st_replace_regex* r,char* val);
@@ -806,8 +814,7 @@ public:
LogFile log_file;
LogFile progress_file;
-void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
- int len);
+void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, size_t len);
void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val);
void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val);
void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING* ds_input,
@@ -832,6 +839,7 @@ static void handle_no_active_connection(struct st_command* command,
#define EMB_END_CONNECTION 3
#define EMB_PREPARE_STMT 4
#define EMB_EXECUTE_STMT 5
+#define EMB_CLOSE_STMT 6
/* workaround for MySQL BUG#57491 */
#undef MY_WME
@@ -880,6 +888,9 @@ pthread_handler_t connection_thread(void *arg)
case EMB_EXECUTE_STMT:
cn->result= mysql_stmt_execute(cn->stmt);
break;
+ case EMB_CLOSE_STMT:
+ cn->result= mysql_stmt_close(cn->stmt);
+ break;
default:
DBUG_ASSERT(0);
}
@@ -977,6 +988,17 @@ static int do_stmt_execute(struct st_connection *cn)
}
+static int do_stmt_close(struct st_connection *cn)
+{
+ /* The cn->stmt is already set. */
+ if (!cn->has_thread)
+ return mysql_stmt_close(cn->stmt);
+ signal_connection_thd(cn, EMB_CLOSE_STMT);
+ wait_query_thread_done(cn);
+ return cn->result;
+}
+
+
static void emb_close_connection(struct st_connection *cn)
{
if (!cn->has_thread)
@@ -1012,6 +1034,7 @@ static void init_connection_thd(struct st_connection *cn)
#define do_read_query_result(cn) mysql_read_query_result(cn->mysql)
#define do_stmt_prepare(cn, q, q_len) mysql_stmt_prepare(cn->stmt, q, q_len)
#define do_stmt_execute(cn) mysql_stmt_execute(cn->stmt)
+#define do_stmt_close(cn) mysql_stmt_close(cn->stmt)
#endif /*EMBEDDED_LIBRARY*/
@@ -1081,7 +1104,7 @@ void do_eval(DYNAMIC_STRING *query_eval, const char *query,
Run query and dump the result to stderr in vertical format
NOTE! This function should be safe to call when an error
- has occured and thus any further errors will be ignored(although logged)
+ has occurred and thus any further errors will be ignored (although logged)
SYNOPSIS
show_query
@@ -1147,7 +1170,7 @@ static void show_query(MYSQL* mysql, const char* query)
is added to the warning stack, only print @@warning_count-1 warnings.
NOTE! This function should be safe to call when an error
- has occured and this any further errors will be ignored(although logged)
+ has occurred and this any further errors will be ignored(although logged)
SYNOPSIS
show_warnings_before_error
@@ -1371,11 +1394,11 @@ void close_connections()
DBUG_ENTER("close_connections");
for (--next_con; next_con >= connections; --next_con)
{
+ if (next_con->stmt)
+ do_stmt_close(next_con);
#ifdef EMBEDDED_LIBRARY
emb_close_connection(next_con);
#endif
- if (next_con->stmt)
- mysql_stmt_close(next_con->stmt);
next_con->stmt= 0;
mysql_close(next_con->mysql);
next_con->mysql= 0;
@@ -1395,7 +1418,7 @@ void close_statements()
for (con= connections; con < next_con; con++)
{
if (con->stmt)
- mysql_stmt_close(con->stmt);
+ do_stmt_close(con);
con->stmt= 0;
}
DBUG_VOID_RETURN;
@@ -2630,6 +2653,7 @@ void var_query_set(VAR *var, const char *query, const char** query_end)
if (!mysql)
{
struct st_command command;
+ DBUG_ASSERT(query_end);
memset(&command, 0, sizeof(command));
command.query= (char*)query;
command.first_word_len= (*query_end - query);
@@ -3327,6 +3351,8 @@ void do_exec(struct st_command *command)
DBUG_ENTER("do_exec");
DBUG_PRINT("enter", ("cmd: '%s'", cmd));
+ var_set_int("$sys_errno",0);
+
/* Skip leading space */
while (*cmd && my_isspace(charset_info, *cmd))
cmd++;
@@ -3443,6 +3469,7 @@ void do_exec(struct st_command *command)
report_or_die("command \"%s\" failed with wrong error: %d",
command->first_argument, status);
}
+ var_set_int("$sys_errno",status);
}
else if (command->expected_errors.err[0].type == ERR_ERRNO &&
command->expected_errors.err[0].code.errnum != 0)
@@ -3697,7 +3724,6 @@ void do_remove_files_wildcard(struct st_command *command)
fn_format(dirname, ds_directory.str, "", "", MY_UNPACK_FILENAME);
DBUG_PRINT("info", ("listing directory: %s", dirname));
- /* Note that my_dir sorts the list if not given any flags */
if (!(dir_info= my_dir(dirname, MYF(MY_DONT_SORT | MY_WANT_STAT | MY_WME))))
{
error= 1;
@@ -3712,7 +3738,7 @@ void do_remove_files_wildcard(struct st_command *command)
/* Set default wild chars for wild_compare, is changed in embedded mode */
set_wild_chars(1);
- for (i= 0; i < (uint) dir_info->number_off_files; i++)
+ for (i= 0; i < (uint) dir_info->number_of_files; i++)
{
file= dir_info->dir_entry + i;
/* Remove only regular files, i.e. no directories etc. */
@@ -3975,17 +4001,12 @@ static int get_list_files(DYNAMIC_STRING *ds, const DYNAMIC_STRING *ds_dirname,
DBUG_ENTER("get_list_files");
DBUG_PRINT("info", ("listing directory: %s", ds_dirname->str));
- /* Note that my_dir sorts the list if not given any flags */
- if (!(dir_info= my_dir(ds_dirname->str, MYF(0))))
+ if (!(dir_info= my_dir(ds_dirname->str, MYF(MY_WANT_SORT))))
DBUG_RETURN(1);
set_wild_chars(1);
- for (i= 0; i < (uint) dir_info->number_off_files; i++)
+ for (i= 0; i < (uint) dir_info->number_of_files; i++)
{
file= dir_info->dir_entry + i;
- if (file->name[0] == '.' &&
- (file->name[1] == '\0' ||
- (file->name[1] == '.' && file->name[2] == '\0')))
- continue; /* . or .. */
if (ds_wild && ds_wild->length &&
wild_compare(file->name, ds_wild->str, 0))
continue;
@@ -4657,19 +4678,21 @@ void do_wait_for_slave_to_stop(struct st_command *c __attribute__((unused)))
}
-void do_sync_with_master2(struct st_command *command, long offset)
+void do_sync_with_master2(struct st_command *command, long offset,
+ const char *connection_name)
{
MYSQL_RES *res;
MYSQL_ROW row;
MYSQL *mysql= cur_con->mysql;
char query_buf[FN_REFLEN+128];
- int timeout= 300; /* seconds */
+ int timeout= opt_wait_for_pos_timeout;
if (!master_pos.file[0])
die("Calling 'sync_with_master' without calling 'save_master_pos'");
- sprintf(query_buf, "select master_pos_wait('%s', %ld, %d)",
- master_pos.file, master_pos.pos + offset, timeout);
+ sprintf(query_buf, "select master_pos_wait('%s', %ld, %d, '%s')",
+ master_pos.file, master_pos.pos + offset, timeout,
+ connection_name);
if (mysql_query(mysql, query_buf))
die("failed in '%s': %d: %s", query_buf, mysql_errno(mysql),
@@ -4704,7 +4727,7 @@ void do_sync_with_master2(struct st_command *command, long offset)
master_pos_wait returned NULL. This indicates that
slave SQL thread is not started, the slave's master
information is not initialized, the arguments are
- incorrect, or an error has occured
+ incorrect, or an error has occurred
*/
die("%.*s failed: '%s' returned NULL " \
"indicating slave SQL thread failure",
@@ -4729,16 +4752,32 @@ void do_sync_with_master(struct st_command *command)
long offset= 0;
char *p= command->first_argument;
const char *offset_start= p;
+ char *start, *buff= 0;
+ start= (char*) "";
+
if (*offset_start)
{
for (; my_isdigit(charset_info, *p); p++)
offset = offset * 10 + *p - '0';
- if(*p && !my_isspace(charset_info, *p))
+ if (*p && !my_isspace(charset_info, *p) && *p != ',')
die("Invalid integer argument \"%s\"", offset_start);
+
+ while (*p && my_isspace(charset_info, *p))
+ p++;
+ if (*p == ',')
+ {
+ p++;
+ while (*p && my_isspace(charset_info, *p))
+ p++;
+ start= buff= (char*)my_malloc(strlen(p)+1,MYF(MY_WME | MY_FAE));
+ get_string(&buff, &p, command);
+ }
command->last_argument= p;
}
- do_sync_with_master2(command, offset);
+ do_sync_with_master2(command, offset, start);
+ if (buff)
+ my_free(start);
return;
}
@@ -5390,7 +5429,7 @@ void do_get_errcodes(struct st_command *command)
{
die("The sqlstate definition must start with an uppercase S");
}
- else if (*p == 'E' || *p == 'H')
+ else if (*p == 'E' || *p == 'W' || *p == 'H')
{
/* Error name string */
@@ -5399,9 +5438,9 @@ void do_get_errcodes(struct st_command *command)
to->type= ERR_ERRNO;
DBUG_PRINT("info", ("ERR_ERRNO: %d", to->code.errnum));
}
- else if (*p == 'e' || *p == 'h')
+ else if (*p == 'e' || *p == 'w' || *p == 'h')
{
- die("The error name definition must start with an uppercase E or H");
+ die("The error name definition must start with an uppercase E or W or H");
}
else
{
@@ -5464,8 +5503,8 @@ void do_get_errcodes(struct st_command *command)
If string is a '$variable', return the value of the variable.
*/
-char *get_string(char **to_ptr, char **from_ptr,
- struct st_command *command)
+static char *get_string(char **to_ptr, char **from_ptr,
+ struct st_command *command)
{
char c, sep;
char *to= *to_ptr, *from= *from_ptr, *start=to;
@@ -5639,7 +5678,11 @@ void do_close_connection(struct st_command *command)
con->mysql->net.vio = 0;
}
}
-#else
+#endif /*!EMBEDDED_LIBRARY*/
+ if (con->stmt)
+ do_stmt_close(con);
+ con->stmt= 0;
+#ifdef EMBEDDED_LIBRARY
/*
As query could be still executed in a separate theread
we need to check if the query's thread was finished and probably wait
@@ -5647,9 +5690,6 @@ void do_close_connection(struct st_command *command)
*/
emb_close_connection(con);
#endif /*EMBEDDED_LIBRARY*/
- if (con->stmt)
- mysql_stmt_close(con->stmt);
- con->stmt= 0;
mysql_close(con->mysql);
con->mysql= 0;
@@ -5726,6 +5766,10 @@ void safe_connect(MYSQL* mysql, const char *name, const char *host,
verbose_msg("Connecting to server %s:%d (socket %s) as '%s'"
", connection '%s', attempt %d ...",
host, port, sock, user, name, failed_attempts);
+
+ mysql_options(mysql, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
+ mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
+ "program_name", "mysqltest");
while(!mysql_real_connect(mysql, host,user, pass, db, port, sock,
CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS))
{
@@ -5826,7 +5870,9 @@ int connect_n_handle_errors(struct st_command *command,
replace_dynstr_append(ds, command->query);
dynstr_append_mem(ds, ";\n", 2);
}
-
+
+ mysql_options(con, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
+ mysql_options4(con, MYSQL_OPT_CONNECT_ATTR_ADD, "program_name", "mysqltest");
while (!mysql_real_connect(con, host, user, pass, db, port, sock ? sock: 0,
CLIENT_MULTI_STATEMENTS))
{
@@ -5910,6 +5956,8 @@ void do_connect(struct st_command *command)
my_bool con_ssl= 0, con_compress= 0;
my_bool con_pipe= 0;
my_bool con_shm __attribute__ ((unused))= 0;
+ int read_timeout= 0;
+ int write_timeout= 0;
int connect_timeout= 0;
struct st_connection* con_slot;
@@ -6007,9 +6055,21 @@ void do_connect(struct st_command *command)
con_pipe= 1;
else if (length == 3 && !strncmp(con_options, "SHM", 3))
con_shm= 1;
+ else if (strncasecmp(con_options, "read_timeout=",
+ sizeof("read_timeout=")-1) == 0)
+ {
+ read_timeout= atoi(con_options + sizeof("read_timeout=")-1);
+ }
+ else if (strncasecmp(con_options, "write_timeout=",
+ sizeof("write_timeout=")-1) == 0)
+ {
+ write_timeout= atoi(con_options + sizeof("write_timeout=")-1);
+ }
else if (strncasecmp(con_options, "connect_timeout=",
sizeof("connect_timeout=")-1) == 0)
+ {
connect_timeout= atoi(con_options + sizeof("connect_timeout=")-1);
+ }
else
die("Illegal option to connect: %.*s",
(int) (end - con_options), con_options);
@@ -6060,6 +6120,8 @@ void do_connect(struct st_command *command)
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
mysql_ssl_set(con_slot->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, ssl_cipher ? ssl_cipher : opt_ssl_cipher);
+ mysql_options(con_slot->mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
+ mysql_options(con_slot->mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
#if MYSQL_VERSION_ID >= 50000
/* Turn on ssl_verify_server_cert only if host is "localhost" */
opt_ssl_verify_server_cert= !strcmp(ds_host.str, "localhost");
@@ -6079,9 +6141,23 @@ void do_connect(struct st_command *command)
if (opt_protocol)
mysql_options(con_slot->mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol);
+ if (read_timeout)
+ {
+ mysql_options(con_slot->mysql, MYSQL_OPT_READ_TIMEOUT,
+ (char*)&read_timeout);
+ }
+
+ if (write_timeout)
+ {
+ mysql_options(con_slot->mysql, MYSQL_OPT_WRITE_TIMEOUT,
+ (char*)&write_timeout);
+ }
+
if (connect_timeout)
+ {
mysql_options(con_slot->mysql, MYSQL_OPT_CONNECT_TIMEOUT,
(char*)&connect_timeout);
+ }
#ifdef HAVE_SMEM
if (con_shm)
@@ -6603,9 +6679,9 @@ int read_line()
}
else if ((c == '{' &&
(!my_strnncoll_simple(charset_info, (const uchar*) "while", 5,
- (uchar*) read_command_buf, min(5, p - read_command_buf), 0) ||
+ (uchar*) read_command_buf, MY_MIN(5, p - read_command_buf), 0) ||
!my_strnncoll_simple(charset_info, (const uchar*) "if", 2,
- (uchar*) read_command_buf, min(2, p - read_command_buf), 0))))
+ (uchar*) read_command_buf, MY_MIN(2, p - read_command_buf), 0))))
{
/* Only if and while commands can be terminated by { */
*p++= c;
@@ -7082,6 +7158,10 @@ static struct my_option my_long_options[] =
"Number of seconds before connection timeout.",
&opt_connect_timeout, &opt_connect_timeout, 0, GET_UINT, REQUIRED_ARG,
120, 0, 3600 * 12, 0, 0, 0},
+ {"wait_for_pos_timeout", 0,
+ "Number of seconds to wait for master_pos_wait",
+ &opt_wait_for_pos_timeout, &opt_wait_for_pos_timeout, 0, GET_UINT,
+ REQUIRED_ARG, 300, 0, 3600 * 12, 0, 0, 0},
{"plugin_dir", 0, "Directory for client-side plugins.",
&opt_plugin_dir, &opt_plugin_dir, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -7361,13 +7441,13 @@ void str_to_file(const char *fname, char *str, int size)
}
-void check_regerr(my_regex_t* r, int err)
+void check_regerr(regex_t* r, int err)
{
char err_buf[1024];
if (err)
{
- my_regerror(err,r,err_buf,sizeof(err_buf));
+ regerror(err,r,err_buf,sizeof(err_buf));
die("Regex error: %s\n", err_buf);
}
}
@@ -7402,7 +7482,7 @@ void init_win_path_patterns()
DBUG_ENTER("init_win_path_patterns");
- my_init_dynamic_array(&patterns, sizeof(const char*), 16, 16);
+ my_init_dynamic_array(&patterns, sizeof(const char*), 16, 16, MYF(0));
/* Loop through all paths in the array */
for (i= 0; i < num_paths; i++)
@@ -7462,7 +7542,7 @@ void free_win_path_patterns()
=> all \ from c:\mysql\m... until next space is converted into /
*/
-void fix_win_paths(const char *val, int len)
+void fix_win_paths(const char *val, size_t len)
{
uint i;
char *p;
@@ -7751,6 +7831,7 @@ int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql)
{
uint count;
MYSQL_RES *warn_res;
+ DYNAMIC_STRING res;
DBUG_ENTER("append_warnings");
if (!(count= mysql_warning_count(mysql)))
@@ -7770,11 +7851,18 @@ int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql)
die("Warning count is %u but didn't get any warnings",
count);
- append_result(ds, warn_res);
+ init_dynamic_string(&res, "", 1024, 1024);
+
+ append_result(&res, warn_res);
mysql_free_result(warn_res);
- DBUG_PRINT("warnings", ("%s", ds->str));
+ DBUG_PRINT("warnings", ("%s", res.str));
+ if (display_result_sorted)
+ dynstr_append_sorted(ds, &res, 0);
+ else
+ dynstr_append_mem(ds, res.str, res.length);
+ dynstr_free(&res);
DBUG_RETURN(count);
}
@@ -8438,7 +8526,8 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
/*
Evaluate query if this is an eval command
*/
- if (command->type == Q_EVAL || command->type == Q_SEND_EVAL)
+ if (command->type == Q_EVAL || command->type == Q_SEND_EVAL ||
+ command->type == Q_EVALP)
{
if (!command->eval_query.str)
init_dynamic_string(&command->eval_query, "", command->query_len + 256,
@@ -8474,10 +8563,20 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
*/
if (!disable_query_log && (flags & QUERY_SEND_FLAG))
{
- replace_dynstr_append_mem(ds, query, query_len);
+ char *print_query= query;
+ int print_len= query_len;
+ if (flags & QUERY_PRINT_ORIGINAL_FLAG)
+ {
+ print_query= command->query;
+ print_len= command->end - command->query;
+ }
+ replace_dynstr_append_mem(ds, print_query, print_len);
dynstr_append_mem(ds, delimiter, delimiter_length);
dynstr_append_mem(ds, "\n", 1);
}
+
+ /* We're done with this flag */
+ flags &= ~QUERY_PRINT_ORIGINAL_FLAG;
/*
Write the command to the result file before we execute the query
@@ -8651,19 +8750,18 @@ char *re_eprint(int err)
{
static char epbuf[100];
size_t len __attribute__((unused))=
- my_regerror(REG_ITOA|err, (my_regex_t *)NULL, epbuf, sizeof(epbuf));
+ regerror(err, (regex_t *)NULL, epbuf, sizeof(epbuf));
assert(len <= sizeof(epbuf));
return(epbuf);
}
-void init_re_comp(my_regex_t *re, const char* str)
+void init_re_comp(regex_t *re, const char* str)
{
- int err= my_regcomp(re, str, (REG_EXTENDED | REG_ICASE | REG_NOSUB),
- &my_charset_latin1);
+ int err= regcomp(re, str, (REG_EXTENDED | REG_ICASE | REG_NOSUB | REG_DOTALL));
if (err)
{
char erbuf[100];
- int len= my_regerror(err, re, erbuf, sizeof(erbuf));
+ int len= regerror(err, re, erbuf, sizeof(erbuf));
die("error %s, %d/%d `%s'\n",
re_eprint(err), (int)len, (int)sizeof(erbuf), erbuf);
}
@@ -8709,7 +8807,7 @@ void init_re(void)
}
-int match_re(my_regex_t *re, char *str)
+int match_re(regex_t *re, char *str)
{
while (my_isspace(charset_info, *str))
str++;
@@ -8721,7 +8819,7 @@ int match_re(my_regex_t *re, char *str)
str= comm_end + 2;
}
- int err= my_regexec(re, str, (size_t)0, NULL, 0);
+ int err= regexec(re, str, (size_t)0, NULL, 0);
if (err == 0)
return 1;
@@ -8730,7 +8828,7 @@ int match_re(my_regex_t *re, char *str)
{
char erbuf[100];
- int len= my_regerror(err, re, erbuf, sizeof(erbuf));
+ int len= regerror(err, re, erbuf, sizeof(erbuf));
die("error %s, %d/%d `%s'\n",
re_eprint(err), (int)len, (int)sizeof(erbuf), erbuf);
}
@@ -8739,10 +8837,9 @@ int match_re(my_regex_t *re, char *str)
void free_re(void)
{
- my_regfree(&ps_re);
- my_regfree(&sp_re);
- my_regfree(&view_re);
- my_regex_end();
+ regfree(&ps_re);
+ regfree(&sp_re);
+ regfree(&view_re);
}
/****************************************************************************/
@@ -9008,12 +9105,16 @@ int main(int argc, char **argv)
cur_block->ok= TRUE; /* Outer block should always be executed */
cur_block->cmd= cmd_none;
- my_init_dynamic_array(&q_lines, sizeof(struct st_command*), 1024, 1024);
+ my_init_dynamic_array(&q_lines, sizeof(struct st_command*), 1024, 1024, MYF(0));
if (my_hash_init2(&var_hash, 64, charset_info,
- 128, 0, 0, get_var_key, var_free, MYF(0)))
+ 128, 0, 0, get_var_key, 0, var_free, MYF(0)))
die("Variable hash initialization failed");
+ {
+ char path_separator[]= { FN_LIBCHAR, 0 };
+ var_set_string("SYSTEM_PATH_SEPARATOR", path_separator);
+ }
var_set_string("MYSQL_SERVER_VERSION", MYSQL_SERVER_VERSION);
var_set_string("MYSQL_SYSTEM_TYPE", SYSTEM_TYPE);
var_set_string("MYSQL_MACHINE_TYPE", MACHINE_TYPE);
@@ -9040,7 +9141,7 @@ int main(int argc, char **argv)
read_command_buf= (char*)my_malloc(read_command_buflen= 65536, MYF(MY_FAE));
init_dynamic_string(&ds_res, "", 2048, 2048);
- init_alloc_root(&require_file_root, 1024, 1024);
+ init_alloc_root(&require_file_root, 1024, 1024, MYF(0));
parse_args(argc, argv);
@@ -9127,6 +9228,8 @@ int main(int argc, char **argv)
{
mysql_ssl_set(con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(con->mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
+ mysql_options(con->mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
#if MYSQL_VERSION_ID >= 50000
/* Turn on ssl_verify_server_cert only if host is "localhost" */
opt_ssl_verify_server_cert= opt_host && !strcmp(opt_host, "localhost");
@@ -9338,6 +9441,7 @@ int main(int argc, char **argv)
case Q_EVAL_RESULT:
die("'eval_result' command is deprecated");
case Q_EVAL:
+ case Q_EVALP:
case Q_QUERY_VERTICAL:
case Q_QUERY_HORIZONTAL:
if (command->query == command->query_buf)
@@ -9365,6 +9469,9 @@ int main(int argc, char **argv)
flags= QUERY_REAP_FLAG;
}
+ if (command->type == Q_EVALP)
+ flags |= QUERY_PRINT_ORIGINAL_FLAG;
+
/* Check for special property for this query */
display_result_vertically|= (command->type == Q_QUERY_VERTICAL);
@@ -9434,7 +9541,7 @@ int main(int argc, char **argv)
select_connection(command);
else
select_connection_name("slave");
- do_sync_with_master2(command, 0);
+ do_sync_with_master2(command, 0, "");
break;
}
case Q_COMMENT:
@@ -9929,36 +10036,34 @@ struct st_regex
int reg_replace(char** buf_p, int* buf_len_p, char *pattern, char *replace,
char *string, int icase);
+bool parse_re_part(char *start_re, char *end_re,
+ char **p, char *end, char **buf)
+{
+ if (*start_re != *end_re)
+ {
+ switch ((*start_re= *(*p)++)) {
+ case '(': *end_re= ')'; break;
+ case '[': *end_re= ']'; break;
+ case '{': *end_re= '}'; break;
+ case '<': *end_re= '>'; break;
+ default: *end_re= *start_re;
+ }
+ }
+ while (*p < end && **p != *end_re)
+ {
+ if ((*p)[0] == '\\' && *p + 1 < end && (*p)[1] == *end_re)
+ (*p)++;
-/*
- Finds the next (non-escaped) '/' in the expression.
- (If the character '/' is needed, it can be escaped using '\'.)
-*/
+ *(*buf)++= *(*p)++;
+ }
+ *(*buf)++= 0;
+
+ (*p)++;
+
+ return *p > end;
+}
-#define PARSE_REGEX_ARG \
- while (p < expr_end) \
- { \
- char c= *p; \
- if (c == '/') \
- { \
- if (last_c == '\\') \
- { \
- buf_p[-1]= '/'; \
- } \
- else \
- { \
- *buf_p++ = 0; \
- break; \
- } \
- } \
- else \
- *buf_p++ = c; \
- \
- last_c= c; \
- p++; \
- } \
- \
/*
Initializes the regular substitution expression to be used in the
result output of test.
@@ -9970,16 +10075,15 @@ struct st_replace_regex* init_replace_regex(char* expr)
{
struct st_replace_regex* res;
char* buf,*expr_end;
- char* p;
+ char* p, start_re, end_re= 1;
char* buf_p;
uint expr_len= strlen(expr);
- char last_c = 0;
struct st_regex reg;
/* my_malloc() will die on fail with MY_FAE */
res=(struct st_replace_regex*)my_malloc(
sizeof(*res)+expr_len ,MYF(MY_FAE+MY_WME));
- my_init_dynamic_array(&res->regex_arr,sizeof(struct st_regex),128,128);
+ my_init_dynamic_array(&res->regex_arr,sizeof(struct st_regex), 128, 128, MYF(0));
buf= (char*)res + sizeof(*res);
expr_end= expr + expr_len;
@@ -9991,44 +10095,32 @@ struct st_replace_regex* init_replace_regex(char* expr)
{
bzero(&reg,sizeof(reg));
/* find the start of the statement */
- while (p < expr_end)
- {
- if (*p == '/')
- break;
+ while (my_isspace(charset_info, *p) && p < expr_end)
p++;
- }
- if (p == expr_end || ++p == expr_end)
+ if (p >= expr_end)
{
if (res->regex_arr.elements)
break;
else
goto err;
}
- /* we found the start */
- reg.pattern= buf_p;
-
- /* Find first argument -- pattern string to be removed */
- PARSE_REGEX_ARG
- if (p == expr_end || ++p == expr_end)
- goto err;
+ start_re= 0;
+ reg.pattern= buf_p;
+ if (parse_re_part(&start_re, &end_re, &p, expr_end, &buf_p))
+ goto err;
- /* buf_p now points to the replacement pattern terminated with \0 */
reg.replace= buf_p;
-
- /* Find second argument -- replace string to replace pattern */
- PARSE_REGEX_ARG
-
- if (p == expr_end)
- goto err;
-
- /* skip the ending '/' in the statement */
- p++;
+ if (parse_re_part(&start_re, &end_re, &p, expr_end, &buf_p))
+ goto err;
/* Check if we should do matching case insensitive */
if (p < expr_end && *p == 'i')
+ {
+ p++;
reg.icase= 1;
+ }
/* done parsing the statement, now place it in regex_arr */
if (insert_dynamic(&res->regex_arr,(uchar*) &reg))
@@ -10176,13 +10268,13 @@ void free_replace_regex()
int reg_replace(char** buf_p, int* buf_len_p, char *pattern,
char *replace, char *string, int icase)
{
- my_regex_t r;
- my_regmatch_t *subs;
+ regex_t r;
+ regmatch_t *subs;
char *replace_end;
char *buf= *buf_p;
int len;
int buf_len, need_buf_len;
- int cflags= REG_EXTENDED;
+ int cflags= REG_EXTENDED | REG_DOTALL;
int err_code;
char *res_p,*str_p,*str_end;
@@ -10201,13 +10293,13 @@ int reg_replace(char** buf_p, int* buf_len_p, char *pattern,
if (icase)
cflags|= REG_ICASE;
- if ((err_code= my_regcomp(&r,pattern,cflags,&my_charset_latin1)))
+ if ((err_code= regcomp(&r,pattern,cflags)))
{
check_regerr(&r,err_code);
return 1;
}
- subs= (my_regmatch_t*)my_malloc(sizeof(my_regmatch_t) * (r.re_nsub+1),
+ subs= (regmatch_t*)my_malloc(sizeof(regmatch_t) * (r.re_nsub+1),
MYF(MY_WME+MY_FAE));
*res_p= 0;
@@ -10218,14 +10310,14 @@ int reg_replace(char** buf_p, int* buf_len_p, char *pattern,
while (!err_code)
{
/* find the match */
- err_code= my_regexec(&r,str_p, r.re_nsub+1, subs,
+ err_code= regexec(&r,str_p, r.re_nsub+1, subs,
(str_p == string) ? REG_NOTBOL : 0);
/* if regular expression error (eg. bad syntax, or out of memory) */
if (err_code && err_code != REG_NOMATCH)
{
check_regerr(&r,err_code);
- my_regfree(&r);
+ regfree(&r);
return 1;
}
@@ -10338,7 +10430,7 @@ int reg_replace(char** buf_p, int* buf_len_p, char *pattern,
}
}
my_free(subs);
- my_regfree(&r);
+ regfree(&r);
*res_p= 0;
*buf_p= buf;
*buf_len_p= buf_len;
@@ -10953,7 +11045,7 @@ void free_pointer_array(POINTER_ARRAY *pa)
/* Append the string to ds, with optional replace */
void replace_dynstr_append_mem(DYNAMIC_STRING *ds,
- const char *val, int len)
+ const char *val, size_t len)
{
char lower[512];
#ifdef __WIN__
@@ -11034,7 +11126,7 @@ void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input,
if (!*start)
DBUG_VOID_RETURN; /* No input */
- my_init_dynamic_array(&lines, sizeof(const char*), 32, 32);
+ my_init_dynamic_array(&lines, sizeof(const char*), 32, 32, MYF(0));
if (keep_header)
{