diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 772f1d15b92..43d479a1043 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] -post_commit_to = "MYSQL_COMMITS_SECURITY_WW@ORACLE.COM" -post_push_to = "MYSQL_COMMITS_SECURITY_WW@ORACLE.COM" -tree_name = "mysql-5.5-security" +post_commit_to = "commits@lists.mysql.com" +post_push_to = "commits@lists.mysql.com" +tree_name = "mysql-5.5" diff --git a/.bzrfileids b/.bzrfileids index 8ddfb9473de..cfd36007ab7 100644 Binary files a/.bzrfileids and b/.bzrfileids differ diff --git a/CMakeLists.txt b/CMakeLists.txt index 6766f76c665..319c214bece 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,8 +79,19 @@ ELSEIF(NOT HAVE_CMAKE_BUILD_TYPE OR OLD_WITH_DEBUG) SET(OLD_WITH_DEBUG 0 CACHE INTERNAL "" FORCE) ENDIF() +# Optionally set project name, e.g. +# foo.xcodeproj (mac) or foo.sln (windows) +SET(MYSQL_PROJECT_NAME_DOCSTRING "MySQL project name") +IF(DEFINED MYSQL_PROJECT_NAME) + SET(MYSQL_PROJECT_NAME ${MYSQL_PROJECT_NAME} CACHE STRING + ${MYSQL_PROJECT_NAME_DOCSTRING} FORCE) +ELSE() + SET(MYSQL_PROJECT_NAME "MySQL" CACHE STRING + ${MYSQL_PROJECT_NAME_DOCSTRING} FORCE) + MARK_AS_ADVANCED(MYSQL_PROJECT_NAME) +ENDIF() +PROJECT(${MYSQL_PROJECT_NAME}) -PROJECT(MySQL) IF(BUILD_CONFIG) INCLUDE( ${CMAKE_SOURCE_DIR}/cmake/build_configurations/${BUILD_CONFIG}.cmake) diff --git a/VERSION b/VERSION index 3d67d80ef19..31b38bc24dd 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=20 -MYSQL_VERSION_EXTRA=.t3 +MYSQL_VERSION_PATCH=21 +MYSQL_VERSION_EXTRA=.t4 diff --git a/client/mysql_plugin.c b/client/mysql_plugin.c index fb2a031bb8e..15f67e2b3e7 100644 --- a/client/mysql_plugin.c +++ b/client/mysql_plugin.c @@ -1018,7 +1018,7 @@ static int find_plugin(char *tp_path) Build the boostrap file. Create a new file and populate it with SQL commands to ENABLE or DISABLE - the plugin via INSERT and DELETE operations on the mysql.plugin table. + the plugin via REPLACE and DELETE operations on the mysql.plugin table. param[in] operation The type of operation (ENABLE or DISABLE) param[out] bootstrap A FILE* pointer @@ -1035,12 +1035,16 @@ static int build_bootstrap_file(char *operation, char *bootstrap) Perform plugin operation : ENABLE or DISABLE The following creates a temporary bootstrap file and populates it with - the appropriate SQL commands for the operation. For ENABLE, INSERT + the appropriate SQL commands for the operation. For ENABLE, REPLACE statements are created. For DISABLE, DELETE statements are created. The values for these statements are derived from the plugin_data read from the .ini configuration file. Once the file is built, a call to mysqld is made in read only, bootstrap modes to read the SQL statements and execute them. + + Note: Replace was used so that if a user loads a newer version of a + library with a different library name, the new library name is + used for symbols that match. */ if ((error= make_tempfile(bootstrap, "sql"))) { @@ -1057,7 +1061,7 @@ static int build_bootstrap_file(char *operation, char *bootstrap) if (strcasecmp(operation, "enable") == 0) { int i= 0; - fprintf(file, "INSERT IGNORE INTO mysql.plugin VALUES "); + fprintf(file, "REPLACE INTO mysql.plugin VALUES "); for (i= 0; i < (int)array_elements(plugin_data.components); i++) { /* stop when we read the end of the symbol list - marked with NULL */ diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 684d20c29a8..00cfdcf964a 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -243,7 +243,6 @@ get_one_option(int optid, const struct my_option *opt, switch (optid) { case '?': - puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011")); printf("%s Ver %s Distrib %s, for %s (%s)\n", my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010")); diff --git a/client/mysqldump.c b/client/mysqldump.c index 6b4dd739906..4cf93201f59 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -77,6 +77,9 @@ /* Size of buffer for dump's select query */ #define QUERY_LENGTH 1536 +/* Size of comment buffer. */ +#define COMMENT_LENGTH 2048 + /* ignore table flags */ #define IGNORE_NONE 0x00 /* no ignore */ #define IGNORE_DATA 0x01 /* don't dump data for this table */ @@ -105,7 +108,7 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1, opt_slave_apply= 0, opt_include_master_host_port= 0, - opt_events= 0, + opt_events= 0, opt_comments_used= 0, opt_alltspcs=0, opt_notspcs= 0; static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0; static ulong opt_max_allowed_packet, opt_net_buffer_length; @@ -539,6 +542,8 @@ static int dump_all_tablespaces(); static int dump_tablespaces_for_tables(char *db, char **table_names, int tables); static int dump_tablespaces_for_databases(char** databases); static int dump_tablespaces(char* ts_where); +static void print_comment(FILE *sql_file, my_bool is_error, const char *format, + ...); /* @@ -562,6 +567,8 @@ static void verbose_msg(const char *fmt, ...) vfprintf(stderr, fmt, args); va_end(args); + fflush(stderr); + DBUG_VOID_RETURN; } @@ -631,19 +638,19 @@ static void write_header(FILE *sql_file, char *db_name) } else if (!opt_compact) { - if (opt_comments) - { - fprintf(sql_file, - "-- MySQL dump %s Distrib %s, for %s (%s)\n--\n", - DUMP_VERSION, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); - fprintf(sql_file, "-- Host: %s Database: %s\n", - current_host ? current_host : "localhost", db_name ? db_name : - ""); - fputs("-- ------------------------------------------------------\n", - sql_file); - fprintf(sql_file, "-- Server version\t%s\n", - mysql_get_server_info(&mysql_connection)); - } + print_comment(sql_file, 0, + "-- MySQL dump %s Distrib %s, for %s (%s)\n--\n", + DUMP_VERSION, MYSQL_SERVER_VERSION, SYSTEM_TYPE, + MACHINE_TYPE); + print_comment(sql_file, 0, "-- Host: %s Database: %s\n", + current_host ? current_host : "localhost", + db_name ? db_name : ""); + print_comment(sql_file, 0, + "-- ------------------------------------------------------\n" + ); + print_comment(sql_file, 0, "-- Server version\t%s\n", + mysql_get_server_info(&mysql_connection)); + if (opt_set_charset) fprintf(sql_file, "\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;" @@ -701,18 +708,16 @@ static void write_footer(FILE *sql_file) fprintf(sql_file, "/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;\n"); fputs("\n", sql_file); - if (opt_comments) + + if (opt_dump_date) { - if (opt_dump_date) - { - char time_str[20]; - get_date(time_str, GETDATE_DATE_TIME, 0); - fprintf(sql_file, "-- Dump completed on %s\n", - time_str); - } - else - fprintf(sql_file, "-- Dump completed\n"); + char time_str[20]; + get_date(time_str, GETDATE_DATE_TIME, 0); + print_comment(sql_file, 0, "-- Dump completed on %s\n", time_str); } + else + print_comment(sql_file, 0, "-- Dump completed\n"); + check_io(sql_file); } } /* write_footer */ @@ -786,6 +791,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), extended_insert= opt_drop= opt_lock= opt_disable_keys= opt_autocommit= opt_create_db= 0; break; + case 'i': + opt_comments_used= 1; + break; case 'I': case '?': usage(); @@ -807,11 +815,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), opt_disable_keys= lock_tables= opt_set_charset= 0; break; case (int) OPT_COMPACT: - if (opt_compact) - { - opt_comments= opt_drop= opt_disable_keys= opt_lock= 0; - opt_set_charset= 0; - } + if (opt_compact) + { + opt_comments= opt_drop= opt_disable_keys= opt_lock= 0; + opt_set_charset= 0; + } + break; case (int) OPT_TABLES: opt_databases=0; break; @@ -1635,20 +1644,20 @@ static char *quote_for_like(const char *name, char *buff) } -/* +/** Quote and print a string. - SYNOPSIS - print_quoted_xml() - xml_file - output file - str - string to print - len - its length + @param xml_file - Output file. + @param str - String to print. + @param len - Its length. + @param is_attribute_name - A check for attribute name or value. - DESCRIPTION + @description Quote '<' '>' '&' '\"' chars and print a string to the xml_file. */ -static void print_quoted_xml(FILE *xml_file, const char *str, ulong len) +static void print_quoted_xml(FILE *xml_file, const char *str, ulong len, + my_bool is_attribute_name) { const char *end; @@ -1667,6 +1676,14 @@ static void print_quoted_xml(FILE *xml_file, const char *str, ulong len) case '\"': fputs(""", xml_file); break; + case ' ': + /* Attribute names cannot contain spaces. */ + if (is_attribute_name) + { + fputs("_", xml_file); + break; + } + /* fall through */ default: fputc(*str, xml_file); break; @@ -1727,7 +1744,7 @@ static void print_xml_tag(FILE * xml_file, const char* sbeg, fputs(attribute_name, xml_file); fputc('\"', xml_file); - print_quoted_xml(xml_file, attribute_value, strlen(attribute_value)); + print_quoted_xml(xml_file, attribute_value, strlen(attribute_value), 0); fputc('\"', xml_file); attribute_name= va_arg(arg_list, char *); @@ -1767,13 +1784,52 @@ static void print_xml_null_tag(FILE * xml_file, const char* sbeg, fputs("<", xml_file); fputs(stag_atr, xml_file); fputs("\"", xml_file); - print_quoted_xml(xml_file, sval, strlen(sval)); + print_quoted_xml(xml_file, sval, strlen(sval), 0); fputs("\" xsi:nil=\"true\" />", xml_file); fputs(line_end, xml_file); check_io(xml_file); } +/** + Print xml CDATA section. + + @param xml_file - output file + @param str - string to print + @param len - length of the string + + @note + This function also takes care of the presence of '[[>' + string in the str. If found, the CDATA section is broken + into two CDATA sections, and ]]. +*/ + +static void print_xml_cdata(FILE *xml_file, const char *str, ulong len) +{ + const char *end; + + fputs("')) + { + fputs("]]]]>", xml_file); + str += 2; + continue; + } + /* fall through */ + default: + fputc(*str, xml_file); + break; + } + } + fputs("\n]]>\n", xml_file); + check_io(xml_file); +} + + /* Print xml tag with many attributes. @@ -1783,6 +1839,7 @@ static void print_xml_null_tag(FILE * xml_file, const char* sbeg, row_name - xml tag name tableRes - query result row - result row + str_create - create statement header string DESCRIPTION Print tag with many attribute to the xml_file. Format is: @@ -1792,9 +1849,13 @@ static void print_xml_null_tag(FILE * xml_file, const char* sbeg, */ static void print_xml_row(FILE *xml_file, const char *row_name, - MYSQL_RES *tableRes, MYSQL_ROW *row) + MYSQL_RES *tableRes, MYSQL_ROW *row, + const char *str_create) { uint i; + my_bool body_found= 0; + char *create_stmt_ptr= NULL; + ulong create_stmt_len= 0; MYSQL_FIELD *field; ulong *lengths= mysql_fetch_lengths(tableRes); @@ -1805,19 +1866,109 @@ static void print_xml_row(FILE *xml_file, const char *row_name, { if ((*row)[i]) { - fputc(' ', xml_file); - print_quoted_xml(xml_file, field->name, field->name_length); - fputs("=\"", xml_file); - print_quoted_xml(xml_file, (*row)[i], lengths[i]); - fputc('"', xml_file); - check_io(xml_file); + /* For 'create' statements, dump using CDATA. */ + if ((str_create) && (strcmp(str_create, field->name) == 0)) + { + create_stmt_ptr= (*row)[i]; + create_stmt_len= lengths[i]; + body_found= 1; + } + else + { + fputc(' ', xml_file); + print_quoted_xml(xml_file, field->name, field->name_length, 1); + fputs("=\"", xml_file); + print_quoted_xml(xml_file, (*row)[i], lengths[i], 0); + fputc('"', xml_file); + check_io(xml_file); + } + } + } + + if (create_stmt_len) + { + DBUG_ASSERT(body_found); + fputs(">\n", xml_file); + print_xml_cdata(xml_file, create_stmt_ptr, create_stmt_len); + fprintf(xml_file, "\t\t\n", row_name); + } + else + fputs(" />\n", xml_file); + + check_io(xml_file); +} + + +/** + Print xml comments. + + @param xml_file - output file + @param len - length of comment message + @param comment_string - comment message + + @description + Print the comment message in the format: + "\n" + + @note + Any occurrence of continuous hyphens will be + squeezed to a single hyphen. +*/ + +static void print_xml_comment(FILE *xml_file, ulong len, + const char *comment_string) +{ + const char* end; + + fputs("\n", xml_file); check_io(xml_file); } + +/* A common printing function for xml and non-xml modes. */ + +static void print_comment(FILE *sql_file, my_bool is_error, const char *format, + ...) +{ + static char comment_buff[COMMENT_LENGTH]; + va_list args; + + /* If its an error message, print it ignoring opt_comments. */ + if (!is_error && !opt_comments) + return; + + va_start(args, format); + my_vsnprintf(comment_buff, COMMENT_LENGTH, format, args); + va_end(args); + + if (!opt_xml) + { + fputs(comment_buff, sql_file); + check_io(sql_file); + return; + } + + print_xml_comment(sql_file, strlen(comment_buff), comment_buff); +} + + /* create_delimiter Generate a new (null-terminated) string that does not exist in query @@ -1884,8 +2035,8 @@ static uint dump_events_for_db(char *db) mysql_real_escape_string(mysql, db_name_buff, db, strlen(db)); /* nice comments */ - if (opt_comments) - fprintf(sql_file, "\n--\n-- Dumping events for database '%s'\n--\n", db); + print_comment(sql_file, 0, + "\n--\n-- Dumping events for database '%s'\n--\n", db); /* not using "mysql_query_with_error_report" because we may have not @@ -1900,12 +2051,17 @@ static uint dump_events_for_db(char *db) strcpy(delimiter, ";"); if (mysql_num_rows(event_list_res) > 0) { - fprintf(sql_file, "/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;\n"); + if (opt_xml) + fputs("\t\n", sql_file); + else + { + fprintf(sql_file, "/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;\n"); - /* Get database collation. */ + /* Get database collation. */ - if (fetch_db_collation(db_name_buff, db_cl_name, sizeof (db_cl_name))) - DBUG_RETURN(1); + if (fetch_db_collation(db_name_buff, db_cl_name, sizeof (db_cl_name))) + DBUG_RETURN(1); + } if (switch_character_set_results(mysql, "binary")) DBUG_RETURN(1); @@ -1922,6 +2078,13 @@ static uint dump_events_for_db(char *db) while ((row= mysql_fetch_row(event_res)) != NULL) { + if (opt_xml) + { + print_xml_row(sql_file, "event", event_res, &row, + "Create Event"); + continue; + } + /* if the user has EXECUTE privilege he can see event names, but not the event body! @@ -2007,8 +2170,16 @@ static uint dump_events_for_db(char *db) mysql_free_result(event_res); } /* end of list of events */ - fprintf(sql_file, "DELIMITER ;\n"); - fprintf(sql_file, "/*!50106 SET TIME_ZONE= @save_time_zone */ ;\n"); + if (opt_xml) + { + fputs("\t\n", sql_file); + check_io(sql_file); + } + else + { + fprintf(sql_file, "DELIMITER ;\n"); + fprintf(sql_file, "/*!50106 SET TIME_ZONE= @save_time_zone */ ;\n"); + } if (switch_character_set_results(mysql, default_charset)) DBUG_RETURN(1); @@ -2062,6 +2233,7 @@ static uint dump_routines_for_db(char *db) const char *routine_type[]= {"FUNCTION", "PROCEDURE"}; char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3]; char *routine_name; + char *query_str; int i; FILE *sql_file= md_result_file; MYSQL_RES *routine_res, *routine_list_res; @@ -2076,8 +2248,8 @@ static uint dump_routines_for_db(char *db) mysql_real_escape_string(mysql, db_name_buff, db, strlen(db)); /* nice comments */ - if (opt_comments) - fprintf(sql_file, "\n--\n-- Dumping routines for database '%s'\n--\n", db); + print_comment(sql_file, 0, + "\n--\n-- Dumping routines for database '%s'\n--\n", db); /* not using "mysql_query_with_error_report" because we may have not @@ -2094,6 +2266,9 @@ static uint dump_routines_for_db(char *db) if (switch_character_set_results(mysql, "binary")) DBUG_RETURN(1); + if (opt_xml) + fputs("\t\n", sql_file); + /* 0, retrieve and dump functions, 1, procedures */ for (i= 0; i <= 1; i++) { @@ -2129,13 +2304,25 @@ static uint dump_routines_for_db(char *db) row[2] ? (int) strlen(row[2]) : 0)); if (row[2] == NULL) { - fprintf(sql_file, "\n-- insufficient privileges to %s\n", query_buff); - fprintf(sql_file, "-- does %s have permissions on mysql.proc?\n\n", current_user); + print_comment(sql_file, 1, "\n-- insufficient privileges to %s\n", + query_buff); + print_comment(sql_file, 1, + "-- does %s have permissions on mysql.proc?\n\n", + current_user); maybe_die(EX_MYSQLERR,"%s has insufficent privileges to %s!", current_user, query_buff); } else if (strlen(row[2])) { - char *query_str; + if (opt_xml) + { + if (i) // Procedures. + print_xml_row(sql_file, "routine", routine_res, &row, + "Create Procedure"); + else // Functions. + print_xml_row(sql_file, "routine", routine_res, &row, + "Create Function"); + continue; + } if (opt_drop) fprintf(sql_file, "/*!50003 DROP %s IF EXISTS %s */;\n", routine_type[i], routine_name); @@ -2215,6 +2402,12 @@ static uint dump_routines_for_db(char *db) mysql_free_result(routine_list_res); } /* end of for i (0 .. 1) */ + if (opt_xml) + { + fputs("\t\n", sql_file); + check_io(sql_file); + } + if (switch_character_set_results(mysql, default_charset)) DBUG_RETURN(1); @@ -2327,16 +2520,16 @@ static uint get_table_structure(char *table, char *db, char *table_type, write_header(sql_file, db); } - if (!opt_xml && opt_comments) - { + if (strcmp (table_type, "VIEW") == 0) /* view */ - fprintf(sql_file, "\n--\n-- Temporary table structure for view %s\n--\n\n", - result_table); + print_comment(sql_file, 0, + "\n--\n-- Temporary table structure for view %s\n--\n\n", + result_table); else - fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n", - result_table); - check_io(sql_file); - } + print_comment(sql_file, 0, + "\n--\n-- Table structure for table %s\n--\n\n", + result_table); + if (opt_drop) { /* @@ -2537,9 +2730,10 @@ static uint get_table_structure(char *table, char *db, char *table_type, DBUG_RETURN(0); write_header(sql_file, db); } - if (!opt_xml && opt_comments) - fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n", - result_table); + + print_comment(sql_file, 0, + "\n--\n-- Table structure for table %s\n--\n\n", + result_table); if (opt_drop) fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", result_table); if (!opt_xml) @@ -2590,7 +2784,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, { if (opt_xml) { - print_xml_row(sql_file, "field", result, &row); + print_xml_row(sql_file, "field", result, &row, NullS); continue; } @@ -2662,7 +2856,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, { if (opt_xml) { - print_xml_row(sql_file, "key", result, &row); + print_xml_row(sql_file, "key", result, &row, NullS); continue; } @@ -2721,7 +2915,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, else { if (opt_xml) - print_xml_row(sql_file, "options", result, &row); + print_xml_row(sql_file, "options", result, &row, NullS); else { fputs("/*!",sql_file); @@ -2765,9 +2959,19 @@ static void dump_trigger_old(FILE *sql_file, MYSQL_RES *show_triggers_rs, char *quoted_table_name= quote_name(table_name, quoted_table_name_buf, 1); char name_buff[NAME_LEN * 4 + 3]; + const char *xml_msg= "\nWarning! mysqldump being run against old server " + "that does not\nsupport 'SHOW CREATE TRIGGERS' " + "statement. Skipping..\n"; DBUG_ENTER("dump_trigger_old"); + if (opt_xml) + { + print_xml_comment(sql_file, strlen(xml_msg), xml_msg); + check_io(sql_file); + DBUG_VOID_RETURN; + } + fprintf(sql_file, "--\n" "-- WARNING: old server version. " @@ -2831,17 +3035,25 @@ static int dump_trigger(FILE *sql_file, MYSQL_RES *show_create_trigger_rs, const char *db_cl_name) { MYSQL_ROW row; + char *query_str; int db_cl_altered= FALSE; DBUG_ENTER("dump_trigger"); while ((row= mysql_fetch_row(show_create_trigger_rs))) { - char *query_str= cover_definer_clause(row[2], strlen(row[2]), - C_STRING_WITH_LEN("50017"), - C_STRING_WITH_LEN("50003"), - C_STRING_WITH_LEN(" TRIGGER")); + if (opt_xml) + { + print_xml_row(sql_file, "trigger", show_create_trigger_rs, &row, + "SQL Original Statement"); + check_io(sql_file); + continue; + } + query_str= cover_definer_clause(row[2], strlen(row[2]), + C_STRING_WITH_LEN("50017"), + C_STRING_WITH_LEN("50003"), + C_STRING_WITH_LEN(" TRIGGER")); if (switch_db_collation(sql_file, db_name, ";", db_cl_name, row[5], &db_cl_altered)) DBUG_RETURN(TRUE); @@ -2929,6 +3141,13 @@ static int dump_triggers_for_table(char *table_name, char *db_name) /* Dump triggers. */ + if (! mysql_num_rows(show_triggers_rs)) + goto skip; + + if (opt_xml) + print_xml_tag(sql_file, "\t", "\n", "triggers", "name=", + table_name, NullS); + while ((row= mysql_fetch_row(show_triggers_rs))) { @@ -2961,6 +3180,13 @@ static int dump_triggers_for_table(char *table_name, char *db_name) } + if (opt_xml) + { + fputs("\t\n", sql_file); + check_io(sql_file); + } + +skip: mysql_free_result(show_triggers_rs); if (switch_character_set_results(mysql, default_charset)) @@ -3209,34 +3435,24 @@ static void dump_table(char *table, char *db) } else { - if (!opt_xml && opt_comments) - { - fprintf(md_result_file,"\n--\n-- Dumping data for table %s\n--\n", - result_table); - check_io(md_result_file); - } + print_comment(md_result_file, 0, + "\n--\n-- Dumping data for table %s\n--\n", + result_table); dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * FROM "); dynstr_append_checked(&query_string, result_table); if (where) { - if (!opt_xml && opt_comments) - { - fprintf(md_result_file, "-- WHERE: %s\n", where); - check_io(md_result_file); - } - + print_comment(md_result_file, 0, "-- WHERE: %s\n", where); + dynstr_append_checked(&query_string, " WHERE "); dynstr_append_checked(&query_string, where); } if (order_by) { - if (!opt_xml && opt_comments) - { - fprintf(md_result_file, "-- ORDER BY: %s\n", order_by); - check_io(md_result_file); - } + print_comment(md_result_file, 0, "-- ORDER BY: %s\n", order_by); + dynstr_append_checked(&query_string, " ORDER BY "); dynstr_append_checked(&query_string, order_by); } @@ -3432,7 +3648,7 @@ static void dump_table(char *table, char *db) { print_xml_tag(md_result_file, "\t\t", "", "field", "name=", field->name, NullS); - print_quoted_xml(md_result_file, row[i], length); + print_quoted_xml(md_result_file, row[i], length, 0); } fputs("\n", md_result_file); } @@ -3736,11 +3952,9 @@ static int dump_tablespaces(char* ts_where) first= 1; if (first) { - if (!opt_xml && opt_comments) - { - fprintf(md_result_file,"\n--\n-- Logfile group: %s\n--\n", row[0]); - check_io(md_result_file); - } + print_comment(md_result_file, 0, "\n--\n-- Logfile group: %s\n--\n", + row[0]); + fprintf(md_result_file, "\nCREATE"); } else @@ -3808,11 +4022,7 @@ static int dump_tablespaces(char* ts_where) first= 1; if (first) { - if (!opt_xml && opt_comments) - { - fprintf(md_result_file,"\n--\n-- Tablespace: %s\n--\n", row[0]); - check_io(md_result_file); - } + print_comment(md_result_file, 0, "\n--\n-- Tablespace: %s\n--\n", row[0]); fprintf(md_result_file, "\nCREATE"); } else @@ -4010,11 +4220,9 @@ static int init_dumping(char *database, int init_func(char*)) */ char quoted_database_buf[NAME_LEN*2+3]; char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted); - if (opt_comments) - { - fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", qdatabase); - check_io(md_result_file); - } + + print_comment(md_result_file, 0, + "\n--\n-- Current Database: %s\n--\n", qdatabase); /* Call the view or table specific function */ init_func(qdatabase); @@ -4079,6 +4287,8 @@ static int dump_all_tables_in_db(char *database) if (mysql_refresh(mysql, REFRESH_LOG)) DB_error(mysql, "when doing refresh"); /* We shall continue here, if --force was given */ + else + verbose_msg("-- dump_all_tables_in_db : logs flushed successfully!\n"); } while ((table= getTableName(0))) { @@ -4088,8 +4298,7 @@ static int dump_all_tables_in_db(char *database) dump_table(table,database); my_free(order_by); order_by= 0; - if (opt_dump_triggers && ! opt_xml && - mysql_get_server_version(mysql) >= 50009) + if (opt_dump_triggers && mysql_get_server_version(mysql) >= 50009) { if (dump_triggers_for_table(table, database)) { @@ -4100,14 +4309,12 @@ static int dump_all_tables_in_db(char *database) } } } - if (opt_events && !opt_xml && - mysql_get_server_version(mysql) >= 50106) + if (opt_events && mysql_get_server_version(mysql) >= 50106) { DBUG_PRINT("info", ("Dumping events for database %s", database)); dump_events_for_db(database); } - if (opt_routines && !opt_xml && - mysql_get_server_version(mysql) >= 50009) + if (opt_routines && mysql_get_server_version(mysql) >= 50009) { DBUG_PRINT("info", ("Dumping routines for database %s", database)); dump_routines_for_db(database); @@ -4179,6 +4386,8 @@ static my_bool dump_all_views_in_db(char *database) if (mysql_refresh(mysql, REFRESH_LOG)) DB_error(mysql, "when doing refresh"); /* We shall continue here, if --force was given */ + else + verbose_msg("-- dump_all_views_in_db : logs flushed successfully!\n"); } while ((table= getTableName(0))) { @@ -4317,6 +4526,8 @@ static int dump_selected_tables(char *db, char **table_names, int tables) DB_error(mysql, "when doing refresh"); } /* We shall countinue here, if --force was given */ + else + verbose_msg("-- dump_selected_tables : logs flushed successfully!\n"); } if (opt_xml) print_xml_tag(md_result_file, "", "\n", "database", "name=", db, NullS); @@ -4344,15 +4555,13 @@ static int dump_selected_tables(char *db, char **table_names, int tables) for (pos= dump_tables; pos < end; pos++) get_view_structure(*pos, db); } - if (opt_events && !opt_xml && - mysql_get_server_version(mysql) >= 50106) + if (opt_events && mysql_get_server_version(mysql) >= 50106) { DBUG_PRINT("info", ("Dumping events for database %s", db)); dump_events_for_db(db); } /* obtain dump of routines (procs/functions) */ - if (opt_routines && !opt_xml && - mysql_get_server_version(mysql) >= 50009) + if (opt_routines && mysql_get_server_version(mysql) >= 50009) { DBUG_PRINT("info", ("Dumping routines for database %s", db)); dump_routines_for_db(db); @@ -4387,10 +4596,9 @@ static int do_show_master_status(MYSQL *mysql_con) if (row && row[0] && row[1]) { /* SHOW MASTER STATUS reports file and position */ - if (opt_comments) - fprintf(md_result_file, - "\n--\n-- Position to start replication or point-in-time " - "recovery from\n--\n\n"); + print_comment(md_result_file, 0, + "\n--\n-- Position to start replication or point-in-time " + "recovery from\n--\n\n"); fprintf(md_result_file, "%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", comment_prefix, row[0], row[1]); @@ -4599,6 +4807,7 @@ static int purge_bin_logs_to(MYSQL *mysql_con, char* log_name) static int start_transaction(MYSQL *mysql_con) { + verbose_msg("-- Starting transaction...\n"); /* We use BEGIN for old servers. --single-transaction --master-data will fail on old servers, but that's ok as it was already silently broken (it didn't @@ -4976,12 +5185,10 @@ static my_bool get_view_structure(char *table, char* db) write_header(sql_file, db); } - if (!opt_xml && opt_comments) - { - fprintf(sql_file, "\n--\n-- Final view structure for view %s\n--\n\n", - result_table); - check_io(sql_file); - } + print_comment(sql_file, 0, + "\n--\n-- Final view structure for view %s\n--\n\n", + result_table); + /* Table might not exist if this view was dumped with --tab. */ fprintf(sql_file, "/*!50001 DROP TABLE IF EXISTS %s*/;\n", opt_quoted_table); if (opt_drop) @@ -5178,6 +5385,12 @@ int main(int argc, char **argv) exit(exit_code); } + /* + Disable comments in xml mode if 'comments' option is not explicitly used. + */ + if (opt_xml && !opt_comments_used) + opt_comments= 0; + if (log_error_file) { if(!(stderror_file= freopen(log_error_file, "a+", stderr))) @@ -5198,24 +5411,39 @@ int main(int argc, char **argv) if (opt_slave_data && do_stop_slave_sql(mysql)) goto err; - if ((opt_lock_all_tables || opt_master_data) && + if ((opt_lock_all_tables || opt_master_data || + (opt_single_transaction && flush_logs)) && do_flush_tables_read_lock(mysql)) goto err; - if (opt_single_transaction && start_transaction(mysql)) - goto err; - if (opt_delete_master_logs) + + /* + Flush logs before starting transaction since + this causes implicit commit starting mysql-5.5. + */ + if (opt_lock_all_tables || opt_master_data || + (opt_single_transaction && flush_logs) || + opt_delete_master_logs) { - if (mysql_refresh(mysql, REFRESH_LOG) || - get_bin_log_name(mysql, bin_log_name, sizeof(bin_log_name))) - goto err; + if (flush_logs || opt_delete_master_logs) + { + if (mysql_refresh(mysql, REFRESH_LOG)) + goto err; + verbose_msg("-- main : logs flushed successfully!\n"); + } + + /* Not anymore! That would not be sensible. */ flush_logs= 0; } - if (opt_lock_all_tables || opt_master_data) + + if (opt_delete_master_logs) { - if (flush_logs && mysql_refresh(mysql, REFRESH_LOG)) + if (get_bin_log_name(mysql, bin_log_name, sizeof(bin_log_name))) goto err; - flush_logs= 0; /* not anymore; that would not be sensible */ } + + if (opt_single_transaction && start_transaction(mysql)) + goto err; + /* Add 'STOP SLAVE to beginning of dump */ if (opt_slave_apply && add_stop_slave()) goto err; diff --git a/cmd-line-utils/libedit/chartype.h b/cmd-line-utils/libedit/chartype.h index 678d13683be..40012afb47d 100644 --- a/cmd-line-utils/libedit/chartype.h +++ b/cmd-line-utils/libedit/chartype.h @@ -45,11 +45,11 @@ * seems to actually advertise this properly, despite Unicode 3.1 having * been around since 2001... */ -/* XXXMYSQL : Added FreeBSD to bypass this check. - TODO : Verify if FreeBSD stores ISO 10646 in wchar_t. */ +/* XXXMYSQL : Added FreeBSD & AIX to bypass this check. + TODO : Verify if FreeBSD & AIX stores ISO 10646 in wchar_t. */ #if !defined(__NetBSD__) && !defined(__sun) \ && !(defined(__APPLE__) && defined(__MACH__)) \ - && !defined(__FreeBSD__) + && !defined(__FreeBSD__) && !defined(_AIX) #ifndef __STDC_ISO_10646__ /* In many places it is assumed that the first 127 code points are ASCII * compatible, so ensure wchar_t indeed does ISO 10646 and not some other diff --git a/cmd-line-utils/libedit/eln.c b/cmd-line-utils/libedit/eln.c index 4b9f16c38f3..f996367115a 100644 --- a/cmd-line-utils/libedit/eln.c +++ b/cmd-line-utils/libedit/eln.c @@ -200,7 +200,7 @@ el_set(EditLine *el, int op, ...) ret = -1; goto out; } - // XXX: The two strdup's leak + /* XXX: The two strdups leak. */ ret = map_addfunc(el, Strdup(wargv[0]), Strdup(wargv[1]), func); ct_free_argv(wargv); diff --git a/cmd-line-utils/libedit/readline.c b/cmd-line-utils/libedit/readline.c index eaf26d4c497..a2a92edc1b4 100644 --- a/cmd-line-utils/libedit/readline.c +++ b/cmd-line-utils/libedit/readline.c @@ -1978,7 +1978,7 @@ rl_callback_read_char() } else wbuf = NULL; (*(void (*)(const char *))rl_linefunc)(wbuf); - //el_set(e, EL_UNBUFFERED, 1); + /*el_set(e, EL_UNBUFFERED, 1);*/ } } diff --git a/include/m_ctype.h b/include/m_ctype.h index 140233bfa0e..158ec07fc73 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -66,6 +66,8 @@ typedef struct unicase_info_st extern MY_UNICASE_INFO *my_unicase_default[256]; extern MY_UNICASE_INFO *my_unicase_turkish[256]; +extern MY_UNICASE_INFO *my_unicase_mysql500[256]; + typedef struct uni_ctype_st { @@ -337,6 +339,7 @@ extern CHARSET_INFO my_charset_tis620_bin; extern CHARSET_INFO my_charset_ucs2_general_ci; extern CHARSET_INFO my_charset_ucs2_bin; extern CHARSET_INFO my_charset_ucs2_unicode_ci; +extern CHARSET_INFO my_charset_ucs2_general_mysql500_ci; extern CHARSET_INFO my_charset_ujis_japanese_ci; extern CHARSET_INFO my_charset_ujis_bin; extern CHARSET_INFO my_charset_utf16_bin; @@ -349,6 +352,7 @@ extern CHARSET_INFO my_charset_utf32_unicode_ci; extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_utf8_general_ci; extern CHARSET_INFO my_charset_utf8_unicode_ci; extern CHARSET_INFO my_charset_utf8_bin; +extern CHARSET_INFO my_charset_utf8_general_mysql500_ci; extern CHARSET_INFO my_charset_utf8mb4_bin; extern CHARSET_INFO my_charset_utf8mb4_general_ci; extern CHARSET_INFO my_charset_utf8mb4_unicode_ci; diff --git a/include/my_global.h b/include/my_global.h index 924c83cd951..11ff377c706 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -1364,11 +1364,31 @@ do { doubleget_union _tmp; \ #ifndef HAVE_DLERROR #ifdef _WIN32 +#define DLERROR_GENERATE(errmsg, error_number) \ + char win_errormsg[2048]; \ + if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, \ + 0, error_number, 0, win_errormsg, 2048, NULL)) \ + { \ + char *ptr; \ + for (ptr= &win_errormsg[0] + strlen(win_errormsg) - 1; \ + ptr >= &win_errormsg[0] && strchr("\r\n\t\0x20", *ptr); \ + ptr--) \ + *ptr= 0; \ + errmsg= win_errormsg; \ + } \ + else \ + errmsg= "" #define dlerror() "" -#else +#define dlopen_errno GetLastError() +#else /* _WIN32 */ #define dlerror() "No support for dynamic loading (static build?)" -#endif -#endif +#define DLERROR_GENERATE(errmsg, error_number) errmsg= dlerror() +#define dlopen_errno errno +#endif /* _WIN32 */ +#else /* HAVE_DLERROR */ +#define DLERROR_GENERATE(errmsg, error_number) errmsg= dlerror() +#define dlopen_errno errno +#endif /* HAVE_DLERROR */ /* diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt index 42125cffb7b..9aa338e1563 100644 --- a/libmysql/CMakeLists.txt +++ b/libmysql/CMakeLists.txt @@ -25,6 +25,8 @@ INCLUDE_DIRECTORIES( ADD_DEFINITIONS(${SSL_DEFINES}) SET(CLIENT_API_FUNCTIONS +get_tty_password +handle_options load_defaults mysql_thread_end mysql_thread_init diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index f528f1c473e..b3623402065 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -24,6 +24,4 @@ sys_vars.wait_timeout_func # Bug#11750645 2010-04-26 alik wai sys_vars.ndb_log_update_as_write_basic sys_vars.have_ndbcluster_basic sys_vars.ndb_log_updated_only_basic -sys_vars.query_cache_size_basic_64 # Bug#11748572 - 36747: ALLOCATING A LARGE QUERY CACHE IS NOT DETERMINISTIC -sys_vars.query_cache_size_basic_32 # Bug#11748572 - 36747: ALLOCATING A LARGE QUERY CACHE IS NOT DETERMINISTIC sys_vars.rpl_init_slave_func # Bug#12535301 2011-05-09 andrei sys_vars.rpl_init_slave_func mismatches in daily-5.5 diff --git a/mysql-test/extra/rpl_tests/rpl_extra_col_master.test b/mysql-test/extra/rpl_tests/rpl_extra_col_master.test index 513bc949c5d..235eb858d34 100644 --- a/mysql-test/extra/rpl_tests/rpl_extra_col_master.test +++ b/mysql-test/extra/rpl_tests/rpl_extra_col_master.test @@ -59,6 +59,8 @@ #VARCHAR(M) # +--let $_saved_conn= $CURRENT_CONNECTION + let $binformat = `SHOW VARIABLES LIKE '%binlog_format%'`; --echo --echo *********************************************************** @@ -1017,3 +1019,5 @@ SELECT c1,hex(c4),c5 FROM t5 ORDER BY c1; connection master; DROP TABLE t5; sync_slave_with_master; + +--connection $_saved_conn diff --git a/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test b/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test index 42250764b54..5aa1d75c516 100644 --- a/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test +++ b/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test @@ -177,3 +177,36 @@ UNLOCK TABLES; --connection master DROP TABLE t1; sync_slave_with_master; + +# +# bug#3593869-64035 uninitialized event_coordinates instance crashes server +# Testing how out of valid range position value is handled with an error. +# + +--connection master +RESET MASTER; +let $master_pos= query_get_value(SHOW MASTER STATUS, Position, 1); +let $master_pos= `SELECT $master_pos + 1`; + +--connection slave +--source include/stop_slave.inc +--replace_regex /[0-9]+/MASTER_POS/ +eval CHANGE MASTER TO master_log_pos=$master_pos; + +START SLAVE; +# ER_MASTER_FATAL_ERROR_READING_BINLOG 1236 +--let $slave_param=Last_IO_Errno +--let $slave_param_value=1236 +--source include/wait_for_slave_param.inc + +--let $slave_field_result_replace= / at [0-9]*/ at XXX/ +--let $status_items= Last_IO_Errno, Last_IO_Error +--source include/show_slave_status.inc + +--source include/stop_slave.inc +RESET SLAVE; + +--connection master +RESET MASTER; + +# Slave is stopped by bug#3593869-64035 tests. diff --git a/mysql-test/include/have_example_plugin.inc b/mysql-test/include/have_example_plugin.inc index 8920399555d..88f4e212102 100644 --- a/mysql-test/include/have_example_plugin.inc +++ b/mysql-test/include/have_example_plugin.inc @@ -15,7 +15,7 @@ if (!$EXAMPLE_PLUGIN) { # # Check if --plugin-dir was setup for exampledb # -if (`SELECT CONCAT('--plugin-dir=', @@plugin_dir) != '$EXAMPLE_PLUGIN_OPT'`) { +if (`SELECT CONCAT('--plugin-dir=', REPLACE(@@plugin_dir, '\\\\', '/')) != '$EXAMPLE_PLUGIN_OPT/'`) { --skip Example plugin requires that --plugin-dir is set to the example plugin dir (either the .opt file does not contain \$EXAMPLE_PLUGIN_OPT or another plugin is in use) } enable_query_log; diff --git a/mysql-test/include/have_semisync_plugin.inc b/mysql-test/include/have_semisync_plugin.inc index 95899f559aa..1cd3b30be1c 100644 --- a/mysql-test/include/have_semisync_plugin.inc +++ b/mysql-test/include/have_semisync_plugin.inc @@ -16,6 +16,6 @@ if (!$SEMISYNC_MASTER_PLUGIN) # # Check if --plugin-dir was setup for semisync # -if (`SELECT CONCAT('--plugin-dir=', @@plugin_dir) != '$SEMISYNC_PLUGIN_OPT'`) { +if (`SELECT CONCAT('--plugin-dir=', REPLACE(@@plugin_dir, '\\\\', '/')) != '$SEMISYNC_PLUGIN_OPT/'`) { --skip SEMISYNC plugin requires that --plugin-dir is set to the semisync plugin dir (either the .opt file does not contain \$SEMISYNC_PLUGIN_OPT or another plugin is in use) } diff --git a/mysql-test/include/have_simple_parser.inc b/mysql-test/include/have_simple_parser.inc index d077916c5e7..0cedad27a77 100644 --- a/mysql-test/include/have_simple_parser.inc +++ b/mysql-test/include/have_simple_parser.inc @@ -15,6 +15,6 @@ if (!$SIMPLE_PARSER) { # # Check if --plugin-dir was setup for simple parser # -if (`SELECT CONCAT('--plugin-dir=', @@plugin_dir) != '$SIMPLE_PARSER_OPT'`) { +if (`SELECT CONCAT('--plugin-dir=', REPLACE(@@plugin_dir, '\\\\', '/')) != '$SIMPLE_PARSER_OPT/'`) { --skip simple parser requires that --plugin-dir is set to the udf plugin dir (either the .opt file does not contain \$UDF_EXAMPLE_LIB_OPT or another plugin is in use) } diff --git a/mysql-test/include/have_udf.inc b/mysql-test/include/have_udf.inc index 5c404b03729..993b9e13fdb 100644 --- a/mysql-test/include/have_udf.inc +++ b/mysql-test/include/have_udf.inc @@ -15,6 +15,6 @@ if (!$UDF_EXAMPLE_LIB) { # # Check if --plugin-dir was setup for udf # -if (`SELECT CONCAT('--plugin-dir=', @@plugin_dir) != '$UDF_EXAMPLE_LIB_OPT'`) { +if (`SELECT CONCAT('--plugin-dir=', REPLACE(@@plugin_dir, '\\\\', '/')) != '$UDF_EXAMPLE_LIB_OPT/'`) { --skip UDF requires that --plugin-dir is set to the udf plugin dir (either the .opt file does not contain \$UDF_EXAMPLE_LIB_OPT or another plugin is in use) } diff --git a/mysql-test/include/libdaemon_example.ini b/mysql-test/include/libdaemon_example.ini new file mode 100644 index 00000000000..7e7df5bd2a2 --- /dev/null +++ b/mysql-test/include/libdaemon_example.ini @@ -0,0 +1,9 @@ +# +# Plugin configuration file. Place the following on a separate line: +# +# library binary file name (without .so or .dll) +# component_name +# [component_name] - additional components in plugin +# +liblibdaemon_example +daemon_example diff --git a/mysql-test/include/show_slave_status.inc b/mysql-test/include/show_slave_status.inc index 67b1c987954..52ec550ce60 100644 --- a/mysql-test/include/show_slave_status.inc +++ b/mysql-test/include/show_slave_status.inc @@ -55,6 +55,18 @@ # comma-separated list. Example: # # --let $status_items= Master_Log_File, Relay_Master_Log_File +# +# $slave_field_result_replace +# If set, one or more regex patterns for replacing variable +# text in the error message. Syntax as --replace-regex +# +# $slave_sql_mode +# If set, change the slave sql mode during this macro, reverting +# to the previous on exit. Default sql_mode is NO_BACKSLASH_ESCAPES +# to allow replace '\' by '/' making paths OS independent. Example: +# +# --let $slave_sql_mode= NO_BACKSLASH_ESCAPES +# --let $_show_slave_status_items=$status_items @@ -64,12 +76,30 @@ if (!$status_items) } +--let $_slave_sql_mode= NO_BACKSLASH_ESCAPES +if ($slave_sql_mode) +{ + --let $_slave_sql_mode= $slave_sql_mode +} +--let $_previous_slave_sql_mode = `SELECT @@sql_mode` +--disable_query_log +eval SET sql_mode= '$_slave_sql_mode'; +--enable_query_log + + while ($_show_slave_status_items) { --let $_show_slave_status_name= `SELECT SUBSTRING_INDEX('$_show_slave_status_items', ',', 1)` --let $_show_slave_status_items= `SELECT LTRIM(SUBSTRING('$_show_slave_status_items', LENGTH('$_show_slave_status_name') + 2))` --let $_show_slave_status_value= query_get_value(SHOW SLAVE STATUS, $_show_slave_status_name, 1) + --let $_slave_field_result_replace= /[\\]/\// $slave_field_result_replace + --replace_regex $_slave_field_result_replace --let $_show_slave_status_value= `SELECT REPLACE("$_show_slave_status_value", '$MYSQL_TEST_DIR', 'MYSQL_TEST_DIR')` --echo $_show_slave_status_name = '$_show_slave_status_value' } + + +--disable_query_log +eval SET sql_mode= '$_previous_slave_sql_mode'; +--enable_query_log diff --git a/mysql-test/include/wait_for_ndb_to_binlog.inc b/mysql-test/include/wait_for_ndb_to_binlog.inc index 77da6d62154..c1f94802724 100644 --- a/mysql-test/include/wait_for_ndb_to_binlog.inc +++ b/mysql-test/include/wait_for_ndb_to_binlog.inc @@ -1,13 +1,11 @@ # ==== Purpose ==== # -# Several test primitives from mysql-test/extra/rpl_tests -# shared for test cases for MyISAM, InnoDB, NDB and other -# engines. But for NDB all events will be added by NDB -# injector and now there are no way to detect the state of -# NDB injector therefore this primitive waits 5 sec -# if engine type is NDB. -# In future that should be fixed by waiting of proper -# state of NDB injector. +# Several test primitives from mysql-test/extra/rpl_tests +# are shared for test cases for MyISAM, InnoDB, NDB and +# other engines. +# For NDB engine all events will be added by NDB injector +# so tests only can continue after injector is ready, +# this test waits for proper injector thread state. # # ==== Usage ==== # @@ -17,25 +15,12 @@ # ==== Parameters ===== # # $engine_type -# Type of engine. If type is NDB then it waits $wait_time sec -# -# $wait_time -# Test will wait $wait_time seconds - -let $_wait_time= 5; - -if (!$wait_time) { - let $_wait_time= $wait_time; -} +# Type of engine. If type is NDB then it waits for injector +# thread proper state. if (`SELECT UPPER(LEFT('$engine_type',3)) = 'NDB'`) { - while (!$_wait_time) { - let $_wait_time_internal= 10; - while (!$_wait_time_internal) { - sleep 0.1; - dec $_wait_time_internal; - } - dec $_wait_time; - } + let $show_statement= SHOW PROCESSLIST; + let $field= State; + let $condition= = 'Waiting for event from ndbcluster'; + source include/wait_show_condition.inc; } - diff --git a/mysql-test/include/wait_for_slave_io_error.inc b/mysql-test/include/wait_for_slave_io_error.inc index e1609113b8f..4177bf4b858 100644 --- a/mysql-test/include/wait_for_slave_io_error.inc +++ b/mysql-test/include/wait_for_slave_io_error.inc @@ -33,6 +33,10 @@ # (e.g., temporary connection error) and does not cause the slave # IO thread to stop. # +# $slave_io_error_replace +# If set, one or more regex patterns for replacing variable +# text in the error message. Syntax as --replace-regex +# # $slave_timeout # See include/wait_for_slave_param.inc # @@ -72,6 +76,7 @@ if ($show_slave_io_error) { --let $_wait_for_slave_io_error_old_status_items= $status_items --let $status_items= Last_IO_Error + --let $slave_field_result_replace= $slave_io_error_replace --source include/show_slave_status.inc --let $status_items= $_wait_for_slave_io_error_old_status_items } diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result index 47a45efa5fd..652c5b96147 100644 --- a/mysql-test/r/bigint.result +++ b/mysql-test/r/bigint.result @@ -438,3 +438,67 @@ Level Code Message Note 1003 select 1 AS `1` from `test`.`t1` where ((`test`.`t1`.`a` = 0) and ('0' = `test`.`t1`.`b`)) DROP TABLE t1; # End of 5.1 tests +# +# Bug#13463415 63502: INCORRECT RESULTS OF BIGINT AND DECIMAL COMPARISON +# +CREATE TABLE t_bigint(id BIGINT); +INSERT INTO t_bigint VALUES (1), (2); +SELECT id, id >= 1.1 FROM t_bigint; +id id >= 1.1 +1 0 +2 1 +SELECT id, 1.1 <= id FROM t_bigint; +id 1.1 <= id +1 0 +2 1 +SELECT id, id = 1.1 FROM t_bigint; +id id = 1.1 +1 0 +2 0 +SELECT id, 1.1 = id FROM t_bigint; +id 1.1 = id +1 0 +2 0 +SELECT * from t_bigint WHERE id = 1.1; +id +SELECT * from t_bigint WHERE id = 1.1e0; +id +SELECT * from t_bigint WHERE id = '1.1'; +id +SELECT * from t_bigint WHERE id = '1.1e0'; +id +SELECT * from t_bigint WHERE id IN (1.1, 2.2); +id +SELECT * from t_bigint WHERE id IN (1.1e0, 2.2e0); +id +SELECT * from t_bigint WHERE id IN ('1.1', '2.2'); +id +SELECT * from t_bigint WHERE id IN ('1.1e0', '2.2e0'); +id +SELECT * from t_bigint WHERE id BETWEEN 1.1 AND 1.9; +id +SELECT * from t_bigint WHERE id BETWEEN 1.1e0 AND 1.9e0; +id +SELECT * from t_bigint WHERE id BETWEEN '1.1' AND '1.9'; +id +SELECT * from t_bigint WHERE id BETWEEN '1.1e0' AND '1.9e0'; +id +DROP TABLE t_bigint; +# +# Bug#11758543 50756: BIGINT '100' MATCHES 1.001E2 +# +CREATE TABLE t1 (a BIGINT); +INSERT INTO t1 VALUES (1); +SELECT * FROM t1 WHERE coalesce(a) BETWEEN 0 and 0.9; +a +SELECT * FROM t1 WHERE coalesce(a)=0.9; +a +SELECT * FROM t1 WHERE coalesce(a) in (0.8,0.9); +a +SELECT * FROM t1 WHERE a BETWEEN 0 AND 0.9; +a +SELECT * FROM t1 WHERE a=0.9; +a +SELECT * FROM t1 WHERE a IN (0.8,0.9); +a +DROP TABLE t1; diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 8237f174514..fc306e499d3 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1928,6 +1928,30 @@ D120 SELECT HEX(INSERT(_utf8 0xD18FD18E, 2, 1, 0x20)); HEX(INSERT(_utf8 0xD18FD18E, 2, 1, 0x20)) D120D18E +# +# Bug#11752408 - 43593: DUMP/BACKUP/RESTORE/UPGRADE TOOLS FAILS BECAUSE OF UTF8_GENERAL_CI +# +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_general_mysql500_ci); +INSERT INTO t1 VALUES ('a'),('r'),('s'),(_latin1 0xDF),(_latin1 0xF7),('t'),('z'); +SELECT * FROM t1 ORDER BY a; +a +a +r +s +t +z +ß +÷ +SELECT a, COUNT(*) FROM t1 GROUP BY a; +a COUNT(*) +a 1 +r 1 +s 1 +t 1 +z 1 +ß 1 +÷ 1 +DROP TABLE t1; End of 5.1 tests Start of 5.4 tests SET NAMES utf8mb3; diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result index 0b6117581f3..279a18e344e 100644 --- a/mysql-test/r/func_in.result +++ b/mysql-test/r/func_in.result @@ -469,6 +469,8 @@ SELECT HEX(a) FROM t2 WHERE a IN HEX(a) 7FFFFFFFFFFFFFFE 7FFFFFFFFFFFFFFF +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'abc' CREATE TABLE t3 (a BIGINT UNSIGNED); INSERT INTO t3 VALUES (9223372036854775551); SELECT HEX(a) FROM t3 WHERE a IN (9223372036854775807, 42); diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index abf76a533b3..adaa2df3a61 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -2826,5 +2826,41 @@ SELECT ((0xf3) * (rpad(1.0,2048,1)) << (0xcc)); ((0xf3) * (rpad(1.0,2048,1)) << (0xcc)) 0 # +# Bug#13359121 LARGE NUMBERS, /STRINGS/DTOA.C:662: +# BALLOC: ASSERTION `K <= 15' FAILED. +# Bug#12985021 SIMPLE QUERY WITH DECIMAL NUMBERS TAKE AN +# EXTRAORDINARY LONG TIME TO EXECUTE +SELECT @tmp_max:= @@global.max_allowed_packet; +@tmp_max:= @@global.max_allowed_packet +1048576 +SET @@global.max_allowed_packet=1024*1024*1024; +SELECT @@global.max_allowed_packet; +@@global.max_allowed_packet +1073741824 +do +format(rpad('111111111.1', +1111111, +'999999999999999999999999999999999999999999'),0,'be_BY') +; +DO +round( +concat( ( +coalesce( ( +linefromwkb('2147483648', +-b'1111111111111111111111111111111111111111111')), +( convert('[.DC2.]',decimal(30,30)) ), +bit_count('') +) ), +( lpad( ( elt('01','}:K5')), +sha1('P'), +( ( select '-9223372036854775808.1' > all (select ''))) +) +) +) +); +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: '[.DC2.]' +SET @@global.max_allowed_packet:= @tmp_max; +# # End of 5.5 tests # diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index bad467b3255..7f3ecc0d602 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -1402,8 +1402,220 @@ NULL # Bug#12584302 AFTER FIX FOR #12403504: ASSERTION FAILED: DELSUM+(INT) Y/4-TEMP > 0, # DO WEEK((DATE_ADD((CAST(0 AS DATE)), INTERVAL 1 YEAR_MONTH)), 5); +# +# BUG#13458237 INCONSISTENT HANDLING OF INVALIDE DATES WITH ZERO DAY +# SIMILAR TO '2009-10-00' +# +SELECT +DATE('20091000'), +STR_TO_DATE('200910','%Y%m'), +LAST_DAY('2009-10-00'), +LAST_DAY(DATE('2009-10-00')), +LAST_DAY(DATE'2009-10-00'), +LAST_DAY(STR_TO_DATE('200910','%Y%m')), +WEEK('2009-10-00'), +WEEK(DATE('2009-10-00')), +WEEK(DATE'2009-10-00'), +WEEK(STR_TO_DATE('200910','%Y%m')), +WEEKOFYEAR('2009-10-00'), +WEEKOFYEAR(DATE('2009-10-00')), +WEEKOFYEAR(DATE'2009-10-00'), +WEEKOFYEAR(STR_TO_DATE('200910','%Y%m')), +DAYOFYEAR('2009-10-00'), +DAYOFYEAR(DATE('2009-10-00')), +DAYOFYEAR(DATE'2009-10-00'), +DAYOFYEAR(STR_TO_DATE('200910','%Y%m')), +WEEKDAY('2009-10-00'), +WEEKDAY(DATE('2009-10-00')), +WEEKDAY(DATE'2009-10-00'), +WEEKDAY(STR_TO_DATE('200910','%Y%m')), +TO_DAYs('2009-10-00'), +TO_DAYs(DATE('2009-10-00')), +TO_DAYs(DATE'2009-10-00'), +TO_DAYs(STR_TO_DATE('200910','%Y%m')); +DATE('20091000') 2009-10-00 +STR_TO_DATE('200910','%Y%m') 2009-10-00 +LAST_DAY('2009-10-00') NULL +LAST_DAY(DATE('2009-10-00')) 2009-10-31 +LAST_DAY(DATE'2009-10-00') NULL +LAST_DAY(STR_TO_DATE('200910','%Y%m')) 2009-10-31 +WEEK('2009-10-00') NULL +WEEK(DATE('2009-10-00')) 39 +WEEK(DATE'2009-10-00') NULL +WEEK(STR_TO_DATE('200910','%Y%m')) NULL +WEEKOFYEAR('2009-10-00') NULL +WEEKOFYEAR(DATE('2009-10-00')) 40 +WEEKOFYEAR(DATE'2009-10-00') NULL +WEEKOFYEAR(STR_TO_DATE('200910','%Y%m')) NULL +DAYOFYEAR('2009-10-00') NULL +DAYOFYEAR(DATE('2009-10-00')) 273 +DAYOFYEAR(DATE'2009-10-00') NULL +DAYOFYEAR(STR_TO_DATE('200910','%Y%m')) NULL +WEEKDAY('2009-10-00') NULL +WEEKDAY(DATE('2009-10-00')) 2 +WEEKDAY(DATE'2009-10-00') NULL +WEEKDAY(STR_TO_DATE('200910','%Y%m')) NULL +TO_DAYs('2009-10-00') NULL +TO_DAYs(DATE('2009-10-00')) 734045 +TO_DAYs(DATE'2009-10-00') NULL +TO_DAYs(STR_TO_DATE('200910','%Y%m')) NULL +Warnings: +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1411 +Message Incorrect datetime value: '200910' for function str_to_date +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1411 +Message Incorrect datetime value: '200910' for function str_to_date +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1411 +Message Incorrect datetime value: '200910' for function str_to_date +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1411 +Message Incorrect datetime value: '200910' for function str_to_date +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '2009-10-00' +Level Warning +Code 1411 +Message Incorrect datetime value: '200910' for function str_to_date +SELECT +DATE('00000100'), +STR_TO_DATE('000001','%Y%m'), +LAST_DAY('0000-01-00'), +LAST_DAY(DATE('0000-01-00')), +LAST_DAY(DATE'0000-01-00'), +LAST_DAY(STR_TO_DATE('000001','%Y%m')), +WEEK('0000-01-00'), +WEEK(DATE('0000-01-00')), +WEEK(DATE'0000-01-00'), +WEEK(STR_TO_DATE('000001','%Y%m')), +WEEKOFYEAR('0000-01-00'), +WEEKOFYEAR(DATE('0000-01-00')), +WEEKOFYEAR(DATE'0000-01-00'), +WEEKOFYEAR(STR_TO_DATE('000001','%Y%m')), +DAYOFYEAR('0000-01-00'), +DAYOFYEAR(DATE('0000-01-00')), +DAYOFYEAR(DATE'0000-01-00'), +DAYOFYEAR(STR_TO_DATE('000001','%Y%m')), +WEEKDAY('0000-01-00'), +WEEKDAY(DATE('0000-01-00')), +WEEKDAY(DATE'0000-01-00'), +WEEKDAY(STR_TO_DATE('000001','%Y%m')), +TO_DAYs('0000-01-00'), +TO_DAYs(DATE('0000-01-00')), +TO_DAYs(DATE'0000-01-00'), +TO_DAYs(STR_TO_DATE('000001','%Y%m')); +DATE('00000100') 0000-01-00 +STR_TO_DATE('000001','%Y%m') 0000-01-00 +LAST_DAY('0000-01-00') NULL +LAST_DAY(DATE('0000-01-00')) 0000-01-31 +LAST_DAY(DATE'0000-01-00') NULL +LAST_DAY(STR_TO_DATE('000001','%Y%m')) 0000-01-31 +WEEK('0000-01-00') NULL +WEEK(DATE('0000-01-00')) 52 +WEEK(DATE'0000-01-00') NULL +WEEK(STR_TO_DATE('000001','%Y%m')) NULL +WEEKOFYEAR('0000-01-00') NULL +WEEKOFYEAR(DATE('0000-01-00')) 52 +WEEKOFYEAR(DATE'0000-01-00') NULL +WEEKOFYEAR(STR_TO_DATE('000001','%Y%m')) NULL +DAYOFYEAR('0000-01-00') NULL +DAYOFYEAR(DATE('0000-01-00')) 0 +DAYOFYEAR(DATE'0000-01-00') NULL +DAYOFYEAR(STR_TO_DATE('000001','%Y%m')) NULL +WEEKDAY('0000-01-00') NULL +WEEKDAY(DATE('0000-01-00')) 5 +WEEKDAY(DATE'0000-01-00') NULL +WEEKDAY(STR_TO_DATE('000001','%Y%m')) NULL +TO_DAYs('0000-01-00') NULL +TO_DAYs(DATE('0000-01-00')) 0 +TO_DAYs(DATE'0000-01-00') NULL +TO_DAYs(STR_TO_DATE('000001','%Y%m')) NULL Warnings: -Warning 1292 Incorrect datetime value: '0' +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1411 +Message Incorrect datetime value: '000001' for function str_to_date +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1411 +Message Incorrect datetime value: '000001' for function str_to_date +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1411 +Message Incorrect datetime value: '000001' for function str_to_date +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1411 +Message Incorrect datetime value: '000001' for function str_to_date +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1292 +Message Incorrect datetime value: '0000-01-00' +Level Warning +Code 1411 +Message Incorrect datetime value: '000001' for function str_to_date End of 5.1 tests # # Bug#57039: constant subtime expression returns incorrect result. @@ -1433,6 +1645,21 @@ NULL 1 NULL SET storage_engine=NULL; ERROR 42000: Variable 'storage_engine' can't be set to the value of 'NULL' # +# BUG#13354387 - CRASH IN IN MY_DECIMAL::OPERATOR FOR VIEW AND FUNCTION UNIX_TIMESTAMP +# Part1 (5.5) +SET time_zone='+03:00'; +CREATE TABLE t1 (a DATETIME NOT NULL); +INSERT INTO t1 VALUES ('2009-09-20 07:32:39.06'); +INSERT INTO t1 VALUES ('0000-00-00 00:00:00.00'); +CREATE VIEW v1 AS SELECT * FROM t1; +SELECT CAST(UNIX_TIMESTAMP(a) AS DECIMAL(25,3)) AS c1 FROM v1 ORDER BY 1; +c1 +0.000 +1253421159.000 +DROP VIEW v1; +DROP TABLE t1; +SET time_zone=DEFAULT; +# # Bug #59686 crash in String::copy() with time data type # SELECT min(timestampadd(month, 1>'', from_days('%Z'))); diff --git a/mysql-test/r/init_connect.result b/mysql-test/r/init_connect.result index f5ec0bdc932..0ff6c206422 100644 --- a/mysql-test/r/init_connect.result +++ b/mysql-test/r/init_connect.result @@ -20,6 +20,8 @@ hex(a) 616263 set GLOBAL init_connect="adsfsdfsdfs"; select @a; +ERROR 08S01: Aborted connection to db: 'test' user: 'user_1' host: 'localhost' (init_connect command failed) +select @a; Got one of the listed errors drop table t1; End of 4.1 tests diff --git a/mysql-test/r/mysql_plugin.result b/mysql-test/r/mysql_plugin.result index 93567e28c3d..636b039047e 100644 --- a/mysql-test/r/mysql_plugin.result +++ b/mysql-test/r/mysql_plugin.result @@ -23,12 +23,24 @@ wacky libdaemon_example.so wicky libdaemon_example.so wonky libdaemon_example.so # +# Ensure the plugin is loaded. +# +SELECT * FROM mysql.plugin WHERE dl like '%libdaemon%' ORDER BY name; +name dl +daemon_example libdaemon_example.so +# +# Ensure the plugin is replaced. +# +SELECT * FROM mysql.plugin WHERE dl like '%libdaemon%' ORDER BY name; +name dl +daemon_example liblibdaemon_example.so +# # Disable the plugin... # # # Ensure the plugin isn't loaded. # -SELECT * FROM mysql.plugin WHERE dl like 'libdaemon%' ORDER BY name; +SELECT * FROM mysql.plugin WHERE dl like '%libdaemon%' ORDER BY name; name dl # # Attempt to load non-existant plugin diff --git a/mysql-test/r/mysqld--help-notwin.result b/mysql-test/r/mysqld--help-notwin.result index a0a8d28c620..72182ccb375 100644 --- a/mysql-test/r/mysqld--help-notwin.result +++ b/mysql-test/r/mysqld--help-notwin.result @@ -674,6 +674,9 @@ The following options may be given as the first argument: replication. --sql-mode=name Syntax: sql-mode=mode[,mode[,mode...]]. See the manual for the complete list of valid sql modes + --stored-program-cache=# + The soft upper limit for number of cached stored routines + for one connection. -s, --symbolic-links Enable symbolic link support. --sync-binlog=# Synchronously flush binary log to disk after every #th @@ -939,6 +942,7 @@ slow-query-log FALSE sort-buffer-size 2097152 sporadic-binlog-dump-fail FALSE sql-mode +stored-program-cache 256 symbolic-links FALSE sync-binlog 0 sync-frm TRUE diff --git a/mysql-test/r/mysqld--help-win.result b/mysql-test/r/mysqld--help-win.result index 2ef52355f90..d7a06c5b23e 100644 --- a/mysql-test/r/mysqld--help-win.result +++ b/mysql-test/r/mysqld--help-win.result @@ -679,6 +679,9 @@ The following options may be given as the first argument: --sql-mode=name Syntax: sql-mode=mode[,mode[,mode...]]. See the manual for the complete list of valid sql modes --standalone Dummy option to start as a standalone program (NT). + --stored-program-cache=# + The soft upper limit for number of cached stored routines + for one connection. -s, --symbolic-links Enable symbolic link support. --sync-binlog=# Synchronously flush binary log to disk after every #th @@ -946,6 +949,7 @@ slow-start-timeout 15000 sort-buffer-size 2097152 sporadic-binlog-dump-fail FALSE sql-mode +stored-program-cache 256 symbolic-links FALSE sync-binlog 0 sync-frm TRUE diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 8f6add75fd3..0148949ef8f 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -4628,6 +4628,445 @@ ALTER DATABASE `test-database` CHARACTER SET utf8 COLLATE utf8_unicode_ci ; DROP DATABASE `test-database`; USE test; # +# BUG#11760384 : 52792: mysqldump in XML mode does not dump routines. +# +CREATE DATABASE BUG52792; +USE BUG52792; +CREATE TABLE t1 (c1 INT, c2 VARCHAR(20)); +CREATE TABLE t2 (c1 INT); +INSERT INTO t1 VALUES (1, 'aaa'), (2, 'bbb'), (3, 'ccc'); +INSERT INTO t2 VALUES (1),(2),(3); +# Stored Procedures. +CREATE PROCEDURE simpleproc1 (OUT param1 INT) +BEGIN +SELECT COUNT(*) INTO param1 FROM t1; +END// +CREATE PROCEDURE simpleproc2 (OUT param1 INT) +BEGIN +SELECT COUNT(*) INTO param1 FROM t2; +END// +# Events. +CREATE EVENT e1 ON SCHEDULE EVERY 1 SECOND DO DROP DATABASE BUG52792; +CREATE EVENT e2 ON SCHEDULE EVERY 1 SECOND DO DROP DATABASE BUG52792; +# Functions. +CREATE FUNCTION `hello1` (s CHAR(20)) +RETURNS CHAR(50) DETERMINISTIC +RETURN CONCAT('Hello, ' ,s ,'!'); +CREATE FUNCTION `hello2` (s CHAR(20)) +RETURNS CHAR(50) DETERMINISTIC +RETURN CONCAT(']]>, ' , s ,'!'); +# Triggers. +CREATE TRIGGER trig1 BEFORE INSERT ON t2 +FOR EACH ROW BEGIN +INSERT INTO t2 VALUES(1); +END; +| +CREATE TRIGGER trig2 AFTER INSERT ON t2 +FOR EACH ROW BEGIN +INSERT INTO t2 VALUES(1, ']]>'); +INSERT INTO t2 VALUES(2, ''); +INSERT INTO t2 VALUES(3, ' & \ " _'); +END; +| +# Views +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE VIEW v2 AS SELECT * FROM t2; + +# Dumping BUG52792 database in xml format. + +# Running 'replace_regex on timestamp' + + + + + + + + + + + 1 + aaa + + + 2 + bbb + + + 3 + ccc + + + + + + + + + 1 + + + 2 + + + 3 + + + + + + + +'); +INSERT INTO t2 VALUES(2, ''); +INSERT INTO t2 VALUES(3, ' & \ " _'); +END +]]> + + + + + + + + + + + + + + + + + + + + + + + + +, ' , s ,'!') +]]> + + + + + + + + + + + +# Dumping BUG52792 database in xml format with comments. + +# Running 'replace_regex on timestamp' + + + + + + + + + + + + + 1 + aaa + + + 2 + bbb + + + 3 + ccc + + + + + + + + + + + 1 + + + 2 + + + 3 + + + + + + + +'); +INSERT INTO t2 VALUES(2, ''); +INSERT INTO t2 VALUES(3, ' & \ " _'); +END +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + +, ' , s ,'!') +]]> + + + + + + + + + + + +# Test to check 'Insufficient privileges' error. + +GRANT ALL PRIVILEGES ON BUG52792.* TO user1; +# Running 'replace_regex on timestamp' + + + + + + + + + + + 1 + aaa + + + 2 + bbb + + + 3 + ccc + + + + + + + + + 1 + + + 2 + + + 3 + + + + + + + +'); +INSERT INTO t2 VALUES(2, ''); +INSERT INTO t2 VALUES(3, ' & \ " _'); +END +]]> + + + + + + + + + + + + + + + + + + + + + + +DROP USER user1; +DROP DATABASE BUG52792; +# UTF-8 +CREATE DATABASE BUG52792; +USE BUG52792; +SET NAMES utf8; +CREATE FUNCTION `straße` ( c1 CHAR(20)) +RETURNS CHAR(50) DETERMINISTIC +RETURN CONCAT(']]>, ', s, '!'); + + + + + +, ', s, '!') +]]> + + + + +DROP DATABASE BUG52792; +USE test; +# # End of 5.1 tests # # @@ -4662,3 +5101,107 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; DROP TABLE t1; +# +# Bug#12809202 61854: MYSQLDUMP --SINGLE-TRANSACTION --FLUSH-LOG BREAKS +# CONSISTENCY +# +DROP DATABASE IF EXISTS b12809202_db; +CREATE DATABASE b12809202_db; +CREATE TABLE b12809202_db.t1 (c1 INT); +CREATE TABLE b12809202_db.t2 (c1 INT); +INSERT INTO b12809202_db.t1 VALUES (1), (2), (3); +INSERT INTO b12809202_db.t2 VALUES (1), (2), (3); +# Starting mysqldump with --single-transaction & --flush-log options.. +# Note : In the following dump the transaction +# should start only after the logs are +# flushed, as 'flush logs' causes implicit +# commit starting 5.5. + +#### Dump starts here #### +-- Connecting to localhost... +-- main : logs flushed successfully! +-- Starting transaction... +-- Retrieving table structure for table t1... +-- Sending SELECT query... +-- Retrieving rows... +-- +-- Host: localhost Database: b12809202_db +-- ------------------------------------------------------ + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `t1` +-- + +DROP TABLE IF EXISTS `t1`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t1` ( + `c1` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `t1` +-- + +LOCK TABLES `t1` WRITE; +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +INSERT INTO `t1` VALUES (1),(2),(3); +-- Retrieving table structure for table t2... +-- Sending SELECT query... +-- Retrieving rows... +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `t2` +-- + +DROP TABLE IF EXISTS `t2`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t2` ( + `c1` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `t2` +-- + +LOCK TABLES `t2` WRITE; +/*!40000 ALTER TABLE `t2` DISABLE KEYS */; +INSERT INTO `t2` VALUES (1),(2),(3); +/*!40000 ALTER TABLE `t2` ENABLE KEYS */; +UNLOCK TABLES; +-- Disconnecting from localhost... +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed +#### Dump ends here #### +DROP TABLE b12809202_db.t1; +DROP TABLE b12809202_db.t2; +DROP DATABASE b12809202_db; +# +# Delete all existing binary logs. +# +RESET MASTER; diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index d8f1f45de0c..256e18a9679 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -1767,4 +1767,121 @@ id select_type table type possible_keys key key_len ref rows Extra SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk; pk i4 pk i4 DROP TABLE t1; +# +# BUG#13519696 - 62940: SELECT RESULTS VARY WITH VERSION AND +# WITH/WITHOUT INDEX RANGE SCAN +# +create table t1 (id int unsigned not null auto_increment primary key); +insert into t1 values (null); +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +create table t2 ( +id int unsigned not null auto_increment, +val decimal(5,3) not null, +primary key (id,val), +unique key (val,id), +unique key (id)); +insert into t2 select null,id*0.0009 from t1; +select count(val) from t2 ignore index (val) where val > 0.1155; +count(val) +128 +select count(val) from t2 force index (val) where val > 0.1155; +count(val) +128 +drop table t2, t1; +# +# BUG#13453382 - REGRESSION SINCE 5.1.39, RANGE OPTIMIZER WRONG +# RESULTS WITH DECIMAL CONVERSION +# +create table t1 (a int,b int,c int,primary key (a,c)); +insert into t1 values (1,1,2),(1,1,3),(1,1,4); +select convert(3, signed integer) > 2.9; +convert(3, signed integer) > 2.9 +1 +select * from t1 force index (primary) where a=1 and c>= 2.9; +a b c +1 1 3 +1 1 4 +select * from t1 ignore index (primary) where a=1 and c>= 2.9; +a b c +1 1 3 +1 1 4 +select * from t1 force index (primary) where a=1 and c> 2.9; +a b c +1 1 3 +1 1 4 +select * from t1 ignore index (primary) where a=1 and c> 2.9; +a b c +1 1 3 +1 1 4 +drop table t1; +# +# BUG#13463488 - 63437: CHAR & BETWEEN WITH INDEX RETURNS WRONG +# RESULT AFTER MYSQL 5.1. +# +CREATE TABLE t1( +F1 CHAR(5) NOT NULL, +F2 CHAR(5) NOT NULL, +F3 CHAR(5) NOT NULL, +PRIMARY KEY(F1), +INDEX IDX_F2(F2) +); +INSERT INTO t1 VALUES +('A','A','A'),('AA','AA','AA'),('AAA','AAA','AAA'), +('AAAA','AAAA','AAAA'),('AAAAA','AAAAA','AAAAA'); +SELECT * FROM t1 WHERE F1 = 'A '; +F1 F2 F3 +A A A +SELECT * FROM t1 IGNORE INDEX(PRIMARY) WHERE F1 = 'A '; +F1 F2 F3 +A A A +SELECT * FROM t1 WHERE F1 >= 'A '; +F1 F2 F3 +A A A +AA AA AA +AAA AAA AAA +AAAA AAAA AAAA +AAAAA AAAAA AAAAA +SELECT * FROM t1 WHERE F1 > 'A '; +F1 F2 F3 +AA AA AA +AAA AAA AAA +AAAA AAAA AAAA +AAAAA AAAAA AAAAA +SELECT * FROM t1 WHERE F1 BETWEEN 'A ' AND 'AAAAA'; +F1 F2 F3 +A A A +AA AA AA +AAA AAA AAA +AAAA AAAA AAAA +AAAAA AAAAA AAAAA +SELECT * FROM t1 WHERE F2 BETWEEN 'A ' AND 'AAAAA'; +F1 F2 F3 +A A A +AA AA AA +AAA AAA AAA +AAAA AAAA AAAA +AAAAA AAAAA AAAAA +SELECT * FROM t1 WHERE F3 BETWEEN 'A ' AND 'AAAAA'; +F1 F2 F3 +A A A +AA AA AA +AAA AAA AAA +AAAA AAAA AAAA +AAAAA AAAAA AAAAA +SELECT * FROM t1 IGNORE INDEX(PRIMARY) WHERE F1 BETWEEN 'A ' AND +'AAAAA'; +F1 F2 F3 +A A A +AA AA AA +AAA AAA AAA +AAAA AAAA AAAA +AAAAA AAAAA AAAAA +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 1644c764431..07c945db5e6 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -2772,20 +2772,23 @@ userid drop procedure bug8116| drop table t3| drop procedure if exists bug6857| -create procedure bug6857(counter int) +create procedure bug6857() begin declare t0, t1 int; declare plus bool default 0; -set t0 = current_time(); -while counter > 0 do -set counter = counter - 1; -end while; -set t1 = current_time(); +set t0 = unix_timestamp(); +select sleep(1.1); +set t1 = unix_timestamp(); if t1 > t0 then set plus = 1; end if; select plus; end| +call bug6857()| +sleep(1.1) +0 +plus +1 drop procedure bug6857| drop procedure if exists bug8757| create procedure bug8757() diff --git a/mysql-test/r/xa.result b/mysql-test/r/xa.result index 7b580abb19f..6db257eafd5 100644 --- a/mysql-test/r/xa.result +++ b/mysql-test/r/xa.result @@ -206,8 +206,8 @@ DROP TABLE t1; # FAILED # DROP TABLE IF EXISTS t1, t2; -CREATE TABLE t1 (a INT); -CREATE TABLE t2 (a INT); +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT) ENGINE=InnoDB; START TRANSACTION; INSERT INTO t1 VALUES (1); # Connection con2 @@ -217,12 +217,14 @@ INSERT INTO t2 SELECT a FROM t1; # Connection default # Waiting until INSERT ... is blocked DELETE FROM t1; -COMMIT; # Connection con2 # Reaping: INSERT INTO t2 SELECT a FROM t1 ERROR 40001: Deadlock found when trying to get lock; try restarting transaction XA COMMIT 'xid1'; ERROR XA102: XA_RBDEADLOCK: Transaction branch was rolled back: deadlock was detected +# Connection default +COMMIT; +# Connection con2 XA START 'xid1'; XA END 'xid1'; XA PREPARE 'xid1'; diff --git a/mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result b/mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result index 23943474541..b006304908a 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result +++ b/mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result @@ -54,13 +54,13 @@ USE test; # SET @old_log_warnings = @@log_warnings; DROP TABLE IF EXISTS t1; -CREATE TABLE t1 (a VARCHAR(36), b VARCHAR(10)); +CREATE TABLE t1 (a VARCHAR(36), b VARCHAR(15)); SET GLOBAL LOG_WARNINGS = 0; -INSERT INTO t1 VALUES(UUID(), 'Bug#46265'); +INSERT INTO t1 VALUES(UUID(), 'timestamp'); Warnings: Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave. SET GLOBAL LOG_WARNINGS = 1; -INSERT INTO t1 VALUES(UUID(), 'Bug#46265'); +INSERT INTO t1 VALUES(UUID(), 'timestamp'); Warnings: Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave. DROP TABLE t1; diff --git a/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test b/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test index 85571a6c582..4a4a75af60f 100644 --- a/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test +++ b/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test @@ -101,16 +101,24 @@ eval USE $old_db; --echo # Bug#46265: Can not disable warning about unsafe statements for binary logging --echo # +let BINLOG_COUNTER1= `select CONVERT(NOW(),UNSIGNED) as timestmap from dual`; + SET @old_log_warnings = @@log_warnings; --disable_warnings DROP TABLE IF EXISTS t1; --enable_warnings -CREATE TABLE t1 (a VARCHAR(36), b VARCHAR(10)); +CREATE TABLE t1 (a VARCHAR(36), b VARCHAR(15)); + SET GLOBAL LOG_WARNINGS = 0; -INSERT INTO t1 VALUES(UUID(), 'Bug#46265'); +# Replacing the result file content here. +# Instead of writing $BINLOG_COUNTER1 value to result file, +# writing a fixed string timestamp to it. +--replace_result $BINLOG_COUNTER1 timestamp +eval INSERT INTO t1 VALUES(UUID(), '$BINLOG_COUNTER1'); SET GLOBAL LOG_WARNINGS = 1; -INSERT INTO t1 VALUES(UUID(), 'Bug#46265'); +--replace_result $BINLOG_COUNTER1 timestamp +eval INSERT INTO t1 VALUES(UUID(), '$BINLOG_COUNTER1'); DROP TABLE t1; SET GLOBAL log_warnings = @old_log_warnings; @@ -132,13 +140,14 @@ perl; use strict; my $log_error= $ENV{'LOG_ERROR'} or die "LOG_ERROR not set"; open(FILE, "$log_error") or die("Unable to open $log_error: $!\n"); - my $count = () = grep(/Bug#46265/g,); + my $binlog_counter= $ENV{'BINLOG_COUNTER1'} or die "BINLOG_COUNTER1 not set"; + my $count = () = grep(/$binlog_counter/g,); + # Grep the timestamp value from the error file. print "Occurrences: $count\n"; close(FILE); EOF # bug#50192: diplaying the unsafe warning comes out to the user warning stack - -- disable_warnings DROP TABLE IF EXISTS t1, t2; -- enable_warnings diff --git a/mysql-test/suite/innodb/r/innodb_bug12400341.result b/mysql-test/suite/innodb/r/innodb_bug12400341.result new file mode 100644 index 00000000000..551e94f5e77 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug12400341.result @@ -0,0 +1,25 @@ +call mtr.add_suppression("InnoDB: Warning: cannot find a free slot for an undo log. Do you have too"); +show variables like "max_connections"; +Variable_name Value +max_connections 64 +show variables like "innodb_thread_concurrency"; +Variable_name Value +innodb_thread_concurrency 0 +show variables like "innodb_file_per_table"; +Variable_name Value +innodb_file_per_table ON +drop database if exists mysqltest; +create database mysqltest; +CREATE TABLE mysqltest.transtable (id int unsigned NOT NULL PRIMARY KEY, val int DEFAULT 0) ENGINE=InnoDB; +select count(*) from information_schema.processlist; +count(*) +33 +CREATE TABLE mysqltest.testtable (id int unsigned not null primary key) ENGINE=InnoDB; +ERROR HY000: Can't create table 'mysqltest.testtable' (errno: 177) +select count(*) from information_schema.processlist; +count(*) +33 +select count(*) from information_schema.processlist; +count(*) +33 +drop database mysqltest; diff --git a/mysql-test/suite/innodb/t/innodb_bug12400341-master.opt b/mysql-test/suite/innodb/t/innodb_bug12400341-master.opt new file mode 100644 index 00000000000..13f480704f5 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug12400341-master.opt @@ -0,0 +1 @@ +--max_connections=64 --innodb_thread_concurrency=0 --innodb_file_per_table --innodb_rollback_segments=2 diff --git a/mysql-test/suite/innodb/t/innodb_bug12400341.test b/mysql-test/suite/innodb/t/innodb_bug12400341.test new file mode 100644 index 00000000000..2ab1be81f6d --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug12400341.test @@ -0,0 +1,103 @@ +# Test for bug #12400341: INNODB CAN LEAVE ORPHAN IBD FILES AROUND + +-- source include/have_innodb.inc + +if (`select count(*)=0 from information_schema.global_variables where variable_name = 'INNODB_TRX_RSEG_N_SLOTS_DEBUG'`) +{ + --skip Test requires InnoDB built with UNIV_DEBUG definition. +} + +call mtr.add_suppression("InnoDB: Warning: cannot find a free slot for an undo log. Do you have too"); + +--disable_query_log +set @old_innodb_trx_rseg_n_slots_debug = @@innodb_trx_rseg_n_slots_debug; +set global innodb_trx_rseg_n_slots_debug = 32; +--enable_query_log + +show variables like "max_connections"; +show variables like "innodb_thread_concurrency"; +show variables like "innodb_file_per_table"; + +--disable_warnings +drop database if exists mysqltest; +--enable_warnings + +create database mysqltest; +CREATE TABLE mysqltest.transtable (id int unsigned NOT NULL PRIMARY KEY, val int DEFAULT 0) ENGINE=InnoDB; + +--disable_query_log +# +# Insert in 1 transaction which needs over 1 page undo record to avoid the insert_undo cached, +# because the cached insert_undo can be reused at "CREATE TABLE" statement later. +# +START TRANSACTION; +let $c = 1024; +while ($c) +{ + eval INSERT INTO mysqltest.transtable (id) VALUES ($c); + dec $c; +} +COMMIT; + +let $c = 32; +while ($c) +{ + # if failed at here, it might be shortage of file descriptors limit. + connect (con$c,localhost,root,,); + dec $c; +} +--enable_query_log + +select count(*) from information_schema.processlist; + +# +# fill the all undo slots +# +--disable_query_log +let $c = 32; +while ($c) +{ + connection con$c; + START TRANSACTION; + eval UPDATE mysqltest.transtable SET val = 1 WHERE id = 33 - $c; + dec $c; +} +--enable_query_log + +connection default; + +--error ER_CANT_CREATE_TABLE +CREATE TABLE mysqltest.testtable (id int unsigned not null primary key) ENGINE=InnoDB; + +select count(*) from information_schema.processlist; + +--disable_query_log +let $c = 32; +while ($c) +{ + connection con$c; + ROLLBACK; + dec $c; +} +--enable_query_log + +connection default; +select count(*) from information_schema.processlist; + +--disable_query_log +let $c = 32; +while ($c) +{ + disconnect con$c; + dec $c; +} +--enable_query_log + +# +# If the isolated .ibd file remained, the drop database should fail. +# +drop database mysqltest; + +--disable_query_log +set global innodb_trx_rseg_n_slots_debug = @old_innodb_trx_rseg_n_slots_debug; +--enable_query_log diff --git a/mysql-test/suite/rpl/r/rpl_cant_read_event_incident.result b/mysql-test/suite/rpl/r/rpl_cant_read_event_incident.result index c1b2c6e3195..a406a6afe92 100644 --- a/mysql-test/suite/rpl/r/rpl_cant_read_event_incident.result +++ b/mysql-test/suite/rpl/r/rpl_cant_read_event_incident.result @@ -11,7 +11,7 @@ reset slave; start slave; include/wait_for_slave_param.inc [Last_IO_Errno] Last_IO_Errno = '1236' -Last_IO_Error = 'Got fatal error 1236 from master when reading data from binary log: 'binlog truncated in the middle of event; consider out of disk space on master; the last event was read from './master-bin.000001' at 316, the last byte read was read from './master-bin.000001' at 335.'' +Last_IO_Error = 'Got fatal error 1236 from master when reading data from binary log: 'binlog truncated in the middle of event; consider out of disk space on master; the start event position from '' at XXX, the last event was read from './master-bin.000001' at XXX, the last byte read was read from './master-bin.000001' at XXX.'' reset master; stop slave; reset slave; diff --git a/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result b/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result index 93faf37053a..d1423dea378 100644 --- a/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result +++ b/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result @@ -270,6 +270,7 @@ Heartbeat event received include/rpl_reset.inc include/stop_slave.inc include/rpl_change_topology.inc [new topology=1->2->1] +CHANGE MASTER TO MASTER_HEARTBEAT_PERIOD=1; include/start_slave.inc CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(10)); INSERT INTO t1 VALUES(1, 'on master'); diff --git a/mysql-test/suite/rpl/r/rpl_known_bugs_detection.result b/mysql-test/suite/rpl/r/rpl_known_bugs_detection.result index 92ccc78aaca..8ed402b9f8d 100644 --- a/mysql-test/suite/rpl/r/rpl_known_bugs_detection.result +++ b/mysql-test/suite/rpl/r/rpl_known_bugs_detection.result @@ -1,5 +1,6 @@ include/master-slave.inc [connection master] +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b INT, UNIQUE(b)); INSERT INTO t1(b) VALUES(1),(1),(2) ON DUPLICATE KEY UPDATE t1.b=10; diff --git a/mysql-test/suite/rpl/r/rpl_log_pos.result b/mysql-test/suite/rpl/r/rpl_log_pos.result index 42b88711f03..49691bea9b6 100644 --- a/mysql-test/suite/rpl/r/rpl_log_pos.result +++ b/mysql-test/suite/rpl/r/rpl_log_pos.result @@ -9,6 +9,7 @@ change master to master_log_pos=MASTER_LOG_POS; Read_Master_Log_Pos = '75' start slave; include/wait_for_slave_io_error.inc [errno=1236] +Last_IO_Error = 'Got fatal error 1236 from master when reading data from binary log: 'log event entry exceeded max_allowed_packet; Increase max_allowed_packet on master; the start event position from 'master-bin.000001' at XXX, the last event was read from './master-bin.000001' at XXX, the last byte read was read from './master-bin.000001' at XXX.'' include/stop_slave_sql.inc show master status; File Position Binlog_Do_DB Binlog_Ignore_DB diff --git a/mysql-test/suite/rpl/r/rpl_manual_change_index_file.result b/mysql-test/suite/rpl/r/rpl_manual_change_index_file.result index a2dc5d402a7..2143b3492d5 100644 --- a/mysql-test/suite/rpl/r/rpl_manual_change_index_file.result +++ b/mysql-test/suite/rpl/r/rpl_manual_change_index_file.result @@ -5,6 +5,7 @@ CREATE TABLE t1(c1 INT); FLUSH LOGS; call mtr.add_suppression('Got fatal error 1236 from master when reading data from binary log: .*could not find next log'); include/wait_for_slave_io_error.inc [errno=1236] +Last_IO_Error = 'Got fatal error 1236 from master when reading data from binary log: 'could not find next log; the start event position from 'master-bin.000001' at XXX, the last event was read from './master-bin.000002' at XXX, the last byte read was read from './master-bin.000002' at XXX.'' CREATE TABLE t2(c1 INT); FLUSH LOGS; CREATE TABLE t3(c1 INT); diff --git a/mysql-test/suite/rpl/r/rpl_packet.result b/mysql-test/suite/rpl/r/rpl_packet.result index 27f85cac7de..7591006abcb 100644 --- a/mysql-test/suite/rpl/r/rpl_packet.result +++ b/mysql-test/suite/rpl/r/rpl_packet.result @@ -37,6 +37,7 @@ DROP TABLE t1; CREATE TABLE t1 (f1 int PRIMARY KEY, f2 LONGTEXT, f3 LONGTEXT) ENGINE=MyISAM; INSERT INTO t1(f1, f2, f3) VALUES(1, REPEAT('a', @@global.max_allowed_packet), REPEAT('b', @@global.max_allowed_packet)); include/wait_for_slave_io_error.inc [errno=1236] +Last_IO_Error = 'Got fatal error 1236 from master when reading data from binary log: 'log event entry exceeded max_allowed_packet; Increase max_allowed_packet on master; the start event position from '' at XXX, the last event was read from './master-bin.000001' at XXX, the last byte read was read from './master-bin.000001' at XXX.'' STOP SLAVE; RESET SLAVE; RESET MASTER; diff --git a/mysql-test/suite/rpl/r/rpl_start_stop_slave.result b/mysql-test/suite/rpl/r/rpl_start_stop_slave.result new file mode 100644 index 00000000000..43a7712bdf1 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_start_stop_slave.result @@ -0,0 +1,10 @@ +include/master-slave.inc +[connection master] +set @time_before_kill := (select CURRENT_TIMESTAMP); +[Time before the query] +[Connection ID of the slave I/O thread found] +kill ; +set @time_after_kill := (select CURRENT_TIMESTAMP); +[Time after the query] +[Killing of the slave IO thread was successful] +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result b/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result index 57206873e2f..a7f3744b582 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result +++ b/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result @@ -69,6 +69,16 @@ include/wait_for_slave_to_stop.inc include/start_slave.inc # Clean up DROP TABLE t1; +RESET MASTER; +include/stop_slave.inc +CHANGE MASTER TO master_log_pos=MASTER_POS; +START SLAVE; +include/wait_for_slave_param.inc [Last_IO_Errno] +Last_IO_Errno = '1236' +Last_IO_Error = 'Got fatal error 1236 from master when reading data from binary log: 'Client requested master to start replication from impossible position; the start event position from 'master-bin.000001' at XXX, the last event was read from './master-bin.000001' at XXX, the last byte read was read from './master-bin.000001' at XXX.'' +include/stop_slave.inc +RESET SLAVE; +RESET MASTER; SET @@global.innodb_flush_log_at_trx_commit= @old_innodb_flush_log_at_trx_commit; call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); SET @@global.innodb_flush_log_at_trx_commit= @old_innodb_flush_log_at_trx_commit; diff --git a/mysql-test/suite/rpl/t/rpl_cant_read_event_incident.test b/mysql-test/suite/rpl/t/rpl_cant_read_event_incident.test index 5e88b163d99..27478a318b8 100644 --- a/mysql-test/suite/rpl/t/rpl_cant_read_event_incident.test +++ b/mysql-test/suite/rpl/t/rpl_cant_read_event_incident.test @@ -14,11 +14,6 @@ --source include/master-slave.inc --source include/have_binlog_format_mixed.inc -# -# Bug#13050593 swallows `\' from Last_IO_Error -# todo: uncomment the filter once the bug is fixed. -# ---source include/not_windows.inc call mtr.add_suppression("Error in Log_event::read_log_event()"); @@ -51,6 +46,7 @@ start slave; --let $slave_param_value=1236 --source include/wait_for_slave_param.inc +--let $slave_field_result_replace= / at [0-9]*/ at XXX/ --let $status_items= Last_IO_Errno, Last_IO_Error --source include/show_slave_status.inc diff --git a/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test b/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test index b9a170c5bc1..78489449ab8 100644 --- a/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test +++ b/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test @@ -480,6 +480,12 @@ let $status_var_comparsion= >; --connection master #--replace_result $SLAVE_MYPORT SLAVE_PORT $slave_binlog SLAVE_BINLOG #eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$SLAVE_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=1, MASTER_LOG_FILE='$slave_binlog'; + +# BUG#12403008 RPL_HEARTBEAT_BASIC FAILS SPORADICALLY ON PUSHBUILD +# MASTER_HEARTBEAT_PERIOD had the default value (slave_net_timeout/2) +# so wait on "Heartbeat event received on master", that only waits for +# 1 minute, sometimes timeout before heartbeat arrives. +CHANGE MASTER TO MASTER_HEARTBEAT_PERIOD=1; --source include/start_slave.inc # Insert data on master and on slave and make sure that it replicated for both directions diff --git a/mysql-test/suite/rpl/t/rpl_known_bugs_detection.test b/mysql-test/suite/rpl/t/rpl_known_bugs_detection.test index 99871b695a6..a713691ec2d 100644 --- a/mysql-test/suite/rpl/t/rpl_known_bugs_detection.test +++ b/mysql-test/suite/rpl/t/rpl_known_bugs_detection.test @@ -6,6 +6,8 @@ source include/have_debug.inc; source include/master-slave.inc; +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); + # Currently only statement-based-specific bugs are here -- source include/have_binlog_format_statement.inc diff --git a/mysql-test/suite/rpl/t/rpl_log_pos.test b/mysql-test/suite/rpl/t/rpl_log_pos.test index 882a05712f2..1043a80b5d5 100644 --- a/mysql-test/suite/rpl/t/rpl_log_pos.test +++ b/mysql-test/suite/rpl/t/rpl_log_pos.test @@ -22,12 +22,9 @@ let $status_items= Read_Master_Log_Pos; source include/show_slave_status.inc; start slave; let $slave_io_errno= 1236; -# -# Win and Unix path is printed differently: BUG#13055685. So -# show_slave_io_error is made 0 until the bug fixes provide necessary -# facilities -# -let $show_slave_io_error= 0; +--let $show_slave_io_error= 1 +# Mask line numbers +--let $slave_io_error_replace= / at [0-9]*/ at XXX/ source include/wait_for_slave_io_error.inc; source include/stop_slave_sql.inc; diff --git a/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test b/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test index 9b648de8486..981cecb66ad 100644 --- a/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test +++ b/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test @@ -60,12 +60,9 @@ call mtr.add_suppression('Got fatal error 1236 from master when reading data fro connection slave; # 1236 = ER_MASTER_FATAL_ERROR_READING_BINLOG --let $slave_io_errno= 1236 -# -# Win and Unix path is printed differently: BUG#13055685. So -# show_slave_io_error is made 0 until the bug fixes provide necessary -# facilities -# ---let $show_slave_io_error= 0 +--let $show_slave_io_error= 1 +# Mask line numbers +--let $slave_io_error_replace= / at [0-9]*/ at XXX/ --source include/wait_for_slave_io_error.inc connection master; diff --git a/mysql-test/suite/rpl/t/rpl_packet.test b/mysql-test/suite/rpl/t/rpl_packet.test index 2b8a1fd8310..4f296fed68e 100644 --- a/mysql-test/suite/rpl/t/rpl_packet.test +++ b/mysql-test/suite/rpl/t/rpl_packet.test @@ -125,12 +125,9 @@ connection slave; # The slave I/O thread must stop after receiving # 1236=ER_MASTER_FATAL_ERROR_READING_BINLOG error message from master. --let $slave_io_errno= 1236 -# -# Win and Unix path is printed differently: BUG#13055685. So -# show_slave_io_error is made 0 until the bug fixes provide necessary -# facilities -# ---let $show_slave_io_error= 0 + +# Mask line numbers +--let $slave_io_error_replace= / at [0-9]*/ at XXX/ --source include/wait_for_slave_io_error.inc # Remove the bad binlog and clear error status on slave. diff --git a/mysql-test/suite/rpl/t/rpl_start_stop_slave.test b/mysql-test/suite/rpl/t/rpl_start_stop_slave.test new file mode 100644 index 00000000000..69d39a066b1 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_start_stop_slave.test @@ -0,0 +1,44 @@ +# +#BUG#11752315 : STOP SLAVE UNABLE TO COMPLETE WHEN SLAVE THREAD IS TRYING +# TO RECONNECT TO +# +# ==== Purpose ==== +# +#Tests that the slave does not go to a sleep for a long duration after the +#master is killed and we do a START_SLAVE and STOP_SLAVE. +# +# ==== Method ==== +# +#This is a new functionality of having an interruptable sleep of the slave. +#We find the thread id for the slave thread. On finding the thread ID of the +#slave thread we kill the slave thread. A successful kill in less than 60 sec +#should serve the purpose of checking the functionality. +# + +--source include/have_log_bin.inc +--source include/master-slave.inc + +connection slave; +--let $connection_id=`SELECT id FROM information_schema.processlist where state LIKE 'Waiting for master to send event'` + +set @time_before_kill := (select CURRENT_TIMESTAMP); + +--echo [Time before the query] +--echo [Connection ID of the slave I/O thread found] + +--replace_regex /kill [0-9]*/kill / +--eval kill $connection_id + +set @time_after_kill := (select CURRENT_TIMESTAMP); + +--echo [Time after the query] + +if(`select TIMESTAMPDIFF(SECOND,@time_after_kill, @time_before_kill) > 60`) +{ +--echo # assert : The difference between the timestamps 'time_after_kill' and 'time_before_kill' should be less than 60sec. +--die +} + +--echo [Killing of the slave IO thread was successful] +# End of test +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_stm_start_stop_slave.test b/mysql-test/suite/rpl/t/rpl_stm_start_stop_slave.test index ada080e9071..dfe2e49bb90 100644 --- a/mysql-test/suite/rpl/t/rpl_stm_start_stop_slave.test +++ b/mysql-test/suite/rpl/t/rpl_stm_start_stop_slave.test @@ -22,5 +22,5 @@ SET @@global.innodb_flush_log_at_trx_commit= @old_innodb_flush_log_at_trx_commit call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); --connection master SET @@global.innodb_flush_log_at_trx_commit= @old_innodb_flush_log_at_trx_commit; - +--let $rpl_only_running_threads= 1 --source include/rpl_end.inc diff --git a/mysql-test/suite/sys_vars/r/all_vars.result b/mysql-test/suite/sys_vars/r/all_vars.result index af05e3bc393..0f741ff930a 100644 --- a/mysql-test/suite/sys_vars/r/all_vars.result +++ b/mysql-test/suite/sys_vars/r/all_vars.result @@ -3,7 +3,6 @@ create table t2 (variable_name text); load data infile "MYSQLTEST_VARDIR/tmp/sys_vars.all_vars.txt" into table t1; insert into t2 select variable_name from information_schema.global_variables; insert into t2 select variable_name from information_schema.session_variables; -delete from t2 where variable_name='innodb_change_buffering_debug'; update t2 set variable_name= replace(variable_name, "PERFORMANCE_SCHEMA_", "PFS_"); select variable_name as `There should be *no* long test name listed below:` from t2 where length(variable_name) > 50; diff --git a/mysql-test/suite/sys_vars/r/character_sets_dir_basic.result b/mysql-test/suite/sys_vars/r/character_sets_dir_basic.result index c04e5dac199..ef8ec0cd9b8 100644 --- a/mysql-test/suite/sys_vars/r/character_sets_dir_basic.result +++ b/mysql-test/suite/sys_vars/r/character_sets_dir_basic.result @@ -1,20 +1,20 @@ select @@global.character_sets_dir; @@global.character_sets_dir -MYSQL_CHARSETSDIR/ +MYSQL_CHARSETSDIR select @@session.character_sets_dir; ERROR HY000: Variable 'character_sets_dir' is a GLOBAL variable show global variables like 'character_sets_dir'; Variable_name Value -character_sets_dir MYSQL_CHARSETSDIR/ +character_sets_dir MYSQL_CHARSETSDIR show session variables like 'character_sets_dir'; Variable_name Value -character_sets_dir MYSQL_CHARSETSDIR/ +character_sets_dir MYSQL_CHARSETSDIR select * from information_schema.global_variables where variable_name='character_sets_dir'; VARIABLE_NAME VARIABLE_VALUE -CHARACTER_SETS_DIR MYSQL_CHARSETSDIR/ +CHARACTER_SETS_DIR MYSQL_CHARSETSDIR select * from information_schema.session_variables where variable_name='character_sets_dir'; VARIABLE_NAME VARIABLE_VALUE -CHARACTER_SETS_DIR MYSQL_CHARSETSDIR/ +CHARACTER_SETS_DIR MYSQL_CHARSETSDIR set global character_sets_dir="foo"; ERROR HY000: Variable 'character_sets_dir' is a read only variable set session character_sets_dir="foo"; diff --git a/mysql-test/suite/sys_vars/r/innodb_change_buffering_debug_basic.result b/mysql-test/suite/sys_vars/r/innodb_change_buffering_debug_basic.result new file mode 100644 index 00000000000..2b74f891050 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/innodb_change_buffering_debug_basic.result @@ -0,0 +1,64 @@ +SET @start_global_value = @@global.innodb_change_buffering_debug; +SELECT @start_global_value; +@start_global_value +0 +select @@global.innodb_change_buffering_debug in (0, 1); +@@global.innodb_change_buffering_debug in (0, 1) +1 +select @@global.innodb_change_buffering_debug; +@@global.innodb_change_buffering_debug +0 +select @@session.innodb_change_buffering_debug; +ERROR HY000: Variable 'innodb_change_buffering_debug' is a GLOBAL variable +show global variables like 'innodb_change_buffering_debug'; +Variable_name Value +innodb_change_buffering_debug 0 +show session variables like 'innodb_change_buffering_debug'; +Variable_name Value +innodb_change_buffering_debug 0 +select * from information_schema.global_variables where variable_name='innodb_change_buffering_debug'; +VARIABLE_NAME VARIABLE_VALUE +INNODB_CHANGE_BUFFERING_DEBUG 0 +select * from information_schema.session_variables where variable_name='innodb_change_buffering_debug'; +VARIABLE_NAME VARIABLE_VALUE +INNODB_CHANGE_BUFFERING_DEBUG 0 +set global innodb_change_buffering_debug=1; +select @@global.innodb_change_buffering_debug; +@@global.innodb_change_buffering_debug +1 +select * from information_schema.global_variables where variable_name='innodb_change_buffering_debug'; +VARIABLE_NAME VARIABLE_VALUE +INNODB_CHANGE_BUFFERING_DEBUG 1 +select * from information_schema.session_variables where variable_name='innodb_change_buffering_debug'; +VARIABLE_NAME VARIABLE_VALUE +INNODB_CHANGE_BUFFERING_DEBUG 1 +set @@global.innodb_change_buffering_debug=0; +select @@global.innodb_change_buffering_debug; +@@global.innodb_change_buffering_debug +0 +select * from information_schema.global_variables where variable_name='innodb_change_buffering_debug'; +VARIABLE_NAME VARIABLE_VALUE +INNODB_CHANGE_BUFFERING_DEBUG 0 +select * from information_schema.session_variables where variable_name='innodb_change_buffering_debug'; +VARIABLE_NAME VARIABLE_VALUE +INNODB_CHANGE_BUFFERING_DEBUG 0 +set session innodb_change_buffering_debug='some'; +ERROR HY000: Variable 'innodb_change_buffering_debug' is a GLOBAL variable and should be set with SET GLOBAL +set @@session.innodb_change_buffering_debug='some'; +ERROR HY000: Variable 'innodb_change_buffering_debug' is a GLOBAL variable and should be set with SET GLOBAL +set global innodb_change_buffering_debug=1.1; +ERROR 42000: Incorrect argument type to variable 'innodb_change_buffering_debug' +set global innodb_change_buffering_debug='foo'; +ERROR 42000: Incorrect argument type to variable 'innodb_change_buffering_debug' +set global innodb_change_buffering_debug=-2; +Warnings: +Warning 1292 Truncated incorrect innodb_change_buffering_debug value: '-2' +set global innodb_change_buffering_debug=1e1; +ERROR 42000: Incorrect argument type to variable 'innodb_change_buffering_debug' +set global innodb_change_buffering_debug=2; +Warnings: +Warning 1292 Truncated incorrect innodb_change_buffering_debug value: '2' +SET @@global.innodb_change_buffering_debug = @start_global_value; +SELECT @@global.innodb_change_buffering_debug; +@@global.innodb_change_buffering_debug +0 diff --git a/mysql-test/suite/sys_vars/r/innodb_trx_rseg_n_slots_debug_basic.result b/mysql-test/suite/sys_vars/r/innodb_trx_rseg_n_slots_debug_basic.result new file mode 100644 index 00000000000..7e253c869e3 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/innodb_trx_rseg_n_slots_debug_basic.result @@ -0,0 +1,65 @@ +SET @start_global_value = @@global.innodb_trx_rseg_n_slots_debug; +SELECT @start_global_value; +@start_global_value +0 +select @@global.innodb_trx_rseg_n_slots_debug between 0 and 1024; +@@global.innodb_trx_rseg_n_slots_debug between 0 and 1024 +1 +select @@global.innodb_trx_rseg_n_slots_debug; +@@global.innodb_trx_rseg_n_slots_debug +0 +select @@session.innodb_trx_rseg_n_slots_debug; +ERROR HY000: Variable 'innodb_trx_rseg_n_slots_debug' is a GLOBAL variable +show global variables like 'innodb_trx_rseg_n_slots_debug'; +Variable_name Value +innodb_trx_rseg_n_slots_debug 0 +show session variables like 'innodb_trx_rseg_n_slots_debug'; +Variable_name Value +innodb_trx_rseg_n_slots_debug 0 +select * from information_schema.global_variables where variable_name='innodb_trx_rseg_n_slots_debug'; +VARIABLE_NAME VARIABLE_VALUE +INNODB_TRX_RSEG_N_SLOTS_DEBUG 0 +select * from information_schema.session_variables where variable_name='innodb_trx_rseg_n_slots_debug'; +VARIABLE_NAME VARIABLE_VALUE +INNODB_TRX_RSEG_N_SLOTS_DEBUG 0 +set global innodb_trx_rseg_n_slots_debug=1; +select @@global.innodb_trx_rseg_n_slots_debug; +@@global.innodb_trx_rseg_n_slots_debug +1 +select * from information_schema.global_variables where variable_name='innodb_trx_rseg_n_slots_debug'; +VARIABLE_NAME VARIABLE_VALUE +INNODB_TRX_RSEG_N_SLOTS_DEBUG 1 +select * from information_schema.session_variables where variable_name='innodb_trx_rseg_n_slots_debug'; +VARIABLE_NAME VARIABLE_VALUE +INNODB_TRX_RSEG_N_SLOTS_DEBUG 1 +set @@global.innodb_trx_rseg_n_slots_debug=0; +select @@global.innodb_trx_rseg_n_slots_debug; +@@global.innodb_trx_rseg_n_slots_debug +0 +select * from information_schema.global_variables where variable_name='innodb_trx_rseg_n_slots_debug'; +VARIABLE_NAME VARIABLE_VALUE +INNODB_TRX_RSEG_N_SLOTS_DEBUG 0 +select * from information_schema.session_variables where variable_name='innodb_trx_rseg_n_slots_debug'; +VARIABLE_NAME VARIABLE_VALUE +INNODB_TRX_RSEG_N_SLOTS_DEBUG 0 +set session innodb_trx_rseg_n_slots_debug='some'; +ERROR HY000: Variable 'innodb_trx_rseg_n_slots_debug' is a GLOBAL variable and should be set with SET GLOBAL +set @@session.innodb_trx_rseg_n_slots_debug='some'; +ERROR HY000: Variable 'innodb_trx_rseg_n_slots_debug' is a GLOBAL variable and should be set with SET GLOBAL +set global innodb_trx_rseg_n_slots_debug=1.1; +ERROR 42000: Incorrect argument type to variable 'innodb_trx_rseg_n_slots_debug' +set global innodb_trx_rseg_n_slots_debug='foo'; +ERROR 42000: Incorrect argument type to variable 'innodb_trx_rseg_n_slots_debug' +set global innodb_trx_rseg_n_slots_debug=-2; +Warnings: +Warning 1292 Truncated incorrect innodb_trx_rseg_n_slots_debug value: '-2' +set global innodb_trx_rseg_n_slots_debug=1e1; +ERROR 42000: Incorrect argument type to variable 'innodb_trx_rseg_n_slots_debug' +set global innodb_trx_rseg_n_slots_debug=1024; +set global innodb_trx_rseg_n_slots_debug=1025; +Warnings: +Warning 1292 Truncated incorrect innodb_trx_rseg_n_slots_debug value: '1025' +SET @@global.innodb_trx_rseg_n_slots_debug = @start_global_value; +SELECT @@global.innodb_trx_rseg_n_slots_debug; +@@global.innodb_trx_rseg_n_slots_debug +0 diff --git a/mysql-test/suite/sys_vars/r/plugin_dir_basic.result b/mysql-test/suite/sys_vars/r/plugin_dir_basic.result index a5f36de73fa..e2c03bcad6a 100644 --- a/mysql-test/suite/sys_vars/r/plugin_dir_basic.result +++ b/mysql-test/suite/sys_vars/r/plugin_dir_basic.result @@ -1,20 +1,20 @@ select @@global.plugin_dir; @@global.plugin_dir -MYSQL_TMP_DIR +MYSQL_TMP_DIR/ select @@session.plugin_dir; ERROR HY000: Variable 'plugin_dir' is a GLOBAL variable show global variables like 'plugin_dir'; Variable_name Value -plugin_dir MYSQL_TMP_DIR +plugin_dir MYSQL_TMP_DIR/ show session variables like 'plugin_dir'; Variable_name Value -plugin_dir MYSQL_TMP_DIR +plugin_dir MYSQL_TMP_DIR/ select * from information_schema.global_variables where variable_name='plugin_dir'; VARIABLE_NAME VARIABLE_VALUE -PLUGIN_DIR MYSQL_TMP_DIR +PLUGIN_DIR MYSQL_TMP_DIR/ select * from information_schema.session_variables where variable_name='plugin_dir'; VARIABLE_NAME VARIABLE_VALUE -PLUGIN_DIR MYSQL_TMP_DIR +PLUGIN_DIR MYSQL_TMP_DIR/ set global plugin_dir=1; ERROR HY000: Variable 'plugin_dir' is a read only variable set session plugin_dir=1; diff --git a/mysql-test/suite/sys_vars/r/stored_program_cache_basic.result b/mysql-test/suite/sys_vars/r/stored_program_cache_basic.result new file mode 100644 index 00000000000..f1638520f72 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/stored_program_cache_basic.result @@ -0,0 +1,59 @@ +# Saving initial value of stored_program_cache in a temporary variable +SET @start_value = @@global.stored_program_cache; +SELECT @start_value; +@start_value +256 +# Display the DEFAULT value of stored_program_cache +SET @@global.stored_program_cache = DEFAULT; +SELECT @@global.stored_program_cache; +@@global.stored_program_cache +256 +# Verify default value of variable +SELECT @@global.stored_program_cache = 256; +@@global.stored_program_cache = 256 +1 +# Change the value of stored_program_cache to a valid value +SET @@global.stored_program_cache = 512; +SELECT @@global.stored_program_cache; +@@global.stored_program_cache +512 +# Change the value of stored_program_cache to invalid value +SET @@global.stored_program_cache = -1; +Warnings: +Warning 1292 Truncated incorrect stored_program_cache value: '-1' +SELECT @@global.stored_program_cache; +@@global.stored_program_cache +256 +SET @@global.stored_program_cache =100000000000; +Warnings: +Warning 1292 Truncated incorrect stored_program_cache value: '100000000000' +SELECT @@global.stored_program_cache; +@@global.stored_program_cache +524288 +SET @@global.stored_program_cache = 0; +Warnings: +Warning 1292 Truncated incorrect stored_program_cache value: '0' +SELECT @@global.stored_program_cache; +@@global.stored_program_cache +256 +SET @@global.stored_program_cache = 10000.01; +ERROR 42000: Incorrect argument type to variable 'stored_program_cache' +SET @@global.stored_program_cache = ON; +ERROR 42000: Incorrect argument type to variable 'stored_program_cache' +SET @@global.stored_program_cache= 'test'; +ERROR 42000: Incorrect argument type to variable 'stored_program_cache' +SET @@global.stored_program_cache = ''; +ERROR 42000: Incorrect argument type to variable 'stored_program_cache' +# Test if accessing session stored_program_cache gives error +SET @@session.stored_program_cache = 0; +ERROR HY000: Variable 'stored_program_cache' is a GLOBAL variable and should be set with SET GLOBAL +# Check if accessing variable without SCOPE points to same global variable +SET @@global.stored_program_cache = 512; +SELECT @@stored_program_cache = @@global.stored_program_cache; +@@stored_program_cache = @@global.stored_program_cache +1 +# Restore initial value +SET @@global.stored_program_cache = @start_value; +SELECT @@global.stored_program_cache; +@@global.stored_program_cache +256 diff --git a/mysql-test/suite/sys_vars/t/all_vars.test b/mysql-test/suite/sys_vars/t/all_vars.test index f4fbf9fc6f1..2f44ef43493 100644 --- a/mysql-test/suite/sys_vars/t/all_vars.test +++ b/mysql-test/suite/sys_vars/t/all_vars.test @@ -47,9 +47,6 @@ eval load data infile "$MYSQLTEST_VARDIR/tmp/sys_vars.all_vars.txt" into table t insert into t2 select variable_name from information_schema.global_variables; insert into t2 select variable_name from information_schema.session_variables; -# This is only present in debug builds. -delete from t2 where variable_name='innodb_change_buffering_debug'; - # Performance schema variables are too long for files named # 'mysql-test/suite/sys_vars/t/' ... # ... 'performance_schema_events_waits_history_long_size_basic-master.opt' diff --git a/mysql-test/suite/sys_vars/t/character_sets_dir_basic.test b/mysql-test/suite/sys_vars/t/character_sets_dir_basic.test index 3d9de961530..0660fbeba2b 100644 --- a/mysql-test/suite/sys_vars/t/character_sets_dir_basic.test +++ b/mysql-test/suite/sys_vars/t/character_sets_dir_basic.test @@ -1,17 +1,26 @@ # # show the global and session values; # ---replace_result $MYSQL_CHARSETSDIR MYSQL_CHARSETSDIR + +# workaround to adjust for the directory separators being different in +# different OSes : slash on unixes and backslash or slash on windows. +# TODO: fix with a proper comparison in mysqltest +let $rcd= `SELECT REPLACE('$MYSQL_CHARSETSDIR', '\\\\\', '.')`; +let $rcd= `SELECT REPLACE('$rcd', '/', '.')`; +let $regex_charsetdir= `SELECT '/$rcd[\\\\\/\\\\\]/MYSQL_CHARSETSDIR/'`; + +--replace_regex $regex_charsetdir select @@global.character_sets_dir; + --error ER_INCORRECT_GLOBAL_LOCAL_VAR select @@session.character_sets_dir; ---replace_result $MYSQL_CHARSETSDIR MYSQL_CHARSETSDIR +--replace_regex $regex_charsetdir show global variables like 'character_sets_dir'; ---replace_result $MYSQL_CHARSETSDIR MYSQL_CHARSETSDIR +--replace_regex $regex_charsetdir show session variables like 'character_sets_dir'; ---replace_result $MYSQL_CHARSETSDIR MYSQL_CHARSETSDIR +--replace_regex $regex_charsetdir select * from information_schema.global_variables where variable_name='character_sets_dir'; ---replace_result $MYSQL_CHARSETSDIR MYSQL_CHARSETSDIR +--replace_regex $regex_charsetdir select * from information_schema.session_variables where variable_name='character_sets_dir'; # diff --git a/mysql-test/suite/sys_vars/t/disabled.def b/mysql-test/suite/sys_vars/t/disabled.def index 3d1c08786cf..e18121be68c 100644 --- a/mysql-test/suite/sys_vars/t/disabled.def +++ b/mysql-test/suite/sys_vars/t/disabled.def @@ -11,5 +11,7 @@ ############################################################################## transaction_prealloc_size_basic_32 : Bug#11748572 transaction_prealloc_size_basic_64 : Bug#11748572 +query_cache_size_basic_32 : Bug#13535584 +query_cache_size_basic_64 : Bug#11748572 #thread_cache_size_func : Bug#11750172: 2008-11-07 joro main.thread_cache_size_func fails in pushbuild when run with pool of threads query_cache_size_basic_64 : Test is not deterministic. It attempts to allocate a very large query cache. diff --git a/mysql-test/suite/sys_vars/t/innodb_change_buffering_debug_basic.test b/mysql-test/suite/sys_vars/t/innodb_change_buffering_debug_basic.test new file mode 100644 index 00000000000..ec1065a538e --- /dev/null +++ b/mysql-test/suite/sys_vars/t/innodb_change_buffering_debug_basic.test @@ -0,0 +1,52 @@ +--source include/have_innodb.inc +--source include/have_debug.inc + +SET @start_global_value = @@global.innodb_change_buffering_debug; +SELECT @start_global_value; + +# +# exists as global only +# +select @@global.innodb_change_buffering_debug in (0, 1); +select @@global.innodb_change_buffering_debug; +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +select @@session.innodb_change_buffering_debug; +show global variables like 'innodb_change_buffering_debug'; +show session variables like 'innodb_change_buffering_debug'; +select * from information_schema.global_variables where variable_name='innodb_change_buffering_debug'; +select * from information_schema.session_variables where variable_name='innodb_change_buffering_debug'; + +# +# show that it's writable +# +set global innodb_change_buffering_debug=1; +select @@global.innodb_change_buffering_debug; +select * from information_schema.global_variables where variable_name='innodb_change_buffering_debug'; +select * from information_schema.session_variables where variable_name='innodb_change_buffering_debug'; +set @@global.innodb_change_buffering_debug=0; +select @@global.innodb_change_buffering_debug; +select * from information_schema.global_variables where variable_name='innodb_change_buffering_debug'; +select * from information_schema.session_variables where variable_name='innodb_change_buffering_debug'; +--error ER_GLOBAL_VARIABLE +set session innodb_change_buffering_debug='some'; +--error ER_GLOBAL_VARIABLE +set @@session.innodb_change_buffering_debug='some'; + +# +# incorrect types +# +--error ER_WRONG_TYPE_FOR_VAR +set global innodb_change_buffering_debug=1.1; +--error ER_WRONG_TYPE_FOR_VAR +set global innodb_change_buffering_debug='foo'; +set global innodb_change_buffering_debug=-2; +--error ER_WRONG_TYPE_FOR_VAR +set global innodb_change_buffering_debug=1e1; +set global innodb_change_buffering_debug=2; + +# +# Cleanup +# + +SET @@global.innodb_change_buffering_debug = @start_global_value; +SELECT @@global.innodb_change_buffering_debug; diff --git a/mysql-test/suite/sys_vars/t/innodb_trx_rseg_n_slots_debug_basic.test b/mysql-test/suite/sys_vars/t/innodb_trx_rseg_n_slots_debug_basic.test new file mode 100644 index 00000000000..d17917de8e9 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/innodb_trx_rseg_n_slots_debug_basic.test @@ -0,0 +1,53 @@ +--source include/have_innodb.inc +--source include/have_debug.inc + +SET @start_global_value = @@global.innodb_trx_rseg_n_slots_debug; +SELECT @start_global_value; + +# +# exists as global only +# +select @@global.innodb_trx_rseg_n_slots_debug between 0 and 1024; +select @@global.innodb_trx_rseg_n_slots_debug; +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +select @@session.innodb_trx_rseg_n_slots_debug; +show global variables like 'innodb_trx_rseg_n_slots_debug'; +show session variables like 'innodb_trx_rseg_n_slots_debug'; +select * from information_schema.global_variables where variable_name='innodb_trx_rseg_n_slots_debug'; +select * from information_schema.session_variables where variable_name='innodb_trx_rseg_n_slots_debug'; + +# +# show that it's writable +# +set global innodb_trx_rseg_n_slots_debug=1; +select @@global.innodb_trx_rseg_n_slots_debug; +select * from information_schema.global_variables where variable_name='innodb_trx_rseg_n_slots_debug'; +select * from information_schema.session_variables where variable_name='innodb_trx_rseg_n_slots_debug'; +set @@global.innodb_trx_rseg_n_slots_debug=0; +select @@global.innodb_trx_rseg_n_slots_debug; +select * from information_schema.global_variables where variable_name='innodb_trx_rseg_n_slots_debug'; +select * from information_schema.session_variables where variable_name='innodb_trx_rseg_n_slots_debug'; +--error ER_GLOBAL_VARIABLE +set session innodb_trx_rseg_n_slots_debug='some'; +--error ER_GLOBAL_VARIABLE +set @@session.innodb_trx_rseg_n_slots_debug='some'; + +# +# incorrect types +# +--error ER_WRONG_TYPE_FOR_VAR +set global innodb_trx_rseg_n_slots_debug=1.1; +--error ER_WRONG_TYPE_FOR_VAR +set global innodb_trx_rseg_n_slots_debug='foo'; +set global innodb_trx_rseg_n_slots_debug=-2; +--error ER_WRONG_TYPE_FOR_VAR +set global innodb_trx_rseg_n_slots_debug=1e1; +set global innodb_trx_rseg_n_slots_debug=1024; +set global innodb_trx_rseg_n_slots_debug=1025; + +# +# Cleanup +# + +SET @@global.innodb_trx_rseg_n_slots_debug = @start_global_value; +SELECT @@global.innodb_trx_rseg_n_slots_debug; diff --git a/mysql-test/suite/sys_vars/t/stored_program_cache_basic.test b/mysql-test/suite/sys_vars/t/stored_program_cache_basic.test new file mode 100644 index 00000000000..9a9ba2ebf81 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/stored_program_cache_basic.test @@ -0,0 +1,59 @@ +# Variable Name: stored_program_cache +# Scope: GLOBAL +# Access Type: Dynamic +# Data Type: numeric +# Default Value: 256 +# Range: 256-524288 + +--source include/load_sysvars.inc + +--echo # Saving initial value of stored_program_cache in a temporary variable +SET @start_value = @@global.stored_program_cache; +SELECT @start_value; + +--echo # Display the DEFAULT value of stored_program_cache +SET @@global.stored_program_cache = DEFAULT; +SELECT @@global.stored_program_cache; + +--echo # Verify default value of variable +SELECT @@global.stored_program_cache = 256; + +--echo # Change the value of stored_program_cache to a valid value +SET @@global.stored_program_cache = 512; +SELECT @@global.stored_program_cache; + +--echo # Change the value of stored_program_cache to invalid value +SET @@global.stored_program_cache = -1; +SELECT @@global.stored_program_cache; + +SET @@global.stored_program_cache =100000000000; +SELECT @@global.stored_program_cache; + +SET @@global.stored_program_cache = 0; +SELECT @@global.stored_program_cache; + +--Error ER_WRONG_TYPE_FOR_VAR +SET @@global.stored_program_cache = 10000.01; + +--Error ER_WRONG_TYPE_FOR_VAR +SET @@global.stored_program_cache = ON; +--Error ER_WRONG_TYPE_FOR_VAR +SET @@global.stored_program_cache= 'test'; + +--Error ER_WRONG_TYPE_FOR_VAR +SET @@global.stored_program_cache = ''; + +--echo # Test if accessing session stored_program_cache gives error + +--Error ER_GLOBAL_VARIABLE +SET @@session.stored_program_cache = 0; + +--echo # Check if accessing variable without SCOPE points to same global variable + +SET @@global.stored_program_cache = 512; +SELECT @@stored_program_cache = @@global.stored_program_cache; + +--echo # Restore initial value + +SET @@global.stored_program_cache = @start_value; +SELECT @@global.stored_program_cache; diff --git a/mysql-test/t/bigint.test b/mysql-test/t/bigint.test index e19bba971f9..41f33b8a7f2 100644 --- a/mysql-test/t/bigint.test +++ b/mysql-test/t/bigint.test @@ -361,4 +361,51 @@ DROP TABLE t1; --echo # End of 5.1 tests +--echo # +--echo # Bug#13463415 63502: INCORRECT RESULTS OF BIGINT AND DECIMAL COMPARISON +--echo # + +CREATE TABLE t_bigint(id BIGINT); +INSERT INTO t_bigint VALUES (1), (2); + +SELECT id, id >= 1.1 FROM t_bigint; +SELECT id, 1.1 <= id FROM t_bigint; + +SELECT id, id = 1.1 FROM t_bigint; +SELECT id, 1.1 = id FROM t_bigint; + +SELECT * from t_bigint WHERE id = 1.1; +SELECT * from t_bigint WHERE id = 1.1e0; +SELECT * from t_bigint WHERE id = '1.1'; +SELECT * from t_bigint WHERE id = '1.1e0'; + +SELECT * from t_bigint WHERE id IN (1.1, 2.2); +SELECT * from t_bigint WHERE id IN (1.1e0, 2.2e0); +SELECT * from t_bigint WHERE id IN ('1.1', '2.2'); +SELECT * from t_bigint WHERE id IN ('1.1e0', '2.2e0'); + +SELECT * from t_bigint WHERE id BETWEEN 1.1 AND 1.9; +SELECT * from t_bigint WHERE id BETWEEN 1.1e0 AND 1.9e0; +SELECT * from t_bigint WHERE id BETWEEN '1.1' AND '1.9'; +SELECT * from t_bigint WHERE id BETWEEN '1.1e0' AND '1.9e0'; +DROP TABLE t_bigint; + +--echo # +--echo # Bug#11758543 50756: BIGINT '100' MATCHES 1.001E2 +--echo # + +CREATE TABLE t1 (a BIGINT); +INSERT INTO t1 VALUES (1); + +# a. These queries correctly return 0 rows: +SELECT * FROM t1 WHERE coalesce(a) BETWEEN 0 and 0.9; +SELECT * FROM t1 WHERE coalesce(a)=0.9; +SELECT * FROM t1 WHERE coalesce(a) in (0.8,0.9); + +# b. These queries mistakenely returned 1 row: +SELECT * FROM t1 WHERE a BETWEEN 0 AND 0.9; +SELECT * FROM t1 WHERE a=0.9; +SELECT * FROM t1 WHERE a IN (0.8,0.9); + +DROP TABLE t1; diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 8254f99249f..acf16568319 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1455,6 +1455,14 @@ SELECT HEX(LPAD(_utf8 0xD18F, 3, 0x20)); SELECT HEX(INSERT(_utf8 0xD18F, 2, 1, 0x20)); SELECT HEX(INSERT(_utf8 0xD18FD18E, 2, 1, 0x20)); +--echo # +--echo # Bug#11752408 - 43593: DUMP/BACKUP/RESTORE/UPGRADE TOOLS FAILS BECAUSE OF UTF8_GENERAL_CI +--echo # +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_general_mysql500_ci); +INSERT INTO t1 VALUES ('a'),('r'),('s'),(_latin1 0xDF),(_latin1 0xF7),('t'),('z'); +SELECT * FROM t1 ORDER BY a; +SELECT a, COUNT(*) FROM t1 GROUP BY a; +DROP TABLE t1; --echo End of 5.1 tests diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 083ed396527..27e196e5b0c 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -1459,6 +1459,45 @@ SELECT stddev_samp(rpad(1.0,2048,1)); SELECT ((127.1) not in ((rpad(1.0,2048,1)),(''),(-1.1))); SELECT ((0xf3) * (rpad(1.0,2048,1)) << (0xcc)); +--echo # +--echo # Bug#13359121 LARGE NUMBERS, /STRINGS/DTOA.C:662: +--echo # BALLOC: ASSERTION `K <= 15' FAILED. +--echo # Bug#12985021 SIMPLE QUERY WITH DECIMAL NUMBERS TAKE AN +--echo # EXTRAORDINARY LONG TIME TO EXECUTE + +SELECT @tmp_max:= @@global.max_allowed_packet; +SET @@global.max_allowed_packet=1024*1024*1024; +# switching connection to allow the new max_allowed_packet take effect +--connect (newconn, localhost, root,,) + +SELECT @@global.max_allowed_packet; + +do +format(rpad('111111111.1', + 1111111, + '999999999999999999999999999999999999999999'),0,'be_BY') +; + +DO +round( + concat( ( + coalesce( ( + linefromwkb('2147483648', + -b'1111111111111111111111111111111111111111111')), + ( convert('[.DC2.]',decimal(30,30)) ), + bit_count('') + ) ), + ( lpad( ( elt('01','}:K5')), + sha1('P'), + ( ( select '-9223372036854775808.1' > all (select ''))) + ) + ) + ) +); + +--connection default +SET @@global.max_allowed_packet:= @tmp_max; +--disconnect newconn --echo # --echo # End of 5.5 tests diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 57a5a656591..b6c70485dbc 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -915,6 +915,67 @@ SELECT WEEK(DATE_ADD(FROM_DAYS(1),INTERVAL 1 MONTH), 1); DO WEEK((DATE_ADD((CAST(0 AS DATE)), INTERVAL 1 YEAR_MONTH)), 5); +--echo # +--echo # BUG#13458237 INCONSISTENT HANDLING OF INVALIDE DATES WITH ZERO DAY +--echo # SIMILAR TO '2009-10-00' +--echo # + +query_vertical SELECT + DATE('20091000'), + STR_TO_DATE('200910','%Y%m'), + LAST_DAY('2009-10-00'), + LAST_DAY(DATE('2009-10-00')), + LAST_DAY(DATE'2009-10-00'), + LAST_DAY(STR_TO_DATE('200910','%Y%m')), + WEEK('2009-10-00'), + WEEK(DATE('2009-10-00')), + WEEK(DATE'2009-10-00'), + WEEK(STR_TO_DATE('200910','%Y%m')), + WEEKOFYEAR('2009-10-00'), + WEEKOFYEAR(DATE('2009-10-00')), + WEEKOFYEAR(DATE'2009-10-00'), + WEEKOFYEAR(STR_TO_DATE('200910','%Y%m')), + DAYOFYEAR('2009-10-00'), + DAYOFYEAR(DATE('2009-10-00')), + DAYOFYEAR(DATE'2009-10-00'), + DAYOFYEAR(STR_TO_DATE('200910','%Y%m')), + WEEKDAY('2009-10-00'), + WEEKDAY(DATE('2009-10-00')), + WEEKDAY(DATE'2009-10-00'), + WEEKDAY(STR_TO_DATE('200910','%Y%m')), + TO_DAYs('2009-10-00'), + TO_DAYs(DATE('2009-10-00')), + TO_DAYs(DATE'2009-10-00'), + TO_DAYs(STR_TO_DATE('200910','%Y%m')); + +query_vertical SELECT + DATE('00000100'), + STR_TO_DATE('000001','%Y%m'), + LAST_DAY('0000-01-00'), + LAST_DAY(DATE('0000-01-00')), + LAST_DAY(DATE'0000-01-00'), + LAST_DAY(STR_TO_DATE('000001','%Y%m')), + WEEK('0000-01-00'), + WEEK(DATE('0000-01-00')), + WEEK(DATE'0000-01-00'), + WEEK(STR_TO_DATE('000001','%Y%m')), + WEEKOFYEAR('0000-01-00'), + WEEKOFYEAR(DATE('0000-01-00')), + WEEKOFYEAR(DATE'0000-01-00'), + WEEKOFYEAR(STR_TO_DATE('000001','%Y%m')), + DAYOFYEAR('0000-01-00'), + DAYOFYEAR(DATE('0000-01-00')), + DAYOFYEAR(DATE'0000-01-00'), + DAYOFYEAR(STR_TO_DATE('000001','%Y%m')), + WEEKDAY('0000-01-00'), + WEEKDAY(DATE('0000-01-00')), + WEEKDAY(DATE'0000-01-00'), + WEEKDAY(STR_TO_DATE('000001','%Y%m')), + TO_DAYs('0000-01-00'), + TO_DAYs(DATE('0000-01-00')), + TO_DAYs(DATE'0000-01-00'), + TO_DAYs(STR_TO_DATE('000001','%Y%m')); + --echo End of 5.1 tests --echo # @@ -940,6 +1001,21 @@ SELECT MONTHNAME(0), MONTHNAME(0) IS NULL, MONTHNAME(0) + 1; --error ER_WRONG_VALUE_FOR_VAR SET storage_engine=NULL; + +--echo # +--echo # BUG#13354387 - CRASH IN IN MY_DECIMAL::OPERATOR FOR VIEW AND FUNCTION UNIX_TIMESTAMP +--echo # Part1 (5.5) +SET time_zone='+03:00'; +CREATE TABLE t1 (a DATETIME NOT NULL); +INSERT INTO t1 VALUES ('2009-09-20 07:32:39.06'); +INSERT INTO t1 VALUES ('0000-00-00 00:00:00.00'); +CREATE VIEW v1 AS SELECT * FROM t1; +SELECT CAST(UNIX_TIMESTAMP(a) AS DECIMAL(25,3)) AS c1 FROM v1 ORDER BY 1; +DROP VIEW v1; +DROP TABLE t1; +SET time_zone=DEFAULT; + + --echo # --echo # Bug #59686 crash in String::copy() with time data type --echo # diff --git a/mysql-test/t/init_connect.test b/mysql-test/t/init_connect.test index b6bac5f65fa..e96d02fe0d1 100644 --- a/mysql-test/t/init_connect.test +++ b/mysql-test/t/init_connect.test @@ -36,6 +36,14 @@ connection con0; set GLOBAL init_connect="adsfsdfsdfs"; connect (con5,localhost,user_1,,); connection con5; +# BUG#11755281/47032: ERROR 2006 / ERROR 2013 INSTEAD OF PROPER ERROR MESSAGE +# We now throw a proper error message here: +--replace_regex /connection .* to/connection to/ +--error ER_NEW_ABORTING_CONNECTION +select @a; +# We got disconnected after receiving the above error message; any further +# requests should fail with a notice that no one's listening to us. +# --error CR_SERVER_GONE_ERROR,CR_SERVER_LOST --error 2013,2006 select @a; connection con0; diff --git a/mysql-test/t/mysql_plugin.test b/mysql-test/t/mysql_plugin.test index e44ef421760..f1bbd7d1f60 100644 --- a/mysql-test/t/mysql_plugin.test +++ b/mysql-test/t/mysql_plugin.test @@ -155,6 +155,74 @@ eval INSERT INTO mysql.plugin VALUES ('wonky', '$DAEMONEXAMPLE'); --replace_regex /\.dll/.so/ SELECT * FROM mysql.plugin WHERE dl like 'libdaemon%' ORDER BY name; +# MTR will remove this file later, but this might be too late. +--error 0,1 +--remove_file $expect_file +--write_file $expect_file +wait +EOF +--shutdown_server 10 +--source include/wait_until_disconnected.inc + +# +# Disable the plugin - to remove winky, wonky entries +# +--exec $MYSQL_PLUGIN_CMD DISABLE daemon_example + +# +# Enable the plugin again +# +--exec $MYSQL_PLUGIN_CMD ENABLE daemon_example + +# +# Restart the server +# +--append_file $expect_file +restart +EOF +--enable_reconnect +--source include/wait_until_connected_again.inc + +--echo # +--echo # Ensure the plugin is loaded. +--echo # +--replace_regex /\.dll/.so/ +SELECT * FROM mysql.plugin WHERE dl like '%libdaemon%' ORDER BY name; + +# MTR will remove this file later, but this might be too late. +--error 0,1 +--remove_file $expect_file +--write_file $expect_file +wait +EOF +--shutdown_server 10 +--source include/wait_until_disconnected.inc + +# To test the case where the same plugin is reloaded with a different soname, +# we must copy the example daemon to a new location renaming it. + +let $DAEMON_RELOAD = lib$DAEMONEXAMPLE; +--copy_file $PLUGIN_DIR/$DAEMONEXAMPLE $PLUGIN_DIR/$DAEMON_RELOAD +--copy_file include/libdaemon_example.ini $PLUGIN_DIR/libdaemon_example.ini + +# Now reload it and see that it is a different name. +--exec $MYSQL_PLUGIN_CMD ENABLE libdaemon_example + +# +# Restart the server +# +--append_file $expect_file +restart +EOF +--enable_reconnect +--source include/wait_until_connected_again.inc + +--echo # +--echo # Ensure the plugin is replaced. +--echo # +--replace_regex /\.dll/.so/ +SELECT * FROM mysql.plugin WHERE dl like '%libdaemon%' ORDER BY name; + --echo # --echo # Disable the plugin... --echo # @@ -170,7 +238,12 @@ EOF # # Disable the plugin # ---exec $MYSQL_PLUGIN_CMD DISABLE daemon_example +--exec $MYSQL_PLUGIN_CMD DISABLE libdaemon_example + +# Remove files for last test case. + +--remove_file $PLUGIN_DIR/$DAEMON_RELOAD +--remove_file $DAEMONEXAMPLE_DIR/libdaemon_example.ini # # Restart the server @@ -184,7 +257,7 @@ EOF --echo # --echo # Ensure the plugin isn't loaded. --echo # -SELECT * FROM mysql.plugin WHERE dl like 'libdaemon%' ORDER BY name; +SELECT * FROM mysql.plugin WHERE dl like '%libdaemon%' ORDER BY name; # # Stop the server for error conditions diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index e224bf6afe3..62d48f6b8e9 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -2201,6 +2201,118 @@ DROP DATABASE `test-database`; # Switching back to test database. USE test; +--echo # +--echo # BUG#11760384 : 52792: mysqldump in XML mode does not dump routines. +--echo # +CREATE DATABASE BUG52792; +USE BUG52792; +CREATE TABLE t1 (c1 INT, c2 VARCHAR(20)); +CREATE TABLE t2 (c1 INT); +INSERT INTO t1 VALUES (1, 'aaa'), (2, 'bbb'), (3, 'ccc'); +INSERT INTO t2 VALUES (1),(2),(3); + +--echo # Stored Procedures. + +DELIMITER //; +CREATE PROCEDURE simpleproc1 (OUT param1 INT) +BEGIN + SELECT COUNT(*) INTO param1 FROM t1; +END// +DELIMITER ;// + +DELIMITER //; +CREATE PROCEDURE simpleproc2 (OUT param1 INT) +BEGIN + SELECT COUNT(*) INTO param1 FROM t2; +END// +DELIMITER ;// + +--echo # Events. + +CREATE EVENT e1 ON SCHEDULE EVERY 1 SECOND DO DROP DATABASE BUG52792; +CREATE EVENT e2 ON SCHEDULE EVERY 1 SECOND DO DROP DATABASE BUG52792; + +--echo # Functions. + +CREATE FUNCTION `hello1` (s CHAR(20)) + RETURNS CHAR(50) DETERMINISTIC +RETURN CONCAT('Hello, ' ,s ,'!'); + +CREATE FUNCTION `hello2` (s CHAR(20)) + RETURNS CHAR(50) DETERMINISTIC +RETURN CONCAT(']]>, ' , s ,'!'); + +--echo # Triggers. + +DELIMITER |; +CREATE TRIGGER trig1 BEFORE INSERT ON t2 + FOR EACH ROW BEGIN + INSERT INTO t2 VALUES(1); +END; +| +DELIMITER ;| + +DELIMITER |; +CREATE TRIGGER trig2 AFTER INSERT ON t2 + FOR EACH ROW BEGIN + INSERT INTO t2 VALUES(1, ']]>'); + INSERT INTO t2 VALUES(2, ''); + INSERT INTO t2 VALUES(3, ' & \ " _'); +END; +| +DELIMITER ;| + +--echo # Views + +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE VIEW v2 AS SELECT * FROM t2; +--echo +--echo # Dumping BUG52792 database in xml format. +--echo +--echo # Running 'replace_regex on timestamp' +--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/--TIME--/ +--exec $MYSQL_DUMP --user=root --compact -R -E --triggers -X BUG52792 +--echo +--echo # Dumping BUG52792 database in xml format with comments. +--echo +--echo # Running 'replace_regex on timestamp' +--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/--TIME--/ +--exec $MYSQL_DUMP --comments --user=root -R -E --triggers -X BUG52792 + +--echo +--echo # Test to check 'Insufficient privileges' error. +--echo + +GRANT ALL PRIVILEGES ON BUG52792.* TO user1; + +connect (conn_1, localhost, user1, , BUG52792, $MASTER_MYPORT, $MASTER_MYSOCK); +connection conn_1; + +--echo # Running 'replace_regex on timestamp' +--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/--TIME--/ +--error 2 +--exec $MYSQL_DUMP --user=user1 -R -E --triggers -X BUG52792 + +connection default; +disconnect conn_1; + +DROP USER user1; +DROP DATABASE BUG52792; +--echo # UTF-8 +CREATE DATABASE BUG52792; +USE BUG52792; +SET NAMES utf8; +CREATE FUNCTION `straße` ( c1 CHAR(20)) + RETURNS CHAR(50) DETERMINISTIC +RETURN CONCAT(']]>, ', s, '!'); + +--exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments --default-character-set=utf8 --compatible=mysql323 -R -X BUG52792 + +DROP DATABASE BUG52792; + +USE test; + --echo # --echo # End of 5.1 tests --echo # @@ -2215,5 +2327,43 @@ CREATE TABLE t1 (a INT); --exec $MYSQL_DUMP --compatible=no_t,no_f --skip-comments test DROP TABLE t1; +--echo # +--echo # Bug#12809202 61854: MYSQLDUMP --SINGLE-TRANSACTION --FLUSH-LOG BREAKS +--echo # CONSISTENCY +--echo # + +--disable_warnings +DROP DATABASE IF EXISTS b12809202_db; +--enable_warnings + +CREATE DATABASE b12809202_db; +CREATE TABLE b12809202_db.t1 (c1 INT); +CREATE TABLE b12809202_db.t2 (c1 INT); + +INSERT INTO b12809202_db.t1 VALUES (1), (2), (3); +INSERT INTO b12809202_db.t2 VALUES (1), (2), (3); + +--echo # Starting mysqldump with --single-transaction & --flush-log options.. +--echo # Note : In the following dump the transaction +--echo # should start only after the logs are +--echo # flushed, as 'flush logs' causes implicit +--echo # commit starting 5.5. +--echo +--echo #### Dump starts here #### +--replace_regex /-- Server version.*// /-- MySQL dump .*// /-- Dump completed on .*/-- Dump completed/ +--exec $MYSQL_DUMP --verbose --single-transaction --flush-log b12809202_db 2>&1 +--echo +--echo #### Dump ends here #### + +# Cleanup +DROP TABLE b12809202_db.t1; +DROP TABLE b12809202_db.t2; +DROP DATABASE b12809202_db; + +--echo # +--echo # Delete all existing binary logs. +--echo # +RESET MASTER; + # Wait till we reached the initial number of concurrent sessions --source include/wait_until_count_sessions.inc diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index 6c9320b708a..30d15798336 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -1392,4 +1392,80 @@ SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk; DROP TABLE t1; +--echo # +--echo # BUG#13519696 - 62940: SELECT RESULTS VARY WITH VERSION AND +--echo # WITH/WITHOUT INDEX RANGE SCAN +--echo # + +create table t1 (id int unsigned not null auto_increment primary key); +insert into t1 values (null); +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +insert into t1 select null from t1; +create table t2 ( + id int unsigned not null auto_increment, + val decimal(5,3) not null, + primary key (id,val), + unique key (val,id), + unique key (id)); +--disable_warnings +insert into t2 select null,id*0.0009 from t1; +--enable_warnings + +select count(val) from t2 ignore index (val) where val > 0.1155; +select count(val) from t2 force index (val) where val > 0.1155; + +drop table t2, t1; + +--echo # +--echo # BUG#13453382 - REGRESSION SINCE 5.1.39, RANGE OPTIMIZER WRONG +--echo # RESULTS WITH DECIMAL CONVERSION +--echo # + +create table t1 (a int,b int,c int,primary key (a,c)); +insert into t1 values (1,1,2),(1,1,3),(1,1,4); +# show that the integer 3 is bigger than the decimal 2.9, +# which should also apply to comparing "c" with 2.9 +# when c is 3. +select convert(3, signed integer) > 2.9; +select * from t1 force index (primary) where a=1 and c>= 2.9; +select * from t1 ignore index (primary) where a=1 and c>= 2.9; +select * from t1 force index (primary) where a=1 and c> 2.9; +select * from t1 ignore index (primary) where a=1 and c> 2.9; +drop table t1; + +--echo # +--echo # BUG#13463488 - 63437: CHAR & BETWEEN WITH INDEX RETURNS WRONG +--echo # RESULT AFTER MYSQL 5.1. +--echo # + +CREATE TABLE t1( + F1 CHAR(5) NOT NULL, + F2 CHAR(5) NOT NULL, + F3 CHAR(5) NOT NULL, + PRIMARY KEY(F1), + INDEX IDX_F2(F2) +); + +INSERT INTO t1 VALUES +('A','A','A'),('AA','AA','AA'),('AAA','AAA','AAA'), +('AAAA','AAAA','AAAA'),('AAAAA','AAAAA','AAAAA'); + +SELECT * FROM t1 WHERE F1 = 'A '; +SELECT * FROM t1 IGNORE INDEX(PRIMARY) WHERE F1 = 'A '; +SELECT * FROM t1 WHERE F1 >= 'A '; +SELECT * FROM t1 WHERE F1 > 'A '; +SELECT * FROM t1 WHERE F1 BETWEEN 'A ' AND 'AAAAA'; +SELECT * FROM t1 WHERE F2 BETWEEN 'A ' AND 'AAAAA'; +SELECT * FROM t1 WHERE F3 BETWEEN 'A ' AND 'AAAAA'; +SELECT * FROM t1 IGNORE INDEX(PRIMARY) WHERE F1 BETWEEN 'A ' AND +'AAAAA'; + +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 3f6c50a9095..d0fe9779da9 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -3336,28 +3336,20 @@ drop table t3| --disable_warnings drop procedure if exists bug6857| --enable_warnings -create procedure bug6857(counter int) +create procedure bug6857() begin declare t0, t1 int; declare plus bool default 0; - - set t0 = current_time(); - while counter > 0 do - set counter = counter - 1; - end while; - set t1 = current_time(); + set t0 = unix_timestamp(); + select sleep(1.1); + set t1 = unix_timestamp(); if t1 > t0 then set plus = 1; end if; select plus; end| -# QQ: This is currently disabled. Not only does it slow down a normal test -# run, it makes running with valgrind (or similar tools) extremely -# painful. -# Make sure this takes at least one second on all machines in all builds. -# 30000 makes it about 3 seconds on an old 1.1GHz linux. -#call bug6857(300000)| +call bug6857()| drop procedure bug6857| diff --git a/mysql-test/t/udf_skip_grants-master.opt b/mysql-test/t/udf_skip_grants-master.opt index 5699a3387b8..015d0014da0 100644 --- a/mysql-test/t/udf_skip_grants-master.opt +++ b/mysql-test/t/udf_skip_grants-master.opt @@ -1 +1,2 @@ --skip-grant-tables +$UDF_EXAMPLE_LIB_OPT diff --git a/mysql-test/t/xa.test b/mysql-test/t/xa.test index 8ce9ce52960..cb4345e9479 100644 --- a/mysql-test/t/xa.test +++ b/mysql-test/t/xa.test @@ -338,8 +338,8 @@ DROP TABLE t1; DROP TABLE IF EXISTS t1, t2; --enable_warnings -CREATE TABLE t1 (a INT); -CREATE TABLE t2 (a INT); +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT) ENGINE=InnoDB; START TRANSACTION; INSERT INTO t1 VALUES (1); @@ -359,7 +359,6 @@ let $wait_condition= --echo # Waiting until INSERT ... is blocked --source include/wait_condition.inc DELETE FROM t1; -COMMIT; --echo # Connection con2 --connection con2 @@ -368,6 +367,14 @@ COMMIT; --reap --error ER_XA_RBDEADLOCK XA COMMIT 'xid1'; + +--echo # Connection default +connection default; + +COMMIT; + +--echo # Connection con2 +connection con2; # This caused the assert to be triggered XA START 'xid1'; diff --git a/mysys/charset-def.c b/mysys/charset-def.c index 2cff57be4b4..2a1ced1c2ac 100644 --- a/mysys/charset-def.c +++ b/mysys/charset-def.c @@ -204,6 +204,7 @@ my_bool init_compiled_charsets(myf flags __attribute__((unused))) #ifdef HAVE_CHARSET_ucs2 add_compiled_collation(&my_charset_ucs2_general_ci); add_compiled_collation(&my_charset_ucs2_bin); + add_compiled_collation(&my_charset_ucs2_general_mysql500_ci); #ifdef HAVE_UCA_COLLATIONS add_compiled_collation(&my_charset_ucs2_unicode_ci); add_compiled_collation(&my_charset_ucs2_icelandic_uca_ci); @@ -236,6 +237,7 @@ my_bool init_compiled_charsets(myf flags __attribute__((unused))) #ifdef HAVE_CHARSET_utf8 add_compiled_collation(&my_charset_utf8_general_ci); add_compiled_collation(&my_charset_utf8_bin); + add_compiled_collation(&my_charset_utf8_general_mysql500_ci); #ifdef HAVE_UTF8_GENERAL_CS add_compiled_collation(&my_charset_utf8_general_cs); #endif diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 67864caf890..ec2b4b5e7ae 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -807,17 +807,55 @@ cmd="$cmd $args" test -n "$NOHUP_NICENESS" && cmd="$cmd < /dev/null" log_notice "Starting $MYSQLD daemon with databases from $DATADIR" + +# variable to track the current number of "fast" (a.k.a. subsecond) restarts +fast_restart=0 +# maximum number of restarts before trottling kicks in +max_fast_restarts=5 +# flag whether a usable sleep command exists +have_sleep=1 + while true do rm -f $safe_mysql_unix_port "$pid_file" # Some extra safety + start_time=`date +%M%S` + eval_log_error "$cmd" + end_time=`date +%M%S` + if test ! -f "$pid_file" # This is removed if normal shutdown then break fi + + # sanity check if time reading is sane and there's sleep + if test $end_time -gt 0 -a $have_sleep -gt 0 + then + # throttle down the fast restarts + if test $end_time -eq $start_time + then + fast_restart=`expr $fast_restart + 1` + if test $fast_restart -ge $max_fast_restarts + then + log_notice "The server is respawning too fast. Sleeping for 1 second." + sleep 1 + sleep_state=$? + if test $sleep_state -gt 0 + then + log_notice "The server is respawning too fast and no working sleep command. Turning off trottling." + have_sleep=0 + fi + + fast_restart=0 + fi + else + fast_restart=0 + fi + fi + if @TARGET_LINUX@ && test $KILL_MYSQLD -eq 1 then # Test if one process was hanging. diff --git a/sql-common/my_time.c b/sql-common/my_time.c index feac016fa00..15627844a64 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -783,7 +783,7 @@ long calc_daynr(uint year,uint month,uint day) temp=(int) ((y/100+1)*3)/4; DBUG_PRINT("exit",("year: %d month: %d day: %d -> daynr: %ld", y+(month <= 2),month,day,delsum+y/4-temp)); - DBUG_ASSERT(delsum+(int) y/4-temp > 0); + DBUG_ASSERT(delsum+(int) y/4-temp >= 0); DBUG_RETURN(delsum+(int) y/4-temp); } /* calc_daynr */ diff --git a/sql/item.cc b/sql/item.cc index c8c68a3924b..7eaea62d538 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -6812,7 +6812,9 @@ bool Item_direct_ref::is_null() bool Item_direct_ref::get_date(MYSQL_TIME *ltime,uint fuzzydate) { - return (null_value=(*ref)->get_date(ltime,fuzzydate)); + bool tmp= (*ref)->get_date(ltime, fuzzydate); + null_value= (*ref)->null_value; + return tmp; } @@ -7397,9 +7399,13 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item) or less than the original Item. A 0 may also be returned if out of memory. - @note We only use this on the range optimizer/partition pruning, + @note We use this in the range optimizer/partition pruning, because in some cases we can't store the value in the field without some precision/character loss. + + We similarly use it to verify that expressions like + BIGINT_FIELD + is done correctly (as int/decimal/float according to literal type). */ int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) @@ -7443,7 +7449,7 @@ int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) return my_time_compare(&field_time, &item_time); } - return stringcmp(field_result, item_result); + return sortcmp(field_result, item_result, field->charset()); } if (res_type == INT_RESULT) return 0; // Both are of type int @@ -7455,12 +7461,17 @@ int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) if (item->null_value) return 0; field_val= field->val_decimal(&field_buf); - return my_decimal_cmp(item_val, field_val); + return my_decimal_cmp(field_val, item_val); } - double result= item->val_real(); + /* + The patch for Bug#13463415 started using this function for comparing + BIGINTs. That uncovered a bug in Visual Studio 32bit optimized mode. + Prefixing the auto variables with volatile fixes the problem.... + */ + volatile double result= item->val_real(); if (item->null_value) return 0; - double field_result= field->val_real(); + volatile double field_result= field->val_real(); if (field_result < result) return -1; else if (field_result > result) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index f30b6adcb93..fb9878ccb0a 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -435,11 +435,22 @@ static bool convert_constant_item(THD *thd, Item_field *field_item, orig_field_val= field->val_int(); if (!(*item)->is_null() && !(*item)->save_in_field(field, 1)) { - Item *tmp= new Item_int_with_ref(field->val_int(), *item, - test(field->flags & UNSIGNED_FLAG)); - if (tmp) - thd->change_item_tree(item, tmp); - result= 1; // Item was replaced + int field_cmp= 0; + // If item is a decimal value, we must reject it if it was truncated. + if (field->type() == MYSQL_TYPE_LONGLONG) + { + field_cmp= stored_field_cmp_to_item(thd, field, *item); + DBUG_PRINT("info", ("convert_constant_item %d", field_cmp)); + } + + if (0 == field_cmp) + { + Item *tmp= new Item_int_with_ref(field->val_int(), *item, + test(field->flags & UNSIGNED_FLAG)); + if (tmp) + thd->change_item_tree(item, tmp); + result= 1; // Item was replaced + } } /* Restore the original field value. */ if (save_field_value) @@ -2321,10 +2332,10 @@ void Item_func_between::fix_length_and_dec() The following can't be recoded with || as convert_constant_item changes the argument */ - if (convert_constant_item(thd, field_item, &args[1])) - cmp_type=INT_RESULT; // Works for all types. - if (convert_constant_item(thd, field_item, &args[2])) - cmp_type=INT_RESULT; // Works for all types. + const bool cvt_arg1= convert_constant_item(thd, field_item, &args[1]); + const bool cvt_arg2= convert_constant_item(thd, field_item, &args[2]); + if (cvt_arg1 && cvt_arg2) + cmp_type=INT_RESULT; // Works for all types. } } } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 6519146d040..97ba38aa5be 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2747,7 +2747,7 @@ String *Item_time_typecast::val_str(String *str) bool Item_date_typecast::get_date(MYSQL_TIME *ltime, uint fuzzy_date) { - bool res= get_arg0_date(ltime, fuzzy_date); + bool res= get_arg0_date(ltime, TIME_FUZZY_DATE); ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0; ltime->time_type= MYSQL_TIMESTAMP_DATE; return res; diff --git a/sql/log_event.h b/sql/log_event.h index d65f2d2c85d..6782f237a36 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -717,11 +717,11 @@ typedef struct st_print_event_info Such identifier is not yet unique generally as the event originating master is resetable. Also the crashed master can be replaced with some other. */ -struct event_coordinates +typedef struct event_coordinates { char * file_name; // binlog file name (directories stripped) my_off_t pos; // event's position in the binlog file -}; +} LOG_POS_COORD; /** @class Log_event diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 2394625d3cb..6064e5737e5 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -512,6 +512,11 @@ uint sync_binlog_period= 0, sync_relaylog_period= 0, sync_relayloginfo_period= 0, sync_masterinfo_period= 0; ulong expire_logs_days = 0; ulong rpl_recovery_rank=0; +/** + Soft upper limit for number of sp_head objects that can be stored + in the sp_cache for one connection. +*/ +ulong stored_program_cache_size= 0; const double log_10[] = { 1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009, @@ -7477,8 +7482,10 @@ static int fix_paths(void) (void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir (void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home); (void) my_load_path(pidfile_name, pidfile_name_ptr, mysql_real_data_home); - (void) my_load_path(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr : - get_relative_path(PLUGINDIR), mysql_home); + + convert_dirname(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr : + get_relative_path(PLUGINDIR), NullS); + (void) my_load_path(opt_plugin_dir, opt_plugin_dir, mysql_home); opt_plugin_dir_ptr= opt_plugin_dir; my_realpath(mysql_unpacked_real_data_home, mysql_real_data_home, MYF(0)); @@ -7681,8 +7688,10 @@ PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_prep_xids, key_LOCK_system_variables_hash, key_LOCK_table_share, key_LOCK_thd_data, key_LOCK_user_conn, key_LOCK_uuid_generator, key_LOG_LOCK_log, key_master_info_data_lock, key_master_info_run_lock, + key_master_info_sleep_lock, key_mutex_slave_reporting_capability_err_lock, key_relay_log_info_data_lock, key_relay_log_info_log_space_lock, key_relay_log_info_run_lock, + key_relay_log_info_sleep_lock, key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data, key_LOCK_error_messages, key_LOG_INFO_lock, key_LOCK_thread_count, key_PARTITION_LOCK_auto_inc; @@ -7728,10 +7737,12 @@ static PSI_mutex_info all_server_mutexes[]= { &key_LOG_LOCK_log, "LOG::LOCK_log", 0}, { &key_master_info_data_lock, "Master_info::data_lock", 0}, { &key_master_info_run_lock, "Master_info::run_lock", 0}, + { &key_master_info_sleep_lock, "Master_info::sleep_lock", 0}, { &key_mutex_slave_reporting_capability_err_lock, "Slave_reporting_capability::err_lock", 0}, { &key_relay_log_info_data_lock, "Relay_log_info::data_lock", 0}, { &key_relay_log_info_log_space_lock, "Relay_log_info::log_space_lock", 0}, { &key_relay_log_info_run_lock, "Relay_log_info::run_lock", 0}, + { &key_relay_log_info_sleep_lock, "Relay_log_info::sleep_lock", 0}, { &key_structure_guard_mutex, "Query_cache::structure_guard_mutex", 0}, { &key_TABLE_SHARE_LOCK_ha_data, "TABLE_SHARE::LOCK_ha_data", 0}, { &key_LOCK_error_messages, "LOCK_error_messages", PSI_FLAG_GLOBAL}, @@ -7767,8 +7778,10 @@ PSI_cond_key key_BINLOG_COND_prep_xids, key_BINLOG_update_cond, key_delayed_insert_cond, key_delayed_insert_cond_client, key_item_func_sleep_cond, key_master_info_data_cond, key_master_info_start_cond, key_master_info_stop_cond, + key_master_info_sleep_cond, key_relay_log_info_data_cond, key_relay_log_info_log_space_cond, key_relay_log_info_start_cond, key_relay_log_info_stop_cond, + key_relay_log_info_sleep_cond, key_TABLE_SHARE_cond, key_user_level_lock_cond, key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache; PSI_cond_key key_RELAYLOG_update_cond; @@ -7796,10 +7809,12 @@ static PSI_cond_info all_server_conds[]= { &key_master_info_data_cond, "Master_info::data_cond", 0}, { &key_master_info_start_cond, "Master_info::start_cond", 0}, { &key_master_info_stop_cond, "Master_info::stop_cond", 0}, + { &key_master_info_sleep_cond, "Master_info::sleep_cond", 0}, { &key_relay_log_info_data_cond, "Relay_log_info::data_cond", 0}, { &key_relay_log_info_log_space_cond, "Relay_log_info::log_space_cond", 0}, { &key_relay_log_info_start_cond, "Relay_log_info::start_cond", 0}, { &key_relay_log_info_stop_cond, "Relay_log_info::stop_cond", 0}, + { &key_relay_log_info_sleep_cond, "Relay_log_info::sleep_cond", 0}, { &key_TABLE_SHARE_cond, "TABLE_SHARE::cond", 0}, { &key_user_level_lock_cond, "User_level_lock::cond", 0}, { &key_COND_thread_count, "COND_thread_count", PSI_FLAG_GLOBAL}, diff --git a/sql/mysqld.h b/sql/mysqld.h index 98452e395b5..3f6f116542e 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -181,6 +181,7 @@ extern ulonglong max_binlog_cache_size, max_binlog_stmt_cache_size; extern ulong max_binlog_size, max_relay_log_size; extern ulong opt_binlog_rows_event_max_size; extern ulong rpl_recovery_rank, thread_cache_size; +extern ulong stored_program_cache_size; extern ulong back_log; extern char language[FN_REFLEN]; extern "C" MYSQL_PLUGIN_IMPORT ulong server_id; @@ -245,8 +246,10 @@ extern PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_prep_xids, key_LOCK_table_share, key_LOCK_thd_data, key_LOCK_user_conn, key_LOCK_uuid_generator, key_LOG_LOCK_log, key_master_info_data_lock, key_master_info_run_lock, + key_master_info_sleep_lock, key_mutex_slave_reporting_capability_err_lock, key_relay_log_info_data_lock, key_relay_log_info_log_space_lock, key_relay_log_info_run_lock, + key_relay_log_info_sleep_lock, key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data, key_LOCK_error_messages, key_LOCK_thread_count, key_PARTITION_LOCK_auto_inc; extern PSI_mutex_key key_RELAYLOG_LOCK_index; @@ -265,8 +268,10 @@ extern PSI_cond_key key_BINLOG_COND_prep_xids, key_BINLOG_update_cond, key_delayed_insert_cond, key_delayed_insert_cond_client, key_item_func_sleep_cond, key_master_info_data_cond, key_master_info_start_cond, key_master_info_stop_cond, + key_master_info_sleep_cond, key_relay_log_info_data_cond, key_relay_log_info_log_space_cond, key_relay_log_info_start_cond, key_relay_log_info_stop_cond, + key_relay_log_info_sleep_cond, key_TABLE_SHARE_cond, key_user_level_lock_cond, key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache; extern PSI_cond_key key_RELAYLOG_update_cond; diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index 0060bcb6b1e..fd4af7a827e 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -49,9 +49,11 @@ Master_info::Master_info(bool is_slave_recovery) bzero((char*) &file, sizeof(file)); mysql_mutex_init(key_master_info_run_lock, &run_lock, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_master_info_data_lock, &data_lock, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_master_info_sleep_lock, &sleep_lock, MY_MUTEX_INIT_FAST); mysql_cond_init(key_master_info_data_cond, &data_cond, NULL); mysql_cond_init(key_master_info_start_cond, &start_cond, NULL); mysql_cond_init(key_master_info_stop_cond, &stop_cond, NULL); + mysql_cond_init(key_master_info_sleep_cond, &sleep_cond, NULL); } Master_info::~Master_info() @@ -59,9 +61,11 @@ Master_info::~Master_info() delete_dynamic(&ignore_server_ids); mysql_mutex_destroy(&run_lock); mysql_mutex_destroy(&data_lock); + mysql_mutex_destroy(&sleep_lock); mysql_cond_destroy(&data_cond); mysql_cond_destroy(&start_cond); mysql_cond_destroy(&stop_cond); + mysql_cond_destroy(&sleep_cond); } /** diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index 1434ba45519..690b7e76542 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -78,8 +78,8 @@ class Master_info : public Slave_reporting_capability File fd; // we keep the file open, so we need to remember the file pointer IO_CACHE file; - mysql_mutex_t data_lock, run_lock; - mysql_cond_t data_cond, start_cond, stop_cond; + mysql_mutex_t data_lock, run_lock, sleep_lock; + mysql_cond_t data_cond, start_cond, stop_cond, sleep_cond; THD *io_thd; MYSQL* mysql; uint32 file_id; /* for 3.23 load data infile */ diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 3371406ba65..351ff5843dd 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -75,10 +75,12 @@ Relay_log_info::Relay_log_info(bool is_slave_recovery) &data_lock, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_relay_log_info_log_space_lock, &log_space_lock, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_relay_log_info_sleep_lock, &sleep_lock, MY_MUTEX_INIT_FAST); mysql_cond_init(key_relay_log_info_data_cond, &data_cond, NULL); mysql_cond_init(key_relay_log_info_start_cond, &start_cond, NULL); mysql_cond_init(key_relay_log_info_stop_cond, &stop_cond, NULL); mysql_cond_init(key_relay_log_info_log_space_cond, &log_space_cond, NULL); + mysql_cond_init(key_relay_log_info_sleep_cond, &sleep_cond, NULL); relay_log.init_pthread_objects(); DBUG_VOID_RETURN; } @@ -91,10 +93,12 @@ Relay_log_info::~Relay_log_info() mysql_mutex_destroy(&run_lock); mysql_mutex_destroy(&data_lock); mysql_mutex_destroy(&log_space_lock); + mysql_mutex_destroy(&sleep_lock); mysql_cond_destroy(&data_cond); mysql_cond_destroy(&start_cond); mysql_cond_destroy(&stop_cond); mysql_cond_destroy(&log_space_cond); + mysql_cond_destroy(&sleep_cond); relay_log.cleanup(); DBUG_VOID_RETURN; } diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index c8a0f549e0f..6e0a100fca7 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -138,15 +138,13 @@ class Relay_log_info : public Slave_reporting_capability standard lock acquisition order to avoid deadlocks: run_lock, data_lock, relay_log.LOCK_log, relay_log.LOCK_index */ - mysql_mutex_t data_lock, run_lock; - + mysql_mutex_t data_lock, run_lock, sleep_lock; /* start_cond is broadcast when SQL thread is started stop_cond - when stopped data_cond - when data protected by data_lock changes */ - mysql_cond_t start_cond, stop_cond, data_cond; - + mysql_cond_t start_cond, stop_cond, data_cond, sleep_cond; /* parent Master_info structure */ Master_info *mi; diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index d59ba8df1a8..378eae8cef9 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -4710,14 +4710,14 @@ ER_NOT_SUPPORTED_YET 42000 spa "Esta versión de MySQL no soporta todavia '%s'" swe "Denna version av MySQL kan ännu inte utföra '%s'" ER_MASTER_FATAL_ERROR_READING_BINLOG - nla "Kreeg fatale fout %d: '%-.256s' van master tijdens lezen van data uit binaire log" - eng "Got fatal error %d from master when reading data from binary log: '%-.256s'" - ger "Schwerer Fehler %d: '%-.256s vom Master beim Lesen des binären Logs" - ita "Errore fatale %d: '%-.256s' dal master leggendo i dati dal log binario" - por "Obteve fatal erro %d: '%-.256s' do master quando lendo dados do binary log" - rus "Получена неисправимая ошибка %d: '%-.256s' от головного сервера в процессе выборки данных из двоичного журнала" - spa "Recibió fatal error %d: '%-.256s' del master cuando leyendo datos del binary log" - swe "Fick fatalt fel %d: '%-.256s' från master vid läsning av binärloggen" + nla "Kreeg fatale fout %d: '%-.512s' van master tijdens lezen van data uit binaire log" + eng "Got fatal error %d from master when reading data from binary log: '%-.512s'" + ger "Schwerer Fehler %d: '%-.512s vom Master beim Lesen des binären Logs" + ita "Errore fatale %d: '%-.512s' dal master leggendo i dati dal log binario" + por "Obteve fatal erro %d: '%-.512s' do master quando lendo dados do binary log" + rus "Получена неисправимая ошибка %d: '%-.512s' от головного сервера в процессе выборки данных из двоичного журнала" + spa "Recibió fatal error %d: '%-.512s' del master cuando leyendo datos del binary log" + swe "Fick fatalt fel %d: '%-.512s' från master vid läsning av binärloggen" ER_SLAVE_IGNORED_TABLE eng "Slave SQL thread ignored the query because of replicate-*-table rules" ger "Slave-SQL-Thread hat die Abfrage aufgrund von replicate-*-table-Regeln ignoriert" diff --git a/sql/slave.cc b/sql/slave.cc index 797bd8e37e7..8385921753b 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -68,8 +68,6 @@ bool use_slave_mask = 0; MY_BITMAP slave_error_mask; char slave_skip_error_names[SHOW_VAR_FUNC_BUFF_SIZE]; -typedef bool (*CHECK_KILLED_FUNC)(THD*,void*); - char* slave_load_tmpdir = 0; Master_info *active_mi= 0; my_bool replicate_same_server_id; @@ -152,9 +150,6 @@ static int safe_reconnect(THD* thd, MYSQL* mysql, Master_info* mi, bool suppress_warnings); static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi, bool reconnect, bool suppress_warnings); -static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed, - void* thread_killed_arg); -static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi); static Log_event* next_event(Relay_log_info* rli); static int queue_event(Master_info* mi,const char* buf,ulong event_len); static int terminate_slave_thread(THD *thd, @@ -2068,35 +2063,42 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type) DBUG_RETURN(0); } +/* + Sleep for a given amount of time or until killed. + + @param thd Thread context of the current thread. + @param seconds The number of seconds to sleep. + @param func Function object to check if the thread has been killed. + @param info The Rpl_info object associated with this sleep. -static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed, - void* thread_killed_arg) + @retval True if the thread has been killed, false otherwise. +*/ +template +static inline bool slave_sleep(THD *thd, time_t seconds, + killed_func func, rpl_info info) { - int nap_time; - thr_alarm_t alarmed; - DBUG_ENTER("safe_sleep"); - thr_alarm_init(&alarmed); - time_t start_time= my_time(0); - time_t end_time= start_time+sec; + bool ret; + struct timespec abstime; + const char *old_proc_info; - while ((nap_time= (int) (end_time - start_time)) > 0) - { - ALARM alarm_buff; - /* - The only reason we are asking for alarm is so that - we will be woken up in case of murder, so if we do not get killed, - set the alarm so it goes off after we wake up naturally - */ - thr_alarm(&alarmed, 2 * nap_time, &alarm_buff); - sleep(nap_time); - thr_end_alarm(&alarmed); + mysql_mutex_t *lock= &info->sleep_lock; + mysql_cond_t *cond= &info->sleep_cond; - if ((*thread_killed)(thd,thread_killed_arg)) - DBUG_RETURN(1); - start_time= my_time(0); + /* Absolute system time at which the sleep time expires. */ + set_timespec(abstime, seconds); + mysql_mutex_lock(lock); + old_proc_info= thd->enter_cond(cond, lock, thd->proc_info); + + while (! (ret= func(thd, info))) + { + int error= mysql_cond_timedwait(cond, lock, &abstime); + if (error == ETIMEDOUT || error == ETIME) + break; } - DBUG_RETURN(0); + /* Implicitly unlocks the mutex. */ + thd->exit_cond(old_proc_info); + return ret; } @@ -2555,8 +2557,8 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli) exec_res= 0; rli->cleanup_context(thd, 1); /* chance for concurrent connection to get more locks */ - safe_sleep(thd, min(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE), - (CHECK_KILLED_FUNC)sql_slave_killed, (void*)rli); + slave_sleep(thd, min(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE), + sql_slave_killed, rli); mysql_mutex_lock(&rli->data_lock); // because of SHOW STATUS rli->trans_retries++; rli->retried_trans++; @@ -2654,8 +2656,7 @@ static int try_to_reconnect(THD *thd, MYSQL *mysql, Master_info *mi, { if (*retry_count > master_retry_count) return 1; // Don't retry forever - safe_sleep(thd, mi->connect_retry, (CHECK_KILLED_FUNC) io_slave_killed, - (void *) mi); + slave_sleep(thd, mi->connect_retry, io_slave_killed, mi); } if (check_io_slave_killed(thd, mi, messages[SLAVE_RECON_MSG_KILLED_WAITING])) return 1; @@ -4248,8 +4249,7 @@ static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi, change_rpl_status(RPL_ACTIVE_SLAVE,RPL_LOST_SOLDIER); break; } - safe_sleep(thd,mi->connect_retry,(CHECK_KILLED_FUNC)io_slave_killed, - (void*)mi); + slave_sleep(thd,mi->connect_retry,io_slave_killed, mi); } if (!slave_was_killed) diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc index 8972303ef03..d6445799a36 100644 --- a/sql/sp_cache.cc +++ b/sql/sp_cache.cc @@ -57,6 +57,20 @@ class sp_cache { my_hash_delete(&m_hashtable, (uchar *)sp); } + + /** + Remove all elements from a stored routine cache if the current + number of elements exceeds the argument value. + + @param[in] upper_limit_for_elements Soft upper limit of elements that + can be stored in the cache. + */ + void enforce_limit(ulong upper_limit_for_elements) + { + if (m_hashtable.records > upper_limit_for_elements) + my_hash_reset(&m_hashtable); + } + private: void init(); void cleanup(); @@ -228,6 +242,21 @@ ulong sp_cache_version() } +/** + Enforce that the current number of elements in the cache don't exceed + the argument value by flushing the cache if necessary. + + @param[in] c Cache to check + @param[in] upper_limit_for_elements Soft upper limit for number of sp_head + objects that can be stored in the cache. +*/ +void +sp_cache_enforce_limit(sp_cache *c, ulong upper_limit_for_elements) +{ + if (c) + c->enforce_limit(upper_limit_for_elements); +} + /************************************************************************* Internal functions *************************************************************************/ diff --git a/sql/sp_cache.h b/sql/sp_cache.h index 39448568a76..db70066587a 100644 --- a/sql/sp_cache.h +++ b/sql/sp_cache.h @@ -62,5 +62,6 @@ sp_head *sp_cache_lookup(sp_cache **cp, sp_name *name); void sp_cache_invalidate(); void sp_cache_flush_obsolete(sp_cache **cp, sp_head **sp); ulong sp_cache_version(); +void sp_cache_enforce_limit(sp_cache *cp, ulong upper_limit_for_elements); #endif /* _SP_CACHE_H_ */ diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index e96d0e818c7..e08303dcb51 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -668,13 +668,38 @@ void prepare_new_connection_state(THD* thd) execute_init_command(thd, &opt_init_connect, &LOCK_sys_init_connect); if (thd->is_error()) { - thd->killed= THD::KILL_CONNECTION; + ulong packet_length; + NET *net= &thd->net; + sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION), - thd->thread_id,(thd->db ? thd->db : "unconnected"), + thd->thread_id, + thd->db ? thd->db : "unconnected", sctx->user ? sctx->user : "unauthenticated", sctx->host_or_ip, "init_connect command failed"); sql_print_warning("%s", thd->stmt_da->message()); + + thd->lex->current_select= 0; + my_net_set_read_timeout(net, thd->variables.net_wait_timeout); + thd->clear_error(); + net_new_transaction(net); + packet_length= my_net_read(net); + /* + If my_net_read() failed, my_error() has been already called, + and the main Diagnostics Area contains an error condition. + */ + if (packet_length != packet_error) + my_error(ER_NEW_ABORTING_CONNECTION, MYF(0), + thd->thread_id, + thd->db ? thd->db : "unconnected", + sctx->user ? sctx->user : "unauthenticated", + sctx->host_or_ip, "init_connect command failed"); + + thd->server_status&= ~SERVER_STATUS_CLEAR_SET; + thd->protocol->end_statement(); + thd->killed = THD::KILL_CONNECTION; + return; } + thd->proc_info=0; thd->set_time(); thd->init_for_queries(); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 9efe909bd04..63c1d89ed09 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5667,6 +5667,8 @@ void mysql_parse(THD *thd, char *rawbuf, uint length, query_cache_abort(&thd->query_cache_tls); } thd_proc_info(thd, "freeing items"); + sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size); + sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size); thd->end_statement(); thd->cleanup_after_query(); DBUG_ASSERT(thd->change_list.is_empty()); diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 2b801b65a09..4a2d450f373 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -463,18 +463,22 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) dlpathlen= strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", dl->str, NullS) - dlpath; + (void) unpack_filename(dlpath, dlpath); plugin_dl.ref_count= 1; /* Open new dll handle */ if (!(plugin_dl.handle= dlopen(dlpath, RTLD_NOW))) { - const char *errmsg=dlerror(); + const char *errmsg; + int error_number= dlopen_errno; + DLERROR_GENERATE(errmsg, error_number); + if (!strncmp(dlpath, errmsg, dlpathlen)) { // if errmsg starts from dlpath, trim this prefix. errmsg+=dlpathlen; if (*errmsg == ':') errmsg++; if (*errmsg == ' ') errmsg++; } - report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, errno, errmsg); + report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, error_number, errmsg); DBUG_RETURN(0); } /* Determine interface version */ diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 48b6886f6f2..cfdf7d27e58 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2195,6 +2195,9 @@ void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length) thd->protocol= save_protocol; + sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size); + sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size); + /* check_prepared_statemnt sends the metadata packet in case of success */ DBUG_VOID_RETURN; } @@ -2560,6 +2563,9 @@ void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length) stmt->execute_loop(&expanded_query, open_cursor, packet, packet_end); thd->protocol= save_protocol; + sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size); + sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size); + /* Close connection socket; for use with client testing (Bug#43560). */ DBUG_EXECUTE_IF("close_conn_after_stmt_execute", vio_close(thd->net.vio);); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 5300a327029..605acc1f393 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -447,8 +447,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, String* packet = &thd->packet; int error; const char *errmsg = "Unknown error"; - const char *fmt= "%s; the last event was read from '%s' at %s, the last byte read was read from '%s' at %s."; - char llbuff1[22], llbuff2[22]; + char llbuff0[22], llbuff1[22], llbuff2[22]; char error_text[MAX_SLAVE_ERRMSG]; // to be send to slave via my_message() NET* net = &thd->net; mysql_mutex_t *log_lock; @@ -468,16 +467,15 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, */ ulonglong heartbeat_period= get_heartbeat_period(thd); struct timespec heartbeat_buf; - struct event_coordinates coord_buf; struct timespec *heartbeat_ts= NULL; - struct event_coordinates *coord= NULL; + const LOG_POS_COORD start_coord= { log_ident, pos }, + *p_start_coord= &start_coord; + LOG_POS_COORD coord_buf= { log_file_name, BIN_LOG_HEADER_SIZE }, + *p_coord= &coord_buf; if (heartbeat_period != LL(0)) { heartbeat_ts= &heartbeat_buf; set_timespec_nsec(*heartbeat_ts, 0); - coord= &coord_buf; - coord->file_name= log_file_name; // initialization basing on what slave remembers - coord->pos= pos; } sql_print_information("Start binlog_dump to slave_server(%d), pos(%s, %lu)", thd->server_id, log_ident, (ulong)pos); @@ -597,6 +595,7 @@ impossible position"; mysql_bin_log, and it's already inited, and it will be destroyed only at shutdown). */ + p_coord->pos= pos; // the first hb matches the slave's last seen value log_lock= mysql_bin_log.get_log_lock(); log_cond= mysql_bin_log.get_log_cond(); if (pos > BIN_LOG_HEADER_SIZE) @@ -694,8 +693,7 @@ impossible position"; /* log's filename does not change while it's active */ - if (coord) - coord->pos= uint4korr(packet->ptr() + ev_offset + LOG_POS_OFFSET); + p_coord->pos= uint4korr(packet->ptr() + ev_offset + LOG_POS_OFFSET); event_type= (Log_event_type)((*packet)[LOG_EVENT_OFFSET+ev_offset]); DBUG_EXECUTE_IF("dump_thread_wait_before_send_xid", @@ -851,8 +849,7 @@ impossible position"; /* we read successfully, so we'll need to send it to the slave */ mysql_mutex_unlock(log_lock); read_packet = 1; - if (coord) - coord->pos= uint4korr(packet->ptr() + ev_offset + LOG_POS_OFFSET); + p_coord->pos= uint4korr(packet->ptr() + ev_offset + LOG_POS_OFFSET); event_type= (Log_event_type)((*packet)[LOG_EVENT_OFFSET+ev_offset]); break; @@ -874,16 +871,16 @@ impossible position"; signal_cnt= mysql_bin_log.signal_cnt; do { - if (coord) + if (heartbeat_period != 0) { - DBUG_ASSERT(heartbeat_ts && heartbeat_period != 0); + DBUG_ASSERT(heartbeat_ts); set_timespec_nsec(*heartbeat_ts, heartbeat_period); } thd->enter_cond(log_cond, log_lock, "Master has sent all binlog to slave; " "waiting for binlog to be updated"); ret= mysql_bin_log.wait_for_update_bin_log(thd, heartbeat_ts); - DBUG_ASSERT(ret == 0 || (heartbeat_period != 0 && coord != NULL)); + DBUG_ASSERT(ret == 0 || (heartbeat_period != 0)); if (ret == ETIMEDOUT || ret == ETIME) { #ifndef DBUG_OFF @@ -901,7 +898,7 @@ impossible position"; thd->exit_cond(old_msg); goto err; } - if (send_heartbeat_event(net, packet, coord)) + if (send_heartbeat_event(net, packet, p_coord)) { errmsg = "Failed on my_net_write()"; my_errno= ER_UNKNOWN_ERROR; @@ -1012,8 +1009,7 @@ impossible position"; goto err; } - if (coord) - coord->file_name= log_file_name; // reset to the next + p_coord->file_name= log_file_name; // reset to the next } } @@ -1038,9 +1034,12 @@ impossible position"; detailing the fatal error message with coordinates of the last position read. */ + const char *fmt= "%s; the start event position from '%s' at %s, the last event was read from '%s' at %s, the last byte read was read from '%s' at %s."; my_snprintf(error_text, sizeof(error_text), fmt, errmsg, - coord->file_name, (llstr(coord->pos, llbuff1), llbuff1), - log_file_name, (llstr(my_b_tell(&log), llbuff2), llbuff2)); + p_start_coord->file_name, + (llstr(p_start_coord->pos, llbuff0), llbuff0), + p_coord->file_name, (llstr(p_coord->pos, llbuff1), llbuff1), + log_file_name, (llstr(my_b_tell(&log), llbuff2), llbuff2)); } else strcpy(error_text, errmsg); diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index bf2de4b39bb..44595ace453 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -221,10 +221,15 @@ void udf_init() char dlpath[FN_REFLEN]; strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", tmp->dl, NullS); + (void) unpack_filename(dlpath, dlpath); if (!(dl= dlopen(dlpath, RTLD_NOW))) { + const char *errmsg; + int error_number= dlopen_errno; + DLERROR_GENERATE(errmsg, error_number); + /* Print warning to log */ - sql_print_error(ER(ER_CANT_OPEN_LIBRARY), tmp->dl, errno, dlerror()); + sql_print_error(ER(ER_CANT_OPEN_LIBRARY), tmp->dl, error_number, errmsg); /* Keep the udf in the hash so that we can remove it later */ continue; } @@ -469,12 +474,18 @@ int mysql_create_function(THD *thd,udf_func *udf) { char dlpath[FN_REFLEN]; strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", udf->dl, NullS); + (void) unpack_filename(dlpath, dlpath); + if (!(dl = dlopen(dlpath, RTLD_NOW))) { + const char *errmsg; + int error_number= dlopen_errno; + DLERROR_GENERATE(errmsg, error_number); + DBUG_PRINT("error",("dlopen of %s failed, error: %d (%s)", - udf->dl, errno, dlerror())); + udf->dl, error_number, errmsg)); my_error(ER_CANT_OPEN_LIBRARY, MYF(0), - udf->dl, errno, dlerror()); + udf->dl, error_number, errmsg); goto err; } new_dl=1; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 2af04e73f06..239691c893a 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3291,6 +3291,13 @@ static Sys_var_tz Sys_time_zone( SESSION_VAR(time_zone), NO_CMD_LINE, DEFAULT(&default_tz), NO_MUTEX_GUARD, IN_BINLOG); +static Sys_var_ulong Sys_sp_cache_size( + "stored_program_cache", + "The soft upper limit for number of cached stored routines for " + "one connection.", + GLOBAL_VAR(stored_program_cache_size), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(256, 512 * 1024), DEFAULT(256), BLOCK_SIZE(1)); + /**************************************************************************** Used templates diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index 06bf180283d..e5421dc30ab 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -1685,6 +1685,16 @@ int ha_federated::close(void) mysql_close(mysql); mysql= NULL; + /* + mysql_close() might return an error if a remote server's gone + for some reason. If that happens while removing a table from + the table cache, the error will be propagated to a client even + if the original query was not issued against the FEDERATED table. + So, don't propagate errors from mysql_close(). + */ + if (table->in_use) + table->in_use->clear_error(); + DBUG_RETURN(free_share(share)); } diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c index b476167af29..88371208230 100644 --- a/storage/innobase/btr/btr0btr.c +++ b/storage/innobase/btr/btr0btr.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -42,6 +42,27 @@ Created 6/2/1994 Heikki Tuuri #include "ibuf0ibuf.h" #include "trx0trx.h" +/**************************************************************//** +Report that an index page is corrupted. */ +UNIV_INTERN +void +btr_corruption_report( +/*==================*/ + const buf_block_t* block, /*!< in: corrupted block */ + const dict_index_t* index) /*!< in: index tree */ +{ + fprintf(stderr, "InnoDB: flag mismatch in space %u page %u" + " index %s of table %s\n", + (unsigned) buf_block_get_space(block), + (unsigned) buf_block_get_page_no(block), + index->name, index->table_name); + buf_page_print(buf_block_get_frame(block), 0); + if (block->page.zip.data) { + buf_page_print(block->page.zip.data, + buf_block_get_zip_size(block)); + } +} + #ifdef UNIV_BLOB_DEBUG # include "srv0srv.h" # include "ut0rbt.h" @@ -692,8 +713,7 @@ btr_root_block_get( block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, index, mtr); - ut_a((ibool)!!page_is_comp(buf_block_get_frame(block)) - == dict_table_is_comp(index->table)); + btr_assert_not_corrupted(block, index); #ifdef UNIV_BTR_DEBUG if (!dict_index_is_ibuf(index)) { const page_t* root = buf_block_get_frame(block); @@ -1532,7 +1552,7 @@ btr_page_reorganize_low( ibool success = FALSE; ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); - ut_ad(!!page_is_comp(page) == dict_table_is_comp(index->table)); + btr_assert_not_corrupted(block, index); #ifdef UNIV_ZIP_DEBUG ut_a(!page_zip || page_zip_validate(page_zip, page)); #endif /* UNIV_ZIP_DEBUG */ @@ -3164,7 +3184,8 @@ btr_compress( block = btr_cur_get_block(cursor); page = btr_cur_get_page(cursor); index = btr_cur_get_index(cursor); - ut_a((ibool) !!page_is_comp(page) == dict_table_is_comp(index->table)); + + btr_assert_not_corrupted(block, index); ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index), MTR_MEMO_X_LOCK)); diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c index 03346337d3f..1551aee5426 100644 --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -408,7 +408,12 @@ btr_cur_search_to_nth_level( ut_ad(dict_index_check_search_tuple(index, tuple)); ut_ad(!dict_index_is_ibuf(index) || ibuf_inside(mtr)); ut_ad(dtuple_check_typed(tuple)); + ut_ad(index->page != FIL_NULL); + UNIV_MEM_INVALID(&cursor->up_match, sizeof cursor->up_match); + UNIV_MEM_INVALID(&cursor->up_bytes, sizeof cursor->up_bytes); + UNIV_MEM_INVALID(&cursor->low_match, sizeof cursor->low_match); + UNIV_MEM_INVALID(&cursor->low_bytes, sizeof cursor->low_bytes); #ifdef UNIV_DEBUG cursor->up_match = ULINT_UNDEFINED; cursor->low_match = ULINT_UNDEFINED; @@ -757,11 +762,11 @@ btr_cur_search_to_nth_level( if (level != 0) { /* x-latch the page */ - page = btr_page_get( + buf_block_t* child_block = btr_block_get( space, zip_size, page_no, RW_X_LATCH, index, mtr); - ut_a((ibool)!!page_is_comp(page) - == dict_table_is_comp(index->table)); + page = buf_block_get_frame(child_block); + btr_assert_not_corrupted(child_block, index); } else { cursor->low_match = low_match; cursor->low_bytes = low_bytes; diff --git a/storage/innobase/btr/btr0pcur.c b/storage/innobase/btr/btr0pcur.c index 57d9752649f..fb153556b2f 100644 --- a/storage/innobase/btr/btr0pcur.c +++ b/storage/innobase/btr/btr0pcur.c @@ -52,12 +52,13 @@ btr_pcur_create_for_mysql(void) } /**************************************************************//** -Frees the memory for a persistent cursor object. */ +Resets a persistent cursor object, freeing ::old_rec_buf if it is +allocated and resetting the other members to their initial values. */ UNIV_INTERN void -btr_pcur_free_for_mysql( -/*====================*/ - btr_pcur_t* cursor) /*!< in, own: persistent cursor */ +btr_pcur_reset( +/*===========*/ + btr_pcur_t* cursor) /*!< in, out: persistent cursor */ { if (cursor->old_rec_buf != NULL) { @@ -66,6 +67,7 @@ btr_pcur_free_for_mysql( cursor->old_rec_buf = NULL; } + cursor->btr_cur.index = NULL; cursor->btr_cur.page_cur.rec = NULL; cursor->old_rec = NULL; cursor->old_n_fields = 0; @@ -73,7 +75,17 @@ btr_pcur_free_for_mysql( cursor->latch_mode = BTR_NO_LATCHES; cursor->pos_state = BTR_PCUR_NOT_POSITIONED; +} +/**************************************************************//** +Frees the memory for a persistent cursor object. */ +UNIV_INTERN +void +btr_pcur_free_for_mysql( +/*====================*/ + btr_pcur_t* cursor) /*!< in, own: persistent cursor */ +{ + btr_pcur_reset(cursor); mem_free(cursor); } diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index e9990d3fbda..7936e70617a 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -606,6 +606,8 @@ buf_page_print( ulint old_checksum; ulint size = zip_size; + ut_ad(0); + if (!size) { size = UNIV_PAGE_SIZE; } @@ -981,11 +983,8 @@ buf_chunk_init( for (i = chunk->size; i--; ) { buf_block_init(buf_pool, block, frame); + UNIV_MEM_INVALID(block->frame, UNIV_PAGE_SIZE); -#ifdef HAVE_purify - /* Wipe contents of frame to eliminate a Purify warning */ - memset(block->frame, '\0', UNIV_PAGE_SIZE); -#endif /* Add the block to the free list */ UT_LIST_ADD_LAST(list, buf_pool->free, (&block->page)); @@ -2827,7 +2826,7 @@ buf_page_get_known_nowait( ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG - ut_a(block->page.file_page_was_freed == FALSE); + ut_a(mode == BUF_KEEP_OLD || !block->page.file_page_was_freed); #endif #ifdef UNIV_IBUF_COUNT_DEBUG diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c index e13cc1b31f1..9828326dde1 100644 --- a/storage/innobase/dict/dict0load.c +++ b/storage/innobase/dict/dict0load.c @@ -2066,8 +2066,9 @@ static void dict_load_foreign_cols( /*===================*/ - const char* id, /*!< in: foreign constraint id as a - null-terminated string */ + const char* id, /*!< in: foreign constraint id, not + necessary '\0'-terminated */ + ulint id_len, /*!< in: id length */ dict_foreign_t* foreign)/*!< in: foreign constraint object */ { dict_table_t* sys_foreign_cols; @@ -2097,7 +2098,7 @@ dict_load_foreign_cols( tuple = dtuple_create(foreign->heap, 1); dfield = dtuple_get_nth_field(tuple, 0); - dfield_set_data(dfield, id, ut_strlen(id)); + dfield_set_data(dfield, id, id_len); dict_index_copy_types(tuple, sys_index, 1); btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, @@ -2110,7 +2111,7 @@ dict_load_foreign_cols( ut_a(!rec_get_deleted_flag(rec, 0)); field = rec_get_nth_field_old(rec, 0, &len); - ut_a(len == ut_strlen(id)); + ut_a(len == id_len); ut_a(ut_memcmp(id, field, len) == 0); field = rec_get_nth_field_old(rec, 1, &len); @@ -2139,8 +2140,9 @@ static ulint dict_load_foreign( /*==============*/ - const char* id, /*!< in: foreign constraint id as a - null-terminated string */ + const char* id, /*!< in: foreign constraint id, not + necessary '\0'-terminated */ + ulint id_len, /*!< in: id length */ ibool check_charsets, /*!< in: TRUE=check charset compatibility */ ibool check_recursive) @@ -2176,7 +2178,7 @@ dict_load_foreign( tuple = dtuple_create(heap2, 1); dfield = dtuple_get_nth_field(tuple, 0); - dfield_set_data(dfield, id, ut_strlen(id)); + dfield_set_data(dfield, id, id_len); dict_index_copy_types(tuple, sys_index, 1); btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, @@ -2188,8 +2190,8 @@ dict_load_foreign( /* Not found */ fprintf(stderr, - "InnoDB: Error A: cannot load foreign constraint %s\n", - id); + "InnoDB: Error A: cannot load foreign constraint " + "%.*s\n", (int) id_len, id); btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -2201,11 +2203,11 @@ dict_load_foreign( field = rec_get_nth_field_old(rec, 0, &len); /* Check if the id in record is the searched one */ - if (len != ut_strlen(id) || ut_memcmp(id, field, len) != 0) { + if (len != id_len || ut_memcmp(id, field, len) != 0) { fprintf(stderr, - "InnoDB: Error B: cannot load foreign constraint %s\n", - id); + "InnoDB: Error B: cannot load foreign constraint " + "%.*s\n", (int) id_len, id); btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -2231,7 +2233,7 @@ dict_load_foreign( foreign->type = (unsigned int) (n_fields_and_type >> 24); foreign->n_fields = (unsigned int) (n_fields_and_type & 0x3FFUL); - foreign->id = mem_heap_strdup(foreign->heap, id); + foreign->id = mem_heap_strdupl(foreign->heap, id, id_len); field = rec_get_nth_field_old(rec, 3, &len); @@ -2247,7 +2249,7 @@ dict_load_foreign( btr_pcur_close(&pcur); mtr_commit(&mtr); - dict_load_foreign_cols(id, foreign); + dict_load_foreign_cols(id, id_len, foreign); ref_table = dict_table_check_if_in_cache_low( foreign->referenced_table_name_lookup); @@ -2326,8 +2328,8 @@ dict_load_foreigns( ibool check_charsets) /*!< in: TRUE=check charset compatibility */ { + char tuple_buf[DTUPLE_EST_ALLOC(1)]; btr_pcur_t pcur; - mem_heap_t* heap; dtuple_t* tuple; dfield_t* dfield; dict_index_t* sec_index; @@ -2335,7 +2337,6 @@ dict_load_foreigns( const rec_t* rec; const byte* field; ulint len; - char* id ; ulint err; mtr_t mtr; @@ -2362,9 +2363,8 @@ dict_load_foreigns( sec_index = dict_table_get_next_index( dict_table_get_first_index(sys_foreign)); start_load: - heap = mem_heap_create(256); - tuple = dtuple_create(heap, 1); + tuple = dtuple_create_from_mem(tuple_buf, sizeof(tuple_buf), 1); dfield = dtuple_get_nth_field(tuple, 0); dfield_set_data(dfield, table_name, ut_strlen(table_name)); @@ -2418,7 +2418,6 @@ dict_load_foreigns( /* Now we get a foreign key constraint id */ field = rec_get_nth_field_old(rec, 1, &len); - id = mem_heap_strdupl(heap, (char*) field, len); btr_pcur_store_position(&pcur, &mtr); @@ -2426,11 +2425,11 @@ dict_load_foreigns( /* Load the foreign constraint definition to the dictionary cache */ - err = dict_load_foreign(id, check_charsets, check_recursive); + err = dict_load_foreign((char*) field, len, check_charsets, + check_recursive); if (err != DB_SUCCESS) { btr_pcur_close(&pcur); - mem_heap_free(heap); return(err); } @@ -2446,7 +2445,6 @@ dict_load_foreigns( load_next_index: btr_pcur_close(&pcur); mtr_commit(&mtr); - mem_heap_free(heap); sec_index = dict_table_get_next_index(sec_index); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 6c47ebbe85a..3e186f8f911 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3403,18 +3403,29 @@ ha_innobase::primary_key_is_clustered() return(true); } +/** Always normalize table name to lower case on Windows */ +#ifdef __WIN__ +#define normalize_table_name(norm_name, name) \ + normalize_table_name_low(norm_name, name, TRUE) +#else +#define normalize_table_name(norm_name, name) \ + normalize_table_name_low(norm_name, name, FALSE) +#endif /* __WIN__ */ + /*****************************************************************//** Normalizes a table name string. A normalized name consists of the database name catenated to '/' and table name. An example: test/mytable. On Windows normalization puts both the database name and the -table name always to lower case. */ +table name always to lower case if "set_lower_case" is set to TRUE. */ static void -normalize_table_name( -/*=================*/ +normalize_table_name_low( +/*=====================*/ char* norm_name, /*!< out: normalized name as a null-terminated string */ - const char* name) /*!< in: table name string */ + const char* name, /*!< in: table name string */ + ibool set_lower_case) /*!< in: TRUE if we want to set + name to lower case */ { char* name_ptr; char* db_ptr; @@ -3444,9 +3455,9 @@ normalize_table_name( norm_name[name_ptr - db_ptr - 1] = '/'; -#ifdef __WIN__ - innobase_casedn_str(norm_name); -#endif + if (set_lower_case) { + innobase_casedn_str(norm_name); + } } /********************************************************************//** @@ -3850,6 +3861,8 @@ ha_innobase::open( THD* thd; ulint retries = 0; char* is_part = NULL; + ibool par_case_name_set = FALSE; + char par_case_name[MAX_FULL_NAME_LEN + 1]; DBUG_ENTER("ha_innobase::open"); @@ -3874,38 +3887,96 @@ ha_innobase::open( DBUG_RETURN(1); } - /* Create buffers for packing the fields of a record. Why - table->reclength did not work here? Obviously, because char - fields when packed actually became 1 byte longer, when we also - stored the string length as the first byte. */ - - upd_and_key_val_buff_len = - table->s->reclength + table->s->max_key_length - + MAX_REF_PARTS * 3; - if (!(uchar*) my_multi_malloc(MYF(MY_WME), - &upd_buff, upd_and_key_val_buff_len, - &key_val_buff, upd_and_key_val_buff_len, - NullS)) { - free_share(share); - - DBUG_RETURN(1); - } + /* Will be allocated if it is needed in ::update_row() */ + upd_buf = NULL; + upd_buf_size = 0; /* We look for pattern #P# to see if the table is partitioned MySQL table. The retry logic for partitioned tables is a workaround for http://bugs.mysql.com/bug.php?id=33349. Look at support issue https://support.mysql.com/view.php?id=21080 for more details. */ +#ifdef __WIN__ + is_part = strstr(norm_name, "#p#"); +#else is_part = strstr(norm_name, "#P#"); +#endif /* __WIN__ */ + retry: /* Get pointer to a table object in InnoDB dictionary cache */ ib_table = dict_table_get(norm_name, TRUE); - + if (NULL == ib_table) { if (is_part && retries < 10) { - ++retries; - os_thread_sleep(100000); - goto retry; + /* MySQL partition engine hard codes the file name + separator as "#P#". The text case is fixed even if + lower_case_table_names is set to 1 or 2. This is true + for sub-partition names as well. InnoDB always + normalises file names to lower case on Windows, this + can potentially cause problems when copying/moving + tables between platforms. + + 1) If boot against an installation from Windows + platform, then its partition table name could + be all be in lower case in system tables. So we + will need to check lower case name when load table. + + 2) If we boot an installation from other case + sensitive platform in Windows, we might need to + check the existence of table name without lowering + case them in the system table. */ + if (innobase_get_lower_case_table_names() == 1) { + + if (!par_case_name_set) { +#ifndef __WIN__ + /* Check for the table using lower + case name, including the partition + separator "P" */ + memcpy(par_case_name, norm_name, + strlen(norm_name)); + par_case_name[strlen(norm_name)] = 0; + innobase_casedn_str(par_case_name); +#else + /* On Windows platfrom, check + whether there exists table name in + system table whose name is + not being normalized to lower case */ + normalize_table_name_low( + par_case_name, name, FALSE); +#endif + par_case_name_set = TRUE; + } + + ib_table = dict_table_get( + par_case_name, FALSE); + } + if (!ib_table) { + ++retries; + os_thread_sleep(100000); + goto retry; + } else { +#ifndef __WIN__ + sql_print_warning("Partition table %s opened " + "after converting to lower " + "case. The table may have " + "been moved from a case " + "in-sensitive file system. " + "Please recreate table in " + "the current file system\n", + norm_name); +#else + sql_print_warning("Partition table %s opened " + "after skipping the step to " + "lower case the table name. " + "The table may have been " + "moved from a case sensitive " + "file system. Please " + "recreate table in the " + "current file system\n", + norm_name); +#endif + goto table_opened; + } } if (is_part) { @@ -3930,12 +4001,13 @@ ha_innobase::open( "how you can resolve the problem.\n", norm_name); free_share(share); - my_free(upd_buff); my_errno = ENOENT; DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); } +table_opened: + if (ib_table->ibd_file_missing && !thd_tablespace_op(thd)) { sql_print_error("MySQL is trying to open a table handle but " "the .ibd file for\ntable %s does not exist.\n" @@ -3946,16 +4018,14 @@ ha_innobase::open( "how you can resolve the problem.\n", norm_name); free_share(share); - my_free(upd_buff); my_errno = ENOENT; dict_table_decrement_handle_count(ib_table, FALSE); DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); } - prebuilt = row_create_prebuilt(ib_table); + prebuilt = row_create_prebuilt(ib_table, table->s->reclength); - prebuilt->mysql_row_len = table->s->reclength; prebuilt->default_rec = table->s->default_values; ut_ad(prebuilt->default_rec); @@ -4144,7 +4214,13 @@ ha_innobase::close(void) row_prebuilt_free(prebuilt, FALSE); - my_free(upd_buff); + if (upd_buf != NULL) { + ut_ad(upd_buf_size != 0); + my_free(upd_buf); + upd_buf = NULL; + upd_buf_size = 0; + } + free_share(share); /* Tell InnoDB server that there might be work for @@ -5437,6 +5513,23 @@ ha_innobase::update_row( ut_a(prebuilt->trx == trx); + if (upd_buf == NULL) { + ut_ad(upd_buf_size == 0); + + /* Create a buffer for packing the fields of a record. Why + table->reclength did not work here? Obviously, because char + fields when packed actually became 1 byte longer, when we also + stored the string length as the first byte. */ + + upd_buf_size = table->s->reclength + table->s->max_key_length + + MAX_REF_PARTS * 3; + upd_buf = (uchar*) my_malloc(upd_buf_size, MYF(MY_WME)); + if (upd_buf == NULL) { + upd_buf_size = 0; + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } + } + ha_statistic_increment(&SSV::ha_update_count); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) @@ -5449,11 +5542,10 @@ ha_innobase::update_row( } /* Build an update vector from the modified fields in the rows - (uses upd_buff of the handle) */ + (uses upd_buf of the handle) */ calc_row_difference(uvect, (uchar*) old_row, new_row, table, - upd_buff, (ulint)upd_and_key_val_buff_len, - prebuilt, user_thd); + upd_buf, upd_buf_size, prebuilt, user_thd); /* This is not a delete */ prebuilt->upd_node->is_delete = FALSE; @@ -5830,8 +5922,7 @@ ha_innobase::index_read( row_sel_convert_mysql_key_to_innobase( prebuilt->search_tuple, - (byte*) key_val_buff, - (ulint)upd_and_key_val_buff_len, + srch_key_val1, sizeof(srch_key_val1), index, (byte*) key_ptr, (ulint) key_len, @@ -7649,12 +7740,6 @@ ha_innobase::records_in_range( { KEY* key; dict_index_t* index; - uchar* key_val_buff2 = (uchar*) my_malloc( - table->s->reclength - + table->s->max_key_length + 100, - MYF(MY_FAE)); - ulint buff2_len = table->s->reclength - + table->s->max_key_length + 100; dtuple_t* range_start; dtuple_t* range_end; ib_int64_t n_rows; @@ -7708,8 +7793,8 @@ ha_innobase::records_in_range( dict_index_copy_types(range_end, index, key->key_parts); row_sel_convert_mysql_key_to_innobase( - range_start, (byte*) key_val_buff, - (ulint)upd_and_key_val_buff_len, + range_start, + srch_key_val1, sizeof(srch_key_val1), index, (byte*) (min_key ? min_key->key : (const uchar*) 0), @@ -7720,8 +7805,9 @@ ha_innobase::records_in_range( : range_start->n_fields == 0); row_sel_convert_mysql_key_to_innobase( - range_end, (byte*) key_val_buff2, - buff2_len, index, + range_end, + srch_key_val2, sizeof(srch_key_val2), + index, (byte*) (max_key ? max_key->key : (const uchar*) 0), (ulint) (max_key ? max_key->length : 0), @@ -7748,7 +7834,6 @@ ha_innobase::records_in_range( mem_heap_free(heap); func_exit: - my_free(key_val_buff2); prebuilt->trx->op_info = (char*)""; @@ -11583,6 +11668,13 @@ static MYSQL_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold, "trigger a readahead.", NULL, NULL, 56, 0, 64, 0); +#ifdef UNIV_DEBUG +static MYSQL_SYSVAR_UINT(trx_rseg_n_slots_debug, trx_rseg_n_slots_debug, + PLUGIN_VAR_RQCMDARG, + "Debug flags for InnoDB to limit TRX_RSEG_N_SLOTS for trx_rsegf_undo_find_free()", + NULL, NULL, 0, 0, 1024, 0); +#endif /* UNIV_DEBUG */ + static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(additional_mem_pool_size), MYSQL_SYSVAR(autoextend_increment), @@ -11653,6 +11745,9 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(purge_threads), MYSQL_SYSVAR(purge_batch_size), MYSQL_SYSVAR(rollback_segments), +#ifdef UNIV_DEBUG + MYSQL_SYSVAR(trx_rseg_n_slots_debug), +#endif /* UNIV_DEBUG */ NULL }; diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 7ab91a12e81..5fcac4589cc 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -78,13 +78,14 @@ class ha_innobase: public handler INNOBASE_SHARE* share; /*!< information for MySQL table locking */ - uchar* upd_buff; /*!< buffer used in updates */ - uchar* key_val_buff; /*!< buffer used in converting + uchar* upd_buf; /*!< buffer used in updates */ + ulint upd_buf_size; /*!< the size of upd_buf in bytes */ + uchar srch_key_val1[REC_VERSION_56_MAX_INDEX_COL_LEN + 2]; + uchar srch_key_val2[REC_VERSION_56_MAX_INDEX_COL_LEN + 2]; + /*!< buffers used in converting search key values from MySQL format - to Innodb format */ - ulong upd_and_key_val_buff_len; - /* the length of each of the previous - two buffers */ + to InnoDB format. "+ 2" for the two + bytes where the length is stored */ Table_flags int_table_flags; uint primary_key; ulong start_of_scan; /*!< this is set to 1 when we are diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 6d5b7b4668f..c6754660b84 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -1008,7 +1008,12 @@ ha_innobase::final_add_index( row_prebuilt_free(prebuilt, TRUE); error = row_merge_drop_table(trx, old_table); add->indexed_table->n_mysql_handles_opened++; - prebuilt = row_create_prebuilt(add->indexed_table); + prebuilt = row_create_prebuilt(add->indexed_table, + 0 /* XXX Do we know the mysql_row_len here? + Before the addition of this parameter to + row_create_prebuilt() the mysql_row_len + member was left 0 (from zalloc) in the + prebuilt object. */); } err = convert_error_code_to_mysql( diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c index 47ec1365cb8..96af9038be2 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.c +++ b/storage/innobase/ibuf/ibuf0ibuf.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2012, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -2546,7 +2546,15 @@ ibuf_get_merge_page_nos_func( } else { rec_page_no = ibuf_rec_get_page_no(mtr, rec); rec_space_id = ibuf_rec_get_space(mtr, rec); - ut_ad(rec_page_no > IBUF_TREE_ROOT_PAGE_NO); + /* In the system tablespace, the smallest + possible secondary index leaf page number is + bigger than IBUF_TREE_ROOT_PAGE_NO (4). In + other tablespaces, the clustered index tree is + created at page 3, which makes page 4 the + smallest possible secondary index leaf page + (and that only after DROP INDEX). */ + ut_ad(rec_page_no + > IBUF_TREE_ROOT_PAGE_NO - (rec_space_id != 0)); } #ifdef UNIV_IBUF_DEBUG @@ -3872,6 +3880,7 @@ ibuf_insert_to_index_page_low( fputs("InnoDB: Submit a detailed bug report" " to http://bugs.mysql.com\n", stderr); + ut_ad(0); } /************************************************************************ @@ -4065,6 +4074,11 @@ ibuf_set_del_mark( TRUE, mtr); } } else { + const page_t* page + = page_cur_get_page(&page_cur); + const buf_block_t* block + = page_cur_get_block(&page_cur); + ut_print_timestamp(stderr); fputs(" InnoDB: unable to find a record to delete-mark\n", stderr); @@ -4073,10 +4087,14 @@ ibuf_set_del_mark( fputs("\n" "InnoDB: record ", stderr); rec_print(stderr, page_cur_get_rec(&page_cur), index); - putc('\n', stderr); - fputs("\n" - "InnoDB: Submit a detailed bug report" - " to http://bugs.mysql.com\n", stderr); + fprintf(stderr, "\nspace %u offset %u" + " (%u records, index id %llu)\n" + "InnoDB: Submit a detailed bug report" + " to http://bugs.mysql.com\n", + (unsigned) buf_block_get_space(block), + (unsigned) buf_block_get_page_no(block), + (unsigned) page_get_n_recs(page), + (ulonglong) btr_page_get_index_id(page)); ut_ad(0); } } @@ -4120,12 +4138,31 @@ ibuf_delete( offsets = rec_get_offsets( rec, index, offsets, ULINT_UNDEFINED, &heap); - /* Refuse to delete the last record. */ - ut_a(page_get_n_recs(page) > 1); - - /* The record should have been marked for deletion. */ - ut_ad(REC_INFO_DELETED_FLAG - & rec_get_info_bits(rec, page_is_comp(page))); + if (page_get_n_recs(page) <= 1 + || !(REC_INFO_DELETED_FLAG + & rec_get_info_bits(rec, page_is_comp(page)))) { + /* Refuse to purge the last record or a + record that has not been marked for deletion. */ + ut_print_timestamp(stderr); + fputs(" InnoDB: unable to purge a record\n", + stderr); + fputs("InnoDB: tuple ", stderr); + dtuple_print(stderr, entry); + fputs("\n" + "InnoDB: record ", stderr); + rec_print_new(stderr, rec, offsets); + fprintf(stderr, "\nspace %u offset %u" + " (%u records, index id %llu)\n" + "InnoDB: Submit a detailed bug report" + " to http://bugs.mysql.com\n", + (unsigned) buf_block_get_space(block), + (unsigned) buf_block_get_page_no(block), + (unsigned) page_get_n_recs(page), + (ulonglong) btr_page_get_index_id(page)); + + ut_ad(0); + return; + } lock_update_delete(block, rec); @@ -4211,6 +4248,7 @@ ibuf_restore_pos( fprintf(stderr, "InnoDB: ibuf tree ok\n"); fflush(stderr); + ut_ad(0); } return(FALSE); diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h index 71e772388a0..93b59fdfafb 100644 --- a/storage/innobase/include/btr0btr.h +++ b/storage/innobase/include/btr0btr.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -92,6 +92,26 @@ insert/delete buffer when the record is not in the buffer pool. */ buffer when the record is not in the buffer pool. */ #define BTR_DELETE 8192 +/**************************************************************//** +Report that an index page is corrupted. */ +UNIV_INTERN +void +btr_corruption_report( +/*==================*/ + const buf_block_t* block, /*!< in: corrupted block */ + const dict_index_t* index) /*!< in: index tree */ + UNIV_COLD __attribute__((nonnull)); + +/** Assert that a B-tree page is not corrupted. +@param block buffer block containing a B-tree page +@param index the B-tree index */ +#define btr_assert_not_corrupted(block, index) \ + if ((ibool) !!page_is_comp(buf_block_get_frame(block)) \ + != dict_table_is_comp((index)->table)) { \ + btr_corruption_report(block, index); \ + ut_error; \ + } + #ifdef UNIV_BLOB_DEBUG # include "ut0rbt.h" /** An index->blobs entry for keeping track of off-page column references */ diff --git a/storage/innobase/include/btr0pcur.h b/storage/innobase/include/btr0pcur.h index 140f94466db..2ebd70a6f23 100644 --- a/storage/innobase/include/btr0pcur.h +++ b/storage/innobase/include/btr0pcur.h @@ -53,6 +53,16 @@ UNIV_INTERN btr_pcur_t* btr_pcur_create_for_mysql(void); /*============================*/ + +/**************************************************************//** +Resets a persistent cursor object, freeing ::old_rec_buf if it is +allocated and resetting the other members to their initial values. */ +UNIV_INTERN +void +btr_pcur_reset( +/*===========*/ + btr_pcur_t* cursor);/*!< in, out: persistent cursor */ + /**************************************************************//** Frees the memory for a persistent cursor object. */ UNIV_INTERN diff --git a/storage/innobase/include/data0data.h b/storage/innobase/include/data0data.h index f7bdd29ed90..6d3c2988fdc 100644 --- a/storage/innobase/include/data0data.h +++ b/storage/innobase/include/data0data.h @@ -231,6 +231,26 @@ dtuple_set_n_fields_cmp( dtuple_t* tuple, /*!< in: tuple */ ulint n_fields_cmp); /*!< in: number of fields used in comparisons in rem0cmp.* */ + +/* Estimate the number of bytes that are going to be allocated when +creating a new dtuple_t object */ +#define DTUPLE_EST_ALLOC(n_fields) \ + (sizeof(dtuple_t) + (n_fields) * sizeof(dfield_t)) + +/**********************************************************//** +Creates a data tuple from an already allocated chunk of memory. +The size of the chunk must be at least DTUPLE_EST_ALLOC(n_fields). +The default value for number of fields used in record comparisons +for this tuple is n_fields. +@return created tuple (inside buf) */ +UNIV_INLINE +dtuple_t* +dtuple_create_from_mem( +/*===================*/ + void* buf, /*!< in, out: buffer to use */ + ulint buf_size, /*!< in: buffer size */ + ulint n_fields); /*!< in: number of fields */ + /**********************************************************//** Creates a data tuple to a memory heap. The default value for number of fields used in record comparisons for this tuple is n_fields. @@ -240,7 +260,8 @@ dtuple_t* dtuple_create( /*==========*/ mem_heap_t* heap, /*!< in: memory heap where the tuple - is created */ + is created, DTUPLE_EST_ALLOC(n_fields) + bytes will be allocated from this heap */ ulint n_fields); /*!< in: number of fields */ /**********************************************************//** diff --git a/storage/innobase/include/data0data.ic b/storage/innobase/include/data0data.ic index 5c0f8039c80..205fa397987 100644 --- a/storage/innobase/include/data0data.ic +++ b/storage/innobase/include/data0data.ic @@ -348,23 +348,25 @@ dtuple_get_nth_field( #endif /* UNIV_DEBUG */ /**********************************************************//** -Creates a data tuple to a memory heap. The default value for number -of fields used in record comparisons for this tuple is n_fields. -@return own: created tuple */ +Creates a data tuple from an already allocated chunk of memory. +The size of the chunk must be at least DTUPLE_EST_ALLOC(n_fields). +The default value for number of fields used in record comparisons +for this tuple is n_fields. +@return created tuple (inside buf) */ UNIV_INLINE dtuple_t* -dtuple_create( -/*==========*/ - mem_heap_t* heap, /*!< in: memory heap where the tuple - is created */ - ulint n_fields) /*!< in: number of fields */ +dtuple_create_from_mem( +/*===================*/ + void* buf, /*!< in, out: buffer to use */ + ulint buf_size, /*!< in: buffer size */ + ulint n_fields) /*!< in: number of fields */ { dtuple_t* tuple; - ut_ad(heap); + ut_ad(buf != NULL); + ut_a(buf_size >= DTUPLE_EST_ALLOC(n_fields)); - tuple = (dtuple_t*) mem_heap_alloc(heap, sizeof(dtuple_t) - + n_fields * sizeof(dfield_t)); + tuple = (dtuple_t*) buf; tuple->info_bits = 0; tuple->n_fields = n_fields; tuple->n_fields_cmp = n_fields; @@ -386,9 +388,38 @@ dtuple_create( dfield_get_type(field)->mtype = DATA_ERROR; } } +#endif + return(tuple); +} + +/**********************************************************//** +Creates a data tuple to a memory heap. The default value for number +of fields used in record comparisons for this tuple is n_fields. +@return own: created tuple */ +UNIV_INLINE +dtuple_t* +dtuple_create( +/*==========*/ + mem_heap_t* heap, /*!< in: memory heap where the tuple + is created, DTUPLE_EST_ALLOC(n_fields) + bytes will be allocated from this heap */ + ulint n_fields) /*!< in: number of fields */ +{ + void* buf; + ulint buf_size; + dtuple_t* tuple; + + ut_ad(heap); + + buf_size = DTUPLE_EST_ALLOC(n_fields); + buf = mem_heap_alloc(heap, buf_size); + tuple = dtuple_create_from_mem(buf, buf_size, n_fields); + +#ifdef UNIV_DEBUG UNIV_MEM_INVALID(tuple->fields, n_fields * sizeof *tuple->fields); #endif + return(tuple); } diff --git a/storage/innobase/include/mem0mem.ic b/storage/innobase/include/mem0mem.ic index d214c3fe6c9..c70615e1ca9 100644 --- a/storage/innobase/include/mem0mem.ic +++ b/storage/innobase/include/mem0mem.ic @@ -208,10 +208,6 @@ mem_heap_alloc( caller */ buf = (byte*)buf + MEM_FIELD_HEADER_SIZE; -#endif -#ifdef UNIV_SET_MEM_TO_ZERO - UNIV_MEM_ALLOC(buf, n); - memset(buf, '\0', n); #endif UNIV_MEM_ALLOC(buf, n); return(buf); diff --git a/storage/innobase/include/mtr0log.ic b/storage/innobase/include/mtr0log.ic index c670a0a8c82..6f871170099 100644 --- a/storage/innobase/include/mtr0log.ic +++ b/storage/innobase/include/mtr0log.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -216,6 +216,7 @@ mlog_write_initial_log_record_fast( "Please post a bug report to " "bugs.mysql.com.\n", type, offset, space); + ut_ad(0); } } diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index dd619406ab9..e17fd584110 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -168,7 +168,9 @@ UNIV_INTERN row_prebuilt_t* row_create_prebuilt( /*================*/ - dict_table_t* table); /*!< in: Innobase table handle */ + dict_table_t* table, /*!< in: Innobase table handle */ + ulint mysql_row_len); /*!< in: length in bytes of a row in + the MySQL format */ /********************************************************************//** Free a prebuilt struct for a MySQL table handle. */ UNIV_INTERN @@ -672,9 +674,9 @@ struct row_prebuilt_struct { in inserts */ que_fork_t* upd_graph; /*!< Innobase SQL query graph used in updates or deletes */ - btr_pcur_t* pcur; /*!< persistent cursor used in selects + btr_pcur_t pcur; /*!< persistent cursor used in selects and updates */ - btr_pcur_t* clust_pcur; /*!< persistent cursor used in + btr_pcur_t clust_pcur; /*!< persistent cursor used in some selects and updates */ que_fork_t* sel_graph; /*!< dummy query graph used in selects */ diff --git a/storage/innobase/include/row0sel.h b/storage/innobase/include/row0sel.h index 8544b9d08ba..1c4ea6f7244 100644 --- a/storage/innobase/include/row0sel.h +++ b/storage/innobase/include/row0sel.h @@ -128,7 +128,12 @@ row_sel_convert_mysql_key_to_innobase( in the tuple is already according to index! */ byte* buf, /*!< in: buffer to use in field - conversions */ + conversions; NOTE that dtuple->data + may end up pointing inside buf so + do not discard that buffer while + the tuple is being used. See + row_mysql_store_col_in_innobase_format() + in the case of DATA_INT */ ulint buf_len, /*!< in: buffer length */ dict_index_t* index, /*!< in: index of the key value */ const byte* key_ptr, /*!< in: MySQL key value */ diff --git a/storage/innobase/include/trx0rseg.ic b/storage/innobase/include/trx0rseg.ic index daffa92fc7d..5e8d2b41120 100644 --- a/storage/innobase/include/trx0rseg.ic +++ b/storage/innobase/include/trx0rseg.ic @@ -25,6 +25,7 @@ Created 3/26/1996 Heikki Tuuri #include "srv0srv.h" #include "mtr0log.h" +#include "trx0sys.h" /******************************************************************//** Gets a rollback segment header. @@ -131,7 +132,13 @@ trx_rsegf_undo_find_free( ulint i; ulint page_no; - for (i = 0; i < TRX_RSEG_N_SLOTS; i++) { + for (i = 0; +#ifndef UNIV_DEBUG + i < TRX_RSEG_N_SLOTS; +#else + i < (trx_rseg_n_slots_debug ? trx_rseg_n_slots_debug : TRX_RSEG_N_SLOTS); +#endif + i++) { page_no = trx_rsegf_get_nth_undo(rsegf, i, mtr); diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h index 9cec1933e9d..3913792d594 100644 --- a/storage/innobase/include/trx0sys.h +++ b/storage/innobase/include/trx0sys.h @@ -223,6 +223,12 @@ trx_id_t trx_sys_get_new_trx_id(void); /*========================*/ #endif /* !UNIV_HOTBACKUP */ + +#ifdef UNIV_DEBUG +/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */ +extern uint trx_rseg_n_slots_debug; +#endif + /*****************************************************************//** Writes a trx id to an index page. In case that the id size changes in some future version, this function should be used instead of diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index e86cd4402bf..71c75469ee9 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -154,14 +154,6 @@ resolved */ /* DEBUG VERSION CONTROL ===================== */ -/* The following flag will make InnoDB to initialize -all memory it allocates to zero. It hides Purify -warnings about reading unallocated memory unless -memory is read outside the allocated blocks. */ -/* -#define UNIV_INIT_MEM_TO_ZERO -*/ - /* When this macro is defined then additional test functions will be compiled. These functions live at the end of each relevant source file and have "test_" prefix. These functions are not called from anywhere in @@ -231,15 +223,6 @@ operations (very slow); also UNIV_DEBUG must be defined */ #define UNIV_BTR_DEBUG /* check B-tree links */ #define UNIV_LIGHT_MEM_DEBUG /* light memory debugging */ -#ifdef HAVE_purify -/* The following sets all new allocated memory to zero before use: -this can be used to eliminate unnecessary Purify warnings, but note that -it also masks many bugs Purify could detect. For detailed Purify analysis it -is best to remove the define below and look through the warnings one -by one. */ -#define UNIV_SET_MEM_TO_ZERO -#endif - /* #define UNIV_SQL_DEBUG #define UNIV_LOG_DEBUG diff --git a/storage/innobase/include/ut0mem.h b/storage/innobase/include/ut0mem.h index faf6f242883..39f5f20dc6d 100644 --- a/storage/innobase/include/ut0mem.h +++ b/storage/innobase/include/ut0mem.h @@ -78,40 +78,19 @@ ut_mem_init(void); /*=============*/ /**********************************************************************//** -Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is -defined and set_to_zero is TRUE. +Allocates memory. @return own: allocated memory */ UNIV_INTERN void* ut_malloc_low( /*==========*/ ulint n, /*!< in: number of bytes to allocate */ - ibool set_to_zero, /*!< in: TRUE if allocated memory - should be set to zero if - UNIV_SET_MEM_TO_ZERO is defined */ - ibool assert_on_error); /*!< in: if TRUE, we crash mysqld if + ibool assert_on_error) /*!< in: if TRUE, we crash mysqld if the memory cannot be allocated */ + __attribute__((malloc)); /**********************************************************************//** -Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is -defined. -@return own: allocated memory */ -UNIV_INTERN -void* -ut_malloc( -/*======*/ - ulint n); /*!< in: number of bytes to allocate */ -#ifndef UNIV_HOTBACKUP -/**********************************************************************//** -Tests if malloc of n bytes would succeed. ut_malloc() asserts if memory runs -out. It cannot be used if we want to return an error message. Prints to -stderr a message if fails. -@return TRUE if succeeded */ -UNIV_INTERN -ibool -ut_test_malloc( -/*===========*/ - ulint n); /*!< in: try to allocate this many bytes */ -#endif /* !UNIV_HOTBACKUP */ +Allocates memory. */ +#define ut_malloc(n) ut_malloc_low(n, TRUE) /**********************************************************************//** Frees a memory block allocated with ut_malloc. Freeing a NULL pointer is a nop. */ diff --git a/storage/innobase/include/ut0rnd.ic b/storage/innobase/include/ut0rnd.ic index df99c384bbe..795b8ab7a85 100644 --- a/storage/innobase/include/ut0rnd.ic +++ b/storage/innobase/include/ut0rnd.ic @@ -114,7 +114,7 @@ ut_rnd_interval( rnd = ut_rnd_gen_ulint(); - return(low + (rnd % (high - low + 1))); + return(low + (rnd % (high - low))); } /*********************************************************//** diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index 666b1e66d8d..4c547d3e716 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -38,6 +38,7 @@ Created 5/7/1996 Heikki Tuuri #include "trx0purge.h" #include "dict0mem.h" #include "trx0sys.h" +#include "btr0btr.h" /* Restricts the length of search we will do in the waits-for graph of transactions */ @@ -1690,7 +1691,7 @@ lock_rec_create( page_no = buf_block_get_page_no(block); page = block->frame; - ut_ad(!!page_is_comp(page) == dict_table_is_comp(index->table)); + btr_assert_not_corrupted(block, index); /* If rec is the supremum record, then we reset the gap and LOCK_REC_NOT_GAP bits, as all locks on the supremum are @@ -1795,6 +1796,7 @@ lock_rec_enqueue_waiting( "InnoDB: Submit a detailed bug report" " to http://bugs.mysql.com\n", stderr); + ut_ad(0); } /* Enqueue the lock request that will wait to be granted */ @@ -3800,6 +3802,7 @@ lock_table_enqueue_waiting( "InnoDB: Submit a detailed bug report" " to http://bugs.mysql.com\n", stderr); + ut_ad(0); } /* Enqueue the lock request that will wait to be granted */ diff --git a/storage/innobase/mem/mem0pool.c b/storage/innobase/mem/mem0pool.c index dc68cf8eb24..50dbe526d64 100644 --- a/storage/innobase/mem/mem0pool.c +++ b/storage/innobase/mem/mem0pool.c @@ -228,11 +228,7 @@ mem_pool_create( pool = ut_malloc(sizeof(mem_pool_t)); - /* We do not set the memory to zero (FALSE) in the pool, - but only when allocated at a higher level in mem0mem.c. - This is to avoid masking useful Purify warnings. */ - - pool->buf = ut_malloc_low(size, FALSE, TRUE); + pool->buf = ut_malloc_low(size, TRUE); pool->size = size; mutex_create(mem_pool_mutex_key, &pool->mutex, SYNC_MEM_POOL); diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c index 144ceeb0237..66086d68abd 100644 --- a/storage/innobase/os/os0file.c +++ b/storage/innobase/os/os0file.c @@ -3254,7 +3254,91 @@ os_aio_linux_create_io_ctx( fprintf(stderr, "InnoDB: You can disable Linux Native AIO by" - " setting innodb_native_aio = off in my.cnf\n"); + " setting innodb_use_native_aio = 0 in my.cnf\n"); + return(FALSE); +} + +/******************************************************************//** +Checks if the system supports native linux aio. On some kernel +versions where native aio is supported it won't work on tmpfs. In such +cases we can't use native aio as it is not possible to mix simulated +and native aio. +@return: TRUE if supported, FALSE otherwise. */ +static +ibool +os_aio_native_aio_supported(void) +/*=============================*/ +{ + int fd; + byte* buf; + byte* ptr; + struct io_event io_event; + io_context_t io_ctx; + struct iocb iocb; + struct iocb* p_iocb; + int err; + + if (!os_aio_linux_create_io_ctx(1, &io_ctx)) { + /* The platform does not support native aio. */ + return(FALSE); + } + + /* Now check if tmpdir supports native aio ops. */ + fd = innobase_mysql_tmpfile(); + + if (fd < 0) { + ut_print_timestamp(stderr); + fprintf(stderr, " InnoDB: Error: unable to create " + "temp file to check native AIO support.\n"); + + return(FALSE); + } + + memset(&io_event, 0x0, sizeof(io_event)); + + buf = (byte*) ut_malloc(UNIV_PAGE_SIZE * 2); + ptr = (byte*) ut_align(buf, UNIV_PAGE_SIZE); + + /* Suppress valgrind warning. */ + memset(buf, 0x00, UNIV_PAGE_SIZE * 2); + + memset(&iocb, 0x0, sizeof(iocb)); + p_iocb = &iocb; + io_prep_pwrite(p_iocb, fd, ptr, UNIV_PAGE_SIZE, 0); + + err = io_submit(io_ctx, 1, &p_iocb); + if (err >= 1) { + /* Now collect the submitted IO request. */ + err = io_getevents(io_ctx, 1, 1, &io_event, NULL); + } + + ut_free(buf); + close(fd); + + switch (err) { + case 1: + return(TRUE); + + case -EINVAL: + case -ENOSYS: + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: Error: Linux Native AIO is not" + " supported on tmpdir.\n" + "InnoDB: You can either move tmpdir to a" + " file system that supports native AIO\n" + "InnoDB: or you can set" + " innodb_use_native_aio to FALSE to avoid" + " this message.\n"); + + /* fall through. */ + default: + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: Error: Linux Native AIO check" + " on tmpdir returned error[%d]\n", -err); + } + return(FALSE); } #endif /* LINUX_NATIVE_AIO */ @@ -3421,6 +3505,19 @@ os_aio_init( os_io_init_simple(); +#if defined(LINUX_NATIVE_AIO) + /* Check if native aio is supported on this system and tmpfs */ + if (srv_use_native_aio + && !os_aio_native_aio_supported()) { + + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: Warning: Linux Native AIO" + " disabled.\n"); + srv_use_native_aio = FALSE; + } +#endif /* LINUX_NATIVE_AIO */ + for (i = 0; i < n_segments; i++) { srv_set_io_thread_op_info(i, "not started yet"); } diff --git a/storage/innobase/os/os0proc.c b/storage/innobase/os/os0proc.c index 34b30b26616..022c9f247a7 100644 --- a/storage/innobase/os/os0proc.c +++ b/storage/innobase/os/os0proc.c @@ -142,9 +142,6 @@ os_mem_alloc_large( os_fast_mutex_lock(&ut_list_mutex); ut_total_allocated_memory += size; os_fast_mutex_unlock(&ut_list_mutex); -# ifdef UNIV_SET_MEM_TO_ZERO - memset(ptr, '\0', size); -# endif UNIV_MEM_ALLOC(ptr, size); return(ptr); } diff --git a/storage/innobase/page/page0page.c b/storage/innobase/page/page0page.c index 4858929082a..e250bb359fe 100644 --- a/storage/innobase/page/page0page.c +++ b/storage/innobase/page/page0page.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -549,8 +549,7 @@ page_copy_rec_list_end_no_locks( page_cur_move_to_next(&cur1); } - ut_a((ibool)!!page_is_comp(new_page) - == dict_table_is_comp(index->table)); + btr_assert_not_corrupted(new_block, index); ut_a(page_is_comp(new_page) == page_rec_is_comp(rec)); ut_a(mach_read_from_2(new_page + UNIV_PAGE_SIZE - 10) == (ulint) (page_is_comp(new_page) ? PAGE_NEW_INFIMUM : PAGE_OLD_INFIMUM)); diff --git a/storage/innobase/pars/pars0pars.c b/storage/innobase/pars/pars0pars.c index ef107f2896f..86f54195682 100644 --- a/storage/innobase/pars/pars0pars.c +++ b/storage/innobase/pars/pars0pars.c @@ -1857,7 +1857,7 @@ pars_sql( ut_ad(str); - heap = mem_heap_create(256); + heap = mem_heap_create(16000); /* Currently, the parser is not reentrant: */ ut_ad(mutex_own(&(dict_sys->mutex))); diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c index 6e311ce2e80..67846ab6f69 100644 --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -950,7 +950,7 @@ row_ins_foreign_check_on_constraint( fputs("\n" "InnoDB: Submit a detailed bug report to" " http://bugs.mysql.com\n", stderr); - + ut_ad(0); err = DB_SUCCESS; goto nonstandard_exit_func; diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 987d6595224..3f81604a1a2 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -667,17 +667,60 @@ UNIV_INTERN row_prebuilt_t* row_create_prebuilt( /*================*/ - dict_table_t* table) /*!< in: Innobase table handle */ + dict_table_t* table, /*!< in: Innobase table handle */ + ulint mysql_row_len) /*!< in: length in bytes of a row in + the MySQL format */ { row_prebuilt_t* prebuilt; mem_heap_t* heap; dict_index_t* clust_index; dtuple_t* ref; ulint ref_len; + ulint search_tuple_n_fields; + + search_tuple_n_fields = 2 * dict_table_get_n_cols(table); + + clust_index = dict_table_get_first_index(table); + + /* Make sure that search_tuple is long enough for clustered index */ + ut_a(2 * dict_table_get_n_cols(table) >= clust_index->n_fields); - heap = mem_heap_create(sizeof *prebuilt + 128); + ref_len = dict_index_get_n_unique(clust_index); - prebuilt = mem_heap_zalloc(heap, sizeof *prebuilt); +#define PREBUILT_HEAP_INITIAL_SIZE \ + ( \ + sizeof(*prebuilt) \ + /* allocd in this function */ \ + + DTUPLE_EST_ALLOC(search_tuple_n_fields) \ + + DTUPLE_EST_ALLOC(ref_len) \ + /* allocd in row_prebuild_sel_graph() */ \ + + sizeof(sel_node_t) \ + + sizeof(que_fork_t) \ + + sizeof(que_thr_t) \ + /* allocd in row_get_prebuilt_update_vector() */ \ + + sizeof(upd_node_t) \ + + sizeof(upd_t) \ + + sizeof(upd_field_t) \ + * dict_table_get_n_cols(table) \ + + sizeof(que_fork_t) \ + + sizeof(que_thr_t) \ + /* allocd in row_get_prebuilt_insert_row() */ \ + + sizeof(ins_node_t) \ + /* mysql_row_len could be huge and we are not \ + sure if this prebuilt instance is going to be \ + used in inserts */ \ + + (mysql_row_len < 256 ? mysql_row_len : 0) \ + + DTUPLE_EST_ALLOC(dict_table_get_n_cols(table)) \ + + sizeof(que_fork_t) \ + + sizeof(que_thr_t) \ + ) + + /* We allocate enough space for the objects that are likely to + be created later in order to minimize the number of malloc() + calls */ + heap = mem_heap_create(PREBUILT_HEAP_INITIAL_SIZE); + + prebuilt = mem_heap_zalloc(heap, sizeof(*prebuilt)); prebuilt->magic_n = ROW_PREBUILT_ALLOCATED; prebuilt->magic_n2 = ROW_PREBUILT_ALLOCATED; @@ -687,23 +730,15 @@ row_create_prebuilt( prebuilt->sql_stat_start = TRUE; prebuilt->heap = heap; - prebuilt->pcur = btr_pcur_create_for_mysql(); - prebuilt->clust_pcur = btr_pcur_create_for_mysql(); + btr_pcur_reset(&prebuilt->pcur); + btr_pcur_reset(&prebuilt->clust_pcur); prebuilt->select_lock_type = LOCK_NONE; prebuilt->stored_select_lock_type = 99999999; UNIV_MEM_INVALID(&prebuilt->stored_select_lock_type, sizeof prebuilt->stored_select_lock_type); - prebuilt->search_tuple = dtuple_create( - heap, 2 * dict_table_get_n_cols(table)); - - clust_index = dict_table_get_first_index(table); - - /* Make sure that search_tuple is long enough for clustered index */ - ut_a(2 * dict_table_get_n_cols(table) >= clust_index->n_fields); - - ref_len = dict_index_get_n_unique(clust_index); + prebuilt->search_tuple = dtuple_create(heap, search_tuple_n_fields); ref = dtuple_create(heap, ref_len); @@ -720,6 +755,8 @@ row_create_prebuilt( prebuilt->autoinc_last_value = 0; + prebuilt->mysql_row_len = mysql_row_len; + return(prebuilt); } @@ -755,8 +792,8 @@ row_prebuilt_free( prebuilt->magic_n = ROW_PREBUILT_FREED; prebuilt->magic_n2 = ROW_PREBUILT_FREED; - btr_pcur_free_for_mysql(prebuilt->pcur); - btr_pcur_free_for_mysql(prebuilt->clust_pcur); + btr_pcur_reset(&prebuilt->pcur); + btr_pcur_reset(&prebuilt->clust_pcur); if (prebuilt->mysql_template) { mem_free(prebuilt->mysql_template); @@ -1416,11 +1453,11 @@ row_update_for_mysql( clust_index = dict_table_get_first_index(table); - if (prebuilt->pcur->btr_cur.index == clust_index) { - btr_pcur_copy_stored_position(node->pcur, prebuilt->pcur); + if (prebuilt->pcur.btr_cur.index == clust_index) { + btr_pcur_copy_stored_position(node->pcur, &prebuilt->pcur); } else { btr_pcur_copy_stored_position(node->pcur, - prebuilt->clust_pcur); + &prebuilt->clust_pcur); } ut_a(node->pcur->rel_pos == BTR_PCUR_ON); @@ -1524,8 +1561,8 @@ row_unlock_for_mysql( clust_pcur, and we do not need to reposition the cursors. */ { - btr_pcur_t* pcur = prebuilt->pcur; - btr_pcur_t* clust_pcur = prebuilt->clust_pcur; + btr_pcur_t* pcur = &prebuilt->pcur; + btr_pcur_t* clust_pcur = &prebuilt->clust_pcur; trx_t* trx = prebuilt->trx; ut_ad(prebuilt && trx); @@ -1954,6 +1991,20 @@ row_create_table_for_mysql( } break; + case DB_TOO_MANY_CONCURRENT_TRXS: + /* We already have .ibd file here. it should be deleted. */ + + if (table->space && !fil_delete_tablespace(table->space)) { + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: Error: not able to" + " delete tablespace %lu of table ", + (ulong) table->space); + ut_print_name(stderr, trx, TRUE, table->name); + fputs("!\n", stderr); + } + /* fall through */ + case DB_DUPLICATE_KEY: default: /* We may also get err == DB_ERROR if the .ibd file for the diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index 5d8f53f68da..0d1d3aad1c6 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2012, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -2301,7 +2301,12 @@ row_sel_convert_mysql_key_to_innobase( in the tuple is already according to index! */ byte* buf, /*!< in: buffer to use in field - conversions */ + conversions; NOTE that dtuple->data + may end up pointing inside buf so + do not discard that buffer while + the tuple is being used. See + row_mysql_store_col_in_innobase_format() + in the case of DATA_INT */ ulint buf_len, /*!< in: buffer length */ dict_index_t* index, /*!< in: index of the key value */ const byte* key_ptr, /*!< in: MySQL key value */ @@ -2433,6 +2438,7 @@ row_sel_convert_mysql_key_to_innobase( /* Storing may use at most data_len bytes of buf */ if (UNIV_LIKELY(!is_null)) { + ut_a(buf + data_len <= original_buf + buf_len); row_mysql_store_col_in_innobase_format( dfield, buf, FALSE, /* MySQL key value format col */ @@ -2915,17 +2921,17 @@ row_sel_get_clust_rec_for_mysql( btr_pcur_open_with_no_init(clust_index, prebuilt->clust_ref, PAGE_CUR_LE, BTR_SEARCH_LEAF, - prebuilt->clust_pcur, 0, mtr); + &prebuilt->clust_pcur, 0, mtr); - clust_rec = btr_pcur_get_rec(prebuilt->clust_pcur); + clust_rec = btr_pcur_get_rec(&prebuilt->clust_pcur); - prebuilt->clust_pcur->trx_if_known = trx; + prebuilt->clust_pcur.trx_if_known = trx; /* Note: only if the search ends up on a non-infimum record is the low_match value the real match to the search tuple */ if (!page_rec_is_user_rec(clust_rec) - || btr_pcur_get_low_match(prebuilt->clust_pcur) + || btr_pcur_get_low_match(&prebuilt->clust_pcur) < dict_index_get_n_unique(clust_index)) { /* In a rare case it is possible that no clust rec is found @@ -2957,6 +2963,7 @@ row_sel_get_clust_rec_for_mysql( fputs("\n" "InnoDB: Submit a detailed bug report" " to http://bugs.mysql.com\n", stderr); + ut_ad(0); } clust_rec = NULL; @@ -2974,7 +2981,7 @@ row_sel_get_clust_rec_for_mysql( we set a LOCK_REC_NOT_GAP type lock */ err = lock_clust_rec_read_check_and_lock( - 0, btr_pcur_get_block(prebuilt->clust_pcur), + 0, btr_pcur_get_block(&prebuilt->clust_pcur), clust_rec, clust_index, *offsets, prebuilt->select_lock_type, LOCK_REC_NOT_GAP, thr); switch (err) { @@ -3052,7 +3059,7 @@ row_sel_get_clust_rec_for_mysql( /* We may use the cursor in update or in unlock_row(): store its position */ - btr_pcur_store_position(prebuilt->clust_pcur, mtr); + btr_pcur_store_position(&prebuilt->clust_pcur, mtr); } err_exit: @@ -3300,7 +3307,7 @@ row_sel_try_search_shortcut_for_mysql( { dict_index_t* index = prebuilt->index; const dtuple_t* search_tuple = prebuilt->search_tuple; - btr_pcur_t* pcur = prebuilt->pcur; + btr_pcur_t* pcur = &prebuilt->pcur; trx_t* trx = prebuilt->trx; const rec_t* rec; @@ -3389,7 +3396,7 @@ row_search_for_mysql( dict_index_t* index = prebuilt->index; ibool comp = dict_table_is_comp(index->table); const dtuple_t* search_tuple = prebuilt->search_tuple; - btr_pcur_t* pcur = prebuilt->pcur; + btr_pcur_t* pcur = &prebuilt->pcur; trx_t* trx = prebuilt->trx; dict_index_t* clust_index; que_thr_t* thr; diff --git a/storage/innobase/row/row0umod.c b/storage/innobase/row/row0umod.c index b86ce9eeabd..9597c476125 100644 --- a/storage/innobase/row/row0umod.c +++ b/storage/innobase/row/row0umod.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1997, 2012, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -509,6 +509,7 @@ row_undo_mod_del_unmark_sec_and_undo_update( fputs("\n" "InnoDB: Submit a detailed bug report" " to http://bugs.mysql.com\n", stderr); + ut_ad(0); break; case ROW_FOUND: btr_cur = btr_pcur_get_btr_cur(&pcur); diff --git a/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c index 765233c8dab..cfa69b8c572 100644 --- a/storage/innobase/row/row0upd.c +++ b/storage/innobase/row/row0upd.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1617,6 +1617,7 @@ row_upd_sec_index_entry( fputs("\n" "InnoDB: Submit a detailed bug report" " to http://bugs.mysql.com\n", stderr); + ut_ad(0); break; case ROW_FOUND: /* Delete mark the old index record; it can already be diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index e007905479e..a0f45cdbb92 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, 2009 Google Inc. Copyright (c) 2009, Percona Inc. @@ -2431,6 +2431,7 @@ srv_error_monitor_thread( "InnoDB: Please submit a bug report" " to http://bugs.mysql.com\n", old_lsn, new_lsn); + ut_ad(0); } old_lsn = new_lsn; diff --git a/storage/innobase/trx/trx0purge.c b/storage/innobase/trx/trx0purge.c index 02ec9f1c072..2370d3deab0 100644 --- a/storage/innobase/trx/trx0purge.c +++ b/storage/innobase/trx/trx0purge.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2011, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -730,6 +730,7 @@ trx_purge_rseg_get_next_history_log( "InnoDB: report, and submit it" " to http://bugs.mysql.com\n", (ulong) trx_sys->rseg_history_len); + ut_ad(0); } mutex_exit(&kernel_mutex); diff --git a/storage/innobase/trx/trx0rec.c b/storage/innobase/trx/trx0rec.c index 0bf41780fcc..786c7be36a4 100644 --- a/storage/innobase/trx/trx0rec.c +++ b/storage/innobase/trx/trx0rec.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1003,6 +1003,7 @@ trx_undo_update_rec_get_update( fprintf(stderr, "\n" "InnoDB: n_fields = %lu, i = %lu, ptr %p\n", (ulong) n_fields, (ulong) i, ptr); + ut_ad(0); *upd = NULL; return(NULL); } @@ -1513,6 +1514,7 @@ trx_undo_prev_version_build( "InnoDB: record version ", stderr); rec_print_new(stderr, rec, offsets); putc('\n', stderr); + ut_ad(0); return(DB_ERROR); } @@ -1618,6 +1620,7 @@ trx_undo_prev_version_build( (ullint) old_roll_ptr, (ullint) roll_ptr); trx_purge_sys_print(); + ut_ad(0); return(DB_ERROR); } diff --git a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c index 8e595353024..66d3ae5463c 100644 --- a/storage/innobase/trx/trx0sys.c +++ b/storage/innobase/trx/trx0sys.c @@ -134,6 +134,11 @@ UNIV_INTERN mysql_pfs_key_t trx_doublewrite_mutex_key; UNIV_INTERN mysql_pfs_key_t file_format_max_mutex_key; #endif /* UNIV_PFS_MUTEX */ +#ifdef UNIV_DEBUG +/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */ +uint trx_rseg_n_slots_debug = 0; +#endif + #ifndef UNIV_HOTBACKUP /** This is used to track the maximum file format id known to InnoDB. It's updated via SET GLOBAL innodb_file_format_max = 'x' or when we open diff --git a/storage/innobase/ut/ut0mem.c b/storage/innobase/ut/ut0mem.c index 303fdd6dd44..cb6b050beca 100644 --- a/storage/innobase/ut/ut0mem.c +++ b/storage/innobase/ut/ut0mem.c @@ -84,17 +84,13 @@ ut_mem_init(void) #endif /* !UNIV_HOTBACKUP */ /**********************************************************************//** -Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is -defined and set_to_zero is TRUE. +Allocates memory. @return own: allocated memory */ UNIV_INTERN void* ut_malloc_low( /*==========*/ ulint n, /*!< in: number of bytes to allocate */ - ibool set_to_zero, /*!< in: TRUE if allocated memory should be - set to zero if UNIV_SET_MEM_TO_ZERO is - defined */ ibool assert_on_error)/*!< in: if TRUE, we crash mysqld if the memory cannot be allocated */ { @@ -106,12 +102,6 @@ ut_malloc_low( ret = malloc(n); ut_a(ret || !assert_on_error); -#ifdef UNIV_SET_MEM_TO_ZERO - if (set_to_zero) { - memset(ret, '\0', n); - UNIV_MEM_ALLOC(ret, n); - } -#endif return(ret); } @@ -193,12 +183,6 @@ ut_malloc_low( } } - if (set_to_zero) { -#ifdef UNIV_SET_MEM_TO_ZERO - memset(ret, '\0', n + sizeof(ut_mem_block_t)); -#endif - } - UNIV_MEM_ALLOC(ret, n + sizeof(ut_mem_block_t)); ((ut_mem_block_t*)ret)->size = n + sizeof(ut_mem_block_t); @@ -215,74 +199,10 @@ ut_malloc_low( void* ret = malloc(n); ut_a(ret || !assert_on_error); -# ifdef UNIV_SET_MEM_TO_ZERO - if (set_to_zero) { - memset(ret, '\0', n); - } -# endif return(ret); #endif /* !UNIV_HOTBACKUP */ } -/**********************************************************************//** -Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is -defined. -@return own: allocated memory */ -UNIV_INTERN -void* -ut_malloc( -/*======*/ - ulint n) /*!< in: number of bytes to allocate */ -{ -#ifndef UNIV_HOTBACKUP - return(ut_malloc_low(n, TRUE, TRUE)); -#else /* !UNIV_HOTBACKUP */ - return(malloc(n)); -#endif /* !UNIV_HOTBACKUP */ -} - -#ifndef UNIV_HOTBACKUP -/**********************************************************************//** -Tests if malloc of n bytes would succeed. ut_malloc() asserts if memory runs -out. It cannot be used if we want to return an error message. Prints to -stderr a message if fails. -@return TRUE if succeeded */ -UNIV_INTERN -ibool -ut_test_malloc( -/*===========*/ - ulint n) /*!< in: try to allocate this many bytes */ -{ - void* ret; - - ret = malloc(n); - - if (ret == NULL) { - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: cannot allocate" - " %lu bytes of memory for\n" - "InnoDB: a BLOB with malloc! Total allocated memory\n" - "InnoDB: by InnoDB %lu bytes." - " Operating system errno: %d\n" - "InnoDB: Check if you should increase" - " the swap file or\n" - "InnoDB: ulimits of your operating system.\n" - "InnoDB: On FreeBSD check you have" - " compiled the OS with\n" - "InnoDB: a big enough maximum process size.\n", - (ulong) n, - (ulong) ut_total_allocated_memory, - (int) errno); - return(FALSE); - } - - free(ret); - - return(TRUE); -} -#endif /* !UNIV_HOTBACKUP */ - /**********************************************************************//** Frees a memory block allocated with ut_malloc. Freeing a NULL pointer is a nop. */ diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 46632f5c148..655dddcb884 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -3154,6 +3154,40 @@ CHARSET_INFO my_charset_ucs2_general_ci= &my_collation_ucs2_general_ci_handler }; + +CHARSET_INFO my_charset_ucs2_general_mysql500_ci= +{ + 159, 0, 0, /* number */ + MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, /* state */ + "ucs2", /* cs name */ + "ucs2_general_mysql500_ci", /* name */ + "", /* comment */ + NULL, /* tailoring */ + ctype_ucs2, /* ctype */ + to_lower_ucs2, /* to_lower */ + to_upper_ucs2, /* to_upper */ + to_upper_ucs2, /* sort_order */ + NULL, /* contractions */ + NULL, /* sort_order_big */ + NULL, /* tab_to_uni */ + NULL, /* tab_from_uni */ + my_unicase_mysql500, /* caseinfo */ + NULL, /* state_map */ + NULL, /* ident_map */ + 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ + 2, /* mbminlen */ + 2, /* mbmaxlen */ + 0, /* min_sort_char */ + 0xFFFF, /* max_sort_char */ + ' ', /* pad char */ + 0, /* escape_with_backslash_is_dangerous */ + &my_charset_ucs2_handler, + &my_collation_ucs2_general_ci_handler +}; + + CHARSET_INFO my_charset_ucs2_bin= { 90,0,0, /* number */ diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index ba4ad2e71ef..b0008d7c6e4 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -193,6 +193,141 @@ static MY_UNICASE_INFO plane00[]={ }; +/* + Almost similar to plane00, but maps sorting order + for U+00DF to 0x00DF instead of 0x0053. +*/ +static MY_UNICASE_INFO plane00_mysql500[]={ + {0x0000,0x0000,0x0000}, {0x0001,0x0001,0x0001}, + {0x0002,0x0002,0x0002}, {0x0003,0x0003,0x0003}, + {0x0004,0x0004,0x0004}, {0x0005,0x0005,0x0005}, + {0x0006,0x0006,0x0006}, {0x0007,0x0007,0x0007}, + {0x0008,0x0008,0x0008}, {0x0009,0x0009,0x0009}, + {0x000A,0x000A,0x000A}, {0x000B,0x000B,0x000B}, + {0x000C,0x000C,0x000C}, {0x000D,0x000D,0x000D}, + {0x000E,0x000E,0x000E}, {0x000F,0x000F,0x000F}, + {0x0010,0x0010,0x0010}, {0x0011,0x0011,0x0011}, + {0x0012,0x0012,0x0012}, {0x0013,0x0013,0x0013}, + {0x0014,0x0014,0x0014}, {0x0015,0x0015,0x0015}, + {0x0016,0x0016,0x0016}, {0x0017,0x0017,0x0017}, + {0x0018,0x0018,0x0018}, {0x0019,0x0019,0x0019}, + {0x001A,0x001A,0x001A}, {0x001B,0x001B,0x001B}, + {0x001C,0x001C,0x001C}, {0x001D,0x001D,0x001D}, + {0x001E,0x001E,0x001E}, {0x001F,0x001F,0x001F}, + {0x0020,0x0020,0x0020}, {0x0021,0x0021,0x0021}, + {0x0022,0x0022,0x0022}, {0x0023,0x0023,0x0023}, + {0x0024,0x0024,0x0024}, {0x0025,0x0025,0x0025}, + {0x0026,0x0026,0x0026}, {0x0027,0x0027,0x0027}, + {0x0028,0x0028,0x0028}, {0x0029,0x0029,0x0029}, + {0x002A,0x002A,0x002A}, {0x002B,0x002B,0x002B}, + {0x002C,0x002C,0x002C}, {0x002D,0x002D,0x002D}, + {0x002E,0x002E,0x002E}, {0x002F,0x002F,0x002F}, + {0x0030,0x0030,0x0030}, {0x0031,0x0031,0x0031}, + {0x0032,0x0032,0x0032}, {0x0033,0x0033,0x0033}, + {0x0034,0x0034,0x0034}, {0x0035,0x0035,0x0035}, + {0x0036,0x0036,0x0036}, {0x0037,0x0037,0x0037}, + {0x0038,0x0038,0x0038}, {0x0039,0x0039,0x0039}, + {0x003A,0x003A,0x003A}, {0x003B,0x003B,0x003B}, + {0x003C,0x003C,0x003C}, {0x003D,0x003D,0x003D}, + {0x003E,0x003E,0x003E}, {0x003F,0x003F,0x003F}, + {0x0040,0x0040,0x0040}, {0x0041,0x0061,0x0041}, + {0x0042,0x0062,0x0042}, {0x0043,0x0063,0x0043}, + {0x0044,0x0064,0x0044}, {0x0045,0x0065,0x0045}, + {0x0046,0x0066,0x0046}, {0x0047,0x0067,0x0047}, + {0x0048,0x0068,0x0048}, {0x0049,0x0069,0x0049}, + {0x004A,0x006A,0x004A}, {0x004B,0x006B,0x004B}, + {0x004C,0x006C,0x004C}, {0x004D,0x006D,0x004D}, + {0x004E,0x006E,0x004E}, {0x004F,0x006F,0x004F}, + {0x0050,0x0070,0x0050}, {0x0051,0x0071,0x0051}, + {0x0052,0x0072,0x0052}, {0x0053,0x0073,0x0053}, + {0x0054,0x0074,0x0054}, {0x0055,0x0075,0x0055}, + {0x0056,0x0076,0x0056}, {0x0057,0x0077,0x0057}, + {0x0058,0x0078,0x0058}, {0x0059,0x0079,0x0059}, + {0x005A,0x007A,0x005A}, {0x005B,0x005B,0x005B}, + {0x005C,0x005C,0x005C}, {0x005D,0x005D,0x005D}, + {0x005E,0x005E,0x005E}, {0x005F,0x005F,0x005F}, + {0x0060,0x0060,0x0060}, {0x0041,0x0061,0x0041}, + {0x0042,0x0062,0x0042}, {0x0043,0x0063,0x0043}, + {0x0044,0x0064,0x0044}, {0x0045,0x0065,0x0045}, + {0x0046,0x0066,0x0046}, {0x0047,0x0067,0x0047}, + {0x0048,0x0068,0x0048}, {0x0049,0x0069,0x0049}, + {0x004A,0x006A,0x004A}, {0x004B,0x006B,0x004B}, + {0x004C,0x006C,0x004C}, {0x004D,0x006D,0x004D}, + {0x004E,0x006E,0x004E}, {0x004F,0x006F,0x004F}, + {0x0050,0x0070,0x0050}, {0x0051,0x0071,0x0051}, + {0x0052,0x0072,0x0052}, {0x0053,0x0073,0x0053}, + {0x0054,0x0074,0x0054}, {0x0055,0x0075,0x0055}, + {0x0056,0x0076,0x0056}, {0x0057,0x0077,0x0057}, + {0x0058,0x0078,0x0058}, {0x0059,0x0079,0x0059}, + {0x005A,0x007A,0x005A}, {0x007B,0x007B,0x007B}, + {0x007C,0x007C,0x007C}, {0x007D,0x007D,0x007D}, + {0x007E,0x007E,0x007E}, {0x007F,0x007F,0x007F}, + {0x0080,0x0080,0x0080}, {0x0081,0x0081,0x0081}, + {0x0082,0x0082,0x0082}, {0x0083,0x0083,0x0083}, + {0x0084,0x0084,0x0084}, {0x0085,0x0085,0x0085}, + {0x0086,0x0086,0x0086}, {0x0087,0x0087,0x0087}, + {0x0088,0x0088,0x0088}, {0x0089,0x0089,0x0089}, + {0x008A,0x008A,0x008A}, {0x008B,0x008B,0x008B}, + {0x008C,0x008C,0x008C}, {0x008D,0x008D,0x008D}, + {0x008E,0x008E,0x008E}, {0x008F,0x008F,0x008F}, + {0x0090,0x0090,0x0090}, {0x0091,0x0091,0x0091}, + {0x0092,0x0092,0x0092}, {0x0093,0x0093,0x0093}, + {0x0094,0x0094,0x0094}, {0x0095,0x0095,0x0095}, + {0x0096,0x0096,0x0096}, {0x0097,0x0097,0x0097}, + {0x0098,0x0098,0x0098}, {0x0099,0x0099,0x0099}, + {0x009A,0x009A,0x009A}, {0x009B,0x009B,0x009B}, + {0x009C,0x009C,0x009C}, {0x009D,0x009D,0x009D}, + {0x009E,0x009E,0x009E}, {0x009F,0x009F,0x009F}, + {0x00A0,0x00A0,0x00A0}, {0x00A1,0x00A1,0x00A1}, + {0x00A2,0x00A2,0x00A2}, {0x00A3,0x00A3,0x00A3}, + {0x00A4,0x00A4,0x00A4}, {0x00A5,0x00A5,0x00A5}, + {0x00A6,0x00A6,0x00A6}, {0x00A7,0x00A7,0x00A7}, + {0x00A8,0x00A8,0x00A8}, {0x00A9,0x00A9,0x00A9}, + {0x00AA,0x00AA,0x00AA}, {0x00AB,0x00AB,0x00AB}, + {0x00AC,0x00AC,0x00AC}, {0x00AD,0x00AD,0x00AD}, + {0x00AE,0x00AE,0x00AE}, {0x00AF,0x00AF,0x00AF}, + {0x00B0,0x00B0,0x00B0}, {0x00B1,0x00B1,0x00B1}, + {0x00B2,0x00B2,0x00B2}, {0x00B3,0x00B3,0x00B3}, + {0x00B4,0x00B4,0x00B4}, {0x039C,0x00B5,0x039C}, + {0x00B6,0x00B6,0x00B6}, {0x00B7,0x00B7,0x00B7}, + {0x00B8,0x00B8,0x00B8}, {0x00B9,0x00B9,0x00B9}, + {0x00BA,0x00BA,0x00BA}, {0x00BB,0x00BB,0x00BB}, + {0x00BC,0x00BC,0x00BC}, {0x00BD,0x00BD,0x00BD}, + {0x00BE,0x00BE,0x00BE}, {0x00BF,0x00BF,0x00BF}, + {0x00C0,0x00E0,0x0041}, {0x00C1,0x00E1,0x0041}, + {0x00C2,0x00E2,0x0041}, {0x00C3,0x00E3,0x0041}, + {0x00C4,0x00E4,0x0041}, {0x00C5,0x00E5,0x0041}, + {0x00C6,0x00E6,0x00C6}, {0x00C7,0x00E7,0x0043}, + {0x00C8,0x00E8,0x0045}, {0x00C9,0x00E9,0x0045}, + {0x00CA,0x00EA,0x0045}, {0x00CB,0x00EB,0x0045}, + {0x00CC,0x00EC,0x0049}, {0x00CD,0x00ED,0x0049}, + {0x00CE,0x00EE,0x0049}, {0x00CF,0x00EF,0x0049}, + {0x00D0,0x00F0,0x00D0}, {0x00D1,0x00F1,0x004E}, + {0x00D2,0x00F2,0x004F}, {0x00D3,0x00F3,0x004F}, + {0x00D4,0x00F4,0x004F}, {0x00D5,0x00F5,0x004F}, + {0x00D6,0x00F6,0x004F}, {0x00D7,0x00D7,0x00D7}, + {0x00D8,0x00F8,0x00D8}, {0x00D9,0x00F9,0x0055}, + {0x00DA,0x00FA,0x0055}, {0x00DB,0x00FB,0x0055}, + {0x00DC,0x00FC,0x0055}, {0x00DD,0x00FD,0x0059}, + {0x00DE,0x00FE,0x00DE}, {0x00DF,0x00DF,0x00DF}, + {0x00C0,0x00E0,0x0041}, {0x00C1,0x00E1,0x0041}, + {0x00C2,0x00E2,0x0041}, {0x00C3,0x00E3,0x0041}, + {0x00C4,0x00E4,0x0041}, {0x00C5,0x00E5,0x0041}, + {0x00C6,0x00E6,0x00C6}, {0x00C7,0x00E7,0x0043}, + {0x00C8,0x00E8,0x0045}, {0x00C9,0x00E9,0x0045}, + {0x00CA,0x00EA,0x0045}, {0x00CB,0x00EB,0x0045}, + {0x00CC,0x00EC,0x0049}, {0x00CD,0x00ED,0x0049}, + {0x00CE,0x00EE,0x0049}, {0x00CF,0x00EF,0x0049}, + {0x00D0,0x00F0,0x00D0}, {0x00D1,0x00F1,0x004E}, + {0x00D2,0x00F2,0x004F}, {0x00D3,0x00F3,0x004F}, + {0x00D4,0x00F4,0x004F}, {0x00D5,0x00F5,0x004F}, + {0x00D6,0x00F6,0x004F}, {0x00F7,0x00F7,0x00F7}, + {0x00D8,0x00F8,0x00D8}, {0x00D9,0x00F9,0x0055}, + {0x00DA,0x00FA,0x0055}, {0x00DB,0x00FB,0x0055}, + {0x00DC,0x00FC,0x0055}, {0x00DD,0x00FD,0x0059}, + {0x00DE,0x00FE,0x00DE}, {0x0178,0x00FF,0x0059} +}; + static MY_UNICASE_INFO plane01[]={ {0x0100,0x0101,0x0041}, {0x0100,0x0101,0x0041}, @@ -1541,6 +1676,47 @@ MY_UNICASE_INFO *my_unicase_default[256]={ }; +/* + Reproduce old utf8_general_ci behaviour before we fixed Bug#27877. +*/ +MY_UNICASE_INFO *my_unicase_mysql500[256]={ + plane00_mysql500, + plane01, plane02, plane03, plane04, plane05, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, plane1E, plane1F, + NULL, plane21, NULL, NULL, plane24, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, planeFF + +}; + + /* Turkish lower/upper mapping: 1. LOWER(0x0049 LATIN CAPITAL LETTER I) -> @@ -2814,6 +2990,39 @@ CHARSET_INFO my_charset_utf8_general_ci= }; +CHARSET_INFO my_charset_utf8_general_mysql500_ci= +{ + 223,0,0, /* number */ + MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE, /* state */ + "utf8", /* cs name */ + "utf8_general_mysql500_ci", /* name */ + "", /* comment */ + NULL, /* tailoring */ + ctype_utf8, /* ctype */ + to_lower_utf8, /* to_lower */ + to_upper_utf8, /* to_upper */ + to_upper_utf8, /* sort_order */ + NULL, /* contractions */ + NULL, /* sort_order_big */ + NULL, /* tab_to_uni */ + NULL, /* tab_from_uni */ + my_unicase_mysql500, /* caseinfo */ + NULL, /* state_map */ + NULL, /* ident_map */ + 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ + 1, /* mbminlen */ + 3, /* mbmaxlen */ + 0, /* min_sort_char */ + 0xFFFF, /* max_sort_char */ + ' ', /* pad char */ + 0, /* escape_with_backslash_is_dangerous */ + &my_charset_utf8_handler, + &my_collation_ci_handler +}; + + CHARSET_INFO my_charset_utf8_bin= { 83,0,0, /* number */ @@ -4325,6 +4534,7 @@ CHARSET_INFO my_charset_filename= &my_collation_filename_handler }; + #ifdef MY_TEST_UTF8 #include diff --git a/strings/dtoa.c b/strings/dtoa.c index f7c38b2420d..2f4749ac171 100644 --- a/strings/dtoa.c +++ b/strings/dtoa.c @@ -783,7 +783,20 @@ static Bigint *multadd(Bigint *b, int m, int a, Stack_alloc *alloc) return b; } - +/** + Converts a string to Bigint. + + Now we have nd0 digits, starting at s, followed by a + decimal point, followed by nd-nd0 digits. + Unless nd0 == nd, in which case we have a number of the form: + ".xxxxxx" or "xxxxxx." + + @param s Input string, already partially parsed by my_strtod_int(). + @param nd0 Number of digits before decimal point. + @param nd Total number of digits. + @param y9 Pre-computed value of the first nine digits. + @param alloc Stack allocator for Bigints. + */ static Bigint *s2b(const char *s, int nd0, int nd, ULong y9, Stack_alloc *alloc) { Bigint *b; @@ -803,10 +816,11 @@ static Bigint *s2b(const char *s, int nd0, int nd, ULong y9, Stack_alloc *alloc) do b= multadd(b, 10, *s++ - '0', alloc); while (++i < nd0); - s++; + s++; /* skip '.' */ } else s+= 10; + /* now do the fractional part */ for(; i < nd; i++) b= multadd(b, 10, *s++ - '0', alloc); return b; @@ -1416,20 +1430,29 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s for (; s < end && c >= '0' && c <= '9'; c = *++s) { have_dig: - nz++; - if (c-= '0') + /* + Here we are parsing the fractional part. + We can stop counting digits after a while: the extra digits + will not contribute to the actual result produced by s2b(). + We have to continue scanning, in case there is an exponent part. + */ + if (nd < 2 * DBL_DIG) { - nf+= nz; - for (i= 1; i < nz; i++) + nz++; + if (c-= '0') + { + nf+= nz; + for (i= 1; i < nz; i++) + if (nd++ < 9) + y*= 10; + else if (nd <= DBL_DIG + 1) + z*= 10; if (nd++ < 9) - y*= 10; + y= 10*y + c; else if (nd <= DBL_DIG + 1) - z*= 10; - if (nd++ < 9) - y= 10*y + c; - else if (nd <= DBL_DIG + 1) - z= 10*z + c; - nz= 0; + z= 10*z + c; + nz= 0; + } } } }