summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/btr/btr0btr.cc59
-rw-r--r--storage/innobase/btr/btr0bulk.cc28
-rw-r--r--storage/innobase/btr/btr0cur.cc34
-rw-r--r--storage/innobase/btr/btr0defragment.cc7
-rw-r--r--storage/innobase/btr/btr0pcur.cc48
-rw-r--r--storage/innobase/btr/btr0sea.cc31
-rw-r--r--storage/innobase/dict/dict0dict.cc13
-rw-r--r--storage/innobase/dict/dict0mem.cc5
-rw-r--r--storage/innobase/dict/dict0stats.cc30
-rw-r--r--storage/innobase/dict/dict0stats_bg.cc19
-rw-r--r--storage/innobase/fts/fts0fts.cc21
-rw-r--r--storage/innobase/gis/gis0rtree.cc66
-rw-r--r--storage/innobase/gis/gis0sea.cc58
-rw-r--r--storage/innobase/handler/ha_innodb.cc12
-rw-r--r--storage/innobase/handler/handler0alter.cc92
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.cc9
-rw-r--r--storage/innobase/include/btr0bulk.h2
-rw-r--r--storage/innobase/include/btr0pcur.h6
-rw-r--r--storage/innobase/include/dict0mem.h73
-rw-r--r--storage/innobase/include/gis0rtree.ic5
-rw-r--r--storage/innobase/include/page0cur.ic5
-rw-r--r--storage/innobase/include/rem0rec.h10
-rw-r--r--storage/innobase/include/row0merge.h20
-rw-r--r--storage/innobase/lock/lock0lock.cc14
-rw-r--r--storage/innobase/page/page0cur.cc36
-rw-r--r--storage/innobase/page/page0page.cc34
-rw-r--r--storage/innobase/page/page0zip.cc30
-rw-r--r--storage/innobase/rem/rem0rec.cc86
-rw-r--r--storage/innobase/row/row0ftsort.cc6
-rw-r--r--storage/innobase/row/row0import.cc3
-rw-r--r--storage/innobase/row/row0ins.cc26
-rw-r--r--storage/innobase/row/row0log.cc11
-rw-r--r--storage/innobase/row/row0merge.cc34
-rw-r--r--storage/innobase/row/row0mysql.cc17
-rw-r--r--storage/innobase/row/row0purge.cc12
-rw-r--r--storage/innobase/row/row0row.cc10
-rw-r--r--storage/innobase/row/row0sel.cc57
-rw-r--r--storage/innobase/row/row0uins.cc3
-rw-r--r--storage/innobase/row/row0umod.cc16
-rw-r--r--storage/innobase/row/row0undo.cc3
-rw-r--r--storage/innobase/row/row0upd.cc22
-rw-r--r--storage/innobase/row/row0vers.cc38
-rw-r--r--storage/innobase/srv/srv0start.cc2
-rw-r--r--storage/innobase/trx/trx0i_s.cc3
-rw-r--r--storage/innobase/trx/trx0rec.cc3
-rw-r--r--storage/innobase/trx/trx0sys.cc2
-rw-r--r--storage/innobase/ut/ut0ut.cc4
47 files changed, 705 insertions, 420 deletions
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc
index fa7f2cfc6f8..19c280eea90 100644
--- a/storage/innobase/btr/btr0btr.cc
+++ b/storage/innobase/btr/btr0btr.cc
@@ -829,7 +829,7 @@ btr_page_get_father_node_ptr_func(
node_ptr = btr_cur_get_rec(cursor);
- offsets = rec_get_offsets(node_ptr, index, offsets, false,
+ offsets = rec_get_offsets(node_ptr, index, offsets, 0,
ULINT_UNDEFINED, &heap);
if (btr_node_ptr_get_child_page_no(node_ptr, offsets) != page_no) {
@@ -846,10 +846,11 @@ btr_page_get_father_node_ptr_func(
print_rec = page_rec_get_next(
page_get_infimum_rec(page_align(user_rec)));
offsets = rec_get_offsets(print_rec, index, offsets,
- page_rec_is_leaf(user_rec),
+ page_rec_is_leaf(user_rec)
+ ? index->n_core_fields : 0,
ULINT_UNDEFINED, &heap);
page_rec_print(print_rec, offsets);
- offsets = rec_get_offsets(node_ptr, index, offsets, false,
+ offsets = rec_get_offsets(node_ptr, index, offsets, 0,
ULINT_UNDEFINED, &heap);
page_rec_print(node_ptr, offsets);
@@ -2241,7 +2242,9 @@ btr_page_get_split_rec(
incl_data += insert_size;
} else {
offsets = rec_get_offsets(rec, cursor->index, offsets,
- page_is_leaf(page),
+ page_is_leaf(page)
+ ? cursor->index->n_core_fields
+ : 0,
ULINT_UNDEFINED, &heap);
incl_data += rec_offs_size(offsets);
}
@@ -2350,7 +2353,9 @@ btr_page_insert_fits(
space after rec is removed from page. */
*offsets = rec_get_offsets(rec, cursor->index, *offsets,
- page_is_leaf(page),
+ page_is_leaf(page)
+ ? cursor->index->n_core_fields
+ : 0,
ULINT_UNDEFINED, heap);
total_data -= rec_offs_size(*offsets);
@@ -2605,7 +2610,8 @@ btr_page_tuple_smaller(
first_rec = page_cur_get_rec(&pcur);
*offsets = rec_get_offsets(
- first_rec, cursor->index, *offsets, page_is_leaf(block->frame),
+ first_rec, cursor->index, *offsets,
+ page_is_leaf(block->frame) ? cursor->index->n_core_fields : 0,
n_uniq, heap);
return(cmp_dtuple_rec(tuple, first_rec, *offsets) < 0);
@@ -2893,7 +2899,9 @@ func_start:
first_rec = move_limit = split_rec;
*offsets = rec_get_offsets(split_rec, cursor->index, *offsets,
- page_is_leaf(page), n_uniq, heap);
+ page_is_leaf(page)
+ ? cursor->index->n_core_fields : 0,
+ n_uniq, heap);
insert_left = !tuple
|| cmp_dtuple_rec(tuple, split_rec, *offsets) < 0;
@@ -3537,7 +3545,7 @@ retry:
rec_offs* offsets2 = NULL;
/* For rtree, we need to update father's mbr. */
- if (dict_index_is_spatial(index)) {
+ if (index->is_spatial()) {
/* We only support merge pages with the same parent
page */
if (!rtr_check_same_block(
@@ -3555,7 +3563,8 @@ retry:
offsets2 = rec_get_offsets(
btr_cur_get_rec(&cursor2), index, NULL,
- page_is_leaf(cursor2.page_cur.block->frame),
+ page_is_leaf(cursor2.page_cur.block->frame)
+ ? index->n_fields : 0,
ULINT_UNDEFINED, &heap);
/* Check if parent entry needs to be updated */
@@ -3723,13 +3732,14 @@ retry:
#endif /* UNIV_DEBUG */
/* For rtree, we need to update father's mbr. */
- if (dict_index_is_spatial(index)) {
+ if (index->is_spatial()) {
rec_offs* offsets2;
ulint rec_info;
offsets2 = rec_get_offsets(
btr_cur_get_rec(&cursor2), index, NULL,
- page_is_leaf(cursor2.page_cur.block->frame),
+ page_is_leaf(cursor2.page_cur.block->frame)
+ ? index->n_fields : 0,
ULINT_UNDEFINED, &heap);
ut_ad(btr_node_ptr_get_child_page_no(
@@ -3941,16 +3951,16 @@ btr_discard_only_page_on_level(
}
#endif /* UNIV_BTR_DEBUG */
- mem_heap_t* heap = NULL;
- const rec_t* rec = NULL;
- rec_offs* offsets = NULL;
-
+ mem_heap_t* heap = nullptr;
+ const rec_t* rec = nullptr;
+ rec_offs* offsets = nullptr;
if (index->table->instant || index->must_avoid_clear_instant_add()) {
if (!rec_is_metadata(r, *index)) {
} else if (!index->table->instant
|| rec_is_alter_metadata(r, *index)) {
heap = mem_heap_create(srv_page_size);
- offsets = rec_get_offsets(r, index, NULL, true,
+ offsets = rec_get_offsets(r, index, nullptr,
+ index->n_core_fields,
ULINT_UNDEFINED, &heap);
rec = rec_copy(mem_heap_alloc(heap,
rec_offs_size(offsets)),
@@ -4207,7 +4217,7 @@ btr_print_recursive(
node_ptr = page_cur_get_rec(&cursor);
*offsets = rec_get_offsets(
- node_ptr, index, *offsets, false,
+ node_ptr, index, *offsets, 0,
ULINT_UNDEFINED, heap);
btr_print_recursive(index,
btr_node_ptr_get_child(node_ptr,
@@ -4356,7 +4366,9 @@ btr_index_rec_validate(
page = page_align(rec);
- if (dict_index_is_ibuf(index)) {
+ ut_ad(index->n_core_fields);
+
+ if (index->is_ibuf()) {
/* The insert buffer index tree can contain records from any
other index: we cannot check the number of fields or
their length */
@@ -4420,7 +4432,8 @@ n_field_mismatch:
}
}
- offsets = rec_get_offsets(rec, index, offsets, page_is_leaf(page),
+ offsets = rec_get_offsets(rec, index, offsets, page_is_leaf(page)
+ ? index->n_core_fields : 0,
ULINT_UNDEFINED, &heap);
const dict_field_t* field = index->fields;
ut_ad(rec_offs_n_fields(offsets)
@@ -4673,7 +4686,7 @@ btr_validate_level(
page_cur_move_to_next(&cursor);
node_ptr = page_cur_get_rec(&cursor);
- offsets = rec_get_offsets(node_ptr, index, offsets, false,
+ offsets = rec_get_offsets(node_ptr, index, offsets, 0,
ULINT_UNDEFINED, &heap);
savepoint2 = mtr_set_savepoint(&mtr);
@@ -4792,10 +4805,12 @@ loop:
right_rec = page_rec_get_next(page_get_infimum_rec(
right_page));
offsets = rec_get_offsets(rec, index, offsets,
- page_is_leaf(page),
+ page_is_leaf(page)
+ ? index->n_core_fields : 0,
ULINT_UNDEFINED, &heap);
offsets2 = rec_get_offsets(right_rec, index, offsets2,
- page_is_leaf(right_page),
+ page_is_leaf(right_page)
+ ? index->n_core_fields : 0,
ULINT_UNDEFINED, &heap);
/* For spatial index, we cannot guarantee the key ordering
diff --git a/storage/innobase/btr/btr0bulk.cc b/storage/innobase/btr/btr0bulk.cc
index 0dbcfd7af25..13e0e3a0eff 100644
--- a/storage/innobase/btr/btr0bulk.cc
+++ b/storage/innobase/btr/btr0bulk.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2014, 2019, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2020, MariaDB Corporation.
+Copyright (c) 2017, 2021, 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
@@ -170,7 +170,8 @@ inline void PageBulk::insertPage(rec_t *rec, rec_offs *offsets)
(fmt == REDUNDANT ? PAGE_OLD_INFIMUM : PAGE_NEW_INFIMUM))
{
const rec_t *old_rec = m_cur_rec;
- rec_offs *old_offsets= rec_get_offsets(old_rec, m_index, nullptr, is_leaf,
+ rec_offs *old_offsets= rec_get_offsets(old_rec, m_index, nullptr, is_leaf
+ ? m_index->n_core_fields : 0,
ULINT_UNDEFINED, &m_heap);
ut_ad(cmp_rec_rec(rec, old_rec, offsets, old_offsets, m_index) > 0);
}
@@ -604,6 +605,7 @@ PageBulk::getSplitRec()
ut_ad(m_page_zip != NULL);
ut_ad(m_rec_no >= 2);
+ ut_ad(!m_index->is_instant());
ut_ad(page_get_free_space_of_empty(m_is_comp) > m_free_space);
total_used_size = page_get_free_space_of_empty(m_is_comp)
@@ -613,13 +615,13 @@ PageBulk::getSplitRec()
n_recs = 0;
offsets = NULL;
rec = page_get_infimum_rec(m_page);
+ const ulint n_core = page_is_leaf(m_page) ? m_index->n_core_fields : 0;
do {
rec = page_rec_get_next(rec);
ut_ad(page_rec_is_user_rec(rec));
- offsets = rec_get_offsets(rec, m_index, offsets,
- page_is_leaf(m_page),
+ offsets = rec_get_offsets(rec, m_index, offsets, n_core,
ULINT_UNDEFINED, &m_heap);
total_recs_size += rec_offs_size(offsets);
n_recs++;
@@ -648,9 +650,11 @@ PageBulk::copyIn(
ut_ad(m_rec_no == 0);
ut_ad(page_rec_is_user_rec(rec));
+ const ulint n_core = page_rec_is_leaf(rec)
+ ? m_index->n_core_fields : 0;
+
do {
- offsets = rec_get_offsets(rec, m_index, offsets,
- page_rec_is_leaf(split_rec),
+ offsets = rec_get_offsets(rec, m_index, offsets, n_core,
ULINT_UNDEFINED, &m_heap);
insert(rec, offsets);
@@ -691,8 +695,10 @@ PageBulk::copyOut(
/* Set last record's next in page */
rec_offs* offsets = NULL;
rec = page_rec_get_prev(split_rec);
- offsets = rec_get_offsets(rec, m_index, offsets,
- page_rec_is_leaf(split_rec),
+ const ulint n_core = page_rec_is_leaf(split_rec)
+ ? m_index->n_core_fields : 0;
+
+ offsets = rec_get_offsets(rec, m_index, offsets, n_core,
ULINT_UNDEFINED, &m_heap);
mach_write_to_2(rec - REC_NEXT, m_is_comp
? static_cast<uint16_t>
@@ -703,8 +709,7 @@ PageBulk::copyOut(
m_cur_rec = rec;
m_heap_top = rec_get_end(rec, offsets);
- offsets = rec_get_offsets(last_rec, m_index, offsets,
- page_rec_is_leaf(split_rec),
+ offsets = rec_get_offsets(last_rec, m_index, offsets, n_core,
ULINT_UNDEFINED, &m_heap);
m_free_space += ulint(rec_get_end(last_rec, offsets) - m_heap_top)
@@ -1116,7 +1121,8 @@ BtrBulk::insert(
/* Convert tuple to rec. */
rec = rec_convert_dtuple_to_rec(static_cast<byte*>(mem_heap_alloc(
page_bulk->m_heap, rec_size)), m_index, tuple, n_ext);
- offsets = rec_get_offsets(rec, m_index, offsets, !level,
+ offsets = rec_get_offsets(rec, m_index, offsets, level
+ ? 0 : m_index->n_core_fields,
ULINT_UNDEFINED, &page_bulk->m_heap);
page_bulk->insert(rec, offsets);
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index 0710aa640a0..158c017f1b0 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -592,7 +592,8 @@ incompatible:
}
mem_heap_t* heap = NULL;
- rec_offs* offsets = rec_get_offsets(rec, index, NULL, true,
+ rec_offs* offsets = rec_get_offsets(rec, index, NULL,
+ index->n_core_fields,
ULINT_UNDEFINED, &heap);
if (rec_offs_any_default(offsets)) {
inconsistent:
@@ -2033,7 +2034,7 @@ retry_page_get:
node_ptr = page_cur_get_rec(page_cursor);
- offsets = rec_get_offsets(node_ptr, index, offsets, false,
+ offsets = rec_get_offsets(node_ptr, index, offsets, 0,
ULINT_UNDEFINED, &heap);
/* If the rec is the first or last in the page for
@@ -2163,7 +2164,7 @@ need_opposite_intention:
offsets2 = rec_get_offsets(
first_rec, index, offsets2,
- false, ULINT_UNDEFINED, &heap);
+ 0, ULINT_UNDEFINED, &heap);
cmp_rec_rec(node_ptr, first_rec,
offsets, offsets2, index, false,
&matched_fields);
@@ -2181,7 +2182,7 @@ need_opposite_intention:
offsets2 = rec_get_offsets(
last_rec, index, offsets2,
- false, ULINT_UNDEFINED, &heap);
+ 0, ULINT_UNDEFINED, &heap);
cmp_rec_rec(
node_ptr, last_rec,
offsets, offsets2, index,
@@ -2350,7 +2351,7 @@ need_opposite_intention:
offsets = rec_get_offsets(
my_node_ptr, index, offsets,
- false, ULINT_UNDEFINED, &heap);
+ 0, ULINT_UNDEFINED, &heap);
ulint my_page_no
= btr_node_ptr_get_child_page_no(
@@ -2772,7 +2773,7 @@ btr_cur_open_at_index_side(
node_ptr = page_cur_get_rec(page_cursor);
offsets = rec_get_offsets(node_ptr, cursor->index, offsets,
- false, ULINT_UNDEFINED, &heap);
+ 0, ULINT_UNDEFINED, &heap);
/* If the rec is the first or last in the page for
pessimistic delete intention, it might cause node_ptr insert
@@ -3061,7 +3062,7 @@ btr_cur_open_at_rnd_pos(
node_ptr = page_cur_get_rec(page_cursor);
offsets = rec_get_offsets(node_ptr, cursor->index, offsets,
- false, ULINT_UNDEFINED, &heap);
+ 0, ULINT_UNDEFINED, &heap);
/* If the rec is the first or last in the page for
pessimistic delete intention, it might cause node_ptr insert
@@ -4581,7 +4582,7 @@ btr_cur_optimistic_update(
ut_ad(fil_page_index_page_check(page));
ut_ad(btr_page_get_index_id(page) == index->id);
- *offsets = rec_get_offsets(rec, index, *offsets, true,
+ *offsets = rec_get_offsets(rec, index, *offsets, index->n_core_fields,
ULINT_UNDEFINED, heap);
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ut_a(!rec_offs_any_null_extern(rec, *offsets)
@@ -5501,7 +5502,8 @@ btr_cur_optimistic_delete_func(
rec = btr_cur_get_rec(cursor);
- offsets = rec_get_offsets(rec, cursor->index, offsets, true,
+ offsets = rec_get_offsets(rec, cursor->index, offsets,
+ cursor->index->n_core_fields,
ULINT_UNDEFINED, &heap);
const ibool no_compress_needed = !rec_offs_any_extern(offsets)
@@ -5710,7 +5712,8 @@ btr_cur_pessimistic_delete(
ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
- offsets = rec_get_offsets(rec, index, NULL, page_is_leaf(page),
+ offsets = rec_get_offsets(rec, index, NULL, page_is_leaf(page)
+ ? index->n_core_fields : 0,
ULINT_UNDEFINED, &heap);
if (rec_offs_any_extern(offsets)) {
@@ -5812,7 +5815,7 @@ discard_page:
pointer as the predefined minimum record */
min_mark_next_rec = true;
- } else if (dict_index_is_spatial(index)) {
+ } else if (index->is_spatial()) {
/* For rtree, if delete the leftmost node pointer,
we need to update parent page. */
rtr_mbr_t father_mbr;
@@ -5827,7 +5830,7 @@ discard_page:
&father_cursor);
offsets = rec_get_offsets(
btr_cur_get_rec(&father_cursor), index, NULL,
- false, ULINT_UNDEFINED, &heap);
+ 0, ULINT_UNDEFINED, &heap);
father_rec = btr_cur_get_rec(&father_cursor);
rtr_read_mbr(rec_get_nth_field(
@@ -6745,12 +6748,13 @@ btr_estimate_number_of_different_key_vals(dict_index_t* index)
page = btr_cur_get_page(&cursor);
rec = page_rec_get_next(page_get_infimum_rec(page));
- const bool is_leaf = page_is_leaf(page);
+ const ulint n_core = page_is_leaf(page)
+ ? index->n_core_fields : 0;
if (!page_rec_is_supremum(rec)) {
not_empty_flag = 1;
offsets_rec = rec_get_offsets(rec, index, offsets_rec,
- is_leaf,
+ n_core,
ULINT_UNDEFINED, &heap);
if (n_not_null != NULL) {
@@ -6771,7 +6775,7 @@ btr_estimate_number_of_different_key_vals(dict_index_t* index)
offsets_next_rec = rec_get_offsets(next_rec, index,
offsets_next_rec,
- is_leaf,
+ n_core,
ULINT_UNDEFINED,
&heap);
diff --git a/storage/innobase/btr/btr0defragment.cc b/storage/innobase/btr/btr0defragment.cc
index 4f23a4f88d3..6bd04253a86 100644
--- a/storage/innobase/btr/btr0defragment.cc
+++ b/storage/innobase/btr/btr0defragment.cc
@@ -258,12 +258,12 @@ btr_defragment_calc_n_recs_for_size(
ulint size = 0;
page_cur_t cur;
+ const ulint n_core = page_is_leaf(page) ? index->n_core_fields : 0;
page_cur_set_before_first(block, &cur);
page_cur_move_to_next(&cur);
while (page_cur_get_rec(&cur) != page_get_supremum_rec(page)) {
rec_t* cur_rec = page_cur_get_rec(&cur);
- offsets = rec_get_offsets(cur_rec, index, offsets,
- page_is_leaf(page),
+ offsets = rec_get_offsets(cur_rec, index, offsets, n_core,
ULINT_UNDEFINED, &heap);
ulint rec_size = rec_offs_size(offsets);
size += rec_size;
@@ -275,6 +275,9 @@ btr_defragment_calc_n_recs_for_size(
page_cur_move_to_next(&cur);
}
*n_recs_size = size;
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_free(heap);
+ }
return n_recs;
}
diff --git a/storage/innobase/btr/btr0pcur.cc b/storage/innobase/btr/btr0pcur.cc
index 00600a5d791..e425ed7820e 100644
--- a/storage/innobase/btr/btr0pcur.cc
+++ b/storage/innobase/btr/btr0pcur.cc
@@ -61,6 +61,7 @@ btr_pcur_reset(
cursor->btr_cur.index = NULL;
cursor->btr_cur.page_cur.rec = NULL;
cursor->old_rec = NULL;
+ cursor->old_n_core_fields = 0;
cursor->old_n_fields = 0;
cursor->old_stored = false;
@@ -184,19 +185,21 @@ before_first:
if (index->is_ibuf()) {
ut_ad(!index->table->not_redundant());
- cursor->old_n_fields = rec_get_n_fields_old(rec);
- } else if (page_rec_is_leaf(rec)) {
- cursor->old_n_fields = dict_index_get_n_unique_in_tree(index);
- } else if (index->is_spatial()) {
- ut_ad(dict_index_get_n_unique_in_tree_nonleaf(index)
- == DICT_INDEX_SPATIAL_NODEPTR_SIZE);
- /* For R-tree, we have to compare
- the child page numbers as well. */
- cursor->old_n_fields = DICT_INDEX_SPATIAL_NODEPTR_SIZE + 1;
+ cursor->old_n_fields = uint16_t(rec_get_n_fields_old(rec));
} else {
- cursor->old_n_fields = dict_index_get_n_unique_in_tree(index);
+ cursor->old_n_fields = static_cast<uint16>(
+ dict_index_get_n_unique_in_tree(index));
+ if (index->is_spatial() && !page_rec_is_leaf(rec)) {
+ ut_ad(dict_index_get_n_unique_in_tree_nonleaf(index)
+ == DICT_INDEX_SPATIAL_NODEPTR_SIZE);
+ /* For R-tree, we have to compare
+ the child page numbers as well. */
+ cursor->old_n_fields
+ = DICT_INDEX_SPATIAL_NODEPTR_SIZE + 1;
+ }
}
+ cursor->old_n_core_fields = index->n_core_fields;
cursor->old_rec = rec_copy_prefix_to_buf(rec, index,
cursor->old_n_fields,
&cursor->old_rec_buf,
@@ -231,6 +234,7 @@ btr_pcur_copy_stored_position(
+ (pcur_donate->old_rec - pcur_donate->old_rec_buf);
}
+ pcur_receive->old_n_core_fields = pcur_donate->old_n_core_fields;
pcur_receive->old_n_fields = pcur_donate->old_n_fields;
}
@@ -317,6 +321,8 @@ btr_pcur_restore_position(
}
ut_a(cursor->old_rec);
+ ut_a(cursor->old_n_core_fields);
+ ut_a(cursor->old_n_core_fields <= index->n_core_fields);
ut_a(cursor->old_n_fields);
switch (latch_mode) {
@@ -345,11 +351,16 @@ btr_pcur_restore_position(
rec_offs_init(offsets2_);
heap = mem_heap_create(256);
+ ut_ad(cursor->old_n_core_fields
+ == index->n_core_fields);
+
offsets1 = rec_get_offsets(
- cursor->old_rec, index, offsets1, true,
+ cursor->old_rec, index, offsets1,
+ cursor->old_n_core_fields,
cursor->old_n_fields, &heap);
offsets2 = rec_get_offsets(
- rec, index, offsets2, true,
+ rec, index, offsets2,
+ index->n_core_fields,
cursor->old_n_fields, &heap);
ut_ad(!cmp_rec_rec(cursor->old_rec,
@@ -374,8 +385,14 @@ btr_pcur_restore_position(
heap = mem_heap_create(256);
- tuple = dict_index_build_data_tuple(cursor->old_rec, index, true,
- cursor->old_n_fields, heap);
+ tuple = dtuple_create(heap, cursor->old_n_fields);
+
+ dict_index_copy_types(tuple, index, cursor->old_n_fields);
+
+ rec_copy_prefix_to_dtuple(tuple, cursor->old_rec, index,
+ cursor->old_n_core_fields,
+ cursor->old_n_fields, heap);
+ ut_ad(dtuple_check_typed(tuple));
/* Save the old search mode of the cursor */
old_mode = cursor->search_mode;
@@ -414,7 +431,8 @@ btr_pcur_restore_position(
&& btr_pcur_is_on_user_rec(cursor)
&& !cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor),
rec_get_offsets(btr_pcur_get_rec(cursor),
- index, offsets, true,
+ index, offsets,
+ index->n_core_fields,
ULINT_UNDEFINED, &heap))) {
/* We have to store the NEW value for the modify clock,
diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc
index d637d41dd13..ccf4992d335 100644
--- a/storage/innobase/btr/btr0sea.cc
+++ b/storage/innobase/btr/btr0sea.cc
@@ -735,7 +735,8 @@ btr_search_update_hash_ref(
ulint fold = rec_fold(
rec,
- rec_get_offsets(rec, index, offsets_, true,
+ rec_get_offsets(rec, index, offsets_,
+ index->n_core_fields,
ULINT_UNDEFINED, &heap),
block->curr_n_fields,
block->curr_n_bytes, index->id);
@@ -793,7 +794,8 @@ btr_search_check_guess(
match = 0;
- offsets = rec_get_offsets(rec, cursor->index, offsets, true,
+ offsets = rec_get_offsets(rec, cursor->index, offsets,
+ cursor->index->n_core_fields,
n_unique, &heap);
cmp = cmp_dtuple_rec_with_match(tuple, rec, offsets, &match);
@@ -844,7 +846,8 @@ btr_search_check_guess(
}
offsets = rec_get_offsets(prev_rec, cursor->index, offsets,
- true, n_unique, &heap);
+ cursor->index->n_core_fields,
+ n_unique, &heap);
cmp = cmp_dtuple_rec_with_match(
tuple, prev_rec, offsets, &match);
if (mode == PAGE_CUR_GE) {
@@ -867,7 +870,8 @@ btr_search_check_guess(
}
offsets = rec_get_offsets(next_rec, cursor->index, offsets,
- true, n_unique, &heap);
+ cursor->index->n_core_fields,
+ n_unique, &heap);
cmp = cmp_dtuple_rec_with_match(
tuple, next_rec, offsets, &match);
if (mode == PAGE_CUR_LE) {
@@ -1330,7 +1334,7 @@ retry:
while (!page_rec_is_supremum(rec)) {
offsets = rec_get_offsets(
- rec, index, offsets, true,
+ rec, index, offsets, index->n_core_fields,
btr_search_get_n_fields(n_fields, n_bytes),
&heap);
fold = rec_fold(rec, offsets, n_fields, n_bytes, index_id);
@@ -1549,7 +1553,7 @@ btr_search_build_page_hash_index(
ut_a(index->id == btr_page_get_index_id(page));
offsets = rec_get_offsets(
- rec, index, offsets, true,
+ rec, index, offsets, index->n_core_fields,
btr_search_get_n_fields(n_fields, n_bytes),
&heap);
ut_ad(page_rec_is_supremum(rec)
@@ -1580,7 +1584,7 @@ btr_search_build_page_hash_index(
}
offsets = rec_get_offsets(
- next_rec, index, offsets, true,
+ next_rec, index, offsets, index->n_core_fields,
btr_search_get_n_fields(n_fields, n_bytes), &heap);
next_fold = rec_fold(next_rec, offsets, n_fields,
n_bytes, index->id);
@@ -1818,7 +1822,8 @@ void btr_search_update_hash_on_delete(btr_cur_t* cursor)
rec = btr_cur_get_rec(cursor);
- fold = rec_fold(rec, rec_get_offsets(rec, index, offsets_, true,
+ fold = rec_fold(rec, rec_get_offsets(rec, index, offsets_,
+ index->n_core_fields,
ULINT_UNDEFINED, &heap),
block->curr_n_fields, block->curr_n_bytes, index->id);
if (UNIV_LIKELY_NULL(heap)) {
@@ -1987,13 +1992,14 @@ void btr_search_update_hash_on_insert(btr_cur_t *cursor,
ins_rec = page_rec_get_next_const(rec);
next_rec = page_rec_get_next_const(ins_rec);
- offsets = rec_get_offsets(ins_rec, index, offsets, true,
+ offsets = rec_get_offsets(ins_rec, index, offsets,
+ index->n_core_fields,
ULINT_UNDEFINED, &heap);
ins_fold = rec_fold(ins_rec, offsets, n_fields, n_bytes, index->id);
if (!page_rec_is_supremum(next_rec)) {
offsets = rec_get_offsets(
- next_rec, index, offsets, true,
+ next_rec, index, offsets, index->n_core_fields,
btr_search_get_n_fields(n_fields, n_bytes), &heap);
next_fold = rec_fold(next_rec, offsets, n_fields,
n_bytes, index->id);
@@ -2005,7 +2011,7 @@ void btr_search_update_hash_on_insert(btr_cur_t *cursor,
if (!page_rec_is_infimum(rec) && !rec_is_metadata(rec, *index)) {
offsets = rec_get_offsets(
- rec, index, offsets, true,
+ rec, index, offsets, index->n_core_fields,
btr_search_get_n_fields(n_fields, n_bytes), &heap);
fold = rec_fold(rec, offsets, n_fields, n_bytes, index->id);
} else {
@@ -2232,7 +2238,8 @@ state_ok:
page_index_id = btr_page_get_index_id(block->frame);
offsets = rec_get_offsets(
- node->data, block->index, offsets, true,
+ node->data, block->index, offsets,
+ block->index->n_core_fields,
btr_search_get_n_fields(block->curr_n_fields,
block->curr_n_bytes),
&heap);
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index fd17f09148e..da8a2bce1ff 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2020, MariaDB Corporation.
+Copyright (c) 2013, 2021, 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
@@ -260,7 +260,7 @@ dict_table_try_drop_aborted(
&& !UT_LIST_GET_FIRST(table->locks)) {
/* Silence a debug assertion in row_merge_drop_indexes(). */
ut_d(table->acquire());
- row_merge_drop_indexes(trx, table, TRUE);
+ row_merge_drop_indexes(trx, table, true);
ut_d(table->release());
ut_ad(table->get_ref_count() == ref_count);
trx_commit_for_mysql(trx);
@@ -3928,7 +3928,9 @@ dict_index_build_node_ptr(
dtype_set(dfield_get_type(field), DATA_SYS_CHILD, DATA_NOT_NULL, 4);
- rec_copy_prefix_to_dtuple(tuple, rec, index, !level, n_unique, heap);
+ rec_copy_prefix_to_dtuple(tuple, rec, index,
+ level ? 0 : index->n_core_fields,
+ n_unique, heap);
dtuple_set_info_bits(tuple, dtuple_get_info_bits(tuple)
| REC_STATUS_NODE_PTR);
@@ -3952,11 +3954,14 @@ dict_index_build_data_tuple(
ulint n_fields,
mem_heap_t* heap)
{
+ ut_ad(!index->is_clust());
+
dtuple_t* tuple = dtuple_create(heap, n_fields);
dict_index_copy_types(tuple, index, n_fields);
- rec_copy_prefix_to_dtuple(tuple, rec, index, leaf, n_fields, heap);
+ rec_copy_prefix_to_dtuple(tuple, rec, index,
+ leaf ? n_fields : 0, n_fields, heap);
ut_ad(dtuple_check_typed(tuple));
diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc
index f4a56faaf28..b489dfd17bd 100644
--- a/storage/innobase/dict/dict0mem.cc
+++ b/storage/innobase/dict/dict0mem.cc
@@ -937,7 +937,7 @@ dict_mem_fill_vcol_from_v_indexes(
Later virtual column set will be
refreshed during loading of table. */
if (!dict_index_has_virtual(index)
- || index->has_new_v_col) {
+ || index->has_new_v_col()) {
continue;
}
@@ -1376,7 +1376,8 @@ dict_index_t::vers_history_row(
rec_t* clust_rec =
row_get_clust_rec(BTR_SEARCH_LEAF, rec, this, &clust_index, &mtr);
if (clust_rec) {
- offsets = rec_get_offsets(clust_rec, clust_index, offsets, true,
+ offsets = rec_get_offsets(clust_rec, clust_index, offsets,
+ clust_index->n_core_fields,
ULINT_UNDEFINED, &heap);
history_row = clust_index->vers_history_row(clust_rec, offsets);
diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc
index b6528e5d26c..bdca018813b 100644
--- a/storage/innobase/dict/dict0stats.cc
+++ b/storage/innobase/dict/dict0stats.cc
@@ -1167,7 +1167,7 @@ dict_stats_analyze_index_level(
prev_rec_offsets = rec_get_offsets(
prev_rec, index, prev_rec_offsets,
- true,
+ index->n_core_fields,
n_uniq, &heap);
prev_rec = rec_copy_prefix_to_buf(
@@ -1179,8 +1179,9 @@ dict_stats_analyze_index_level(
continue;
}
- rec_offsets = rec_get_offsets(
- rec, index, rec_offsets, !level, n_uniq, &heap);
+ rec_offsets = rec_get_offsets(rec, index, rec_offsets,
+ level ? 0 : index->n_core_fields,
+ n_uniq, &heap);
(*total_recs)++;
@@ -1188,7 +1189,8 @@ dict_stats_analyze_index_level(
ulint matched_fields;
prev_rec_offsets = rec_get_offsets(
- prev_rec, index, prev_rec_offsets, !level,
+ prev_rec, index, prev_rec_offsets,
+ level ? 0 : index->n_core_fields,
n_uniq, &heap);
cmp_rec_rec(prev_rec, rec,
@@ -1342,7 +1344,7 @@ be big enough)
@param[in] index index of the page
@param[in] page the page to scan
@param[in] n_prefix look at the first n_prefix columns
-@param[in] is_leaf whether this is the leaf page
+@param[in] n_core 0, or index->n_core_fields for leaf
@param[out] n_diff number of distinct records encountered
@param[out] n_external_pages if this is non-NULL then it will be set
to the number of externally stored pages which were encountered
@@ -1357,7 +1359,7 @@ dict_stats_scan_page(
const dict_index_t* index,
const page_t* page,
ulint n_prefix,
- bool is_leaf,
+ ulint n_core,
ib_uint64_t* n_diff,
ib_uint64_t* n_external_pages)
{
@@ -1369,9 +1371,9 @@ dict_stats_scan_page(
Because offsets1,offsets2 should be big enough,
this memory heap should never be used. */
mem_heap_t* heap = NULL;
- ut_ad(is_leaf == page_is_leaf(page));
+ ut_ad(!!n_core == page_is_leaf(page));
const rec_t* (*get_next)(const rec_t*)
- = !is_leaf || srv_stats_include_delete_marked
+ = !n_core || srv_stats_include_delete_marked
? page_rec_get_next_const
: page_rec_get_next_non_del_marked;
@@ -1390,7 +1392,7 @@ dict_stats_scan_page(
return(NULL);
}
- offsets_rec = rec_get_offsets(rec, index, offsets_rec, is_leaf,
+ offsets_rec = rec_get_offsets(rec, index, offsets_rec, n_core,
ULINT_UNDEFINED, &heap);
if (should_count_external_pages) {
@@ -1407,7 +1409,7 @@ dict_stats_scan_page(
ulint matched_fields;
offsets_next_rec = rec_get_offsets(next_rec, index,
- offsets_next_rec, is_leaf,
+ offsets_next_rec, n_core,
ULINT_UNDEFINED,
&heap);
@@ -1421,7 +1423,7 @@ dict_stats_scan_page(
(*n_diff)++;
- if (!is_leaf) {
+ if (!n_core) {
break;
}
}
@@ -1508,7 +1510,7 @@ dict_stats_analyze_index_below_cur(
page = page_align(rec);
ut_ad(!page_rec_is_leaf(rec));
- offsets_rec = rec_get_offsets(rec, index, offsets1, false,
+ offsets_rec = rec_get_offsets(rec, index, offsets1, 0,
ULINT_UNDEFINED, &heap);
page_id_t page_id(index->table->space_id,
@@ -1544,7 +1546,7 @@ dict_stats_analyze_index_below_cur(
/* search for the first non-boring record on the page */
offsets_rec = dict_stats_scan_page(
&rec, offsets1, offsets2, index, page, n_prefix,
- false, n_diff, NULL);
+ 0, n_diff, NULL);
/* pages on level > 0 are not allowed to be empty */
ut_a(offsets_rec != NULL);
@@ -1589,7 +1591,7 @@ dict_stats_analyze_index_below_cur(
offsets_rec = dict_stats_scan_page(
&rec, offsets1, offsets2, index, page, n_prefix,
- true, n_diff,
+ index->n_core_fields, n_diff,
n_external_pages);
#if 0
diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc
index 8b9cc02484c..52ff6d7bfe4 100644
--- a/storage/innobase/dict/dict0stats_bg.cc
+++ b/storage/innobase/dict/dict0stats_bg.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2020, MariaDB Corporation.
+Copyright (c) 2017, 2021, 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
@@ -146,9 +146,24 @@ schedule new estimates for table and index statistics to be calculated.
void dict_stats_update_if_needed_func(dict_table_t *table)
#endif
{
- ut_ad(table->stat_initialized);
dict_sys.assert_not_locked();
+ if (UNIV_UNLIKELY(!table->stat_initialized)) {
+ /* The table may have been evicted from dict_sys
+ and reloaded internally by InnoDB for FOREIGN KEY
+ processing, but not reloaded by the SQL layer.
+
+ We can (re)compute the transient statistics when the
+ table is actually loaded by the SQL layer.
+
+ Note: If InnoDB persistent statistics are enabled,
+ we will skip the updates. We must do this, because
+ dict_table_get_n_rows() below assumes that the
+ statistics have been initialized. The DBA may have
+ to execute ANALYZE TABLE. */
+ return;
+ }
+
ulonglong counter = table->stat_modified_counter++;
ulonglong n_rows = dict_table_get_n_rows(table);
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index cc7ffa4d8bc..ae88d0bd3c0 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -2507,7 +2507,8 @@ fts_get_max_cache_size(
}
} else {
ib::error() << "(" << error << ") reading max"
- " cache config value from config table";
+ " cache config value from config table "
+ << fts_table->table->name;
}
ut_free(value.f_str);
@@ -2680,7 +2681,8 @@ func_exit:
} else {
*doc_id = 0;
- ib::error() << "(" << error << ") while getting next doc id.";
+ ib::error() << "(" << error << ") while getting next doc id "
+ "for table " << table->name;
fts_sql_rollback(trx);
if (error == DB_DEADLOCK) {
@@ -2760,7 +2762,8 @@ fts_update_sync_doc_id(
cache->synced_doc_id = doc_id;
} else {
ib::error() << "(" << error << ") while"
- " updating last doc id.";
+ " updating last doc id for table"
+ << table->name;
fts_sql_rollback(trx);
}
@@ -3471,7 +3474,8 @@ fts_add_doc_by_id(
}
- offsets = rec_get_offsets(clust_rec, clust_index, NULL, true,
+ offsets = rec_get_offsets(clust_rec, clust_index, NULL,
+ clust_index->n_core_fields,
ULINT_UNDEFINED, &heap);
for (ulint i = 0; i < num_idx; ++i) {
@@ -3993,7 +3997,8 @@ fts_sync_write_words(
if (UNIV_UNLIKELY(error != DB_SUCCESS) && !print_error) {
ib::error() << "(" << error << ") writing"
- " word node to FTS auxiliary index table.";
+ " word node to FTS auxiliary index table "
+ << table->name;
print_error = TRUE;
}
}
@@ -4148,7 +4153,8 @@ fts_sync_commit(
fts_sql_commit(trx);
} else {
fts_sql_rollback(trx);
- ib::error() << "(" << error << ") during SYNC.";
+ ib::error() << "(" << error << ") during SYNC of "
+ "table " << sync->table->name;
}
if (UNIV_UNLIKELY(fts_enable_diag_print) && elapsed_time) {
@@ -4910,7 +4916,8 @@ fts_get_rows_count(
trx->error_state = DB_SUCCESS;
} else {
ib::error() << "(" << error
- << ") while reading FTS table.";
+ << ") while reading FTS table "
+ << table_name;
break; /* Exit the loop. */
}
diff --git a/storage/innobase/gis/gis0rtree.cc b/storage/innobase/gis/gis0rtree.cc
index fef850d1ca7..a003100b3a2 100644
--- a/storage/innobase/gis/gis0rtree.cc
+++ b/storage/innobase/gis/gis0rtree.cc
@@ -87,8 +87,9 @@ rtr_page_split_initialize_nodes(
stop = task + n_recs;
rec = page_rec_get_next(page_get_infimum_rec(page));
- const bool is_leaf = page_is_leaf(page);
- *offsets = rec_get_offsets(rec, cursor->index, *offsets, is_leaf,
+ const ulint n_core = page_is_leaf(page)
+ ? cursor->index->n_core_fields : 0;
+ *offsets = rec_get_offsets(rec, cursor->index, *offsets, n_core,
n_uniq, &heap);
source_cur = rec_get_nth_field(rec, *offsets, 0, &len);
@@ -101,7 +102,7 @@ rtr_page_split_initialize_nodes(
rec = page_rec_get_next(rec);
*offsets = rec_get_offsets(rec, cursor->index, *offsets,
- is_leaf, n_uniq, &heap);
+ n_core, n_uniq, &heap);
source_cur = rec_get_nth_field(rec, *offsets, 0, &len);
}
@@ -230,7 +231,8 @@ rtr_update_mbr_field(
ut_ad(page == buf_block_get_frame(block));
child = btr_node_ptr_get_child_page_no(rec, offsets);
- const bool is_leaf = page_is_leaf(block->frame);
+ const ulint n_core = page_is_leaf(block->frame)
+ ? index->n_core_fields : 0;
if (new_rec) {
child_rec = new_rec;
@@ -246,7 +248,7 @@ rtr_update_mbr_field(
if (cursor2) {
rec_t* del_rec = btr_cur_get_rec(cursor2);
offsets2 = rec_get_offsets(btr_cur_get_rec(cursor2),
- index, NULL, false,
+ index, NULL, 0,
ULINT_UNDEFINED, &heap);
del_page_no = btr_node_ptr_get_child_page_no(del_rec, offsets2);
cur2_pos = page_rec_get_n_recs_before(btr_cur_get_rec(cursor2));
@@ -313,7 +315,7 @@ rtr_update_mbr_field(
= page_rec_get_nth(page, cur2_pos);
}
offsets2 = rec_get_offsets(btr_cur_get_rec(cursor2),
- index, NULL, false,
+ index, NULL, 0,
ULINT_UNDEFINED, &heap);
ut_ad(del_page_no == btr_node_ptr_get_child_page_no(
cursor2->page_cur.rec,
@@ -351,7 +353,7 @@ rtr_update_mbr_field(
ut_ad(old_rec != insert_rec);
page_cur_position(old_rec, block, &page_cur);
- offsets2 = rec_get_offsets(old_rec, index, NULL, is_leaf,
+ offsets2 = rec_get_offsets(old_rec, index, NULL, n_core,
ULINT_UNDEFINED, &heap);
page_cur_delete_rec(&page_cur, index, offsets2, mtr);
@@ -381,7 +383,7 @@ update_mbr:
cur2_rec = cursor2->page_cur.rec;
offsets2 = rec_get_offsets(cur2_rec, index, NULL,
- is_leaf,
+ n_core,
ULINT_UNDEFINED, &heap);
cur2_rec_info = rec_get_info_bits(cur2_rec,
@@ -441,7 +443,7 @@ update_mbr:
if (ins_suc) {
btr_cur_position(index, insert_rec, block, cursor);
offsets = rec_get_offsets(insert_rec,
- index, offsets, is_leaf,
+ index, offsets, n_core,
ULINT_UNDEFINED, &heap);
}
@@ -456,7 +458,7 @@ update_mbr:
cur2_rec = btr_cur_get_rec(cursor2);
offsets2 = rec_get_offsets(cur2_rec, index, NULL,
- is_leaf,
+ n_core,
ULINT_UNDEFINED, &heap);
/* If the cursor2 position is on a wrong rec, we
@@ -470,7 +472,7 @@ update_mbr:
while (!page_rec_is_supremum(cur2_rec)) {
offsets2 = rec_get_offsets(cur2_rec, index,
NULL,
- is_leaf,
+ n_core,
ULINT_UNDEFINED,
&heap);
cur2_pno = btr_node_ptr_get_child_page_no(
@@ -747,7 +749,8 @@ rtr_split_page_move_rec_list(
rec_move = static_cast<rtr_rec_move_t*>(mem_heap_alloc(
heap,
sizeof (*rec_move) * max_to_move));
- const bool is_leaf = page_is_leaf(page);
+ const ulint n_core = page_is_leaf(page)
+ ? index->n_core_fields : 0;
/* Insert the recs in group 2 to new page. */
for (cur_split_node = node_array;
@@ -757,10 +760,10 @@ rtr_split_page_move_rec_list(
block, cur_split_node->key);
offsets = rec_get_offsets(cur_split_node->key,
- index, offsets, is_leaf,
+ index, offsets, n_core,
ULINT_UNDEFINED, &heap);
- ut_ad(!is_leaf || cur_split_node->key != first_rec);
+ ut_ad(!n_core || cur_split_node->key != first_rec);
rec = page_cur_insert_rec_low(
&new_page_cursor,
@@ -792,7 +795,7 @@ rtr_split_page_move_rec_list(
same temp-table in parallel.
max_trx_id is ignored for temp tables because it not required
for MVCC. */
- if (is_leaf && !index->table->is_temporary()) {
+ if (n_core && !index->table->is_temporary()) {
page_update_max_trx_id(new_block, NULL,
page_get_max_trx_id(page),
mtr);
@@ -846,7 +849,7 @@ rtr_split_page_move_rec_list(
block, &page_cursor);
offsets = rec_get_offsets(
page_cur_get_rec(&page_cursor), index,
- offsets, is_leaf, ULINT_UNDEFINED,
+ offsets, n_core, ULINT_UNDEFINED,
&heap);
page_cur_delete_rec(&page_cursor,
index, offsets, mtr);
@@ -1049,6 +1052,9 @@ func_start:
/* Update the lock table */
lock_rtr_move_rec_list(new_block, block, rec_move, moved);
+ const ulint n_core = page_level
+ ? 0 : cursor->index->n_core_fields;
+
/* Delete recs in first group from the new page. */
for (cur_split_node = rtr_split_node_array;
cur_split_node < end_split_node - 1; ++cur_split_node) {
@@ -1067,7 +1073,7 @@ func_start:
*offsets = rec_get_offsets(
page_cur_get_rec(page_cursor),
- cursor->index, *offsets, !page_level,
+ cursor->index, *offsets, n_core,
ULINT_UNDEFINED, heap);
page_cur_delete_rec(page_cursor,
@@ -1084,7 +1090,7 @@ func_start:
block, page_cursor);
*offsets = rec_get_offsets(
page_cur_get_rec(page_cursor),
- cursor->index, *offsets, !page_level,
+ cursor->index, *offsets, n_core,
ULINT_UNDEFINED, heap);
page_cur_delete_rec(page_cursor,
cursor->index, *offsets, mtr);
@@ -1312,7 +1318,8 @@ rtr_page_copy_rec_list_end_no_locks(
rec_offs offsets_2[REC_OFFS_NORMAL_SIZE];
rec_offs* offsets2 = offsets_2;
ulint moved = 0;
- bool is_leaf = page_is_leaf(new_page);
+ const ulint n_core = page_is_leaf(new_page)
+ ? index->n_core_fields : 0;
rec_offs_init(offsets_1);
rec_offs_init(offsets_2);
@@ -1341,14 +1348,14 @@ rtr_page_copy_rec_list_end_no_locks(
cur_rec = page_rec_get_next(cur_rec);
}
- offsets1 = rec_get_offsets(cur1_rec, index, offsets1, is_leaf,
+ offsets1 = rec_get_offsets(cur1_rec, index, offsets1, n_core,
ULINT_UNDEFINED, &heap);
while (!page_rec_is_supremum(cur_rec)) {
ulint cur_matched_fields = 0;
int cmp;
offsets2 = rec_get_offsets(cur_rec, index, offsets2,
- is_leaf,
+ n_core,
ULINT_UNDEFINED, &heap);
cmp = cmp_rec_rec(cur1_rec, cur_rec,
offsets1, offsets2, index, false,
@@ -1360,7 +1367,7 @@ rtr_page_copy_rec_list_end_no_locks(
/* Skip small recs. */
page_cur_move_to_next(&page_cur);
cur_rec = page_cur_get_rec(&page_cur);
- } else if (is_leaf) {
+ } else if (n_core) {
if (rec_get_deleted_flag(cur1_rec,
dict_table_is_comp(index->table))) {
goto next;
@@ -1383,7 +1390,7 @@ rtr_page_copy_rec_list_end_no_locks(
cur_rec = page_cur_get_rec(&page_cur);
- offsets1 = rec_get_offsets(cur1_rec, index, offsets1, is_leaf,
+ offsets1 = rec_get_offsets(cur1_rec, index, offsets1, n_core,
ULINT_UNDEFINED, &heap);
ins_rec = page_cur_insert_rec_low(&page_cur, index,
@@ -1439,7 +1446,8 @@ rtr_page_copy_rec_list_start_no_locks(
rec_offs* offsets2 = offsets_2;
page_cur_t page_cur;
ulint moved = 0;
- bool is_leaf = page_is_leaf(buf_block_get_frame(block));
+ const ulint n_core = page_is_leaf(buf_block_get_frame(block))
+ ? index->n_core_fields : 0;
rec_offs_init(offsets_1);
rec_offs_init(offsets_2);
@@ -1459,14 +1467,14 @@ rtr_page_copy_rec_list_start_no_locks(
cur_rec = page_rec_get_next(cur_rec);
}
- offsets1 = rec_get_offsets(cur1_rec, index, offsets1, is_leaf,
+ offsets1 = rec_get_offsets(cur1_rec, index, offsets1, n_core,
ULINT_UNDEFINED, &heap);
while (!page_rec_is_supremum(cur_rec)) {
ulint cur_matched_fields = 0;
offsets2 = rec_get_offsets(cur_rec, index, offsets2,
- is_leaf,
+ n_core,
ULINT_UNDEFINED, &heap);
int cmp = cmp_rec_rec(cur1_rec, cur_rec,
offsets1, offsets2, index, false,
@@ -1479,7 +1487,7 @@ rtr_page_copy_rec_list_start_no_locks(
/* Skip small recs. */
page_cur_move_to_next(&page_cur);
cur_rec = page_cur_get_rec(&page_cur);
- } else if (is_leaf) {
+ } else if (n_core) {
if (rec_get_deleted_flag(
cur1_rec,
dict_table_is_comp(index->table))) {
@@ -1503,7 +1511,7 @@ rtr_page_copy_rec_list_start_no_locks(
cur_rec = page_cur_get_rec(&page_cur);
- offsets1 = rec_get_offsets(cur1_rec, index, offsets1, is_leaf,
+ offsets1 = rec_get_offsets(cur1_rec, index, offsets1, n_core,
ULINT_UNDEFINED, &heap);
ins_rec = page_cur_insert_rec_low(&page_cur, index,
@@ -1654,7 +1662,7 @@ rtr_check_same_block(
while (!page_rec_is_supremum(rec)) {
offsets = rec_get_offsets(
- rec, index, NULL, false, ULINT_UNDEFINED, &heap);
+ rec, index, NULL, 0, ULINT_UNDEFINED, &heap);
if (btr_node_ptr_get_child_page_no(rec, offsets) == page_no) {
btr_cur_position(index, rec, parentb, cursor);
diff --git a/storage/innobase/gis/gis0sea.cc b/storage/innobase/gis/gis0sea.cc
index 1d882d48aa9..f067d43d6a3 100644
--- a/storage/innobase/gis/gis0sea.cc
+++ b/storage/innobase/gis/gis0sea.cc
@@ -520,8 +520,7 @@ rtr_compare_cursor_rec(
rec = btr_cur_get_rec(cursor);
- offsets = rec_get_offsets(
- rec, index, NULL, false, ULINT_UNDEFINED, heap);
+ offsets = rec_get_offsets(rec, index, NULL, 0, ULINT_UNDEFINED, heap);
return(btr_node_ptr_get_child_page_no(rec, offsets) == page_no);
}
@@ -801,7 +800,8 @@ rtr_page_get_father_node_ptr(
user_rec = btr_cur_get_rec(cursor);
ut_a(page_rec_is_user_rec(user_rec));
- offsets = rec_get_offsets(user_rec, index, offsets, !level,
+ offsets = rec_get_offsets(user_rec, index, offsets,
+ level ? 0 : index->n_fields,
ULINT_UNDEFINED, &heap);
rtr_get_mbr_from_rec(user_rec, offsets, &mbr);
@@ -818,7 +818,7 @@ rtr_page_get_father_node_ptr(
node_ptr = btr_cur_get_rec(cursor);
ut_ad(!page_rec_is_comp(node_ptr)
|| rec_get_status(node_ptr) == REC_STATUS_NODE_PTR);
- offsets = rec_get_offsets(node_ptr, index, offsets, false,
+ offsets = rec_get_offsets(node_ptr, index, offsets, 0,
ULINT_UNDEFINED, &heap);
ulint child_page = btr_node_ptr_get_child_page_no(node_ptr, offsets);
@@ -836,13 +836,14 @@ rtr_page_get_father_node_ptr(
print_rec = page_rec_get_next(
page_get_infimum_rec(page_align(user_rec)));
offsets = rec_get_offsets(print_rec, index, offsets,
- page_rec_is_leaf(user_rec),
+ page_rec_is_leaf(user_rec)
+ ? index->n_fields : 0,
ULINT_UNDEFINED, &heap);
error << "; child ";
rec_print(error.m_oss, print_rec,
rec_get_info_bits(print_rec, rec_offs_comp(offsets)),
offsets);
- offsets = rec_get_offsets(node_ptr, index, offsets, false,
+ offsets = rec_get_offsets(node_ptr, index, offsets, 0,
ULINT_UNDEFINED, &heap);
error << "; parent ";
rec_print(error.m_oss, print_rec,
@@ -1266,10 +1267,12 @@ rtr_cur_restore_position(
heap = mem_heap_create(256);
offsets1 = rec_get_offsets(
- r_cursor->old_rec, index, NULL, !level,
+ r_cursor->old_rec, index, NULL,
+ level ? 0 : r_cursor->old_n_fields,
r_cursor->old_n_fields, &heap);
offsets2 = rec_get_offsets(
- rec, index, NULL, !level,
+ rec, index, NULL,
+ level ? 0 : r_cursor->old_n_fields,
r_cursor->old_n_fields, &heap);
comp = rec_offs_comp(offsets1);
@@ -1333,12 +1336,12 @@ search_again:
rec = btr_pcur_get_rec(r_cursor);
- offsets1 = rec_get_offsets(
- r_cursor->old_rec, index, NULL, !level,
- r_cursor->old_n_fields, &heap);
- offsets2 = rec_get_offsets(
- rec, index, NULL, !level,
- r_cursor->old_n_fields, &heap);
+ offsets1 = rec_get_offsets(r_cursor->old_rec, index, NULL,
+ level ? 0 : r_cursor->old_n_fields,
+ r_cursor->old_n_fields, &heap);
+ offsets2 = rec_get_offsets(rec, index, NULL,
+ level ? 0 : r_cursor->old_n_fields,
+ r_cursor->old_n_fields, &heap);
comp = rec_offs_comp(offsets1);
@@ -1674,7 +1677,7 @@ rtr_cur_search_with_match(
page = buf_block_get_frame(block);
const ulint level = btr_page_get_level(page);
- const bool is_leaf = !level;
+ const ulint n_core = level ? 0 : index->n_fields;
if (mode == PAGE_CUR_RTREE_LOCATE) {
ut_ad(level != 0);
@@ -1696,7 +1699,7 @@ rtr_cur_search_with_match(
ulint new_rec_size = rec_get_converted_size(index, tuple, 0);
- offsets = rec_get_offsets(rec, index, offsets, is_leaf,
+ offsets = rec_get_offsets(rec, index, offsets, n_core,
dtuple_get_n_fields_cmp(tuple),
&heap);
@@ -1717,7 +1720,7 @@ rtr_cur_search_with_match(
}
while (!page_rec_is_supremum(rec)) {
- if (!is_leaf) {
+ if (!n_core) {
switch (mode) {
case PAGE_CUR_CONTAIN:
case PAGE_CUR_INTERSECT:
@@ -1798,7 +1801,7 @@ rtr_cur_search_with_match(
to rtr_info->path for non-leaf nodes, or
rtr_info->matches for leaf nodes */
if (rtr_info && mode != PAGE_CUR_RTREE_INSERT) {
- if (!is_leaf) {
+ if (!n_core) {
uint32_t page_no;
node_seq_t new_seq;
bool is_loc;
@@ -1809,7 +1812,7 @@ rtr_cur_search_with_match(
== PAGE_CUR_RTREE_GET_FATHER);
offsets = rec_get_offsets(
- rec, index, offsets, false,
+ rec, index, offsets, 0,
ULINT_UNDEFINED, &heap);
page_no = btr_node_ptr_get_child_page_no(
@@ -1862,7 +1865,8 @@ rtr_cur_search_with_match(
/* Collect matched records on page */
offsets = rec_get_offsets(
- rec, index, offsets, true,
+ rec, index, offsets,
+ index->n_fields,
ULINT_UNDEFINED, &heap);
rtr_leaf_push_match_rec(
rec, rtr_info, offsets,
@@ -1885,7 +1889,7 @@ rtr_cur_search_with_match(
/* All records on page are searched */
if (page_rec_is_supremum(rec)) {
- if (!is_leaf) {
+ if (!n_core) {
if (!found) {
/* No match case, if it is for insertion,
then we select the record that result in
@@ -1894,7 +1898,7 @@ rtr_cur_search_with_match(
ut_ad(least_inc < DBL_MAX);
offsets = rec_get_offsets(
best_rec, index, offsets,
- false, ULINT_UNDEFINED, &heap);
+ 0, ULINT_UNDEFINED, &heap);
uint32_t child_no =
btr_node_ptr_get_child_page_no(
best_rec, offsets);
@@ -1946,11 +1950,11 @@ rtr_cur_search_with_match(
/* Verify the record to be positioned is the same
as the last record in matched_rec vector */
offsets2 = rec_get_offsets(test_rec.r_rec, index,
- offsets2, true,
+ offsets2, index->n_fields,
ULINT_UNDEFINED, &heap);
offsets = rec_get_offsets(last_match_rec, index,
- offsets, true,
+ offsets, index->n_fields,
ULINT_UNDEFINED, &heap);
ut_ad(cmp_rec_rec(test_rec.r_rec, last_match_rec,
@@ -1970,7 +1974,7 @@ rtr_cur_search_with_match(
mach_read_from_4(rec + DATA_MBR_LEN),
block, rec, 0);
- } else if (rtr_info && found && !is_leaf) {
+ } else if (rtr_info && found && !n_core) {
rec = last_match_rec;
}
@@ -1980,11 +1984,11 @@ rtr_cur_search_with_match(
#ifdef UNIV_DEBUG
/* Verify that we are positioned at the same child page as pushed in
the path stack */
- if (!is_leaf && (!page_rec_is_supremum(rec) || found)
+ if (!n_core && (!page_rec_is_supremum(rec) || found)
&& mode != PAGE_CUR_RTREE_INSERT) {
ulint page_no;
- offsets = rec_get_offsets(rec, index, offsets, false,
+ offsets = rec_get_offsets(rec, index, offsets, 0,
ULINT_UNDEFINED, &heap);
page_no = btr_node_ptr_get_child_page_no(rec, offsets);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 7ffbe3fe374..b9f5984f3f4 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -8036,26 +8036,24 @@ wsrep_calc_row_hash(
dictionary */
row_prebuilt_t* prebuilt) /*!< in: InnoDB prebuilt struct */
{
- ulint len;
- const byte* ptr;
-
void *ctx = alloca(my_md5_context_size());
my_md5_init(ctx);
for (uint i = 0; i < table->s->fields; i++) {
byte null_byte=0;
byte true_byte=1;
+ unsigned is_unsigned;
const Field* field = table->field[i];
if (!field->stored_in_db()) {
continue;
}
- ptr = (const byte*) row + get_field_offset(table, field);
- len = field->pack_length();
-
- switch (prebuilt->table->cols[i].mtype) {
+ auto ptr = row + get_field_offset(table, field);
+ ulint len = field->pack_length();
+ switch (get_innobase_type_from_mysql_type(&is_unsigned,
+ field)) {
case DATA_BLOB:
ptr = row_mysql_read_blob_ref(&len, ptr, len);
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 58e17cd3ead..298f8347053 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -1023,13 +1023,6 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx
@return whether the table will be rebuilt */
bool need_rebuild () const { return(old_table != new_table); }
- /** Clear uncommmitted added indexes after a failed operation. */
- void clear_added_indexes()
- {
- for (ulint i= 0; i < num_to_add_index; i++)
- add_index[i]->detach_columns(true);
- }
-
/** Convert table-rebuilding ALTER to instant ALTER. */
void prepare_instant()
{
@@ -1127,6 +1120,42 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx
}
}
+ /** @return whether the given column is being added */
+ bool is_new_vcol(const dict_v_col_t &v_col) const
+ {
+ for (ulint i= 0; i < num_to_add_vcol; i++)
+ if (&add_vcol[i] == &v_col)
+ return true;
+ return false;
+ }
+
+ /** During rollback, make newly added indexes point to
+ newly added virtual columns. */
+ void clean_new_vcol_index()
+ {
+ ut_ad(old_table == new_table);
+ const dict_index_t *index= dict_table_get_first_index(old_table);
+ while ((index= dict_table_get_next_index(index)) != NULL)
+ {
+ if (!index->has_virtual() || index->is_committed())
+ continue;
+ ulint n_drop_new_vcol= index->get_new_n_vcol();
+ for (ulint i= 0; n_drop_new_vcol && i < index->n_fields; i++)
+ {
+ dict_col_t *col= index->fields[i].col;
+ /* Skip the non-virtual and old virtual columns */
+ if (!col->is_virtual())
+ continue;
+ dict_v_col_t *vcol= reinterpret_cast<dict_v_col_t*>(col);
+ if (!is_new_vcol(*vcol))
+ continue;
+
+ index->fields[i].col= &index->new_vcol_info->
+ add_drop_v_col(index->heap, vcol, --n_drop_new_vcol)->m_col;
+ }
+ }
+ }
+
private:
// Disable copying
ha_innobase_inplace_ctx(const ha_innobase_inplace_ctx&);
@@ -3731,9 +3760,11 @@ innobase_fts_check_doc_id_index(
for (index = dict_table_get_first_index(table);
index; index = dict_table_get_next_index(index)) {
+
/* Check if there exists a unique index with the name of
- FTS_DOC_ID_INDEX_NAME */
- if (innobase_strcasecmp(index->name, FTS_DOC_ID_INDEX_NAME)) {
+ FTS_DOC_ID_INDEX_NAME and ignore the corrupted index */
+ if (index->type & DICT_CORRUPT
+ || innobase_strcasecmp(index->name, FTS_DOC_ID_INDEX_NAME)) {
continue;
}
@@ -4041,7 +4072,7 @@ online_retry_drop_indexes_low(
ut_ad(table->get_ref_count() >= 1);
if (table->drop_aborted) {
- row_merge_drop_indexes(trx, table, TRUE);
+ row_merge_drop_indexes(trx, table, true);
}
}
@@ -5901,7 +5932,7 @@ add_all_virtual:
offsets = rec_get_offsets(
btr_pcur_get_rec(&pcur), index, offsets,
- true, ULINT_UNDEFINED, &offsets_heap);
+ index->n_core_fields, ULINT_UNDEFINED, &offsets_heap);
if (big_rec) {
if (err == DB_SUCCESS) {
err = btr_store_big_rec_extern_fields(
@@ -6812,7 +6843,7 @@ new_table_failed:
for (ulint a = 0; a < ctx->num_to_add_index; a++) {
dict_index_t* index = ctx->add_index[a];
- const bool has_new_v_col = index->has_new_v_col;
+ const ulint n_v_col = index->get_new_n_vcol();
index = create_index_dict(ctx->trx, index, add_v);
error = ctx->trx->error_state;
if (error != DB_SUCCESS) {
@@ -6842,7 +6873,9 @@ error_handling_drop_uncached_1:
goto error_handling_drop_uncached_1;
}
index->parser = index_defs[a].parser;
- index->has_new_v_col = has_new_v_col;
+ if (n_v_col) {
+ index->assign_new_v_col(n_v_col);
+ }
/* Note the id of the transaction that created this
index, we use it to restrict readers from accessing
this index, to ensure read consistency. */
@@ -6913,7 +6946,7 @@ error_handling_drop_uncached_1:
for (ulint a = 0; a < ctx->num_to_add_index; a++) {
dict_index_t* index = ctx->add_index[a];
- const bool has_new_v_col = index->has_new_v_col;
+ const ulint n_v_col = index->get_new_n_vcol();
DBUG_EXECUTE_IF(
"create_index_metadata_fail",
if (a + 1 == ctx->num_to_add_index) {
@@ -6945,7 +6978,9 @@ error_handling_drop_uncached:
}
index->parser = index_defs[a].parser;
- index->has_new_v_col = has_new_v_col;
+ if (n_v_col) {
+ index->assign_new_v_col(n_v_col);
+ }
/* Note the id of the transaction that created this
index, we use it to restrict readers from accessing
this index, to ensure read consistency. */
@@ -7172,7 +7207,7 @@ error_handled:
online_retry_drop_indexes_with_trx(user_table, ctx->trx);
} else {
ut_ad(!ctx->need_rebuild());
- row_merge_drop_indexes(ctx->trx, user_table, TRUE);
+ row_merge_drop_indexes(ctx->trx, user_table, true);
trx_commit_for_mysql(ctx->trx);
}
@@ -8532,7 +8567,6 @@ oom:
that we hold at most a shared lock on the table. */
m_prebuilt->trx->error_info = NULL;
ctx->trx->error_state = DB_SUCCESS;
- ctx->clear_added_indexes();
DBUG_RETURN(true);
}
@@ -8624,17 +8658,18 @@ temparary index prefix
@param table the TABLE
@param locked TRUE=table locked, FALSE=may need to do a lazy drop
@param trx the transaction
-*/
-static MY_ATTRIBUTE((nonnull))
+@param alter_trx transaction which takes S-lock on the table
+ while creating the index */
+static
void
innobase_rollback_sec_index(
-/*========================*/
- dict_table_t* user_table,
- const TABLE* table,
- ibool locked,
- trx_t* trx)
+ dict_table_t* user_table,
+ const TABLE* table,
+ bool locked,
+ trx_t* trx,
+ const trx_t* alter_trx=NULL)
{
- row_merge_drop_indexes(trx, user_table, locked);
+ row_merge_drop_indexes(trx, user_table, locked, alter_trx);
/* Free the table->fts only if there is no FTS_DOC_ID
in the table */
@@ -8762,7 +8797,12 @@ rollback_inplace_alter_table(
}
innobase_rollback_sec_index(
- prebuilt->table, table, FALSE, ctx->trx);
+ prebuilt->table, table,
+ (ha_alter_info->alter_info->requested_lock
+ == Alter_info::ALTER_TABLE_LOCK_EXCLUSIVE),
+ ctx->trx, prebuilt->trx);
+
+ ctx->clean_new_vcol_index();
}
trx_commit_for_mysql(ctx->trx);
diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc
index d28aca23de1..d357011bf22 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.cc
+++ b/storage/innobase/ibuf/ibuf0ibuf.cc
@@ -3722,7 +3722,7 @@ dump:
row_ins_sec_index_entry_by_modify(BTR_MODIFY_LEAF). */
ut_ad(rec_get_deleted_flag(rec, page_is_comp(page)));
- offsets = rec_get_offsets(rec, index, NULL, true,
+ offsets = rec_get_offsets(rec, index, NULL, index->n_fields,
ULINT_UNDEFINED, &heap);
update = row_upd_build_sec_rec_difference_binary(
rec, index, offsets, entry, heap);
@@ -3882,7 +3882,8 @@ ibuf_delete(
ut_ad(ibuf_inside(mtr));
ut_ad(dtuple_check_typed(entry));
- ut_ad(!dict_index_is_spatial(index));
+ ut_ad(!index->is_spatial());
+ ut_ad(!index->is_clust());
low_match = page_cur_search(block, index, entry, &page_cur);
@@ -3901,8 +3902,8 @@ ibuf_delete(
rec_offs_init(offsets_);
- offsets = rec_get_offsets(
- rec, index, offsets, true, ULINT_UNDEFINED, &heap);
+ offsets = rec_get_offsets(rec, index, offsets, index->n_fields,
+ ULINT_UNDEFINED, &heap);
if (page_get_n_recs(page) <= 1
|| !(REC_INFO_DELETED_FLAG
diff --git a/storage/innobase/include/btr0bulk.h b/storage/innobase/include/btr0bulk.h
index 375b7b34fe4..943836f8759 100644
--- a/storage/innobase/include/btr0bulk.h
+++ b/storage/innobase/include/btr0bulk.h
@@ -314,6 +314,8 @@ public:
/** Re-latch all latches */
void latch();
+ table_name_t table_name() { return m_index->table->name; }
+
private:
/** Insert a tuple to a page in a level
@param[in] tuple tuple to insert
diff --git a/storage/innobase/include/btr0pcur.h b/storage/innobase/include/btr0pcur.h
index 745a2c969fc..312e51971bb 100644
--- a/storage/innobase/include/btr0pcur.h
+++ b/storage/innobase/include/btr0pcur.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2020, MariaDB Corporation.
+Copyright (c) 2017, 2021, 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
@@ -477,8 +477,10 @@ struct btr_pcur_t{
/** if cursor position is stored, contains an initial segment of the
latest record cursor was positioned either on, before or after */
rec_t* old_rec;
+ /** btr_cur.index->n_core_fields when old_rec was copied */
+ uint16 old_n_core_fields;
/** number of fields in old_rec */
- ulint old_n_fields;
+ uint16 old_n_fields;
/** BTR_PCUR_ON, BTR_PCUR_BEFORE, or BTR_PCUR_AFTER, depending on
whether cursor was on, before, or after the old_rec record */
enum btr_pcur_pos_t rel_pos;
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 43d55b765ee..a7f04c3015e 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -790,6 +790,35 @@ struct dict_v_col_t{
}
};
+/** Data structure for newly added virtual column in a index.
+It is used only during rollback_inplace_alter_table() of
+addition of index depending on newly added virtual columns
+and uses index heap. Should be freed when index is being
+removed from cache. */
+struct dict_add_v_col_info
+{
+ ulint n_v_col;
+ dict_v_col_t *v_col;
+
+ /** Add the newly added virtual column while rollbacking
+ the index which contains new virtual columns
+ @param col virtual column to be duplicated
+ @param offset offset where to duplicate virtual column */
+ dict_v_col_t* add_drop_v_col(mem_heap_t *heap, dict_v_col_t *col,
+ ulint offset)
+ {
+ ut_ad(n_v_col);
+ ut_ad(offset < n_v_col);
+ if (!v_col)
+ v_col= static_cast<dict_v_col_t*>
+ (mem_heap_alloc(heap, n_v_col * sizeof *v_col));
+ new (&v_col[offset]) dict_v_col_t();
+ v_col[offset].m_col= col->m_col;
+ v_col[offset].v_pos= col->v_pos;
+ return &v_col[offset];
+ }
+};
+
/** Data structure for newly added virtual column in a table */
struct dict_add_v_col_t{
/** number of new virtual column */
@@ -1037,9 +1066,12 @@ struct dict_index_t {
dict_field_t* fields; /*!< array of field descriptions */
st_mysql_ftparser*
parser; /*!< fulltext parser plugin */
- bool has_new_v_col;
- /*!< whether it has a newly added virtual
- column in ALTER */
+
+ /** It just indicates whether newly added virtual column
+ during alter. It stores column in case of alter failure.
+ It should use heap from dict_index_t. It should be freed
+ while removing the index from table. */
+ dict_add_v_col_info* new_vcol_info;
UT_LIST_NODE_T(dict_index_t)
indexes;/*!< list of indexes of the table */
#ifdef BTR_CUR_ADAPT
@@ -1199,9 +1231,8 @@ public:
/** @return whether the index is corrupted */
inline bool is_corrupted() const;
- /** Detach the virtual columns from the index that is to be removed.
- @param whether to reset fields[].col */
- void detach_columns(bool clear= false)
+ /** Detach the virtual columns from the index that is to be removed. */
+ void detach_columns()
{
if (!has_virtual() || !cached)
return;
@@ -1211,8 +1242,6 @@ public:
if (!col || !col->is_virtual())
continue;
col->detach(*this);
- if (clear)
- fields[i].col= nullptr;
}
}
@@ -1275,6 +1304,23 @@ public:
bool
vers_history_row(const rec_t* rec, bool &history_row);
+ /** Assign the number of new column to be added as a part
+ of the index
+ @param n_vcol number of virtual columns to be added */
+ void assign_new_v_col(ulint n_vcol)
+ {
+ new_vcol_info= static_cast<dict_add_v_col_info*>
+ (mem_heap_zalloc(heap, sizeof *new_vcol_info));
+ new_vcol_info->n_v_col= n_vcol;
+ }
+
+ /* @return whether index has new virtual column */
+ bool has_new_v_col() const { return new_vcol_info; }
+
+ /* @return number of newly added virtual column */
+ ulint get_new_n_vcol() const
+ { return new_vcol_info ? new_vcol_info->n_v_col : 0; }
+
/** Reconstruct the clustered index fields. */
inline void reconstruct_fields();
@@ -2385,6 +2431,17 @@ public:
/** mysql_row_templ_t for base columns used for compute the virtual
columns */
dict_vcol_templ_t* vc_templ;
+
+ /* @return whether the table has any other transcation lock
+ other than the given transaction */
+ bool has_lock_other_than(const trx_t *trx) const
+ {
+ for (lock_t *lock= UT_LIST_GET_FIRST(locks); lock;
+ lock= UT_LIST_GET_NEXT(un_member.tab_lock.locks, lock))
+ if (lock->trx != trx)
+ return true;
+ return false;
+ }
};
inline void dict_index_t::set_modified(mtr_t& mtr) const
diff --git a/storage/innobase/include/gis0rtree.ic b/storage/innobase/include/gis0rtree.ic
index cb47c12da80..2564df7e0d6 100644
--- a/storage/innobase/include/gis0rtree.ic
+++ b/storage/innobase/include/gis0rtree.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2014, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2020, MariaDB Corporation.
+Copyright (c) 2017, 2021, 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
@@ -57,7 +57,8 @@ rtr_page_cal_mbr(
page = buf_block_get_frame(block);
rec = page_rec_get_next(page_get_infimum_rec(page));
- offsets = rec_get_offsets(rec, index, offsets, page_is_leaf(page),
+ offsets = rec_get_offsets(rec, index, offsets, page_is_leaf(page)
+ ? index->n_fields : 0,
ULINT_UNDEFINED, &heap);
do {
diff --git a/storage/innobase/include/page0cur.ic b/storage/innobase/include/page0cur.ic
index e8f7afcaf01..828be6840d2 100644
--- a/storage/innobase/include/page0cur.ic
+++ b/storage/innobase/include/page0cur.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2020, MariaDB Corporation.
+Copyright (c) 2015, 2021, 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
@@ -273,7 +273,8 @@ page_cur_tuple_insert(
index, tuple, n_ext);
*offsets = rec_get_offsets(rec, index, *offsets,
- page_is_leaf(cursor->block->frame),
+ page_is_leaf(cursor->block->frame)
+ ? index->n_core_fields : 0,
ULINT_UNDEFINED, heap);
ut_ad(size == rec_offs_size(*offsets));
diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h
index cda0d38ba44..dbcff3e6fd6 100644
--- a/storage/innobase/include/rem0rec.h
+++ b/storage/innobase/include/rem0rec.h
@@ -466,7 +466,7 @@ rec_get_n_extern_new(
@param[in] index the index that the record belongs to
@param[in,out] offsets array comprising offsets[0] allocated elements,
or an array from rec_get_offsets(), or NULL
-@param[in] leaf whether this is a leaf-page record
+@param[in] n_core 0, or index->n_core_fields for leaf page
@param[in] n_fields maximum number of offsets to compute
(ULINT_UNDEFINED to compute all offsets)
@param[in,out] heap memory heap
@@ -476,7 +476,7 @@ rec_get_offsets_func(
const rec_t* rec,
const dict_index_t* index,
rec_offs* offsets,
- bool leaf,
+ ulint n_core,
ulint n_fields,
#ifdef UNIV_DEBUG
const char* file, /*!< in: file name where called */
@@ -1082,7 +1082,9 @@ rec_get_converted_size(
The fields are copied into the memory heap.
@param[out] tuple data tuple
@param[in] rec index record, or a copy thereof
-@param[in] is_leaf whether rec is a leaf page record
+@param[in] index index of rec
+@param[in] n_core index->n_core_fields at the time rec was
+ copied, or 0 if non-leaf page record
@param[in] n_fields number of fields to copy
@param[in,out] heap memory heap */
void
@@ -1090,7 +1092,7 @@ rec_copy_prefix_to_dtuple(
dtuple_t* tuple,
const rec_t* rec,
const dict_index_t* index,
- bool is_leaf,
+ ulint n_core,
ulint n_fields,
mem_heap_t* heap)
MY_ATTRIBUTE((nonnull));
diff --git a/storage/innobase/include/row0merge.h b/storage/innobase/include/row0merge.h
index d9410298c01..1d7f9bb145b 100644
--- a/storage/innobase/include/row0merge.h
+++ b/storage/innobase/include/row0merge.h
@@ -167,18 +167,20 @@ row_merge_drop_indexes_dict(
table_id_t table_id)/*!< in: table identifier */
MY_ATTRIBUTE((nonnull));
-/*********************************************************************//**
-Drop those indexes which were created before an error occurred.
+/** Drop indexes that were created before an error occurred.
The data dictionary must have been locked exclusively by the caller,
-because the transaction will not be committed. */
+because the transaction will not be committed.
+@param trx dictionary transaction
+@param table table containing the indexes
+@param locked True if table is locked,
+ false - may need to do lazy drop
+@param alter_trx Alter table transaction */
void
row_merge_drop_indexes(
-/*===================*/
- trx_t* trx, /*!< in/out: transaction */
- dict_table_t* table, /*!< in/out: table containing the indexes */
- ibool locked) /*!< in: TRUE=table locked,
- FALSE=may need to do a lazy drop */
- MY_ATTRIBUTE((nonnull));
+ trx_t* trx,
+ dict_table_t* table,
+ bool locked,
+ const trx_t* alter_trx=NULL);
/*********************************************************************//**
Drop all partially created indexes during crash recovery. */
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 62582e61b0b..5a047635577 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -3989,7 +3989,8 @@ static void lock_rec_print(FILE* file, const lock_t* lock, mtr_t& mtr)
ut_ad(!page_rec_is_metadata(rec));
offsets = rec_get_offsets(
- rec, lock->index, offsets, true,
+ rec, lock->index, offsets,
+ lock->index->n_core_fields,
ULINT_UNDEFINED, &heap);
putc(' ', file);
@@ -4497,8 +4498,8 @@ loop:
ut_ad(!lock_rec_get_nth_bit(lock, i)
|| page_rec_is_leaf(rec));
offsets = rec_get_offsets(rec, lock->index, offsets,
- true, ULINT_UNDEFINED,
- &heap);
+ lock->index->n_core_fields,
+ ULINT_UNDEFINED, &heap);
/* If this thread is holding the file space
latch (fil_space_t::latch), the following
@@ -4746,7 +4747,7 @@ lock_rec_insert_check_and_lock(
const rec_offs *offsets;
rec_offs_init(offsets_);
- offsets= rec_get_offsets(next_rec, index, offsets_, true,
+ offsets= rec_get_offsets(next_rec, index, offsets_, index->n_core_fields,
ULINT_UNDEFINED, &heap);
ut_ad(lock_rec_queue_validate(false, id, next_rec, index, offsets));
@@ -5072,7 +5073,8 @@ lock_sec_rec_modify_check_and_lock(
const rec_offs* offsets;
rec_offs_init(offsets_);
- offsets = rec_get_offsets(rec, index, offsets_, true,
+ offsets = rec_get_offsets(rec, index, offsets_,
+ index->n_core_fields,
ULINT_UNDEFINED, &heap);
ut_ad(lock_rec_queue_validate(
@@ -5288,7 +5290,7 @@ lock_clust_rec_read_check_and_lock_alt(
rec_offs_init(offsets_);
ut_ad(page_rec_is_leaf(rec));
- offsets = rec_get_offsets(rec, index, offsets, true,
+ offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields,
ULINT_UNDEFINED, &tmp_heap);
err = lock_clust_rec_read_check_and_lock(flags, block, rec, index,
offsets, mode, gap_mode, thr);
diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc
index 5e751010f44..025d4b9b967 100644
--- a/storage/innobase/page/page0cur.cc
+++ b/storage/innobase/page/page0cur.cc
@@ -75,7 +75,7 @@ page_cur_try_search_shortcut(
ut_ad(page_is_leaf(page));
rec = page_header_get_ptr(page, PAGE_LAST_INSERT);
- offsets = rec_get_offsets(rec, index, offsets, true,
+ offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields,
dtuple_get_n_fields(tuple), &heap);
ut_ad(rec);
@@ -90,7 +90,8 @@ page_cur_try_search_shortcut(
next_rec = page_rec_get_next_const(rec);
if (!page_rec_is_supremum(next_rec)) {
- offsets = rec_get_offsets(next_rec, index, offsets, true,
+ offsets = rec_get_offsets(next_rec, index, offsets,
+ index->n_core_fields,
dtuple_get_n_fields(tuple), &heap);
if (cmp_dtuple_rec_with_match(tuple, next_rec, offsets,
@@ -159,7 +160,7 @@ page_cur_try_search_shortcut_bytes(
ut_ad(page_is_leaf(page));
rec = page_header_get_ptr(page, PAGE_LAST_INSERT);
- offsets = rec_get_offsets(rec, index, offsets, true,
+ offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields,
dtuple_get_n_fields(tuple), &heap);
ut_ad(rec);
@@ -180,7 +181,8 @@ page_cur_try_search_shortcut_bytes(
next_rec = page_rec_get_next_const(rec);
if (!page_rec_is_supremum(next_rec)) {
- offsets = rec_get_offsets(next_rec, index, offsets, true,
+ offsets = rec_get_offsets(next_rec, index, offsets,
+ index->n_core_fields,
dtuple_get_n_fields(tuple), &heap);
if (cmp_dtuple_rec_with_match_bytes(
@@ -321,14 +323,14 @@ page_cur_search_with_match(
#endif /* UNIV_ZIP_DEBUG */
ut_d(page_check_dir(page));
- const bool is_leaf = page_is_leaf(page);
+ const ulint n_core = page_is_leaf(page) ? index->n_core_fields : 0;
#ifdef BTR_CUR_HASH_ADAPT
- if (is_leaf
+ if (n_core
&& page_get_direction(page) == PAGE_RIGHT
&& page_header_get_offs(page, PAGE_LAST_INSERT)
&& mode == PAGE_CUR_LE
- && !dict_index_is_spatial(index)
+ && !index->is_spatial()
&& page_header_get_field(page, PAGE_N_DIRECTION) > 3
&& page_cur_try_search_shortcut(
block, index, tuple,
@@ -344,10 +346,10 @@ page_cur_search_with_match(
/* If the mode is for R-tree indexes, use the special MBR
related compare functions */
- if (dict_index_is_spatial(index) && mode > PAGE_CUR_LE) {
+ if (index->is_spatial() && mode > PAGE_CUR_LE) {
/* For leaf level insert, we still use the traditional
compare function for now */
- if (mode == PAGE_CUR_RTREE_INSERT && is_leaf) {
+ if (mode == PAGE_CUR_RTREE_INSERT && n_core) {
mode = PAGE_CUR_LE;
} else {
rtr_cur_search_with_match(
@@ -392,7 +394,7 @@ page_cur_search_with_match(
offsets = offsets_;
offsets = rec_get_offsets(
- mid_rec, index, offsets, is_leaf,
+ mid_rec, index, offsets, n_core,
dtuple_get_n_fields_cmp(tuple), &heap);
cmp = cmp_dtuple_rec_with_match(
@@ -446,7 +448,7 @@ up_slot_match:
offsets = offsets_;
offsets = rec_get_offsets(
- mid_rec, index, offsets, is_leaf,
+ mid_rec, index, offsets, n_core,
dtuple_get_n_fields_cmp(tuple), &heap);
cmp = cmp_dtuple_rec_with_match(
@@ -627,7 +629,7 @@ page_cur_search_with_match_bytes(
/* Perform binary search until the lower and upper limit directory
slots come to the distance 1 of each other */
- const bool is_leaf = page_is_leaf(page);
+ const ulint n_core = page_is_leaf(page) ? index->n_core_fields : 0;
while (up - low > 1) {
mid = (low + up) / 2;
@@ -639,7 +641,7 @@ page_cur_search_with_match_bytes(
up_matched_fields, up_matched_bytes);
offsets = rec_get_offsets(
- mid_rec, index, offsets_, is_leaf,
+ mid_rec, index, offsets_, n_core,
dtuple_get_n_fields_cmp(tuple), &heap);
cmp = cmp_dtuple_rec_with_match_bytes(
@@ -707,7 +709,7 @@ up_slot_match:
}
offsets = rec_get_offsets(
- mid_rec, index, offsets_, is_leaf,
+ mid_rec, index, offsets_, n_core,
dtuple_get_n_fields_cmp(tuple), &heap);
cmp = cmp_dtuple_rec_with_match_bytes(
@@ -1343,7 +1345,8 @@ page_cur_insert_rec_low(
rec_offs_init(foffsets_);
rec_offs *foffsets= rec_get_offsets(free_rec, index, foffsets_,
- page_is_leaf(block->frame),
+ page_is_leaf(block->frame)
+ ? index->n_core_fields : 0,
ULINT_UNDEFINED, &heap);
const ulint fextra_size= rec_offs_extra_size(foffsets);
insert_buf= free_rec - fextra_size;
@@ -1838,7 +1841,8 @@ page_cur_insert_rec_zip(
rec_offs *foffsets= rec_get_offsets(cursor->block->frame + free_rec, index,
foffsets_,
- page_is_leaf(cursor->block->frame),
+ page_is_leaf(cursor->block->frame)
+ ? index->n_core_fields : 0,
ULINT_UNDEFINED, &heap);
insert_buf= cursor->block->frame + free_rec -
rec_offs_extra_size(foffsets);
diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc
index 5fe029d5b4d..9b83470e65c 100644
--- a/storage/innobase/page/page0page.cc
+++ b/storage/innobase/page/page0page.cc
@@ -2,7 +2,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2017, 2020, MariaDB Corporation.
+Copyright (c) 2017, 2021, 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
@@ -482,7 +482,8 @@ page_copy_rec_list_end_no_locks(
ut_a(page_is_comp(new_page) == page_rec_is_comp(rec));
ut_a(mach_read_from_2(new_page + srv_page_size - 10) == (ulint)
(page_is_comp(new_page) ? PAGE_NEW_INFIMUM : PAGE_OLD_INFIMUM));
- const bool is_leaf = page_is_leaf(block->frame);
+ const ulint n_core = page_is_leaf(block->frame)
+ ? index->n_core_fields : 0;
page_cur_set_before_first(new_block, &cur2);
@@ -490,7 +491,7 @@ page_copy_rec_list_end_no_locks(
while (!page_cur_is_after_last(&cur1)) {
rec_t* ins_rec;
- offsets = rec_get_offsets(cur1.rec, index, offsets, is_leaf,
+ offsets = rec_get_offsets(cur1.rec, index, offsets, n_core,
ULINT_UNDEFINED, &heap);
ins_rec = page_cur_insert_rec_low(&cur2, index,
cur1.rec, offsets, mtr);
@@ -721,7 +722,7 @@ page_copy_rec_list_start(
page_cur_position(ret, new_block, &cur2);
- const bool is_leaf = page_rec_is_leaf(rec);
+ const ulint n_core = page_rec_is_leaf(rec) ? index->n_core_fields : 0;
/* Copy records from the original page to the new page */
if (index->is_spatial()) {
@@ -743,7 +744,7 @@ page_copy_rec_list_start(
} else {
while (page_cur_get_rec(&cur1) != rec) {
offsets = rec_get_offsets(cur1.rec, index, offsets,
- is_leaf,
+ n_core,
ULINT_UNDEFINED, &heap);
cur2.rec = page_cur_insert_rec_low(&cur2, index,
cur1.rec, offsets,
@@ -764,7 +765,7 @@ page_copy_rec_list_start(
same temp-table in parallel.
max_trx_id is ignored for temp tables because it not required
for MVCC. */
- if (is_leaf && dict_index_is_sec_or_ibuf(index)
+ if (n_core && dict_index_is_sec_or_ibuf(index)
&& !index->table->is_temporary()) {
page_update_max_trx_id(new_block,
new_page_zip,
@@ -884,10 +885,10 @@ page_delete_rec_list_end(
}
#endif
- /* The page gets invalid for optimistic searches */
+ /* The page becomes invalid for optimistic searches */
buf_block_modify_clock_inc(block);
- const bool is_leaf= page_is_leaf(block->frame);
+ const ulint n_core= page_is_leaf(block->frame) ? index->n_core_fields : 0;
mem_heap_t *heap= nullptr;
rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs *offsets= offsets_;
@@ -901,7 +902,7 @@ page_delete_rec_list_end(
{
page_cur_t cur;
page_cur_position(rec, block, &cur);
- offsets= rec_get_offsets(rec, index, offsets, is_leaf,
+ offsets= rec_get_offsets(rec, index, offsets, n_core,
ULINT_UNDEFINED, &heap);
rec= rec_get_next_ptr(rec, TRUE);
#ifdef UNIV_ZIP_DEBUG
@@ -932,7 +933,7 @@ page_delete_rec_list_end(
do
{
- offsets = rec_get_offsets(rec2, index, offsets, is_leaf,
+ offsets = rec_get_offsets(rec2, index, offsets, n_core,
ULINT_UNDEFINED, &heap);
ulint s= rec_offs_size(offsets);
ut_ad(ulint(rec2 - block->frame) + s - rec_offs_extra_size(offsets) <
@@ -1097,11 +1098,12 @@ page_delete_rec_list_start(
page_cur_set_before_first(block, &cur1);
page_cur_move_to_next(&cur1);
- const bool is_leaf = page_rec_is_leaf(rec);
+ const ulint n_core = page_rec_is_leaf(rec)
+ ? index->n_core_fields : 0;
while (page_cur_get_rec(&cur1) != rec) {
offsets = rec_get_offsets(page_cur_get_rec(&cur1), index,
- offsets, is_leaf,
+ offsets, n_core,
ULINT_UNDEFINED, &heap);
page_cur_delete_rec(&cur1, index, offsets, mtr);
}
@@ -2104,9 +2106,10 @@ wrong_page_type:
rec = page_get_infimum_rec(page);
+ const ulint n_core = page_is_leaf(page) ? index->n_core_fields : 0;
+
for (;;) {
- offsets = rec_get_offsets(rec, index, offsets,
- page_is_leaf(page),
+ offsets = rec_get_offsets(rec, index, offsets, n_core,
ULINT_UNDEFINED, &heap);
if (page_is_comp(page) && page_rec_is_user_rec(rec)
@@ -2352,8 +2355,7 @@ n_owned_zero:
rec = page_header_get_ptr(page, PAGE_FREE);
while (rec != NULL) {
- offsets = rec_get_offsets(rec, index, offsets,
- page_is_leaf(page),
+ offsets = rec_get_offsets(rec, index, offsets, n_core,
ULINT_UNDEFINED, &heap);
if (UNIV_UNLIKELY(!page_rec_validate(rec, offsets))) {
ret = FALSE;
diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc
index 198d83f3030..09ac48bce0f 100644
--- a/storage/innobase/page/page0zip.cc
+++ b/storage/innobase/page/page0zip.cc
@@ -903,7 +903,7 @@ page_zip_compress_node_ptrs(
do {
const rec_t* rec = *recs++;
- offsets = rec_get_offsets(rec, index, offsets, false,
+ offsets = rec_get_offsets(rec, index, offsets, 0,
ULINT_UNDEFINED, &heap);
/* Only leaf nodes may contain externally stored columns. */
ut_ad(!rec_offs_any_extern(offsets));
@@ -1152,7 +1152,7 @@ page_zip_compress_clust(
do {
const rec_t* rec = *recs++;
- offsets = rec_get_offsets(rec, index, offsets, true,
+ offsets = rec_get_offsets(rec, index, offsets, index->n_fields,
ULINT_UNDEFINED, &heap);
ut_ad(rec_offs_n_fields(offsets)
== dict_index_get_n_fields(index));
@@ -2027,7 +2027,7 @@ page_zip_apply_log(
sorted by address (indexed by
heap_no - PAGE_HEAP_NO_USER_LOW) */
ulint n_dense,/*!< in: size of recs[] */
- bool is_leaf,/*!< in: whether this is a leaf page */
+ ulint n_core, /*!< in: index->n_fields, or 0 for non-leaf */
ulint trx_id_col,/*!< in: column number of trx_id in the index,
or ULINT_UNDEFINED if none */
ulint heap_status,
@@ -2103,7 +2103,7 @@ page_zip_apply_log(
/* Clear the data bytes of the record. */
mem_heap_t* heap = NULL;
rec_offs* offs;
- offs = rec_get_offsets(rec, index, offsets, is_leaf,
+ offs = rec_get_offsets(rec, index, offsets, n_core,
ULINT_UNDEFINED, &heap);
memset(rec, 0, rec_offs_data_size(offs));
@@ -2121,7 +2121,7 @@ page_zip_apply_log(
This will be overwritten in page_zip_set_extra_bytes(),
called by page_zip_decompress_low(). */
ut_d(rec[-REC_NEW_INFO_BITS] = 0);
- rec_offs_make_valid(rec, index, is_leaf, offsets);
+ rec_offs_make_valid(rec, index, n_core != 0, offsets);
/* Copy the extra bytes (backwards). */
{
@@ -2301,7 +2301,7 @@ page_zip_decompress_node_ptrs(
}
/* Read the offsets. The status bits are needed here. */
- offsets = rec_get_offsets(rec, index, offsets, false,
+ offsets = rec_get_offsets(rec, index, offsets, 0,
ULINT_UNDEFINED, &heap);
/* Non-leaf nodes should not have any externally
@@ -2388,7 +2388,7 @@ zlib_done:
const byte* mod_log_ptr;
mod_log_ptr = page_zip_apply_log(d_stream->next_in,
d_stream->avail_in + 1,
- recs, n_dense, false,
+ recs, n_dense, 0,
ULINT_UNDEFINED, heap_status,
index, offsets);
@@ -2419,7 +2419,7 @@ zlib_done:
for (slot = 0; slot < n_dense; slot++) {
rec_t* rec = recs[slot];
- offsets = rec_get_offsets(rec, index, offsets, false,
+ offsets = rec_get_offsets(rec, index, offsets, 0,
ULINT_UNDEFINED, &heap);
/* Non-leaf nodes should not have any externally
stored columns. */
@@ -2541,7 +2541,8 @@ zlib_done:
const byte* mod_log_ptr;
mod_log_ptr = page_zip_apply_log(d_stream->next_in,
d_stream->avail_in + 1,
- recs, n_dense, true,
+ recs, n_dense,
+ index->n_fields,
ULINT_UNDEFINED, heap_status,
index, offsets);
@@ -2744,7 +2745,7 @@ page_zip_decompress_clust(
}
/* Read the offsets. The status bits are needed here. */
- offsets = rec_get_offsets(rec, index, offsets, true,
+ offsets = rec_get_offsets(rec, index, offsets, index->n_fields,
ULINT_UNDEFINED, &heap);
/* This is a leaf page in a clustered index. */
@@ -2871,7 +2872,8 @@ zlib_done:
const byte* mod_log_ptr;
mod_log_ptr = page_zip_apply_log(d_stream->next_in,
d_stream->avail_in + 1,
- recs, n_dense, true,
+ recs, n_dense,
+ index->n_fields,
trx_id_col, heap_status,
index, offsets);
@@ -2907,7 +2909,7 @@ zlib_done:
rec_t* rec = recs[slot];
bool exists = !page_zip_dir_find_free(
page_zip, page_offset(rec));
- offsets = rec_get_offsets(rec, index, offsets, true,
+ offsets = rec_get_offsets(rec, index, offsets, index->n_fields,
ULINT_UNDEFINED, &heap);
dst = rec_get_nth_field(rec, offsets,
@@ -3430,7 +3432,7 @@ page_zip_validate_low(
page + PAGE_NEW_INFIMUM, TRUE);
trec = page_rec_get_next_low(
temp_page + PAGE_NEW_INFIMUM, TRUE);
- const bool is_leaf = page_is_leaf(page);
+ const ulint n_core = page_is_leaf(page) ? index->n_fields : 0;
do {
if (page_offset(rec) != page_offset(trec)) {
@@ -3445,7 +3447,7 @@ page_zip_validate_low(
if (index) {
/* Compare the data. */
offsets = rec_get_offsets(
- rec, index, offsets, is_leaf,
+ rec, index, offsets, n_core,
ULINT_UNDEFINED, &heap);
if (memcmp(rec - rec_offs_extra_size(offsets),
diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc
index aae621b6f56..419727b4d37 100644
--- a/storage/innobase/rem/rem0rec.cc
+++ b/storage/innobase/rem/rem0rec.cc
@@ -273,9 +273,9 @@ rec_init_offsets_comp_ordinary(
ulint n_fields = n_core;
ulint null_mask = 1;
- ut_ad(index->n_core_fields >= n_core);
ut_ad(n_core > 0);
- ut_ad(index->n_fields >= n_core);
+ ut_ad(index->n_core_fields >= n_core);
+ ut_ad(index->n_fields >= index->n_core_fields);
ut_ad(index->n_core_null_bytes <= UT_BITS_IN_BYTES(index->n_nullable));
ut_ad(format == REC_LEAF_TEMP || format == REC_LEAF_TEMP_INSTANT
|| dict_table_is_comp(index->table));
@@ -283,6 +283,11 @@ rec_init_offsets_comp_ordinary(
|| index->n_fields == rec_offs_n_fields(offsets));
ut_d(ulint n_null= 0);
+ const unsigned n_core_null_bytes = UNIV_UNLIKELY(index->n_core_fields
+ != n_core)
+ ? UT_BITS_IN_BYTES(unsigned(index->get_n_nullable(n_core)))
+ : index->n_core_null_bytes;
+
if (mblob) {
ut_ad(index->table->instant);
ut_ad(index->is_instant());
@@ -297,7 +302,7 @@ rec_init_offsets_comp_ordinary(
const ulint n_null_bytes = UT_BITS_IN_BYTES(n_nullable);
ut_d(n_null = n_nullable);
ut_ad(n_null <= index->n_nullable);
- ut_ad(n_null_bytes >= index->n_core_null_bytes
+ ut_ad(n_null_bytes >= n_core_null_bytes
|| n_core < index->n_core_fields);
lens = --nulls - n_null_bytes;
goto start;
@@ -314,10 +319,10 @@ rec_init_offsets_comp_ordinary(
case REC_LEAF_ORDINARY:
nulls -= REC_N_NEW_EXTRA_BYTES;
ordinary:
- lens = --nulls - index->n_core_null_bytes;
+ lens = --nulls - n_core_null_bytes;
- ut_d(n_null = std::min<uint>(index->n_core_null_bytes * 8U,
- index->n_nullable));
+ ut_d(n_null = std::min(n_core_null_bytes * 8U,
+ index->n_nullable));
break;
case REC_LEAF_INSTANT:
nulls -= REC_N_NEW_EXTRA_BYTES;
@@ -330,7 +335,7 @@ ordinary:
const ulint n_null_bytes = UT_BITS_IN_BYTES(n_nullable);
ut_d(n_null = n_nullable);
ut_ad(n_null <= index->n_nullable);
- ut_ad(n_null_bytes >= index->n_core_null_bytes
+ ut_ad(n_null_bytes >= n_core_null_bytes
|| n_core < index->n_core_fields);
lens = --nulls - n_null_bytes;
}
@@ -588,14 +593,14 @@ is (SQL_NULL), the field i is NULL. When the type of the offset at [i+1]
is (STORED_OFFPAGE), the field i is stored externally.
@param[in] rec record
@param[in] index the index that the record belongs in
-@param[in] leaf whether the record resides in a leaf page
+@param[in] n_core 0, or index->n_core_fields for leaf page
@param[in,out] offsets array of offsets, with valid rec_offs_n_fields() */
static
void
rec_init_offsets(
const rec_t* rec,
const dict_index_t* index,
- bool leaf,
+ ulint n_core,
rec_offs* offsets)
{
ulint i = 0;
@@ -610,6 +615,8 @@ rec_init_offsets(
|| index->in_instant_init);
ut_d(memcpy(&offsets[RECORD_OFFSET], &rec, sizeof(rec)));
ut_d(memcpy(&offsets[INDEX_OFFSET], &index, sizeof(index)));
+ ut_ad(index->n_fields >= n_core);
+ ut_ad(index->n_core_fields >= n_core);
if (dict_table_is_comp(index->table)) {
const byte* nulls;
@@ -628,23 +635,21 @@ rec_init_offsets(
rec_offs_base(offsets)[1] = 8;
return;
case REC_STATUS_NODE_PTR:
- ut_ad(!leaf);
+ ut_ad(!n_core);
n_node_ptr_field
= dict_index_get_n_unique_in_tree_nonleaf(
index);
break;
case REC_STATUS_INSTANT:
- ut_ad(leaf);
ut_ad(index->is_instant());
rec_init_offsets_comp_ordinary(rec, index, offsets,
- index->n_core_fields,
+ n_core,
NULL,
REC_LEAF_INSTANT);
return;
case REC_STATUS_ORDINARY:
- ut_ad(leaf);
rec_init_offsets_comp_ordinary(rec, index, offsets,
- index->n_core_fields,
+ n_core,
NULL,
REC_LEAF_ORDINARY);
return;
@@ -806,7 +811,7 @@ resolved:
@param[in] index the index that the record belongs to
@param[in,out] offsets array comprising offsets[0] allocated elements,
or an array from rec_get_offsets(), or NULL
-@param[in] leaf whether this is a leaf-page record
+@param[in] n_core 0, or index->n_core_fields for leaf page
@param[in] n_fields maximum number of offsets to compute
(ULINT_UNDEFINED to compute all offsets)
@param[in,out] heap memory heap
@@ -816,7 +821,7 @@ rec_get_offsets_func(
const rec_t* rec,
const dict_index_t* index,
rec_offs* offsets,
- bool leaf,
+ ulint n_core,
ulint n_fields,
#ifdef UNIV_DEBUG
const char* file, /*!< in: file name where called */
@@ -828,6 +833,15 @@ rec_get_offsets_func(
ulint size;
bool alter_metadata = false;
+ ut_ad(index->n_core_fields >= n_core);
+ /* This assertion was relaxed for the btr_cur_open_at_index_side()
+ call in btr_cur_instant_init_low(). We cannot invoke
+ index->is_instant(), because the same assertion would fail there
+ until btr_cur_instant_init_low() has invoked
+ dict_table_t::deserialise_columns(). */
+ ut_ad(index->n_fields >= index->n_core_fields
+ || index->in_instant_init);
+
if (dict_table_is_comp(index->table)) {
switch (UNIV_EXPECT(rec_get_status(rec),
REC_STATUS_ORDINARY)) {
@@ -835,14 +849,14 @@ rec_get_offsets_func(
alter_metadata = rec_is_alter_metadata(rec, true);
/* fall through */
case REC_STATUS_ORDINARY:
- ut_ad(leaf);
+ ut_ad(n_core);
n = dict_index_get_n_fields(index) + alter_metadata;
break;
case REC_STATUS_NODE_PTR:
/* Node pointer records consist of the
uniquely identifying fields of the record
followed by a child page number field. */
- ut_ad(!leaf);
+ ut_ad(!n_core);
n = dict_index_get_n_unique_in_tree_nonleaf(index) + 1;
break;
case REC_STATUS_INFIMUM:
@@ -871,19 +885,19 @@ rec_get_offsets_func(
>= PAGE_HEAP_NO_USER_LOW;
/* The infimum and supremum records carry 1 field. */
ut_ad(is_user_rec || n == 1);
- ut_ad(!is_user_rec || leaf || index->is_dummy
+ ut_ad(!is_user_rec || n_core || index->is_dummy
|| dict_index_is_ibuf(index)
|| n == n_fields /* dict_stats_analyze_index_level() */
|| n - 1
== dict_index_get_n_unique_in_tree_nonleaf(index));
- ut_ad(!is_user_rec || !leaf || index->is_dummy
+ ut_ad(!is_user_rec || !n_core || index->is_dummy
|| dict_index_is_ibuf(index)
|| n == n_fields /* btr_pcur_restore_position() */
|| (n + (index->id == DICT_INDEXES_ID)
- >= index->n_core_fields && n <= index->n_fields
+ >= n_core && n <= index->n_fields
+ unsigned(rec_is_alter_metadata(rec, false))));
- if (is_user_rec && leaf && n < index->n_fields) {
+ if (is_user_rec && n_core && n < index->n_fields) {
ut_ad(!index->is_dummy);
ut_ad(!dict_index_is_ibuf(index));
n = index->n_fields;
@@ -917,17 +931,17 @@ rec_get_offsets_func(
memcpy(&offsets[RECORD_OFFSET], &rec, sizeof rec);
memcpy(&offsets[INDEX_OFFSET], &index, sizeof index);
#endif /* UNIV_DEBUG */
- ut_ad(leaf);
+ ut_ad(n_core);
ut_ad(index->table->instant);
ut_ad(index->is_instant());
ut_ad(rec_offs_n_fields(offsets)
<= ulint(index->n_fields) + 1);
rec_init_offsets_comp_ordinary<true>(rec, index, offsets,
index->n_core_fields,
- NULL,
+ nullptr,
REC_LEAF_INSTANT);
} else {
- rec_init_offsets(rec, index, leaf, offsets);
+ rec_init_offsets(rec, index, n_core, offsets);
}
return offsets;
}
@@ -1850,7 +1864,9 @@ template void rec_convert_dtuple_to_temp<true>(
The fields are copied into the memory heap.
@param[out] tuple data tuple
@param[in] rec index record, or a copy thereof
-@param[in] is_leaf whether rec is a leaf page record
+@param[in] index index of rec
+@param[in] n_core index->n_core_fields at the time rec was
+ copied, or 0 if non-leaf page record
@param[in] n_fields number of fields to copy
@param[in,out] heap memory heap */
void
@@ -1858,7 +1874,7 @@ rec_copy_prefix_to_dtuple(
dtuple_t* tuple,
const rec_t* rec,
const dict_index_t* index,
- bool is_leaf,
+ ulint n_core,
ulint n_fields,
mem_heap_t* heap)
{
@@ -1866,10 +1882,11 @@ rec_copy_prefix_to_dtuple(
rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
- ut_ad(is_leaf || n_fields - 1
+ ut_ad(n_core <= index->n_core_fields);
+ ut_ad(n_core || n_fields - 1
<= dict_index_get_n_unique_in_tree_nonleaf(index));
- offsets = rec_get_offsets(rec, index, offsets, is_leaf,
+ offsets = rec_get_offsets(rec, index, offsets, n_core,
n_fields, &heap);
ut_ad(rec_validate(rec, offsets));
@@ -2509,7 +2526,8 @@ rec_print(
rec_print_new(file, rec,
rec_get_offsets(rec, index, offsets_,
- page_rec_is_leaf(rec),
+ page_rec_is_leaf(rec)
+ ? index->n_core_fields : 0,
ULINT_UNDEFINED, &heap));
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
@@ -2585,7 +2603,8 @@ operator<<(std::ostream& o, const rec_index_print& r)
{
mem_heap_t* heap = NULL;
rec_offs* offsets = rec_get_offsets(
- r.m_rec, r.m_index, NULL, page_rec_is_leaf(r.m_rec),
+ r.m_rec, r.m_index, NULL, page_rec_is_leaf(r.m_rec)
+ ? r.m_index->n_core_fields : 0,
ULINT_UNDEFINED, &heap);
rec_print(o, r.m_rec,
rec_get_info_bits(r.m_rec, rec_offs_comp(offsets)),
@@ -2624,7 +2643,7 @@ rec_get_trx_id(
rec_offs_init(offsets_);
rec_offs* offsets = offsets_;
- offsets = rec_get_offsets(rec, index, offsets, true,
+ offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields,
index->db_trx_id() + 1, &heap);
trx_id = rec_get_nth_field(rec, offsets, index->db_trx_id(), &len);
@@ -2675,7 +2694,8 @@ wsrep_rec_get_foreign_key(
ut_ad(index_ref);
rec_offs_init(offsets_);
- offsets = rec_get_offsets(rec, index_for, offsets_, true,
+ offsets = rec_get_offsets(rec, index_for, offsets_,
+ index_for->n_core_fields,
ULINT_UNDEFINED, &heap);
ut_ad(rec_offs_validate(rec, NULL, offsets));
diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc
index 891e9318da5..7c1488c82cb 100644
--- a/storage/innobase/row/row0ftsort.cc
+++ b/storage/innobase/row/row0ftsort.cc
@@ -910,7 +910,7 @@ loop:
<< " records, the sort queue has "
<< UT_LIST_GET_LEN(psort_info->fts_doc_list)
<< " records. But sort cannot get the next"
- " records";
+ " records during alter table " << table->name;
goto exit;
}
} else if (psort_info->state == FTS_PARENT_EXITING) {
@@ -1192,7 +1192,9 @@ row_merge_write_fts_word(
if (UNIV_UNLIKELY(error != DB_SUCCESS)) {
ib::error() << "Failed to write word to FTS auxiliary"
- " index table, error " << error;
+ " index table "
+ << ins_ctx->btr_bulk->table_name()
+ << ", error " << error;
ret = error;
}
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index e1864fd27bc..3060ec05bc8 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -1839,7 +1839,8 @@ PageConverter::update_records(
if (deleted || clust_index) {
m_offsets = rec_get_offsets(
- rec, m_index->m_srv_index, m_offsets, true,
+ rec, m_index->m_srv_index, m_offsets,
+ m_index->m_srv_index->n_core_fields,
ULINT_UNDEFINED, &m_heap);
}
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index 1caa9d88ca0..880554d76b4 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -885,7 +885,7 @@ row_ins_foreign_fill_virtual(
rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs_init(offsets_);
const rec_offs* offsets =
- rec_get_offsets(rec, index, offsets_, true,
+ rec_get_offsets(rec, index, offsets_, index->n_core_fields,
ULINT_UNDEFINED, &cascade->heap);
TABLE* mysql_table= NULL;
upd_t* update = cascade->update;
@@ -1199,7 +1199,8 @@ row_ins_foreign_check_on_constraint(
if (table->fts) {
doc_id = fts_get_doc_id_from_rec(
clust_rec, clust_index,
- rec_get_offsets(clust_rec, clust_index, NULL, true,
+ rec_get_offsets(clust_rec, clust_index, NULL,
+ clust_index->n_core_fields,
ULINT_UNDEFINED, &tmp_heap));
}
@@ -1640,7 +1641,8 @@ row_ins_check_foreign_constraint(
continue;
}
- offsets = rec_get_offsets(rec, check_index, offsets, true,
+ offsets = rec_get_offsets(rec, check_index, offsets,
+ check_index->n_core_fields,
ULINT_UNDEFINED, &heap);
if (page_rec_is_supremum(rec)) {
@@ -2124,7 +2126,8 @@ row_ins_scan_sec_index_for_duplicate(
continue;
}
- offsets = rec_get_offsets(rec, index, offsets, true,
+ offsets = rec_get_offsets(rec, index, offsets,
+ index->n_core_fields,
ULINT_UNDEFINED, &offsets_heap);
if (flags & BTR_NO_LOCKING_FLAG) {
@@ -2261,7 +2264,8 @@ row_ins_duplicate_error_in_clust_online(
ut_ad(!cursor->index->is_instant());
if (cursor->low_match >= n_uniq && !page_rec_is_infimum(rec)) {
- *offsets = rec_get_offsets(rec, cursor->index, *offsets, true,
+ *offsets = rec_get_offsets(rec, cursor->index, *offsets,
+ cursor->index->n_fields,
ULINT_UNDEFINED, heap);
err = row_ins_duplicate_online(n_uniq, entry, rec, *offsets);
if (err != DB_SUCCESS) {
@@ -2272,7 +2276,8 @@ row_ins_duplicate_error_in_clust_online(
rec = page_rec_get_next_const(btr_cur_get_rec(cursor));
if (cursor->up_match >= n_uniq && !page_rec_is_supremum(rec)) {
- *offsets = rec_get_offsets(rec, cursor->index, *offsets, true,
+ *offsets = rec_get_offsets(rec, cursor->index, *offsets,
+ cursor->index->n_fields,
ULINT_UNDEFINED, heap);
err = row_ins_duplicate_online(n_uniq, entry, rec, *offsets);
}
@@ -2328,7 +2333,7 @@ row_ins_duplicate_error_in_clust(
if (!page_rec_is_infimum(rec)) {
offsets = rec_get_offsets(rec, cursor->index, offsets,
- true,
+ cursor->index->n_core_fields,
ULINT_UNDEFINED, &heap);
/* We set a lock on the possible duplicate: this
@@ -2394,7 +2399,7 @@ duplicate:
if (!page_rec_is_supremum(rec)) {
offsets = rec_get_offsets(rec, cursor->index, offsets,
- true,
+ cursor->index->n_core_fields,
ULINT_UNDEFINED, &heap);
if (trx->duplicates) {
@@ -2511,7 +2516,7 @@ row_ins_index_entry_big_rec(
btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_MODIFY_TREE,
&pcur, &mtr);
rec = btr_pcur_get_rec(&pcur);
- offsets = rec_get_offsets(rec, index, offsets, true,
+ offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields,
ULINT_UNDEFINED, heap);
DEBUG_SYNC_C_IF_THD(thd, "before_row_ins_extern");
@@ -3117,7 +3122,8 @@ row_ins_sec_index_entry_low(
prefix, we must convert the insert into a modify of an
existing record */
offsets = rec_get_offsets(
- btr_cur_get_rec(&cursor), index, offsets, true,
+ btr_cur_get_rec(&cursor), index, offsets,
+ index->n_core_fields,
ULINT_UNDEFINED, &offsets_heap);
err = row_ins_sec_index_entry_by_modify(
diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc
index d271092166f..610ac1ad2ae 100644
--- a/storage/innobase/row/row0log.cc
+++ b/storage/innobase/row/row0log.cc
@@ -1289,7 +1289,8 @@ row_log_table_get_pk(
if (!offsets) {
offsets = rec_get_offsets(
- rec, index, NULL, true,
+ rec, index, nullptr,
+ index->n_core_fields,
index->db_trx_id() + 1, heap);
}
@@ -1339,7 +1340,8 @@ row_log_table_get_pk(
}
if (!offsets) {
- offsets = rec_get_offsets(rec, index, NULL, true,
+ offsets = rec_get_offsets(rec, index, nullptr,
+ index->n_core_fields,
ULINT_UNDEFINED, heap);
}
@@ -2011,7 +2013,8 @@ all_done:
return(DB_SUCCESS);
}
- offsets = rec_get_offsets(btr_pcur_get_rec(&pcur), index, NULL, true,
+ offsets = rec_get_offsets(btr_pcur_get_rec(&pcur), index, nullptr,
+ index->n_core_fields,
ULINT_UNDEFINED, &offsets_heap);
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ut_a(!rec_offs_any_null_extern(btr_pcur_get_rec(&pcur), offsets));
@@ -2208,7 +2211,7 @@ func_exit_committed:
/* Prepare to update (or delete) the record. */
rec_offs* cur_offsets = rec_get_offsets(
- btr_pcur_get_rec(&pcur), index, NULL, true,
+ btr_pcur_get_rec(&pcur), index, nullptr, index->n_core_fields,
ULINT_UNDEFINED, &offsets_heap);
if (!log->same_pk) {
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index b21b17be15f..1358617b0db 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -2043,7 +2043,8 @@ end_of_index:
rec = page_cur_get_rec(cur);
if (online) {
- offsets = rec_get_offsets(rec, clust_index, NULL, true,
+ offsets = rec_get_offsets(rec, clust_index, NULL,
+ clust_index->n_core_fields,
ULINT_UNDEFINED, &row_heap);
rec_trx_id = row_get_rec_trx_id(rec, clust_index,
offsets);
@@ -2135,7 +2136,8 @@ end_of_index:
duplicate keys. */
continue;
} else {
- offsets = rec_get_offsets(rec, clust_index, NULL, true,
+ offsets = rec_get_offsets(rec, clust_index, NULL,
+ clust_index->n_core_fields,
ULINT_UNDEFINED, &row_heap);
/* This is a locking ALTER TABLE.
@@ -3790,17 +3792,20 @@ row_merge_drop_indexes_dict(
trx->op_info = "";
}
-/*********************************************************************//**
-Drop indexes that were created before an error occurred.
+/** Drop indexes that were created before an error occurred.
The data dictionary must have been locked exclusively by the caller,
-because the transaction will not be committed. */
+because the transaction will not be committed.
+@param trx dictionary transaction
+@param table table containing the indexes
+@param locked True if table is locked,
+ false - may need to do lazy drop
+@param alter_trx Alter table transaction */
void
row_merge_drop_indexes(
-/*===================*/
- trx_t* trx, /*!< in/out: dictionary transaction */
- dict_table_t* table, /*!< in/out: table containing the indexes */
- ibool locked) /*!< in: TRUE=table locked,
- FALSE=may need to do a lazy drop */
+ trx_t* trx,
+ dict_table_t* table,
+ bool locked,
+ const trx_t* alter_trx)
{
dict_index_t* index;
dict_index_t* next_index;
@@ -3825,7 +3830,7 @@ row_merge_drop_indexes(
A concurrent purge will be prevented by dict_sys.latch. */
if (!locked && (table->get_ref_count() > 1
- || UT_LIST_GET_FIRST(table->locks))) {
+ || table->has_lock_other_than(alter_trx))) {
/* 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
@@ -4251,6 +4256,7 @@ row_merge_create_index(
dict_index_t* index;
ulint n_fields = index_def->n_fields;
ulint i;
+ ulint n_add_vcol = 0;
DBUG_ENTER("row_merge_create_index");
@@ -4275,7 +4281,7 @@ row_merge_create_index(
ut_ad(ifield->col_no >= table->n_v_def);
name = add_v->v_col_name[
ifield->col_no - table->n_v_def];
- index->has_new_v_col = true;
+ n_add_vcol++;
} else {
name = dict_table_get_v_col_name(
table, ifield->col_no);
@@ -4287,6 +4293,10 @@ row_merge_create_index(
dict_mem_index_add_field(index, name, ifield->prefix_len);
}
+ if (n_add_vcol) {
+ index->assign_new_v_col(n_add_vcol);
+ }
+
DBUG_RETURN(index);
}
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index efdc47de0f9..cf979d03e0a 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -688,6 +688,7 @@ row_mysql_handle_errors(
dberr_t err;
DBUG_ENTER("row_mysql_handle_errors");
+ DEBUG_SYNC_C("row_mysql_handle_errors");
err = trx->error_state;
@@ -1773,12 +1774,11 @@ row_update_for_mysql(row_prebuilt_t* prebuilt)
clust_index = dict_table_get_first_index(table);
- if (prebuilt->pcur->btr_cur.index == clust_index) {
- btr_pcur_copy_stored_position(node->pcur, prebuilt->pcur);
- } else {
- btr_pcur_copy_stored_position(node->pcur,
- prebuilt->clust_pcur);
- }
+ btr_pcur_copy_stored_position(node->pcur,
+ prebuilt->pcur->btr_cur.index
+ == clust_index
+ ? prebuilt->pcur
+ : prebuilt->clust_pcur);
ut_a(node->pcur->rel_pos == BTR_PCUR_ON);
@@ -1981,7 +1981,8 @@ row_unlock_for_mysql(
rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
- offsets = rec_get_offsets(rec, index, offsets, true,
+ offsets = rec_get_offsets(rec, index, offsets,
+ index->n_core_fields,
ULINT_UNDEFINED, &heap);
rec_trx_id = row_get_rec_trx_id(rec, index, offsets);
@@ -4670,7 +4671,7 @@ func_exit:
rec = buf + mach_read_from_4(buf);
- offsets = rec_get_offsets(rec, index, offsets_, true,
+ offsets = rec_get_offsets(rec, index, offsets_, index->n_core_fields,
ULINT_UNDEFINED, &heap);
if (prev_entry != NULL) {
diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc
index 0fdc1763eb4..c0a898855b1 100644
--- a/storage/innobase/row/row0purge.cc
+++ b/storage/innobase/row/row0purge.cc
@@ -137,8 +137,9 @@ row_purge_remove_clust_if_poss_low(
rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs_init(offsets_);
mem_heap_t* heap = NULL;
- rec_offs* offsets = rec_get_offsets(
- rec, index, offsets_, true, ULINT_UNDEFINED, &heap);
+ rec_offs* offsets = rec_get_offsets(rec, index, offsets_,
+ index->n_core_fields,
+ ULINT_UNDEFINED, &heap);
bool success = true;
if (node->roll_ptr != row_get_rec_roll_ptr(rec, index, offsets)) {
@@ -615,7 +616,7 @@ row_purge_skip_uncommitted_virtual_index(
not support LOCK=NONE when adding an index on newly
added virtual column.*/
while (index != NULL && dict_index_has_virtual(index)
- && !index->is_committed() && index->has_new_v_col) {
+ && !index->is_committed() && index->has_new_v_col()) {
index = dict_table_get_next_index(index);
}
}
@@ -681,7 +682,8 @@ static void row_purge_reset_trx_id(purge_node_t* node, mtr_t* mtr)
rec_offs offsets_[REC_OFFS_HEADER_SIZE + MAX_REF_PARTS + 2];
rec_offs_init(offsets_);
rec_offs* offsets = rec_get_offsets(
- rec, index, offsets_, true, trx_id_pos + 2, &heap);
+ rec, index, offsets_, index->n_core_fields,
+ trx_id_pos + 2, &heap);
ut_ad(heap == NULL);
ut_ad(dict_index_get_nth_field(index, trx_id_pos)
@@ -1217,7 +1219,7 @@ purge_node_t::validate_pcur()
dict_index_t* clust_index = pcur.btr_cur.index;
rec_offs* offsets = rec_get_offsets(
- pcur.old_rec, clust_index, NULL, true,
+ pcur.old_rec, clust_index, NULL, pcur.old_n_core_fields,
pcur.old_n_fields, &heap);
/* Here we are comparing the purge ref record and the stored initial
diff --git a/storage/innobase/row/row0row.cc b/storage/innobase/row/row0row.cc
index 4c8eba9f4a4..19870906df8 100644
--- a/storage/innobase/row/row0row.cc
+++ b/storage/innobase/row/row0row.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2018, 2020, MariaDB Corporation.
+Copyright (c) 2018, 2021, 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
@@ -440,7 +440,8 @@ row_build_low(
ut_ad(!col_map || col_table);
if (!offsets) {
- offsets = rec_get_offsets(rec, index, offsets_, true,
+ offsets = rec_get_offsets(rec, index, offsets_,
+ index->n_core_fields,
ULINT_UNDEFINED, &tmp_heap);
} else {
ut_ad(rec_offs_validate(rec, index, offsets));
@@ -1004,7 +1005,7 @@ row_build_row_ref(
ut_ad(heap != NULL);
ut_ad(!dict_index_is_clust(index));
- offsets = rec_get_offsets(rec, index, offsets, true,
+ offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields,
ULINT_UNDEFINED, &tmp_heap);
/* Secondary indexes must not contain externally stored columns. */
ut_ad(!rec_offs_any_extern(offsets));
@@ -1113,7 +1114,8 @@ row_build_row_ref_in_tuple(
ut_ad(clust_index);
if (!offsets) {
- offsets = rec_get_offsets(rec, index, offsets_, true,
+ offsets = rec_get_offsets(rec, index, offsets_,
+ index->n_core_fields,
ULINT_UNDEFINED, &heap);
} else {
ut_ad(rec_offs_validate(rec, index, offsets));
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index e5e033857ec..bfe54e4cbe9 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -203,9 +203,11 @@ row_sel_sec_rec_is_for_clust_rec(
ib_vcol_row vc(heap);
clust_offs = rec_get_offsets(clust_rec, clust_index, clust_offs,
- true, ULINT_UNDEFINED, &heap);
+ clust_index->n_core_fields,
+ ULINT_UNDEFINED, &heap);
sec_offs = rec_get_offsets(sec_rec, sec_index, sec_offs,
- true, ULINT_UNDEFINED, &heap);
+ sec_index->n_fields,
+ ULINT_UNDEFINED, &heap);
n = dict_index_get_n_ordering_defined_by_user(sec_index);
@@ -927,7 +929,9 @@ row_sel_get_clust_rec(
offsets = rec_get_offsets(rec,
btr_pcur_get_btr_cur(&plan->pcur)->index,
- offsets, true, ULINT_UNDEFINED, &heap);
+ offsets,
+ btr_pcur_get_btr_cur(&plan->pcur)->index
+ ->n_core_fields, ULINT_UNDEFINED, &heap);
row_build_row_ref_fast(plan->clust_ref, plan->clust_map, rec, offsets);
@@ -962,7 +966,8 @@ row_sel_get_clust_rec(
goto err_exit;
}
- offsets = rec_get_offsets(clust_rec, index, offsets, true,
+ offsets = rec_get_offsets(clust_rec, index, offsets,
+ index->n_core_fields,
ULINT_UNDEFINED, &heap);
if (!node->read_view) {
@@ -1169,7 +1174,8 @@ re_scan:
rec = btr_pcur_get_rec(pcur);
my_offsets = offsets_;
- my_offsets = rec_get_offsets(rec, index, my_offsets, true,
+ my_offsets = rec_get_offsets(rec, index, my_offsets,
+ index->n_fields,
ULINT_UNDEFINED, &heap);
/* No match record */
@@ -1192,7 +1198,7 @@ re_scan:
rtr_rec_t* rtr_rec = &(*it);
my_offsets = rec_get_offsets(
- rtr_rec->r_rec, index, my_offsets, true,
+ rtr_rec->r_rec, index, my_offsets, index->n_fields,
ULINT_UNDEFINED, &heap);
err = lock_sec_rec_read_check_and_lock(
@@ -1508,7 +1514,7 @@ exhausted:
rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
- offsets = rec_get_offsets(rec, index, offsets, true,
+ offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields,
ULINT_UNDEFINED, &heap);
if (dict_index_is_clust(index)) {
@@ -1721,7 +1727,7 @@ rec_loop:
unsigned lock_type;
offsets = rec_get_offsets(next_rec, index, offsets,
- true,
+ index->n_core_fields,
ULINT_UNDEFINED, &heap);
/* At READ UNCOMMITTED or READ COMMITTED
@@ -1780,7 +1786,8 @@ skip_lock:
/* Try to place a lock on the index record */
unsigned lock_type;
- offsets = rec_get_offsets(rec, index, offsets, true,
+ offsets = rec_get_offsets(rec, index, offsets,
+ index->n_core_fields,
ULINT_UNDEFINED, &heap);
/* At READ UNCOMMITTED or READ COMMITTED isolation level,
@@ -1863,7 +1870,7 @@ skip_lock:
/* PHASE 3: Get previous version in a consistent read */
cons_read_requires_clust_rec = FALSE;
- offsets = rec_get_offsets(rec, index, offsets, true,
+ offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields,
ULINT_UNDEFINED, &heap);
if (node->read_view) {
@@ -1893,7 +1900,8 @@ skip_lock:
exhausted. */
offsets = rec_get_offsets(
- rec, index, offsets, true,
+ rec, index, offsets,
+ index->n_core_fields,
ULINT_UNDEFINED, &heap);
/* Fetch the columns needed in
@@ -3193,7 +3201,8 @@ class Row_sel_get_clust_rec_for_mysql
ut_ad(rec_offs_validate(cached_clust_rec, index, offsets));
ut_ad(index->first_user_field() <= rec_offs_n_fields(offsets));
- ut_ad(vers_offs == rec_get_offsets(cached_old_vers, index, vers_offs, true,
+ ut_ad(vers_offs == rec_get_offsets(cached_old_vers, index, vers_offs,
+ index->n_core_fields,
index->db_trx_id(), &heap));
ut_ad(!heap);
for (auto n= index->db_trx_id(); n--; )
@@ -3379,7 +3388,8 @@ Row_sel_get_clust_rec_for_mysql::operator()(
goto func_exit;
}
- *offsets = rec_get_offsets(clust_rec, clust_index, *offsets, true,
+ *offsets = rec_get_offsets(clust_rec, clust_index, *offsets,
+ clust_index->n_core_fields,
ULINT_UNDEFINED, offset_heap);
if (prebuilt->select_lock_type != LOCK_NONE) {
@@ -3450,7 +3460,8 @@ Row_sel_get_clust_rec_for_mysql::operator()(
ut_d(check_eq(clust_index, *offsets));
*offsets = rec_get_offsets(
old_vers, clust_index, *offsets,
- true, ULINT_UNDEFINED, offset_heap);
+ clust_index->n_core_fields,
+ ULINT_UNDEFINED, offset_heap);
}
}
@@ -3889,7 +3900,7 @@ exhausted:
/* This is a non-locking consistent read: if necessary, fetch
a previous version of the record */
- *offsets = rec_get_offsets(rec, index, *offsets, true,
+ *offsets = rec_get_offsets(rec, index, *offsets, index->n_core_fields,
ULINT_UNDEFINED, heap);
if (!row_sel_clust_sees(rec, *index, *offsets, trx->read_view)) {
@@ -4054,7 +4065,7 @@ row_sel_fill_vrow(
ut_ad(!index->is_instant());
ut_ad(page_rec_is_leaf(rec));
- offsets = rec_get_offsets(rec, index, offsets, true,
+ offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields,
ULINT_UNDEFINED, &heap);
*vrow = dtuple_create_with_vcol(
@@ -4683,7 +4694,7 @@ wait_table_again:
const rec_t* next_rec = page_rec_get_next_const(rec);
offsets = rec_get_offsets(next_rec, index, offsets,
- true,
+ index->n_core_fields,
ULINT_UNDEFINED, &heap);
err = sel_set_rec_lock(pcur,
next_rec, index, offsets,
@@ -4808,7 +4819,8 @@ rec_loop:
we do not lock gaps. Supremum record is really
a gap and therefore we do not set locks there. */
- offsets = rec_get_offsets(rec, index, offsets, true,
+ offsets = rec_get_offsets(rec, index, offsets,
+ index->n_core_fields,
ULINT_UNDEFINED, &heap);
err = sel_set_rec_lock(pcur,
rec, index, offsets,
@@ -4910,7 +4922,7 @@ wrong_offs:
ut_ad(fil_page_index_page_check(btr_pcur_get_page(pcur)));
ut_ad(btr_page_get_index_id(btr_pcur_get_page(pcur)) == index->id);
- offsets = rec_get_offsets(rec, index, offsets, true,
+ offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields,
ULINT_UNDEFINED, &heap);
if (UNIV_UNLIKELY(srv_force_recovery > 0)) {
@@ -5154,7 +5166,8 @@ no_gap_lock:
Do a normal locking read. */
offsets = rec_get_offsets(
- rec, index, offsets, true,
+ rec, index, offsets,
+ index->n_core_fields,
ULINT_UNDEFINED, &heap);
goto locks_ok;
case DB_DEADLOCK:
@@ -5555,7 +5568,7 @@ use_covering_index:
/* We used 'offsets' for the clust
rec, recalculate them for 'rec' */
offsets = rec_get_offsets(rec, index, offsets,
- true,
+ index->n_core_fields,
ULINT_UNDEFINED,
&heap);
result_rec = rec;
@@ -5995,7 +6008,7 @@ row_search_autoinc_read_column(
rec_offs_init(offsets_);
ut_ad(page_rec_is_leaf(rec));
- offsets = rec_get_offsets(rec, index, offsets, true,
+ offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields,
col_no + 1, &heap);
if (rec_offs_nth_sql_null(offsets, col_no)) {
diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc
index 0818a35c480..1a61a529e2c 100644
--- a/storage/innobase/row/row0uins.cc
+++ b/storage/innobase/row/row0uins.cc
@@ -120,7 +120,8 @@ row_undo_ins_remove_clust_rec(
if (online && dict_index_is_online_ddl(index)) {
mem_heap_t* heap = NULL;
const rec_offs* offsets = rec_get_offsets(
- rec, index, NULL, true, ULINT_UNDEFINED, &heap);
+ rec, index, NULL, index->n_core_fields,
+ ULINT_UNDEFINED, &heap);
row_log_table_delete(rec, index, offsets, NULL);
mem_heap_free(heap);
} else {
diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc
index 462563de540..064a7ffd888 100644
--- a/storage/innobase/row/row0umod.cc
+++ b/storage/innobase/row/row0umod.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2020, MariaDB Corporation.
+Copyright (c) 2017, 2021, 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
@@ -189,8 +189,9 @@ static ulint row_trx_id_offset(const rec_t* rec, const dict_index_t* index)
rec_offs_init(offsets_);
mem_heap_t* heap = NULL;
const ulint trx_id_pos = index->n_uniq ? index->n_uniq : 1;
- rec_offs* offsets = rec_get_offsets(rec, index, offsets_, true,
- trx_id_pos + 1, &heap);
+ rec_offs* offsets = rec_get_offsets(rec, index, offsets_,
+ index->n_core_fields,
+ trx_id_pos + 1, &heap);
ut_ad(!heap);
ulint len;
trx_id_offset = rec_get_nth_field_offs(
@@ -461,9 +462,9 @@ row_undo_mod_clust(
} else {
ut_ad(index->n_uniq <= MAX_REF_PARTS);
rec_offs_init(offsets_);
- offsets = rec_get_offsets(
- rec, index, offsets_, true, trx_id_pos + 2,
- &heap);
+ offsets = rec_get_offsets(rec, index, offsets_,
+ index->n_core_fields,
+ trx_id_pos + 2, &heap);
ulint len;
trx_id_offset = rec_get_nth_field_offs(
offsets, trx_id_pos, &len);
@@ -853,7 +854,8 @@ try_again:
offsets_heap = NULL;
offsets = rec_get_offsets(
btr_cur_get_rec(btr_cur),
- index, NULL, true, ULINT_UNDEFINED, &offsets_heap);
+ index, nullptr, index->n_core_fields, ULINT_UNDEFINED,
+ &offsets_heap);
update = row_upd_build_sec_rec_difference_binary(
btr_cur_get_rec(btr_cur), index, offsets, entry, heap);
if (upd_get_n_fields(update) == 0) {
diff --git a/storage/innobase/row/row0undo.cc b/storage/innobase/row/row0undo.cc
index 960d83d32ab..eb672eb0caa 100644
--- a/storage/innobase/row/row0undo.cc
+++ b/storage/innobase/row/row0undo.cc
@@ -187,7 +187,8 @@ row_undo_search_clust_to_pcur(
rec = btr_pcur_get_rec(&node->pcur);
- offsets = rec_get_offsets(rec, clust_index, offsets, true,
+ offsets = rec_get_offsets(rec, clust_index, offsets,
+ clust_index->n_core_fields,
ULINT_UNDEFINED, &heap);
found = row_get_rec_roll_ptr(rec, clust_index, offsets)
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index a625b24afa3..0a259726198 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -693,7 +693,8 @@ row_upd_build_difference_binary(
n_diff = 0;
if (!offsets) {
- offsets = rec_get_offsets(rec, index, offsets_, true,
+ offsets = rec_get_offsets(rec, index, offsets_,
+ index->n_core_fields,
ULINT_UNDEFINED, &heap);
} else {
ut_ad(rec_offs_validate(rec, index, offsets));
@@ -1894,7 +1895,8 @@ row_upd_store_row(
rec = btr_pcur_get_rec(node->pcur);
- offsets = rec_get_offsets(rec, clust_index, offsets_, true,
+ offsets = rec_get_offsets(rec, clust_index, offsets_,
+ clust_index->n_core_fields,
ULINT_UNDEFINED, &heap);
if (dict_table_has_atomic_blobs(node->table)) {
@@ -2133,7 +2135,7 @@ row_upd_sec_index_entry(
&& !wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
rec_offs* offsets = rec_get_offsets(
- rec, index, NULL, true,
+ rec, index, NULL, index->n_core_fields,
ULINT_UNDEFINED, &heap);
err = wsrep_row_upd_check_foreign_constraints(
@@ -2176,12 +2178,9 @@ row_upd_sec_index_entry(
ut_ad(err == DB_SUCCESS);
if (referenced) {
-
- rec_offs* offsets;
-
- offsets = rec_get_offsets(
- rec, index, NULL, true, ULINT_UNDEFINED,
- &heap);
+ rec_offs* offsets = rec_get_offsets(
+ rec, index, NULL, index->n_core_fields,
+ ULINT_UNDEFINED, &heap);
/* NOTE that the following call loses
the position of pcur ! */
@@ -2432,7 +2431,8 @@ row_upd_clust_rec_by_insert(
we update the primary key. Delete-mark the old record
in the clustered index and prepare to insert a new entry. */
rec = btr_cur_get_rec(btr_cur);
- offsets = rec_get_offsets(rec, index, offsets, true,
+ offsets = rec_get_offsets(rec, index, offsets,
+ index->n_core_fields,
ULINT_UNDEFINED, &heap);
ut_ad(page_rec_is_user_rec(rec));
@@ -2821,7 +2821,7 @@ row_upd_clust_step(
}
rec = btr_pcur_get_rec(pcur);
- offsets = rec_get_offsets(rec, index, offsets_, true,
+ offsets = rec_get_offsets(rec, index, offsets_, index->n_core_fields,
ULINT_UNDEFINED, &heap);
if (!flags && !node->has_clust_rec_x_lock) {
diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc
index c64a9d07131..210a09e637d 100644
--- a/storage/innobase/row/row0vers.cc
+++ b/storage/innobase/row/row0vers.cc
@@ -116,7 +116,8 @@ row_vers_impl_x_locked_low(
heap = mem_heap_create(1024);
clust_offsets = rec_get_offsets(clust_rec, clust_index, clust_offsets_,
- true, ULINT_UNDEFINED, &heap);
+ clust_index->n_core_fields,
+ ULINT_UNDEFINED, &heap);
trx_id = row_get_rec_trx_id(clust_rec, clust_index, clust_offsets);
if (trx_id == 0) {
@@ -239,7 +240,8 @@ not_locked:
}
clust_offsets = rec_get_offsets(
- prev_version, clust_index, clust_offsets_, true,
+ prev_version, clust_index, clust_offsets_,
+ clust_index->n_core_fields,
ULINT_UNDEFINED, &heap);
vers_del = rec_get_deleted_flag(prev_version, comp);
@@ -553,7 +555,8 @@ row_vers_build_cur_vrow_low(
clust_offsets = rec_get_offsets(prev_version, clust_index,
NULL,
- true, ULINT_UNDEFINED, &heap);
+ clust_index->n_core_fields,
+ ULINT_UNDEFINED, &heap);
ulint entry_len = dict_index_get_n_fields(index);
@@ -694,7 +697,8 @@ row_vers_vc_matches_cluster(
clust_offsets = rec_get_offsets(prev_version, clust_index,
NULL,
- true, ULINT_UNDEFINED, &heap);
+ clust_index->n_core_fields,
+ ULINT_UNDEFINED, &heap);
ulint entry_len = dict_index_get_n_fields(index);
@@ -821,7 +825,8 @@ row_vers_build_cur_vrow(
index, roll_ptr, trx_id, v_heap, &cur_vrow, mtr);
}
- *clust_offsets = rec_get_offsets(rec, clust_index, NULL, true,
+ *clust_offsets = rec_get_offsets(rec, clust_index, NULL,
+ clust_index->n_core_fields,
ULINT_UNDEFINED, &heap);
return(cur_vrow);
}
@@ -873,7 +878,8 @@ row_vers_old_has_index_entry(
comp = page_rec_is_comp(rec);
ut_ad(!dict_table_is_comp(index->table) == !comp);
heap = mem_heap_create(1024);
- clust_offsets = rec_get_offsets(rec, clust_index, NULL, true,
+ clust_offsets = rec_get_offsets(rec, clust_index, NULL,
+ clust_index->n_core_fields,
ULINT_UNDEFINED, &heap);
if (dict_index_has_virtual(index)) {
@@ -951,7 +957,8 @@ row_vers_old_has_index_entry(
}
}
clust_offsets = rec_get_offsets(rec, clust_index, NULL,
- true,
+ clust_index
+ ->n_core_fields,
ULINT_UNDEFINED, &heap);
} else {
@@ -1026,7 +1033,8 @@ unsafe_to_purge:
}
clust_offsets = rec_get_offsets(prev_version, clust_index,
- NULL, true,
+ NULL,
+ clust_index->n_core_fields,
ULINT_UNDEFINED, &heap);
if (dict_index_has_virtual(index)) {
@@ -1166,7 +1174,7 @@ row_vers_build_for_consistent_read(
*offsets = rec_get_offsets(
prev_version, index, *offsets,
- true, ULINT_UNDEFINED, offset_heap);
+ index->n_core_fields, ULINT_UNDEFINED, offset_heap);
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ut_a(!rec_offs_any_null_extern(prev_version, *offsets));
@@ -1281,11 +1289,10 @@ committed_version_trx:
semi-consistent read. */
version = rec;
- *offsets = rec_get_offsets(version,
- index, *offsets,
- true,
- ULINT_UNDEFINED,
- offset_heap);
+ *offsets = rec_get_offsets(
+ version, index, *offsets,
+ index->n_core_fields, ULINT_UNDEFINED,
+ offset_heap);
}
buf = static_cast<byte*>(
@@ -1328,7 +1335,8 @@ committed_version_trx:
}
version = prev_version;
- *offsets = rec_get_offsets(version, index, *offsets, true,
+ *offsets = rec_get_offsets(version, index, *offsets,
+ index->n_core_fields,
ULINT_UNDEFINED, offset_heap);
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ut_a(!rec_offs_any_null_extern(version, *offsets));
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index 4ae427b767d..d1eaea3095e 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -1575,7 +1575,7 @@ file_checked:
to the data files and truncate or delete the log.
Unless --export is specified, no further change to
InnoDB files is needed. */
- ut_ad(!srv_force_recovery);
+ ut_ad(srv_force_recovery <= SRV_FORCE_IGNORE_CORRUPT);
ut_ad(recv_no_log_write);
err = fil_write_flushed_lsn(log_sys.get_lsn());
DBUG_ASSERT(!buf_pool.any_io_pending());
diff --git a/storage/innobase/trx/trx0i_s.cc b/storage/innobase/trx/trx0i_s.cc
index b79c1169d33..f40ac9fedbe 100644
--- a/storage/innobase/trx/trx0i_s.cc
+++ b/storage/innobase/trx/trx0i_s.cc
@@ -654,7 +654,8 @@ fill_lock_data(
ut_a(n_fields > 0);
heap = NULL;
- offsets = rec_get_offsets(rec, index, offsets, true, n_fields, &heap);
+ offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields,
+ n_fields, &heap);
/* format and store the data */
diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc
index 1e7dfbed032..683825559a3 100644
--- a/storage/innobase/trx/trx0rec.cc
+++ b/storage/innobase/trx/trx0rec.cc
@@ -2533,7 +2533,8 @@ trx_undo_prev_version_build(
rec_offs offsets_dbg[REC_OFFS_NORMAL_SIZE];
rec_offs_init(offsets_dbg);
ut_a(!rec_offs_any_null_extern(
- *old_vers, rec_get_offsets(*old_vers, index, offsets_dbg, true,
+ *old_vers, rec_get_offsets(*old_vers, index, offsets_dbg,
+ index->n_core_fields,
ULINT_UNDEFINED, &heap)));
#endif // defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc
index 551ff4b9f3d..6b7a9e98d46 100644
--- a/storage/innobase/trx/trx0sys.cc
+++ b/storage/innobase/trx/trx0sys.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2020, MariaDB Corporation.
+Copyright (c) 2017, 2021, 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
diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc
index b0738b899fb..b6ad91babe4 100644
--- a/storage/innobase/ut/ut0ut.cc
+++ b/storage/innobase/ut/ut0ut.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2020, MariaDB Corporation.
+Copyright (c) 2017, 2021, 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
@@ -586,7 +586,7 @@ const char * dbug_print_rec(const rec_t* rec, dict_index_t* index)
rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
mem_heap_t* tmp_heap = NULL;
- offsets = rec_get_offsets(rec, index, offsets, true,
+ offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields,
ULINT_UNDEFINED, &tmp_heap);
rec_printer r(rec, offsets);
strmake(dbug_print_buf, r.str().c_str(), sizeof(dbug_print_buf) - 1);