summaryrefslogtreecommitdiff
path: root/client/mysqldump.c
diff options
context:
space:
mode:
Diffstat (limited to 'client/mysqldump.c')
-rw-r--r--client/mysqldump.c359
1 files changed, 299 insertions, 60 deletions
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 7b18b1d92da..907b6233590 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -37,7 +37,7 @@
** 10 Jun 2003: SET NAMES and --no-set-names by Alexander Barkov
*/
-#define DUMP_VERSION "10.9"
+#define DUMP_VERSION "10.10"
#include <my_global.h>
#include <my_sys.h>
@@ -120,6 +120,8 @@ static const char *mysql_universal_client_charset=
static char *default_charset;
static CHARSET_INFO *charset_info= &my_charset_latin1;
const char *default_dbug_option="d:t:o,/tmp/mysqldump.trace";
+/* do we met VIEWs during tables scaning */
+my_bool was_views= 0;
const char *compatible_mode_names[]=
{
@@ -209,7 +211,9 @@ static struct my_option my_long_options[] =
{"default-character-set", OPT_DEFAULT_CHARSET,
"Set the default character set.", (gptr*) &default_charset,
(gptr*) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"delayed-insert", OPT_DELAYED, "Insert rows with INSERT DELAYED.",
+ {"delayed-insert", OPT_DELAYED, "Insert rows with INSERT DELAYED; "
+ "currently ignored because of http://bugs.mysql.com/bug.php?id=7815 "
+ "but will be re-enabled later",
(gptr*) &opt_delayed, (gptr*) &opt_delayed, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
{"delete-master-logs", OPT_DELETE_MASTER_LOGS,
@@ -387,7 +391,7 @@ static struct my_option my_long_options[] =
(gptr*) &where, (gptr*) &where, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"xml", 'X', "Dump a database as well formed XML.", 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}
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
static const char *load_default_groups[]= { "mysqldump","client",0 };
@@ -405,6 +409,8 @@ 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 get_view_structure(char *table, char* db);
+static my_bool dump_all_views_in_db(char *database);
#include <help_start.h>
@@ -712,6 +718,25 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
}
break;
}
+#ifndef REMOVE_THIS_CODE_WHEN_FIX_BUG_7815
+ case (int) OPT_DELAYED:
+ /*
+ Because of http://bugs.mysql.com/bug.php?id=7815, we disable
+ --delayed-insert; when the bug gets fixed by checking the storage engine
+ (using the table definition cache) before printing INSERT DELAYED, we
+ can correct the option's description and re-enable it again (scheduled
+ for later 5.0 or 5.1 versions).
+ It's ok to do the if() below as get_one_option is called after
+ opt_delayed is set.
+ */
+ if (opt_delayed)
+ {
+ fprintf(stderr, "Warning: ignoring --delayed-insert (as explained "
+ "in the output of 'mysqldump --help').\n");
+ opt_delayed= 0;
+ }
+ break;
+#endif
}
return 0;
}
@@ -784,16 +809,16 @@ static int get_options(int *argc, char ***argv)
/*
-** DBerror -- prints mysql error message and exits the program.
+** DB_error -- prints mysql error message and exits the program.
*/
-static void DBerror(MYSQL *mysql, const char *when)
+static void DB_error(MYSQL *mysql, const char *when)
{
- DBUG_ENTER("DBerror");
+ DBUG_ENTER("DB_error");
my_printf_error(0,"Got error: %d: %s %s", MYF(0),
mysql_errno(mysql), mysql_error(mysql), when);
safe_exit(EX_MYSQLERR);
DBUG_VOID_RETURN;
-} /* DBerror */
+} /* DB_error */
/*
@@ -869,7 +894,7 @@ static int dbConnect(char *host, char *user,char *passwd)
NULL,opt_mysql_port,opt_mysql_unix_port,
0)))
{
- DBerror(&mysql_connection, "when trying to connect");
+ DB_error(&mysql_connection, "when trying to connect");
return 1;
}
/*
@@ -1100,7 +1125,7 @@ static void print_xml_row(FILE *xml_file, const char *row_name,
number of fields in table, 0 if error
*/
-static uint getTableStructure(char *table, char* db)
+static uint get_table_structure(char *table, char *db)
{
MYSQL_RES *tableRes;
MYSQL_ROW row;
@@ -1113,7 +1138,7 @@ static uint getTableStructure(char *table, char* db)
char query_buff[512];
FILE *sql_file = md_result_file;
int len;
- DBUG_ENTER("getTableStructure");
+ DBUG_ENTER("get_table_structure");
if (!insert_pat_inited)
{
@@ -1148,6 +1173,7 @@ static uint getTableStructure(char *table, char* db)
{
/* Make an sql-file, if path was given iow. option -T was given */
char buff[20+FN_REFLEN];
+ MYSQL_FIELD *field;
my_snprintf(buff, sizeof(buff), "show create table %s", result_table);
if (mysql_query_with_error_report(sock, 0, buff))
@@ -1181,8 +1207,16 @@ static uint getTableStructure(char *table, char* db)
check_io(sql_file);
}
- tableRes=mysql_store_result(sock);
- row=mysql_fetch_row(tableRes);
+ tableRes= mysql_store_result(sock);
+ field= mysql_fetch_field_direct(tableRes, 0);
+ if (strcmp(field->name, "View") == 0)
+ {
+ if (verbose)
+ fprintf(stderr, "-- It's a view, skipped\n");
+ was_views= 1;
+ DBUG_RETURN(0);
+ }
+ row= mysql_fetch_row(tableRes);
fprintf(sql_file, "%s;\n", row[1]);
check_io(sql_file);
mysql_free_result(tableRes);
@@ -1340,6 +1374,14 @@ static uint getTableStructure(char *table, char* db)
my_snprintf(buff, sizeof(buff), "show keys from %s", result_table);
if (mysql_query_with_error_report(sock, &tableRes, buff))
{
+ if (mysql_errno(sock) == ER_WRONG_OBJECT)
+ {
+ /* it is VIEW */
+ fputs("\t\t<options Comment=\"view\" />\n", sql_file);
+ goto continue_xml;
+ }
+ fprintf(stderr, "%s: Can't get keys for table %s (%s)\n",
+ my_progname, result_table, mysql_error(sock));
if (path)
my_fclose(sql_file, MYF(MY_WME));
safe_exit(EX_MYSQLERR);
@@ -1406,10 +1448,9 @@ static uint getTableStructure(char *table, char* db)
/* Get MySQL specific create options */
if (create_options)
{
- char show_name_buff[FN_REFLEN];
+ char show_name_buff[NAME_LEN*2+2+24];
/* Check memory for quote_for_like() */
- DBUG_ASSERT(2*sizeof(table) < sizeof(show_name_buff));
my_snprintf(buff, sizeof(buff), "show table status like %s",
quote_for_like(table, show_name_buff));
@@ -1447,6 +1488,7 @@ static uint getTableStructure(char *table, char* db)
}
mysql_free_result(tableRes); /* Is always safe to free */
}
+continue_xml:
if (!opt_xml)
fputs(";\n", sql_file);
else
@@ -1467,7 +1509,7 @@ static uint getTableStructure(char *table, char* db)
my_fclose(sql_file, MYF(MY_WME));
}
DBUG_RETURN(numFields);
-} /* getTableStructure */
+} /* get_table_structure */
static char *add_load_option(char *ptr,const char *object,
@@ -1533,10 +1575,12 @@ static char *alloc_query_str(ulong size)
return query;
}
+
/*
-** dumpTable saves database contents as a series of INSERT statements.
+** dump_table saves database contents as a series of INSERT statements.
*/
-static void dumpTable(uint numFields, char *table)
+
+static void dump_table(uint numFields, char *table)
{
char query_buf[QUERY_LENGTH], *end, buff[256],table_buff[NAME_LEN+3];
char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table;
@@ -1602,7 +1646,7 @@ static void dumpTable(uint numFields, char *table)
}
if (mysql_real_query(sock, query, (uint) (end - query)))
{
- DBerror(sock, "when executing 'SELECT INTO OUTFILE'");
+ DB_error(sock, "when executing 'SELECT INTO OUTFILE'");
return;
}
}
@@ -1649,13 +1693,13 @@ static void dumpTable(uint numFields, char *table)
check_io(md_result_file);
}
if (mysql_query_with_error_report(sock, 0, query))
- DBerror(sock, "when retrieving data from server");
+ DB_error(sock, "when retrieving data from server");
if (quick)
res=mysql_use_result(sock);
else
res=mysql_store_result(sock);
if (!res)
- DBerror(sock, "when retrieving data from server");
+ DB_error(sock, "when retrieving data from server");
if (verbose)
fprintf(stderr, "-- Retrieving rows...\n");
if (mysql_num_fields(res) != numFields)
@@ -1728,12 +1772,13 @@ static void dumpTable(uint numFields, char *table)
we'll dump in hex only BLOB columns.
*/
is_blob= (opt_hex_blob && field->charsetnr == 63 &&
- (field->type == FIELD_TYPE_STRING ||
- field->type == FIELD_TYPE_VAR_STRING ||
- field->type == FIELD_TYPE_BLOB ||
- field->type == FIELD_TYPE_LONG_BLOB ||
- field->type == FIELD_TYPE_MEDIUM_BLOB ||
- field->type == FIELD_TYPE_TINY_BLOB)) ? 1 : 0;
+ (field->type == MYSQL_TYPE_STRING ||
+ field->type == MYSQL_TYPE_VAR_STRING ||
+ field->type == MYSQL_TYPE_VARCHAR ||
+ field->type == MYSQL_TYPE_BLOB ||
+ field->type == MYSQL_TYPE_LONG_BLOB ||
+ field->type == MYSQL_TYPE_MEDIUM_BLOB ||
+ field->type == MYSQL_TYPE_TINY_BLOB)) ? 1 : 0;
if (extended_insert)
{
ulong length = lengths[i];
@@ -1955,7 +2000,7 @@ err:
my_free(query, MYF(MY_ALLOW_ZERO_PTR));
safe_exit(error);
return;
-} /* dumpTable */
+} /* dump_table */
static char *getTableName(int reset)
@@ -1995,6 +2040,21 @@ static int dump_all_databases()
if (dump_all_tables_in_db(row[0]))
result=1;
}
+ if (was_views)
+ {
+ if (mysql_query(sock, "SHOW DATABASES") ||
+ !(tableres = mysql_store_result(sock)))
+ {
+ my_printf_error(0, "Error: Couldn't execute 'SHOW DATABASES': %s",
+ MYF(0), mysql_error(sock));
+ return 1;
+ }
+ while ((row = mysql_fetch_row(tableres)))
+ {
+ if (dump_all_views_in_db(row[0]))
+ result=1;
+ }
+ }
return result;
}
/* dump_all_databases */
@@ -2003,20 +2063,33 @@ static int dump_all_databases()
static int dump_databases(char **db_names)
{
int result=0;
- for ( ; *db_names ; db_names++)
+ char **db;
+ for (db= db_names ; *db ; db++)
{
- if (dump_all_tables_in_db(*db_names))
+ if (dump_all_tables_in_db(*db))
result=1;
}
+ if (!result && was_views)
+ {
+ for (db= db_names ; *db ; db++)
+ {
+ if (dump_all_views_in_db(*db))
+ result=1;
+ }
+ }
return result;
} /* dump_databases */
static int init_dumping(char *database)
{
+ if (mysql_get_server_version(sock) >= 50003 &&
+ !my_strcasecmp(&my_charset_latin1, database, "information_schema"))
+ return 1;
+
if (mysql_select_db(sock, database))
{
- DBerror(sock, "when selecting the database");
+ DB_error(sock, "when selecting the database");
return 1; /* If --force */
}
if (!path && !opt_xml)
@@ -2112,14 +2185,14 @@ static int dump_all_tables_in_db(char *database)
dynstr_append(&query, " READ /*!32311 LOCAL */,");
}
if (numrows && mysql_real_query(sock, query.str, query.length-1))
- DBerror(sock, "when using LOCK TABLES");
+ DB_error(sock, "when using LOCK TABLES");
/* We shall continue here, if --force was given */
dynstr_free(&query);
}
if (flush_logs)
{
if (mysql_refresh(sock, REFRESH_LOG))
- DBerror(sock, "when doing refresh");
+ DB_error(sock, "when doing refresh");
/* We shall continue here, if --force was given */
}
while ((table= getTableName(0)))
@@ -2127,9 +2200,9 @@ static int dump_all_tables_in_db(char *database)
char *end= strmov(afterdot, table);
if (include_table(hash_key, end - hash_key))
{
- numrows = getTableStructure(table, database);
+ numrows = get_table_structure(table, database);
if (!dFlag && numrows > 0)
- dumpTable(numrows,table);
+ dump_table(numrows,table);
my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
order_by= 0;
}
@@ -2146,6 +2219,61 @@ static int dump_all_tables_in_db(char *database)
/*
+ dump structure of views of database
+
+ SYNOPSIS
+ dump_all_views_in_db()
+ database database name
+
+ RETURN
+ 0 OK
+ 1 ERROR
+*/
+
+static my_bool dump_all_views_in_db(char *database)
+{
+ char *table;
+ uint numrows;
+ char table_buff[NAME_LEN*2+3];
+
+ if (init_dumping(database))
+ return 1;
+ if (opt_xml)
+ print_xml_tag1(md_result_file, "", "database name=", database, "\n");
+ if (lock_tables)
+ {
+ DYNAMIC_STRING query;
+ init_dynamic_string(&query, "LOCK TABLES ", 256, 1024);
+ for (numrows= 0 ; (table= getTableName(1)); numrows++)
+ {
+ dynstr_append(&query, quote_name(table, table_buff, 1));
+ dynstr_append(&query, " READ /*!32311 LOCAL */,");
+ }
+ if (numrows && mysql_real_query(sock, query.str, query.length-1))
+ DB_error(sock, "when using LOCK TABLES");
+ /* We shall continue here, if --force was given */
+ dynstr_free(&query);
+ }
+ if (flush_logs)
+ {
+ if (mysql_refresh(sock, REFRESH_LOG))
+ DB_error(sock, "when doing refresh");
+ /* We shall continue here, if --force was given */
+ }
+ while ((table= getTableName(0)))
+ get_view_structure(table, database);
+ if (opt_xml)
+ {
+ fputs("</database>\n", md_result_file);
+ check_io(md_result_file);
+ }
+ if (lock_tables)
+ mysql_query(sock,"UNLOCK TABLES");
+ return 0;
+} /* dump_all_tables_in_db */
+
+
+/*
get_actual_table_name -- executes a SHOW TABLES LIKE '%s' to get the actual
table name from the server for the table name given on the command line.
we do this because the table name given on the command line may be a
@@ -2160,7 +2288,7 @@ static int get_actual_table_name(const char *old_table_name,
int buf_size)
{
int retval;
- MYSQL_RES *tableRes;
+ MYSQL_RES *table_res;
MYSQL_ROW row;
char query[50 + 2*NAME_LEN];
char show_name_buff[FN_REFLEN];
@@ -2176,18 +2304,22 @@ static int get_actual_table_name(const char *old_table_name,
safe_exit(EX_MYSQLERR);
}
- tableRes= mysql_store_result( sock );
retval = 1;
- if (tableRes != NULL)
+
+ if ((table_res= mysql_store_result(sock)))
{
- my_ulonglong numRows = mysql_num_rows(tableRes);
- if (numRows > 0)
- {
- row= mysql_fetch_row( tableRes );
- strmake(new_table_name, row[0], buf_size-1);
- retval = 0;
- }
- mysql_free_result(tableRes);
+ my_ulonglong num_rows= mysql_num_rows(table_res);
+ if (num_rows > 0)
+ {
+ /*
+ Return first row
+ TODO: Return all matching rows
+ */
+ row= mysql_fetch_row(table_res);
+ strmake(new_table_name, row[0], buf_size-1);
+ retval= 0;
+ }
+ mysql_free_result(table_res);
}
return retval;
}
@@ -2196,6 +2328,7 @@ static int get_actual_table_name(const char *old_table_name,
static int dump_selected_tables(char *db, char **table_names, int tables)
{
uint numrows;
+ int i;
char table_buff[NAME_LEN*+3];
if (init_dumping(db))
@@ -2203,7 +2336,6 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
if (lock_tables)
{
DYNAMIC_STRING query;
- int i;
init_dynamic_string(&query, "LOCK TABLES ", 256, 1024);
for (i=0 ; i < tables ; i++)
@@ -2212,32 +2344,37 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
dynstr_append(&query, " READ /*!32311 LOCAL */,");
}
if (mysql_real_query(sock, query.str, query.length-1))
- DBerror(sock, "when doing LOCK TABLES");
+ DB_error(sock, "when doing LOCK TABLES");
/* We shall countinue here, if --force was given */
dynstr_free(&query);
}
if (flush_logs)
{
if (mysql_refresh(sock, REFRESH_LOG))
- DBerror(sock, "when doing refresh");
+ DB_error(sock, "when doing refresh");
/* We shall countinue here, if --force was given */
}
if (opt_xml)
print_xml_tag1(md_result_file, "", "database name=", db, "\n");
- for (; tables > 0 ; tables-- , table_names++)
+ for (i=0 ; i < tables ; i++)
{
- char new_table_name[NAME_LEN];
+ char new_table_name[NAME_LEN];
- /* the table name passed on commandline may be wrong case */
- if (!get_actual_table_name( *table_names, new_table_name, sizeof(new_table_name) ))
- {
- numrows = getTableStructure(new_table_name, db);
- if (!dFlag && numrows > 0)
- dumpTable(numrows, new_table_name);
- }
+ /* the table name passed on commandline may be wrong case */
+ if (!get_actual_table_name( table_names[i], new_table_name,
+ sizeof(new_table_name)))
+ {
+ numrows= get_table_structure(new_table_name, db);
+ dump_table(numrows, new_table_name);
+ }
my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
order_by= 0;
}
+ if (was_views)
+ {
+ for (i=0 ; i < tables ; i++)
+ get_view_structure(table_names[i], db);
+ }
if (opt_xml)
{
fputs("</database>\n", md_result_file);
@@ -2449,9 +2586,14 @@ static const char *check_if_ignore_table(const char *table_name)
mysql_free_result(res);
return 0; /* assume table is ok */
}
- if (strcmp(row[1], (result= "MRG_MyISAM")) &&
- strcmp(row[1], (result= "MRG_ISAM")))
- result= 0;
+ if (!(row[1]))
+ result= "VIEW";
+ else
+ {
+ if (strcmp(row[1], (result= "MRG_MyISAM")) &&
+ strcmp(row[1], (result= "MRG_ISAM")))
+ result= 0;
+ }
mysql_free_result(res);
return result;
}
@@ -2532,6 +2674,103 @@ cleanup:
}
+/*
+ Getting VIEW structure
+
+ SYNOPSIS
+ get_view_structure()
+ table view name
+ db db name
+
+ RETURN
+ 0 OK
+ 1 ERROR
+*/
+
+static my_bool get_view_structure(char *table, char* db)
+{
+ MYSQL_RES *table_res;
+ MYSQL_ROW row;
+ MYSQL_FIELD *field;
+ char *result_table, *opt_quoted_table;
+ char table_buff[NAME_LEN*2+3];
+ char table_buff2[NAME_LEN*2+3];
+ char buff[20+FN_REFLEN];
+ FILE *sql_file = md_result_file;
+ DBUG_ENTER("get_view_structure");
+
+ if (tFlag)
+ DBUG_RETURN(0);
+
+ if (verbose)
+ fprintf(stderr, "-- Retrieving view structure for table %s...\n", table);
+
+#ifdef NOT_REALLY_USED_YET
+ sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d",
+ (opt_quoted || opt_keywords));
+#endif
+
+ result_table= quote_name(table, table_buff, 1);
+ opt_quoted_table= quote_name(table, table_buff2, 0);
+
+ sprintf(buff,"show create table %s", result_table);
+ if (mysql_query(sock, buff))
+ {
+ fprintf(stderr, "%s: Can't get CREATE TABLE for view %s (%s)\n",
+ my_progname, result_table, mysql_error(sock));
+ safe_exit(EX_MYSQLERR);
+ DBUG_RETURN(0);
+ }
+
+ if (path)
+ {
+ char filename[FN_REFLEN], tmp_path[FN_REFLEN];
+ convert_dirname(tmp_path,path,NullS);
+ sql_file= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
+ O_WRONLY, MYF(MY_WME));
+ if (!sql_file) /* If file couldn't be opened */
+ {
+ safe_exit(EX_MYSQLERR);
+ DBUG_RETURN(1);
+ }
+ write_header(sql_file, db);
+ }
+ table_res= mysql_store_result(sock);
+ field= mysql_fetch_field_direct(table_res, 0);
+ if (strcmp(field->name, "View") != 0)
+ {
+ if (verbose)
+ fprintf(stderr, "-- It's base table, skipped\n");
+ DBUG_RETURN(0);
+ }
+
+ if (!opt_xml && opt_comments)
+ {
+ fprintf(sql_file, "\n--\n-- View structure for view %s\n--\n\n",
+ result_table);
+ check_io(sql_file);
+ }
+ if (opt_drop)
+ {
+ fprintf(sql_file, "DROP VIEW IF EXISTS %s;\n", opt_quoted_table);
+ check_io(sql_file);
+ }
+
+ row= mysql_fetch_row(table_res);
+ fprintf(sql_file, "%s;\n", row[1]);
+ check_io(sql_file);
+ mysql_free_result(table_res);
+
+ if (sql_file != md_result_file)
+ {
+ fputs("\n", sql_file);
+ write_footer(sql_file);
+ my_fclose(sql_file, MYF(MY_WME));
+ }
+ DBUG_RETURN(0);
+}
+
+
int main(int argc, char **argv)
{
compatible_mode_normal_str[0]= 0;