From b7aafca7b708b40cdfbeeff3798e2074722ece7e Mon Sep 17 00:00:00 2001 From: Balasubramanian Kandasamy Date: Mon, 26 Feb 2018 15:55:16 +0530 Subject: Raise version number after cloning 5.5.60 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 44f719ca097..23e938e60e1 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=60 +MYSQL_VERSION_PATCH=61 MYSQL_VERSION_EXTRA= -- cgit v1.2.1 From d4e94739231be30cbda7f910eb1d76cfba2e549b Mon Sep 17 00:00:00 2001 From: Faustin Lammler Date: Tue, 3 Apr 2018 10:33:11 -0300 Subject: Package dependency case problem --- debian/control | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/control b/debian/control index 862cd4f3cea..79ccf8c8fd4 100644 --- a/debian/control +++ b/debian/control @@ -373,10 +373,10 @@ Description: MariaDB database regression test suite (metapackage depending on th Package: mariadb-connect-engine-10.0 Section: database Architecture: any -Depends: libxml2, mariadb-server-10.0|mariadb-galera-server-10.0, unixODBC +Depends: libxml2, mariadb-server-10.0|mariadb-galera-server-10.0, unixodbc Build-depends: libxml2-dev, mariadb-server-10.0|mariadb-galera-server-10.0, - unixODBC-dev + unixodbc-dev Description: Connect storage engine for MariaDB Connect engine supports a number of file formats (dbf, xml, txt, bin, etc), connections to ODBC tables and remote MySQL tables, as well as a number of -- cgit v1.2.1 From d982e717aba67227ec40761a21a4211db91aa0e2 Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Mon, 9 Apr 2018 11:18:12 +0530 Subject: Bug#27510150: MYSQLDUMP FAILS FOR SPECIFIC --WHERE CLAUSES Description: Mysqldump utility fails for specific clauses used with the option, 'where'. Analysis:- Method, "fix_identifier_with_newline()" that prefixes all occurrences of newline char ('\n') in incoming buffer does not verify the size of the buffer. The buffer in which the incoming buffer is copied is limited to 2048 bytes and the method does not try to allocate additional memory for larger incoming buffers. Fix:- Method, "fix_identifier_with_newline()" is modified to fix this issue. --- client/mysqldump.c | 182 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 142 insertions(+), 40 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 2775769fe52..34037337091 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2018, 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 @@ -549,7 +549,8 @@ 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, ...); -static const char* fix_identifier_with_newline(char*); +static char const* fix_identifier_with_newline(char const* object_name, + my_bool* freemem); /* @@ -644,13 +645,19 @@ static void write_header(FILE *sql_file, char *db_name) } else if (!opt_compact) { + my_bool freemem= FALSE; + char const* text= fix_identifier_with_newline(db_name, &freemem); + 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 ? fix_identifier_with_newline(db_name) : ""); + text); + if (freemem) + my_free((void*)text); + print_comment(sql_file, 0, "-- ------------------------------------------------------\n" ); @@ -1982,31 +1989,84 @@ static void print_comment(FILE *sql_file, my_bool is_error, const char *format, print_xml_comment(sql_file, strlen(comment_buff), comment_buff); } -/* - This function accepts object names and prefixes -- wherever \n - character is found. - @param[in] object_name +/** + @brief Accepts object names and prefixes them with "-- " wherever + end-of-line character ('\n') is found. - @return - @retval fixed object name. -*/ + @param[in] object_name object name list (concatenated string) + @param[out] freemem should buffer be released after usage -static const char* fix_identifier_with_newline(char* object_name) + @return + @retval pointer to a string with prefixed objects +*/ +static char const* fix_identifier_with_newline(char const* object_name, my_bool* freemem) { - static char buff[COMMENT_LENGTH]= {0}; - char *ptr= buff; - memset(buff, 0, 255); - while(*object_name) + const size_t PREFIX_LENGTH= 3; // strlen ("-- ") + + // static buffer for replacement procedure + static char storage[NAME_LEN + 1]; + static char* buffer= storage; + static size_t buffer_size= sizeof(storage) - 1; + size_t index= 0; + size_t required_size= 0; + + // we presume memory allocation won't be needed + *freemem= FALSE; + + // traverse and reformat objects + while (object_name && *object_name) { - *ptr++ = *object_name; + ++required_size; if (*object_name == '\n') - ptr= strmov(ptr, "-- "); - object_name++; + required_size+= PREFIX_LENGTH; + + // do we need dynamic (re)allocation + if (required_size > buffer_size) + { + // new alloc size increased in COMMENT_LENGTH multiple + buffer_size= COMMENT_LENGTH * (1 + required_size/COMMENT_LENGTH); + + // is our buffer already dynamically allocated + if (*freemem) + { + // just realloc + buffer= (char*)my_realloc(buffer, buffer_size + 1, MYF(MY_WME)); + if (!buffer) + exit(1); + } + else + { + // dynamic allocation + copy from static buffer + buffer= (char*)my_malloc(buffer_size + 1, MYF(MY_WME)); + if (!buffer) + exit(1); + + strncpy(buffer, storage, index); + *freemem= TRUE; + } + } + + // copy a character + buffer[index]= *object_name; + ++index; + + // prefix new lines with double dash + if (*object_name == '\n') + { + strcpy(buffer + index, "-- "); + index += PREFIX_LENGTH; + } + + ++object_name; } - return buff; + + // don't forget null termination + buffer[index]= '\0'; + return buffer; } + /* create_delimiter Generate a new (null-terminated) string that does not exist in query @@ -2066,6 +2126,8 @@ static uint dump_events_for_db(char *db) char db_cl_name[MY_CS_NAME_SIZE]; int db_cl_altered= FALSE; + my_bool freemem= FALSE; + char const *text= fix_identifier_with_newline(db, &freemem); DBUG_ENTER("dump_events_for_db"); DBUG_PRINT("enter", ("db: '%s'", db)); @@ -2075,7 +2137,9 @@ static uint dump_events_for_db(char *db) /* nice comments */ print_comment(sql_file, 0, "\n--\n-- Dumping events for database '%s'\n--\n", - fix_identifier_with_newline(db)); + text); + if (freemem) + my_free((void*)text); /* not using "mysql_query_with_error_report" because we may have not @@ -2284,6 +2348,8 @@ static uint dump_routines_for_db(char *db) char db_cl_name[MY_CS_NAME_SIZE]; int db_cl_altered= FALSE; + my_bool freemem= FALSE; + char const *text= fix_identifier_with_newline(db, &freemem); DBUG_ENTER("dump_routines_for_db"); DBUG_PRINT("enter", ("db: '%s'", db)); @@ -2292,8 +2358,10 @@ static uint dump_routines_for_db(char *db) /* nice comments */ print_comment(sql_file, 0, - "\n--\n-- Dumping routines for database '%s'\n--\n", - fix_identifier_with_newline(db)); + "\n--\n-- Dumping routines for database '%s'\n--\n", text); + + if (freemem) + my_free((void*)text); /* not using "mysql_query_with_error_report" because we may have not @@ -2348,11 +2416,17 @@ static uint dump_routines_for_db(char *db) row[2] ? strlen(row[2]) : 0)); if (row[2] == NULL) { + my_bool freemem= FALSE; + char const* text= fix_identifier_with_newline(current_user, &freemem); + 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", - fix_identifier_with_newline(current_user)); + text); + if (freemem) + my_free((void*)text); + maybe_die(EX_MYSQLERR,"%s has insufficent privileges to %s!", current_user, query_buff); } else if (strlen(row[2])) @@ -2547,6 +2621,8 @@ static uint get_table_structure(char *table, char *db, char *table_type, /* Make an sql-file, if path was given iow. option -T was given */ char buff[20+FN_REFLEN]; MYSQL_FIELD *field; + my_bool freemem= FALSE; + char const *text; my_snprintf(buff, sizeof(buff), "show create table %s", result_table); @@ -2563,14 +2639,17 @@ static uint get_table_structure(char *table, char *db, char *table_type, write_header(sql_file, db); } + text= fix_identifier_with_newline(result_table, &freemem); if (strcmp (table_type, "VIEW") == 0) /* view */ print_comment(sql_file, 0, "\n--\n-- Temporary table structure for view %s\n--\n\n", - fix_identifier_with_newline(result_table)); + text); else print_comment(sql_file, 0, - "\n--\n-- Table structure for table %s\n--\n\n", - fix_identifier_with_newline(result_table)); + "\n--\n-- Table structure for table %s\n--\n\n", text); + + if (freemem) + my_free((void*)text); if (opt_drop) { @@ -2803,6 +2882,9 @@ static uint get_table_structure(char *table, char *db, char *table_type, /* Make an sql-file, if path was given iow. option -T was given */ if (!opt_no_create_info) { + my_bool freemem= FALSE; + char const *text; + if (path) { if (!(sql_file= open_sql_file_for_table(table, O_WRONLY))) @@ -2810,9 +2892,13 @@ static uint get_table_structure(char *table, char *db, char *table_type, write_header(sql_file, db); } + text= fix_identifier_with_newline(result_table, &freemem); print_comment(sql_file, 0, "\n--\n-- Table structure for table %s\n--\n\n", - fix_identifier_with_newline(result_table)); + text); + if (freemem) + my_free((void*)text); + if (opt_drop) fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", result_table); if (!opt_xml) @@ -3515,25 +3601,34 @@ static void dump_table(char *table, char *db) } else { - print_comment(md_result_file, 0, - "\n--\n-- Dumping data for table %s\n--\n", - fix_identifier_with_newline(result_table)); - + my_bool freemem= FALSE; + char const* text= fix_identifier_with_newline(result_table, &freemem); + print_comment(md_result_file, 0, "\n--\n-- Dumping data for table %s\n--\n", + text); + if (freemem) + my_free((void*)text); + dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * FROM "); dynstr_append_checked(&query_string, result_table); if (where) { - print_comment(md_result_file, 0, "-- WHERE: %s\n", - fix_identifier_with_newline(where)); + freemem= FALSE; + text= fix_identifier_with_newline(where, &freemem); + print_comment(md_result_file, 0, "-- WHERE: %s\n", text); + if (freemem) + my_free((void*)text); dynstr_append_checked(&query_string, " WHERE "); dynstr_append_checked(&query_string, where); } if (order_by) { - print_comment(md_result_file, 0, "-- ORDER BY: %s\n", - fix_identifier_with_newline(order_by)); + freemem= FALSE; + text= fix_identifier_with_newline(order_by, &freemem); + print_comment(md_result_file, 0, "-- ORDER BY: %s\n", text); + if (freemem) + my_free((void*)text); dynstr_append_checked(&query_string, " ORDER BY "); dynstr_append_checked(&query_string, order_by); @@ -4302,10 +4397,13 @@ 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); + my_bool freemem= FALSE; + char const* text= fix_identifier_with_newline(qdatabase, &freemem); - print_comment(md_result_file, 0, - "\n--\n-- Current Database: %s\n--\n", - fix_identifier_with_newline(qdatabase)); + print_comment(md_result_file, 0, "\n--\n-- Current Database: %s\n--\n", + text); + if (freemem) + my_free((void*)text); /* Call the view or table specific function */ init_func(qdatabase); @@ -5265,6 +5363,8 @@ static my_bool get_view_structure(char *table, char* db) char table_buff2[NAME_LEN*2+3]; char query[QUERY_LENGTH]; FILE *sql_file= md_result_file; + my_bool freemem= FALSE; + char const *text; DBUG_ENTER("get_view_structure"); if (opt_no_create_info) /* Don't write table creation info */ @@ -5309,9 +5409,11 @@ static my_bool get_view_structure(char *table, char* db) write_header(sql_file, db); } + text= fix_identifier_with_newline(result_table, &freemem); print_comment(sql_file, 0, - "\n--\n-- Final view structure for view %s\n--\n\n", - fix_identifier_with_newline(result_table)); + "\n--\n-- Final view structure for view %s\n--\n\n", text); + if (freemem) + my_free((void*)text); /* Table might not exist if this view was dumped with --tab. */ fprintf(sql_file, "/*!50001 DROP TABLE IF EXISTS %s*/;\n", opt_quoted_table); -- cgit v1.2.1 From 940b88b686bcf037a36f6e81be4017a07fcf782a Mon Sep 17 00:00:00 2001 From: Ajo Robert Date: Tue, 10 Apr 2018 00:30:59 +0530 Subject: Bug#27197235 USER VARIABLE + UINON + DECIMAL COLUMN RETURNS WRONG VALUES User variables will have the default session collation associated with it. And a select which uses it as part of a union may infer the collation while type merging. This leads to problems when the result is of DECIMAL type. Setting the appropriate collation of DECIMAL result type is missing in 5.7 code base. Added code to set appropriate collation when the result is of DECIMAL type during Item_type_holder::join_types(). --- mysql-test/r/union.result | 16 ++++++++++++++++ mysql-test/t/union.test | 14 ++++++++++++++ sql/item.cc | 3 ++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 97c1a8b4d49..c0b364d0fde 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -1860,3 +1860,19 @@ DROP TABLE t17059925, t2, t3; SET @@long_query_time= @old_long_query_time; SET @@global.log_output= @old_log_output; SET @@global.slow_query_log= @old_slow_query_log; +# +# Bug#27197235 USER VARIABLE + UINON + DECIMAL COLUMN RETURNS +# WRONG VALUES +# +SET NAMES utf8; +SET @advertAcctId = 1000003; +select @advertAcctId as a from dual union all select 1.0 from dual; +a +1000003.0 +1.0 +SET NAMES latin1; +SET @advertAcctId = 1000003; +select @advertAcctId as a from dual union all select 1.0 from dual; +a +1000003.0 +1.0 diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 147c1d3834b..d7e362558e3 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -1256,3 +1256,17 @@ SET @@long_query_time= @old_long_query_time; SET @@global.log_output= @old_log_output; SET @@global.slow_query_log= @old_slow_query_log; +--echo # +--echo # Bug#27197235 USER VARIABLE + UINON + DECIMAL COLUMN RETURNS +--echo # WRONG VALUES +--echo # + +let $old_charset= `SELECT @@character_set_client`; + +SET NAMES utf8; +SET @advertAcctId = 1000003; +select @advertAcctId as a from dual union all select 1.0 from dual; + +eval SET NAMES $old_charset; +SET @advertAcctId = 1000003; +select @advertAcctId as a from dual union all select 1.0 from dual; diff --git a/sql/item.cc b/sql/item.cc index a37a61453e8..07d64881eeb 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2018, 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 @@ -8266,6 +8266,7 @@ bool Item_type_holder::join_types(THD *thd, Item *item) } if (Field::result_merge_type(fld_type) == DECIMAL_RESULT) { + collation.set_numeric(); decimals= min(max(decimals, item->decimals), DECIMAL_MAX_SCALE); int item_int_part= item->decimal_int_part(); int item_prec = max(prev_decimal_int_part, item_int_part) + decimals; -- cgit v1.2.1 From a08508abf83d953f11e4823798398d9229ba0237 Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Tue, 24 Apr 2018 10:02:04 +0530 Subject: Bug#27407480: AUTOMATIC_SP_PRIVILEGES REQUIRES NEED THE INSERT PRIVILEGES FOR MYSQL.USER TABLE Description:- Incorrect granting of EXECUTE and ALTER ROUTINE privileges when the 'automatic_sp_privileges' variable is set. Fix:- EXECUTE and ALTER ROUTINE privileges are correctly granted to the creator of the procedure when the 'automatic_sp_privileges' is SET. --- mysql-test/r/grant.result | 3 +-- sql/sql_acl.cc | 15 ++++----------- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index 7603e4b1b1c..e524bb5cac2 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1780,8 +1780,6 @@ BEGIN SET @x = 0; REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT; END ;|| -Warnings: -Warning 1404 Failed to grant EXECUTE and ALTER ROUTINE privileges SHOW GRANTS FOR 'user1'@'localhost'; Grants for user1@localhost GRANT USAGE ON *.* TO 'user1'@'localhost' @@ -1791,6 +1789,7 @@ SHOW GRANTS FOR 'user2'; Grants for user2@% GRANT USAGE ON *.* TO 'user2'@'%' GRANT CREATE, CREATE ROUTINE ON `db1`.* TO 'user2'@'%' +GRANT EXECUTE, ALTER ROUTINE ON PROCEDURE `db1`.`proc2` TO 'user2'@'%' DROP PROCEDURE db1.proc1; DROP PROCEDURE db1.proc2; REVOKE ALL ON db1.* FROM 'user1'@'localhost'; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 385484f2b01..705b4792a37 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2018, 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 @@ -7670,19 +7670,12 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, if (!(combo=(LEX_USER*) thd->alloc(sizeof(st_lex_user)))) DBUG_RETURN(TRUE); - combo->user.str= sctx->user; + combo->user.str= (char *) sctx->priv_user; mysql_mutex_lock(&acl_cache->lock); - if ((au= find_acl_user(combo->host.str=(char*)sctx->host_or_ip,combo->user.str,FALSE))) - goto found_acl; - if ((au= find_acl_user(combo->host.str=(char*)sctx->get_host()->ptr(), - combo->user.str,FALSE))) - goto found_acl; - if ((au= find_acl_user(combo->host.str=(char*)sctx->get_ip()->ptr(), - combo->user.str,FALSE))) - goto found_acl; - if((au= find_acl_user(combo->host.str=(char*)"%", combo->user.str, FALSE))) + if ((au= find_acl_user(combo->host.str= (char *) sctx->priv_host, + combo->user.str, FALSE))) goto found_acl; mysql_mutex_unlock(&acl_cache->lock); -- cgit v1.2.1 From f47eac2882b8635b8de252cdca8e46200b1ff724 Mon Sep 17 00:00:00 2001 From: Mayank Prasad Date: Wed, 10 Jan 2018 20:54:09 +0530 Subject: Bug #25928471: ONLINE ALTER AND CONCURRENT DELETE ON TABLE WITH MANY TEXT COLUMNS CAUSES CRASH Issue: ------ Prefix for externally stored columns were being stored in online_log when a table is altered and alter causes table to be rebuilt. Space in online_log is limited and if length of prefix of externally stored columns is very big, then it is being written to online log without making sure if it fits. This leads to memory corruption. Fix: ---- After fix for Bug#16544143, there is no need to store prefixes of externally stored columnd in online_log. Thus remove the code which stores column prefixes for externally stored columns. Also, before writing anything on online_log, make sure it fits to available memory to avoid memory corruption. Read RB page for more details. Reviewed-by: Annamalai Gurusami RB: 18239 --- storage/innobase/row/row0log.cc | 126 ++++++---------------------------------- storage/xtradb/row/row0log.cc | 126 ++++++---------------------------------- 2 files changed, 36 insertions(+), 216 deletions(-) diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index 62ca32b712c..1383c91f41f 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -435,6 +435,8 @@ err_exit: *avail = srv_sort_buf_size - log->tail.bytes; if (size > *avail) { + /* Make sure log->tail.buf is large enough */ + ut_ad(size <= sizeof log->tail.buf); return(log->tail.buf); } else { return(log->tail.block + log->tail.bytes); @@ -528,12 +530,10 @@ row_log_table_delete( { ulint old_pk_extra_size; ulint old_pk_size; - ulint ext_size = 0; ulint mrec_size; ulint avail_size; mem_heap_t* heap = NULL; const dtuple_t* old_pk; - row_ext_t* ext; ut_ad(dict_index_is_clust(index)); ut_ad(rec_offs_validate(rec, index, offsets)); @@ -614,72 +614,20 @@ row_log_table_delete( &old_pk_extra_size); ut_ad(old_pk_extra_size < 0x100); - mrec_size = 6 + old_pk_size; - - /* Log enough prefix of the BLOB unless both the - old and new table are in COMPACT or REDUNDANT format, - which store the prefix in the clustered index record. */ - if (rec_offs_any_extern(offsets) - && (dict_table_get_format(index->table) >= UNIV_FORMAT_B - || dict_table_get_format(new_table) >= UNIV_FORMAT_B)) { - - /* Build a cache of those off-page column prefixes - that are referenced by secondary indexes. It can be - that none of the off-page columns are needed. */ - row_build(ROW_COPY_DATA, index, rec, - offsets, NULL, NULL, NULL, &ext, heap); - if (ext) { - /* Log the row_ext_t, ext->ext and ext->buf */ - ext_size = ext->n_ext * ext->max_len - + sizeof(*ext) - + ext->n_ext * sizeof(ulint) - + (ext->n_ext - 1) * sizeof ext->len; - mrec_size += ext_size; - } - } + /* 2 = 1 (extra_size) + at least 1 byte payload */ + mrec_size = 2 + old_pk_size; if (byte* b = row_log_table_open(index->online_log, mrec_size, &avail_size)) { *b++ = ROW_T_DELETE; *b++ = static_cast(old_pk_extra_size); - /* Log the size of external prefix we saved */ - mach_write_to_4(b, ext_size); - b += 4; - rec_convert_dtuple_to_temp( b + old_pk_extra_size, new_index, old_pk->fields, old_pk->n_fields); b += old_pk_size; - if (ext_size) { - ulint cur_ext_size = sizeof(*ext) - + (ext->n_ext - 1) * sizeof ext->len; - - memcpy(b, ext, cur_ext_size); - b += cur_ext_size; - - /* Check if we need to col_map to adjust the column - number. If columns were added/removed/reordered, - adjust the column number. */ - if (const ulint* col_map = - index->online_log->col_map) { - for (ulint i = 0; i < ext->n_ext; i++) { - const_cast(ext->ext[i]) = - col_map[ext->ext[i]]; - } - } - - memcpy(b, ext->ext, ext->n_ext * sizeof(*ext->ext)); - b += ext->n_ext * sizeof(*ext->ext); - - ext_size -= cur_ext_size - + ext->n_ext * sizeof(*ext->ext); - memcpy(b, ext->buf, ext_size); - b += ext_size; - } - row_log_table_close( index->online_log, b, mrec_size, avail_size); } @@ -1601,15 +1549,13 @@ row_log_table_apply_insert( /******************************************************//** Deletes a record from a table that is being rebuilt. @return DB_SUCCESS or error code */ -static MY_ATTRIBUTE((nonnull(1, 2, 4, 5), warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_log_table_apply_delete_low( /*===========================*/ btr_pcur_t* pcur, /*!< in/out: B-tree cursor, will be trashed */ const ulint* offsets, /*!< in: offsets on pcur */ - const row_ext_t* save_ext, /*!< in: saved external field - info, or NULL */ mem_heap_t* heap, /*!< in/out: memory heap */ mtr_t* mtr) /*!< in/out: mini-transaction, will be committed */ @@ -1633,11 +1579,7 @@ row_log_table_apply_delete_low( /* Build a row template for purging secondary index entries. */ row = row_build( ROW_COPY_DATA, index, btr_pcur_get_rec(pcur), - offsets, NULL, NULL, NULL, - save_ext ? NULL : &ext, heap); - if (!save_ext) { - save_ext = ext; - } + offsets, NULL, NULL, NULL, &ext, heap); } else { row = NULL; } @@ -1656,7 +1598,7 @@ row_log_table_apply_delete_low( } const dtuple_t* entry = row_build_index_entry( - row, save_ext, index, heap); + row, ext, index, heap); mtr_start(mtr); btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_MODIFY_TREE, pcur, mtr); @@ -1699,11 +1641,10 @@ flag_ok: /******************************************************//** Replays a delete operation on a table that was rebuilt. @return DB_SUCCESS or error code */ -static MY_ATTRIBUTE((nonnull(1, 3, 4, 5, 6, 7), warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_log_table_apply_delete( /*=======================*/ - que_thr_t* thr, /*!< in: query graph */ ulint trx_id_col, /*!< in: position of DB_TRX_ID in the new clustered index */ @@ -1712,9 +1653,7 @@ row_log_table_apply_delete( mem_heap_t* offsets_heap, /*!< in/out: memory heap that can be emptied */ mem_heap_t* heap, /*!< in/out: memory heap */ - const row_log_t* log, /*!< in: online log */ - const row_ext_t* save_ext) /*!< in: saved external field - info, or NULL */ + const row_log_t* log) /*!< in: online log */ { dict_table_t* new_table = log->table; dict_index_t* index = dict_table_get_first_index(new_table); @@ -1814,8 +1753,7 @@ all_done: } } - return(row_log_table_apply_delete_low(&pcur, offsets, save_ext, - heap, &mtr)); + return row_log_table_apply_delete_low(&pcur, offsets, heap, &mtr); } /******************************************************//** @@ -2026,7 +1964,7 @@ func_exit_committed: /* Some BLOBs are missing, so we are interpreting this ROW_T_UPDATE as ROW_T_DELETE (see *1). */ error = row_log_table_apply_delete_low( - &pcur, cur_offsets, NULL, heap, &mtr); + &pcur, cur_offsets, heap, &mtr); goto func_exit_committed; } @@ -2064,7 +2002,7 @@ func_exit_committed: } error = row_log_table_apply_delete_low( - &pcur, cur_offsets, NULL, heap, &mtr); + &pcur, cur_offsets, heap, &mtr); ut_ad(mtr.state == MTR_COMMITTED); if (error == DB_SUCCESS) { @@ -2210,8 +2148,6 @@ row_log_table_apply_op( ulint extra_size; const mrec_t* next_mrec; dtuple_t* old_pk; - row_ext_t* ext; - ulint ext_size; ut_ad(dict_index_is_clust(dup->index)); ut_ad(dup->index->table != log->table); @@ -2219,7 +2155,7 @@ row_log_table_apply_op( *error = DB_SUCCESS; - /* 3 = 1 (op type) + 1 (ext_size) + at least 1 byte payload */ + /* 3 = 1 (op type) + 1 (extra_size) + at least 1 byte payload */ if (mrec + 3 >= mrec_end) { return(NULL); } @@ -2269,14 +2205,12 @@ row_log_table_apply_op( break; case ROW_T_DELETE: - /* 1 (extra_size) + 4 (ext_size) + at least 1 (payload) */ - if (mrec + 6 >= mrec_end) { + /* 1 (extra_size) + at least 1 (payload) */ + if (mrec + 2 >= mrec_end) { return(NULL); } extra_size = *mrec++; - ext_size = mach_read_from_4(mrec); - mrec += 4; ut_ad(mrec < mrec_end); /* We assume extra_size < 0x100 for the PRIMARY KEY prefix. @@ -2285,40 +2219,16 @@ row_log_table_apply_op( rec_offs_set_n_fields(offsets, new_index->n_uniq + 2); rec_init_offsets_temp(mrec, new_index, offsets); - next_mrec = mrec + rec_offs_data_size(offsets) + ext_size; + next_mrec = mrec + rec_offs_data_size(offsets); if (next_mrec > mrec_end) { return(NULL); } log->head.total += next_mrec - mrec_start; - /* If there are external fields, retrieve those logged - prefix info and reconstruct the row_ext_t */ - if (ext_size) { - /* We use memcpy to avoid unaligned - access on some non-x86 platforms.*/ - ext = static_cast( - mem_heap_dup(heap, - mrec + rec_offs_data_size(offsets), - ext_size)); - - byte* ext_start = reinterpret_cast(ext); - - ulint ext_len = sizeof(*ext) - + (ext->n_ext - 1) * sizeof ext->len; - - ext->ext = reinterpret_cast(ext_start + ext_len); - ext_len += ext->n_ext * sizeof(*ext->ext); - - ext->buf = static_cast(ext_start + ext_len); - } else { - ext = NULL; - } - *error = row_log_table_apply_delete( - thr, new_trx_id_col, - mrec, offsets, offsets_heap, heap, - log, ext); + new_trx_id_col, + mrec, offsets, offsets_heap, heap, log); break; case ROW_T_UPDATE: diff --git a/storage/xtradb/row/row0log.cc b/storage/xtradb/row/row0log.cc index 52f6a963ec6..c239722e4f7 100644 --- a/storage/xtradb/row/row0log.cc +++ b/storage/xtradb/row/row0log.cc @@ -435,6 +435,8 @@ err_exit: *avail = srv_sort_buf_size - log->tail.bytes; if (size > *avail) { + /* Make sure log->tail.buf is large enough */ + ut_ad(size <= sizeof log->tail.buf); return(log->tail.buf); } else { return(log->tail.block + log->tail.bytes); @@ -528,12 +530,10 @@ row_log_table_delete( { ulint old_pk_extra_size; ulint old_pk_size; - ulint ext_size = 0; ulint mrec_size; ulint avail_size; mem_heap_t* heap = NULL; const dtuple_t* old_pk; - row_ext_t* ext; ut_ad(dict_index_is_clust(index)); ut_ad(rec_offs_validate(rec, index, offsets)); @@ -614,72 +614,20 @@ row_log_table_delete( &old_pk_extra_size); ut_ad(old_pk_extra_size < 0x100); - mrec_size = 6 + old_pk_size; - - /* Log enough prefix of the BLOB unless both the - old and new table are in COMPACT or REDUNDANT format, - which store the prefix in the clustered index record. */ - if (rec_offs_any_extern(offsets) - && (dict_table_get_format(index->table) >= UNIV_FORMAT_B - || dict_table_get_format(new_table) >= UNIV_FORMAT_B)) { - - /* Build a cache of those off-page column prefixes - that are referenced by secondary indexes. It can be - that none of the off-page columns are needed. */ - row_build(ROW_COPY_DATA, index, rec, - offsets, NULL, NULL, NULL, &ext, heap); - if (ext) { - /* Log the row_ext_t, ext->ext and ext->buf */ - ext_size = ext->n_ext * ext->max_len - + sizeof(*ext) - + ext->n_ext * sizeof(ulint) - + (ext->n_ext - 1) * sizeof ext->len; - mrec_size += ext_size; - } - } + /* 2 = 1 (extra_size) + at least 1 byte payload */ + mrec_size = 2 + old_pk_size; if (byte* b = row_log_table_open(index->online_log, mrec_size, &avail_size)) { *b++ = ROW_T_DELETE; *b++ = static_cast(old_pk_extra_size); - /* Log the size of external prefix we saved */ - mach_write_to_4(b, ext_size); - b += 4; - rec_convert_dtuple_to_temp( b + old_pk_extra_size, new_index, old_pk->fields, old_pk->n_fields); b += old_pk_size; - if (ext_size) { - ulint cur_ext_size = sizeof(*ext) - + (ext->n_ext - 1) * sizeof ext->len; - - memcpy(b, ext, cur_ext_size); - b += cur_ext_size; - - /* Check if we need to col_map to adjust the column - number. If columns were added/removed/reordered, - adjust the column number. */ - if (const ulint* col_map = - index->online_log->col_map) { - for (ulint i = 0; i < ext->n_ext; i++) { - const_cast(ext->ext[i]) = - col_map[ext->ext[i]]; - } - } - - memcpy(b, ext->ext, ext->n_ext * sizeof(*ext->ext)); - b += ext->n_ext * sizeof(*ext->ext); - - ext_size -= cur_ext_size - + ext->n_ext * sizeof(*ext->ext); - memcpy(b, ext->buf, ext_size); - b += ext_size; - } - row_log_table_close( index->online_log, b, mrec_size, avail_size); } @@ -1601,15 +1549,13 @@ row_log_table_apply_insert( /******************************************************//** Deletes a record from a table that is being rebuilt. @return DB_SUCCESS or error code */ -static MY_ATTRIBUTE((nonnull(1, 2, 4, 5), warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_log_table_apply_delete_low( /*===========================*/ btr_pcur_t* pcur, /*!< in/out: B-tree cursor, will be trashed */ const ulint* offsets, /*!< in: offsets on pcur */ - const row_ext_t* save_ext, /*!< in: saved external field - info, or NULL */ mem_heap_t* heap, /*!< in/out: memory heap */ mtr_t* mtr) /*!< in/out: mini-transaction, will be committed */ @@ -1633,11 +1579,7 @@ row_log_table_apply_delete_low( /* Build a row template for purging secondary index entries. */ row = row_build( ROW_COPY_DATA, index, btr_pcur_get_rec(pcur), - offsets, NULL, NULL, NULL, - save_ext ? NULL : &ext, heap); - if (!save_ext) { - save_ext = ext; - } + offsets, NULL, NULL, NULL, &ext, heap); } else { row = NULL; } @@ -1656,7 +1598,7 @@ row_log_table_apply_delete_low( } const dtuple_t* entry = row_build_index_entry( - row, save_ext, index, heap); + row, ext, index, heap); mtr_start(mtr); btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_MODIFY_TREE, pcur, mtr); @@ -1699,11 +1641,10 @@ flag_ok: /******************************************************//** Replays a delete operation on a table that was rebuilt. @return DB_SUCCESS or error code */ -static MY_ATTRIBUTE((nonnull(1, 3, 4, 5, 6, 7), warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_log_table_apply_delete( /*=======================*/ - que_thr_t* thr, /*!< in: query graph */ ulint trx_id_col, /*!< in: position of DB_TRX_ID in the new clustered index */ @@ -1712,9 +1653,7 @@ row_log_table_apply_delete( mem_heap_t* offsets_heap, /*!< in/out: memory heap that can be emptied */ mem_heap_t* heap, /*!< in/out: memory heap */ - const row_log_t* log, /*!< in: online log */ - const row_ext_t* save_ext) /*!< in: saved external field - info, or NULL */ + const row_log_t* log) /*!< in: online log */ { dict_table_t* new_table = log->table; dict_index_t* index = dict_table_get_first_index(new_table); @@ -1814,8 +1753,7 @@ all_done: } } - return(row_log_table_apply_delete_low(&pcur, offsets, save_ext, - heap, &mtr)); + return row_log_table_apply_delete_low(&pcur, offsets, heap, &mtr); } /******************************************************//** @@ -2026,7 +1964,7 @@ func_exit_committed: /* Some BLOBs are missing, so we are interpreting this ROW_T_UPDATE as ROW_T_DELETE (see *1). */ error = row_log_table_apply_delete_low( - &pcur, cur_offsets, NULL, heap, &mtr); + &pcur, cur_offsets, heap, &mtr); goto func_exit_committed; } @@ -2064,7 +2002,7 @@ func_exit_committed: } error = row_log_table_apply_delete_low( - &pcur, cur_offsets, NULL, heap, &mtr); + &pcur, cur_offsets, heap, &mtr); ut_ad(mtr.state == MTR_COMMITTED); if (error == DB_SUCCESS) { @@ -2210,8 +2148,6 @@ row_log_table_apply_op( ulint extra_size; const mrec_t* next_mrec; dtuple_t* old_pk; - row_ext_t* ext; - ulint ext_size; ut_ad(dict_index_is_clust(dup->index)); ut_ad(dup->index->table != log->table); @@ -2219,7 +2155,7 @@ row_log_table_apply_op( *error = DB_SUCCESS; - /* 3 = 1 (op type) + 1 (ext_size) + at least 1 byte payload */ + /* 3 = 1 (op type) + 1 (extra_size) + at least 1 byte payload */ if (mrec + 3 >= mrec_end) { return(NULL); } @@ -2269,14 +2205,12 @@ row_log_table_apply_op( break; case ROW_T_DELETE: - /* 1 (extra_size) + 4 (ext_size) + at least 1 (payload) */ - if (mrec + 6 >= mrec_end) { + /* 1 (extra_size) + at least 1 (payload) */ + if (mrec + 2 >= mrec_end) { return(NULL); } extra_size = *mrec++; - ext_size = mach_read_from_4(mrec); - mrec += 4; ut_ad(mrec < mrec_end); /* We assume extra_size < 0x100 for the PRIMARY KEY prefix. @@ -2285,40 +2219,16 @@ row_log_table_apply_op( rec_offs_set_n_fields(offsets, new_index->n_uniq + 2); rec_init_offsets_temp(mrec, new_index, offsets); - next_mrec = mrec + rec_offs_data_size(offsets) + ext_size; + next_mrec = mrec + rec_offs_data_size(offsets); if (next_mrec > mrec_end) { return(NULL); } log->head.total += next_mrec - mrec_start; - /* If there are external fields, retrieve those logged - prefix info and reconstruct the row_ext_t */ - if (ext_size) { - /* We use memcpy to avoid unaligned - access on some non-x86 platforms.*/ - ext = static_cast( - mem_heap_dup(heap, - mrec + rec_offs_data_size(offsets), - ext_size)); - - byte* ext_start = reinterpret_cast(ext); - - ulint ext_len = sizeof(*ext) - + (ext->n_ext - 1) * sizeof ext->len; - - ext->ext = reinterpret_cast(ext_start + ext_len); - ext_len += ext->n_ext * sizeof(*ext->ext); - - ext->buf = static_cast(ext_start + ext_len); - } else { - ext = NULL; - } - *error = row_log_table_apply_delete( - thr, new_trx_id_col, - mrec, offsets, offsets_heap, heap, - log, ext); + new_trx_id_col, + mrec, offsets, offsets_heap, heap, log); break; case ROW_T_UPDATE: -- cgit v1.2.1 From a411910dd677f161b301c095f36373f4f5da5555 Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Thu, 3 May 2018 10:26:00 -0400 Subject: bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 75daccdd9d4..59a439d4152 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=0 -MYSQL_VERSION_PATCH=35 +MYSQL_VERSION_PATCH=36 -- cgit v1.2.1 From 1cb7c4bfc05b85f4384f4a719568d29b83abf1da Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 3 May 2018 16:14:54 +0100 Subject: MDEV-16084 Calling exit() from a signal handler is unsafe. Call _exit() from signal handler. main() can just do return. --- mysql-test/lib/My/SafeProcess/safe_process.cc | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/mysql-test/lib/My/SafeProcess/safe_process.cc b/mysql-test/lib/My/SafeProcess/safe_process.cc index feb3eb4df66..5f6544414e2 100644 --- a/mysql-test/lib/My/SafeProcess/safe_process.cc +++ b/mysql-test/lib/My/SafeProcess/safe_process.cc @@ -89,7 +89,7 @@ static void die(const char* fmt, ...) } -static void kill_child(bool was_killed) +static int kill_child(bool was_killed) { int status= 0; @@ -108,15 +108,15 @@ static void kill_child(bool was_killed) exit_code= WEXITSTATUS(status); message("Child exit: %d", exit_code); // Exit with exit status of the child - exit(exit_code); + return exit_code; } if (WIFSIGNALED(status)) message("Child killed by signal: %d", WTERMSIG(status)); - exit(exit_code); + return exit_code; } - exit(5); + return 5; } @@ -136,7 +136,7 @@ extern "C" void handle_signal(int sig) terminated= 1; if (child_pid > 0) - kill_child(sig == SIGCHLD); + _exit(kill_child(sig == SIGCHLD)); // Ignore further signals signal(SIGTERM, SIG_IGN); @@ -292,8 +292,6 @@ int main(int argc, char* const argv[] ) /* Wait for parent or child to die */ sleep(1); } - kill_child(0); - - return 4; + return kill_child(0); } -- cgit v1.2.1 From 1d58d184c2c4ddd8a3b2be6f86d76c4e57bbe14f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 4 May 2018 00:09:45 +0200 Subject: protocol: verify that number of rows is correct --- sql-common/client.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/sql-common/client.c b/sql-common/client.c index 00e2877bedb..6321e64bc75 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1483,7 +1483,9 @@ unpack_fields(MYSQL *mysql, MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, { uchar *pos; /* fields count may be wrong */ - DBUG_ASSERT((uint) (field - result) < fields); + if (field - result >= fields) + goto err; + cli_fetch_lengths(&lengths[0], row->data, default_value ? 8 : 7); field->catalog= strmake_root(alloc,(char*) row->data[0], lengths[0]); field->db= strmake_root(alloc,(char*) row->data[1], lengths[1]); @@ -1501,12 +1503,7 @@ unpack_fields(MYSQL *mysql, MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, /* Unpack fixed length parts */ if (lengths[6] != 12) - { - /* malformed packet. signal an error. */ - free_rows(data); /* Free old data */ - set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate); - DBUG_RETURN(0); - } + goto err; pos= (uchar*) row->data[6]; field->charsetnr= uint2korr(pos); @@ -1533,6 +1530,8 @@ unpack_fields(MYSQL *mysql, MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, /* old protocol, for backward compatibility */ for (row=data->data; row ; row = row->next,field++) { + if (field - result >= fields) + goto err; cli_fetch_lengths(&lengths[0], row->data, default_value ? 6 : 5); field->org_table= field->table= strdup_root(alloc,(char*) row->data[0]); field->name= strdup_root(alloc,(char*) row->data[1]); @@ -1569,8 +1568,17 @@ unpack_fields(MYSQL *mysql, MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, } } #endif /* DELETE_SUPPORT_OF_4_0_PROTOCOL */ + if (field - result < fields) + goto err; free_rows(data); /* Free old data */ DBUG_RETURN(result); + +err: + /* malformed packet. signal an error. */ + free_rows(data); + free_root(alloc, MYF(0)); + set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate); + DBUG_RETURN(0); } /* Read all rows (fields or data) from server */ -- cgit v1.2.1 From 04b1e61d69ebfdeab196c28ef19316b27f8588bc Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 4 May 2018 15:51:13 +0200 Subject: compiler warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit storage/connect/tabjson.cpp:198:10: warning: converting to non-pointer type ‘int’ from NULL [-Wconversion-null] return NULL; --- storage/connect/tabjson.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp index b66682e0190..9e4f5ab987d 100644 --- a/storage/connect/tabjson.cpp +++ b/storage/connect/tabjson.cpp @@ -195,7 +195,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) tdp->Fn = GetStringTableOption(g, topt, "Filename", NULL); if (!(tdp->Database = SetPath(g, db))) - return NULL; + return 0; tdp->Objname = GetStringTableOption(g, topt, "Object", NULL); tdp->Base = GetIntegerTableOption(g, topt, "Base", 0) ? 1 : 0; @@ -243,14 +243,14 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) tjsp = new(g) TDBJSON(tdp, new(g) MAPFAM(tdp)); if (tjsp->MakeDocument(g)) - return NULL; + return 0; jsp = (tjsp->GetDoc()) ? tjsp->GetDoc()->GetValue(0) : NULL; } else { if (!(tdp->Lrecl = GetIntegerTableOption(g, topt, "Lrecl", 0))) if (!mgo) { sprintf(g->Message, "LRECL must be specified for pretty=%d", tdp->Pretty); - return NULL; + return 0; } else tdp->Lrecl = 8192; // Should be enough @@ -269,14 +269,14 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) tjnp = new(g) TDBJSN(tdp, new(g) CMGFAM(tdp)); #else sprintf(g->Message, "Mongo %s Driver not available", "C"); - return NULL; + return 0; #endif } else if (tdp->Driver && toupper(*tdp->Driver) == 'J') { #if defined(JAVA_SUPPORT) tjnp = new(g) TDBJSN(tdp, new(g) JMGFAM(tdp)); #else sprintf(g->Message, "Mongo %s Driver not available", "Java"); - return NULL; + return 0; #endif } else { // Driver not specified #if defined(CMGO_SUPPORT) @@ -285,7 +285,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) tjnp = new(g) TDBJSN(tdp, new(g) JMGFAM(tdp)); #else sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "MONGO"); - return NULL; + return 0; #endif } // endif Driver @@ -304,7 +304,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) tjnp->SetG(G); if (tjnp->OpenDB(g)) - return NULL; + return 0; switch (tjnp->ReadDB(g)) { case RC_EF: -- cgit v1.2.1 From 7b9486d2eb3876d55edc05173235e6ccad2e6ae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 7 May 2018 11:52:05 +0300 Subject: MDEV-14693 XA: Assertion `!clust_index->online_log' failed in rollback_inplace_alter_table ha_innobase::commit_inplace_alter_table(): Defer the freeing of ctx->trx until after the operation has been successfully committed. In this way, rollback on a partitioned table will be possible. rollback_inplace_alter_table(): Handle ctx->new_table == NULL when ctx->trx != NULL. --- .../suite/innodb/r/alter_partitioned_xa.result | 15 +++++++ .../suite/innodb/t/alter_partitioned_xa.test | 31 +++++++++++++ storage/innobase/handler/handler0alter.cc | 52 ++++++++++++---------- storage/xtradb/handler/handler0alter.cc | 52 ++++++++++++---------- 4 files changed, 104 insertions(+), 46 deletions(-) create mode 100644 mysql-test/suite/innodb/r/alter_partitioned_xa.result create mode 100644 mysql-test/suite/innodb/t/alter_partitioned_xa.test diff --git a/mysql-test/suite/innodb/r/alter_partitioned_xa.result b/mysql-test/suite/innodb/r/alter_partitioned_xa.result new file mode 100644 index 00000000000..4bce2f8676f --- /dev/null +++ b/mysql-test/suite/innodb/r/alter_partitioned_xa.result @@ -0,0 +1,15 @@ +# +# MDEV-14693 XA: Assertion `!clust_index->online_log' failed +# in rollback_inplace_alter_table +# +CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB PARTITION BY HASH(a) PARTITIONS 2; +XA START 'xid'; +INSERT INTO t1 VALUES (1,10); +CREATE DATABASE IF NOT EXISTS db; +ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state +SET innodb_lock_wait_timeout= 1, lock_wait_timeout= 2; +ALTER TABLE t1 FORCE; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +XA END 'xid'; +XA ROLLBACK 'xid'; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/alter_partitioned_xa.test b/mysql-test/suite/innodb/t/alter_partitioned_xa.test new file mode 100644 index 00000000000..f0883802cd6 --- /dev/null +++ b/mysql-test/suite/innodb/t/alter_partitioned_xa.test @@ -0,0 +1,31 @@ +--source include/have_innodb.inc +--source include/have_partition.inc + +--echo # +--echo # MDEV-14693 XA: Assertion `!clust_index->online_log' failed +--echo # in rollback_inplace_alter_table +--echo # + +# A bug in meta-data locking (MDL) for XA transactions causes +# a bug in InnoDB error handling for ALTER TABLE to be triggered. +CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB PARTITION BY HASH(a) PARTITIONS 2; +XA START 'xid'; +INSERT INTO t1 VALUES (1,10); +# XA bug: The following releases the MDL on t1! +--error ER_XAER_RMFAIL +CREATE DATABASE IF NOT EXISTS db; + +--connect (con1,localhost,root,,test) +SET innodb_lock_wait_timeout= 1, lock_wait_timeout= 2; +# Here, innodb_lock_wait_timeout would be exceeded, causing the operation +# to roll back when InnoDB is attempting to commit. +# (Instead, lock_wait_timeout should be exceeded!) +--error ER_LOCK_WAIT_TIMEOUT +ALTER TABLE t1 FORCE; + +# Cleanup +--disconnect con1 +--connection default +XA END 'xid'; +XA ROLLBACK 'xid'; +DROP TABLE t1; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 508275f091d..86935a4aa34 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -4296,12 +4296,16 @@ rollback_inplace_alter_table( row_mysql_lock_data_dictionary(ctx->trx); if (ctx->need_rebuild()) { - dberr_t err; - ulint flags = ctx->new_table->flags; - /* DML threads can access ctx->new_table via the online rebuild log. Free it first. */ innobase_online_rebuild_log_free(prebuilt->table); + } + + if (!ctx->new_table) { + ut_ad(ctx->need_rebuild()); + } else if (ctx->need_rebuild()) { + dberr_t err; + ulint flags = ctx->new_table->flags; /* Since the FTS index specific auxiliary tables has not yet registered with "table->fts" by fts_add_index(), @@ -5669,21 +5673,6 @@ ha_innobase::commit_inplace_alter_table( ut_ad(prebuilt->table == ctx0->old_table); ha_alter_info->group_commit_ctx = NULL; - /* Free the ctx->trx of other partitions, if any. We will only - use the ctx0->trx here. Others may have been allocated in - the prepare stage. */ - - for (inplace_alter_handler_ctx** pctx = &ctx_array[1]; *pctx; - pctx++) { - ha_innobase_inplace_ctx* ctx - = static_cast(*pctx); - - if (ctx->trx) { - trx_free_for_mysql(ctx->trx); - ctx->trx = NULL; - } - } - trx_start_if_not_started_xa(prebuilt->trx); for (inplace_alter_handler_ctx** pctx = ctx_array; *pctx; pctx++) { @@ -6056,10 +6045,6 @@ foreign_fail: covering all partitions. */ share->idx_trans_tbl.index_count = 0; - if (trx == ctx0->trx) { - ctx0->trx = NULL; - } - /* Tell the InnoDB server that there might be work for utility threads: */ @@ -6082,10 +6067,31 @@ foreign_fail: } row_mysql_unlock_data_dictionary(trx); - trx_free_for_mysql(trx); + if (trx != ctx0->trx) { + trx_free_for_mysql(trx); + } DBUG_RETURN(true); } + if (trx == ctx0->trx) { + ctx0->trx = NULL; + } + + /* Free the ctx->trx of other partitions, if any. We will only + use the ctx0->trx here. Others may have been allocated in + the prepare stage. */ + + for (inplace_alter_handler_ctx** pctx = &ctx_array[1]; *pctx; + pctx++) { + ha_innobase_inplace_ctx* ctx + = static_cast(*pctx); + + if (ctx->trx) { + trx_free_for_mysql(ctx->trx); + ctx->trx = NULL; + } + } + /* Release the table locks. */ trx_commit_for_mysql(prebuilt->trx); diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index 4a50b324e22..ff524e6a9be 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -4310,12 +4310,16 @@ rollback_inplace_alter_table( row_mysql_lock_data_dictionary(ctx->trx); if (ctx->need_rebuild()) { - dberr_t err; - ulint flags = ctx->new_table->flags; - /* DML threads can access ctx->new_table via the online rebuild log. Free it first. */ innobase_online_rebuild_log_free(prebuilt->table); + } + + if (!ctx->new_table) { + ut_ad(ctx->need_rebuild()); + } else if (ctx->need_rebuild()) { + dberr_t err; + ulint flags = ctx->new_table->flags; /* Since the FTS index specific auxiliary tables has not yet registered with "table->fts" by fts_add_index(), @@ -5677,21 +5681,6 @@ ha_innobase::commit_inplace_alter_table( ut_ad(prebuilt->table == ctx0->old_table); ha_alter_info->group_commit_ctx = NULL; - /* Free the ctx->trx of other partitions, if any. We will only - use the ctx0->trx here. Others may have been allocated in - the prepare stage. */ - - for (inplace_alter_handler_ctx** pctx = &ctx_array[1]; *pctx; - pctx++) { - ha_innobase_inplace_ctx* ctx - = static_cast(*pctx); - - if (ctx->trx) { - trx_free_for_mysql(ctx->trx); - ctx->trx = NULL; - } - } - trx_start_if_not_started_xa(prebuilt->trx); for (inplace_alter_handler_ctx** pctx = ctx_array; *pctx; pctx++) { @@ -6057,10 +6046,6 @@ foreign_fail: covering all partitions. */ share->idx_trans_tbl.index_count = 0; - if (trx == ctx0->trx) { - ctx0->trx = NULL; - } - /* Tell the InnoDB server that there might be work for utility threads: */ @@ -6083,10 +6068,31 @@ foreign_fail: } row_mysql_unlock_data_dictionary(trx); - trx_free_for_mysql(trx); + if (trx != ctx0->trx) { + trx_free_for_mysql(trx); + } DBUG_RETURN(true); } + if (trx == ctx0->trx) { + ctx0->trx = NULL; + } + + /* Free the ctx->trx of other partitions, if any. We will only + use the ctx0->trx here. Others may have been allocated in + the prepare stage. */ + + for (inplace_alter_handler_ctx** pctx = &ctx_array[1]; *pctx; + pctx++) { + ha_innobase_inplace_ctx* ctx + = static_cast(*pctx); + + if (ctx->trx) { + trx_free_for_mysql(ctx->trx); + ctx->trx = NULL; + } + } + /* Release the table locks. */ trx_commit_for_mysql(prebuilt->trx); -- cgit v1.2.1 From 0d429dcb37aec2c9f768b57162e9751dff5cf1f7 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 6 May 2018 22:47:30 +0200 Subject: rename a test --- mysql-test/r/assign_key_cache-5405.result | 14 -------------- mysql-test/r/assign_key_cache_debug.result | 14 ++++++++++++++ mysql-test/t/assign_key_cache-5405.test | 27 --------------------------- mysql-test/t/assign_key_cache_debug.test | 27 +++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 41 deletions(-) delete mode 100644 mysql-test/r/assign_key_cache-5405.result create mode 100644 mysql-test/r/assign_key_cache_debug.result delete mode 100644 mysql-test/t/assign_key_cache-5405.test create mode 100644 mysql-test/t/assign_key_cache_debug.test diff --git a/mysql-test/r/assign_key_cache-5405.result b/mysql-test/r/assign_key_cache-5405.result deleted file mode 100644 index 4a0fc58cd4f..00000000000 --- a/mysql-test/r/assign_key_cache-5405.result +++ /dev/null @@ -1,14 +0,0 @@ -create table t1 (f int, key(f)) engine=myisam; -set global kc1.key_buffer_size = 65536; -set debug_sync='assign_key_cache_op_unlock wait_for op_locked'; -cache index t1 in kc1; -set debug_sync='assign_key_cache_op_lock signal op_locked wait_for assigned'; -cache index t1 in kc1; -Table Op Msg_type Msg_text -test.t1 assign_to_keycache status OK -set debug_sync='now signal assigned'; -Table Op Msg_type Msg_text -test.t1 assign_to_keycache status OK -drop table t1; -set global kc1.key_buffer_size = 0; -set debug_sync='reset'; diff --git a/mysql-test/r/assign_key_cache_debug.result b/mysql-test/r/assign_key_cache_debug.result new file mode 100644 index 00000000000..4a0fc58cd4f --- /dev/null +++ b/mysql-test/r/assign_key_cache_debug.result @@ -0,0 +1,14 @@ +create table t1 (f int, key(f)) engine=myisam; +set global kc1.key_buffer_size = 65536; +set debug_sync='assign_key_cache_op_unlock wait_for op_locked'; +cache index t1 in kc1; +set debug_sync='assign_key_cache_op_lock signal op_locked wait_for assigned'; +cache index t1 in kc1; +Table Op Msg_type Msg_text +test.t1 assign_to_keycache status OK +set debug_sync='now signal assigned'; +Table Op Msg_type Msg_text +test.t1 assign_to_keycache status OK +drop table t1; +set global kc1.key_buffer_size = 0; +set debug_sync='reset'; diff --git a/mysql-test/t/assign_key_cache-5405.test b/mysql-test/t/assign_key_cache-5405.test deleted file mode 100644 index 2839e040bd3..00000000000 --- a/mysql-test/t/assign_key_cache-5405.test +++ /dev/null @@ -1,27 +0,0 @@ -# -# MDEV-5405 RQG induced crash in mi_assign_to_key_cache in safe mutex unlock -# ---source include/have_debug_sync.inc -create table t1 (f int, key(f)) engine=myisam; -set global kc1.key_buffer_size = 65536; - -connect (con1, localhost, root); - -set debug_sync='assign_key_cache_op_unlock wait_for op_locked'; -send cache index t1 in kc1; - -connection default; -sleep 1; -set debug_sync='assign_key_cache_op_lock signal op_locked wait_for assigned'; -send cache index t1 in kc1; - -connection con1; -reap; -set debug_sync='now signal assigned'; -disconnect con1; -connection default; -reap; - -drop table t1; -set global kc1.key_buffer_size = 0; -set debug_sync='reset'; diff --git a/mysql-test/t/assign_key_cache_debug.test b/mysql-test/t/assign_key_cache_debug.test new file mode 100644 index 00000000000..2839e040bd3 --- /dev/null +++ b/mysql-test/t/assign_key_cache_debug.test @@ -0,0 +1,27 @@ +# +# MDEV-5405 RQG induced crash in mi_assign_to_key_cache in safe mutex unlock +# +--source include/have_debug_sync.inc +create table t1 (f int, key(f)) engine=myisam; +set global kc1.key_buffer_size = 65536; + +connect (con1, localhost, root); + +set debug_sync='assign_key_cache_op_unlock wait_for op_locked'; +send cache index t1 in kc1; + +connection default; +sleep 1; +set debug_sync='assign_key_cache_op_lock signal op_locked wait_for assigned'; +send cache index t1 in kc1; + +connection con1; +reap; +set debug_sync='now signal assigned'; +disconnect con1; +connection default; +reap; + +drop table t1; +set global kc1.key_buffer_size = 0; +set debug_sync='reset'; -- cgit v1.2.1 From 087ea8f820f46e200a2f8f84328c078555dda45f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 8 May 2018 10:31:35 +0200 Subject: de-obfuscate rpl_*_implicit_commit_binlog test --- .../rpl_tests/rpl_implicit_commit_binlog.test | 708 +++------------------ .../rpl/r/rpl_mixed_implicit_commit_binlog.result | 530 ++++----------- .../rpl/r/rpl_row_implicit_commit_binlog.result | 519 ++++----------- .../rpl/r/rpl_stm_implicit_commit_binlog.result | 517 ++++----------- 4 files changed, 443 insertions(+), 1831 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_implicit_commit_binlog.test b/mysql-test/extra/rpl_tests/rpl_implicit_commit_binlog.test index 765757c3427..20c79ed4b3b 100644 --- a/mysql-test/extra/rpl_tests/rpl_implicit_commit_binlog.test +++ b/mysql-test/extra/rpl_tests/rpl_implicit_commit_binlog.test @@ -32,627 +32,97 @@ INSERT INTO tt_2(ddl_case) VALUES(0); --echo # CHECK IMPLICT COMMIT --echo ######################################################################### SET AUTOCOMMIT= 0; -let $ddl_cases= 43; -while ($ddl_cases >= 1) -{ - --echo -b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- - let $in_temporary= no; - let $ok= yes; - # - # In SBR and MIXED modes, the commit event is usually the third event in the - # binary log: - # - # 1: BEGIN - # 2: INSERT - # 3: COMMIT - # 4: DDL EVENT which triggered the previous commmit. - # - if (`select @@binlog_format = 'STATEMENT' || @@binlog_format = 'MIXED'`) - { - let $commit_event_row_number= 3; - } - # - # In RBR mode, the commit event is usually the fourth event in the binary log: - # - # 1: BEGIN - # 2: TABLE MAP EVENT - # 3: ROW EVENT - # 4: COMMIT - # 5: DDL EVENT which triggered the previous commmit. - # - if (`select @@binlog_format = 'ROW'`) - { - let $commit_event_row_number= 4; - } - # - # In NDB (RBR and MIXED modes), the commit event is usually the seventh event - # in the binary log: - # - # 1: COMMAND - # 2: BEGIN - # 3: TABLE MAP EVENT - # 4: TABLE MAP EVENT (ndb_apply_status) - # 5: ROW EVENT - # 6: ROW EVENT - # 7: COMMIT - # - if ($engine == NDB) - { - let $commit_event_row_number= 7; - } - - let $first_binlog_position= query_get_value("SHOW MASTER STATUS", Position, 1); - --enable_query_log - eval INSERT INTO tt_1(ddl_case) VALUES ($ddl_cases); - if ($ddl_cases == 43) - { - let $cmd= CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "$UDF_EXAMPLE_SO"; - } - if ($ddl_cases == 42) - { - let $cmd= DROP FUNCTION myfunc_int; - } - if ($ddl_cases == 41) - { - let $cmd= LOAD INDEX INTO CACHE nt_1 IGNORE LEAVES; - if ($engine == NDB) - { - # This seems to be related to epochs. - # We need to check this against an updated version or avoid it. - let $ok= no; - let $commit_event_row_number= 6; - } - } - if ($ddl_cases == 40) - { - let $cmd= LOAD INDEX INTO CACHE tt_1, tt_2 IGNORE LEAVES; - # - # In NDB (RBR and MIXED modes), the commit event is the sixth event - # in the binary log: - # - # 1: BEGIN - # 2: TABLE MAP EVENT - # 3: TABLE MAP EVENT (ndb_apply_status) - # 4: ROW EVENT - # 5: ROW EVENT - # 6: COMMIT - # - if ($engine == NDB) - { - let $commit_event_row_number= 6; - } - } - if ($ddl_cases == 39) - { - let $cmd= ANALYZE TABLE nt_1; - } - if ($ddl_cases == 38) - { - let $cmd= CHECK TABLE nt_1; - # - # In NDB (RBR and MIXED modes), the commit event is the sixth event - # in the binary log: - # - # 1: BEGIN - # 2: TABLE MAP EVENT - # 3: TABLE MAP EVENT (ndb_apply_status) - # 4: ROW EVENT - # 5: ROW EVENT - # 6: COMMIT - # - if ($engine == NDB) - { - let $commit_event_row_number= 6; - } - } - if ($ddl_cases == 37) - { - let $cmd= OPTIMIZE TABLE nt_1; - } - if ($ddl_cases == 36) - { - let $cmd= REPAIR TABLE nt_1; - } - if ($ddl_cases == 35) - { - let $cmd= LOCK TABLES tt_1 WRITE; - # - # In NDB (RBR and MIXED modes), the commit event is the sixth event - # in the binary log: - # - # 1: BEGIN - # 2: TABLE MAP EVENT - # 3: TABLE MAP EVENT (ndb_apply_status) - # 4: ROW EVENT - # 5: ROW EVENT - # 6: COMMIT - # - if ($engine == NDB) - { - let $commit_event_row_number= 6; - } - } - if ($ddl_cases == 34) - { - let $cmd= UNLOCK TABLES; - # - # In NDB (RBR and MIXED modes), the commit event is the sixth event - # in the binary log: - # - # 1: BEGIN - # 2: TABLE MAP EVENT - # 3: TABLE MAP EVENT (ndb_apply_status) - # 4: ROW EVENT - # 5: ROW EVENT - # 6: COMMIT - # - if ($engine == NDB) - { - let $commit_event_row_number= 6; - } - } - if ($ddl_cases == 33) - { - let $cmd= CREATE USER 'user'@'localhost'; - } - if ($ddl_cases == 32) - { - let $cmd= GRANT ALL ON *.* TO 'user'@'localhost'; - } - if ($ddl_cases == 31) - { - let $cmd= SET PASSWORD FOR 'user'@'localhost' = PASSWORD('newpass'); - # - # In NDB (RBR mode), the commit event is the eleventh event - # in the binary log: - # - # 1: DDL EVENT which triggered the previous commmit. - # 2: BEGIN - # 3: TABLE MAP EVENT - # 4: ROW EVENT - # 5: COMMIT - # 6: BEGIN - # 7: TABLE MAP EVENT - # 8: TABLE MAP EVENT (ndb_apply_status) - # 9: ROW EVENT - # 10: ROW EVENT - # 11: COMMIT - # - if (`SELECT '$engine' = 'NDB' && @@binlog_format = 'ROW'`) - { - let $commit_event_row_number= 11; - } - # - # In NDB (MIXED mode), the commit event is the eighth event - # in the binary log: - # - # 1: DDL EVENT which triggered the previous commmit. - # 2: BEGIN - # 3: TABLE MAP EVENT - # 4: TABLE MAP EVENT (ndb_apply_status) - # 5: ROW EVENT - # 6: ROW EVENT - # 7: COMMIT - # - if (`SELECT '$engine' = 'NDB' && @@binlog_format != 'ROW'`) - { - let $commit_event_row_number= 7; - } - } - if ($ddl_cases == 30) - { - let $cmd= REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user'@'localhost'; - } - if ($ddl_cases == 29) - { - let $cmd= RENAME USER 'user'@'localhost' TO 'user_new'@'localhost'; - } - if ($ddl_cases == 28) - { - let $cmd= DROP USER 'user_new'@'localhost'; - } - if ($ddl_cases == 27) - { - let $cmd= CREATE EVENT evt ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO SELECT * FROM tt_1; - } - if ($ddl_cases == 26) - { - let $cmd= ALTER EVENT evt COMMENT 'evt'; - } - if ($ddl_cases == 25) - { - let $cmd= DROP EVENT evt; - } - if ($ddl_cases == 24) - { - let $cmd= CREATE TRIGGER tr AFTER INSERT ON tt_1 FOR EACH ROW UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case; - } - if ($ddl_cases == 23) - { - let $cmd= DROP TRIGGER tr; - # - # In RBR mode, due to the trigger the tt_2 is also updated: - # - # 1: BEGIN - # 2: TABLE MAP EVENT - # 3: TABLE MAP EVENT - # 4: ROW EVENT - # 5: COMMIT - # 6: DDL EVENT which triggered the previous commmit. - # - if (`select @@binlog_format = 'ROW' && '$engine' != 'NDB'`) - { - let $commit_event_row_number= 5; - } - } - if ($ddl_cases == 22) - { - let $cmd= CREATE FUNCTION fc () RETURNS VARCHAR(64) RETURN "fc"; - } - if ($ddl_cases == 21) - { - let $cmd= ALTER FUNCTION fc COMMENT 'fc'; - } - if ($ddl_cases == 20) - { - let $cmd= DROP FUNCTION fc; - } - if ($ddl_cases == 19) - { - let $cmd= CREATE PROCEDURE pc () UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case; - } - if ($ddl_cases == 18) - { - let $cmd= ALTER PROCEDURE pc COMMENT 'pc'; - } - if ($ddl_cases == 17) - { - let $cmd= DROP PROCEDURE pc; - } - if ($ddl_cases == 16) - { - let $cmd= CREATE VIEW v AS SELECT * FROM tt_1; - } - if ($ddl_cases == 15) - { - let $cmd= ALTER VIEW v AS SELECT * FROM tt_1; - } - if ($ddl_cases == 14) - { - let $cmd= DROP VIEW v; - } - if ($ddl_cases == 13) - { - let $cmd= CREATE INDEX ix ON tt_1(ddl_case); - # - # In NDB (RBR and MIXED modes), the commit event is the sixth event - # in the binary log: - # - # 1: BEGIN - # 2: TABLE MAP EVENT - # 3: TABLE MAP EVENT (ndb_apply_status) - # 4: ROW EVENT - # 5: ROW EVENT - # 6: COMMIT - # 7: DDL EVENT which triggered the previous commmit. - # - if ($engine == NDB) - { - let $commit_event_row_number= 6; - } - } - if ($ddl_cases == 12) - { - let $cmd= DROP INDEX ix ON tt_1; - # - # In NDB (RBR and MIXED modes), the commit event is the sixth event - # in the binary log: - # - # 1: BEGIN - # 2: TABLE MAP EVENT - # 3: TABLE MAP EVENT (ndb_apply_status) - # 4: ROW EVENT - # 5: ROW EVENT - # 6: COMMIT - # 7: DDL EVENT which triggered the previous commmit. - # - if ($engine == NDB) - { - let $commit_event_row_number= 6; - } - } - if ($ddl_cases == 11) - { - let $cmd= CREATE TEMPORARY TABLE tt_xx (a int); - let $in_temporary= yes; - # In SBR and MIXED modes, the DDL statement is written to the binary log but - # does not commit the current transaction. - # - # 1: BEGIN - # 2: CREATE TEMPORARY - # 3: INSERT - # 4: COMMIT - # - # In RBR the transaction is not committed either and the statement is not - # written to the binary log: - # - # 1: BEGIN - # 2: TABLE MAP EVENT - # 3: ROW EVENT - # 4: COMMIT - # - if (`select @@binlog_format = 'STATEMENT' || @@binlog_format = 'MIXED'` ) - { - let $commit_event_row_number= 4; - } - # - # In NDB (RBR mode), the commit event is the sixth event - # in the binary log: - # - # 1: BEGIN - # 2: TABLE MAP EVENT - # 3: TABLE MAP EVENT (ndb_apply_status) - # 4: ROW EVENT - # 5: ROW EVENT - # 6: COMMIT - # - if (`SELECT '$engine' = 'NDB' && @@binlog_format = 'ROW'` ) - { - let $commit_event_row_number= 6; - } - # - # In NDB (MIXED mode), the commit event is the nineth event - # in the binary log: - # - # 1: BEGIN - # 2: DDL EVENT which triggered the previous commmit. - # 3: COMMIT - # 4: BEGIN - # 5: TABLE MAP EVENT - # 6: TABLE MAP EVENT (ndb_apply_status) - # 7: ROW EVENT - # 8: ROW EVENT - # 9: COMMIT - # - if (`SELECT '$engine' = 'NDB' && @@binlog_format != 'ROW'` ) - { - let $commit_event_row_number= 9; - } - } - if ($ddl_cases == 10) - { - let $cmd= ALTER TABLE tt_xx ADD COLUMN (b int); - # - # In MIXED mode, the changes are logged as rows and we have what follows: - # - # 1: BEGIN - # 2: TABLE MAP EVENT - # 3: ROW EVENT - # 4: COMMIT - # 5: DDL EVENT which triggered the previous commmit. - # - if (`select @@binlog_format = 'MIXED'`) - { - let $commit_event_row_number= 4; - } - # - # In NDB (RBR and MIXED modes), the commit event is the sixth event - # in the binary log: - # - # 1: BEGIN - # 2: TABLE MAP EVENT - # 3: TABLE MAP EVENT (ndb_apply_status) - # 4: ROW EVENT - # 5: ROW EVENT - # 6: COMMIT - # - if ($engine == NDB) - { - let $commit_event_row_number= 6; - } - } - if ($ddl_cases == 9) - { - let $cmd= ALTER TABLE tt_xx RENAME new_tt_xx; - # - # In MIXED mode, the changes are logged as rows and we have what follows: - # - # 1: BEGIN - # 2: TABLE MAP EVENT - # 3: ROW EVENT - # 4: COMMIT - # 5: DDL EVENT which triggered the previous commmit. - # - if (`select @@binlog_format = 'MIXED'`) - { - let $commit_event_row_number= 4; - } - # - # In NDB (RBR and MIXED modes), the commit event is the sixth event - # in the binary log: - # - # 1: BEGIN - # 2: TABLE MAP EVENT - # 3: TABLE MAP EVENT (ndb_apply_status) - # 4: ROW EVENT - # 5: ROW EVENT - # 6: COMMIT - # - if ($engine == NDB) - { - let $commit_event_row_number= 6; - } - } - if ($ddl_cases == 8) - { - let $cmd= DROP TEMPORARY TABLE IF EXISTS new_tt_xx; - let $in_temporary= yes; - # - # In SBR and MIXED modes, the DDL statement is written to the binary log - # but does not commit the current transaction: - # - # In SBR, we have what follows: - # - # 1: BEGIN - # 2: INSERT - # 3: DROP TEMPORARY - # 4: COMMIT - # - # In RBR the transaction is not committed either and the statement is not - # written to the binary log: - # - # 1: BEGIN - # 2: TABLE MAP EVENT - # 3: ROW EVENT - # 4: COMMIT - # - if (`select @@binlog_format = 'STATEMENT'`) - { - let $commit_event_row_number= 4; - } - # In MIXED mode, the changes are logged as rows and we have what follows: - # - # 1: BEGIN - # 2: TABLE MAP EVENT - # 3: ROW EVENT - # 4: DROP TEMPORARY table IF EXISTS - # 5: COMMIT - # - if (`select @@binlog_format = 'MIXED' || @@binlog_format = 'ROW'`) - { - let $commit_event_row_number= 5; - } - # - # In NDB (RBR and MIXED modes), the commit event is the sixth event - # in the binary log: - # - # 1: BEGIN - # 2: DROP TEMPORARY table IF EXISTS - # 3: COMMIT - # 4: BEGIN - # 5: TABLE MAP EVENT - # 6: TABLE MAP EVENT (ndb_apply_status) - # 7: ROW EVENT - # 8: ROW EVENT - # 9: COMMIT - # - if ($engine == NDB) - { - let $commit_event_row_number= 9; - } - # - # In NDB (MIXED mode), the commit event is the nineth event - # in the binary log: - # - # 1: BEGIN - # 2: DDL EVENT which triggered the previous commmit. - # 3: COMMIT - # 4: BEGIN - # 5: TABLE MAP EVENT - # 6: TABLE MAP EVENT (ndb_apply_status) - # 7: ROW EVENT - # 8: ROW EVENT - # 9: COMMIT - # - if (`SELECT '$engine' = 'NDB' && @@binlog_format != 'ROW'` ) - { - let $commit_event_row_number= 9; - } - } - if ($ddl_cases == 7) - { - let $cmd= CREATE TABLE tt_xx (a int); - } - if ($ddl_cases == 6) - { - let $cmd= ALTER TABLE tt_xx ADD COLUMN (b int); - } - if ($ddl_cases == 5) - { - let $cmd= RENAME TABLE tt_xx TO new_tt_xx; - } - if ($ddl_cases == 4) - { - let $cmd= TRUNCATE TABLE new_tt_xx; - } - if ($ddl_cases == 3) - { - let $cmd= DROP TABLE IF EXISTS tt_xx, new_tt_xx; - } - if ($ddl_cases == 2) - { - let $cmd= CREATE DATABASE db; - # - # In NDB (RBR and MIXED modes), the commit event is the sixth event - # in the binary log: - # - # 1: BEGIN - # 2: TABLE MAP EVENT - # 3: TABLE MAP EVENT (ndb_apply_status) - # 4: ROW EVENT - # 5: ROW EVENT - # 6: COMMIT - # 7: DDL EVENT which triggered the previous commmit. - # - if ($engine == NDB) - { - let $commit_event_row_number= 6; - } - } - if ($ddl_cases == 1) - { - let $cmd= DROP DATABASE IF EXISTS db; - # - # In NDB (RBR and MIXED modes), the commit event is the sixth event - # in the binary log: - # - # 1: BEGIN - # 2: TABLE MAP EVENT - # 3: TABLE MAP EVENT (ndb_apply_status) - # 4: ROW EVENT - # 5: ROW EVENT - # 6: COMMIT - # 7: DDL EVENT which triggered the previous commmit. - # - if ($engine == NDB) - { - let $commit_event_row_number= 6; - } - } - --replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB - --eval $cmd - --disable_query_log - # - # When a temporary table is either created or dropped, there is no implicit - # commit. The flag in_temporary is used to avoid aborting the test in such - # cases. Thus we force the commit. - # - if ($in_temporary == yes) - { - --eval COMMIT - } - let $event_commit= query_get_value("SHOW BINLOG EVENTS FROM $first_binlog_position", Info, $commit_event_row_number); - if (`SELECT SUBSTRING("$event_commit",1,6) != "COMMIT"`) - { - if ($ok == yes) - { - --echo it *does not* commit the current transaction. - --echo $cmd - --echo $event_commit - SHOW BINLOG EVENTS; - exit; - } - } +INSERT INTO tt_1(ddl_case) VALUES (43); +replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB; +eval CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "$UDF_EXAMPLE_SO"; +INSERT INTO tt_1(ddl_case) VALUES (42); +DROP FUNCTION myfunc_int; +INSERT INTO tt_1(ddl_case) VALUES (41); +LOAD INDEX INTO CACHE nt_1 IGNORE LEAVES; +INSERT INTO tt_1(ddl_case) VALUES (40); +LOAD INDEX INTO CACHE tt_1, tt_2 IGNORE LEAVES; +INSERT INTO tt_1(ddl_case) VALUES (39); +ANALYZE TABLE nt_1; +INSERT INTO tt_1(ddl_case) VALUES (38); +CHECK TABLE nt_1; +INSERT INTO tt_1(ddl_case) VALUES (37); +OPTIMIZE TABLE nt_1; +INSERT INTO tt_1(ddl_case) VALUES (36); +REPAIR TABLE nt_1; +INSERT INTO tt_1(ddl_case) VALUES (35); +LOCK TABLES tt_1 WRITE; +INSERT INTO tt_1(ddl_case) VALUES (34); +UNLOCK TABLES; +INSERT INTO tt_1(ddl_case) VALUES (33); +CREATE USER 'user'@'localhost'; +INSERT INTO tt_1(ddl_case) VALUES (32); +GRANT ALL ON *.* TO 'user'@'localhost'; +INSERT INTO tt_1(ddl_case) VALUES (31); +SET PASSWORD FOR 'user'@'localhost' = PASSWORD('newpass'); +INSERT INTO tt_1(ddl_case) VALUES (30); +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user'@'localhost'; +INSERT INTO tt_1(ddl_case) VALUES (29); +RENAME USER 'user'@'localhost' TO 'user_new'@'localhost'; +INSERT INTO tt_1(ddl_case) VALUES (28); +DROP USER 'user_new'@'localhost'; +INSERT INTO tt_1(ddl_case) VALUES (27); +CREATE EVENT evt ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO SELECT * FROM tt_1; +INSERT INTO tt_1(ddl_case) VALUES (26); +ALTER EVENT evt COMMENT 'evt'; +INSERT INTO tt_1(ddl_case) VALUES (25); +DROP EVENT evt; +INSERT INTO tt_1(ddl_case) VALUES (24); +CREATE TRIGGER tr AFTER INSERT ON tt_1 FOR EACH ROW UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case; +INSERT INTO tt_1(ddl_case) VALUES (23); +DROP TRIGGER tr; +INSERT INTO tt_1(ddl_case) VALUES (22); +CREATE FUNCTION fc () RETURNS VARCHAR(64) RETURN "fc"; +INSERT INTO tt_1(ddl_case) VALUES (21); +ALTER FUNCTION fc COMMENT 'fc'; +INSERT INTO tt_1(ddl_case) VALUES (20); +DROP FUNCTION fc; +INSERT INTO tt_1(ddl_case) VALUES (19); +CREATE PROCEDURE pc () UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case; +INSERT INTO tt_1(ddl_case) VALUES (18); +ALTER PROCEDURE pc COMMENT 'pc'; +INSERT INTO tt_1(ddl_case) VALUES (17); +DROP PROCEDURE pc; +INSERT INTO tt_1(ddl_case) VALUES (16); +CREATE VIEW v AS SELECT * FROM tt_1; +INSERT INTO tt_1(ddl_case) VALUES (15); +ALTER VIEW v AS SELECT * FROM tt_1; +INSERT INTO tt_1(ddl_case) VALUES (14); +DROP VIEW v; +INSERT INTO tt_1(ddl_case) VALUES (13); +CREATE INDEX ix ON tt_1(ddl_case); +INSERT INTO tt_1(ddl_case) VALUES (12); +DROP INDEX ix ON tt_1; +INSERT INTO tt_1(ddl_case) VALUES (11); +CREATE TEMPORARY TABLE tt_xx (a int); +INSERT INTO tt_1(ddl_case) VALUES (10); +ALTER TABLE tt_xx ADD COLUMN (b int); +INSERT INTO tt_1(ddl_case) VALUES (9); +ALTER TABLE tt_xx RENAME new_tt_xx; +INSERT INTO tt_1(ddl_case) VALUES (8); +DROP TEMPORARY TABLE IF EXISTS new_tt_xx; +INSERT INTO tt_1(ddl_case) VALUES (7); +CREATE TABLE tt_xx (a int); +INSERT INTO tt_1(ddl_case) VALUES (6); +ALTER TABLE tt_xx ADD COLUMN (b int); +INSERT INTO tt_1(ddl_case) VALUES (5); +RENAME TABLE tt_xx TO new_tt_xx; +INSERT INTO tt_1(ddl_case) VALUES (4); +TRUNCATE TABLE new_tt_xx; +INSERT INTO tt_1(ddl_case) VALUES (3); +DROP TABLE IF EXISTS tt_xx, new_tt_xx; +INSERT INTO tt_1(ddl_case) VALUES (2); +CREATE DATABASE db; +INSERT INTO tt_1(ddl_case) VALUES (1); +DROP DATABASE IF EXISTS db; + +source include/show_binlog_events.inc; - --echo -e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - let $binlog_start= $first_binlog_position; - --echo -b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- - --source include/show_binlog_events.inc - --echo -e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --echo - dec $ddl_cases; -} SET AUTOCOMMIT= 1; --echo ################################################################################### diff --git a/mysql-test/suite/rpl/r/rpl_mixed_implicit_commit_binlog.result b/mysql-test/suite/rpl/r/rpl_mixed_implicit_commit_binlog.result index 328c3c3423f..e272961abe9 100644 --- a/mysql-test/suite/rpl/r/rpl_mixed_implicit_commit_binlog.result +++ b/mysql-test/suite/rpl/r/rpl_mixed_implicit_commit_binlog.result @@ -13,612 +13,323 @@ INSERT INTO tt_2(ddl_case) VALUES(0); # CHECK IMPLICT COMMIT ######################################################################### SET AUTOCOMMIT= 0; --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- INSERT INTO tt_1(ddl_case) VALUES (43); CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB"; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_1(ddl_case) VALUES (42); +DROP FUNCTION myfunc_int; +INSERT INTO tt_1(ddl_case) VALUES (41); +LOAD INDEX INTO CACHE nt_1 IGNORE LEAVES; +Table Op Msg_type Msg_text +test.nt_1 preload_keys status OK +INSERT INTO tt_1(ddl_case) VALUES (40); +LOAD INDEX INTO CACHE tt_1, tt_2 IGNORE LEAVES; +Table Op Msg_type Msg_text +test.tt_1 preload_keys note The storage engine for the table doesn't support preload_keys +test.tt_2 preload_keys note The storage engine for the table doesn't support preload_keys +INSERT INTO tt_1(ddl_case) VALUES (39); +ANALYZE TABLE nt_1; +Table Op Msg_type Msg_text +test.nt_1 analyze status Table is already up to date +INSERT INTO tt_1(ddl_case) VALUES (38); +CHECK TABLE nt_1; +Table Op Msg_type Msg_text +test.nt_1 check status OK +INSERT INTO tt_1(ddl_case) VALUES (37); +OPTIMIZE TABLE nt_1; +Table Op Msg_type Msg_text +test.nt_1 optimize status Table is already up to date +INSERT INTO tt_1(ddl_case) VALUES (36); +REPAIR TABLE nt_1; +Table Op Msg_type Msg_text +test.nt_1 repair status OK +INSERT INTO tt_1(ddl_case) VALUES (35); +LOCK TABLES tt_1 WRITE; +INSERT INTO tt_1(ddl_case) VALUES (34); +UNLOCK TABLES; +INSERT INTO tt_1(ddl_case) VALUES (33); +CREATE USER 'user'@'localhost'; +INSERT INTO tt_1(ddl_case) VALUES (32); +GRANT ALL ON *.* TO 'user'@'localhost'; +INSERT INTO tt_1(ddl_case) VALUES (31); +SET PASSWORD FOR 'user'@'localhost' = PASSWORD('newpass'); +INSERT INTO tt_1(ddl_case) VALUES (30); +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user'@'localhost'; +INSERT INTO tt_1(ddl_case) VALUES (29); +RENAME USER 'user'@'localhost' TO 'user_new'@'localhost'; +INSERT INTO tt_1(ddl_case) VALUES (28); +DROP USER 'user_new'@'localhost'; +INSERT INTO tt_1(ddl_case) VALUES (27); +CREATE EVENT evt ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO SELECT * FROM tt_1; +INSERT INTO tt_1(ddl_case) VALUES (26); +ALTER EVENT evt COMMENT 'evt'; +INSERT INTO tt_1(ddl_case) VALUES (25); +DROP EVENT evt; +INSERT INTO tt_1(ddl_case) VALUES (24); +CREATE TRIGGER tr AFTER INSERT ON tt_1 FOR EACH ROW UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case; +INSERT INTO tt_1(ddl_case) VALUES (23); +DROP TRIGGER tr; +INSERT INTO tt_1(ddl_case) VALUES (22); +CREATE FUNCTION fc () RETURNS VARCHAR(64) RETURN "fc"; +INSERT INTO tt_1(ddl_case) VALUES (21); +ALTER FUNCTION fc COMMENT 'fc'; +INSERT INTO tt_1(ddl_case) VALUES (20); +DROP FUNCTION fc; +INSERT INTO tt_1(ddl_case) VALUES (19); +CREATE PROCEDURE pc () UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case; +INSERT INTO tt_1(ddl_case) VALUES (18); +ALTER PROCEDURE pc COMMENT 'pc'; +INSERT INTO tt_1(ddl_case) VALUES (17); +DROP PROCEDURE pc; +INSERT INTO tt_1(ddl_case) VALUES (16); +CREATE VIEW v AS SELECT * FROM tt_1; +INSERT INTO tt_1(ddl_case) VALUES (15); +ALTER VIEW v AS SELECT * FROM tt_1; +INSERT INTO tt_1(ddl_case) VALUES (14); +DROP VIEW v; +INSERT INTO tt_1(ddl_case) VALUES (13); +CREATE INDEX ix ON tt_1(ddl_case); +INSERT INTO tt_1(ddl_case) VALUES (12); +DROP INDEX ix ON tt_1; +INSERT INTO tt_1(ddl_case) VALUES (11); +CREATE TEMPORARY TABLE tt_xx (a int); +INSERT INTO tt_1(ddl_case) VALUES (10); +ALTER TABLE tt_xx ADD COLUMN (b int); +INSERT INTO tt_1(ddl_case) VALUES (9); +ALTER TABLE tt_xx RENAME new_tt_xx; +INSERT INTO tt_1(ddl_case) VALUES (8); +DROP TEMPORARY TABLE IF EXISTS new_tt_xx; +INSERT INTO tt_1(ddl_case) VALUES (7); +CREATE TABLE tt_xx (a int); +INSERT INTO tt_1(ddl_case) VALUES (6); +ALTER TABLE tt_xx ADD COLUMN (b int); +INSERT INTO tt_1(ddl_case) VALUES (5); +RENAME TABLE tt_xx TO new_tt_xx; +INSERT INTO tt_1(ddl_case) VALUES (4); +TRUNCATE TABLE new_tt_xx; +INSERT INTO tt_1(ddl_case) VALUES (3); +DROP TABLE IF EXISTS tt_xx, new_tt_xx; +Warnings: +Note 1051 Unknown table 'test.tt_xx' +INSERT INTO tt_1(ddl_case) VALUES (2); +CREATE DATABASE db; +INSERT INTO tt_1(ddl_case) VALUES (1); +DROP DATABASE IF EXISTS db; include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE tt_1 (ddl_case INT, PRIMARY KEY(ddl_case)) ENGINE = Innodb +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE tt_2 (ddl_case INT, PRIMARY KEY(ddl_case)) ENGINE = Innodb +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE nt_1 (ddl_case INT, PRIMARY KEY(ddl_case)) ENGINE = MyIsam +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES(0) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2(ddl_case) VALUES(0) +master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (43) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "LIB" --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (42); -DROP FUNCTION myfunc_int; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (42) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP FUNCTION myfunc_int --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (41); -LOAD INDEX INTO CACHE nt_1 IGNORE LEAVES; -Table Op Msg_type Msg_text -test.nt_1 preload_keys status OK --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (41) master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (40); -LOAD INDEX INTO CACHE tt_1, tt_2 IGNORE LEAVES; -Table Op Msg_type Msg_text -test.tt_1 preload_keys note The storage engine for the table doesn't support preload_keys -test.tt_2 preload_keys note The storage engine for the table doesn't support preload_keys --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (40) master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (39); -ANALYZE TABLE nt_1; -Table Op Msg_type Msg_text -test.nt_1 analyze status Table is already up to date --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (39) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; ANALYZE TABLE nt_1 --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (38); -CHECK TABLE nt_1; -Table Op Msg_type Msg_text -test.nt_1 check status OK --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (38) master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (37); -OPTIMIZE TABLE nt_1; -Table Op Msg_type Msg_text -test.nt_1 optimize status Table is already up to date --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (37) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; OPTIMIZE TABLE nt_1 --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (36); -REPAIR TABLE nt_1; -Table Op Msg_type Msg_text -test.nt_1 repair status OK --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (36) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; REPAIR TABLE nt_1 --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (35); -LOCK TABLES tt_1 WRITE; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (35) master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (34); -UNLOCK TABLES; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (34) master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (33); -CREATE USER 'user'@'localhost'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (33) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE USER 'user'@'localhost' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (32); -GRANT ALL ON *.* TO 'user'@'localhost'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (32) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; GRANT ALL ON *.* TO 'user'@'localhost' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (31); -SET PASSWORD FOR 'user'@'localhost' = PASSWORD('newpass'); --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (31) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; SET PASSWORD FOR 'user'@'localhost'='*D8DECEC305209EEFEC43008E1D420E1AA06B19E0' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (30); -REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user'@'localhost'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (30) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user'@'localhost' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (29); -RENAME USER 'user'@'localhost' TO 'user_new'@'localhost'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (29) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; RENAME USER 'user'@'localhost' TO 'user_new'@'localhost' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (28); -DROP USER 'user_new'@'localhost'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (28) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP USER 'user_new'@'localhost' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (27); -CREATE EVENT evt ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO SELECT * FROM tt_1; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (27) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` EVENT evt ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO SELECT * FROM tt_1 --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (26); -ALTER EVENT evt COMMENT 'evt'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (26) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; ALTER EVENT evt COMMENT 'evt' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (25); -DROP EVENT evt; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (25) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP EVENT evt --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (24); -CREATE TRIGGER tr AFTER INSERT ON tt_1 FOR EACH ROW UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (24) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER tr AFTER INSERT ON tt_1 FOR EACH ROW UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (23); -DROP TRIGGER tr; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (23) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP TRIGGER tr --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (22); -CREATE FUNCTION fc () RETURNS VARCHAR(64) RETURN "fc"; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (22) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `fc`() RETURNS varchar(64) CHARSET latin1 RETURN "fc" --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (21); -ALTER FUNCTION fc COMMENT 'fc'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (21) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; ALTER FUNCTION fc COMMENT 'fc' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (20); -DROP FUNCTION fc; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (20) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP FUNCTION fc --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (19); -CREATE PROCEDURE pc () UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (19) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `pc`() UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (18); -ALTER PROCEDURE pc COMMENT 'pc'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (18) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; ALTER PROCEDURE pc COMMENT 'pc' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (17); -DROP PROCEDURE pc; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (17) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP PROCEDURE pc --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (16); -CREATE VIEW v AS SELECT * FROM tt_1; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (16) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v` AS SELECT * FROM tt_1 --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (15); -ALTER VIEW v AS SELECT * FROM tt_1; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (15) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; ALTER ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v` AS SELECT * FROM tt_1 --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (14); -DROP VIEW v; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (14) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP VIEW v --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (13); -CREATE INDEX ix ON tt_1(ddl_case); --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (13) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE INDEX ix ON tt_1(ddl_case) --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (12); -DROP INDEX ix ON tt_1; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (12) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP INDEX ix ON tt_1 --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (11); -CREATE TEMPORARY TABLE tt_xx (a int); --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (11) master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tt_xx (a int) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (10) master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (10); -ALTER TABLE tt_xx ADD COLUMN (b int); --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Gtid # # BEGIN GTID #-#-# -master-bin.000001 # Table_map # # table_id: # (test.tt_1) -master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (9); -ALTER TABLE tt_xx RENAME new_tt_xx; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; ALTER TABLE tt_xx ADD COLUMN (b int) master-bin.000001 # Gtid # # BEGIN GTID #-#-# -master-bin.000001 # Table_map # # table_id: # (test.tt_1) -master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (9) master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (8); -DROP TEMPORARY TABLE IF EXISTS new_tt_xx; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; ALTER TABLE tt_xx RENAME new_tt_xx master-bin.000001 # Gtid # # BEGIN GTID #-#-# -master-bin.000001 # Table_map # # table_id: # (test.tt_1) -master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (8) master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`new_tt_xx` /* generated by server */ -master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (7); -CREATE TABLE tt_xx (a int); --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (7) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE TABLE tt_xx (a int) --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (6); -ALTER TABLE tt_xx ADD COLUMN (b int); --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (6) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; ALTER TABLE tt_xx ADD COLUMN (b int) --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (5); -RENAME TABLE tt_xx TO new_tt_xx; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (5) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; RENAME TABLE tt_xx TO new_tt_xx --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (4); -TRUNCATE TABLE new_tt_xx; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (4) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE new_tt_xx --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (3); -DROP TABLE IF EXISTS tt_xx, new_tt_xx; -Warnings: -Note 1051 Unknown table 'test.tt_xx' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (3) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `tt_xx`,`new_tt_xx` /* generated by server */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (2); -CREATE DATABASE db; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (2) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # CREATE DATABASE db --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (1); -DROP DATABASE IF EXISTS db; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (1) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # DROP DATABASE IF EXISTS db --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - +SET AUTOCOMMIT= 1; ################################################################################### # CHECK CONSISTENCY ################################################################################### @@ -626,4 +337,7 @@ include/diff_tables.inc [master:tt_1,slave:tt_1] ################################################################################### # CLEAN ################################################################################### +DROP TABLE tt_1; +DROP TABLE tt_2; +DROP TABLE nt_1; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_row_implicit_commit_binlog.result b/mysql-test/suite/rpl/r/rpl_row_implicit_commit_binlog.result index cc537f83ca4..5d6590bd821 100644 --- a/mysql-test/suite/rpl/r/rpl_row_implicit_commit_binlog.result +++ b/mysql-test/suite/rpl/r/rpl_row_implicit_commit_binlog.result @@ -13,316 +13,233 @@ INSERT INTO tt_2(ddl_case) VALUES(0); # CHECK IMPLICT COMMIT ######################################################################### SET AUTOCOMMIT= 0; --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- INSERT INTO tt_1(ddl_case) VALUES (43); CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB"; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_1(ddl_case) VALUES (42); +DROP FUNCTION myfunc_int; +INSERT INTO tt_1(ddl_case) VALUES (41); +LOAD INDEX INTO CACHE nt_1 IGNORE LEAVES; +Table Op Msg_type Msg_text +test.nt_1 preload_keys status OK +INSERT INTO tt_1(ddl_case) VALUES (40); +LOAD INDEX INTO CACHE tt_1, tt_2 IGNORE LEAVES; +Table Op Msg_type Msg_text +test.tt_1 preload_keys note The storage engine for the table doesn't support preload_keys +test.tt_2 preload_keys note The storage engine for the table doesn't support preload_keys +INSERT INTO tt_1(ddl_case) VALUES (39); +ANALYZE TABLE nt_1; +Table Op Msg_type Msg_text +test.nt_1 analyze status Table is already up to date +INSERT INTO tt_1(ddl_case) VALUES (38); +CHECK TABLE nt_1; +Table Op Msg_type Msg_text +test.nt_1 check status OK +INSERT INTO tt_1(ddl_case) VALUES (37); +OPTIMIZE TABLE nt_1; +Table Op Msg_type Msg_text +test.nt_1 optimize status Table is already up to date +INSERT INTO tt_1(ddl_case) VALUES (36); +REPAIR TABLE nt_1; +Table Op Msg_type Msg_text +test.nt_1 repair status OK +INSERT INTO tt_1(ddl_case) VALUES (35); +LOCK TABLES tt_1 WRITE; +INSERT INTO tt_1(ddl_case) VALUES (34); +UNLOCK TABLES; +INSERT INTO tt_1(ddl_case) VALUES (33); +CREATE USER 'user'@'localhost'; +INSERT INTO tt_1(ddl_case) VALUES (32); +GRANT ALL ON *.* TO 'user'@'localhost'; +INSERT INTO tt_1(ddl_case) VALUES (31); +SET PASSWORD FOR 'user'@'localhost' = PASSWORD('newpass'); +INSERT INTO tt_1(ddl_case) VALUES (30); +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user'@'localhost'; +INSERT INTO tt_1(ddl_case) VALUES (29); +RENAME USER 'user'@'localhost' TO 'user_new'@'localhost'; +INSERT INTO tt_1(ddl_case) VALUES (28); +DROP USER 'user_new'@'localhost'; +INSERT INTO tt_1(ddl_case) VALUES (27); +CREATE EVENT evt ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO SELECT * FROM tt_1; +INSERT INTO tt_1(ddl_case) VALUES (26); +ALTER EVENT evt COMMENT 'evt'; +INSERT INTO tt_1(ddl_case) VALUES (25); +DROP EVENT evt; +INSERT INTO tt_1(ddl_case) VALUES (24); +CREATE TRIGGER tr AFTER INSERT ON tt_1 FOR EACH ROW UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case; +INSERT INTO tt_1(ddl_case) VALUES (23); +DROP TRIGGER tr; +INSERT INTO tt_1(ddl_case) VALUES (22); +CREATE FUNCTION fc () RETURNS VARCHAR(64) RETURN "fc"; +INSERT INTO tt_1(ddl_case) VALUES (21); +ALTER FUNCTION fc COMMENT 'fc'; +INSERT INTO tt_1(ddl_case) VALUES (20); +DROP FUNCTION fc; +INSERT INTO tt_1(ddl_case) VALUES (19); +CREATE PROCEDURE pc () UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case; +INSERT INTO tt_1(ddl_case) VALUES (18); +ALTER PROCEDURE pc COMMENT 'pc'; +INSERT INTO tt_1(ddl_case) VALUES (17); +DROP PROCEDURE pc; +INSERT INTO tt_1(ddl_case) VALUES (16); +CREATE VIEW v AS SELECT * FROM tt_1; +INSERT INTO tt_1(ddl_case) VALUES (15); +ALTER VIEW v AS SELECT * FROM tt_1; +INSERT INTO tt_1(ddl_case) VALUES (14); +DROP VIEW v; +INSERT INTO tt_1(ddl_case) VALUES (13); +CREATE INDEX ix ON tt_1(ddl_case); +INSERT INTO tt_1(ddl_case) VALUES (12); +DROP INDEX ix ON tt_1; +INSERT INTO tt_1(ddl_case) VALUES (11); +CREATE TEMPORARY TABLE tt_xx (a int); +INSERT INTO tt_1(ddl_case) VALUES (10); +ALTER TABLE tt_xx ADD COLUMN (b int); +INSERT INTO tt_1(ddl_case) VALUES (9); +ALTER TABLE tt_xx RENAME new_tt_xx; +INSERT INTO tt_1(ddl_case) VALUES (8); +DROP TEMPORARY TABLE IF EXISTS new_tt_xx; +INSERT INTO tt_1(ddl_case) VALUES (7); +CREATE TABLE tt_xx (a int); +INSERT INTO tt_1(ddl_case) VALUES (6); +ALTER TABLE tt_xx ADD COLUMN (b int); +INSERT INTO tt_1(ddl_case) VALUES (5); +RENAME TABLE tt_xx TO new_tt_xx; +INSERT INTO tt_1(ddl_case) VALUES (4); +TRUNCATE TABLE new_tt_xx; +INSERT INTO tt_1(ddl_case) VALUES (3); +DROP TABLE IF EXISTS tt_xx, new_tt_xx; +Warnings: +Note 1051 Unknown table 'test.tt_xx' +INSERT INTO tt_1(ddl_case) VALUES (2); +CREATE DATABASE db; +INSERT INTO tt_1(ddl_case) VALUES (1); +DROP DATABASE IF EXISTS db; include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE tt_1 (ddl_case INT, PRIMARY KEY(ddl_case)) ENGINE = Innodb +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE tt_2 (ddl_case INT, PRIMARY KEY(ddl_case)) ENGINE = Innodb +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE nt_1 (ddl_case INT, PRIMARY KEY(ddl_case)) ENGINE = MyIsam +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Table_map # # table_id: # (test.tt_1) +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "LIB" --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (42); -DROP FUNCTION myfunc_int; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP FUNCTION myfunc_int --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (41); -LOAD INDEX INTO CACHE nt_1 IGNORE LEAVES; -Table Op Msg_type Msg_text -test.nt_1 preload_keys status OK --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (40); -LOAD INDEX INTO CACHE tt_1, tt_2 IGNORE LEAVES; -Table Op Msg_type Msg_text -test.tt_1 preload_keys note The storage engine for the table doesn't support preload_keys -test.tt_2 preload_keys note The storage engine for the table doesn't support preload_keys --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (39); -ANALYZE TABLE nt_1; -Table Op Msg_type Msg_text -test.nt_1 analyze status Table is already up to date --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; ANALYZE TABLE nt_1 --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (38); -CHECK TABLE nt_1; -Table Op Msg_type Msg_text -test.nt_1 check status OK --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (37); -OPTIMIZE TABLE nt_1; -Table Op Msg_type Msg_text -test.nt_1 optimize status Table is already up to date --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; OPTIMIZE TABLE nt_1 --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (36); -REPAIR TABLE nt_1; -Table Op Msg_type Msg_text -test.nt_1 repair status OK --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; REPAIR TABLE nt_1 --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (35); -LOCK TABLES tt_1 WRITE; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (34); -UNLOCK TABLES; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (33); -CREATE USER 'user'@'localhost'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE USER 'user'@'localhost' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (32); -GRANT ALL ON *.* TO 'user'@'localhost'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; GRANT ALL ON *.* TO 'user'@'localhost' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (31); -SET PASSWORD FOR 'user'@'localhost' = PASSWORD('newpass'); --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; SET PASSWORD FOR 'user'@'localhost'='*D8DECEC305209EEFEC43008E1D420E1AA06B19E0' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (30); -REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user'@'localhost'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user'@'localhost' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (29); -RENAME USER 'user'@'localhost' TO 'user_new'@'localhost'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; RENAME USER 'user'@'localhost' TO 'user_new'@'localhost' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (28); -DROP USER 'user_new'@'localhost'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP USER 'user_new'@'localhost' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (27); -CREATE EVENT evt ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO SELECT * FROM tt_1; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` EVENT evt ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO SELECT * FROM tt_1 --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (26); -ALTER EVENT evt COMMENT 'evt'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; ALTER EVENT evt COMMENT 'evt' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (25); -DROP EVENT evt; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP EVENT evt --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (24); -CREATE TRIGGER tr AFTER INSERT ON tt_1 FOR EACH ROW UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER tr AFTER INSERT ON tt_1 FOR EACH ROW UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (23); -DROP TRIGGER tr; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Table_map # # table_id: # (test.tt_2) @@ -330,15 +247,6 @@ master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP TRIGGER tr --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (22); -CREATE FUNCTION fc () RETURNS VARCHAR(64) RETURN "fc"; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F @@ -346,45 +254,18 @@ master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `fc`() RETURNS varchar(64) CHARSET latin1 RETURN "fc" --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (21); -ALTER FUNCTION fc COMMENT 'fc'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; ALTER FUNCTION fc COMMENT 'fc' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (20); -DROP FUNCTION fc; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP FUNCTION fc --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (19); -CREATE PROCEDURE pc () UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F @@ -392,273 +273,104 @@ master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `pc`() UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (18); -ALTER PROCEDURE pc COMMENT 'pc'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; ALTER PROCEDURE pc COMMENT 'pc' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (17); -DROP PROCEDURE pc; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP PROCEDURE pc --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (16); -CREATE VIEW v AS SELECT * FROM tt_1; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v` AS SELECT * FROM tt_1 --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (15); -ALTER VIEW v AS SELECT * FROM tt_1; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; ALTER ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v` AS SELECT * FROM tt_1 --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (14); -DROP VIEW v; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP VIEW v --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (13); -CREATE INDEX ix ON tt_1(ddl_case); --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE INDEX ix ON tt_1(ddl_case) --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (12); -DROP INDEX ix ON tt_1; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP INDEX ix ON tt_1 --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (11); -CREATE TEMPORARY TABLE tt_xx (a int); --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (10); -ALTER TABLE tt_xx ADD COLUMN (b int); --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (9); -ALTER TABLE tt_xx RENAME new_tt_xx; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (8); -DROP TEMPORARY TABLE IF EXISTS new_tt_xx; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`new_tt_xx` /* generated by server */ -master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (7); -CREATE TABLE tt_xx (a int); --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE TABLE tt_xx (a int) --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (6); -ALTER TABLE tt_xx ADD COLUMN (b int); --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; ALTER TABLE tt_xx ADD COLUMN (b int) --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (5); -RENAME TABLE tt_xx TO new_tt_xx; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; RENAME TABLE tt_xx TO new_tt_xx --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (4); -TRUNCATE TABLE new_tt_xx; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE new_tt_xx --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (3); -DROP TABLE IF EXISTS tt_xx, new_tt_xx; -Warnings: -Note 1051 Unknown table 'test.tt_xx' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `tt_xx`,`new_tt_xx` /* generated by server */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (2); -CREATE DATABASE db; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # CREATE DATABASE db --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (1); -DROP DATABASE IF EXISTS db; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # DROP DATABASE IF EXISTS db --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - +SET AUTOCOMMIT= 1; ################################################################################### # CHECK CONSISTENCY ################################################################################### @@ -666,4 +378,7 @@ include/diff_tables.inc [master:tt_1,slave:tt_1] ################################################################################### # CLEAN ################################################################################### +DROP TABLE tt_1; +DROP TABLE tt_2; +DROP TABLE nt_1; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_stm_implicit_commit_binlog.result b/mysql-test/suite/rpl/r/rpl_stm_implicit_commit_binlog.result index cb702ad64ef..e272961abe9 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_implicit_commit_binlog.result +++ b/mysql-test/suite/rpl/r/rpl_stm_implicit_commit_binlog.result @@ -13,613 +13,323 @@ INSERT INTO tt_2(ddl_case) VALUES(0); # CHECK IMPLICT COMMIT ######################################################################### SET AUTOCOMMIT= 0; --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- INSERT INTO tt_1(ddl_case) VALUES (43); CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB"; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_1(ddl_case) VALUES (42); +DROP FUNCTION myfunc_int; +INSERT INTO tt_1(ddl_case) VALUES (41); +LOAD INDEX INTO CACHE nt_1 IGNORE LEAVES; +Table Op Msg_type Msg_text +test.nt_1 preload_keys status OK +INSERT INTO tt_1(ddl_case) VALUES (40); +LOAD INDEX INTO CACHE tt_1, tt_2 IGNORE LEAVES; +Table Op Msg_type Msg_text +test.tt_1 preload_keys note The storage engine for the table doesn't support preload_keys +test.tt_2 preload_keys note The storage engine for the table doesn't support preload_keys +INSERT INTO tt_1(ddl_case) VALUES (39); +ANALYZE TABLE nt_1; +Table Op Msg_type Msg_text +test.nt_1 analyze status Table is already up to date +INSERT INTO tt_1(ddl_case) VALUES (38); +CHECK TABLE nt_1; +Table Op Msg_type Msg_text +test.nt_1 check status OK +INSERT INTO tt_1(ddl_case) VALUES (37); +OPTIMIZE TABLE nt_1; +Table Op Msg_type Msg_text +test.nt_1 optimize status Table is already up to date +INSERT INTO tt_1(ddl_case) VALUES (36); +REPAIR TABLE nt_1; +Table Op Msg_type Msg_text +test.nt_1 repair status OK +INSERT INTO tt_1(ddl_case) VALUES (35); +LOCK TABLES tt_1 WRITE; +INSERT INTO tt_1(ddl_case) VALUES (34); +UNLOCK TABLES; +INSERT INTO tt_1(ddl_case) VALUES (33); +CREATE USER 'user'@'localhost'; +INSERT INTO tt_1(ddl_case) VALUES (32); +GRANT ALL ON *.* TO 'user'@'localhost'; +INSERT INTO tt_1(ddl_case) VALUES (31); +SET PASSWORD FOR 'user'@'localhost' = PASSWORD('newpass'); +INSERT INTO tt_1(ddl_case) VALUES (30); +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user'@'localhost'; +INSERT INTO tt_1(ddl_case) VALUES (29); +RENAME USER 'user'@'localhost' TO 'user_new'@'localhost'; +INSERT INTO tt_1(ddl_case) VALUES (28); +DROP USER 'user_new'@'localhost'; +INSERT INTO tt_1(ddl_case) VALUES (27); +CREATE EVENT evt ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO SELECT * FROM tt_1; +INSERT INTO tt_1(ddl_case) VALUES (26); +ALTER EVENT evt COMMENT 'evt'; +INSERT INTO tt_1(ddl_case) VALUES (25); +DROP EVENT evt; +INSERT INTO tt_1(ddl_case) VALUES (24); +CREATE TRIGGER tr AFTER INSERT ON tt_1 FOR EACH ROW UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case; +INSERT INTO tt_1(ddl_case) VALUES (23); +DROP TRIGGER tr; +INSERT INTO tt_1(ddl_case) VALUES (22); +CREATE FUNCTION fc () RETURNS VARCHAR(64) RETURN "fc"; +INSERT INTO tt_1(ddl_case) VALUES (21); +ALTER FUNCTION fc COMMENT 'fc'; +INSERT INTO tt_1(ddl_case) VALUES (20); +DROP FUNCTION fc; +INSERT INTO tt_1(ddl_case) VALUES (19); +CREATE PROCEDURE pc () UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case; +INSERT INTO tt_1(ddl_case) VALUES (18); +ALTER PROCEDURE pc COMMENT 'pc'; +INSERT INTO tt_1(ddl_case) VALUES (17); +DROP PROCEDURE pc; +INSERT INTO tt_1(ddl_case) VALUES (16); +CREATE VIEW v AS SELECT * FROM tt_1; +INSERT INTO tt_1(ddl_case) VALUES (15); +ALTER VIEW v AS SELECT * FROM tt_1; +INSERT INTO tt_1(ddl_case) VALUES (14); +DROP VIEW v; +INSERT INTO tt_1(ddl_case) VALUES (13); +CREATE INDEX ix ON tt_1(ddl_case); +INSERT INTO tt_1(ddl_case) VALUES (12); +DROP INDEX ix ON tt_1; +INSERT INTO tt_1(ddl_case) VALUES (11); +CREATE TEMPORARY TABLE tt_xx (a int); +INSERT INTO tt_1(ddl_case) VALUES (10); +ALTER TABLE tt_xx ADD COLUMN (b int); +INSERT INTO tt_1(ddl_case) VALUES (9); +ALTER TABLE tt_xx RENAME new_tt_xx; +INSERT INTO tt_1(ddl_case) VALUES (8); +DROP TEMPORARY TABLE IF EXISTS new_tt_xx; +INSERT INTO tt_1(ddl_case) VALUES (7); +CREATE TABLE tt_xx (a int); +INSERT INTO tt_1(ddl_case) VALUES (6); +ALTER TABLE tt_xx ADD COLUMN (b int); +INSERT INTO tt_1(ddl_case) VALUES (5); +RENAME TABLE tt_xx TO new_tt_xx; +INSERT INTO tt_1(ddl_case) VALUES (4); +TRUNCATE TABLE new_tt_xx; +INSERT INTO tt_1(ddl_case) VALUES (3); +DROP TABLE IF EXISTS tt_xx, new_tt_xx; +Warnings: +Note 1051 Unknown table 'test.tt_xx' +INSERT INTO tt_1(ddl_case) VALUES (2); +CREATE DATABASE db; +INSERT INTO tt_1(ddl_case) VALUES (1); +DROP DATABASE IF EXISTS db; include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE tt_1 (ddl_case INT, PRIMARY KEY(ddl_case)) ENGINE = Innodb +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE tt_2 (ddl_case INT, PRIMARY KEY(ddl_case)) ENGINE = Innodb +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE nt_1 (ddl_case INT, PRIMARY KEY(ddl_case)) ENGINE = MyIsam +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES(0) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2(ddl_case) VALUES(0) +master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (43) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "LIB" --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (42); -DROP FUNCTION myfunc_int; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (42) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP FUNCTION myfunc_int --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (41); -LOAD INDEX INTO CACHE nt_1 IGNORE LEAVES; -Table Op Msg_type Msg_text -test.nt_1 preload_keys status OK --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (41) master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (40); -LOAD INDEX INTO CACHE tt_1, tt_2 IGNORE LEAVES; -Table Op Msg_type Msg_text -test.tt_1 preload_keys note The storage engine for the table doesn't support preload_keys -test.tt_2 preload_keys note The storage engine for the table doesn't support preload_keys --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (40) master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (39); -ANALYZE TABLE nt_1; -Table Op Msg_type Msg_text -test.nt_1 analyze status Table is already up to date --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (39) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; ANALYZE TABLE nt_1 --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (38); -CHECK TABLE nt_1; -Table Op Msg_type Msg_text -test.nt_1 check status OK --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (38) master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (37); -OPTIMIZE TABLE nt_1; -Table Op Msg_type Msg_text -test.nt_1 optimize status Table is already up to date --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (37) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; OPTIMIZE TABLE nt_1 --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (36); -REPAIR TABLE nt_1; -Table Op Msg_type Msg_text -test.nt_1 repair status OK --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (36) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; REPAIR TABLE nt_1 --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (35); -LOCK TABLES tt_1 WRITE; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (35) master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (34); -UNLOCK TABLES; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (34) master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (33); -CREATE USER 'user'@'localhost'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (33) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE USER 'user'@'localhost' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (32); -GRANT ALL ON *.* TO 'user'@'localhost'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (32) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; GRANT ALL ON *.* TO 'user'@'localhost' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (31); -SET PASSWORD FOR 'user'@'localhost' = PASSWORD('newpass'); --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (31) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; SET PASSWORD FOR 'user'@'localhost'='*D8DECEC305209EEFEC43008E1D420E1AA06B19E0' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (30); -REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user'@'localhost'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (30) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user'@'localhost' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (29); -RENAME USER 'user'@'localhost' TO 'user_new'@'localhost'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (29) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; RENAME USER 'user'@'localhost' TO 'user_new'@'localhost' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (28); -DROP USER 'user_new'@'localhost'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (28) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP USER 'user_new'@'localhost' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (27); -CREATE EVENT evt ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO SELECT * FROM tt_1; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (27) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` EVENT evt ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO SELECT * FROM tt_1 --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (26); -ALTER EVENT evt COMMENT 'evt'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (26) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; ALTER EVENT evt COMMENT 'evt' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (25); -DROP EVENT evt; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (25) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP EVENT evt --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (24); -CREATE TRIGGER tr AFTER INSERT ON tt_1 FOR EACH ROW UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (24) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER tr AFTER INSERT ON tt_1 FOR EACH ROW UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (23); -DROP TRIGGER tr; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (23) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP TRIGGER tr --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (22); -CREATE FUNCTION fc () RETURNS VARCHAR(64) RETURN "fc"; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (22) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `fc`() RETURNS varchar(64) CHARSET latin1 RETURN "fc" --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (21); -ALTER FUNCTION fc COMMENT 'fc'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (21) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; ALTER FUNCTION fc COMMENT 'fc' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (20); -DROP FUNCTION fc; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (20) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP FUNCTION fc --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (19); -CREATE PROCEDURE pc () UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (19) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `pc`() UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (18); -ALTER PROCEDURE pc COMMENT 'pc'; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (18) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; ALTER PROCEDURE pc COMMENT 'pc' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (17); -DROP PROCEDURE pc; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (17) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP PROCEDURE pc --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (16); -CREATE VIEW v AS SELECT * FROM tt_1; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (16) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v` AS SELECT * FROM tt_1 --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (15); -ALTER VIEW v AS SELECT * FROM tt_1; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (15) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; ALTER ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v` AS SELECT * FROM tt_1 --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (14); -DROP VIEW v; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (14) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP VIEW v --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (13); -CREATE INDEX ix ON tt_1(ddl_case); --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (13) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE INDEX ix ON tt_1(ddl_case) --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (12); -DROP INDEX ix ON tt_1; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (12) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP INDEX ix ON tt_1 --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (11); -CREATE TEMPORARY TABLE tt_xx (a int); --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (11) master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tt_xx (a int) -master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (10); -ALTER TABLE tt_xx ADD COLUMN (b int); --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (10) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; ALTER TABLE tt_xx ADD COLUMN (b int) --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (9); -ALTER TABLE tt_xx RENAME new_tt_xx; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (9) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; ALTER TABLE tt_xx RENAME new_tt_xx --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (8); -DROP TEMPORARY TABLE IF EXISTS new_tt_xx; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (8) master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`new_tt_xx` /* generated by server */ -master-bin.000001 # Xid # # COMMIT /* XID */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (7); -CREATE TABLE tt_xx (a int); --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (7) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE TABLE tt_xx (a int) --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (6); -ALTER TABLE tt_xx ADD COLUMN (b int); --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (6) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; ALTER TABLE tt_xx ADD COLUMN (b int) --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (5); -RENAME TABLE tt_xx TO new_tt_xx; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (5) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; RENAME TABLE tt_xx TO new_tt_xx --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (4); -TRUNCATE TABLE new_tt_xx; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (4) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; TRUNCATE TABLE new_tt_xx --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (3); -DROP TABLE IF EXISTS tt_xx, new_tt_xx; -Warnings: -Note 1051 Unknown table 'test.tt_xx' --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (3) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `tt_xx`,`new_tt_xx` /* generated by server */ --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (2); -CREATE DATABASE db; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (2) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # CREATE DATABASE db --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -INSERT INTO tt_1(ddl_case) VALUES (1); -DROP DATABASE IF EXISTS db; --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- --b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (1) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # DROP DATABASE IF EXISTS db --e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e- - +SET AUTOCOMMIT= 1; ################################################################################### # CHECK CONSISTENCY ################################################################################### @@ -627,4 +337,7 @@ include/diff_tables.inc [master:tt_1,slave:tt_1] ################################################################################### # CLEAN ################################################################################### +DROP TABLE tt_1; +DROP TABLE tt_2; +DROP TABLE nt_1; include/rpl_end.inc -- cgit v1.2.1 From 34045af03f25fc2edd7c0c8db054e505f271513c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 6 May 2018 22:46:56 +0200 Subject: MDEV-15216 Assertion `! is_set() || m_can_overwrite_status' failed in Diagnostics_area::set_error_status upon operation inside XA don't implicitly commit or rollback in mysql_admin_table() unless the statement has CF_IMPLICIT_COMMIT_END flag. --- mysql-test/r/assign_key_cache.result | 13 +++++++++++++ mysql-test/r/implicit_commit.result | 4 ++-- .../suite/rpl/r/rpl_mixed_implicit_commit_binlog.result | 4 ---- .../suite/rpl/r/rpl_row_implicit_commit_binlog.result | 4 ---- .../suite/rpl/r/rpl_stm_implicit_commit_binlog.result | 4 ---- mysql-test/t/assign_key_cache.test | 13 +++++++++++++ sql/sql_admin.cc | 7 +++++-- sql/sql_parse.cc | 4 ++-- sql/sql_parse.h | 1 + 9 files changed, 36 insertions(+), 18 deletions(-) create mode 100644 mysql-test/r/assign_key_cache.result create mode 100644 mysql-test/t/assign_key_cache.test diff --git a/mysql-test/r/assign_key_cache.result b/mysql-test/r/assign_key_cache.result new file mode 100644 index 00000000000..4ed6170136b --- /dev/null +++ b/mysql-test/r/assign_key_cache.result @@ -0,0 +1,13 @@ +set global my_cache.key_buffer_size = 1024*1024; +create table t1 (i int) engine=myisam partition by hash (i) partitions 2; +xa start 'xid'; +cache index t1 partition (non_existing_partition) in my_cache; +Table Op Msg_type Msg_text +test.t1 assign_to_keycache error Error in list of partitions to test.t1 +cache index t1 partition (p1) in my_cache; +Table Op Msg_type Msg_text +test.t1 assign_to_keycache status OK +xa end 'xid'; +xa rollback 'xid'; +drop table t1; +set global my_cache.key_buffer_size = 0; diff --git a/mysql-test/r/implicit_commit.result b/mysql-test/r/implicit_commit.result index d568d05e7b7..0dcee1b8f06 100644 --- a/mysql-test/r/implicit_commit.result +++ b/mysql-test/r/implicit_commit.result @@ -561,7 +561,7 @@ INSERT INTO db1.trans (a) VALUES (1); cache index t3 in keycache; CALL db1.test_if_commit(); IMPLICIT COMMIT -YES +NO set global keycache.key_buffer_size=0; # # SQLCOM_PRELOAD_KEYS @@ -570,7 +570,7 @@ INSERT INTO db1.trans (a) VALUES (1); load index into cache t3; CALL db1.test_if_commit(); IMPLICIT COMMIT -YES +NO # # SQLCOM_FLUSH # diff --git a/mysql-test/suite/rpl/r/rpl_mixed_implicit_commit_binlog.result b/mysql-test/suite/rpl/r/rpl_mixed_implicit_commit_binlog.result index e272961abe9..7efb1f7162b 100644 --- a/mysql-test/suite/rpl/r/rpl_mixed_implicit_commit_binlog.result +++ b/mysql-test/suite/rpl/r/rpl_mixed_implicit_commit_binlog.result @@ -140,11 +140,7 @@ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP FUNCTION myfunc_int master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (41) -master-bin.000001 # Xid # # COMMIT /* XID */ -master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (40) -master-bin.000001 # Xid # # COMMIT /* XID */ -master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (39) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# diff --git a/mysql-test/suite/rpl/r/rpl_row_implicit_commit_binlog.result b/mysql-test/suite/rpl/r/rpl_row_implicit_commit_binlog.result index 5d6590bd821..e24a84e02a1 100644 --- a/mysql-test/suite/rpl/r/rpl_row_implicit_commit_binlog.result +++ b/mysql-test/suite/rpl/r/rpl_row_implicit_commit_binlog.result @@ -145,12 +145,8 @@ master-bin.000001 # Query # # use `test`; DROP FUNCTION myfunc_int master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Xid # # COMMIT /* XID */ -master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Xid # # COMMIT /* XID */ -master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.tt_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ diff --git a/mysql-test/suite/rpl/r/rpl_stm_implicit_commit_binlog.result b/mysql-test/suite/rpl/r/rpl_stm_implicit_commit_binlog.result index e272961abe9..7efb1f7162b 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_implicit_commit_binlog.result +++ b/mysql-test/suite/rpl/r/rpl_stm_implicit_commit_binlog.result @@ -140,11 +140,7 @@ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP FUNCTION myfunc_int master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (41) -master-bin.000001 # Xid # # COMMIT /* XID */ -master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (40) -master-bin.000001 # Xid # # COMMIT /* XID */ -master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(ddl_case) VALUES (39) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Gtid # # GTID #-#-# diff --git a/mysql-test/t/assign_key_cache.test b/mysql-test/t/assign_key_cache.test new file mode 100644 index 00000000000..401e7bf9138 --- /dev/null +++ b/mysql-test/t/assign_key_cache.test @@ -0,0 +1,13 @@ +# +# MDEV-15216 Assertion `! is_set() || m_can_overwrite_status' failed in Diagnostics_area::set_error_status upon operation inside XA +# +--source include/have_partition.inc +set global my_cache.key_buffer_size = 1024*1024; +create table t1 (i int) engine=myisam partition by hash (i) partitions 2; +xa start 'xid'; +cache index t1 partition (non_existing_partition) in my_cache; +cache index t1 partition (p1) in my_cache; +xa end 'xid'; +xa rollback 'xid'; +drop table t1; +set global my_cache.key_buffer_size = 0; diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index 06a453e1bb7..4fe51a2189e 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -1064,7 +1064,9 @@ send_result_message: } else { - if (trans_commit_stmt(thd) || trans_commit_implicit(thd)) + if (trans_commit_stmt(thd) || + (stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END) && + trans_commit_implicit(thd))) goto err; } close_thread_tables(thd); @@ -1098,7 +1100,8 @@ send_result_message: err: /* Make sure this table instance is not reused after the failure. */ trans_rollback_stmt(thd); - trans_rollback(thd); + if (stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END)) + trans_rollback(thd); if (table && table->table) { table->table->m_needs_reopen= true; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4c0be4ebc8b..87edf93bb4a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -192,7 +192,7 @@ static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables) /* - Implicitly commit a active transaction if statement requires so. + Check whether the statement implicitly commits an active transaction. @param thd Thread handle. @param mask Bitmask used for the SQL command match. @@ -200,7 +200,7 @@ static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables) @return 0 No implicit commit @return 1 Do a commit */ -static bool stmt_causes_implicit_commit(THD *thd, uint mask) +bool stmt_causes_implicit_commit(THD *thd, uint mask) { LEX *lex= thd->lex; bool skip= FALSE; diff --git a/sql/sql_parse.h b/sql/sql_parse.h index fa414911093..39d92e656c8 100644 --- a/sql/sql_parse.h +++ b/sql/sql_parse.h @@ -84,6 +84,7 @@ bool check_identifier_name(LEX_STRING *str, uint max_char_length, uint err_code, const char *param_for_err_msg); bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length); bool sqlcom_can_generate_row_events(const THD *thd); +bool stmt_causes_implicit_commit(THD *thd, uint mask); bool is_update_query(enum enum_sql_command command); bool is_log_table_write_query(enum enum_sql_command command); bool alloc_query(THD *thd, const char *packet, uint packet_length); -- cgit v1.2.1 From 4f42f0d1eafd82adef513a1064ff44b50063db7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 9 May 2018 15:06:48 +0300 Subject: MDEV-16119 InnoDB lock->index refers to a freed object after failed ADD INDEX The problem is hard to repeat, and I failed to create a deterministic test case. Online index creation creates stubs for to-be-created indexes. If index creation fails, we could remove these stubs while locks exist in the indexes. (This would require that the index creation was completed, and a concurrent DML operation acquired a lock on a record in the uncommitted index. If a duplicate key error occurs in an uncommitted index, the error will be reported for the CREATE UNIQUE INDEX, not for the DML operation that tried to insert the duplicate.) dict_table_try_drop_aborted(), row_merge_drop_indexes(): If transactional locks exist on the table, keep the table->indexes intact. --- storage/innobase/dict/dict0dict.cc | 3 ++- storage/innobase/row/row0merge.cc | 3 ++- storage/xtradb/dict/dict0dict.cc | 3 ++- storage/xtradb/row/row0merge.cc | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 0c8a278586d..7575a4aed62 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -507,7 +507,8 @@ dict_table_try_drop_aborted( ut_ad(table->id == table_id); } - if (table && table->n_ref_count == ref_count && table->drop_aborted) { + if (table && table->n_ref_count == ref_count && table->drop_aborted + && !UT_LIST_GET_FIRST(table->locks)) { /* Silence a debug assertion in row_merge_drop_indexes(). */ ut_d(table->n_ref_count++); row_merge_drop_indexes(trx, table, TRUE); diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 49c9aa4b51f..4090e388610 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -2907,7 +2907,8 @@ row_merge_drop_indexes( A concurrent purge will be prevented by dict_operation_lock. */ - if (!locked && table->n_ref_count > 1) { + if (!locked && (table->n_ref_count > 1 + || UT_LIST_GET_FIRST(table->locks))) { /* We will have to drop the indexes later, when the table is guaranteed to be no longer in use. Mark the indexes as incomplete and corrupted, so that other diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc index e2aefc909f8..b76414eeea4 100644 --- a/storage/xtradb/dict/dict0dict.cc +++ b/storage/xtradb/dict/dict0dict.cc @@ -507,7 +507,8 @@ dict_table_try_drop_aborted( ut_ad(table->id == table_id); } - if (table && table->n_ref_count == ref_count && table->drop_aborted) { + if (table && table->n_ref_count == ref_count && table->drop_aborted + && !UT_LIST_GET_FIRST(table->locks)) { /* Silence a debug assertion in row_merge_drop_indexes(). */ ut_d(table->n_ref_count++); row_merge_drop_indexes(trx, table, TRUE); diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc index 00da85a19dd..e15b87b8ed5 100644 --- a/storage/xtradb/row/row0merge.cc +++ b/storage/xtradb/row/row0merge.cc @@ -2911,7 +2911,8 @@ row_merge_drop_indexes( A concurrent purge will be prevented by dict_operation_lock. */ - if (!locked && table->n_ref_count > 1) { + if (!locked && (table->n_ref_count > 1 + || UT_LIST_GET_FIRST(table->locks))) { /* We will have to drop the indexes later, when the table is guaranteed to be no longer in use. Mark the indexes as incomplete and corrupted, so that other -- cgit v1.2.1 From 6d570d729682039edd6c490187a0434e7d75d486 Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Thu, 10 May 2018 10:14:30 +0530 Subject: Bug#27230925: HANDLE_FATAL_SIGNAL (SIG=11) IN SHOW_ROUTINE_GRANTS Description :- Server crashes in show_routine_grants(). Analysis :- When "grant_reload_procs_priv" encounters an error, the grant structures (structures with column, function and procedure privileges) are freed. Server crashes when trying to access these structures later. Fix :- Grant structures are retained even when "grant_reload_procs_priv()" encounters an error while reloading column, function and procedure privileges. --- mysql-test/r/grant.result | 1 + mysql-test/t/grant.test | 3 ++ sql/sql_acl.cc | 92 +++++++++++++++++++++++++++++++---------------- 3 files changed, 65 insertions(+), 31 deletions(-) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index e524bb5cac2..d151b58e9ce 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1692,6 +1692,7 @@ revoke create, insert on mysqltest.t6 from mysqltest@localhost; drop user mysqltest@localhost; drop database mysqltest; use test; +call mtr.add_suppression("Can't open and lock privilege tables"); FLUSH PRIVILEGES without procs_priv table. RENAME TABLE mysql.procs_priv TO mysql.procs_gone; FLUSH PRIVILEGES; diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index 1e1cb6c24dc..2a1a8e34efb 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -1667,6 +1667,9 @@ use test; # # Bug#16470 crash on grant if old grant tables # + +call mtr.add_suppression("Can't open and lock privilege tables"); + --echo FLUSH PRIVILEGES without procs_priv table. RENAME TABLE mysql.procs_priv TO mysql.procs_gone; --error ER_NO_SUCH_TABLE diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 705b4792a37..64888f7308a 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -4871,6 +4871,7 @@ end_index_init: exists. @param thd A pointer to the thread handler object. + @param table A pointer to the table list. @see grant_reload @@ -4879,31 +4880,22 @@ end_index_init: @retval TRUE An error has occurred. */ -static my_bool grant_reload_procs_priv(THD *thd) +static my_bool grant_reload_procs_priv(THD *thd, TABLE_LIST *table) { HASH old_proc_priv_hash, old_func_priv_hash; - TABLE_LIST table; my_bool return_val= FALSE; DBUG_ENTER("grant_reload_procs_priv"); - table.init_one_table("mysql", 5, "procs_priv", - strlen("procs_priv"), "procs_priv", - TL_READ); - table.open_type= OT_BASE_ONLY; - - if (open_and_lock_tables(thd, &table, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT)) - DBUG_RETURN(TRUE); - - mysql_rwlock_wrlock(&LOCK_grant); /* Save a copy of the current hash if we need to undo the grant load */ old_proc_priv_hash= proc_priv_hash; old_func_priv_hash= func_priv_hash; - if ((return_val= grant_load_procs_priv(table.table))) + if ((return_val= grant_load_procs_priv(table->table))) { /* Error; Reverting to old hash */ DBUG_PRINT("error",("Reverting to old privileges")); - grant_free(); + my_hash_free(&proc_priv_hash); + my_hash_free(&func_priv_hash); proc_priv_hash= old_proc_priv_hash; func_priv_hash= old_func_priv_hash; } @@ -4912,9 +4904,7 @@ static my_bool grant_reload_procs_priv(THD *thd) my_hash_free(&old_proc_priv_hash); my_hash_free(&old_func_priv_hash); } - mysql_rwlock_unlock(&LOCK_grant); - close_mysql_tables(thd); DBUG_RETURN(return_val); } @@ -4936,7 +4926,7 @@ static my_bool grant_reload_procs_priv(THD *thd) my_bool grant_reload(THD *thd) { - TABLE_LIST tables[2]; + TABLE_LIST tables[3]; HASH old_column_priv_hash; MEM_ROOT old_mem; my_bool return_val= 1; @@ -4952,15 +4942,57 @@ my_bool grant_reload(THD *thd) tables[1].init_one_table(C_STRING_WITH_LEN("mysql"), C_STRING_WITH_LEN("columns_priv"), "columns_priv", TL_READ); + tables[2].init_one_table(C_STRING_WITH_LEN("mysql"), + C_STRING_WITH_LEN("procs_priv"), + "procs_priv", TL_READ); + tables[0].next_local= tables[0].next_global= tables+1; - tables[0].open_type= tables[1].open_type= OT_BASE_ONLY; + tables[1].next_local= tables[1].next_global= tables+2; + tables[0].open_type= tables[1].open_type= tables[2].open_type= OT_BASE_ONLY; + + /* + Reload will work in the following manner:- + + proc_priv_hash structure + / \ + not initialized initialized + / \ | + mysql.procs_priv table Server Startup | + is missing \ | + | open_and_lock_tables() + Assume we are working on /success \failure + pre 4.1 system tables. Normal Scenario. An error is thrown. + A warning is printed Reload column privilege. Retain the old hash. + and continue with Reload function and + reloading the column procedure privileges, + privileges. if available. + */ + + if (!(my_hash_inited(&proc_priv_hash))) + tables[2].open_strategy= TABLE_LIST::OPEN_IF_EXISTS; /* To avoid deadlocks we should obtain table locks before obtaining LOCK_grant rwlock. */ if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT)) + { + if (thd->stmt_da->is_error()) + { + sql_print_error("Fatal error: Can't open and lock privilege tables: %s", + thd->stmt_da->message()); + } goto end; + } + + if (tables[2].table == NULL) + { + sql_print_warning("Table 'mysql.procs_priv' does not exist. " + "Please run mysql_upgrade."); + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_NO_SUCH_TABLE, + ER(ER_NO_SUCH_TABLE), tables[2].db, + tables[2].table_name); + } mysql_rwlock_wrlock(&LOCK_grant); old_column_priv_hash= column_priv_hash; @@ -4972,10 +5004,18 @@ my_bool grant_reload(THD *thd) old_mem= memex; init_sql_alloc(&memex, ACL_ALLOC_BLOCK_SIZE, 0); - if ((return_val= grant_load(thd, tables))) + /* + tables[2].table i.e. procs_priv can be null if we are working with + pre 4.1 privilage tables + */ + if ((return_val= (grant_load(thd, tables) || + (tables[2].table != NULL && + grant_reload_procs_priv(thd, &tables[2]))) + )) { // Error. Revert to old hash DBUG_PRINT("error",("Reverting to old privileges")); - grant_free(); /* purecov: deadcode */ + my_hash_free(&column_priv_hash); + free_root(&memex,MYF(0)); column_priv_hash= old_column_priv_hash; /* purecov: deadcode */ memex= old_mem; /* purecov: deadcode */ } @@ -4983,22 +5023,12 @@ my_bool grant_reload(THD *thd) { my_hash_free(&old_column_priv_hash); free_root(&old_mem,MYF(0)); + grant_version++; } mysql_rwlock_unlock(&LOCK_grant); - close_mysql_tables(thd); - - /* - It is OK failing to load procs_priv table because we may be - working with 4.1 privilege tables. - */ - if (grant_reload_procs_priv(thd)) - return_val= 1; - - mysql_rwlock_wrlock(&LOCK_grant); - grant_version++; - mysql_rwlock_unlock(&LOCK_grant); end: + close_mysql_tables(thd); DBUG_RETURN(return_val); } -- cgit v1.2.1 From 318097bb8f6e12c546b5dcd287416158209dbb39 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Thu, 10 May 2018 19:00:54 +0400 Subject: MDEV-15480 Audit plugin does not respect QUERY_DML for audit plugin. QUERY_DML_NO_SELECT flag added. --- mysql-test/suite/plugins/r/server_audit.result | 12 +++++++++++ mysql-test/suite/plugins/t/server_audit.test | 7 +++++++ plugin/server_audit/server_audit.c | 29 ++++++++++++++++++++++---- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/plugins/r/server_audit.result b/mysql-test/suite/plugins/r/server_audit.result index 80b434553e5..2e18a489dc7 100644 --- a/mysql-test/suite/plugins/r/server_audit.result +++ b/mysql-test/suite/plugins/r/server_audit.result @@ -182,6 +182,17 @@ select 2; 2 2 drop table t1; +set global server_audit_events='query_dml_no_select'; +create table t1(id int); +insert into t1 values (1), (2); +select * from t1; +id +1 +2 +select 2; +2 +2 +drop table t1; set global server_audit_events=''; set global server_audit_query_log_limit= 15; select (1), (2), (3), (4); @@ -332,6 +343,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD \n# comment\nFOR u1 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1=',ID TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *****',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop user u1, u2, u3',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'insert into t1 values (1), (2)',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'set global server_audit_events=\'\'',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'set global serv',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'select (1), (2)',0 diff --git a/mysql-test/suite/plugins/t/server_audit.test b/mysql-test/suite/plugins/t/server_audit.test index 6c5eaffd9a2..4af1ed883e3 100644 --- a/mysql-test/suite/plugins/t/server_audit.test +++ b/mysql-test/suite/plugins/t/server_audit.test @@ -121,6 +121,13 @@ select 2; /*! select 2*/; /*comment*/ select 2; drop table t1; +set global server_audit_events='query_dml_no_select'; +create table t1(id int); +insert into t1 values (1), (2); +select * from t1; +select 2; +drop table t1; + set global server_audit_events=''; set global server_audit_query_log_limit= 15; diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c index 9a3418e7784..d27da280a2a 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.c @@ -15,7 +15,7 @@ #define PLUGIN_VERSION 0x104 -#define PLUGIN_STR_VERSION "1.4.3" +#define PLUGIN_STR_VERSION "1.4.4" #define _my_thread_var loc_thread_var @@ -366,16 +366,17 @@ static MYSQL_SYSVAR_STR(excl_users, excl_users, PLUGIN_VAR_RQCMDARG, /* bits in the event filter. */ #define EVENT_CONNECT 1 #define EVENT_QUERY_ALL 2 -#define EVENT_QUERY 58 +#define EVENT_QUERY 122 #define EVENT_TABLE 4 #define EVENT_QUERY_DDL 8 #define EVENT_QUERY_DML 16 #define EVENT_QUERY_DCL 32 +#define EVENT_QUERY_DML_NO_SELECT 64 static const char *event_names[]= { "CONNECT", "QUERY", "TABLE", "QUERY_DDL", "QUERY_DML", "QUERY_DCL", - NULL + "QUERY_DML_NO_SELECT", NULL }; static TYPELIB events_typelib= { @@ -383,7 +384,7 @@ static TYPELIB events_typelib= }; static MYSQL_SYSVAR_SET(events, events, PLUGIN_VAR_RQCMDARG, "Specifies the set of events to monitor. Can be CONNECT, QUERY, TABLE," - " QUERY_DDL, QUERY_DML, QUERY_DCL.", + " QUERY_DDL, QUERY_DML, QUERY_DML_NO_SELECT, QUERY_DCL.", NULL, NULL, 0, &events_typelib); #define OUTPUT_SYSLOG 0 #define OUTPUT_FILE 1 @@ -857,6 +858,21 @@ struct sa_keyword dml_keywords[]= }; +struct sa_keyword dml_no_select_keywords[]= +{ + {2, "DO", 0, SQLCOM_DML}, + {4, "CALL", 0, SQLCOM_DML}, + {4, "LOAD", &data_word, SQLCOM_DML}, + {4, "LOAD", &xml_word, SQLCOM_DML}, + {6, "DELETE", 0, SQLCOM_DML}, + {6, "INSERT", 0, SQLCOM_DML}, + {6, "UPDATE", 0, SQLCOM_DML}, + {7, "HANDLER", 0, SQLCOM_DML}, + {7, "REPLACE", 0, SQLCOM_DML}, + {0, NULL, 0, SQLCOM_DML} +}; + + struct sa_keyword dcl_keywords[]= { {6, "CREATE", &user_word, SQLCOM_DCL}, @@ -1637,6 +1653,11 @@ static int log_statement_ex(const struct connection_info *cn, if (filter_query_type(query, dml_keywords)) goto do_log_query; } + if (events & EVENT_QUERY_DML_NO_SELECT) + { + if (filter_query_type(query, dml_no_select_keywords)) + goto do_log_query; + } if (events & EVENT_QUERY_DCL) { if (filter_query_type(query, dcl_keywords)) -- cgit v1.2.1 From 3cbfe8cc47d48ff2c528149b4866480b50d8a116 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Thu, 10 May 2018 19:00:54 +0400 Subject: MDEV-15480 Audit plugin does not respect QUERY_DML for audit plugin. QUERY_DML_NO_SELECT flag added. --- mysql-test/suite/plugins/r/server_audit.result | 12 +++++++++++ mysql-test/suite/plugins/t/server_audit.test | 7 +++++++ plugin/server_audit/server_audit.c | 29 ++++++++++++++++++++++---- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/plugins/r/server_audit.result b/mysql-test/suite/plugins/r/server_audit.result index 3971504b238..5c355b34ba1 100644 --- a/mysql-test/suite/plugins/r/server_audit.result +++ b/mysql-test/suite/plugins/r/server_audit.result @@ -182,6 +182,17 @@ select 2; 2 2 drop table t1; +set global server_audit_events='query_dml_no_select'; +create table t1(id int); +insert into t1 values (1), (2); +select * from t1; +id +1 +2 +select 2; +2 +2 +drop table t1; set global server_audit_events=''; set global server_audit_query_log_limit= 15; select (1), (2), (3), (4); @@ -343,6 +354,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD \n# comment\nFOR u1 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1=',ID TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *****',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop user u1, u2, u3',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'insert into t1 values (1), (2)',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'set global server_audit_events=\'\'',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'set global serv',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'select (1), (2)',0 diff --git a/mysql-test/suite/plugins/t/server_audit.test b/mysql-test/suite/plugins/t/server_audit.test index 6c5eaffd9a2..4af1ed883e3 100644 --- a/mysql-test/suite/plugins/t/server_audit.test +++ b/mysql-test/suite/plugins/t/server_audit.test @@ -121,6 +121,13 @@ select 2; /*! select 2*/; /*comment*/ select 2; drop table t1; +set global server_audit_events='query_dml_no_select'; +create table t1(id int); +insert into t1 values (1), (2); +select * from t1; +select 2; +drop table t1; + set global server_audit_events=''; set global server_audit_query_log_limit= 15; diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c index 323179d5f84..17d3154089f 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.c @@ -15,7 +15,7 @@ #define PLUGIN_VERSION 0x104 -#define PLUGIN_STR_VERSION "1.4.3" +#define PLUGIN_STR_VERSION "1.4.4" #define _my_thread_var loc_thread_var @@ -364,16 +364,17 @@ static MYSQL_SYSVAR_STR(excl_users, excl_users, PLUGIN_VAR_RQCMDARG, /* bits in the event filter. */ #define EVENT_CONNECT 1 #define EVENT_QUERY_ALL 2 -#define EVENT_QUERY 58 +#define EVENT_QUERY 122 #define EVENT_TABLE 4 #define EVENT_QUERY_DDL 8 #define EVENT_QUERY_DML 16 #define EVENT_QUERY_DCL 32 +#define EVENT_QUERY_DML_NO_SELECT 64 static const char *event_names[]= { "CONNECT", "QUERY", "TABLE", "QUERY_DDL", "QUERY_DML", "QUERY_DCL", - NULL + "QUERY_DML_NO_SELECT", NULL }; static TYPELIB events_typelib= { @@ -381,7 +382,7 @@ static TYPELIB events_typelib= }; static MYSQL_SYSVAR_SET(events, events, PLUGIN_VAR_RQCMDARG, "Specifies the set of events to monitor. Can be CONNECT, QUERY, TABLE," - " QUERY_DDL, QUERY_DML, QUERY_DCL.", + " QUERY_DDL, QUERY_DML, QUERY_DML_NO_SELECT, QUERY_DCL.", NULL, NULL, 0, &events_typelib); #define OUTPUT_SYSLOG 0 #define OUTPUT_FILE 1 @@ -855,6 +856,21 @@ struct sa_keyword dml_keywords[]= }; +struct sa_keyword dml_no_select_keywords[]= +{ + {2, "DO", 0, SQLCOM_DML}, + {4, "CALL", 0, SQLCOM_DML}, + {4, "LOAD", &data_word, SQLCOM_DML}, + {4, "LOAD", &xml_word, SQLCOM_DML}, + {6, "DELETE", 0, SQLCOM_DML}, + {6, "INSERT", 0, SQLCOM_DML}, + {6, "UPDATE", 0, SQLCOM_DML}, + {7, "HANDLER", 0, SQLCOM_DML}, + {7, "REPLACE", 0, SQLCOM_DML}, + {0, NULL, 0, SQLCOM_DML} +}; + + struct sa_keyword dcl_keywords[]= { {6, "CREATE", &user_word, SQLCOM_DCL}, @@ -1636,6 +1652,11 @@ static int log_statement_ex(const struct connection_info *cn, if (filter_query_type(query, dml_keywords)) goto do_log_query; } + if (events & EVENT_QUERY_DML_NO_SELECT) + { + if (filter_query_type(query, dml_no_select_keywords)) + goto do_log_query; + } if (events & EVENT_QUERY_DCL) { if (filter_query_type(query, dcl_keywords)) -- cgit v1.2.1 From 580a8061a752946cfd9d6e57f88d46ce099d11c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 11 May 2018 13:48:57 +0300 Subject: Remove a redundant condition added by the 5.6.40 merge When Oracle fixed MDEV-13899 in their own way, they moved the condition to the only caller of PageConverter::update_records(). Thus, the merge of 5.6.40 into MariaDB added a redundant condition. PageConverter::update_records(): Move the page_is_leaf() condition to the only caller, PageConverter::update_index_page(). --- storage/innobase/row/row0import.cc | 10 +--------- storage/xtradb/row/row0import.cc | 6 +----- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index df696f3188d..f93d004d8f9 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -1820,10 +1820,6 @@ PageConverter::update_records( m_rec_iter.open(block); - if (!page_is_leaf(block->frame)) { - return DB_SUCCESS; - } - while (!m_rec_iter.end()) { rec_t* rec = m_rec_iter.current(); @@ -1928,11 +1924,7 @@ PageConverter::update_index_page( return(DB_SUCCESS); } - if (!page_is_leaf(block->frame)) { - return (DB_SUCCESS); - } - - return(update_records(block)); + return page_is_leaf(block->frame) ? update_records(block) : DB_SUCCESS; } /** diff --git a/storage/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc index 26ed99a483c..39e450bd7c5 100644 --- a/storage/xtradb/row/row0import.cc +++ b/storage/xtradb/row/row0import.cc @@ -1820,10 +1820,6 @@ PageConverter::update_records( m_rec_iter.open(block); - if (!page_is_leaf(block->frame)) { - return DB_SUCCESS; - } - while (!m_rec_iter.end()) { rec_t* rec = m_rec_iter.current(); ibool deleted = rec_get_deleted_flag(rec, comp); @@ -1927,7 +1923,7 @@ PageConverter::update_index_page( return(DB_SUCCESS); } - return(update_records(block)); + return page_is_leaf(block->frame) ? update_records(block) : DB_SUCCESS; } /** -- cgit v1.2.1 From 9c03ba8f0d8e579432671d5bdde5f1b5aca3954c Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Wed, 27 Dec 2017 11:56:11 +0530 Subject: Bug #27041445 SERVER ABORTS IF FTS_DOC_ID EXCEEDS FTS_DOC_ID_MAX_STEP Problem: ======= Multiple insert statement in table contains FULLTEXT KEY and a FTS_DOC_ID column aborts the server if the FTS_DOC_ID exceeds FTS_DOC_ID_MAX_STEP. Solution: ======== Remove the exception for first committed insert statement. Reviewed-by: Jimmy Yang RB: 18023 --- mysql-test/suite/innodb_fts/r/basic.result | 293 +++++++++++++++++++++ .../suite/innodb_fts/r/innodb-fts-basic.result | 259 ------------------ mysql-test/suite/innodb_fts/t/basic.test | 257 ++++++++++++++++++ .../suite/innodb_fts/t/innodb-fts-basic.test | 228 ---------------- storage/xtradb/row/row0mysql.cc | 3 +- 5 files changed, 551 insertions(+), 489 deletions(-) create mode 100644 mysql-test/suite/innodb_fts/r/basic.result delete mode 100644 mysql-test/suite/innodb_fts/r/innodb-fts-basic.result create mode 100644 mysql-test/suite/innodb_fts/t/basic.test delete mode 100644 mysql-test/suite/innodb_fts/t/innodb-fts-basic.test diff --git a/mysql-test/suite/innodb_fts/r/basic.result b/mysql-test/suite/innodb_fts/r/basic.result new file mode 100644 index 00000000000..ae23b93dc84 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/basic.result @@ -0,0 +1,293 @@ +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT (title,body) +) ENGINE=InnoDB; +INSERT INTO articles (title,body) VALUES +('MySQL Tutorial','DBMS stands for DataBase ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +ANALYZE TABLE articles; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('Database' IN NATURAL LANGUAGE MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +5 MySQL vs. YourSQL In the following database comparison ... +SELECT COUNT(*) FROM articles +WHERE MATCH (title,body) +AGAINST ('database' IN NATURAL LANGUAGE MODE); +COUNT(*) +2 +SELECT * FROM articles +WHERE MATCH (title, body) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT COUNT(IF(MATCH (title,body) +AGAINST ('database' IN NATURAL LANGUAGE MODE), 1, NULL)) +AS count FROM articles; +count +2 +SELECT id, body, MATCH (title,body) +AGAINST ('Database' IN NATURAL LANGUAGE MODE) AS score +FROM articles; +id body score +1 DBMS stands for DataBase ... 0.22764469683170319 +2 After you went through a ... 0 +3 In this tutorial we will show ... 0 +4 1. Never run mysqld as root. 2. ... 0 +5 In the following database comparison ... 0.22764469683170319 +6 When configured properly, MySQL ... 0 +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL' IN NATURAL LANGUAGE MODE); +id title body +6 MySQL Security When configured properly, MySQL ... +1 MySQL Tutorial DBMS stands for DataBase ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE); +id title body +6 MySQL Security When configured properly, MySQL ... +1 MySQL Tutorial DBMS stands for DataBase ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('DBMS Security' IN BOOLEAN MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +6 MySQL Security When configured properly, MySQL ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+MySQL +YourSQL' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+MySQL YourSQL' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +6 MySQL Security When configured properly, MySQL ... +1 MySQL Tutorial DBMS stands for DataBase ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+MySQL ~YourSQL' IN BOOLEAN MODE); +id title body +6 MySQL Security When configured properly, MySQL ... +1 MySQL Tutorial DBMS stands for DataBase ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('t*' IN BOOLEAN MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('MY*' IN BOOLEAN MODE); +id title body +6 MySQL Security When configured properly, MySQL ... +1 MySQL Tutorial DBMS stands for DataBase ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('ru*' IN BOOLEAN MODE); +id title body +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+ MySQL >Well < stands' IN BOOLEAN MODE); +id title body +2 How To Use MySQL Well After you went through a ... +6 MySQL Security When configured properly, MySQL ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +5 MySQL vs. YourSQL In the following database comparison ... +1 MySQL Tutorial DBMS stands for DataBase ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+ MySQL - (Well stands)' IN BOOLEAN MODE); +id title body +6 MySQL Security When configured properly, MySQL ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+ MySQL + (>Well < stands)' IN BOOLEAN MODE); +id title body +2 How To Use MySQL Well After you went through a ... +1 MySQL Tutorial DBMS stands for DataBase ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('YourSQL + (+MySQL - (Tricks Security))' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +1 MySQL Tutorial DBMS stands for DataBase ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('(+MySQL - (Tricks Security)) - YourSQL' IN BOOLEAN MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysql - Security&DBMS' IN BOOLEAN MODE); +id title body +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysql - (Security DBMS)' IN BOOLEAN MODE); +id title body +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) AGAINST (' - Security&DBMS + YourSQL' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('+YourSQL - Security&DBMS' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT COUNT(*) FROM articles +WHERE MATCH (title,body) +AGAINST ('database' WITH QUERY EXPANSION); +COUNT(*) +6 +INSERT INTO articles (title,body) VALUES +('test query expansion','for database ...'); +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('test' WITH QUERY EXPANSION); +id title body +7 test query expansion for database ... +1 MySQL Tutorial DBMS stands for DataBase ... +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"following comparison"@3' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"following comparison"@2' IN BOOLEAN MODE); +id title body +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"following database"' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +INSERT INTO articles (title,body) VALUES +('test proximity search, test, proximity and phrase', +'search, with proximity innodb'); +INSERT INTO articles (title,body) VALUES +('test my proximity fts new search, test, proximity and phrase', +'search, with proximity innodb'); +INSERT INTO articles (title,body) VALUES +('test more of proximity fts search, test, more proximity and phrase', +'search, with proximity innodb'); +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"proximity search"@3' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"proximity search"@2' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"proximity search"@5' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"test proximity"@5' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"test proximity"@1' IN BOOLEAN MODE); +id title body +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"test proximity"@4' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"test proximity"@3' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"more test proximity"@4' IN BOOLEAN MODE); +id title body +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"more test proximity"@3' IN BOOLEAN MODE); +id title body +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"more test proximity"' IN BOOLEAN MODE); +id title body +drop table articles; +# +# Bug #22679185 INVALID INNODB FTS DOC ID DURING INSERT +# +create table t1 (f1 int not null primary key, f2 varchar(100), +FTS_DOC_ID bigint(20) unsigned not null, +unique key `FTS_DOC_ID_INDEX` (`FTS_DOC_ID`), +fulltext key (f2))engine=innodb; +insert into t1 values(1, "This is the first record", 20000); +insert into t1 values(2, "This is the second record", 40000); +select FTS_DOC_ID from t1; +FTS_DOC_ID +20000 +40000 +drop table t1; +create table t1 (f1 int not null primary key, f2 varchar(100), +FTS_DOC_ID bigint(20) unsigned not null auto_increment, +unique key `FTS_DOC_ID_INDEX` (`FTS_DOC_ID`), +fulltext key (f2))engine=innodb; +set auto_increment_increment = 65535; +insert into t1(f1, f2) values(1, "This is the first record"); +insert into t1(f1, f2) values(2, "This is the second record"); +insert into t1(f1, f2) values(3, "This is the third record"); +select FTS_DOC_ID from t1; +FTS_DOC_ID +1 +65536 +131071 +drop table t1; +call mtr.add_suppression("\\[ERROR\\] InnoDB: Doc ID 20030101000000 is too big. Its difference with largest used Doc ID 0 cannot exceed or equal to 65535"); +CREATE TABLE t1 (FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), FULLTEXT(title)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (NULL, NULL), (20030101000000, 20030102000000); +ERROR HY000: Invalid InnoDB FTS Doc ID +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/r/innodb-fts-basic.result b/mysql-test/suite/innodb_fts/r/innodb-fts-basic.result deleted file mode 100644 index fe767476fe6..00000000000 --- a/mysql-test/suite/innodb_fts/r/innodb-fts-basic.result +++ /dev/null @@ -1,259 +0,0 @@ -CREATE TABLE articles ( -id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, -title VARCHAR(200), -body TEXT, -FULLTEXT (title,body) -) ENGINE=InnoDB; -INSERT INTO articles (title,body) VALUES -('MySQL Tutorial','DBMS stands for DataBase ...') , -('How To Use MySQL Well','After you went through a ...'), -('Optimizing MySQL','In this tutorial we will show ...'), -('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), -('MySQL vs. YourSQL','In the following database comparison ...'), -('MySQL Security','When configured properly, MySQL ...'); -ANALYZE TABLE articles; -SELECT * FROM articles -WHERE MATCH (title,body) -AGAINST ('Database' IN NATURAL LANGUAGE MODE); -id title body -1 MySQL Tutorial DBMS stands for DataBase ... -5 MySQL vs. YourSQL In the following database comparison ... -SELECT COUNT(*) FROM articles -WHERE MATCH (title,body) -AGAINST ('database' IN NATURAL LANGUAGE MODE); -COUNT(*) -2 -SELECT * FROM articles -WHERE MATCH (title, body) -AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); -id title body -1 MySQL Tutorial DBMS stands for DataBase ... -3 Optimizing MySQL In this tutorial we will show ... -SELECT COUNT(IF(MATCH (title,body) -AGAINST ('database' IN NATURAL LANGUAGE MODE), 1, NULL)) -AS count FROM articles; -count -2 -SELECT id, body, MATCH (title,body) -AGAINST ('Database' IN NATURAL LANGUAGE MODE) AS score -FROM articles; -id body score -1 DBMS stands for DataBase ... 0.22764469683170319 -2 After you went through a ... 0 -3 In this tutorial we will show ... 0 -4 1. Never run mysqld as root. 2. ... 0 -5 In the following database comparison ... 0.22764469683170319 -6 When configured properly, MySQL ... 0 -SELECT * FROM articles -WHERE MATCH (title,body) -AGAINST ('MySQL' IN NATURAL LANGUAGE MODE); -id title body -6 MySQL Security When configured properly, MySQL ... -1 MySQL Tutorial DBMS stands for DataBase ... -2 How To Use MySQL Well After you went through a ... -3 Optimizing MySQL In this tutorial we will show ... -4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... -5 MySQL vs. YourSQL In the following database comparison ... -SELECT * FROM articles WHERE MATCH (title,body) -AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE); -id title body -6 MySQL Security When configured properly, MySQL ... -1 MySQL Tutorial DBMS stands for DataBase ... -2 How To Use MySQL Well After you went through a ... -3 Optimizing MySQL In this tutorial we will show ... -4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... -SELECT * FROM articles WHERE MATCH (title,body) -AGAINST ('DBMS Security' IN BOOLEAN MODE); -id title body -1 MySQL Tutorial DBMS stands for DataBase ... -6 MySQL Security When configured properly, MySQL ... -SELECT * FROM articles WHERE MATCH (title,body) -AGAINST ('+MySQL +YourSQL' IN BOOLEAN MODE); -id title body -5 MySQL vs. YourSQL In the following database comparison ... -SELECT * FROM articles WHERE MATCH (title,body) -AGAINST ('+MySQL YourSQL' IN BOOLEAN MODE); -id title body -5 MySQL vs. YourSQL In the following database comparison ... -6 MySQL Security When configured properly, MySQL ... -1 MySQL Tutorial DBMS stands for DataBase ... -2 How To Use MySQL Well After you went through a ... -3 Optimizing MySQL In this tutorial we will show ... -4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... -SELECT * FROM articles WHERE MATCH (title,body) -AGAINST ('+MySQL ~YourSQL' IN BOOLEAN MODE); -id title body -6 MySQL Security When configured properly, MySQL ... -1 MySQL Tutorial DBMS stands for DataBase ... -2 How To Use MySQL Well After you went through a ... -3 Optimizing MySQL In this tutorial we will show ... -4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... -5 MySQL vs. YourSQL In the following database comparison ... -SELECT * FROM articles WHERE MATCH (title,body) -AGAINST ('t*' IN BOOLEAN MODE); -id title body -1 MySQL Tutorial DBMS stands for DataBase ... -2 How To Use MySQL Well After you went through a ... -3 Optimizing MySQL In this tutorial we will show ... -4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... -SELECT * FROM articles WHERE MATCH (title,body) -AGAINST ('MY*' IN BOOLEAN MODE); -id title body -6 MySQL Security When configured properly, MySQL ... -1 MySQL Tutorial DBMS stands for DataBase ... -2 How To Use MySQL Well After you went through a ... -3 Optimizing MySQL In this tutorial we will show ... -4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... -5 MySQL vs. YourSQL In the following database comparison ... -SELECT * FROM articles WHERE MATCH (title,body) -AGAINST ('ru*' IN BOOLEAN MODE); -id title body -4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... -SELECT * FROM articles WHERE MATCH (title,body) -AGAINST ('+ MySQL >Well < stands' IN BOOLEAN MODE); -id title body -2 How To Use MySQL Well After you went through a ... -6 MySQL Security When configured properly, MySQL ... -3 Optimizing MySQL In this tutorial we will show ... -4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... -5 MySQL vs. YourSQL In the following database comparison ... -1 MySQL Tutorial DBMS stands for DataBase ... -SELECT * FROM articles WHERE MATCH (title,body) -AGAINST ('+ MySQL - (Well stands)' IN BOOLEAN MODE); -id title body -6 MySQL Security When configured properly, MySQL ... -3 Optimizing MySQL In this tutorial we will show ... -4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... -5 MySQL vs. YourSQL In the following database comparison ... -SELECT * FROM articles WHERE MATCH (title,body) -AGAINST ('+ MySQL + (>Well < stands)' IN BOOLEAN MODE); -id title body -2 How To Use MySQL Well After you went through a ... -1 MySQL Tutorial DBMS stands for DataBase ... -SELECT * FROM articles WHERE MATCH (title,body) -AGAINST ('YourSQL + (+MySQL - (Tricks Security))' IN BOOLEAN MODE); -id title body -5 MySQL vs. YourSQL In the following database comparison ... -1 MySQL Tutorial DBMS stands for DataBase ... -2 How To Use MySQL Well After you went through a ... -3 Optimizing MySQL In this tutorial we will show ... -SELECT * FROM articles WHERE MATCH (title,body) -AGAINST ('(+MySQL - (Tricks Security)) - YourSQL' IN BOOLEAN MODE); -id title body -1 MySQL Tutorial DBMS stands for DataBase ... -2 How To Use MySQL Well After you went through a ... -3 Optimizing MySQL In this tutorial we will show ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysql - Security&DBMS' IN BOOLEAN MODE); -id title body -2 How To Use MySQL Well After you went through a ... -3 Optimizing MySQL In this tutorial we will show ... -4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... -5 MySQL vs. YourSQL In the following database comparison ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysql - (Security DBMS)' IN BOOLEAN MODE); -id title body -2 How To Use MySQL Well After you went through a ... -3 Optimizing MySQL In this tutorial we will show ... -4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... -5 MySQL vs. YourSQL In the following database comparison ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST (' - Security&DBMS + YourSQL' IN BOOLEAN MODE); -id title body -5 MySQL vs. YourSQL In the following database comparison ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('+YourSQL - Security&DBMS' IN BOOLEAN MODE); -id title body -5 MySQL vs. YourSQL In the following database comparison ... -SELECT COUNT(*) FROM articles -WHERE MATCH (title,body) -AGAINST ('database' WITH QUERY EXPANSION); -COUNT(*) -6 -INSERT INTO articles (title,body) VALUES -('test query expansion','for database ...'); -SELECT * FROM articles -WHERE MATCH (title,body) -AGAINST ('test' WITH QUERY EXPANSION); -id title body -7 test query expansion for database ... -1 MySQL Tutorial DBMS stands for DataBase ... -5 MySQL vs. YourSQL In the following database comparison ... -SELECT * FROM articles -WHERE MATCH (title,body) -AGAINST ('"following comparison"@3' IN BOOLEAN MODE); -id title body -5 MySQL vs. YourSQL In the following database comparison ... -SELECT * FROM articles -WHERE MATCH (title,body) -AGAINST ('"following comparison"@2' IN BOOLEAN MODE); -id title body -SELECT * FROM articles -WHERE MATCH (title,body) -AGAINST ('"following database"' IN BOOLEAN MODE); -id title body -5 MySQL vs. YourSQL In the following database comparison ... -INSERT INTO articles (title,body) VALUES -('test proximity search, test, proximity and phrase', -'search, with proximity innodb'); -INSERT INTO articles (title,body) VALUES -('test my proximity fts new search, test, proximity and phrase', -'search, with proximity innodb'); -INSERT INTO articles (title,body) VALUES -('test more of proximity fts search, test, more proximity and phrase', -'search, with proximity innodb'); -SELECT * FROM articles -WHERE MATCH (title,body) -AGAINST ('"proximity search"@3' IN BOOLEAN MODE); -id title body -8 test proximity search, test, proximity and phrase search, with proximity innodb -9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb -10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb -SELECT * FROM articles -WHERE MATCH (title,body) -AGAINST ('"proximity search"@2' IN BOOLEAN MODE); -id title body -8 test proximity search, test, proximity and phrase search, with proximity innodb -SELECT * FROM articles -WHERE MATCH (title,body) -AGAINST ('"proximity search"@5' IN BOOLEAN MODE); -id title body -8 test proximity search, test, proximity and phrase search, with proximity innodb -9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb -10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb -SELECT * FROM articles -WHERE MATCH (title,body) -AGAINST ('"test proximity"@5' IN BOOLEAN MODE); -id title body -8 test proximity search, test, proximity and phrase search, with proximity innodb -9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb -10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb -SELECT * FROM articles -WHERE MATCH (title,body) -AGAINST ('"test proximity"@1' IN BOOLEAN MODE); -id title body -SELECT * FROM articles -WHERE MATCH (title,body) -AGAINST ('"test proximity"@4' IN BOOLEAN MODE); -id title body -8 test proximity search, test, proximity and phrase search, with proximity innodb -9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb -10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb -SELECT * FROM articles -WHERE MATCH (title,body) -AGAINST ('"test proximity"@3' IN BOOLEAN MODE); -id title body -8 test proximity search, test, proximity and phrase search, with proximity innodb -9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb -10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb -SELECT * FROM articles -WHERE MATCH (title,body) -AGAINST ('"more test proximity"@4' IN BOOLEAN MODE); -id title body -10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb -SELECT * FROM articles -WHERE MATCH (title,body) -AGAINST ('"more test proximity"@3' IN BOOLEAN MODE); -id title body -10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb -SELECT * FROM articles -WHERE MATCH (title,body) -AGAINST ('"more test proximity"' IN BOOLEAN MODE); -id title body -drop table articles; diff --git a/mysql-test/suite/innodb_fts/t/basic.test b/mysql-test/suite/innodb_fts/t/basic.test new file mode 100644 index 00000000000..58f36be08a5 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/basic.test @@ -0,0 +1,257 @@ +# This is the basic function tests for innodb FTS + +-- source include/have_innodb.inc + +# Create FTS table +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) + ) ENGINE=InnoDB; + +# Insert six rows +INSERT INTO articles (title,body) VALUES + ('MySQL Tutorial','DBMS stands for DataBase ...') , + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'), + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + +-- disable_result_log +ANALYZE TABLE articles; +-- enable_result_log + +# Look for 'Database' in table article +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('Database' IN NATURAL LANGUAGE MODE); + +SELECT COUNT(*) FROM articles + WHERE MATCH (title,body) + AGAINST ('database' IN NATURAL LANGUAGE MODE); + +SELECT * FROM articles + WHERE MATCH (title, body) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + + +SELECT COUNT(IF(MATCH (title,body) + AGAINST ('database' IN NATURAL LANGUAGE MODE), 1, NULL)) + AS count FROM articles; + +# Select Relevance Ranking +SELECT id, body, MATCH (title,body) + AGAINST ('Database' IN NATURAL LANGUAGE MODE) AS score + FROM articles; + +# 'MySQL' treated as stopword (stopword functionality not yet supported) +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('MySQL' IN NATURAL LANGUAGE MODE); + +# Boolean search +# Select rows contain "MySQL" but not "YourSQL" +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE); + +# Select rows contain at least one of the two words +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('DBMS Security' IN BOOLEAN MODE); + +# Select rows contain both "MySQL" and "YourSQL" +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('+MySQL +YourSQL' IN BOOLEAN MODE); + +# Select rows contain "MySQL" but rank rows with "YourSQL" higher +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('+MySQL YourSQL' IN BOOLEAN MODE); + +# Test negation operator. Select rows contain MySQL, +# if the row contains "YourSQL", rank it lower +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('+MySQL ~YourSQL' IN BOOLEAN MODE); + +# Test wild card search operator +# Notice row with "the" will not get fetched due to +# stopword filtering +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('t*' IN BOOLEAN MODE); + +# Test wild card search, notice row 6 with 2 "MySQL" rank first +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('MY*' IN BOOLEAN MODE); + +# Another wild card search +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('ru*' IN BOOLEAN MODE); + +# Test ">" and "<" Operator, the ">" operator increases +# the word relevance rank and the "<" operator decreases it +# Following test puts rows with "Well" on top and rows +# with "stands" at the bottom +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('+ MySQL >Well < stands' IN BOOLEAN MODE); + +# Test sub-expression boolean search. Find rows contain +# "MySQL" but not "Well" or "stands". +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('+ MySQL - (Well stands)' IN BOOLEAN MODE); + +# Test sub-expression boolean search. Find rows contain +# "MySQL" and "Well" or "MySQL" and "stands". But rank the +# doc with "Well" higher, and doc with "stands" lower. +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('+ MySQL + (>Well < stands)' IN BOOLEAN MODE); + +# Test nested sub-expression. +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('YourSQL + (+MySQL - (Tricks Security))' IN BOOLEAN MODE); + +# Find rows with "MySQL" but not "Tricks", "Security" nor "YourSQL" +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('(+MySQL - (Tricks Security)) - YourSQL' IN BOOLEAN MODE); + +# Test non-word delimiter combined with negate "-" operator +# This should return the same result as 'mysql - (Security DBMS)' +SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysql - Security&DBMS' IN BOOLEAN MODE); +SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysql - (Security DBMS)' IN BOOLEAN MODE); + +# Again, the operator sequence should not matter +SELECT * FROM articles WHERE MATCH (title,body) AGAINST (' - Security&DBMS + YourSQL' IN BOOLEAN MODE); + +SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('+YourSQL - Security&DBMS' IN BOOLEAN MODE); + +# Test query expansion +SELECT COUNT(*) FROM articles + WHERE MATCH (title,body) + AGAINST ('database' WITH QUERY EXPANSION); + +INSERT INTO articles (title,body) VALUES + ('test query expansion','for database ...'); + +# This query will return result containing word "database" as +# the query expand from "test" to words in document just +# inserted above +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('test' WITH QUERY EXPANSION); + +# This is to test the proximity search, search two word +# "following" and "comparison" within 19 character space +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"following comparison"@3' IN BOOLEAN MODE); + +# This is to test the proximity search, search two word +# "following" and "comparison" within 19 character space +# This search should come with no return result +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"following comparison"@2' IN BOOLEAN MODE); + +# This is to test the phrase search, searching phrase +# "following database" +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"following database"' IN BOOLEAN MODE); + +# Insert into table with similar word of different distances +INSERT INTO articles (title,body) VALUES + ('test proximity search, test, proximity and phrase', + 'search, with proximity innodb'); + +INSERT INTO articles (title,body) VALUES + ('test my proximity fts new search, test, proximity and phrase', + 'search, with proximity innodb'); + +INSERT INTO articles (title,body) VALUES + ('test more of proximity fts search, test, more proximity and phrase', + 'search, with proximity innodb'); + +# This should only return the first document +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"proximity search"@3' IN BOOLEAN MODE); + +# This would return no document +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"proximity search"@2' IN BOOLEAN MODE); + +# This give you all three documents +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"proximity search"@5' IN BOOLEAN MODE); + +# Similar boundary testing for the words +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"test proximity"@5' IN BOOLEAN MODE); + +# No document will be returned +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"test proximity"@1' IN BOOLEAN MODE); + +# All three documents will be returned +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"test proximity"@4' IN BOOLEAN MODE); + +# Only two document will be returned. +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"test proximity"@3' IN BOOLEAN MODE); + +# Test with more word The last document will return, please notice there +# is no ordering requirement for proximity search. +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"more test proximity"@4' IN BOOLEAN MODE); + +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"more test proximity"@3' IN BOOLEAN MODE); + +# The phrase search will not require exact word ordering +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"more test proximity"' IN BOOLEAN MODE); + +drop table articles; + +--echo # +--echo # Bug #22679185 INVALID INNODB FTS DOC ID DURING INSERT +--echo # + +create table t1 (f1 int not null primary key, f2 varchar(100), + FTS_DOC_ID bigint(20) unsigned not null, + unique key `FTS_DOC_ID_INDEX` (`FTS_DOC_ID`), + fulltext key (f2))engine=innodb; + +insert into t1 values(1, "This is the first record", 20000); +insert into t1 values(2, "This is the second record", 40000); +select FTS_DOC_ID from t1; +drop table t1; + + +create table t1 (f1 int not null primary key, f2 varchar(100), + FTS_DOC_ID bigint(20) unsigned not null auto_increment, + unique key `FTS_DOC_ID_INDEX` (`FTS_DOC_ID`), + fulltext key (f2))engine=innodb; + +set auto_increment_increment = 65535; +insert into t1(f1, f2) values(1, "This is the first record"); +insert into t1(f1, f2) values(2, "This is the second record"); +insert into t1(f1, f2) values(3, "This is the third record"); +select FTS_DOC_ID from t1; +drop table t1; + +call mtr.add_suppression("\\[ERROR\\] InnoDB: Doc ID 20030101000000 is too big. Its difference with largest used Doc ID 0 cannot exceed or equal to 65535"); +CREATE TABLE t1 (FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), FULLTEXT(title)) ENGINE=InnoDB; +--error 182 +INSERT INTO t1 VALUES (NULL, NULL), (20030101000000, 20030102000000); +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/t/innodb-fts-basic.test b/mysql-test/suite/innodb_fts/t/innodb-fts-basic.test deleted file mode 100644 index 095713130f1..00000000000 --- a/mysql-test/suite/innodb_fts/t/innodb-fts-basic.test +++ /dev/null @@ -1,228 +0,0 @@ -# This is the basic function tests for innodb FTS - --- source include/have_innodb.inc - -if (`select plugin_auth_version <= "5.6.10" from information_schema.plugins where plugin_name='innodb'`) -{ - --skip Not fixed in InnoDB 5.6.10 or earlier -} - -# Create FTS table -CREATE TABLE articles ( - id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, - title VARCHAR(200), - body TEXT, - FULLTEXT (title,body) - ) ENGINE=InnoDB; - -# Insert six rows -INSERT INTO articles (title,body) VALUES - ('MySQL Tutorial','DBMS stands for DataBase ...') , - ('How To Use MySQL Well','After you went through a ...'), - ('Optimizing MySQL','In this tutorial we will show ...'), - ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), - ('MySQL vs. YourSQL','In the following database comparison ...'), - ('MySQL Security','When configured properly, MySQL ...'); - --- disable_result_log -ANALYZE TABLE articles; --- enable_result_log - -# Look for 'Database' in table article -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('Database' IN NATURAL LANGUAGE MODE); - -SELECT COUNT(*) FROM articles - WHERE MATCH (title,body) - AGAINST ('database' IN NATURAL LANGUAGE MODE); - -SELECT * FROM articles - WHERE MATCH (title, body) - AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); - - -SELECT COUNT(IF(MATCH (title,body) - AGAINST ('database' IN NATURAL LANGUAGE MODE), 1, NULL)) - AS count FROM articles; - -# Select Relevance Ranking -SELECT id, body, MATCH (title,body) - AGAINST ('Database' IN NATURAL LANGUAGE MODE) AS score - FROM articles; - -# 'MySQL' treated as stopword (stopword functionality not yet supported) -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('MySQL' IN NATURAL LANGUAGE MODE); - -# Boolean search -# Select rows contain "MySQL" but not "YourSQL" -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE); - -# Select rows contain at least one of the two words -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('DBMS Security' IN BOOLEAN MODE); - -# Select rows contain both "MySQL" and "YourSQL" -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('+MySQL +YourSQL' IN BOOLEAN MODE); - -# Select rows contain "MySQL" but rank rows with "YourSQL" higher -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('+MySQL YourSQL' IN BOOLEAN MODE); - -# Test negation operator. Select rows contain MySQL, -# if the row contains "YourSQL", rank it lower -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('+MySQL ~YourSQL' IN BOOLEAN MODE); - -# Test wild card search operator -# Notice row with "the" will not get fetched due to -# stopword filtering -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('t*' IN BOOLEAN MODE); - -# Test wild card search, notice row 6 with 2 "MySQL" rank first -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('MY*' IN BOOLEAN MODE); - -# Another wild card search -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('ru*' IN BOOLEAN MODE); - -# Test ">" and "<" Operator, the ">" operator increases -# the word relevance rank and the "<" operator decreases it -# Following test puts rows with "Well" on top and rows -# with "stands" at the bottom -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('+ MySQL >Well < stands' IN BOOLEAN MODE); - -# Test sub-expression boolean search. Find rows contain -# "MySQL" but not "Well" or "stands". -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('+ MySQL - (Well stands)' IN BOOLEAN MODE); - -# Test sub-expression boolean search. Find rows contain -# "MySQL" and "Well" or "MySQL" and "stands". But rank the -# doc with "Well" higher, and doc with "stands" lower. -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('+ MySQL + (>Well < stands)' IN BOOLEAN MODE); - -# Test nested sub-expression. -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('YourSQL + (+MySQL - (Tricks Security))' IN BOOLEAN MODE); - -# Find rows with "MySQL" but not "Tricks", "Security" nor "YourSQL" -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('(+MySQL - (Tricks Security)) - YourSQL' IN BOOLEAN MODE); - -# Test non-word delimiter combined with negate "-" operator -# This should return the same result as 'mysql - (Security DBMS)' -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysql - Security&DBMS' IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysql - (Security DBMS)' IN BOOLEAN MODE); - -# Again, the operator sequence should not matter -SELECT * FROM articles WHERE MATCH (title,body) AGAINST (' - Security&DBMS + YourSQL' IN BOOLEAN MODE); - -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('+YourSQL - Security&DBMS' IN BOOLEAN MODE); - -# Test query expansion -SELECT COUNT(*) FROM articles - WHERE MATCH (title,body) - AGAINST ('database' WITH QUERY EXPANSION); - -INSERT INTO articles (title,body) VALUES - ('test query expansion','for database ...'); - -# This query will return result containing word "database" as -# the query expand from "test" to words in document just -# inserted above -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('test' WITH QUERY EXPANSION); - -# This is to test the proximity search, search two word -# "following" and "comparison" within 19 character space -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"following comparison"@3' IN BOOLEAN MODE); - -# This is to test the proximity search, search two word -# "following" and "comparison" within 19 character space -# This search should come with no return result -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"following comparison"@2' IN BOOLEAN MODE); - -# This is to test the phrase search, searching phrase -# "following database" -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"following database"' IN BOOLEAN MODE); - -# Insert into table with similar word of different distances -INSERT INTO articles (title,body) VALUES - ('test proximity search, test, proximity and phrase', - 'search, with proximity innodb'); - -INSERT INTO articles (title,body) VALUES - ('test my proximity fts new search, test, proximity and phrase', - 'search, with proximity innodb'); - -INSERT INTO articles (title,body) VALUES - ('test more of proximity fts search, test, more proximity and phrase', - 'search, with proximity innodb'); - -# This should only return the first document -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"proximity search"@3' IN BOOLEAN MODE); - -# This would return no document -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"proximity search"@2' IN BOOLEAN MODE); - -# This give you all three documents -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"proximity search"@5' IN BOOLEAN MODE); - -# Similar boundary testing for the words -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"test proximity"@5' IN BOOLEAN MODE); - -# No document will be returned -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"test proximity"@1' IN BOOLEAN MODE); - -# All three documents will be returned -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"test proximity"@4' IN BOOLEAN MODE); - -# Only two document will be returned. -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"test proximity"@3' IN BOOLEAN MODE); - -# Test with more word The last document will return, please notice there -# is no ordering requirement for proximity search. -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"more test proximity"@4' IN BOOLEAN MODE); - -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"more test proximity"@3' IN BOOLEAN MODE); - -# The phrase search will not require exact word ordering -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"more test proximity"' IN BOOLEAN MODE); - -drop table articles; diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc index 7a4c5e114c1..838506c8786 100644 --- a/storage/xtradb/row/row0mysql.cc +++ b/storage/xtradb/row/row0mysql.cc @@ -1442,8 +1442,7 @@ error_exit: doc_ids difference should not exceed FTS_DOC_ID_MAX_STEP value. */ - if (next_doc_id > 1 - && doc_id - next_doc_id >= FTS_DOC_ID_MAX_STEP) { + if (doc_id - next_doc_id >= FTS_DOC_ID_MAX_STEP) { fprintf(stderr, "InnoDB: Doc ID " UINT64PF " is too" " big. Its difference with largest" -- cgit v1.2.1 From 197bf0fe35efb148c4e751e1b695786d61238e8e Mon Sep 17 00:00:00 2001 From: Sachin Agarwal Date: Thu, 22 Feb 2018 18:45:38 +0530 Subject: Bug #26334149 - MYSQL CRASHES WHEN FULL TEXT INDEXES IBD FILES ARE ORPHANED DUE TO RENAME TABLE Problem: When FTS index is added into a table which doesn't have 'FTS_DOC_ID' column, Innodb rebuilds table to add column 'FTS_DOC_ID'. when this FTS index is dropped from this table. Innodb doesn't not rebuild table to remove 'FTS_DOC_ID' column and deletes FTS index auxiliary tables. But it doesn't delete FTS common auxiliary tables. Later when the database having this table is renamed, FTS auxiliary tables are not renamed because table's flags2 (dict_table_t.flags2) has been resetted for DICT_TF2_FTS flag during FTS index drop operation. Now when we drop old database, it leads to an assert. Fix: During renaming of FTS auxiliary tables, ORed a condition to check if table has DICT_TF2_FTS_HAS_DOC_ID flag set. RB: 18769 Reviewed by : Jimmy.Yang@oracle.com --- mysql-test/suite/innodb/r/innodb-alter.result | 29 +++++++++++++++++++++++++++ mysql-test/suite/innodb/t/innodb-alter.test | 21 +++++++++++++++++++ storage/xtradb/row/row0mysql.cc | 5 +++-- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb-alter.result b/mysql-test/suite/innodb/r/innodb-alter.result index 0bad6c5e0c1..bd82cc8a764 100644 --- a/mysql-test/suite/innodb/r/innodb-alter.result +++ b/mysql-test/suite/innodb/r/innodb-alter.result @@ -859,3 +859,32 @@ DROP TABLE dest_db.t1; DROP TABLE source_db.t1; DROP DATABASE source_db; DROP DATABASE dest_db; +# +# BUG #26334149 MYSQL CRASHES WHEN FULL TEXT INDEXES IBD FILES ARE +# ORPHANED DUE TO RENAME TABLE +# +CREATE DATABASE db1; +USE db1; +CREATE TABLE notes ( +id int(11) NOT NULL AUTO_INCREMENT, +body text COLLATE utf8_unicode_ci, +PRIMARY KEY (id) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 +COLLATE=utf8_unicode_ci +ROW_FORMAT=COMPRESSED; +Warnings: +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +ALTER TABLE notes ADD FULLTEXT INDEX index_ft_body (body(255)); +Warnings: +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID +DROP INDEX index_ft_body ON notes; +Warnings: +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +CREATE DATABASE db2; +RENAME TABLE db1.notes TO db2.notes; +DROP DATABASE db1; +DROP DATABASE db2; diff --git a/mysql-test/suite/innodb/t/innodb-alter.test b/mysql-test/suite/innodb/t/innodb-alter.test index af75482703c..0d3cc6f1733 100644 --- a/mysql-test/suite/innodb/t/innodb-alter.test +++ b/mysql-test/suite/innodb/t/innodb-alter.test @@ -481,3 +481,24 @@ eval ALTER TABLE $source_db.t1 DROP INDEX index2, algorithm=inplace; eval DROP TABLE $source_db.t1; eval DROP DATABASE $source_db; eval DROP DATABASE $dest_db; + +--echo # +--echo # BUG #26334149 MYSQL CRASHES WHEN FULL TEXT INDEXES IBD FILES ARE +--echo # ORPHANED DUE TO RENAME TABLE +--echo # +CREATE DATABASE db1; USE db1; +CREATE TABLE notes ( + id int(11) NOT NULL AUTO_INCREMENT, + body text COLLATE utf8_unicode_ci, + PRIMARY KEY (id) + ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 +COLLATE=utf8_unicode_ci +ROW_FORMAT=COMPRESSED; + +ALTER TABLE notes ADD FULLTEXT INDEX index_ft_body (body(255)); +DROP INDEX index_ft_body ON notes; + +CREATE DATABASE db2; +RENAME TABLE db1.notes TO db2.notes; +DROP DATABASE db1; +DROP DATABASE db2; diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc index 838506c8786..cb496965f01 100644 --- a/storage/xtradb/row/row0mysql.cc +++ b/storage/xtradb/row/row0mysql.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2000, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2017, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -5168,7 +5168,8 @@ row_rename_table_for_mysql( } } - if (dict_table_has_fts_index(table) + if ((dict_table_has_fts_index(table) + || DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID)) && !dict_tables_have_same_db(old_name, new_name)) { err = fts_rename_aux_tables(table, new_name, trx); if (err != DB_TABLE_NOT_FOUND) { -- cgit v1.2.1 From bbc2e37fe4e0ca3a7cfa1437a763dc43829e98e2 Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Mon, 14 May 2018 11:28:13 +0530 Subject: Bug#27759871: BACKRONYM ISSUE IS STILL IN MYSQL 5.7 Description:- Client applications establishes connection to server, which does not support SSL, via TCP even when SSL is enforced via MYSQL_OPT_SSL_MODE or MYSQL_OPT_SSL_ENFORCE or MYSQL_OPT_SSL_VERIFY_SERVER_CERT. Analysis:- There exist no error handling for catching client applications which enforces SSL connection to connect to a server which does not support SSL. Fix:- Error handling is done to catch above mentioned scenarios. --- include/sql_common.h | 5 ++++- libmysqld/libmysqld.c | 5 ++++- sql-common/client.c | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/include/sql_common.h b/include/sql_common.h index 45e90d438fb..9571dff9778 100644 --- a/include/sql_common.h +++ b/include/sql_common.h @@ -1,7 +1,7 @@ #ifndef SQL_COMMON_INCLUDED #define SQL_COMMON_INCLUDED -/* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2003, 2018, 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 @@ -96,6 +96,9 @@ void set_stmt_error(MYSQL_STMT *stmt, int errcode, const char *sqlstate, void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate); void set_mysql_extended_error(MYSQL *mysql, int errcode, const char *sqlstate, const char *format, ...); +#ifdef EMBEDDED_LIBRARY +int embedded_ssl_check(MYSQL *mysql); +#endif /* client side of the pluggable authentication */ struct st_plugin_vio_info; diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c index 6de1e3383d2..85ca0cf4bd8 100644 --- a/libmysqld/libmysqld.c +++ b/libmysqld/libmysqld.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2001, 2018, 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 @@ -173,6 +173,9 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, if (db) client_flag|=CLIENT_CONNECT_WITH_DB; + if (embedded_ssl_check(mysql)) + goto error; + mysql->info_buffer= my_malloc(MYSQL_ERRMSG_SIZE, MYF(0)); mysql->thd= create_embedded_thd(client_flag); diff --git a/sql-common/client.c b/sql-common/client.c index 9972ca741f2..3247fd8e339 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -2020,6 +2020,34 @@ error: #endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */ +/** + Checks if any SSL option is set for libmysqld embedded server. + + @param mysql the connection handle + @retval 0 success + @retval 1 failure +*/ +#ifdef EMBEDDED_LIBRARY +int embedded_ssl_check(MYSQL *mysql) +{ + if (mysql->options.ssl_key || mysql->options.ssl_cert || + mysql->options.ssl_ca || mysql->options.ssl_capath || + mysql->options.ssl_cipher || + mysql->options.client_flag & CLIENT_SSL_VERIFY_SERVER_CERT || + (mysql->options.extension && + mysql->options.extension->ssl_mode == SSL_MODE_REQUIRED)) + { + set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate, + ER(CR_SSL_CONNECTION_ERROR), + "Embedded server libmysqld library doesn't support " + "SSL connections"); + return 1; + } + return 0; +} +#endif + + /* Note that the mysql argument must be initialized with mysql_init() before calling mysql_real_connect ! @@ -3592,6 +3620,11 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, mysql->client_flag= client_flag; +#ifdef EMBEDDED_LIBRARY + if (embedded_ssl_check(mysql)) + goto error; +#endif + /* Part 2: invoke the plugin to send the authentication data to the server */ @@ -4271,10 +4304,14 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg) mysql->reconnect= *(my_bool *) arg; break; case MYSQL_OPT_SSL_VERIFY_SERVER_CERT: +#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) if (*(my_bool*) arg) mysql->options.client_flag|= CLIENT_SSL_VERIFY_SERVER_CERT; else mysql->options.client_flag&= ~CLIENT_SSL_VERIFY_SERVER_CERT; +#elif defined(EMBEDDED_LIBRARY) + DBUG_RETURN(1); +#endif break; case MYSQL_PLUGIN_DIR: EXTENSION_SET_STRING(&mysql->options, plugin_dir, arg); @@ -4288,11 +4325,15 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg) (*(my_bool*) arg) ? TRUE : FALSE; break; case MYSQL_OPT_SSL_MODE: +#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) if (*(uint *) arg == SSL_MODE_REQUIRED) { ENSURE_EXTENSIONS_PRESENT(&mysql->options); mysql->options.extension->ssl_mode= SSL_MODE_REQUIRED; } +#elif defined(EMBEDDED_LIBRARY) + DBUG_RETURN(1); +#endif break; default: DBUG_RETURN(1); -- cgit v1.2.1 From 2b749a7bf4f6a6d70f05e8e4b42d088b397adea8 Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 15 May 2018 11:46:55 +0300 Subject: MDEV-654 Assertion `share->now_transactional' failed in flush_log_for_bitmap on concurrent workload with Aria tables Problem was that we the bitmap needs to be flushed before disabling logging of redo entires, as writing the bitmap to disk by background checkpoint may cause redo entries. --- storage/maria/ha_maria.cc | 1 + storage/maria/ma_recovery.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 0c41037f33e..ca2d050ddfe 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -1312,6 +1312,7 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt) old_proc_info= thd_proc_info(thd, "Checking status"); thd_progress_init(thd, 3); error= maria_chk_status(param, file); // Not fatal + /* maria_chk_size() will flush the page cache for this file */ if (maria_chk_size(param, file)) error= 1; if (!error) diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c index 75a8f4f4559..af0d9476f2a 100644 --- a/storage/maria/ma_recovery.c +++ b/storage/maria/ma_recovery.c @@ -3521,6 +3521,14 @@ void _ma_tmp_disable_logging_for_table(MARIA_HA *info, { MARIA_SHARE *share= info->s; DBUG_ENTER("_ma_tmp_disable_logging_for_table"); + + /* + We have to ensure that bitmap is flushed, as it's checking + that share->now_transactional is set + */ + if (share->now_transactional && share->data_file_type == BLOCK_RECORD) + _ma_bitmap_flush_all(share); + if (log_incomplete) { uchar log_data[FILEID_STORE_SIZE]; -- cgit v1.2.1 From b050df4fd3ee5f2377a814fd24ac3774d1458f99 Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 15 May 2018 12:30:32 +0300 Subject: MDEV-14943 Alter table ORDER BY bug Problem was that if copy_data_between_tables() didn't do proper clean up in case of failures: - copy object was not properly freed - end_bulk_insert() was not called - mysql_trans_prepare_alter_copy_data() set THD->transaction.on to false which was not properly restored The last part caused a crash in Aria as Aria depends on that THD is correct. Other things: - Reset info->switched_transactional after usage (safety) - Reset bulk_insert_single_undo (safety) --- mysql-test/suite/maria/alter.result | 16 ++++++++++++++++ mysql-test/suite/maria/alter.test | 17 +++++++++++++++++ sql/sql_table.cc | 32 ++++++++++++++++++++++++-------- storage/maria/ha_maria.cc | 1 + storage/maria/ma_recovery.c | 3 +++ 5 files changed, 61 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/maria/alter.result b/mysql-test/suite/maria/alter.result index 1a7daf5a1ee..c63688dddd6 100644 --- a/mysql-test/suite/maria/alter.result +++ b/mysql-test/suite/maria/alter.result @@ -31,3 +31,19 @@ pk i 8 88 9 99 DROP TABLE t1; +CREATE TABLE t1 (f INT) ENGINE=Aria transactional=1; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f` int(11) DEFAULT NULL +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 +INSERT INTO t1 VALUES (1),(2); +ALTER TABLE t1 ORDER BY unknown_column; +ERROR 42S22: Unknown column 'unknown_column' in 'order clause' +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f` int(11) DEFAULT NULL +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 +CREATE TABLE t2 SELECT * FROM t1; +DROP TABLE t1, t2; diff --git a/mysql-test/suite/maria/alter.test b/mysql-test/suite/maria/alter.test index abca4865688..09672cdfa3b 100644 --- a/mysql-test/suite/maria/alter.test +++ b/mysql-test/suite/maria/alter.test @@ -25,3 +25,20 @@ INSERT INTO t1 VALUES (2,0),(3,33),(4,0),(5,55),(6,66),(7,0),(8,88),(9,99); ALTER TABLE t1 ENABLE KEYS; SELECT * FROM t1 WHERE i = 0 OR pk BETWEEN 6 AND 10; DROP TABLE t1; + +# +# MDEV-14943 +# Assertion `block->type == PAGECACHE_EMPTY_PAGE || block->type == type || +# type == PAGECACHE_LSN_PAGE || type == PAGECACHE_READ_UNKNOWN_PAGE || +# block->type == PAGECACHE_READ_UNKNOWN_PAGE' failed in pagecache_read upon +# CREATE ... SELECT from Aria table +# + +CREATE TABLE t1 (f INT) ENGINE=Aria transactional=1; +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES (1),(2); +--error ER_BAD_FIELD_ERROR +ALTER TABLE t1 ORDER BY unknown_column; +SHOW CREATE TABLE t1; +CREATE TABLE t2 SELECT * FROM t1; +DROP TABLE t1, t2; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 8f3468a44db..27d579a6b19 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -9356,9 +9356,7 @@ bool mysql_trans_prepare_alter_copy_data(THD *thd) This needs to be done before external_lock. */ - if (ha_enable_transaction(thd, FALSE)) - DBUG_RETURN(TRUE); - DBUG_RETURN(FALSE); + DBUG_RETURN(ha_enable_transaction(thd, FALSE) != 0); } @@ -9409,6 +9407,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, ha_rows examined_rows; ha_rows found_rows; bool auto_increment_field_copied= 0; + bool cleanup_done= 0; ulonglong save_sql_mode= thd->variables.sql_mode; ulonglong prev_insert_id, time_to_report_progress; Field **dfield_ptr= to->default_field; @@ -9417,15 +9416,23 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, /* Two or 3 stages; Sorting, copying data and update indexes */ thd_progress_init(thd, 2 + MY_TEST(order)); - if (mysql_trans_prepare_alter_copy_data(thd)) - DBUG_RETURN(-1); - if (!(copy= new Copy_field[to->s->fields])) DBUG_RETURN(-1); /* purecov: inspected */ + if (mysql_trans_prepare_alter_copy_data(thd)) + { + delete [] copy; + DBUG_RETURN(-1); + } + /* We need external lock before we can disable/enable keys */ if (to->file->ha_external_lock(thd, F_WRLCK)) + { + /* Undo call to mysql_trans_prepare_alter_copy_data() */ + ha_enable_transaction(thd, TRUE); + delete [] copy; DBUG_RETURN(-1); + } alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff); @@ -9435,7 +9442,6 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, from->file->info(HA_STATUS_VARIABLE); to->file->ha_start_bulk_insert(from->file->stats.records, ignore ? 0 : HA_CREATE_UNIQUE_INDEX_BY_SORT); - List_iterator it(create); Create_field *def; copy_end=copy; @@ -9637,7 +9643,6 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, } end_read_record(&info); free_io_cache(from); - delete [] copy; THD_STAGE_INFO(thd, stage_enabling_keys); thd_progress_next_stage(thd); @@ -9652,6 +9657,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, to->file->print_error(my_errno,MYF(0)); error= 1; } + cleanup_done= 1; to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); if (mysql_trans_commit_alter_copy_data(thd)) @@ -9663,6 +9669,16 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, *copied= found_count; *deleted=delete_count; to->file->ha_release_auto_increment(); + delete [] copy; + + if (!cleanup_done) + { + /* This happens if we get an error during initialzation of data */ + DBUG_ASSERT(error); + to->file->ha_end_bulk_insert(); + ha_enable_transaction(thd, TRUE); + } + if (to->file->ha_external_lock(thd,F_UNLCK)) error=1; if (error < 0 && to->file->extra(HA_EXTRA_PREPARE_FOR_RENAME)) diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index f52336de9d0..80f278ab2eb 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -2224,6 +2224,7 @@ end: _ma_reenable_logging_for_table(file, bulk_insert_single_undo == BULK_INSERT_SINGLE_UNDO_AND_NO_REPAIR); + bulk_insert_single_undo= BULK_INSERT_NONE; // Safety } DBUG_RETURN(err); } diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c index 4c3310c68c5..b0c38e9f24d 100644 --- a/storage/maria/ma_recovery.c +++ b/storage/maria/ma_recovery.c @@ -3583,7 +3583,10 @@ my_bool _ma_reenable_logging_for_table(MARIA_HA *info, my_bool flush_pages) if (share->now_transactional == share->base.born_transactional || !info->switched_transactional) + { + info->switched_transactional= FALSE; DBUG_RETURN(0); + } info->switched_transactional= FALSE; if ((share->now_transactional= share->base.born_transactional)) -- cgit v1.2.1 From d703e09cd6706673fbb127f540d3917068b40755 Mon Sep 17 00:00:00 2001 From: Monty Date: Thu, 21 Sep 2017 16:30:24 +0300 Subject: Fix that FLUSH TABLES FOR EXPORT also works for Aria tables. - Added missing test case for MyISAM --- mysql-test/r/myisam.result | 8 ++++++++ mysql-test/suite/maria/maria.result | 8 ++++++++ mysql-test/suite/maria/maria.test | 13 +++++++++++++ mysql-test/t/myisam.test | 13 +++++++++++++ storage/maria/ha_maria.cc | 2 +- 5 files changed, 43 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 6b23aefd73b..bedfa413b55 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -2545,6 +2545,14 @@ OPTIMIZE TABLE t1; Table Op Msg_type Msg_text test.t1 optimize status OK DROP TABLE t1; +CREATE TABLE t1(a INT, b CHAR(10), KEY(a), KEY(b)) engine=myisam; +INSERT INTO t1 VALUES(1,'0'),(2,'0'),(3,'0'),(4,'0'),(5,'0'), +(6,'0'),(7,'0'); +flush tables test.t1 for export; +insert into t1 values (8,'0'); +ERROR HY000: Table 't1' was locked with a READ lock and can't be updated +unlock tables; +drop table t1; show variables like 'myisam_block_size'; Variable_name Value myisam_block_size 1024 diff --git a/mysql-test/suite/maria/maria.result b/mysql-test/suite/maria/maria.result index 8078687dad5..f4d7f3d32c6 100644 --- a/mysql-test/suite/maria/maria.result +++ b/mysql-test/suite/maria/maria.result @@ -2771,3 +2771,11 @@ test.t1 check status OK SET aria_repair_threads=@@global.aria_repair_threads; SET aria_sort_buffer_size=@@global.aria_sort_buffer_size; DROP TABLE t1; +CREATE TABLE t1(a INT, b CHAR(10), KEY(a), KEY(b)); +INSERT INTO t1 VALUES(1,'0'),(2,'0'),(3,'0'),(4,'0'),(5,'0'), +(6,'0'),(7,'0'); +flush tables test.t1 for export; +insert into t1 values (8,'0'); +ERROR HY000: Table 't1' was locked with a READ lock and can't be updated +unlock tables; +drop table t1; diff --git a/mysql-test/suite/maria/maria.test b/mysql-test/suite/maria/maria.test index 27e9a45fda7..17dfb803328 100644 --- a/mysql-test/suite/maria/maria.test +++ b/mysql-test/suite/maria/maria.test @@ -2028,6 +2028,19 @@ SET aria_repair_threads=@@global.aria_repair_threads; SET aria_sort_buffer_size=@@global.aria_sort_buffer_size; DROP TABLE t1; +# +# Check FLUSH FOR EXPORT +# + +CREATE TABLE t1(a INT, b CHAR(10), KEY(a), KEY(b)); +INSERT INTO t1 VALUES(1,'0'),(2,'0'),(3,'0'),(4,'0'),(5,'0'), + (6,'0'),(7,'0'); +flush tables test.t1 for export; +--error ER_TABLE_NOT_LOCKED_FOR_WRITE +insert into t1 values (8,'0'); +unlock tables; +drop table t1; + # # End of test # diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 62260ba43aa..796083c0622 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -1762,6 +1762,19 @@ ALTER TABLE t1 DISABLE KEYS; OPTIMIZE TABLE t1; DROP TABLE t1; +# +# Check FLUSH FOR EXPORT +# + +CREATE TABLE t1(a INT, b CHAR(10), KEY(a), KEY(b)) engine=myisam; +INSERT INTO t1 VALUES(1,'0'),(2,'0'),(3,'0'),(4,'0'),(5,'0'), + (6,'0'),(7,'0'); +flush tables test.t1 for export; +--error ER_TABLE_NOT_LOCKED_FOR_WRITE +insert into t1 values (8,'0'); +unlock tables; +drop table t1; + # # Check some variables # diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 80f278ab2eb..748300e48b8 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -980,7 +980,7 @@ int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER | HA_DUPLICATE_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY | HA_FILE_BASED | HA_CAN_GEOMETRY | CANNOT_ROLLBACK_FLAG | HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS | HA_CAN_REPAIR | - HA_CAN_VIRTUAL_COLUMNS | + HA_CAN_VIRTUAL_COLUMNS | HA_CAN_EXPORT | HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT), can_enable_indexes(1), bulk_insert_single_undo(BULK_INSERT_NONE) {} -- cgit v1.2.1 From aa2e1ade17e656446c534c02e9cb0adab50b46e1 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 16 May 2018 21:01:26 +0400 Subject: (almost) sane core handling in mtr Analyze core independently of max-save-datadir and max-save-core setting. Increment $num_saved_cores only if core was actually saved. "Move any core files from e.g. mysqltest" independently of max-save-datadir setting. Note: it may overwrite core from mysqld, which might not be desired (it did work this way even before). --- mysql-test/mysql-test-run.pl | 81 ++++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 36 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 0f915a8777a..de1871cbf03 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -637,50 +637,59 @@ sub run_test_server ($$$) { my $worker_savename= basename($worker_savedir); my $savedir= "$opt_vardir/log/$worker_savename"; + # Move any core files from e.g. mysqltest + foreach my $coref (glob("core*"), glob("*.dmp")) + { + mtr_report(" - found '$coref', moving it to '$worker_savedir'"); + move($coref, $worker_savedir); + } + + find( + { + no_chdir => 1, + wanted => sub + { + my $core_file= $File::Find::name; + my $core_name= basename($core_file); + + # Name beginning with core, not ending in .gz + if (($core_name =~ /^core/ and $core_name !~ /\.gz$/) + or (IS_WINDOWS and $core_name =~ /\.dmp$/)) + { + # Ending with .dmp + mtr_report(" - found '$core_name'", + "($num_saved_cores/$opt_max_save_core)"); + + My::CoreDump->show($core_file, $exe_mysqld, $opt_parallel); + + # Limit number of core files saved + if ($opt_max_save_core > 0 && + $num_saved_cores >= $opt_max_save_core) + { + mtr_report(" - deleting it, already saved", + "$opt_max_save_core"); + unlink("$core_file"); + } + else + { + mtr_compress_file($core_file) unless @opt_cases; + ++$num_saved_cores; + } + } + } + }, + $worker_savedir); + if ($opt_max_save_datadir > 0 && $num_saved_datadir >= $opt_max_save_datadir) { mtr_report(" - skipping '$worker_savedir/'"); rmtree($worker_savedir); } - else { + else + { mtr_report(" - saving '$worker_savedir/' to '$savedir/'"); rename($worker_savedir, $savedir); - # Move any core files from e.g. mysqltest - foreach my $coref (glob("core*"), glob("*.dmp")) - { - mtr_report(" - found '$coref', moving it to '$savedir'"); - move($coref, $savedir); - } - if ($opt_max_save_core > 0) { - # Limit number of core files saved - find({ no_chdir => 1, - wanted => sub { - my $core_file= $File::Find::name; - my $core_name= basename($core_file); - - # Name beginning with core, not ending in .gz - if (($core_name =~ /^core/ and $core_name !~ /\.gz$/) - or (IS_WINDOWS and $core_name =~ /\.dmp$/)){ - # Ending with .dmp - mtr_report(" - found '$core_name'", - "($num_saved_cores/$opt_max_save_core)"); - - My::CoreDump->show($core_file, $exe_mysqld, $opt_parallel); - - if ($num_saved_cores >= $opt_max_save_core) { - mtr_report(" - deleting it, already saved", - "$opt_max_save_core"); - unlink("$core_file"); - } else { - mtr_compress_file($core_file) unless @opt_cases; - } - ++$num_saved_cores; - } - } - }, - $savedir); - } } resfile_print_test(); $num_saved_datadir++; -- cgit v1.2.1 From ef295c31e3d50a99a90beccfb4deb9d9d36ac1e3 Mon Sep 17 00:00:00 2001 From: Monty Date: Wed, 16 May 2018 21:51:46 +0300 Subject: MDEV-11129 CREATE OR REPLACE TABLE t1 AS SELECT spfunc() crashes if spfunc() references t1 Fixed by extending unique_table() with a flag to not allow usage of the replaced table. I also cleaned up find_dup_table() to not use goto next. I also added more comments to the code in find_dup_table() --- mysql-test/r/create_or_replace.result | 20 +++++++++++++++ mysql-test/t/create_or_replace.test | 25 +++++++++++++++++++ sql/sql_base.cc | 46 +++++++++++++++++++++-------------- sql/sql_base.h | 6 ++++- sql/sql_delete.cc | 2 +- sql/sql_insert.cc | 3 ++- sql/sql_parse.cc | 2 +- 7 files changed, 82 insertions(+), 22 deletions(-) diff --git a/mysql-test/r/create_or_replace.result b/mysql-test/r/create_or_replace.result index a43dc2eaca4..0d171f9f87a 100644 --- a/mysql-test/r/create_or_replace.result +++ b/mysql-test/r/create_or_replace.result @@ -453,3 +453,23 @@ CREATE OR REPLACE TABLE t1 AS SELECT f1(); UNLOCK TABLES; DROP FUNCTION f1; DROP TABLE t1; +# +# MDEV-11129 +# CREATE OR REPLACE TABLE t1 AS SELECT spfunc() crashes if spfunc() +# references t1 +# +CREATE OR REPLACE TABLE t1(a INT); +CREATE FUNCTION f1() RETURNS VARCHAR(16383) +BEGIN +INSERT INTO t1 VALUES(1); +RETURN 'test'; +END; +$$ +CREATE OR REPLACE TABLE t1 AS SELECT f1(); +ERROR HY000: Table 't1' is specified twice, both as a target for 'CREATE' and as a separate source for data +LOCK TABLE t1 WRITE; +CREATE OR REPLACE TABLE t1 AS SELECT f1(); +ERROR HY000: Table 't1' was not locked with LOCK TABLES +UNLOCK TABLES; +DROP FUNCTION f1; +DROP TABLE t1; diff --git a/mysql-test/t/create_or_replace.test b/mysql-test/t/create_or_replace.test index b37417f39d0..5ebb3031be3 100644 --- a/mysql-test/t/create_or_replace.test +++ b/mysql-test/t/create_or_replace.test @@ -398,3 +398,28 @@ CREATE OR REPLACE TABLE t1 AS SELECT f1(); UNLOCK TABLES; DROP FUNCTION f1; DROP TABLE t1; + +--echo # +--echo # MDEV-11129 +--echo # CREATE OR REPLACE TABLE t1 AS SELECT spfunc() crashes if spfunc() +--echo # references t1 +--echo # + +CREATE OR REPLACE TABLE t1(a INT); +DELIMITER $$; +CREATE FUNCTION f1() RETURNS VARCHAR(16383) +BEGIN + INSERT INTO t1 VALUES(1); + RETURN 'test'; +END; +$$ +DELIMITER ;$$ +--error ER_UPDATE_TABLE_USED +CREATE OR REPLACE TABLE t1 AS SELECT f1(); +LOCK TABLE t1 WRITE; +--error ER_TABLE_NOT_LOCKED +CREATE OR REPLACE TABLE t1 AS SELECT f1(); +UNLOCK TABLES; + +DROP FUNCTION f1; +DROP TABLE t1; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 554c8cffeaf..bdde123f18c 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1278,7 +1278,8 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table, @param thd thread handle @param table table which should be checked @param table_list list of tables - @param check_alias whether to check tables' aliases + @param check_flag whether to check tables' aliases + Currently this is only used by INSERT NOTE: to exclude derived tables from check we use following mechanism: a) during derived table processing set THD::derived_tables_processing @@ -1307,9 +1308,9 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table, static TABLE_LIST* find_dup_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, - bool check_alias) + uint check_flag) { - TABLE_LIST *res; + TABLE_LIST *res= 0; const char *d_name, *t_name, *t_alias; DBUG_ENTER("find_dup_table"); DBUG_PRINT("enter", ("table alias: %s", table->alias)); @@ -1345,17 +1346,15 @@ TABLE_LIST* find_dup_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, retry: DBUG_PRINT("info", ("real table: %s.%s", d_name, t_name)); - for (TABLE_LIST *tl= table_list;;) + for (TABLE_LIST *tl= table_list; tl ; tl= tl->next_global, res= 0) { - if (tl && - tl->select_lex && tl->select_lex->master_unit() && + if (tl->select_lex && tl->select_lex->master_unit() && tl->select_lex->master_unit()->executed) { /* There is no sense to check tables of already executed parts of the query */ - tl= tl->next_global; continue; } /* @@ -1364,21 +1363,29 @@ retry: */ if (! (res= find_table_in_global_list(tl, d_name, t_name))) break; + tl= res; // We can continue search after this table /* Skip if same underlying table. */ if (res->table && (res->table == table->table)) - goto next; + continue; + + if (check_flag & CHECK_DUP_FOR_CREATE) + DBUG_RETURN(res); /* Skip if table alias does not match. */ - if (check_alias) + if (check_flag & CHECK_DUP_FOR_CREATE) { if (my_strcasecmp(table_alias_charset, t_alias, res->alias)) - goto next; + continue; } /* - Skip if marked to be excluded (could be a derived table) or if - entry is a prelocking placeholder. + If table is not excluded (could be a derived table) and table is not + a prelocking placeholder then we found either a duplicate entry + or a table that is part of a derived table (handled below). + Examples are: + INSERT INTO t1 SELECT * FROM t1; + INSERT INTO t1 SELECT * FROM view_containing_t1; */ if (res->select_lex && !res->select_lex->exclude_from_table_unique_test && @@ -1390,14 +1397,17 @@ retry: processed in derived table or top select of multi-update/multi-delete (exclude_from_table_unique_test) or prelocking placeholder. */ -next: - tl= res->next_global; DBUG_PRINT("info", ("found same copy of table or table which we should skip")); } if (res && res->belong_to_derived) { - /* Try to fix */ + /* + We come here for queries of type: + INSERT INTO t1 (SELECT tmp.a FROM (select * FROM t1) as tmp); + + Try to fix by materializing the derived table + */ TABLE_LIST *derived= res->belong_to_derived; if (derived->is_merged_derived()) { @@ -1429,7 +1439,7 @@ next: TABLE_LIST* unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, - bool check_alias) + uint check_flag) { TABLE_LIST *dup; @@ -1443,12 +1453,12 @@ unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, for (child= table->next_global; child && child->parent_l == table; child= child->next_global) { - if ((dup= find_dup_table(thd, child, child->next_global, check_alias))) + if ((dup= find_dup_table(thd, child, child->next_global, check_flag))) break; } } else - dup= find_dup_table(thd, table, table_list, check_alias); + dup= find_dup_table(thd, table, table_list, check_flag); return dup; } /* diff --git a/sql/sql_base.h b/sql/sql_base.h index 04f132ac936..af42a15ab29 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -61,6 +61,10 @@ enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND, IGNORE_ERRORS, REPORT_EXCEPT_NON_UNIQUE, IGNORE_EXCEPT_NON_UNIQUE}; +/* Flag bits for unique_table() */ +#define CHECK_DUP_ALLOW_DIFFERENT_ALIAS 1 +#define CHECK_DUP_FOR_CREATE 2 + uint create_tmp_table_def_key(THD *thd, char *key, const char *db, const char *table_name); uint get_table_def_key(const TABLE_LIST *table_list, const char **key); @@ -254,7 +258,7 @@ void kill_delayed_threads_for_table(TABLE_SHARE *share); void close_thread_table(THD *thd, TABLE **table_ptr); bool close_temporary_tables(THD *thd); TABLE_LIST *unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, - bool check_alias); + uint check_flag); int drop_temporary_table(THD *thd, TABLE *table, bool *is_trans); void close_temporary_table(THD *thd, TABLE *table, bool free_share, bool delete_table); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 0780f418c80..609e5472ba6 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -903,7 +903,7 @@ multi_delete::initialize_tables(JOIN *join) TABLE_LIST *tbl= walk->correspondent_table->find_table_for_update(); tables_to_delete_from|= tbl->table->map; if (delete_while_scanning && - unique_table(thd, tbl, join->tables_list, false)) + unique_table(thd, tbl, join->tables_list, 0)) { /* If the table we are going to delete from appears diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 6036bbeb8b1..8b03c722898 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1483,7 +1483,8 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, { Item *fake_conds= 0; TABLE_LIST *duplicate; - if ((duplicate= unique_table(thd, table_list, table_list->next_global, 1))) + if ((duplicate= unique_table(thd, table_list, table_list->next_global, + CHECK_DUP_ALLOW_DIFFERENT_ALIAS))) { update_non_unique_table_error(table_list, "INSERT", duplicate); DBUG_RETURN(TRUE); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 87edf93bb4a..1162aa901d1 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2970,7 +2970,7 @@ case SQLCOM_PREPARE: TABLE_LIST *duplicate; if ((duplicate= unique_table(thd, lex->query_tables, lex->query_tables->next_global, - 0))) + CHECK_DUP_FOR_CREATE))) { update_non_unique_table_error(lex->query_tables, "CREATE", duplicate); -- cgit v1.2.1 From 1b2078b4d8aa64bad8bc2b3a201e0cf8c075e6a6 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 15 May 2018 17:34:47 +0200 Subject: MDEV-15318 CREATE .. SELECT VALUES produces invalid table structure When Item_insert_value needs a dummy field, use zero-length Field_string, not Field_null. The latter isn't compatible with CREATE ... SELECT. --- mysql-test/r/insert_select.result | 9 +++++++++ mysql-test/t/insert_select.test | 10 ++++++++++ sql/item.cc | 8 ++++---- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result index 8bfc4e9215e..157cc677d85 100644 --- a/mysql-test/r/insert_select.result +++ b/mysql-test/r/insert_select.result @@ -853,3 +853,12 @@ INSERT IGNORE INTO t1 SELECT t1.a FROM t1,t1 t2,t1 t3,t1 t4,t1 t5,t1 t6,t1 t7; SET GLOBAL myisam_data_pointer_size = @old_myisam_data_pointer_size; DROP TABLE t1; End of 5.1 tests +create table t1 (i int); +create table t2 as select values(i) as a from t1; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` binary(0) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1, t2; +End of 5.5 tests diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test index bcd87c2688d..385e372bc3b 100644 --- a/mysql-test/t/insert_select.test +++ b/mysql-test/t/insert_select.test @@ -423,3 +423,13 @@ SET GLOBAL myisam_data_pointer_size = @old_myisam_data_pointer_size; DROP TABLE t1; --echo End of 5.1 tests + +# +# MDEV-15318 CREATE .. SELECT VALUES produces invalid table structure +# +create table t1 (i int); +create table t2 as select values(i) as a from t1; +show create table t2; +drop table t1, t2; + +--echo End of 5.5 tests diff --git a/sql/item.cc b/sql/item.cc index c5c6df0ec48..135255ee21e 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -8541,10 +8541,10 @@ bool Item_insert_value::fix_fields(THD *thd, Item **items) } else { - Field *tmp_field= field_arg->field; - /* charset doesn't matter here, it's to avoid sigsegv only */ - tmp_field= new Field_null(0, 0, Field::NONE, field_arg->field->field_name, - &my_charset_bin); + static uchar null_bit=1; + /* charset doesn't matter here */ + Field *tmp_field= new Field_string(0, 0, &null_bit, 1, Field::NONE, + field_arg->field->field_name, &my_charset_bin); if (tmp_field) { tmp_field->init(field_arg->field->table); -- cgit v1.2.1 From 27a7365f42ce0184a004e09b3bb1cadb868c8f64 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 18 May 2018 00:23:15 +0100 Subject: MDEV-16220 MTR - do not pass UTF8 on the command line for mysql client. It should work ok on all Unixes, but on Windows ,only worked by accident in the past, with client not being Unicode safe. It stopped working with Visual Studio 2017 15.7 update now. --- mysql-test/r/grant.result | 5 ----- mysql-test/r/grant_not_windows.result | 7 ++++++ mysql-test/t/grant.test | 8 ------- mysql-test/t/grant_not_windows.test | 13 +++++++++++ mysql-test/t/mysql.test | 16 +++++++++---- mysql-test/t/mysql_cp932.test | 42 ++++++++++++++++++++++++++++++----- 6 files changed, 68 insertions(+), 23 deletions(-) create mode 100644 mysql-test/r/grant_not_windows.result create mode 100644 mysql-test/t/grant_not_windows.test diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index 94087393489..66cf6d35758 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1647,11 +1647,6 @@ drop user mysqluser11@localhost; drop database mysqltest1; End of 5.0 tests set names utf8; -grant select on test.* to юзер_юзер@localhost; -user() -юзер_юзер@localhost -revoke all on test.* from юзер_юзер@localhost; -drop user юзер_юзер@localhost; grant select on test.* to очень_длинный_юзер@localhost; ERROR HY000: String 'очень_длинный_юзер' is too long for user name (should be no longer than 16) set names default; diff --git a/mysql-test/r/grant_not_windows.result b/mysql-test/r/grant_not_windows.result new file mode 100644 index 00000000000..5cf0c1deb32 --- /dev/null +++ b/mysql-test/r/grant_not_windows.result @@ -0,0 +1,7 @@ +set names utf8; +grant select on test.* to юзер_юзер@localhost; +user() +юзер_юзер@localhost +revoke all on test.* from юзер_юзер@localhost; +drop user юзер_юзер@localhost; +set names default; diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index efa79c5b768..2a8961e46a9 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -1574,15 +1574,7 @@ drop database mysqltest1; --echo End of 5.0 tests - -# -# Bug#21432 Database/Table name limited to 64 bytes, not chars, problems with multi-byte -# set names utf8; -grant select on test.* to юзер_юзер@localhost; ---exec $MYSQL --default-character-set=utf8 --user=юзер_юзер -e "select user()" -revoke all on test.* from юзер_юзер@localhost; -drop user юзер_юзер@localhost; --error ER_WRONG_STRING_LENGTH grant select on test.* to очень_длинный_юзер@localhost; set names default; diff --git a/mysql-test/t/grant_not_windows.test b/mysql-test/t/grant_not_windows.test new file mode 100644 index 00000000000..575516c409b --- /dev/null +++ b/mysql-test/t/grant_not_windows.test @@ -0,0 +1,13 @@ + # UTF8 parameters to mysql client do not work on Windows +--source include/not_windows.inc +--source include/not_embedded.inc + +# +# Bug#21432 Database/Table name limited to 64 bytes, not chars, problems with multi-byte +# +set names utf8; +grant select on test.* to юзер_юзер@localhost; +--exec $MYSQL --default-character-set=utf8 --user=юзер_юзер -e "select user()" +revoke all on test.* from юзер_юзер@localhost; +drop user юзер_юзер@localhost; +set names default; diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index dd964c46420..87756768c7f 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -51,14 +51,22 @@ drop table t1; # # Bug#17939 Wrong table format when using UTF8 strings -# ---exec $MYSQL --default-character-set=utf8 --table -e "SELECT 'John Doe' as '__tañgè Ñãmé'" 2>&1 ---exec $MYSQL --default-character-set=utf8 --table -e "SELECT '__tañgè Ñãmé' as 'John Doe'" 2>&1 +write_file $MYSQL_TMP_DIR/mysql_in; +SELECT 'John Doe' as '__tañgè Ñãmé'; +SELECT '__tañgè Ñãmé' as 'John Doe'; +EOF +--exec $MYSQL --default-character-set=utf8 --table < $MYSQL_TMP_DIR/mysql_in 2>&1 +remove_file $MYSQL_TMP_DIR/mysql_in; # # Bug#18265 -- mysql client: No longer right-justifies numeric columns # ---exec $MYSQL -t --default-character-set utf8 test -e "create table t1 (i int, j int, k char(25) charset utf8); insert into t1 (i) values (1); insert into t1 (k) values ('<----------------------->'); insert into t1 (k) values ('<-----'); insert into t1 (k) values ('Τη γλώσσα'); insert into t1 (k) values ('ᛖᚴ ᚷᛖᛏ'); select * from t1; DROP TABLE t1;" +write_file $MYSQL_TMP_DIR/mysql_in; +create table t1 (i int, j int, k char(25) charset utf8); insert into t1 (i) values (1); insert into t1 (k) values ('<----------------------->'); insert into t1 (k) values ('<-----'); insert into t1 (k) values ('Τη γλώσσα'); insert into t1 (k) values ('ᛖᚴ ᚷᛖᛏ'); select * from t1; DROP TABLE t1; +EOF +--exec $MYSQL -t --default-character-set utf8 test < $MYSQL_TMP_DIR/mysql_in +remove_file $MYSQL_TMP_DIR/mysql_in; + # # "DESCRIBE" commands may return strange NULLness flags. diff --git a/mysql-test/t/mysql_cp932.test b/mysql-test/t/mysql_cp932.test index 60a129c3805..8fba5750d89 100644 --- a/mysql-test/t/mysql_cp932.test +++ b/mysql-test/t/mysql_cp932.test @@ -10,13 +10,43 @@ # BUG#16217 - MySQL client misinterprets multi-byte char as escape `\' # +let $mysql_in= $MYSQL_TMP_DIR/mysql_in; + # new command \C or charset ---exec $MYSQL --default-character-set=utf8 test -e "\C cp932 \g" ---exec $MYSQL --default-character-set=cp932 test -e "charset utf8;" +write_file $mysql_in; +\C cp932 \g +EOF +--exec $MYSQL --default-character-set=utf8 test < $mysql_in +remove_file $mysql_in; + +write_file $mysql_in; +charset utf8; +EOF +--exec $MYSQL --default-character-set=cp932 test < $mysql_in +remove_file $mysql_in; # its usage to switch internally in mysql to requested charset ---exec $MYSQL --default-character-set=utf8 test -e "charset cp932; select '\'; create table t1 (c_cp932 TEXT CHARACTER SET cp932); insert into t1 values('\'); select * from t1; drop table t1;" ---exec $MYSQL --default-character-set=utf8 test -e "charset cp932; select '\'" ---exec $MYSQL --default-character-set=utf8 test -e "/*charset cp932 */; set character_set_client= cp932; select '\'" ---exec $MYSQL --default-character-set=utf8 test -e "/*!\C cp932 */; set character_set_client= cp932; select '\'" +write_file $mysql_in; +charset cp932; select '\'; create table t1 (c_cp932 TEXT CHARACTER SET cp932); insert into t1 values('\'); select * from t1; drop table t1; +EOF +--exec $MYSQL --default-character-set=utf8 test < $mysql_in +remove_file $mysql_in; + +write_file $mysql_in; +charset cp932; select '\' +EOF +--exec $MYSQL --default-character-set=utf8 test < $mysql_in +remove_file $mysql_in; + +write_file $mysql_in; +/*charset cp932 */; set character_set_client= cp932; select '\' +EOF +--exec $MYSQL --default-character-set=utf8 test < $mysql_in +remove_file $mysql_in; + +write_file $mysql_in; +/*!\C cp932 */; set character_set_client= cp932; select '\' +EOF +--exec $MYSQL --default-character-set=utf8 test < $mysql_in +remove_file $mysql_in; -- cgit v1.2.1 From cf5226174bcb41611e9650ac04104a9b16f368be Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 19 May 2018 15:34:17 +0200 Subject: MDEV-11129 CREATE OR REPLACE TABLE t1 AS SELECT spfunc() crashes if spfunc() references t1 fix a typo that broke the main.view test followup for ef295c31e3d --- sql/sql_base.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index bdde123f18c..dc61f396605 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1373,7 +1373,7 @@ retry: DBUG_RETURN(res); /* Skip if table alias does not match. */ - if (check_flag & CHECK_DUP_FOR_CREATE) + if (check_flag & CHECK_DUP_ALLOW_DIFFERENT_ALIAS) { if (my_strcasecmp(table_alias_charset, t_alias, res->alias)) continue; -- cgit v1.2.1 From bd5ca6acece65858591c2bf54f86ff34aeea2821 Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Mon, 21 May 2018 08:42:45 +0530 Subject: Bug#25541037: MYSQL BUG ON DELETE Description:- MyISAM table gets corrupted with concurrent executions of INSERT, DELETE statements in a particular sequence. Analysis:- Due to the inappropriate manipulation of w_lock and r_lock associated with a MyISAM table, there arises a scenario where the table's state information becomes invalid. Fix:- A lock is introduced to resolve this issue. --- storage/myisam/ha_myisam.cc | 6 +++++- storage/myisam/mi_check.c | 6 +++++- storage/myisam/mi_locking.c | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 21cbef32188..6eed1be1ba9 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2018, 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 @@ -1172,10 +1172,14 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize) if (file->s->base.auto_key) update_auto_increment_key(¶m, file, 1); if (optimize_done) + { + mysql_mutex_lock(&share->intern_lock); error = update_state_info(¶m, file, UPDATE_TIME | UPDATE_OPEN_COUNT | (local_testflag & T_STATISTICS ? UPDATE_STAT : 0)); + mysql_mutex_unlock(&share->intern_lock); + } info(HA_STATUS_NO_LOCK | HA_STATUS_TIME | HA_STATUS_VARIABLE | HA_STATUS_CONST); if (rows != file->state->records && ! (param.testflag & T_VERY_SILENT)) diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index fe0d4c9c30b..7134cfc265a 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2018, 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 @@ -4474,6 +4474,10 @@ int update_state_info(MI_CHECK *param, MI_INFO *info,uint update) int error; uint r_locks=share->r_locks,w_locks=share->w_locks; share->r_locks= share->w_locks= share->tot_locks= 0; + + DBUG_EXECUTE_IF("simulate_incorrect_share_wlock_value", + DEBUG_SYNC_C("after_share_wlock_set_to_0");); + error=_mi_writeinfo(info,WRITEINFO_NO_UNLOCK); share->r_locks=r_locks; share->w_locks=w_locks; diff --git a/storage/myisam/mi_locking.c b/storage/myisam/mi_locking.c index 4a33e838fb9..dcfeaca5b8c 100644 --- a/storage/myisam/mi_locking.c +++ b/storage/myisam/mi_locking.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2018, 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 @@ -229,6 +229,10 @@ int mi_lock_database(MI_INFO *info, int lock_type) info->invalidator=info->s->invalidator; share->w_locks++; share->tot_locks++; + + DBUG_EXECUTE_IF("simulate_incorrect_share_wlock_value", + DEBUG_SYNC_C("after_share_wlock_increment");); + info->s->in_use= list_add(info->s->in_use, &info->in_use); break; default: -- cgit v1.2.1 From 6a04c2a1aa60e67c07d4e6ada63f65cc3b26a5a9 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 22 May 2018 12:09:05 -0700 Subject: MDEV-16235 Server crashes in my_utf8_uni or in my_strtod_int upon SELECT .. LIMIT 0 The code must differentiate between a SELECT with contradictory WHERE/HAVING and one with LIMIT 0. Also for the latter printed 'Zero limit' instead of 'Impossible where' in the EXPLAIN output. --- mysql-test/r/limit.result | 16 ++++++++++++++++ mysql-test/r/subselect4.result | 2 +- mysql-test/r/subselect_mat_cost_bugs.result | 2 +- mysql-test/t/limit.test | 14 ++++++++++++++ mysql-test/t/subselect4.test | 2 +- sql/sql_select.cc | 17 +++++++++++++---- 6 files changed, 46 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/limit.result b/mysql-test/r/limit.result index 176a93c7a46..deb4ca2ab95 100644 --- a/mysql-test/r/limit.result +++ b/mysql-test/r/limit.result @@ -146,3 +146,19 @@ a 16 DROP TABLE t1; End of 5.1 tests +# +# mdev-16235: SELECT over a table with LIMIT 0 +# +EXPLAIN +SELECT * FROM mysql.slow_log WHERE sql_text != 'foo' LIMIT 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Zero limit +SELECT * FROM mysql.slow_log WHERE sql_text != 'foo' LIMIT 0; +start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text +EXPLAIN +SELECT * FROM mysql.help_topic WHERE help_category_id != example LIMIT 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Zero limit +SELECT * FROM mysql.help_topic WHERE help_category_id != example LIMIT 0; +help_topic_id name help_category_id description example url +End of 5.5 tests diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result index 6accc23d18a..8973330c7da 100644 --- a/mysql-test/r/subselect4.result +++ b/mysql-test/r/subselect4.result @@ -2512,7 +2512,7 @@ SELECT 2 IN (SELECT 2 from DUAL WHERE 1 != 1); SET optimizer_switch= @@global.optimizer_switch; set @@tmp_table_size= @@global.tmp_table_size; # -# mfrv-14515: Wrong results for tableless query with subquery in WHERE +# mdev-14515: Wrong results for tableless query with subquery in WHERE # and implicit aggregation # create table t1 (i1 int, i2 int); diff --git a/mysql-test/r/subselect_mat_cost_bugs.result b/mysql-test/r/subselect_mat_cost_bugs.result index df6b543bab8..d33f1488e4d 100644 --- a/mysql-test/r/subselect_mat_cost_bugs.result +++ b/mysql-test/r/subselect_mat_cost_bugs.result @@ -334,7 +334,7 @@ SELECT * FROM t1 WHERE (f1) IN (SELECT f1 FROM t2) LIMIT 0; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Zero limit 2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where SELECT * FROM t1 WHERE (f1) IN (SELECT f1 FROM t2) diff --git a/mysql-test/t/limit.test b/mysql-test/t/limit.test index 4dbe13096d4..668d3b74518 100644 --- a/mysql-test/t/limit.test +++ b/mysql-test/t/limit.test @@ -115,3 +115,17 @@ SELECT a FROM t1 ORDER BY a LIMIT 2 OFFSET 14; DROP TABLE t1; --echo End of 5.1 tests + +--echo # +--echo # mdev-16235: SELECT over a table with LIMIT 0 +--echo # + +EXPLAIN +SELECT * FROM mysql.slow_log WHERE sql_text != 'foo' LIMIT 0; +SELECT * FROM mysql.slow_log WHERE sql_text != 'foo' LIMIT 0; + +EXPLAIN +SELECT * FROM mysql.help_topic WHERE help_category_id != example LIMIT 0; +SELECT * FROM mysql.help_topic WHERE help_category_id != example LIMIT 0; + +--echo End of 5.5 tests diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test index 2b53b55b735..2727fd9daed 100644 --- a/mysql-test/t/subselect4.test +++ b/mysql-test/t/subselect4.test @@ -2047,7 +2047,7 @@ SET optimizer_switch= @@global.optimizer_switch; set @@tmp_table_size= @@global.tmp_table_size; --echo # ---echo # mfrv-14515: Wrong results for tableless query with subquery in WHERE +--echo # mdev-14515: Wrong results for tableless query with subquery in WHERE --echo # and implicit aggregation --echo # diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 1e9f1c0848b..d6d269a700f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1136,10 +1136,19 @@ JOIN::optimize() if (cond_value == Item::COND_FALSE || having_value == Item::COND_FALSE || (!unit->select_limit_cnt && !(select_options & OPTION_FOUND_ROWS))) { /* Impossible cond */ - DBUG_PRINT("info", (having_value == Item::COND_FALSE ? - "Impossible HAVING" : "Impossible WHERE")); - zero_result_cause= having_value == Item::COND_FALSE ? - "Impossible HAVING" : "Impossible WHERE"; + if (unit->select_limit_cnt) + { + DBUG_PRINT("info", (having_value == Item::COND_FALSE ? + "Impossible HAVING" : "Impossible WHERE")); + zero_result_cause= having_value == Item::COND_FALSE ? + "Impossible HAVING" : "Impossible WHERE"; + } + else + { + DBUG_PRINT("info", ("Zero limit")); + zero_result_cause= "Zero limit"; + conds= 0; + } table_count= top_join_tab_count= 0; error= 0; goto setup_subq_exit; -- cgit v1.2.1 From 2f3779d31cbbabcb171c22237253c82146118446 Mon Sep 17 00:00:00 2001 From: Monty Date: Sun, 20 May 2018 14:19:14 +0300 Subject: Fixes for Aria transaction handling with lock tables MDEV-10130 Assertion `share->in_trans == 0' failed in storage/maria/ma_close.c MDEV-10378 Assertion `trn' failed in virtual int ha_maria::start_stmt The problem was that maria_handler->trn was not properly reset at commit/rollback and ha_maria::exernal_lock() could get confused because. There was some old code in ha_maria::implicit_commit() that tried to take care of this, but it was not bullet proof. Fixed by adding list of all tables that is part of the maria transaction to TRN. A nice side effect was of the fix is that loops in ha_maria::implict_commit() got to be much simpler. Other things: - Fixed a bug in mysql_admin_table() where argument open_for_modify was wrongly reset for the next table in the chain - rollback admin command also in case of fatal error. - Split _ma_set_trn_for_table() to three version to simplify code and debugging. - Several new asserts to detect the original problem (that file was not properly removed from trn before calling ma_close()) --- mysql-test/suite/maria/lock.result | 10 +++ mysql-test/suite/maria/lock.test | 12 ++++ sql/sql_admin.cc | 12 ++-- sql/sql_handler.cc | 4 +- storage/maria/ha_maria.cc | 137 +++++++++++++++---------------------- storage/maria/ha_maria.h | 1 + storage/maria/ma_blockrec.c | 3 +- storage/maria/ma_close.c | 2 + storage/maria/ma_commit.c | 17 +++-- storage/maria/ma_extra.c | 4 +- storage/maria/ma_open.c | 4 +- storage/maria/ma_state.c | 48 +++++++++++-- storage/maria/ma_state.h | 2 +- storage/maria/ma_trnman.h | 65 ++++++++++++++++++ storage/maria/maria_def.h | 14 +--- storage/maria/trnman.c | 1 + storage/maria/trnman.h | 3 +- 17 files changed, 219 insertions(+), 120 deletions(-) create mode 100644 storage/maria/ma_trnman.h diff --git a/mysql-test/suite/maria/lock.result b/mysql-test/suite/maria/lock.result index 90250568ef5..1c9d6b18100 100644 --- a/mysql-test/suite/maria/lock.result +++ b/mysql-test/suite/maria/lock.result @@ -99,3 +99,13 @@ f2 3 unlock tables; DROP TABLE t1,t2,tmp; +# +# MDEV-10378 Assertion `trn' failed in virtual int ha_maria::start_stmt +# +CREATE TABLE t1 (f1 VARCHAR(3), f2 INT, pk INT, PRIMARY KEY (pk)) ENGINE=Aria; +INSERT INTO t1 VALUES ('foo',10,1), ('foo',1,2); +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD UNIQUE KEY (f1); +ERROR 23000: Duplicate entry 'foo' for key 'f1' +ALTER TABLE t1 ADD KEY (f2); +DROP TABLE t1; diff --git a/mysql-test/suite/maria/lock.test b/mysql-test/suite/maria/lock.test index 57447a18c55..4f3d4e8065e 100644 --- a/mysql-test/suite/maria/lock.test +++ b/mysql-test/suite/maria/lock.test @@ -105,3 +105,15 @@ INSERT INTO t2 (f2) SELECT f3 FROM tmp AS tmp_alias; select * from t2; unlock tables; DROP TABLE t1,t2,tmp; + +--echo # +--echo # MDEV-10378 Assertion `trn' failed in virtual int ha_maria::start_stmt +--echo # + +CREATE TABLE t1 (f1 VARCHAR(3), f2 INT, pk INT, PRIMARY KEY (pk)) ENGINE=Aria; +INSERT INTO t1 VALUES ('foo',10,1), ('foo',1,2); +LOCK TABLE t1 WRITE; +--error ER_DUP_ENTRY +ALTER TABLE t1 ADD UNIQUE KEY (f1); +ALTER TABLE t1 ADD KEY (f2); +DROP TABLE t1; diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index 4fe51a2189e..10fcbd56e18 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -302,7 +302,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt, const char *operator_name, thr_lock_type lock_type, - bool open_for_modify, + bool org_open_for_modify, bool repair_table_use_frm, uint extra_open_options, int (*prepare_func)(THD *, TABLE_LIST *, @@ -359,10 +359,10 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, for (table= tables; table; table= table->next_local) { char table_name[SAFE_NAME_LEN*2+2]; - char* db = table->db; + char *db= table->db; bool fatal_error=0; bool open_error; - + bool open_for_modify= org_open_for_modify; DBUG_PRINT("admin", ("table: '%s'.'%s'", table->db, table->table_name)); strxmov(table_name, db, ".", table->table_name, NullS); thd->open_options|= extra_open_options; @@ -395,8 +395,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, /* CHECK TABLE command is allowed for views as well. Check on alter flags - to differentiate from ALTER TABLE...CHECK PARTITION on which view is not - allowed. + to differentiate from ALTER TABLE...CHECK PARTITION on which view is + not allowed. */ if (lex->alter_info.flags & Alter_info::ALTER_ADMIN_PARTITION || view_operator_func == NULL) @@ -1053,7 +1053,7 @@ send_result_message: } } /* Error path, a admin command failed. */ - if (thd->transaction_rollback_request) + if (thd->transaction_rollback_request || fatal_error) { /* Unlikely, but transaction rollback was requested by one of storage diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 5fc7c20d409..52ce42e2e6a 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -155,10 +155,11 @@ static void mysql_ha_close_table(SQL_HANDLER *handler) { THD *thd= handler->thd; TABLE *table= handler->table; + DBUG_ENTER("mysql_ha_close_table"); /* check if table was already closed */ if (!table) - return; + DBUG_VOID_RETURN; if (!table->s->tmp_table) { @@ -184,6 +185,7 @@ static void mysql_ha_close_table(SQL_HANDLER *handler) } my_free(handler->lock); handler->init(); + DBUG_VOID_RETURN; } /* diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index dbd4a3331df..e56cc943390 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -37,6 +37,7 @@ C_MODE_START #include "ma_checkpoint.h" #include "ma_recovery.h" C_MODE_END +#include "ma_trnman.h" //#include "sql_priv.h" #include "protocol.h" @@ -1384,7 +1385,8 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt) } /* Reset trn, that may have been set by repair */ - _ma_set_trn_for_table(file, old_trn); + if (old_trn && old_trn != file->trn) + _ma_set_trn_for_table(file, old_trn); thd_proc_info(thd, old_proc_info); thd_progress_end(thd); return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK; @@ -1518,7 +1520,8 @@ int ha_maria::zerofill(THD * thd, HA_CHECK_OPT *check_opt) error=maria_zerofill(param, file, share->open_file_name.str); /* Reset trn, that may have been set by repair */ - _ma_set_trn_for_table(file, old_trn); + if (old_trn && old_trn != file->trn) + _ma_set_trn_for_table(file, old_trn); if (!error) { @@ -1758,7 +1761,8 @@ int ha_maria::repair(THD *thd, HA_CHECK *param, bool do_optimize) maria_lock_database(file, F_UNLCK); /* Reset trn, that may have been set by repair */ - _ma_set_trn_for_table(file, old_trn); + if (old_trn && old_trn != file->trn) + _ma_set_trn_for_table(file, old_trn); error= error ? HA_ADMIN_FAILED : (optimize_done ? (write_log_record_for_repair(param, file) ? HA_ADMIN_FAILED : @@ -2579,9 +2583,12 @@ int ha_maria::extra(enum ha_extra_function operation) without calling commit/rollback in between. If file->trn is not set we can't remove file->share from the transaction list in the extra() call. - We also ensure that we set file->trn to 0 if THD_TRN is 0 as in - this case we have already freed the trn. This can happen when one - implicit_commit() is called as part of alter table. + In current code we don't have to do this for HA_EXTRA_PREPARE_FOR_RENAME + as this is only used the intermediate table used by ALTER TABLE which + is not part of the transaction (it's not in the TRN list). Better to + keep this for now, to not break anything in a stable release. + When HA_EXTRA_PREPARE_FOR_RENAME is not handled below, we can change + the warnings in _ma_remove_table_from_trnman() to asserts. table->in_use is not set in the case this is a done as part of closefrm() as part of drop table. @@ -2594,7 +2601,7 @@ int ha_maria::extra(enum ha_extra_function operation) { THD *thd= table->in_use; TRN *trn= THD_TRN; - _ma_set_trn_for_table(file, trn); + _ma_set_tmp_trn_for_table(file, trn); } DBUG_ASSERT(file->s->base.born_transactional || file->trn == 0 || file->trn == &dummy_transaction_object); @@ -2710,6 +2717,7 @@ int ha_maria::external_lock(THD *thd, int lock_type) if (file->trn) { /* This can only happen with tables created with clone() */ + DBUG_PRINT("info",("file->trn: %p", file->trn)); trnman_increment_locked_tables(file->trn); } @@ -2730,7 +2738,7 @@ int ha_maria::external_lock(THD *thd, int lock_type) } else { - TRN *trn= THD_TRN; + TRN *trn= (file->trn != &dummy_transaction_object ? file->trn : 0); /* End of transaction */ /* @@ -2745,8 +2753,7 @@ int ha_maria::external_lock(THD *thd, int lock_type) */ if (_ma_reenable_logging_for_table(file, TRUE)) DBUG_RETURN(1); - /** @todo zero file->trn also in commit and rollback */ - _ma_set_trn_for_table(file, NULL); // Safety + _ma_reset_trn_for_table(file); /* Ensure that file->state points to the current number of rows. This is needed if someone calls maria_info() without first doing an @@ -2802,13 +2809,6 @@ int ha_maria::start_stmt(THD *thd, thr_lock_type lock_type) DBUG_ASSERT(lock_type != TL_UNLOCK); DBUG_ASSERT(file->trn == trn); - /* - If there was an implicit commit under this LOCK TABLES by a previous - statement (like a DDL), at least if that previous statement was about a - different ha_maria than 'this' then this->file->trn is a stale - pointer. We fix it: - */ - _ma_set_trn_for_table(file, trn); /* As external_lock() was already called, don't increment locked_tables. Note that we call the function below possibly several times when @@ -2833,6 +2833,23 @@ int ha_maria::start_stmt(THD *thd, thr_lock_type lock_type) } +/* + Reset THD_TRN and all file->trn related to the transaction + This is needed as some calls, like extra() or external_lock() may access + it before next transaction is started +*/ + +static void reset_thd_trn(THD *thd, MARIA_HA *first_table) +{ + DBUG_ENTER("reset_thd_trn"); + THD_TRN= NULL; + for (MARIA_HA *table= first_table; table ; + table= table->trn_next) + _ma_reset_trn_for_table(table); + DBUG_VOID_RETURN; +} + + /** Performs an implicit commit of the Maria transaction and creates a new one. @@ -2856,9 +2873,9 @@ int ha_maria::implicit_commit(THD *thd, bool new_trn) TRN *trn; int error; uint locked_tables; - DYNAMIC_ARRAY used_tables; - + MARIA_HA *used_tables, *trn_next; DBUG_ENTER("ha_maria::implicit_commit"); + if (!maria_hton || !(trn= THD_TRN)) DBUG_RETURN(0); if (!new_trn && (thd->locked_tables_mode == LTM_LOCK_TABLES || @@ -2876,48 +2893,16 @@ int ha_maria::implicit_commit(THD *thd, bool new_trn) locked_tables= trnman_has_locked_tables(trn); - if (new_trn && trn && trn->used_tables) - { - MARIA_USED_TABLES *tables; - /* - Save locked tables so that we can move them to another transaction - We are using a dynamic array as locked_tables in some cases can be - smaller than the used_tables list (for example when the server does - early unlock of tables. - */ - - my_init_dynamic_array2(&used_tables, sizeof(MARIA_SHARE*), (void*) 0, - locked_tables, 8, MYF(MY_THREAD_SPECIFIC)); - for (tables= (MARIA_USED_TABLES*) trn->used_tables; - tables; - tables= tables->next) - { - if (tables->share->base.born_transactional) - { - if (insert_dynamic(&used_tables, (uchar*) &tables->share)) - { - error= HA_ERR_OUT_OF_MEM; - goto end_and_free; - } - } - } - } - else - bzero(&used_tables, sizeof(used_tables)); - + used_tables= (MARIA_HA*) trn->used_instances; error= 0; if (unlikely(ma_commit(trn))) error= 1; if (!new_trn) { - /* - To be extra safe, we should also reset file->trn for all open - tables as some calls, like extra() may access it. We take care - of this in extra() by resetting file->trn if THD_TRN is 0. - */ - THD_TRN= NULL; + reset_thd_trn(thd, used_tables); goto end; } + /* We need to create a new transaction and put it in THD_TRN. Indeed, tables may be under LOCK TABLES, and so they will start the next @@ -2927,8 +2912,9 @@ int ha_maria::implicit_commit(THD *thd, bool new_trn) THD_TRN= trn; if (unlikely(trn == NULL)) { + reset_thd_trn(thd, used_tables); error= HA_ERR_OUT_OF_MEM; - goto end_and_free; + goto end; } /* Move all locked tables to the new transaction @@ -2938,35 +2924,25 @@ int ha_maria::implicit_commit(THD *thd, bool new_trn) in check table, we use the table without calling start_stmt(). */ - uint i; - for (i= 0 ; i < used_tables.elements ; i++) + for (MARIA_HA *handler= used_tables; handler ; + handler= trn_next) { - MARIA_SHARE *share; - LIST *handlers; + trn_next= handler->trn_next; + DBUG_ASSERT(handler->s->base.born_transactional); - share= *(dynamic_element(&used_tables, i, MARIA_SHARE**)); - /* Find table instances that was used in this transaction */ - for (handlers= share->open_list; handlers; handlers= handlers->next) + /* If handler uses versioning */ + if (handler->s->lock_key_trees) { - MARIA_HA *handler= (MARIA_HA*) handlers->data; - if (handler->external_ref && - ((TABLE*) handler->external_ref)->in_use == thd) - { - _ma_set_trn_for_table(handler, trn); - /* If handler uses versioning */ - if (handler->s->lock_key_trees) - { - if (_ma_setup_live_state(handler)) - error= HA_ERR_OUT_OF_MEM; - } - } + /* _ma_set_trn_for_table() will be called indirectly */ + if (_ma_setup_live_state(handler)) + error= HA_ERR_OUT_OF_MEM; } + else + _ma_set_trn_for_table(handler, trn); } /* This is just a commit, tables stay locked if they were: */ trnman_reset_locked_tables(trn, locked_tables); -end_and_free: - delete_dynamic(&used_tables); end: DBUG_RETURN(error); } @@ -3340,10 +3316,10 @@ static int maria_commit(handlerton *hton __attribute__ ((unused)), trnman_set_flags(trn, trnman_get_flags(trn) & ~TRN_STATE_INFO_LOGGED); /* statement or transaction ? */ - if ((thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) && !all) + if ((thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) && + !all) DBUG_RETURN(0); // end of statement - DBUG_PRINT("info", ("THD_TRN set to 0x0")); - THD_TRN= 0; + reset_thd_trn(thd, (MARIA_HA*) trn->used_instances); DBUG_RETURN(ma_commit(trn)); // end of transaction } @@ -3360,8 +3336,7 @@ static int maria_rollback(handlerton *hton __attribute__ ((unused)), trnman_rollback_statement(trn); DBUG_RETURN(0); // end of statement } - DBUG_PRINT("info", ("THD_TRN set to 0x0")); - THD_TRN= 0; + reset_thd_trn(thd, (MARIA_HA*) trn->used_instances); DBUG_RETURN(trnman_rollback_trn(trn) ? HA_ERR_OUT_OF_MEM : 0); // end of transaction } diff --git a/storage/maria/ha_maria.h b/storage/maria/ha_maria.h index 2b99c31ec5d..16adc0c19a2 100644 --- a/storage/maria/ha_maria.h +++ b/storage/maria/ha_maria.h @@ -193,6 +193,7 @@ public: private: DsMrr_impl ds_mrr; friend ICP_RESULT index_cond_func_maria(void *arg); + friend void reset_thd_trn(THD *thd); }; #endif /* HA_MARIA_INCLUDED */ diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c index 9c92f8b63e5..ac46ac95101 100644 --- a/storage/maria/ma_blockrec.c +++ b/storage/maria/ma_blockrec.c @@ -271,6 +271,7 @@ #include "maria_def.h" #include "ma_blockrec.h" #include "trnman.h" +#include "ma_trnman.h" #include "ma_key_recover.h" #include "ma_recovery_util.h" #include @@ -7488,7 +7489,7 @@ void maria_ignore_trids(MARIA_HA *info) if (info->s->base.born_transactional) { if (!info->trn) - _ma_set_trn_for_table(info, &dummy_transaction_object); + _ma_set_tmp_trn_for_table(info, &dummy_transaction_object); /* Ignore transaction id when row is read */ info->trn->min_read_from= ~(TrID) 0; } diff --git a/storage/maria/ma_close.c b/storage/maria/ma_close.c index 4532b029126..75a996313e3 100644 --- a/storage/maria/ma_close.c +++ b/storage/maria/ma_close.c @@ -36,6 +36,8 @@ int maria_close(register MARIA_HA *info) /* Check that we have unlocked key delete-links properly */ DBUG_ASSERT(info->key_del_used == 0); + /* Check that file is not part of any uncommited transactions */ + DBUG_ASSERT(info->trn == 0 || info->trn == &dummy_transaction_object); if (share->reopen == 1) { diff --git a/storage/maria/ma_commit.c b/storage/maria/ma_commit.c index 46db3ca4ae5..7ad5e23e5f7 100644 --- a/storage/maria/ma_commit.c +++ b/storage/maria/ma_commit.c @@ -15,6 +15,7 @@ #include "maria_def.h" #include "trnman.h" +#include "ma_trnman.h" /** writes a COMMIT record to log and commits transaction in memory @@ -43,9 +44,9 @@ int ma_commit(TRN *trn) COMMIT record) and this is not an issue as * transaction's updates were not made visible to other transactions * "commit ok" was not sent to client - Alternatively, Recovery might commit trn (if MY_MIN(rec_lsn) is before COMMIT - record), which is ok too. All in all it means that "trn committed" is not - 100% equal to "COMMIT record written". + Alternatively, Recovery might commit trn (if MY_MIN(rec_lsn) is before + COMMIT record), which is ok too. All in all it means that "trn committed" + is not 100% equal to "COMMIT record written". - if COMMIT record is written after trnman_commit_trn(): if crash happens between the two, trn will be rolled back which is an issue (transaction's updates were made visible to other transactions). @@ -93,7 +94,12 @@ int ma_commit(TRN *trn) int maria_commit(MARIA_HA *info) { - return info->s->now_transactional ? ma_commit(info->trn) : 0; + TRN *trn; + if (!info->s->now_transactional) + return 0; + trn= info->trn; + info->trn= 0; /* checked in maria_close() */ + return ma_commit(trn); } @@ -120,10 +126,7 @@ int maria_begin(MARIA_HA *info) TRN *trn= trnman_new_trn(0); if (unlikely(!trn)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); - - DBUG_PRINT("info", ("TRN set to 0x%lx", (ulong) trn)); _ma_set_trn_for_table(info, trn); } DBUG_RETURN(0); } - diff --git a/storage/maria/ma_extra.c b/storage/maria/ma_extra.c index d2e81184630..dc04e8aacde 100644 --- a/storage/maria/ma_extra.c +++ b/storage/maria/ma_extra.c @@ -345,7 +345,7 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function, _ma_decrement_open_count(info, 0); if (info->trn) { - _ma_remove_table_from_trnman(share, info->trn); + _ma_remove_table_from_trnman(info); /* Ensure we don't point to the deleted data in trn */ info->state= info->state_start= &share->state.state; } @@ -408,7 +408,7 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function, if (info->trn) { mysql_mutex_lock(&share->intern_lock); - _ma_remove_table_from_trnman(share, info->trn); + _ma_remove_table_from_trnman(info); /* Ensure we don't point to the deleted data in trn */ info->state= info->state_start= &share->state.state; mysql_mutex_unlock(&share->intern_lock); diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c index 1db85180fcf..8fda846172b 100644 --- a/storage/maria/ma_open.c +++ b/storage/maria/ma_open.c @@ -19,6 +19,8 @@ #include "ma_sp_defs.h" #include "ma_rt_index.h" #include "ma_blockrec.h" +#include "trnman.h" +#include "ma_trnman.h" #include #if defined(MSDOS) || defined(__WIN__) @@ -183,7 +185,7 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, if (!share->base.born_transactional) /* For transactional ones ... */ { /* ... force crash if no trn given */ - _ma_set_trn_for_table(&info, &dummy_transaction_object); + _ma_set_tmp_trn_for_table(&info, &dummy_transaction_object); info.state= &share->state.state; /* Change global values by default */ } else diff --git a/storage/maria/ma_state.c b/storage/maria/ma_state.c index 1b5a55cc91d..d3fa5acf198 100644 --- a/storage/maria/ma_state.c +++ b/storage/maria/ma_state.c @@ -66,7 +66,7 @@ my_bool _ma_setup_live_state(MARIA_HA *info) DBUG_RETURN(1); trn= info->trn; - for (tables= (MARIA_USED_TABLES*) info->trn->used_tables; + for (tables= (MARIA_USED_TABLES*) trn->used_tables; tables; tables= tables->next) { @@ -551,6 +551,7 @@ my_bool _ma_trnman_end_trans_hook(TRN *trn, my_bool commit, my_free(tables); } trn->used_tables= 0; + trn->used_instances= 0; DBUG_RETURN(error); } @@ -565,18 +566,25 @@ my_bool _ma_trnman_end_trans_hook(TRN *trn, my_bool commit, share->internal_lock must be locked when function is called */ -void _ma_remove_table_from_trnman(MARIA_SHARE *share, TRN *trn) +void _ma_remove_table_from_trnman(MARIA_HA *info) { + MARIA_SHARE *share= info->s; + TRN *trn= info->trn; MARIA_USED_TABLES *tables, **prev; + MARIA_HA *handler, **prev_file; DBUG_ENTER("_ma_remove_table_from_trnman"); DBUG_PRINT("enter", ("trn: %p used_tables: %p share: %p in_trans: %d", trn, trn->used_tables, share, share->in_trans)); mysql_mutex_assert_owner(&share->intern_lock); + + if (trn == &dummy_transaction_object) + DBUG_VOID_RETURN; - for (prev= (MARIA_USED_TABLES**) (char*) &trn->used_tables, tables= *prev; - tables; - tables= *prev) + /* First remove share from used_tables */ + for (prev= (MARIA_USED_TABLES**) (char*) &trn->used_tables; + (tables= *prev); + prev= &tables->next) { if (tables->share == share) { @@ -585,8 +593,36 @@ void _ma_remove_table_from_trnman(MARIA_SHARE *share, TRN *trn) my_free(tables); break; } - prev= &tables->next; } + if (tables != 0) + { + /* + This can only happens in case of rename of intermediate table as + part of alter table + */ + DBUG_PRINT("warning", ("share: %p where not in used_tables_list", share)); + } + + /* unlink table from used_instances */ + for (prev_file= (MARIA_HA**) &trn->used_instances; + (handler= *prev_file); + prev_file= &handler->trn_next) + { + if (handler == info) + { + *prev_file= info->trn_next; + break; + } + } + if (handler != 0) + { + /* + This can only happens in case of rename of intermediate table as + part of alter table + */ + DBUG_PRINT("warning", ("table: %p where not in used_instances", info)); + } + info->trn= 0; /* Not part of trans anymore */ DBUG_VOID_RETURN; } diff --git a/storage/maria/ma_state.h b/storage/maria/ma_state.h index d662b9899f8..d47595ee08d 100644 --- a/storage/maria/ma_state.h +++ b/storage/maria/ma_state.h @@ -84,5 +84,5 @@ my_bool _ma_row_visible_non_transactional_table(MARIA_HA *info); my_bool _ma_row_visible_transactional_table(MARIA_HA *info); void _ma_remove_not_visible_states_with_lock(struct st_maria_share *share, my_bool all); -void _ma_remove_table_from_trnman(struct st_maria_share *share, TRN *trn); +void _ma_remove_table_from_trnman(MARIA_HA *info); void _ma_reset_history(struct st_maria_share *share); diff --git a/storage/maria/ma_trnman.h b/storage/maria/ma_trnman.h new file mode 100644 index 00000000000..9bfd1f0d047 --- /dev/null +++ b/storage/maria/ma_trnman.h @@ -0,0 +1,65 @@ +/* Copyright (C) 2006-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. + + 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 Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef _ma_trnman_h +#define _ma_trnman_h + +/** + Sets table's trn and prints debug information + Links table into used_instances if new_trn is not 0 + + @param tbl MARIA_HA of table + @param newtrn what to put into tbl->trn +*/ + +static inline void _ma_set_trn_for_table(MARIA_HA *tbl, TRN *newtrn) +{ + DBUG_PRINT("info",("table: %p trn: %p -> %p", + tbl, tbl->trn, newtrn)); + + /* check that we are not calling this twice in a row */ + DBUG_ASSERT(newtrn->used_instances != (void*) tbl); + + tbl->trn= newtrn; + /* Link into used list */ + tbl->trn_next= (MARIA_HA*) newtrn->used_instances; + newtrn->used_instances= tbl; +} + + +/* + Same as _ma_set_trn_for_table(), but don't link table into used_instance list + Used when we want to temporary set trn for a table in extra() +*/ + +static inline void _ma_set_tmp_trn_for_table(MARIA_HA *tbl, TRN *newtrn) +{ + DBUG_PRINT("info",("table: %p trn: %p -> %p", + tbl, tbl->trn, newtrn)); + tbl->trn= newtrn; +} + + +/* + Reset TRN in table +*/ + +static inline void _ma_reset_trn_for_table(MARIA_HA *tbl) +{ + DBUG_PRINT("info",("table: %p trn: %p -> NULL", tbl, tbl->trn)); + tbl->trn= 0; +} + +#endif /* _ma_trnman_h */ diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h index e4fd80d1151..bbf29d8b21a 100644 --- a/storage/maria/maria_def.h +++ b/storage/maria/maria_def.h @@ -576,6 +576,7 @@ struct st_maria_handler { MARIA_SHARE *s; /* Shared between open:s */ struct st_ma_transaction *trn; /* Pointer to active transaction */ + struct st_maria_handler *trn_next; MARIA_STATUS_INFO *state, state_save; MARIA_STATUS_INFO *state_start; /* State at start of transaction */ MARIA_USED_TABLES *used_tables; @@ -824,19 +825,6 @@ struct st_maria_handler #define get_pack_length(length) ((length) >= 255 ? 3 : 1) #define _ma_have_versioning(info) ((info)->row_flag & ROW_FLAG_TRANSID) -/** - Sets table's trn and prints debug information - @param tbl MARIA_HA of table - @param newtrn what to put into tbl->trn - @note cast of newtrn is because %p of NULL gives warning (NULL is int) -*/ -#define _ma_set_trn_for_table(tbl, newtrn) do { \ - DBUG_PRINT("info",("table: %p trn: %p -> %p", \ - (tbl), (tbl)->trn, (void *)(newtrn))); \ - (tbl)->trn= (newtrn); \ - } while (0) - - #define MARIA_MIN_BLOCK_LENGTH 20 /* Because of delete-link */ /* Don't use to small record-blocks */ #define MARIA_EXTEND_BLOCK_LENGTH 20 diff --git a/storage/maria/trnman.c b/storage/maria/trnman.c index daccf3550c2..1ad655b8a22 100644 --- a/storage/maria/trnman.c +++ b/storage/maria/trnman.c @@ -366,6 +366,7 @@ TRN *trnman_new_trn(WT_THD *wt) trn->commit_trid= MAX_TRID; trn->rec_lsn= trn->undo_lsn= trn->first_undo_lsn= 0; trn->used_tables= 0; + trn->used_instances= 0; trn->locked_tables= 0; trn->flags= 0; diff --git a/storage/maria/trnman.h b/storage/maria/trnman.h index 77e2916390a..057d9396473 100644 --- a/storage/maria/trnman.h +++ b/storage/maria/trnman.h @@ -46,7 +46,8 @@ struct st_ma_transaction LF_PINS *pins; WT_THD *wt; mysql_mutex_t state_lock; - void *used_tables; /**< Tables used by transaction */ + void *used_tables; /**< Table shares used by transaction */ + void *used_instances; /* table files used by transaction */ TRN *next, *prev; TrID trid, min_read_from, commit_trid; LSN rec_lsn, undo_lsn; -- cgit v1.2.1 From da71c1bad79ee11009b3b28a2a745709e04020cf Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 22 May 2018 14:36:06 +0300 Subject: MDEV-16229 Replication aborts with ER_VIEW_SELECT_TMPTABLE after half-failed RENAME Problem was that detection of temporary tables was all wrong for RENAME TABLE. (Temporary tables where opened by top level call to open_temporary_tables(), which can't detect if a temporary table was renamed to something and then reused). Fixed by adding proper parsing of rename list to check against the current name of a table at each rename stage. Also change do_rename_temporary() to check against the current state of temporary tables, not according to the state of start of RENAME TABLE. --- mysql-test/r/grant2.result | 3 +- mysql-test/r/rename.result | 66 ++++++++++++++++++++++++++++++++++++ mysql-test/suite/rpl/r/rename.result | 34 +++++++++++++++++++ mysql-test/suite/rpl/t/rename.test | 33 ++++++++++++++++++ mysql-test/t/grant2.test | 3 +- mysql-test/t/rename.test | 46 +++++++++++++++++++++++++ sql/sql_parse.cc | 65 +++++++++++++++++++++++++++++++++-- sql/sql_rename.cc | 2 +- 8 files changed, 245 insertions(+), 7 deletions(-) create mode 100644 mysql-test/suite/rpl/r/rename.result create mode 100644 mysql-test/suite/rpl/t/rename.test diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index 9e9b3ffc4e5..70292240d84 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -705,10 +705,9 @@ LOAD INDEX INTO CACHE t3; Table Op Msg_type Msg_text mysqltest_db1.t3 preload_keys status OK # -# RENAME (doesn't work for temporary tables, thus should fail). +# RENAME should work for temporary tables # RENAME TABLE t3 TO t3_1; -ERROR 42000: INSERT, CREATE command denied to user 'mysqltest_u1'@'localhost' for table 't3_1' # # HANDLER OPEN/READ/CLOSE. # diff --git a/mysql-test/r/rename.result b/mysql-test/r/rename.result index 74370ba74dd..c90aaf24e9b 100644 --- a/mysql-test/r/rename.result +++ b/mysql-test/r/rename.result @@ -67,3 +67,69 @@ ERROR HY000: 'test.v1' is not BASE TABLE drop view v1; drop table t1; End of 5.0 tests +CREATE OR REPLACE TABLE t1 (a INT); +CREATE OR REPLACE TABLE t2 (a INT); +CREATE OR REPLACE TEMPORARY TABLE t1_tmp (b INT); +CREATE OR REPLACE TEMPORARY TABLE t2_tmp (b INT); +rename table t1 to t2; +ERROR 42S01: Table 't2' already exists +rename table t1 to tmp, tmp to t2; +ERROR 42S01: Table 't2' already exists +rename table t1_tmp to t2_tmp; +ERROR 42S01: Table 't2_tmp' already exists +rename table t1_tmp to tmp, tmp to t2_tmp; +ERROR 42S01: Table 't2_tmp' already exists +show create table t1_tmp; +Table Create Table +t1_tmp CREATE TEMPORARY TABLE `t1_tmp` ( + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +show create table t2_tmp; +Table Create Table +t2_tmp CREATE TEMPORARY TABLE `t2_tmp` ( + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +rename table t1 to t1_tmp; +rename table t2_tmp to t2; +rename table t2 to tmp, tmp to t2; +rename table t1_tmp to tmp, tmp to t1_tmp; +show tables; +Tables_in_test +t1_tmp +t2 +SHOW CREATE TABLE t1_tmp; +Table Create Table +t1_tmp CREATE TEMPORARY TABLE `t1_tmp` ( + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1_tmp; +SHOW CREATE TABLE t1_tmp; +Table Create Table +t1_tmp CREATE TABLE `t1_tmp` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1_tmp; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TEMPORARY TABLE `t2` ( + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t2; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t2; +CREATE TABLE t1 (a INT); +insert into t1 values (1); +CREATE TEMPORARY TABLE t1 (b INT); +insert into t1 values (2); +RENAME TABLE t1 TO tmp, t1 TO t2; +select * from tmp; +b +2 +select * from t2; +a +1 +drop table tmp,t2; diff --git a/mysql-test/suite/rpl/r/rename.result b/mysql-test/suite/rpl/r/rename.result new file mode 100644 index 00000000000..5cedea51c86 --- /dev/null +++ b/mysql-test/suite/rpl/r/rename.result @@ -0,0 +1,34 @@ +include/master-slave.inc +[connection master] +# +# MDEV-16229 Replication aborts with ER_VIEW_SELECT_TMPTABLE after +# half-failed RENAME +# +CREATE TABLE t1 (a INT); +CREATE TEMPORARY TABLE t1 (b INT); +RENAME TABLE t1 TO tmp, tmp TO t1; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TEMPORARY TABLE `t1` ( + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +CREATE VIEW v AS SELECT * FROM t1; +ERROR HY000: View's SELECT refers to a temporary table 't1' +RENAME TABLE t1 TO tmp, t1 TO t2; +SHOW CREATE TABLE tmp; +Table Create Table +tmp CREATE TEMPORARY TABLE `tmp` ( + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +CREATE VIEW v AS SELECT * FROM tmp; +ERROR HY000: View's SELECT refers to a temporary table 'tmp' +CREATE VIEW v AS SELECT * FROM t2; +DROP VIEW v; +DROP TABLE tmp; +DROP TABLE t2; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rename.test b/mysql-test/suite/rpl/t/rename.test new file mode 100644 index 00000000000..ac499157918 --- /dev/null +++ b/mysql-test/suite/rpl/t/rename.test @@ -0,0 +1,33 @@ +--source include/have_binlog_format_mixed.inc +--source include/master-slave.inc + +--echo # +--echo # MDEV-16229 Replication aborts with ER_VIEW_SELECT_TMPTABLE after +--echo # half-failed RENAME +--echo # + +CREATE TABLE t1 (a INT); +CREATE TEMPORARY TABLE t1 (b INT); +RENAME TABLE t1 TO tmp, tmp TO t1; +SHOW CREATE TABLE t1; +--error ER_VIEW_SELECT_TMPTABLE +CREATE VIEW v AS SELECT * FROM t1; + +RENAME TABLE t1 TO tmp, t1 TO t2; +SHOW CREATE TABLE tmp; +SHOW CREATE TABLE t2; +--error ER_VIEW_SELECT_TMPTABLE +CREATE VIEW v AS SELECT * FROM tmp; +CREATE VIEW v AS SELECT * FROM t2; + +--sync_slave_with_master + +# Cleanup + +--connection master + +DROP VIEW v; +DROP TABLE tmp; +DROP TABLE t2; + +--source include/rpl_end.inc diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test index 8590dccd1d1..55eb21ed6f7 100644 --- a/mysql-test/t/grant2.test +++ b/mysql-test/t/grant2.test @@ -873,9 +873,8 @@ CACHE INDEX t3 IN keycache1; LOAD INDEX INTO CACHE t3; --echo # ---echo # RENAME (doesn't work for temporary tables, thus should fail). +--echo # RENAME should work for temporary tables --echo # ---error ER_TABLEACCESS_DENIED_ERROR RENAME TABLE t3 TO t3_1; --echo # diff --git a/mysql-test/t/rename.test b/mysql-test/t/rename.test index a55bc845acc..67732d5b5b9 100644 --- a/mysql-test/t/rename.test +++ b/mysql-test/t/rename.test @@ -95,3 +95,49 @@ drop table t1; --source include/wait_until_count_sessions.inc +# +# Test of rename with temporary tables +# + +CREATE OR REPLACE TABLE t1 (a INT); +CREATE OR REPLACE TABLE t2 (a INT); +CREATE OR REPLACE TEMPORARY TABLE t1_tmp (b INT); +CREATE OR REPLACE TEMPORARY TABLE t2_tmp (b INT); + +# Can't rename table over another one +--error ER_TABLE_EXISTS_ERROR +rename table t1 to t2; +--error ER_TABLE_EXISTS_ERROR +rename table t1 to tmp, tmp to t2; +--error ER_TABLE_EXISTS_ERROR +rename table t1_tmp to t2_tmp; +--error ER_TABLE_EXISTS_ERROR +rename table t1_tmp to tmp, tmp to t2_tmp; + +show create table t1_tmp; +show create table t2_tmp; + +# The following should work +rename table t1 to t1_tmp; +rename table t2_tmp to t2; +rename table t2 to tmp, tmp to t2; +rename table t1_tmp to tmp, tmp to t1_tmp; +show tables; +SHOW CREATE TABLE t1_tmp; +drop table t1_tmp; +SHOW CREATE TABLE t1_tmp; +drop table t1_tmp; +SHOW CREATE TABLE t2; +drop table t2; +SHOW CREATE TABLE t2; +drop table t2; + +CREATE TABLE t1 (a INT); +insert into t1 values (1); +CREATE TEMPORARY TABLE t1 (b INT); +insert into t1 values (2); +RENAME TABLE t1 TO tmp, t1 TO t2; +select * from tmp; +select * from t2; +drop table tmp,t2; + diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1162aa901d1..28d11ef2e5c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -495,6 +495,8 @@ void init_update_queries(void) There are other statements that deal with temporary tables and open them, but which are not listed here. The thing is that the order of pre-opening temporary tables for those statements is somewhat custom. + + Note that SQLCOM_RENAME_TABLE should not be in this list! */ sql_command_flags[SQLCOM_CREATE_TABLE]|= CF_PREOPEN_TMP_TABLES; sql_command_flags[SQLCOM_DROP_TABLE]|= CF_PREOPEN_TMP_TABLES; @@ -508,7 +510,6 @@ void init_update_queries(void) sql_command_flags[SQLCOM_INSERT_SELECT]|= CF_PREOPEN_TMP_TABLES; sql_command_flags[SQLCOM_DELETE]|= CF_PREOPEN_TMP_TABLES; sql_command_flags[SQLCOM_DELETE_MULTI]|= CF_PREOPEN_TMP_TABLES; - sql_command_flags[SQLCOM_RENAME_TABLE]|= CF_PREOPEN_TMP_TABLES; sql_command_flags[SQLCOM_REPLACE_SELECT]|= CF_PREOPEN_TMP_TABLES; sql_command_flags[SQLCOM_SELECT]|= CF_PREOPEN_TMP_TABLES; sql_command_flags[SQLCOM_SET_OPTION]|= CF_PREOPEN_TMP_TABLES; @@ -5333,6 +5334,60 @@ static bool execute_show_status(THD *thd, TABLE_LIST *all_tables) } +/* + Find out if a table is a temporary table + + A table is a temporary table if it's a temporary table or + there has been before a temporary table that has been renamed + to the current name. + + Some examples: + A->B B is a temporary table if and only if A is a temp. + A->B, B->C Second B is temp if A is temp + A->B, A->C Second A can't be temp as if A was temp then B is temp + and Second A can only be a normal table. C is also not temp +*/ + +static TABLE *find_temporary_table_for_rename(THD *thd, + TABLE_LIST *first_table, + TABLE_LIST *cur_table) +{ + TABLE_LIST *table; + TABLE *res= 0; + bool found= 0; + DBUG_ENTER("find_temporary_table_for_rename"); + + /* Find last instance when cur_table is in TO part */ + for (table= first_table; + table != cur_table; + table= table->next_local->next_local) + { + TABLE_LIST *next= table->next_local; + + if (!strcmp(table->get_db_name(), cur_table->get_db_name()) && + !strcmp(table->get_table_name(), cur_table->get_table_name())) + { + /* Table was moved away, can't be same as 'table' */ + found= 1; + res= 0; // Table can't be a temporary table + } + if (!strcmp(next->get_db_name(), cur_table->get_db_name()) && + !strcmp(next->get_table_name(), cur_table->get_table_name())) + { + /* + Table has matching name with new name of this table. cur_table should + have same temporary type as this table. + */ + found= 1; + res= table->table; + } + } + if (!found) + res= find_temporary_table(thd, table); + DBUG_RETURN(res); +} + + static bool execute_rename_table(THD *thd, TABLE_LIST *first_table, TABLE_LIST *all_tables) { @@ -5349,13 +5404,19 @@ static bool execute_rename_table(THD *thd, TABLE_LIST *first_table, &table->next_local->grant.m_internal, 0, 0)) return 1; + + /* check if these are refering to temporary tables */ + table->table= find_temporary_table_for_rename(thd, first_table, table); + table->next_local->table= table->table; + TABLE_LIST old_list, new_list; /* we do not need initialize old_list and new_list because we will - come table[0] and table->next[0] there + copy table[0] and table->next[0] there */ old_list= table[0]; new_list= table->next_local[0]; + if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, FALSE, 1, FALSE) || (!test_all_bits(table->next_local->grant.privilege, INSERT_ACL | CREATE_ACL) && diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 1a9cb842e6a..119f9063724 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -222,7 +222,7 @@ do_rename_temporary(THD *thd, TABLE_LIST *ren_table, TABLE_LIST *new_table, new_alias= (lower_case_table_names == 2) ? new_table->alias : new_table->table_name; - if (is_temporary_table(new_table)) + if (find_temporary_table(thd, new_table)) { my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias); DBUG_RETURN(1); // This can't be skipped -- cgit v1.2.1 From 908676dfd9d981fd0f37a7cf9332abac522f1936 Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 22 May 2018 23:05:01 +0300 Subject: MDEV-15308 Assertion `ha_alter_info->alter_info->drop_list.elements Problem was that handle_if_exists_options() didn't correct alter_info->flags when things was removed from the list. --- mysql-test/r/alter_table.result | 61 +++++++++++++++++++++++++++++++++++++++++ mysql-test/t/alter_table.test | 32 +++++++++++++++++++++ sql/sql_table.cc | 29 +++++++++++++++++--- 3 files changed, 118 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index e32037c4be9..bb78df907ad 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -2164,3 +2164,64 @@ t1 CREATE TABLE `t1` ( `b` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 DROP TABLE t1; +# +# +# MDEV-15308 +# Assertion `ha_alter_info->alter_info->drop_list.elements > 0' failed +# in ha_innodb::prepare_inplace_alter_table +# +CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB; +ALTER TABLE t1 DROP FOREIGN KEY IF EXISTS fk, DROP COLUMN b; +Warnings: +Note 1091 Can't DROP 'fk'; check that column/key exists +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB; +ALTER TABLE t1 DROP INDEX IF EXISTS fk, DROP COLUMN b; +Warnings: +Note 1091 Can't DROP 'fk'; check that column/key exists +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (a INT, b INT, c INT, KEY(c)) ENGINE=InnoDB; +ALTER TABLE t1 DROP FOREIGN KEY IF EXISTS fk, DROP COLUMN c; +Warnings: +Note 1091 Can't DROP 'fk'; check that column/key exists +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (a INT, b INT, c INT, KEY c1(c)) ENGINE=InnoDB; +ALTER TABLE t1 DROP FOREIGN KEY IF EXISTS fk, DROP INDEX c1; +Warnings: +Note 1091 Can't DROP 'fk'; check that column/key exists +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB; +ALTER TABLE t1 DROP INDEX IF EXISTS fk, DROP COLUMN IF EXISTS c; +Warnings: +Note 1091 Can't DROP 'fk'; check that column/key exists +Note 1091 Can't DROP 'c'; check that column/key exists +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t1; diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index 8fcc7d044e5..585a272de9b 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -1809,3 +1809,35 @@ SHOW CREATE TABLE t1; ALTER TABLE t1 CONVERT TO CHARACTER SET utf8; SHOW CREATE TABLE t1; DROP TABLE t1; + +--echo # +--echo # +--echo # MDEV-15308 +--echo # Assertion `ha_alter_info->alter_info->drop_list.elements > 0' failed +--echo # in ha_innodb::prepare_inplace_alter_table +--echo # + +CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB; +ALTER TABLE t1 DROP FOREIGN KEY IF EXISTS fk, DROP COLUMN b; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB; +ALTER TABLE t1 DROP INDEX IF EXISTS fk, DROP COLUMN b; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1 (a INT, b INT, c INT, KEY(c)) ENGINE=InnoDB; +ALTER TABLE t1 DROP FOREIGN KEY IF EXISTS fk, DROP COLUMN c; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1 (a INT, b INT, c INT, KEY c1(c)) ENGINE=InnoDB; +ALTER TABLE t1 DROP FOREIGN KEY IF EXISTS fk, DROP INDEX c1; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB; +ALTER TABLE t1 DROP INDEX IF EXISTS fk, DROP COLUMN IF EXISTS c; +SHOW CREATE TABLE t1; +DROP TABLE t1; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 27d579a6b19..376c1362cc7 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5808,10 +5808,28 @@ drop_create_field: List_iterator drop_it(alter_info->drop_list); Alter_drop *drop; bool remove_drop; + ulonglong left_flags= 0; while ((drop= drop_it++)) { + ulonglong cur_flag= 0; + switch (drop->type) { + case Alter_drop::COLUMN: + cur_flag= Alter_info::ALTER_DROP_COLUMN; + break; + case Alter_drop::FOREIGN_KEY: + cur_flag= Alter_info::DROP_FOREIGN_KEY; + break; + case Alter_drop::KEY: + cur_flag= Alter_info::ALTER_DROP_INDEX; + break; + default: + break; + } if (!drop->drop_if_exists) + { + left_flags|= cur_flag; continue; + } remove_drop= TRUE; if (drop->type == Alter_drop::COLUMN) { @@ -5887,12 +5905,15 @@ drop_create_field: ER_CANT_DROP_FIELD_OR_KEY, ER(ER_CANT_DROP_FIELD_OR_KEY), drop->name); drop_it.remove(); - if (alter_info->drop_list.is_empty()) - alter_info->flags&= ~(Alter_info::ALTER_DROP_COLUMN | - Alter_info::ALTER_DROP_INDEX | - Alter_info::DROP_FOREIGN_KEY); } + else + left_flags|= cur_flag; } + /* Reset state to what's left in drop list */ + alter_info->flags&= ~(Alter_info::ALTER_DROP_COLUMN | + Alter_info::ALTER_DROP_INDEX | + Alter_info::DROP_FOREIGN_KEY); + alter_info->flags|= left_flags; } /* ALTER TABLE ADD KEY IF NOT EXISTS */ -- cgit v1.2.1 From a816aa066e5c879a92819d694a93d245e6ec6e47 Mon Sep 17 00:00:00 2001 From: Monty Date: Wed, 23 May 2018 11:26:49 +0300 Subject: Fixed ASAN heap-use-after-free handler::ha_index_or_rnd_end MDEV-16123 ASAN heap-use-after-free handler::ha_index_or_rnd_end MDEV-13828 Segmentation fault on RENAME TABLE Problem was that destructor called methods for closed table. Fixed by removing code in destructor. --- mysql-test/r/statistics_close.result | 6 ++++++ mysql-test/t/statistics_close.test | 18 ++++++++++++++++++ sql/sql_statistics.cc | 3 ++- 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 mysql-test/r/statistics_close.result create mode 100644 mysql-test/t/statistics_close.test diff --git a/mysql-test/r/statistics_close.result b/mysql-test/r/statistics_close.result new file mode 100644 index 00000000000..348681c3311 --- /dev/null +++ b/mysql-test/r/statistics_close.result @@ -0,0 +1,6 @@ +CREATE TABLE t1 (i int); +RENAME TABLE t1 TO t2; +FLUSH TABLES; +DROP TABLE IF EXISTS t1, t2; +Warnings: +Note 1051 Unknown table 'test.t1' diff --git a/mysql-test/t/statistics_close.test b/mysql-test/t/statistics_close.test new file mode 100644 index 00000000000..de22a5a44fe --- /dev/null +++ b/mysql-test/t/statistics_close.test @@ -0,0 +1,18 @@ +# +# MDEV-16123 ASAN heap-use-after-free handler::ha_index_or_rnd_end +# MDEV-13828 Segmentation fault on RENAME TABLE +# + +CREATE TABLE t1 (i int); +--connect (con1,localhost,root,,test) +--send +RENAME TABLE t1 TO t2; +--connection default +FLUSH TABLES; +--connection con1 +--reap + +# Cleanup +--disconnect con1 +--connection default +DROP TABLE IF EXISTS t1, t2; diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index ce320e87a4f..471749ad346 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -1376,7 +1376,8 @@ public: ~Stat_table_write_iter() { - cleanup(); + /* Ensure that cleanup has been run */ + DBUG_ASSERT(rowid_buf == 0); } }; -- cgit v1.2.1 From 1ada4afb0a51f7283b6187a95019ec2cb80c8a0b Mon Sep 17 00:00:00 2001 From: Teodor Mircea Ionita Date: Sun, 29 Apr 2018 19:47:48 +0300 Subject: mtr: use process launch -- args to start mysqld in lldb gdb's "set args" equivalent for lldb would be "settings set target.run-args", however it doesn't play well with double dashed args (--). --- mysql-test/mysql-test-run.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index de1871cbf03..ba49d88a85f 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -6051,7 +6051,7 @@ sub lldb_arguments { $input = $input ? "< $input" : ""; # write init file for mysqld or client - mtr_tofile($lldb_init_file, "set args $str $input\n"); + mtr_tofile($lldb_init_file, "process launch --stop-at-entry -- $str $input\n"); print "\nTo start lldb for $type, type in another window:\n"; print "cd $glob_mysql_test_dir && lldb -s $lldb_init_file $$exe\n"; -- cgit v1.2.1 From a61724a3ca187f6eb44fc67948acb76a94efa783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 24 May 2018 11:38:34 +0300 Subject: MDEV-16267 Wrong INFORMATION_SCHEMA.INNODB_BUFFER_PAGE.TABLE_NAME i_s_innodb_buffer_page_fill(), i_s_innodb_buf_page_lru_fill(): Only invoke Field::set_notnull() if the index was found. --- storage/innobase/handler/i_s.cc | 28 +++++++++++++++++++--------- storage/xtradb/handler/i_s.cc | 28 +++++++++++++++++++--------- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 41f4114494d..f8aa3bd4637 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2017, 2018, MariaDB Corporation. 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 @@ -4955,9 +4955,11 @@ i_s_innodb_buffer_page_fill( mutex_enter(&dict_sys->mutex); - if (const dict_index_t* index = - dict_index_get_if_in_cache_low( - page_info->index_id)) { + const dict_index_t* index = + dict_index_get_if_in_cache_low( + page_info->index_id); + + if (index) { table_name_end = innobase_convert_name( table_name, sizeof(table_name), index->table_name, @@ -4980,7 +4982,10 @@ i_s_innodb_buffer_page_fill( OK(ret); - fields[IDX_BUFFER_PAGE_TABLE_NAME]->set_notnull(); + if (index) { + fields[IDX_BUFFER_PAGE_TABLE_NAME] + ->set_notnull(); + } } OK(fields[IDX_BUFFER_PAGE_NUM_RECS]->store( @@ -5657,9 +5662,11 @@ i_s_innodb_buf_page_lru_fill( mutex_enter(&dict_sys->mutex); - if (const dict_index_t* index = - dict_index_get_if_in_cache_low( - page_info->index_id)) { + const dict_index_t* index = + dict_index_get_if_in_cache_low( + page_info->index_id); + + if (index) { table_name_end = innobase_convert_name( table_name, sizeof(table_name), index->table_name, @@ -5682,7 +5689,10 @@ i_s_innodb_buf_page_lru_fill( OK(ret); - fields[IDX_BUF_LRU_PAGE_TABLE_NAME]->set_notnull(); + if (index) { + fields[IDX_BUF_LRU_PAGE_TABLE_NAME] + ->set_notnull(); + } } OK(fields[IDX_BUF_LRU_PAGE_NUM_RECS]->store( diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc index 011bc77dc3c..834bae399fb 100644 --- a/storage/xtradb/handler/i_s.cc +++ b/storage/xtradb/handler/i_s.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2017, 2018, MariaDB Corporation. 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 @@ -4943,9 +4943,11 @@ i_s_innodb_buffer_page_fill( mutex_enter(&dict_sys->mutex); - if (const dict_index_t* index = - dict_index_get_if_in_cache_low( - page_info->index_id)) { + const dict_index_t* index = + dict_index_get_if_in_cache_low( + page_info->index_id); + + if (index) { table_name_end = innobase_convert_name( table_name, sizeof(table_name), index->table_name, @@ -4968,7 +4970,10 @@ i_s_innodb_buffer_page_fill( OK(ret); - fields[IDX_BUFFER_PAGE_TABLE_NAME]->set_notnull(); + if (index) { + fields[IDX_BUFFER_PAGE_TABLE_NAME] + ->set_notnull(); + } } OK(fields[IDX_BUFFER_PAGE_NUM_RECS]->store( @@ -5642,9 +5647,11 @@ i_s_innodb_buf_page_lru_fill( mutex_enter(&dict_sys->mutex); - if (const dict_index_t* index = - dict_index_get_if_in_cache_low( - page_info->index_id)) { + const dict_index_t* index = + dict_index_get_if_in_cache_low( + page_info->index_id); + + if (index) { table_name_end = innobase_convert_name( table_name, sizeof(table_name), index->table_name, @@ -5667,7 +5674,10 @@ i_s_innodb_buf_page_lru_fill( OK(ret); - fields[IDX_BUF_LRU_PAGE_TABLE_NAME]->set_notnull(); + if (index) { + fields[IDX_BUF_LRU_PAGE_TABLE_NAME] + ->set_notnull(); + } } OK(fields[IDX_BUF_LRU_PAGE_NUM_RECS]->store( -- cgit v1.2.1 From 5fb2c586f225361deae0f04dc6f72a3f0d168ac2 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Sat, 2 Jun 2018 11:52:48 +0530 Subject: MDEV-16225: wrong resultset from query with semijoin=on For non-semi-join subquery optimization we do a cost based decision between Materialisation and IN -> EXIST transformation. The issue in this case is that for IN->EXIST transformation we run JOIN::reoptimize with the IN->EXISt conditions and we come up with a new query plan. But when we compare the cost with Materialization, we make the decision to chose Materialization so we need to restore the query plan for Materilization. The saving and restoring for keyuse array and join_tab keyuse is only done when we have atleast one element in the keyuse_array , we are now changing to do it even for 0 elements to main the generality. --- mysql-test/r/subselect_sj2_mat.result | 57 +++++++++++++++++++++++++++++++++++ mysql-test/t/subselect_sj2_mat.test | 42 ++++++++++++++++++++++++++ sql/sql_select.cc | 46 ++++++++++++---------------- 3 files changed, 119 insertions(+), 26 deletions(-) diff --git a/mysql-test/r/subselect_sj2_mat.result b/mysql-test/r/subselect_sj2_mat.result index 835742a3ff4..19aa3bd3f02 100644 --- a/mysql-test/r/subselect_sj2_mat.result +++ b/mysql-test/r/subselect_sj2_mat.result @@ -1601,3 +1601,60 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY eq_ref distinct_key distinct_key 11 func 1 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where DROP TABLE t1,t2; +# +# MDEV-16225: wrong resultset from query with semijoin=on +# +CREATE TABLE t1 ( +`id` int(10) NOT NULL AUTO_INCREMENT, +`local_name` varchar(64) NOT NULL, +PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=latin1; +insert into t1(`id`,`local_name`) values +(1,'Cash Advance'), +(2,'Cash Advance'), +(3,'Rollover'), +(4,'AL Installment'), +(5,'AL Installment'), +(6,'AL Installment'), +(7,'AL Installment'), +(8,'AL Installment'), +(9,'AL Installment'), +(10,'Internet Payday'), +(11,'Rollover - Internet Payday'), +(12,'AL Monthly Installment'), +(13,'AL Semi-Monthly Installment'); +explain +SELECT SQL_NO_CACHE t.id +FROM t1 t +WHERE ( +t.id IN (SELECT A.id FROM t1 AS A WHERE A.local_name IN (SELECT B.local_name FROM t1 AS B WHERE B.id IN (0,4,12,13,1,10,3,11))) +OR +(t.id IN (0,4,12,13,1,10,3,11)) +); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t index PRIMARY PRIMARY 4 NULL 13 Using where; Using index +2 MATERIALIZED ALL distinct_key NULL NULL NULL 8 +2 MATERIALIZED A ALL PRIMARY NULL NULL NULL 13 Using where; Using join buffer (flat, BNL join) +3 MATERIALIZED B ALL PRIMARY NULL NULL NULL 13 Using where +SELECT SQL_NO_CACHE t.id +FROM t1 t +WHERE ( +t.id IN (SELECT A.id FROM t1 AS A WHERE A.local_name IN (SELECT B.local_name FROM t1 AS B WHERE B.id IN (0,4,12,13,1,10,3,11))) +OR +(t.id IN (0,4,12,13,1,10,3,11)) +); +id +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +drop table t1; diff --git a/mysql-test/t/subselect_sj2_mat.test b/mysql-test/t/subselect_sj2_mat.test index cfb6c8c2819..0665cdf68fe 100644 --- a/mysql-test/t/subselect_sj2_mat.test +++ b/mysql-test/t/subselect_sj2_mat.test @@ -303,3 +303,45 @@ eval $q; eval explain $q; DROP TABLE t1,t2; + +--echo # +--echo # MDEV-16225: wrong resultset from query with semijoin=on +--echo # + +CREATE TABLE t1 ( + `id` int(10) NOT NULL AUTO_INCREMENT, + `local_name` varchar(64) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=latin1; + +insert into t1(`id`,`local_name`) values +(1,'Cash Advance'), +(2,'Cash Advance'), +(3,'Rollover'), +(4,'AL Installment'), +(5,'AL Installment'), +(6,'AL Installment'), +(7,'AL Installment'), +(8,'AL Installment'), +(9,'AL Installment'), +(10,'Internet Payday'), +(11,'Rollover - Internet Payday'), +(12,'AL Monthly Installment'), +(13,'AL Semi-Monthly Installment'); + +explain +SELECT SQL_NO_CACHE t.id +FROM t1 t +WHERE ( + t.id IN (SELECT A.id FROM t1 AS A WHERE A.local_name IN (SELECT B.local_name FROM t1 AS B WHERE B.id IN (0,4,12,13,1,10,3,11))) + OR + (t.id IN (0,4,12,13,1,10,3,11)) +); +SELECT SQL_NO_CACHE t.id +FROM t1 t +WHERE ( + t.id IN (SELECT A.id FROM t1 AS A WHERE A.local_name IN (SELECT B.local_name FROM t1 AS B WHERE B.id IN (0,4,12,13,1,10,3,11))) + OR + (t.id IN (0,4,12,13,1,10,3,11)) +); +drop table t1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d6d269a700f..016dd594e08 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -23739,21 +23739,18 @@ void JOIN::set_allowed_join_cache_types() void JOIN::save_query_plan(Join_plan_state *save_to) { - if (keyuse.elements) - { - DYNAMIC_ARRAY tmp_keyuse; - /* Swap the current and the backup keyuse internal arrays. */ - tmp_keyuse= keyuse; - keyuse= save_to->keyuse; /* keyuse is reset to an empty array. */ - save_to->keyuse= tmp_keyuse; + DYNAMIC_ARRAY tmp_keyuse; + /* Swap the current and the backup keyuse internal arrays. */ + tmp_keyuse= keyuse; + keyuse= save_to->keyuse; /* keyuse is reset to an empty array. */ + save_to->keyuse= tmp_keyuse; - for (uint i= 0; i < table_count; i++) - { - save_to->join_tab_keyuse[i]= join_tab[i].keyuse; - join_tab[i].keyuse= NULL; - save_to->join_tab_checked_keys[i]= join_tab[i].checked_keys; - join_tab[i].checked_keys.clear_all(); - } + for (uint i= 0; i < table_count; i++) + { + save_to->join_tab_keyuse[i]= join_tab[i].keyuse; + join_tab[i].keyuse= NULL; + save_to->join_tab_checked_keys[i]= join_tab[i].checked_keys; + join_tab[i].checked_keys.clear_all(); } memcpy((uchar*) save_to->best_positions, (uchar*) best_positions, sizeof(POSITION) * (table_count + 1)); @@ -23791,20 +23788,17 @@ void JOIN::reset_query_plan() void JOIN::restore_query_plan(Join_plan_state *restore_from) { - if (restore_from->keyuse.elements) - { - DYNAMIC_ARRAY tmp_keyuse; - tmp_keyuse= keyuse; - keyuse= restore_from->keyuse; - restore_from->keyuse= tmp_keyuse; - - for (uint i= 0; i < table_count; i++) - { - join_tab[i].keyuse= restore_from->join_tab_keyuse[i]; - join_tab[i].checked_keys= restore_from->join_tab_checked_keys[i]; - } + DYNAMIC_ARRAY tmp_keyuse; + tmp_keyuse= keyuse; + keyuse= restore_from->keyuse; + restore_from->keyuse= tmp_keyuse; + for (uint i= 0; i < table_count; i++) + { + join_tab[i].keyuse= restore_from->join_tab_keyuse[i]; + join_tab[i].checked_keys= restore_from->join_tab_checked_keys[i]; } + memcpy((uchar*) best_positions, (uchar*) restore_from->best_positions, sizeof(POSITION) * (table_count + 1)); /* Restore SJM nests */ -- cgit v1.2.1 From eee5bd9a2e2949ef468670f1ec4431a4ce54ada0 Mon Sep 17 00:00:00 2001 From: Faustin Lammler Date: Tue, 3 Apr 2018 10:33:11 -0300 Subject: Package dependency case problem dummy commit, add carriage return rollback and add travis build remove travis CI config --- debian/control | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/control b/debian/control index 862cd4f3cea..79ccf8c8fd4 100644 --- a/debian/control +++ b/debian/control @@ -373,10 +373,10 @@ Description: MariaDB database regression test suite (metapackage depending on th Package: mariadb-connect-engine-10.0 Section: database Architecture: any -Depends: libxml2, mariadb-server-10.0|mariadb-galera-server-10.0, unixODBC +Depends: libxml2, mariadb-server-10.0|mariadb-galera-server-10.0, unixodbc Build-depends: libxml2-dev, mariadb-server-10.0|mariadb-galera-server-10.0, - unixODBC-dev + unixodbc-dev Description: Connect storage engine for MariaDB Connect engine supports a number of file formats (dbf, xml, txt, bin, etc), connections to ODBC tables and remote MySQL tables, as well as a number of -- cgit v1.2.1 From 55abcfa7b70968246a1a26a8839013ebb8f5c506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 5 Jun 2018 18:16:12 +0300 Subject: MDEV-16124 fil_rename_tablespace() times out and crashes server during table-rebuilding ALTER TABLE InnoDB insisted on closing the file handle before renaming a file. Renaming a file should never be a problem on POSIX systems. Also on Windows it should work if the file was opened in FILE_SHARE_DELETE mode. fil_space_t::stop_ios: Remove. We no longer need to stop file access during rename operations. fil_mutex_enter_and_prepare_for_io(): Remove the wait for stop_ios. fil_rename_tablespace(): Remove the retry logic; do not close the file handle. Remove the unused fault injection that was added along with the DATA DIRECTORY functionality (MySQL WL#5980). os_file_create_simple_func(), os_file_create_func(), os_file_create_simple_no_error_handling_func(): Include FILE_SHARE_DELETE in the share_mode. (We will still prevent multiple InnoDB instances from using the same files by not setting FILE_SHARE_WRITE.) --- storage/innobase/fil/fil0fil.cc | 110 ------------------------------------- storage/innobase/include/fil0fil.h | 4 -- storage/innobase/os/os0file.cc | 9 +-- storage/xtradb/fil/fil0fil.cc | 110 ------------------------------------- storage/xtradb/include/fil0fil.h | 4 -- storage/xtradb/os/os0file.cc | 9 +-- 6 files changed, 10 insertions(+), 236 deletions(-) diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 7167b99a750..f852a64e2e9 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -845,7 +845,6 @@ fil_mutex_enter_and_prepare_for_io( ibool success; ibool print_info = FALSE; ulint count = 0; - ulint count2 = 0; retry: mutex_enter(&fil_system->mutex); @@ -862,46 +861,6 @@ retry: space = fil_space_get_by_id(space_id); - if (space != NULL && space->stop_ios) { - /* We are going to do a rename file and want to stop new i/o's - for a while */ - - if (count2 > 20000) { - fputs("InnoDB: Warning: tablespace ", stderr); - ut_print_filename(stderr, space->name); - fprintf(stderr, - " has i/o ops stopped for a long time %lu\n", - (ulong) count2); - } - - mutex_exit(&fil_system->mutex); - -#ifndef UNIV_HOTBACKUP - - /* Wake the i/o-handler threads to make sure pending - i/o's are performed */ - os_aio_simulated_wake_handler_threads(); - - /* The sleep here is just to give IO helper threads a - bit of time to do some work. It is not required that - all IO related to the tablespace being renamed must - be flushed here as we do fil_flush() in - fil_rename_tablespace() as well. */ - os_thread_sleep(20000); - -#endif /* UNIV_HOTBACKUP */ - - /* Flush tablespaces so that we can close modified - files in the LRU list */ - fil_flush_file_spaces(FIL_TABLESPACE); - - os_thread_sleep(20000); - - count2++; - - goto retry; - } - if (fil_system->n_open < fil_system->max_n_open) { return; @@ -2898,7 +2857,6 @@ fil_rename_tablespace( ibool success; fil_space_t* space; fil_node_t* node; - ulint count = 0; char* new_path; char* old_name; char* old_path; @@ -2906,25 +2864,10 @@ fil_rename_tablespace( ut_a(id != 0); -retry: - count++; - - if (!(count % 1000)) { - ut_print_timestamp(stderr); - fputs(" InnoDB: Warning: problems renaming ", stderr); - ut_print_filename(stderr, - old_name_in ? old_name_in : not_given); - fputs(" to ", stderr); - ut_print_filename(stderr, new_name); - fprintf(stderr, ", %lu iterations\n", (ulong) count); - } - mutex_enter(&fil_system->mutex); space = fil_space_get_by_id(id); - DBUG_EXECUTE_IF("fil_rename_tablespace_failure_1", space = NULL; ); - if (space == NULL) { ib_logf(IB_LOG_LEVEL_ERROR, "Cannot find space id %lu in the tablespace " @@ -2936,54 +2879,11 @@ retry: return(FALSE); } - if (count > 25000) { - space->stop_ios = FALSE; - mutex_exit(&fil_system->mutex); - - return(FALSE); - } - - /* We temporarily close the .ibd file because we do not trust that - operating systems can rename an open file. For the closing we have to - wait until there are no pending i/o's or flushes on the file. */ - - space->stop_ios = TRUE; - /* The following code must change when InnoDB supports multiple datafiles per tablespace. */ ut_a(UT_LIST_GET_LEN(space->chain) == 1); node = UT_LIST_GET_FIRST(space->chain); - if (node->n_pending > 0 - || node->n_pending_flushes > 0 - || node->being_extended) { - /* There are pending i/o's or flushes or the file is - currently being extended, sleep for a while and - retry */ - - mutex_exit(&fil_system->mutex); - - os_thread_sleep(20000); - - goto retry; - - } else if (node->modification_counter > node->flush_counter) { - /* Flush the space */ - - mutex_exit(&fil_system->mutex); - - os_thread_sleep(20000); - - fil_flush(id); - - goto retry; - - } else if (node->open) { - /* Close the file */ - - fil_node_close_file(node, fil_system); - } - /* Check that the old name in the space is right */ if (old_name_in) { @@ -3002,17 +2902,9 @@ retry: space, node, new_name, new_path); if (success) { - - DBUG_EXECUTE_IF("fil_rename_tablespace_failure_2", - goto skip_second_rename; ); - success = os_file_rename( innodb_file_data_key, old_path, new_path); - DBUG_EXECUTE_IF("fil_rename_tablespace_failure_2", -skip_second_rename: - success = FALSE; ); - if (!success) { /* We have to revert the changes we made to the tablespace memory cache */ @@ -3022,8 +2914,6 @@ skip_second_rename: } } - space->stop_ios = FALSE; - mutex_exit(&fil_system->mutex); #ifndef UNIV_HOTBACKUP diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 9374bb88bb7..6e772e31772 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -256,10 +256,6 @@ struct fil_space_t { the space corresponds to a table in the InnoDB data dictionary; so we can print a warning of orphaned tablespaces */ - ibool stop_ios;/*!< TRUE if we want to rename the - .ibd file of tablespace and want to - stop temporarily posting of new i/o - requests on the file */ ibool stop_new_ops; /*!< we set this TRUE when we start deleting a single-table tablespace. diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 55d2c15f906..8f3f3716fc2 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -2,7 +2,7 @@ Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2009, Percona Inc. -Copyright (c) 2013, 2017, MariaDB Corporation. +Copyright (c) 2013, 2018, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Percona Inc.. Those modifications are @@ -1186,7 +1186,8 @@ os_file_create_simple_func( /* Use default security attributes and no template file. */ file = CreateFile( - (LPCTSTR) name, access, FILE_SHARE_READ, NULL, + (LPCTSTR) name, access, + FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, create_flag, attributes, NULL); if (file == INVALID_HANDLE_VALUE) { @@ -1314,7 +1315,7 @@ os_file_create_simple_no_error_handling_func( DWORD access; DWORD create_flag; DWORD attributes = 0; - DWORD share_mode = FILE_SHARE_READ; + DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_DELETE; ut_a(name); ut_a(!(create_mode & OS_FILE_ON_ERROR_SILENT)); @@ -1554,7 +1555,7 @@ os_file_create_func( #ifdef __WIN__ DWORD create_flag; - DWORD share_mode = FILE_SHARE_READ; + DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_DELETE; on_error_no_exit = create_mode & OS_FILE_ON_ERROR_NO_EXIT ? TRUE : FALSE; diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index 3807e6b3395..49c5f4b090b 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -862,7 +862,6 @@ fil_mutex_enter_and_prepare_for_io( ibool success; ibool print_info = FALSE; ulint count = 0; - ulint count2 = 0; retry: mutex_enter(&fil_system->mutex); @@ -879,46 +878,6 @@ retry: space = fil_space_get_by_id(space_id); - if (space != NULL && space->stop_ios) { - /* We are going to do a rename file and want to stop new i/o's - for a while */ - - if (count2 > 20000) { - fputs("InnoDB: Warning: tablespace ", stderr); - ut_print_filename(stderr, space->name); - fprintf(stderr, - " has i/o ops stopped for a long time %lu\n", - (ulong) count2); - } - - mutex_exit(&fil_system->mutex); - -#ifndef UNIV_HOTBACKUP - - /* Wake the i/o-handler threads to make sure pending - i/o's are performed */ - os_aio_simulated_wake_handler_threads(); - - /* The sleep here is just to give IO helper threads a - bit of time to do some work. It is not required that - all IO related to the tablespace being renamed must - be flushed here as we do fil_flush() in - fil_rename_tablespace() as well. */ - os_thread_sleep(20000); - -#endif /* UNIV_HOTBACKUP */ - - /* Flush tablespaces so that we can close modified - files in the LRU list */ - fil_flush_file_spaces(FIL_TABLESPACE); - - os_thread_sleep(20000); - - count2++; - - goto retry; - } - if (fil_system->n_open < fil_system->max_n_open) { return; @@ -2950,7 +2909,6 @@ fil_rename_tablespace( ibool success; fil_space_t* space; fil_node_t* node; - ulint count = 0; char* new_path; char* old_name; char* old_path; @@ -2958,25 +2916,10 @@ fil_rename_tablespace( ut_a(id != 0); -retry: - count++; - - if (!(count % 1000)) { - ut_print_timestamp(stderr); - fputs(" InnoDB: Warning: problems renaming ", stderr); - ut_print_filename(stderr, - old_name_in ? old_name_in : not_given); - fputs(" to ", stderr); - ut_print_filename(stderr, new_name); - fprintf(stderr, ", %lu iterations\n", (ulong) count); - } - mutex_enter(&fil_system->mutex); space = fil_space_get_by_id(id); - DBUG_EXECUTE_IF("fil_rename_tablespace_failure_1", space = NULL; ); - if (space == NULL) { ib_logf(IB_LOG_LEVEL_ERROR, "Cannot find space id %lu in the tablespace " @@ -2988,54 +2931,11 @@ retry: return(FALSE); } - if (count > 25000) { - space->stop_ios = FALSE; - mutex_exit(&fil_system->mutex); - - return(FALSE); - } - - /* We temporarily close the .ibd file because we do not trust that - operating systems can rename an open file. For the closing we have to - wait until there are no pending i/o's or flushes on the file. */ - - space->stop_ios = TRUE; - /* The following code must change when InnoDB supports multiple datafiles per tablespace. */ ut_a(UT_LIST_GET_LEN(space->chain) == 1); node = UT_LIST_GET_FIRST(space->chain); - if (node->n_pending > 0 - || node->n_pending_flushes > 0 - || node->being_extended) { - /* There are pending i/o's or flushes or the file is - currently being extended, sleep for a while and - retry */ - - mutex_exit(&fil_system->mutex); - - os_thread_sleep(20000); - - goto retry; - - } else if (node->modification_counter > node->flush_counter) { - /* Flush the space */ - - mutex_exit(&fil_system->mutex); - - os_thread_sleep(20000); - - fil_flush(id); - - goto retry; - - } else if (node->open) { - /* Close the file */ - - fil_node_close_file(node, fil_system); - } - /* Check that the old name in the space is right */ if (old_name_in) { @@ -3054,17 +2954,9 @@ retry: space, node, new_name, new_path); if (success) { - - DBUG_EXECUTE_IF("fil_rename_tablespace_failure_2", - goto skip_second_rename; ); - success = os_file_rename( innodb_file_data_key, old_path, new_path); - DBUG_EXECUTE_IF("fil_rename_tablespace_failure_2", -skip_second_rename: - success = FALSE; ); - if (!success) { /* We have to revert the changes we made to the tablespace memory cache */ @@ -3074,8 +2966,6 @@ skip_second_rename: } } - space->stop_ios = FALSE; - mutex_exit(&fil_system->mutex); #ifndef UNIV_HOTBACKUP diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h index 6230bd7a4d4..86b1c561349 100644 --- a/storage/xtradb/include/fil0fil.h +++ b/storage/xtradb/include/fil0fil.h @@ -249,10 +249,6 @@ struct fil_space_t { the space corresponds to a table in the InnoDB data dictionary; so we can print a warning of orphaned tablespaces */ - ibool stop_ios;/*!< TRUE if we want to rename the - .ibd file of tablespace and want to - stop temporarily posting of new i/o - requests on the file */ ibool stop_new_ops; /*!< we set this TRUE when we start deleting a single-table tablespace. diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc index 5ed7cbbc9b3..c1ddc83d852 100644 --- a/storage/xtradb/os/os0file.cc +++ b/storage/xtradb/os/os0file.cc @@ -2,7 +2,7 @@ Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2009, Percona Inc. -Copyright (c) 2013, 2017, MariaDB Corporation. +Copyright (c) 2013, 2018, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Percona Inc.. Those modifications are @@ -1301,7 +1301,8 @@ os_file_create_simple_func( /* Use default security attributes and no template file. */ file = CreateFile( - (LPCTSTR) name, access, FILE_SHARE_READ, NULL, + (LPCTSTR) name, access, + FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, create_flag, attributes, NULL); if (file == INVALID_HANDLE_VALUE) { @@ -1460,7 +1461,7 @@ os_file_create_simple_no_error_handling_func( DWORD access; DWORD create_flag; DWORD attributes = 0; - DWORD share_mode = FILE_SHARE_READ; + DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_DELETE; ut_a(name); ut_a(!(create_mode & OS_FILE_ON_ERROR_SILENT)); @@ -1737,7 +1738,7 @@ os_file_create_func( #ifdef __WIN__ DWORD create_flag; - DWORD share_mode = FILE_SHARE_READ; + DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_DELETE; on_error_no_exit = create_mode & OS_FILE_ON_ERROR_NO_EXIT ? TRUE : FALSE; -- cgit v1.2.1 From 72b6d01848e56a75349d663bc61bbe71f97a280b Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 5 Jun 2018 22:13:19 +0100 Subject: MDEV-10246 ssl-* config file options have no effect without mysql_ssl_set() Partially revert 4ef74979969ac9339d0d42c11a6f26632e6776f1 that caused regression. Any ssl- option must imply use_ssl=1, even if mysql_set_ssl() was not used. --- sql-common/client.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sql-common/client.c b/sql-common/client.c index 6321e64bc75..ec992f80e8d 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -2541,6 +2541,10 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio, mysql->client_flag|= CLIENT_MULTI_RESULTS; #ifdef HAVE_OPENSSL + if (mysql->options.ssl_key || mysql->options.ssl_cert || + mysql->options.ssl_ca || mysql->options.ssl_capath || + mysql->options.ssl_cipher) + mysql->options.use_ssl = 1; if (mysql->options.use_ssl) mysql->client_flag|= CLIENT_SSL; #endif /* HAVE_OPENSSL */ -- cgit v1.2.1 From 75b4eb5cc969a1f5fc221d03c62987b8e57d6332 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 6 Jun 2018 15:27:57 +0200 Subject: Catch of OOM situation. --- sql/sql_base.cc | 3 +++ sql/table.cc | 2 ++ 2 files changed, 5 insertions(+) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index f5864256440..71bbb538b5c 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -6426,6 +6426,9 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name, column reference. See create_view_field() for details. */ item= nj_col->create_item(thd); + if (!item) + DBUG_RETURN(NULL); + /* *ref != NULL means that *ref contains the item that we need to replace. If the item was aliased by the user, set the alias to diff --git a/sql/table.cc b/sql/table.cc index bb4eae9b1e2..552f514283d 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -5252,6 +5252,8 @@ Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref, Item *item= new Item_direct_view_ref(&view->view->select_lex.context, field_ref, view->alias, name, view); + if (!item) + return NULL; /* Force creation of nullable item for the result tmp table for outer joined views/derived tables. -- cgit v1.2.1 From d9b159a2027c56c5c87385cfe1ae43b8c73a97b6 Mon Sep 17 00:00:00 2001 From: Chris Calender Date: Tue, 17 Apr 2018 15:00:15 -0400 Subject: MDEV-15789 - mysqlslap use incorrect table def The bug arises when one uses --auto-generate-sql-guid-primary (and --auto-generate-sql-secondary-indexes) with mysqlslap and also have sql_mode=STRICT_TRANS_TABLE. When using this option, mysqlslap should create a column with varchar(36), but it appears to create it as a varchar(32) only. Then if one has sql_mode=STRICT_TRANS_TABLES, it throws an error, like: mysqlslap: Cannot run query INSERT INTO t1 VALUES (...) ERROR : Data too long for column 'id' at row 1 Upstream bug report: BUG#80329. --- client/mysqlslap.c | 4 ++-- mysql-test/r/mysqlslap.result | 3 +++ mysql-test/t/mysqlslap.test | 8 ++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/client/mysqlslap.c b/client/mysqlslap.c index a9746916411..ba7b8cea6a9 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -840,7 +840,7 @@ build_table_string(void) if (auto_generate_sql_guid_primary) { - dynstr_append(&table_string, "id varchar(32) primary key"); + dynstr_append(&table_string, "id varchar(36) primary key"); if (num_int_cols || num_char_cols || auto_generate_sql_guid_primary) dynstr_append(&table_string, ","); @@ -855,7 +855,7 @@ build_table_string(void) if (count) /* Except for the first pass we add a comma */ dynstr_append(&table_string, ","); - if (snprintf(buf, HUGE_STRING_LENGTH, "id%d varchar(32) unique key", count) + if (snprintf(buf, HUGE_STRING_LENGTH, "id%d varchar(36) unique key", count) > HUGE_STRING_LENGTH) { fprintf(stderr, "Memory Allocation error in create table\n"); diff --git a/mysql-test/r/mysqlslap.result b/mysql-test/r/mysqlslap.result index af78677647f..50bd53f4263 100644 --- a/mysql-test/r/mysqlslap.result +++ b/mysql-test/r/mysqlslap.result @@ -255,3 +255,6 @@ Benchmark # MDEV-4684 - Enhancement request: --init-command support for mysqlslap # DROP TABLE t1; +# +# Bug MDEV-15789 (Upstream: #80329): MYSQLSLAP OPTIONS --AUTO-GENERATE-SQL-GUID-PRIMARY and --AUTO-GENERATE-SQL-SECONDARY-INDEXES DONT WORK +# diff --git a/mysql-test/t/mysqlslap.test b/mysql-test/t/mysqlslap.test index c49c4ab3d7d..81115d59d09 100644 --- a/mysql-test/t/mysqlslap.test +++ b/mysql-test/t/mysqlslap.test @@ -80,3 +80,11 @@ DROP DATABASE bug58090; --exec $MYSQL_SLAP --create-schema=test --init-command="CREATE TABLE t1(a INT)" --silent --concurrency=1 --iterations=1 DROP TABLE t1; + +--echo # +--echo # Bug MDEV-15789 (Upstream: #80329): MYSQLSLAP OPTIONS --AUTO-GENERATE-SQL-GUID-PRIMARY and --AUTO-GENERATE-SQL-SECONDARY-INDEXES DONT WORK +--echo # + +--exec $MYSQL_SLAP --concurrency=1 --silent --iterations=1 --number-int-cols=2 --number-char-cols=3 --auto-generate-sql --auto-generate-sql-guid-primary --create-schema=slap + +--exec $MYSQL_SLAP --concurrency=1 --silent --iterations=1 --number-int-cols=2 --number-char-cols=3 --auto-generate-sql --auto-generate-sql-secondary-indexes=1 --create-schema=slap -- cgit v1.2.1 From 141bc58ac9926aff0a4eb5bac204f44f60d58840 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 8 Jun 2018 19:52:30 +0100 Subject: MDEV-16430: mysql_upgrade_service does not write log file. Fixed CreateFile() for the log file - TRUNCATE_EXISTING does not create a new file, use CREATE_ALWAYS - Make log file handle inheritable --- sql/mysql_upgrade_service.cc | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/sql/mysql_upgrade_service.cc b/sql/mysql_upgrade_service.cc index db916101eb1..0723d1c0356 100644 --- a/sql/mysql_upgrade_service.cc +++ b/sql/mysql_upgrade_service.cc @@ -146,6 +146,11 @@ static void die(const char *fmt, ...) exit(1); } +#define WRITE_LOG(fmt,...) {\ + char log_buf[1024]; \ + snprintf(log_buf,sizeof(log_buf), fmt, __VA_ARGS__);\ + WriteFile(logfile_handle,log_buf, strlen(log_buf), 0 , 0);\ +} /* spawn-like function to run subprocesses. @@ -187,17 +192,22 @@ static intptr_t run_tool(int wait_flag, const char *program,...) { char tmpdir[FN_REFLEN]; GetTempPath(FN_REFLEN, tmpdir); - sprintf_s(logfile_path, "%s\\mysql_upgrade_service.%s.log", tmpdir, + sprintf_s(logfile_path, "%smysql_upgrade_service.%s.log", tmpdir, opt_service); - logfile_handle= CreateFile(logfile_path, GENERIC_WRITE, FILE_SHARE_READ, - NULL, TRUNCATE_EXISTING, 0, NULL); - if (!logfile_handle) + SECURITY_ATTRIBUTES attr= {0}; + attr.nLength= sizeof(SECURITY_ATTRIBUTES); + attr.bInheritHandle= TRUE; + logfile_handle= CreateFile(logfile_path, FILE_APPEND_DATA, + FILE_SHARE_READ|FILE_SHARE_WRITE, &attr, CREATE_ALWAYS, 0, NULL); + if (logfile_handle == INVALID_HANDLE_VALUE) { die("Cannot open log file %s, windows error %u", logfile_path, GetLastError()); } } + WRITE_LOG("Executing %s\r\n", cmdline); + /* Start child process */ STARTUPINFO si= {0}; si.cb= sizeof(si); -- cgit v1.2.1 From 5bfd562a00828035ec873e5a6ee0af2c3f52a33a Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 8 Jun 2018 20:42:25 +0100 Subject: MDEV-16445 mysql_upgrade_service should add skip-slave-start to server start parameters --- sql/mysql_upgrade_service.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/mysql_upgrade_service.cc b/sql/mysql_upgrade_service.cc index 0723d1c0356..809161193a5 100644 --- a/sql/mysql_upgrade_service.cc +++ b/sql/mysql_upgrade_service.cc @@ -468,7 +468,7 @@ int main(int argc, char **argv) log("Phase 3/8: Starting mysqld for upgrade"); mysqld_process= (HANDLE)run_tool(P_NOWAIT, mysqld_path, defaults_file_param, "--skip-networking", "--skip-grant-tables", - "--enable-named-pipe", socket_param, NULL); + "--enable-named-pipe", socket_param,"--skip-slave-start", NULL); if (mysqld_process == INVALID_HANDLE_VALUE) { -- cgit v1.2.1 From 15155ecd3483c47d8f2c05727184f6bf47bbf0b0 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 8 Jun 2018 20:42:39 +0100 Subject: fix typo --- sql/mysql_install_db.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/mysql_install_db.cc b/sql/mysql_install_db.cc index de799874a8f..f9343aab011 100644 --- a/sql/mysql_install_db.cc +++ b/sql/mysql_install_db.cc @@ -195,7 +195,7 @@ int main(int argc, char **argv) die("database creation failed"); } - printf("Creation of the database was successfull"); + printf("Creation of the database was successful"); return 0; } -- cgit v1.2.1 From cd33280b682692f0517a26178d7b5337db648751 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Sat, 9 Jun 2018 11:26:52 +0530 Subject: MDEV-16374: Filtered shows 0 for materilization scan for a semi join, which makes optimizer always picks materialization scan over materialization lookup For non-mergeable semi-joins we don't store the estimates of the IN subquery in table->file->stats.records. In the function TABLE_LIST::fetch_number_of_rows, we store the number of rows in the tables (estimates in case of derived table/views). Currently we don't store the estimates for non-mergeable semi-joins, which leads to a problem of selecting materialization scan over materialization lookup. Fixed this by storing these estimated appropriately --- mysql-test/r/selectivity.result | 70 ++++++++++++++++++++++++++++-- mysql-test/r/selectivity_innodb.result | 70 ++++++++++++++++++++++++++++-- mysql-test/r/subselect_sj_nonmerged.result | 6 +-- mysql-test/t/selectivity.test | 18 ++++++++ sql/table.cc | 8 ++++ 5 files changed, 161 insertions(+), 11 deletions(-) diff --git a/mysql-test/r/selectivity.result b/mysql-test/r/selectivity.result index 61a77d135e7..3e8fb8e2e41 100644 --- a/mysql-test/r/selectivity.result +++ b/mysql-test/r/selectivity.result @@ -356,13 +356,13 @@ and o_orderkey = l_orderkey group by c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice order by o_totalprice desc, o_orderdate; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 6005 0.00 Using temporary; Using filesort -1 PRIMARY orders eq_ref PRIMARY,i_o_custkey PRIMARY 4 .l_orderkey 1 100.00 Using where +1 PRIMARY orders ALL PRIMARY,i_o_custkey NULL NULL NULL 1500 100.00 Using where; Using temporary; Using filesort +1 PRIMARY eq_ref distinct_key distinct_key 4 dbt3_s001.orders.o_orderkey 1 100.00 1 PRIMARY customer eq_ref PRIMARY PRIMARY 4 dbt3_s001.orders.o_custkey 1 100.00 -1 PRIMARY lineitem ref PRIMARY,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 .l_orderkey 4 100.00 +1 PRIMARY lineitem ref PRIMARY,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey_quantity 4 dbt3_s001.orders.o_orderkey 4 100.00 Using index 2 MATERIALIZED lineitem index NULL i_l_orderkey_quantity 13 NULL 6005 100.00 Using index Warnings: -Note 1003 select `dbt3_s001`.`customer`.`c_name` AS `c_name`,`dbt3_s001`.`customer`.`c_custkey` AS `c_custkey`,`dbt3_s001`.`orders`.`o_orderkey` AS `o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE` AS `o_orderdate`,`dbt3_s001`.`orders`.`o_totalprice` AS `o_totalprice`,sum(`dbt3_s001`.`lineitem`.`l_quantity`) AS `sum(l_quantity)` from (select `dbt3_s001`.`lineitem`.`l_orderkey` from `dbt3_s001`.`lineitem` group by `dbt3_s001`.`lineitem`.`l_orderkey` having (sum(`dbt3_s001`.`lineitem`.`l_quantity`) > 250)) join `dbt3_s001`.`customer` join `dbt3_s001`.`orders` join `dbt3_s001`.`lineitem` where ((`dbt3_s001`.`customer`.`c_custkey` = `dbt3_s001`.`orders`.`o_custkey`) and (`dbt3_s001`.`orders`.`o_orderkey` = ``.`l_orderkey`) and (`dbt3_s001`.`lineitem`.`l_orderkey` = ``.`l_orderkey`)) group by `dbt3_s001`.`customer`.`c_name`,`dbt3_s001`.`customer`.`c_custkey`,`dbt3_s001`.`orders`.`o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE`,`dbt3_s001`.`orders`.`o_totalprice` order by `dbt3_s001`.`orders`.`o_totalprice` desc,`dbt3_s001`.`orders`.`o_orderDATE` +Note 1003 select `dbt3_s001`.`customer`.`c_name` AS `c_name`,`dbt3_s001`.`customer`.`c_custkey` AS `c_custkey`,`dbt3_s001`.`orders`.`o_orderkey` AS `o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE` AS `o_orderdate`,`dbt3_s001`.`orders`.`o_totalprice` AS `o_totalprice`,sum(`dbt3_s001`.`lineitem`.`l_quantity`) AS `sum(l_quantity)` from (select `dbt3_s001`.`lineitem`.`l_orderkey` from `dbt3_s001`.`lineitem` group by `dbt3_s001`.`lineitem`.`l_orderkey` having (sum(`dbt3_s001`.`lineitem`.`l_quantity`) > 250)) join `dbt3_s001`.`customer` join `dbt3_s001`.`orders` join `dbt3_s001`.`lineitem` where ((`dbt3_s001`.`customer`.`c_custkey` = `dbt3_s001`.`orders`.`o_custkey`) and (``.`l_orderkey` = `dbt3_s001`.`orders`.`o_orderkey`) and (`dbt3_s001`.`lineitem`.`l_orderkey` = `dbt3_s001`.`orders`.`o_orderkey`)) group by `dbt3_s001`.`customer`.`c_name`,`dbt3_s001`.`customer`.`c_custkey`,`dbt3_s001`.`orders`.`o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE`,`dbt3_s001`.`orders`.`o_totalprice` order by `dbt3_s001`.`orders`.`o_totalprice` desc,`dbt3_s001`.`orders`.`o_orderDATE` select c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice, sum(l_quantity) from customer, orders, lineitem @@ -1535,6 +1535,68 @@ t 10:00:00 11:00:00 DROP TABLE t1; +# +# MDEV-16374: filtered shows 0 for materilization scan for a semi join, which makes optimizer +# always pick materialization scan over materialization lookup +# +create table t0(a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (a int, b int); +insert into t1 values (0,0),(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(10,10), +(11,11),(12,12),(13,13),(14,14),(15,15); +set @@optimizer_use_condition_selectivity=2; +explain extended select * from t1 where a in (select max(a) from t1 group by b); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 16 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 16 100.00 Using temporary +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (select max(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`b`) join `test`.`t1` where (``.`max(a)` = `test`.`t1`.`a`) +select * from t1 where a in (select max(a) from t1 group by b); +a b +0 0 +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +9 9 +10 10 +11 11 +12 12 +13 13 +14 14 +15 15 +set @@optimizer_use_condition_selectivity=1; +explain extended select * from t1 where a in (select max(a) from t1 group by b); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 16 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 16 100.00 Using temporary +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (select max(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`b`) join `test`.`t1` where (``.`max(a)` = `test`.`t1`.`a`) +select * from t1 where a in (select max(a) from t1 group by b); +a b +0 0 +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +9 9 +10 10 +11 11 +12 12 +13 13 +14 14 +15 15 +drop table t1,t0; set histogram_size=@save_histogram_size; set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; set use_stat_tables=@save_use_stat_tables; diff --git a/mysql-test/r/selectivity_innodb.result b/mysql-test/r/selectivity_innodb.result index a026c2e6d92..748ef0cb6ca 100644 --- a/mysql-test/r/selectivity_innodb.result +++ b/mysql-test/r/selectivity_innodb.result @@ -359,13 +359,13 @@ and o_orderkey = l_orderkey group by c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice order by o_totalprice desc, o_orderdate; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 6005 0.00 Using temporary; Using filesort -1 PRIMARY orders eq_ref PRIMARY,i_o_custkey PRIMARY 4 .l_orderkey 1 100.00 Using where +1 PRIMARY orders ALL PRIMARY,i_o_custkey NULL NULL NULL 1500 100.00 Using where; Using temporary; Using filesort +1 PRIMARY eq_ref distinct_key distinct_key 4 dbt3_s001.orders.o_orderkey 1 100.00 1 PRIMARY customer eq_ref PRIMARY PRIMARY 4 dbt3_s001.orders.o_custkey 1 100.00 -1 PRIMARY lineitem ref PRIMARY,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 .l_orderkey 4 100.00 +1 PRIMARY lineitem ref PRIMARY,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey_quantity 4 dbt3_s001.orders.o_orderkey 4 100.00 Using index 2 MATERIALIZED lineitem index NULL PRIMARY 8 NULL 6005 100.00 Warnings: -Note 1003 select `dbt3_s001`.`customer`.`c_name` AS `c_name`,`dbt3_s001`.`customer`.`c_custkey` AS `c_custkey`,`dbt3_s001`.`orders`.`o_orderkey` AS `o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE` AS `o_orderdate`,`dbt3_s001`.`orders`.`o_totalprice` AS `o_totalprice`,sum(`dbt3_s001`.`lineitem`.`l_quantity`) AS `sum(l_quantity)` from (select `dbt3_s001`.`lineitem`.`l_orderkey` from `dbt3_s001`.`lineitem` group by `dbt3_s001`.`lineitem`.`l_orderkey` having (sum(`dbt3_s001`.`lineitem`.`l_quantity`) > 250)) join `dbt3_s001`.`customer` join `dbt3_s001`.`orders` join `dbt3_s001`.`lineitem` where ((`dbt3_s001`.`customer`.`c_custkey` = `dbt3_s001`.`orders`.`o_custkey`) and (`dbt3_s001`.`orders`.`o_orderkey` = ``.`l_orderkey`) and (`dbt3_s001`.`lineitem`.`l_orderkey` = ``.`l_orderkey`)) group by `dbt3_s001`.`customer`.`c_name`,`dbt3_s001`.`customer`.`c_custkey`,`dbt3_s001`.`orders`.`o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE`,`dbt3_s001`.`orders`.`o_totalprice` order by `dbt3_s001`.`orders`.`o_totalprice` desc,`dbt3_s001`.`orders`.`o_orderDATE` +Note 1003 select `dbt3_s001`.`customer`.`c_name` AS `c_name`,`dbt3_s001`.`customer`.`c_custkey` AS `c_custkey`,`dbt3_s001`.`orders`.`o_orderkey` AS `o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE` AS `o_orderdate`,`dbt3_s001`.`orders`.`o_totalprice` AS `o_totalprice`,sum(`dbt3_s001`.`lineitem`.`l_quantity`) AS `sum(l_quantity)` from (select `dbt3_s001`.`lineitem`.`l_orderkey` from `dbt3_s001`.`lineitem` group by `dbt3_s001`.`lineitem`.`l_orderkey` having (sum(`dbt3_s001`.`lineitem`.`l_quantity`) > 250)) join `dbt3_s001`.`customer` join `dbt3_s001`.`orders` join `dbt3_s001`.`lineitem` where ((`dbt3_s001`.`customer`.`c_custkey` = `dbt3_s001`.`orders`.`o_custkey`) and (``.`l_orderkey` = `dbt3_s001`.`orders`.`o_orderkey`) and (`dbt3_s001`.`lineitem`.`l_orderkey` = `dbt3_s001`.`orders`.`o_orderkey`)) group by `dbt3_s001`.`customer`.`c_name`,`dbt3_s001`.`customer`.`c_custkey`,`dbt3_s001`.`orders`.`o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE`,`dbt3_s001`.`orders`.`o_totalprice` order by `dbt3_s001`.`orders`.`o_totalprice` desc,`dbt3_s001`.`orders`.`o_orderDATE` select c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice, sum(l_quantity) from customer, orders, lineitem @@ -1539,6 +1539,68 @@ t 10:00:00 11:00:00 DROP TABLE t1; +# +# MDEV-16374: filtered shows 0 for materilization scan for a semi join, which makes optimizer +# always pick materialization scan over materialization lookup +# +create table t0(a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (a int, b int); +insert into t1 values (0,0),(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(10,10), +(11,11),(12,12),(13,13),(14,14),(15,15); +set @@optimizer_use_condition_selectivity=2; +explain extended select * from t1 where a in (select max(a) from t1 group by b); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 16 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 16 100.00 Using temporary +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (select max(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`b`) join `test`.`t1` where (``.`max(a)` = `test`.`t1`.`a`) +select * from t1 where a in (select max(a) from t1 group by b); +a b +0 0 +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +9 9 +10 10 +11 11 +12 12 +13 13 +14 14 +15 15 +set @@optimizer_use_condition_selectivity=1; +explain extended select * from t1 where a in (select max(a) from t1 group by b); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 16 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 16 100.00 Using temporary +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (select max(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`b`) join `test`.`t1` where (``.`max(a)` = `test`.`t1`.`a`) +select * from t1 where a in (select max(a) from t1 group by b); +a b +0 0 +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +9 9 +10 10 +11 11 +12 12 +13 13 +14 14 +15 15 +drop table t1,t0; set histogram_size=@save_histogram_size; set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; set use_stat_tables=@save_use_stat_tables; diff --git a/mysql-test/r/subselect_sj_nonmerged.result b/mysql-test/r/subselect_sj_nonmerged.result index c7e04225ffe..47970668ae5 100644 --- a/mysql-test/r/subselect_sj_nonmerged.result +++ b/mysql-test/r/subselect_sj_nonmerged.result @@ -77,9 +77,9 @@ explain select * from t4 where t4.a in (select max(t2.a) from t1, t2 group by t2.b) and t4.b in (select max(t2.a) from t1, t2 group by t2.b); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 5 -1 PRIMARY ALL distinct_key NULL NULL NULL 5 Using join buffer (flat, BNL join) -1 PRIMARY t4 ref a a 10 .max(t2.a),.max(t2.a) 12 +1 PRIMARY ALL distinct_key NULL NULL NULL 5 +1 PRIMARY t4 ref a a 5 .max(t2.a) 12 Using index condition +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t4.b 1 3 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using temporary 3 MATERIALIZED t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join) 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using temporary diff --git a/mysql-test/t/selectivity.test b/mysql-test/t/selectivity.test index 548ef295fb2..afaa937c360 100644 --- a/mysql-test/t/selectivity.test +++ b/mysql-test/t/selectivity.test @@ -1043,6 +1043,24 @@ SELECT * FROM (SELECT t FROM t1 WHERE d IS NULL) sq; DROP TABLE t1; +--echo # +--echo # MDEV-16374: filtered shows 0 for materilization scan for a semi join, which makes optimizer +--echo # always pick materialization scan over materialization lookup +--echo # + +create table t0(a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (a int, b int); +insert into t1 values (0,0),(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(10,10), +(11,11),(12,12),(13,13),(14,14),(15,15); +set @@optimizer_use_condition_selectivity=2; +explain extended select * from t1 where a in (select max(a) from t1 group by b); +select * from t1 where a in (select max(a) from t1 group by b); +set @@optimizer_use_condition_selectivity=1; +explain extended select * from t1 where a in (select max(a) from t1 group by b); +select * from t1 where a in (select max(a) from t1 group by b); +drop table t1,t0; + set histogram_size=@save_histogram_size; set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; set use_stat_tables=@save_use_stat_tables; diff --git a/sql/table.cc b/sql/table.cc index bc6e1e754ee..b5082df7076 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -7099,7 +7099,15 @@ int TABLE_LIST::fetch_number_of_rows() { int error= 0; if (jtbm_subselect) + { + if (jtbm_subselect->is_jtbm_merged) + { + table->file->stats.records= jtbm_subselect->jtbm_record_count; + set_if_bigger(table->file->stats.records, 2); + table->used_stat_records= table->file->stats.records; + } return 0; + } if (is_materialized_derived() && !fill_me) { -- cgit v1.2.1 From b8e267c0c5007dbfebc2dee8a4f408f28b637ba5 Mon Sep 17 00:00:00 2001 From: Teodor Mircea Ionita Date: Wed, 9 May 2018 15:14:57 +0300 Subject: MDEV-15778: Manually backport TokuDB macOS fixes from 10.0 Fix build on macOS 10.13: 39dceaae607 MDEV-10983: TokuDB does not compile on OS X 10.12 Make use of a different function to get the current tid. Additionally, librt doesn't exist on OS X. Use System library instead. storage/tokudb/PerconaFT/cmake_modules/TokuFeatureDetection.cmake | 4 +++- storage/tokudb/PerconaFT/portability/portability.cc | 9 ++++++++- storage/tokudb/PerconaFT/portability/tests/test-xid.cc | 9 ++++++++- storage/tokudb/PerconaFT/portability/toku_config.h.in | 1 + 4 files changed, 20 insertions(+), 3 deletions(-) --- storage/tokudb/ft-index/cmake_modules/TokuFeatureDetection.cmake | 4 +++- storage/tokudb/ft-index/portability/portability.cc | 9 ++++++++- storage/tokudb/ft-index/portability/tests/test-xid.cc | 9 ++++++++- storage/tokudb/ft-index/portability/toku_config.h.in | 1 + 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/storage/tokudb/ft-index/cmake_modules/TokuFeatureDetection.cmake b/storage/tokudb/ft-index/cmake_modules/TokuFeatureDetection.cmake index e7fd27525d5..ef7934a5a09 100644 --- a/storage/tokudb/ft-index/cmake_modules/TokuFeatureDetection.cmake +++ b/storage/tokudb/ft-index/cmake_modules/TokuFeatureDetection.cmake @@ -96,7 +96,7 @@ if (NOT HAVE_BACKTRACE_WITHOUT_EXECINFO) endif () endif () -if(HAVE_CLOCK_REALTIME) +if(HAVE_CLOCK_REALTIME AND (NOT APPLE)) list(APPEND EXTRA_SYSTEM_LIBS rt) else() list(APPEND EXTRA_SYSTEM_LIBS System) @@ -108,6 +108,8 @@ check_function_exists(pthread_rwlockattr_setkind_np HAVE_PTHREAD_RWLOCKATTR_SETK ## check for the right way to yield using pthreads check_function_exists(pthread_yield HAVE_PTHREAD_YIELD) check_function_exists(pthread_yield_np HAVE_PTHREAD_YIELD_NP) +## check if we have pthread_threadid_np() (i.e. osx) +check_function_exists(pthread_threadid_np HAVE_PTHREAD_THREADID_NP) ## check if we have pthread_getthreadid_np() (i.e. freebsd) check_function_exists(pthread_getthreadid_np HAVE_PTHREAD_GETTHREADID_NP) diff --git a/storage/tokudb/ft-index/portability/portability.cc b/storage/tokudb/ft-index/portability/portability.cc index 09c1ccd50be..9863c45c60d 100644 --- a/storage/tokudb/ft-index/portability/portability.cc +++ b/storage/tokudb/ft-index/portability/portability.cc @@ -115,6 +115,9 @@ PATENT RIGHTS GRANT: #if defined(HAVE_SYS_SYSCTL_H) # include #endif +#if defined(HAVE_PTHREAD_H) +# include +#endif #if defined(HAVE_PTHREAD_NP_H) # include #endif @@ -154,7 +157,11 @@ toku_os_getpid(void) { int toku_os_gettid(void) { -#if defined(__NR_gettid) +#if defined(HAVE_PTHREAD_THREADID_NP) + uint64_t result; + pthread_threadid_np(NULL, &result); + return (int) result; // Used for instrumentation so overflow is ok here. +#elif defined(__NR_gettid) return syscall(__NR_gettid); #elif defined(SYS_gettid) return syscall(SYS_gettid); diff --git a/storage/tokudb/ft-index/portability/tests/test-xid.cc b/storage/tokudb/ft-index/portability/tests/test-xid.cc index 9277f984b43..fb1abd33793 100644 --- a/storage/tokudb/ft-index/portability/tests/test-xid.cc +++ b/storage/tokudb/ft-index/portability/tests/test-xid.cc @@ -103,11 +103,18 @@ PATENT RIGHTS GRANT: #if defined(HAVE_PTHREAD_NP_H) # include #endif +#if defined(HAVE_PTHREAD_H) +# include +#endif // since we implement the same thing here as in toku_os_gettid, this test // is pretty pointless static int gettid(void) { -#if defined(__NR_gettid) +#if defined(HAVE_PTHREAD_THREADID_NP) + uint64_t result; + pthread_threadid_np(NULL, &result); + return (int) result; +#elif defined(__NR_gettid) return syscall(__NR_gettid); #elif defined(SYS_gettid) return syscall(SYS_gettid); diff --git a/storage/tokudb/ft-index/portability/toku_config.h.in b/storage/tokudb/ft-index/portability/toku_config.h.in index c56674ece9e..b8a89e81da6 100644 --- a/storage/tokudb/ft-index/portability/toku_config.h.in +++ b/storage/tokudb/ft-index/portability/toku_config.h.in @@ -57,6 +57,7 @@ #cmakedefine HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP 1 #cmakedefine HAVE_PTHREAD_YIELD 1 #cmakedefine HAVE_PTHREAD_YIELD_NP 1 +#cmakedefine HAVE_PTHREAD_THREADID_NP 1 #cmakedefine HAVE_PTHREAD_GETTHREADID_NP 1 #cmakedefine PTHREAD_YIELD_RETURNS_INT 1 -- cgit v1.2.1 From 1735fa340a9d7ca8683f18fe2ecc148423e78ba7 Mon Sep 17 00:00:00 2001 From: Teodor Mircea Ionita Date: Wed, 9 May 2018 16:54:16 +0300 Subject: MDEV-15778: Remove packed attr from omt_ and subtree_ classes This is happening because they are declared as packed and clang has -Waddress-of-packed-member when passing the address of a packed member, a legit concern on different architectures. The easiest way to get rid of the errors is to remove the packed attribute from said structs. --- storage/tokudb/ft-index/util/omt.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/storage/tokudb/ft-index/util/omt.h b/storage/tokudb/ft-index/util/omt.h index 02f3f0d759a..6cf3f80d2bc 100644 --- a/storage/tokudb/ft-index/util/omt.h +++ b/storage/tokudb/ft-index/util/omt.h @@ -181,7 +181,7 @@ public: paranoid_invariant(index != NODE_NULL); m_index = index; } -} __attribute__((__packed__,aligned(4))); +} ; template<> class subtree_templated { @@ -238,7 +238,7 @@ public: inline void disable_bit(void) { m_bitfield &= MASK_INDEX; } -} __attribute__((__packed__)) ; +} ; template class omt_node_templated { @@ -251,7 +251,7 @@ public: // this needs to be in both implementations because we don't have // a "static if" the caller can use inline void clear_stolen_bits(void) {} -} __attribute__((__packed__,aligned(4))); +} ; template class omt_node_templated { @@ -288,7 +288,7 @@ public: this->unset_marked_bit(); this->unset_marks_below_bit(); } -} __attribute__((__packed__,aligned(4))); +} ; } -- cgit v1.2.1 From 8f82c4844342f42c27e2336b64f7bdd1a1344cbd Mon Sep 17 00:00:00 2001 From: Teodor Mircea Ionita Date: Wed, 9 May 2018 16:29:18 +0300 Subject: MDEV-15778: Restore file permissions lost in merge Permissions were probably due to a file copy in: 15f7f5c6bb4 Merge branch 'merge-tokudb-5.6' into 10.0 --- storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/autogen.sh | 0 storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/compile | 0 .../tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.guess | 0 .../tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.rpath | 0 storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.sub | 0 storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/depcomp | 0 storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/install-sh | 0 storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/ltmain.sh | 0 storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/missing | 0 .../PerconaFT/third_party/xz-4.999.9beta/extra/7z2lzma/7z2lzma.bash | 0 .../tokudb/PerconaFT/third_party/xz-4.999.9beta/tests/test_compress.sh | 0 storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/tests/test_files.sh | 0 12 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/autogen.sh mode change 100644 => 100755 storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/compile mode change 100644 => 100755 storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.guess mode change 100644 => 100755 storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.rpath mode change 100644 => 100755 storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.sub mode change 100644 => 100755 storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/depcomp mode change 100644 => 100755 storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/install-sh mode change 100644 => 100755 storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/ltmain.sh mode change 100644 => 100755 storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/missing mode change 100644 => 100755 storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/extra/7z2lzma/7z2lzma.bash mode change 100644 => 100755 storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/tests/test_compress.sh mode change 100644 => 100755 storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/tests/test_files.sh diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/autogen.sh b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/autogen.sh old mode 100644 new mode 100755 diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/compile b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/compile old mode 100644 new mode 100755 diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.guess b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.guess old mode 100644 new mode 100755 diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.rpath b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.rpath old mode 100644 new mode 100755 diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.sub b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/config.sub old mode 100644 new mode 100755 diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/depcomp b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/depcomp old mode 100644 new mode 100755 diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/install-sh b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/install-sh old mode 100644 new mode 100755 diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/ltmain.sh b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/ltmain.sh old mode 100644 new mode 100755 diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/missing b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/build-aux/missing old mode 100644 new mode 100755 diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/extra/7z2lzma/7z2lzma.bash b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/extra/7z2lzma/7z2lzma.bash old mode 100644 new mode 100755 diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/tests/test_compress.sh b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/tests/test_compress.sh old mode 100644 new mode 100755 diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/tests/test_files.sh b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/tests/test_files.sh old mode 100644 new mode 100755 -- cgit v1.2.1 From 7053e26e1869962ef473043686996f40ac0fb88c Mon Sep 17 00:00:00 2001 From: Teodor Mircea Ionita Date: Thu, 10 May 2018 10:00:51 +0300 Subject: MDEV-15778: Fix TokuDB build issues on macOS 10.13.4 Several issues were encountered and fixed as explained bellow: * missing link to dbug lib; * user proper fprintf format specifier; * ZERO_COND_INITIALIZER was using wrong toku_cond_t struct initializer for first member of type pthread_cond_t and not considering the TOKU_PTHREAD_DEBUG case which has one extra struct member of type pfs_key_t; * Remove likely(!opt_debug_sync_timeout), argument is declared extern and not available to Toku; * pthread_mutex_timedlock() is not available in pthreads for Mac, as it's not part of the POSIX pthreads spec. The encompassing event_t::wait(ms) methods are unused, thus have been removed; --- storage/tokudb/PerconaFT/ft/ft-ops.cc | 4 +- .../tokudb/PerconaFT/ft/serialize/ft-serialize.cc | 6 +-- .../PerconaFT/ft/serialize/ft_node-serialize.cc | 58 +++++++++++----------- .../tokudb/PerconaFT/portability/toku_debug_sync.h | 3 -- .../tokudb/PerconaFT/portability/toku_pthread.h | 12 ++++- storage/tokudb/PerconaFT/src/CMakeLists.txt | 2 +- storage/tokudb/tokudb_thread.h | 49 ------------------ 7 files changed, 46 insertions(+), 88 deletions(-) diff --git a/storage/tokudb/PerconaFT/ft/ft-ops.cc b/storage/tokudb/PerconaFT/ft/ft-ops.cc index d036366dd63..d7ea5efdff5 100644 --- a/storage/tokudb/PerconaFT/ft/ft-ops.cc +++ b/storage/tokudb/PerconaFT/ft/ft-ops.cc @@ -821,7 +821,7 @@ int toku_ftnode_fetch_callback(CACHEFILE UU(cachefile), fprintf( stderr, "%s:%d:toku_ftnode_fetch_callback - " - "file[%s], blocknum[%ld], toku_deserialize_ftnode_from " + "file[%s], blocknum[%lld], toku_deserialize_ftnode_from " "failed with a checksum error.\n", __FILE__, __LINE__, @@ -831,7 +831,7 @@ int toku_ftnode_fetch_callback(CACHEFILE UU(cachefile), fprintf( stderr, "%s:%d:toku_ftnode_fetch_callback - " - "file[%s], blocknum[%ld], toku_deserialize_ftnode_from " + "file[%s], blocknum[%lld], toku_deserialize_ftnode_from " "failed with %d.\n", __FILE__, __LINE__, diff --git a/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc b/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc index b24d72a5dff..fe68e1b20e0 100644 --- a/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc +++ b/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc @@ -656,9 +656,9 @@ exit: fprintf(stderr, \ "%s:%d toku_deserialize_ft_from: " \ "filename[%s] " \ - "r[%d] max_acceptable_lsn[%lu]" \ - "r0[%d] checkpoint_lsn_0[%lu] checkpoint_count_0[%lu] " \ - "r1[%d] checkpoint_lsn_1[%lu] checkpoint_count_1[%lu]\n", \ + "r[%d] max_acceptable_lsn[%llu]" \ + "r0[%d] checkpoint_lsn_0[%llu] checkpoint_count_0[%llu] " \ + "r1[%d] checkpoint_lsn_1[%llu] checkpoint_count_1[%llu]\n", \ __FILE__, \ __LINE__, \ fn, \ diff --git a/storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc b/storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc index 55899905baf..02d0cc691cd 100644 --- a/storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc +++ b/storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc @@ -1170,7 +1170,7 @@ int verify_ftnode_sub_block(struct sub_block *sb, fprintf( stderr, "%s:%d:verify_ftnode_sub_block - " - "file[%s], blocknum[%ld], stored_xsum[%u] != actual_xsum[%u]\n", + "file[%s], blocknum[%lld], stored_xsum[%u] != actual_xsum[%u]\n", __FILE__, __LINE__, fname ? fname : "unknown", @@ -1197,7 +1197,7 @@ static int deserialize_ftnode_info(struct sub_block *sb, FTNODE node) { fprintf( stderr, "%s:%d:deserialize_ftnode_info - " - "file[%s], blocknum[%ld], verify_ftnode_sub_block failed with %d\n", + "file[%s], blocknum[%lld], verify_ftnode_sub_block failed with %d\n", __FILE__, __LINE__, fname ? fname : "unknown", @@ -1253,7 +1253,7 @@ static int deserialize_ftnode_info(struct sub_block *sb, FTNODE node) { fprintf( stderr, "%s:%d:deserialize_ftnode_info - " - "file[%s], blocknum[%ld], data_size[%d] != rb.ndone[%d]\n", + "file[%s], blocknum[%lld], data_size[%d] != rb.ndone[%d]\n", __FILE__, __LINE__, fname ? fname : "unknown", @@ -1388,7 +1388,7 @@ static int deserialize_ftnode_partition( if (r != 0) { fprintf(stderr, "%s:%d:deserialize_ftnode_partition - " - "file[%s], blocknum[%ld], " + "file[%s], blocknum[%lld], " "verify_ftnode_sub_block failed with %d\n", __FILE__, __LINE__, @@ -1410,7 +1410,7 @@ static int deserialize_ftnode_partition( if (ch != FTNODE_PARTITION_MSG_BUFFER) { fprintf(stderr, "%s:%d:deserialize_ftnode_partition - " - "file[%s], blocknum[%ld], ch[%d] != " + "file[%s], blocknum[%lld], ch[%d] != " "FTNODE_PARTITION_MSG_BUFFER[%d]\n", __FILE__, __LINE__, @@ -1433,7 +1433,7 @@ static int deserialize_ftnode_partition( if (ch != FTNODE_PARTITION_DMT_LEAVES) { fprintf(stderr, "%s:%d:deserialize_ftnode_partition - " - "file[%s], blocknum[%ld], ch[%d] != " + "file[%s], blocknum[%lld], ch[%d] != " "FTNODE_PARTITION_DMT_LEAVES[%d]\n", __FILE__, __LINE__, @@ -1457,7 +1457,7 @@ static int deserialize_ftnode_partition( if (rb.ndone != rb.size) { fprintf(stderr, "%s:%d:deserialize_ftnode_partition - " - "file[%s], blocknum[%ld], rb.ndone[%d] != rb.size[%d]\n", + "file[%s], blocknum[%lld], rb.ndone[%d] != rb.size[%d]\n", __FILE__, __LINE__, fname ? fname : "unknown", @@ -1485,7 +1485,7 @@ static int decompress_and_deserialize_worker(struct rbuf curr_rbuf, const char *fname = toku_ftnode_get_cachefile_fname_in_env(node); fprintf(stderr, "%s:%d:decompress_and_deserialize_worker - " - "file[%s], blocknum[%ld], read_and_decompress_sub_block failed " + "file[%s], blocknum[%lld], read_and_decompress_sub_block failed " "with %d\n", __FILE__, __LINE__, @@ -1502,7 +1502,7 @@ static int decompress_and_deserialize_worker(struct rbuf curr_rbuf, const char *fname = toku_ftnode_get_cachefile_fname_in_env(node); fprintf(stderr, "%s:%d:decompress_and_deserialize_worker - " - "file[%s], blocknum[%ld], deserialize_ftnode_partition failed " + "file[%s], blocknum[%lld], deserialize_ftnode_partition failed " "with %d\n", __FILE__, __LINE__, @@ -1582,7 +1582,7 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( fprintf( stderr, "%s:%d:deserialize_ftnode_header_from_rbuf_if_small_enough - " - "file[%s], blocknum[%ld], rb->size[%u] < 24\n", + "file[%s], blocknum[%lld], rb->size[%u] < 24\n", __FILE__, __LINE__, fname ? fname : "unknown", @@ -1602,7 +1602,7 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( fprintf( stderr, "%s:%d:deserialize_ftnode_header_from_rbuf_if_small_enough - " - "file[%s], blocknum[%ld], unrecognized magic number " + "file[%s], blocknum[%lld], unrecognized magic number " "%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", __FILE__, __LINE__, @@ -1627,7 +1627,7 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( fprintf( stderr, "%s:%d:deserialize_ftnode_header_from_rbuf_if_small_enough - " - "file[%s], blocknum[%ld], node->layout_version_read_from_disk[%d] " + "file[%s], blocknum[%lld], node->layout_version_read_from_disk[%d] " "< FT_FIRST_LAYOUT_VERSION_WITH_BASEMENT_NODES[%d]\n", __FILE__, __LINE__, @@ -1667,7 +1667,7 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( fprintf( stderr, "%s:%d:deserialize_ftnode_header_from_rbuf_if_small_enough - " - "file[%s], blocknum[%ld], needed_size[%d] > rb->size[%d]\n", + "file[%s], blocknum[%lld], needed_size[%d] > rb->size[%d]\n", __FILE__, __LINE__, fname ? fname : "unknown", @@ -1695,7 +1695,7 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( fprintf( stderr, "%s:%d:deserialize_ftnode_header_from_rbuf_if_small_enough - " - "file[%s], blocknum[%ld], stored_checksum[%d] != checksum[%d]\n", + "file[%s], blocknum[%lld], stored_checksum[%d] != checksum[%d]\n", __FILE__, __LINE__, fname ? fname : "unknown", @@ -1717,7 +1717,7 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( fprintf( stderr, "%s:%d:deserialize_ftnode_header_from_rbuf_if_small_enough - " - "file[%s], blocknum[%ld], rb->size[%d] - rb->ndone[%d] < " + "file[%s], blocknum[%lld], rb->size[%d] - rb->ndone[%d] < " "sb_node_info.compressed_size[%d] + 8\n", __FILE__, __LINE__, @@ -1744,7 +1744,7 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( fprintf( stderr, "%s:%d:deserialize_ftnode_header_from_rbuf_if_small_enough - " - "file[%s], blocknum[%ld], sb_node_info.xsum[%d] != actual_xsum[%d]\n", + "file[%s], blocknum[%lld], sb_node_info.xsum[%d] != actual_xsum[%d]\n", __FILE__, __LINE__, fname ? fname : "unknown", @@ -1774,7 +1774,7 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( fprintf( stderr, "%s:%d:deserialize_ftnode_header_from_rbuf_if_small_enough - " - "file[%s], blocknum[%ld], deserialize_ftnode_info failed with " + "file[%s], blocknum[%lld], deserialize_ftnode_info failed with " "%d\n", __FILE__, __LINE__, @@ -1812,7 +1812,7 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( fprintf( stderr, "%s:%d:deserialize_ftnode_header_from_rbuf_if_small_enough - " - "file[%s], blocknum[%ld], toku_ftnode_pf_callback failed with " + "file[%s], blocknum[%lld], toku_ftnode_pf_callback failed with " "%d\n", __FILE__, __LINE__, @@ -2164,7 +2164,7 @@ static int deserialize_and_upgrade_ftnode(FTNODE node, const char* fname = toku_cachefile_fname_in_env(bfe->ft->cf); fprintf(stderr, "%s:%d:deserialize_and_upgrade_ftnode - " - "file[%s], blocknum[%ld], " + "file[%s], blocknum[%lld], " "read_and_decompress_block_from_fd_into_rbuf failed with %d\n", __FILE__, __LINE__, @@ -2190,7 +2190,7 @@ static int deserialize_and_upgrade_ftnode(FTNODE node, const char* fname = toku_cachefile_fname_in_env(bfe->ft->cf); fprintf(stderr, "%s:%d:deserialize_and_upgrade_ftnode - " - "file[%s], blocknum[%ld], version[%d] > " + "file[%s], blocknum[%lld], version[%d] > " "FT_LAYOUT_VERSION_14[%d]\n", __FILE__, __LINE__, @@ -2278,7 +2278,7 @@ static int deserialize_ftnode_from_rbuf(FTNODE *ftnode, memcmp(magic, "tokunode", 8) != 0) { fprintf(stderr, "%s:%d:deserialize_ftnode_from_rbuf - " - "file[%s], blocknum[%ld], unrecognized magic number " + "file[%s], blocknum[%lld], unrecognized magic number " "%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", __FILE__, __LINE__, @@ -2309,7 +2309,7 @@ static int deserialize_ftnode_from_rbuf(FTNODE *ftnode, if (r != 0) { fprintf(stderr, "%s:%d:deserialize_ftnode_from_rbuf - " - "file[%s], blocknum[%ld], deserialize_and_upgrade_ftnode " + "file[%s], blocknum[%lld], deserialize_and_upgrade_ftnode " "failed with %d\n", __FILE__, __LINE__, @@ -2355,7 +2355,7 @@ static int deserialize_ftnode_from_rbuf(FTNODE *ftnode, fprintf( stderr, "%s:%d:deserialize_ftnode_from_rbuf - " - "file[%s], blocknum[%ld], stored_checksum[%d] != checksum[%d]\n", + "file[%s], blocknum[%lld], stored_checksum[%d] != checksum[%d]\n", __FILE__, __LINE__, fname ? fname : "unknown", @@ -2377,7 +2377,7 @@ static int deserialize_ftnode_from_rbuf(FTNODE *ftnode, fprintf( stderr, "%s:%d:deserialize_ftnode_from_rbuf - " - "file[%s], blocknum[%ld], read_and_decompress_sub_block failed " + "file[%s], blocknum[%lld], read_and_decompress_sub_block failed " "with %d\n", __FILE__, __LINE__, @@ -2398,7 +2398,7 @@ static int deserialize_ftnode_from_rbuf(FTNODE *ftnode, fprintf( stderr, "%s:%d:deserialize_ftnode_from_rbuf - " - "file[%s], blocknum[%ld], deserialize_ftnode_info failed with " + "file[%s], blocknum[%lld], deserialize_ftnode_info failed with " "%d\n", __FILE__, __LINE__, @@ -2470,7 +2470,7 @@ static int deserialize_ftnode_from_rbuf(FTNODE *ftnode, fprintf( stderr, "%s:%d:deserialize_ftnode_from_rbuf - " - "file[%s], blocknum[%ld], childnum[%d], " + "file[%s], blocknum[%lld], childnum[%d], " "decompress_and_deserialize_worker failed with %d\n", __FILE__, __LINE__, @@ -2490,7 +2490,7 @@ static int deserialize_ftnode_from_rbuf(FTNODE *ftnode, fprintf( stderr, "%s:%d:deserialize_ftnode_from_rbuf - " - "file[%s], blocknum[%ld], childnum[%d], " + "file[%s], blocknum[%lld], childnum[%d], " "check_and_copy_compressed_sub_block_worker failed with " "%d\n", __FILE__, @@ -2641,7 +2641,7 @@ int toku_deserialize_bp_from_compressed(FTNODE node, const char* fname = toku_cachefile_fname_in_env(bfe->ft->cf); fprintf(stderr, "%s:%d:toku_deserialize_bp_from_compressed - " - "file[%s], blocknum[%ld], " + "file[%s], blocknum[%lld], " "deserialize_ftnode_partition failed with %d\n", __FILE__, __LINE__, @@ -2689,7 +2689,7 @@ static int deserialize_ftnode_from_fd(int fd, fprintf( stderr, "%s:%d:deserialize_ftnode_from_fd - " - "file[%s], blocknum[%ld], deserialize_ftnode_from_rbuf failed with " + "file[%s], blocknum[%lld], deserialize_ftnode_from_rbuf failed with " "%d\n", __FILE__, __LINE__, diff --git a/storage/tokudb/PerconaFT/portability/toku_debug_sync.h b/storage/tokudb/PerconaFT/portability/toku_debug_sync.h index b5394e58d68..493075c36c3 100644 --- a/storage/tokudb/PerconaFT/portability/toku_debug_sync.h +++ b/storage/tokudb/PerconaFT/portability/toku_debug_sync.h @@ -62,9 +62,6 @@ inline void toku_debug_sync(struct tokutxn *txn, const char *sync_point_name) { void *client_extra; THD *thd; - if (likely(!opt_debug_sync_timeout)) - return; - toku_txn_get_client_id(txn, &client_id, &client_extra); thd = reinterpret_cast(client_extra); DEBUG_SYNC(thd, sync_point_name); diff --git a/storage/tokudb/PerconaFT/portability/toku_pthread.h b/storage/tokudb/PerconaFT/portability/toku_pthread.h index e3bd3bce598..a0dfcc246a7 100644 --- a/storage/tokudb/PerconaFT/portability/toku_pthread.h +++ b/storage/tokudb/PerconaFT/portability/toku_pthread.h @@ -162,10 +162,20 @@ typedef struct toku_mutex_aligned { #define ZERO_COND_INITIALIZER \ { 0 } #elif defined(__APPLE__) +#if TOKU_PTHREAD_DEBUG +#define ZERO_COND_INITIALIZER \ + { \ + { 0 , { 0 } }, \ + nullptr, \ + 0 \ + } +#else #define ZERO_COND_INITIALIZER \ { \ - { 0 } \ + { 0 , { 0 } }, \ + nullptr \ } +#endif #else // __linux__, at least #define ZERO_COND_INITIALIZER \ {} diff --git a/storage/tokudb/PerconaFT/src/CMakeLists.txt b/storage/tokudb/PerconaFT/src/CMakeLists.txt index 65bf4814cf8..bae37389004 100644 --- a/storage/tokudb/PerconaFT/src/CMakeLists.txt +++ b/storage/tokudb/PerconaFT/src/CMakeLists.txt @@ -18,7 +18,7 @@ set(tokudb_srcs ## make the shared library add_library(${LIBTOKUDB} SHARED ${tokudb_srcs}) add_dependencies(${LIBTOKUDB} install_tdb_h generate_log_code) -target_link_libraries(${LIBTOKUDB} LINK_PRIVATE locktree_static ft_static util_static lzma snappy ${LIBTOKUPORTABILITY}) +target_link_libraries(${LIBTOKUDB} LINK_PRIVATE locktree_static ft_static util_static lzma snappy dbug ${LIBTOKUPORTABILITY}) target_link_libraries(${LIBTOKUDB} LINK_PUBLIC ${ZLIB_LIBRARY} ) ## make the static library diff --git a/storage/tokudb/tokudb_thread.h b/storage/tokudb/tokudb_thread.h index dec58f3fd35..5df0159901f 100644 --- a/storage/tokudb/tokudb_thread.h +++ b/storage/tokudb/tokudb_thread.h @@ -111,7 +111,6 @@ public: // wait for the event to become signalled void wait(void); - int wait(ulonglong microseconds); // signal the event void signal(void); @@ -152,7 +151,6 @@ public: // wait for the semaphore to become signalled E_WAIT wait(void); - E_WAIT wait(ulonglong microseconds); // signal the semaphore to increase the count // return true if signalled, false if ignored due to count @@ -372,28 +370,6 @@ inline void event_t::wait(void) { assert_debug(r == 0); return; } -inline int event_t::wait(ulonglong microseconds) { - timespec waittime = time::offset_timespec(microseconds); - int r = pthread_mutex_timedlock(&_mutex, &waittime); - if (r == ETIMEDOUT) return ETIMEDOUT; - assert_debug(r == 0); - while (_signalled == false && _pulsed == false) { - r = pthread_cond_timedwait(&_cond, &_mutex, &waittime); - if (r == ETIMEDOUT) { - r = pthread_mutex_unlock(&_mutex); - assert_debug(r == 0); - return ETIMEDOUT; - } - assert_debug(r == 0); - } - if (_manual_reset == false) - _signalled = false; - if (_pulsed) - _pulsed = false; - r = pthread_mutex_unlock(&_mutex); - assert_debug(r == 0); - return 0; -} inline void event_t::signal(void) { int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex); assert_debug(r == 0); @@ -479,31 +455,6 @@ inline semaphore_t::E_WAIT semaphore_t::wait(void) { assert_debug(r == 0); return ret; } -inline semaphore_t::E_WAIT semaphore_t::wait(ulonglong microseconds) { - E_WAIT ret; - timespec waittime = time::offset_timespec(microseconds); - int r = pthread_mutex_timedlock(&_mutex, &waittime); - if (r == ETIMEDOUT) return E_TIMEDOUT; - assert_debug(r == 0); - while (_signalled == 0 && _interrupted == false) { - r = pthread_cond_timedwait(&_cond, &_mutex, &waittime); - if (r == ETIMEDOUT) { - r = pthread_mutex_unlock(&_mutex); - assert_debug(r == 0); - return E_TIMEDOUT; - } - assert_debug(r == 0); - } - if (_interrupted) { - ret = E_INTERRUPTED; - } else { - _signalled--; - ret = E_SIGNALLED; - } - r = pthread_mutex_unlock(&_mutex); - assert_debug(r == 0); - return ret; -} inline bool semaphore_t::signal(void) { bool ret = false; int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex); -- cgit v1.2.1 From 814a284f22b617e2d1ced74ba10d1a870ee6267b Mon Sep 17 00:00:00 2001 From: Teodor Mircea Ionita Date: Thu, 12 Apr 2018 13:33:39 +0300 Subject: Ignore .cbp QtCreator && CodeBlocks project files --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 4e3d2a1e66e..0e00a27cbf0 100644 --- a/.gitignore +++ b/.gitignore @@ -236,3 +236,6 @@ storage/mroonga/vendor/groonga/src/grnslap storage/mroonga/vendor/groonga/src/groonga storage/mroonga/vendor/groonga/src/groonga-benchmark storage/mroonga/vendor/groonga/src/suggest/groonga-suggest-create-dataset + +# QtCreator && CodeBlocks +*.cbp -- cgit v1.2.1 From 0e6d6354bf32ac26d36a5a1bb854f2b22de3a494 Mon Sep 17 00:00:00 2001 From: Teodor Mircea Ionita Date: Tue, 15 May 2018 10:25:47 +0300 Subject: Also ignore macOS .DS_Store Finder junk. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 0e00a27cbf0..5f2bf5a0fcd 100644 --- a/.gitignore +++ b/.gitignore @@ -237,5 +237,8 @@ storage/mroonga/vendor/groonga/src/groonga storage/mroonga/vendor/groonga/src/groonga-benchmark storage/mroonga/vendor/groonga/src/suggest/groonga-suggest-create-dataset +# macOS garbage +.DS_Store + # QtCreator && CodeBlocks *.cbp -- cgit v1.2.1 From d39629f01ebdd5b89186e6c8a4a8d3dd528bd26a Mon Sep 17 00:00:00 2001 From: Teodor Mircea Ionita Date: Mon, 7 May 2018 22:40:27 +0300 Subject: MDEV-16075: Workaround to run MTR test suite for make test Assign all tests added via MY_ADD_TEST to a bogus default_ignore target, so that they are not ran by default when doing bare make test. Add default test named MTR that calls mysql-test-run suite, which is now the single test run by make test. In consequence, modified unit/suite.pm to exclude the MTR test and run the real ctests flagged for default_ignore target, thus no circular loop. --- CMakeLists.txt | 4 ++++ cmake/ctest.cmake | 2 +- mysql-test/suite/unit/suite.pm | 2 +- unittest/sql/CMakeLists.txt | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ab17ebf64c..21ed1fcc24b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -366,6 +366,10 @@ INCLUDE(maintainer) IF(WITH_UNIT_TESTS) ENABLE_TESTING() + # This is the only instance where ADD_TEST should be used, + # to make sure that make test will run MTR, + # use MY_ADD_TEST macro to add other tests + ADD_TEST(NAME MTR COMMAND ./mysql-test-run WORKING_DIRECTORY "mysql-test") ADD_SUBDIRECTORY(unittest/mytap) ADD_SUBDIRECTORY(unittest/strings) ADD_SUBDIRECTORY(unittest/examples) diff --git a/cmake/ctest.cmake b/cmake/ctest.cmake index 08852a366f6..fde7e1632f6 100644 --- a/cmake/ctest.cmake +++ b/cmake/ctest.cmake @@ -2,7 +2,7 @@ INCLUDE(${MYSQL_CMAKE_SCRIPT_DIR}/cmake_parse_arguments.cmake) MACRO(MY_ADD_TEST name) - ADD_TEST(${name} ${name}-t) + ADD_TEST(NAME ${name} COMMAND ${name}-t CONFIGURATIONS default_ignore) ENDMACRO() MACRO (MY_ADD_TESTS) diff --git a/mysql-test/suite/unit/suite.pm b/mysql-test/suite/unit/suite.pm index 78d82ccb31d..43eaa970350 100644 --- a/mysql-test/suite/unit/suite.pm +++ b/mysql-test/suite/unit/suite.pm @@ -31,7 +31,7 @@ sub start_test { return "Not run for embedded server" if $::opt_embedded_server; return "Not configured to run ctest" unless -f "../CTestTestfile.cmake"; my ($ctest_vs)= $opt_vs_config ? "--build-config $opt_vs_config" : ""; - my (@ctest_list)= `cd .. && ctest $opt_vs_config --show-only --verbose`; + my (@ctest_list)= `cd .. && ctest $opt_vs_config -E MTR -C default_ignore --show-only --verbose`; return "No ctest" if $?; my ($command, %tests); diff --git a/unittest/sql/CMakeLists.txt b/unittest/sql/CMakeLists.txt index f80f2a5ae70..1efb0ac9cd1 100644 --- a/unittest/sql/CMakeLists.txt +++ b/unittest/sql/CMakeLists.txt @@ -26,4 +26,4 @@ ELSE() ENDIF() TARGET_LINK_LIBRARIES(explain_filename-t sql mytap) -ADD_TEST(explain_filename explain_filename-t) +MY_ADD_TEST(explain_filename explain_filename-t) -- cgit v1.2.1 From 7fca4b50ffbe750532cfcdb95bcd425ec1b8e22b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Sun, 10 Jun 2018 15:20:43 +0300 Subject: Revert "MDEV-15778: Remove packed attr from omt_ and subtree_ classes" This reverts commit 1735fa340a9d7ca8683f18fe2ecc148423e78ba7. --- storage/tokudb/ft-index/util/omt.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/storage/tokudb/ft-index/util/omt.h b/storage/tokudb/ft-index/util/omt.h index 6cf3f80d2bc..02f3f0d759a 100644 --- a/storage/tokudb/ft-index/util/omt.h +++ b/storage/tokudb/ft-index/util/omt.h @@ -181,7 +181,7 @@ public: paranoid_invariant(index != NODE_NULL); m_index = index; } -} ; +} __attribute__((__packed__,aligned(4))); template<> class subtree_templated { @@ -238,7 +238,7 @@ public: inline void disable_bit(void) { m_bitfield &= MASK_INDEX; } -} ; +} __attribute__((__packed__)) ; template class omt_node_templated { @@ -251,7 +251,7 @@ public: // this needs to be in both implementations because we don't have // a "static if" the caller can use inline void clear_stolen_bits(void) {} -} ; +} __attribute__((__packed__,aligned(4))); template class omt_node_templated { @@ -288,7 +288,7 @@ public: this->unset_marked_bit(); this->unset_marks_below_bit(); } -} ; +} __attribute__((__packed__,aligned(4))); } -- cgit v1.2.1 From 21246066b296bd9c6e44272a8f93cb7dc73ea43c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Sun, 10 Jun 2018 15:54:57 +0300 Subject: Make TokuDB compile with GCC-8 GCC-8 introduced multiple warnings and increased the level of strictness. * -Wshadow will warn if a local variable shadows a typedef. * GCC will also warn when memsetting a non-trivial type. In this case a non-trivial type can not have a custom constructor. For all intents and purposes, the class is trivially-copyable. * GCC will also warn if you use too many paranthesses which are not necessary --- storage/tokudb/CMakeLists.txt | 6 ++++++ storage/tokudb/ft-index/portability/memory.h | 2 +- storage/tokudb/ft-index/tools/ba_replay.cc | 2 +- storage/tokudb/ft-index/util/dmt.cc | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt index 903471b097c..9bff7d4729f 100644 --- a/storage/tokudb/CMakeLists.txt +++ b/storage/tokudb/CMakeLists.txt @@ -17,6 +17,12 @@ IF(NOT LIBJEMALLOC) MESSAGE(WARNING "TokuDB is enabled, but jemalloc is not. This configuration is not supported") ENDIF() +CHECK_C_COMPILER_FLAG("-Wshadow" HAVE_WSHADOW) +IF (HAVE_WSHADOW) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-shadow") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-shadow") +ENDIF() + IF (HAVE_WVLA) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-vla") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-vla") diff --git a/storage/tokudb/ft-index/portability/memory.h b/storage/tokudb/ft-index/portability/memory.h index 837b0a70265..52e0c69575f 100644 --- a/storage/tokudb/ft-index/portability/memory.h +++ b/storage/tokudb/ft-index/portability/memory.h @@ -160,7 +160,7 @@ size_t toku_malloc_usable_size(void *p) __attribute__((__visibility__("default") #define XMALLOC(v) CAST_FROM_VOIDP(v, toku_xmalloc(sizeof(*v))) #define XMALLOC_N(n,v) CAST_FROM_VOIDP(v, toku_xmalloc((n)*sizeof(*v))) #define XCALLOC_N(n,v) CAST_FROM_VOIDP(v, toku_xcalloc((n), (sizeof(*v)))) -#define XCALLOC(v) XCALLOC_N(1,(v)) +#define XCALLOC(v) XCALLOC_N(1,v) #define XREALLOC(v,s) CAST_FROM_VOIDP(v, toku_xrealloc(v, s)) #define XREALLOC_N(n,v) CAST_FROM_VOIDP(v, toku_xrealloc(v, (n)*sizeof(*v))) diff --git a/storage/tokudb/ft-index/tools/ba_replay.cc b/storage/tokudb/ft-index/tools/ba_replay.cc index e274ac0a1e8..8f2bc3a02ec 100644 --- a/storage/tokudb/ft-index/tools/ba_replay.cc +++ b/storage/tokudb/ft-index/tools/ba_replay.cc @@ -638,7 +638,7 @@ int main(int argc, char *argv[]) { it == candidate_strategies.begin() ? &stats : &dummy_stats); struct fragmentation_report aggregate_report; - memset(&aggregate_report, 0, sizeof(aggregate_report)); + memset(static_cast(&aggregate_report), 0, sizeof(aggregate_report)); for (map::iterator rp = reports.begin(); rp != reports.end(); rp++) { const struct fragmentation_report &report = rp->second; diff --git a/storage/tokudb/ft-index/util/dmt.cc b/storage/tokudb/ft-index/util/dmt.cc index 3e0b512d7a7..1a7e2db9f40 100644 --- a/storage/tokudb/ft-index/util/dmt.cc +++ b/storage/tokudb/ft-index/util/dmt.cc @@ -132,8 +132,8 @@ void dmt::create_from_sorted_memory_of_fix paranoid_invariant(numvalues > 0); void *ptr = toku_mempool_malloc(&this->mp, aligned_memsize); paranoid_invariant_notnull(ptr); - uint8_t * const CAST_FROM_VOIDP(dest, ptr); - const uint8_t * const CAST_FROM_VOIDP(src, mem); + uint8_t * CAST_FROM_VOIDP(dest, ptr); + const uint8_t * CAST_FROM_VOIDP(src, mem); if (pad_bytes == 0) { paranoid_invariant(aligned_memsize == mem_length); memcpy(dest, src, aligned_memsize); -- cgit v1.2.1 From 953d70f960421ef4a6a2d711b66ef3d04592efc7 Mon Sep 17 00:00:00 2001 From: Teodor Mircea Ionita Date: Sun, 10 Jun 2018 16:37:49 +0300 Subject: MDEV-15778: Remove packed attr from omt_ and subtree_ classes Undo the revert that happened by mystake in commit 7fca4b50ffbe750532cfcdb95bcd425ec1b8e22b. --- storage/tokudb/ft-index/util/omt.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/storage/tokudb/ft-index/util/omt.h b/storage/tokudb/ft-index/util/omt.h index 02f3f0d759a..6cf3f80d2bc 100644 --- a/storage/tokudb/ft-index/util/omt.h +++ b/storage/tokudb/ft-index/util/omt.h @@ -181,7 +181,7 @@ public: paranoid_invariant(index != NODE_NULL); m_index = index; } -} __attribute__((__packed__,aligned(4))); +} ; template<> class subtree_templated { @@ -238,7 +238,7 @@ public: inline void disable_bit(void) { m_bitfield &= MASK_INDEX; } -} __attribute__((__packed__)) ; +} ; template class omt_node_templated { @@ -251,7 +251,7 @@ public: // this needs to be in both implementations because we don't have // a "static if" the caller can use inline void clear_stolen_bits(void) {} -} __attribute__((__packed__,aligned(4))); +} ; template class omt_node_templated { @@ -288,7 +288,7 @@ public: this->unset_marked_bit(); this->unset_marks_below_bit(); } -} __attribute__((__packed__,aligned(4))); +} ; } -- cgit v1.2.1 From 1d43f71c7b4c39a6fd196c104b5ebafb65376199 Mon Sep 17 00:00:00 2001 From: Rutuja Surve Date: Sun, 10 Jun 2018 11:19:39 +0300 Subject: MDEV-15021: mysqldump --tables --routines generates non importable dump file The order of outputting stored procedures is important. Stored procedures must be available on view creation, for views which make use of them. Make sure to print them before outputting tables. --- client/mysqldump.c | 12 ++++++------ mysql-test/r/mysqldump.result | 15 +++++++++++++++ mysql-test/t/mysqldump.test | 22 ++++++++++++++++++++++ 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 4e611ed5cb2..ad71a4dd0ce 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -4701,6 +4701,12 @@ static int dump_selected_tables(char *db, char **table_names, int tables) if (opt_xml) print_xml_tag(md_result_file, "", "\n", "database", "name=", db, NullS); + /* obtain dump of routines (procs/functions) */ + if (opt_routines && mysql_get_server_version(mysql) >= 50009) + { + DBUG_PRINT("info", ("Dumping routines for database %s", db)); + dump_routines_for_db(db); + } /* Dump each selected table */ for (pos= dump_tables; pos < end; pos++) { @@ -4729,12 +4735,6 @@ static int dump_selected_tables(char *db, char **table_names, int tables) DBUG_PRINT("info", ("Dumping events for database %s", db)); dump_events_for_db(db); } - /* obtain dump of routines (procs/functions) */ - if (opt_routines && mysql_get_server_version(mysql) >= 50009) - { - DBUG_PRINT("info", ("Dumping routines for database %s", db)); - dump_routines_for_db(db); - } free_root(&root, MYF(0)); my_free(order_by); order_by= 0; diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 68de653742c..99b14189282 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -5401,3 +5401,18 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; ALTER DATABASE `a\"'``b` CHARACTER SET utf8 COLLATE utf8_general_ci ; DROP DATABASE `a\"'``b`; +# +# MDEV-15021: Fix the order in which routines are called +# +use test; +CREATE FUNCTION f() RETURNS INT RETURN 1; +CREATE VIEW v1 AS SELECT f(); +# Running mysqldump -uroot test --routines --tables v1 > **vardir**/test.dmp +DROP VIEW v1; +DROP FUNCTION f; +# Running mysql -uroot test < **vardir**/test.dmp +# +# Cleanup after succesful import. +# +DROP VIEW v1; +DROP FUNCTION f; diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 39ca5b3c58e..cb12919a823 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -2567,3 +2567,25 @@ let SEARCH_FILE=$MYSQLTEST_VARDIR/tmp/bug11505.sql; let SEARCH_PATTERN=Database: mysql; exec $MYSQL_DUMP mysql func > $SEARCH_FILE; source include/search_pattern_in_file.inc; + +--echo # +--echo # MDEV-15021: Fix the order in which routines are called +--echo # +use test; +CREATE FUNCTION f() RETURNS INT RETURN 1; +CREATE VIEW v1 AS SELECT f(); + +--echo # Running mysqldump -uroot test --routines --tables v1 > **vardir**/test.dmp +--exec $MYSQL_DUMP -uroot test --routines --tables v1 > $MYSQLTEST_VARDIR/test.dmp + +DROP VIEW v1; +DROP FUNCTION f; + +--echo # Running mysql -uroot test < **vardir**/test.dmp +--exec $MYSQL -uroot test < $MYSQLTEST_VARDIR/test.dmp + +--echo # +--echo # Cleanup after succesful import. +--echo # +DROP VIEW v1; +DROP FUNCTION f; -- cgit v1.2.1 From 719ed09e5e96b53467ede331631de641f98a348f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Sun, 10 Jun 2018 18:25:11 +0300 Subject: Update test results post-merge --- mysql-test/r/limit.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/r/limit.result b/mysql-test/r/limit.result index deb4ca2ab95..6c295bb86af 100644 --- a/mysql-test/r/limit.result +++ b/mysql-test/r/limit.result @@ -154,7 +154,7 @@ SELECT * FROM mysql.slow_log WHERE sql_text != 'foo' LIMIT 0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Zero limit SELECT * FROM mysql.slow_log WHERE sql_text != 'foo' LIMIT 0; -start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text +start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text thread_id EXPLAIN SELECT * FROM mysql.help_topic WHERE help_category_id != example LIMIT 0; id select_type table type possible_keys key key_len ref rows Extra -- cgit v1.2.1 From e5a3d24b876a266c67b9a6f4390ae31435ec746d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Sun, 10 Jun 2018 21:45:05 +0300 Subject: Followup for make TokuDB compile with GCC-8 Missed printfs from: 21246066b296bd9c6e44272a8f93cb7dc73ea43c --- storage/tokudb/PerconaFT/ft/ft-ops.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/tokudb/PerconaFT/ft/ft-ops.cc b/storage/tokudb/PerconaFT/ft/ft-ops.cc index d7ea5efdff5..eb8696423ca 100644 --- a/storage/tokudb/PerconaFT/ft/ft-ops.cc +++ b/storage/tokudb/PerconaFT/ft/ft-ops.cc @@ -826,7 +826,7 @@ int toku_ftnode_fetch_callback(CACHEFILE UU(cachefile), __FILE__, __LINE__, toku_cachefile_fname_in_env(cachefile), - blocknum.b); + (longlong)blocknum.b); } else { fprintf( stderr, @@ -836,7 +836,7 @@ int toku_ftnode_fetch_callback(CACHEFILE UU(cachefile), __FILE__, __LINE__, toku_cachefile_fname_in_env(cachefile), - blocknum.b, + (longlong)blocknum.b, r); } // make absolutely sure we crash before doing anything else. -- cgit v1.2.1 From 24d7cbe1e0a16f75e2325c84f23531742e2a035d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Sun, 10 Jun 2018 16:26:57 +0300 Subject: Ensure TokuDB compiles both on Linux and OS X On OS X, (u)int64_t is defined as (unsigned) long long int while on 74 bit Linux it is defined as (unsigned) long int. Ensure the type matches when doing printf on all systems. --- .../tokudb/PerconaFT/ft/serialize/ft-serialize.cc | 10 ++-- .../PerconaFT/ft/serialize/ft_node-serialize.cc | 58 +++++++++++----------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc b/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc index fe68e1b20e0..0d6573972d7 100644 --- a/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc +++ b/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc @@ -663,13 +663,13 @@ exit: __LINE__, \ fn, \ r, \ - max_acceptable_lsn.lsn, \ + (ulonglong)max_acceptable_lsn.lsn, \ r0, \ - checkpoint_lsn_0.lsn, \ - checkpoint_count_0, \ + (ulonglong)checkpoint_lsn_0.lsn, \ + (ulonglong)checkpoint_count_0, \ r1, \ - checkpoint_lsn_1.lsn, \ - checkpoint_count_1); + (ulonglong)checkpoint_lsn_1.lsn, \ + (ulonglong)checkpoint_count_1); int toku_deserialize_ft_from(int fd, const char *fn, diff --git a/storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc b/storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc index 02d0cc691cd..46bb8f81412 100644 --- a/storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc +++ b/storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc @@ -1174,7 +1174,7 @@ int verify_ftnode_sub_block(struct sub_block *sb, __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, stored_xsum, actual_xsum); dump_bad_block((Bytef *) sb->uncompressed_ptr, sb->uncompressed_size); @@ -1201,7 +1201,7 @@ static int deserialize_ftnode_info(struct sub_block *sb, FTNODE node) { __FILE__, __LINE__, fname ? fname : "unknown", - node->blocknum.b, + (longlong)node->blocknum.b, r); dump_bad_block(static_cast(sb->uncompressed_ptr), sb->uncompressed_size); @@ -1257,7 +1257,7 @@ static int deserialize_ftnode_info(struct sub_block *sb, FTNODE node) { __FILE__, __LINE__, fname ? fname : "unknown", - node->blocknum.b, + (longlong)node->blocknum.b, data_size, rb.ndone); dump_bad_block(rb.buf, rb.size); @@ -1393,7 +1393,7 @@ static int deserialize_ftnode_partition( __FILE__, __LINE__, fname ? fname : "unknown", - node->blocknum.b, + (longlong)node->blocknum.b, r); goto exit; } @@ -1415,7 +1415,7 @@ static int deserialize_ftnode_partition( __FILE__, __LINE__, fname ? fname : "unknown", - node->blocknum.b, + (longlong)node->blocknum.b, ch, FTNODE_PARTITION_MSG_BUFFER); dump_bad_block(rb.buf, rb.size); @@ -1438,7 +1438,7 @@ static int deserialize_ftnode_partition( __FILE__, __LINE__, fname ? fname : "unknown", - node->blocknum.b, + (longlong)node->blocknum.b, ch, FTNODE_PARTITION_DMT_LEAVES); dump_bad_block(rb.buf, rb.size); @@ -1461,7 +1461,7 @@ static int deserialize_ftnode_partition( __FILE__, __LINE__, fname ? fname : "unknown", - node->blocknum.b, + (longlong)node->blocknum.b, rb.ndone, rb.size); dump_bad_block(rb.buf, rb.size); @@ -1490,7 +1490,7 @@ static int decompress_and_deserialize_worker(struct rbuf curr_rbuf, __FILE__, __LINE__, fname ? fname : "unknown", - node->blocknum.b, + (longlong)node->blocknum.b, r); dump_bad_block(curr_rbuf.buf, curr_rbuf.size); goto exit; @@ -1507,7 +1507,7 @@ static int decompress_and_deserialize_worker(struct rbuf curr_rbuf, __FILE__, __LINE__, fname ? fname : "unknown", - node->blocknum.b, + (longlong)node->blocknum.b, r); dump_bad_block(curr_rbuf.buf, curr_rbuf.size); goto exit; @@ -1586,7 +1586,7 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, rb->size); dump_bad_block(rb->buf, rb->size); // TODO: What error do we return here? @@ -1607,7 +1607,7 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, static_cast(magic)[0], static_cast(magic)[1], static_cast(magic)[2], @@ -1632,7 +1632,7 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, node->layout_version_read_from_disk, FT_FIRST_LAYOUT_VERSION_WITH_BASEMENT_NODES); dump_bad_block(rb->buf, rb->size); @@ -1671,7 +1671,7 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, needed_size, rb->size); dump_bad_block(rb->buf, rb->size); @@ -1699,7 +1699,7 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, stored_checksum, checksum); dump_bad_block(rb->buf, rb->size); @@ -1722,7 +1722,7 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, rb->size, rb->ndone, sb_node_info.compressed_size); @@ -1748,7 +1748,7 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, sb_node_info.xsum, actual_xsum); dump_bad_block(rb->buf, rb->size); @@ -1779,7 +1779,7 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, r); dump_bad_block( static_cast(sb_node_info.uncompressed_ptr), @@ -1817,7 +1817,7 @@ static int deserialize_ftnode_header_from_rbuf_if_small_enough( __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, r); dump_bad_block(rb->buf, rb->size); goto cleanup; @@ -2169,7 +2169,7 @@ static int deserialize_and_upgrade_ftnode(FTNODE node, __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, r); goto exit; } @@ -2195,7 +2195,7 @@ static int deserialize_and_upgrade_ftnode(FTNODE node, __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, version, FT_LAYOUT_VERSION_14); dump_bad_block(rb.buf, rb.size); @@ -2283,7 +2283,7 @@ static int deserialize_ftnode_from_rbuf(FTNODE *ftnode, __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, static_cast(magic)[0], static_cast(magic)[1], static_cast(magic)[2], @@ -2314,7 +2314,7 @@ static int deserialize_ftnode_from_rbuf(FTNODE *ftnode, __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, r); dump_bad_block(rb->buf, rb->size); goto cleanup; @@ -2359,7 +2359,7 @@ static int deserialize_ftnode_from_rbuf(FTNODE *ftnode, __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, stored_checksum, checksum); dump_bad_block(rb->buf, rb->size); @@ -2382,7 +2382,7 @@ static int deserialize_ftnode_from_rbuf(FTNODE *ftnode, __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, r); dump_bad_block( static_cast(sb_node_info.uncompressed_ptr), @@ -2403,7 +2403,7 @@ static int deserialize_ftnode_from_rbuf(FTNODE *ftnode, __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, r); dump_bad_block(rb->buf, rb->size); goto cleanup; @@ -2475,7 +2475,7 @@ static int deserialize_ftnode_from_rbuf(FTNODE *ftnode, __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, i, r); dump_bad_block(rb->buf, rb->size); @@ -2496,7 +2496,7 @@ static int deserialize_ftnode_from_rbuf(FTNODE *ftnode, __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, i, r); dump_bad_block(rb->buf, rb->size); @@ -2646,7 +2646,7 @@ int toku_deserialize_bp_from_compressed(FTNODE node, __FILE__, __LINE__, fname ? fname : "unknown", - node->blocknum.b, + (longlong)node->blocknum.b, r); dump_bad_block(static_cast(curr_sb->compressed_ptr), curr_sb->compressed_size); @@ -2694,7 +2694,7 @@ static int deserialize_ftnode_from_fd(int fd, __FILE__, __LINE__, fname ? fname : "unknown", - blocknum.b, + (longlong)blocknum.b, r); dump_bad_block(rb.buf, rb.size); } -- cgit v1.2.1 From e7ca377cb73a64e40832e9306194412fb07b8fa5 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 5 Jun 2018 15:21:45 +0200 Subject: MDEV-16342 SHOW ENGINES: MyISAM description is useless rewrite tautological engine descriptions --- mysql-test/r/information_schema.result | 2 +- mysql-test/suite/federated/have_federatedx.inc | 2 +- mysql-test/suite/funcs_1/r/is_engines_archive.result | 2 +- mysql-test/suite/funcs_1/r/is_engines_csv.result | 2 +- mysql-test/suite/funcs_1/r/is_engines_federated.result | 2 +- mysql-test/suite/funcs_1/r/is_engines_myisam.result | 2 +- storage/archive/ha_archive.cc | 2 +- storage/csv/ha_tina.cc | 2 +- storage/federated/ha_federated.cc | 2 +- storage/federatedx/ha_federatedx.cc | 2 +- storage/myisam/ha_myisam.cc | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 1f765a70137..dfa7b12562d 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1387,7 +1387,7 @@ USE test; End of 5.0 tests. select * from information_schema.engines WHERE ENGINE="MyISAM"; ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS -MyISAM DEFAULT MyISAM storage engine NO NO NO +MyISAM DEFAULT Non-transactional engine with good performance and small data footprint NO NO NO grant select on *.* to user3148@localhost; select user,db from information_schema.processlist; user db diff --git a/mysql-test/suite/federated/have_federatedx.inc b/mysql-test/suite/federated/have_federatedx.inc index 56ce31f5b2f..2250dd205bd 100644 --- a/mysql-test/suite/federated/have_federatedx.inc +++ b/mysql-test/suite/federated/have_federatedx.inc @@ -1,5 +1,5 @@ if (!`SELECT count(*) FROM information_schema.plugins WHERE plugin_name = 'federated' AND plugin_status = 'active' AND - plugin_description LIKE '%FederatedX%'`){ + plugin_description LIKE '%transactions%'`){ skip Need FederatedX engine; } diff --git a/mysql-test/suite/funcs_1/r/is_engines_archive.result b/mysql-test/suite/funcs_1/r/is_engines_archive.result index 2772992495c..52802b17acd 100644 --- a/mysql-test/suite/funcs_1/r/is_engines_archive.result +++ b/mysql-test/suite/funcs_1/r/is_engines_archive.result @@ -2,7 +2,7 @@ SELECT * FROM information_schema.engines WHERE ENGINE = 'ARCHIVE'; ENGINE ARCHIVE SUPPORT YES -COMMENT Archive storage engine +COMMENT gzip-compresses tables for a low storage footprint TRANSACTIONS NO XA NO SAVEPOINTS NO diff --git a/mysql-test/suite/funcs_1/r/is_engines_csv.result b/mysql-test/suite/funcs_1/r/is_engines_csv.result index 2a7e61ee4d3..7e413b9af6f 100644 --- a/mysql-test/suite/funcs_1/r/is_engines_csv.result +++ b/mysql-test/suite/funcs_1/r/is_engines_csv.result @@ -2,7 +2,7 @@ SELECT * FROM information_schema.engines WHERE ENGINE = 'CSV'; ENGINE CSV SUPPORT YES -COMMENT CSV storage engine +COMMENT Stores tables as CSV files TRANSACTIONS NO XA NO SAVEPOINTS NO diff --git a/mysql-test/suite/funcs_1/r/is_engines_federated.result b/mysql-test/suite/funcs_1/r/is_engines_federated.result index 8057a0266c5..20926458ed0 100644 --- a/mysql-test/suite/funcs_1/r/is_engines_federated.result +++ b/mysql-test/suite/funcs_1/r/is_engines_federated.result @@ -2,7 +2,7 @@ SELECT * FROM information_schema.engines WHERE ENGINE = 'FEDERATED'; ENGINE FEDERATED SUPPORT YES -COMMENT FederatedX pluggable storage engine +COMMENT Allows to access tables on other MariaDB servers, supports transactions and more TRANSACTIONS YES XA NO SAVEPOINTS YES diff --git a/mysql-test/suite/funcs_1/r/is_engines_myisam.result b/mysql-test/suite/funcs_1/r/is_engines_myisam.result index 7e42c864187..d307ce4be6a 100644 --- a/mysql-test/suite/funcs_1/r/is_engines_myisam.result +++ b/mysql-test/suite/funcs_1/r/is_engines_myisam.result @@ -2,7 +2,7 @@ SELECT * FROM information_schema.engines WHERE ENGINE = 'MyISAM'; ENGINE MyISAM SUPPORT DEFAULT -COMMENT MyISAM storage engine +COMMENT Non-transactional engine with good performance and small data footprint TRANSACTIONS NO XA NO SAVEPOINTS NO diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index d39d1187ce6..3b8e58134b0 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -1840,7 +1840,7 @@ maria_declare_plugin(archive) &archive_storage_engine, "ARCHIVE", "Brian Aker, MySQL AB", - "Archive storage engine", + "gzip-compresses tables for a low storage footprint", PLUGIN_LICENSE_GPL, archive_db_init, /* Plugin Init */ archive_db_done, /* Plugin Deinit */ diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc index 54a85ec3a44..fe39d0e2fa6 100644 --- a/storage/csv/ha_tina.cc +++ b/storage/csv/ha_tina.cc @@ -1800,7 +1800,7 @@ maria_declare_plugin(csv) &csv_storage_engine, "CSV", "Brian Aker, MySQL AB", - "CSV storage engine", + "Stores tables as CSV files", PLUGIN_LICENSE_GPL, tina_init_func, /* Plugin Init */ tina_done_func, /* Plugin Deinit */ diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index 8680c3aac25..c621653f9f0 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -3503,7 +3503,7 @@ maria_declare_plugin(federated) &federated_storage_engine, "FEDERATED", "Patrick Galbraith and Brian Aker, MySQL AB", - "Federated MySQL storage engine", + "Allows to access tables on other MariaDB servers", PLUGIN_LICENSE_GPL, federated_db_init, /* Plugin Init */ federated_done, /* Plugin Deinit */ diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc index bafae614fab..647cc57e101 100644 --- a/storage/federatedx/ha_federatedx.cc +++ b/storage/federatedx/ha_federatedx.cc @@ -3608,7 +3608,7 @@ maria_declare_plugin(federatedx) &federatedx_storage_engine, "FEDERATED", "Patrick Galbraith", - "FederatedX pluggable storage engine", + "Allows to access tables on other MariaDB servers, supports transactions and more", PLUGIN_LICENSE_GPL, federatedx_db_init, /* Plugin Init */ federatedx_done, /* Plugin Deinit */ diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index f63b9c85372..4305fab1778 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -2346,7 +2346,7 @@ maria_declare_plugin(myisam) &myisam_storage_engine, "MyISAM", "MySQL AB", - "MyISAM storage engine", + "Non-transactional engine with good performance and small data footprint", PLUGIN_LICENSE_GPL, myisam_init, /* Plugin Init */ NULL, /* Plugin Deinit */ -- cgit v1.2.1 From 6da8192174f033c2958ddafb2a15c14360bb1ecc Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 10 Jun 2018 17:23:53 +0200 Subject: mysqltest: Allow HANDLER READ in --ps-protocol tests adjust tests --- client/mysqltest.cc | 1 + mysql-test/r/lock.result | 2 +- mysql-test/suite/handler/handler.inc | 2 ++ mysql-test/suite/handler/interface.result | 2 +- mysql-test/suite/handler/interface.test | 2 +- mysql-test/t/lock.test | 2 +- 6 files changed, 7 insertions(+), 4 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 98e35136b2a..43dbff981d3 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -8672,6 +8672,7 @@ void init_re(void) "[[:space:]]*SELECT[[:space:]]|" "[[:space:]]*CREATE[[:space:]]+TABLE[[:space:]]|" "[[:space:]]*DO[[:space:]]|" + "[[:space:]]*HANDLER[[:space:]]+.*[[:space:]]+READ[[:space:]]|" "[[:space:]]*SET[[:space:]]+OPTION[[:space:]]|" "[[:space:]]*DELETE[[:space:]]+MULTI[[:space:]]|" "[[:space:]]*UPDATE[[:space:]]+MULTI[[:space:]]|" diff --git a/mysql-test/r/lock.result b/mysql-test/r/lock.result index 501c379b257..0dcc0de828f 100644 --- a/mysql-test/r/lock.result +++ b/mysql-test/r/lock.result @@ -407,7 +407,7 @@ LOCK TABLE t1 WRITE; HANDLER t1 OPEN; ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction HANDLER t1 READ FIRST; -ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction +Got one of the listed errors HANDLER t1 CLOSE; ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction UNLOCK TABLES; diff --git a/mysql-test/suite/handler/handler.inc b/mysql-test/suite/handler/handler.inc index 5b2dd5ef7e9..bfc21a3b2c3 100644 --- a/mysql-test/suite/handler/handler.inc +++ b/mysql-test/suite/handler/handler.inc @@ -377,7 +377,9 @@ send optimize table t1; # client 1 --echo proceed with the normal connection connection default; +--disable_ps_protocol handler t1 read next; +--enable_ps_protocol handler t1 close; # client 2 --echo read the result from the other connection diff --git a/mysql-test/suite/handler/interface.result b/mysql-test/suite/handler/interface.result index fb633bb94c4..c9cffba33f7 100644 --- a/mysql-test/suite/handler/interface.result +++ b/mysql-test/suite/handler/interface.result @@ -269,7 +269,7 @@ handler t1 open; lock table t1 write; alter table t1 engine=csv; handler t1 read a next; -ERROR HY000: Table storage engine for 't1' doesn't have this option +Got one of the listed errors handler t1 close; unlock tables; drop table t1; diff --git a/mysql-test/suite/handler/interface.test b/mysql-test/suite/handler/interface.test index 2ef617c3ce7..06797ed6980 100644 --- a/mysql-test/suite/handler/interface.test +++ b/mysql-test/suite/handler/interface.test @@ -326,7 +326,7 @@ let $wait_condition= info = "alter table t1 engine=csv"; --source include/wait_condition.inc connection default; ---error ER_ILLEGAL_HA +--error ER_ILLEGAL_HA,ER_KEY_DOES_NOT_EXITS handler t1 read a next; handler t1 close; connection con1; diff --git a/mysql-test/t/lock.test b/mysql-test/t/lock.test index 78f0e2ecf8d..6cfaf9fc320 100644 --- a/mysql-test/t/lock.test +++ b/mysql-test/t/lock.test @@ -481,7 +481,7 @@ LOCK TABLE t1 WRITE; --echo # HANDLER commands are not allowed in LOCK TABLES mode --error ER_LOCK_OR_ACTIVE_TRANSACTION HANDLER t1 OPEN; ---error ER_LOCK_OR_ACTIVE_TRANSACTION +--error ER_LOCK_OR_ACTIVE_TRANSACTION,ER_UNKNOWN_TABLE HANDLER t1 READ FIRST; --error ER_LOCK_OR_ACTIVE_TRANSACTION HANDLER t1 CLOSE; -- cgit v1.2.1 From ca733d03c82b02cd842ff2a226fee7b12eb86f8d Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 10 Jun 2018 21:19:11 +0200 Subject: MDEV-15729 Server crashes in Field::make_field upon HANDLER READ executed with PS protocol update table->pos_in_table_list during prepare, just like it's done in normal execution. otherwise it'll be a dangling pointer --- mysql-test/suite/handler/ps.result | 9 +++++++++ mysql-test/suite/handler/ps.test | 11 +++++++++++ sql/sql_handler.cc | 1 + 3 files changed, 21 insertions(+) create mode 100644 mysql-test/suite/handler/ps.result create mode 100644 mysql-test/suite/handler/ps.test diff --git a/mysql-test/suite/handler/ps.result b/mysql-test/suite/handler/ps.result new file mode 100644 index 00000000000..54685f9156b --- /dev/null +++ b/mysql-test/suite/handler/ps.result @@ -0,0 +1,9 @@ +create table t1 (i int); +handler test.t1 open handler_a; +flush status; +handler handler_a read first; +i +show status like 'Com_stmt_prepare%'; +Variable_name Value +Com_stmt_prepare OK +drop table t1; diff --git a/mysql-test/suite/handler/ps.test b/mysql-test/suite/handler/ps.test new file mode 100644 index 00000000000..68091190c85 --- /dev/null +++ b/mysql-test/suite/handler/ps.test @@ -0,0 +1,11 @@ +# +# MDEV-15729 Server crashes in Field::make_field upon HANDLER READ executed with PS protocol +# +create table t1 (i int); +handler test.t1 open handler_a; +flush status; +handler handler_a read first; +# handler...read must be prepared in --ps-protocol mode +--replace_result $PS_PROTOCOL OK +show status like 'Com_stmt_prepare%'; +drop table t1; diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index f5c79e59bf2..778507ebc38 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -980,6 +980,7 @@ SQL_HANDLER *mysql_ha_read_prepare(THD *thd, TABLE_LIST *tables, if (!(handler= mysql_ha_find_handler(thd, tables->alias))) DBUG_RETURN(0); tables->table= handler->table; // This is used by fix_fields + handler->table->pos_in_table_list= tables; if (mysql_ha_fix_cond_and_key(handler, mode, keyname, key_expr, cond, 1)) DBUG_RETURN(0); DBUG_RETURN(handler); -- cgit v1.2.1 From 147744d455d57c753ca75fccca106d3326d251ab Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Mon, 11 Jun 2018 08:52:26 -0700 Subject: MDEV-16235 Server crashes in my_utf8_uni or in my_strtod_int upon SELECT .. LIMIT 0 (new variant) This is another attempt to fix the problem of mdev-14515. --- mysql-test/r/having.result | 11 +++++++++++ mysql-test/r/subselect4.result | 4 ++-- mysql-test/t/having.test | 9 +++++++++ sql/opt_subselect.cc | 3 ++- sql/sql_select.cc | 1 - 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result index 18915da1a09..9e0466efb9f 100644 --- a/mysql-test/r/having.result +++ b/mysql-test/r/having.result @@ -712,3 +712,14 @@ a ct 4 2 set sql_mode=@save_sql_mode; drop table t1; +# +# mdev-16235: impossible HAVING in query without aggregation +# +explain extended +select * from mysql.help_topic where example = 'foo' having description is null; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING +Warnings: +Note 1003 select `mysql`.`help_topic`.`help_topic_id` AS `help_topic_id`,`mysql`.`help_topic`.`name` AS `name`,`mysql`.`help_topic`.`help_category_id` AS `help_category_id`,`mysql`.`help_topic`.`description` AS `description`,`mysql`.`help_topic`.`example` AS `example`,`mysql`.`help_topic`.`url` AS `url` from `mysql`.`help_topic` where (`mysql`.`help_topic`.`example` = 'foo') having 0 +select * from mysql.help_topic where example = 'foo' having description is null; +help_topic_id name help_category_id description example url diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result index 8973330c7da..f726bcfa15e 100644 --- a/mysql-test/r/subselect4.result +++ b/mysql-test/r/subselect4.result @@ -1056,7 +1056,7 @@ EXPLAIN SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE -2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10); f1 f2 SET @@optimizer_switch = 'materialization=off,in_to_exists=on,semijoin=off'; @@ -1147,7 +1147,7 @@ EXPLAIN SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE -2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10); f1 f2 set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test index a470f462d6a..c8bd47940cc 100644 --- a/mysql-test/t/having.test +++ b/mysql-test/t/having.test @@ -744,3 +744,12 @@ SELECT a, COUNT(a) as ct FROM t1 GROUP BY a HAVING ct>0; set sql_mode=@save_sql_mode; drop table t1; + +--echo # +--echo # mdev-16235: impossible HAVING in query without aggregation +--echo # + +explain extended +select * from mysql.help_topic where example = 'foo' having description is null; + +select * from mysql.help_topic where example = 'foo' having description is null; diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index a7edd64e68b..ec7b10f20c8 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -5880,6 +5880,7 @@ bool JOIN::choose_tableless_subquery_plan() functions produce empty subquery result. There is no need to further rewrite the subquery because it will not be executed at all. */ + exec_const_cond= 0; return FALSE; } @@ -5911,6 +5912,6 @@ bool JOIN::choose_tableless_subquery_plan() tmp_having= having; } } - exec_const_cond= conds; + exec_const_cond= zero_result_cause ? 0 : conds; return FALSE; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 016dd594e08..b79431ae2f6 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1147,7 +1147,6 @@ JOIN::optimize() { DBUG_PRINT("info", ("Zero limit")); zero_result_cause= "Zero limit"; - conds= 0; } table_count= top_join_tab_count= 0; error= 0; -- cgit v1.2.1 From e425216045c7a998139bd953b0aed83c3a085c8c Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 31 Jan 2018 09:35:38 +0100 Subject: MDEV-15113: Hang in Aria loghandler Added unregistering writers in case of log error. Added more debugging control about adding/removing writers to the buffers. --- storage/maria/ma_loghandler.c | 219 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 187 insertions(+), 32 deletions(-) diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index 2118b3b6ce6..7cca14d0785 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -78,6 +78,32 @@ typedef union uchar buffer[TRANSLOG_PAGE_SIZE]; } TRANSLOG_PAGE_SIZE_BUFF; +#define MAX_TRUNSLOG_USED_BUFFERS 3 + +typedef struct +{ + struct st_translog_buffer *buff[MAX_TRUNSLOG_USED_BUFFERS]; + uint8 wrt_ptr; + uint8 unlck_ptr; +} TRUNSLOG_USED_BUFFERS; + +static void +used_buffs_init(TRUNSLOG_USED_BUFFERS *buffs) +{ + buffs->unlck_ptr= buffs->wrt_ptr= 0; +} + +static void +used_buffs_add(TRUNSLOG_USED_BUFFERS *buffs, + struct st_translog_buffer *buff); + +static void +used_buffs_register_unlock(TRUNSLOG_USED_BUFFERS *buffs, + struct st_translog_buffer *buff); + +static void +used_buffs_urgent_unlock(TRUNSLOG_USED_BUFFERS *buffs); + /* min chunk length */ #define TRANSLOG_MIN_CHUNK 3 /* @@ -156,7 +182,28 @@ struct st_translog_buffer TRANSLOG_FILE *file; /* Threads which are waiting for buffer filling/freeing */ mysql_cond_t waiting_filling_buffer; - /* Number of records which are in copy progress */ + /* + Number of records which are in copy progress. + + Controlled via translog_buffer_increase_writers() and + translog_buffer_decrease_writers(). + + 1 Simple case: translog_force_current_buffer_to_finish both called in + the same procedure. + + 2 Simple case: translog_write_variable_record_1group: + translog_advance_pointer() increase writer of the buffer and + translog_buffer_decrease_writers() decrease it. + + Usual case: + 1) translog_advance_pointer (i.e. reserve place for future writing) + increase writers for all buffers where place reserved. + Simpliest case: just all space reserved in one buffer + complex case: end of the first buffer, all second buffer, beginning + of the third buffer. + 2) When we finish with writing translog_chaser_page_next() will be + called and unlock the buffer by decreasing number of writers. + */ uint copy_to_buffer_in_progress; /* list of waiting buffer ready threads */ struct st_my_thread_var *waiting_flush; @@ -214,6 +261,7 @@ struct st_translog_buffer struct st_buffer_cursor { + TRUNSLOG_USED_BUFFERS buffs; /* pointer into the buffer */ uchar *ptr; /* current buffer */ @@ -1663,15 +1711,12 @@ static my_bool translog_create_new_file() DBUG_PRINT("info", ("file_no: %lu", (ulong)file_no)); if (translog_write_file_header()) - DBUG_RETURN(1); + goto error; if (ma_control_file_write_and_force(last_checkpoint_lsn, file_no, max_trid_in_control_file, recovery_failures)) - { - translog_stop_writing(); - DBUG_RETURN(1); - } + goto error; DBUG_RETURN(0); @@ -1711,10 +1756,6 @@ static void translog_buffer_lock(struct st_translog_buffer *buffer) SYNOPSIS translog_buffer_unlock() buffer This buffer which should be unlocked - - RETURN - 0 OK - 1 Error */ static void translog_buffer_unlock(struct st_translog_buffer *buffer) @@ -1908,7 +1949,10 @@ static void translog_finish_page(TRANSLOG_ADDRESS *horizon, (ulong) cursor->buffer->size, (ulong) (cursor->ptr -cursor->buffer->buffer), (uint) cursor->current_page_fill, (uint) left)); - DBUG_ASSERT(LSN_FILE_NO(*horizon) == LSN_FILE_NO(cursor->buffer->offset)); + DBUG_ASSERT(LSN_FILE_NO(*horizon) == LSN_FILE_NO(cursor->buffer->offset) + || translog_status == TRANSLOG_UNINITED); + if ((LSN_FILE_NO(*horizon) != LSN_FILE_NO(cursor->buffer->offset))) + DBUG_VOID_RETURN; // everything wrong do not write to awoid more problems translog_check_cursor(cursor); if (cursor->protected) { @@ -4607,6 +4651,7 @@ static my_bool translog_chaser_page_next(TRANSLOG_ADDRESS *horizon, { translog_buffer_lock(buffer_to_flush); translog_buffer_decrease_writers(buffer_to_flush); + used_buffs_register_unlock(&cursor->buffs, buffer_to_flush); if (!rc) rc= translog_buffer_flush(buffer_to_flush); translog_buffer_unlock(buffer_to_flush); @@ -4711,7 +4756,8 @@ translog_write_variable_record_chunk3_page(struct st_translog_parts *parts, 1 Error */ -static my_bool translog_advance_pointer(int pages, uint16 last_page_data) +static my_bool translog_advance_pointer(int pages, uint16 last_page_data, + TRUNSLOG_USED_BUFFERS *buffs) { translog_size_t last_page_offset= (log_descriptor.page_overhead + last_page_data); @@ -4728,6 +4774,8 @@ static my_bool translog_advance_pointer(int pages, uint16 last_page_data) (uint) last_page_data)); translog_lock_assert_owner(); + used_buffs_init(buffs); + if (pages == -1) { /* @@ -4805,8 +4853,10 @@ static my_bool translog_advance_pointer(int pages, uint16 last_page_data) translog_wait_for_buffer_free(new_buffer); #ifndef DBUG_OFF /* We keep the handler locked so nobody can start this new buffer */ - DBUG_ASSERT(offset == new_buffer->offset && new_buffer->file == NULL && - (file == NULL ? ver : (uint8)(ver + 1)) == new_buffer->ver); + DBUG_ASSERT((offset == new_buffer->offset && new_buffer->file == NULL && + (file == NULL ? ver : (uint8)(ver + 1)) == + new_buffer->ver) || + translog_status == TRANSLOG_READONLY); } #endif @@ -4827,6 +4877,8 @@ static my_bool translog_advance_pointer(int pages, uint16 last_page_data) DBUG_ASSERT(log_descriptor.bc.buffer->buffer_no == log_descriptor.bc.buffer_no); translog_buffer_increase_writers(log_descriptor.bc.buffer); + // register for case of error + used_buffs_add(buffs, log_descriptor.bc.buffer); if (file_end_offset <= buffer_end_offset) { @@ -4837,6 +4889,10 @@ static my_bool translog_advance_pointer(int pages, uint16 last_page_data) (ulong) LSN_FILE_NO(log_descriptor.horizon))); if (translog_create_new_file()) { + struct st_translog_buffer *ob= log_descriptor.bc.buffer; + translog_buffer_unlock(ob); + used_buffs_urgent_unlock(buffs); + translog_buffer_lock(ob); DBUG_RETURN(1); } } @@ -4858,6 +4914,7 @@ end: log_descriptor.bc.ptr+= offset; log_descriptor.bc.buffer->size+= offset; translog_buffer_increase_writers(log_descriptor.bc.buffer); + used_buffs_add(buffs, log_descriptor.bc.buffer); log_descriptor.horizon+= offset; /* offset increasing */ log_descriptor.bc.current_page_fill= last_page_offset; DBUG_PRINT("info", ("NewP buffer #%u: 0x%lx chaser: %d Size: %lu (%lu) " @@ -4878,6 +4935,56 @@ end: DBUG_RETURN(0); } +static void +used_buffs_add(TRUNSLOG_USED_BUFFERS *buffs, + struct st_translog_buffer *buff) +{ + DBUG_ENTER("used_buffs_add"); + DBUG_PRINT("enter", ("ADD buffs: %p unlk %u (%p) wrt_ptr: %u (%p)" + " buff %p (%u)", + buffs, + buffs->wrt_ptr, buffs->buff[buffs->wrt_ptr], + buffs->unlck_ptr, buffs->buff[buffs->unlck_ptr], + buff, buff->buffer_no)); + DBUG_ASSERT(buffs->wrt_ptr < MAX_TRUNSLOG_USED_BUFFERS); + buffs->buff[buffs->wrt_ptr++]= buff; + DBUG_VOID_RETURN; +} + +static void +used_buffs_register_unlock(TRUNSLOG_USED_BUFFERS *buffs, + struct st_translog_buffer *buff + __attribute__((unused)) ) +{ + DBUG_ENTER("used_buffs_register_unlock"); + DBUG_PRINT("enter", ("SUB buffs: %p unlk %u (%p) wrt_ptr: %u (%p)" + " buff %p (%u)", + buffs, + buffs->wrt_ptr, buffs->buff[buffs->wrt_ptr], + buffs->unlck_ptr, buffs->buff[buffs->unlck_ptr], + buff, buff->buffer_no)); + DBUG_ASSERT(buffs->buff[buffs->unlck_ptr] == buff); + buffs->unlck_ptr++; + DBUG_VOID_RETURN; +} +static void used_buffs_urgent_unlock(TRUNSLOG_USED_BUFFERS *buffs) +{ + uint i; + DBUG_ENTER("used_buffs_urgent_unlock"); + translog_lock(); + translog_stop_writing(); + translog_unlock(); + for (i= buffs->unlck_ptr; i < buffs->wrt_ptr; i++) + { + struct st_translog_buffer *buf= buffs->buff[i]; + translog_buffer_lock(buf); + translog_buffer_decrease_writers(buf); + translog_buffer_unlock(buf); + buffs->buff[i]= NULL; + } + used_buffs_init(buffs); + DBUG_VOID_RETURN; +} /* Get page rest @@ -5016,6 +5123,11 @@ translog_write_variable_record_1group(LSN *lsn, lsn, hook_arg))) { translog_unlock(); + if (buffer_to_flush != NULL) + { + translog_buffer_flush(buffer_to_flush); + translog_buffer_unlock(buffer_to_flush); + } DBUG_RETURN(1); } cursor= log_descriptor.bc; @@ -5046,8 +5158,9 @@ translog_write_variable_record_1group(LSN *lsn, (log_descriptor.page_capacity_chunk_2 - 1), record_rest, parts->record_length)); /* record_rest + 3 is chunk type 3 overhead + record_rest */ - rc|= translog_advance_pointer((int)(full_pages + additional_chunk3_page), - (record_rest ? record_rest + 3 : 0)); + rc= translog_advance_pointer((int)(full_pages + additional_chunk3_page), + (record_rest ? record_rest + 3 : 0), + &cursor.buffs); log_descriptor.bc.buffer->last_lsn= *lsn; DBUG_PRINT("info", ("last_lsn set to (%lu,0x%lx) buffer: 0x%lx", LSN_IN_PARTS(log_descriptor.bc.buffer->last_lsn), @@ -5066,7 +5179,11 @@ translog_write_variable_record_1group(LSN *lsn, translog_buffer_unlock(buffer_to_flush); } if (rc) + { + //translog_advance_pointer decreased writers so it is OK + DBUG_ASSERT(cursor.buffs.unlck_ptr == cursor.buffs.wrt_ptr); DBUG_RETURN(1); + } translog_write_variable_record_1group_header(parts, type, short_trid, header_length, chunk0_header); @@ -5081,7 +5198,7 @@ translog_write_variable_record_1group(LSN *lsn, for (i= 0; i < full_pages; i++) { if (translog_write_variable_record_chunk2_page(parts, &horizon, &cursor)) - DBUG_RETURN(1); + goto error; DBUG_PRINT("info", ("absolute horizon: (%lu,0x%lx) local: (%lu,0x%lx)", LSN_IN_PARTS(log_descriptor.horizon), @@ -5094,7 +5211,7 @@ translog_write_variable_record_1group(LSN *lsn, log_descriptor. page_capacity_chunk_2 - 2, &horizon, &cursor)) - DBUG_RETURN(1); + goto error; DBUG_PRINT("info", ("absolute horizon: (%lu,0x%lx) local: (%lu,0x%lx)", LSN_IN_PARTS(log_descriptor.horizon), LSN_IN_PARTS(horizon))); @@ -5104,17 +5221,22 @@ translog_write_variable_record_1group(LSN *lsn, if (translog_write_variable_record_chunk3_page(parts, record_rest, &horizon, &cursor)) - DBUG_RETURN(1); - DBUG_PRINT("info", ("absolute horizon: (%lu,0x%lx) local: (%lu,0x%lx)", - (ulong) LSN_FILE_NO(log_descriptor.horizon), - (ulong) LSN_OFFSET(log_descriptor.horizon), - (ulong) LSN_FILE_NO(horizon), - (ulong) LSN_OFFSET(horizon))); + goto error; + DBUG_PRINT("info", ("absolute horizon: (%lu,0x%lx) local: (%lu,0x%lx)", + (ulong) LSN_FILE_NO(log_descriptor.horizon), + (ulong) LSN_OFFSET(log_descriptor.horizon), + (ulong) LSN_FILE_NO(horizon), + (ulong) LSN_OFFSET(horizon))); translog_buffer_lock(cursor.buffer); translog_buffer_decrease_writers(cursor.buffer); + used_buffs_register_unlock(&cursor.buffs, cursor.buffer); translog_buffer_unlock(cursor.buffer); - DBUG_RETURN(rc); + DBUG_ASSERT(cursor.buffs.unlck_ptr == cursor.buffs.wrt_ptr); + DBUG_RETURN(0); +error: + used_buffs_urgent_unlock(&cursor.buffs); + DBUG_RETURN(1); } @@ -5168,7 +5290,8 @@ translog_write_variable_record_1chunk(LSN *lsn, lsn, hook_arg))) { translog_unlock(); - DBUG_RETURN(1); + rc= 1; + goto err; } rc= translog_write_parts_on_page(&log_descriptor.horizon, @@ -5184,6 +5307,7 @@ translog_write_variable_record_1chunk(LSN *lsn, check if we switched buffer and need process it (current buffer is unlocked already => we will not delay other threads */ +err: if (buffer_to_flush != NULL) { if (!rc) @@ -5523,9 +5647,11 @@ translog_write_variable_record_mgroup(LSN *lsn, uint file_of_the_first_group; int pages_to_skip; struct st_translog_buffer *buffer_of_last_lsn; + my_bool external_buffer_to_flush= TRUE; DBUG_ENTER("translog_write_variable_record_mgroup"); translog_lock_assert_owner(); + used_buffs_init(&cursor.buffs); chunk2_header[0]= TRANSLOG_CHUNK_NOHDR; if (my_init_dynamic_array(&groups, @@ -5533,6 +5659,11 @@ translog_write_variable_record_mgroup(LSN *lsn, 10, 10)) { translog_unlock(); + if (buffer_to_flush != NULL) + { + translog_buffer_flush(buffer_to_flush); + translog_buffer_unlock(buffer_to_flush); + } DBUG_PRINT("error", ("init array failed")); DBUG_RETURN(1); } @@ -5559,6 +5690,7 @@ translog_write_variable_record_mgroup(LSN *lsn, translog_mark_file_unfinished(file_of_the_first_group); do { + DBUG_ASSERT(cursor.buffs.unlck_ptr == cursor.buffs.wrt_ptr); group.addr= horizon= log_descriptor.horizon; cursor= log_descriptor.bc; cursor.chaser= 1; @@ -5591,21 +5723,26 @@ translog_write_variable_record_mgroup(LSN *lsn, (ulong)(parts->record_length - (first_page - 1 + buffer_rest) - done))); - rc|= translog_advance_pointer((int)full_pages, 0); + rc= translog_advance_pointer((int)full_pages, 0, &cursor.buffs); translog_unlock(); if (buffer_to_flush != NULL) { - translog_buffer_decrease_writers(buffer_to_flush); + if (!external_buffer_to_flush) + translog_buffer_decrease_writers(buffer_to_flush); if (!rc) rc= translog_buffer_flush(buffer_to_flush); translog_buffer_unlock(buffer_to_flush); buffer_to_flush= NULL; } + external_buffer_to_flush= FALSE; + if (rc) { DBUG_PRINT("error", ("flush of unlock buffer failed")); + //translog_advance_pointer decreased writers so it is OK + DBUG_ASSERT(cursor.buffs.unlck_ptr == cursor.buffs.wrt_ptr); goto err; } @@ -5642,6 +5779,7 @@ translog_write_variable_record_mgroup(LSN *lsn, } translog_buffer_lock(cursor.buffer); translog_buffer_decrease_writers(cursor.buffer); + used_buffs_register_unlock(&cursor.buffs, cursor.buffer); translog_buffer_unlock(cursor.buffer); translog_lock(); @@ -5656,6 +5794,11 @@ translog_write_variable_record_mgroup(LSN *lsn, first_page= translog_get_current_page_rest(); } buffer_rest= translog_get_current_group_size(); + + if (buffer_to_flush) + used_buffs_register_unlock(&cursor.buffs, + buffer_to_flush); // will be unlocked + } while ((translog_size_t)(first_page + buffer_rest) < (translog_size_t)(parts->record_length - done)); @@ -5751,17 +5894,21 @@ translog_write_variable_record_mgroup(LSN *lsn, (ulong) full_pages * log_descriptor.page_capacity_chunk_2, chunk3_pages, (uint) chunk3_size, (uint) record_rest)); + + DBUG_ASSERT(cursor.buffs.unlck_ptr == cursor.buffs.wrt_ptr); rc= translog_advance_pointer(pages_to_skip + (int)(chunk0_pages - 1), record_rest + header_fixed_part + (groups.elements - ((page_capacity - header_fixed_part) / (7 + 1)) * - (chunk0_pages - 1)) * (7 + 1)); + (chunk0_pages - 1)) * (7 + 1), + &cursor.buffs); buffer_of_last_lsn= log_descriptor.bc.buffer; translog_unlock(); if (buffer_to_flush != NULL) { + DBUG_ASSERT(!external_buffer_to_flush); translog_buffer_decrease_writers(buffer_to_flush); if (!rc) rc= translog_buffer_flush(buffer_to_flush); @@ -5925,8 +6072,10 @@ translog_write_variable_record_mgroup(LSN *lsn, } while (chunk0_pages != 0); translog_buffer_lock(cursor.buffer); translog_buffer_decrease_writers(cursor.buffer); + used_buffs_register_unlock(&cursor.buffs, cursor.buffer); translog_buffer_unlock(cursor.buffer); rc= 0; + DBUG_ASSERT(cursor.buffs.unlck_ptr == cursor.buffs.wrt_ptr); if (translog_set_lsn_for_files(file_of_the_first_group, LSN_FILE_NO(*lsn), *lsn, FALSE)) @@ -5935,17 +6084,22 @@ translog_write_variable_record_mgroup(LSN *lsn, translog_mark_file_finished(file_of_the_first_group); delete_dynamic(&groups); - DBUG_RETURN(rc); + DBUG_RETURN(0); err_unlock: translog_unlock(); err: + + if (cursor.buffs.unlck_ptr != cursor.buffs.wrt_ptr) + used_buffs_urgent_unlock(&cursor.buffs); + if (buffer_to_flush != NULL) { /* This is to prevent locking buffer forever in case of error */ - translog_buffer_decrease_writers(buffer_to_flush); + if (!external_buffer_to_flush) + translog_buffer_decrease_writers(buffer_to_flush); if (!rc) rc= translog_buffer_flush(buffer_to_flush); translog_buffer_unlock(buffer_to_flush); @@ -7500,7 +7654,8 @@ static void translog_force_current_buffer_to_finish() DBUG_ASSERT(log_descriptor.bc.ptr !=NULL); DBUG_ASSERT(LSN_FILE_NO(log_descriptor.horizon) == - LSN_FILE_NO(old_buffer->offset)); + LSN_FILE_NO(old_buffer->offset) || + translog_status == TRANSLOG_READONLY ); translog_check_cursor(&log_descriptor.bc); DBUG_ASSERT(left < TRANSLOG_PAGE_SIZE); if (left) -- cgit v1.2.1 From 0ad9c3a0160d1dd46139b3e6b6b05d0fba01540b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 11 Jun 2018 13:02:47 +0300 Subject: MDEV-16456 InnoDB error "returned OS error 71" complains about wrong path When attempting to rename a table to a non-existing database, InnoDB would misleadingly report "OS error 71" when in fact the error code is InnoDB's own (OS_FILE_NOT_FOUND), and not report both pathnames. Errors on rename could occur due to reasons connected to either pathname. os_file_handle_rename_error(): New function, to report errors in renaming files. --- mysql-test/suite/innodb/r/rename_table.result | 5 +++++ mysql-test/suite/innodb/t/innodb-mdev7046.test | 7 ++++--- mysql-test/suite/innodb/t/rename_table.test | 11 +++++++++++ storage/innobase/os/os0file.cc | 24 ++++++++++++++++++++---- storage/xtradb/os/os0file.cc | 22 ++++++++++++++++++++-- 5 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 mysql-test/suite/innodb/r/rename_table.result create mode 100644 mysql-test/suite/innodb/t/rename_table.test diff --git a/mysql-test/suite/innodb/r/rename_table.result b/mysql-test/suite/innodb/r/rename_table.result new file mode 100644 index 00000000000..b2e15c87348 --- /dev/null +++ b/mysql-test/suite/innodb/r/rename_table.result @@ -0,0 +1,5 @@ +call mtr.add_suppression("InnoDB: (Operating system error|The error means|Cannot rename file)"); +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +RENAME TABLE t1 TO non_existing_db.t1; +ERROR HY000: Error on rename of './test/t1' to './non_existing_db/t1' (errno: -1 "Internal error < 0 (Not system error)") +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb-mdev7046.test b/mysql-test/suite/innodb/t/innodb-mdev7046.test index b4085228e02..85a257a1739 100644 --- a/mysql-test/suite/innodb/t/innodb-mdev7046.test +++ b/mysql-test/suite/innodb/t/innodb-mdev7046.test @@ -9,9 +9,10 @@ # Ignore OS errors -call mtr.add_suppression("InnoDB: File ./test/t1*"); -call mtr.add_suppression("InnoDB: Error number*"); -call mtr.add_suppression("InnoDB: File ./test/t1#p#p1#sp#p1sp0.ibd: 'rename' returned OS error*"); +call mtr.add_suppression("InnoDB: File ./test/t1"); +call mtr.add_suppression("InnoDB: Error number"); +call mtr.add_suppression("InnoDB: Cannot rename file '.*/test/t1#[Pp]#p1#[Ss][Pp]#p1sp0\\.ibd' to"); +call mtr.add_suppression("InnoDB: Operating system error number .* in a file operation."); # MDEV-7046: MySQL#74480 - Failing assertion: os_file_status(newpath, &exists, &type) # after Operating system error number 36 in a file operation diff --git a/mysql-test/suite/innodb/t/rename_table.test b/mysql-test/suite/innodb/t/rename_table.test new file mode 100644 index 00000000000..60df8b5d2ec --- /dev/null +++ b/mysql-test/suite/innodb/t/rename_table.test @@ -0,0 +1,11 @@ +--source include/have_innodb.inc + +call mtr.add_suppression("InnoDB: (Operating system error|The error means|Cannot rename file)"); + +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +--replace_result "\\" "/" +--error ER_ERROR_ON_RENAME +RENAME TABLE t1 TO non_existing_db.t1; + +# Cleanup +DROP TABLE t1; diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 8f3f3716fc2..038d59c2170 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -1939,6 +1939,24 @@ loop: #endif } +/** Handle RENAME error. +@param name old name of the file +@param new_name new name of the file */ +static void os_file_handle_rename_error(const char* name, const char* new_name) +{ + if (os_file_get_last_error(true) != OS_FILE_DISK_FULL) { + ib_logf(IB_LOG_LEVEL_ERROR, "Cannot rename file '%s' to '%s'", + name, new_name); + } else if (!os_has_said_disk_full) { + os_has_said_disk_full = true; + /* Disk full error is reported irrespective of the + on_error_silent setting. */ + ib_logf(IB_LOG_LEVEL_ERROR, + "Full disk prevents renaming file '%s' to '%s'", + name, new_name); + } +} + /***********************************************************************//** NOTE! Use the corresponding macro os_file_rename(), not directly this function! Renames a file (can also move it to another directory). It is safest that the @@ -1974,8 +1992,7 @@ os_file_rename_func( return(TRUE); } - os_file_handle_error_no_exit(oldpath, "rename", FALSE); - + os_file_handle_rename_error(oldpath, newpath); return(FALSE); #else int ret; @@ -1983,8 +2000,7 @@ os_file_rename_func( ret = rename(oldpath, newpath); if (ret != 0) { - os_file_handle_error_no_exit(oldpath, "rename", FALSE); - + os_file_handle_rename_error(oldpath, newpath); return(FALSE); } diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc index c1ddc83d852..9df42470e5a 100644 --- a/storage/xtradb/os/os0file.cc +++ b/storage/xtradb/os/os0file.cc @@ -2146,6 +2146,24 @@ loop: #endif } +/** Handle RENAME error. +@param name old name of the file +@param new_name new name of the file */ +static void os_file_handle_rename_error(const char* name, const char* new_name) +{ + if (os_file_get_last_error(true) != OS_FILE_DISK_FULL) { + ib_logf(IB_LOG_LEVEL_ERROR, "Cannot rename file '%s' to '%s'", + name, new_name); + } else if (!os_has_said_disk_full) { + os_has_said_disk_full = true; + /* Disk full error is reported irrespective of the + on_error_silent setting. */ + ib_logf(IB_LOG_LEVEL_ERROR, + "Full disk prevents renaming file '%s' to '%s'", + name, new_name); + } +} + /***********************************************************************//** NOTE! Use the corresponding macro os_file_rename(), not directly this function! Renames a file (can also move it to another directory). It is safest that the @@ -2181,7 +2199,7 @@ os_file_rename_func( return(TRUE); } - os_file_handle_error_no_exit(oldpath, "rename", FALSE); + os_file_handle_rename_error(oldpath, newpath); return(FALSE); #else @@ -2190,7 +2208,7 @@ os_file_rename_func( ret = rename(oldpath, newpath); if (ret != 0) { - os_file_handle_error_no_exit(oldpath, "rename", FALSE); + os_file_handle_rename_error(oldpath, newpath); return(FALSE); } -- cgit v1.2.1 From 6b8d34fe0d5e73a469383bcb0818d3ff91ed9a84 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Tue, 12 Jun 2018 12:36:51 +0400 Subject: MDEV-14668 ADD PRIMARY KEY IF NOT EXISTS on composite key. Check the name of the primary key to be 'PRIMARY'. Than differs it from any implicit primary keys created by an engine. --- mysql-test/r/alter_table.result | 23 +++++++++++++++++++++++ mysql-test/t/alter_table.test | 16 ++++++++++++++++ sql/sql_table.cc | 4 +++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index bb78df907ad..c6e3c7e31d9 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -2225,3 +2225,26 @@ t1 CREATE TABLE `t1` ( `b` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 DROP TABLE t1; +# +# MDEV-14668 ADD PRIMARY KEY IF NOT EXISTS on composite key +# +CREATE TABLE t1 ( +`ID` BIGINT(20) NOT NULL, +`RANK` MEDIUMINT(4) NOT NULL, +`CHECK_POINT` BIGINT(20) NOT NULL, +UNIQUE INDEX `HORIZON_UIDX01` (`ID`, `RANK`) +) ENGINE=InnoDB; +ALTER TABLE t1 ADD PRIMARY KEY IF NOT EXISTS (`ID`, `CHECK_POINT`); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `ID` bigint(20) NOT NULL, + `RANK` mediumint(4) NOT NULL, + `CHECK_POINT` bigint(20) NOT NULL, + PRIMARY KEY (`ID`,`CHECK_POINT`), + UNIQUE KEY `HORIZON_UIDX01` (`ID`,`RANK`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +ALTER TABLE t1 ADD PRIMARY KEY IF NOT EXISTS (`ID`, `CHECK_POINT`); +Warnings: +Note 1061 Multiple primary key defined +DROP TABLE t1; diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index 585a272de9b..28d8c5bf5e9 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -1841,3 +1841,19 @@ CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB; ALTER TABLE t1 DROP INDEX IF EXISTS fk, DROP COLUMN IF EXISTS c; SHOW CREATE TABLE t1; DROP TABLE t1; + +--echo # +--echo # MDEV-14668 ADD PRIMARY KEY IF NOT EXISTS on composite key +--echo # +CREATE TABLE t1 ( + `ID` BIGINT(20) NOT NULL, + `RANK` MEDIUMINT(4) NOT NULL, + `CHECK_POINT` BIGINT(20) NOT NULL, + UNIQUE INDEX `HORIZON_UIDX01` (`ID`, `RANK`) + ) ENGINE=InnoDB; + +ALTER TABLE t1 ADD PRIMARY KEY IF NOT EXISTS (`ID`, `CHECK_POINT`); +SHOW CREATE TABLE t1; +ALTER TABLE t1 ADD PRIMARY KEY IF NOT EXISTS (`ID`, `CHECK_POINT`); +DROP TABLE t1; + diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 376c1362cc7..6c71067d51b 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5930,7 +5930,9 @@ drop_create_field: /* Check if the table already has a PRIMARY KEY */ if (key->type == Key::PRIMARY && - table->s->primary_key != MAX_KEY) + table->s->primary_key != MAX_KEY && + (keyname= table->s->key_info[table->s->primary_key].name) && + my_strcasecmp(system_charset_info, keyname, primary_key_name) == 0) { push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_DUP_KEYNAME, ER(ER_MULTIPLE_PRI_KEY)); -- cgit v1.2.1 From d2e1ed8b936a78ceeec0e64231997d7ed18a4daf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Wed, 13 Jun 2018 08:33:25 +0300 Subject: Fix innodb.rename_table for embedded An embedded run will output the full path name instead of a relative one. Update results to cover both cases. --- mysql-test/suite/innodb/r/rename_table.result | 2 +- mysql-test/suite/innodb/t/rename_table.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/innodb/r/rename_table.result b/mysql-test/suite/innodb/r/rename_table.result index b2e15c87348..49ce3254091 100644 --- a/mysql-test/suite/innodb/r/rename_table.result +++ b/mysql-test/suite/innodb/r/rename_table.result @@ -1,5 +1,5 @@ call mtr.add_suppression("InnoDB: (Operating system error|The error means|Cannot rename file)"); CREATE TABLE t1 (a INT) ENGINE=InnoDB; RENAME TABLE t1 TO non_existing_db.t1; -ERROR HY000: Error on rename of './test/t1' to './non_existing_db/t1' (errno: -1 "Internal error < 0 (Not system error)") +ERROR HY000: Error on rename of '**path-to-t1**' to '**path-to-non-existing-db-t1**' (errno: -1 "Internal error < 0 (Not system error)") DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/rename_table.test b/mysql-test/suite/innodb/t/rename_table.test index 60df8b5d2ec..695c0915d14 100644 --- a/mysql-test/suite/innodb/t/rename_table.test +++ b/mysql-test/suite/innodb/t/rename_table.test @@ -3,7 +3,7 @@ call mtr.add_suppression("InnoDB: (Operating system error|The error means|Cannot rename file)"); CREATE TABLE t1 (a INT) ENGINE=InnoDB; ---replace_result "\\" "/" +--replace_regex /\'.*t1\' to/'**path-to-t1**' to/ /to \'.*non.*t1\'/to '**path-to-non-existing-db-t1**'/ --error ER_ERROR_ON_RENAME RENAME TABLE t1 TO non_existing_db.t1; -- cgit v1.2.1 From 51254da52c144781695250a98f365fbc090ef619 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 12 Jun 2018 12:37:28 +0200 Subject: MDEV-15359 Thread stay in "cleaning up" status after finishing make thd_get_error_context_description() to show not just thd->proc_info, but exactly the same thread state that SHOW PROCESSLIST shows. --- mysql-test/suite/plugins/r/processlist.result | 8 +++ mysql-test/suite/plugins/t/processlist.test | 18 +++++ sql/sql_class.cc | 97 --------------------------- sql/sql_show.cc | 85 +++++++++++++++++++++++ 4 files changed, 111 insertions(+), 97 deletions(-) create mode 100644 mysql-test/suite/plugins/r/processlist.result create mode 100644 mysql-test/suite/plugins/t/processlist.test diff --git a/mysql-test/suite/plugins/r/processlist.result b/mysql-test/suite/plugins/r/processlist.result new file mode 100644 index 00000000000..d08ea9d3523 --- /dev/null +++ b/mysql-test/suite/plugins/r/processlist.result @@ -0,0 +1,8 @@ +create table t1 (a int) engine=innodb; +start transaction; +insert t1 values (1); +state from show engine innodb status + +state from show processlist + +drop table t1; diff --git a/mysql-test/suite/plugins/t/processlist.test b/mysql-test/suite/plugins/t/processlist.test new file mode 100644 index 00000000000..5aacef317b9 --- /dev/null +++ b/mysql-test/suite/plugins/t/processlist.test @@ -0,0 +1,18 @@ +# +# MDEV-15359 Thread stay in "cleaning up" status after finishing +# +source include/have_innodb.inc; + +create table t1 (a int) engine=innodb; +start transaction; +insert t1 values (1); +let id=`select connection_id()`; +connect con2,localhost,root; +let s=query_get_value(show engine innodb status,Status,1); +disable_query_log; +eval select regexp_replace("$s", '(?s)^.*MySQL thread id $id,.*root([^\n]*)\n.*', '\\\\1') as `state from show engine innodb status`; +eval select state as `state from show processlist` from information_schema.processlist where id = $id; +enable_query_log; +disconnect con2; +connection default; +drop table t1; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index a644df9771c..3b293935048 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -717,103 +717,6 @@ extern "C" } -/** - Dumps a text description of a thread, its security context - (user, host) and the current query. - - @param thd thread context - @param buffer pointer to preferred result buffer - @param length length of buffer - @param max_query_len how many chars of query to copy (0 for all) - - @return Pointer to string -*/ - -extern "C" -char *thd_get_error_context_description(THD *thd, char *buffer, - unsigned int length, - unsigned int max_query_len) -{ - String str(buffer, length, &my_charset_latin1); - const Security_context *sctx= &thd->main_security_ctx; - char header[256]; - int len; - - mysql_mutex_lock(&LOCK_thread_count); - - /* - The pointers thd->query and thd->proc_info might change since they are - being modified concurrently. This is acceptable for proc_info since its - values doesn't have to very accurate and the memory it points to is static, - but we need to attempt a snapshot on the pointer values to avoid using NULL - values. The pointer to thd->query however, doesn't point to static memory - and has to be protected by thd->LOCK_thd_data or risk pointing to - uninitialized memory. - */ - const char *proc_info= thd->proc_info; - - len= my_snprintf(header, sizeof(header), - "MySQL thread id %lu, OS thread handle 0x%lx, query id %lu", - thd->thread_id, (ulong) thd->real_id, (ulong) thd->query_id); - str.length(0); - str.append(header, len); - - if (sctx->host) - { - str.append(' '); - str.append(sctx->host); - } - - if (sctx->ip) - { - str.append(' '); - str.append(sctx->ip); - } - - if (sctx->user) - { - str.append(' '); - str.append(sctx->user); - } - - if (proc_info) - { - str.append(' '); - str.append(proc_info); - } - - /* Don't wait if LOCK_thd_data is used as this could cause a deadlock */ - if (!mysql_mutex_trylock(&thd->LOCK_thd_data)) - { - if (thd->query()) - { - if (max_query_len < 1) - len= thd->query_length(); - else - len= MY_MIN(thd->query_length(), max_query_len); - str.append('\n'); - str.append(thd->query(), len); - } - mysql_mutex_unlock(&thd->LOCK_thd_data); - } - mysql_mutex_unlock(&LOCK_thread_count); - - if (str.c_ptr_safe() == buffer) - return buffer; - - /* - We have to copy the new string to the destination buffer because the string - was reallocated to a larger buffer to be able to fit. - */ - DBUG_ASSERT(buffer != NULL); - length= MY_MIN(str.length(), length-1); - memcpy(buffer, str.c_ptr_quick(), length); - /* Make sure that the new string is null terminated */ - buffer[length]= '\0'; - return buffer; -} - - #if MARIA_PLUGIN_INTERFACE_VERSION < 0x0200 /** TODO: This function is for API compatibility, remove it eventually. diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 965bed80148..d7641a6a96d 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -9773,3 +9773,88 @@ static void get_cs_converted_string_value(THD *thd, return; } #endif + +/** + Dumps a text description of a thread, its security context + (user, host) and the current query. + + @param thd thread context + @param buffer pointer to preferred result buffer + @param length length of buffer + @param max_query_len how many chars of query to copy (0 for all) + + @return Pointer to string +*/ + +extern "C" +char *thd_get_error_context_description(THD *thd, char *buffer, + unsigned int length, + unsigned int max_query_len) +{ + String str(buffer, length, &my_charset_latin1); + const Security_context *sctx= &thd->main_security_ctx; + char header[256]; + int len; + + mysql_mutex_lock(&LOCK_thread_count); + + len= my_snprintf(header, sizeof(header), + "MySQL thread id %lu, OS thread handle 0x%lx, query id %lu", + thd->thread_id, (ulong) thd->real_id, (ulong) thd->query_id); + str.length(0); + str.append(header, len); + + if (sctx->host) + { + str.append(' '); + str.append(sctx->host); + } + + if (sctx->ip) + { + str.append(' '); + str.append(sctx->ip); + } + + if (sctx->user) + { + str.append(' '); + str.append(sctx->user); + } + + /* Don't wait if LOCK_thd_data is used as this could cause a deadlock */ + if (!mysql_mutex_trylock(&thd->LOCK_thd_data)) + { + if (const char *info= thread_state_info(thd)) + { + str.append(' '); + str.append(info); + } + + if (thd->query()) + { + if (max_query_len < 1) + len= thd->query_length(); + else + len= MY_MIN(thd->query_length(), max_query_len); + str.append('\n'); + str.append(thd->query(), len); + } + mysql_mutex_unlock(&thd->LOCK_thd_data); + } + mysql_mutex_unlock(&LOCK_thread_count); + + if (str.c_ptr_safe() == buffer) + return buffer; + + /* + We have to copy the new string to the destination buffer because the string + was reallocated to a larger buffer to be able to fit. + */ + DBUG_ASSERT(buffer != NULL); + length= MY_MIN(str.length(), length-1); + memcpy(buffer, str.c_ptr_quick(), length); + /* Make sure that the new string is null terminated */ + buffer[length]= '\0'; + return buffer; +} -- cgit v1.2.1 From 3661d9882224dd485556ce937c1294eaeda02ef8 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 13 Jun 2018 20:31:40 +0200 Subject: fix SHOW PROCESSLIST for --embedded make it return the same Info values as for the standalone server. This fixes plugins.processlist for --embedded --- sql/sql_show.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index d7641a6a96d..af02c74c58b 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2267,16 +2267,16 @@ static const char *thread_state_info(THD *tmp) else return "Reading from net"; } - else +#else + if (tmp->get_command() == COM_SLEEP) + return ""; #endif - { - if (tmp->proc_info) - return tmp->proc_info; - else if (tmp->mysys_var && tmp->mysys_var->current_cond) - return "Waiting on cond"; - else - return NULL; - } + if (tmp->proc_info) + return tmp->proc_info; + else if (tmp->mysys_var && tmp->mysys_var->current_cond) + return "Waiting on cond"; + else + return NULL; } void mysqld_list_processes(THD *thd,const char *user, bool verbose) -- cgit v1.2.1 From e48d775c6f066add457fa8cfb2ebc4d5ff0c7613 Mon Sep 17 00:00:00 2001 From: Ivo Roylev Date: Thu, 14 Jun 2018 17:27:54 +0300 Subject: Bug#27980823: HEAP OVERFLOW VULNERABILITIES IN MYSQL CLIENT LIBRARY (cherry picked from commit b5b986b2cbd9a7848dc3f48e5c42b6d4e1e5fb22) --- sql-common/client.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sql-common/client.c b/sql-common/client.c index 3247fd8e339..7938403db59 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1505,7 +1505,8 @@ unpack_fields(MYSQL *mysql, MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, { uchar *pos; /* fields count may be wrong */ - DBUG_ASSERT((uint) (field - result) < fields); + if (field < result || (uint) (field - result) >= fields) + DBUG_RETURN(NULL); cli_fetch_lengths(&lengths[0], row->data, default_value ? 8 : 7); field->catalog= strmake_root(alloc,(char*) row->data[0], lengths[0]); field->db= strmake_root(alloc,(char*) row->data[1], lengths[1]); @@ -1612,6 +1613,7 @@ MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, if ((pkt_len= cli_safe_read(mysql)) == packet_error) DBUG_RETURN(0); + if (pkt_len == 0) DBUG_RETURN(0); if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA), MYF(MY_WME | MY_ZEROFILL)))) { -- cgit v1.2.1 From 15b92915ed93661a56f40430204d18bf7b7cf1fc Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 19 Jun 2018 13:02:02 +0400 Subject: MDEV-15834 The code in TABLE_SHARE::init_from_binary_frm_image() is not safe --- mysql-test/std_data/frm/t1.frm | Bin 0 -> 8584 bytes mysql-test/suite/vcol/r/vcol_misc.result | 10 ++++++++++ mysql-test/suite/vcol/t/vcol_misc.test | 16 ++++++++++++++++ sql/table.cc | 6 +++++- 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 mysql-test/std_data/frm/t1.frm diff --git a/mysql-test/std_data/frm/t1.frm b/mysql-test/std_data/frm/t1.frm new file mode 100644 index 00000000000..a998f54ec67 Binary files /dev/null and b/mysql-test/std_data/frm/t1.frm differ diff --git a/mysql-test/suite/vcol/r/vcol_misc.result b/mysql-test/suite/vcol/r/vcol_misc.result index 0a8d87dc2f7..92be94cbb81 100644 --- a/mysql-test/suite/vcol/r/vcol_misc.result +++ b/mysql-test/suite/vcol/r/vcol_misc.result @@ -354,5 +354,15 @@ a b c DROP TABLE t1; SET sql_mode=DEFAULT; # +# MDEV-15834 The code in TABLE_SHARE::init_from_binary_frm_image() is not safe +# +SHOW TABLES; +Tables_in_test +t1 +SHOW CREATE TABLE t1; +ERROR HY000: Incorrect information in file: './test/t1.frm' +ALTER TABLE t1; +ERROR HY000: Incorrect information in file: './test/t1.frm' +# # End of 5.5 tests # diff --git a/mysql-test/suite/vcol/t/vcol_misc.test b/mysql-test/suite/vcol/t/vcol_misc.test index 1ac0b4f80b7..a123d21d574 100644 --- a/mysql-test/suite/vcol/t/vcol_misc.test +++ b/mysql-test/suite/vcol/t/vcol_misc.test @@ -1,5 +1,7 @@ --source include/have_ucs2.inc +let $MYSQLD_DATADIR= `select @@datadir`; + --disable_warnings drop table if exists t1,t2; --enable_warnings @@ -318,6 +320,20 @@ SELECT * FROM t1; DROP TABLE t1; SET sql_mode=DEFAULT; + +--echo # +--echo # MDEV-15834 The code in TABLE_SHARE::init_from_binary_frm_image() is not safe +--echo # + +--copy_file std_data/frm/t1.frm $MYSQLD_DATADIR/test/t1.frm +SHOW TABLES; +--error ER_NOT_FORM_FILE +SHOW CREATE TABLE t1; +--error ER_NOT_FORM_FILE +ALTER TABLE t1; +--remove_file $MYSQLD_DATADIR/test/t1.frm + + --echo # --echo # End of 5.5 tests --echo # diff --git a/sql/table.cc b/sql/table.cc index 552f514283d..87a249defa0 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1462,7 +1462,11 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, if ((uchar)field_type == (uchar)MYSQL_TYPE_VIRTUAL) { - DBUG_ASSERT(interval_nr); // Expect non-null expression + if (!interval_nr) // Expect non-null expression + { + error= 4; + goto err; + } /* The interval_id byte in the .frm file stores the length of the expression statement for a virtual column. -- cgit v1.2.1 From 5f2a67a6c35fd0d833024652ddc33eab8bcb1ed4 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Wed, 20 Jun 2018 02:36:00 +0530 Subject: MDEV-15247: Crash when SET NAMES 'utf8' is set In this case we are accessing incorrect memory when we have mergeable semi-joins. In the case when we have mergeable semi joins parent select will have a table count of all the tables in that select plus all the tables involved in the IN-subquery. But this table count does not include the "sjm table" (only includes the inner and outer tables) denotes as in explain. --- mysql-test/r/subselect_sj2_mat.result | 90 +++++++++++++++++++++++++++++++++++ mysql-test/t/subselect_sj2_mat.test | 87 +++++++++++++++++++++++++++++++++ sql/sql_select.cc | 4 +- 3 files changed, 180 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/subselect_sj2_mat.result b/mysql-test/r/subselect_sj2_mat.result index c629c8196c7..c27beb295b8 100644 --- a/mysql-test/r/subselect_sj2_mat.result +++ b/mysql-test/r/subselect_sj2_mat.result @@ -1691,3 +1691,93 @@ id 12 13 drop table t1; +# +# MDEV-15247: Crash when SET NAMES 'utf8' is set +# +CREATE TABLE t1 ( +id_category int unsigned, +id_product int unsigned, +PRIMARY KEY (id_category,id_product) +) ENGINE=MyISAM; +INSERT INTO `t1` VALUES (31,216), (31,215), (31,214), (31,213), (31,212), (32,211), (32,210), (32,209), (32,208), (29,207), (30,315372), (2,161), (2,132), (33,315380), (31,315371), (29,315370), (29,315373), (29,315369), (29,315374), (29,315368), (29,315375), (29,315367), (29,183), (29,182), (30,177), (29,315376), (13,315365), (2,167), (2,315357), (2,164), (2,159), (2,131), (2,127), (14,315364), (27,315363), (29,205), (29,204), (29,203), (29,202), (29,201), (29,200), (29,199), (29,198), (29,197), (29,196), (29,195), (29,194), (29,193), (29,192), (29,191), (29,190), (29,189), (14,188), (29,187), (29,186), (29,185), (29,184), (29,315377), (29,315378), (29,181), (33,315379), (29,179), (30,178), (29,180), (30,176), (30,175), (30,174), (30,173), (30,172), (11,171), (27,315357), (23,108), (23,102); +CREATE TABLE t2 ( +id_product int, +id_t2 int, +KEY id_t2 (id_t2), +KEY id_product (id_product) +) ENGINE=MyISAM; +INSERT INTO `t2` VALUES (11,31), (11,31), (11,31), (11,32), (11,32), +(11,32), (10,26), (11,32), (10,28), (11,32), (10,29), (11,33), (10,26), +(11,33), (10,27), (9,23), (11,32), (10,26), (8,18), (7,15), (11,32), +(10,28), (11,32), (10,28), (11,32), (10,29), (11,32), (10,29), (8,19), +(7,16), (8,18), (7,16), (8,20), (7,16), (11,32), (10,28), (8,19), +(7,16), (8,20), (7,16), (11,32), (10,29), (8,19), (7,16), (8,20), +(7,16), (10,27), (9,23), (10,27), (9,23), (10,27), (9,23), (11,32), +(10,27), (11,32), (10,27), (8,18), (7,15), (10,26), (9,24), (8,19), +(7,16), (10,26), (9,23), (8,19), (7,16), (8,18), (7,16), (8,18), (7,16), +(9,23), (8,18), (9,23), (8,19), (7,16), (7,16), (8,19), (7,16), (11,31), +(10,27), (9,24), (11,31), (10,27), (9,23), (8,19), (11,31), (10,26), (9,24), +(8,19), (11,31), (10,26), (9,25), (8,18), (11,31), (10,26), (9,23), (8,19), +(11,31), (10,26), (9,23), (8,18), (11,31), (10,30), (9,23), (8,18), (11,31), +(10,30), (9,23), (8,19), (11,31), (10,26), (9,25), (8,19), (8,21), (11,32), +(10,26), (9,22), (8,19), (11,32), (10,26), (9,22), (8,18), (11,32), (10,26), +(9,22), (8,20), (11,33), (10,26), (9,22), (8,19), (11,33), (10,26), (9,22), +(8,18), (11,33), (10,26), (9,22), (8,20), (11,32), (10,26), (9,24), (8,19), +(11,32), (10,26), (9,25), (8,19), (11,32), (10,26), (9,25), (8,18), (11,32), +(10,26), (9,23), (8,18), (11,32), (10,30), (9,23), (8,18), (11,32), (10,30), +(9,23), (8,19), (11,32), (10,26), (9,23), (8,19), (11,32), (10,27), (9,23), +(11,32), (10,27), (9,23), (11,32), (10,27), (9,23), (10,26), (9,22), (8,19), +(7,15), (10,26), (9,22), (8,20), (7,15), (10,26), (9,22), (8,18), (7,15), +(8,19), (10,26), (10,26), (11,33), (10,26), (11,33), (10,26), (11,33), +(10,27), (11,33), (10,27), (11,31), (10,26), (11,31), (10,26), (8,18), +(7,15), (9,23), (9,23), (9,24), (8,21), (7,15), (7,15), (7,15), (7,15), +(7,15), (7,15), (7,15), (7,15), (7,15), (8,18), (7,17), (8,18), (7,17), (8,19), (8,19); +CREATE TABLE t3 ( +id_product int unsigned, +PRIMARY KEY (id_product) +) ENGINE=MyISAM; +INSERT INTO t3 VALUES +(102),(103),(104),(105),(106),(107),(108),(109),(110), +(315371),(315373),(315374),(315375),(315376),(315377), +(315378),(315379),(315380); +CREATE TABLE t4 ( +id_product int not null, +id_shop int, +PRIMARY KEY (id_product,id_shop) +) ENGINE=MyISAM ; +INSERT INTO t4 VALUES +(202,1),(201,1),(200,1),(199,1),(198,1),(197,1),(196,1),(195,1), +(194,1),(193,1),(192,1),(191,1),(190,1),(189,1),(188,1),(187,1), +(186,1),(185,1),(184,1),(183,1),(182,1),(181,1),(179,1),(178,1), +(177,1),(176,1),(126,1),(315380,1); +CREATE TABLE t5 (id_product int) ENGINE=MyISAM; +INSERT INTO `t5` VALUES +(652),(668),(669),(670),(671),(673),(674),(675),(676), +(677),(679),(680),(681),(682),(683),(684),(685),(686); +explain +SELECT * FROM t3 +JOIN t4 ON (t4.id_product = t3.id_product AND t4.id_shop = 1) +JOIN t1 ON (t1.id_product = t3.id_product) +LEFT JOIN t5 ON (t5.id_product = t3.id_product) +WHERE 1=1 +AND t3.id_product IN (SELECT id_product FROM t2 t2_1 WHERE t2_1.id_t2 = 32) +AND t3.id_product IN (SELECT id_product FROM t2 t2_2 WHERE t2_2.id_t2 = 15) +AND t3.id_product IN (SELECT id_product FROM t2 t2_3 WHERE t2_3.id_t2 = 18 OR t2_3.id_t2 = 19) +AND t3.id_product IN (SELECT id_product FROM t2 t2_4 WHERE t2_4.id_t2 = 34 OR t2_4.id_t2 = 23) +AND t3.id_product IN (SELECT id_product FROM t2 t2_5 WHERE t2_5.id_t2 = 29 OR t2_5.id_t2 = 28 OR t2_5.id_t2 = 26); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index NULL PRIMARY 8 NULL 73 Using index +1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t1.id_product 1 Using index +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 Using where +1 PRIMARY t4 eq_ref PRIMARY PRIMARY 8 test.t1.id_product,const 1 Using where; Using index +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 Using where +1 PRIMARY t5 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) +5 MATERIALIZED t2_4 range id_t2,id_product id_t2 5 NULL 18 Using index condition; Using where +4 MATERIALIZED t2_3 range id_t2,id_product id_t2 5 NULL 32 Using index condition; Using where +3 MATERIALIZED t2_2 ref id_t2,id_product id_t2 5 const 12 +2 MATERIALIZED t2_1 ref id_t2,id_product id_t2 5 const 50 +6 MATERIALIZED t2_5 range id_t2,id_product id_t2 5 NULL 30 Using index condition; Using where +drop table t1,t2,t3,t4,t5; diff --git a/mysql-test/t/subselect_sj2_mat.test b/mysql-test/t/subselect_sj2_mat.test index 0665cdf68fe..68a888012f2 100644 --- a/mysql-test/t/subselect_sj2_mat.test +++ b/mysql-test/t/subselect_sj2_mat.test @@ -345,3 +345,90 @@ WHERE ( (t.id IN (0,4,12,13,1,10,3,11)) ); drop table t1; + +--echo # +--echo # MDEV-15247: Crash when SET NAMES 'utf8' is set +--echo # + +CREATE TABLE t1 ( + id_category int unsigned, + id_product int unsigned, + PRIMARY KEY (id_category,id_product) +) ENGINE=MyISAM; + +INSERT INTO `t1` VALUES (31,216), (31,215), (31,214), (31,213), (31,212), (32,211), (32,210), (32,209), (32,208), (29,207), (30,315372), (2,161), (2,132), (33,315380), (31,315371), (29,315370), (29,315373), (29,315369), (29,315374), (29,315368), (29,315375), (29,315367), (29,183), (29,182), (30,177), (29,315376), (13,315365), (2,167), (2,315357), (2,164), (2,159), (2,131), (2,127), (14,315364), (27,315363), (29,205), (29,204), (29,203), (29,202), (29,201), (29,200), (29,199), (29,198), (29,197), (29,196), (29,195), (29,194), (29,193), (29,192), (29,191), (29,190), (29,189), (14,188), (29,187), (29,186), (29,185), (29,184), (29,315377), (29,315378), (29,181), (33,315379), (29,179), (30,178), (29,180), (30,176), (30,175), (30,174), (30,173), (30,172), (11,171), (27,315357), (23,108), (23,102); + +CREATE TABLE t2 ( + id_product int, + id_t2 int, + KEY id_t2 (id_t2), + KEY id_product (id_product) +) ENGINE=MyISAM; + +INSERT INTO `t2` VALUES (11,31), (11,31), (11,31), (11,32), (11,32), +(11,32), (10,26), (11,32), (10,28), (11,32), (10,29), (11,33), (10,26), +(11,33), (10,27), (9,23), (11,32), (10,26), (8,18), (7,15), (11,32), +(10,28), (11,32), (10,28), (11,32), (10,29), (11,32), (10,29), (8,19), +(7,16), (8,18), (7,16), (8,20), (7,16), (11,32), (10,28), (8,19), +(7,16), (8,20), (7,16), (11,32), (10,29), (8,19), (7,16), (8,20), +(7,16), (10,27), (9,23), (10,27), (9,23), (10,27), (9,23), (11,32), +(10,27), (11,32), (10,27), (8,18), (7,15), (10,26), (9,24), (8,19), +(7,16), (10,26), (9,23), (8,19), (7,16), (8,18), (7,16), (8,18), (7,16), +(9,23), (8,18), (9,23), (8,19), (7,16), (7,16), (8,19), (7,16), (11,31), +(10,27), (9,24), (11,31), (10,27), (9,23), (8,19), (11,31), (10,26), (9,24), +(8,19), (11,31), (10,26), (9,25), (8,18), (11,31), (10,26), (9,23), (8,19), +(11,31), (10,26), (9,23), (8,18), (11,31), (10,30), (9,23), (8,18), (11,31), +(10,30), (9,23), (8,19), (11,31), (10,26), (9,25), (8,19), (8,21), (11,32), +(10,26), (9,22), (8,19), (11,32), (10,26), (9,22), (8,18), (11,32), (10,26), +(9,22), (8,20), (11,33), (10,26), (9,22), (8,19), (11,33), (10,26), (9,22), +(8,18), (11,33), (10,26), (9,22), (8,20), (11,32), (10,26), (9,24), (8,19), +(11,32), (10,26), (9,25), (8,19), (11,32), (10,26), (9,25), (8,18), (11,32), +(10,26), (9,23), (8,18), (11,32), (10,30), (9,23), (8,18), (11,32), (10,30), +(9,23), (8,19), (11,32), (10,26), (9,23), (8,19), (11,32), (10,27), (9,23), +(11,32), (10,27), (9,23), (11,32), (10,27), (9,23), (10,26), (9,22), (8,19), +(7,15), (10,26), (9,22), (8,20), (7,15), (10,26), (9,22), (8,18), (7,15), +(8,19), (10,26), (10,26), (11,33), (10,26), (11,33), (10,26), (11,33), +(10,27), (11,33), (10,27), (11,31), (10,26), (11,31), (10,26), (8,18), +(7,15), (9,23), (9,23), (9,24), (8,21), (7,15), (7,15), (7,15), (7,15), +(7,15), (7,15), (7,15), (7,15), (7,15), (8,18), (7,17), (8,18), (7,17), (8,19), (8,19); + +CREATE TABLE t3 ( + id_product int unsigned, + PRIMARY KEY (id_product) +) ENGINE=MyISAM; + +INSERT INTO t3 VALUES +(102),(103),(104),(105),(106),(107),(108),(109),(110), +(315371),(315373),(315374),(315375),(315376),(315377), +(315378),(315379),(315380); + +CREATE TABLE t4 ( + id_product int not null, + id_shop int, + PRIMARY KEY (id_product,id_shop) +) ENGINE=MyISAM ; + +INSERT INTO t4 VALUES +(202,1),(201,1),(200,1),(199,1),(198,1),(197,1),(196,1),(195,1), +(194,1),(193,1),(192,1),(191,1),(190,1),(189,1),(188,1),(187,1), +(186,1),(185,1),(184,1),(183,1),(182,1),(181,1),(179,1),(178,1), +(177,1),(176,1),(126,1),(315380,1); + +CREATE TABLE t5 (id_product int) ENGINE=MyISAM; +INSERT INTO `t5` VALUES +(652),(668),(669),(670),(671),(673),(674),(675),(676), +(677),(679),(680),(681),(682),(683),(684),(685),(686); + +explain +SELECT * FROM t3 + JOIN t4 ON (t4.id_product = t3.id_product AND t4.id_shop = 1) + JOIN t1 ON (t1.id_product = t3.id_product) +LEFT JOIN t5 ON (t5.id_product = t3.id_product) +WHERE 1=1 +AND t3.id_product IN (SELECT id_product FROM t2 t2_1 WHERE t2_1.id_t2 = 32) +AND t3.id_product IN (SELECT id_product FROM t2 t2_2 WHERE t2_2.id_t2 = 15) +AND t3.id_product IN (SELECT id_product FROM t2 t2_3 WHERE t2_3.id_t2 = 18 OR t2_3.id_t2 = 19) +AND t3.id_product IN (SELECT id_product FROM t2 t2_4 WHERE t2_4.id_t2 = 34 OR t2_4.id_t2 = 23) +AND t3.id_product IN (SELECT id_product FROM t2 t2_5 WHERE t2_5.id_t2 = 29 OR t2_5.id_t2 = 28 OR t2_5.id_t2 = 26); + +drop table t1,t2,t3,t4,t5; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 39209f04c9f..1ec6cca7c5b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -9592,7 +9592,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) table_map current_map; i= join->const_tables; for (tab= first_depth_first_tab(join); tab; - tab= next_depth_first_tab(join, tab), i++) + tab= next_depth_first_tab(join, tab)) { bool is_hj; /* @@ -10063,6 +10063,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) } first_inner_tab= first_inner_tab->first_upper; } + if (!tab->bush_children) + i++; } } DBUG_RETURN(0); -- cgit v1.2.1 From 170b43c1568ba6b9a772e8bdfbe90bd06cc2a345 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 20 Jun 2018 16:36:46 +0400 Subject: MDEV-16534 PPC64: Unexpected error with a negative value into auto-increment columns in HEAP, MyISAM, ARIA --- mysql-test/r/auto_increment.result | 29 ++++++++++++++++++++++++ mysql-test/suite/heap/heap_auto_increment.result | 29 ++++++++++++++++++++++++ mysql-test/suite/heap/heap_auto_increment.test | 25 ++++++++++++++++++++ mysql-test/suite/maria/maria.result | 29 ++++++++++++++++++++++++ mysql-test/suite/maria/maria.test | 25 ++++++++++++++++++++ mysql-test/t/auto_increment.test | 25 ++++++++++++++++++++ storage/heap/hp_hash.c | 2 +- storage/maria/ma_key.c | 2 +- storage/myisam/mi_key.c | 2 +- 9 files changed, 165 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/auto_increment.result b/mysql-test/r/auto_increment.result index 12cbf294b69..4c04c00b79f 100644 --- a/mysql-test/r/auto_increment.result +++ b/mysql-test/r/auto_increment.result @@ -537,3 +537,32 @@ pk -5 1 drop table t1; +# +# Start of 5.5 tests +# +# +# MDEV-16534 PPC64: Unexpected error with a negative values into auto-increment columns in HEAP, MyISAM, ARIA +# +CREATE TABLE t1 ( +id TINYINT NOT NULL AUTO_INCREMENT, +name CHAR(30) NOT NULL, +PRIMARY KEY (id) +) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` tinyint(4) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 (name) VALUES ('dog'); +UPDATE t1 SET id=-1 WHERE id=1; +INSERT INTO t1 (name) VALUES ('cat'); +SELECT * FROM t1; +id name +-1 dog +2 cat +DROP TABLE t1; +# +# End of 5.5 tests +# diff --git a/mysql-test/suite/heap/heap_auto_increment.result b/mysql-test/suite/heap/heap_auto_increment.result index 5b04a77e9eb..ab0c852f253 100644 --- a/mysql-test/suite/heap/heap_auto_increment.result +++ b/mysql-test/suite/heap/heap_auto_increment.result @@ -39,3 +39,32 @@ _rowid _rowid skey sval 1 1 1 hello 2 2 2 hey drop table t1; +# +# Start of 5.5 tests +# +# +# MDEV-16534 PPC64: Unexpected error with a negative values into auto-increment columns in HEAP, MyISAM, ARIA +# +CREATE TABLE t1 ( +id TINYINT NOT NULL AUTO_INCREMENT, +name CHAR(30) NOT NULL, +PRIMARY KEY (id) +) ENGINE=MEMORY; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` tinyint(4) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MEMORY DEFAULT CHARSET=latin1 +INSERT INTO t1 (name) VALUES ('dog'); +UPDATE t1 SET id=-1 WHERE id=1; +INSERT INTO t1 (name) VALUES ('cat'); +SELECT * FROM t1; +id name +-1 dog +2 cat +DROP TABLE t1; +# +# End of 5.5 tests +# diff --git a/mysql-test/suite/heap/heap_auto_increment.test b/mysql-test/suite/heap/heap_auto_increment.test index 016bc946209..bd4a0eaa886 100644 --- a/mysql-test/suite/heap/heap_auto_increment.test +++ b/mysql-test/suite/heap/heap_auto_increment.test @@ -33,3 +33,28 @@ select _rowid,t1._rowid,skey,sval from t1; drop table t1; # End of 4.1 tests + +--echo # +--echo # Start of 5.5 tests +--echo # + +--echo # +--echo # MDEV-16534 PPC64: Unexpected error with a negative values into auto-increment columns in HEAP, MyISAM, ARIA +--echo # + +CREATE TABLE t1 ( + id TINYINT NOT NULL AUTO_INCREMENT, + name CHAR(30) NOT NULL, + PRIMARY KEY (id) +) ENGINE=MEMORY; +SHOW CREATE TABLE t1; +INSERT INTO t1 (name) VALUES ('dog'); +UPDATE t1 SET id=-1 WHERE id=1; +INSERT INTO t1 (name) VALUES ('cat'); +SELECT * FROM t1; +DROP TABLE t1; + +--echo # +--echo # End of 5.5 tests +--echo # + diff --git a/mysql-test/suite/maria/maria.result b/mysql-test/suite/maria/maria.result index 7f8badb78ae..2aca47538cb 100644 --- a/mysql-test/suite/maria/maria.result +++ b/mysql-test/suite/maria/maria.result @@ -2697,3 +2697,32 @@ ALTER TABLE t1 DISABLE KEYS; INSERT INTO t1 (b) VALUES (''); ALTER TABLE t1 ENABLE KEYS; DROP TABLE t1; +# +# Start of 5.5 tests +# +# +# MDEV-16534 PPC64: Unexpected error with a negative values into auto-increment columns in HEAP, MyISAM, ARIA +# +CREATE TABLE t1 ( +id TINYINT NOT NULL AUTO_INCREMENT, +name CHAR(30) NOT NULL, +PRIMARY KEY (id) +) ENGINE=ARIA; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` tinyint(4) NOT NULL AUTO_INCREMENT, + `name` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +INSERT INTO t1 (name) VALUES ('dog'); +UPDATE t1 SET id=-1 WHERE id=1; +INSERT INTO t1 (name) VALUES ('cat'); +SELECT * FROM t1; +id name +-1 dog +2 cat +DROP TABLE t1; +# +# End of 5.5 tests +# diff --git a/mysql-test/suite/maria/maria.test b/mysql-test/suite/maria/maria.test index 39a9a06c4c2..ab8e72dc321 100644 --- a/mysql-test/suite/maria/maria.test +++ b/mysql-test/suite/maria/maria.test @@ -1990,3 +1990,28 @@ aria_page_checksum=$default_checksum, aria_log_file_size=$default_log_file_size; --enable_result_log --enable_query_log + + +--echo # +--echo # Start of 5.5 tests +--echo # + +--echo # +--echo # MDEV-16534 PPC64: Unexpected error with a negative values into auto-increment columns in HEAP, MyISAM, ARIA +--echo # + +CREATE TABLE t1 ( + id TINYINT NOT NULL AUTO_INCREMENT, + name CHAR(30) NOT NULL, + PRIMARY KEY (id) +) ENGINE=ARIA; +SHOW CREATE TABLE t1; +INSERT INTO t1 (name) VALUES ('dog'); +UPDATE t1 SET id=-1 WHERE id=1; +INSERT INTO t1 (name) VALUES ('cat'); +SELECT * FROM t1; +DROP TABLE t1; + +--echo # +--echo # End of 5.5 tests +--echo # diff --git a/mysql-test/t/auto_increment.test b/mysql-test/t/auto_increment.test index 7f0ab5dc169..2fea2cfd351 100644 --- a/mysql-test/t/auto_increment.test +++ b/mysql-test/t/auto_increment.test @@ -397,3 +397,28 @@ insert into t1 values(null); select last_insert_id(); select * from t1; drop table t1; + + +--echo # +--echo # Start of 5.5 tests +--echo # + +--echo # +--echo # MDEV-16534 PPC64: Unexpected error with a negative values into auto-increment columns in HEAP, MyISAM, ARIA +--echo # + +CREATE TABLE t1 ( + id TINYINT NOT NULL AUTO_INCREMENT, + name CHAR(30) NOT NULL, + PRIMARY KEY (id) +) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +INSERT INTO t1 (name) VALUES ('dog'); +UPDATE t1 SET id=-1 WHERE id=1; +INSERT INTO t1 (name) VALUES ('cat'); +SELECT * FROM t1; +DROP TABLE t1; + +--echo # +--echo # End of 5.5 tests +--echo # diff --git a/storage/heap/hp_hash.c b/storage/heap/hp_hash.c index 2d4c0e9a031..ce59b79f990 100644 --- a/storage/heap/hp_hash.c +++ b/storage/heap/hp_hash.c @@ -1012,7 +1012,7 @@ void heap_update_auto_increment(HP_INFO *info, const uchar *record) switch (info->s->auto_key_type) { case HA_KEYTYPE_INT8: - s_value= (longlong) *(char*)key; + s_value= (longlong) *(const signed char*) key; break; case HA_KEYTYPE_BINARY: value=(ulonglong) *(uchar*) key; diff --git a/storage/maria/ma_key.c b/storage/maria/ma_key.c index 246e5fb6d94..42203e5d0f3 100644 --- a/storage/maria/ma_key.c +++ b/storage/maria/ma_key.c @@ -728,7 +728,7 @@ ulonglong ma_retrieve_auto_increment(const uchar *key, uint8 key_type) switch (key_type) { case HA_KEYTYPE_INT8: - s_value= (longlong) *(const char*)key; + s_value= (longlong) *(const signed char*) key; break; case HA_KEYTYPE_BINARY: value=(ulonglong) *key; diff --git a/storage/myisam/mi_key.c b/storage/myisam/mi_key.c index 9a2526ad2cf..18ecc9e8ba3 100644 --- a/storage/myisam/mi_key.c +++ b/storage/myisam/mi_key.c @@ -553,7 +553,7 @@ ulonglong retrieve_auto_increment(MI_INFO *info,const uchar *record) switch (keyseg->type) { case HA_KEYTYPE_INT8: - s_value= (longlong) *(char*)key; + s_value= (longlong) *(const signed char*) key; break; case HA_KEYTYPE_BINARY: value=(ulonglong) *(uchar*) key; -- cgit v1.2.1 From 0a9d78f51d74be7708f2efd940311bf7b33108e9 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 20 Jun 2018 23:27:23 +0200 Subject: Revert "MDEV-16075: Workaround to run MTR test suite for make test" This reverts commit d39629f01ebdd5b89186e6c8a4a8d3dd528bd26a. Because running mtr for many hours with no output whatsoever is not really what we should do. And in 5.5 `make test` just works anyway, nothing to fix here. --- CMakeLists.txt | 4 ---- cmake/ctest.cmake | 2 +- mysql-test/suite/unit/suite.pm | 2 +- unittest/sql/CMakeLists.txt | 2 +- 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 21ed1fcc24b..6ab17ebf64c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -366,10 +366,6 @@ INCLUDE(maintainer) IF(WITH_UNIT_TESTS) ENABLE_TESTING() - # This is the only instance where ADD_TEST should be used, - # to make sure that make test will run MTR, - # use MY_ADD_TEST macro to add other tests - ADD_TEST(NAME MTR COMMAND ./mysql-test-run WORKING_DIRECTORY "mysql-test") ADD_SUBDIRECTORY(unittest/mytap) ADD_SUBDIRECTORY(unittest/strings) ADD_SUBDIRECTORY(unittest/examples) diff --git a/cmake/ctest.cmake b/cmake/ctest.cmake index fde7e1632f6..08852a366f6 100644 --- a/cmake/ctest.cmake +++ b/cmake/ctest.cmake @@ -2,7 +2,7 @@ INCLUDE(${MYSQL_CMAKE_SCRIPT_DIR}/cmake_parse_arguments.cmake) MACRO(MY_ADD_TEST name) - ADD_TEST(NAME ${name} COMMAND ${name}-t CONFIGURATIONS default_ignore) + ADD_TEST(${name} ${name}-t) ENDMACRO() MACRO (MY_ADD_TESTS) diff --git a/mysql-test/suite/unit/suite.pm b/mysql-test/suite/unit/suite.pm index 43eaa970350..78d82ccb31d 100644 --- a/mysql-test/suite/unit/suite.pm +++ b/mysql-test/suite/unit/suite.pm @@ -31,7 +31,7 @@ sub start_test { return "Not run for embedded server" if $::opt_embedded_server; return "Not configured to run ctest" unless -f "../CTestTestfile.cmake"; my ($ctest_vs)= $opt_vs_config ? "--build-config $opt_vs_config" : ""; - my (@ctest_list)= `cd .. && ctest $opt_vs_config -E MTR -C default_ignore --show-only --verbose`; + my (@ctest_list)= `cd .. && ctest $opt_vs_config --show-only --verbose`; return "No ctest" if $?; my ($command, %tests); diff --git a/unittest/sql/CMakeLists.txt b/unittest/sql/CMakeLists.txt index 1efb0ac9cd1..f80f2a5ae70 100644 --- a/unittest/sql/CMakeLists.txt +++ b/unittest/sql/CMakeLists.txt @@ -26,4 +26,4 @@ ELSE() ENDIF() TARGET_LINK_LIBRARIES(explain_filename-t sql mytap) -MY_ADD_TEST(explain_filename explain_filename-t) +ADD_TEST(explain_filename explain_filename-t) -- cgit v1.2.1 From 2b8f2b3e882f7ea93c6743f2ad717f968bd245fe Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 20 Jun 2018 23:30:49 +0200 Subject: Fix unit suite on Windows and in out-of-source builds --- mysql-test/suite/unit/suite.pm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/unit/suite.pm b/mysql-test/suite/unit/suite.pm index 78d82ccb31d..ce7ccefe926 100644 --- a/mysql-test/suite/unit/suite.pm +++ b/mysql-test/suite/unit/suite.pm @@ -28,10 +28,11 @@ sub start_test { } { + my $bin=$ENV{MTR_BINDIR} || '..'; return "Not run for embedded server" if $::opt_embedded_server; - return "Not configured to run ctest" unless -f "../CTestTestfile.cmake"; - my ($ctest_vs)= $opt_vs_config ? "--build-config $opt_vs_config" : ""; - my (@ctest_list)= `cd .. && ctest $opt_vs_config --show-only --verbose`; + return "Not configured to run ctest" unless -f "$bin/CTestTestfile.cmake"; + my ($ctest_vs)= $::opt_vs_config ? "-C ".substr($::opt_vs_config,1) : ""; + my (@ctest_list)= `cd $bin && ctest $ctest_vs --show-only --verbose`; return "No ctest" if $?; my ($command, %tests); -- cgit v1.2.1 From 364a20fe0b072fb1d2a9b54a8c4e47a5012f3e97 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sat, 23 Jun 2018 19:36:26 -0700 Subject: MDEV-16507 SIGSEGV when use_stat_tables = preferably and optimizer_use_condition_selectivity = 4 It does not makes sense to try to read statistics for temporary tables because it's not collected. --- mysql-test/r/statistics.result | 20 ++++++++++++++++++++ mysql-test/t/statistics.test | 24 ++++++++++++++++++++++++ sql/sql_statistics.cc | 8 ++++---- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/statistics.result b/mysql-test/r/statistics.result index 74997c92d3e..23c8807897b 100644 --- a/mysql-test/r/statistics.result +++ b/mysql-test/r/statistics.result @@ -1659,3 +1659,23 @@ id set use_stat_tables=@save_use_stat_tables; set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; drop table t1,t2; +# +# MDEV-16507: statistics for temporary tables should not be used +# +SET +@save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity; +SET @@use_stat_tables = preferably ; +SET @@optimizer_use_condition_selectivity = 4; +CREATE TABLE t1 ( +TIMESTAMP TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +ON UPDATE CURRENT_TIMESTAMP +); +SET @had_t1_table= @@warning_count != 0; +CREATE TEMPORARY TABLE tmp_t1 LIKE t1; +INSERT INTO tmp_t1 VALUES (now()); +INSERT INTO t1 SELECT * FROM tmp_t1 WHERE @had_t1_table=0; +DROP TABLE t1; +SET +use_stat_tables=@save_use_stat_tables; +SET +optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; diff --git a/mysql-test/t/statistics.test b/mysql-test/t/statistics.test index 0ab42453125..5831e0b1d60 100644 --- a/mysql-test/t/statistics.test +++ b/mysql-test/t/statistics.test @@ -737,3 +737,27 @@ set use_stat_tables=@save_use_stat_tables; set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; drop table t1,t2; +--echo # +--echo # MDEV-16507: statistics for temporary tables should not be used +--echo # + +SET +@save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity; +SET @@use_stat_tables = preferably ; +SET @@optimizer_use_condition_selectivity = 4; + +CREATE TABLE t1 ( + TIMESTAMP TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP + ON UPDATE CURRENT_TIMESTAMP +); + +SET @had_t1_table= @@warning_count != 0; +CREATE TEMPORARY TABLE tmp_t1 LIKE t1; +INSERT INTO tmp_t1 VALUES (now()); +INSERT INTO t1 SELECT * FROM tmp_t1 WHERE @had_t1_table=0; +DROP TABLE t1; + +SET +use_stat_tables=@save_use_stat_tables; +SET +optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 471749ad346..1febc02b903 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -2952,7 +2952,7 @@ bool statistics_for_tables_is_needed(THD *thd, TABLE_LIST *tables) for (TABLE_LIST *tl= tables; tl; tl= tl->next_global) { - if (!tl->is_view_or_derived() && tl->table) + if (!tl->is_view_or_derived() && !is_temporary_table(tl) && tl->table) { TABLE_SHARE *table_share= tl->table->s; if (table_share && @@ -2964,7 +2964,7 @@ bool statistics_for_tables_is_needed(THD *thd, TABLE_LIST *tables) for (TABLE_LIST *tl= tables; tl; tl= tl->next_global) { - if (!tl->is_view_or_derived() && tl->table) + if (!tl->is_view_or_derived() && !is_temporary_table(tl) && tl->table) { TABLE_SHARE *table_share= tl->table->s; if (table_share && @@ -3093,7 +3093,7 @@ int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables) for (TABLE_LIST *tl= tables; tl; tl= tl->next_global) { - if (!tl->is_view_or_derived() && tl->table) + if (!tl->is_view_or_derived() && !is_temporary_table(tl) && tl->table) { TABLE_SHARE *table_share= tl->table->s; if (table_share && @@ -3867,4 +3867,4 @@ bool is_stat_table(const char *db, const char *table) } } return false; -} \ No newline at end of file +} -- cgit v1.2.1 From 28e1f1453f12b8b748c31a86a22b336f62002654 Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Tue, 19 Jun 2018 18:14:47 +0300 Subject: MDEV-15242 Poor RBR update performance with partitioned tables Observed and described partitioned engine execution time difference between master and slave was caused by excessive invocation of base_engine::rnd_init which was done also for partitions uninvolved into Rows-event operation. The bug's slave slowdown therefore scales with the number of partitions. Fixed with applying an upstream patch. References: ---------- https://bugs.mysql.com/bug.php?id=73648 Bug#25687813 REPLICATION REGRESSION WITH RBR AND PARTITIONED TABLES --- sql/ha_partition.cc | 3 ++- sql/handler.h | 10 +++++++++- sql/log_event.cc | 4 ---- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 6a6627f9276..0488ebfb60f 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -5090,7 +5090,8 @@ int ha_partition::rnd_pos_by_record(uchar *record) if (unlikely(get_part_for_delete(record, m_rec0, m_part_info, &m_last_part))) DBUG_RETURN(1); - DBUG_RETURN(handler::rnd_pos_by_record(record)); + int err= m_file[m_last_part]->rnd_pos_by_record(record); + DBUG_RETURN(err); } diff --git a/sql/handler.h b/sql/handler.h index 74d50536ec4..52396b84c0d 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -3042,9 +3042,17 @@ private: */ virtual int rnd_pos_by_record(uchar *record) { + int error; DBUG_ASSERT(table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION); + + error = ha_rnd_init(false); + if (error != 0) + return error; + position(record); - return rnd_pos(record, ref); + error = ha_rnd_pos(record, ref); + ha_rnd_end(); + return error; } virtual int read_first_row(uchar *buf, uint primary_key); public: diff --git a/sql/log_event.cc b/sql/log_event.cc index 7989db9c687..3638269cbf5 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -12135,10 +12135,6 @@ int Rows_log_event::find_row(rpl_group_info *rgi) int error; DBUG_PRINT("info",("locating record using primary key (position)")); - if (!table->file->inited && - (error= table->file->ha_rnd_init_with_error(0))) - DBUG_RETURN(error); - error= table->file->ha_rnd_pos_by_record(table->record[0]); if (error) { -- cgit v1.2.1 From 90e608c6acd150e727cb0002f36767d0866aa633 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 26 Jun 2018 11:42:02 +0400 Subject: A test cleanup for MDEV-15834: fixing failure in "mtr --embedded" --- mysql-test/suite/vcol/t/vcol_misc.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/suite/vcol/t/vcol_misc.test b/mysql-test/suite/vcol/t/vcol_misc.test index a123d21d574..fab705eaaa6 100644 --- a/mysql-test/suite/vcol/t/vcol_misc.test +++ b/mysql-test/suite/vcol/t/vcol_misc.test @@ -327,8 +327,10 @@ SET sql_mode=DEFAULT; --copy_file std_data/frm/t1.frm $MYSQLD_DATADIR/test/t1.frm SHOW TABLES; +--replace_result $MYSQLD_DATADIR ./ --error ER_NOT_FORM_FILE SHOW CREATE TABLE t1; +--replace_result $MYSQLD_DATADIR ./ --error ER_NOT_FORM_FILE ALTER TABLE t1; --remove_file $MYSQLD_DATADIR/test/t1.frm -- cgit v1.2.1 From ff8b3c8df89e973f3b91fa82a5fec65ef0e01c53 Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Sat, 23 Jun 2018 13:49:36 +0300 Subject: MDEV-15953 Alter InnoDB Partitioned Table Moves Files (which were originally not in the datadir) to the datadir ha_innobase::prepare_inplace_alter_table: preserve DATA DICTIONARY for table --- .../parts/r/alter_data_directory_innodb.result | 65 ++++++++++++++++++++++ .../suite/parts/t/alter_data_directory_innodb.test | 46 +++++++++++++++ storage/innobase/handler/handler0alter.cc | 6 ++ storage/xtradb/handler/handler0alter.cc | 6 ++ 4 files changed, 123 insertions(+) create mode 100644 mysql-test/suite/parts/r/alter_data_directory_innodb.result create mode 100644 mysql-test/suite/parts/t/alter_data_directory_innodb.test diff --git a/mysql-test/suite/parts/r/alter_data_directory_innodb.result b/mysql-test/suite/parts/r/alter_data_directory_innodb.result new file mode 100644 index 00000000000..ee0a7b80ebb --- /dev/null +++ b/mysql-test/suite/parts/r/alter_data_directory_innodb.result @@ -0,0 +1,65 @@ +# +# MDEV-15953 Alter InnoDB Partitioned Table Moves Files (which were originally not in the datadir) to the datadir +# +CREATE TABLE t ( +a INT NOT NULL +) ENGINE=INNODB +PARTITION BY HASH (a) ( +PARTITION p1 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here/' ENGINE = INNODB, +PARTITION p2 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here/' ENGINE = INNODB +); +INSERT INTO t VALUES (1); +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY HASH (a) +(PARTITION p1 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB, + PARTITION p2 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB) */ +ALTER TABLE t ADD PRIMARY KEY pk(a), ALGORITHM=INPLACE; +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY HASH (a) +(PARTITION p1 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB, + PARTITION p2 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB) */ +ALTER TABLE t DROP PRIMARY KEY, ALGORITHM=COPY; +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY HASH (a) +(PARTITION p1 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB, + PARTITION p2 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB) */ +SET @TMP = @@GLOBAL.INNODB_FILE_PER_TABLE; +SET GLOBAL INNODB_FILE_PER_TABLE=OFF; +ALTER TABLE t ADD PRIMARY KEY pk(a), ALGORITHM=INPLACE; +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY HASH (a) +(PARTITION p1 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB, + PARTITION p2 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB) */ +SET GLOBAL INNODB_FILE_PER_TABLE=@TMP; +ALTER TABLE t REORGANIZE PARTITION p1,p2 INTO ( +PARTITION p1 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = INNODB, +PARTITION p2 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = INNODB +); +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY HASH (a) +(PARTITION p1 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB, + PARTITION p2 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB) */ +DROP TABLE t; diff --git a/mysql-test/suite/parts/t/alter_data_directory_innodb.test b/mysql-test/suite/parts/t/alter_data_directory_innodb.test new file mode 100644 index 00000000000..ac15e9bec6c --- /dev/null +++ b/mysql-test/suite/parts/t/alter_data_directory_innodb.test @@ -0,0 +1,46 @@ +--source include/have_innodb.inc +--source include/have_partition.inc + +--echo # +--echo # MDEV-15953 Alter InnoDB Partitioned Table Moves Files (which were originally not in the datadir) to the datadir +--echo # + +mkdir $MYSQLTEST_VARDIR/tmp/partitions_here; + +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval CREATE TABLE t ( + a INT NOT NULL +) ENGINE=INNODB +PARTITION BY HASH (a) ( + PARTITION p1 DATA DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_here/' ENGINE = INNODB, + PARTITION p2 DATA DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_here/' ENGINE = INNODB +); +INSERT INTO t VALUES (1); + +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +SHOW CREATE TABLE t; +ALTER TABLE t ADD PRIMARY KEY pk(a), ALGORITHM=INPLACE; +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +SHOW CREATE TABLE t; +ALTER TABLE t DROP PRIMARY KEY, ALGORITHM=COPY; +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +SHOW CREATE TABLE t; +SET @TMP = @@GLOBAL.INNODB_FILE_PER_TABLE; +SET GLOBAL INNODB_FILE_PER_TABLE=OFF; +ALTER TABLE t ADD PRIMARY KEY pk(a), ALGORITHM=INPLACE; +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +SHOW CREATE TABLE t; +SET GLOBAL INNODB_FILE_PER_TABLE=@TMP; + +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval ALTER TABLE t REORGANIZE PARTITION p1,p2 INTO ( + PARTITION p1 DATA DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = INNODB, + PARTITION p2 DATA DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = INNODB +); +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +SHOW CREATE TABLE t; + +DROP TABLE t; + +rmdir $MYSQLTEST_VARDIR/tmp/partitions_here/test; +rmdir $MYSQLTEST_VARDIR/tmp/partitions_here; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 86935a4aa34..3de46ed4f80 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -3572,6 +3572,12 @@ check_if_ok_to_rename: goto err_exit_no_heap; } + /* Preserve this flag, because it currenlty can't be changed during + ALTER TABLE*/ + if (flags2 & DICT_TF2_USE_TABLESPACE) { + flags |= prebuilt->table->flags & 1U << DICT_TF_POS_DATA_DIR; + } + max_col_len = DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(flags); /* Check each index's column length to make sure they do not diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index ff524e6a9be..755c07848e1 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -3586,6 +3586,12 @@ check_if_ok_to_rename: goto err_exit_no_heap; } + /* Preserve this flag, because it currenlty can't be changed during + ALTER TABLE*/ + if (flags2 & DICT_TF2_USE_TABLESPACE) { + flags |= prebuilt->table->flags & 1U << DICT_TF_POS_DATA_DIR; + } + max_col_len = DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(flags); /* Check each index's column length to make sure they do not -- cgit v1.2.1 From 1f6a89a8fdf88029518584f3e906d0e55bc1889a Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Wed, 27 Jun 2018 13:18:03 +0300 Subject: Added valgrind suppression for OpenSuse 42.2 --- mysql-test/valgrind.supp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index 71e6836365e..c9c06c2634a 100644 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp @@ -608,6 +608,19 @@ fun:dlopen* } +# +# Warning caused by small memory leak in _dl_init +# + +{ + dl_init memory leak + Memcheck:Leak + fun:malloc + obj:*/libstdc++.so* + fun:call_init.part* + fun:_dl_init +} + # # In glibc (checked version 2.7), inet_ntoa allocates an 18-byte # per-thread static buffer for the return value. That memory is freed -- cgit v1.2.1 From faef2e6a44de8e1c1301104671d08dfc1deef1e0 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Wed, 27 Jun 2018 13:18:30 +0300 Subject: Added more help text in case mysql_install_db fails. --- scripts/mysql_install_db.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 2c5f8d7082d..a8f32526a7e 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -211,6 +211,11 @@ cannot_find_file() echo "If you compiled from source, you need to run 'make install' to" echo "copy the software into the correct location ready for operation." echo + echo "If you compiled from source, you need to either run 'make install' to" + echo "copy the software into the correct location ready for operation." + echo "If you don't want to do a full install, you can use the --srcdir" + echo "option to only install the mysql database and privilege tables" + echo echo "If you are using a binary release, you must either be at the top" echo "level of the extracted archive, or pass the --basedir option" echo "pointing to that location." -- cgit v1.2.1 From 937c19318819f63d72a66dac5a60c638386512d6 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Wed, 27 Jun 2018 13:17:18 +0300 Subject: Fixed MDEV-16512, crashing on re-execution of failing SP MDEV-16512 Server crashes in find_field_in_table_ref on 2nd execution of SP referring to non-existing field Problem was in the natural join code that it changed TABLE_LIST and Item_fields but didn't restore changed things if things goes wrong and was not able to re-execute after failure. Some of the problems could have been avoided if we would have run fix_fields before doing natural join transformations. Fixed by marking functions complete AFTER they had executed, instead at start. I had also to change some tests that checked if Item_fields are usable. This doesn't fix all known problems, but at least avoids some crashes. What should be done in the near future is to mark the statement in the SP as 'not re-executable' and force a reparse of it on next execution. Reviewer: Sergei Petrunia --- mysql-test/r/join.result | 40 +++++++++++++++++++++++++++++++++++++ mysql-test/t/join.test | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ sql/sql_base.cc | 12 ++++++----- sql/table.cc | 6 +++--- 4 files changed, 102 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result index 1e51d55f012..7b0e7807e39 100644 --- a/mysql-test/r/join.result +++ b/mysql-test/r/join.result @@ -1497,3 +1497,43 @@ Note 1003 select NULL AS `i1`,`v2`.`i2` AS `i2`,`v2`.`a` AS `a`,`v2`.`b` AS `b` DROP VIEW v2; DROP TABLE t1,t2; SET optimizer_switch=@save_optimizer_switch; +# +# MDEV-16512 +# Server crashes in find_field_in_table_ref on 2nd execution of SP referring to +# non-existing field +# +CREATE TABLE t (i INT); +CREATE PROCEDURE p() SELECT t1.f FROM t AS t1 JOIN t AS t2 USING (f); +CALL p; +ERROR 42S22: Unknown column 'f' in 'from clause' +CALL p; +ERROR 42S22: Unknown column 'f' in 'from clause' +FLUSH TABLES; +CALL p; +ERROR 42S22: Unknown column 'f' in 'from clause' +DROP TABLE t; +CREATE TABLE t (f INT); +CALL p; +ERROR 42S22: Unknown column 'f' in 'from clause' +DROP TABLE t; +CREATE TABLE t (i INT); +CALL p; +ERROR 42S22: Unknown column 'f' in 'from clause' +DROP PROCEDURE p; +DROP TABLE t; +CREATE TABLE t1 (a INT, b INT); +CREATE TABLE t2 (a INT); +CREATE TABLE t3 (a INT, c INT); +CREATE TABLE t4 (a INT, c INT); +CREATE TABLE t5 (a INT, c INT); +CREATE PROCEDURE p1() SELECT c FROM t1 JOIN (t2 LEFT JOIN t3 USING (a) LEFT JOIN t4 USING (a) +LEFT JOIN t5 USING (a)) USING (a); +CALL p1; +ERROR 23000: Column 'c' in field list is ambiguous +CALL p1; +ERROR 23000: Column 'c' in field list is ambiguous +DROP PROCEDURE p1; +DROP TABLE t1,t2,t3,t4,t5; +# +# End of MariaDB 5.5 tests +# diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test index 203a7d377a5..feafac57a7e 100644 --- a/mysql-test/t/join.test +++ b/mysql-test/t/join.test @@ -1159,3 +1159,55 @@ DROP VIEW v2; DROP TABLE t1,t2; SET optimizer_switch=@save_optimizer_switch; + +--echo # +--echo # MDEV-16512 +--echo # Server crashes in find_field_in_table_ref on 2nd execution of SP referring to +--echo # non-existing field +--echo # + +CREATE TABLE t (i INT); +CREATE PROCEDURE p() SELECT t1.f FROM t AS t1 JOIN t AS t2 USING (f); +--error ER_BAD_FIELD_ERROR +CALL p; +--error ER_BAD_FIELD_ERROR +CALL p; +FLUSH TABLES; +--error ER_BAD_FIELD_ERROR +CALL p; +DROP TABLE t; + +# +# Fix the table definition to match the using +# + +CREATE TABLE t (f INT); +# +# The following shouldn't fail as the table is now matching the using +# +--error ER_BAD_FIELD_ERROR +CALL p; +DROP TABLE t; +CREATE TABLE t (i INT); +--error ER_BAD_FIELD_ERROR +CALL p; +DROP PROCEDURE p; +DROP TABLE t; + +CREATE TABLE t1 (a INT, b INT); +CREATE TABLE t2 (a INT); +CREATE TABLE t3 (a INT, c INT); +CREATE TABLE t4 (a INT, c INT); +CREATE TABLE t5 (a INT, c INT); +CREATE PROCEDURE p1() SELECT c FROM t1 JOIN (t2 LEFT JOIN t3 USING (a) LEFT JOIN t4 USING (a) +LEFT JOIN t5 USING (a)) USING (a); +--error ER_NON_UNIQ_ERROR +CALL p1; +--error ER_NON_UNIQ_ERROR +CALL p1; +DROP PROCEDURE p1; +DROP TABLE t1,t2,t3,t4,t5; + +--echo # +--echo # End of MariaDB 5.5 tests +--echo # diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 71bbb538b5c..8ffb7bc118b 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -7687,6 +7687,7 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join, Query_arena *arena, backup; bool result= TRUE; List *non_join_columns; + List *join_columns; DBUG_ENTER("store_natural_using_join_columns"); DBUG_ASSERT(!natural_using_join->join_columns); @@ -7694,7 +7695,7 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join, arena= thd->activate_stmt_arena_if_needed(&backup); if (!(non_join_columns= new List) || - !(natural_using_join->join_columns= new List)) + !(join_columns= new List)) goto err; /* Append the columns of the first join operand. */ @@ -7703,7 +7704,7 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join, nj_col_1= it_1.get_natural_column_ref(); if (nj_col_1->is_common) { - natural_using_join->join_columns->push_back(nj_col_1); + join_columns->push_back(nj_col_1); /* Reset the common columns for the next call to mark_common_columns. */ nj_col_1->is_common= FALSE; } @@ -7724,7 +7725,7 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join, { const char *using_field_name_ptr= using_field_name->c_ptr(); List_iterator_fast - it(*(natural_using_join->join_columns)); + it(*join_columns); Natural_join_column *common_field; for (;;) @@ -7757,7 +7758,8 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join, } if (non_join_columns->elements > 0) - natural_using_join->join_columns->concat(non_join_columns); + join_columns->concat(non_join_columns); + natural_using_join->join_columns= join_columns; natural_using_join->is_join_columns_complete= TRUE; result= FALSE; @@ -7989,7 +7991,6 @@ static bool setup_natural_join_row_types(THD *thd, DBUG_PRINT("info", ("using cached setup_natural_join_row_types")); DBUG_RETURN(false); } - context->select_lex->first_natural_join_processing= false; List_iterator_fast table_ref_it(*from_clause); TABLE_LIST *table_ref; /* Current table reference. */ @@ -8034,6 +8035,7 @@ static bool setup_natural_join_row_types(THD *thd, change on re-execution */ context->natural_join_first_table= context->first_name_resolution_table; + context->select_lex->first_natural_join_processing= false; DBUG_RETURN (false); } diff --git a/sql/table.cc b/sql/table.cc index 87a249defa0..48aa445e1aa 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -5487,7 +5487,7 @@ Field_iterator_table_ref::get_or_create_column_ref(THD *thd, TABLE_LIST *parent_ nj_col= natural_join_it.column_ref(); DBUG_ASSERT(nj_col); } - DBUG_ASSERT(!nj_col->table_field || + DBUG_ASSERT(!nj_col->table_field || !nj_col->table_field->field || nj_col->table_ref->table == nj_col->table_field->field->table); /* @@ -5536,7 +5536,7 @@ Field_iterator_table_ref::get_or_create_column_ref(THD *thd, TABLE_LIST *parent_ RETURN # Pointer to a column of a natural join (or its operand) - NULL No memory to allocate the column + NULL We didn't originally have memory to allocate the column */ Natural_join_column * @@ -5552,7 +5552,7 @@ Field_iterator_table_ref::get_natural_column_ref() */ nj_col= natural_join_it.column_ref(); DBUG_ASSERT(nj_col && - (!nj_col->table_field || + (!nj_col->table_field || !nj_col->table_field->field || nj_col->table_ref->table == nj_col->table_field->field->table)); return nj_col; } -- cgit v1.2.1 From bf4244d1a0d921defbd92deb1e54b59ee1ce35b4 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 27 Jun 2018 17:01:09 +0400 Subject: MDEV-8540 - Crash on server shutdown since 10.0.16 Only close stdin if it was open initinally. Otherwise we may close file descriptor which is reused for different puprose (specifically for binlog index file in case of this bug). --- sql/mysqld.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index fb49c05def5..d760986a303 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5149,6 +5149,9 @@ int win_main(int argc, char **argv) int mysqld_main(int argc, char **argv) #endif { + /* We can't close stdin just now, because it may be booststrap mode. */ + bool please_close_stdin= fcntl(STDIN_FILENO, F_GETFD) >= 0; + /* Perform basic thread library and malloc initialization, to be able to read defaults files and parse options. @@ -5492,7 +5495,9 @@ int mysqld_main(int argc, char **argv) (char*) "" : mysqld_unix_port), mysqld_port, MYSQL_COMPILATION_COMMENT); - fclose(stdin); + /* Only close stdin if it was open initinally. */ + if (please_close_stdin) + fclose(stdin); #if defined(_WIN32) && !defined(EMBEDDED_LIBRARY) Service.SetRunning(); #endif -- cgit v1.2.1 From 9d41dd2f39f5a0c840d77e5fb7fc8d1396bf1a33 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 27 Jun 2018 15:34:11 +0400 Subject: MDEV-8540 - Crash on server shutdown since 10.0.16 For the purpose of reporting an error to error log, shutdown thread was attempting to access current_thd->variables.lc_messages->errmsgs->errmsgs. Whereas current_thd was NULL. We should log errors according to global lc_messages setting instead of session setting. --- sql/log.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index 5b4ba87ef52..2504b5e2d06 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2499,14 +2499,14 @@ void MYSQL_LOG::close(uint exiting) if (log_type == LOG_BIN && mysql_file_sync(log_file.file, MYF(MY_WME)) && ! write_error) { write_error= 1; - sql_print_error(ER_THD_OR_DEFAULT(current_thd, ER_ERROR_ON_WRITE), name, errno); + sql_print_error(ER_DEFAULT(ER_ERROR_ON_WRITE), name, errno); } if (!(exiting & LOG_CLOSE_DELAYED_CLOSE) && mysql_file_close(log_file.file, MYF(MY_WME)) && ! write_error) { write_error= 1; - sql_print_error(ER_THD_OR_DEFAULT(current_thd, ER_ERROR_ON_WRITE), name, errno); + sql_print_error(ER_DEFAULT(ER_ERROR_ON_WRITE), name, errno); } } @@ -2690,7 +2690,7 @@ err: if (!write_error) { write_error= 1; - sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno); + sql_print_error(ER_DEFAULT(ER_ERROR_ON_WRITE), name, errno); } mysql_mutex_unlock(&LOCK_log); return TRUE; @@ -2866,7 +2866,7 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time, if (! write_error) { write_error= 1; - sql_print_error(ER(ER_ERROR_ON_WRITE), name, tmp_errno); + sql_print_error(ER_DEFAULT(ER_ERROR_ON_WRITE), name, tmp_errno); } } } @@ -6385,7 +6385,7 @@ void MYSQL_BIN_LOG::close(uint exiting) if (mysql_file_close(index_file.file, MYF(0)) < 0 && ! write_error) { write_error= 1; - sql_print_error(ER(ER_ERROR_ON_WRITE), index_file_name, errno); + sql_print_error(ER_DEFAULT(ER_ERROR_ON_WRITE), index_file_name, errno); } } log_state= (exiting & LOG_CLOSE_TO_BE_OPENED) ? LOG_TO_BE_OPENED : LOG_CLOSED; -- cgit v1.2.1 From 3d4beee1a98cebd6eb566e38569e19599c2b9a98 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 28 Jun 2018 11:59:25 +0200 Subject: remove double-counting rnd_pos_by_record calls ha_rnd_pos, which does the counting --- sql/sql_class.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/sql/sql_class.h b/sql/sql_class.h index ec94f6c45d2..9428f6f6ce5 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -5012,8 +5012,6 @@ inline int handler::ha_ft_read(uchar *buf) inline int handler::ha_rnd_pos_by_record(uchar *buf) { int error= rnd_pos_by_record(buf); - if (!error) - update_rows_read(); table->status=error ? STATUS_NOT_FOUND: 0; return error; } -- cgit v1.2.1 From 90cb7212742e9ae3a63bd183e171c95bd12d559f Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 29 Jun 2018 22:46:38 -0700 Subject: MDEV-16603 Crash with set join_cache_level=4 When the definition of the index used for hash join was created in create_hj_key_for_table() it could cause memory overwrite due to a bug that led to an underestimation of the number of the index component. --- mysql-test/r/join_cache.result | 33 +++++++++++++++++++++++++++++++++ mysql-test/t/join_cache.test | 31 +++++++++++++++++++++++++++++++ sql/sql_select.cc | 4 ++-- 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index 386f7119bc8..f1e6fb577c8 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -5871,4 +5871,37 @@ SET join_buffer_size = default; SET join_buffer_space_limit= default; set optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t4,t5,t2; +# +# MDEV-16603: BNLH for query with materialized semi-join +# +set join_cache_level=4; +CREATE TABLE t1 ( i1 int, v1 varchar(1)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (7,'x'); +CREATE TABLE t2 (i1 int, v1 varchar(1), KEY v1 (v1,i1)) ENGINE=InnoDB; +INSERT INTO t2 VALUES +(NULL,'x'),(1,'x'),(3,'x'),(5,'x'),(8,'x'),(48,'x'), +(228,'x'),(3,'y'),(1,'z'),(9,'z'); +CREATE TABLE temp +SELECT t1.i1 AS f1, t1.v1 AS f2 FROM (t2 JOIN t1 ON (t1.v1 = t2.v1)); +SELECT * FROM temp +WHERE (f1,f2) IN (SELECT t1.i1, t1.v1 FROM (t2 JOIN t1 ON (t1.v1 = t2.v1))); +f1 f2 +7 x +7 x +7 x +7 x +7 x +7 x +7 x +EXPLAIN EXTENDED SELECT * FROM temp +WHERE (f1,f2) IN (SELECT t1.i1, t1.v1 FROM (t2 JOIN t1 ON (t1.v1 = t2.v1))); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY ALL distinct_key NULL NULL NULL 1 100.00 +1 PRIMARY temp hash_ALL NULL #hash#$hj 9 test.t1.i1,test.t1.v1 7 100.00 Using where; Using join buffer (flat, BNLH join) +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 1 100.00 Using where +2 MATERIALIZED t2 hash_index v1 #hash#v1:v1 4:9 test.t1.v1 10 10.00 Using join buffer (flat, BNLH join) +Warnings: +Note 1003 select `test`.`temp`.`f1` AS `f1`,`test`.`temp`.`f2` AS `f2` from `test`.`temp` semi join (`test`.`t2` join `test`.`t1`) where ((`test`.`temp`.`f1` = `test`.`t1`.`i1`) and (`test`.`t2`.`v1` = `test`.`t1`.`v1`) and (`test`.`temp`.`f2` = `test`.`t1`.`v1`)) +DROP TABLE t1,t2,temp; +SET join_cache_level = default; set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test index 58a7b885356..d82b4fa6030 100644 --- a/mysql-test/t/join_cache.test +++ b/mysql-test/t/join_cache.test @@ -3836,5 +3836,36 @@ set optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t4,t5,t2; +--echo # +--echo # MDEV-16603: BNLH for query with materialized semi-join +--echo # + +--source include/have_innodb.inc + +set join_cache_level=4; + +CREATE TABLE t1 ( i1 int, v1 varchar(1)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (7,'x'); + +CREATE TABLE t2 (i1 int, v1 varchar(1), KEY v1 (v1,i1)) ENGINE=InnoDB; + +INSERT INTO t2 VALUES + (NULL,'x'),(1,'x'),(3,'x'),(5,'x'),(8,'x'),(48,'x'), + (228,'x'),(3,'y'),(1,'z'),(9,'z'); + +CREATE TABLE temp +SELECT t1.i1 AS f1, t1.v1 AS f2 FROM (t2 JOIN t1 ON (t1.v1 = t2.v1)); + +let $q = +SELECT * FROM temp +WHERE (f1,f2) IN (SELECT t1.i1, t1.v1 FROM (t2 JOIN t1 ON (t1.v1 = t2.v1))); + +eval $q; +eval EXPLAIN EXTENDED $q; + +DROP TABLE t1,t2,temp; + +SET join_cache_level = default; + # this must be the last command in the file set @@optimizer_switch=@save_optimizer_switch; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b79431ae2f6..700b7b37928 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7994,7 +7994,6 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab, if (first_keyuse) { key_parts++; - first_keyuse= FALSE; } else { @@ -8004,7 +8003,7 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab, if (curr->keypart == keyuse->keypart && !(~used_tables & curr->used_tables) && join_tab->keyuse_is_valid_for_access_in_chosen_plan(join, - keyuse) && + curr) && are_tables_local(join_tab, curr->used_tables)) break; } @@ -8012,6 +8011,7 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab, key_parts++; } } + first_keyuse= FALSE; keyuse++; } while (keyuse->table == table && keyuse->is_for_hash_join()); if (!key_parts) -- cgit v1.2.1 From 0897a25c0f0b9b86590fd581795aa64b3fbef009 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 2 Jul 2018 15:02:31 +0100 Subject: MDEV-16596 : Windows - redo log does not work on native 4K sector disks. Disks with native 4K sectors need 4K alignment and size for unbuffered IO (i.e for files opened with FILE_FLAG_NO_BUFFERING) Innodb opens redo log with FILE_FLAG_NO_BUFFERING, however it always does 512byte IOs. Thus, the IO on 4K native sectors will fail, rendering Innodb non-functional. The fix is to check whether OS_FILE_LOG_BLOCK_SIZE is multiple of logical sector size, and if it is not, reopen the redo log without FILE_FLAG_NO_BUFFERING flag. --- cmake/os/Windows.cmake | 2 +- storage/xtradb/os/os0file.cc | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/cmake/os/Windows.cmake b/cmake/os/Windows.cmake index e4221227d91..b69ae9bebf8 100644 --- a/cmake/os/Windows.cmake +++ b/cmake/os/Windows.cmake @@ -51,7 +51,7 @@ IF(CMAKE_C_COMPILER MATCHES "icl") ENDIF() ADD_DEFINITIONS(-D_WINDOWS -D__WIN__ -D_CRT_SECURE_NO_DEPRECATE) -ADD_DEFINITIONS(-D_WIN32_WINNT=0x0501) +ADD_DEFINITIONS(-D_WIN32_WINNT=0x0A00) # We do not want the windows.h macros min/max ADD_DEFINITIONS(-DNOMINMAX) # Speed up build process excluding unused header files diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc index 9df42470e5a..bf9db50b7f7 100644 --- a/storage/xtradb/os/os0file.cc +++ b/storage/xtradb/os/os0file.cc @@ -1691,6 +1691,31 @@ os_file_set_atomic_writes( #endif } +/** Check that IO of specific size is possible for the file +opened with FILE_FLAG_NO_BUFFERING. + +The requirement is that IO is multiple of the disk sector size. + +@param[in] file file handle +@param[in] io_size expected io size +@return true - unbuffered io of requested size is possible, false otherwise. + +@note: this function only works correctly with Windows 8 or later, +(GetFileInformationByHandleEx with FileStorageInfo is only supported there). +It will return true on earlier Windows version. +*/ +static bool unbuffered_io_possible(HANDLE file, size_t io_size) +{ + FILE_STORAGE_INFO info; + if (GetFileInformationByHandleEx( + file, FileStorageInfo, &info, sizeof(info))) { + ULONG sector_size = info.LogicalBytesPerSector; + if (sector_size) + return io_size % sector_size == 0; + } + return true; +} + /****************************************************************//** NOTE! Use the corresponding macro os_file_create(), not directly this function! @@ -1851,6 +1876,18 @@ os_file_create_func( (LPCTSTR) name, access, share_mode, NULL, create_flag, attributes, NULL); + /* If FILE_FLAG_NO_BUFFERING was set, check if this can work at all, + for expected IO sizes. Reopen without the unbuffered flag, if it is won't work*/ + if ((file.m_file != INVALID_HANDLE_VALUE) + && (attributes & FILE_FLAG_NO_BUFFERING) + && (type == OS_LOG_FILE) + && !unbuffered_io_possible(file.m_file, OS_FILE_LOG_BLOCK_SIZE)) { + ut_a(CloseHandle(file.m_file)); + attributes &= ~FILE_FLAG_NO_BUFFERING; + create_flag = OPEN_ALWAYS; + continue; + } + if (file.m_file == INVALID_HANDLE_VALUE) { const char* operation; -- cgit v1.2.1 From 8c5d64dafb3051749f3762cbad88553568abbb16 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 2 Jul 2018 15:22:52 +0100 Subject: Post-fix after MDEV-8540 - do not close stdin on Windows. It is not open. --- sql/mysqld.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d760986a303..75d6cca7fda 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5149,8 +5149,10 @@ int win_main(int argc, char **argv) int mysqld_main(int argc, char **argv) #endif { +#ifndef _WIN32 /* We can't close stdin just now, because it may be booststrap mode. */ bool please_close_stdin= fcntl(STDIN_FILENO, F_GETFD) >= 0; +#endif /* Perform basic thread library and malloc initialization, @@ -5495,9 +5497,12 @@ int mysqld_main(int argc, char **argv) (char*) "" : mysqld_unix_port), mysqld_port, MYSQL_COMPILATION_COMMENT); +#ifndef _WIN32 /* Only close stdin if it was open initinally. */ if (please_close_stdin) fclose(stdin); +#endif + #if defined(_WIN32) && !defined(EMBEDDED_LIBRARY) Service.SetRunning(); #endif -- cgit v1.2.1 From a2c0376e08d80d7b7dad8713d1df334b2b81eff9 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 2 Jul 2018 17:45:19 +0100 Subject: Fix build on non-Windows, broken by 0897a25c0f0b9b865 --- storage/xtradb/os/os0file.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc index bf9db50b7f7..4246bfbff70 100644 --- a/storage/xtradb/os/os0file.cc +++ b/storage/xtradb/os/os0file.cc @@ -1691,6 +1691,7 @@ os_file_set_atomic_writes( #endif } +#ifdef _WIN32 /** Check that IO of specific size is possible for the file opened with FILE_FLAG_NO_BUFFERING. @@ -1715,6 +1716,7 @@ static bool unbuffered_io_possible(HANDLE file, size_t io_size) } return true; } +#endif /****************************************************************//** NOTE! Use the corresponding macro os_file_create(), not directly -- cgit v1.2.1 From 24a0a74f5d92a861989fcea17a0c62c1ee7b1299 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Tue, 10 Jul 2018 13:54:04 +0530 Subject: MDEV-16307: Incorrect results when using BNLH join instead of BNL join with views In this issue we are using derived_with_keys optimization and we are using these keys to do a hash join which is incorrect. We cannot create keys for dervied tables whose keyparts have types are of BLOB or TEXT type. TEXT or BLOB columns can only be indexed over a specified length. --- mysql-test/r/derived.result | 33 +++++++++++++++++++++++++++++++++ mysql-test/t/derived.test | 21 +++++++++++++++++++++ sql/table.cc | 13 +++++++++++-- 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index 54c78dc9f6f..5debfaed5e3 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -1023,6 +1023,7 @@ INSERT INTO t2 VALUES (NULL),(NULL); CREATE TABLE t3 (c VARCHAR(1024) CHARACTER SET utf8, d INT) ENGINE=MyISAM; CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v3 AS SELECT * FROM t3; INSERT INTO t3 VALUES ('abc',NULL),('def',4); +set @save_join_cache_level= @@join_cache_level; SET join_cache_level= 8; explain SELECT * FROM v1, t2, v3 WHERE a = c AND b = d; @@ -1052,4 +1053,36 @@ i drop procedure pr; drop view v1; drop table t1; +set @@join_cache_level= @save_join_cache_level; +# +# MDEV-16307: Incorrect results when using BNLH join instead of BNL join with views +# +CREATE TABLE t1 (c1 text, c2 int); +INSERT INTO t1 VALUES ('a',1), ('c',3), ('g',7), ('d',4), ('c',3); +CREATE TABLE t2 (c1 text, c2 int); +INSERT INTO t2 VALUES ('b',2), ('c',3); +CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1; +explain SELECT v1.c1, v1.c2, t2.c1, t2.c2 FROM v1, t2 WHERE v1.c1=t2.c1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 +1 PRIMARY ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 5 +SELECT v1.c1, v1.c2, t2.c1, t2.c2 FROM v1, t2 WHERE v1.c1=t2.c1; +c1 c2 c1 c2 +c 3 c 3 +c 3 c 3 +set @save_join_cache_level= @@join_cache_level; +set @@join_cache_level=4; +explain SELECT v1.c1, v1.c2, t2.c1, t2.c2 FROM v1, t2 WHERE v1.c1=t2.c1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where +1 PRIMARY hash_ALL NULL #hash#$hj 3 test.t2.c1 5 Using where; Using join buffer (flat, BNLH join) +2 DERIVED t1 ALL NULL NULL NULL NULL 5 +SELECT v1.c1, v1.c2, t2.c1, t2.c2 FROM v1, t2 WHERE v1.c1=t2.c1; +c1 c2 c1 c2 +c 3 c 3 +c 3 c 3 +drop table t1,t2; +drop view v1; +set @@join_cache_level= @save_join_cache_level; # end of 5.5 diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test index c5b792c8d4d..217203422e0 100644 --- a/mysql-test/t/derived.test +++ b/mysql-test/t/derived.test @@ -880,6 +880,7 @@ CREATE TABLE t3 (c VARCHAR(1024) CHARACTER SET utf8, d INT) ENGINE=MyISAM; CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v3 AS SELECT * FROM t3; INSERT INTO t3 VALUES ('abc',NULL),('def',4); +set @save_join_cache_level= @@join_cache_level; SET join_cache_level= 8; explain SELECT * FROM v1, t2, v3 WHERE a = c AND b = d; @@ -902,5 +903,25 @@ call pr(2); drop procedure pr; drop view v1; drop table t1; +set @@join_cache_level= @save_join_cache_level; +--echo # +--echo # MDEV-16307: Incorrect results when using BNLH join instead of BNL join with views +--echo # + +CREATE TABLE t1 (c1 text, c2 int); +INSERT INTO t1 VALUES ('a',1), ('c',3), ('g',7), ('d',4), ('c',3); +CREATE TABLE t2 (c1 text, c2 int); +INSERT INTO t2 VALUES ('b',2), ('c',3); +CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1; + +explain SELECT v1.c1, v1.c2, t2.c1, t2.c2 FROM v1, t2 WHERE v1.c1=t2.c1; +SELECT v1.c1, v1.c2, t2.c1, t2.c2 FROM v1, t2 WHERE v1.c1=t2.c1; +set @save_join_cache_level= @@join_cache_level; +set @@join_cache_level=4; +explain SELECT v1.c1, v1.c2, t2.c1, t2.c2 FROM v1, t2 WHERE v1.c1=t2.c1; +SELECT v1.c1, v1.c2, t2.c1, t2.c2 FROM v1, t2 WHERE v1.c1=t2.c1; +drop table t1,t2; +drop view v1; +set @@join_cache_level= @save_join_cache_level; --echo # end of 5.5 diff --git a/sql/table.cc b/sql/table.cc index 48aa445e1aa..f6152a36eef 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -6060,6 +6060,14 @@ void TABLE::create_key_part_by_field(KEY_PART_INFO *key_part_info, The function checks whether a possible key satisfies the constraints imposed on the keys of any temporary table. + We need to filter out BLOB columns here, because ref access optimizer creates + KEYUSE objects for equalities for non-key columns for two puproses: + 1. To discover possible keys for derived_with_keys optimization + 2. To do hash joins + For the purpose of #1, KEYUSE objects are not created for "blob_column=..." . + However, they might be created for #2. In order to catch that case, we filter + them out here. + @return TRUE if the key is valid @return FALSE otherwise */ @@ -6075,11 +6083,12 @@ bool TABLE::check_tmp_key(uint key, uint key_parts, { uint fld_idx= next_field_no(arg); reg_field= field + fld_idx; + if ((*reg_field)->type() == MYSQL_TYPE_BLOB) + return FALSE; uint fld_store_len= (uint16) (*reg_field)->key_length(); if ((*reg_field)->real_maybe_null()) fld_store_len+= HA_KEY_NULL_LENGTH; - if ((*reg_field)->type() == MYSQL_TYPE_BLOB || - (*reg_field)->real_type() == MYSQL_TYPE_VARCHAR || + if ((*reg_field)->real_type() == MYSQL_TYPE_VARCHAR || (*reg_field)->type() == MYSQL_TYPE_GEOMETRY) fld_store_len+= HA_KEY_BLOB_LENGTH; key_len+= fld_store_len; -- cgit v1.2.1 From 2fbf2277ffec86d69f793534da7043b6dd540780 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Wed, 11 Jul 2018 10:43:38 +0300 Subject: MDEV-15982: Incorrect results when subquery is materialized fix_semijoin_strategies_for_picked_join_order() should set join->sjm_lookup_tables to be a bitmap of tables inside SJ-Materialization-Lookup nests. --- mysql-test/r/subselect_sj2_mat.result | 51 +++++++++++++++++++++++++++++++++++ mysql-test/t/subselect_sj2_mat.test | 49 +++++++++++++++++++++++++++++++++ sql/opt_subselect.cc | 3 ++- 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/subselect_sj2_mat.result b/mysql-test/r/subselect_sj2_mat.result index 19aa3bd3f02..7f97e1aabee 100644 --- a/mysql-test/r/subselect_sj2_mat.result +++ b/mysql-test/r/subselect_sj2_mat.result @@ -1658,3 +1658,54 @@ id 12 13 drop table t1; +# +# MDEV-15982: Incorrect results when subquery is materialized +# +CREATE TABLE `t1` (`id` int(32) NOT NULL primary key); +INSERT INTO `t1` VALUES +(45), (46), (47), (48), (49), (50), (51), (52), (53), (54), (55), (56), (57), (58), (59), (60), (61), (62), +(63), (64), (65), (66), (67), (68), (69), (70), (71), (72), (73), (74), (75), (76), (77), (78), (79), (80), +(81), (82), (83), (84), (85), (86), (87), (88), (89), (90), (91), (92),(93),(94),(95),(96), (97), (98), +(99), (100), (101), (102), (103), (104), (105), (106), (107), (108), (109), (110), (111), (112), (113), +(114), (115), (116), (117), (118), (119), (120), (121), (122), (123), (124), (125), (126), (127), (128), +(129), (130), (131), (132), (133), (134), (135), (136), (137), (138), (139), (140), (141), (142), (143), (144), (145), (146), +(147), (148), (149), (150), (151), (152), (153), (154), (155), (156), (157), (158), (159), (160), (161), +(162), (163), (164), (165), (166), (167), (168), (169), (170), (171), (172), (173), +(174), (175), (176), (177), (178), (179), (180), (181), (182), (183), (2), (3), (4), (5), (6), (19), (35), +(7), (20), (8), (36), (219), (22), (10), (23), (37), (11), (24); +CREATE TABLE `t2` (`type` int , `id` int(32) NOT NULL primary key); +INSERT INTO `t2` VALUES +(2,2),(2,3),(1,4),(2,5),(1,6),(1,19),(5,7),(1,20),(1,8),(1,21),(1,9), +(1,22),(2,10),(1,23),(2,11),(1,24),(1,12),(1,25),(2,13),(2,26),(2,14), +(2,27),(1,15),(1,28),(3,16),(1,29),(2,17),(1,30),(5,18),(2,1); +CREATE TABLE `t3` (`ref_id` int(32) unsigned ,`type` varchar(80),`id` int(32) NOT NULL ); +INSERT INTO `t3` VALUES +(1,'incident',31),(2,'faux pas',32), +(5,'oopsies',33),(3,'deniable',34), +(11,'wasntme',35),(10,'wasntme',36), +(17,'faux pas',37),(13,'unlikely',38), +(13,'improbable',39),(14,'incident',40), +(26,'problem',41),(14,'problem',42), +(26,'incident',43),(27,'incident',44); +explain +SELECT t2.id FROM t2,t1 +WHERE t2.id IN (SELECT t3.ref_id FROM t3,t1 where t3.id = t1.id) and t2.id = t1.id; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 30 Using index +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 Using where +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t2.id 1 Using index +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 14 +2 MATERIALIZED t1 eq_ref PRIMARY PRIMARY 4 test.t3.id 1 Using index +SELECT t2.id FROM t2,t1 +WHERE t2.id IN (SELECT t3.ref_id FROM t3,t1 where t3.id = t1.id) and t2.id = t1.id; +id +10 +11 +set optimizer_switch='materialization=off'; +SELECT t2.id FROM t2,t1 +WHERE t2.id IN (SELECT t3.ref_id FROM t3,t1 where t3.id = t1.id) and t2.id = t1.id; +id +11 +10 +set optimizer_switch='materialization=on'; +DROP TABLE t1,t2,t3; diff --git a/mysql-test/t/subselect_sj2_mat.test b/mysql-test/t/subselect_sj2_mat.test index 0665cdf68fe..43b63459928 100644 --- a/mysql-test/t/subselect_sj2_mat.test +++ b/mysql-test/t/subselect_sj2_mat.test @@ -345,3 +345,52 @@ WHERE ( (t.id IN (0,4,12,13,1,10,3,11)) ); drop table t1; +--echo # +--echo # MDEV-15982: Incorrect results when subquery is materialized +--echo # + +CREATE TABLE `t1` (`id` int(32) NOT NULL primary key); +INSERT INTO `t1` VALUES +(45), (46), (47), (48), (49), (50), (51), (52), (53), (54), (55), (56), (57), (58), (59), (60), (61), (62), +(63), (64), (65), (66), (67), (68), (69), (70), (71), (72), (73), (74), (75), (76), (77), (78), (79), (80), +(81), (82), (83), (84), (85), (86), (87), (88), (89), (90), (91), (92),(93),(94),(95),(96), (97), (98), +(99), (100), (101), (102), (103), (104), (105), (106), (107), (108), (109), (110), (111), (112), (113), +(114), (115), (116), (117), (118), (119), (120), (121), (122), (123), (124), (125), (126), (127), (128), +(129), (130), (131), (132), (133), (134), (135), (136), (137), (138), (139), (140), (141), (142), (143), (144), (145), (146), +(147), (148), (149), (150), (151), (152), (153), (154), (155), (156), (157), (158), (159), (160), (161), +(162), (163), (164), (165), (166), (167), (168), (169), (170), (171), (172), (173), +(174), (175), (176), (177), (178), (179), (180), (181), (182), (183), (2), (3), (4), (5), (6), (19), (35), +(7), (20), (8), (36), (219), (22), (10), (23), (37), (11), (24); + +CREATE TABLE `t2` (`type` int , `id` int(32) NOT NULL primary key); +INSERT INTO `t2` VALUES +(2,2),(2,3),(1,4),(2,5),(1,6),(1,19),(5,7),(1,20),(1,8),(1,21),(1,9), +(1,22),(2,10),(1,23),(2,11),(1,24),(1,12),(1,25),(2,13),(2,26),(2,14), +(2,27),(1,15),(1,28),(3,16),(1,29),(2,17),(1,30),(5,18),(2,1); + +CREATE TABLE `t3` (`ref_id` int(32) unsigned ,`type` varchar(80),`id` int(32) NOT NULL ); +INSERT INTO `t3` VALUES +(1,'incident',31),(2,'faux pas',32), +(5,'oopsies',33),(3,'deniable',34), +(11,'wasntme',35),(10,'wasntme',36), +(17,'faux pas',37),(13,'unlikely',38), +(13,'improbable',39),(14,'incident',40), +(26,'problem',41),(14,'problem',42), +(26,'incident',43),(27,'incident',44); + +explain +SELECT t2.id FROM t2,t1 + WHERE t2.id IN (SELECT t3.ref_id FROM t3,t1 where t3.id = t1.id) and t2.id = t1.id; + +SELECT t2.id FROM t2,t1 + WHERE t2.id IN (SELECT t3.ref_id FROM t3,t1 where t3.id = t1.id) and t2.id = t1.id; + +set optimizer_switch='materialization=off'; + +SELECT t2.id FROM t2,t1 + WHERE t2.id IN (SELECT t3.ref_id FROM t3,t1 where t3.id = t1.id) and t2.id = t1.id; +set optimizer_switch='materialization=on'; + +DROP TABLE t1,t2,t3; + + diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index ec7b10f20c8..14b2aaee591 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -3532,7 +3532,8 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) first= tablenr - sjm->tables + 1; join->best_positions[first].n_sj_tables= sjm->tables; join->best_positions[first].sj_strategy= SJ_OPT_MATERIALIZE; - join->sjm_lookup_tables|= s->table->map; + for (uint i= first; i < first+ sjm->tables; i++) + join->sjm_lookup_tables |= join->best_positions[i].table->table->map; } else if (pos->sj_strategy == SJ_OPT_MATERIALIZE_SCAN) { -- cgit v1.2.1 From ad9d1e8c3f5a8e1b3e222921e825247aa47c4d23 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Wed, 11 Jul 2018 02:28:42 +0530 Subject: MDEV-16552: [10.0] ASAN global-buffer-overflow in is_stat_table / statistics_for_tables_is_needed Backport the fix f214d365121 to 10.0 Author: Sergei Golubchik Date: Tue Apr 17 00:44:34 2018 +0200 ASAN error in is_stat_table() don't memcmp beyond the first argument's end Also: use my_strcasecmp(table_alias_charset), like elsewhere, not memcmp --- mysql-test/r/stat_tables.result | 7 +++++++ mysql-test/r/stat_tables_innodb.result | 7 +++++++ mysql-test/t/stat_tables.test | 6 ++++++ sql/sql_statistics.cc | 4 ++-- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/stat_tables.result b/mysql-test/r/stat_tables.result index fcced761283..4a608089d7d 100644 --- a/mysql-test/r/stat_tables.result +++ b/mysql-test/r/stat_tables.result @@ -516,4 +516,11 @@ use test; drop database db1; drop database db2; drop table t1; +# +# MDEV-16552: [10.0] ASAN global-buffer-overflow in is_stat_table / statistics_for_tables_is_needed +# +SET use_stat_tables = PREFERABLY; +SELECT CONVERT_TZ( '1991-09-20 10:11:02', '+00:00', 'GMT' ); +CONVERT_TZ( '1991-09-20 10:11:02', '+00:00', 'GMT' ) +NULL set use_stat_tables=@save_use_stat_tables; diff --git a/mysql-test/r/stat_tables_innodb.result b/mysql-test/r/stat_tables_innodb.result index 0e866755532..87049b228e5 100644 --- a/mysql-test/r/stat_tables_innodb.result +++ b/mysql-test/r/stat_tables_innodb.result @@ -543,6 +543,13 @@ use test; drop database db1; drop database db2; drop table t1; +# +# MDEV-16552: [10.0] ASAN global-buffer-overflow in is_stat_table / statistics_for_tables_is_needed +# +SET use_stat_tables = PREFERABLY; +SELECT CONVERT_TZ( '1991-09-20 10:11:02', '+00:00', 'GMT' ); +CONVERT_TZ( '1991-09-20 10:11:02', '+00:00', 'GMT' ) +NULL set use_stat_tables=@save_use_stat_tables; set optimizer_switch=@save_optimizer_switch_for_stat_tables_test; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/t/stat_tables.test b/mysql-test/t/stat_tables.test index 4cbaa9e27c8..9f94cf1b5a7 100644 --- a/mysql-test/t/stat_tables.test +++ b/mysql-test/t/stat_tables.test @@ -305,4 +305,10 @@ drop database db1; drop database db2; drop table t1; +--echo # +--echo # MDEV-16552: [10.0] ASAN global-buffer-overflow in is_stat_table / statistics_for_tables_is_needed +--echo # + +SET use_stat_tables = PREFERABLY; +SELECT CONVERT_TZ( '1991-09-20 10:11:02', '+00:00', 'GMT' ); set use_stat_tables=@save_use_stat_tables; diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 1febc02b903..be4547a69df 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -3858,11 +3858,11 @@ bool is_stat_table(const char *db, const char *table) { DBUG_ASSERT(db && table); - if (!memcmp(db, stat_tables_db_name.str, stat_tables_db_name.length)) + if (!my_strcasecmp(table_alias_charset, db, stat_tables_db_name.str)) { for (uint i= 0; i < STATISTICS_TABLES; i ++) { - if (!memcmp(table, stat_table_name[i].str, stat_table_name[i].length)) + if (!my_strcasecmp(table_alias_charset, table, stat_table_name[i].str)) return true; } } -- cgit v1.2.1 From c89bb15c31f98d2d368414c7366ce61955b70b44 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 13 Jul 2018 17:48:30 -0700 Subject: MDEV-16757 Memory leak after adding manually min/max statistical data for blob column ANALYZE TABLE does not collect statistical data on min/max values for BLOB columns of
. However these values can be added into mysql.column_stats manually by executing proper statements. Unfortunately this led to a memory leak because the memory allocated for these values was never freed. This patch provides the server with a function to free memory allocated for min/max statistical values of BLOB types. --- mysql-test/r/stat_tables.result | 28 ++++++++++++++++++++++++++++ mysql-test/r/stat_tables_innodb.result | 28 ++++++++++++++++++++++++++++ mysql-test/t/stat_tables.test | 24 ++++++++++++++++++++++++ sql/sql_statistics.cc | 33 +++++++++++++++++++++++++++++++++ sql/sql_statistics.h | 1 + sql/table_cache.cc | 2 ++ 6 files changed, 116 insertions(+) diff --git a/mysql-test/r/stat_tables.result b/mysql-test/r/stat_tables.result index 4a608089d7d..e6b675060a5 100644 --- a/mysql-test/r/stat_tables.result +++ b/mysql-test/r/stat_tables.result @@ -524,3 +524,31 @@ SELECT CONVERT_TZ( '1991-09-20 10:11:02', '+00:00', 'GMT' ); CONVERT_TZ( '1991-09-20 10:11:02', '+00:00', 'GMT' ) NULL set use_stat_tables=@save_use_stat_tables; +# +# MDEV-16757: manual addition of min/max statistics for BLOB +# +SET use_stat_tables= PREFERABLY; +CREATE TABLE t1 (pk INT PRIMARY KEY, t TEXT); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +test t1 t NULL NULL 0.0000 3.0000 NULL NULL NULL NULL +DELETE FROM mysql.column_stats +WHERE db_name='test' AND table_name='t1' AND column_name='t'; +INSERT INTO mysql.column_stats VALUES +('test','t1','t','bar','foo', 0.0, 3.0, 1.0, 0, NULL, NULL); +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +test t1 t bar foo 0.0000 3.0000 1.0000 0 NULL NULL +SELECT pk FROM t1; +pk +1 +2 +DROP TABLE t1; +set use_stat_tables=@save_use_stat_tables; diff --git a/mysql-test/r/stat_tables_innodb.result b/mysql-test/r/stat_tables_innodb.result index 87049b228e5..04d73868cfb 100644 --- a/mysql-test/r/stat_tables_innodb.result +++ b/mysql-test/r/stat_tables_innodb.result @@ -551,5 +551,33 @@ SELECT CONVERT_TZ( '1991-09-20 10:11:02', '+00:00', 'GMT' ); CONVERT_TZ( '1991-09-20 10:11:02', '+00:00', 'GMT' ) NULL set use_stat_tables=@save_use_stat_tables; +# +# MDEV-16757: manual addition of min/max statistics for BLOB +# +SET use_stat_tables= PREFERABLY; +CREATE TABLE t1 (pk INT PRIMARY KEY, t TEXT); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +test t1 t NULL NULL 0.0000 3.0000 NULL NULL NULL NULL +DELETE FROM mysql.column_stats +WHERE db_name='test' AND table_name='t1' AND column_name='t'; +INSERT INTO mysql.column_stats VALUES +('test','t1','t','bar','foo', 0.0, 3.0, 1.0, 0, NULL, NULL); +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +test t1 t bar foo 0.0000 3.0000 1.0000 0 NULL NULL +SELECT pk FROM t1; +pk +1 +2 +DROP TABLE t1; +set use_stat_tables=@save_use_stat_tables; set optimizer_switch=@save_optimizer_switch_for_stat_tables_test; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/t/stat_tables.test b/mysql-test/t/stat_tables.test index 9f94cf1b5a7..843e6f8aa0b 100644 --- a/mysql-test/t/stat_tables.test +++ b/mysql-test/t/stat_tables.test @@ -312,3 +312,27 @@ drop table t1; SET use_stat_tables = PREFERABLY; SELECT CONVERT_TZ( '1991-09-20 10:11:02', '+00:00', 'GMT' ); set use_stat_tables=@save_use_stat_tables; + +--echo # +--echo # MDEV-16757: manual addition of min/max statistics for BLOB +--echo # + +SET use_stat_tables= PREFERABLY; + +CREATE TABLE t1 (pk INT PRIMARY KEY, t TEXT); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +ANALYZE TABLE t1; +--sorted_result +SELECT * FROM mysql.column_stats; +DELETE FROM mysql.column_stats + WHERE db_name='test' AND table_name='t1' AND column_name='t'; +INSERT INTO mysql.column_stats VALUES + ('test','t1','t','bar','foo', 0.0, 3.0, 1.0, 0, NULL, NULL); +--sorted_result +SELECT * FROM mysql.column_stats; + +SELECT pk FROM t1; + +DROP TABLE t1; + +set use_stat_tables=@save_use_stat_tables; diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index be4547a69df..537ede91710 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -2916,6 +2916,39 @@ int read_statistics_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables) } +/** + @breif + Cleanup of min/max statistical values for table share +*/ + +void delete_stat_values_for_table_share(TABLE_SHARE *table_share) +{ + TABLE_STATISTICS_CB *stats_cb= &table_share->stats_cb; + Table_statistics *table_stats= stats_cb->table_stats; + if (!table_stats) + return; + Column_statistics *column_stats= table_stats->column_stats; + if (!column_stats) + return; + + for (Field **field_ptr= table_share->field; + *field_ptr; + field_ptr++, column_stats++) + { + if (column_stats->min_value) + { + delete column_stats->min_value; + column_stats->min_value= NULL; + } + if (column_stats->max_value) + { + delete column_stats->max_value; + column_stats->max_value= NULL; + } + } +} + + /** @brief Check whether any statistics is to be read for tables from a table list diff --git a/sql/sql_statistics.h b/sql/sql_statistics.h index 20b2eb66449..6a43e42ab96 100644 --- a/sql/sql_statistics.h +++ b/sql/sql_statistics.h @@ -89,6 +89,7 @@ int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables); int collect_statistics_for_table(THD *thd, TABLE *table); int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *share, bool is_safe); +void delete_stat_values_for_table_share(TABLE_SHARE *table_share); int alloc_statistics_for_table(THD *thd, TABLE *table); int update_statistics_for_table(THD *thd, TABLE *table); int delete_statistics_for_table(THD *thd, LEX_STRING *db, LEX_STRING *tab); diff --git a/sql/table_cache.cc b/sql/table_cache.cc index bdb7914c32b..a31068c9bc3 100644 --- a/sql/table_cache.cc +++ b/sql/table_cache.cc @@ -52,6 +52,7 @@ #include "hash.h" #include "table.h" #include "sql_base.h" +#include "sql_statistics.h" /** Configuration. */ ulong tdc_size; /**< Table definition cache threshold for LRU eviction. */ @@ -869,6 +870,7 @@ void tdc_release_share(TABLE_SHARE *share) mysql_mutex_lock(&share->tdc.LOCK_table_share); if (share->tdc.flushed) { + delete_stat_values_for_table_share(share); mysql_mutex_unlock(&share->tdc.LOCK_table_share); mysql_mutex_unlock(&LOCK_unused_shares); tdc_delete_share_from_hash(share); -- cgit v1.2.1 From 1fd84f9129f2ed98706f6e225b06b16a13d0ebd0 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 13 Jul 2018 23:03:57 -0700 Subject: MDEV-16760 CREATE OR REPLACE TABLE never updates statistical tables If the command CREATE OR REPLACE TABLE really replaces a table then it should remove all data on this table from all statistical tables. --- mysql-test/r/stat_tables.result | 25 +++++++++++++++++++++++++ mysql-test/r/stat_tables_innodb.result | 25 +++++++++++++++++++++++++ mysql-test/t/stat_tables.test | 20 ++++++++++++++++++++ sql/sql_table.cc | 4 ++++ 4 files changed, 74 insertions(+) diff --git a/mysql-test/r/stat_tables.result b/mysql-test/r/stat_tables.result index e6b675060a5..c1457d5e91a 100644 --- a/mysql-test/r/stat_tables.result +++ b/mysql-test/r/stat_tables.result @@ -552,3 +552,28 @@ pk 2 DROP TABLE t1; set use_stat_tables=@save_use_stat_tables; +# +# MDEV-16760: CREATE OR REPLACE TABLE after ANALYZE TABLE +# +SET use_stat_tables= PREFERABLY; +CREATE TABLE t1 (pk int PRIMARY KEY, c varchar(32)); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +SELECT * FROM t1; +pk c +1 foo +2 bar +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +test t1 c bar foo 0.0000 3.0000 1.0000 0 NULL NULL +CREATE OR REPLACE TABLE t1 (pk int PRIMARY KEY, a char(7)); +SELECT * FROM t1; +pk a +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +DROP TABLE t1; +set use_stat_tables=@save_use_stat_tables; diff --git a/mysql-test/r/stat_tables_innodb.result b/mysql-test/r/stat_tables_innodb.result index 04d73868cfb..2ac868e9341 100644 --- a/mysql-test/r/stat_tables_innodb.result +++ b/mysql-test/r/stat_tables_innodb.result @@ -579,5 +579,30 @@ pk 2 DROP TABLE t1; set use_stat_tables=@save_use_stat_tables; +# +# MDEV-16760: CREATE OR REPLACE TABLE after ANALYZE TABLE +# +SET use_stat_tables= PREFERABLY; +CREATE TABLE t1 (pk int PRIMARY KEY, c varchar(32)); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +SELECT * FROM t1; +pk c +1 foo +2 bar +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +test t1 c bar foo 0.0000 3.0000 1.0000 0 NULL NULL +CREATE OR REPLACE TABLE t1 (pk int PRIMARY KEY, a char(7)); +SELECT * FROM t1; +pk a +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +DROP TABLE t1; +set use_stat_tables=@save_use_stat_tables; set optimizer_switch=@save_optimizer_switch_for_stat_tables_test; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/t/stat_tables.test b/mysql-test/t/stat_tables.test index 843e6f8aa0b..d69b00618ea 100644 --- a/mysql-test/t/stat_tables.test +++ b/mysql-test/t/stat_tables.test @@ -336,3 +336,23 @@ SELECT pk FROM t1; DROP TABLE t1; set use_stat_tables=@save_use_stat_tables; + +--echo # +--echo # MDEV-16760: CREATE OR REPLACE TABLE after ANALYZE TABLE +--echo # + +SET use_stat_tables= PREFERABLY; + +CREATE TABLE t1 (pk int PRIMARY KEY, c varchar(32)); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +ANALYZE TABLE t1; +SELECT * FROM t1; +SELECT * FROM mysql.column_stats; + +CREATE OR REPLACE TABLE t1 (pk int PRIMARY KEY, a char(7)); +SELECT * FROM t1; +SELECT * FROM mysql.column_stats; + +DROP TABLE t1; + +set use_stat_tables=@save_use_stat_tables; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6c71067d51b..ee02b5fc7aa 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4762,6 +4762,10 @@ int create_table_impl(THD *thd, { if (create_info->options & HA_LEX_CREATE_REPLACE) { + LEX_STRING db_name= {(char *) db, strlen(db)}; + LEX_STRING tab_name= {(char *) table_name, strlen(table_name)}; + (void) delete_statistics_for_table(thd, &db_name, &tab_name); + TABLE_LIST table_list; table_list.init_one_table(db, strlen(db), table_name, strlen(table_name), table_name, -- cgit v1.2.1 From 8c45eb3ea51e80b429c789713fa85ef380cecdd3 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 13 Jan 2018 12:27:28 +1100 Subject: MDEV-15050 scripts: mysql_install_db.{sh|pl}, mysqld_multi - mysqld is in @sbindir@ Closes #551 --- scripts/mysql_install_db.pl.in | 2 +- scripts/mysql_install_db.sh | 2 +- scripts/mysqld_multi.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/mysql_install_db.pl.in b/scripts/mysql_install_db.pl.in index c6714f66bff..2a65dc94ba8 100644 --- a/scripts/mysql_install_db.pl.in +++ b/scripts/mysql_install_db.pl.in @@ -326,7 +326,7 @@ else $opt->{basedir} = '@prefix@'; $bindir = '@bindir@'; $extra_bindir = $bindir; - $mysqld = '@libexecdir@/mysqld'; + $mysqld = '@sbindir@/mysqld'; $pkgdatadir = '@pkgdatadir@'; $scriptdir = '@scriptdir@'; } diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index a8f32526a7e..0272a19931f 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -311,7 +311,7 @@ else basedir="@prefix@" bindir="@bindir@" resolveip="$bindir/resolveip" - mysqld="@libexecdir@/mysqld" + mysqld="@sbindir@/mysqld" pkgdatadir="@pkgdatadir@" fi diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh index e96d12e3f89..8f5adfe4842 100644 --- a/scripts/mysqld_multi.sh +++ b/scripts/mysqld_multi.sh @@ -30,7 +30,7 @@ $opt_example = 0; $opt_help = 0; $opt_log = undef(); $opt_mysqladmin = "@bindir@/mysqladmin"; -$opt_mysqld = "@libexecdir@/mysqld"; +$opt_mysqld = "@sbindir@/mysqld"; $opt_no_log = 0; $opt_password = undef(); $opt_tcp_ip = 0; -- cgit v1.2.1 From ada54101a7185782657813c553907f61f2a35faf Mon Sep 17 00:00:00 2001 From: sachin Date: Wed, 30 May 2018 16:25:44 +0530 Subject: MDEV-9266 Creating index on temporaray table breaks replication Problem:- Create/drop index was logged into binlog. Goal:- Operation on temporary table should not be binlog when binlog format is row. Solution:- We should add CF_FORCE_ORIGINAL_BINLOG_FORMAT when there is ddl on temp table. For optimize, analyze, repair we wont change anything ,Then will be logged in binlog , But they also dont throw any error if operation fails Since slave wont be having any temp table , but these operation on tmp table will be processed without breaking replication. For rename we need a different logic MDEV-16728 will solve it. --- .../suite/binlog/include/check_binlog_size.inc | 31 ++++++++++++++++++++++ .../suite/binlog/r/binlog_tmp_table_row.result | 7 +++++ .../suite/binlog/t/binlog_tmp_table_row.test | 30 +++++++++++++++++++++ sql/sql_parse.cc | 3 +++ 4 files changed, 71 insertions(+) create mode 100644 mysql-test/suite/binlog/include/check_binlog_size.inc create mode 100644 mysql-test/suite/binlog/r/binlog_tmp_table_row.result create mode 100644 mysql-test/suite/binlog/t/binlog_tmp_table_row.test diff --git a/mysql-test/suite/binlog/include/check_binlog_size.inc b/mysql-test/suite/binlog/include/check_binlog_size.inc new file mode 100644 index 00000000000..9df161ec843 --- /dev/null +++ b/mysql-test/suite/binlog/include/check_binlog_size.inc @@ -0,0 +1,31 @@ +# This file runs the query and checks +# whether the size of binlog is increased or not +# If size is changed it issue die command +# Parameters +# $sql_query = query to run + +#Only last row of show binlog events matter +--let $tmp= 0 +--let $counter= 1 +while ($tmp != "No such row") +{ + --let $initial_binlog_size= $tmp + --let $tmp= query_get_value(show binary logs, File_size, $counter) + --inc $counter +} + +--eval $sql_query + +--let $tmp= 0 +--let $counter= 1 +while ($tmp != "No such row") +{ + --let $current_binlog_size= $tmp + --let $tmp= query_get_value(show binary logs, File_size, $counter) + --inc $counter +} + +if ($initial_binlog_size != $current_binlog_size) +{ + die "Binlog size changed"; +} diff --git a/mysql-test/suite/binlog/r/binlog_tmp_table_row.result b/mysql-test/suite/binlog/r/binlog_tmp_table_row.result new file mode 100644 index 00000000000..71bd75d89cb --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_tmp_table_row.result @@ -0,0 +1,7 @@ +RESET MASTER; +#Create table test +create temporary table t1(a int, b int); +#Add index test +create index index_a on t1(a); +#drop index test +drop index index_a on t1; diff --git a/mysql-test/suite/binlog/t/binlog_tmp_table_row.test b/mysql-test/suite/binlog/t/binlog_tmp_table_row.test new file mode 100644 index 00000000000..ce11c880679 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_tmp_table_row.test @@ -0,0 +1,30 @@ +# ==== Purpose ==== +# +# Test if statements used temporary tables are not binlogged in the case of +# binlog_format=row +# +# ==== Method ==== +# +# We will see if binlog file size is increased or not, It should be constant for the +# entire period of test. +# +# ==== Related bugs ==== +# +# Mdev-9266 +# +source include/have_log_bin.inc; +source include/have_binlog_format_row.inc; + +RESET MASTER; + +--echo #Create table test +--let $sql_query= create temporary table t1(a int, b int) +--source suite/binlog/include/check_binlog_size.inc + +--echo #Add index test +--let $sql_query= create index index_a on t1(a) +--source suite/binlog/include/check_binlog_size.inc + +--echo #drop index test +--let $sql_query= drop index index_a on t1 +--source suite/binlog/include/check_binlog_size.inc diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 28d11ef2e5c..a9849c7248d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -457,6 +457,9 @@ void init_update_queries(void) sql_command_flags[SQLCOM_TRUNCATE]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT; /* We don't want to replicate DROP for temp tables in row format */ sql_command_flags[SQLCOM_DROP_TABLE]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT; + /* We don't want to replicate CREATE/DROP INDEX for temp tables in row format */ + sql_command_flags[SQLCOM_CREATE_INDEX]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT; + sql_command_flags[SQLCOM_DROP_INDEX]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT; /* One can change replication mode with SET */ sql_command_flags[SQLCOM_SET_OPTION]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT; -- cgit v1.2.1 From ab58493db22d870cb6a470d6b0551cfc70dd09f3 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 19 Jul 2018 09:55:19 +0400 Subject: MDEV-13118 Wrong results with LOWER and UPPER and subquery This problem is similar to MDEV-10306. 1. Fixing Item_str_conv::val_str(String *str) to return the result in "str", and to use tmp_value only as a temporary buffer for args[0]->val_str(). The new code version now guarantees that the result is always returned in "str". The trick with copy_if_not_alloced() is not used any more. 2. The change #1 revealed the same problem in SUBSTRING_INDEX(), so some tests with combinations of UPPER()/LOWER() and SUBSTRING_INDEX() started to fail. Fixing Item_func_substr_index::val_str() the same way, to return the result in "str" and use tmp_value as a temporary buffer for args[0]->val_str(). --- mysql-test/include/ctype_mdev13118.inc | 15 +++++ mysql-test/r/ctype_binary.result | 23 +++++++ mysql-test/r/ctype_eucjpms.result | 23 +++++++ mysql-test/r/ctype_euckr.result | 29 +++++++++ mysql-test/r/ctype_gbk.result | 23 +++++++ mysql-test/r/ctype_latin1.result | 23 +++++++ mysql-test/r/ctype_ucs.result | 23 +++++++ mysql-test/r/ctype_ujis.result | 23 +++++++ mysql-test/r/ctype_utf16.result | 23 +++++++ mysql-test/r/ctype_utf16le.result | 29 +++++++++ mysql-test/r/ctype_utf32.result | 23 +++++++ mysql-test/r/ctype_utf8.result | 23 +++++++ mysql-test/r/ctype_utf8mb4.result | 23 +++++++ mysql-test/t/ctype_binary.test | 3 + mysql-test/t/ctype_eucjpms.test | 2 + mysql-test/t/ctype_euckr.test | 11 ++++ mysql-test/t/ctype_gbk.test | 3 + mysql-test/t/ctype_latin1.test | 3 + mysql-test/t/ctype_ucs.test | 4 ++ mysql-test/t/ctype_ujis.test | 4 ++ mysql-test/t/ctype_utf16.test | 5 ++ mysql-test/t/ctype_utf16le.test | 13 ++++ mysql-test/t/ctype_utf32.test | 8 +++ mysql-test/t/ctype_utf8.test | 7 +++ mysql-test/t/ctype_utf8mb4.test | 8 +++ sql/item_strfunc.cc | 107 ++++++++++++++++++--------------- 26 files changed, 433 insertions(+), 48 deletions(-) create mode 100644 mysql-test/include/ctype_mdev13118.inc diff --git a/mysql-test/include/ctype_mdev13118.inc b/mysql-test/include/ctype_mdev13118.inc new file mode 100644 index 00000000000..efcb57299df --- /dev/null +++ b/mysql-test/include/ctype_mdev13118.inc @@ -0,0 +1,15 @@ +--echo # +--echo # MDEV-13118 Wrong results with LOWER and UPPER and subquery +--echo # + +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +--sorted_result +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +--sorted_result +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/r/ctype_binary.result b/mysql-test/r/ctype_binary.result index 48b481883ca..b28d9040547 100644 --- a/mysql-test/r/ctype_binary.result +++ b/mysql-test/r/ctype_binary.result @@ -3022,6 +3022,29 @@ DROP TABLE t1; SELECT _binary 0x7E, _binary X'7E', _binary B'01111110'; _binary 0x7E _binary X'7E' _binary B'01111110' ~ ~ ~ +SET NAMES utf8, character_set_connection=binary; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varbinary(10) NOT NULL DEFAULT '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +abcdefghi-abcdefghi +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; # # End of 10.0 tests # diff --git a/mysql-test/r/ctype_eucjpms.result b/mysql-test/r/ctype_eucjpms.result index a1232c115e9..1e2312638c9 100644 --- a/mysql-test/r/ctype_eucjpms.result +++ b/mysql-test/r/ctype_eucjpms.result @@ -33636,6 +33636,29 @@ HEX(a) CHAR_LENGTH(a) DROP TABLE t1; SELECT _eucjpms 0x8EA0; ERROR HY000: Invalid eucjpms character string: '8EA0' +SET NAMES eucjpms; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) CHARACTER SET eucjpms NOT NULL DEFAULT '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; # # End of 10.0 tests # diff --git a/mysql-test/r/ctype_euckr.result b/mysql-test/r/ctype_euckr.result index dcb68cfe60b..cea93b0c808 100644 --- a/mysql-test/r/ctype_euckr.result +++ b/mysql-test/r/ctype_euckr.result @@ -25274,3 +25274,32 @@ A1A1A1A1A1A120202020202020202020202020202020202020 # # End of 5.6 tests # +# +# Start of 10.0 tests +# +SET NAMES utf8, character_set_connection=euckr; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) CHARACTER SET euckr NOT NULL DEFAULT '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; +# +# End of 10.0 tests +# diff --git a/mysql-test/r/ctype_gbk.result b/mysql-test/r/ctype_gbk.result index 2d31a15bb62..15f9bc6bfea 100644 --- a/mysql-test/r/ctype_gbk.result +++ b/mysql-test/r/ctype_gbk.result @@ -4943,6 +4943,29 @@ E05C5B E05B DROP TABLE t1; # Start of ctype_E05C.inc +SET NAMES utf8, character_set_connection=gbk; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) CHARACTER SET gbk NOT NULL DEFAULT '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; # # MDEV-9886 Illegal mix of collations with a view comparing a field to a binary constant # diff --git a/mysql-test/r/ctype_latin1.result b/mysql-test/r/ctype_latin1.result index cf48aaab09b..8913c8082c8 100644 --- a/mysql-test/r/ctype_latin1.result +++ b/mysql-test/r/ctype_latin1.result @@ -7939,6 +7939,29 @@ a 0 DROP VIEW v1; DROP TABLE t1; +SET NAMES latin1; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) NOT NULL DEFAULT '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; # # End of 10.0 tests # diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index 59d88414cab..58fd308c7e2 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -5629,6 +5629,29 @@ c2 YWJjZGVmZ2hp-YWJjZGVmZ2hp DROP TABLE t1; SET optimizer_switch=@save_optimizer_switch; +SET NAMES utf8, character_set_connection=ucs2; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) CHARACTER SET ucs2 NOT NULL DEFAULT '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; # # End of 10.0 tests # diff --git a/mysql-test/r/ctype_ujis.result b/mysql-test/r/ctype_ujis.result index 413ab4efe31..d4589f62ae5 100644 --- a/mysql-test/r/ctype_ujis.result +++ b/mysql-test/r/ctype_ujis.result @@ -25942,6 +25942,29 @@ HEX(a) CHAR_LENGTH(a) DROP TABLE t1; SELECT _ujis 0x8EA0; ERROR HY000: Invalid ujis character string: '8EA0' +SET NAMES ujis; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) CHARACTER SET ujis NOT NULL DEFAULT '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; # # End of 10.0 tests # diff --git a/mysql-test/r/ctype_utf16.result b/mysql-test/r/ctype_utf16.result index 958ade902df..e182432faec 100644 --- a/mysql-test/r/ctype_utf16.result +++ b/mysql-test/r/ctype_utf16.result @@ -2134,6 +2134,29 @@ EXECUTE stmt USING @arg00; CONCAT(_utf16'a' COLLATE utf16_unicode_ci, ?) aÿ DEALLOCATE PREPARE stmt; +SET NAMES utf8, character_set_connection=utf16; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) CHARACTER SET utf16 NOT NULL DEFAULT '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; # # End of 10.0 tests # diff --git a/mysql-test/r/ctype_utf16le.result b/mysql-test/r/ctype_utf16le.result index 8098b0d1666..f6a4d351ad4 100644 --- a/mysql-test/r/ctype_utf16le.result +++ b/mysql-test/r/ctype_utf16le.result @@ -2319,3 +2319,32 @@ DFFFFFDFFFFF9CFFFF9DFFFF9EFFFF # # End of 5.6 tests # +# +# Start of 10.0 tests +# +SET NAMES utf8, character_set_connection=utf16le; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) CHARACTER SET utf16le NOT NULL DEFAULT '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; +# +# Start of 10.0 tests +# diff --git a/mysql-test/r/ctype_utf32.result b/mysql-test/r/ctype_utf32.result index 1f3e519a525..91277cd5108 100644 --- a/mysql-test/r/ctype_utf32.result +++ b/mysql-test/r/ctype_utf32.result @@ -2231,6 +2231,29 @@ EXECUTE stmt USING @arg00; CONCAT(_utf32'a' COLLATE utf32_unicode_ci, ?) aÿ DEALLOCATE PREPARE stmt; +SET NAMEs utf8, character_set_connection=utf32; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) CHARACTER SET utf32 NOT NULL DEFAULT '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; # # End of 10.0 tests # diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 7a3ff3732c3..6a4001597c4 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -10127,6 +10127,29 @@ SELECT * FROM v1; c ß DROP VIEW v1; +SET NAMES utf8; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) CHARACTER SET utf8 NOT NULL DEFAULT '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; # # End of 10.0 tests # diff --git a/mysql-test/r/ctype_utf8mb4.result b/mysql-test/r/ctype_utf8mb4.result index f31b7a6781e..4d91c42cf51 100644 --- a/mysql-test/r/ctype_utf8mb4.result +++ b/mysql-test/r/ctype_utf8mb4.result @@ -3427,6 +3427,29 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; SET NAMES default; +SET NAMES utf8mb4; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) CHARACTER SET utf8mb4 NOT NULL DEFAULT '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; # End of 10.0 tests # # End of tests diff --git a/mysql-test/t/ctype_binary.test b/mysql-test/t/ctype_binary.test index 3d3f90b444b..801e1328892 100644 --- a/mysql-test/t/ctype_binary.test +++ b/mysql-test/t/ctype_binary.test @@ -24,6 +24,9 @@ SET NAMES binary; --echo # SELECT _binary 0x7E, _binary X'7E', _binary B'01111110'; +SET NAMES utf8, character_set_connection=binary; +--source include/ctype_mdev13118.inc + --echo # --echo # End of 10.0 tests --echo # diff --git a/mysql-test/t/ctype_eucjpms.test b/mysql-test/t/ctype_eucjpms.test index 49ca81850ed..590f2ca9950 100644 --- a/mysql-test/t/ctype_eucjpms.test +++ b/mysql-test/t/ctype_eucjpms.test @@ -536,6 +536,8 @@ DROP TABLE t1; --error ER_INVALID_CHARACTER_STRING SELECT _eucjpms 0x8EA0; +SET NAMES eucjpms; +--source include/ctype_mdev13118.inc --echo # --echo # End of 10.0 tests diff --git a/mysql-test/t/ctype_euckr.test b/mysql-test/t/ctype_euckr.test index 155b8ebed00..d81ba2a8bdf 100644 --- a/mysql-test/t/ctype_euckr.test +++ b/mysql-test/t/ctype_euckr.test @@ -197,3 +197,14 @@ set collation_connection=euckr_bin; --echo # End of 5.6 tests --echo # + +--echo # +--echo # Start of 10.0 tests +--echo # + +SET NAMES utf8, character_set_connection=euckr; +--source include/ctype_mdev13118.inc + +--echo # +--echo # End of 10.0 tests +--echo # diff --git a/mysql-test/t/ctype_gbk.test b/mysql-test/t/ctype_gbk.test index 454377d98a7..bcdcc09b473 100644 --- a/mysql-test/t/ctype_gbk.test +++ b/mysql-test/t/ctype_gbk.test @@ -199,6 +199,9 @@ let $ctype_unescape_combinations=selected; SET NAMES gbk; --source include/ctype_E05C.inc +SET NAMES utf8, character_set_connection=gbk; +--source include/ctype_mdev13118.inc + --echo # --echo # MDEV-9886 Illegal mix of collations with a view comparing a field to a binary constant --echo # diff --git a/mysql-test/t/ctype_latin1.test b/mysql-test/t/ctype_latin1.test index 8a188b71e24..da4d76ee2cf 100644 --- a/mysql-test/t/ctype_latin1.test +++ b/mysql-test/t/ctype_latin1.test @@ -260,6 +260,9 @@ SELECT * FROM v1; DROP VIEW v1; DROP TABLE t1; +SET NAMES latin1; +--source include/ctype_mdev13118.inc + --echo # --echo # End of 10.0 tests diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test index d78977a3d1c..050e199e5b7 100644 --- a/mysql-test/t/ctype_ucs.test +++ b/mysql-test/t/ctype_ucs.test @@ -984,6 +984,10 @@ DROP TABLE t1; SET optimizer_switch=@save_optimizer_switch; +SET NAMES utf8, character_set_connection=ucs2; +--source include/ctype_mdev13118.inc + + --echo # --echo # End of 10.0 tests --echo # diff --git a/mysql-test/t/ctype_ujis.test b/mysql-test/t/ctype_ujis.test index 48dc0e63058..8d55819acf7 100644 --- a/mysql-test/t/ctype_ujis.test +++ b/mysql-test/t/ctype_ujis.test @@ -1366,6 +1366,10 @@ DROP TABLE t1; SELECT _ujis 0x8EA0; +SET NAMES ujis; +--source include/ctype_mdev13118.inc + + --echo # --echo # End of 10.0 tests --echo # diff --git a/mysql-test/t/ctype_utf16.test b/mysql-test/t/ctype_utf16.test index cda85239512..b562b15eeeb 100644 --- a/mysql-test/t/ctype_utf16.test +++ b/mysql-test/t/ctype_utf16.test @@ -866,6 +866,11 @@ SET @arg00=_binary 0x00FF; EXECUTE stmt USING @arg00; DEALLOCATE PREPARE stmt; + +SET NAMES utf8, character_set_connection=utf16; +--source include/ctype_mdev13118.inc + + --echo # --echo # End of 10.0 tests --echo # diff --git a/mysql-test/t/ctype_utf16le.test b/mysql-test/t/ctype_utf16le.test index a8326900847..f5b89aa9dc4 100644 --- a/mysql-test/t/ctype_utf16le.test +++ b/mysql-test/t/ctype_utf16le.test @@ -744,3 +744,16 @@ SET NAMES utf8, collation_connection=utf16le_bin; --echo # --echo # End of 5.6 tests --echo # + + +--echo # +--echo # Start of 10.0 tests +--echo # + + +SET NAMES utf8, character_set_connection=utf16le; +--source include/ctype_mdev13118.inc + +--echo # +--echo # Start of 10.0 tests +--echo # diff --git a/mysql-test/t/ctype_utf32.test b/mysql-test/t/ctype_utf32.test index c747abb8b08..1a4c9fd28ee 100644 --- a/mysql-test/t/ctype_utf32.test +++ b/mysql-test/t/ctype_utf32.test @@ -979,6 +979,14 @@ SET @arg00=_binary 0x00FF; EXECUTE stmt USING @arg00; DEALLOCATE PREPARE stmt; + +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET NAMEs utf8, character_set_connection=utf32; +--source include/ctype_mdev13118.inc + + --echo # --echo # End of 10.0 tests --echo # diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 2524daffa9e..11dfef67765 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1880,6 +1880,13 @@ SELECT * FROM v1; DROP VIEW v1; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET NAMES utf8; +--source include/ctype_mdev13118.inc + + --echo # --echo # End of 10.0 tests --echo # diff --git a/mysql-test/t/ctype_utf8mb4.test b/mysql-test/t/ctype_utf8mb4.test index f68cfd57e2a..89007546492 100644 --- a/mysql-test/t/ctype_utf8mb4.test +++ b/mysql-test/t/ctype_utf8mb4.test @@ -1913,6 +1913,14 @@ DROP TABLE t1; SET NAMES default; + +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET NAMES utf8mb4; +--source include/ctype_mdev13118.inc + + --echo # End of 10.0 tests --echo # diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index e0bd3cc2195..160e740a9f7 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1566,32 +1566,27 @@ String *Item_str_conv::val_str(String *str) { DBUG_ASSERT(fixed == 1); String *res; - if (!(res=args[0]->val_str(str))) - { - null_value=1; /* purecov: inspected */ - return 0; /* purecov: inspected */ - } - null_value=0; + uint alloced_length, len; + + if ((null_value= (!(res= args[0]->val_str(&tmp_value)) || + str->alloc((alloced_length= res->length() * multiply))))) + return 0; + if (multiply == 1) { - uint len; - res= copy_if_not_alloced(&tmp_value, res, res->length()); - len= converter(collation.collation, (char*) res->ptr(), res->length(), - (char*) res->ptr(), res->length()); - DBUG_ASSERT(len <= res->length()); - res->length(len); + str->copy(*res); // Should not fail (it was alloced above) + len= converter(collation.collation, (char*) str->ptr(), str->length(), + (char*) str->ptr(), alloced_length); } else { - uint len= res->length() * multiply; - tmp_value.alloc(len); - tmp_value.set_charset(collation.collation); len= converter(collation.collation, (char*) res->ptr(), res->length(), - (char*) tmp_value.ptr(), len); - tmp_value.length(len); - res= &tmp_value; + (char*) str->ptr(), alloced_length); + str->set_charset(collation.collation); } - return res; + DBUG_ASSERT(len <= alloced_length); + str->length(len); + return str; } @@ -1783,7 +1778,7 @@ String *Item_func_substr_index::val_str(String *str) DBUG_ASSERT(fixed == 1); char buff[MAX_FIELD_WIDTH]; String tmp(buff,sizeof(buff),system_charset_info); - String *res= args[0]->val_str(str); + String *res= args[0]->val_str(&tmp_value); String *delimiter= args[1]->val_str(&tmp); int32 count= (int32) args[2]->val_int(); uint offset; @@ -1832,20 +1827,31 @@ String *Item_func_substr_index::val_str(String *str) if (pass == 0) /* count<0 */ { c+=n+1; - if (c<=0) return res; /* not found, return original string */ + if (c<=0) + { + str->copy(res->ptr(), res->length(), collation.collation); + return str; // not found, return the original string + } ptr=res->ptr(); } else { - if (c) return res; /* Not found, return original string */ + if (c) + { + str->copy(res->ptr(), res->length(), collation.collation); + return str; // not found, return the original string + } if (count>0) /* return left part */ { - tmp_value.set(*res,0,(ulong) (ptr-res->ptr())); + str->copy(res->ptr(), (uint32) (ptr-res->ptr()), collation.collation); + return str; } else /* return right part */ { - ptr+= delimiter_length; - tmp_value.set(*res,(ulong) (ptr-res->ptr()), (ulong) (strend-ptr)); + ptr+= delimiter_length; + str->copy(res->ptr() + (ptr-res->ptr()), (uint32) (strend - ptr), + collation.collation); + return str; } } } @@ -1857,13 +1863,16 @@ String *Item_func_substr_index::val_str(String *str) { // start counting from the beginning for (offset=0; ; offset+= delimiter_length) { - if ((int) (offset= res->strstr(*delimiter, offset)) < 0) - return res; // Didn't find, return org string - if (!--count) - { - tmp_value.set(*res,0,offset); - break; - } + if ((int) (offset= res->strstr(*delimiter, offset)) < 0) + { + str->copy(res->ptr(), res->length(), collation.collation); + return str; // not found, return the original string + } + if (!--count) + { + str->copy(res->ptr(), offset, collation.collation); + return str; + } } } else @@ -1878,30 +1887,32 @@ String *Item_func_substr_index::val_str(String *str) address space less than where the found substring is located in res */ - if ((int) (offset= res->strrstr(*delimiter, offset)) < 0) - return res; // Didn't find, return org string + if ((int) (offset= res->strrstr(*delimiter, offset)) < 0) + { + str->copy(res->ptr(), res->length(), collation.collation); + return str; // not found, return the original string + } /* At this point, we've searched for the substring the number of times as supplied by the index value */ - if (!++count) - { - offset+= delimiter_length; - tmp_value.set(*res,offset,res->length()- offset); - break; - } + if (!++count) + { + offset+= delimiter_length; + str->copy(res->ptr() + offset, res->length() - offset, + collation.collation); + return str; + } } if (count) - return res; // Didn't find, return org string + { + str->copy(res->ptr(), res->length(), collation.collation); + return str; // not found, return the original string + } } } - /* - We always mark tmp_value as const so that if val_str() is called again - on this object, we don't disrupt the contents of tmp_value when it was - derived from another String. - */ - tmp_value.mark_as_const(); - return (&tmp_value); + DBUG_ASSERT(0); + return NULL; } /* -- cgit v1.2.1 From e2ac4098ed507957ba6dac9b408d31054a8e6b6d Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 19 Jul 2018 13:02:14 +0400 Subject: Simplify caseup() and casedn() in charsets After the MDEV-13118 fix there's no code in the server that wants caseup/casedn to change the argument in place for simple charsets. Let's remove this logic and always return the result in a new string for all charsets, both simple and complex. 1. Removing the optimization that *some* character sets used in casedn() and caseup(), which allowed (and required) to change the case in-place, overwriting the string passed as the "src" argument. Now all CHARSET_INFO's work in the same way: non of them change the source string in-place, all of them now convert case from the source string to the destination string, leaving the source string untouched. 2. Adding "const" qualifier to the "char *src" parameter to caseup() and casedn(). 3. Removing duplicate implementations in ctype-mb.c. Now both caseup() and casedn() implementations for all CJK character sets use internally the same function my_casefold_mb() (the former my_casefold_mb_varlen()). 4. Removing the "unused" attribute from parameters of some my_case{up|dn}_xxx() implementations, as the affected parameters are now *used* in the code. Previously these parameters were used only in DBUG_ASSERT(). --- include/m_ctype.h | 28 +++++++------- sql/item_strfunc.cc | 15 ++------ strings/ctype-bin.c | 8 ++-- strings/ctype-euc_kr.c | 4 +- strings/ctype-mb.c | 100 +++++++------------------------------------------ strings/ctype-simple.c | 22 +++++------ strings/ctype-ucs2.c | 78 ++++++++++++++++++++------------------ strings/ctype-ujis.c | 8 ++-- strings/ctype-utf8.c | 20 ++++++---- 9 files changed, 106 insertions(+), 177 deletions(-) diff --git a/include/m_ctype.h b/include/m_ctype.h index 8d9838fdde2..eb2d760359b 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -365,7 +365,7 @@ typedef int (*my_charset_conv_mb_wc)(CHARSET_INFO *, my_wc_t *, typedef int (*my_charset_conv_wc_mb)(CHARSET_INFO *, my_wc_t, uchar *, uchar *); typedef size_t (*my_charset_conv_case)(CHARSET_INFO *, - char *, size_t, char *, size_t); + const char *, size_t, char *, size_t); /* See strings/CHARSET_INFO.txt about information on this structure */ @@ -565,9 +565,11 @@ extern uint my_instr_simple(CHARSET_INFO *, /* Functions for 8bit */ extern size_t my_caseup_str_8bit(CHARSET_INFO *, char *); extern size_t my_casedn_str_8bit(CHARSET_INFO *, char *); -extern size_t my_caseup_8bit(CHARSET_INFO *, char *src, size_t srclen, +extern size_t my_caseup_8bit(CHARSET_INFO *, + const char *src, size_t srclen, char *dst, size_t dstlen); -extern size_t my_casedn_8bit(CHARSET_INFO *, char *src, size_t srclen, +extern size_t my_casedn_8bit(CHARSET_INFO *, + const char *src, size_t srclen, char *dst, size_t dstlen); extern int my_strcasecmp_8bit(CHARSET_INFO * cs, const char *, const char *); @@ -658,17 +660,17 @@ uint my_mbcharlen_8bit(CHARSET_INFO *, uint c); /* Functions for multibyte charsets */ extern size_t my_caseup_str_mb(CHARSET_INFO *, char *); extern size_t my_casedn_str_mb(CHARSET_INFO *, char *); -extern size_t my_caseup_mb(CHARSET_INFO *, char *src, size_t srclen, - char *dst, size_t dstlen); -extern size_t my_casedn_mb(CHARSET_INFO *, char *src, size_t srclen, - char *dst, size_t dstlen); -extern size_t my_caseup_mb_varlen(CHARSET_INFO *, char *src, size_t srclen, - char *dst, size_t dstlen); -extern size_t my_casedn_mb_varlen(CHARSET_INFO *, char *src, size_t srclen, - char *dst, size_t dstlen); -extern size_t my_caseup_ujis(CHARSET_INFO *, char *src, size_t srclen, +extern size_t my_caseup_mb(CHARSET_INFO *, + const char *src, size_t srclen, + char *dst, size_t dstlen); +extern size_t my_casedn_mb(CHARSET_INFO *, + const char *src, size_t srclen, + char *dst, size_t dstlen); +extern size_t my_caseup_ujis(CHARSET_INFO *, + const char *src, size_t srclen, char *dst, size_t dstlen); -extern size_t my_casedn_ujis(CHARSET_INFO *, char *src, size_t srclen, +extern size_t my_casedn_ujis(CHARSET_INFO *, + const char *src, size_t srclen, char *dst, size_t dstlen); extern int my_strcasecmp_mb(CHARSET_INFO * cs,const char *, const char *); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 160e740a9f7..ba9f14fb63f 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1572,19 +1572,10 @@ String *Item_str_conv::val_str(String *str) str->alloc((alloced_length= res->length() * multiply))))) return 0; - if (multiply == 1) - { - str->copy(*res); // Should not fail (it was alloced above) - len= converter(collation.collation, (char*) str->ptr(), str->length(), - (char*) str->ptr(), alloced_length); - } - else - { - len= converter(collation.collation, (char*) res->ptr(), res->length(), - (char*) str->ptr(), alloced_length); - str->set_charset(collation.collation); - } + len= converter(collation.collation, (char*) res->ptr(), res->length(), + (char*) str->ptr(), alloced_length); DBUG_ASSERT(len <= alloced_length); + str->set_charset(collation.collation); str->length(len); return str; } diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index 2e699db0bd3..53a0e850b54 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -220,11 +220,11 @@ static size_t my_case_str_bin(CHARSET_INFO *cs __attribute__((unused)), static size_t my_case_bin(CHARSET_INFO *cs __attribute__((unused)), - char *src __attribute__((unused)), - size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) + const char *src, size_t srclen, + char *dst, size_t dstlen) { + DBUG_ASSERT(srclen <= dstlen); + memcpy(dst, src, srclen); return srclen; } diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c index b7065369258..f35c3f07c79 100644 --- a/strings/ctype-euc_kr.c +++ b/strings/ctype-euc_kr.c @@ -9994,8 +9994,8 @@ static MY_CHARSET_HANDLER my_charset_handler= my_mb_ctype_mb, my_caseup_str_mb, my_casedn_str_mb, - my_caseup_mb_varlen, /* UPPER() can reduce length: Turkish DOTLESS i -> I */ - my_casedn_mb, /* LOWER() does not change length, use simple version*/ + my_caseup_mb, /* UPPER() can reduce length: Turkish DOTLESS i -> I */ + my_casedn_mb, /* LOWER() does not change length */ my_snprintf_8bit, my_long10_to_str_8bit, my_longlong10_to_str_8bit, diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index 02a9a91ca6a..318e581792a 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -71,81 +71,8 @@ get_case_info_for_ch(const CHARSET_INFO *cs, uint page, uint offs) /* - For character sets which don't change octet length in case conversion. -*/ -size_t my_caseup_mb(CHARSET_INFO * cs, char *src, size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) -{ - register uint32 l; - register char *srcend= src + srclen; - register const uchar *map= cs->to_upper; - - DBUG_ASSERT(cs->caseup_multiply == 1); - DBUG_ASSERT(src == dst && srclen == dstlen); - DBUG_ASSERT(cs->mbmaxlen == 2); - - while (src < srcend) - { - if ((l=my_ismbchar(cs, src, srcend))) - { - MY_UNICASE_CHARACTER *ch; - if ((ch= get_case_info_for_ch(cs, (uchar) src[0], (uchar) src[1]))) - { - *src++= ch->toupper >> 8; - *src++= ch->toupper & 0xFF; - } - else - src+= l; - } - else - { - *src=(char) map[(uchar) *src]; - src++; - } - } - return srclen; -} - - -size_t my_casedn_mb(CHARSET_INFO * cs, char *src, size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) -{ - register uint32 l; - register char *srcend= src + srclen; - register const uchar *map=cs->to_lower; - - DBUG_ASSERT(cs->casedn_multiply == 1); - DBUG_ASSERT(src == dst && srclen == dstlen); - DBUG_ASSERT(cs->mbmaxlen == 2); - - while (src < srcend) - { - if ((l= my_ismbchar(cs, src, srcend))) - { - MY_UNICASE_CHARACTER *ch; - if ((ch= get_case_info_for_ch(cs, (uchar) src[0], (uchar) src[1]))) - { - *src++= ch->tolower >> 8; - *src++= ch->tolower & 0xFF; - } - else - src+= l; - } - else - { - *src= (char) map[(uchar)*src]; - src++; - } - } - return srclen; -} - - -/* - Case folding functions for character set - where case conversion can change string octet length. + Case folding functions for CJK character set. + Case conversion can optionally reduce string octet length. For example, in EUCKR, _euckr 0xA9A5 == "LATIN LETTER DOTLESS I" (Turkish letter) is upper-cased to to @@ -153,13 +80,14 @@ size_t my_casedn_mb(CHARSET_INFO * cs, char *src, size_t srclen, Length is reduced in this example from two bytes to one byte. */ static size_t -my_casefold_mb_varlen(CHARSET_INFO *cs, - char *src, size_t srclen, - char *dst, size_t dstlen __attribute__((unused)), - const uchar *map, - size_t is_upper) +my_casefold_mb(CHARSET_INFO *cs, + const char *src, size_t srclen, + char *dst, size_t dstlen __attribute__((unused)), + const uchar *map, + size_t is_upper) { - char *srcend= src + srclen, *dst0= dst; + const char *srcend= src + srclen; + char *dst0= dst; DBUG_ASSERT(cs->mbmaxlen == 2); @@ -193,22 +121,22 @@ my_casefold_mb_varlen(CHARSET_INFO *cs, size_t -my_casedn_mb_varlen(CHARSET_INFO * cs, char *src, size_t srclen, +my_casedn_mb(CHARSET_INFO * cs, const char *src, size_t srclen, char *dst, size_t dstlen) { DBUG_ASSERT(dstlen >= srclen * cs->casedn_multiply); DBUG_ASSERT(src != dst || cs->casedn_multiply == 1); - return my_casefold_mb_varlen(cs, src, srclen, dst, dstlen, cs->to_lower, 0); + return my_casefold_mb(cs, src, srclen, dst, dstlen, cs->to_lower, 0); } size_t -my_caseup_mb_varlen(CHARSET_INFO * cs, char *src, size_t srclen, - char *dst, size_t dstlen) +my_caseup_mb(CHARSET_INFO * cs, const char *src, size_t srclen, + char *dst, size_t dstlen) { DBUG_ASSERT(dstlen >= srclen * cs->caseup_multiply); DBUG_ASSERT(src != dst || cs->caseup_multiply == 1); - return my_casefold_mb_varlen(cs, src, srclen, dst, dstlen, cs->to_upper, 1); + return my_casefold_mb(cs, src, srclen, dst, dstlen, cs->to_upper, 1); } diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index 7f13cef4474..61b14b84820 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -214,28 +214,26 @@ size_t my_casedn_str_8bit(CHARSET_INFO * cs,char *str) } -size_t my_caseup_8bit(CHARSET_INFO * cs, char *src, size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) +size_t my_caseup_8bit(CHARSET_INFO * cs, const char *src, size_t srclen, + char *dst, size_t dstlen) { - char *end= src + srclen; + const char *end= src + srclen; register const uchar *map= cs->to_upper; - DBUG_ASSERT(src == dst && srclen == dstlen); + DBUG_ASSERT(srclen <= dstlen); for ( ; src != end ; src++) - *src= (char) map[(uchar) *src]; + *dst++= (char) map[(uchar) *src]; return srclen; } -size_t my_casedn_8bit(CHARSET_INFO * cs, char *src, size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) +size_t my_casedn_8bit(CHARSET_INFO * cs, const char *src, size_t srclen, + char *dst, size_t dstlen) { - char *end= src + srclen; + const char *end= src + srclen; register const uchar *map=cs->to_lower; - DBUG_ASSERT(src == dst && srclen == dstlen); + DBUG_ASSERT(srclen <= dstlen); for ( ; src != end ; src++) - *src= (char) map[(uchar) *src]; + *dst++= (char) map[(uchar) *src]; return srclen; } diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 318c248f742..724e69872de 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -1196,25 +1196,26 @@ my_tosort_utf16(MY_UNICASE_INFO *uni_plane, my_wc_t *wc) static size_t -my_caseup_utf16(CHARSET_INFO *cs, char *src, size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) +my_caseup_utf16(CHARSET_INFO *cs, const char *src, size_t srclen, + char *dst, size_t dstlen) { my_wc_t wc; my_charset_conv_mb_wc mb_wc= cs->cset->mb_wc; my_charset_conv_wc_mb wc_mb= cs->cset->wc_mb; int res; - char *srcend= src + srclen; + const char *srcend= src + srclen; + char *dstend= dst + dstlen; MY_UNICASE_INFO *uni_plane= cs->caseinfo; - DBUG_ASSERT(src == dst && srclen == dstlen); + DBUG_ASSERT(srclen <= dstlen); while ((src < srcend) && (res= mb_wc(cs, &wc, (uchar *) src, (uchar *) srcend)) > 0) { my_toupper_utf16(uni_plane, &wc); - if (res != wc_mb(cs, wc, (uchar *) src, (uchar *) srcend)) + if (res != wc_mb(cs, wc, (uchar *) dst, (uchar *) dstend)) break; src+= res; + dst+= res; } return srclen; } @@ -1243,25 +1244,26 @@ my_hash_sort_utf16(CHARSET_INFO *cs, const uchar *s, size_t slen, static size_t -my_casedn_utf16(CHARSET_INFO *cs, char *src, size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) +my_casedn_utf16(CHARSET_INFO *cs, const char *src, size_t srclen, + char *dst, size_t dstlen) { my_wc_t wc; my_charset_conv_mb_wc mb_wc= cs->cset->mb_wc; my_charset_conv_wc_mb wc_mb= cs->cset->wc_mb; int res; - char *srcend= src + srclen; + const char *srcend= src + srclen; + char *dstend= dst + dstlen; MY_UNICASE_INFO *uni_plane= cs->caseinfo; - DBUG_ASSERT(src == dst && srclen == dstlen); + DBUG_ASSERT(srclen <= dstlen); while ((src < srcend) && (res= mb_wc(cs, &wc, (uchar *) src, (uchar *) srcend)) > 0) { my_tolower_utf16(uni_plane, &wc); - if (res != wc_mb(cs, wc, (uchar *) src, (uchar *) srcend)) + if (res != wc_mb(cs, wc, (uchar *) dst, (uchar *) dstend)) break; src+= res; + dst+= res; } return srclen; } @@ -1987,23 +1989,24 @@ my_tosort_utf32(MY_UNICASE_INFO *uni_plane, my_wc_t *wc) static size_t -my_caseup_utf32(CHARSET_INFO *cs, char *src, size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) +my_caseup_utf32(CHARSET_INFO *cs, const char *src, size_t srclen, + char *dst, size_t dstlen) { my_wc_t wc; int res; - char *srcend= src + srclen; + const char *srcend= src + srclen; + char *dstend= dst + dstlen; MY_UNICASE_INFO *uni_plane= cs->caseinfo; - DBUG_ASSERT(src == dst && srclen == dstlen); + DBUG_ASSERT(srclen <= dstlen); while ((src < srcend) && (res= my_utf32_uni(cs, &wc, (uchar *)src, (uchar*) srcend)) > 0) { my_toupper_utf32(uni_plane, &wc); - if (res != my_uni_utf32(cs, wc, (uchar*) src, (uchar*) srcend)) + if (res != my_uni_utf32(cs, wc, (uchar*) dst, (uchar*) dstend)) break; src+= res; + dst+= res; } return srclen; } @@ -2038,22 +2041,23 @@ my_hash_sort_utf32(CHARSET_INFO *cs, const uchar *s, size_t slen, static size_t -my_casedn_utf32(CHARSET_INFO *cs, char *src, size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) +my_casedn_utf32(CHARSET_INFO *cs, const char *src, size_t srclen, + char *dst, size_t dstlen) { my_wc_t wc; int res; - char *srcend= src + srclen; + const char *srcend= src + srclen; + char *dstend= dst + dstlen; MY_UNICASE_INFO *uni_plane= cs->caseinfo; - DBUG_ASSERT(src == dst && srclen == dstlen); + DBUG_ASSERT(srclen <= dstlen); while ((res= my_utf32_uni(cs, &wc, (uchar*) src, (uchar*) srcend)) > 0) { my_tolower_utf32(uni_plane,&wc); - if (res != my_uni_utf32(cs, wc, (uchar*) src, (uchar*) srcend)) + if (res != my_uni_utf32(cs, wc, (uchar*) dst, (uchar*) dstend)) break; src+= res; + dst+= res; } return srclen; } @@ -2950,23 +2954,24 @@ my_tosort_ucs2(MY_UNICASE_INFO *uni_plane, my_wc_t *wc) *wc= page[*wc & 0xFF].sort; } -static size_t my_caseup_ucs2(CHARSET_INFO *cs, char *src, size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) +static size_t my_caseup_ucs2(CHARSET_INFO *cs, const char *src, size_t srclen, + char *dst, size_t dstlen) { my_wc_t wc; int res; - char *srcend= src + srclen; + const char *srcend= src + srclen; + char *dstend= dst + dstlen; MY_UNICASE_INFO *uni_plane= cs->caseinfo; - DBUG_ASSERT(src == dst && srclen == dstlen); + DBUG_ASSERT(srclen <= dstlen); while ((src < srcend) && (res= my_ucs2_uni(cs, &wc, (uchar *)src, (uchar*) srcend)) > 0) { my_toupper_ucs2(uni_plane, &wc); - if (res != my_uni_ucs2(cs, wc, (uchar*) src, (uchar*) srcend)) + if (res != my_uni_ucs2(cs, wc, (uchar*) dst, (uchar*) dstend)) break; src+= res; + dst+= res; } return srclen; } @@ -2995,23 +3000,24 @@ static void my_hash_sort_ucs2(CHARSET_INFO *cs, const uchar *s, size_t slen, } -static size_t my_casedn_ucs2(CHARSET_INFO *cs, char *src, size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) +static size_t my_casedn_ucs2(CHARSET_INFO *cs, const char *src, size_t srclen, + char *dst, size_t dstlen) { my_wc_t wc; int res; - char *srcend= src + srclen; + const char *srcend= src + srclen; + char *dstend= dst + dstlen; MY_UNICASE_INFO *uni_plane= cs->caseinfo; - DBUG_ASSERT(src == dst && srclen == dstlen); + DBUG_ASSERT(srclen <= dstlen); while ((src < srcend) && (res= my_ucs2_uni(cs, &wc, (uchar*) src, (uchar*) srcend)) > 0) { my_tolower_ucs2(uni_plane, &wc); - if (res != my_uni_ucs2(cs, wc, (uchar*) src, (uchar*) srcend)) + if (res != my_uni_ucs2(cs, wc, (uchar*) dst, (uchar*) dstend)) break; src+= res; + dst+= res; } return srclen; } diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index e7dbefe6c1d..25f8881d819 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -67179,12 +67179,12 @@ get_case_info_for_ch(CHARSET_INFO *cs, uint plane, uint page, uint offs) */ static size_t my_casefold_ujis(CHARSET_INFO *cs, - char *src, size_t srclen, + const char *src, size_t srclen, char *dst, size_t dstlen __attribute__((unused)), const uchar * const map, size_t is_upper) { - char *srcend= src + srclen, *dst0= dst; + const char *srcend= src + srclen, *dst0= dst; while (src < srcend) { @@ -67226,7 +67226,7 @@ my_casefold_ujis(CHARSET_INFO *cs, LOWER() */ size_t -my_casedn_ujis(CHARSET_INFO * cs, char *src, size_t srclen, +my_casedn_ujis(CHARSET_INFO * cs, const char *src, size_t srclen, char *dst, size_t dstlen) { DBUG_ASSERT(dstlen >= srclen * cs->casedn_multiply); @@ -67239,7 +67239,7 @@ my_casedn_ujis(CHARSET_INFO * cs, char *src, size_t srclen, UPPER() */ size_t -my_caseup_ujis(CHARSET_INFO * cs, char *src, size_t srclen, +my_caseup_ujis(CHARSET_INFO * cs, const char *src, size_t srclen, char *dst, size_t dstlen) { DBUG_ASSERT(dstlen >= srclen * cs->caseup_multiply); diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index cd4e82a107c..7d7e61ce511 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -5065,12 +5065,13 @@ my_tosort_utf8mb3(MY_UNICASE_INFO *uni_plane, my_wc_t *wc) *wc= page[*wc & 0xFF].sort; } -static size_t my_caseup_utf8(CHARSET_INFO *cs, char *src, size_t srclen, +static size_t my_caseup_utf8(CHARSET_INFO *cs, const char *src, size_t srclen, char *dst, size_t dstlen) { my_wc_t wc; int srcres, dstres; - char *srcend= src + srclen, *dstend= dst + dstlen, *dst0= dst; + const char *srcend= src + srclen; + char *dstend= dst + dstlen, *dst0= dst; MY_UNICASE_INFO *uni_plane= cs->caseinfo; DBUG_ASSERT(src != dst || cs->caseup_multiply == 1); @@ -5136,12 +5137,13 @@ static size_t my_caseup_str_utf8(CHARSET_INFO *cs, char *src) } -static size_t my_casedn_utf8(CHARSET_INFO *cs, char *src, size_t srclen, +static size_t my_casedn_utf8(CHARSET_INFO *cs, const char *src, size_t srclen, char *dst, size_t dstlen) { my_wc_t wc; int srcres, dstres; - char *srcend= src + srclen, *dstend= dst + dstlen, *dst0= dst; + const char *srcend= src + srclen; + char *dstend= dst + dstlen, *dst0= dst; MY_UNICASE_INFO *uni_plane= cs->caseinfo; DBUG_ASSERT(src != dst || cs->casedn_multiply == 1); @@ -7579,12 +7581,13 @@ my_toupper_utf8mb4(MY_UNICASE_INFO *uni_plane, my_wc_t *wc) static size_t -my_caseup_utf8mb4(CHARSET_INFO *cs, char *src, size_t srclen, +my_caseup_utf8mb4(CHARSET_INFO *cs, const char *src, size_t srclen, char *dst, size_t dstlen) { my_wc_t wc; int srcres, dstres; - char *srcend= src + srclen, *dstend= dst + dstlen, *dst0= dst; + const char *srcend= src + srclen; + char *dstend= dst + dstlen, *dst0= dst; MY_UNICASE_INFO *uni_plane= cs->caseinfo; DBUG_ASSERT(src != dst || cs->caseup_multiply == 1); @@ -7666,12 +7669,13 @@ my_caseup_str_utf8mb4(CHARSET_INFO *cs, char *src) static size_t my_casedn_utf8mb4(CHARSET_INFO *cs, - char *src, size_t srclen, + const char *src, size_t srclen, char *dst, size_t dstlen) { my_wc_t wc; int srcres, dstres; - char *srcend= src + srclen, *dstend= dst + dstlen, *dst0= dst; + const char *srcend= src + srclen; + char *dstend= dst + dstlen, *dst0= dst; MY_UNICASE_INFO *uni_plane= cs->caseinfo; DBUG_ASSERT(src != dst || cs->casedn_multiply == 1); -- cgit v1.2.1 From 0b3e28a4cd3f8000eedb8ba190c0ea461544651a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 12 Jul 2018 21:58:11 +0200 Subject: MDEV-8941 Compile on Solaris (SPARC) fails with errors in filamvct.cpp remove unnecessary declaration --- storage/connect/filamvct.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/storage/connect/filamvct.cpp b/storage/connect/filamvct.cpp index 244acfdc5c8..dd827d084fa 100755 --- a/storage/connect/filamvct.cpp +++ b/storage/connect/filamvct.cpp @@ -65,11 +65,6 @@ extern int num_read, num_there; // Statistics static int num_write; -#if defined(UNIX) -// Add dummy strerror (NGC) -char *strerror(int num); -#endif // UNIX - /***********************************************************************/ /* Header containing block info for not split VEC tables. */ /* Block and last values can be calculated from NumRec and Nrec. */ -- cgit v1.2.1 From bd5cf02bbe7bce029b0275be1b15d2108806d5e9 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 13 Jul 2018 16:54:47 +0200 Subject: MDEV-11741 handler::ha_reset(): Assertion `bitmap_is_set_all(&table->s->all_set)' failed or server crash in mi_reset or buffer overrun or unexpected ER_CANT_REMOVE_ALL_FIELDS MEMORY table could be renamed into a non-extistent database. rename() is documented to return ENOENT when the source file does not exist OR when the target directory not exist. Nonexistent source .frm file is ok (table can still exist in the engine), nonexistent target directory is not. Make my_rename to use ENOTDIR for the latter case. Make RENAME TABLE issue an appropriate error ("unknown database" instead of "unknown table") --- mysql-test/r/rename.result | 4 ++++ mysql-test/t/rename.test | 7 +++++++ mysys/my_rename.c | 5 ++++- sql/sql_table.cc | 2 ++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/rename.result b/mysql-test/r/rename.result index c90aaf24e9b..f019527c951 100644 --- a/mysql-test/r/rename.result +++ b/mysql-test/r/rename.result @@ -133,3 +133,7 @@ select * from t2; a 1 drop table tmp,t2; +create table t1 (a int) engine=memory; +rename table t1 to non_existent.t2; +ERROR 42000: Unknown database 'non_existent' +drop table t1; diff --git a/mysql-test/t/rename.test b/mysql-test/t/rename.test index 67732d5b5b9..215ecbcbb18 100644 --- a/mysql-test/t/rename.test +++ b/mysql-test/t/rename.test @@ -141,3 +141,10 @@ select * from tmp; select * from t2; drop table tmp,t2; +# +# MDEV-11741 handler::ha_reset(): Assertion `bitmap_is_set_all(&table->s->all_set)' failed or server crash in mi_reset or buffer overrun or unexpected ER_CANT_REMOVE_ALL_FIELDS +# +create table t1 (a int) engine=memory; +--error ER_BAD_DB_ERROR +rename table t1 to non_existent.t2; +drop table t1; diff --git a/mysys/my_rename.c b/mysys/my_rename.c index 09e7eafa980..17f693629a8 100644 --- a/mysys/my_rename.c +++ b/mysys/my_rename.c @@ -39,7 +39,10 @@ int my_rename(const char *from, const char *to, myf MyFlags) if (link(from, to) || unlink(from)) { #endif - my_errno=errno; + if (errno == ENOENT && !access(from, F_OK)) + my_errno= ENOTDIR; + else + my_errno= errno; error = -1; if (MyFlags & (MY_FAE+MY_WME)) my_error(EE_LINK, MYF(ME_BELL+ME_WAITTANG),from,to,my_errno); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index ee02b5fc7aa..9a2b4901d4e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5257,6 +5257,8 @@ mysql_rename_table(handlerton *base, const char *old_db, delete file; if (error == HA_ERR_WRONG_COMMAND) my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER TABLE"); + else if (error == ENOTDIR) + my_error(ER_BAD_DB_ERROR, MYF(0), new_db); else if (error) my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error); else if (!(flags & FN_IS_TMP)) -- cgit v1.2.1 From 33eccb577657a127a877cea53ee4dc41cb4604c2 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 13 Jul 2018 21:37:22 +0200 Subject: MDEV-11790 WITHOUT_SERVER installs mysqld_safe_helper Don't install server files if WITHOUT_SERVER is specified. "Server files" are defined as files going into the MariaDB-Server RPM, that is files in the components Server, ManPagesServer, Server_Scripts, IniFiles, SuportFiles, and Readme. --- CMakeLists.txt | 6 ++++++ cmake/install_macros.cmake | 8 ++++++++ cmake/mysql_add_executable.cmake | 3 +++ scripts/CMakeLists.txt | 2 ++ sql/share/CMakeLists.txt | 12 +++++++----- support-files/CMakeLists.txt | 2 ++ 6 files changed, 28 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 11874650d18..5a9ec265de0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -165,6 +165,12 @@ ENDIF() OPTION (WITH_UNIT_TESTS "Compile MySQL with unit tests" ON) MARK_AS_ADVANCED(CYBOZU BACKUP_TEST WITHOUT_SERVER DISABLE_SHARED) +IF (WITHOUT_SERVER) + SET (SKIP_COMPONENTS "Server|IniFiles|SuportFiles|Readme") +ELSE() + SET (SKIP_COMPONENTS "N-O-N-E") +ENDIF() + OPTION(NOT_FOR_DISTRIBUTION "Allow linking with GPLv2-incompatible system libraries. Only set it you never plan to distribute the resulting binaries" OFF) include(CheckCSourceCompiles) diff --git a/cmake/install_macros.cmake b/cmake/install_macros.cmake index 7da8edd22eb..ff4ba593415 100644 --- a/cmake/install_macros.cmake +++ b/cmake/install_macros.cmake @@ -115,6 +115,10 @@ FUNCTION(INSTALL_SCRIPT) SET(COMP) ENDIF() + IF (COMP MATCHES ${SKIP_COMPONENTS}) + RETURN() + ENDIF() + INSTALL(FILES ${script} DESTINATION ${ARG_DESTINATION} @@ -138,6 +142,10 @@ FUNCTION(INSTALL_DOCUMENTATION) SET(destination ${INSTALL_DOCDIR}) ENDIF() + IF (ARG_COMPONENT MATCHES ${SKIP_COMPONENTS}) + RETURN() + ENDIF() + STRING(TOUPPER ${ARG_COMPONENT} COMPUP) IF(CPACK_COMPONENT_${COMPUP}_GROUP) SET(group ${CPACK_COMPONENT_${COMPUP}_GROUP}) diff --git a/cmake/mysql_add_executable.cmake b/cmake/mysql_add_executable.cmake index 45575bdd536..c8a2e522d66 100644 --- a/cmake/mysql_add_executable.cmake +++ b/cmake/mysql_add_executable.cmake @@ -59,6 +59,9 @@ FUNCTION (MYSQL_ADD_EXECUTABLE) ELSE() SET(COMP COMPONENT Client) ENDIF() + IF (COMP MATCHES ${SKIP_COMPONENTS}) + RETURN() + ENDIF() MYSQL_INSTALL_TARGETS(${target} DESTINATION ${ARG_DESTINATION} ${COMP}) ENDIF() ENDFUNCTION() diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index 40273b1a1c2..24b48e1920e 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -74,6 +74,7 @@ IF(UNIX) ) ENDIF() +IF (NOT WITHOUT_SERVER) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/mysql_system_tables.sql ${CMAKE_CURRENT_SOURCE_DIR}/mysql_system_tables_data.sql @@ -83,6 +84,7 @@ INSTALL(FILES ${FIX_PRIVILEGES_SQL} DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT Server ) +ENDIF() # TCMalloc hacks IF(MALLOC_LIB) diff --git a/sql/share/CMakeLists.txt b/sql/share/CMakeLists.txt index e0d5fb6c1a7..4293c0b528c 100644 --- a/sql/share/CMakeLists.txt +++ b/sql/share/CMakeLists.txt @@ -44,12 +44,14 @@ SET(files errmsg-utf8.txt ) -FOREACH (dir ${dirs}) - INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${dir} - DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT Server) -ENDFOREACH() INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/charsets DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT Common PATTERN "languages.html" EXCLUDE ) -INSTALL(FILES ${files} DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT Server) +IF (NOT WITHOUT_SERVER) + FOREACH (dir ${dirs}) + INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${dir} + DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT Server) + ENDFOREACH() + INSTALL(FILES ${files} DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT Server) +ENDIF() diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt index 5e9fd081a09..cc9eed6c7be 100644 --- a/support-files/CMakeLists.txt +++ b/support-files/CMakeLists.txt @@ -41,12 +41,14 @@ ELSE() SET(inst_location ${INSTALL_SUPPORTFILESDIR}) ENDIF() +IF (NOT WITHOUT_SERVER) FOREACH(inifile my-huge my-innodb-heavy-4G my-large my-medium my-small) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${inifile}.cnf.sh ${CMAKE_CURRENT_BINARY_DIR}/${inifile}.${ini_file_extension} @ONLY) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${inifile}.${ini_file_extension} DESTINATION ${inst_location} COMPONENT IniFiles) ENDFOREACH() +ENDIF() IF(UNIX) SET(prefix ${CMAKE_INSTALL_PREFIX}) -- cgit v1.2.1 From 40f29ecbf1c8bf36be443c40382fe8cdc8a7f413 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 14 Jul 2018 00:51:23 +0200 Subject: MDEV-13397 MariaDB upgrade fail when using default_time_zone don't try to set default time zone in --bootstrap, this generally cannot be done, as timezone tables aren't loaded. and bootstrap scripts don't need it anyway. --- mysql-test/t/bootstrap.test | 9 +++++++++ sql/tztime.cc | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/mysql-test/t/bootstrap.test b/mysql-test/t/bootstrap.test index 5ab736cee15..3df3919220e 100644 --- a/mysql-test/t/bootstrap.test +++ b/mysql-test/t/bootstrap.test @@ -105,3 +105,12 @@ use test; EOF --exec $MYSQLD_BOOTSTRAP_CMD --ignore-db-dirs='some_dir' --ignore-db-dirs='some_dir' < $MYSQLTEST_VARDIR/tmp/bootstrap_9969.sql >> $MYSQLTEST_VARDIR/tmp/bootstrap.log 2>&1 --remove_file $MYSQLTEST_VARDIR/tmp/bootstrap_9969.sql + +# +# MDEV-13397 MariaDB upgrade fail when using default_time_zone +# +--write_file $MYSQLTEST_VARDIR/tmp/bootstrap_9969.sql +use test; +EOF +--exec $MYSQLD_BOOTSTRAP_CMD --default-time-zone=Europe/Moscow < $MYSQLTEST_VARDIR/tmp/bootstrap_9969.sql >> $MYSQLTEST_VARDIR/tmp/bootstrap.log 2>&1 +--remove_file $MYSQLTEST_VARDIR/tmp/bootstrap_9969.sql diff --git a/sql/tztime.cc b/sql/tztime.cc index 75b732f4436..9933c1e6364 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1663,7 +1663,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) { /* If we are in bootstrap mode we should not load time zone tables */ return_val= time_zone_tables_exist= 0; - goto end_with_setting_default_tz; + goto end_with_cleanup; } /* -- cgit v1.2.1 From 5c744bb5350acbf2d3abce28d01fc829c4f2375c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 14 Jul 2018 13:48:50 +0200 Subject: MDEV-14882 mysql_upgrade performs unnecessary conversions back and forth avoid round-robin conversions, if the column is MODIFY-ed, it should always be modified to its final definition, not to some intermediate state. also avoid other unconditional changes, like ALTER TABLE event DROP PRIMARY KEY; ALTER TABLE event ADD PRIMARY KEY(db, name); --- scripts/mysql_system_tables_fix.sql | 50 ++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql index 1bb601ef5f9..194b1615c2b 100644 --- a/scripts/mysql_system_tables_fix.sql +++ b/scripts/mysql_system_tables_fix.sql @@ -1,5 +1,5 @@ -- Copyright (C) 2003, 2013 Oracle and/or its affiliates. --- Copyright (C) 2010, 2014 SkySQL Ab. +-- Copyright (C) 2010, 2018 MariaDB Corporation -- -- 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 @@ -27,15 +27,24 @@ set sql_mode=''; set storage_engine=MyISAM; -ALTER TABLE user add File_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL; +ALTER TABLE user add File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; # Detect whether or not we had the Grant_priv column SET @hadGrantPriv:=0; SELECT @hadGrantPriv:=1 FROM user WHERE Grant_priv LIKE '%'; -ALTER TABLE user add Grant_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add References_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Index_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Alter_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL; -ALTER TABLE host add Grant_priv enum('N','Y') NOT NULL,add References_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Index_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Alter_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL; -ALTER TABLE db add Grant_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add References_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Index_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Alter_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL; +ALTER TABLE user add Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + add References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + add Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + add Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; +ALTER TABLE host add Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + add References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + add Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + add Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; +ALTER TABLE db add Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + add References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + add Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + add Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; # Fix privileges for old tables UPDATE user SET Grant_priv=File_priv,References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Create_priv WHERE @hadGrantPriv = 0; @@ -47,11 +56,11 @@ UPDATE host SET References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Cr # Adding columns needed by GRANT .. REQUIRE (openssl) ALTER TABLE user -ADD ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci NOT NULL, +ADD ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL, ADD ssl_cipher BLOB NOT NULL, ADD x509_issuer BLOB NOT NULL, ADD x509_subject BLOB NOT NULL; -ALTER TABLE user MODIFY ssl_type enum('','ANY','X509', 'SPECIFIED') NOT NULL; +ALTER TABLE user MODIFY ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL; # # tables_priv @@ -62,9 +71,9 @@ ALTER TABLE tables_priv ALTER TABLE tables_priv MODIFY Host char(60) NOT NULL default '', MODIFY Db char(64) NOT NULL default '', - MODIFY User char(80) NOT NULL default '', + MODIFY User char(80) binary NOT NULL default '', MODIFY Table_name char(64) NOT NULL default '', - MODIFY Grantor char(141) NOT NULL default '', + MODIFY Grantor char(141) COLLATE utf8_bin NOT NULL default '', ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; @@ -90,7 +99,7 @@ ALTER TABLE columns_priv ALTER TABLE columns_priv MODIFY Host char(60) NOT NULL default '', MODIFY Db char(64) NOT NULL default '', - MODIFY User char(80) NOT NULL default '', + MODIFY User char(80) binary NOT NULL default '', MODIFY Table_name char(64) NOT NULL default '', MODIFY Column_name char(64) NOT NULL default '', ENGINE=MyISAM, @@ -161,7 +170,7 @@ alter table func comment='User defined functions'; # and reset all char columns to correct width ALTER TABLE user MODIFY Host char(60) NOT NULL default '', - MODIFY User char(80) NOT NULL default '', + MODIFY User char(80) binary NOT NULL default '', ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; ALTER TABLE user MODIFY Password char(41) character set latin1 collate latin1_bin NOT NULL default '', @@ -191,7 +200,7 @@ ALTER TABLE user ALTER TABLE db MODIFY Host char(60) NOT NULL default '', MODIFY Db char(64) NOT NULL default '', - MODIFY User char(80) NOT NULL default '', + MODIFY User char(80) binary NOT NULL default '', ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; ALTER TABLE db MODIFY Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, @@ -451,7 +460,7 @@ ALTER TABLE proc MODIFY db MODIFY definer char(141) collate utf8_bin DEFAULT '' NOT NULL, MODIFY comment - char(64) collate utf8_bin DEFAULT '' NOT NULL; + text collate utf8_bin NOT NULL; ALTER TABLE proc ADD character_set_client char(32) collate utf8_bin DEFAULT NULL @@ -515,19 +524,18 @@ ALTER TABLE proc MODIFY comment SET @hadEventPriv := 0; SELECT @hadEventPriv :=1 FROM user WHERE Event_priv LIKE '%'; -ALTER TABLE user add Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NOT NULL AFTER Create_user_priv; +ALTER TABLE user ADD Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NOT NULL AFTER Create_user_priv; ALTER TABLE user MODIFY Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NOT NULL AFTER Create_user_priv; UPDATE user SET Event_priv=Super_priv WHERE @hadEventPriv = 0; -ALTER TABLE db add Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NOT NULL; +ALTER TABLE db ADD Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NOT NULL; ALTER TABLE db MODIFY Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NOT NULL; # # EVENT table # -ALTER TABLE event DROP PRIMARY KEY; -ALTER TABLE event ADD PRIMARY KEY(db, name); +ALTER TABLE event DROP PRIMARY KEY, ADD PRIMARY KEY(db, name); # Add sql_mode column just in case. ALTER TABLE event ADD sql_mode set ('IGNORE_BAD_TABLE_OPTIONS') AFTER on_completion; # Update list of sql_mode values. @@ -567,8 +575,8 @@ ALTER TABLE event MODIFY sql_mode ) DEFAULT '' NOT NULL AFTER on_completion; ALTER TABLE event MODIFY name char(64) CHARACTER SET utf8 NOT NULL default ''; -ALTER TABLE event MODIFY COLUMN originator INT UNSIGNED NOT NULL; ALTER TABLE event ADD COLUMN originator INT UNSIGNED NOT NULL AFTER comment; +ALTER TABLE event MODIFY COLUMN originator INT UNSIGNED NOT NULL; ALTER TABLE event MODIFY COLUMN status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED'; @@ -630,10 +638,12 @@ ALTER TABLE user MODIFY Create_tablespace_priv enum('N','Y') COLLATE utf8_genera UPDATE user SET Create_tablespace_priv = Super_priv WHERE @hadCreateTablespacePriv = 0; -ALTER TABLE user ADD plugin char(64) DEFAULT '', ADD authentication_string TEXT; +ALTER TABLE user ADD plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL, + ADD authentication_string TEXT NOT NULL; +ALTER TABLE user MODIFY plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL, + MODIFY authentication_string TEXT NOT NULL; ALTER TABLE user ADD password_expired ENUM('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; ALTER TABLE user ADD is_role enum('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; -ALTER TABLE user MODIFY plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL, MODIFY authentication_string TEXT NOT NULL; -- Somewhere above, we ran ALTER TABLE user .... CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin. -- we want password_expired column to have collation utf8_general_ci. ALTER TABLE user MODIFY password_expired ENUM('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; -- cgit v1.2.1 From d57ddaa1904d3c2f08460c539c72652f0c78c09a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 16 Jul 2018 15:12:38 +0200 Subject: MDEV-15551 Server hangs or assertion `strcmp(share->unique_file_name,filename) || share->last_version' fails in test_if_reopen or unexpected ER_LOCK_DEADLOCK only use HA_EXTRA_PREPARE_FOR_DROP when the table is going to be dropped --- mysql-test/suite/parts/r/truncate_locked.result | 7 +++++++ mysql-test/suite/parts/t/truncate_locked.test | 10 ++++++++++ sql/sql_truncate.cc | 3 ++- 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/parts/r/truncate_locked.result create mode 100644 mysql-test/suite/parts/t/truncate_locked.test diff --git a/mysql-test/suite/parts/r/truncate_locked.result b/mysql-test/suite/parts/r/truncate_locked.result new file mode 100644 index 00000000000..54a3722938e --- /dev/null +++ b/mysql-test/suite/parts/r/truncate_locked.result @@ -0,0 +1,7 @@ +create table t1 (i int) engine=myisam partition by hash(i) partitions 2 ; +lock table t1 write; +truncate table t1; +desc t1; +Field Type Null Key Default Extra +i int(11) YES NULL +drop table t1; diff --git a/mysql-test/suite/parts/t/truncate_locked.test b/mysql-test/suite/parts/t/truncate_locked.test new file mode 100644 index 00000000000..4ff1016fb05 --- /dev/null +++ b/mysql-test/suite/parts/t/truncate_locked.test @@ -0,0 +1,10 @@ +# +# MDEV-15551 Server hangs or assertion `strcmp(share->unique_file_name,filename) || share->last_version' fails in test_if_reopen or unexpected ER_LOCK_DEADLOCK +# +--source include/have_partition.inc +create table t1 (i int) engine=myisam partition by hash(i) partitions 2 ; +lock table t1 write; +truncate table t1; +desc t1; +drop table t1; + diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index 75a0678928b..f5161c09b2c 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -400,7 +400,8 @@ bool Sql_cmd_truncate_table::lock_table(THD *thd, TABLE_LIST *table_ref, { DEBUG_SYNC(thd, "upgrade_lock_for_truncate"); /* To remove the table from the cache we need an exclusive lock. */ - if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DROP)) + if (wait_while_table_is_used(thd, table, + *hton_can_recreate ? HA_EXTRA_PREPARE_FOR_DROP : HA_EXTRA_NOT_USED)) DBUG_RETURN(TRUE); m_ticket_downgrade= table->mdl_ticket; /* Close if table is going to be recreated. */ -- cgit v1.2.1 From 9cea4ccf12cb6e8746b9b440d9c62408a9ef04af Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 19 Jul 2018 15:31:30 -0700 Subject: MDEV-16726 Assertion `tab->type == JT_REF || tab->type == JT_EQ_REF' failed Due to a legacy bug in the code of make_join_statistics() detecting so-called constant tables could miss some of them in rare queries that used RIGHT JOIN. As a result these queries had execution plans different from the execution plans of the equivalent queries with LEFT JOIN. Besides starting from 10.2 this could trigger an assertion failure. --- mysql-test/r/join_outer.result | 50 +++++++++++++++++++++++++++++ mysql-test/r/join_outer_jcl6.result | 50 +++++++++++++++++++++++++++++ mysql-test/r/subselect_mat_cost_bugs.result | 2 +- mysql-test/t/join_outer.test | 48 +++++++++++++++++++++++++++ sql/sql_select.cc | 4 +-- 5 files changed, 151 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index 67b22ca86b2..d55f11cc2f2 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -2368,5 +2368,55 @@ id sid id 1 NULL NULL 2 NULL NULL drop table t1, t2; +# +# MDEV-16726: SELECT with STRAGHT JOIN containing NESTED RIGHT JOIN +# converted to INNER JOIN with first constant inner table +# +CREATE TABLE t1 ( +pk int PRIMARY KEY, i1 int, v1 varchar(1), v2 varchar(1), KEY v1 (v1,i1) +) engine=MyISAM; +INSERT INTO t1 VALUES +(8,3,'c','c'),(9,4,'z','z'),(10,3,'i','i'),(11,186,'x','x'), +(14,226,'m','m'),(15,133,'p','p'); +CREATE TABLE t2 ( +pk int PRIMARY KEY, i1 int, v1 varchar(1), v2 varchar(1) +) engine=MyISAM; +INSERT INTO t2 VALUES (10,6,'p','p'); +EXPLAIN EXTENDED +SELECT STRAIGHT_JOIN t2.v2 +FROM +(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2) +RIGHT JOIN +(t2,t1) +ON t1.pk = t2.pk AND t2.v2 = tb1.v1 +WHERE tb1.pk = 40 +ORDER BY tb1.i1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +Warnings: +Note 1003 select straight_join 'p' AS `v2` from `test`.`t1` join `test`.`t1` `tb1` left join `test`.`t1` `tb2` on(multiple equal(`test`.`tb2`.`v1`, NULL)) where 0 order by NULL +EXPLAIN EXTENDED +SELECT STRAIGHT_JOIN t2.v2 +FROM +(t2,t1) +LEFT JOIN +(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2) +ON t1.pk = t2.pk AND t2.v2 = tb1.v1 +WHERE tb1.pk = 40 +ORDER BY tb1.i1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +Warnings: +Note 1003 select straight_join 'p' AS `v2` from `test`.`t1` join `test`.`t1` `tb1` left join `test`.`t1` `tb2` on(multiple equal(`test`.`tb2`.`v1`, NULL)) where 0 order by NULL +SELECT STRAIGHT_JOIN DISTINCT t2.v2 +FROM +(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2) +RIGHT JOIN +(t2,t1) +ON t1.pk = t2.pk AND t2.v2 = tb1.v1 +WHERE tb1.pk = 40 +ORDER BY tb1.i1; +v2 +DROP TABLE t1,t2; # end of 5.5 tests SET optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/r/join_outer_jcl6.result b/mysql-test/r/join_outer_jcl6.result index c019da6197b..8a9b395edff 100644 --- a/mysql-test/r/join_outer_jcl6.result +++ b/mysql-test/r/join_outer_jcl6.result @@ -2379,6 +2379,56 @@ id sid id 1 NULL NULL 2 NULL NULL drop table t1, t2; +# +# MDEV-16726: SELECT with STRAGHT JOIN containing NESTED RIGHT JOIN +# converted to INNER JOIN with first constant inner table +# +CREATE TABLE t1 ( +pk int PRIMARY KEY, i1 int, v1 varchar(1), v2 varchar(1), KEY v1 (v1,i1) +) engine=MyISAM; +INSERT INTO t1 VALUES +(8,3,'c','c'),(9,4,'z','z'),(10,3,'i','i'),(11,186,'x','x'), +(14,226,'m','m'),(15,133,'p','p'); +CREATE TABLE t2 ( +pk int PRIMARY KEY, i1 int, v1 varchar(1), v2 varchar(1) +) engine=MyISAM; +INSERT INTO t2 VALUES (10,6,'p','p'); +EXPLAIN EXTENDED +SELECT STRAIGHT_JOIN t2.v2 +FROM +(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2) +RIGHT JOIN +(t2,t1) +ON t1.pk = t2.pk AND t2.v2 = tb1.v1 +WHERE tb1.pk = 40 +ORDER BY tb1.i1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +Warnings: +Note 1003 select straight_join 'p' AS `v2` from `test`.`t1` join `test`.`t1` `tb1` left join `test`.`t1` `tb2` on(multiple equal(`test`.`tb2`.`v1`, NULL)) where 0 order by NULL +EXPLAIN EXTENDED +SELECT STRAIGHT_JOIN t2.v2 +FROM +(t2,t1) +LEFT JOIN +(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2) +ON t1.pk = t2.pk AND t2.v2 = tb1.v1 +WHERE tb1.pk = 40 +ORDER BY tb1.i1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +Warnings: +Note 1003 select straight_join 'p' AS `v2` from `test`.`t1` join `test`.`t1` `tb1` left join `test`.`t1` `tb2` on(multiple equal(`test`.`tb2`.`v1`, NULL)) where 0 order by NULL +SELECT STRAIGHT_JOIN DISTINCT t2.v2 +FROM +(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2) +RIGHT JOIN +(t2,t1) +ON t1.pk = t2.pk AND t2.v2 = tb1.v1 +WHERE tb1.pk = 40 +ORDER BY tb1.i1; +v2 +DROP TABLE t1,t2; # end of 5.5 tests SET optimizer_switch=@save_optimizer_switch; set join_cache_level=default; diff --git a/mysql-test/r/subselect_mat_cost_bugs.result b/mysql-test/r/subselect_mat_cost_bugs.result index d33f1488e4d..03f4b3e1903 100644 --- a/mysql-test/r/subselect_mat_cost_bugs.result +++ b/mysql-test/r/subselect_mat_cost_bugs.result @@ -442,7 +442,7 @@ SELECT i2 FROM t2 RIGHT JOIN t3 ON (c3 = c2) WHERE pk3 = i1 id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 2 DEPENDENT SUBQUERY t3 const PRIMARY PRIMARY 4 const 1 -2 DEPENDENT SUBQUERY t2 index NULL i2 11 NULL 2 Using where; Using index +2 DEPENDENT SUBQUERY t2 index i2 i2 11 NULL 2 Using where; Using index DROP TABLE t1,t2,t3; # # MDEV-7599: in-to-exists chosen after min/max optimization diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test index 2769aea9969..305421c10d5 100644 --- a/mysql-test/t/join_outer.test +++ b/mysql-test/t/join_outer.test @@ -1911,6 +1911,54 @@ select * from t1 t on t.id=r.id ; drop table t1, t2; +--echo # +--echo # MDEV-16726: SELECT with STRAGHT JOIN containing NESTED RIGHT JOIN +--echo # converted to INNER JOIN with first constant inner table +--echo # + +CREATE TABLE t1 ( + pk int PRIMARY KEY, i1 int, v1 varchar(1), v2 varchar(1), KEY v1 (v1,i1) +) engine=MyISAM; +INSERT INTO t1 VALUES + (8,3,'c','c'),(9,4,'z','z'),(10,3,'i','i'),(11,186,'x','x'), + (14,226,'m','m'),(15,133,'p','p'); + +CREATE TABLE t2 ( + pk int PRIMARY KEY, i1 int, v1 varchar(1), v2 varchar(1) +) engine=MyISAM; +INSERT INTO t2 VALUES (10,6,'p','p'); + +EXPLAIN EXTENDED +SELECT STRAIGHT_JOIN t2.v2 +FROM + (t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2) + RIGHT JOIN + (t2,t1) + ON t1.pk = t2.pk AND t2.v2 = tb1.v1 +WHERE tb1.pk = 40 +ORDER BY tb1.i1; + +EXPLAIN EXTENDED +SELECT STRAIGHT_JOIN t2.v2 +FROM + (t2,t1) + LEFT JOIN + (t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2) + ON t1.pk = t2.pk AND t2.v2 = tb1.v1 +WHERE tb1.pk = 40 +ORDER BY tb1.i1; + +SELECT STRAIGHT_JOIN DISTINCT t2.v2 +FROM + (t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2) + RIGHT JOIN + (t2,t1) + ON t1.pk = t2.pk AND t2.v2 = tb1.v1 +WHERE tb1.pk = 40 +ORDER BY tb1.i1; + +DROP TABLE t1,t2; + --echo # end of 5.5 tests SET optimizer_switch=@save_optimizer_switch; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 700b7b37928..6a64a0e9952 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3456,8 +3456,8 @@ make_join_statistics(JOIN *join, List &tables_list, int ref_changed; do { - more_const_tables_found: ref_changed = 0; + more_const_tables_found: found_ref=0; /* @@ -3622,7 +3622,7 @@ make_join_statistics(JOIN *join, List &tables_list, } } } - } while (join->const_table_map & found_ref && ref_changed); + } while (ref_changed); join->sort_by_table= get_sort_by_table(join->order, join->group_list, join->select_lex->leaf_tables, -- cgit v1.2.1 From e0139c2b92ba1f8819a3ed75d020d9665545e2bf Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Tue, 24 Jul 2018 18:16:41 +0200 Subject: fix plugins.processlist make it not to fail when `show engine innodb status` output contains a double quote --- mysql-test/suite/plugins/t/processlist.test | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/plugins/t/processlist.test b/mysql-test/suite/plugins/t/processlist.test index 5aacef317b9..e8f03aacb10 100644 --- a/mysql-test/suite/plugins/t/processlist.test +++ b/mysql-test/suite/plugins/t/processlist.test @@ -8,7 +8,8 @@ start transaction; insert t1 values (1); let id=`select connection_id()`; connect con2,localhost,root; -let s=query_get_value(show engine innodb status,Status,1); +replace_regex /\"/-/; #" +let s=`show engine innodb status`; disable_query_log; eval select regexp_replace("$s", '(?s)^.*MySQL thread id $id,.*root([^\n]*)\n.*', '\\\\1') as `state from show engine innodb status`; eval select state as `state from show processlist` from information_schema.processlist where id = $id; -- cgit v1.2.1 From 9fbe360e9f7d41d169eb5abed22dc15f26f6c749 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Tue, 24 Jul 2018 18:24:21 +0200 Subject: make plugins.processlist more robust --- mysql-test/suite/plugins/r/processlist.result | 4 +--- mysql-test/suite/plugins/t/processlist.test | 5 +++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/mysql-test/suite/plugins/r/processlist.result b/mysql-test/suite/plugins/r/processlist.result index d08ea9d3523..9200c865533 100644 --- a/mysql-test/suite/plugins/r/processlist.result +++ b/mysql-test/suite/plugins/r/processlist.result @@ -1,8 +1,6 @@ create table t1 (a int) engine=innodb; start transaction; insert t1 values (1); -state from show engine innodb status +state from show engine innodb status, must be empty -state from show processlist - drop table t1; diff --git a/mysql-test/suite/plugins/t/processlist.test b/mysql-test/suite/plugins/t/processlist.test index e8f03aacb10..39b715b867b 100644 --- a/mysql-test/suite/plugins/t/processlist.test +++ b/mysql-test/suite/plugins/t/processlist.test @@ -8,11 +8,12 @@ start transaction; insert t1 values (1); let id=`select connection_id()`; connect con2,localhost,root; +let $wait_condition=select state='' from information_schema.processlist where id = $id; +--source include/wait_condition.inc replace_regex /\"/-/; #" let s=`show engine innodb status`; disable_query_log; -eval select regexp_replace("$s", '(?s)^.*MySQL thread id $id,.*root([^\n]*)\n.*', '\\\\1') as `state from show engine innodb status`; -eval select state as `state from show processlist` from information_schema.processlist where id = $id; +eval select regexp_replace("$s", '(?s)^.*MySQL thread id $id,.*root([^\n]*)\n.*', '\\\\1') as `state from show engine innodb status, must be empty`; enable_query_log; disconnect con2; connection default; -- cgit v1.2.1 From 1bda5e3a8f21d14b4af416259f293a92c49daebb Mon Sep 17 00:00:00 2001 From: Elena Stepanova Date: Tue, 24 Jul 2018 20:09:42 +0300 Subject: List of unstable tests for 10.0.36 release --- mysql-test/unstable-tests | 156 ++++++++++++++++++++++++++-------------------- 1 file changed, 89 insertions(+), 67 deletions(-) diff --git a/mysql-test/unstable-tests b/mysql-test/unstable-tests index d50a9acc92e..5fa6f6653c3 100644 --- a/mysql-test/unstable-tests +++ b/mysql-test/unstable-tests @@ -23,59 +23,79 @@ # ############################################################################## -# Based on 10.0 48636f09720af45454e5db1183b62a1991db8faf - +# Based on 10.0 5e67567b158db5d294b11b310ff35a454f58d034 + +main.alter_table : Modified in 10.0.36 +main.assign_key_cache : Added in 10.0.36 +main.assign_key_cache_debug : Added in 10.0.36 +main.auto_increment : Modified in 10.0.36 +main.bootstrap : Modified in 10.0.36 +main.connect_debug : Added in 10.0.36 main.count_distinct2 : MDEV-11768 - timeout main.create_delayed : MDEV-10605 - failed with timeout -main.ctype_ucs : Modified in 10.0.35 -main.ctype_utf8mb4 : Modified in 10.0.35 +main.create_or_replace : Modified in 10.0.36 +ctype_binary : Modified in 10.0.36 +ctype_eucjpms : Modified in 10.0.36 +ctype_euckr : Modified in 10.0.36 +ctype_gbk : Modified in 10.0.36 +ctype_latin1 : Modified in 10.0.36 +ctype_ucs : Modified in 10.0.36 +ctype_ujis : Modified in 10.0.36 +ctype_utf16le : Modified in 10.0.36 +ctype_utf16 : Modified in 10.0.36 +ctype_utf32 : Modified in 10.0.36 +ctype_utf8mb4 : Modified in 10.0.36 +ctype_utf8 : Modified in 10.0.36 main.debug_sync : MDEV-10607 - internal error +main.derived : Modified in 10.0.36 main.derived_opt : MDEV-11768 - timeout -main.dyncol : Modified in 10.0.35 main.events_slowlog : MDEV-12821 - wrong result -main.func_concat : Modified in 10.0.35 -main.func_misc : Modified in 10.0.35 -main.func_str : Modified in 10.0.35 -main.func_time : Modified in 10.0.35 -main.having : Modified in 10.0.35 main.gis : MDEV-13411 - wrong result on P8 +main.grant : Modified in 10.0.36 +main.grant2 : Modified in 10.0.36 +main.grant_not_windows : Added in 10.0.36 +main.having : Modified in 10.0.36 main.host_cache_size_functionality : MDEV-10606 - sporadic failure on shutdown main.index_intersect_innodb : MDEV-10643 - failed with timeout main.index_merge_innodb : MDEV-7142 - wrong result main.innodb_mysql_lock : MDEV-7861 - sporadic lock detection failure -main.join_outer : Modified in 10.0.35 +main.insert_select : Modified in 10.0.36 +main.join : Modified in 10.0.36 +main.join_cache : Modified in 10.0.36 +main.join_outer : Modified in 10.0.36 main.kill_processlist-6619 : MDEV-10793 - wrong result +main.limit : Modified in 10.0.36 main.log_tables-big : MDEV-13408 - wrong result main.mdev-504 : MDEV-10607 - sporadic "can't connect" main.mdev375 : MDEV-10607 - sporadic "can't connect" main.merge : MDEV-10607 - sporadic "can't connect" +main.myisam : Modified in 10.0.36 +main.mysql : Modified in 10.0.36 +main.mysql_cp932 : Modified in 10.0.36 +main.mysqldump : Modified in 10.0.36 main.mysqlhotcopy_myisam : MDEV-10995 - test hangs on debug build +main.mysqlslap : Modified in 10.0.36 main.mysqltest : MDEV-9269 - fails on Alpha main.mysql_client_test_nonblock : MDEV-15096 - exec failed -main.parser : Modified in 10.0.35 -main.partition : Modified in 10.0.35 main.ps : MDEV-11017 - sporadic wrong Prepared_stmt_count -main.ps_qc_innodb : Added in 10.0.35 +main.rename : Modified in 10.0.36 main.query_cache_debug : MDEV-15281 - resize or similar command in progress -main.read_only_innodb : Modified in 10.0.35 +main.selectivity : Modified in 10.0.36 main.show_explain : MDEV-10674 - wrong result -main.sp-destruct : Modified in 10.0.35 +main.sp-innodb : Modified in 10.0.36 main.sp_notembedded : MDEV-10607 - internal error main.sp-security : MDEV-10607 - sporadic "can't connect" +main.statistics : Modified in 10.0.36 +main.statistics_close : Added in 10.0.36 +main.stat_tables : Modified in 10.0.36 main.stat_tables_par_innodb : MDEV-14155 - wrong rounding -main.statistics : Modified in 10.0.35 main.subselect_innodb : MDEV-10614 - sporadic wrong results -main.subselect_mat : Modified in 10.0.35 -main.subselect4 : Modified in 10.0.35 -main.symlink-aria-11902 : MDEV-15098 - error 40 from storage engine -main.symlink-myisam-11902 : MDEV-15098 - error 40 from storage engine +main.subselect_sj : Modified in 10.0.36 +main.subselect_sj2_mat : Modified in 10.0.36 +main.subselect4 : Modified in 10.0.36 main.tc_heuristic_recover : MDEV-15200 - wrong error on mysqld_stub_cmd main.type_datetime : MDEV-14322 - wrong result -main.type_time_6065 : Modified in 10.0.35 -main.update_innodb : Modified in 10.0.35 -main.view : Modified in 10.0.35 main.xa : MDEV-11769 - lock wait timeout -main.xml : Modified in 10.0.35 #---------------------------------------------------------------- @@ -84,27 +104,16 @@ archive.archive_symlink : MDEV-12170 - unexpected error on rmdir archive.discover : MDEV-10510 - table is marked as crashed archive.mysqlhotcopy_archive : MDEV-10995 - test hangs on debug build, MDEV-14726 - table is marked as crashed +archive-test_sql_discovery.discover : MDEV-16817 - Table marked as crashed + #---------------------------------------------------------------- binlog.binlog_commit_wait : MDEV-10150 - Error: too much time elapsed +binlog.binlog_tmp_table_row : Added in 10.0.36 binlog.binlog_xa_recover : MDEV-8517 - Extra checkpoint #---------------------------------------------------------------- -connect.jdbc : Included file modified in 10.0.35 -connect.jdbc_new : Included file modified in 10.0.35 -connect.jdbc_oracle : Included file modified in 10.0.35 -connect.jdbc_postgresql : Modified in 10.0.35 -connect.json_java_2 : Included file modified in 10.0.35 -connect.json_java_3 : Included file modified in 10.0.35 -connect.json_mongo_c : Included file modified in 10.0.35 -connect.json_udf : Modified in 10.0.35 -connect.mongo_c : Included file modified in 10.0.35 -connect.mongo_java_2 : Included file modified in 10.0.35 -connect.mongo_java_3 : Included file modified in 10.0.35 -connect.mongo_test : Modified in 10.0.35 -connect.tbl_thread : Modified in 10.0.35 -connect.vcol : Added in 10.0.35 connect.zip : MDEV-13884 - wrong result #---------------------------------------------------------------- @@ -113,14 +122,16 @@ engines/rr_trx.* : MDEV-10998 - tests not maintained #---------------------------------------------------------------- -federated.federatedx : MDEV-10617 - Wrong checksum, timeouts +federated.assisted_discovery : Include file modified in 10.0.36 +federated.federatedx : MDEV-10617 - Wrong checksum, timeouts; include file modified in 10.0.36 federated.federated_bug_35333 : MDEV-13410 - Wrong result federated.federated_innodb : MDEV-10617, MDEV-10417 - Wrong checksum, timeouts, fails on Mips -federated.federated_partition : MDEV-10417 - Fails on Mips -federated.federated_transactions : MDEV-10617, MDEV-10417 - Wrong checksum, timeouts, fails on Mips +federated.federated_partition : MDEV-10417 - Fails on Mips; include file modified in 10.0.36 +federated.federated_transactions : MDEV-10617, MDEV-10417 - Wrong checksum, timeouts, fails on Mips; include file modified in 10.0.36 #---------------------------------------------------------------- +funcs_1.is_engines_federated : Include file modified in 10.0.36 funcs_1.memory_views : MDEV-11773 - timeout funcs_1.processlist_val_ps : MDEV-12175 - Wrong result funcs_1.processlist_val_no_prot : MDEV-11223 - Wrong result @@ -129,34 +140,40 @@ funcs_2/charset.* : MDEV-10999 - test not maintained #---------------------------------------------------------------- +handler.ps : Added in 10.0.36 + +#---------------------------------------------------------------- + +heap.heap_auto_increment : Modified in 10.0.36 + +#---------------------------------------------------------------- + +innodb.alter_partitioned_xa : Added in 10.0.36 innodb.binlog_consistent : MDEV-10618 - Server fails to start innodb.group_commit_crash : MDEV-11770 - checksum mismatch innodb.group_commit_crash_no_optimize_thread : MDEV-11770 - checksum mismatch -innodb.innodb-alter-nullable : Modified in 10.0.35 +innodb.innodb-alter : Modified in 10.0.36 innodb.innodb-alter-table : MDEV-10619 - Testcase timeout -innodb.innodb_bug11754376 : Modified in 10.0.35 -innodb.innodb_bug27216817 : Added in 10.0.35 innodb.innodb_bug30423 : MDEV-7311 - Wrong number of rows in the plan innodb.innodb_bug48024 : MDEV-14352 - Assertion failure -innodb.innodb_bug56947 : Modified in 10.0.35 -innodb.innodb_corrupt_bit : Modified in 10.0.35 +innodb.innodb_bug54044 : Modified in 10.0.36 +innodb.innodb-mdev7046 : Modified in 10.0.36 innodb.innodb_monitor : MDEV-10939 - Testcase timeout -innodb.innodb-replace-debug : Modified in 10.0.35 -innodb.log_file_size : MDEV-15668 - Not found pattern; modified in 10.0.35 -innodb.mvcc : Added in 10.0.35 -innodb.read_only_recover_committed : Added in 10.0.35 -innodb.recovery_shutdown : MDEV-15671 - Warning: database page corruption; modified in 10.0.35 +innodb.log_file_size : MDEV-15668 - Not found pattern +innodb.recovery_shutdown : MDEV-15671 - Warning: database page corruption +innodb.rename_table : Added in 10.0.36 +innodb.table_definition_cache_debug : MDEV-14206 - Unexpected warning innodb.xa_recovery : MDEV-15279 - mysqld got exception -innodb_fts.innobase_drop_fts_index_table : Modified in 10.0.35 +innodb_fts.basic : Added in 10.0.36 innodb_fts.innodb-fts-fic : MDEV-14154 - Assertion failure -innodb_fts.innodb_fts_misc_debug : MDEV-14156 - Unexpected warning; modified in 10.0.35 -innodb_fts.innodb_fts_result_cache_limit : Modified in 10.0.35 +innodb_fts.innodb_fts_misc_debug : MDEV-14156 - Unexpected warning #---------------------------------------------------------------- -maria.dynamic : Added in 10.0.35 -maria.maria : MDEV-14430 - Wrong result +maria.alter : Modified in 10.0.36 +maria.lock : Modified in 10.0.36 +maria.maria : MDEV-14430 - Wrong result; modified in 10.0.36 #---------------------------------------------------------------- @@ -178,12 +195,11 @@ multi_source.status_vars : MDEV-4632 - failed while waiting for Slave_received_h #---------------------------------------------------------------- -parts.partition_alter_innodb : Include file modified in 10.0.35 -parts.partition_alter_maria : Modified in 10.0.35 -parts.partition_alter_myisam : Include file modified in 10.0.35 -parts.partition_auto_increment_maria : MDEV-14430 - wrong result -parts.partition_debug_innodb : MDEV-15095 - table does not exist -parts.partition_exch_qa_10 : MDEV-11765 - wrong result +parts.alter_data_directory_innodb : Added in 10.0.36 +parts.partition_auto_increment_archive : MDEV-16491 - Table marked as crashed +parts.partition_auto_increment_maria : MDEV-14430 - wrong result +parts.partition_exch_qa_10 : MDEV-11765 - wrong result +parts.truncate_locked : Added in 10.0.36 #---------------------------------------------------------------- @@ -198,7 +214,8 @@ perfschema_stress.* : MDEV-10996 - tests not maintained #---------------------------------------------------------------- plugins.feedback_plugin_send : MDEV-7932 - ssl failed for url, MDEV-11118 - wrong result -plugins.server_audit : MDEV-9562 - crashes on sol10-sparc; modified in 10.0.35 +plugins.processlist : MDEV-16818 - Syntax error; added in 10.0.36 +plugins.server_audit : MDEV-9562 - crashes on sol10-sparc; modified in 10.0.36 plugins.thread_pool_server_audit : MDEV-9562 - crashes on sol10-sparc, MDEV-14295 - wrong result #---------------------------------------------------------------- @@ -208,6 +225,7 @@ roles.create_and_grant_role : MDEV-11772 - wrong result #---------------------------------------------------------------- rpl.last_insert_id : MDEV-10625 - warnings in error log +rpl.rename : Added in 10.0.36 rpl.rpl_auto_increment : MDEV-10417 - Fails on Mips rpl.rpl_auto_increment_bug45679 : MDEV-10417 - Fails on Mips rpl.rpl_auto_increment_update_failure : MDEV-10625 - warnings in error log @@ -219,14 +237,17 @@ rpl.rpl_gtid_until : MDEV-10625 - warnings in error log rpl.rpl_innodb_bug30888 : MDEV-10417 - Fails on Mips rpl.rpl_insert : MDEV-9329 - Fails on Ubuntu/s390x rpl.rpl_insert_delayed : MDEV-9329 - Fails on Ubuntu/s390x +rpl.rpl_insert_id_pk : MDEV-16567 - Assertion failure rpl.rpl_invoked_features : MDEV-10417 - Fails on Mips -rpl.rpl_mdev6020 : MDEV-10630, MDEV-10417 - Timeouts, fails on Mips +rpl.rpl_mdev6020 : MDEV-10417 - Timeouts, fails on Mips +rpl.rpl_mixed_implicit_commit_binlog : Included file modified in 10.0.36 rpl.rpl_parallel : MDEV-10653 - Timeouts rpl.rpl_parallel_mdev6589 : MDEV-12979 - Assertion failure rpl.rpl_parallel_multilevel2 : MDEV-14723 - Timeout rpl.rpl_parallel_temptable : MDEV-10356 - Crash in close_thread_tables rpl.rpl_partition_innodb : MDEV-10417 - Fails on Mips rpl.rpl_row_basic_11bugs : MDEV-12171 - Server failed to start +rpl.rpl_row_implicit_commit_binlog : Included file modified in 10.0.36 rpl.rpl_row_index_choice : MDEV-13409 - Server crash rpl.rpl_row_sp001 : MDEV-9329 - Fails on Ubuntu/s390x rpl.rpl_semi_sync : MDEV-11220 - Wrong result @@ -234,6 +255,7 @@ rpl.rpl_semi_sync_uninstall_plugin : MDEV-7140 - Wrong plugin status rpl.rpl_show_slave_hosts : MDEV-12171 - Server failed to start rpl.rpl_skip_replication : MDEV-9268 - Fails with timeout in sync_slave_with_master on Alpha rpl.rpl_slave_grp_exec : MDEV-10514 - Unexpected deadlock +rpl.rpl_stm_implicit_commit_binlog : Included file modified in 10.0.36 rpl.rpl_sync : MDEV-10633 - Database page corruption rpl.rpl_temporary_error2 : MDEV-10634 - Wrong number of retries @@ -247,7 +269,7 @@ spider/bg.direct_aggregate : MDEV-7098 - Trying to unlock mutex that wasn't spider/bg.direct_aggregate_part : MDEV-7098 - Trying to unlock mutex that wasn't locked spider/bg.spider3_fixes : MDEV-7098 - Trying to unlock mutex that wasn't locked spider/bg.spider_fixes_part : MDEV-7098 - Trying to unlock mutex that wasn't locked -spider/bg.ha : MDEV-7914 (fixed in 10.3), MDEV-9329 - Crash, failures on s390x +spider/bg.ha : MDEV-7914 (fixed in 10.1), MDEV-9329 - Crash, failures on s390x spider/bg.ha_part : MDEV-9329 - Fails on Ubuntu/s390x spider/bg.spider_fixes : MDEV-7098, MDEV-9329 - Mutex problem, failures on s390x spider/bg.vp_fixes : MDEV-9329 - Fails on Ubuntu/s390x @@ -267,7 +289,6 @@ stress.ddl_innodb : MDEV-10635 - Testcase timeout #---------------------------------------------------------------- sys_vars.autocommit_func2 : MDEV-9329 - Fails on Ubuntu/s390x -sys_vars.max_prepared_stmt_count_basic : Modified in 10.0.35 sys_vars.thread_cache_size_func : MDEV-11775 - wrong result #---------------------------------------------------------------- @@ -310,5 +331,6 @@ unit.my_atomic : MDEV-15670 - Signal 11 thrown vcol.not_supported : MDEV-10639 - Testcase timeout vcol.vcol_keys_innodb : MDEV-10639 - Testcase timeout +vcol.vcol_misc : MDEV-16651 - Wrong error message; modified in 10.0.36 #---------------------------------------------------------------- -- cgit v1.2.1 From d567f1611e27a17427380e9aae67939792f68ad1 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 24 Jul 2018 20:00:28 -0700 Subject: MDEV-16820 Lost 'Impossible where' from query with inexpensive subquery This patch fixes another problem introduced by the patch for mdev-4817. The latter changed Item_cond::fix_fields() in such a way that it could call the virtual method is_expensive(). With the first its call the method saves the result in Item::is_expensive_cache. For all next calls the method returns the result from this cache. So if the item once was determined as expensive the method always returns true. For subqueries it's not good, because non-optimized subqueries always is considered as expensive. It means that the cache should be invalidated after the call of optimize_constant_subqueries(). --- mysql-test/r/subselect.result | 16 ++++++++++++++++ mysql-test/r/subselect_no_mat.result | 16 ++++++++++++++++ mysql-test/r/subselect_no_opts.result | 16 ++++++++++++++++ mysql-test/r/subselect_no_scache.result | 16 ++++++++++++++++ mysql-test/r/subselect_no_semijoin.result | 16 ++++++++++++++++ mysql-test/t/subselect.test | 15 +++++++++++++++ sql/item.h | 5 +++++ sql/sql_select.cc | 7 +++++++ 8 files changed, 107 insertions(+) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index e2f2b6521c8..cdedc02f825 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -7171,4 +7171,20 @@ a 5 SET @@optimizer_switch= @optimiser_switch_save; DROP TABLE t1, t2, t3; +# +# MDEV-16820: impossible where with inexpensive subquery +# +create table t1 (a int) engine=myisam; +insert into t1 values (3), (1), (7); +create table t2 (b int, index idx(b)); +insert into t2 values (2), (5), (3), (2); +explain select * from t1 where (select max(b) from t2) = 10; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +drop table t1,t2; End of 5.5 tests diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result index 25ef4a76962..a7291297e7c 100644 --- a/mysql-test/r/subselect_no_mat.result +++ b/mysql-test/r/subselect_no_mat.result @@ -7168,6 +7168,22 @@ a 5 SET @@optimizer_switch= @optimiser_switch_save; DROP TABLE t1, t2, t3; +# +# MDEV-16820: impossible where with inexpensive subquery +# +create table t1 (a int) engine=myisam; +insert into t1 values (3), (1), (7); +create table t2 (b int, index idx(b)); +insert into t2 values (2), (5), (3), (2); +explain select * from t1 where (select max(b) from t2) = 10; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +drop table t1,t2; End of 5.5 tests set optimizer_switch=default; select @@optimizer_switch like '%materialization=on%'; diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result index 074874fbd5b..c41fa1be47b 100644 --- a/mysql-test/r/subselect_no_opts.result +++ b/mysql-test/r/subselect_no_opts.result @@ -7166,5 +7166,21 @@ a 5 SET @@optimizer_switch= @optimiser_switch_save; DROP TABLE t1, t2, t3; +# +# MDEV-16820: impossible where with inexpensive subquery +# +create table t1 (a int) engine=myisam; +insert into t1 values (3), (1), (7); +create table t2 (b int, index idx(b)); +insert into t2 values (2), (5), (3), (2); +explain select * from t1 where (select max(b) from t2) = 10; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +drop table t1,t2; End of 5.5 tests set @optimizer_switch_for_subselect_test=null; diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result index de49585b562..1c181357050 100644 --- a/mysql-test/r/subselect_no_scache.result +++ b/mysql-test/r/subselect_no_scache.result @@ -7177,6 +7177,22 @@ a 5 SET @@optimizer_switch= @optimiser_switch_save; DROP TABLE t1, t2, t3; +# +# MDEV-16820: impossible where with inexpensive subquery +# +create table t1 (a int) engine=myisam; +insert into t1 values (3), (1), (7); +create table t2 (b int, index idx(b)); +insert into t2 values (2), (5), (3), (2); +explain select * from t1 where (select max(b) from t2) = 10; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +drop table t1,t2; End of 5.5 tests set optimizer_switch=default; select @@optimizer_switch like '%subquery_cache=on%'; diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result index 46a46c91ddc..89c671252ff 100644 --- a/mysql-test/r/subselect_no_semijoin.result +++ b/mysql-test/r/subselect_no_semijoin.result @@ -7166,6 +7166,22 @@ a 5 SET @@optimizer_switch= @optimiser_switch_save; DROP TABLE t1, t2, t3; +# +# MDEV-16820: impossible where with inexpensive subquery +# +create table t1 (a int) engine=myisam; +insert into t1 values (3), (1), (7); +create table t2 (b int, index idx(b)); +insert into t2 values (2), (5), (3), (2); +explain select * from t1 where (select max(b) from t2) = 10; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +drop table t1,t2; End of 5.5 tests set @optimizer_switch_for_subselect_test=null; set @join_cache_level_for_subselect_test=NULL; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index e6233e9de78..4e35032a789 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -6060,4 +6060,19 @@ and t1.a in (select `test`.`t3`.`c` from `test`.`t3`); SET @@optimizer_switch= @optimiser_switch_save; DROP TABLE t1, t2, t3; +--echo # +--echo # MDEV-16820: impossible where with inexpensive subquery +--echo # + +create table t1 (a int) engine=myisam; +insert into t1 values (3), (1), (7); + +create table t2 (b int, index idx(b)); +insert into t2 values (2), (5), (3), (2); + +explain select * from t1 where (select max(b) from t2) = 10; +explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3; + +drop table t1,t2; + --echo End of 5.5 tests diff --git a/sql/item.h b/sql/item.h index d756cf8301b..1bded7377ee 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1234,6 +1234,11 @@ public: { return FALSE; } + bool cleanup_is_expensive_cache_processor(uchar *arg) + { + is_expensive_cache= (int8)(-1); + return 0; + } /* To call bool function for all arguments */ struct bool_func_call_args diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 6a64a0e9952..5228dd4f439 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1098,6 +1098,13 @@ JOIN::optimize() if (optimize_constant_subqueries()) DBUG_RETURN(1); + if (conds && conds->has_subquery()) + (void) conds->walk(&Item::cleanup_is_expensive_cache_processor, + 0, (uchar*)0); + if (having && having->has_subquery()) + (void) having->walk(&Item::cleanup_is_expensive_cache_processor, + 0, (uchar*)0); + if (setup_jtbm_semi_joins(this, join_list, &conds)) DBUG_RETURN(1); -- cgit v1.2.1 From c631060713a2af2890284feb7aea96c0cf4ba49f Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 24 Jul 2018 23:45:55 -0700 Subject: MDEV-16820 Lost 'Impossible where' from query with inexpensive subquery This patch fixes another problem introduced by the patch for mdev-4817. The latter changed Item_cond::fix_fields() in such a way that it could call the virtual method is_expensive(). With the first its call the method saves the result in Item::is_expensive_cache. For all next calls the method returns the result from this cache. So if the item once was determined as expensive the method always returns true. For subqueries it's not good, because non-optimized subqueries always is considered as expensive. It means that the cache should be invalidated after the call of optimize_constant_subqueries(). --- mysql-test/r/subselect.result | 16 ++++++++++++++++ mysql-test/r/subselect_no_exists_to_in.result | 16 ++++++++++++++++ mysql-test/r/subselect_no_mat.result | 16 ++++++++++++++++ mysql-test/r/subselect_no_opts.result | 16 ++++++++++++++++ mysql-test/r/subselect_no_scache.result | 16 ++++++++++++++++ mysql-test/r/subselect_no_semijoin.result | 16 ++++++++++++++++ mysql-test/t/subselect.test | 15 +++++++++++++++ sql/item.h | 5 +++++ sql/sql_select.cc | 7 +++++++ 9 files changed, 123 insertions(+) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 79b2810d529..b074fb371a5 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -7211,4 +7211,20 @@ a 5 SET @@optimizer_switch= @optimiser_switch_save; DROP TABLE t1, t2, t3; +# +# MDEV-16820: impossible where with inexpensive subquery +# +create table t1 (a int) engine=myisam; +insert into t1 values (3), (1), (7); +create table t2 (b int, index idx(b)); +insert into t2 values (2), (5), (3), (2); +explain select * from t1 where (select max(b) from t2) = 10; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +drop table t1,t2; End of 5.5 tests diff --git a/mysql-test/r/subselect_no_exists_to_in.result b/mysql-test/r/subselect_no_exists_to_in.result index 7b2054f4a67..d5aa16a2ce9 100644 --- a/mysql-test/r/subselect_no_exists_to_in.result +++ b/mysql-test/r/subselect_no_exists_to_in.result @@ -7211,6 +7211,22 @@ a 5 SET @@optimizer_switch= @optimiser_switch_save; DROP TABLE t1, t2, t3; +# +# MDEV-16820: impossible where with inexpensive subquery +# +create table t1 (a int) engine=myisam; +insert into t1 values (3), (1), (7); +create table t2 (b int, index idx(b)); +insert into t2 values (2), (5), (3), (2); +explain select * from t1 where (select max(b) from t2) = 10; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +drop table t1,t2; End of 5.5 tests set optimizer_switch=default; select @@optimizer_switch like '%exists_to_in=off%'; diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result index 51c5263ad8a..aff68bd6729 100644 --- a/mysql-test/r/subselect_no_mat.result +++ b/mysql-test/r/subselect_no_mat.result @@ -7204,6 +7204,22 @@ a 5 SET @@optimizer_switch= @optimiser_switch_save; DROP TABLE t1, t2, t3; +# +# MDEV-16820: impossible where with inexpensive subquery +# +create table t1 (a int) engine=myisam; +insert into t1 values (3), (1), (7); +create table t2 (b int, index idx(b)); +insert into t2 values (2), (5), (3), (2); +explain select * from t1 where (select max(b) from t2) = 10; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +drop table t1,t2; End of 5.5 tests set optimizer_switch=default; select @@optimizer_switch like '%materialization=on%'; diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result index 574af7b4d1f..f1181785a5c 100644 --- a/mysql-test/r/subselect_no_opts.result +++ b/mysql-test/r/subselect_no_opts.result @@ -7202,5 +7202,21 @@ a 5 SET @@optimizer_switch= @optimiser_switch_save; DROP TABLE t1, t2, t3; +# +# MDEV-16820: impossible where with inexpensive subquery +# +create table t1 (a int) engine=myisam; +insert into t1 values (3), (1), (7); +create table t2 (b int, index idx(b)); +insert into t2 values (2), (5), (3), (2); +explain select * from t1 where (select max(b) from t2) = 10; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +drop table t1,t2; End of 5.5 tests set @optimizer_switch_for_subselect_test=null; diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result index 03285cf2968..6cefce21c20 100644 --- a/mysql-test/r/subselect_no_scache.result +++ b/mysql-test/r/subselect_no_scache.result @@ -7217,6 +7217,22 @@ a 5 SET @@optimizer_switch= @optimiser_switch_save; DROP TABLE t1, t2, t3; +# +# MDEV-16820: impossible where with inexpensive subquery +# +create table t1 (a int) engine=myisam; +insert into t1 values (3), (1), (7); +create table t2 (b int, index idx(b)); +insert into t2 values (2), (5), (3), (2); +explain select * from t1 where (select max(b) from t2) = 10; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +drop table t1,t2; End of 5.5 tests set optimizer_switch=default; select @@optimizer_switch like '%subquery_cache=on%'; diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result index 6669c27ede7..884374a74b1 100644 --- a/mysql-test/r/subselect_no_semijoin.result +++ b/mysql-test/r/subselect_no_semijoin.result @@ -7202,6 +7202,22 @@ a 5 SET @@optimizer_switch= @optimiser_switch_save; DROP TABLE t1, t2, t3; +# +# MDEV-16820: impossible where with inexpensive subquery +# +create table t1 (a int) engine=myisam; +insert into t1 values (3), (1), (7); +create table t2 (b int, index idx(b)); +insert into t2 values (2), (5), (3), (2); +explain select * from t1 where (select max(b) from t2) = 10; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +drop table t1,t2; End of 5.5 tests set @optimizer_switch_for_subselect_test=null; set @join_cache_level_for_subselect_test=NULL; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 8c9a4893be2..390d36361b2 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -6096,4 +6096,19 @@ and t1.a in (select `test`.`t3`.`c` from `test`.`t3`); SET @@optimizer_switch= @optimiser_switch_save; DROP TABLE t1, t2, t3; +--echo # +--echo # MDEV-16820: impossible where with inexpensive subquery +--echo # + +create table t1 (a int) engine=myisam; +insert into t1 values (3), (1), (7); + +create table t2 (b int, index idx(b)); +insert into t2 values (2), (5), (3), (2); + +explain select * from t1 where (select max(b) from t2) = 10; +explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3; + +drop table t1,t2; + --echo End of 5.5 tests diff --git a/sql/item.h b/sql/item.h index b111d74057c..7c95239b242 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1275,6 +1275,11 @@ public: virtual bool exists2in_processor(uchar *opt_arg) { return 0; } virtual bool find_selective_predicates_list_processor(uchar *opt_arg) { return 0; } + bool cleanup_is_expensive_cache_processor(uchar *arg) + { + is_expensive_cache= (int8)(-1); + return 0; + } /* To call bool function for all arguments */ struct bool_func_call_args diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 43b8d2b8636..19a727f696b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1207,6 +1207,13 @@ TODO: make view to decide if it is possible to write to WHERE directly or make S if (optimize_constant_subqueries()) DBUG_RETURN(1); + if (conds && conds->has_subquery()) + (void) conds->walk(&Item::cleanup_is_expensive_cache_processor, + 0, (uchar*)0); + if (having && having->has_subquery()) + (void) having->walk(&Item::cleanup_is_expensive_cache_processor, + 0, (uchar*)0); + if (setup_jtbm_semi_joins(this, join_list, &conds)) DBUG_RETURN(1); -- cgit v1.2.1 From f9b43c2565284feefe94e4feaa4c02bf25a6f921 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Wed, 25 Jul 2018 14:20:16 +0530 Subject: MDEV-16751: Server crashes in st_join_table::cleanup or TABLE_LIST::is_with_table_recursive_reference with join_cache_level>2 During muliple equality propagation for a query in which we have an IN subquery, the items in the select list of the subquery may not be part of the multiple equality because there might be another occurence of the same field in the where clause of the subquery. So we keyuse_is_valid_for_access_in_chosen_plan function which expects the items in the select list of the subquery to be same to the ones in the multiple equality (through these multiple equalities we create keyuse array). The solution would be that we expect the same field not the same Item because when we have SEMI JOIN MATERIALIZATION SCAN, we use copy back technique to copies back the materialised table fields to the original fields of the base tables. --- mysql-test/r/subselect_mat.result | 35 +++++++++++++++++++++++++++++++++++ mysql-test/r/subselect_sj_mat.result | 35 +++++++++++++++++++++++++++++++++++ mysql-test/t/subselect_sj_mat.test | 25 +++++++++++++++++++++++++ sql/opt_subselect.cc | 3 +++ sql/sql_select.cc | 9 +++++++-- 5 files changed, 105 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result index 00448ac4f91..a56d076d528 100644 --- a/mysql-test/r/subselect_mat.result +++ b/mysql-test/r/subselect_mat.result @@ -2360,6 +2360,41 @@ ec70316637232000158bbfc8bcbe5d60 ebb4620037332000158bbfc8bcbe5d89 DROP TABLE t1,t2,t3; set optimizer_switch=@save_optimizer_switch; +# +# MDEV-16751: Server crashes in st_join_table::cleanup or +# TABLE_LIST::is_with_table_recursive_reference with join_cache_level>2 +# +set @save_join_cache_level= @@join_cache_level; +set join_cache_level=4; +CREATE TABLE t1 ( id int NOT NULL); +INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19); +CREATE TABLE t2 (i1 int NOT NULL, i2 int NOT NULL) ; +INSERT INTO t2 VALUES (11,11),(12,12),(13,13); +explain +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL distinct_key NULL NULL NULL 3 +1 PRIMARY t1 hash_ALL NULL #hash#$hj 4 test.t2.i1 9 Using where; Using join buffer (flat, BNLH join) +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); +1 +1 +1 +1 +set @@join_cache_level= @save_join_cache_level; +alter table t1 add key(id); +explain +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL distinct_key NULL NULL NULL 3 +1 PRIMARY t1 ref id id 4 test.t2.i1 2 Using index +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); +1 +1 +1 +1 +drop table t1,t2; # End of 5.5 tests set @subselect_mat_test_optimizer_switch_value=null; set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off'; diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result index cb5012a91c9..fa62259e3d6 100644 --- a/mysql-test/r/subselect_sj_mat.result +++ b/mysql-test/r/subselect_sj_mat.result @@ -2400,4 +2400,39 @@ ec70316637232000158bbfc8bcbe5d60 ebb4620037332000158bbfc8bcbe5d89 DROP TABLE t1,t2,t3; set optimizer_switch=@save_optimizer_switch; +# +# MDEV-16751: Server crashes in st_join_table::cleanup or +# TABLE_LIST::is_with_table_recursive_reference with join_cache_level>2 +# +set @save_join_cache_level= @@join_cache_level; +set join_cache_level=4; +CREATE TABLE t1 ( id int NOT NULL); +INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19); +CREATE TABLE t2 (i1 int NOT NULL, i2 int NOT NULL) ; +INSERT INTO t2 VALUES (11,11),(12,12),(13,13); +explain +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL distinct_key NULL NULL NULL 3 +1 PRIMARY t1 hash_ALL NULL #hash#$hj 4 test.t2.i1 9 Using where; Using join buffer (flat, BNLH join) +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); +1 +1 +1 +1 +set @@join_cache_level= @save_join_cache_level; +alter table t1 add key(id); +explain +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL distinct_key NULL NULL NULL 3 +1 PRIMARY t1 ref id id 4 test.t2.i1 2 Using index +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); +1 +1 +1 +1 +drop table t1,t2; # End of 5.5 tests diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test index 90f63bea561..f1b64337702 100644 --- a/mysql-test/t/subselect_sj_mat.test +++ b/mysql-test/t/subselect_sj_mat.test @@ -2151,4 +2151,29 @@ eval $q; DROP TABLE t1,t2,t3; set optimizer_switch=@save_optimizer_switch; +--echo # +--echo # MDEV-16751: Server crashes in st_join_table::cleanup or +--echo # TABLE_LIST::is_with_table_recursive_reference with join_cache_level>2 +--echo # + +set @save_join_cache_level= @@join_cache_level; +set join_cache_level=4; +CREATE TABLE t1 ( id int NOT NULL); +INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19); + +CREATE TABLE t2 (i1 int NOT NULL, i2 int NOT NULL) ; +INSERT INTO t2 VALUES (11,11),(12,12),(13,13); + +explain +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); + +set @@join_cache_level= @save_join_cache_level; +alter table t1 add key(id); + +explain +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); + +drop table t1,t2; --echo # End of 5.5 tests diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 14b2aaee591..783e3d4d22f 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -815,6 +815,9 @@ int check_and_do_in_subquery_rewrites(JOIN *join) details) * require that compared columns have exactly the same type. This is a temporary measure to avoid BUG#36752-type problems. + + JOIN_TAB::keyuse_is_valid_for_access_in_chosen_plan expects that for Semi Join Materialization + Scan all the items in the select list of the IN Subquery are of the type Item::FIELD_ITEM. */ static diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5228dd4f439..45a1372988b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7445,8 +7445,13 @@ bool JOIN_TAB::keyuse_is_valid_for_access_in_chosen_plan(JOIN *join, st_select_lex *sjm_sel= emb_sj_nest->sj_subq_pred->unit->first_select(); for (uint i= 0; i < sjm_sel->item_list.elements; i++) { - if (sjm_sel->ref_pointer_array[i] == keyuse->val) - return true; + DBUG_ASSERT(sjm_sel->ref_pointer_array[i]->type() == Item::FIELD_ITEM); + if (keyuse->val->type() == Item::FIELD_ITEM) + { + Field *field = ((Item_field*)sjm_sel->ref_pointer_array[i])->field; + if (field->eq(((Item_field*)keyuse->val)->field)) + return true; + } } return false; } -- cgit v1.2.1 From 37dee22d27c55c14f0be7005c3e5bdbb09e1fc92 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Wed, 25 Jul 2018 21:17:50 +0530 Subject: MDEV-15454: Nested SELECT IN returns wrong results In this case we are setting the field Item_func_eq::in_eqaulity_no for the semi-join equalities. This helps us to remove these equalites as the inner tables are not available during parent select execution while the outer tables are not available during materialization phase. We only have it set for the equalites for the fields involved with the IN subquery and reset it for the equalities which do not belong to the IN subquery. For example in case of nested IN subqueries: SELECT t1.a FROM t1 WHERE t1.a IN (SELECT t2.a FROM t2 where t2.b IN (select t3.b from t3 where t3.c=27 )) there are two equalites involving the fields of the IN subquery 1) t2.b = t3.b : the field Item_func_eq::in_eqaulity_no is set when we merge the grandchild select into the child select 2) t1.a = t2.a : the field Item_func_eq::in_eqaulity_no is set when we merge the child select into the parent select But when we perform case 2) we should ensure that we reset the equalities in the child's WHERE clause. --- mysql-test/r/subselect_mat.result | 41 +++++++++++++++++++++++ mysql-test/r/subselect_sj_mat.result | 41 +++++++++++++++++++++++ mysql-test/t/subselect_sj_mat.test | 45 ++++++++++++++++++++++++++ sql/opt_subselect.cc | 63 ++++++++++++++++++++++++++++++++++++ 4 files changed, 190 insertions(+) diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result index a56d076d528..7f39f1fb788 100644 --- a/mysql-test/r/subselect_mat.result +++ b/mysql-test/r/subselect_mat.result @@ -2395,6 +2395,47 @@ SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); 1 1 drop table t1,t2; +# +# MDEV-15454: Nested SELECT IN returns wrong results +# +CREATE TABLE t1 ( a int NOT NULL PRIMARY KEY); +CREATE TABLE t2 ( a int, b int ); +INSERT INTO t2 VALUES (7878, 96),(3465, 96),(1403, 96),(4189, 96),(8732, 96), (5,96); +CREATE TABLE t3 (c int unsigned NOT NULL, b int unsigned NOT NULL, PRIMARY KEY (c,b)); +INSERT INTO t3 (c, b) VALUES (27, 96); +CREATE PROCEDURE prepare_data() +BEGIN +DECLARE i INT DEFAULT 1; +WHILE i < 1000 DO +INSERT INTO t1 (a) VALUES (i); +INSERT INTO t2 (a,b) VALUES (i,56); +INSERT INTO t3 (c,b) VALUES (i,i); +SET i = i + 1; +END WHILE; +END$$ +CALL prepare_data(); +SELECT t2.a FROM t2 WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.c= 27); +a +7878 +3465 +1403 +4189 +8732 +5 +set @save_optimizer_switch= @@optimizer_switch; +SET optimizer_switch='materialization=off'; +SELECT t1.a FROM t1 +WHERE t1.a IN (SELECT t2.a FROM t2 WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.c= 27)) LIMIT 5; +a +5 +SET optimizer_switch='materialization=on'; +SELECT t1.a FROM t1 +WHERE t1.a IN (SELECT t2.a FROM t2 WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.c= 27)) LIMIT 5; +a +5 +drop procedure prepare_data; +set @@optimizer_switch= @save_optimizer_switch; +drop table t1,t2,t3; # End of 5.5 tests set @subselect_mat_test_optimizer_switch_value=null; set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off'; diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result index fa62259e3d6..44006eadfc6 100644 --- a/mysql-test/r/subselect_sj_mat.result +++ b/mysql-test/r/subselect_sj_mat.result @@ -2435,4 +2435,45 @@ SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); 1 1 drop table t1,t2; +# +# MDEV-15454: Nested SELECT IN returns wrong results +# +CREATE TABLE t1 ( a int NOT NULL PRIMARY KEY); +CREATE TABLE t2 ( a int, b int ); +INSERT INTO t2 VALUES (7878, 96),(3465, 96),(1403, 96),(4189, 96),(8732, 96), (5,96); +CREATE TABLE t3 (c int unsigned NOT NULL, b int unsigned NOT NULL, PRIMARY KEY (c,b)); +INSERT INTO t3 (c, b) VALUES (27, 96); +CREATE PROCEDURE prepare_data() +BEGIN +DECLARE i INT DEFAULT 1; +WHILE i < 1000 DO +INSERT INTO t1 (a) VALUES (i); +INSERT INTO t2 (a,b) VALUES (i,56); +INSERT INTO t3 (c,b) VALUES (i,i); +SET i = i + 1; +END WHILE; +END$$ +CALL prepare_data(); +SELECT t2.a FROM t2 WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.c= 27); +a +7878 +3465 +1403 +4189 +8732 +5 +set @save_optimizer_switch= @@optimizer_switch; +SET optimizer_switch='materialization=off'; +SELECT t1.a FROM t1 +WHERE t1.a IN (SELECT t2.a FROM t2 WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.c= 27)) LIMIT 5; +a +5 +SET optimizer_switch='materialization=on'; +SELECT t1.a FROM t1 +WHERE t1.a IN (SELECT t2.a FROM t2 WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.c= 27)) LIMIT 5; +a +5 +drop procedure prepare_data; +set @@optimizer_switch= @save_optimizer_switch; +drop table t1,t2,t3; # End of 5.5 tests diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test index f1b64337702..794545b53a7 100644 --- a/mysql-test/t/subselect_sj_mat.test +++ b/mysql-test/t/subselect_sj_mat.test @@ -2176,4 +2176,49 @@ SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); drop table t1,t2; + +--echo # +--echo # MDEV-15454: Nested SELECT IN returns wrong results +--echo # + +CREATE TABLE t1 ( a int NOT NULL PRIMARY KEY); + +CREATE TABLE t2 ( a int, b int ); +INSERT INTO t2 VALUES (7878, 96),(3465, 96),(1403, 96),(4189, 96),(8732, 96), (5,96); + +CREATE TABLE t3 (c int unsigned NOT NULL, b int unsigned NOT NULL, PRIMARY KEY (c,b)); +INSERT INTO t3 (c, b) VALUES (27, 96); + +DELIMITER $$; +CREATE PROCEDURE prepare_data() +BEGIN + DECLARE i INT DEFAULT 1; + WHILE i < 1000 DO + INSERT INTO t1 (a) VALUES (i); + INSERT INTO t2 (a,b) VALUES (i,56); + INSERT INTO t3 (c,b) VALUES (i,i); + SET i = i + 1; + END WHILE; +END$$ +DELIMITER ;$$ + +CALL prepare_data(); + +SELECT t2.a FROM t2 WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.c= 27); + +set @save_optimizer_switch= @@optimizer_switch; +SET optimizer_switch='materialization=off'; + +SELECT t1.a FROM t1 +WHERE t1.a IN (SELECT t2.a FROM t2 WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.c= 27)) LIMIT 5; + +SET optimizer_switch='materialization=on'; + +SELECT t1.a FROM t1 +WHERE t1.a IN (SELECT t2.a FROM t2 WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.c= 27)) LIMIT 5; + +drop procedure prepare_data; +set @@optimizer_switch= @save_optimizer_switch; +drop table t1,t2,t3; + --echo # End of 5.5 tests diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 783e3d4d22f..f472cf16710 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -440,6 +440,7 @@ bool subquery_types_allow_materialization(Item_in_subselect *in_subs); static bool replace_where_subcondition(JOIN *, Item **, Item *, Item *, bool); static int subq_sj_candidate_cmp(Item_in_subselect* el1, Item_in_subselect* el2, void *arg); +static void reset_equality_number_for_subq_conds(Item * cond); static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred); static bool convert_subq_to_jtbm(JOIN *parent_join, Item_in_subselect *subq_pred, bool *remove); @@ -1456,6 +1457,67 @@ static int subq_sj_candidate_cmp(Item_in_subselect* el1, Item_in_subselect* el2, } +/** + @brief + reset the value of the field in_eqaulity_no for all Item_func_eq + items in the where clause of the subquery. + + Look for in_equality_no description in Item_func_eq class + + DESCRIPTION + Lets have an example: + SELECT t1.a FROM t1 WHERE t1.a IN + (SELECT t2.a FROM t2 where t2.b IN + (select t3.b from t3 where t3.c=27 )) + + So for such a query we have the parent, child and + grandchild select. + + So for the equality t2.b = t3.b we set the value for in_equality_no to + 0 according to its description. Wewe do the same for t1.a = t2.a. + But when we look at the child select (with the grandchild select merged), + the query would be + + SELECT t1.a FROM t1 WHERE t1.a IN + (SELECT t2.a FROM t2 where t2.b = t3.b and t3.c=27) + + and then when the child select is merged into the parent select the query + would look like + + SELECT t1.a FROM t1, semi-join-nest(t2,t3) + WHERE t1.a =t2.a and t2.b = t3.b and t3.c=27 + + Still we would have in_equality_no set for t2.b = t3.b + though it does not take part in the semi-join equality for the parent select, + so we should reset its value to UINT_MAX. + + @param cond WHERE clause of the subquery +*/ + +static void reset_equality_number_for_subq_conds(Item * cond) +{ + if (!cond) + return; + if (cond->type() == Item::COND_ITEM) + { + List_iterator li(*((Item_cond*) cond)->argument_list()); + Item *item; + while ((item=li++)) + { + if (item->type() == Item::FUNC_ITEM && + ((Item_func*)item)->functype()== Item_func::EQ_FUNC) + ((Item_func_eq*)item)->in_equality_no= UINT_MAX; + } + } + else + { + if (cond->type() == Item::FUNC_ITEM && + ((Item_func*)cond)->functype()== Item_func::EQ_FUNC) + ((Item_func_eq*)cond)->in_equality_no= UINT_MAX; + } + return; +} + /* Convert a subquery predicate into a TABLE_LIST semi-join nest @@ -1713,6 +1775,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred) */ sj_nest->sj_in_exprs= subq_pred->left_expr->cols(); sj_nest->nested_join->sj_outer_expr_list.empty(); + reset_equality_number_for_subq_conds(sj_nest->sj_on_expr); if (subq_pred->left_expr->cols() == 1) { -- cgit v1.2.1 From bd0b368119b48ffbb1e5ab3cd2887270c5c6840e Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Fri, 27 Jul 2018 11:34:34 +0530 Subject: Fix added along with a test for a case missed in the patch for MDEV-16751 --- mysql-test/r/subselect_mat.result | 17 +++++++++++++++++ mysql-test/r/subselect_sj_mat.result | 17 +++++++++++++++++ mysql-test/t/subselect_sj_mat.test | 9 +++++++++ sql/sql_select.cc | 8 ++++---- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result index 7f39f1fb788..eca3b760b65 100644 --- a/mysql-test/r/subselect_mat.result +++ b/mysql-test/r/subselect_mat.result @@ -2436,6 +2436,23 @@ a drop procedure prepare_data; set @@optimizer_switch= @save_optimizer_switch; drop table t1,t2,t3; +CREATE TABLE t1 ( id int NOT NULL, key(id)); +INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19); +CREATE TABLE t2 (i1 int NOT NULL, i2 int NOT NULL); +INSERT INTO t2 VALUES (11,11),(12,12),(13,13); +CREATE VIEW v1 AS SELECT t2.i1 FROM t2 where t2.i1 = t2.i2; +explain SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL distinct_key NULL NULL NULL 3 +1 PRIMARY t1 ref id id 4 test.t2.i1 2 Using index +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); +1 +1 +1 +1 +drop table t1,t2; +drop view v1; # End of 5.5 tests set @subselect_mat_test_optimizer_switch_value=null; set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off'; diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result index 44006eadfc6..180c182a51a 100644 --- a/mysql-test/r/subselect_sj_mat.result +++ b/mysql-test/r/subselect_sj_mat.result @@ -2476,4 +2476,21 @@ a drop procedure prepare_data; set @@optimizer_switch= @save_optimizer_switch; drop table t1,t2,t3; +CREATE TABLE t1 ( id int NOT NULL, key(id)); +INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19); +CREATE TABLE t2 (i1 int NOT NULL, i2 int NOT NULL); +INSERT INTO t2 VALUES (11,11),(12,12),(13,13); +CREATE VIEW v1 AS SELECT t2.i1 FROM t2 where t2.i1 = t2.i2; +explain SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL distinct_key NULL NULL NULL 3 +1 PRIMARY t1 ref id id 4 test.t2.i1 2 Using index +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); +1 +1 +1 +1 +drop table t1,t2; +drop view v1; # End of 5.5 tests diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test index 794545b53a7..c82c1e7acec 100644 --- a/mysql-test/t/subselect_sj_mat.test +++ b/mysql-test/t/subselect_sj_mat.test @@ -2221,4 +2221,13 @@ drop procedure prepare_data; set @@optimizer_switch= @save_optimizer_switch; drop table t1,t2,t3; +CREATE TABLE t1 ( id int NOT NULL, key(id)); +INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19); +CREATE TABLE t2 (i1 int NOT NULL, i2 int NOT NULL); +INSERT INTO t2 VALUES (11,11),(12,12),(13,13); +CREATE VIEW v1 AS SELECT t2.i1 FROM t2 where t2.i1 = t2.i2; +explain SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); +SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); +drop table t1,t2; +drop view v1; --echo # End of 5.5 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 45a1372988b..b2b2bcde80c 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7445,11 +7445,11 @@ bool JOIN_TAB::keyuse_is_valid_for_access_in_chosen_plan(JOIN *join, st_select_lex *sjm_sel= emb_sj_nest->sj_subq_pred->unit->first_select(); for (uint i= 0; i < sjm_sel->item_list.elements; i++) { - DBUG_ASSERT(sjm_sel->ref_pointer_array[i]->type() == Item::FIELD_ITEM); - if (keyuse->val->type() == Item::FIELD_ITEM) + DBUG_ASSERT(sjm_sel->ref_pointer_array[i]->real_item()->type() == Item::FIELD_ITEM); + if (keyuse->val->real_item()->type() == Item::FIELD_ITEM) { - Field *field = ((Item_field*)sjm_sel->ref_pointer_array[i])->field; - if (field->eq(((Item_field*)keyuse->val)->field)) + Field *field = ((Item_field*)sjm_sel->ref_pointer_array[i]->real_item())->field; + if (field->eq(((Item_field*)keyuse->val->real_item())->field)) return true; } } -- cgit v1.2.1 From 340963351c5fb9dbeb03d6c887b18d328073ed79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 30 Jul 2018 10:39:42 +0300 Subject: Use a more precise argument for memset() --- storage/innobase/buf/buf0buddy.cc | 2 +- storage/xtradb/buf/buf0buddy.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/buf/buf0buddy.cc b/storage/innobase/buf/buf0buddy.cc index 7a441b4239a..c8c39e0caaf 100644 --- a/storage/innobase/buf/buf0buddy.cc +++ b/storage/innobase/buf/buf0buddy.cc @@ -132,7 +132,7 @@ buf_buddy_stamp_free( buf_buddy_free_t* buf, /*!< in/out: block to stamp */ ulint i) /*!< in: block size */ { - ut_d(memset(buf, static_cast(i), BUF_BUDDY_LOW << i)); + ut_d(memset(&buf->stamp.bytes, int(i), BUF_BUDDY_LOW << i)); buf_buddy_mem_invalid(buf, i); mach_write_to_4(buf->stamp.bytes + BUF_BUDDY_STAMP_OFFSET, BUF_BUDDY_STAMP_FREE); diff --git a/storage/xtradb/buf/buf0buddy.cc b/storage/xtradb/buf/buf0buddy.cc index 1c50e71e687..ee687efc9ec 100644 --- a/storage/xtradb/buf/buf0buddy.cc +++ b/storage/xtradb/buf/buf0buddy.cc @@ -132,7 +132,7 @@ buf_buddy_stamp_free( buf_buddy_free_t* buf, /*!< in/out: block to stamp */ ulint i) /*!< in: block size */ { - ut_d(memset(buf, static_cast(i), BUF_BUDDY_LOW << i)); + ut_d(memset(&buf->stamp.bytes, int(i), BUF_BUDDY_LOW << i)); buf_buddy_mem_invalid(buf, i); mach_write_to_4(buf->stamp.bytes + BUF_BUDDY_STAMP_OFFSET, BUF_BUDDY_STAMP_FREE); -- cgit v1.2.1 From 8bdd125067851a201348ae24cac7f9097d494d53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 30 Jul 2018 13:13:43 +0300 Subject: MDEV-16851 On schema mismatch in IMPORT TABLESPACE, display ROW_FORMAT in clear text This is motivated by Oracle MySQL Bug #27542720 SCHEMA MISMATCH - TABLE FLAGS DON'T MATCH, BUT FLAGS ARE NUMBERS but using a different approach. row_import::match_schema(): In case of a mismatch, display the ROW_FORMAT and optionally KEY_BLOCK_SIZE of the .cfg file. --- mysql-test/suite/innodb/r/innodb-wl5522.result | 263 ++++++++++++++++++++++++- mysql-test/suite/innodb/t/innodb-wl5522.test | 258 +++++++++++++++++++++++- storage/innobase/row/row0import.cc | 59 +++++- storage/xtradb/row/row0import.cc | 52 ++++- 4 files changed, 608 insertions(+), 24 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb-wl5522.result b/mysql-test/suite/innodb/r/innodb-wl5522.result index 2116dfbf3fa..fb80580f797 100644 --- a/mysql-test/suite/innodb/r/innodb-wl5522.result +++ b/mysql-test/suite/innodb/r/innodb-wl5522.result @@ -1,4 +1,3 @@ -DROP TABLE IF EXISTS t1; SET GLOBAL innodb_file_per_table = 1; SELECT @@innodb_file_per_table; @@innodb_file_per_table @@ -580,7 +579,7 @@ SELECT * FROM t1; ERROR HY000: Tablespace has been discarded for table 't1' restore: t1 .ibd and .cfg files ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x1 and the meta-data file has 0x0) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x1 and the meta-data file has 0x0; .cfg file uses ROW_FORMAT=REDUNDANT) unlink: t1.ibd unlink: t1.cfg DROP TABLE t1; @@ -592,7 +591,19 @@ SELECT * FROM t1; ERROR HY000: Tablespace has been discarded for table 't1' restore: t1 .ibd and .cfg files ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x21 and the meta-data file has 0x0) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x21 and the meta-data file has 0x0; .cfg file uses ROW_FORMAT=REDUNDANT) +unlink: t1.ibd +unlink: t1.cfg +DROP TABLE t1; +CREATE TABLE t1( +c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +ALTER TABLE t1 DISCARD TABLESPACE; +SELECT * FROM t1; +ERROR HY000: Tablespace has been discarded for table 't1' +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x29 and the meta-data file has 0x0; .cfg file uses ROW_FORMAT=REDUNDANT) unlink: t1.ibd unlink: t1.cfg DROP TABLE t1; @@ -766,7 +777,7 @@ SELECT * FROM t1; ERROR HY000: Tablespace has been discarded for table 't1' restore: t1 .ibd and .cfg files ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x0 and the meta-data file has 0x1) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x0 and the meta-data file has 0x1; .cfg file uses ROW_FORMAT=COMPACT) unlink: t1.ibd unlink: t1.cfg DROP TABLE t1; @@ -778,7 +789,19 @@ SELECT * FROM t1; ERROR HY000: Tablespace has been discarded for table 't1' restore: t1 .ibd and .cfg files ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x21 and the meta-data file has 0x1) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x21 and the meta-data file has 0x1; .cfg file uses ROW_FORMAT=COMPACT) +unlink: t1.ibd +unlink: t1.cfg +DROP TABLE t1; +CREATE TABLE t1( +c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +ALTER TABLE t1 DISCARD TABLESPACE; +SELECT * FROM t1; +ERROR HY000: Tablespace has been discarded for table 't1' +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x29 and the meta-data file has 0x1; .cfg file uses ROW_FORMAT=COMPACT) unlink: t1.ibd unlink: t1.cfg DROP TABLE t1; @@ -955,7 +978,7 @@ SELECT * FROM t1; ERROR HY000: Tablespace has been discarded for table 't1' restore: t1 .ibd and .cfg files ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x1 and the meta-data file has 0x21) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x1 and the meta-data file has 0x21; .cfg file uses ROW_FORMAT=DYNAMIC) unlink: t1.ibd unlink: t1.cfg DROP TABLE t1; @@ -967,7 +990,19 @@ SELECT * FROM t1; ERROR HY000: Tablespace has been discarded for table 't1' restore: t1 .ibd and .cfg files ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x0 and the meta-data file has 0x21) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x0 and the meta-data file has 0x21; .cfg file uses ROW_FORMAT=DYNAMIC) +unlink: t1.ibd +unlink: t1.cfg +DROP TABLE t1; +CREATE TABLE t1( +c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +ALTER TABLE t1 DISCARD TABLESPACE; +SELECT * FROM t1; +ERROR HY000: Tablespace has been discarded for table 't1' +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x29 and the meta-data file has 0x21; .cfg file uses ROW_FORMAT=DYNAMIC) unlink: t1.ibd unlink: t1.cfg DROP TABLE t1; @@ -1026,6 +1061,220 @@ c1 c2 42 1 43 1 DROP TABLE t1; +CREATE TABLE t1( +c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +INSERT INTO t1(c2) VALUES(1); +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` int(11) DEFAULT NULL, + PRIMARY KEY (`c1`), + KEY `idx` (`c2`) +) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED +SELECT * FROM t1; +c1 c2 +1 1 +2 1 +3 1 +4 1 +6 1 +7 1 +8 1 +9 1 +13 1 +14 1 +15 1 +16 1 +17 1 +18 1 +19 1 +20 1 +28 1 +29 1 +30 1 +31 1 +32 1 +33 1 +34 1 +35 1 +36 1 +37 1 +38 1 +39 1 +40 1 +41 1 +42 1 +43 1 +FLUSH TABLES t1 FOR EXPORT; +backup: t1 +UNLOCK TABLES; +DROP TABLE t1; +CREATE TABLE t1( +c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +ALTER TABLE t1 DISCARD TABLESPACE; +SELECT * FROM t1; +ERROR HY000: Tablespace has been discarded for table 't1' +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +unlink: t1.cfg +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` int(11) DEFAULT NULL, + PRIMARY KEY (`c1`), + KEY `idx` (`c2`) +) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED +SELECT * FROM t1; +c1 c2 +1 1 +2 1 +3 1 +4 1 +6 1 +7 1 +8 1 +9 1 +13 1 +14 1 +15 1 +16 1 +17 1 +18 1 +19 1 +20 1 +28 1 +29 1 +30 1 +31 1 +32 1 +33 1 +34 1 +35 1 +36 1 +37 1 +38 1 +39 1 +40 1 +41 1 +42 1 +43 1 +DROP TABLE t1; +CREATE TABLE t1( +c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; +ALTER TABLE t1 DISCARD TABLESPACE; +SELECT * FROM t1; +ERROR HY000: Tablespace has been discarded for table 't1' +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x0 and the meta-data file has 0x29; .cfg file uses ROW_FORMAT=COMPRESSED) +unlink: t1.ibd +unlink: t1.cfg +DROP TABLE t1; +CREATE TABLE t1( +c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPACT; +ALTER TABLE t1 DISCARD TABLESPACE; +SELECT * FROM t1; +ERROR HY000: Tablespace has been discarded for table 't1' +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x1 and the meta-data file has 0x29; .cfg file uses ROW_FORMAT=COMPRESSED) +unlink: t1.ibd +unlink: t1.cfg +DROP TABLE t1; +CREATE TABLE t1( +c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +ALTER TABLE t1 DISCARD TABLESPACE; +SELECT * FROM t1; +ERROR HY000: Tablespace has been discarded for table 't1' +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x21 and the meta-data file has 0x29; .cfg file uses ROW_FORMAT=COMPRESSED) +unlink: t1.ibd +unlink: t1.cfg +DROP TABLE t1; +CREATE TABLE t1( +c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c2 INT, INDEX idx(c2)) ENGINE=InnoDB +ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +ALTER TABLE t1 DISCARD TABLESPACE; +SELECT * FROM t1; +ERROR HY000: Tablespace has been discarded for table 't1' +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x23 and the meta-data file has 0x29; .cfg file uses ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8) +unlink: t1.ibd +unlink: t1.cfg +DROP TABLE t1; +CREATE TABLE t1( +c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +ALTER TABLE t1 DISCARD TABLESPACE; +SELECT * FROM t1; +ERROR HY000: Tablespace has been discarded for table 't1' +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +unlink: t1.cfg +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` int(11) DEFAULT NULL, + PRIMARY KEY (`c1`), + KEY `idx` (`c2`) +) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED +SELECT * FROM t1; +c1 c2 +1 1 +2 1 +3 1 +4 1 +6 1 +7 1 +8 1 +9 1 +13 1 +14 1 +15 1 +16 1 +17 1 +18 1 +19 1 +20 1 +28 1 +29 1 +30 1 +31 1 +32 1 +33 1 +34 1 +35 1 +36 1 +37 1 +38 1 +39 1 +40 1 +41 1 +42 1 +43 1 +DROP TABLE t1; call mtr.add_suppression("Got error -1 when reading table '.*'"); call mtr.add_suppression("InnoDB: Error: tablespace id and flags in file '.*'.*"); call mtr.add_suppression("InnoDB: The table .* doesn't have a corresponding tablespace, it was discarded"); diff --git a/mysql-test/suite/innodb/t/innodb-wl5522.test b/mysql-test/suite/innodb/t/innodb-wl5522.test index c9e7748cb47..d50032c3be7 100644 --- a/mysql-test/suite/innodb/t/innodb-wl5522.test +++ b/mysql-test/suite/innodb/t/innodb-wl5522.test @@ -3,10 +3,6 @@ -- source include/have_innodb.inc ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings - let $innodb_file_per_table = `SELECT @@innodb_file_per_table`; let $innodb_file_format = `SELECT @@innodb_file_format`; @@ -481,7 +477,7 @@ SELECT * FROM t1; DROP TABLE t1; # -# Row format tests [EXPORT REDUNDANT - IMPORT COMPACT & DYNAMIC] +# EXPORT ROW_FORMAT=REDUNDANT # CREATE TABLE t1( c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, @@ -583,6 +579,29 @@ EOF DROP TABLE t1; +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +--error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t1 IMPORT TABLESPACE; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_unlink_tablespace("test", "t1"); +EOF + +DROP TABLE t1; + # This should be OK. CREATE TABLE t1( c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, @@ -611,7 +630,7 @@ SELECT * FROM t1; DROP TABLE t1; # -# Row format tests [EXPORT COMPACT - IMPORT REDUNDANT & DYNAMIC] +# EXPORT ROW_FORMAT=COMPACT # CREATE TABLE t1( c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, @@ -713,6 +732,29 @@ EOF DROP TABLE t1; +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +--error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t1 IMPORT TABLESPACE; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_unlink_tablespace("test", "t1"); +EOF + +DROP TABLE t1; + # This should be OK. CREATE TABLE t1( c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, @@ -742,7 +784,7 @@ SELECT * FROM t1; DROP TABLE t1; # -# Row format tests [EXPORT DYNAMIC- IMPORT REDUNDANT & DYNAMIC] +# EXPORT ROW_FORMAT=DYNAMIC # CREATE TABLE t1( c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, @@ -844,6 +886,29 @@ EOF DROP TABLE t1; +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +--error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t1 IMPORT TABLESPACE; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_unlink_tablespace("test", "t1"); +EOF + +DROP TABLE t1; + # This should be OK. CREATE TABLE t1( c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, @@ -872,6 +937,185 @@ SELECT * FROM t1; DROP TABLE t1; +# +# EXPORT ROW_FORMAT=COMPRESSED +# +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; + +INSERT INTO t1(c2) VALUES(1); +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; + +SHOW CREATE TABLE t1; +SELECT * FROM t1; + +FLUSH TABLES t1 FOR EXPORT; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_backup_tablespaces("test", "t1"); +EOF + +UNLOCK TABLES; + +DROP TABLE t1; + +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; + +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +ALTER TABLE t1 IMPORT TABLESPACE; +CHECK TABLE t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_cleanup("test", "t1"); +EOF + +SHOW CREATE TABLE t1; +SELECT * FROM t1; + +DROP TABLE t1; + +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; + +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +--error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t1 IMPORT TABLESPACE; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_unlink_tablespace("test", "t1"); +EOF + +DROP TABLE t1; + +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPACT; + +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +--error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t1 IMPORT TABLESPACE; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_unlink_tablespace("test", "t1"); +EOF + +DROP TABLE t1; + +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +--error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t1 IMPORT TABLESPACE; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_unlink_tablespace("test", "t1"); +EOF + +DROP TABLE t1; + + +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB + ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +--error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t1 IMPORT TABLESPACE; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_unlink_tablespace("test", "t1"); +EOF + +DROP TABLE t1; + +# This should be OK. +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; + +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +ALTER TABLE t1 IMPORT TABLESPACE; +CHECK TABLE t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_cleanup("test", "t1"); +EOF + +SHOW CREATE TABLE t1; +SELECT * FROM t1; + +DROP TABLE t1; + call mtr.add_suppression("Got error -1 when reading table '.*'"); call mtr.add_suppression("InnoDB: Error: tablespace id and flags in file '.*'.*"); call mtr.add_suppression("InnoDB: The table .* doesn't have a corresponding tablespace, it was discarded"); diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index f93d004d8f9..127f1df8df5 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2012, 2018, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2015, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -1333,17 +1333,63 @@ row_import::match_schema( { /* Do some simple checks. */ - if ((m_table->flags ^ m_flags) & ~DICT_TF_MASK_DATA_DIR) { + if (ulint mismatch = (m_table->flags ^ m_flags) + & ~DICT_TF_MASK_DATA_DIR) { + const char* msg; + if (mismatch & DICT_TF_MASK_ZIP_SSIZE) { + if ((m_table->flags & DICT_TF_MASK_ZIP_SSIZE) + && (m_flags & DICT_TF_MASK_ZIP_SSIZE)) { + switch (m_flags & DICT_TF_MASK_ZIP_SSIZE) { + case 0U << DICT_TF_POS_ZIP_SSIZE: + goto uncompressed; + case 1U << DICT_TF_POS_ZIP_SSIZE: + msg = "ROW_FORMAT=COMPRESSED" + " KEY_BLOCK_SIZE=1"; + break; + case 2U << DICT_TF_POS_ZIP_SSIZE: + msg = "ROW_FORMAT=COMPRESSED" + " KEY_BLOCK_SIZE=2"; + break; + case 3U << DICT_TF_POS_ZIP_SSIZE: + msg = "ROW_FORMAT=COMPRESSED" + " KEY_BLOCK_SIZE=4"; + break; + case 4U << DICT_TF_POS_ZIP_SSIZE: + msg = "ROW_FORMAT=COMPRESSED" + " KEY_BLOCK_SIZE=8"; + break; + case 5U << DICT_TF_POS_ZIP_SSIZE: + msg = "ROW_FORMAT=COMPRESSED" + " KEY_BLOCK_SIZE=16"; + break; + default: + msg = "strange KEY_BLOCK_SIZE"; + } + } else if (m_flags & DICT_TF_MASK_ZIP_SSIZE) { + msg = "ROW_FORMAT=COMPRESSED"; + } else { + goto uncompressed; + } + } else { +uncompressed: + msg = (m_flags & DICT_TF_MASK_ATOMIC_BLOBS) + ? "ROW_FORMAT=DYNAMIC" + : (m_flags & DICT_TF_MASK_COMPACT) + ? "ROW_FORMAT=COMPACT" + : "ROW_FORMAT=REDUNDANT"; + } + ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, "Table flags don't match, server table has 0x%x" - " and the meta-data file has 0x%lx", - m_table->flags, ulong(m_flags)); + " and the meta-data file has 0x%lx;" + " .cfg file uses %s", + m_table->flags, ulong(m_flags), msg); return(DB_ERROR); } else if (m_table->n_cols != m_n_cols) { ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, - "Number of columns don't match, table has %u" - " columns but the tablespace meta-data file has " + "Number of columns don't match, table has %u " + "columns but the tablespace meta-data file has " ULINTPF " columns", m_table->n_cols, m_n_cols); @@ -1822,7 +1868,6 @@ PageConverter::update_records( while (!m_rec_iter.end()) { rec_t* rec = m_rec_iter.current(); - ibool deleted = rec_get_deleted_flag(rec, comp); /* For the clustered index we have to adjust the BLOB diff --git a/storage/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc index 39e450bd7c5..127f1df8df5 100644 --- a/storage/xtradb/row/row0import.cc +++ b/storage/xtradb/row/row0import.cc @@ -1333,11 +1333,57 @@ row_import::match_schema( { /* Do some simple checks. */ - if ((m_table->flags ^ m_flags) & ~DICT_TF_MASK_DATA_DIR) { + if (ulint mismatch = (m_table->flags ^ m_flags) + & ~DICT_TF_MASK_DATA_DIR) { + const char* msg; + if (mismatch & DICT_TF_MASK_ZIP_SSIZE) { + if ((m_table->flags & DICT_TF_MASK_ZIP_SSIZE) + && (m_flags & DICT_TF_MASK_ZIP_SSIZE)) { + switch (m_flags & DICT_TF_MASK_ZIP_SSIZE) { + case 0U << DICT_TF_POS_ZIP_SSIZE: + goto uncompressed; + case 1U << DICT_TF_POS_ZIP_SSIZE: + msg = "ROW_FORMAT=COMPRESSED" + " KEY_BLOCK_SIZE=1"; + break; + case 2U << DICT_TF_POS_ZIP_SSIZE: + msg = "ROW_FORMAT=COMPRESSED" + " KEY_BLOCK_SIZE=2"; + break; + case 3U << DICT_TF_POS_ZIP_SSIZE: + msg = "ROW_FORMAT=COMPRESSED" + " KEY_BLOCK_SIZE=4"; + break; + case 4U << DICT_TF_POS_ZIP_SSIZE: + msg = "ROW_FORMAT=COMPRESSED" + " KEY_BLOCK_SIZE=8"; + break; + case 5U << DICT_TF_POS_ZIP_SSIZE: + msg = "ROW_FORMAT=COMPRESSED" + " KEY_BLOCK_SIZE=16"; + break; + default: + msg = "strange KEY_BLOCK_SIZE"; + } + } else if (m_flags & DICT_TF_MASK_ZIP_SSIZE) { + msg = "ROW_FORMAT=COMPRESSED"; + } else { + goto uncompressed; + } + } else { +uncompressed: + msg = (m_flags & DICT_TF_MASK_ATOMIC_BLOBS) + ? "ROW_FORMAT=DYNAMIC" + : (m_flags & DICT_TF_MASK_COMPACT) + ? "ROW_FORMAT=COMPACT" + : "ROW_FORMAT=REDUNDANT"; + } + ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, "Table flags don't match, server table has 0x%x" - " and the meta-data file has 0x%lx", - m_table->flags, ulong(m_flags)); + " and the meta-data file has 0x%lx;" + " .cfg file uses %s", + m_table->flags, ulong(m_flags), msg); return(DB_ERROR); } else if (m_table->n_cols != m_n_cols) { -- cgit v1.2.1 From d17e9a02c4a08da9ac1b8f4c653f29f067d75a22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 30 Jul 2018 14:05:24 +0300 Subject: Fix InnoDB/XtraDB warnings by GCC 8.2.0 --- storage/innobase/buf/buf0dump.cc | 2 +- storage/innobase/handler/i_s.cc | 19 ++++++++----------- storage/innobase/row/row0import.cc | 26 ++++++++++++-------------- storage/innobase/trx/trx0trx.cc | 4 ++-- storage/innobase/trx/trx0undo.cc | 3 +-- storage/xtradb/buf/buf0dump.cc | 2 +- storage/xtradb/handler/i_s.cc | 19 ++++++++----------- storage/xtradb/row/row0import.cc | 26 ++++++++++++-------------- storage/xtradb/trx/trx0trx.cc | 4 ++-- storage/xtradb/trx/trx0undo.cc | 3 +-- 10 files changed, 48 insertions(+), 60 deletions(-) diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc index b2b8733c8ce..9642fc86018 100644 --- a/storage/innobase/buf/buf0dump.cc +++ b/storage/innobase/buf/buf0dump.cc @@ -203,7 +203,7 @@ buf_dump( #define SHOULD_QUIT() (SHUTTING_DOWN() && obey_shutdown) char full_filename[OS_FILE_MAX_PATH]; - char tmp_filename[OS_FILE_MAX_PATH]; + char tmp_filename[OS_FILE_MAX_PATH + sizeof "incomplete"]; char now[32]; FILE* f; ulint i; diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index f8aa3bd4637..de164e42273 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -1452,19 +1452,16 @@ i_s_cmp_fill_low( clear it. We could introduce mutex protection, but it could cause a measureable performance hit in page0zip.cc. */ - table->field[1]->store( - static_cast(zip_stat->compressed)); - table->field[2]->store( - static_cast(zip_stat->compressed_ok)); - table->field[3]->store( - static_cast(zip_stat->compressed_usec / 1000000)); - table->field[4]->store( - static_cast(zip_stat->decompressed)); - table->field[5]->store( - static_cast(zip_stat->decompressed_usec / 1000000)); + table->field[1]->store(zip_stat->compressed, true); + table->field[2]->store(zip_stat->compressed_ok, true); + table->field[3]->store(zip_stat->compressed_usec / 1000000, + true); + table->field[4]->store(zip_stat->decompressed, true); + table->field[5]->store(zip_stat->decompressed_usec / 1000000, + true); if (reset) { - memset(zip_stat, 0, sizeof *zip_stat); + new (zip_stat) page_zip_stat_t(); } if (schema_table_store_record(thd, table)) { diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 127f1df8df5..dad55205bc2 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -105,18 +105,18 @@ struct row_index_t { struct row_import { row_import() UNIV_NOTHROW : - m_table(), - m_version(), - m_hostname(), - m_table_name(), - m_autoinc(), - m_page_size(), - m_flags(), - m_n_cols(), - m_cols(), - m_col_names(), - m_n_indexes(), - m_indexes(), + m_table(NULL), + m_version(0), + m_hostname(NULL), + m_table_name(NULL), + m_autoinc(0), + m_page_size(0), + m_flags(0), + m_n_cols(0), + m_cols(NULL), + m_col_names(NULL), + m_n_indexes(0), + m_indexes(NULL), m_missing(true) { } ~row_import() UNIV_NOTHROW; @@ -3558,8 +3558,6 @@ row_import_for_mysql( row_import cfg; - memset(&cfg, 0x0, sizeof(cfg)); - err = row_import_read_cfg(table, trx->mysql_thd, cfg); /* Check if the table column definitions match the contents diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 4a332d22cbc..2401783648a 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -2145,6 +2145,7 @@ trx_get_trx_by_xid_low( if (trx->is_recovered && trx_state_eq(trx, TRX_STATE_PREPARED) + && !trx->xid.is_null() && xid->gtrid_length == trx->xid.gtrid_length && xid->bqual_length == trx->xid.bqual_length && memcmp(xid->data, trx->xid.data, @@ -2152,8 +2153,7 @@ trx_get_trx_by_xid_low( /* Invalidate the XID, so that subsequent calls will not find it. */ - memset(&trx->xid, 0, sizeof(trx->xid)); - trx->xid.formatID = -1; + trx->xid.null(); break; } } diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc index 370b3f181a1..b137c461ec3 100644 --- a/storage/innobase/trx/trx0undo.cc +++ b/storage/innobase/trx/trx0undo.cc @@ -1314,8 +1314,7 @@ trx_undo_mem_create_at_db_start( /* Read X/Open XA transaction identification if it exists, or set it to NULL. */ - memset(&xid, 0, sizeof(xid)); - xid.formatID = -1; + xid.null(); if (xid_exists == TRUE) { trx_undo_read_xid(undo_header, &xid); diff --git a/storage/xtradb/buf/buf0dump.cc b/storage/xtradb/buf/buf0dump.cc index 51c41cc1b78..d5f07250f05 100644 --- a/storage/xtradb/buf/buf0dump.cc +++ b/storage/xtradb/buf/buf0dump.cc @@ -203,7 +203,7 @@ buf_dump( #define SHOULD_QUIT() (SHUTTING_DOWN() && obey_shutdown) char full_filename[OS_FILE_MAX_PATH]; - char tmp_filename[OS_FILE_MAX_PATH]; + char tmp_filename[OS_FILE_MAX_PATH + sizeof "incomplete"]; char now[32]; FILE* f; ulint i; diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc index 834bae399fb..b864830657e 100644 --- a/storage/xtradb/handler/i_s.cc +++ b/storage/xtradb/handler/i_s.cc @@ -1458,19 +1458,16 @@ i_s_cmp_fill_low( clear it. We could introduce mutex protection, but it could cause a measureable performance hit in page0zip.cc. */ - table->field[1]->store( - static_cast(zip_stat->compressed)); - table->field[2]->store( - static_cast(zip_stat->compressed_ok)); - table->field[3]->store( - static_cast(zip_stat->compressed_usec / 1000000)); - table->field[4]->store( - static_cast(zip_stat->decompressed)); - table->field[5]->store( - static_cast(zip_stat->decompressed_usec / 1000000)); + table->field[1]->store(zip_stat->compressed, true); + table->field[2]->store(zip_stat->compressed_ok, true); + table->field[3]->store(zip_stat->compressed_usec / 1000000, + true); + table->field[4]->store(zip_stat->decompressed, true); + table->field[5]->store(zip_stat->decompressed_usec / 1000000, + true); if (reset) { - memset(zip_stat, 0, sizeof *zip_stat); + new (zip_stat) page_zip_stat_t(); } if (schema_table_store_record(thd, table)) { diff --git a/storage/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc index 127f1df8df5..dad55205bc2 100644 --- a/storage/xtradb/row/row0import.cc +++ b/storage/xtradb/row/row0import.cc @@ -105,18 +105,18 @@ struct row_index_t { struct row_import { row_import() UNIV_NOTHROW : - m_table(), - m_version(), - m_hostname(), - m_table_name(), - m_autoinc(), - m_page_size(), - m_flags(), - m_n_cols(), - m_cols(), - m_col_names(), - m_n_indexes(), - m_indexes(), + m_table(NULL), + m_version(0), + m_hostname(NULL), + m_table_name(NULL), + m_autoinc(0), + m_page_size(0), + m_flags(0), + m_n_cols(0), + m_cols(NULL), + m_col_names(NULL), + m_n_indexes(0), + m_indexes(NULL), m_missing(true) { } ~row_import() UNIV_NOTHROW; @@ -3558,8 +3558,6 @@ row_import_for_mysql( row_import cfg; - memset(&cfg, 0x0, sizeof(cfg)); - err = row_import_read_cfg(table, trx->mysql_thd, cfg); /* Check if the table column definitions match the contents diff --git a/storage/xtradb/trx/trx0trx.cc b/storage/xtradb/trx/trx0trx.cc index 701ac3ed72d..8e62a7dba46 100644 --- a/storage/xtradb/trx/trx0trx.cc +++ b/storage/xtradb/trx/trx0trx.cc @@ -2421,6 +2421,7 @@ trx_get_trx_by_xid_low( if (trx->is_recovered && trx_state_eq(trx, TRX_STATE_PREPARED) + && !trx->xid.is_null() && xid->gtrid_length == trx->xid.gtrid_length && xid->bqual_length == trx->xid.bqual_length && memcmp(xid->data, trx->xid.data, @@ -2428,8 +2429,7 @@ trx_get_trx_by_xid_low( /* Invalidate the XID, so that subsequent calls will not find it. */ - memset(&trx->xid, 0, sizeof(trx->xid)); - trx->xid.formatID = -1; + trx->xid.null(); break; } } diff --git a/storage/xtradb/trx/trx0undo.cc b/storage/xtradb/trx/trx0undo.cc index 370b3f181a1..b137c461ec3 100644 --- a/storage/xtradb/trx/trx0undo.cc +++ b/storage/xtradb/trx/trx0undo.cc @@ -1314,8 +1314,7 @@ trx_undo_mem_create_at_db_start( /* Read X/Open XA transaction identification if it exists, or set it to NULL. */ - memset(&xid, 0, sizeof(xid)); - xid.formatID = -1; + xid.null(); if (xid_exists == TRUE) { trx_undo_read_xid(undo_header, &xid); -- cgit v1.2.1 From 29ddc6e9e37cbb74193b55e85a1b9cc3f47f28b6 Mon Sep 17 00:00:00 2001 From: Sachin Agarwal Date: Thu, 17 May 2018 16:53:30 +0530 Subject: Bug #27326796 - MYSQL CRASH WITH INNODB ASSERTION FAILURE IN FILE PARS0PARS.CC Problem: As part of bug #24938374 fix, dict_operation_lock was not taken by fts_optimize_thread while syncing fts cache. Due to this change, alter query is able to update SYS_TABLE rows simultaneously. Now when fts_optimizer_thread goes open index table, It doesn't open index table if the record corresponding to that table is set to REC_INFO_DELETED_FLAG in SYS_TABLES and hits an assert. Fix: If fts sync is already in progress, Alter query would wait for sync to complete before renaming table. RB: #19604 Reviewed by : Jimmy.Yang@oracle.com --- storage/innobase/fts/fts0fts.cc | 57 ++++++++++++++--------------------- storage/innobase/handler/ha_innodb.cc | 37 ++++++++++++++++++++++- storage/xtradb/fts/fts0fts.cc | 57 ++++++++++++++--------------------- storage/xtradb/handler/ha_innodb.cc | 37 ++++++++++++++++++++++- 4 files changed, 116 insertions(+), 72 deletions(-) diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 8ccc8afe7b4..86dd76bbf49 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2016, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -869,37 +869,28 @@ fts_drop_index( err = fts_drop_index_tables(trx, index); - for(;;) { - bool retry = false; - if (index->index_fts_syncing) { - retry = true; - } - if (!retry){ - fts_free(table); - break; - } + while (index->index_fts_syncing + && !trx_is_interrupted(trx)) { DICT_BG_YIELD(trx); } + + fts_free(table); + return(err); } - for(;;) { - bool retry = false; - if (index->index_fts_syncing) { - retry = true; - } - if (!retry){ - current_doc_id = table->fts->cache->next_doc_id; - first_doc_id = table->fts->cache->first_doc_id; - fts_cache_clear(table->fts->cache); - fts_cache_destroy(table->fts->cache); - table->fts->cache = fts_cache_create(table); - table->fts->cache->next_doc_id = current_doc_id; - table->fts->cache->first_doc_id = first_doc_id; - break; - } + while (index->index_fts_syncing + && !trx_is_interrupted(trx)) { DICT_BG_YIELD(trx); } + + current_doc_id = table->fts->cache->next_doc_id; + first_doc_id = table->fts->cache->first_doc_id; + fts_cache_clear(table->fts->cache); + fts_cache_destroy(table->fts->cache); + table->fts->cache = fts_cache_create(table); + table->fts->cache->next_doc_id = current_doc_id; + table->fts->cache->first_doc_id = first_doc_id; } else { fts_cache_t* cache = table->fts->cache; fts_index_cache_t* index_cache; @@ -909,18 +900,14 @@ fts_drop_index( index_cache = fts_find_index_cache(cache, index); if (index_cache != NULL) { - for(;;) { - bool retry = false; - if (index->index_fts_syncing) { - retry = true; - } - if (!retry && index_cache->words) { - fts_words_free(index_cache->words); - rbt_free(index_cache->words); - break; - } + while (index->index_fts_syncing + && !trx_is_interrupted(trx)) { DICT_BG_YIELD(trx); } + if (index_cache->words) { + fts_words_free(index_cache->words); + rbt_free(index_cache->words); + } ib_vector_remove(cache->indexes, *(void**) index_cache); } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index b35eeb432fc..3959b49b600 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -10877,6 +10877,7 @@ static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t innobase_rename_table( /*==================*/ + THD* thd, /*!< Connection thread handle */ trx_t* trx, /*!< in: transaction */ const char* from, /*!< in: old name of the table */ const char* to) /*!< in: new name of the table */ @@ -10902,6 +10903,36 @@ innobase_rename_table( row_mysql_lock_data_dictionary(trx); + dict_table_t* table = dict_table_open_on_name(norm_from, TRUE, FALSE, + DICT_ERR_IGNORE_NONE); + + /* Since DICT_BG_YIELD has sleep for 250 milliseconds, + Convert lock_wait_timeout unit from second to 250 milliseconds */ + long int lock_wait_timeout = thd_lock_wait_timeout(thd) * 4; + if (table != NULL) { + for (dict_index_t* index = dict_table_get_first_index(table); + index != NULL; + index = dict_table_get_next_index(index)) { + + if (index->type & DICT_FTS) { + /* Found */ + while (index->index_fts_syncing + && !trx_is_interrupted(trx) + && (lock_wait_timeout--) > 0) { + DICT_BG_YIELD(trx); + } + } + } + dict_table_close(table, TRUE, FALSE); + } + + /* FTS sync is in progress. We shall timeout this operation */ + if (lock_wait_timeout < 0) { + error = DB_LOCK_WAIT_TIMEOUT; + row_mysql_unlock_data_dictionary(trx); + DBUG_RETURN(error); + } + /* Transaction must be flagged as a locking transaction or it hasn't been started yet. */ @@ -11011,7 +11042,7 @@ ha_innobase::rename_table( ++trx->will_lock; trx_set_dict_operation(trx, TRX_DICT_OP_INDEX); - error = innobase_rename_table(trx, from, to); + error = innobase_rename_table(thd, trx, from, to); DEBUG_SYNC(thd, "after_innobase_rename_table"); @@ -11055,6 +11086,10 @@ ha_innobase::rename_table( my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to); error = DB_ERROR; + } else if (error == DB_LOCK_WAIT_TIMEOUT) { + my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0), to); + + error = DB_LOCK_WAIT; } DBUG_RETURN(convert_error_code_to_mysql(error, 0, NULL)); diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc index d2c20405e6a..36a1d234bf4 100644 --- a/storage/xtradb/fts/fts0fts.cc +++ b/storage/xtradb/fts/fts0fts.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2016, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -869,37 +869,28 @@ fts_drop_index( err = fts_drop_index_tables(trx, index); - for(;;) { - bool retry = false; - if (index->index_fts_syncing) { - retry = true; - } - if (!retry){ - fts_free(table); - break; - } + while (index->index_fts_syncing + && !trx_is_interrupted(trx)) { DICT_BG_YIELD(trx); } + + fts_free(table); + return(err); } - for(;;) { - bool retry = false; - if (index->index_fts_syncing) { - retry = true; - } - if (!retry){ - current_doc_id = table->fts->cache->next_doc_id; - first_doc_id = table->fts->cache->first_doc_id; - fts_cache_clear(table->fts->cache); - fts_cache_destroy(table->fts->cache); - table->fts->cache = fts_cache_create(table); - table->fts->cache->next_doc_id = current_doc_id; - table->fts->cache->first_doc_id = first_doc_id; - break; - } + while (index->index_fts_syncing + && !trx_is_interrupted(trx)) { DICT_BG_YIELD(trx); } + + current_doc_id = table->fts->cache->next_doc_id; + first_doc_id = table->fts->cache->first_doc_id; + fts_cache_clear(table->fts->cache); + fts_cache_destroy(table->fts->cache); + table->fts->cache = fts_cache_create(table); + table->fts->cache->next_doc_id = current_doc_id; + table->fts->cache->first_doc_id = first_doc_id; } else { fts_cache_t* cache = table->fts->cache; fts_index_cache_t* index_cache; @@ -909,18 +900,14 @@ fts_drop_index( index_cache = fts_find_index_cache(cache, index); if (index_cache != NULL) { - for(;;) { - bool retry = false; - if (index->index_fts_syncing) { - retry = true; - } - if (!retry && index_cache->words) { - fts_words_free(index_cache->words); - rbt_free(index_cache->words); - break; - } + while (index->index_fts_syncing + && !trx_is_interrupted(trx)) { DICT_BG_YIELD(trx); } + if (index_cache->words) { + fts_words_free(index_cache->words); + rbt_free(index_cache->words); + } ib_vector_remove(cache->indexes, *(void**) index_cache); } diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 89f4b9cb7b5..f153b6e28ae 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -11695,6 +11695,7 @@ static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t innobase_rename_table( /*==================*/ + THD* thd, /*!< Connection thread handle */ trx_t* trx, /*!< in: transaction */ const char* from, /*!< in: old name of the table */ const char* to) /*!< in: new name of the table */ @@ -11720,6 +11721,36 @@ innobase_rename_table( row_mysql_lock_data_dictionary(trx); + dict_table_t* table = dict_table_open_on_name(norm_from, TRUE, FALSE, + DICT_ERR_IGNORE_NONE); + + /* Since DICT_BG_YIELD has sleep for 250 milliseconds, + Convert lock_wait_timeout unit from second to 250 milliseconds */ + long int lock_wait_timeout = thd_lock_wait_timeout(thd) * 4; + if (table != NULL) { + for (dict_index_t* index = dict_table_get_first_index(table); + index != NULL; + index = dict_table_get_next_index(index)) { + + if (index->type & DICT_FTS) { + /* Found */ + while (index->index_fts_syncing + && !trx_is_interrupted(trx) + && (lock_wait_timeout--) > 0) { + DICT_BG_YIELD(trx); + } + } + } + dict_table_close(table, TRUE, FALSE); + } + + /* FTS sync is in progress. We shall timeout this operation */ + if (lock_wait_timeout < 0) { + error = DB_LOCK_WAIT_TIMEOUT; + row_mysql_unlock_data_dictionary(trx); + DBUG_RETURN(error); + } + /* Transaction must be flagged as a locking transaction or it hasn't been started yet. */ @@ -11834,7 +11865,7 @@ ha_innobase::rename_table( ++trx->will_lock; trx_set_dict_operation(trx, TRX_DICT_OP_INDEX); - error = innobase_rename_table(trx, from, to); + error = innobase_rename_table(thd, trx, from, to); DEBUG_SYNC(thd, "after_innobase_rename_table"); @@ -11878,6 +11909,10 @@ ha_innobase::rename_table( my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to); error = DB_ERROR; + } else if (error == DB_LOCK_WAIT_TIMEOUT) { + my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0), to); + + error = DB_LOCK_WAIT; } DBUG_RETURN(convert_error_code_to_mysql(error, 0, NULL)); -- cgit v1.2.1 From a49ec980422e04ce1a37344be09aa6254f16fa2a Mon Sep 17 00:00:00 2001 From: Karthik Kamath Date: Wed, 14 Feb 2018 09:35:18 +0530 Subject: --- storage/xtradb/handler/ha_innodb.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 94e49d4897a..1fe93f0ff9d 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2000, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, 2009 Google Inc. Copyright (c) 2009, Percona Inc. @@ -10689,8 +10689,10 @@ ha_innobase::start_stmt( case SQLCOM_INSERT: case SQLCOM_UPDATE: case SQLCOM_DELETE: + case SQLCOM_REPLACE: init_table_handle_for_HANDLER(); prebuilt->select_lock_type = LOCK_X; + prebuilt->stored_select_lock_type = LOCK_X; error = row_lock_table_for_mysql(prebuilt, NULL, 1); if (error != DB_SUCCESS) { -- cgit v1.2.1 From 5ed2da9587c0dd6dcf9cfcb19f5e434488d79e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 30 Jul 2018 16:28:20 +0300 Subject: Apply the 5.6.40 security fixes to XtraDB We did not merge Percona XtraDB 5.6.40-84.0 yet. The changes in it are mostly cosmetic, except for 2 bug fixes from Oracle MySQL 5.6.40, which could be security bugs. This was achieved by taking the applicable parts of an earlier InnoDB commit to XtraDB: git diff 15ec8c2f28f08517ecbffb959d756b4bdd53ab45{~,} storage/innobase| sed -e s+/innobase/+/xtradb/+|patch -p1 --- storage/xtradb/handler/handler0alter.cc | 51 +++++++++++++++++++++------------ storage/xtradb/row/row0log.cc | 12 ++++++-- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index 755c07848e1..151c3237b2b 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2005, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2017, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -4782,13 +4782,15 @@ processed_field: } /** Get the auto-increment value of the table on commit. -@param ha_alter_info Data used during in-place alter -@param ctx In-place ALTER TABLE context -@param altered_table MySQL table that is being altered -@param old_table MySQL table as it is before the ALTER operation -@return the next auto-increment value (0 if not present) */ +@param[in] ha_alter_info Data used during in-place alter +@param[in,out] ctx In-place ALTER TABLE context + return autoinc value in ctx->max_autoinc +@param altered_table[in] MySQL table that is being altered +@param old_table[in] MySQL table as it is before the ALTER operation +retval true Failure +@retval false Success*/ static MY_ATTRIBUTE((nonnull, warn_unused_result)) -ulonglong +bool commit_get_autoinc( /*===============*/ Alter_inplace_info* ha_alter_info, @@ -4796,23 +4798,28 @@ commit_get_autoinc( const TABLE* altered_table, const TABLE* old_table) { - ulonglong max_autoinc; DBUG_ENTER("commit_get_autoinc"); if (!altered_table->found_next_number_field) { /* There is no AUTO_INCREMENT column in the table after the ALTER operation. */ - max_autoinc = 0; + ctx->max_autoinc = 0; } else if (ctx->add_autoinc != ULINT_UNDEFINED) { /* An AUTO_INCREMENT column was added. Get the last value from the sequence, which may be based on a supplied AUTO_INCREMENT value. */ - max_autoinc = ctx->sequence.last(); + ctx->max_autoinc = ctx->sequence.last(); } else if ((ha_alter_info->handler_flags & Alter_inplace_info::CHANGE_CREATE_OPTION) && (ha_alter_info->create_info->used_fields & HA_CREATE_USED_AUTO)) { + + /* Check if the table is discarded */ + if(dict_table_is_discarded(ctx->old_table)) { + DBUG_RETURN(true); + } + /* An AUTO_INCREMENT value was supplied, but the table was not rebuilt. Get the user-supplied value or the last value from the sequence. */ @@ -4827,7 +4834,8 @@ commit_get_autoinc( dict_index_t* index = dict_table_get_index_on_name( ctx->old_table, autoinc_key->name); - max_autoinc = ha_alter_info->create_info->auto_increment_value; + ctx->max_autoinc = + ha_alter_info->create_info->auto_increment_value; dict_table_autoinc_lock(ctx->old_table); @@ -4836,8 +4844,8 @@ commit_get_autoinc( if (err != DB_SUCCESS) { ut_ad(0); - max_autoinc = 0; - } else if (max_autoinc <= max_value_table) { + ctx->max_autoinc = 0; + } else if (ctx->max_autoinc <= max_value_table) { ulonglong col_max_value; ulonglong offset; @@ -4845,7 +4853,7 @@ commit_get_autoinc( old_table->found_next_number_field); offset = ctx->prebuilt->autoinc_offset; - max_autoinc = innobase_next_autoinc( + ctx->max_autoinc = innobase_next_autoinc( max_value_table, 1, 1, offset, col_max_value); } @@ -4855,11 +4863,11 @@ commit_get_autoinc( Read the old counter value from the table. */ ut_ad(old_table->found_next_number_field); dict_table_autoinc_lock(ctx->old_table); - max_autoinc = ctx->old_table->autoinc; + ctx->max_autoinc = ctx->old_table->autoinc; dict_table_autoinc_unlock(ctx->old_table); } - DBUG_RETURN(max_autoinc); + DBUG_RETURN(false); } /** Add or drop foreign key constraints to the data dictionary tables, @@ -5828,8 +5836,13 @@ ha_innobase::commit_inplace_alter_table( DBUG_ASSERT(new_clustered == ctx->need_rebuild()); - ctx->max_autoinc = commit_get_autoinc( - ha_alter_info, ctx, altered_table, table); + if (commit_get_autoinc(ha_alter_info, ctx, altered_table, + table)) { + fail = true; + my_error(ER_TABLESPACE_DISCARDED, MYF(0), + table->s->table_name.str); + goto rollback_trx; + } if (ctx->need_rebuild()) { ctx->tmp_name = dict_mem_create_temporary_tablename( @@ -5861,6 +5874,8 @@ ha_innobase::commit_inplace_alter_table( #endif } +rollback_trx: + /* Commit or roll back the changes to the data dictionary. */ if (fail) { diff --git a/storage/xtradb/row/row0log.cc b/storage/xtradb/row/row0log.cc index c239722e4f7..7cab4cbbebb 100644 --- a/storage/xtradb/row/row0log.cc +++ b/storage/xtradb/row/row0log.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2017, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -2631,7 +2631,15 @@ all_done: while (!trx_is_interrupted(trx)) { mrec = next_mrec; - ut_ad(mrec < mrec_end); + ut_ad(mrec <= mrec_end); + + if (mrec == mrec_end) { + /* We are at the end of the log. + Mark the replay all_done. */ + if (has_index_lock) { + goto all_done; + } + } if (!has_index_lock) { /* We are applying operations from a different -- cgit v1.2.1 From e52315a4a2c7e752e786f9fcf63b0b5685b0d474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 30 Jul 2018 18:06:30 +0300 Subject: MDEV-16855 Fix fts_sync_synchronization in InnoDB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a backport of the following fix from MySQL 5.7.23. Some code refactoring has been omitted, and the test case has been adapted to MariaDB. commit 7a689acaa65e9d602575f7aa53fe36a64a07460f Author: Krzysztof Kapuścik Date: Tue Mar 13 12:34:03 2018 +0100 Bug#27082268 Invalid FTS sync synchronization The fix closes two issues: Bug #27082268 - INNODB: FAILING ASSERTION: SYM_NODE->TABLE != NULL DURING FTS SYNC Bug #27095935 - DEADLOCK BETWEEN FTS_DROP_INDEX AND FTS_OPTIMIZE_SYNC_TABLE Both issues were related to a FTS cache sync being done during operations that perfomed DDL actions on internal FTS tables (ALTER TABLE, TRUNCATE). In some cases the FTS tables and/or internal cache structures could get removed while still being used to perform FTS synchronization leading to crashes. In other the sync operations could not get finishes as it was waiting for dict lock which was taken by thread waiting for the background sync to be finished. The changes done includes: - Stopping background operations during ALTER TABLE and TRUNCATE. - Removal of unused code in FTS. - Cleanup of FTS sync related code to make it more readable and easier to maintain. RB#18262 --- mysql-test/suite/innodb_fts/r/sync_ddl.result | 117 +++++++++++++++++ mysql-test/suite/innodb_fts/t/sync_ddl.test | 177 ++++++++++++++++++++++++++ storage/innobase/fts/fts0fts.cc | 19 +-- storage/innobase/fts/fts0opt.cc | 175 ++----------------------- storage/innobase/handler/handler0alter.cc | 66 +++++----- storage/innobase/include/fts0fts.h | 8 +- storage/innobase/include/fts0priv.h | 18 +-- storage/innobase/row/row0mysql.cc | 12 ++ storage/xtradb/fts/fts0fts.cc | 19 +-- storage/xtradb/fts/fts0opt.cc | 175 ++----------------------- storage/xtradb/handler/handler0alter.cc | 66 +++++----- storage/xtradb/include/fts0fts.h | 8 +- storage/xtradb/include/fts0priv.h | 18 +-- storage/xtradb/row/row0mysql.cc | 12 ++ 14 files changed, 450 insertions(+), 440 deletions(-) create mode 100644 mysql-test/suite/innodb_fts/r/sync_ddl.result create mode 100644 mysql-test/suite/innodb_fts/t/sync_ddl.test diff --git a/mysql-test/suite/innodb_fts/r/sync_ddl.result b/mysql-test/suite/innodb_fts/r/sync_ddl.result new file mode 100644 index 00000000000..1e98594b28e --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/sync_ddl.result @@ -0,0 +1,117 @@ +CREATE TABLE t1 ( +id INT AUTO_INCREMENT NOT NULL PRIMARY KEY, +value VARCHAR(1024) +) ENGINE=InnoDB; +CREATE FULLTEXT INDEX idx1 ON t1(value); +Warnings: +Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID +SET @save_debug = @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_sync_before_syncing,ib_trunc_sleep_before_fts_cache_clear'; +INSERT INTO t1 (value) VALUES +('By default or with the IN NATURAL LANGUAGE MODE modifier') +; +TRUNCATE TABLE t1; +DROP TABLE t1; +SET GLOBAL debug_dbug = @save_debug; +CREATE TABLE t1 ( +id INT AUTO_INCREMENT NOT NULL PRIMARY KEY, +value VARCHAR(1024) +) ENGINE=InnoDB; +CREATE FULLTEXT INDEX idx1 ON t1(value); +Warnings: +Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_write_words_before_select_index,ib_trunc_sleep_before_fts_cache_clear'; +INSERT INTO t1 (value) VALUES +('By default or with the IN NATURAL LANGUAGE MODE modifier'), +('performs a natural language search for a string'), +('collection is a set of one or more columns included'), +('returns a relevance value; that is, a similarity measure'), +('and the text in that row in the columns named in'), +('By default, the search is performed in case-insensitive'), +('sensitive full-text search, use a binary collation '), +('example, a column that uses the latin1 character'), +('collation of latin1_bin to make it case sensitive') +; +TRUNCATE TABLE t1; +DROP TABLE t1; +SET GLOBAL debug_dbug = @save_debug; +CREATE TABLE t1 ( +value VARCHAR(1024) +) ENGINE=InnoDB; +CREATE FULLTEXT INDEX idx1 ON t1(value); +Warnings: +Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep'; +INSERT INTO t1 (value) VALUES +('By default or with the IN NATURAL LANGUAGE MODE modifier'), +('performs a natural language search for a string'), +('collection is a set of one or more columns included'), +('returns a relevance value; that is, a similarity measure'), +('and the text in that row in the columns named in'), +('By default, the search is performed in case-insensitive'), +('sensitive full-text search, use a binary collation '), +('example, a column that uses the latin1 character'), +('collation of latin1_bin to make it case sensitive') +; +DROP INDEX idx1 ON t1; +DROP TABLE t1; +SET GLOBAL debug_dbug = @save_debug; +CREATE TABLE t1 ( +value VARCHAR(1024) +) ENGINE=InnoDB; +CREATE FULLTEXT INDEX idx1 ON t1(value); +Warnings: +Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep'; +INSERT INTO t1 (value) VALUES +('By default or with the IN NATURAL LANGUAGE MODE modifier'), +('performs a natural language search for a string'), +('collection is a set of one or more columns included'), +('returns a relevance value; that is, a similarity measure'), +('and the text in that row in the columns named in'), +('By default, the search is performed in case-insensitive'), +('sensitive full-text search, use a binary collation '), +('example, a column that uses the latin1 character'), +('collation of latin1_bin to make it case sensitive') +; +ALTER TABLE t1 +DROP INDEX idx1, +ALGORITHM=INPLACE; +DROP TABLE t1; +SET GLOBAL debug_dbug = @save_debug; +CREATE TABLE t1 ( +value VARCHAR(1024) +) ENGINE=InnoDB; +CREATE FULLTEXT INDEX idx1 ON t1(value); +Warnings: +Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep'; +INSERT INTO t1 (value) VALUES +('example, a column that uses the latin1 character'), +('collation of latin1_bin to make it case sensitive') +; +ALTER TABLE t1 +DROP INDEX idx1, +ALGORITHM=COPY; +DROP TABLE t1; +SET GLOBAL debug_dbug = @save_debug; +CREATE TABLE t1 ( +id1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +value VARCHAR(1024) +) ENGINE=InnoDB; +CREATE FULLTEXT INDEX idx1 ON t1(value); +Warnings: +Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep'; +INSERT INTO t1 (value) VALUES +('example, a column that uses the latin1 character'), +('collation of latin1_bin to make it case sensitive') +; +ALTER TABLE t1 +DROP COLUMN id1, +ADD COLUMN id2 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +DROP INDEX idx1, +ADD FULLTEXT INDEX idx2(value), +ALGORITHM=INPLACE; +DROP TABLE t1; +SET GLOBAL debug_dbug = @save_debug; diff --git a/mysql-test/suite/innodb_fts/t/sync_ddl.test b/mysql-test/suite/innodb_fts/t/sync_ddl.test new file mode 100644 index 00000000000..2950297d5bb --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/sync_ddl.test @@ -0,0 +1,177 @@ +# +# BUG#27082268 FTS synchronization issues +# + +--source include/have_innodb.inc +--source include/have_debug.inc + +#-------------------------------------- +# Check FTS_sync vs TRUNCATE (1) +#-------------------------------------- + +CREATE TABLE t1 ( + id INT AUTO_INCREMENT NOT NULL PRIMARY KEY, + value VARCHAR(1024) + ) ENGINE=InnoDB; + +CREATE FULLTEXT INDEX idx1 ON t1(value); + +SET @save_debug = @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_sync_before_syncing,ib_trunc_sleep_before_fts_cache_clear'; + +INSERT INTO t1 (value) VALUES + ('By default or with the IN NATURAL LANGUAGE MODE modifier') + ; + +TRUNCATE TABLE t1; + +DROP TABLE t1; + +SET GLOBAL debug_dbug = @save_debug; + +#-------------------------------------- +# Check FTS sync vs DROP INDEX (2) +#-------------------------------------- + +CREATE TABLE t1 ( + id INT AUTO_INCREMENT NOT NULL PRIMARY KEY, + value VARCHAR(1024) + ) ENGINE=InnoDB; + +CREATE FULLTEXT INDEX idx1 ON t1(value); + +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_write_words_before_select_index,ib_trunc_sleep_before_fts_cache_clear'; + +INSERT INTO t1 (value) VALUES + ('By default or with the IN NATURAL LANGUAGE MODE modifier'), + ('performs a natural language search for a string'), + ('collection is a set of one or more columns included'), + ('returns a relevance value; that is, a similarity measure'), + ('and the text in that row in the columns named in'), + ('By default, the search is performed in case-insensitive'), + ('sensitive full-text search, use a binary collation '), + ('example, a column that uses the latin1 character'), + ('collation of latin1_bin to make it case sensitive') + ; + +TRUNCATE TABLE t1; + +DROP TABLE t1; + +SET GLOBAL debug_dbug = @save_debug; + +#-------------------------------------- +# Check FTS sync vs DROP INDEX +#-------------------------------------- + +CREATE TABLE t1 ( + value VARCHAR(1024) + ) ENGINE=InnoDB; + +CREATE FULLTEXT INDEX idx1 ON t1(value); + +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep'; + +INSERT INTO t1 (value) VALUES + ('By default or with the IN NATURAL LANGUAGE MODE modifier'), + ('performs a natural language search for a string'), + ('collection is a set of one or more columns included'), + ('returns a relevance value; that is, a similarity measure'), + ('and the text in that row in the columns named in'), + ('By default, the search is performed in case-insensitive'), + ('sensitive full-text search, use a binary collation '), + ('example, a column that uses the latin1 character'), + ('collation of latin1_bin to make it case sensitive') + ; + +DROP INDEX idx1 ON t1; + +DROP TABLE t1; + +SET GLOBAL debug_dbug = @save_debug; + +#-------------------------------------- +# Check FTS sync vs ALTER TABLE DROP INDEX (INPLACE) +#-------------------------------------- + +CREATE TABLE t1 ( + value VARCHAR(1024) + ) ENGINE=InnoDB; + +CREATE FULLTEXT INDEX idx1 ON t1(value); + +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep'; + +INSERT INTO t1 (value) VALUES + ('By default or with the IN NATURAL LANGUAGE MODE modifier'), + ('performs a natural language search for a string'), + ('collection is a set of one or more columns included'), + ('returns a relevance value; that is, a similarity measure'), + ('and the text in that row in the columns named in'), + ('By default, the search is performed in case-insensitive'), + ('sensitive full-text search, use a binary collation '), + ('example, a column that uses the latin1 character'), + ('collation of latin1_bin to make it case sensitive') + ; + +ALTER TABLE t1 + DROP INDEX idx1, + ALGORITHM=INPLACE; + +DROP TABLE t1; + +SET GLOBAL debug_dbug = @save_debug; + +#-------------------------------------- +# Check FTS sync vs ALTER TABLE DROP INDEX (COPY) +#-------------------------------------- + +CREATE TABLE t1 ( + value VARCHAR(1024) + ) ENGINE=InnoDB; + +CREATE FULLTEXT INDEX idx1 ON t1(value); + +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep'; + +INSERT INTO t1 (value) VALUES + ('example, a column that uses the latin1 character'), + ('collation of latin1_bin to make it case sensitive') + ; + +ALTER TABLE t1 + DROP INDEX idx1, + ALGORITHM=COPY; + +DROP TABLE t1; + +SET GLOBAL debug_dbug = @save_debug; + +#-------------------------------------- +# Check FTS sync vs ALTER TABLE (INPLACE, new cluster) +#-------------------------------------- + +CREATE TABLE t1 ( + id1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + value VARCHAR(1024) + ) ENGINE=InnoDB; + +CREATE FULLTEXT INDEX idx1 ON t1(value); + +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep'; + +INSERT INTO t1 (value) VALUES + ('example, a column that uses the latin1 character'), + ('collation of latin1_bin to make it case sensitive') + ; + +ALTER TABLE t1 + DROP COLUMN id1, + ADD COLUMN id2 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + DROP INDEX idx1, + ADD FULLTEXT INDEX idx2(value), + ALGORITHM=INPLACE; + +DROP TABLE t1; + +SET GLOBAL debug_dbug = @save_debug; diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 86dd76bbf49..6044abd8e79 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -268,7 +268,7 @@ FTS auxiliary INDEX table and clear the cache at the end. @param[in,out] sync sync state @param[in] unlock_cache whether unlock cache lock when write node @param[in] wait whether wait when a sync is in progress -@param[in] has_dict whether has dict operation lock +@param[in] has_dict whether has dict operation lock @return DB_SUCCESS if all OK */ static dberr_t @@ -3961,6 +3961,9 @@ fts_sync_write_words( word = rbt_value(fts_tokenizer_word_t, rbt_node); + DBUG_EXECUTE_IF("fts_instrument_write_words_before_select_index", + os_thread_sleep(300000);); + selected = fts_select_index( index_cache->charset, word->text.f_str, word->text.f_len); @@ -4525,7 +4528,7 @@ FTS auxiliary INDEX table and clear the cache at the end. @param[in,out] sync sync state @param[in] unlock_cache whether unlock cache lock when write node @param[in] wait whether wait when a sync is in progress -@param[in] has_dict whether has dict operation lock +@param[in] has_dict whether has dict operation lock @return DB_SUCCESS if all OK */ static dberr_t @@ -4587,15 +4590,13 @@ begin_sync: continue; } + DBUG_EXECUTE_IF("fts_instrument_sync_before_syncing", + os_thread_sleep(300000);); index_cache->index->index_fts_syncing = true; - DBUG_EXECUTE_IF("fts_instrument_sync_sleep_drop_waits", - os_thread_sleep(10000000); - ); error = fts_sync_index(sync, index_cache); - if (error != DB_SUCCESS && !sync->interrupted) { - + if (error != DB_SUCCESS) { goto end_sync; } } @@ -4630,8 +4631,8 @@ end_sync: } rw_lock_x_lock(&cache->lock); - /* Clear fts syncing flags of any indexes incase sync is - interrupeted */ + /* Clear fts syncing flags of any indexes in case sync is + interrupted */ for (i = 0; i < ib_vector_size(cache->indexes); ++i) { static_cast( ib_vector_get(cache->indexes, i)) diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc index d9f96948000..77293bc867a 100644 --- a/storage/innobase/fts/fts0opt.cc +++ b/storage/innobase/fts/fts0opt.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2007, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2016, MariaDB Corporation. All Rights reserved. This program is free software; you can redistribute it and/or modify it under @@ -58,12 +58,6 @@ static const ulint FTS_WORD_NODES_INIT_SIZE = 64; /** Last time we did check whether system need a sync */ static ib_time_t last_check_sync_time; -#if 0 -/** Check each table in round robin to see whether they'd -need to be "optimized" */ -static ulint fts_optimize_sync_iterator = 0; -#endif - /** State of a table within the optimization sub system. */ enum fts_state_t { FTS_STATE_LOADED, @@ -75,17 +69,11 @@ enum fts_state_t { /** FTS optimize thread message types. */ enum fts_msg_type_t { - FTS_MSG_START, /*!< Start optimizing thread */ - - FTS_MSG_PAUSE, /*!< Pause optimizing thread */ - FTS_MSG_STOP, /*!< Stop optimizing and exit thread */ FTS_MSG_ADD_TABLE, /*!< Add table to the optimize thread's work queue */ - FTS_MSG_OPTIMIZE_TABLE, /*!< Optimize a table */ - FTS_MSG_DEL_TABLE, /*!< Remove a table from the optimize threads work queue */ FTS_MSG_SYNC_TABLE /*!< Sync fts cache of a table */ @@ -235,7 +223,7 @@ struct fts_msg_t { /** The number of words to read and optimize in a single pass. */ UNIV_INTERN ulong fts_num_word_optimize; -// FIXME +/** Whether to enable additional FTS diagnostic printout. */ UNIV_INTERN char fts_enable_diag_print; /** ZLib compressed block size.*/ @@ -2560,13 +2548,9 @@ fts_optimize_create_msg( return(msg); } -/**********************************************************************//** -Add the table to add to the OPTIMIZER's list. */ -UNIV_INTERN -void -fts_optimize_add_table( -/*===================*/ - dict_table_t* table) /*!< in: table to add */ +/** Add the table to add to the OPTIMIZER's list. +@param[in] table table to add */ +UNIV_INTERN void fts_optimize_add_table(dict_table_t* table) { fts_msg_t* msg; @@ -2584,26 +2568,6 @@ fts_optimize_add_table( ib_wqueue_add(fts_optimize_wq, msg, msg->heap); } -/**********************************************************************//** -Optimize a table. */ -UNIV_INTERN -void -fts_optimize_do_table( -/*==================*/ - dict_table_t* table) /*!< in: table to optimize */ -{ - fts_msg_t* msg; - - /* Optimizer thread could be shutdown */ - if (!fts_optimize_wq) { - return; - } - - msg = fts_optimize_create_msg(FTS_MSG_OPTIMIZE_TABLE, table); - - ib_wqueue_add(fts_optimize_wq, msg, msg->heap); -} - /**********************************************************************//** Remove the table from the OPTIMIZER's list. We do wait for acknowledgement from the consumer of the message. */ @@ -2618,7 +2582,7 @@ fts_optimize_remove_table( fts_msg_del_t* remove; /* if the optimize system not yet initialized, return */ - if (!fts_optimize_wq) { + if (!fts_optimize_is_init()) { return; } @@ -2660,7 +2624,7 @@ fts_optimize_request_sync_table( table_id_t* table_id; /* if the optimize system not yet initialized, return */ - if (!fts_optimize_wq) { + if (!fts_optimize_is_init()) { return; } @@ -2682,54 +2646,6 @@ fts_optimize_request_sync_table( ib_wqueue_add(fts_optimize_wq, msg, msg->heap); } -/**********************************************************************//** -Find the slot for a particular table. -@return slot if found else NULL. */ -static -fts_slot_t* -fts_optimize_find_slot( -/*===================*/ - ib_vector_t* tables, /*!< in: vector of tables */ - const dict_table_t* table) /*!< in: table to add */ -{ - ulint i; - - for (i = 0; i < ib_vector_size(tables); ++i) { - fts_slot_t* slot; - - slot = static_cast(ib_vector_get(tables, i)); - - if (slot->table->id == table->id) { - return(slot); - } - } - - return(NULL); -} - -/**********************************************************************//** -Start optimizing table. */ -static -void -fts_optimize_start_table( -/*=====================*/ - ib_vector_t* tables, /*!< in/out: vector of tables */ - dict_table_t* table) /*!< in: table to optimize */ -{ - fts_slot_t* slot; - - slot = fts_optimize_find_slot(tables, table); - - if (slot == NULL) { - ut_print_timestamp(stderr); - fprintf(stderr, " InnoDB: Error: table %s not registered " - "with the optimize thread.\n", table->name); - } else { - slot->last_run = 0; - slot->completed = 0; - } -} - /**********************************************************************//** Add the table to the vector if it doesn't already exist. */ static @@ -2912,57 +2828,6 @@ fts_is_sync_needed( return(false); } -#if 0 -/*********************************************************************//** -Check whether a table needs to be optimized. */ -static -void -fts_optimize_need_sync( -/*===================*/ - ib_vector_t* tables) /*!< in: list of tables */ -{ - dict_table_t* table = NULL; - fts_slot_t* slot; - ulint num_table = ib_vector_size(tables); - - if (!num_table) { - return; - } - - if (fts_optimize_sync_iterator >= num_table) { - fts_optimize_sync_iterator = 0; - } - - slot = ib_vector_get(tables, fts_optimize_sync_iterator); - table = slot->table; - - if (!table) { - return; - } - - ut_ad(table->fts); - - if (table->fts->cache) { - ulint deleted = table->fts->cache->deleted; - - if (table->fts->cache->added - >= fts_optimize_add_threshold) { - fts_sync_table(table); - } else if (deleted >= fts_optimize_delete_threshold) { - fts_optimize_do_table(table); - - mutex_enter(&table->fts->cache->deleted_lock); - table->fts->cache->deleted -= deleted; - mutex_exit(&table->fts->cache->deleted_lock); - } - } - - fts_optimize_sync_iterator++; - - return; -} -#endif - /** Sync fts cache of a table @param[in] table_id table id */ void @@ -2975,7 +2840,7 @@ fts_optimize_sync_table( if (table) { if (dict_table_has_fts_index(table) && table->fts->cache) { - fts_sync_table(table, true, false, true); + fts_sync_table(table, true, false, false); } dict_table_close(table, FALSE, FALSE); @@ -3047,8 +2912,7 @@ fts_optimize_thread( fts_msg_t* msg; msg = static_cast( - ib_wqueue_timedwait(wq, - FTS_QUEUE_WAIT_IN_USECS)); + ib_wqueue_timedwait(wq, FTS_QUEUE_WAIT_IN_USECS)); /* Timeout ? */ if (msg == NULL) { @@ -3060,12 +2924,6 @@ fts_optimize_thread( } switch (msg->type) { - case FTS_MSG_START: - break; - - case FTS_MSG_PAUSE: - break; - case FTS_MSG_STOP: done = TRUE; exit_event = (os_event_t) msg->ptr; @@ -3081,15 +2939,6 @@ fts_optimize_thread( } break; - case FTS_MSG_OPTIMIZE_TABLE: - if (!done) { - fts_optimize_start_table( - tables, - static_cast( - msg->ptr)); - } - break; - case FTS_MSG_DEL_TABLE: if (fts_optimize_del_table( tables, static_cast( @@ -3104,6 +2953,10 @@ fts_optimize_thread( break; case FTS_MSG_SYNC_TABLE: + DBUG_EXECUTE_IF( + "fts_instrument_msg_sync_sleep", + os_thread_sleep(300000);); + fts_optimize_sync_table( *static_cast(msg->ptr)); break; @@ -3163,7 +3016,7 @@ fts_optimize_init(void) ut_ad(!srv_read_only_mode); /* For now we only support one optimize thread. */ - ut_a(fts_optimize_wq == NULL); + ut_a(!fts_optimize_is_init()); fts_optimize_wq = ib_wqueue_create(); ut_a(fts_optimize_wq != NULL); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 3de46ed4f80..6a3e9575eb1 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -5710,24 +5710,24 @@ ha_innobase::commit_inplace_alter_table( trx_t* trx = ctx0->trx; bool fail = false; - if (new_clustered) { - for (inplace_alter_handler_ctx** pctx = ctx_array; - *pctx; pctx++) { - ha_innobase_inplace_ctx* ctx - = static_cast(*pctx); - DBUG_ASSERT(ctx->need_rebuild()); + /* Stop background FTS operations. */ + for (inplace_alter_handler_ctx** pctx = ctx_array; + *pctx; pctx++) { + ha_innobase_inplace_ctx* ctx + = static_cast(*pctx); + + DBUG_ASSERT(new_clustered == ctx->need_rebuild()); + if (new_clustered) { if (ctx->old_table->fts) { ut_ad(!ctx->old_table->fts->add_wq); - fts_optimize_remove_table( - ctx->old_table); + fts_optimize_remove_table(ctx->old_table); } + } - if (ctx->new_table->fts) { - ut_ad(!ctx->new_table->fts->add_wq); - fts_optimize_remove_table( - ctx->new_table); - } + if (ctx->new_table->fts) { + ut_ad(!ctx->new_table->fts->add_wq); + fts_optimize_remove_table(ctx->new_table); } } @@ -5772,41 +5772,40 @@ ha_innobase::commit_inplace_alter_table( /* Make a concurrent Drop fts Index to wait until sync of that fts index is happening in the background */ - for (;;) { + for (int retry_count = 0;;) { bool retry = false; for (inplace_alter_handler_ctx** pctx = ctx_array; *pctx; pctx++) { - int count =0; ha_innobase_inplace_ctx* ctx = static_cast(*pctx); DBUG_ASSERT(new_clustered == ctx->need_rebuild()); if (dict_fts_index_syncing(ctx->old_table)) { - count++; - if (count == 100) { - fprintf(stderr, - "Drop index waiting for background sync" - "to finish\n"); - } retry = true; + break; } if (new_clustered && dict_fts_index_syncing(ctx->new_table)) { - count++; - if (count == 100) { - fprintf(stderr, - "Drop index waiting for background sync" - "to finish\n"); - } retry = true; + break; } } - if (!retry) { + if (!retry) { break; } + /* Print a message if waiting for a long time. */ + if (retry_count < 100) { + retry_count++; + } else { + ib_logf(IB_LOG_LEVEL_INFO, + "Drop index waiting for background sync" + " to finish"); + retry_count = 0; + } + DICT_BG_YIELD(trx); } @@ -6070,6 +6069,11 @@ foreign_fail: ut_a(fts_check_cached_index(ctx->old_table)); DBUG_INJECT_CRASH("ib_commit_inplace_crash_fail", crash_fail_inject_count++); + + /* Restart the FTS background operations. */ + if (ctx->old_table->fts) { + fts_optimize_add_table(ctx->old_table); + } } row_mysql_unlock_data_dictionary(trx); @@ -6118,8 +6122,6 @@ foreign_fail: dict_table_autoinc_unlock(t); } - bool add_fts = false; - /* Publish the created fulltext index, if any. Note that a fulltext index can be created without creating the clustered index, if there already exists @@ -6134,14 +6136,14 @@ foreign_fail: is left unset when a drop proceeds the add. */ DICT_TF2_FLAG_SET(ctx->new_table, DICT_TF2_FTS); fts_add_index(index, ctx->new_table); - add_fts = true; } } ut_d(dict_table_check_for_dup_indexes( ctx->new_table, CHECK_ALL_COMPLETE)); - if (add_fts) { + /* Start/Restart the FTS background operations. */ + if (ctx->new_table->fts) { fts_optimize_add_table(ctx->new_table); } diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index cd94956dc55..4c2d247e0a6 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2016, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -705,6 +705,12 @@ fts_drop_index_tables( dict_index_t* index) /*!< in: Index to drop */ MY_ATTRIBUTE((nonnull, warn_unused_result)); +/** Add the table to add to the OPTIMIZER's list. +@param[in] table table to add */ +void +fts_optimize_add_table( + dict_table_t* table); + /******************************************************************//** Remove the table from the OPTIMIZER's list. We do wait for acknowledgement from the consumer of the message. */ diff --git a/storage/innobase/include/fts0priv.h b/storage/innobase/include/fts0priv.h index 2d4e9d88fd1..a3936f54a48 100644 --- a/storage/innobase/include/fts0priv.h +++ b/storage/innobase/include/fts0priv.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2018, 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 @@ -598,22 +598,6 @@ fts_get_table_id( long */ MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** -Add the table to add to the OPTIMIZER's list. */ -UNIV_INTERN -void -fts_optimize_add_table( -/*===================*/ - dict_table_t* table) /*!< in: table to add */ - MY_ATTRIBUTE((nonnull)); -/******************************************************************//** -Optimize a table. */ -UNIV_INTERN -void -fts_optimize_do_table( -/*==================*/ - dict_table_t* table) /*!< in: table to optimize */ - MY_ATTRIBUTE((nonnull)); -/******************************************************************//** Construct the prefix name of an FTS table. @return own: table name, must be freed with mem_free() */ UNIV_INTERN diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index bb1a27be4ba..87d40ee2ba4 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -3309,6 +3309,10 @@ row_truncate_table_for_mysql( return(DB_TABLESPACE_NOT_FOUND); } + if (table->fts) { + fts_optimize_remove_table(table); + } + trx_start_for_ddl(trx, TRX_DICT_OP_TABLE); trx->op_info = "truncating table"; @@ -3709,6 +3713,9 @@ next_rec: /* Reset the Doc ID in cache to 0 */ if (has_internal_doc_id && table->fts->cache) { + DBUG_EXECUTE_IF("ib_trunc_sleep_before_fts_cache_clear", + os_thread_sleep(10000000);); + table->fts->fts_status |= TABLE_DICT_LOCKED; fts_update_next_doc_id(trx, table, NULL, 0); fts_cache_clear(table->fts->cache); @@ -3732,6 +3739,11 @@ funct_exit: table->memcached_sync_count = 0; } + /* Add the table back to FTS optimize background thread. */ + if (table->fts) { + fts_optimize_add_table(table); + } + row_mysql_unlock_data_dictionary(trx); dict_stats_update(table, DICT_STATS_EMPTY_TABLE); diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc index 36a1d234bf4..2f9e331219b 100644 --- a/storage/xtradb/fts/fts0fts.cc +++ b/storage/xtradb/fts/fts0fts.cc @@ -268,7 +268,7 @@ FTS auxiliary INDEX table and clear the cache at the end. @param[in,out] sync sync state @param[in] unlock_cache whether unlock cache lock when write node @param[in] wait whether wait when a sync is in progress -@param[in] has_dict whether has dict operation lock +@param[in] has_dict whether has dict operation lock @return DB_SUCCESS if all OK */ static dberr_t @@ -3961,6 +3961,9 @@ fts_sync_write_words( word = rbt_value(fts_tokenizer_word_t, rbt_node); + DBUG_EXECUTE_IF("fts_instrument_write_words_before_select_index", + os_thread_sleep(300000);); + selected = fts_select_index( index_cache->charset, word->text.f_str, word->text.f_len); @@ -4525,7 +4528,7 @@ FTS auxiliary INDEX table and clear the cache at the end. @param[in,out] sync sync state @param[in] unlock_cache whether unlock cache lock when write node @param[in] wait whether wait when a sync is in progress -@param[in] has_dict whether has dict operation lock +@param[in] has_dict whether has dict operation lock @return DB_SUCCESS if all OK */ static dberr_t @@ -4587,15 +4590,13 @@ begin_sync: continue; } + DBUG_EXECUTE_IF("fts_instrument_sync_before_syncing", + os_thread_sleep(300000);); index_cache->index->index_fts_syncing = true; - DBUG_EXECUTE_IF("fts_instrument_sync_sleep_drop_waits", - os_thread_sleep(10000000); - ); error = fts_sync_index(sync, index_cache); - if (error != DB_SUCCESS && !sync->interrupted) { - + if (error != DB_SUCCESS) { goto end_sync; } } @@ -4630,8 +4631,8 @@ end_sync: } rw_lock_x_lock(&cache->lock); - /* Clear fts syncing flags of any indexes incase sync is - interrupeted */ + /* Clear fts syncing flags of any indexes in case sync is + interrupted */ for (i = 0; i < ib_vector_size(cache->indexes); ++i) { static_cast( ib_vector_get(cache->indexes, i)) diff --git a/storage/xtradb/fts/fts0opt.cc b/storage/xtradb/fts/fts0opt.cc index d9f96948000..77293bc867a 100644 --- a/storage/xtradb/fts/fts0opt.cc +++ b/storage/xtradb/fts/fts0opt.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2007, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2016, MariaDB Corporation. All Rights reserved. This program is free software; you can redistribute it and/or modify it under @@ -58,12 +58,6 @@ static const ulint FTS_WORD_NODES_INIT_SIZE = 64; /** Last time we did check whether system need a sync */ static ib_time_t last_check_sync_time; -#if 0 -/** Check each table in round robin to see whether they'd -need to be "optimized" */ -static ulint fts_optimize_sync_iterator = 0; -#endif - /** State of a table within the optimization sub system. */ enum fts_state_t { FTS_STATE_LOADED, @@ -75,17 +69,11 @@ enum fts_state_t { /** FTS optimize thread message types. */ enum fts_msg_type_t { - FTS_MSG_START, /*!< Start optimizing thread */ - - FTS_MSG_PAUSE, /*!< Pause optimizing thread */ - FTS_MSG_STOP, /*!< Stop optimizing and exit thread */ FTS_MSG_ADD_TABLE, /*!< Add table to the optimize thread's work queue */ - FTS_MSG_OPTIMIZE_TABLE, /*!< Optimize a table */ - FTS_MSG_DEL_TABLE, /*!< Remove a table from the optimize threads work queue */ FTS_MSG_SYNC_TABLE /*!< Sync fts cache of a table */ @@ -235,7 +223,7 @@ struct fts_msg_t { /** The number of words to read and optimize in a single pass. */ UNIV_INTERN ulong fts_num_word_optimize; -// FIXME +/** Whether to enable additional FTS diagnostic printout. */ UNIV_INTERN char fts_enable_diag_print; /** ZLib compressed block size.*/ @@ -2560,13 +2548,9 @@ fts_optimize_create_msg( return(msg); } -/**********************************************************************//** -Add the table to add to the OPTIMIZER's list. */ -UNIV_INTERN -void -fts_optimize_add_table( -/*===================*/ - dict_table_t* table) /*!< in: table to add */ +/** Add the table to add to the OPTIMIZER's list. +@param[in] table table to add */ +UNIV_INTERN void fts_optimize_add_table(dict_table_t* table) { fts_msg_t* msg; @@ -2584,26 +2568,6 @@ fts_optimize_add_table( ib_wqueue_add(fts_optimize_wq, msg, msg->heap); } -/**********************************************************************//** -Optimize a table. */ -UNIV_INTERN -void -fts_optimize_do_table( -/*==================*/ - dict_table_t* table) /*!< in: table to optimize */ -{ - fts_msg_t* msg; - - /* Optimizer thread could be shutdown */ - if (!fts_optimize_wq) { - return; - } - - msg = fts_optimize_create_msg(FTS_MSG_OPTIMIZE_TABLE, table); - - ib_wqueue_add(fts_optimize_wq, msg, msg->heap); -} - /**********************************************************************//** Remove the table from the OPTIMIZER's list. We do wait for acknowledgement from the consumer of the message. */ @@ -2618,7 +2582,7 @@ fts_optimize_remove_table( fts_msg_del_t* remove; /* if the optimize system not yet initialized, return */ - if (!fts_optimize_wq) { + if (!fts_optimize_is_init()) { return; } @@ -2660,7 +2624,7 @@ fts_optimize_request_sync_table( table_id_t* table_id; /* if the optimize system not yet initialized, return */ - if (!fts_optimize_wq) { + if (!fts_optimize_is_init()) { return; } @@ -2682,54 +2646,6 @@ fts_optimize_request_sync_table( ib_wqueue_add(fts_optimize_wq, msg, msg->heap); } -/**********************************************************************//** -Find the slot for a particular table. -@return slot if found else NULL. */ -static -fts_slot_t* -fts_optimize_find_slot( -/*===================*/ - ib_vector_t* tables, /*!< in: vector of tables */ - const dict_table_t* table) /*!< in: table to add */ -{ - ulint i; - - for (i = 0; i < ib_vector_size(tables); ++i) { - fts_slot_t* slot; - - slot = static_cast(ib_vector_get(tables, i)); - - if (slot->table->id == table->id) { - return(slot); - } - } - - return(NULL); -} - -/**********************************************************************//** -Start optimizing table. */ -static -void -fts_optimize_start_table( -/*=====================*/ - ib_vector_t* tables, /*!< in/out: vector of tables */ - dict_table_t* table) /*!< in: table to optimize */ -{ - fts_slot_t* slot; - - slot = fts_optimize_find_slot(tables, table); - - if (slot == NULL) { - ut_print_timestamp(stderr); - fprintf(stderr, " InnoDB: Error: table %s not registered " - "with the optimize thread.\n", table->name); - } else { - slot->last_run = 0; - slot->completed = 0; - } -} - /**********************************************************************//** Add the table to the vector if it doesn't already exist. */ static @@ -2912,57 +2828,6 @@ fts_is_sync_needed( return(false); } -#if 0 -/*********************************************************************//** -Check whether a table needs to be optimized. */ -static -void -fts_optimize_need_sync( -/*===================*/ - ib_vector_t* tables) /*!< in: list of tables */ -{ - dict_table_t* table = NULL; - fts_slot_t* slot; - ulint num_table = ib_vector_size(tables); - - if (!num_table) { - return; - } - - if (fts_optimize_sync_iterator >= num_table) { - fts_optimize_sync_iterator = 0; - } - - slot = ib_vector_get(tables, fts_optimize_sync_iterator); - table = slot->table; - - if (!table) { - return; - } - - ut_ad(table->fts); - - if (table->fts->cache) { - ulint deleted = table->fts->cache->deleted; - - if (table->fts->cache->added - >= fts_optimize_add_threshold) { - fts_sync_table(table); - } else if (deleted >= fts_optimize_delete_threshold) { - fts_optimize_do_table(table); - - mutex_enter(&table->fts->cache->deleted_lock); - table->fts->cache->deleted -= deleted; - mutex_exit(&table->fts->cache->deleted_lock); - } - } - - fts_optimize_sync_iterator++; - - return; -} -#endif - /** Sync fts cache of a table @param[in] table_id table id */ void @@ -2975,7 +2840,7 @@ fts_optimize_sync_table( if (table) { if (dict_table_has_fts_index(table) && table->fts->cache) { - fts_sync_table(table, true, false, true); + fts_sync_table(table, true, false, false); } dict_table_close(table, FALSE, FALSE); @@ -3047,8 +2912,7 @@ fts_optimize_thread( fts_msg_t* msg; msg = static_cast( - ib_wqueue_timedwait(wq, - FTS_QUEUE_WAIT_IN_USECS)); + ib_wqueue_timedwait(wq, FTS_QUEUE_WAIT_IN_USECS)); /* Timeout ? */ if (msg == NULL) { @@ -3060,12 +2924,6 @@ fts_optimize_thread( } switch (msg->type) { - case FTS_MSG_START: - break; - - case FTS_MSG_PAUSE: - break; - case FTS_MSG_STOP: done = TRUE; exit_event = (os_event_t) msg->ptr; @@ -3081,15 +2939,6 @@ fts_optimize_thread( } break; - case FTS_MSG_OPTIMIZE_TABLE: - if (!done) { - fts_optimize_start_table( - tables, - static_cast( - msg->ptr)); - } - break; - case FTS_MSG_DEL_TABLE: if (fts_optimize_del_table( tables, static_cast( @@ -3104,6 +2953,10 @@ fts_optimize_thread( break; case FTS_MSG_SYNC_TABLE: + DBUG_EXECUTE_IF( + "fts_instrument_msg_sync_sleep", + os_thread_sleep(300000);); + fts_optimize_sync_table( *static_cast(msg->ptr)); break; @@ -3163,7 +3016,7 @@ fts_optimize_init(void) ut_ad(!srv_read_only_mode); /* For now we only support one optimize thread. */ - ut_a(fts_optimize_wq == NULL); + ut_a(!fts_optimize_is_init()); fts_optimize_wq = ib_wqueue_create(); ut_a(fts_optimize_wq != NULL); diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index 151c3237b2b..bc6a6dd68d4 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -5726,24 +5726,24 @@ ha_innobase::commit_inplace_alter_table( trx_t* trx = ctx0->trx; bool fail = false; - if (new_clustered) { - for (inplace_alter_handler_ctx** pctx = ctx_array; - *pctx; pctx++) { - ha_innobase_inplace_ctx* ctx - = static_cast(*pctx); - DBUG_ASSERT(ctx->need_rebuild()); + /* Stop background FTS operations. */ + for (inplace_alter_handler_ctx** pctx = ctx_array; + *pctx; pctx++) { + ha_innobase_inplace_ctx* ctx + = static_cast(*pctx); + + DBUG_ASSERT(new_clustered == ctx->need_rebuild()); + if (new_clustered) { if (ctx->old_table->fts) { ut_ad(!ctx->old_table->fts->add_wq); - fts_optimize_remove_table( - ctx->old_table); + fts_optimize_remove_table(ctx->old_table); } + } - if (ctx->new_table->fts) { - ut_ad(!ctx->new_table->fts->add_wq); - fts_optimize_remove_table( - ctx->new_table); - } + if (ctx->new_table->fts) { + ut_ad(!ctx->new_table->fts->add_wq); + fts_optimize_remove_table(ctx->new_table); } } @@ -5788,41 +5788,40 @@ ha_innobase::commit_inplace_alter_table( /* Make a concurrent Drop fts Index to wait until sync of that fts index is happening in the background */ - for (;;) { + for (int retry_count = 0;;) { bool retry = false; for (inplace_alter_handler_ctx** pctx = ctx_array; *pctx; pctx++) { - int count =0; ha_innobase_inplace_ctx* ctx = static_cast(*pctx); DBUG_ASSERT(new_clustered == ctx->need_rebuild()); if (dict_fts_index_syncing(ctx->old_table)) { - count++; - if (count == 100) { - fprintf(stderr, - "Drop index waiting for background sync" - "to finish\n"); - } retry = true; + break; } if (new_clustered && dict_fts_index_syncing(ctx->new_table)) { - count++; - if (count == 100) { - fprintf(stderr, - "Drop index waiting for background sync" - "to finish\n"); - } retry = true; + break; } } - if (!retry) { + if (!retry) { break; } + /* Print a message if waiting for a long time. */ + if (retry_count < 100) { + retry_count++; + } else { + ib_logf(IB_LOG_LEVEL_INFO, + "Drop index waiting for background sync" + " to finish"); + retry_count = 0; + } + DICT_BG_YIELD(trx); } @@ -6086,6 +6085,11 @@ foreign_fail: ut_a(fts_check_cached_index(ctx->old_table)); DBUG_INJECT_CRASH("ib_commit_inplace_crash_fail", crash_fail_inject_count++); + + /* Restart the FTS background operations. */ + if (ctx->old_table->fts) { + fts_optimize_add_table(ctx->old_table); + } } row_mysql_unlock_data_dictionary(trx); @@ -6134,8 +6138,6 @@ foreign_fail: dict_table_autoinc_unlock(t); } - bool add_fts = false; - /* Publish the created fulltext index, if any. Note that a fulltext index can be created without creating the clustered index, if there already exists @@ -6150,14 +6152,14 @@ foreign_fail: is left unset when a drop proceeds the add. */ DICT_TF2_FLAG_SET(ctx->new_table, DICT_TF2_FTS); fts_add_index(index, ctx->new_table); - add_fts = true; } } ut_d(dict_table_check_for_dup_indexes( ctx->new_table, CHECK_ALL_COMPLETE)); - if (add_fts) { + /* Start/Restart the FTS background operations. */ + if (ctx->new_table->fts) { fts_optimize_add_table(ctx->new_table); } diff --git a/storage/xtradb/include/fts0fts.h b/storage/xtradb/include/fts0fts.h index cd94956dc55..4c2d247e0a6 100644 --- a/storage/xtradb/include/fts0fts.h +++ b/storage/xtradb/include/fts0fts.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2016, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -705,6 +705,12 @@ fts_drop_index_tables( dict_index_t* index) /*!< in: Index to drop */ MY_ATTRIBUTE((nonnull, warn_unused_result)); +/** Add the table to add to the OPTIMIZER's list. +@param[in] table table to add */ +void +fts_optimize_add_table( + dict_table_t* table); + /******************************************************************//** Remove the table from the OPTIMIZER's list. We do wait for acknowledgement from the consumer of the message. */ diff --git a/storage/xtradb/include/fts0priv.h b/storage/xtradb/include/fts0priv.h index 2d4e9d88fd1..a3936f54a48 100644 --- a/storage/xtradb/include/fts0priv.h +++ b/storage/xtradb/include/fts0priv.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2018, 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 @@ -598,22 +598,6 @@ fts_get_table_id( long */ MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** -Add the table to add to the OPTIMIZER's list. */ -UNIV_INTERN -void -fts_optimize_add_table( -/*===================*/ - dict_table_t* table) /*!< in: table to add */ - MY_ATTRIBUTE((nonnull)); -/******************************************************************//** -Optimize a table. */ -UNIV_INTERN -void -fts_optimize_do_table( -/*==================*/ - dict_table_t* table) /*!< in: table to optimize */ - MY_ATTRIBUTE((nonnull)); -/******************************************************************//** Construct the prefix name of an FTS table. @return own: table name, must be freed with mem_free() */ UNIV_INTERN diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc index cb496965f01..44e358aab89 100644 --- a/storage/xtradb/row/row0mysql.cc +++ b/storage/xtradb/row/row0mysql.cc @@ -3328,6 +3328,10 @@ row_truncate_table_for_mysql( return(DB_TABLESPACE_NOT_FOUND); } + if (table->fts) { + fts_optimize_remove_table(table); + } + trx_start_for_ddl(trx, TRX_DICT_OP_TABLE); trx->op_info = "truncating table"; @@ -3734,6 +3738,9 @@ next_rec: /* Reset the Doc ID in cache to 0 */ if (has_internal_doc_id && table->fts->cache) { + DBUG_EXECUTE_IF("ib_trunc_sleep_before_fts_cache_clear", + os_thread_sleep(10000000);); + table->fts->fts_status |= TABLE_DICT_LOCKED; fts_update_next_doc_id(trx, table, NULL, 0); fts_cache_clear(table->fts->cache); @@ -3757,6 +3764,11 @@ funct_exit: table->memcached_sync_count = 0; } + /* Add the table back to FTS optimize background thread. */ + if (table->fts) { + fts_optimize_add_table(table); + } + row_mysql_unlock_data_dictionary(trx); dict_stats_update(table, DICT_STATS_EMPTY_TABLE); -- cgit v1.2.1 From e023f9a4d5a620b54d7f7132567150d80b630692 Mon Sep 17 00:00:00 2001 From: Elena Stepanova Date: Tue, 31 Jul 2018 15:19:01 +0300 Subject: Unstable tests for 10.0.36 release, latest additions --- mysql-test/unstable-tests | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/mysql-test/unstable-tests b/mysql-test/unstable-tests index 5fa6f6653c3..e8bb02f51e0 100644 --- a/mysql-test/unstable-tests +++ b/mysql-test/unstable-tests @@ -23,7 +23,7 @@ # ############################################################################## -# Based on 10.0 5e67567b158db5d294b11b310ff35a454f58d034 +# Based on 10.0 e52315a4a2c7e752e786f9fcf63b0b5685b0d474 main.alter_table : Modified in 10.0.36 main.assign_key_cache : Added in 10.0.36 @@ -89,12 +89,15 @@ main.statistics : Modified in 10.0.36 main.statistics_close : Added in 10.0.36 main.stat_tables : Modified in 10.0.36 main.stat_tables_par_innodb : MDEV-14155 - wrong rounding +main.subselect : Modified in 10.0.36 main.subselect_innodb : MDEV-10614 - sporadic wrong results main.subselect_sj : Modified in 10.0.36 +main.subselect_sj_mat : Modified in 10.0.36 main.subselect_sj2_mat : Modified in 10.0.36 main.subselect4 : Modified in 10.0.36 main.tc_heuristic_recover : MDEV-15200 - wrong error on mysqld_stub_cmd main.type_datetime : MDEV-14322 - wrong result +main.union : Modified in 10.0.36 main.xa : MDEV-11769 - lock wait timeout #---------------------------------------------------------------- @@ -159,6 +162,7 @@ innodb.innodb_bug48024 : MDEV-14352 - Assertion failure innodb.innodb_bug54044 : Modified in 10.0.36 innodb.innodb-mdev7046 : Modified in 10.0.36 innodb.innodb_monitor : MDEV-10939 - Testcase timeout +innodb.innodb-wl5522 : Modified in 10.0.36 innodb.log_file_size : MDEV-15668 - Not found pattern innodb.recovery_shutdown : MDEV-15671 - Warning: database page corruption innodb.rename_table : Added in 10.0.36 @@ -168,6 +172,7 @@ innodb.xa_recovery : MDEV-15279 - mysqld got exception innodb_fts.basic : Added in 10.0.36 innodb_fts.innodb-fts-fic : MDEV-14154 - Assertion failure innodb_fts.innodb_fts_misc_debug : MDEV-14156 - Unexpected warning +innodb_fts.sync_ddl : Added in 10.0.36 #---------------------------------------------------------------- @@ -214,7 +219,7 @@ perfschema_stress.* : MDEV-10996 - tests not maintained #---------------------------------------------------------------- plugins.feedback_plugin_send : MDEV-7932 - ssl failed for url, MDEV-11118 - wrong result -plugins.processlist : MDEV-16818 - Syntax error; added in 10.0.36 +plugins.processlist : MDEV-16818 - Added in 10.0.36 plugins.server_audit : MDEV-9562 - crashes on sol10-sparc; modified in 10.0.36 plugins.thread_pool_server_audit : MDEV-9562 - crashes on sol10-sparc, MDEV-14295 - wrong result -- cgit v1.2.1