summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2004-12-06 11:38:56 +0200
committerunknown <monty@mysql.com>2004-12-06 11:38:56 +0200
commit796bd7de96a1d1ec422708b90df5328388201c10 (patch)
treea7bb331b7dac7ac2b3cda915e99bb8c1333f4fec /client
parent289d3b2ee0f912dd4f128e1c61685d7bb170eb90 (diff)
parentf8cdf570979c550ef04c53f691118ed2b1296a7c (diff)
downloadmariadb-git-796bd7de96a1d1ec422708b90df5328388201c10.tar.gz
Merge with 4.1
BitKeeper/etc/ignore: auto-union BitKeeper/etc/logging_ok: auto-union BUILD/SETUP.sh: Auto merged Build-tools/Do-compile: Auto merged client/mysqladmin.cc: Auto merged configure.in: Auto merged innobase/include/lock0lock.h: Auto merged innobase/os/os0file.c: Auto merged libmysqld/Makefile.am: Auto merged mysql-test/mysql-test-run.sh: Auto merged mysql-test/r/ctype_ucs.result: Auto merged mysql-test/r/heap.result: Auto merged mysql-test/r/insert_select.result: Auto merged mysql-test/r/lowercase_table3.result: Auto merged mysql-test/r/rpl_start_stop_slave.result: Auto merged mysql-test/r/subselect.result: Auto merged mysql-test/t/ctype_ucs.test: Auto merged mysql-test/t/rpl_until.test: Auto merged mysql-test/t/subselect.test: Auto merged ndb/src/kernel/blocks/dblqh/DblqhMain.cpp: Auto merged sql/field.cc: Auto merged sql/field.h: Auto merged sql/ha_myisam.h: Auto merged sql/handler.cc: Auto merged sql/handler.h: Auto merged sql/item.h: Auto merged sql/item_cmpfunc.cc: Auto merged sql/item_func.cc: Auto merged sql/lock.cc: Auto merged sql/log_event.h: Auto merged sql/mysql_priv.h: Auto merged sql/mysqld.cc: Auto merged sql/set_var.cc: Auto merged sql/slave.cc: Auto merged sql/slave.h: Auto merged sql/sql_acl.cc: Auto merged sql/sql_base.cc: Auto merged sql/sql_class.h: Auto merged sql/sql_db.cc: Auto merged sql/sql_delete.cc: Auto merged sql/sql_prepare.cc: Auto merged sql/sql_rename.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_show.cc: Auto merged sql/sql_update.cc: Auto merged sql/sql_yacc.yy: Auto merged sql/log_event.cc: Merge with 4.1 Trivial cleanup
Diffstat (limited to 'client')
-rw-r--r--client/client_priv.h2
-rw-r--r--client/mysqladmin.cc11
-rw-r--r--client/mysqldump.c145
3 files changed, 131 insertions, 27 deletions
diff --git a/client/client_priv.h b/client/client_priv.h
index 184eed241ed..e86a56f58c1 100644
--- a/client/client_priv.h
+++ b/client/client_priv.h
@@ -45,7 +45,7 @@ enum options_client
OPT_COMPATIBLE, OPT_RECONNECT, OPT_DELIMITER, OPT_SECURE_AUTH,
OPT_OPEN_FILES_LIMIT, OPT_SET_CHARSET, OPT_CREATE_OPTIONS,
OPT_START_POSITION, OPT_STOP_POSITION, OPT_START_DATETIME, OPT_STOP_DATETIME,
- OPT_SIGINT_IGNORE, OPT_HEXBLOB
+ OPT_SIGINT_IGNORE, OPT_HEXBLOB, OPT_ORDER_BY_PRIMARY
#ifdef HAVE_NDBCLUSTER_DB
,OPT_NDBCLUSTER,OPT_NDB_CONNECTSTRING
#endif
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc
index 37c4971497a..924af3a9977 100644
--- a/client/mysqladmin.cc
+++ b/client/mysqladmin.cc
@@ -825,10 +825,17 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
if (argv[1][0])
{
+ char *pw= argv[1];
+#ifdef __WIN__
+ uint pw_len= strlen(pw);
+ if (pw_len > 1 && pw[0] == '\'' && pw[pw_len-1] == '\'')
+ printf("Warning: single quotes were not trimmed from the password by"
+ " your command\nline client, as you might have expected.\n");
+#endif
if (find_type(argv[0], &command_typelib, 2) == ADMIN_OLD_PASSWORD)
- make_scrambled_password_323(crypted_pw, argv[1]);
+ make_scrambled_password_323(crypted_pw, pw);
else
- make_scrambled_password(crypted_pw, argv[1]);
+ make_scrambled_password(crypted_pw, pw);
}
else
crypted_pw[0]=0; /* No password */
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 0d0e67454f8..472dfa4c6dc 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -75,20 +75,20 @@ static ulong find_set(TYPELIB *lib, const char *x, uint length,
static char *field_escape(char *to,const char *from,uint length);
static my_bool verbose=0,tFlag=0,cFlag=0,dFlag=0,quick= 1, extended_insert= 1,
- lock_tables=1,ignore_errors=0,flush_logs=0,replace=0,
- ignore=0,opt_drop=1,opt_keywords=0,opt_lock=1,opt_compress=0,
+ lock_tables=1,ignore_errors=0,flush_logs=0,
+ opt_drop=1,opt_keywords=0,opt_lock=1,opt_compress=0,
opt_delayed=0,create_options=1,opt_quoted=0,opt_databases=0,
opt_alldbs=0,opt_create_db=0,opt_lock_all_tables=0,opt_set_charset,
opt_autocommit=0,opt_disable_keys=1,opt_xml=0,
opt_delete_master_logs=0, tty_password=0,
opt_single_transaction=0, opt_comments= 0, opt_compact= 0,
- opt_hex_blob=0;
+ opt_hex_blob=0, opt_order_by_primary=0;
static ulong opt_max_allowed_packet, opt_net_buffer_length;
static MYSQL mysql_connection,*sock=0;
static char insert_pat[12 * 1024],*opt_password=0,*current_user=0,
*current_host=0,*path=0,*fields_terminated=0,
*lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0,
- *where=0,
+ *where=0, *order_by=0,
*opt_compatible_mode_str= 0,
*err_ptr= 0;
static char compatible_mode_normal_str[255];
@@ -334,6 +334,9 @@ static struct my_option my_long_options[] =
{"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},
+ {"order-by-primary", OPT_ORDER_BY_PRIMARY,
+ "Sorts each table's rows by primary key, or first unique key, if such a key exists. Useful when dumping a MyISAM table to be loaded into an InnoDB table, but will make the dump itself take considerably longer.",
+ (gptr*) &opt_order_by_primary, (gptr*) &opt_order_by_primary, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#include <sslopt-longopts.h>
{"tab",'T',
"Creates tab separated textfile for each table to given path. (creates .sql and .txt files). NOTE: This only works if mysqldump is run on the same machine as the mysqld daemon.",
@@ -370,6 +373,7 @@ static int dump_databases(char **);
static int dump_all_databases();
static char *quote_name(const char *name, char *buff, my_bool force);
static const char *check_if_ignore_table(const char *table_name);
+static char *primary_key_fields(const char *table_name);
static my_bool getViewStructure(char *table, char* db);
static my_bool dump_all_views_in_db(char *database);
@@ -673,11 +677,6 @@ static int get_options(int *argc, char ***argv)
fprintf(stderr, "%s: You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n", my_progname);
return(1);
}
- if (replace && ignore)
- {
- fprintf(stderr, "%s: You can't use --ignore (-i) and --replace (-r) at the same time.\n",my_progname);
- return(1);
- }
if ((opt_databases || opt_alldbs) && path)
{
fprintf(stderr,
@@ -758,7 +757,6 @@ static void safe_exit(int error)
/*
** dbConnect -- connects to the host and selects DB.
-** Also checks whether the tablename is a valid table name.
*/
static int dbConnect(char *host, char *user,char *passwd)
{
@@ -896,7 +894,7 @@ static char *quote_for_like(const char *name, char *buff)
len - its length
DESCRIPTION
- Quote '<' '>' '&' '\"' singns and print a string to the xml_file.
+ Quote '<' '>' '&' '\"' chars and print a string to the xml_file.
*/
static void print_quoted_xml(FILE *xml_file, const char *str, ulong len)
@@ -1037,6 +1035,10 @@ static uint getTableStructure(char *table, char* db)
result_table= quote_name(table, table_buff, 1);
opt_quoted_table= quote_name(table, table_buff2, 0);
+
+ if (opt_order_by_primary)
+ order_by = primary_key_fields(opt_quoted_table);
+
if (!opt_xml && !mysql_query_with_error_report(sock, 0, insert_pat))
{
/* using SHOW CREATE statement */
@@ -1471,10 +1473,6 @@ static void dumpTable(uint numFields, char *table)
sprintf(query, "SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '%s'",
filename);
end= strend(query);
- if (replace)
- end= strmov(end, " REPLACE");
- if (ignore)
- end= strmov(end, " IGNORE");
if (fields_terminated || enclosed || opt_enclosed || escaped)
end= strmov(end, " FIELDS");
@@ -1487,10 +1485,17 @@ static void dumpTable(uint numFields, char *table)
sprintf(buff," FROM %s", result_table);
end= strmov(end,buff);
- if (where)
+ if (where || order_by)
{
- query= alloc_query_str((ulong) (strlen(where) + (end - query) + 10));
- end= strxmov(query, query_buf, " WHERE ", where, NullS);
+ query = alloc_query_str((ulong) ((end - query) + 1 +
+ (where ? strlen(where) + 7 : 0) +
+ (order_by ? strlen(order_by) + 10 : 0)));
+ end = strmov(query, query_buf);
+
+ if (where)
+ end = strxmov(end, " WHERE ", where, NullS);
+ if (order_by)
+ end = strxmov(end, " ORDER BY ", order_by, NullS);
}
if (mysql_real_query(sock, query, (uint) (end - query)))
{
@@ -1508,15 +1513,31 @@ static void dumpTable(uint numFields, char *table)
}
sprintf(query, "SELECT /*!40001 SQL_NO_CACHE */ * FROM %s",
result_table);
- if (where)
+ if (where || order_by)
{
- if (!opt_xml && opt_comments)
+ query = alloc_query_str((ulong) (strlen(query) + 1 +
+ (where ? strlen(where) + 7 : 0) +
+ (order_by ? strlen(order_by) + 10 : 0)));
+ end = strmov(query, query_buf);
+
+ if (where)
{
- fprintf(md_result_file,"-- WHERE: %s\n",where);
- check_io(md_result_file);
+ if (!opt_xml && opt_comments)
+ {
+ fprintf(md_result_file, "-- WHERE: %s\n", where);
+ check_io(md_result_file);
+ }
+ end = strxmov(end, " WHERE ", where, NullS);
+ }
+ if (order_by)
+ {
+ if (!opt_xml && opt_comments)
+ {
+ fprintf(md_result_file, "-- ORDER BY: %s\n", order_by);
+ check_io(md_result_file);
+ }
+ end = strxmov(end, " ORDER BY ", order_by, NullS);
}
- query= alloc_query_str((ulong) (strlen(where) + strlen(query) + 10));
- strxmov(query, query_buf, " WHERE ", where, NullS);
}
if (!opt_xml && !opt_compact)
{
@@ -1826,6 +1847,8 @@ static void dumpTable(uint numFields, char *table)
err:
if (query != query_buf)
my_free(query, MYF(MY_ALLOW_ZERO_PTR));
+ if (order_by)
+ my_free(order_by, MYF(0));
safe_exit(error);
return;
} /* dumpTable */
@@ -2323,6 +2346,80 @@ static const char *check_if_ignore_table(const char *table_name)
return result;
}
+/*
+ Get string of comma-separated primary key field names
+
+ SYNOPSIS
+ char *primary_key_fields(const char *table_name)
+ RETURNS pointer to allocated buffer (must be freed by caller)
+ table_name quoted table name
+
+ DESCRIPTION
+ Use SHOW KEYS FROM table_name, allocate a buffer to hold the
+ field names, and then build that string and return the pointer
+ to that buffer.
+
+ Returns NULL if there is no PRIMARY or UNIQUE key on the table,
+ or if there is some failure. It is better to continue to dump
+ the table unsorted, rather than exit without dumping the data.
+*/
+static char *primary_key_fields(const char *table_name)
+{
+ MYSQL_RES *res = NULL;
+ MYSQL_ROW row;
+ /* SHOW KEYS FROM + table name * 2 (escaped) + 2 quotes + \0 */
+ char show_keys_buff[15 + 64 * 2 + 3];
+ uint result_length = 0;
+ char *result = 0;
+
+ sprintf(show_keys_buff, "SHOW KEYS FROM %s", table_name);
+ if (mysql_query(sock, show_keys_buff) ||
+ !(res = mysql_store_result(sock)))
+ {
+ fprintf(stderr, "Warning: Couldn't read keys from table %s;"
+ " records are NOT sorted (%s)\n",
+ table_name, mysql_error(sock));
+ /* Don't exit, because it's better to print out unsorted records */
+ goto cleanup;
+ }
+
+ /*
+ * Figure out the length of the ORDER BY clause result.
+ * Note that SHOW KEYS is ordered: a PRIMARY key is always the first
+ * row, and UNIQUE keys come before others. So we only need to check
+ * the first key, not all keys.
+ */
+ if ((row = mysql_fetch_row(res)) && atoi(row[1]) == 0)
+ {
+ /* Key is unique */
+ do
+ result_length += strlen(row[4]) + 1; /* + 1 for ',' or \0 */
+ while ((row = mysql_fetch_row(res)) && atoi(row[3]) > 1);
+ }
+
+ /* Build the ORDER BY clause result */
+ if (result_length) {
+ char *end;
+ /* result (terminating \0 is already in result_length) */
+ result = my_malloc(result_length + 10, MYF(MY_WME));
+ if (!result) {
+ fprintf(stderr, "Error: Not enough memory to store ORDER BY clause\n");
+ goto cleanup;
+ }
+ mysql_data_seek(res, 0);
+ row = mysql_fetch_row(res);
+ end = strmov(result, row[4]);
+ while ((row = mysql_fetch_row(res)) && atoi(row[3]) > 1)
+ end = strxmov(end, ",", row[4], NullS);
+ }
+
+cleanup:
+ if (res)
+ mysql_free_result(res);
+
+ return result;
+}
+
/*
Getting VIEW structure