summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <msvensson@pilot.(none)>2007-08-20 13:47:31 +0200
committerunknown <msvensson@pilot.(none)>2007-08-20 13:47:31 +0200
commit8ef4122511b924f5eabcb9e03feaddb00c113448 (patch)
treee791b3c227804891ea58b05aea712804aa698b25
parenta2e4cc6c774e0cecb1857125c67a08b2433277e1 (diff)
parent5dc6ba8255361053243010ff7ee24bfeb84d255d (diff)
downloadmariadb-git-8ef4122511b924f5eabcb9e03feaddb00c113448.tar.gz
Merge pilot.(none):/data/msvensson/mysql/work/my51-work
into pilot.(none):/data/msvensson/mysql/mysql-5.1-new-maint strings/ctype-extra.c: Auto merged
-rw-r--r--client/mysqldump.c554
-rw-r--r--mysql-test/r/federated.result14
-rw-r--r--mysql-test/r/lock.result70
-rw-r--r--mysql-test/r/lock_multi.result10
-rw-r--r--mysql-test/r/log_state.result4
-rw-r--r--mysql-test/t/federated.test14
-rw-r--r--mysql-test/t/lock.test65
-rw-r--r--mysql-test/t/lock_multi.test35
-rw-r--r--mysql-test/t/log_state.test4
-rw-r--r--mysys/thr_lock.c40
-rw-r--r--sql/item.cc2
-rw-r--r--sql/table.cc1
-rw-r--r--tests/mysql_client_test.c53
13 files changed, 668 insertions, 198 deletions
diff --git a/client/mysqldump.c b/client/mysqldump.c
index c56c4423470..566760d2db3 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -1236,6 +1236,125 @@ static int switch_character_set_results(MYSQL *mysql, const char *cs_name)
return mysql_real_query(mysql, query_buffer, query_length);
}
+/**
+ Rewrite CREATE TRIGGER statement, enclosing DEFINER clause in
+ version-specific comment.
+
+ This function parses the CREATE TRIGGER statement and encloses
+ DEFINER-clause in version-specific comment:
+ input query: CREATE DEFINER=a@b TRIGGER ...
+ rewritten query: CREATE * / / *!50017 DEFINER=a@b * / / *!50003 TRIGGER ...
+
+ @note This function will go away when WL#3995 is implemented.
+
+ @param[in] trigger_def_str CREATE TRIGGER statement string.
+ @param[in] trigger_def_length length of the trigger_def_str.
+
+ @return pointer to the new allocated query string.
+*/
+
+static char *cover_definer_clause_in_trigger(const char *trigger_def_str,
+ uint trigger_def_length)
+{
+ char *query_str= NULL;
+ char *definer_begin= my_case_str(trigger_def_str, trigger_def_length,
+ C_STRING_WITH_LEN(" DEFINER"));
+ char *definer_end;
+
+ if (!definer_begin)
+ return NULL;
+
+ definer_end= my_case_str(definer_begin, strlen(definer_begin),
+ C_STRING_WITH_LEN(" TRIGGER"));
+
+ if (definer_end)
+ {
+ char *query_str_tail;
+
+ /*
+ Allocate memory for new query string: original string
+ from SHOW statement and version-specific comments.
+ */
+ query_str= alloc_query_str(trigger_def_length + 23);
+
+ query_str_tail= strnmov(query_str,
+ trigger_def_str,
+ definer_begin - trigger_def_str);
+
+ query_str_tail= strmov(query_str_tail,
+ "*/ /*!50017");
+
+ query_str_tail= strnmov(query_str_tail,
+ definer_begin,
+ definer_end - definer_begin);
+
+ query_str_tail= strxmov(query_str_tail,
+ "*/ /*!50003",
+ definer_end,
+ NullS);
+ }
+
+ return query_str;
+}
+
+/**
+ Rewrite CREATE FUNCTION or CREATE PROCEDURE statement, enclosing DEFINER
+ clause in version-specific comment.
+
+ This function parses the CREATE FUNCTION | PROCEDURE statement and
+ encloses DEFINER-clause in version-specific comment:
+ input query: CREATE DEFINER=a@b FUNCTION ...
+ rewritten query: CREATE * / / *!50020 DEFINER=a@b * / / *!50003 FUNCTION ...
+
+ @note This function will go away when WL#3995 is implemented.
+
+ @param[in] def_str CREATE FUNCTION|PROCEDURE statement string.
+ @param[in] def_length length of the def_str.
+
+ @return pointer to the new allocated query string.
+*/
+
+static char *cover_definer_clause_in_sp(const char *def_str,
+ uint def_str_length)
+{
+ char *query_str= NULL;
+ char *definer_begin= my_case_str(def_str, def_str_length,
+ C_STRING_WITH_LEN(" DEFINER"));
+ char *definer_end;
+
+ if (!definer_begin)
+ return NULL;
+
+ definer_end= my_case_str(definer_begin, strlen(definer_begin),
+ C_STRING_WITH_LEN(" PROCEDURE"));
+
+ if (!definer_end)
+ {
+ definer_end= my_case_str(definer_begin, strlen(definer_begin),
+ C_STRING_WITH_LEN(" FUNCTION"));
+ }
+
+ if (definer_end)
+ {
+ char *query_str_tail;
+
+ /*
+ Allocate memory for new query string: original string
+ from SHOW statement and version-specific comments.
+ */
+ query_str= alloc_query_str(def_str_length + 23);
+
+ query_str_tail= strnmov(query_str, def_str, definer_begin - def_str);
+ query_str_tail= strmov(query_str_tail, "*/ /*!50020");
+ query_str_tail= strnmov(query_str_tail, definer_begin,
+ definer_end - definer_begin);
+ query_str_tail= strxmov(query_str_tail, "*/ /*!50003",
+ definer_end, NullS);
+ }
+
+ return query_str;
+}
+
/*
Open a new .sql file to dump the table or view into
@@ -1710,7 +1829,7 @@ static uint dump_events_for_db(char *db)
MYSQL_ROW row, event_list_row;
char db_cl_name[MY_CS_NAME_SIZE];
- int db_cl_altered;
+ int db_cl_altered= FALSE;
DBUG_ENTER("dump_events_for_db");
DBUG_PRINT("enter", ("db: '%s'", db));
@@ -1775,16 +1894,36 @@ static uint dump_events_for_db(char *db)
fprintf(sql_file, "DELIMITER %s\n", delimiter);
- if (switch_db_collation(sql_file, db_name_buff, delimiter, db_cl_name,
- row[6], &db_cl_altered))
+ if (mysql_num_fields(event_res) >= 7)
{
- DBUG_RETURN(1);
- }
+ if (switch_db_collation(sql_file, db_name_buff, delimiter,
+ db_cl_name, row[6], &db_cl_altered))
+ {
+ DBUG_RETURN(1);
+ }
- switch_cs_variables(sql_file, delimiter,
- row[4], /* character_set_client */
- row[4], /* character_set_results */
- row[5]); /* collation_connection */
+ switch_cs_variables(sql_file, delimiter,
+ row[4], /* character_set_client */
+ row[4], /* character_set_results */
+ row[5]); /* collation_connection */
+ }
+ else
+ {
+ /*
+ mysqldump is being run against the server, that does not
+ provide character set information in SHOW CREATE
+ statements.
+
+ NOTE: the dump may be incorrect, since character set
+ information is required in order to restore event properly.
+ */
+
+ fprintf(sql_file,
+ "--\n"
+ "-- WARNING: old server version. "
+ "The following dump may be incomplete.\n"
+ "--\n");
+ }
switch_sql_mode(sql_file, delimiter, row[1]);
@@ -1797,13 +1936,17 @@ static uint dump_events_for_db(char *db)
restore_time_zone(sql_file, delimiter);
restore_sql_mode(sql_file, delimiter);
- restore_cs_variables(sql_file, delimiter);
- if (db_cl_altered)
+ if (mysql_num_fields(event_res) >= 7)
{
- if (restore_db_collation(sql_file, db_name_buff, delimiter,
- db_cl_name))
- DBUG_RETURN(1);
+ restore_cs_variables(sql_file, delimiter);
+
+ if (db_cl_altered)
+ {
+ if (restore_db_collation(sql_file, db_name_buff, delimiter,
+ db_cl_name))
+ DBUG_RETURN(1);
+ }
}
}
} /* end of event printing */
@@ -1871,7 +2014,7 @@ static uint dump_routines_for_db(char *db)
MYSQL_ROW row, routine_list_row;
char db_cl_name[MY_CS_NAME_SIZE];
- int db_cl_altered;
+ int db_cl_altered= FALSE;
DBUG_ENTER("dump_routines_for_db");
DBUG_PRINT("enter", ("db: '%s'", db));
@@ -1938,74 +2081,45 @@ static uint dump_routines_for_db(char *db)
}
else if (strlen(row[2]))
{
- char *query_str= NULL;
- char *definer_begin;
-
+ char *query_str;
if (opt_drop)
fprintf(sql_file, "/*!50003 DROP %s IF EXISTS %s */;\n",
routine_type[i], routine_name);
- /*
- Cover DEFINER-clause in version-specific comments.
-
- TODO: this is definitely a BAD IDEA to parse SHOW CREATE output.
- However, we can not use INFORMATION_SCHEMA instead:
- 1. INFORMATION_SCHEMA provides data in UTF8, but here we
- need data in the original character set;
- 2. INFORMATION_SCHEMA does not provide information about
- routine parameters now.
- */
-
- definer_begin= my_case_str(row[2], strlen(row[2]),
- C_STRING_WITH_LEN(" DEFINER"));
+ query_str= cover_definer_clause_in_sp(row[2], strlen(row[2]));
- if (definer_begin)
+ if (mysql_num_fields(routine_res) >= 6)
{
- char *definer_end= my_case_str(definer_begin,
- strlen(definer_begin),
- C_STRING_WITH_LEN(" PROCEDURE"));
-
- if (!definer_end)
+ if (switch_db_collation(sql_file, db_name_buff, ";",
+ db_cl_name, row[5], &db_cl_altered))
{
- definer_end= my_case_str(definer_begin, strlen(definer_begin),
- C_STRING_WITH_LEN(" FUNCTION"));
+ DBUG_RETURN(1);
}
- if (definer_end)
- {
- char *query_str_tail;
-
- /*
- Allocate memory for new query string: original string
- from SHOW statement and version-specific comments.
- */
- query_str= alloc_query_str(strlen(row[2]) + 23);
-
- query_str_tail= strnmov(query_str, row[2],
- definer_begin - row[2]);
- query_str_tail= strmov(query_str_tail, "*/ /*!50020");
- query_str_tail= strnmov(query_str_tail, definer_begin,
- definer_end - definer_begin);
- query_str_tail= strxmov(query_str_tail, "*/ /*!50003",
- definer_end, NullS);
- }
+ switch_cs_variables(sql_file, ";",
+ row[3], /* character_set_client */
+ row[3], /* character_set_results */
+ row[4]); /* collation_connection */
}
-
- /*
- we need to change sql_mode only for the CREATE
- PROCEDURE/FUNCTION otherwise we may need to re-quote routine_name
- */
-
- if (switch_db_collation(sql_file, db_name_buff, ";",
- db_cl_name, row[5], &db_cl_altered))
+ else
{
- DBUG_RETURN(1);
+ /*
+ mysqldump is being run against the server, that does not
+ provide character set information in SHOW CREATE
+ statements.
+
+ NOTE: the dump may be incorrect, since character set
+ information is required in order to restore stored
+ procedure/function properly.
+ */
+
+ fprintf(sql_file,
+ "--\n"
+ "-- WARNING: old server version. "
+ "The following dump may be incomplete.\n"
+ "--\n");
}
- switch_cs_variables(sql_file, ";",
- row[3], /* character_set_client */
- row[3], /* character_set_results */
- row[4]); /* collation_connection */
switch_sql_mode(sql_file, ";", row[1]);
@@ -2016,12 +2130,16 @@ static uint dump_routines_for_db(char *db)
(const char *) (query_str != NULL ? query_str : row[2]));
restore_sql_mode(sql_file, ";");
- restore_cs_variables(sql_file, ";");
- if (db_cl_altered)
+ if (mysql_num_fields(routine_res) >= 6)
{
- if (restore_db_collation(sql_file, db_name_buff, ";", db_cl_name))
- DBUG_RETURN(1);
+ restore_cs_variables(sql_file, ";");
+
+ if (db_cl_altered)
+ {
+ if (restore_db_collation(sql_file, db_name_buff, ";", db_cl_name))
+ DBUG_RETURN(1);
+ }
}
my_free(query_str, MYF(MY_ALLOW_ZERO_PTR));
@@ -2560,153 +2678,211 @@ continue_xml:
DBUG_RETURN((uint) num_fields);
} /* get_table_structure */
+static void dump_trigger_old(MYSQL_RES *show_triggers_rs,
+ MYSQL_ROW *show_trigger_row,
+ const char *table_name)
+{
+ FILE *sql_file= md_result_file;
-/*
+ char quoted_table_name_buf[NAME_LEN * 2 + 3];
+ char *quoted_table_name= quote_name(table_name, quoted_table_name_buf, 1);
+
+ char name_buff[NAME_LEN * 4 + 3];
+
+ DBUG_ENTER("dump_trigger_old");
- dump_triggers_for_table
+ fprintf(sql_file,
+ "--\n"
+ "-- WARNING: old server version. "
+ "The following dump may be incomplete.\n"
+ "--\n");
+
+ if (opt_compact)
+ fprintf(sql_file, "/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;\n");
- Dumps the triggers given a table/db name. This should be called after
- the tables have been dumped in case a trigger depends on the existence
- of a table
+ fprintf(sql_file,
+ "DELIMITER ;;\n"
+ "/*!50003 SET SESSION SQL_MODE=\"%s\" */;;\n"
+ "/*!50003 CREATE */ ",
+ (*show_trigger_row)[6]);
+
+ if (mysql_num_fields(show_triggers_rs) > 7)
+ {
+ /*
+ mysqldump can be run against the server, that does not support
+ definer in triggers (there is no DEFINER column in SHOW TRIGGERS
+ output). So, we should check if we have this column before
+ accessing it.
+ */
+ size_t user_name_len;
+ char user_name_str[USERNAME_LENGTH + 1];
+ char quoted_user_name_str[USERNAME_LENGTH * 2 + 3];
+ size_t host_name_len;
+ char host_name_str[HOSTNAME_LENGTH + 1];
+ char quoted_host_name_str[HOSTNAME_LENGTH * 2 + 3];
+
+ parse_user((*show_trigger_row)[7],
+ strlen((*show_trigger_row)[7]),
+ user_name_str, &user_name_len,
+ host_name_str, &host_name_len);
+
+ fprintf(sql_file,
+ "/*!50017 DEFINER=%s@%s */ ",
+ quote_name(user_name_str, quoted_user_name_str, FALSE),
+ quote_name(host_name_str, quoted_host_name_str, FALSE));
+ }
+
+ fprintf(sql_file,
+ "/*!50003 TRIGGER %s %s %s ON %s FOR EACH ROW%s%s */;;\n"
+ "DELIMITER ;\n",
+ quote_name((*show_trigger_row)[0], name_buff, 0), /* Trigger */
+ (*show_trigger_row)[4], /* Timing */
+ (*show_trigger_row)[1], /* Event */
+ quoted_table_name,
+ (strchr(" \t\n\r", *((*show_trigger_row)[3]))) ? "" : " ",
+ (*show_trigger_row)[3] /* Statement */);
+
+ if (opt_compact)
+ fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE */;\n");
+
+ DBUG_VOID_RETURN;
+}
+
+static int dump_trigger(MYSQL_RES *show_create_trigger_rs,
+ const char *db_name,
+ const char *db_cl_name)
+{
+ FILE *sql_file= md_result_file;
+ MYSQL_ROW row;
+ int db_cl_altered= FALSE;
+
+ DBUG_ENTER("dump_trigger");
+
+ while ((row= mysql_fetch_row(show_create_trigger_rs)))
+ {
+ char *query_str= cover_definer_clause_in_trigger(row[2], strlen(row[2]));
+
+
+ if (switch_db_collation(sql_file, db_name, ";",
+ db_cl_name, row[5], &db_cl_altered))
+ DBUG_RETURN(TRUE);
+
+ switch_cs_variables(sql_file, ";",
+ row[3], /* character_set_client */
+ row[3], /* character_set_results */
+ row[4]); /* collation_connection */
+
+ switch_sql_mode(sql_file, ";", row[1]);
+
+ fprintf(sql_file,
+ "DELIMITER ;;\n"
+ "/*!50003 %s */;;\n"
+ "DELIMITER ;\n",
+ (const char *) (query_str != NULL ? query_str : row[2]));
+
+ restore_sql_mode(sql_file, ";");
+ restore_cs_variables(sql_file, ";");
+
+ if (db_cl_altered)
+ {
+ if (restore_db_collation(sql_file, db_name, ";", db_cl_name))
+ DBUG_RETURN(TRUE);
+ }
+
+ my_free(query_str, MYF(MY_ALLOW_ZERO_PTR));
+ }
+
+ DBUG_RETURN(FALSE);
+}
+
+/**
+ Dump the triggers for a given table.
+
+ This should be called after the tables have been dumped in case a trigger
+ depends on the existence of a table.
+
+ @param[in] table_name
+ @param[in] db_name
+
+ @return Error status.
+ @retval TRUE error has occurred.
+ @retval FALSE operation succeed.
*/
-static void dump_triggers_for_table(char *table, char *db_name)
+static int dump_triggers_for_table(char *table_name, char *db_name)
{
- char *result_table;
- char name_buff[NAME_LEN*4+3], table_buff[NAME_LEN*2+3];
+ char name_buff[NAME_LEN*4+3];
char query_buff[QUERY_LENGTH];
- uint old_opt_compatible_mode=opt_compatible_mode;
- FILE *sql_file= md_result_file;
- MYSQL_RES *result;
+ uint old_opt_compatible_mode= opt_compatible_mode;
+ MYSQL_RES *show_triggers_rs;
MYSQL_ROW row;
char db_cl_name[MY_CS_NAME_SIZE];
- int db_cl_altered;
DBUG_ENTER("dump_triggers_for_table");
- DBUG_PRINT("enter", ("db: %s, table: %s", db_name, table));
+ DBUG_PRINT("enter", ("db: %s, table_name: %s", db_name, table_name));
/* Do not use ANSI_QUOTES on triggers in dump */
opt_compatible_mode&= ~MASK_ANSI_QUOTES;
- result_table= quote_name(table, table_buff, 1);
-
- my_snprintf(query_buff, sizeof(query_buff),
- "SHOW TRIGGERS LIKE %s",
- quote_for_like(table, name_buff));
-
- if (mysql_query_with_error_report(mysql, &result, query_buff))
- {
- if (path)
- my_fclose(sql_file, MYF(MY_WME));
- DBUG_VOID_RETURN;
- }
/* Get database collation. */
+ if (switch_character_set_results(mysql, "binary"))
+ DBUG_RETURN(TRUE);
+
if (fetch_db_collation(db_name, db_cl_name, sizeof (db_cl_name)))
- DBUG_VOID_RETURN;
+ DBUG_RETURN(TRUE);
- if (switch_character_set_results(mysql, "binary"))
- DBUG_VOID_RETURN;
+ /* Get list of triggers. */
+
+ my_snprintf(query_buff, sizeof(query_buff),
+ "SHOW TRIGGERS LIKE %s",
+ quote_for_like(table_name, name_buff));
+
+ if (mysql_query_with_error_report(mysql, &show_triggers_rs, query_buff))
+ DBUG_RETURN(TRUE);
/* Dump triggers. */
- while ((row= mysql_fetch_row(result)))
+ while ((row= mysql_fetch_row(show_triggers_rs)))
{
- MYSQL_RES *res2;
my_snprintf(query_buff, sizeof (query_buff),
"SHOW CREATE TRIGGER %s",
quote_name(row[0], name_buff, TRUE));
- if (mysql_query_with_error_report(mysql, &res2, query_buff))
+ if (mysql_query(mysql, query_buff))
{
- if (path)
- my_fclose(sql_file, MYF(MY_WME));
- maybe_exit(EX_MYSQLERR);
- DBUG_VOID_RETURN;
- }
-
- while ((row= mysql_fetch_row(res2)))
- {
- char *query_str= NULL;
- char *definer_begin;
-
/*
- Cover DEFINER-clause in version-specific comments.
-
- TODO: this is definitely a BAD IDEA to parse SHOW CREATE output.
- However, we can not use INFORMATION_SCHEMA instead:
- 1. INFORMATION_SCHEMA provides data in UTF8, but here we
- need data in the original character set;
- 2. INFORMATION_SCHEMA does not provide information about
- routine parameters now.
- */
-
- definer_begin= my_case_str(row[2], strlen(row[2]),
- C_STRING_WITH_LEN(" DEFINER"));
+ mysqldump is being run against old server, that does not support
+ SHOW CREATE TRIGGER statement. We should use SHOW TRIGGERS output.
- if (definer_begin)
- {
- char *definer_end= my_case_str(definer_begin, strlen(definer_begin),
- C_STRING_WITH_LEN(" TRIGGER"));
-
- if (definer_end)
- {
- char *query_str_tail;
-
- /*
- Allocate memory for new query string: original string
- from SHOW statement and version-specific comments.
- */
- query_str= alloc_query_str(strlen(row[2]) + 23);
-
- query_str_tail= strnmov(query_str, row[2],
- definer_begin - row[2]);
- query_str_tail= strmov(query_str_tail, "*/ /*!50017");
- query_str_tail= strnmov(query_str_tail, definer_begin,
- definer_end - definer_begin);
- query_str_tail= strxmov(query_str_tail, "*/ /*!50003",
- definer_end, NullS);
- }
- }
-
- if (switch_db_collation(sql_file, db_name, ";",
- db_cl_name, row[5], &db_cl_altered))
- DBUG_VOID_RETURN;
-
- switch_cs_variables(sql_file, ";",
- row[3], /* character_set_client */
- row[3], /* character_set_results */
- row[4]); /* collation_connection */
-
- switch_sql_mode(sql_file, ";", row[1]);
-
- fprintf(sql_file,
- "DELIMITER ;;\n"
- "/*!50003 %s */;;\n"
- "DELIMITER ;\n",
- (const char *) (query_str != NULL ? query_str : row[2]));
+ NOTE: the dump may be incorrect, as old SHOW TRIGGERS does not
+ provide all the necessary information to restore trigger properly.
+ */
- restore_sql_mode(sql_file, ";");
- restore_cs_variables(sql_file, ";");
+ dump_trigger_old(show_triggers_rs, &row, table_name);
+ }
+ else
+ {
+ MYSQL_RES *show_create_trigger_rs= mysql_store_result(mysql);
- if (db_cl_altered)
+ if (!show_create_trigger_rs ||
+ dump_trigger(show_create_trigger_rs, db_name, db_cl_name))
{
- if (restore_db_collation(sql_file, db_name, ";", db_cl_name))
- DBUG_VOID_RETURN;
+ DBUG_RETURN(TRUE);
}
- my_free(query_str, MYF(MY_ALLOW_ZERO_PTR));
+ mysql_free_result(show_create_trigger_rs);
}
- mysql_free_result(res2);
+
}
- mysql_free_result(result);
+ mysql_free_result(show_triggers_rs);
if (switch_character_set_results(mysql, default_charset))
- DBUG_VOID_RETURN;
+ DBUG_RETURN(TRUE);
/*
make sure to set back opt_compatible mode to
@@ -2714,7 +2890,7 @@ static void dump_triggers_for_table(char *table, char *db_name)
*/
opt_compatible_mode=old_opt_compatible_mode;
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
static void add_load_option(DYNAMIC_STRING *str, const char *option,
@@ -3737,7 +3913,7 @@ static int init_dumping(char *database, int init_func(char*))
/* Return 1 if we should copy the table */
-my_bool include_table(uchar* hash_key, uint len)
+my_bool include_table(const char* hash_key, uint len)
{
return !hash_search(&ignore_table, (uchar*) hash_key, len);
}
@@ -3795,7 +3971,14 @@ static int dump_all_tables_in_db(char *database)
order_by= 0;
if (opt_dump_triggers && ! opt_xml &&
mysql_get_server_version(mysql) >= 50009)
- dump_triggers_for_table(table, database);
+ {
+ if (dump_triggers_for_table(table, database))
+ {
+ if (path)
+ my_fclose(md_result_file, MYF(MY_WME));
+ maybe_exit(EX_MYSQLERR);
+ }
+ }
}
}
if (opt_events && !opt_xml &&
@@ -4021,7 +4204,14 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
dump_table(*pos, db);
if (opt_dump_triggers &&
mysql_get_server_version(mysql) >= 50009)
- dump_triggers_for_table(*pos, db);
+ {
+ if (dump_triggers_for_table(*pos, db))
+ {
+ if (path)
+ my_fclose(md_result_file, MYF(MY_WME));
+ maybe_exit(EX_MYSQLERR);
+ }
+ }
}
/* Dump each selected view */
diff --git a/mysql-test/r/federated.result b/mysql-test/r/federated.result
index ca936cd5fde..8f1fe20ea3b 100644
--- a/mysql-test/r/federated.result
+++ b/mysql-test/r/federated.result
@@ -1920,6 +1920,20 @@ a b
2 Curly
drop table federated.t1;
drop table federated.t1;
+
+Bug#18287 create federated table always times out, error 1159 ' '
+
+Test that self-references work
+
+create table federated.t1 (a int primary key);
+create table federated.t2 (a int primary key)
+ENGINE=FEDERATED
+connection='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
+insert into federated.t1 (a) values (1);
+select * from federated.t2;
+a
+1
+drop table federated.t1, federated.t2;
CREATE TABLE federated.t1 (a INT PRIMARY KEY) DEFAULT CHARSET=utf8;
CREATE TABLE federated.t1 (a INT PRIMARY KEY)
ENGINE=FEDERATED
diff --git a/mysql-test/r/lock.result b/mysql-test/r/lock.result
index e2000a9ec91..6152e403637 100644
--- a/mysql-test/r/lock.result
+++ b/mysql-test/r/lock.result
@@ -96,4 +96,74 @@ ERROR HY000: You can't combine write-locking of system tables with other tables
LOCK TABLES mysql.time_zone READ, mysql.proc WRITE;
ERROR HY000: You can't combine write-locking of system tables with other tables or lock types
DROP TABLE t1;
+
+Bug#5719 impossible to lock VIEW
+
+Just covering existing behaviour with tests.
+Consistency has not been found here.
+
+drop view if exists v_bug5719;
+drop table if exists t1, t2, t3;
+create table t1 (a int);
+create temporary table t2 (a int);
+create table t3 (a int);
+create view v_bug5719 as select 1;
+lock table v_bug5719 write;
+select * from t1;
+ERROR HY000: Table 't1' was not locked with LOCK TABLES
+
+Allowed to select from a temporary talbe under LOCK TABLES
+
+select * from t2;
+a
+select * from t3;
+ERROR HY000: Table 't3' was not locked with LOCK TABLES
+select * from v_bug5719;
+1
+1
+drop view v_bug5719;
+
+sic: did not left LOCK TABLES mode automatically
+
+select * from t1;
+ERROR HY000: Table 't1' was not locked with LOCK TABLES
+unlock tables;
+create view v_bug5719 as select * from t1;
+lock tables v_bug5719 write;
+select * from v_bug5719;
+a
+
+Allowed to use an underlying table under LOCK TABLES <view>
+
+select * from t1;
+a
+
+Allowed to select from a temporary table under LOCK TABLES
+
+select * from t2;
+a
+select * from t3;
+ERROR HY000: Table 't3' was not locked with LOCK TABLES
+drop table t1;
+
+sic: left LOCK TABLES mode
+
+select * from t3;
+a
+select * from v_bug5719;
+ERROR HY000: View 'test.v_bug5719' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+unlock tables;
+drop view v_bug5719;
+
+When limitation to use temporary tables in views is removed, please
+add a test that shows what happens under LOCK TABLES when a view
+references a temporary table, is locked, and the underlying table
+is dropped.
+
+create view v_bug5719 as select * from t2;
+ERROR HY000: View's SELECT refers to a temporary table 't2'
+
+Cleanup.
+
+drop table t2, t3;
End of 5.1 tests.
diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result
index 2445b3e0c69..a3f7ab4505c 100644
--- a/mysql-test/r/lock_multi.result
+++ b/mysql-test/r/lock_multi.result
@@ -95,3 +95,13 @@ alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1
alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; //
unlock tables;
drop table t1;
+create table t1 (i int);
+lock table t1 read;
+update t1 set i= 10;;
+select * from t1;;
+kill query ID;
+i
+ERROR 70100: Query execution was interrupted
+unlock tables;
+drop table t1;
+End of 5.1 tests
diff --git a/mysql-test/r/log_state.result b/mysql-test/r/log_state.result
index 0c6be16b9b7..3a3ef584ce3 100644
--- a/mysql-test/r/log_state.result
+++ b/mysql-test/r/log_state.result
@@ -37,14 +37,14 @@ set session long_query_time=1;
select sleep(2);
sleep(2)
0
-select * from mysql.slow_log;
+select * from mysql.slow_log where sql_text NOT LIKE '%slow_log%';
start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text
set global slow_query_log= ON;
set session long_query_time=1;
select sleep(2);
sleep(2)
0
-select * from mysql.slow_log;
+select * from mysql.slow_log where sql_text NOT LIKE '%slow_log%';
start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text
TIMESTAMP USER_HOST QUERY_TIME 00:00:00 1 0 test 0 0 1 select sleep(2)
show global variables
diff --git a/mysql-test/t/federated.test b/mysql-test/t/federated.test
index 6597c77e798..90f1fa36bb4 100644
--- a/mysql-test/t/federated.test
+++ b/mysql-test/t/federated.test
@@ -1725,6 +1725,20 @@ drop table federated.t1;
connection slave;
drop table federated.t1;
+--echo
+--echo Bug#18287 create federated table always times out, error 1159 ' '
+--echo
+--echo Test that self-references work
+--echo
+connection slave;
+create table federated.t1 (a int primary key);
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval create table federated.t2 (a int primary key)
+ ENGINE=FEDERATED
+ connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
+insert into federated.t1 (a) values (1);
+select * from federated.t2;
+drop table federated.t1, federated.t2;
#
# BUG#29875 Disable support for transactions
diff --git a/mysql-test/t/lock.test b/mysql-test/t/lock.test
index 2b8b430f096..6069bbf7018 100644
--- a/mysql-test/t/lock.test
+++ b/mysql-test/t/lock.test
@@ -148,5 +148,70 @@ LOCK TABLES mysql.time_zone READ, mysql.proc WRITE;
DROP TABLE t1;
+--echo
+--echo Bug#5719 impossible to lock VIEW
+--echo
+--echo Just covering existing behaviour with tests.
+--echo Consistency has not been found here.
+--echo
+--disable_warnings
+drop view if exists v_bug5719;
+drop table if exists t1, t2, t3;
+--enable_warnings
+create table t1 (a int);
+create temporary table t2 (a int);
+create table t3 (a int);
+create view v_bug5719 as select 1;
+lock table v_bug5719 write;
+--error ER_TABLE_NOT_LOCKED
+select * from t1;
+--echo
+--echo Allowed to select from a temporary talbe under LOCK TABLES
+--echo
+select * from t2;
+--error ER_TABLE_NOT_LOCKED
+select * from t3;
+select * from v_bug5719;
+drop view v_bug5719;
+--echo
+--echo sic: did not left LOCK TABLES mode automatically
+--echo
+--error ER_TABLE_NOT_LOCKED
+select * from t1;
+unlock tables;
+create view v_bug5719 as select * from t1;
+lock tables v_bug5719 write;
+select * from v_bug5719;
+--echo
+--echo Allowed to use an underlying table under LOCK TABLES <view>
+--echo
+select * from t1;
+--echo
+--echo Allowed to select from a temporary table under LOCK TABLES
+--echo
+select * from t2;
+--error ER_TABLE_NOT_LOCKED
+select * from t3;
+drop table t1;
+--echo
+--echo sic: left LOCK TABLES mode
+--echo
+select * from t3;
+--error ER_VIEW_INVALID
+select * from v_bug5719;
+unlock tables;
+drop view v_bug5719;
+--echo
+--echo When limitation to use temporary tables in views is removed, please
+--echo add a test that shows what happens under LOCK TABLES when a view
+--echo references a temporary table, is locked, and the underlying table
+--echo is dropped.
+--echo
+--error ER_VIEW_SELECT_TMPTABLE
+create view v_bug5719 as select * from t2;
+--echo
+--echo Cleanup.
+--echo
+drop table t2, t3;
--echo End of 5.1 tests.
diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test
index 4a6b4ff5e56..b7c406f9637 100644
--- a/mysql-test/t/lock_multi.test
+++ b/mysql-test/t/lock_multi.test
@@ -270,3 +270,38 @@ drop table t1;
# End of 5.0 tests
+
+#
+# Bug #21281 "Pending write lock is incorrectly removed when its
+# statement being KILLed"
+#
+create table t1 (i int);
+connection locker;
+lock table t1 read;
+connection writer;
+--send update t1 set i= 10;
+connection reader;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Locked" and info = "update t1 set i= 10";
+--source include/wait_condition.inc
+--send select * from t1;
+connection default;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Locked" and info = "select * from t1";
+--source include/wait_condition.inc
+let $ID= `select id from information_schema.processlist where state = "Locked" and info = "update t1 set i= 10"`;
+--replace_result $ID ID
+eval kill query $ID;
+connection reader;
+--reap
+connection writer;
+--error ER_QUERY_INTERRUPTED
+--reap
+connection locker;
+unlock tables;
+connection default;
+drop table t1;
+
+--echo End of 5.1 tests
diff --git a/mysql-test/t/log_state.test b/mysql-test/t/log_state.test
index b0bb818b783..c67da261ef1 100644
--- a/mysql-test/t/log_state.test
+++ b/mysql-test/t/log_state.test
@@ -28,7 +28,7 @@ connection con1;
set session long_query_time=1;
select sleep(2);
--replace_column 1 TIMESTAMP 2 USER_HOST 3 QUERY_TIME
-select * from mysql.slow_log;
+select * from mysql.slow_log where sql_text NOT LIKE '%slow_log%';
connection default;
set global slow_query_log= ON;
@@ -36,7 +36,7 @@ connection con1;
set session long_query_time=1;
select sleep(2);
--replace_column 1 TIMESTAMP 2 USER_HOST 3 QUERY_TIME
-select * from mysql.slow_log;
+select * from mysql.slow_log where sql_text NOT LIKE '%slow_log%';
connection default;
show global variables
where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c
index 20edffb49c2..a81ed925562 100644
--- a/mysys/thr_lock.c
+++ b/mysys/thr_lock.c
@@ -384,6 +384,9 @@ static inline my_bool have_specific_lock(THR_LOCK_DATA *data,
}
+static void wake_up_waiters(THR_LOCK *lock);
+
+
static enum enum_thr_lock_result
wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
my_bool in_wait_list)
@@ -445,8 +448,13 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
else
wait->last=data->prev;
data->type= TL_UNLOCK; /* No lock */
+ check_locks(data->lock, "killed or timed out wait_for_lock", 1);
+ wake_up_waiters(data->lock);
+ }
+ else
+ {
+ check_locks(data->lock, "aborted wait_for_lock", 0);
}
- check_locks(data->lock,"failed wait_for_lock",0);
}
else
{
@@ -776,6 +784,26 @@ void thr_unlock(THR_LOCK_DATA *data)
lock->read_no_write_count--;
data->type=TL_UNLOCK; /* Mark unlocked */
check_locks(lock,"after releasing lock",1);
+ wake_up_waiters(lock);
+ pthread_mutex_unlock(&lock->mutex);
+ DBUG_VOID_RETURN;
+}
+
+
+/**
+ @brief Wake up all threads which pending requests for the lock
+ can be satisfied.
+
+ @param lock Lock for which threads should be woken up
+
+*/
+
+static void wake_up_waiters(THR_LOCK *lock)
+{
+ THR_LOCK_DATA *data;
+ enum thr_lock_type lock_type;
+
+ DBUG_ENTER("wake_up_waiters");
if (!lock->write.data) /* If no active write locks */
{
@@ -827,11 +855,7 @@ void thr_unlock(THR_LOCK_DATA *data)
data=lock->write_wait.data; /* Free this too */
}
if (data->type >= TL_WRITE_LOW_PRIORITY)
- {
- check_locks(lock,"giving write lock",0);
- pthread_mutex_unlock(&lock->mutex);
- DBUG_VOID_RETURN;
- }
+ goto end;
/* Release possible read locks together with the write lock */
}
if (lock->read_wait.data)
@@ -886,8 +910,7 @@ void thr_unlock(THR_LOCK_DATA *data)
free_all_read_locks(lock,0);
}
end:
- check_locks(lock,"thr_unlock",0);
- pthread_mutex_unlock(&lock->mutex);
+ check_locks(lock, "after waking up waiters", 0);
DBUG_VOID_RETURN;
}
@@ -1101,6 +1124,7 @@ my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread_id)
lock->write_wait.last= data->prev;
}
}
+ wake_up_waiters(lock);
pthread_mutex_unlock(&lock->mutex);
DBUG_RETURN(found);
}
diff --git a/sql/item.cc b/sql/item.cc
index 006595a39a9..76aad708d22 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1705,7 +1705,7 @@ void Item_ident_for_show::make_field(Send_field *tmp_field)
tmp_field->type=field->type();
tmp_field->flags= field->table->maybe_null ?
(field->flags & ~NOT_NULL_FLAG) : field->flags;
- tmp_field->decimals= 0;
+ tmp_field->decimals= field->decimals();
}
/**********************************************/
diff --git a/sql/table.cc b/sql/table.cc
index 12fffe1dde7..27f9ccc418e 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -2484,6 +2484,7 @@ void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table)
create_info->row_type= share->row_type;
create_info->default_table_charset= share->table_charset;
create_info->table_charset= 0;
+ create_info->comment= share->comment;
DBUG_VOID_RETURN;
}
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index eac1ad413ea..3656364820e 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -16077,7 +16077,6 @@ static void test_bug24179()
/*
Bug#28075 "COM_DEBUG crashes mysqld"
- Note: Test disabled because of failure in PushBuild.
*/
static void test_bug28075()
@@ -16106,7 +16105,7 @@ static void test_bug27876()
int rc;
MYSQL_RES *result;
- char utf8_func[] =
+ unsigned char utf8_func[] =
{
0xd1, 0x84, 0xd1, 0x83, 0xd0, 0xbd, 0xd0, 0xba,
0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb9, 0xd0, 0xba,
@@ -16114,7 +16113,7 @@ static void test_bug27876()
0x00
};
- char utf8_param[] =
+ unsigned char utf8_param[] =
{
0xd0, 0xbf, 0xd0, 0xb0, 0xd1, 0x80, 0xd0, 0xb0,
0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x8a,
@@ -16334,7 +16333,54 @@ static void test_bug29692()
mysql_close(conn);
}
+/**
+ Bug#29306 Truncated data in MS Access with decimal (3,1) columns in a VIEW
+*/
+
+static void test_bug29306()
+{
+ MYSQL_FIELD *field;
+ int rc;
+ MYSQL_RES *res;
+
+ DBUG_ENTER("test_bug29306");
+ myheader("test_bug29306");
+
+ rc= mysql_query(mysql, "DROP TABLE IF EXISTS tab17557");
+ myquery(rc);
+ rc= mysql_query(mysql, "DROP VIEW IF EXISTS view17557");
+ myquery(rc);
+ rc= mysql_query(mysql, "CREATE TABLE tab17557 (dd decimal (3,1))");
+ myquery(rc);
+ rc= mysql_query(mysql, "CREATE VIEW view17557 as SELECT dd FROM tab17557");
+ myquery(rc);
+ rc= mysql_query(mysql, "INSERT INTO tab17557 VALUES (7.6)");
+ myquery(rc);
+
+ /* Checking the view */
+ res= mysql_list_fields(mysql, "view17557", NULL);
+ while ((field= mysql_fetch_field(res)))
+ {
+ if (! opt_silent)
+ {
+ printf("field name %s\n", field->name);
+ printf("field table %s\n", field->table);
+ printf("field decimals %d\n", field->decimals);
+ if (field->decimals < 1)
+ printf("Error! No decimals! \n");
+ printf("\n\n");
+ }
+ DIE_UNLESS(field->decimals == 1);
+ }
+ mysql_free_result(res);
+
+ rc= mysql_query(mysql, "DROP TABLE tab17557");
+ myquery(rc);
+ rc= mysql_query(mysql, "DROP VIEW view17557");
+ myquery(rc);
+ DBUG_VOID_RETURN;
+}
/*
Read and parse arguments and MySQL options from my.cnf
*/
@@ -16626,6 +16672,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug27592", test_bug27592 },
{ "test_bug29687", test_bug29687 },
{ "test_bug29692", test_bug29692 },
+ { "test_bug29306", test_bug29306 },
{ 0, 0 }
};