summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2017-10-13 21:59:15 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2017-10-13 21:59:15 +0300
commitc65fdcf7c81c47791966ec693a2dbcf6253e77bb (patch)
treea76e73bba2004b606193b9d683e5868e2cfcd2cc
parentf3ad3bbe7704d2a45e825b763d9ca36e3a7b4483 (diff)
downloadmariadb-git-10.3-georg.tar.gz
MDEV-14062 Upgrade from 10.0 fails on assertion during ALTER TABLE10.3-georg
The fix in MDEV-14022 was incomplete. We must adjust some more code for the fact that SYS_INDEXES records may lack the column MERGE_THRESHOLD that was "instantly" added in MySQL 5.7 and MariaDB 10.2.2. dict_boot(): Hard-core SYS_INDEXES.MERGE_THRESHOLD as DEFAULT NULL. dict_index_t::instant_field_value(), rec_offs_make_valid(): Tolerate the missing SYS_INDEXES.MERGE_THRESHOLD column.
-rw-r--r--storage/innobase/dict/dict0boot.cc7
-rw-r--r--storage/innobase/include/dict0boot.h2
-rw-r--r--storage/innobase/include/dict0mem.h6
-rw-r--r--storage/innobase/rem/rem0rec.cc3
4 files changed, 14 insertions, 4 deletions
diff --git a/storage/innobase/dict/dict0boot.cc b/storage/innobase/dict/dict0boot.cc
index 29707e5bdc2..1d79a2b4bcf 100644
--- a/storage/innobase/dict/dict0boot.cc
+++ b/storage/innobase/dict/dict0boot.cc
@@ -440,6 +440,13 @@ dict_boot(void)
table->id = DICT_INDEXES_ID;
dict_table_add_system_columns(table, heap);
+ /* The column SYS_INDEXES.MERGE_THRESHOLD was "instantly"
+ added in MySQL 5.7 and MariaDB 10.2.2. Assign it DEFAULT NULL.
+ Because of file format compatibility, we must treat SYS_INDEXES
+ as a special case, relaxing some debug assertions
+ for DICT_INDEXES_ID. */
+ dict_table_get_nth_col(table, DICT_COL__SYS_INDEXES__MERGE_THRESHOLD)
+ ->def_val.len = UNIV_SQL_NULL;
table->add_to_cache();
dict_sys->sys_indexes = table;
mem_heap_empty(heap);
diff --git a/storage/innobase/include/dict0boot.h b/storage/innobase/include/dict0boot.h
index d6de7dcf71b..25aced44b2e 100644
--- a/storage/innobase/include/dict0boot.h
+++ b/storage/innobase/include/dict0boot.h
@@ -122,7 +122,7 @@ dict_is_sys_table(
/* The ids for the basic system tables and their indexes */
#define DICT_TABLES_ID 1
#define DICT_COLUMNS_ID 2
-#define DICT_INDEXES_ID 3
+#define DICT_INDEXES_ID dict_index_t::DICT_INDEXES_ID /* 3 */
#define DICT_FIELDS_ID 4
/* The following is a secondary index on SYS_TABLES */
#define DICT_TABLE_IDS_ID 5
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 152ff3f2fd6..ecfe37f9cc7 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -906,6 +906,8 @@ struct dict_index_t{
/** magic value signalling that n_core_null_bytes was not
initialized yet */
static const unsigned NO_CORE_NULL_BYTES = 0xff;
+ /** The clustered index ID of the hard-coded SYS_INDEXES table. */
+ static const unsigned DICT_INDEXES_ID = 3;
unsigned cached:1;/*!< TRUE if the index object is in the
dictionary cache */
unsigned to_be_dropped:1;
@@ -1065,8 +1067,8 @@ struct dict_index_t{
@retval NULL if the default value is SQL NULL (len=UNIV_SQL_NULL) */
const byte* instant_field_value(uint n, ulint* len) const
{
- DBUG_ASSERT(is_instant());
- DBUG_ASSERT(n >= n_core_fields);
+ DBUG_ASSERT(is_instant() || id == DICT_INDEXES_ID);
+ DBUG_ASSERT(n + (id == DICT_INDEXES_ID) >= n_core_fields);
DBUG_ASSERT(n < n_fields);
return fields[n].col->instant_value(len);
}
diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc
index 3fed98f0f3d..c9d35521708 100644
--- a/storage/innobase/rem/rem0rec.cc
+++ b/storage/innobase/rem/rem0rec.cc
@@ -480,7 +480,8 @@ rec_offs_make_valid(
/* The infimum and supremum records carry 1 field. */
ut_ad(is_user_rec || n == 1);
ut_ad(is_user_rec || rec_offs_n_fields(offsets) == 1);
- ut_ad(!is_user_rec || n >= index->n_core_fields
+ ut_ad(!is_user_rec
+ || (n + (index->id == DICT_INDEXES_ID)) >= index->n_core_fields
|| n >= rec_offs_n_fields(offsets));
for (; n < rec_offs_n_fields(offsets); n++) {
ut_ad(leaf);