diff --git a/cmake/pcre.cmake b/cmake/pcre.cmake index 009dbbe5ae1..3d4f163fab9 100644 --- a/cmake/pcre.cmake +++ b/cmake/pcre.cmake @@ -43,8 +43,8 @@ MACRO(BUNDLE_PCRE2) ExternalProject_Add( pcre2 PREFIX "${dir}" - URL "http://ftp.pcre.org/pub/pcre/pcre2-10.36.zip" - URL_MD5 ba9e743af42aac5642f7504b12af4116 + URL "http://ftp.pcre.org/pub/pcre/pcre2-10.37.zip" + URL_MD5 8c1699a725d4b28410adf4b964ebbcb7 INSTALL_COMMAND "" CMAKE_ARGS "-DPCRE2_BUILD_TESTS=OFF" diff --git a/mysql-test/main/processlist_notembedded.result b/mysql-test/main/processlist_notembedded.result index d5c25c0a1d9..26f6e4f9247 100644 --- a/mysql-test/main/processlist_notembedded.result +++ b/mysql-test/main/processlist_notembedded.result @@ -28,6 +28,7 @@ id select_type table type possible_keys key key_len ref rows Extra Warnings: Note 1003 select sleep(100000) KILL QUERY $con_id; +disconnect con1; # # End of 10.2 tests # diff --git a/mysql-test/main/processlist_notembedded.test b/mysql-test/main/processlist_notembedded.test index cc577200368..35cac36bb95 100644 --- a/mysql-test/main/processlist_notembedded.test +++ b/mysql-test/main/processlist_notembedded.test @@ -1,4 +1,3 @@ -source include/have_debug.inc; source include/have_debug_sync.inc; source include/not_embedded.inc; source include/count_sessions.inc; @@ -37,8 +36,6 @@ connection default; SET DEBUG_SYNC = 'RESET'; -source include/wait_until_count_sessions.inc; - --echo # --echo # End of 5.5 tests --echo # @@ -52,8 +49,12 @@ source include/wait_until_count_sessions.inc; --send select sleep(100000) --connection default +let $wait_condition= SELECT COUNT(*)=1 FROM information_schema.processlist where state='User sleep'; +source include/wait_condition.inc; evalp SHOW EXPLAIN FOR $con_id; evalp KILL QUERY $con_id; +disconnect con1; +source include/wait_until_count_sessions.inc; --echo # --echo # End of 10.2 tests diff --git a/mysql-test/suite/gcol/inc/gcol_partition.inc b/mysql-test/suite/gcol/inc/gcol_partition.inc index 4e4af4f0023..50a743c0153 100644 --- a/mysql-test/suite/gcol/inc/gcol_partition.inc +++ b/mysql-test/suite/gcol/inc/gcol_partition.inc @@ -169,3 +169,15 @@ CREATE TABLE t1 ( INSERT INTO t1 () VALUES (),(); UPDATE t1 SET a = 0 WHERE b IS NULL ORDER BY pk; DROP TABLE t1; + +--echo # +--echo # MDEV-26220 Server crashes with indexed by prefix virtual column +--echo # + +CREATE TABLE t1 (pk INT PRIMARY KEY, a INT, b CHAR(20), c CHAR(20) AS (b), + KEY (c(10),a)) PARTITION BY HASH(pk); +INSERT INTO t1 (pk,a,b) VALUES (1,10,'foo'),(2,11,'baz'); +SELECT a FROM t1; + +# Cleanup +DROP TABLE t1; diff --git a/mysql-test/suite/gcol/r/gcol_partition_innodb.result b/mysql-test/suite/gcol/r/gcol_partition_innodb.result index d3f211c9b9a..e61c0a26417 100644 --- a/mysql-test/suite/gcol/r/gcol_partition_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_partition_innodb.result @@ -104,6 +104,17 @@ INSERT INTO t1 () VALUES (),(); UPDATE t1 SET a = 0 WHERE b IS NULL ORDER BY pk; DROP TABLE t1; # +# MDEV-26220 Server crashes with indexed by prefix virtual column +# +CREATE TABLE t1 (pk INT PRIMARY KEY, a INT, b CHAR(20), c CHAR(20) AS (b), +KEY (c(10),a)) PARTITION BY HASH(pk); +INSERT INTO t1 (pk,a,b) VALUES (1,10,'foo'),(2,11,'baz'); +SELECT a FROM t1; +a +11 +10 +DROP TABLE t1; +# # MDEV-16980 Wrongly set tablename len while opening the # table for purge thread # diff --git a/mysql-test/suite/gcol/r/gcol_partition_myisam.result b/mysql-test/suite/gcol/r/gcol_partition_myisam.result index 75e216f903b..e54b0ad83c6 100644 --- a/mysql-test/suite/gcol/r/gcol_partition_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_partition_myisam.result @@ -101,6 +101,17 @@ KEY (b,d) INSERT INTO t1 () VALUES (),(); UPDATE t1 SET a = 0 WHERE b IS NULL ORDER BY pk; DROP TABLE t1; +# +# MDEV-26220 Server crashes with indexed by prefix virtual column +# +CREATE TABLE t1 (pk INT PRIMARY KEY, a INT, b CHAR(20), c CHAR(20) AS (b), +KEY (c(10),a)) PARTITION BY HASH(pk); +INSERT INTO t1 (pk,a,b) VALUES (1,10,'foo'),(2,11,'baz'); +SELECT a FROM t1; +a +11 +10 +DROP TABLE t1; DROP VIEW IF EXISTS v1,v2; DROP TABLE IF EXISTS t1,t2,t3; DROP PROCEDURE IF EXISTS p1; diff --git a/mysql-test/suite/gcol/r/innodb_virtual_index.result b/mysql-test/suite/gcol/r/innodb_virtual_index.result index 2e9b762500d..aafe65b7fa3 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_index.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_index.result @@ -296,3 +296,17 @@ Table Op Msg_type Msg_text test.t1 optimize note Table does not support optimize, doing recreate + analyze instead test.t1 optimize status OK DROP TABLE t1; +# +# MDEV-20154 Assertion `len <= col->len || ((col->mtype) == 5 +# || (col->mtype) == 14)' failed in row_merge_buf_add +# +CREATE TABLE t1 ( +a VARCHAR(2500), +b VARCHAR(2499) AS (a) VIRTUAL +) ENGINE=InnoDB; +INSERT INTO t1 (a) VALUES ('foo'); +ALTER TABLE t1 MODIFY a VARCHAR(2600), ALGORITHM=INPLACE; +ALTER TABLE t1 ADD KEY (b), ALGORITHM=INPLACE; +# Cleanup +DROP TABLE t1; +# End of 10.2 tests diff --git a/mysql-test/suite/gcol/t/innodb_virtual_index.test b/mysql-test/suite/gcol/t/innodb_virtual_index.test index bb47379f3b2..4a41623264e 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_index.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_index.test @@ -321,3 +321,23 @@ CREATE TABLE t1 (id INT PRIMARY KEY, a CHAR(3), INSERT INTO t1 (id,a) VALUES (1,'foo'); OPTIMIZE TABLE t1; DROP TABLE t1; + +--echo # +--echo # MDEV-20154 Assertion `len <= col->len || ((col->mtype) == 5 +--echo # || (col->mtype) == 14)' failed in row_merge_buf_add +--echo # + +CREATE TABLE t1 ( + a VARCHAR(2500), + b VARCHAR(2499) AS (a) VIRTUAL +) ENGINE=InnoDB; +INSERT INTO t1 (a) VALUES ('foo'); + +ALTER TABLE t1 MODIFY a VARCHAR(2600), ALGORITHM=INPLACE; +ALTER TABLE t1 ADD KEY (b), ALGORITHM=INPLACE; + +--echo # Cleanup +DROP TABLE t1; + +--echo # End of 10.2 tests + diff --git a/sql/table.cc b/sql/table.cc index 3bfca699b50..ec950c582c3 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -4185,6 +4185,21 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share, /* Update to use trigger fields */ switch_defaults_to_nullable_trigger_fields(outparam); + + for (uint k= 0; k < share->keys; k++) + { + KEY &key_info= outparam->key_info[k]; + uint parts = (share->use_ext_keys ? key_info.ext_key_parts : + key_info.user_defined_key_parts); + for (uint p= 0; p < parts; p++) + { + KEY_PART_INFO &kp= key_info.key_part[p]; + if (kp.field != outparam->field[kp.fieldnr - 1]) + { + kp.field->vcol_info = outparam->field[kp.fieldnr - 1]->vcol_info; + } + } + } } #ifdef WITH_PARTITION_STORAGE_ENGINE diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index c48eeeed48a..be05e4fb521 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -6109,58 +6109,3 @@ func_exit: dict_sys.mutex_unlock(); } } - -/** Check if the all the auxillary tables associated with FTS index are in -consistent state. For now consistency is check only by ensuring -index->page_no != FIL_NULL -@param[out] base_table table has host fts index -@param[in,out] trx trx handler */ -void -fts_check_corrupt( - dict_table_t* base_table, - trx_t* trx) -{ - bool sane = true; - fts_table_t fts_table; - - /* Iterate over the common table and check for their sanity. */ - FTS_INIT_FTS_TABLE(&fts_table, NULL, FTS_COMMON_TABLE, base_table); - - for (ulint i = 0; fts_common_tables[i] != NULL && sane; ++i) { - - char table_name[MAX_FULL_NAME_LEN]; - - fts_table.suffix = fts_common_tables[i]; - fts_get_table_name(&fts_table, table_name); - - dict_table_t* aux_table = dict_table_open_on_name( - table_name, true, FALSE, DICT_ERR_IGNORE_NONE); - - if (aux_table == NULL) { - dict_set_corrupted( - dict_table_get_first_index(base_table), - trx, "FTS_SANITY_CHECK"); - ut_ad(base_table->corrupted == TRUE); - sane = false; - continue; - } - - for (dict_index_t* aux_table_index = - UT_LIST_GET_FIRST(aux_table->indexes); - aux_table_index != NULL; - aux_table_index = - UT_LIST_GET_NEXT(indexes, aux_table_index)) { - - /* Check if auxillary table needed for FTS is sane. */ - if (aux_table_index->page == FIL_NULL) { - dict_set_corrupted( - dict_table_get_first_index(base_table), - trx, "FTS_SANITY_CHECK"); - ut_ad(base_table->corrupted == TRUE); - sane = false; - } - } - - dict_table_close(aux_table, FALSE, FALSE); - } -} diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index af39363047c..9d027140335 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -7495,6 +7495,10 @@ alter_fill_stored_column( } } +static bool alter_templ_needs_rebuild(const TABLE* altered_table, + const Alter_inplace_info* ha_alter_info, + const dict_table_t* table); + /** Allows InnoDB to update internal structures with concurrent writes blocked (provided that check_if_supported_inplace_alter() @@ -7642,11 +7646,7 @@ ha_innobase::prepare_inplace_alter_table( ha_alter_info->key_count)) { err_exit_no_heap: DBUG_ASSERT(m_prebuilt->trx->dict_operation_lock_mode == 0); - if (ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE) { - - online_retry_drop_indexes( - m_prebuilt->table, m_user_thd); - } + online_retry_drop_indexes(m_prebuilt->table, m_user_thd); DBUG_RETURN(true); } @@ -8095,6 +8095,8 @@ err_exit: const ha_table_option_struct& alt_opt= *ha_alter_info->create_info->option_struct; + ha_innobase_inplace_ctx *ctx = NULL; + if (!(ha_alter_info->handler_flags & INNOBASE_ALTER_DATA) || ((ha_alter_info->handler_flags & ~(INNOBASE_INPLACE_IGNORE | INNOBASE_ALTER_NOCREATE @@ -8102,15 +8104,11 @@ err_exit: == ALTER_OPTIONS && !alter_options_need_rebuild(ha_alter_info, table))) { - DBUG_ASSERT(!m_prebuilt->trx->dict_operation_lock_mode); - if (ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE) { - online_retry_drop_indexes(m_prebuilt->table, - m_user_thd); - } + DBUG_ASSERT(m_prebuilt->trx->dict_operation_lock_mode == 0); + online_retry_drop_indexes(m_prebuilt->table, m_user_thd); if (heap) { - ha_alter_info->handler_ctx - = new ha_innobase_inplace_ctx( + ctx = new ha_innobase_inplace_ctx( m_prebuilt, drop_index, n_drop_index, drop_fk, n_drop_fk, @@ -8122,6 +8120,7 @@ err_exit: || !thd_is_strict_mode(m_user_thd)), alt_opt.page_compressed, alt_opt.page_compression_level); + ha_alter_info->handler_ctx = ctx; } if ((ha_alter_info->handler_flags @@ -8137,6 +8136,25 @@ err_exit: DBUG_RETURN(true); } + if (!(ha_alter_info->handler_flags & INNOBASE_ALTER_DATA) + && alter_templ_needs_rebuild(altered_table, ha_alter_info, + ctx->new_table) + && ctx->new_table->n_v_cols > 0) { + /* Changing maria record structure may end up here only + if virtual columns were altered. In this case, however, + vc_templ should be rebuilt. Since we don't actually + change any stored data, we can just dispose vc_templ; + it will be recreated on next ha_innobase::open(). */ + + DBUG_ASSERT(ctx->new_table == ctx->old_table); + + dict_free_vc_templ(ctx->new_table->vc_templ); + UT_DELETE(ctx->new_table->vc_templ); + + ctx->new_table->vc_templ = NULL; + } + + success: /* Memorize the future transaction ID for committing the data dictionary change, to be reported by @@ -8261,35 +8279,6 @@ found_col: DBUG_RETURN(true); } -/** Check that the column is part of a virtual index(index contains -virtual column) in the table -@param[in] table Table containing column -@param[in] col column to be checked -@return true if this column is indexed with other virtual columns */ -static -bool -dict_col_in_v_indexes( - dict_table_t* table, - dict_col_t* col) -{ - for (dict_index_t* index = dict_table_get_next_index( - dict_table_get_first_index(table)); index != NULL; - index = dict_table_get_next_index(index)) { - if (!dict_index_has_virtual(index)) { - continue; - } - for (ulint k = 0; k < index->n_fields; k++) { - dict_field_t* field - = dict_index_get_nth_field(index, k); - if (field->col->ind == col->ind) { - return(true); - } - } - } - - return(false); -} - /* Check whether a columnn length change alter operation requires to rebuild the template. @param[in] altered_table TABLE object for new version of table. @@ -8301,9 +8290,9 @@ to rebuild the template. static bool alter_templ_needs_rebuild( - TABLE* altered_table, - Alter_inplace_info* ha_alter_info, - dict_table_t* table) + const TABLE* altered_table, + const Alter_inplace_info* ha_alter_info, + const dict_table_t* table) { ulint i = 0; @@ -8313,8 +8302,7 @@ alter_templ_needs_rebuild( for (ulint j=0; j < table->n_cols; j++) { dict_col_t* cols = dict_table_get_nth_col(table, j); - if (cf.length > cols->len - && dict_col_in_v_indexes(table, cols)) { + if (cf.length > cols->len) { return(true); } } diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index bb61eae43f2..95b5131a526 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -931,16 +931,6 @@ fts_check_cached_index( /*===================*/ dict_table_t* table); /*!< in: Table where indexes are dropped */ -/** Check if the all the auxillary tables associated with FTS index are in -consistent state. For now consistency is check only by ensuring -index->page_no != FIL_NULL -@param[out] base_table table has host fts index -@param[in,out] trx trx handler */ -void -fts_check_corrupt( - dict_table_t* base_table, - trx_t* trx); - /** Fetch the document from tuple, tokenize the text data and insert the text data into fts auxiliary table and its cache. Moreover this tuple fields doesn't contain any information