summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorunknown <peter@mysql.com>2002-11-24 17:26:26 +0300
committerunknown <peter@mysql.com>2002-11-24 17:26:26 +0300
commit5b1ced458013509629c7e8e052b88910cfbb6afd (patch)
treebce40fe371fa0025ed0a77a664f62de77cdd04bf /client
parent8c8b97fdf4756a699346ae1688136624d76713bc (diff)
parent1049175831a4aa145f64e912388cc6079d7f5789 (diff)
downloadmariadb-git-5b1ced458013509629c7e8e052b88910cfbb6afd.tar.gz
Merge....
BitKeeper/etc/logging_ok: auto-union client/mysqladmin.c: Auto merged include/mysql.h: Auto merged libmysql/libmysql.c: Auto merged sql/item_strfunc.cc: Auto merged sql/item_strfunc.h: Auto merged sql/lex.h: Auto merged sql/mini_client.cc: Auto merged sql/mysql_priv.h: Auto merged libmysql/password.c: Auto merged sql/sql_acl.cc: Auto merged sql/sql_acl.h: Auto merged sql/sql_class.h: Auto merged sql/sql_parse.cc: Auto merged sql/sql_yacc.yy: Auto merged sql/mysqld.cc: Manual merge
Diffstat (limited to 'client')
-rw-r--r--client/client_priv.h5
-rw-r--r--client/mysql.cc36
-rw-r--r--client/mysqladmin.c33
-rw-r--r--client/mysqlbinlog.cc3
-rw-r--r--client/mysqlcheck.c75
-rw-r--r--client/mysqldump.c75
-rw-r--r--client/mysqlimport.c32
-rw-r--r--client/mysqlshow.c75
-rw-r--r--client/mysqltest.c12
-rw-r--r--client/sql_string.cc380
-rw-r--r--client/sql_string.h48
11 files changed, 419 insertions, 355 deletions
diff --git a/client/client_priv.h b/client/client_priv.h
index acf9455bf9c..eb4473cb10f 100644
--- a/client/client_priv.h
+++ b/client/client_priv.h
@@ -17,7 +17,7 @@
/* Common defines for all clients */
#include <my_global.h>
-#include <my_sys.h>
+#include <my_sys.h>
#include <m_string.h>
#include <mysql.h>
#include <mysql_embed.h>
@@ -37,4 +37,5 @@ enum options { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET,
OPT_SELECT_LIMIT, OPT_MAX_JOIN_SIZE, OPT_SSL_SSL,
OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH,
OPT_SSL_CIPHER, OPT_SHUTDOWN_TIMEOUT, OPT_LOCAL_INFILE,
- OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION };
+ OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION,OPT_MYSQL_PROTOCOL,
+ OPT_SHARED_MEMORY_BASE_NAME, OPT_FRM };
diff --git a/client/mysql.cc b/client/mysql.cc
index fbd3b13ca83..241f4cf7ecc 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -152,6 +152,11 @@ static FILE *PAGER, *OUTFILE;
static MEM_ROOT hash_mem_root;
static uint prompt_counter;
+#ifdef HAVE_SMEM
+static char *shared_memory_base_name=0;
+#endif
+static uint opt_protocol=0;
+
#include "sslopt-vars.h"
#ifndef DBUG_OFF
@@ -425,6 +430,9 @@ sig_handler mysql_end(int sig)
my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
my_free(default_prompt,MYF(MY_ALLOW_ZERO_PTR));
+#ifdef HAVE_SMEM
+ my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
+#endif
my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
mysql_server_end();
free_defaults(defaults_argv);
@@ -532,6 +540,8 @@ static struct my_option my_long_options[] =
{"prompt", OPT_PROMPT, "Set the mysql prompt to this value.",
(gptr*) &current_prompt, (gptr*) &current_prompt, 0, GET_STR_ALLOC,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory)",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"quick", 'q',
"Don't cache result, print it row by row. This may slow down the server if the output is suspended. Doesn't use history file. ",
(gptr*) &quick, (gptr*) &quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -540,6 +550,11 @@ static struct my_option my_long_options[] =
0, 0, 0},
{"silent", 's', "Be more silent.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,
0, 0},
+#ifdef HAVE_SMEM
+ {"shared_memory_base_name", OPT_SHARED_MEMORY_BASE_NAME,
+ "Base name of shared memory", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name,
+ 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#endif
{"socket", 'S', "Socket file to use for connection.",
(gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR_ALLOC,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -644,6 +659,15 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case OPT_NOPAGER:
printf("WARNING: option deprecated; use --disable-pager instead.\n");
opt_nopager= 1;
+ case OPT_MYSQL_PROTOCOL:
+ {
+ if ((opt_protocol = find_type(argument, &sql_protocol_typelib,0)) == ~(ulong) 0)
+ {
+ fprintf(stderr, "Unknown option to protocol: %s\n", argument);
+ exit(1);
+ }
+ break;
+ }
break;
case 'A':
rehash= 0;
@@ -706,7 +730,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
case 'W':
#ifdef __WIN__
- opt_mysql_unix_port= my_strdup(MYSQL_NAMEDPIPE, MYF(0));
+ opt_protocol = MYSQL_PROTOCOL_PIPE;
#endif
break;
#include <sslopt-case.h>
@@ -952,7 +976,7 @@ static bool add_line(String &buffer,char *line,char *in_string)
}
if ((com=find_command(NullS,(char) inchar)))
{
- const String tmp(line,(uint) (out-line));
+ const String tmp(line,(uint) (out-line), system_charset_info);
buffer.append(tmp);
if ((*com->func)(&buffer,pos-1) > 0)
return 1; // Quit
@@ -1709,7 +1733,7 @@ print_table_data(MYSQL_RES *result)
print_field_types(result);
mysql_field_seek(result,0);
}
- separator.copy("+",1);
+ separator.copy("+",1,system_charset_info);
while ((field = mysql_fetch_field(result)))
{
uint length= column_names ? (uint) strlen(field->name) : 0;
@@ -2350,6 +2374,12 @@ sql_real_connect(char *host,char *database,char *user,char *password,
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
#endif
+ if (opt_protocol)
+ mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
+#ifdef HAVE_SMEM
+ if (shared_memory_base_name)
+ mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
+#endif
if (safe_updates)
{
char init_command[100];
diff --git a/client/mysqladmin.c b/client/mysqladmin.c
index cf6368cc707..925e67978bf 100644
--- a/client/mysqladmin.c
+++ b/client/mysqladmin.c
@@ -23,6 +23,7 @@
#include <my_pthread.h> /* because of signal() */
#endif
#include <sys/stat.h>
+#include <mysql.h>
#define ADMIN_VERSION "8.38"
#define MAX_MYSQL_VAR 128
@@ -42,6 +43,11 @@ static uint tcp_port = 0, option_wait = 0, option_silent=0, nr_iterations,
static ulong opt_connect_timeout, opt_shutdown_timeout;
static my_string unix_port=0;
+#ifdef HAVE_SMEM
+static char *shared_memory_base_name=0;
+#endif
+static uint opt_protocol=0;
+
/*
When using extended-status relatively, ex_val_max_len is the estimated
maximum length for any relative value printed by extended-status. The
@@ -135,6 +141,8 @@ static struct my_option my_long_options[] =
#endif
{"port", 'P', "Port number to use for connection.", (gptr*) &tcp_port,
(gptr*) &tcp_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory)",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"relative", 'r',
"Show difference between current and previous values when used with -i. Currently works only with extended-status.",
(gptr*) &opt_relative, (gptr*) &opt_relative, 0, GET_BOOL, NO_ARG, 0, 0, 0,
@@ -142,6 +150,11 @@ static struct my_option my_long_options[] =
{"set-variable", 'O',
"Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef HAVE_SMEM
+ {"shared_memory_base_name", OPT_SHARED_MEMORY_BASE_NAME,
+ "Base name of shared memory", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name,
+ 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#endif
{"silent", 's', "Silently exit if one can't connect to server",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"socket", 'S', "Socket file to use for connection.",
@@ -205,7 +218,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
case 'W':
#ifdef __WIN__
- unix_port=MYSQL_NAMEDPIPE;
+ opt_protocol = MYSQL_PROTOCOL_PIPE;
#endif
break;
case '#':
@@ -234,6 +247,15 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
charsets_dir = argument;
#endif
break;
+ case OPT_MYSQL_PROTOCOL:
+ {
+ if ((opt_protocol = find_type(argument, &sql_protocol_typelib,0)) == ~(ulong) 0)
+ {
+ fprintf(stderr, "Unknown option to protocol: %s\n", argument);
+ exit(1);
+ }
+ break;
+ }
}
if (error)
{
@@ -284,6 +306,12 @@ int main(int argc,char *argv[])
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
#endif
+ if (opt_protocol)
+ mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
+#ifdef HAVE_SMEM
+ if (shared_memory_base_name)
+ mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
+#endif
if (sql_connect(&mysql, option_wait))
error = 1;
else
@@ -326,6 +354,9 @@ int main(int argc,char *argv[])
}
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
my_free(user,MYF(MY_ALLOW_ZERO_PTR));
+#ifdef HAVE_SMEM
+ my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
+#endif
free_defaults(save_argv);
my_end(0);
exit(error ? 1 : 0);
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index b2100ac1596..4cf86eb31c7 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -176,7 +176,7 @@ static void dump_remote_file(NET* net, const char* fname)
}
-static my_bool
+extern "C" my_bool
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
char *argument)
{
@@ -210,7 +210,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
print_version();
exit(0);
case '?':
- default:
usage();
exit(0);
}
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index 24b67a60255..f9719f05bf3 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -34,13 +34,17 @@ static my_bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0,
opt_compress = 0, opt_databases = 0, opt_fast = 0,
opt_medium_check = 0, opt_quick = 0, opt_all_in_1 = 0,
opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0,
- tty_password = 0;
+ tty_password = 0, opt_frm = 0;
static uint verbose = 0, opt_mysql_port=0;
static my_string opt_mysql_unix_port = 0;
static char *opt_password = 0, *current_user = 0, *default_charset = 0,
*current_host = 0;
static int first_error = 0;
DYNAMIC_ARRAY tables4repair;
+#ifdef HAVE_SMEM
+static char *shared_memory_base_name=0;
+#endif
+static uint opt_protocol=0;
enum operations {DO_CHECK, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE};
@@ -109,6 +113,8 @@ static struct my_option my_long_options[] =
{"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port,
(gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
0},
+ {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory)",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"quick", 'q',
"If you are using this option with CHECK TABLE, it prevents the check from scanning the rows to check for wrong links. This is the fastest check. If you are using this option with REPAIR TABLE, it will try to repair only the index tree. This is the fastest repair method for a table.",
(gptr*) &opt_quick, (gptr*) &opt_quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
@@ -116,6 +122,11 @@ static struct my_option my_long_options[] =
{"repair", 'r',
"Can fix almost anything except unique keys that aren't unique.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef HAVE_SMEM
+ {"shared_memory_base_name", OPT_SHARED_MEMORY_BASE_NAME,
+ "Base name of shared memory", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name,
+ 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#endif
{"silent", 's', "Print only error messages.", (gptr*) &opt_silent,
(gptr*) &opt_silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"socket", 'S', "Socket file to use for connection.",
@@ -128,13 +139,17 @@ static struct my_option my_long_options[] =
{"user", 'u', "User for login if not current user.", (gptr*) &current_user,
(gptr*) &current_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
+ {"use-frm", OPT_FRM,
+ "When used with REPAIR, get table structure from .frm file, so the table can be repaired even if .MYI header is corrupted.",
+ (gptr*) &opt_frm, (gptr*) &opt_frm, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
+ 0},
{"verbose", 'v', "Print info about the various stages.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
{"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
-
+
static const char *load_default_groups[] = { "mysqlcheck", "client", 0 };
@@ -223,7 +238,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
opt_password = my_strdup(argument, MYF(MY_FAE));
while (*argument) *argument++= 'x'; /* Destroy argument */
if (*start)
- start[1] = 0; /* Cut length of argument */
+ start[1] = 0; /* Cut length of argument */
}
else
tty_password = 1;
@@ -233,7 +248,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
case 'W':
#ifdef __WIN__
- opt_mysql_unix_port = MYSQL_NAMEDPIPE;
+ opt_protocol = MYSQL_PROTOCOL_PIPE;
#endif
break;
case '#':
@@ -247,6 +262,15 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
verbose++;
break;
case 'V': print_version(); exit(0);
+ case OPT_MYSQL_PROTOCOL:
+ {
+ if ((opt_protocol = find_type(argument, &sql_protocol_typelib,0)) == ~(ulong) 0)
+ {
+ fprintf(stderr, "Unknown option to protocol: %s\n", argument);
+ exit(1);
+ }
+ break;
+ }
}
return 0;
}
@@ -348,21 +372,25 @@ static int process_selected_tables(char *db, char **table_names, int tables)
return 1;
if (opt_all_in_1)
{
+ /*
+ We need table list in form `a`, `b`, `c`
+ that's why we need 4 more chars added to to each table name
+ space is for more readable output in logs and in case of error
+ */
char *table_names_comma_sep, *end;
int i, tot_length = 0;
for (i = 0; i < tables; i++)
- tot_length += strlen(*(table_names + i)) + 1;
+ tot_length += strlen(*(table_names + i)) + 4;
if (!(table_names_comma_sep = (char *)
- my_malloc((sizeof(char) * tot_length) + 1, MYF(MY_WME))))
+ my_malloc((sizeof(char) * tot_length) + 4, MYF(MY_WME))))
return 1;
for (end = table_names_comma_sep + 1; tables > 0;
tables--, table_names++)
{
- end = strmov(end, *table_names);
- *end++= ',';
+ end = strxmov(end, " `", *table_names, "`,", NullS);
}
*--end = 0;
handle_request_for_tables(table_names_comma_sep + 1, tot_length - 1);
@@ -389,22 +417,27 @@ static int process_all_tables_in_db(char *database)
if (opt_all_in_1)
{
+ /*
+ We need table list in form `a`, `b`, `c`
+ that's why we need 4 more chars added to to each table name
+ space is for more readable output in logs and in case of error
+ */
+
char *tables, *end;
uint tot_length = 0;
while ((row = mysql_fetch_row(res)))
- tot_length += strlen(row[0]) + 1;
+ tot_length += strlen(row[0]) + 4;
mysql_data_seek(res, 0);
- if (!(tables=(char *) my_malloc(sizeof(char)*tot_length+1, MYF(MY_WME))))
+ if (!(tables=(char *) my_malloc(sizeof(char)*tot_length+4, MYF(MY_WME))))
{
mysql_free_result(res);
return 1;
}
for (end = tables + 1; (row = mysql_fetch_row(res)) ;)
{
- end = strmov(end, row[0]);
- *end++= ',';
+ end = strxmov(end, " `", row[0], "`,", NullS);
}
*--end = 0;
if (tot_length)
@@ -452,6 +485,7 @@ static int handle_request_for_tables(char *tables, uint length)
op = "REPAIR";
if (opt_quick) end = strmov(end, " QUICK");
if (opt_extended) end = strmov(end, " EXTENDED");
+ if (opt_frm) end = strmov(end, " USE_FRM");
break;
case DO_ANALYZE:
op = "ANALYZE";
@@ -463,10 +497,14 @@ static int handle_request_for_tables(char *tables, uint length)
if (!(query =(char *) my_malloc((sizeof(char)*(length+110)), MYF(MY_WME))))
return 1;
- sprintf(query, "%s TABLE %s %s", op, tables, options);
+ if (opt_all_in_1)
+ /* No backticks here as we added them before */
+ sprintf(query, "%s TABLE %s %s", op, tables, options);
+ else
+ sprintf(query, "%s TABLE `%s` %s", op, tables, options);
if (mysql_query(sock, query))
{
- sprintf(message, "when executing '%s TABLE `%s` %s", op, tables,options);
+ sprintf(message, "when executing '%s TABLE ... %s'", op, options);
DBerror(sock, message);
return 1;
}
@@ -534,6 +572,12 @@ static int dbConnect(char *host, char *user, char *passwd)
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
#endif
+ if (opt_protocol)
+ mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
+#ifdef HAVE_SMEM
+ if (shared_memory_base_name)
+ mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
+#endif
if (!(sock = mysql_real_connect(&mysql_connection, host, user, passwd,
NULL, opt_mysql_port, opt_mysql_unix_port, 0)))
{
@@ -621,6 +665,9 @@ int main(int argc, char **argv)
if (opt_auto_repair)
delete_dynamic(&tables4repair);
my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
+#ifdef HAVE_SMEM
+ my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
+#endif
my_end(0);
return(first_error!=0);
} /* main */
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 9470786705d..9534cc68ed4 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -90,6 +90,10 @@ extern ulong net_buffer_length;
static DYNAMIC_STRING extended_row;
#include <sslopt-vars.h>
FILE *md_result_file;
+#ifdef HAVE_SMEM
+static char *shared_memory_base_name=0;
+#endif
+static uint opt_protocol=0;
static struct my_option my_long_options[] =
{
@@ -200,6 +204,8 @@ static struct my_option my_long_options[] =
{"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port,
(gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
0},
+ {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory)",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"quick", 'q', "Don't buffer query, dump directly to stdout.",
(gptr*) &quick, (gptr*) &quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"quote-names",'Q', "Quote table and column names with a `",
@@ -208,6 +214,11 @@ static struct my_option my_long_options[] =
{"result-file", 'r',
"Direct output to a given file. This option should be used in MSDOS, because it prevents new line '\\n' from being converted to '\\r\\n' (carriage return + line feed).",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef HAVE_SMEM
+ {"shared_memory_base_name", OPT_SHARED_MEMORY_BASE_NAME,
+ "Base name of shared memory", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name,
+ 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#endif
{"socket", 'S', "Socket file to use for connection.",
(gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -294,7 +305,10 @@ static void short_usage(void)
static void write_header(FILE *sql_file, char *db_name)
{
if (opt_xml)
+ {
fprintf(sql_file,"<?xml version=\"1.0\"?>\n");
+ fprintf(sql_file,"<mysqldump>\n");
+ }
else
{
fprintf(sql_file, "-- MySQL dump %s\n--\n", DUMP_VERSION);
@@ -308,6 +322,12 @@ static void write_header(FILE *sql_file, char *db_name)
return;
} /* write_header */
+static void write_footer(FILE *sql_file)
+{
+ if (opt_xml)
+ fprintf(sql_file,"</mysqldump>");
+ fputs("\n", sql_file);
+} /* write_footer */
static my_bool
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
@@ -338,7 +358,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
case 'W':
#ifdef __WIN__
- opt_mysql_unix_port=MYSQL_NAMEDPIPE;
+ opt_protocol = MYSQL_PROTOCOL_PIPE;
#endif
break;
case 'T':
@@ -365,6 +385,15 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case (int) OPT_TABLES:
opt_databases=0;
break;
+ case OPT_MYSQL_PROTOCOL:
+ {
+ if ((opt_protocol = find_type(argument, &sql_protocol_typelib,0)) == ~(ulong) 0)
+ {
+ fprintf(stderr, "Unknown option to protocol: %s\n", argument);
+ exit(1);
+ }
+ break;
+ }
}
return 0;
}
@@ -474,6 +503,12 @@ static int dbConnect(char *host, char *user,char *passwd)
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
#endif
+ if (opt_protocol)
+ mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
+#ifdef HAVE_SMEM
+ if (shared_memory_base_name)
+ mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
+#endif
if (!(sock= mysql_real_connect(&mysql_connection,host,user,passwd,
NULL,opt_mysql_port,opt_mysql_unix_port,
0)))
@@ -978,7 +1013,7 @@ static void dumpTable(uint numFields, char *table)
rownr=0;
init_length=(uint) strlen(insert_pat)+4;
if (opt_xml)
- fprintf(md_result_file, "\t<%s>\n", table);
+ fprintf(md_result_file, "\t<table name=\"%s\">\n", table);
if (opt_autocommit)
fprintf(md_result_file, "set autocommit=0;\n");
@@ -1068,9 +1103,9 @@ static void dumpTable(uint numFields, char *table)
/* change any strings ("inf","nan",..) into NULL */
char *ptr = row[i];
if (opt_xml)
- fprintf(md_result_file, "\t\t<%s>%s</%s>\n",
+ fprintf(md_result_file, "\t\t<field name=\"%s\">%s</field>\n",
field->name,
- !my_isalpha(system_charset_info,*ptr) ?ptr: "NULL",field->name);
+ !my_isalpha(system_charset_info, *ptr) ? ptr: "NULL");
else
fputs((!my_isalpha(system_charset_info,*ptr)) ?
ptr : "NULL", md_result_file);
@@ -1079,8 +1114,8 @@ static void dumpTable(uint numFields, char *table)
else
{
if (opt_xml)
- fprintf(md_result_file, "\t\t<%s>%s</%s>\n",
- field->name, "NULL", field->name);
+ fprintf(md_result_file, "\t\t<field name=\"%s\">%s</field>\n",
+ field->name, "NULL");
else
fputs("NULL", md_result_file);
}
@@ -1121,7 +1156,7 @@ static void dumpTable(uint numFields, char *table)
/* XML - close table tag and supress regular output */
if (opt_xml)
- fprintf(md_result_file, "\t</%s>\n", table);
+ fprintf(md_result_file, "\t</table>\n");
else if (extended_insert && row_break)
fputs(";\n", md_result_file); /* If not empty table */
fflush(md_result_file);
@@ -1153,7 +1188,7 @@ static void print_quoted_xml(FILE *output, char *fname, char *str, uint len)
{
const char *end;
- fprintf(output, "\t\t<%s>", fname);
+ fprintf(output, "\t\t<field name=\"%s\">", fname);
for (end = str + len; str != end; str++)
{
if (*str == '<')
@@ -1167,7 +1202,7 @@ static void print_quoted_xml(FILE *output, char *fname, char *str, uint len)
else
fputc(*str, output);
}
- fprintf(output, "</%s>\n", fname);
+ fprintf(output, "</field>\n");
}
static char *getTableName(int reset)
@@ -1222,13 +1257,8 @@ static int dump_databases(char **db_names)
int result=0;
for ( ; *db_names ; db_names++)
{
- /* XML edit - add database element */
- if (opt_xml)
- fprintf(md_result_file, "<%s>\n", *db_names);
if (dump_all_tables_in_db(*db_names))
result=1;
- if (opt_xml)
- fprintf(md_result_file, "</%s>\n", *db_names);
}
return result;
} /* dump_databases */
@@ -1241,7 +1271,7 @@ static int init_dumping(char *database)
DBerror(sock, "when selecting the database");
return 1; /* If --force */
}
- if (!path)
+ if (!path && !opt_xml)
{
if (opt_databases || opt_alldbs)
{
@@ -1252,7 +1282,7 @@ static int init_dumping(char *database)
MYSQL_ROW row;
MYSQL_RES *dbinfo;
- sprintf(qbuf,"SHOW CREATE DATABASE IF NOT EXISTS %s",database);
+ sprintf(qbuf,"SHOW CREATE DATABASE WITH IF NOT EXISTS %s",database);
if (mysql_query(sock, qbuf) || !(dbinfo = mysql_store_result(sock)))
{
@@ -1287,6 +1317,8 @@ static int dump_all_tables_in_db(char *database)
if (init_dumping(database))
return 1;
+ if (opt_xml)
+ fprintf(md_result_file, "<database name=\"%s\">\n", database);
if (lock_tables)
{
DYNAMIC_STRING query;
@@ -1313,6 +1345,8 @@ static int dump_all_tables_in_db(char *database)
if (!dFlag && numrows > 0)
dumpTable(numrows,table);
}
+ if (opt_xml)
+ fprintf(md_result_file, "</database>\n");
if (lock_tables)
mysql_query(sock,"UNLOCK_TABLES");
return 0;
@@ -1349,12 +1383,16 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
DBerror(sock, "when doing refresh");
/* We shall countinue here, if --force was given */
}
+ if (opt_xml)
+ fprintf(md_result_file, "<database name=\"%s\">\n", db);
for (; tables > 0 ; tables-- , table_names++)
{
numrows = getTableStructure(*table_names, db);
if (!dFlag && numrows > 0)
dumpTable(numrows, *table_names);
}
+ if (opt_xml)
+ fprintf(md_result_file, "</database>\n");
if (lock_tables)
mysql_query(sock,"UNLOCK_TABLES");
return 0;
@@ -1471,6 +1509,9 @@ int main(int argc, char **argv)
MYF(0), mysql_error(sock));
}
else if (opt_single_transaction) /* Just to make it beautiful enough */
+#ifdef HAVE_SMEM
+ my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
+#endif
{
/*
In case we were locking all tables, we did not start transaction
@@ -1485,7 +1526,7 @@ int main(int argc, char **argv)
}
}
dbDisconnect(current_host);
- fputs("\n", md_result_file);
+ write_footer(md_result_file);
if (md_result_file != stdout)
my_fclose(md_result_file, MYF(0));
my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index a11b7383517..2de4a9b81b5 100644
--- a/client/mysqlimport.c
+++ b/client/mysqlimport.c
@@ -49,6 +49,11 @@ static my_string opt_mysql_unix_port=0;
static my_string opt_ignore_lines=0;
#include <sslopt-vars.h>
+#ifdef HAVE_SMEM
+static char *shared_memory_base_name=0;
+#endif
+static uint opt_protocol=0;
+
static struct my_option my_long_options[] =
{
{"character-sets-dir", OPT_CHARSETS_DIR,
@@ -112,8 +117,15 @@ static struct my_option my_long_options[] =
{"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port,
(gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
0},
+ {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory)",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"replace", 'r', "If duplicate unique key was found, replace old row.",
(gptr*) &replace, (gptr*) &replace, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef HAVE_SMEM
+ {"shared_memory_base_name", OPT_SHARED_MEMORY_BASE_NAME,
+ "Base name of shared memory", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name,
+ 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#endif
{"silent", 's', "Be more silent.", (gptr*) &silent, (gptr*) &silent, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"socket", 'S', "Socket file to use for connection.",
@@ -181,10 +193,19 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
#ifdef __WIN__
case 'W':
- opt_mysql_unix_port=MYSQL_NAMEDPIPE;
+ opt_protocol = MYSQL_PROTOCOL_PIPE;
opt_local_file=1;
break;
#endif
+ case OPT_MYSQL_PROTOCOL:
+ {
+ if ((opt_protocol = find_type(argument, &sql_protocol_typelib,0)) == ~(ulong) 0)
+ {
+ fprintf(stderr, "Unknown option to protocol: %s\n", argument);
+ exit(1);
+ }
+ break;
+ }
case '#':
DBUG_PUSH(argument ? argument : "d:t:o");
break;
@@ -352,6 +373,12 @@ static MYSQL *db_connect(char *host, char *database, char *user, char *passwd)
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
#endif
+ if (opt_protocol)
+ mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
+#ifdef HAVE_SMEM
+ if (shared_memory_base_name)
+ mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
+#endif
if (!(sock= mysql_real_connect(&mysql_connection,host,user,passwd,
database,opt_mysql_port,opt_mysql_unix_port,
0)))
@@ -486,6 +513,9 @@ int main(int argc, char **argv)
exitcode = error;
db_disconnect(current_host, sock);
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+#ifdef HAVE_SMEM
+ my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
+#endif
free_defaults(argv_to_free);
my_end(0);
return(exitcode);
diff --git a/client/mysqlshow.c b/client/mysqlshow.c
index 5475fc7b531..df624a02c55 100644
--- a/client/mysqlshow.c
+++ b/client/mysqlshow.c
@@ -31,6 +31,11 @@ static my_string host=0,opt_password=0,user=0;
static my_bool opt_show_keys=0,opt_compress=0,opt_status=0, tty_password=0;
static uint opt_verbose=0;
+#ifdef HAVE_SMEM
+static char *shared_memory_base_name=0;
+#endif
+static uint opt_protocol=0;
+
static void get_options(int *argc,char ***argv);
static uint opt_mysql_port=0;
static int list_dbs(MYSQL *mysql,const char *wild);
@@ -51,6 +56,7 @@ static my_string opt_mysql_unix_port=0;
int main(int argc, char **argv)
{
int error;
+ my_bool first_argument_uses_wildcards=0;
char *wild;
MYSQL mysql;
MY_INIT(argv[0]);
@@ -58,21 +64,37 @@ int main(int argc, char **argv)
get_options(&argc,&argv);
wild=0;
- if (argc && strcont(argv[argc-1],"*?%_"))
+ if (argc)
{
- char *pos;
-
- wild=argv[--argc];
- for (pos=wild ; *pos ; pos++)
- { /* Unix wildcards to sql */
- if (*pos == '*')
- *pos='%';
- else if (*pos == '?')
- *pos='_';
- }
+ char *pos= argv[argc-1], *to;
+ for (to= pos ; *pos ; pos++, to++)
+ {
+ switch (*pos)
+ {
+ case '*':
+ *pos= '%';
+ first_argument_uses_wildcards= 1;
+ break;
+ case '?':
+ *pos= '_';
+ first_argument_uses_wildcards= 1;
+ break;
+ case '%':
+ case '_':
+ first_argument_uses_wildcards= 1;
+ break;
+ case '\\':
+ pos++;
+ default: break;
+ }
+ *to= *pos;
+ }
+ *to= *pos; // just to copy a '\0' if '\\' was used
}
+ if (first_argument_uses_wildcards)
+ wild= argv[--argc];
else if (argc == 3) /* We only want one field */
- wild=argv[--argc];
+ wild= argv[--argc];
if (argc > 2)
{
@@ -87,8 +109,14 @@ int main(int argc, char **argv)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
#endif
+ if (opt_protocol)
+ mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
+#ifdef HAVE_SMEM
+ if (shared_memory_base_name)
+ mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
+#endif
if (!(mysql_real_connect(&mysql,host,user,opt_password,
- argv[0],opt_mysql_port,opt_mysql_unix_port,
+ (first_argument_uses_wildcards) ? "" : argv[0],opt_mysql_port,opt_mysql_unix_port,
0)))
{
fprintf(stderr,"%s: %s\n",my_progname,mysql_error(&mysql));
@@ -114,6 +142,9 @@ int main(int argc, char **argv)
mysql_close(&mysql); /* Close & free connection */
if (opt_password)
my_free(opt_password,MYF(0));
+#ifdef HAVE_SMEM
+ my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
+#endif
my_end(0);
exit(error ? 1 : 0);
return 0; /* No compiler warnings */
@@ -148,6 +179,13 @@ static struct my_option my_long_options[] =
{"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
+ {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory)",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef HAVE_SMEM
+ {"shared_memory_base_name", OPT_SHARED_MEMORY_BASE_NAME,
+ "Base name of shared memory", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name,
+ 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#endif
{"socket", 'S', "Socket file to use for connection.",
(gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -213,9 +251,18 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
case 'W':
#ifdef __WIN__
- opt_mysql_unix_port=MYSQL_NAMEDPIPE;
+ opt_protocol = MYSQL_PROTOCOL_PIPE;
#endif
break;
+ case OPT_MYSQL_PROTOCOL:
+ {
+ if ((opt_protocol = find_type(argument, &sql_protocol_typelib,0)) == ~(ulong) 0)
+ {
+ fprintf(stderr, "Unknown option to protocol: %s\n", argument);
+ exit(1);
+ }
+ break;
+ }
case '#':
DBUG_PUSH(argument ? argument : "d:t:o");
break;
diff --git a/client/mysqltest.c b/client/mysqltest.c
index 036130f2d80..9d724404edc 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -91,7 +91,7 @@
enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD,
- OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT};
+ OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT, OPT_SKIP_SAFEMALLOC};
static int record = 0, opt_sleep=0;
static char *db = 0, *pass=0;
@@ -1850,6 +1850,9 @@ static struct my_option my_long_options[] =
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"silent", 's', "Suppress all normal output. Synonym for --quiet.",
(gptr*) &silent, (gptr*) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-safemalloc", OPT_SKIP_SAFEMALLOC,
+ "Don't use the memory allocation checking", 0, 0, 0, GET_NO_ARG, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
{"sleep", 'T', "Sleep always this many seconds on sleep commands",
(gptr*) &opt_sleep, (gptr*) &opt_sleep, 0, GET_INT, REQUIRED_ARG, 0, 0, 0,
0, 0, 0},
@@ -1949,6 +1952,11 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
if (read_server_arguments(argument))
die(NullS);
break;
+ case OPT_SKIP_SAFEMALLOC:
+#ifdef SAFEMALLOC
+ sf_malloc_quick=1;
+#endif
+ break;
case 'V':
print_version();
exit(0);
@@ -2323,6 +2331,7 @@ static void var_from_env(const char* name, const char* def_val)
static void init_var_hash()
{
VAR* v;
+ DBUG_ENTER("init_var_hash");
if (hash_init(&var_hash, system_charset_info,
1024, 0, 0, get_var_key, var_free, MYF(0)))
die("Variable hash initialization failed");
@@ -2332,6 +2341,7 @@ static void init_var_hash()
var_from_env("BIG_TEST", opt_big_test ? "1" : "0");
v=var_init(0,"MAX_TABLES", 0, (sizeof(ulong) == 4) ? "31" : "63",0);
hash_insert(&var_hash, (byte*)v);
+ DBUG_VOID_RETURN;
}
diff --git a/client/sql_string.cc b/client/sql_string.cc
index 65854ece0ef..5083fb13105 100644
--- a/client/sql_string.cc
+++ b/client/sql_string.cc
@@ -40,19 +40,16 @@ extern void sql_element_free(void *ptr);
bool String::real_alloc(uint32 arg_length)
{
arg_length=ALIGN_SIZE(arg_length+1);
+ str_length=0;
if (Alloced_length < arg_length)
{
free();
if (!(Ptr=(char*) my_malloc(arg_length,MYF(MY_WME))))
- {
- str_length=0;
return TRUE;
- }
Alloced_length=arg_length;
alloced=1;
}
Ptr[0]=0;
- str_length=0;
return FALSE;
}
@@ -94,36 +91,58 @@ bool String::realloc(uint32 alloc_length)
return FALSE;
}
-bool String::set(longlong num)
+bool String::set(longlong num, CHARSET_INFO *cs)
{
- if (alloc(21))
+ uint l=20*cs->mbmaxlen+1;
+
+ if (alloc(l))
return TRUE;
- str_length=(uint32) (longlong10_to_str(num,Ptr,-10)-Ptr);
+ if (cs->snprintf == my_snprintf_8bit)
+ {
+ str_length=(uint32) (longlong10_to_str(num,Ptr,-10)-Ptr);
+ }
+ else
+ {
+ str_length=cs->snprintf(cs,Ptr,l,"%d",num);
+ }
+ str_charset=cs;
return FALSE;
}
-bool String::set(ulonglong num)
+bool String::set(ulonglong num, CHARSET_INFO *cs)
{
- if (alloc(21))
+ uint l=20*cs->mbmaxlen+1;
+
+ if (alloc(l))
return TRUE;
- str_length=(uint32) (longlong10_to_str(num,Ptr,10)-Ptr);
+ if (cs->snprintf == my_snprintf_8bit)
+ {
+ str_length=(uint32) (longlong10_to_str(num,Ptr,10)-Ptr);
+ }
+ else
+ {
+ str_length=cs->snprintf(cs,Ptr,l,"%d",num);
+ }
+ str_charset=cs;
return FALSE;
}
-bool String::set(double num,uint decimals)
+bool String::set(double num,uint decimals, CHARSET_INFO *cs)
{
char buff[331];
+
+ str_charset=cs;
if (decimals >= NOT_FIXED_DEC)
{
sprintf(buff,"%.14g",num); // Enough for a DATETIME
- return copy(buff, (uint32) strlen(buff));
+ return copy(buff, (uint32) strlen(buff), my_charset_latin1, cs);
}
#ifdef HAVE_FCONVERT
int decpt,sign;
char *pos,*to;
VOID(fconvert(num,(int) decimals,&decpt,&sign,buff+1));
- if (!isdigit(buff[1]))
+ if (!my_isdigit(my_charset_latin1, buff[1]))
{ // Nan or Inf
pos=buff+1;
if (sign)
@@ -131,7 +150,7 @@ bool String::set(double num,uint decimals)
buff[0]='-';
pos=buff;
}
- return copy(pos,(uint32) strlen(pos));
+ return copy(pos,(uint32) strlen(pos), my_charset_latin1, cs);
}
if (alloc((uint32) ((uint32) decpt+3+decimals)))
return TRUE;
@@ -181,7 +200,7 @@ end:
#else
sprintf(buff,"%.*f",(int) decimals,num);
#endif
- return copy(buff,(uint32) strlen(buff));
+ return copy(buff,(uint32) strlen(buff), my_charset_latin1, cs);
#endif
}
@@ -203,16 +222,67 @@ bool String::copy(const String &str)
str_length=str.str_length;
bmove(Ptr,str.Ptr,str_length); // May be overlapping
Ptr[str_length]=0;
+ str_charset=str.str_charset;
return FALSE;
}
-bool String::copy(const char *str,uint32 arg_length)
+bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs)
{
if (alloc(arg_length))
return TRUE;
if ((str_length=arg_length))
memcpy(Ptr,str,arg_length);
Ptr[arg_length]=0;
+ str_charset=cs;
+ return FALSE;
+}
+
+/* Copy with charset convertion */
+bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *from, CHARSET_INFO *to)
+{
+ uint32 new_length=to->mbmaxlen*arg_length;
+ int cnvres;
+ my_wc_t wc;
+ const uchar *s=(const uchar *)str;
+ const uchar *se=s+arg_length;
+ uchar *d, *de;
+
+ if (alloc(new_length))
+ return TRUE;
+
+ d=(uchar *)Ptr;
+ de=d+new_length;
+
+ for (str_length=new_length ; s < se && d < de ; )
+ {
+ if ((cnvres=from->mb_wc(from,&wc,s,se)) > 0 )
+ {
+ s+=cnvres;
+ }
+ else if (cnvres==MY_CS_ILSEQ)
+ {
+ s++;
+ wc='?';
+ }
+ else
+ break;
+
+outp:
+ if((cnvres=to->wc_mb(to,wc,d,de)) >0 )
+ {
+ d+=cnvres;
+ }
+ else if (cnvres==MY_CS_ILUNI && wc!='?')
+ {
+ wc='?';
+ goto outp;
+ }
+ else
+ break;
+ }
+ Ptr[new_length]=0;
+ length((uint32) (d-(uchar *)Ptr));
+ str_charset=to;
return FALSE;
}
@@ -489,7 +559,7 @@ void String::qs_append(double d)
void String::qs_append(double *d)
{
double ld;
- float8get(ld, d);
+ float8get(ld, (char*) d);
qs_append(ld);
}
@@ -523,12 +593,23 @@ int sortcmp(const String *x,const String *y)
#endif /* USE_STRCOLL */
x_len-=len; // For easy end space test
y_len-=len;
- while (len--)
+ if (x->str_charset->sort_order)
{
- if (x->str_charset->sort_order[(uchar) *s++] !=
+ while (len--)
+ {
+ if (x->str_charset->sort_order[(uchar) *s++] !=
x->str_charset->sort_order[(uchar) *t++])
- return ((int) x->str_charset->sort_order[(uchar) s[-1]] -
- (int) x->str_charset->sort_order[(uchar) t[-1]]);
+ return ((int) x->str_charset->sort_order[(uchar) s[-1]] -
+ (int) x->str_charset->sort_order[(uchar) t[-1]]);
+ }
+ }
+ else
+ {
+ while (len--)
+ {
+ if (*s++ != *t++)
+ return ((int) s[-1] - (int) t[-1]);
+ }
}
#ifndef CMP_ENDSPACE
/* Don't compare end space in strings */
@@ -586,264 +667,9 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length)
return from; // Actually an error
if ((to->str_length=min(from->str_length,from_length)))
memcpy(to->Ptr,from->Ptr,to->str_length);
+ to->str_charset=from->str_charset;
return to;
}
-/* Make it easier to handle different charactersets */
-
-#ifdef USE_MB
-#define INC_PTR(cs,A,B) A+=((use_mb_flag && \
- my_ismbchar(cs,A,B)) ? my_ismbchar(cs,A,B) : 1)
-#else
-#define INC_PTR(cs,A,B) A++
-#endif
-
-/*
-** Compare string against string with wildcard
-** 0 if matched
-** -1 if not matched with wildcard
-** 1 if matched with wildcard
-*/
-
-#ifdef LIKE_CMP_TOUPPER
-#define likeconv(s,A) (uchar) my_toupper(s,A)
-#else
-#define likeconv(s,A) (uchar) (s)->sort_order[(uchar) (A)]
-#endif
-
-int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *str_end,
- const char *wildstr,const char *wildend,
- char escape)
-{
- int result= -1; // Not found, using wildcards
-#ifdef USE_MB
- bool use_mb_flag=use_mb(cs);
-#endif
- while (wildstr != wildend)
- {
- while (*wildstr != wild_many && *wildstr != wild_one)
- {
- if (*wildstr == escape && wildstr+1 != wildend)
- wildstr++;
-#ifdef USE_MB
- int l;
- if (use_mb_flag &&
- (l = my_ismbchar(cs, wildstr, wildend)))
- {
- if (str+l > str_end || memcmp(str, wildstr, l) != 0)
- return 1;
- str += l;
- wildstr += l;
- }
- else
-#endif
- if (str == str_end || likeconv(cs,*wildstr++) != likeconv(cs,*str++))
- return(1); // No match
- if (wildstr == wildend)
- return (str != str_end); // Match if both are at end
- result=1; // Found an anchor char
- }
- if (*wildstr == wild_one)
- {
- do
- {
- if (str == str_end) // Skip one char if possible
- return (result);
- INC_PTR(cs,str,str_end);
- } while (++wildstr < wildend && *wildstr == wild_one);
- if (wildstr == wildend)
- break;
- }
- if (*wildstr == wild_many)
- { // Found wild_many
- wildstr++;
- /* Remove any '%' and '_' from the wild search string */
- for ( ; wildstr != wildend ; wildstr++)
- {
- if (*wildstr == wild_many)
- continue;
- if (*wildstr == wild_one)
- {
- if (str == str_end)
- return (-1);
- INC_PTR(cs,str,str_end);
- continue;
- }
- break; // Not a wild character
- }
- if (wildstr == wildend)
- return(0); // Ok if wild_many is last
- if (str == str_end)
- return -1;
-
- uchar cmp;
- if ((cmp= *wildstr) == escape && wildstr+1 != wildend)
- cmp= *++wildstr;
-#ifdef USE_MB
- const char* mb = wildstr;
- int mblen;
- LINT_INIT(mblen);
- if (use_mb_flag)
- mblen = my_ismbchar(cs, wildstr, wildend);
-#endif
- INC_PTR(cs,wildstr,wildend); // This is compared trough cmp
- cmp=likeconv(cs,cmp);
- do
- {
-#ifdef USE_MB
- if (use_mb_flag)
- {
- for (;;)
- {
- if (str >= str_end)
- return -1;
- if (mblen)
- {
- if (str+mblen <= str_end && memcmp(str, mb, mblen) == 0)
- {
- str += mblen;
- break;
- }
- }
- else if (!my_ismbchar(cs, str, str_end) &&
- likeconv(cs,*str) == cmp)
- {
- str++;
- break;
- }
- INC_PTR(cs,str, str_end);
- }
- }
- else
- {
-#endif /* USE_MB */
- while (str != str_end && likeconv(cs,*str) != cmp)
- str++;
- if (str++ == str_end) return (-1);
-#ifdef USE_MB
- }
-#endif
- {
- int tmp=wild_case_compare(cs,str,str_end,wildstr,wildend,escape);
- if (tmp <= 0)
- return (tmp);
- }
- } while (str != str_end && wildstr[0] != wild_many);
- return(-1);
- }
- }
- return (str != str_end ? 1 : 0);
-}
-
-
-int wild_case_compare(String &match,String &wild, char escape)
-{
- DBUG_ENTER("wild_case_compare");
- DBUG_PRINT("enter",("match='%s', wild='%s', escape='%c'"
- ,match.ptr(),wild.ptr(),escape));
- DBUG_RETURN(wild_case_compare(match.str_charset,match.ptr(),match.ptr()+match.length(),
- wild.ptr(), wild.ptr()+wild.length(),escape));
-}
-
-/*
-** The following is used when using LIKE on binary strings
-*/
-
-int wild_compare(const char *str,const char *str_end,
- const char *wildstr,const char *wildend,char escape)
-{
- DBUG_ENTER("wild_compare");
- DBUG_PRINT("enter",("str='%s', str_end='%s', wildstr='%s', wildend='%s', escape='%c'"
- ,str,str_end,wildstr,wildend,escape));
- int result= -1; // Not found, using wildcards
- while (wildstr != wildend)
- {
- while (*wildstr != wild_many && *wildstr != wild_one)
- {
- if (*wildstr == escape && wildstr+1 != wildend)
- wildstr++;
- if (str == str_end || *wildstr++ != *str++)
- {
- DBUG_RETURN(1);
- }
- if (wildstr == wildend)
- {
- DBUG_RETURN(str != str_end); // Match if both are at end
- }
- result=1; // Found an anchor char
- }
- if (*wildstr == wild_one)
- {
- do
- {
- if (str == str_end) // Skip one char if possible
- DBUG_RETURN(result);
- str++;
- } while (*++wildstr == wild_one && wildstr != wildend);
- if (wildstr == wildend)
- break;
- }
- if (*wildstr == wild_many)
- { // Found wild_many
- wildstr++;
- /* Remove any '%' and '_' from the wild search string */
- for ( ; wildstr != wildend ; wildstr++)
- {
- if (*wildstr == wild_many)
- continue;
- if (*wildstr == wild_one)
- {
- if (str == str_end)
- {
- DBUG_RETURN(-1);
- }
- str++;
- continue;
- }
- break; // Not a wild character
- }
- if (wildstr == wildend)
- {
- DBUG_RETURN(0); // Ok if wild_many is last
- }
- if (str == str_end)
- {
- DBUG_RETURN(-1);
- }
- char cmp;
- if ((cmp= *wildstr) == escape && wildstr+1 != wildend)
- cmp= *++wildstr;
- wildstr++; // This is compared trough cmp
- do
- {
- while (str != str_end && *str != cmp)
- str++;
- if (str++ == str_end)
- {
- DBUG_RETURN(-1);
- }
- {
- int tmp=wild_compare(str,str_end,wildstr,wildend,escape);
- if (tmp <= 0)
- {
- DBUG_RETURN(tmp);
- }
- }
- } while (str != str_end && wildstr[0] != wild_many);
- DBUG_RETURN(-1);
- }
- }
- DBUG_RETURN(str != str_end ? 1 : 0);
-}
-
-
-int wild_compare(String &match,String &wild, char escape)
-{
- DBUG_ENTER("wild_compare");
- DBUG_PRINT("enter",("match='%s', wild='%s', escape='%c'"
- ,match.ptr(),wild.ptr(),escape));
- DBUG_RETURN(wild_compare(match.ptr(),match.ptr()+match.length(),
- wild.ptr(), wild.ptr()+wild.length(),escape));
-}
diff --git a/client/sql_string.h b/client/sql_string.h
index 811e49a0d02..42f9e446981 100644
--- a/client/sql_string.h
+++ b/client/sql_string.h
@@ -28,8 +28,6 @@ class String;
int sortcmp(const String *a,const String *b);
int stringcmp(const String *a,const String *b);
String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
-int wild_case_compare(String &match,String &wild,char escape);
-int wild_compare(String &match,String &wild,char escape);
class String
{
@@ -46,22 +44,22 @@ public:
String(uint32 length_arg)
{
alloced=0; Alloced_length=0; (void) real_alloc(length_arg);
- str_charset=default_charset_info;
+ str_charset=default_charset_info;
}
- String(const char *str)
+ String(const char *str, CHARSET_INFO *cs)
{
Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0;
- str_charset=default_charset_info;
+ str_charset=cs;
}
- String(const char *str,uint32 len)
+ String(const char *str,uint32 len, CHARSET_INFO *cs)
{
Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0;
- str_charset=default_charset_info;
+ str_charset=cs;
}
- String(char *str,uint32 len)
+ String(char *str,uint32 len, CHARSET_INFO *cs)
{
Ptr=(char*) str; Alloced_length=str_length=len; alloced=0;
- str_charset=default_charset_info;
+ str_charset=cs;
}
String(const String &str)
{
@@ -74,6 +72,7 @@ public:
{ sql_element_free(ptr_arg); }
~String() { free(); }
+ inline void set_charset(CHARSET_INFO *charset) { str_charset=charset; }
inline CHARSET_INFO *charset() const { return str_charset; }
inline uint32 length() const { return str_length;}
inline uint32 alloced_length() const { return Alloced_length;}
@@ -102,28 +101,31 @@ public:
Alloced_length=str.Alloced_length-offset;
else
Alloced_length=0;
+ str_charset=str.str_charset;
}
- inline void set(char *str,uint32 arg_length)
+ inline void set(char *str,uint32 arg_length, CHARSET_INFO *cs)
{
free();
Ptr=(char*) str; str_length=Alloced_length=arg_length ; alloced=0;
+ str_charset=cs;
}
- inline void set(const char *str,uint32 arg_length)
+ inline void set(const char *str,uint32 arg_length, CHARSET_INFO *cs)
{
free();
Ptr=(char*) str; str_length=arg_length; Alloced_length=0 ; alloced=0;
+ str_charset=cs;
}
- inline void set_quick(char *str,uint32 arg_length)
+ inline void set_quick(char *str,uint32 arg_length, CHARSET_INFO *cs)
{
if (!alloced)
{
Ptr=(char*) str; str_length=Alloced_length=arg_length;
}
+ str_charset=cs;
}
- bool set(longlong num);
- /* bool set(long num); */
- bool set(ulonglong num);
- bool set(double num,uint decimals=2);
+ bool set(longlong num, CHARSET_INFO *cs);
+ bool set(ulonglong num, CHARSET_INFO *cs);
+ bool set(double num,uint decimals, CHARSET_INFO *cs);
inline void free()
{
if (alloced)
@@ -174,7 +176,8 @@ public:
bool copy(); // Alloc string if not alloced
bool copy(const String &s); // Allocate new string
- bool copy(const char *s,uint32 arg_length); // Allocate new string
+ bool copy(const char *s,uint32 arg_length, CHARSET_INFO *cs); // Allocate new string
+ bool copy(const char*s,uint32 arg_length, CHARSET_INFO *csfrom, CHARSET_INFO *csto);
bool append(const String &s);
bool append(const char *s,uint32 arg_length=0);
bool append(IO_CACHE* file, uint32 arg_length);
@@ -203,21 +206,20 @@ public:
friend int sortcmp(const String *a,const String *b);
friend int stringcmp(const String *a,const String *b);
friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
- friend int wild_case_compare(String &match,String &wild,char escape);
- friend int wild_compare(String &match,String &wild,char escape);
uint32 numchars();
int charpos(int i,uint32 offset=0);
-// added by Holyfoot for "geometry" needs
int reserve(uint32 space_needed)
{
return realloc(str_length + space_needed);
}
int reserve(uint32 space_needed, uint32 grow_by);
-// these append operations do NOT check alloced memory
-// q_*** methods writes values of parameters itself
-// qs_*** methods writes string representation of value
+ /*
+ The following append operations do NOT check alloced memory
+ q_*** methods writes values of parameters itself
+ qs_*** methods writes string representation of value
+ */
void q_append(const char &c)
{
Ptr[str_length++] = c;