MDEV-24620 ASAN heap-buffer-overflow in btr_pcur_restore_position()

Between btr_pcur_store_position() and btr_pcur_restore_position()
it is possible that purge empties a table and enlarges
index->n_core_fields and index->n_core_null_bytes.
Therefore, we must cache index->n_core_fields in
btr_pcur_t::old_n_core_fields so that btr_pcur_t::old_rec can be
parsed correctly.

Unfortunately, this is a huge change, because we will replace
"bool leaf" parameters with "ulint n_core"
(passing index->n_core_fields, or 0 for non-leaf pages).
For special cases where we know that index->is_instant() cannot hold,
we may also pass index->n_fields.
This commit is contained in:
Marko Mäkelä 2021-04-13 10:28:13 +03:00
commit b8c8692fd9
42 changed files with 614 additions and 421 deletions

View file

@ -317,5 +317,33 @@ SELECT * FROM t1 WHERE c<>1 ORDER BY c DESC;
c d c d
DROP TABLE t1; DROP TABLE t1;
SET GLOBAL innodb_limit_optimistic_insert_debug = @saved_limit; SET GLOBAL innodb_limit_optimistic_insert_debug = @saved_limit;
#
# MDEV-24620 ASAN heap-buffer-overflow in btr_pcur_restore_position()
#
CREATE TABLE t1 (a VARCHAR(1) PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1);
connect stop_purge,localhost,root,,;
START TRANSACTION WITH CONSISTENT SNAPSHOT;
connection default;
ALTER TABLE t1 ADD c INT;
BEGIN;
DELETE FROM t1;
connect dml,localhost,root,,test;
SET DEBUG_SYNC='row_mysql_handle_errors SIGNAL s1 WAIT_FOR s2';
UPDATE t1 SET c=1;
connection default;
SET DEBUG_SYNC='now WAIT_FOR s1';
COMMIT;
connection stop_purge;
COMMIT;
disconnect stop_purge;
connection default;
InnoDB 0 transactions not purged
SET DEBUG_SYNC='now SIGNAL s2';
connection dml;
disconnect dml;
connection default;
SET DEBUG_SYNC=RESET;
DROP TABLE t1;
# End of 10.3 tests # End of 10.3 tests
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency; SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;

View file

@ -364,6 +364,44 @@ DROP TABLE t1;
SET GLOBAL innodb_limit_optimistic_insert_debug = @saved_limit; SET GLOBAL innodb_limit_optimistic_insert_debug = @saved_limit;
--echo #
--echo # MDEV-24620 ASAN heap-buffer-overflow in btr_pcur_restore_position()
--echo #
CREATE TABLE t1 (a VARCHAR(1) PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1);
connect (stop_purge,localhost,root,,);
START TRANSACTION WITH CONSISTENT SNAPSHOT;
connection default;
ALTER TABLE t1 ADD c INT;
BEGIN;
DELETE FROM t1;
connect (dml,localhost,root,,test);
SET DEBUG_SYNC='row_mysql_handle_errors SIGNAL s1 WAIT_FOR s2';
send UPDATE t1 SET c=1;
connection default;
SET DEBUG_SYNC='now WAIT_FOR s1';
COMMIT;
connection stop_purge;
COMMIT;
disconnect stop_purge;
connection default;
--source include/wait_all_purged.inc
SET DEBUG_SYNC='now SIGNAL s2';
connection dml;
reap;
disconnect dml;
connection default;
SET DEBUG_SYNC=RESET;
DROP TABLE t1;
--echo # End of 10.3 tests --echo # End of 10.3 tests
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency; SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;

View file

@ -2,7 +2,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc. Copyright (c) 2012, Facebook Inc.
Copyright (c) 2014, 2020, MariaDB Corporation. Copyright (c) 2014, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
@ -890,7 +890,7 @@ btr_page_get_father_node_ptr_func(
node_ptr = btr_cur_get_rec(cursor); 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); ULINT_UNDEFINED, &heap);
if (btr_node_ptr_get_child_page_no(node_ptr, offsets) != page_no) { if (btr_node_ptr_get_child_page_no(node_ptr, offsets) != page_no) {
@ -907,10 +907,11 @@ btr_page_get_father_node_ptr_func(
print_rec = page_rec_get_next( print_rec = page_rec_get_next(
page_get_infimum_rec(page_align(user_rec))); page_get_infimum_rec(page_align(user_rec)));
offsets = rec_get_offsets(print_rec, index, offsets, 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); ULINT_UNDEFINED, &heap);
page_rec_print(print_rec, offsets); 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); ULINT_UNDEFINED, &heap);
page_rec_print(node_ptr, offsets); page_rec_print(node_ptr, offsets);
@ -2214,7 +2215,9 @@ btr_page_get_split_rec(
incl_data += insert_size; incl_data += insert_size;
} else { } else {
offsets = rec_get_offsets(rec, cursor->index, offsets, 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); ULINT_UNDEFINED, &heap);
incl_data += rec_offs_size(offsets); incl_data += rec_offs_size(offsets);
} }
@ -2323,7 +2326,9 @@ btr_page_insert_fits(
space after rec is removed from page. */ space after rec is removed from page. */
*offsets = rec_get_offsets(rec, cursor->index, *offsets, *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); ULINT_UNDEFINED, heap);
total_data -= rec_offs_size(*offsets); total_data -= rec_offs_size(*offsets);
@ -2610,7 +2615,8 @@ btr_page_tuple_smaller(
first_rec = page_cur_get_rec(&pcur); first_rec = page_cur_get_rec(&pcur);
*offsets = rec_get_offsets( *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); n_uniq, heap);
return(cmp_dtuple_rec(tuple, first_rec, *offsets) < 0); return(cmp_dtuple_rec(tuple, first_rec, *offsets) < 0);
@ -2894,7 +2900,9 @@ func_start:
first_rec = move_limit = split_rec; first_rec = move_limit = split_rec;
*offsets = rec_get_offsets(split_rec, cursor->index, *offsets, *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 insert_left = !tuple
|| cmp_dtuple_rec(tuple, split_rec, *offsets) < 0; || cmp_dtuple_rec(tuple, split_rec, *offsets) < 0;
@ -3665,7 +3673,7 @@ retry:
rec_offs* offsets2 = NULL; rec_offs* offsets2 = NULL;
/* For rtree, we need to update father's mbr. */ /* 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 /* We only support merge pages with the same parent
page */ page */
if (!rtr_check_same_block( if (!rtr_check_same_block(
@ -3683,7 +3691,8 @@ retry:
offsets2 = rec_get_offsets( offsets2 = rec_get_offsets(
btr_cur_get_rec(&cursor2), index, NULL, 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); ULINT_UNDEFINED, &heap);
/* Check if parent entry needs to be updated */ /* Check if parent entry needs to be updated */
@ -3857,13 +3866,14 @@ retry:
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
/* For rtree, we need to update father's mbr. */ /* For rtree, we need to update father's mbr. */
if (dict_index_is_spatial(index)) { if (index->is_spatial()) {
rec_offs* offsets2; rec_offs* offsets2;
ulint rec_info; ulint rec_info;
offsets2 = rec_get_offsets( offsets2 = rec_get_offsets(
btr_cur_get_rec(&cursor2), index, NULL, 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); ULINT_UNDEFINED, &heap);
ut_ad(btr_node_ptr_get_child_page_no( ut_ad(btr_node_ptr_get_child_page_no(
@ -4341,7 +4351,7 @@ btr_print_recursive(
node_ptr = page_cur_get_rec(&cursor); node_ptr = page_cur_get_rec(&cursor);
*offsets = rec_get_offsets( *offsets = rec_get_offsets(
node_ptr, index, *offsets, false, node_ptr, index, *offsets, 0,
ULINT_UNDEFINED, heap); ULINT_UNDEFINED, heap);
btr_print_recursive(index, btr_print_recursive(index,
btr_node_ptr_get_child(node_ptr, btr_node_ptr_get_child(node_ptr,
@ -4490,7 +4500,9 @@ btr_index_rec_validate(
page = page_align(rec); 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 /* The insert buffer index tree can contain records from any
other index: we cannot check the number of fields or other index: we cannot check the number of fields or
their length */ their length */
@ -4536,7 +4548,8 @@ btr_index_rec_validate(
} }
} }
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); ULINT_UNDEFINED, &heap);
for (unsigned i = 0; i < index->n_fields; i++) { for (unsigned i = 0; i < index->n_fields; i++) {
@ -4792,7 +4805,7 @@ btr_validate_level(
page_cur_move_to_next(&cursor); page_cur_move_to_next(&cursor);
node_ptr = page_cur_get_rec(&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); ULINT_UNDEFINED, &heap);
savepoint2 = mtr_set_savepoint(&mtr); savepoint2 = mtr_set_savepoint(&mtr);
@ -4916,10 +4929,12 @@ loop:
right_rec = page_rec_get_next(page_get_infimum_rec( right_rec = page_rec_get_next(page_get_infimum_rec(
right_page)); right_page));
offsets = rec_get_offsets(rec, index, offsets, offsets = rec_get_offsets(rec, index, offsets,
page_is_leaf(page), page_is_leaf(page)
? index->n_core_fields : 0,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
offsets2 = rec_get_offsets(right_rec, index, offsets2, 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); ULINT_UNDEFINED, &heap);
/* For spatial index, we cannot guarantee the key ordering /* For spatial index, we cannot guarantee the key ordering

View file

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2014, 2019, Oracle and/or its affiliates. All Rights Reserved. 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 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 the terms of the GNU General Public License as published by the Free Software
@ -193,7 +193,8 @@ PageBulk::insert(
if (!page_rec_is_infimum_low(page_offset(m_cur_rec))) { if (!page_rec_is_infimum_low(page_offset(m_cur_rec))) {
rec_t* old_rec = m_cur_rec; rec_t* old_rec = m_cur_rec;
rec_offs* old_offsets = rec_get_offsets( rec_offs* old_offsets = rec_get_offsets(
old_rec, m_index, NULL, is_leaf, old_rec, m_index, NULL, is_leaf
? m_index->n_core_fields : 0,
ULINT_UNDEFINED, &m_heap); ULINT_UNDEFINED, &m_heap);
ut_ad(cmp_rec_rec(rec, old_rec, offsets, old_offsets, m_index) ut_ad(cmp_rec_rec(rec, old_rec, offsets, old_offsets, m_index)
@ -447,6 +448,7 @@ PageBulk::getSplitRec()
ut_ad(m_page_zip != NULL); ut_ad(m_page_zip != NULL);
ut_ad(m_rec_no >= 2); 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); 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) total_used_size = page_get_free_space_of_empty(m_is_comp)
@ -456,13 +458,13 @@ PageBulk::getSplitRec()
n_recs = 0; n_recs = 0;
offsets = NULL; offsets = NULL;
rec = page_get_infimum_rec(m_page); rec = page_get_infimum_rec(m_page);
const ulint n_core = page_is_leaf(m_page) ? m_index->n_core_fields : 0;
do { do {
rec = page_rec_get_next(rec); rec = page_rec_get_next(rec);
ut_ad(page_rec_is_user_rec(rec)); ut_ad(page_rec_is_user_rec(rec));
offsets = rec_get_offsets(rec, m_index, offsets, offsets = rec_get_offsets(rec, m_index, offsets, n_core,
page_is_leaf(m_page),
ULINT_UNDEFINED, &m_heap); ULINT_UNDEFINED, &m_heap);
total_recs_size += rec_offs_size(offsets); total_recs_size += rec_offs_size(offsets);
n_recs++; n_recs++;
@ -491,9 +493,11 @@ PageBulk::copyIn(
ut_ad(m_rec_no == 0); ut_ad(m_rec_no == 0);
ut_ad(page_rec_is_user_rec(rec)); ut_ad(page_rec_is_user_rec(rec));
const ulint n_core = page_rec_is_leaf(rec)
? m_index->n_core_fields : 0;
do { do {
offsets = rec_get_offsets(rec, m_index, offsets, offsets = rec_get_offsets(rec, m_index, offsets, n_core,
page_rec_is_leaf(split_rec),
ULINT_UNDEFINED, &m_heap); ULINT_UNDEFINED, &m_heap);
insert(rec, offsets); insert(rec, offsets);
@ -534,8 +538,10 @@ PageBulk::copyOut(
/* Set last record's next in page */ /* Set last record's next in page */
rec_offs* offsets = NULL; rec_offs* offsets = NULL;
rec = page_rec_get_prev(split_rec); rec = page_rec_get_prev(split_rec);
offsets = rec_get_offsets(rec, m_index, offsets, const ulint n_core = page_rec_is_leaf(split_rec)
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); ULINT_UNDEFINED, &m_heap);
page_rec_set_next(rec, page_get_supremum_rec(m_page)); page_rec_set_next(rec, page_get_supremum_rec(m_page));
@ -543,8 +549,7 @@ PageBulk::copyOut(
m_cur_rec = rec; m_cur_rec = rec;
m_heap_top = rec_get_end(rec, offsets); m_heap_top = rec_get_end(rec, offsets);
offsets = rec_get_offsets(last_rec, m_index, offsets, offsets = rec_get_offsets(last_rec, m_index, offsets, n_core,
page_rec_is_leaf(split_rec),
ULINT_UNDEFINED, &m_heap); ULINT_UNDEFINED, &m_heap);
m_free_space += ulint(rec_get_end(last_rec, offsets) - m_heap_top) m_free_space += ulint(rec_get_end(last_rec, offsets) - m_heap_top)
@ -975,7 +980,8 @@ BtrBulk::insert(
/* Convert tuple to rec. */ /* Convert tuple to rec. */
rec = rec_convert_dtuple_to_rec(static_cast<byte*>(mem_heap_alloc( rec = rec_convert_dtuple_to_rec(static_cast<byte*>(mem_heap_alloc(
page_bulk->m_heap, rec_size)), m_index, tuple, n_ext); 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); ULINT_UNDEFINED, &page_bulk->m_heap);
page_bulk->insert(rec, offsets); page_bulk->insert(rec, offsets);

View file

@ -479,7 +479,8 @@ incompatible:
from the cache. */ from the cache. */
mem_heap_t* heap = NULL; 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); ULINT_UNDEFINED, &heap);
if (rec_offs_any_default(offsets)) { if (rec_offs_any_default(offsets)) {
inconsistent: inconsistent:
@ -1920,7 +1921,7 @@ retry_page_get:
node_ptr = page_cur_get_rec(page_cursor); 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); ULINT_UNDEFINED, &heap);
/* If the rec is the first or last in the page for /* If the rec is the first or last in the page for
@ -2051,7 +2052,7 @@ need_opposite_intention:
offsets2 = rec_get_offsets( offsets2 = rec_get_offsets(
first_rec, index, offsets2, first_rec, index, offsets2,
false, ULINT_UNDEFINED, &heap); 0, ULINT_UNDEFINED, &heap);
cmp_rec_rec(node_ptr, first_rec, cmp_rec_rec(node_ptr, first_rec,
offsets, offsets2, index, false, offsets, offsets2, index, false,
&matched_fields); &matched_fields);
@ -2069,7 +2070,7 @@ need_opposite_intention:
offsets2 = rec_get_offsets( offsets2 = rec_get_offsets(
last_rec, index, offsets2, last_rec, index, offsets2,
false, ULINT_UNDEFINED, &heap); 0, ULINT_UNDEFINED, &heap);
cmp_rec_rec( cmp_rec_rec(
node_ptr, last_rec, node_ptr, last_rec,
offsets, offsets2, index, offsets, offsets2, index,
@ -2238,7 +2239,7 @@ need_opposite_intention:
offsets = rec_get_offsets( offsets = rec_get_offsets(
my_node_ptr, index, offsets, my_node_ptr, index, offsets,
false, ULINT_UNDEFINED, &heap); 0, ULINT_UNDEFINED, &heap);
ulint my_page_no ulint my_page_no
= btr_node_ptr_get_child_page_no( = btr_node_ptr_get_child_page_no(
@ -2690,7 +2691,7 @@ btr_cur_open_at_index_side_func(
node_ptr = page_cur_get_rec(page_cursor); node_ptr = page_cur_get_rec(page_cursor);
offsets = rec_get_offsets(node_ptr, cursor->index, offsets, 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 /* If the rec is the first or last in the page for
pessimistic delete intention, it might cause node_ptr insert pessimistic delete intention, it might cause node_ptr insert
@ -2985,7 +2986,7 @@ btr_cur_open_at_rnd_pos_func(
node_ptr = page_cur_get_rec(page_cursor); node_ptr = page_cur_get_rec(page_cursor);
offsets = rec_get_offsets(node_ptr, cursor->index, offsets, 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 /* If the rec is the first or last in the page for
pessimistic delete intention, it might cause node_ptr insert pessimistic delete intention, it might cause node_ptr insert
@ -3932,7 +3933,8 @@ btr_cur_parse_update_in_place(
flags != (BTR_NO_UNDO_LOG_FLAG flags != (BTR_NO_UNDO_LOG_FLAG
| BTR_NO_LOCKING_FLAG | BTR_NO_LOCKING_FLAG
| BTR_KEEP_SYS_FLAG) | BTR_KEEP_SYS_FLAG)
|| page_is_leaf(page), || page_is_leaf(page)
? index->n_core_fields : 0,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
if (!(flags & BTR_KEEP_SYS_FLAG)) { if (!(flags & BTR_KEEP_SYS_FLAG)) {
@ -4318,7 +4320,7 @@ btr_cur_optimistic_update(
ut_ad(fil_page_index_page_check(page)); ut_ad(fil_page_index_page_check(page));
ut_ad(btr_page_get_index_id(page) == index->id); 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); ULINT_UNDEFINED, heap);
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ut_a(!rec_offs_any_null_extern(rec, *offsets) ut_a(!rec_offs_any_null_extern(rec, *offsets)
@ -5158,7 +5160,8 @@ btr_cur_parse_del_mark_set_clust_rec(
if (!(flags & BTR_KEEP_SYS_FLAG)) { if (!(flags & BTR_KEEP_SYS_FLAG)) {
row_upd_rec_sys_fields_in_recovery( row_upd_rec_sys_fields_in_recovery(
rec, page_zip, rec, page_zip,
rec_get_offsets(rec, index, offsets, true, rec_get_offsets(rec, index, offsets,
index->n_core_fields,
pos + 2, &heap), pos + 2, &heap),
pos, trx_id, roll_ptr); pos, trx_id, roll_ptr);
} else { } else {
@ -5167,7 +5170,8 @@ btr_cur_parse_del_mark_set_clust_rec(
ut_ad(memcmp(rec_get_nth_field( ut_ad(memcmp(rec_get_nth_field(
rec, rec,
rec_get_offsets(rec, index, rec_get_offsets(rec, index,
offsets, true, offsets, index
->n_core_fields,
pos, &heap), pos, &heap),
pos, &offset), pos, &offset),
field_ref_zero, DATA_TRX_ID_LEN)); field_ref_zero, DATA_TRX_ID_LEN));
@ -5502,7 +5506,8 @@ btr_cur_optimistic_delete_func(
rec = btr_cur_get_rec(cursor); 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); ULINT_UNDEFINED, &heap);
const ibool no_compress_needed = !rec_offs_any_extern(offsets) const ibool no_compress_needed = !rec_offs_any_extern(offsets)
@ -5711,7 +5716,8 @@ btr_cur_pessimistic_delete(
ut_a(!page_zip || page_zip_validate(page_zip, page, index)); ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */ #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); ULINT_UNDEFINED, &heap);
if (rec_offs_any_extern(offsets)) { if (rec_offs_any_extern(offsets)) {
@ -5807,7 +5813,7 @@ discard_page:
pointer as the predefined minimum record */ pointer as the predefined minimum record */
min_mark_next_rec = true; 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, /* For rtree, if delete the leftmost node pointer,
we need to update parent page. */ we need to update parent page. */
rtr_mbr_t father_mbr; rtr_mbr_t father_mbr;
@ -5822,7 +5828,7 @@ discard_page:
&father_cursor); &father_cursor);
offsets = rec_get_offsets( offsets = rec_get_offsets(
btr_cur_get_rec(&father_cursor), index, NULL, btr_cur_get_rec(&father_cursor), index, NULL,
false, ULINT_UNDEFINED, &heap); 0, ULINT_UNDEFINED, &heap);
father_rec = btr_cur_get_rec(&father_cursor); father_rec = btr_cur_get_rec(&father_cursor);
rtr_read_mbr(rec_get_nth_field( rtr_read_mbr(rec_get_nth_field(
@ -6744,12 +6750,13 @@ btr_estimate_number_of_different_key_vals(dict_index_t* index)
page = btr_cur_get_page(&cursor); page = btr_cur_get_page(&cursor);
rec = page_rec_get_next(page_get_infimum_rec(page)); 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)) { if (!page_rec_is_supremum(rec)) {
not_empty_flag = 1; not_empty_flag = 1;
offsets_rec = rec_get_offsets(rec, index, offsets_rec, offsets_rec = rec_get_offsets(rec, index, offsets_rec,
is_leaf, n_core,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
if (n_not_null != NULL) { if (n_not_null != NULL) {
@ -6770,7 +6777,7 @@ btr_estimate_number_of_different_key_vals(dict_index_t* index)
offsets_next_rec = rec_get_offsets(next_rec, index, offsets_next_rec = rec_get_offsets(next_rec, index,
offsets_next_rec, offsets_next_rec,
is_leaf, n_core,
ULINT_UNDEFINED, ULINT_UNDEFINED,
&heap); &heap);

View file

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (C) 2012, 2014 Facebook, Inc. All Rights Reserved. Copyright (C) 2012, 2014 Facebook, Inc. All Rights Reserved.
Copyright (C) 2014, 2019, MariaDB Corporation. Copyright (C) 2014, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
@ -340,12 +340,12 @@ btr_defragment_calc_n_recs_for_size(
ulint size = 0; ulint size = 0;
page_cur_t cur; 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_set_before_first(block, &cur);
page_cur_move_to_next(&cur); page_cur_move_to_next(&cur);
while (page_cur_get_rec(&cur) != page_get_supremum_rec(page)) { while (page_cur_get_rec(&cur) != page_get_supremum_rec(page)) {
rec_t* cur_rec = page_cur_get_rec(&cur); rec_t* cur_rec = page_cur_get_rec(&cur);
offsets = rec_get_offsets(cur_rec, index, offsets, offsets = rec_get_offsets(cur_rec, index, offsets, n_core,
page_is_leaf(page),
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
ulint rec_size = rec_offs_size(offsets); ulint rec_size = rec_offs_size(offsets);
size += rec_size; size += rec_size;
@ -357,6 +357,9 @@ btr_defragment_calc_n_recs_for_size(
page_cur_move_to_next(&cur); page_cur_move_to_next(&cur);
} }
*n_recs_size = size; *n_recs_size = size;
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return n_recs; return n_recs;
} }

View file

@ -61,6 +61,7 @@ btr_pcur_reset(
cursor->btr_cur.index = NULL; cursor->btr_cur.index = NULL;
cursor->btr_cur.page_cur.rec = NULL; cursor->btr_cur.page_cur.rec = NULL;
cursor->old_rec = NULL; cursor->old_rec = NULL;
cursor->old_n_core_fields = 0;
cursor->old_n_fields = 0; cursor->old_n_fields = 0;
cursor->old_stored = false; cursor->old_stored = false;
@ -178,9 +179,28 @@ before_first:
cursor->rel_pos = BTR_PCUR_ON; cursor->rel_pos = BTR_PCUR_ON;
} }
cursor->old_rec = dict_index_copy_rec_order_prefix( UNIV_PREFETCH_R(rec);
index, rec, &cursor->old_n_fields,
&cursor->old_rec_buf, &cursor->buf_size); if (index->is_ibuf()) {
cursor->old_n_fields = uint16(rec_get_n_fields_old(rec));
} else {
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,
&cursor->buf_size);
cursor->block_when_stored.store(block); cursor->block_when_stored.store(block);
@ -212,6 +232,7 @@ btr_pcur_copy_stored_position(
+ (pcur_donate->old_rec - pcur_donate->old_rec_buf); + (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; pcur_receive->old_n_fields = pcur_donate->old_n_fields;
} }
@ -303,6 +324,8 @@ btr_pcur_restore_position_func(
} }
ut_a(cursor->old_rec); 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); ut_a(cursor->old_n_fields);
switch (latch_mode) { switch (latch_mode) {
@ -336,11 +359,16 @@ btr_pcur_restore_position_func(
rec_offs_init(offsets2_); rec_offs_init(offsets2_);
heap = mem_heap_create(256); heap = mem_heap_create(256);
ut_ad(cursor->old_n_core_fields
== index->n_core_fields);
offsets1 = rec_get_offsets( 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); cursor->old_n_fields, &heap);
offsets2 = rec_get_offsets( offsets2 = rec_get_offsets(
rec, index, offsets2, true, rec, index, offsets2,
index->n_core_fields,
cursor->old_n_fields, &heap); cursor->old_n_fields, &heap);
ut_ad(!cmp_rec_rec(cursor->old_rec, ut_ad(!cmp_rec_rec(cursor->old_rec,
@ -365,8 +393,14 @@ btr_pcur_restore_position_func(
heap = mem_heap_create(256); heap = mem_heap_create(256);
tuple = dict_index_build_data_tuple(cursor->old_rec, index, true, tuple = dtuple_create(heap, cursor->old_n_fields);
cursor->old_n_fields, heap);
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 */ /* Save the old search mode of the cursor */
old_mode = cursor->search_mode; old_mode = cursor->search_mode;
@ -405,7 +439,8 @@ btr_pcur_restore_position_func(
&& btr_pcur_is_on_user_rec(cursor) && btr_pcur_is_on_user_rec(cursor)
&& !cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor), && !cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor),
rec_get_offsets(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))) { ULINT_UNDEFINED, &heap))) {
/* We have to store the NEW value for the modify clock, /* We have to store the NEW value for the modify clock,

View file

@ -703,7 +703,8 @@ btr_search_update_hash_ref(
ulint fold = rec_fold( ulint fold = rec_fold(
rec, rec,
rec_get_offsets(rec, index, offsets_, true, rec_get_offsets(rec, index, offsets_,
index->n_core_fields,
ULINT_UNDEFINED, &heap), ULINT_UNDEFINED, &heap),
block->curr_n_fields, block->curr_n_fields,
block->curr_n_bytes, index->id); block->curr_n_bytes, index->id);
@ -762,7 +763,8 @@ btr_search_check_guess(
match = 0; 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); n_unique, &heap);
cmp = cmp_dtuple_rec_with_match(tuple, rec, offsets, &match); cmp = cmp_dtuple_rec_with_match(tuple, rec, offsets, &match);
@ -813,7 +815,8 @@ btr_search_check_guess(
} }
offsets = rec_get_offsets(prev_rec, cursor->index, offsets, 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( cmp = cmp_dtuple_rec_with_match(
tuple, prev_rec, offsets, &match); tuple, prev_rec, offsets, &match);
if (mode == PAGE_CUR_GE) { if (mode == PAGE_CUR_GE) {
@ -836,7 +839,8 @@ btr_search_check_guess(
} }
offsets = rec_get_offsets(next_rec, cursor->index, offsets, 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( cmp = cmp_dtuple_rec_with_match(
tuple, next_rec, offsets, &match); tuple, next_rec, offsets, &match);
if (mode == PAGE_CUR_LE) { if (mode == PAGE_CUR_LE) {
@ -1202,7 +1206,7 @@ retry:
while (!page_rec_is_supremum(rec)) { while (!page_rec_is_supremum(rec)) {
offsets = rec_get_offsets( offsets = rec_get_offsets(
rec, index, offsets, true, rec, index, offsets, index->n_core_fields,
btr_search_get_n_fields(n_fields, n_bytes), btr_search_get_n_fields(n_fields, n_bytes),
&heap); &heap);
fold = rec_fold(rec, offsets, n_fields, n_bytes, index_id); fold = rec_fold(rec, offsets, n_fields, n_bytes, index_id);
@ -1428,7 +1432,7 @@ btr_search_build_page_hash_index(
ut_a(index->id == btr_page_get_index_id(page)); ut_a(index->id == btr_page_get_index_id(page));
offsets = rec_get_offsets( offsets = rec_get_offsets(
rec, index, offsets, true, rec, index, offsets, index->n_core_fields,
btr_search_get_n_fields(n_fields, n_bytes), btr_search_get_n_fields(n_fields, n_bytes),
&heap); &heap);
ut_ad(page_rec_is_supremum(rec) ut_ad(page_rec_is_supremum(rec)
@ -1459,7 +1463,7 @@ btr_search_build_page_hash_index(
} }
offsets = rec_get_offsets( 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); btr_search_get_n_fields(n_fields, n_bytes), &heap);
next_fold = rec_fold(next_rec, offsets, n_fields, next_fold = rec_fold(next_rec, offsets, n_fields,
n_bytes, index->id); n_bytes, index->id);
@ -1699,7 +1703,8 @@ void btr_search_update_hash_on_delete(btr_cur_t* cursor)
rec = btr_cur_get_rec(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), ULINT_UNDEFINED, &heap),
block->curr_n_fields, block->curr_n_bytes, index->id); block->curr_n_fields, block->curr_n_bytes, index->id);
if (UNIV_LIKELY_NULL(heap)) { if (UNIV_LIKELY_NULL(heap)) {
@ -1876,13 +1881,14 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch)
ins_rec = page_rec_get_next_const(rec); ins_rec = page_rec_get_next_const(rec);
next_rec = page_rec_get_next_const(ins_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); ULINT_UNDEFINED, &heap);
ins_fold = rec_fold(ins_rec, offsets, n_fields, n_bytes, index->id); ins_fold = rec_fold(ins_rec, offsets, n_fields, n_bytes, index->id);
if (!page_rec_is_supremum(next_rec)) { if (!page_rec_is_supremum(next_rec)) {
offsets = rec_get_offsets( 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); btr_search_get_n_fields(n_fields, n_bytes), &heap);
next_fold = rec_fold(next_rec, offsets, n_fields, next_fold = rec_fold(next_rec, offsets, n_fields,
n_bytes, index->id); n_bytes, index->id);
@ -1894,7 +1900,7 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch)
if (!page_rec_is_infimum(rec) && !rec_is_metadata(rec, index)) { if (!page_rec_is_infimum(rec) && !rec_is_metadata(rec, index)) {
offsets = rec_get_offsets( 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); btr_search_get_n_fields(n_fields, n_bytes), &heap);
fold = rec_fold(rec, offsets, n_fields, n_bytes, index->id); fold = rec_fold(rec, offsets, n_fields, n_bytes, index->id);
} else { } else {
@ -2100,7 +2106,8 @@ btr_search_hash_table_validate(ulint hash_table_id)
page_index_id = btr_page_get_index_id(block->frame); page_index_id = btr_page_get_index_id(block->frame);
offsets = rec_get_offsets( 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, btr_search_get_n_fields(block->curr_n_fields,
block->curr_n_bytes), block->curr_n_bytes),
&heap); &heap);

View file

@ -2,7 +2,7 @@
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc. 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 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 the terms of the GNU General Public License as published by the Free Software
@ -5035,7 +5035,9 @@ dict_index_build_node_ptr(
dtype_set(dfield_get_type(field), DATA_SYS_CHILD, DATA_NOT_NULL, 4); 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) dtuple_set_info_bits(tuple, dtuple_get_info_bits(tuple)
| REC_STATUS_NODE_PTR); | REC_STATUS_NODE_PTR);
@ -5044,46 +5046,6 @@ dict_index_build_node_ptr(
return(tuple); return(tuple);
} }
/**********************************************************************//**
Copies an initial segment of a physical record, long enough to specify an
index entry uniquely.
@return pointer to the prefix record */
rec_t*
dict_index_copy_rec_order_prefix(
/*=============================*/
const dict_index_t* index, /*!< in: index */
const rec_t* rec, /*!< in: record for which to
copy prefix */
ulint* n_fields,/*!< out: number of fields copied */
byte** buf, /*!< in/out: memory buffer for the
copied prefix, or NULL */
ulint* buf_size)/*!< in/out: buffer size */
{
ulint n;
UNIV_PREFETCH_R(rec);
if (dict_index_is_ibuf(index)) {
ut_ad(!dict_table_is_comp(index->table));
n = rec_get_n_fields_old(rec);
} else {
if (page_rec_is_leaf(rec)) {
n = dict_index_get_n_unique_in_tree(index);
} else if (dict_index_is_spatial(index)) {
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. */
n = DICT_INDEX_SPATIAL_NODEPTR_SIZE + 1;
} else {
n = dict_index_get_n_unique_in_tree(index);
}
}
*n_fields = n;
return(rec_copy_prefix_to_buf(rec, index, n, buf, buf_size));
}
/** Convert a physical record into a search tuple. /** Convert a physical record into a search tuple.
@param[in] rec index record (not necessarily in an index page) @param[in] rec index record (not necessarily in an index page)
@param[in] index index @param[in] index index
@ -5099,11 +5061,14 @@ dict_index_build_data_tuple(
ulint n_fields, ulint n_fields,
mem_heap_t* heap) mem_heap_t* heap)
{ {
ut_ad(!index->is_clust());
dtuple_t* tuple = dtuple_create(heap, n_fields); dtuple_t* tuple = dtuple_create(heap, n_fields);
dict_index_copy_types(tuple, index, 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)); ut_ad(dtuple_check_typed(tuple));

View file

@ -2,7 +2,7 @@
Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc. 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 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 the terms of the GNU General Public License as published by the Free Software
@ -1544,7 +1544,8 @@ dict_index_t::vers_history_row(
rec_t* clust_rec = rec_t* clust_rec =
row_get_clust_rec(BTR_SEARCH_LEAF, rec, this, &clust_index, &mtr); row_get_clust_rec(BTR_SEARCH_LEAF, rec, this, &clust_index, &mtr);
if (clust_rec) { 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); ULINT_UNDEFINED, &heap);
history_row = clust_index->vers_history_row(clust_rec, offsets); history_row = clust_index->vers_history_row(clust_rec, offsets);

View file

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2009, 2019, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2009, 2019, 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 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 the terms of the GNU General Public License as published by the Free Software
@ -1158,7 +1158,7 @@ dict_stats_analyze_index_level(
prev_rec_offsets = rec_get_offsets( prev_rec_offsets = rec_get_offsets(
prev_rec, index, prev_rec_offsets, prev_rec, index, prev_rec_offsets,
true, index->n_core_fields,
n_uniq, &heap); n_uniq, &heap);
prev_rec = rec_copy_prefix_to_buf( prev_rec = rec_copy_prefix_to_buf(
@ -1170,8 +1170,9 @@ dict_stats_analyze_index_level(
continue; continue;
} }
rec_offsets = rec_get_offsets( rec_offsets = rec_get_offsets(rec, index, rec_offsets,
rec, index, rec_offsets, !level, n_uniq, &heap); level ? 0 : index->n_core_fields,
n_uniq, &heap);
(*total_recs)++; (*total_recs)++;
@ -1179,7 +1180,8 @@ dict_stats_analyze_index_level(
ulint matched_fields; ulint matched_fields;
prev_rec_offsets = rec_get_offsets( 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); n_uniq, &heap);
cmp_rec_rec(prev_rec, rec, cmp_rec_rec(prev_rec, rec,
@ -1333,7 +1335,7 @@ be big enough)
@param[in] index index of the page @param[in] index index of the page
@param[in] page the page to scan @param[in] page the page to scan
@param[in] n_prefix look at the first n_prefix columns @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_diff number of distinct records encountered
@param[out] n_external_pages if this is non-NULL then it will be set @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 to the number of externally stored pages which were encountered
@ -1348,7 +1350,7 @@ dict_stats_scan_page(
const dict_index_t* index, const dict_index_t* index,
const page_t* page, const page_t* page,
ulint n_prefix, ulint n_prefix,
bool is_leaf, ulint n_core,
ib_uint64_t* n_diff, ib_uint64_t* n_diff,
ib_uint64_t* n_external_pages) ib_uint64_t* n_external_pages)
{ {
@ -1360,9 +1362,9 @@ dict_stats_scan_page(
Because offsets1,offsets2 should be big enough, Because offsets1,offsets2 should be big enough,
this memory heap should never be used. */ this memory heap should never be used. */
mem_heap_t* heap = NULL; 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*) 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_const
: page_rec_get_next_non_del_marked; : page_rec_get_next_non_del_marked;
@ -1381,7 +1383,7 @@ dict_stats_scan_page(
return(NULL); 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); ULINT_UNDEFINED, &heap);
if (should_count_external_pages) { if (should_count_external_pages) {
@ -1398,7 +1400,7 @@ dict_stats_scan_page(
ulint matched_fields; ulint matched_fields;
offsets_next_rec = rec_get_offsets(next_rec, index, offsets_next_rec = rec_get_offsets(next_rec, index,
offsets_next_rec, is_leaf, offsets_next_rec, n_core,
ULINT_UNDEFINED, ULINT_UNDEFINED,
&heap); &heap);
@ -1412,7 +1414,7 @@ dict_stats_scan_page(
(*n_diff)++; (*n_diff)++;
if (!is_leaf) { if (!n_core) {
break; break;
} }
} }
@ -1498,7 +1500,7 @@ dict_stats_analyze_index_below_cur(
rec = btr_cur_get_rec(cur); rec = btr_cur_get_rec(cur);
ut_ad(!page_rec_is_leaf(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); ULINT_UNDEFINED, &heap);
page_id_t page_id(index->table->space_id, page_id_t page_id(index->table->space_id,
@ -1532,7 +1534,7 @@ dict_stats_analyze_index_below_cur(
/* search for the first non-boring record on the page */ /* search for the first non-boring record on the page */
offsets_rec = dict_stats_scan_page( offsets_rec = dict_stats_scan_page(
&rec, offsets1, offsets2, index, page, n_prefix, &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 */ /* pages on level > 0 are not allowed to be empty */
ut_a(offsets_rec != NULL); ut_a(offsets_rec != NULL);
@ -1577,7 +1579,7 @@ dict_stats_analyze_index_below_cur(
offsets_rec = dict_stats_scan_page( offsets_rec = dict_stats_scan_page(
&rec, offsets1, offsets2, index, page, n_prefix, &rec, offsets1, offsets2, index, page, n_prefix,
true, n_diff, index->n_core_fields, n_diff,
n_external_pages); n_external_pages);
#if 0 #if 0

View file

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, 2020, MariaDB Corporation. Copyright (c) 2016, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
@ -3495,7 +3495,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); ULINT_UNDEFINED, &heap);
for (ulint i = 0; i < num_idx; ++i) { for (ulint i = 0; i < num_idx; ++i) {
@ -3671,7 +3672,8 @@ fts_get_max_doc_id(
ut_ad(!rec_is_metadata(rec, index)); ut_ad(!rec_is_metadata(rec, index));
offsets = rec_get_offsets( offsets = rec_get_offsets(
rec, index, offsets, true, ULINT_UNDEFINED, &heap); rec, index, offsets, index->n_core_fields,
ULINT_UNDEFINED, &heap);
data = rec_get_nth_field(rec, offsets, 0, &len); data = rec_get_nth_field(rec, offsets, 0, &len);
@ -5166,7 +5168,8 @@ fts_get_doc_id_from_rec(
rec_offs_init(offsets_); rec_offs_init(offsets_);
offsets = rec_get_offsets( offsets = rec_get_offsets(
rec, index, offsets, true, ULINT_UNDEFINED, &my_heap); rec, index, offsets, index->n_core_fields,
ULINT_UNDEFINED, &my_heap);
col_no = dict_col_get_index_pos( col_no = dict_col_get_index_pos(
&table->cols[table->fts->doc_col], index); &table->cols[table->fts->doc_col], index);

View file

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2016, 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 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 the terms of the GNU General Public License as published by the Free Software
@ -87,8 +87,9 @@ rtr_page_split_initialize_nodes(
stop = task + n_recs; stop = task + n_recs;
rec = page_rec_get_next(page_get_infimum_rec(page)); 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)
*offsets = rec_get_offsets(rec, cursor->index, *offsets, is_leaf, ? cursor->index->n_core_fields : 0;
*offsets = rec_get_offsets(rec, cursor->index, *offsets, n_core,
n_uniq, &heap); n_uniq, &heap);
source_cur = rec_get_nth_field(rec, *offsets, 0, &len); 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); rec = page_rec_get_next(rec);
*offsets = rec_get_offsets(rec, cursor->index, *offsets, *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); source_cur = rec_get_nth_field(rec, *offsets, 0, &len);
} }
@ -308,7 +309,8 @@ rtr_update_mbr_field(
page_zip = buf_block_get_page_zip(block); page_zip = buf_block_get_page_zip(block);
child = btr_node_ptr_get_child_page_no(rec, offsets); 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) { if (new_rec) {
child_rec = new_rec; child_rec = new_rec;
@ -324,7 +326,7 @@ rtr_update_mbr_field(
if (cursor2) { if (cursor2) {
rec_t* del_rec = btr_cur_get_rec(cursor2); rec_t* del_rec = btr_cur_get_rec(cursor2);
offsets2 = rec_get_offsets(btr_cur_get_rec(cursor2), offsets2 = rec_get_offsets(btr_cur_get_rec(cursor2),
index, NULL, false, index, NULL, 0,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
del_page_no = btr_node_ptr_get_child_page_no(del_rec, offsets2); 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)); cur2_pos = page_rec_get_n_recs_before(btr_cur_get_rec(cursor2));
@ -389,7 +391,7 @@ rtr_update_mbr_field(
= page_rec_get_nth(page, cur2_pos); = page_rec_get_nth(page, cur2_pos);
} }
offsets2 = rec_get_offsets(btr_cur_get_rec(cursor2), offsets2 = rec_get_offsets(btr_cur_get_rec(cursor2),
index, NULL, false, index, NULL, 0,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
ut_ad(del_page_no == btr_node_ptr_get_child_page_no( ut_ad(del_page_no == btr_node_ptr_get_child_page_no(
cursor2->page_cur.rec, cursor2->page_cur.rec,
@ -427,7 +429,7 @@ rtr_update_mbr_field(
ut_ad(old_rec != insert_rec); ut_ad(old_rec != insert_rec);
page_cur_position(old_rec, block, &page_cur); 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); ULINT_UNDEFINED, &heap);
page_cur_delete_rec(&page_cur, index, offsets2, mtr); page_cur_delete_rec(&page_cur, index, offsets2, mtr);
@ -457,7 +459,7 @@ update_mbr:
cur2_rec = cursor2->page_cur.rec; cur2_rec = cursor2->page_cur.rec;
offsets2 = rec_get_offsets(cur2_rec, index, NULL, offsets2 = rec_get_offsets(cur2_rec, index, NULL,
is_leaf, n_core,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
cur2_rec_info = rec_get_info_bits(cur2_rec, cur2_rec_info = rec_get_info_bits(cur2_rec,
@ -517,7 +519,7 @@ update_mbr:
if (ins_suc) { if (ins_suc) {
btr_cur_position(index, insert_rec, block, cursor); btr_cur_position(index, insert_rec, block, cursor);
offsets = rec_get_offsets(insert_rec, offsets = rec_get_offsets(insert_rec,
index, offsets, is_leaf, index, offsets, n_core,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
} }
@ -532,7 +534,7 @@ update_mbr:
cur2_rec = btr_cur_get_rec(cursor2); cur2_rec = btr_cur_get_rec(cursor2);
offsets2 = rec_get_offsets(cur2_rec, index, NULL, offsets2 = rec_get_offsets(cur2_rec, index, NULL,
is_leaf, n_core,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
/* If the cursor2 position is on a wrong rec, we /* If the cursor2 position is on a wrong rec, we
@ -546,7 +548,7 @@ update_mbr:
while (!page_rec_is_supremum(cur2_rec)) { while (!page_rec_is_supremum(cur2_rec)) {
offsets2 = rec_get_offsets(cur2_rec, index, offsets2 = rec_get_offsets(cur2_rec, index,
NULL, NULL,
is_leaf, n_core,
ULINT_UNDEFINED, ULINT_UNDEFINED,
&heap); &heap);
cur2_pno = btr_node_ptr_get_child_page_no( cur2_pno = btr_node_ptr_get_child_page_no(
@ -834,7 +836,8 @@ rtr_split_page_move_rec_list(
rec_move = static_cast<rtr_rec_move_t*>(mem_heap_alloc( rec_move = static_cast<rtr_rec_move_t*>(mem_heap_alloc(
heap, heap,
sizeof (*rec_move) * max_to_move)); 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. */ /* Insert the recs in group 2 to new page. */
for (cur_split_node = node_array; for (cur_split_node = node_array;
@ -844,10 +847,10 @@ rtr_split_page_move_rec_list(
block, cur_split_node->key); block, cur_split_node->key);
offsets = rec_get_offsets(cur_split_node->key, offsets = rec_get_offsets(cur_split_node->key,
index, offsets, is_leaf, index, offsets, n_core,
ULINT_UNDEFINED, &heap); 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( rec = page_cur_insert_rec_low(
page_cur_get_rec(&new_page_cursor), page_cur_get_rec(&new_page_cursor),
@ -882,7 +885,7 @@ rtr_split_page_move_rec_list(
same temp-table in parallel. same temp-table in parallel.
max_trx_id is ignored for temp tables because it not required max_trx_id is ignored for temp tables because it not required
for MVCC. */ 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_update_max_trx_id(new_block, NULL,
page_get_max_trx_id(page), page_get_max_trx_id(page),
mtr); mtr);
@ -935,7 +938,7 @@ rtr_split_page_move_rec_list(
block, &page_cursor); block, &page_cursor);
offsets = rec_get_offsets( offsets = rec_get_offsets(
page_cur_get_rec(&page_cursor), index, page_cur_get_rec(&page_cursor), index,
offsets, is_leaf, ULINT_UNDEFINED, offsets, n_core, ULINT_UNDEFINED,
&heap); &heap);
page_cur_delete_rec(&page_cursor, page_cur_delete_rec(&page_cursor,
index, offsets, mtr); index, offsets, mtr);
@ -1134,6 +1137,9 @@ func_start:
/* Update the lock table */ /* Update the lock table */
lock_rtr_move_rec_list(new_block, block, rec_move, moved); 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. */ /* Delete recs in first group from the new page. */
for (cur_split_node = rtr_split_node_array; for (cur_split_node = rtr_split_node_array;
cur_split_node < end_split_node - 1; ++cur_split_node) { cur_split_node < end_split_node - 1; ++cur_split_node) {
@ -1152,7 +1158,7 @@ func_start:
*offsets = rec_get_offsets( *offsets = rec_get_offsets(
page_cur_get_rec(page_cursor), page_cur_get_rec(page_cursor),
cursor->index, *offsets, !page_level, cursor->index, *offsets, n_core,
ULINT_UNDEFINED, heap); ULINT_UNDEFINED, heap);
page_cur_delete_rec(page_cursor, page_cur_delete_rec(page_cursor,
@ -1169,7 +1175,7 @@ func_start:
block, page_cursor); block, page_cursor);
*offsets = rec_get_offsets( *offsets = rec_get_offsets(
page_cur_get_rec(page_cursor), page_cur_get_rec(page_cursor),
cursor->index, *offsets, !page_level, cursor->index, *offsets, n_core,
ULINT_UNDEFINED, heap); ULINT_UNDEFINED, heap);
page_cur_delete_rec(page_cursor, page_cur_delete_rec(page_cursor,
cursor->index, *offsets, mtr); cursor->index, *offsets, mtr);
@ -1398,7 +1404,8 @@ rtr_page_copy_rec_list_end_no_locks(
rec_offs offsets_2[REC_OFFS_NORMAL_SIZE]; rec_offs offsets_2[REC_OFFS_NORMAL_SIZE];
rec_offs* offsets2 = offsets_2; rec_offs* offsets2 = offsets_2;
ulint moved = 0; 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_1);
rec_offs_init(offsets_2); rec_offs_init(offsets_2);
@ -1427,14 +1434,14 @@ rtr_page_copy_rec_list_end_no_locks(
cur_rec = page_rec_get_next(cur_rec); 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); ULINT_UNDEFINED, &heap);
while (!page_rec_is_supremum(cur_rec)) { while (!page_rec_is_supremum(cur_rec)) {
ulint cur_matched_fields = 0; ulint cur_matched_fields = 0;
int cmp; int cmp;
offsets2 = rec_get_offsets(cur_rec, index, offsets2, offsets2 = rec_get_offsets(cur_rec, index, offsets2,
is_leaf, n_core,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
cmp = cmp_rec_rec(cur1_rec, cur_rec, cmp = cmp_rec_rec(cur1_rec, cur_rec,
offsets1, offsets2, index, false, offsets1, offsets2, index, false,
@ -1446,7 +1453,7 @@ rtr_page_copy_rec_list_end_no_locks(
/* Skip small recs. */ /* Skip small recs. */
page_cur_move_to_next(&page_cur); page_cur_move_to_next(&page_cur);
cur_rec = page_cur_get_rec(&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, if (rec_get_deleted_flag(cur1_rec,
dict_table_is_comp(index->table))) { dict_table_is_comp(index->table))) {
goto next; goto next;
@ -1469,7 +1476,7 @@ rtr_page_copy_rec_list_end_no_locks(
cur_rec = page_cur_get_rec(&page_cur); 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); ULINT_UNDEFINED, &heap);
ins_rec = page_cur_insert_rec_low(cur_rec, index, ins_rec = page_cur_insert_rec_low(cur_rec, index,
@ -1525,7 +1532,8 @@ rtr_page_copy_rec_list_start_no_locks(
rec_offs* offsets2 = offsets_2; rec_offs* offsets2 = offsets_2;
page_cur_t page_cur; page_cur_t page_cur;
ulint moved = 0; 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_1);
rec_offs_init(offsets_2); rec_offs_init(offsets_2);
@ -1545,14 +1553,14 @@ rtr_page_copy_rec_list_start_no_locks(
cur_rec = page_rec_get_next(cur_rec); 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); ULINT_UNDEFINED, &heap);
while (!page_rec_is_supremum(cur_rec)) { while (!page_rec_is_supremum(cur_rec)) {
ulint cur_matched_fields = 0; ulint cur_matched_fields = 0;
offsets2 = rec_get_offsets(cur_rec, index, offsets2, offsets2 = rec_get_offsets(cur_rec, index, offsets2,
is_leaf, n_core,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
int cmp = cmp_rec_rec(cur1_rec, cur_rec, int cmp = cmp_rec_rec(cur1_rec, cur_rec,
offsets1, offsets2, index, false, offsets1, offsets2, index, false,
@ -1565,7 +1573,7 @@ rtr_page_copy_rec_list_start_no_locks(
/* Skip small recs. */ /* Skip small recs. */
page_cur_move_to_next(&page_cur); page_cur_move_to_next(&page_cur);
cur_rec = page_cur_get_rec(&page_cur); cur_rec = page_cur_get_rec(&page_cur);
} else if (is_leaf) { } else if (n_core) {
if (rec_get_deleted_flag( if (rec_get_deleted_flag(
cur1_rec, cur1_rec,
dict_table_is_comp(index->table))) { dict_table_is_comp(index->table))) {
@ -1589,7 +1597,7 @@ rtr_page_copy_rec_list_start_no_locks(
cur_rec = page_cur_get_rec(&page_cur); 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); ULINT_UNDEFINED, &heap);
ins_rec = page_cur_insert_rec_low(cur_rec, index, ins_rec = page_cur_insert_rec_low(cur_rec, index,
@ -1743,7 +1751,7 @@ rtr_check_same_block(
while (!page_rec_is_supremum(rec)) { while (!page_rec_is_supremum(rec)) {
offsets = rec_get_offsets( 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) { if (btr_node_ptr_get_child_page_no(rec, offsets) == page_no) {
btr_cur_position(index, rec, parentb, cursor); btr_cur_position(index, rec, parentb, cursor);

View file

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2016, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2016, 2018, 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 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 the terms of the GNU General Public License as published by the Free Software
@ -530,8 +530,7 @@ rtr_compare_cursor_rec(
rec = btr_cur_get_rec(cursor); rec = btr_cur_get_rec(cursor);
offsets = rec_get_offsets( offsets = rec_get_offsets(rec, index, NULL, 0, ULINT_UNDEFINED, heap);
rec, index, NULL, false, ULINT_UNDEFINED, heap);
return(btr_node_ptr_get_child_page_no(rec, offsets) == page_no); return(btr_node_ptr_get_child_page_no(rec, offsets) == page_no);
} }
@ -836,7 +835,8 @@ rtr_page_get_father_node_ptr(
user_rec = btr_cur_get_rec(cursor); user_rec = btr_cur_get_rec(cursor);
ut_a(page_rec_is_user_rec(user_rec)); 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); ULINT_UNDEFINED, &heap);
rtr_get_mbr_from_rec(user_rec, offsets, &mbr); rtr_get_mbr_from_rec(user_rec, offsets, &mbr);
@ -853,7 +853,7 @@ rtr_page_get_father_node_ptr(
node_ptr = btr_cur_get_rec(cursor); node_ptr = btr_cur_get_rec(cursor);
ut_ad(!page_rec_is_comp(node_ptr) ut_ad(!page_rec_is_comp(node_ptr)
|| rec_get_status(node_ptr) == REC_STATUS_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_UNDEFINED, &heap);
ulint child_page = btr_node_ptr_get_child_page_no(node_ptr, offsets); ulint child_page = btr_node_ptr_get_child_page_no(node_ptr, offsets);
@ -871,13 +871,14 @@ rtr_page_get_father_node_ptr(
print_rec = page_rec_get_next( print_rec = page_rec_get_next(
page_get_infimum_rec(page_align(user_rec))); page_get_infimum_rec(page_align(user_rec)));
offsets = rec_get_offsets(print_rec, index, offsets, 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); ULINT_UNDEFINED, &heap);
error << "; child "; error << "; child ";
rec_print(error.m_oss, print_rec, rec_print(error.m_oss, print_rec,
rec_get_info_bits(print_rec, rec_offs_comp(offsets)), rec_get_info_bits(print_rec, rec_offs_comp(offsets)),
offsets); offsets);
offsets = rec_get_offsets(node_ptr, index, offsets, false, offsets = rec_get_offsets(node_ptr, index, offsets, 0,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
error << "; parent "; error << "; parent ";
rec_print(error.m_oss, print_rec, rec_print(error.m_oss, print_rec,
@ -1323,10 +1324,12 @@ rtr_cur_restore_position(
heap = mem_heap_create(256); heap = mem_heap_create(256);
offsets1 = rec_get_offsets( 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); r_cursor->old_n_fields, &heap);
offsets2 = rec_get_offsets( offsets2 = rec_get_offsets(
rec, index, NULL, !level, rec, index, NULL,
level ? 0 : r_cursor->old_n_fields,
r_cursor->old_n_fields, &heap); r_cursor->old_n_fields, &heap);
comp = rec_offs_comp(offsets1); comp = rec_offs_comp(offsets1);
@ -1394,12 +1397,12 @@ search_again:
rec = btr_pcur_get_rec(r_cursor); rec = btr_pcur_get_rec(r_cursor);
offsets1 = rec_get_offsets( offsets1 = rec_get_offsets(r_cursor->old_rec, index, NULL,
r_cursor->old_rec, index, NULL, !level, level ? 0 : r_cursor->old_n_fields,
r_cursor->old_n_fields, &heap); r_cursor->old_n_fields, &heap);
offsets2 = rec_get_offsets( offsets2 = rec_get_offsets(rec, index, NULL,
rec, index, NULL, !level, level ? 0 : r_cursor->old_n_fields,
r_cursor->old_n_fields, &heap); r_cursor->old_n_fields, &heap);
comp = rec_offs_comp(offsets1); comp = rec_offs_comp(offsets1);
@ -1689,7 +1692,7 @@ rtr_cur_search_with_match(
page = buf_block_get_frame(block); page = buf_block_get_frame(block);
const ulint level = btr_page_get_level(page); 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) { if (mode == PAGE_CUR_RTREE_LOCATE) {
ut_ad(level != 0); ut_ad(level != 0);
@ -1711,7 +1714,7 @@ rtr_cur_search_with_match(
ulint new_rec_size = rec_get_converted_size(index, tuple, 0); 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), dtuple_get_n_fields_cmp(tuple),
&heap); &heap);
@ -1732,10 +1735,10 @@ rtr_cur_search_with_match(
} }
while (!page_rec_is_supremum(rec)) { while (!page_rec_is_supremum(rec)) {
offsets = rec_get_offsets(rec, index, offsets, is_leaf, offsets = rec_get_offsets(rec, index, offsets, n_core,
dtuple_get_n_fields_cmp(tuple), dtuple_get_n_fields_cmp(tuple),
&heap); &heap);
if (!is_leaf) { if (!n_core) {
switch (mode) { switch (mode) {
case PAGE_CUR_CONTAIN: case PAGE_CUR_CONTAIN:
case PAGE_CUR_INTERSECT: case PAGE_CUR_INTERSECT:
@ -1816,7 +1819,7 @@ rtr_cur_search_with_match(
to rtr_info->path for non-leaf nodes, or to rtr_info->path for non-leaf nodes, or
rtr_info->matches for leaf nodes */ rtr_info->matches for leaf nodes */
if (rtr_info && mode != PAGE_CUR_RTREE_INSERT) { if (rtr_info && mode != PAGE_CUR_RTREE_INSERT) {
if (!is_leaf) { if (!n_core) {
ulint page_no; ulint page_no;
node_seq_t new_seq; node_seq_t new_seq;
bool is_loc; bool is_loc;
@ -1827,7 +1830,7 @@ rtr_cur_search_with_match(
== PAGE_CUR_RTREE_GET_FATHER); == PAGE_CUR_RTREE_GET_FATHER);
offsets = rec_get_offsets( offsets = rec_get_offsets(
rec, index, offsets, false, rec, index, offsets, 0,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
page_no = btr_node_ptr_get_child_page_no( page_no = btr_node_ptr_get_child_page_no(
@ -1876,7 +1879,8 @@ rtr_cur_search_with_match(
/* Collect matched records on page */ /* Collect matched records on page */
offsets = rec_get_offsets( offsets = rec_get_offsets(
rec, index, offsets, true, rec, index, offsets,
index->n_fields,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
rtr_leaf_push_match_rec( rtr_leaf_push_match_rec(
rec, rtr_info, offsets, rec, rtr_info, offsets,
@ -1899,7 +1903,7 @@ rtr_cur_search_with_match(
/* All records on page are searched */ /* All records on page are searched */
if (page_rec_is_supremum(rec)) { if (page_rec_is_supremum(rec)) {
if (!is_leaf) { if (!n_core) {
if (!found) { if (!found) {
/* No match case, if it is for insertion, /* No match case, if it is for insertion,
then we select the record that result in then we select the record that result in
@ -1909,7 +1913,7 @@ rtr_cur_search_with_match(
ut_ad(least_inc < DBL_MAX); ut_ad(least_inc < DBL_MAX);
offsets = rec_get_offsets( offsets = rec_get_offsets(
best_rec, index, offsets, best_rec, index, offsets,
false, ULINT_UNDEFINED, &heap); 0, ULINT_UNDEFINED, &heap);
child_no = child_no =
btr_node_ptr_get_child_page_no( btr_node_ptr_get_child_page_no(
best_rec, offsets); best_rec, offsets);
@ -1961,11 +1965,11 @@ rtr_cur_search_with_match(
/* Verify the record to be positioned is the same /* Verify the record to be positioned is the same
as the last record in matched_rec vector */ as the last record in matched_rec vector */
offsets2 = rec_get_offsets(test_rec.r_rec, index, offsets2 = rec_get_offsets(test_rec.r_rec, index,
offsets2, true, offsets2, index->n_fields,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
offsets = rec_get_offsets(last_match_rec, index, offsets = rec_get_offsets(last_match_rec, index,
offsets, true, offsets, index->n_fields,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
ut_ad(cmp_rec_rec(test_rec.r_rec, last_match_rec, ut_ad(cmp_rec_rec(test_rec.r_rec, last_match_rec,
@ -1982,9 +1986,8 @@ rtr_cur_search_with_match(
ulint child_no; ulint child_no;
ut_ad(!last_match_rec && rec); ut_ad(!last_match_rec && rec);
offsets = rec_get_offsets( offsets = rec_get_offsets(rec, index, offsets, 0,
rec, index, offsets, false, ULINT_UNDEFINED, &heap);
ULINT_UNDEFINED, &heap);
child_no = btr_node_ptr_get_child_page_no(rec, offsets); child_no = btr_node_ptr_get_child_page_no(rec, offsets);
@ -1992,7 +1995,7 @@ rtr_cur_search_with_match(
index, rtr_info->parent_path, level, child_no, index, rtr_info->parent_path, level, child_no,
block, rec, 0); block, rec, 0);
} else if (rtr_info && found && !is_leaf) { } else if (rtr_info && found && !n_core) {
rec = last_match_rec; rec = last_match_rec;
} }
@ -2002,11 +2005,11 @@ rtr_cur_search_with_match(
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
/* Verify that we are positioned at the same child page as pushed in /* Verify that we are positioned at the same child page as pushed in
the path stack */ 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) { && mode != PAGE_CUR_RTREE_INSERT) {
ulint page_no; ulint page_no;
offsets = rec_get_offsets(rec, index, offsets, false, offsets = rec_get_offsets(rec, index, offsets, 0,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
page_no = btr_node_ptr_get_child_page_no(rec, offsets); page_no = btr_node_ptr_get_child_page_no(rec, offsets);

View file

@ -3906,7 +3906,7 @@ dump:
row_ins_sec_index_entry_by_modify(BTR_MODIFY_LEAF). */ row_ins_sec_index_entry_by_modify(BTR_MODIFY_LEAF). */
ut_ad(rec_get_deleted_flag(rec, page_is_comp(page))); 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); ULINT_UNDEFINED, &heap);
update = row_upd_build_sec_rec_difference_binary( update = row_upd_build_sec_rec_difference_binary(
rec, index, offsets, entry, heap); rec, index, offsets, entry, heap);
@ -4079,7 +4079,8 @@ ibuf_delete(
ut_ad(ibuf_inside(mtr)); ut_ad(ibuf_inside(mtr));
ut_ad(dtuple_check_typed(entry)); 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); low_match = page_cur_search(block, index, entry, &page_cur);
@ -4098,8 +4099,8 @@ ibuf_delete(
rec_offs_init(offsets_); rec_offs_init(offsets_);
offsets = rec_get_offsets( offsets = rec_get_offsets(rec, index, offsets, index->n_fields,
rec, index, offsets, true, ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
if (page_get_n_recs(page) <= 1 if (page_get_n_recs(page) <= 1
|| !(REC_INFO_DELETED_FLAG || !(REC_INFO_DELETED_FLAG

View file

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 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 the terms of the GNU General Public License as published by the Free Software
@ -497,8 +497,10 @@ struct btr_pcur_t{
/** if cursor position is stored, contains an initial segment of the /** if cursor position is stored, contains an initial segment of the
latest record cursor was positioned either on, before or after */ latest record cursor was positioned either on, before or after */
rec_t* old_rec; 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 */ /** 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 /** BTR_PCUR_ON, BTR_PCUR_BEFORE, or BTR_PCUR_AFTER, depending on
whether cursor was on, before, or after the old_rec record */ whether cursor was on, before, or after the old_rec record */
enum btr_pcur_pos_t rel_pos; enum btr_pcur_pos_t rel_pos;

View file

@ -2,7 +2,7 @@
Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc. 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 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 the terms of the GNU General Public License as published by the Free Software
@ -1348,21 +1348,6 @@ dict_index_build_node_ptr(
ulint level) /*!< in: level of rec in tree: ulint level) /*!< in: level of rec in tree:
0 means leaf level */ 0 means leaf level */
MY_ATTRIBUTE((nonnull, warn_unused_result)); MY_ATTRIBUTE((nonnull, warn_unused_result));
/**********************************************************************//**
Copies an initial segment of a physical record, long enough to specify an
index entry uniquely.
@return pointer to the prefix record */
rec_t*
dict_index_copy_rec_order_prefix(
/*=============================*/
const dict_index_t* index, /*!< in: index */
const rec_t* rec, /*!< in: record for which to
copy prefix */
ulint* n_fields,/*!< out: number of fields copied */
byte** buf, /*!< in/out: memory buffer for the
copied prefix, or NULL */
ulint* buf_size)/*!< in/out: buffer size */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/** Convert a physical record into a search tuple. /** Convert a physical record into a search tuple.
@param[in] rec index record (not necessarily in an index page) @param[in] rec index record (not necessarily in an index page)
@param[in] index index @param[in] index index

View file

@ -2,7 +2,7 @@
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc. 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 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 the terms of the GNU General Public License as published by the Free Software
@ -1070,6 +1070,15 @@ struct dict_index_t{
return DICT_CLUSTERED == (type & (DICT_CLUSTERED | DICT_IBUF)); return DICT_CLUSTERED == (type & (DICT_CLUSTERED | DICT_IBUF));
} }
/** @return whether this is a generated clustered index */
bool is_gen_clust() const { return type == DICT_CLUSTERED; }
/** @return whether this is a clustered index */
bool is_clust() const { return type & DICT_CLUSTERED; }
/** @return whether this is a unique index */
bool is_unique() const { return type & DICT_UNIQUE; }
/** @return whether this is a spatial index */ /** @return whether this is a spatial index */
bool is_spatial() const { return UNIV_UNLIKELY(type & DICT_SPATIAL); } bool is_spatial() const { return UNIV_UNLIKELY(type & DICT_SPATIAL); }

View file

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2014, Oracle and/or its affiliates. All Rights Reserved. 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 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 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); page = buf_block_get_frame(block);
rec = page_rec_get_next(page_get_infimum_rec(page)); 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); ULINT_UNDEFINED, &heap);
do { do {

View file

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2015, 2018, MariaDB Corporation. Copyright (c) 2015, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
@ -278,7 +278,8 @@ page_cur_tuple_insert(
index, tuple, n_ext); index, tuple, n_ext);
*offsets = rec_get_offsets(rec, index, *offsets, *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); ULINT_UNDEFINED, heap);
if (buf_block_get_page_zip(cursor->block)) { if (buf_block_get_page_zip(cursor->block)) {

View file

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1994, 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 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 the terms of the GNU General Public License as published by the Free Software
@ -554,7 +554,7 @@ rec_get_n_extern_new(
@param[in] index the index that the record belongs to @param[in] index the index that the record belongs to
@param[in,out] offsets array comprising offsets[0] allocated elements, @param[in,out] offsets array comprising offsets[0] allocated elements,
or an array from rec_get_offsets(), or NULL 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 @param[in] n_fields maximum number of offsets to compute
(ULINT_UNDEFINED to compute all offsets) (ULINT_UNDEFINED to compute all offsets)
@param[in,out] heap memory heap @param[in,out] heap memory heap
@ -564,7 +564,7 @@ rec_get_offsets_func(
const rec_t* rec, const rec_t* rec,
const dict_index_t* index, const dict_index_t* index,
rec_offs* offsets, rec_offs* offsets,
bool leaf, ulint n_core,
ulint n_fields, ulint n_fields,
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
const char* file, /*!< in: file name where called */ const char* file, /*!< in: file name where called */
@ -1121,7 +1121,9 @@ rec_get_converted_size(
The fields are copied into the memory heap. The fields are copied into the memory heap.
@param[out] tuple data tuple @param[out] tuple data tuple
@param[in] rec index record, or a copy thereof @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] n_fields number of fields to copy
@param[in,out] heap memory heap */ @param[in,out] heap memory heap */
void void
@ -1129,7 +1131,7 @@ rec_copy_prefix_to_dtuple(
dtuple_t* tuple, dtuple_t* tuple,
const rec_t* rec, const rec_t* rec,
const dict_index_t* index, const dict_index_t* index,
bool is_leaf, ulint n_core,
ulint n_fields, ulint n_fields,
mem_heap_t* heap) mem_heap_t* heap)
MY_ATTRIBUTE((nonnull)); MY_ATTRIBUTE((nonnull));

View file

@ -4486,7 +4486,8 @@ static void lock_rec_print(FILE* file, const lock_t* lock, mtr_t& mtr)
ut_ad(!page_rec_is_metadata(rec)); ut_ad(!page_rec_is_metadata(rec));
offsets = rec_get_offsets( offsets = rec_get_offsets(
rec, lock->index, offsets, true, rec, lock->index, offsets,
lock->index->n_core_fields,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
putc(' ', file); putc(' ', file);
@ -5032,8 +5033,8 @@ loop:
ut_ad(!lock_rec_get_nth_bit(lock, i) ut_ad(!lock_rec_get_nth_bit(lock, i)
|| page_rec_is_leaf(rec)); || page_rec_is_leaf(rec));
offsets = rec_get_offsets(rec, lock->index, offsets, offsets = rec_get_offsets(rec, lock->index, offsets,
true, ULINT_UNDEFINED, lock->index->n_core_fields,
&heap); ULINT_UNDEFINED, &heap);
/* If this thread is holding the file space /* If this thread is holding the file space
latch (fil_space_t::latch), the following latch (fil_space_t::latch), the following
@ -5364,7 +5365,8 @@ lock_rec_insert_check_and_lock(
const rec_offs* offsets; const rec_offs* offsets;
rec_offs_init(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); ULINT_UNDEFINED, &heap);
ut_ad(lock_rec_queue_validate( ut_ad(lock_rec_queue_validate(
@ -5704,7 +5706,8 @@ lock_sec_rec_modify_check_and_lock(
const rec_offs* offsets; const rec_offs* offsets;
rec_offs_init(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); ULINT_UNDEFINED, &heap);
ut_ad(lock_rec_queue_validate( ut_ad(lock_rec_queue_validate(
@ -5916,7 +5919,7 @@ lock_clust_rec_read_check_and_lock_alt(
rec_offs_init(offsets_); rec_offs_init(offsets_);
ut_ad(page_rec_is_leaf(rec)); 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); ULINT_UNDEFINED, &tmp_heap);
err = lock_clust_rec_read_check_and_lock(flags, block, rec, index, err = lock_clust_rec_read_check_and_lock(flags, block, rec, index,
offsets, mode, gap_mode, thr); offsets, mode, gap_mode, thr);

View file

@ -2,7 +2,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc. Copyright (c) 2012, Facebook Inc.
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 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 the terms of the GNU General Public License as published by the Free Software
@ -75,7 +75,7 @@ page_cur_try_search_shortcut(
ut_ad(page_is_leaf(page)); ut_ad(page_is_leaf(page));
rec = page_header_get_ptr(page, PAGE_LAST_INSERT); 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); dtuple_get_n_fields(tuple), &heap);
ut_ad(rec); ut_ad(rec);
@ -90,7 +90,8 @@ page_cur_try_search_shortcut(
next_rec = page_rec_get_next_const(rec); next_rec = page_rec_get_next_const(rec);
if (!page_rec_is_supremum(next_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); dtuple_get_n_fields(tuple), &heap);
if (cmp_dtuple_rec_with_match(tuple, next_rec, offsets, 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)); ut_ad(page_is_leaf(page));
rec = page_header_get_ptr(page, PAGE_LAST_INSERT); 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); dtuple_get_n_fields(tuple), &heap);
ut_ad(rec); ut_ad(rec);
@ -180,7 +181,8 @@ page_cur_try_search_shortcut_bytes(
next_rec = page_rec_get_next_const(rec); next_rec = page_rec_get_next_const(rec);
if (!page_rec_is_supremum(next_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); dtuple_get_n_fields(tuple), &heap);
if (cmp_dtuple_rec_with_match_bytes( if (cmp_dtuple_rec_with_match_bytes(
@ -321,14 +323,14 @@ page_cur_search_with_match(
#endif /* UNIV_ZIP_DEBUG */ #endif /* UNIV_ZIP_DEBUG */
ut_d(page_check_dir(page)); 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 #ifdef BTR_CUR_HASH_ADAPT
if (is_leaf if (n_core
&& page_get_direction(page) == PAGE_RIGHT && page_get_direction(page) == PAGE_RIGHT
&& page_header_get_offs(page, PAGE_LAST_INSERT) && page_header_get_offs(page, PAGE_LAST_INSERT)
&& mode == PAGE_CUR_LE && mode == PAGE_CUR_LE
&& !dict_index_is_spatial(index) && !index->is_spatial()
&& page_header_get_field(page, PAGE_N_DIRECTION) > 3 && page_header_get_field(page, PAGE_N_DIRECTION) > 3
&& page_cur_try_search_shortcut( && page_cur_try_search_shortcut(
block, index, tuple, block, index, tuple,
@ -344,10 +346,10 @@ page_cur_search_with_match(
/* If the mode is for R-tree indexes, use the special MBR /* If the mode is for R-tree indexes, use the special MBR
related compare functions */ 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 /* For leaf level insert, we still use the traditional
compare function for now */ compare function for now */
if (mode == PAGE_CUR_RTREE_INSERT && is_leaf) { if (mode == PAGE_CUR_RTREE_INSERT && n_core) {
mode = PAGE_CUR_LE; mode = PAGE_CUR_LE;
} else { } else {
rtr_cur_search_with_match( rtr_cur_search_with_match(
@ -392,7 +394,7 @@ page_cur_search_with_match(
offsets = offsets_; offsets = offsets_;
offsets = rec_get_offsets( offsets = rec_get_offsets(
mid_rec, index, offsets, is_leaf, mid_rec, index, offsets, n_core,
dtuple_get_n_fields_cmp(tuple), &heap); dtuple_get_n_fields_cmp(tuple), &heap);
cmp = cmp_dtuple_rec_with_match( cmp = cmp_dtuple_rec_with_match(
@ -446,7 +448,7 @@ up_slot_match:
offsets = offsets_; offsets = offsets_;
offsets = rec_get_offsets( offsets = rec_get_offsets(
mid_rec, index, offsets, is_leaf, mid_rec, index, offsets, n_core,
dtuple_get_n_fields_cmp(tuple), &heap); dtuple_get_n_fields_cmp(tuple), &heap);
cmp = cmp_dtuple_rec_with_match( 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 /* Perform binary search until the lower and upper limit directory
slots come to the distance 1 of each other */ 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) { while (up - low > 1) {
mid = (low + up) / 2; mid = (low + up) / 2;
@ -639,7 +641,7 @@ page_cur_search_with_match_bytes(
up_matched_fields, up_matched_bytes); up_matched_fields, up_matched_bytes);
offsets = rec_get_offsets( offsets = rec_get_offsets(
mid_rec, index, offsets_, is_leaf, mid_rec, index, offsets_, n_core,
dtuple_get_n_fields_cmp(tuple), &heap); dtuple_get_n_fields_cmp(tuple), &heap);
cmp = cmp_dtuple_rec_with_match_bytes( cmp = cmp_dtuple_rec_with_match_bytes(
@ -707,7 +709,7 @@ up_slot_match:
} }
offsets = rec_get_offsets( offsets = rec_get_offsets(
mid_rec, index, offsets_, is_leaf, mid_rec, index, offsets_, n_core,
dtuple_get_n_fields_cmp(tuple), &heap); dtuple_get_n_fields_cmp(tuple), &heap);
cmp = cmp_dtuple_rec_with_match_bytes( cmp = cmp_dtuple_rec_with_match_bytes(
@ -817,7 +819,8 @@ page_cur_insert_rec_write_log(
ut_ad(!page_rec_is_comp(insert_rec) ut_ad(!page_rec_is_comp(insert_rec)
== !dict_table_is_comp(index->table)); == !dict_table_is_comp(index->table));
const bool is_leaf = page_rec_is_leaf(cursor_rec); const ulint n_core = page_rec_is_leaf(cursor_rec)
? index->n_core_fields : 0;
{ {
mem_heap_t* heap = NULL; mem_heap_t* heap = NULL;
@ -831,9 +834,9 @@ page_cur_insert_rec_write_log(
rec_offs_init(ins_offs_); rec_offs_init(ins_offs_);
cur_offs = rec_get_offsets(cursor_rec, index, cur_offs_, cur_offs = rec_get_offsets(cursor_rec, index, cur_offs_,
is_leaf, ULINT_UNDEFINED, &heap); n_core, ULINT_UNDEFINED, &heap);
ins_offs = rec_get_offsets(insert_rec, index, ins_offs_, ins_offs = rec_get_offsets(insert_rec, index, ins_offs_,
is_leaf, ULINT_UNDEFINED, &heap); n_core, ULINT_UNDEFINED, &heap);
extra_size = rec_offs_extra_size(ins_offs); extra_size = rec_offs_extra_size(ins_offs);
cur_extra_size = rec_offs_extra_size(cur_offs); cur_extra_size = rec_offs_extra_size(cur_offs);
@ -1091,9 +1094,9 @@ page_cur_parse_insert_rec(
/* Read from the log the inserted index record end segment which /* Read from the log the inserted index record end segment which
differs from the cursor record */ differs from the cursor record */
const bool is_leaf = page_is_leaf(page); const ulint n_core = page_is_leaf(page) ? index->n_core_fields : 0;
offsets = rec_get_offsets(cursor_rec, index, offsets, is_leaf, offsets = rec_get_offsets(cursor_rec, index, offsets, n_core,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
if (!(end_seg_len & 0x1UL)) { if (!(end_seg_len & 0x1UL)) {
@ -1142,7 +1145,7 @@ page_cur_parse_insert_rec(
page_cur_position(cursor_rec, block, &cursor); page_cur_position(cursor_rec, block, &cursor);
offsets = rec_get_offsets(buf + origin_offset, index, offsets, offsets = rec_get_offsets(buf + origin_offset, index, offsets,
is_leaf, ULINT_UNDEFINED, &heap); n_core, ULINT_UNDEFINED, &heap);
if (UNIV_UNLIKELY(!page_cur_rec_insert(&cursor, if (UNIV_UNLIKELY(!page_cur_rec_insert(&cursor,
buf + origin_offset, buf + origin_offset,
index, offsets, mtr))) { index, offsets, mtr))) {
@ -1323,7 +1326,8 @@ page_cur_insert_rec_low(
rec_offs_init(foffsets_); rec_offs_init(foffsets_);
foffsets = rec_get_offsets( foffsets = rec_get_offsets(
free_rec, index, foffsets, page_is_leaf(page), free_rec, index, foffsets,
page_is_leaf(page) ? index->n_core_fields : 0,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
if (rec_offs_size(foffsets) < rec_size) { if (rec_offs_size(foffsets) < rec_size) {
if (UNIV_LIKELY_NULL(heap)) { if (UNIV_LIKELY_NULL(heap)) {
@ -1736,7 +1740,8 @@ page_cur_insert_rec_zip(
rec_offs_init(foffsets_); rec_offs_init(foffsets_);
foffsets = rec_get_offsets(free_rec, index, foffsets, foffsets = rec_get_offsets(free_rec, index, foffsets,
page_rec_is_leaf(free_rec), page_rec_is_leaf(free_rec)
? index->n_core_fields : 0,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
if (rec_offs_size(foffsets) < rec_size) { if (rec_offs_size(foffsets) < rec_size) {
too_small: too_small:
@ -2103,10 +2108,11 @@ page_copy_rec_list_end_to_created_page(
slot_index = 0; slot_index = 0;
n_recs = 0; n_recs = 0;
const bool is_leaf = page_is_leaf(new_page); const ulint n_core = page_is_leaf(new_page)
? index->n_core_fields : 0;
do { do {
offsets = rec_get_offsets(rec, index, offsets, is_leaf, offsets = rec_get_offsets(rec, index, offsets, n_core,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
insert_rec = rec_copy(heap_top, rec, offsets); insert_rec = rec_copy(heap_top, rec, offsets);
@ -2148,7 +2154,7 @@ page_copy_rec_list_end_to_created_page(
heap_top += rec_size; heap_top += rec_size;
rec_offs_make_valid(insert_rec, index, is_leaf, offsets); rec_offs_make_valid(insert_rec, index, n_core != 0, offsets);
page_cur_insert_rec_write_log(insert_rec, rec_size, prev_rec, page_cur_insert_rec_write_log(insert_rec, rec_size, prev_rec,
index, mtr); index, mtr);
prev_rec = insert_rec; prev_rec = insert_rec;
@ -2285,7 +2291,8 @@ page_cur_parse_delete_rec(
page_cur_delete_rec(&cursor, index, page_cur_delete_rec(&cursor, index,
rec_get_offsets(rec, index, offsets_, rec_get_offsets(rec, index, offsets_,
page_rec_is_leaf(rec), page_rec_is_leaf(rec)
? index->n_core_fields : 0,
ULINT_UNDEFINED, &heap), ULINT_UNDEFINED, &heap),
mtr); mtr);
if (UNIV_LIKELY_NULL(heap)) { if (UNIV_LIKELY_NULL(heap)) {

View file

@ -2,7 +2,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc. 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 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 the terms of the GNU General Public License as published by the Free Software
@ -560,7 +560,8 @@ page_copy_rec_list_end_no_locks(
ut_a(page_is_comp(new_page) == page_rec_is_comp(rec)); 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) ut_a(mach_read_from_2(new_page + srv_page_size - 10) == (ulint)
(page_is_comp(new_page) ? PAGE_NEW_INFIMUM : PAGE_OLD_INFIMUM)); (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;
cur2 = page_get_infimum_rec(buf_block_get_frame(new_block)); cur2 = page_get_infimum_rec(buf_block_get_frame(new_block));
@ -568,7 +569,7 @@ page_copy_rec_list_end_no_locks(
while (!page_cur_is_after_last(&cur1)) { while (!page_cur_is_after_last(&cur1)) {
rec_t* ins_rec; 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); ULINT_UNDEFINED, &heap);
ins_rec = page_cur_insert_rec_low(cur2, index, ins_rec = page_cur_insert_rec_low(cur2, index,
cur1.rec, offsets, mtr); cur1.rec, offsets, mtr);
@ -800,7 +801,7 @@ page_copy_rec_list_start(
cur2 = ret; cur2 = ret;
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 */ /* Copy records from the original page to the new page */
if (index->is_spatial()) { if (index->is_spatial()) {
@ -822,7 +823,7 @@ page_copy_rec_list_start(
} else { } else {
while (page_cur_get_rec(&cur1) != rec) { while (page_cur_get_rec(&cur1) != rec) {
offsets = rec_get_offsets(cur1.rec, index, offsets, offsets = rec_get_offsets(cur1.rec, index, offsets,
is_leaf, n_core,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
cur2 = page_cur_insert_rec_low(cur2, index, cur2 = page_cur_insert_rec_low(cur2, index,
cur1.rec, offsets, mtr); cur1.rec, offsets, mtr);
@ -842,7 +843,7 @@ page_copy_rec_list_start(
same temp-table in parallel. same temp-table in parallel.
max_trx_id is ignored for temp tables because it not required max_trx_id is ignored for temp tables because it not required
for MVCC. */ 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()) { && !index->table->is_temporary()) {
page_update_max_trx_id(new_block, NULL, page_update_max_trx_id(new_block, NULL,
page_get_max_trx_id(page_align(rec)), page_get_max_trx_id(page_align(rec)),
@ -1073,7 +1074,7 @@ delete_all:
? MLOG_COMP_LIST_END_DELETE ? MLOG_COMP_LIST_END_DELETE
: MLOG_LIST_END_DELETE, mtr); : MLOG_LIST_END_DELETE, mtr);
const bool is_leaf = page_is_leaf(page); const ulint n_core = page_is_leaf(page) ? index->n_core_fields : 0;
if (page_zip) { if (page_zip) {
mtr_log_t log_mode; mtr_log_t log_mode;
@ -1087,7 +1088,7 @@ delete_all:
page_cur_t cur; page_cur_t cur;
page_cur_position(rec, block, &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); ULINT_UNDEFINED, &heap);
rec = rec_get_next_ptr(rec, TRUE); rec = rec_get_next_ptr(rec, TRUE);
#ifdef UNIV_ZIP_DEBUG #ifdef UNIV_ZIP_DEBUG
@ -1120,8 +1121,7 @@ delete_all:
do { do {
ulint s; ulint s;
offsets = rec_get_offsets(rec2, index, offsets, offsets = rec_get_offsets(rec2, index, offsets, n_core,
is_leaf,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
s = rec_offs_size(offsets); s = rec_offs_size(offsets);
ut_ad(ulint(rec2 - page) + s ut_ad(ulint(rec2 - page) + s
@ -1267,11 +1267,12 @@ page_delete_rec_list_start(
/* Individual deletes are not logged */ /* Individual deletes are not logged */
mtr_log_t log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE); mtr_log_t log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE);
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) { while (page_cur_get_rec(&cur1) != rec) {
offsets = rec_get_offsets(page_cur_get_rec(&cur1), index, offsets = rec_get_offsets(page_cur_get_rec(&cur1), index,
offsets, is_leaf, offsets, n_core,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
page_cur_delete_rec(&cur1, index, offsets, mtr); page_cur_delete_rec(&cur1, index, offsets, mtr);
} }
@ -2482,9 +2483,10 @@ wrong_page_type:
rec = page_get_infimum_rec(page); rec = page_get_infimum_rec(page);
const ulint n_core = page_is_leaf(page) ? index->n_core_fields : 0;
for (;;) { for (;;) {
offsets = rec_get_offsets(rec, index, offsets, offsets = rec_get_offsets(rec, index, offsets, n_core,
page_is_leaf(page),
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
if (page_is_comp(page) && page_rec_is_user_rec(rec) if (page_is_comp(page) && page_rec_is_user_rec(rec)
@ -2732,8 +2734,7 @@ n_owned_zero:
rec = page_header_get_ptr(page, PAGE_FREE); rec = page_header_get_ptr(page, PAGE_FREE);
while (rec != NULL) { while (rec != NULL) {
offsets = rec_get_offsets(rec, index, offsets, offsets = rec_get_offsets(rec, index, offsets, n_core,
page_is_leaf(page),
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
if (UNIV_UNLIKELY(!page_rec_validate(rec, offsets))) { if (UNIV_UNLIKELY(!page_rec_validate(rec, offsets))) {
ret = FALSE; ret = FALSE;

View file

@ -2,7 +2,7 @@
Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc. Copyright (c) 2012, Facebook Inc.
Copyright (c) 2014, 2020, MariaDB Corporation. Copyright (c) 2014, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
@ -881,7 +881,7 @@ page_zip_compress_node_ptrs(
do { do {
const rec_t* rec = *recs++; const rec_t* rec = *recs++;
offsets = rec_get_offsets(rec, index, offsets, false, offsets = rec_get_offsets(rec, index, offsets, 0,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
/* Only leaf nodes may contain externally stored columns. */ /* Only leaf nodes may contain externally stored columns. */
ut_ad(!rec_offs_any_extern(offsets)); ut_ad(!rec_offs_any_extern(offsets));
@ -1130,7 +1130,7 @@ page_zip_compress_clust(
do { do {
const rec_t* rec = *recs++; 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); ULINT_UNDEFINED, &heap);
ut_ad(rec_offs_n_fields(offsets) ut_ad(rec_offs_n_fields(offsets)
== dict_index_get_n_fields(index)); == dict_index_get_n_fields(index));
@ -2052,7 +2052,7 @@ page_zip_apply_log(
sorted by address (indexed by sorted by address (indexed by
heap_no - PAGE_HEAP_NO_USER_LOW) */ heap_no - PAGE_HEAP_NO_USER_LOW) */
ulint n_dense,/*!< in: size of recs[] */ 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, ulint trx_id_col,/*!< in: column number of trx_id in the index,
or ULINT_UNDEFINED if none */ or ULINT_UNDEFINED if none */
ulint heap_status, ulint heap_status,
@ -2128,7 +2128,7 @@ page_zip_apply_log(
/* Clear the data bytes of the record. */ /* Clear the data bytes of the record. */
mem_heap_t* heap = NULL; mem_heap_t* heap = NULL;
rec_offs* offs; rec_offs* offs;
offs = rec_get_offsets(rec, index, offsets, is_leaf, offs = rec_get_offsets(rec, index, offsets, n_core,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
memset(rec, 0, rec_offs_data_size(offs)); memset(rec, 0, rec_offs_data_size(offs));
@ -2142,7 +2142,7 @@ page_zip_apply_log(
rec_get_offsets_reverse(data, index, rec_get_offsets_reverse(data, index,
hs & REC_STATUS_NODE_PTR, hs & REC_STATUS_NODE_PTR,
offsets); offsets);
rec_offs_make_valid(rec, index, is_leaf, offsets); rec_offs_make_valid(rec, index, n_core != 0, offsets);
/* Copy the extra bytes (backwards). */ /* Copy the extra bytes (backwards). */
{ {
@ -2322,7 +2322,7 @@ page_zip_decompress_node_ptrs(
} }
/* Read the offsets. The status bits are needed here. */ /* 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); ULINT_UNDEFINED, &heap);
/* Non-leaf nodes should not have any externally /* Non-leaf nodes should not have any externally
@ -2409,7 +2409,7 @@ zlib_done:
const byte* mod_log_ptr; const byte* mod_log_ptr;
mod_log_ptr = page_zip_apply_log(d_stream->next_in, mod_log_ptr = page_zip_apply_log(d_stream->next_in,
d_stream->avail_in + 1, d_stream->avail_in + 1,
recs, n_dense, false, recs, n_dense, 0,
ULINT_UNDEFINED, heap_status, ULINT_UNDEFINED, heap_status,
index, offsets); index, offsets);
@ -2440,7 +2440,7 @@ zlib_done:
for (slot = 0; slot < n_dense; slot++) { for (slot = 0; slot < n_dense; slot++) {
rec_t* rec = recs[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); ULINT_UNDEFINED, &heap);
/* Non-leaf nodes should not have any externally /* Non-leaf nodes should not have any externally
stored columns. */ stored columns. */
@ -2562,7 +2562,8 @@ zlib_done:
const byte* mod_log_ptr; const byte* mod_log_ptr;
mod_log_ptr = page_zip_apply_log(d_stream->next_in, mod_log_ptr = page_zip_apply_log(d_stream->next_in,
d_stream->avail_in + 1, d_stream->avail_in + 1,
recs, n_dense, true, recs, n_dense,
index->n_fields,
ULINT_UNDEFINED, heap_status, ULINT_UNDEFINED, heap_status,
index, offsets); index, offsets);
@ -2765,7 +2766,7 @@ page_zip_decompress_clust(
} }
/* Read the offsets. The status bits are needed here. */ /* 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); ULINT_UNDEFINED, &heap);
/* This is a leaf page in a clustered index. */ /* This is a leaf page in a clustered index. */
@ -2892,7 +2893,8 @@ zlib_done:
const byte* mod_log_ptr; const byte* mod_log_ptr;
mod_log_ptr = page_zip_apply_log(d_stream->next_in, mod_log_ptr = page_zip_apply_log(d_stream->next_in,
d_stream->avail_in + 1, d_stream->avail_in + 1,
recs, n_dense, true, recs, n_dense,
index->n_fields,
trx_id_col, heap_status, trx_id_col, heap_status,
index, offsets); index, offsets);
@ -2928,7 +2930,7 @@ zlib_done:
rec_t* rec = recs[slot]; rec_t* rec = recs[slot];
bool exists = !page_zip_dir_find_free( bool exists = !page_zip_dir_find_free(
page_zip, page_offset(rec)); 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); ULINT_UNDEFINED, &heap);
dst = rec_get_nth_field(rec, offsets, dst = rec_get_nth_field(rec, offsets,
@ -3452,7 +3454,7 @@ page_zip_validate_low(
page + PAGE_NEW_INFIMUM, TRUE); page + PAGE_NEW_INFIMUM, TRUE);
trec = page_rec_get_next_low( trec = page_rec_get_next_low(
temp_page + PAGE_NEW_INFIMUM, TRUE); 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 { do {
if (page_offset(rec) != page_offset(trec)) { if (page_offset(rec) != page_offset(trec)) {
@ -3467,7 +3469,7 @@ page_zip_validate_low(
if (index) { if (index) {
/* Compare the data. */ /* Compare the data. */
offsets = rec_get_offsets( offsets = rec_get_offsets(
rec, index, offsets, is_leaf, rec, index, offsets, n_core,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
if (memcmp(rec - rec_offs_extra_size(offsets), if (memcmp(rec - rec_offs_extra_size(offsets),

View file

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2019, MariaDB Corporation. Copyright (c) 2017, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
@ -290,9 +290,9 @@ rec_init_offsets_comp_ordinary(
ulint n_fields = n_core; ulint n_fields = n_core;
ulint null_mask = 1; ulint null_mask = 1;
ut_ad(index->n_core_fields >= n_core);
ut_ad(n_core > 0); 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(index->n_core_null_bytes <= UT_BITS_IN_BYTES(index->n_nullable));
ut_ad(format == REC_LEAF_TEMP || format == REC_LEAF_TEMP_COLUMNS_ADDED ut_ad(format == REC_LEAF_TEMP || format == REC_LEAF_TEMP_COLUMNS_ADDED
|| dict_table_is_comp(index->table)); || dict_table_is_comp(index->table));
@ -300,6 +300,11 @@ rec_init_offsets_comp_ordinary(
|| index->n_fields == rec_offs_n_fields(offsets)); || index->n_fields == rec_offs_n_fields(offsets));
ut_d(ulint n_null= 0); 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;
switch (format) { switch (format) {
case REC_LEAF_TEMP: case REC_LEAF_TEMP:
if (dict_table_is_comp(index->table)) { if (dict_table_is_comp(index->table)) {
@ -311,9 +316,9 @@ rec_init_offsets_comp_ordinary(
case REC_LEAF_ORDINARY: case REC_LEAF_ORDINARY:
nulls -= REC_N_NEW_EXTRA_BYTES; nulls -= REC_N_NEW_EXTRA_BYTES;
ordinary: ordinary:
lens = --nulls - index->n_core_null_bytes; lens = --nulls - n_core_null_bytes;
ut_d(n_null = std::min(index->n_core_null_bytes * 8U, ut_d(n_null = std::min(n_core_null_bytes * 8U,
index->n_nullable)); index->n_nullable));
break; break;
case REC_LEAF_COLUMNS_ADDED: case REC_LEAF_COLUMNS_ADDED:
@ -329,7 +334,7 @@ ordinary:
const ulint n_null_bytes = UT_BITS_IN_BYTES(n_nullable); const ulint n_null_bytes = UT_BITS_IN_BYTES(n_nullable);
ut_d(n_null = n_nullable); ut_d(n_null = n_nullable);
ut_ad(n_null <= index->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); || n_core < index->n_core_fields);
lens = --nulls - n_null_bytes; lens = --nulls - n_null_bytes;
} }
@ -559,14 +564,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. is (STORED_OFFPAGE), the field i is stored externally.
@param[in] rec record @param[in] rec record
@param[in] index the index that the record belongs in @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() */ @param[in,out] offsets array of offsets, with valid rec_offs_n_fields() */
static static
void void
rec_init_offsets( rec_init_offsets(
const rec_t* rec, const rec_t* rec,
const dict_index_t* index, const dict_index_t* index,
bool leaf, ulint n_core,
rec_offs* offsets) rec_offs* offsets)
{ {
ulint i = 0; ulint i = 0;
@ -575,6 +580,8 @@ rec_init_offsets(
ut_ad(index->n_core_null_bytes <= UT_BITS_IN_BYTES(index->n_nullable)); ut_ad(index->n_core_null_bytes <= UT_BITS_IN_BYTES(index->n_nullable));
ut_d(memcpy(&offsets[RECORD_OFFSET], &rec, sizeof(rec))); ut_d(memcpy(&offsets[RECORD_OFFSET], &rec, sizeof(rec)));
ut_d(memcpy(&offsets[INDEX_OFFSET], &index, sizeof(index))); 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)) { if (dict_table_is_comp(index->table)) {
const byte* nulls; const byte* nulls;
@ -593,23 +600,21 @@ rec_init_offsets(
rec_offs_base(offsets)[1] = 8; rec_offs_base(offsets)[1] = 8;
return; return;
case REC_STATUS_NODE_PTR: case REC_STATUS_NODE_PTR:
ut_ad(!leaf); ut_ad(!n_core);
n_node_ptr_field n_node_ptr_field
= dict_index_get_n_unique_in_tree_nonleaf( = dict_index_get_n_unique_in_tree_nonleaf(
index); index);
break; break;
case REC_STATUS_COLUMNS_ADDED: case REC_STATUS_COLUMNS_ADDED:
ut_ad(leaf);
ut_ad(index->is_instant()); ut_ad(index->is_instant());
rec_init_offsets_comp_ordinary(rec, index, offsets, rec_init_offsets_comp_ordinary(rec, index, offsets,
index->n_core_fields, n_core,
NULL, NULL,
REC_LEAF_COLUMNS_ADDED); REC_LEAF_COLUMNS_ADDED);
return; return;
case REC_STATUS_ORDINARY: case REC_STATUS_ORDINARY:
ut_ad(leaf);
rec_init_offsets_comp_ordinary(rec, index, offsets, rec_init_offsets_comp_ordinary(rec, index, offsets,
index->n_core_fields, n_core,
NULL, NULL,
REC_LEAF_ORDINARY); REC_LEAF_ORDINARY);
return; return;
@ -766,7 +771,7 @@ resolved:
@param[in] index the index that the record belongs to @param[in] index the index that the record belongs to
@param[in,out] offsets array comprising offsets[0] allocated elements, @param[in,out] offsets array comprising offsets[0] allocated elements,
or an array from rec_get_offsets(), or NULL 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 @param[in] n_fields maximum number of offsets to compute
(ULINT_UNDEFINED to compute all offsets) (ULINT_UNDEFINED to compute all offsets)
@param[in,out] heap memory heap @param[in,out] heap memory heap
@ -776,7 +781,7 @@ rec_get_offsets_func(
const rec_t* rec, const rec_t* rec,
const dict_index_t* index, const dict_index_t* index,
rec_offs* offsets, rec_offs* offsets,
bool leaf, ulint n_core,
ulint n_fields, ulint n_fields,
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
const char* file, /*!< in: file name where called */ const char* file, /*!< in: file name where called */
@ -787,19 +792,22 @@ rec_get_offsets_func(
ulint n; ulint n;
ulint size; ulint size;
ut_ad(index->n_core_fields >= n_core);
ut_ad(index->n_fields >= index->n_core_fields);
if (dict_table_is_comp(index->table)) { if (dict_table_is_comp(index->table)) {
switch (UNIV_EXPECT(rec_get_status(rec), switch (UNIV_EXPECT(rec_get_status(rec),
REC_STATUS_ORDINARY)) { REC_STATUS_ORDINARY)) {
case REC_STATUS_COLUMNS_ADDED: case REC_STATUS_COLUMNS_ADDED:
case REC_STATUS_ORDINARY: case REC_STATUS_ORDINARY:
ut_ad(leaf); ut_ad(n_core);
n = dict_index_get_n_fields(index); n = dict_index_get_n_fields(index);
break; break;
case REC_STATUS_NODE_PTR: case REC_STATUS_NODE_PTR:
/* Node pointer records consist of the /* Node pointer records consist of the
uniquely identifying fields of the record uniquely identifying fields of the record
followed by a child page number field. */ 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; n = dict_index_get_n_unique_in_tree_nonleaf(index) + 1;
break; break;
case REC_STATUS_INFIMUM: case REC_STATUS_INFIMUM:
@ -828,18 +836,18 @@ rec_get_offsets_func(
>= PAGE_HEAP_NO_USER_LOW; >= PAGE_HEAP_NO_USER_LOW;
/* The infimum and supremum records carry 1 field. */ /* The infimum and supremum records carry 1 field. */
ut_ad(is_user_rec || n == 1); 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) || dict_index_is_ibuf(index)
|| n == n_fields /* dict_stats_analyze_index_level() */ || n == n_fields /* dict_stats_analyze_index_level() */
|| n || n
== dict_index_get_n_unique_in_tree_nonleaf(index) + 1); == dict_index_get_n_unique_in_tree_nonleaf(index) + 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) || dict_index_is_ibuf(index)
|| n == n_fields /* btr_pcur_restore_position() */ || n == n_fields /* btr_pcur_restore_position() */
|| (n + (index->id == DICT_INDEXES_ID) || (n + (index->id == DICT_INDEXES_ID)
>= index->n_core_fields && n <= index->n_fields)); >= n_core && n <= index->n_fields));
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(!index->is_dummy);
ut_ad(!dict_index_is_ibuf(index)); ut_ad(!dict_index_is_ibuf(index));
n = index->n_fields; n = index->n_fields;
@ -867,7 +875,7 @@ rec_get_offsets_func(
} }
rec_offs_set_n_fields(offsets, n); rec_offs_set_n_fields(offsets, n);
rec_init_offsets(rec, index, leaf, offsets); rec_init_offsets(rec, index, n_core, offsets);
return(offsets); return(offsets);
} }
@ -1764,7 +1772,9 @@ template void rec_convert_dtuple_to_temp<true>(
The fields are copied into the memory heap. The fields are copied into the memory heap.
@param[out] tuple data tuple @param[out] tuple data tuple
@param[in] rec index record, or a copy thereof @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] n_fields number of fields to copy
@param[in,out] heap memory heap */ @param[in,out] heap memory heap */
void void
@ -1772,7 +1782,7 @@ rec_copy_prefix_to_dtuple(
dtuple_t* tuple, dtuple_t* tuple,
const rec_t* rec, const rec_t* rec,
const dict_index_t* index, const dict_index_t* index,
bool is_leaf, ulint n_core,
ulint n_fields, ulint n_fields,
mem_heap_t* heap) mem_heap_t* heap)
{ {
@ -1780,10 +1790,11 @@ rec_copy_prefix_to_dtuple(
rec_offs* offsets = offsets_; rec_offs* offsets = offsets_;
rec_offs_init(offsets_); rec_offs_init(offsets_);
ut_ad(is_leaf || n_fields ut_ad(n_core <= index->n_core_fields);
ut_ad(n_core || n_fields
<= dict_index_get_n_unique_in_tree_nonleaf(index) + 1); <= dict_index_get_n_unique_in_tree_nonleaf(index) + 1);
offsets = rec_get_offsets(rec, index, offsets, is_leaf, offsets = rec_get_offsets(rec, index, offsets, n_core,
n_fields, &heap); n_fields, &heap);
ut_ad(rec_validate(rec, offsets)); ut_ad(rec_validate(rec, offsets));
@ -2421,7 +2432,8 @@ rec_print(
rec_print_new(file, rec, rec_print_new(file, rec,
rec_get_offsets(rec, index, offsets_, rec_get_offsets(rec, index, offsets_,
page_rec_is_leaf(rec), page_rec_is_leaf(rec)
? index->n_core_fields : 0,
ULINT_UNDEFINED, &heap)); ULINT_UNDEFINED, &heap));
if (UNIV_LIKELY_NULL(heap)) { if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap); mem_heap_free(heap);
@ -2497,7 +2509,8 @@ operator<<(std::ostream& o, const rec_index_print& r)
{ {
mem_heap_t* heap = NULL; mem_heap_t* heap = NULL;
rec_offs* offsets = rec_get_offsets( 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); ULINT_UNDEFINED, &heap);
rec_print(o, r.m_rec, rec_print(o, r.m_rec,
rec_get_info_bits(r.m_rec, rec_offs_comp(offsets)), rec_get_info_bits(r.m_rec, rec_offs_comp(offsets)),
@ -2543,7 +2556,7 @@ rec_get_trx_id(
ut_ad(trx_id_col > 0); ut_ad(trx_id_col > 0);
ut_ad(trx_id_col != ULINT_UNDEFINED); ut_ad(trx_id_col != ULINT_UNDEFINED);
offsets = rec_get_offsets(rec, index, offsets, true, offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields,
trx_id_col + 1, &heap); trx_id_col + 1, &heap);
trx_id = rec_get_nth_field(rec, offsets, trx_id_col, &len); trx_id = rec_get_nth_field(rec, offsets, trx_id_col, &len);
@ -2594,7 +2607,8 @@ wsrep_rec_get_foreign_key(
ut_ad(index_ref); ut_ad(index_ref);
rec_offs_init(offsets_); 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); ULINT_UNDEFINED, &heap);
ut_ad(rec_offs_validate(rec, NULL, offsets)); ut_ad(rec_offs_validate(rec, NULL, offsets));

View file

@ -1811,7 +1811,8 @@ PageConverter::update_records(
if (deleted || clust_index) { if (deleted || clust_index) {
m_offsets = rec_get_offsets( 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); ULINT_UNDEFINED, &m_heap);
} }
@ -2377,7 +2378,8 @@ row_import_set_sys_max_row_id(
rec_offs_init(offsets_); rec_offs_init(offsets_);
offsets = rec_get_offsets( offsets = rec_get_offsets(
rec, index, offsets_, true, ULINT_UNDEFINED, &heap); rec, index, offsets_, index->n_core_fields,
ULINT_UNDEFINED, &heap);
field = rec_get_nth_field( field = rec_get_nth_field(
rec, offsets, rec, offsets,

View file

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, 2020, MariaDB Corporation. Copyright (c) 2016, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
@ -886,7 +886,7 @@ row_ins_foreign_fill_virtual(
rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs_init(offsets_); rec_offs_init(offsets_);
const rec_offs* 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); ULINT_UNDEFINED, &cascade->heap);
TABLE* mysql_table= NULL; TABLE* mysql_table= NULL;
upd_t* update = cascade->update; upd_t* update = cascade->update;
@ -1640,7 +1640,8 @@ row_ins_check_foreign_constraint(
continue; 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); ULINT_UNDEFINED, &heap);
if (page_rec_is_supremum(rec)) { if (page_rec_is_supremum(rec)) {
@ -2138,7 +2139,8 @@ row_ins_scan_sec_index_for_duplicate(
continue; continue;
} }
offsets = rec_get_offsets(rec, index, offsets, true, offsets = rec_get_offsets(rec, index, offsets,
index->n_core_fields,
ULINT_UNDEFINED, &offsets_heap); ULINT_UNDEFINED, &offsets_heap);
if (flags & BTR_NO_LOCKING_FLAG) { if (flags & BTR_NO_LOCKING_FLAG) {
@ -2275,7 +2277,8 @@ row_ins_duplicate_error_in_clust_online(
ut_ad(!cursor->index->is_instant()); ut_ad(!cursor->index->is_instant());
if (cursor->low_match >= n_uniq && !page_rec_is_infimum(rec)) { 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); ULINT_UNDEFINED, heap);
err = row_ins_duplicate_online(n_uniq, entry, rec, *offsets); err = row_ins_duplicate_online(n_uniq, entry, rec, *offsets);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
@ -2286,7 +2289,8 @@ row_ins_duplicate_error_in_clust_online(
rec = page_rec_get_next_const(btr_cur_get_rec(cursor)); rec = page_rec_get_next_const(btr_cur_get_rec(cursor));
if (cursor->up_match >= n_uniq && !page_rec_is_supremum(rec)) { 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); ULINT_UNDEFINED, heap);
err = row_ins_duplicate_online(n_uniq, entry, rec, *offsets); err = row_ins_duplicate_online(n_uniq, entry, rec, *offsets);
} }
@ -2342,7 +2346,7 @@ row_ins_duplicate_error_in_clust(
if (!page_rec_is_infimum(rec)) { if (!page_rec_is_infimum(rec)) {
offsets = rec_get_offsets(rec, cursor->index, offsets, offsets = rec_get_offsets(rec, cursor->index, offsets,
true, cursor->index->n_core_fields,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
/* We set a lock on the possible duplicate: this /* We set a lock on the possible duplicate: this
@ -2408,7 +2412,7 @@ duplicate:
if (!page_rec_is_supremum(rec)) { if (!page_rec_is_supremum(rec)) {
offsets = rec_get_offsets(rec, cursor->index, offsets, offsets = rec_get_offsets(rec, cursor->index, offsets,
true, cursor->index->n_core_fields,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
if (trx->duplicates) { if (trx->duplicates) {
@ -2525,7 +2529,7 @@ row_ins_index_entry_big_rec(
btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_MODIFY_TREE, btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_MODIFY_TREE,
&pcur, &mtr); &pcur, &mtr);
rec = btr_pcur_get_rec(&pcur); 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); ULINT_UNDEFINED, heap);
DEBUG_SYNC_C_IF_THD(thd, "before_row_ins_extern"); DEBUG_SYNC_C_IF_THD(thd, "before_row_ins_extern");
@ -3084,7 +3088,8 @@ row_ins_sec_index_entry_low(
prefix, we must convert the insert into a modify of an prefix, we must convert the insert into a modify of an
existing record */ existing record */
offsets = rec_get_offsets( 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); ULINT_UNDEFINED, &offsets_heap);
err = row_ins_sec_index_entry_by_modify( err = row_ins_sec_index_entry_by_modify(

View file

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2011, 2018, 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 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 the terms of the GNU General Public License as published by the Free Software
@ -1258,7 +1258,8 @@ row_log_table_get_pk(
if (!offsets) { if (!offsets) {
offsets = rec_get_offsets( offsets = rec_get_offsets(
rec, index, NULL, true, rec, index, NULL,
index->n_core_fields,
pos + 1, heap); pos + 1, heap);
} }
@ -1308,7 +1309,8 @@ row_log_table_get_pk(
} }
if (!offsets) { if (!offsets) {
offsets = rec_get_offsets(rec, index, NULL, true, offsets = rec_get_offsets(rec, index, NULL,
index->n_core_fields,
ULINT_UNDEFINED, heap); ULINT_UNDEFINED, heap);
} }
@ -1980,7 +1982,8 @@ all_done:
return(DB_SUCCESS); 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, NULL,
index->n_core_fields,
ULINT_UNDEFINED, &offsets_heap); ULINT_UNDEFINED, &offsets_heap);
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ut_a(!rec_offs_any_null_extern(btr_pcur_get_rec(&pcur), offsets)); ut_a(!rec_offs_any_null_extern(btr_pcur_get_rec(&pcur), offsets));
@ -2178,7 +2181,7 @@ func_exit_committed:
/* Prepare to update (or delete) the record. */ /* Prepare to update (or delete) the record. */
rec_offs* cur_offsets = rec_get_offsets( rec_offs* cur_offsets = rec_get_offsets(
btr_pcur_get_rec(&pcur), index, NULL, true, btr_pcur_get_rec(&pcur), index, NULL, index->n_core_fields,
ULINT_UNDEFINED, &offsets_heap); ULINT_UNDEFINED, &offsets_heap);
if (!log->same_pk) { if (!log->same_pk) {

View file

@ -2038,7 +2038,8 @@ end_of_index:
rec = page_cur_get_rec(cur); rec = page_cur_get_rec(cur);
if (online) { 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); ULINT_UNDEFINED, &row_heap);
rec_trx_id = row_get_rec_trx_id(rec, clust_index, rec_trx_id = row_get_rec_trx_id(rec, clust_index,
offsets); offsets);
@ -2130,7 +2131,8 @@ end_of_index:
duplicate keys. */ duplicate keys. */
continue; continue;
} else { } 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); ULINT_UNDEFINED, &row_heap);
/* This is a locking ALTER TABLE. /* This is a locking ALTER TABLE.

View file

@ -689,6 +689,7 @@ row_mysql_handle_errors(
dberr_t err; dberr_t err;
DBUG_ENTER("row_mysql_handle_errors"); DBUG_ENTER("row_mysql_handle_errors");
DEBUG_SYNC_C("row_mysql_handle_errors");
handle_new_error: handle_new_error:
err = trx->error_state; err = trx->error_state;
@ -1800,12 +1801,11 @@ row_update_for_mysql(row_prebuilt_t* prebuilt)
clust_index = dict_table_get_first_index(table); clust_index = dict_table_get_first_index(table);
if (prebuilt->pcur->btr_cur.index == clust_index) { btr_pcur_copy_stored_position(node->pcur,
btr_pcur_copy_stored_position(node->pcur, prebuilt->pcur); prebuilt->pcur->btr_cur.index
} else { == clust_index
btr_pcur_copy_stored_position(node->pcur, ? prebuilt->pcur
prebuilt->clust_pcur); : prebuilt->clust_pcur);
}
ut_a(node->pcur->rel_pos == BTR_PCUR_ON); ut_a(node->pcur->rel_pos == BTR_PCUR_ON);
@ -2023,7 +2023,8 @@ row_unlock_for_mysql(
rec_offs* offsets = offsets_; rec_offs* offsets = offsets_;
rec_offs_init(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); ULINT_UNDEFINED, &heap);
rec_trx_id = row_get_rec_trx_id(rec, index, offsets); rec_trx_id = row_get_rec_trx_id(rec, index, offsets);
@ -4795,7 +4796,7 @@ func_exit:
rec = buf + mach_read_from_4(buf); 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); ULINT_UNDEFINED, &heap);
if (prev_entry != NULL) { if (prev_entry != NULL) {

View file

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. 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 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 the terms of the GNU General Public License as published by the Free Software
@ -127,8 +127,8 @@ row_purge_remove_clust_if_poss_low(
rec = btr_pcur_get_rec(&node->pcur); rec = btr_pcur_get_rec(&node->pcur);
offsets = rec_get_offsets( offsets = rec_get_offsets(rec, index, offsets_, index->n_core_fields,
rec, index, offsets_, true, ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
if (node->roll_ptr != row_get_rec_roll_ptr(rec, index, offsets)) { if (node->roll_ptr != row_get_rec_roll_ptr(rec, index, offsets)) {
/* Someone else has modified the record later: do not remove */ /* Someone else has modified the record later: do not remove */
@ -803,7 +803,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 offsets_[REC_OFFS_HEADER_SIZE + MAX_REF_PARTS + 2];
rec_offs_init(offsets_); rec_offs_init(offsets_);
rec_offs* offsets = rec_get_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(heap == NULL);
ut_ad(dict_index_get_nth_field(index, trx_id_pos) ut_ad(dict_index_get_nth_field(index, trx_id_pos)
@ -1360,7 +1361,7 @@ purge_node_t::validate_pcur()
dict_index_t* clust_index = pcur.btr_cur.index; dict_index_t* clust_index = pcur.btr_cur.index;
rec_offs* offsets = rec_get_offsets( 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); pcur.old_n_fields, &heap);
/* Here we are comparing the purge ref record and the stored initial /* Here we are comparing the purge ref record and the stored initial

View file

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved. 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 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 the terms of the GNU General Public License as published by the Free Software
@ -422,7 +422,8 @@ row_build_low(
ut_ad(!col_map || col_table); ut_ad(!col_map || col_table);
if (!offsets) { 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); ULINT_UNDEFINED, &tmp_heap);
} else { } else {
ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(rec_offs_validate(rec, index, offsets));
@ -836,7 +837,7 @@ row_build_row_ref(
ut_ad(heap != NULL); ut_ad(heap != NULL);
ut_ad(!dict_index_is_clust(index)); 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); ULINT_UNDEFINED, &tmp_heap);
/* Secondary indexes must not contain externally stored columns. */ /* Secondary indexes must not contain externally stored columns. */
ut_ad(!rec_offs_any_extern(offsets)); ut_ad(!rec_offs_any_extern(offsets));
@ -945,7 +946,8 @@ row_build_row_ref_in_tuple(
ut_ad(clust_index); ut_ad(clust_index);
if (!offsets) { if (!offsets) {
offsets = rec_get_offsets(rec, index, offsets_, true, offsets = rec_get_offsets(rec, index, offsets_,
index->n_core_fields,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
} else { } else {
ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(rec_offs_validate(rec, index, offsets));

View file

@ -200,9 +200,11 @@ row_sel_sec_rec_is_for_clust_rec(
ib_vcol_row vc(heap); ib_vcol_row vc(heap);
clust_offs = rec_get_offsets(clust_rec, clust_index, clust_offs, 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, 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); n = dict_index_get_n_ordering_defined_by_user(sec_index);
@ -906,7 +908,9 @@ row_sel_get_clust_rec(
offsets = rec_get_offsets(rec, offsets = rec_get_offsets(rec,
btr_pcur_get_btr_cur(&plan->pcur)->index, 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); row_build_row_ref_fast(plan->clust_ref, plan->clust_map, rec, offsets);
@ -941,7 +945,8 @@ row_sel_get_clust_rec(
goto err_exit; 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); ULINT_UNDEFINED, &heap);
if (!node->read_view) { if (!node->read_view) {
@ -1161,7 +1166,8 @@ re_scan:
rec = btr_pcur_get_rec(pcur); rec = btr_pcur_get_rec(pcur);
my_offsets = offsets_; 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); ULINT_UNDEFINED, &heap);
/* No match record */ /* No match record */
@ -1184,7 +1190,7 @@ re_scan:
rtr_rec_t* rtr_rec = &(*it); rtr_rec_t* rtr_rec = &(*it);
my_offsets = rec_get_offsets( 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); ULINT_UNDEFINED, &heap);
err = lock_sec_rec_read_check_and_lock( err = lock_sec_rec_read_check_and_lock(
@ -1493,7 +1499,7 @@ exhausted:
rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs* offsets = offsets_; rec_offs* offsets = offsets_;
rec_offs_init(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); ULINT_UNDEFINED, &heap);
if (dict_index_is_clust(index)) { if (dict_index_is_clust(index)) {
@ -1709,7 +1715,7 @@ rec_loop:
trx = thr_get_trx(thr); trx = thr_get_trx(thr);
offsets = rec_get_offsets(next_rec, index, offsets, offsets = rec_get_offsets(next_rec, index, offsets,
true, index->n_core_fields,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
/* If innodb_locks_unsafe_for_binlog option is used /* If innodb_locks_unsafe_for_binlog option is used
@ -1774,7 +1780,8 @@ skip_lock:
ulint lock_type; ulint lock_type;
trx_t* trx; trx_t* trx;
offsets = rec_get_offsets(rec, index, offsets, true, offsets = rec_get_offsets(rec, index, offsets,
index->n_core_fields,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
trx = thr_get_trx(thr); trx = thr_get_trx(thr);
@ -1861,7 +1868,7 @@ skip_lock:
/* PHASE 3: Get previous version in a consistent read */ /* PHASE 3: Get previous version in a consistent read */
cons_read_requires_clust_rec = FALSE; 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); ULINT_UNDEFINED, &heap);
if (consistent_read) { if (consistent_read) {
@ -1892,7 +1899,8 @@ skip_lock:
exhausted. */ exhausted. */
offsets = rec_get_offsets( offsets = rec_get_offsets(
rec, index, offsets, true, rec, index, offsets,
index->n_core_fields,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
/* Fetch the columns needed in /* Fetch the columns needed in
@ -3217,7 +3225,8 @@ class Row_sel_get_clust_rec_for_mysql
ut_ad(rec_offs_validate(cached_clust_rec, index, offsets)); ut_ad(rec_offs_validate(cached_clust_rec, index, offsets));
ut_ad(index->first_user_field() <= rec_offs_n_fields(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)); index->db_trx_id(), &heap));
ut_ad(!heap); ut_ad(!heap);
for (unsigned n= index->db_trx_id(); n--; ) for (unsigned n= index->db_trx_id(); n--; )
@ -3404,7 +3413,8 @@ Row_sel_get_clust_rec_for_mysql::operator()(
goto func_exit; 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); ULINT_UNDEFINED, offset_heap);
if (prebuilt->select_lock_type != LOCK_NONE) { if (prebuilt->select_lock_type != LOCK_NONE) {
@ -3478,7 +3488,8 @@ Row_sel_get_clust_rec_for_mysql::operator()(
ut_d(check_eq(clust_index, *offsets)); ut_d(check_eq(clust_index, *offsets));
*offsets = rec_get_offsets( *offsets = rec_get_offsets(
old_vers, clust_index, *offsets, old_vers, clust_index, *offsets,
true, ULINT_UNDEFINED, offset_heap); clust_index->n_core_fields,
ULINT_UNDEFINED, offset_heap);
} }
} }
@ -3901,7 +3912,7 @@ exhausted:
/* This is a non-locking consistent read: if necessary, fetch /* This is a non-locking consistent read: if necessary, fetch
a previous version of the record */ 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); ULINT_UNDEFINED, heap);
if (!lock_clust_rec_cons_read_sees(rec, index, *offsets, if (!lock_clust_rec_cons_read_sees(rec, index, *offsets,
@ -4035,7 +4046,7 @@ row_sel_fill_vrow(
ut_ad(!index->is_instant()); ut_ad(!index->is_instant());
ut_ad(page_rec_is_leaf(rec)); 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); ULINT_UNDEFINED, &heap);
*vrow = dtuple_create_with_vcol( *vrow = dtuple_create_with_vcol(
@ -4678,7 +4689,7 @@ wait_table_again:
const rec_t* next_rec = page_rec_get_next_const(rec); const rec_t* next_rec = page_rec_get_next_const(rec);
offsets = rec_get_offsets(next_rec, index, offsets, offsets = rec_get_offsets(next_rec, index, offsets,
true, index->n_core_fields,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
err = sel_set_rec_lock(pcur, err = sel_set_rec_lock(pcur,
next_rec, index, offsets, next_rec, index, offsets,
@ -4762,7 +4773,8 @@ rec_loop:
level we do not lock gaps. Supremum record is really level we do not lock gaps. Supremum record is really
a gap and therefore we do not set locks there. */ 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); ULINT_UNDEFINED, &heap);
err = sel_set_rec_lock(pcur, err = sel_set_rec_lock(pcur,
rec, index, offsets, rec, index, offsets,
@ -4865,7 +4877,7 @@ wrong_offs:
ut_ad(fil_page_index_page_check(btr_pcur_get_page(pcur))); 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); 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); ULINT_UNDEFINED, &heap);
if (UNIV_UNLIKELY(srv_force_recovery > 0)) { if (UNIV_UNLIKELY(srv_force_recovery > 0)) {
@ -5128,7 +5140,8 @@ no_gap_lock:
Do a normal locking read. */ Do a normal locking read. */
offsets = rec_get_offsets( offsets = rec_get_offsets(
rec, index, offsets, true, rec, index, offsets,
index->n_core_fields,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
goto locks_ok; goto locks_ok;
case DB_DEADLOCK: case DB_DEADLOCK:
@ -5502,7 +5515,7 @@ use_covering_index:
/* We used 'offsets' for the clust /* We used 'offsets' for the clust
rec, recalculate them for 'rec' */ rec, recalculate them for 'rec' */
offsets = rec_get_offsets(rec, index, offsets, offsets = rec_get_offsets(rec, index, offsets,
true, index->n_core_fields,
ULINT_UNDEFINED, ULINT_UNDEFINED,
&heap); &heap);
result_rec = rec; result_rec = rec;
@ -5955,7 +5968,7 @@ row_search_autoinc_read_column(
rec_offs_init(offsets_); rec_offs_init(offsets_);
ut_ad(page_rec_is_leaf(rec)); 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); col_no + 1, &heap);
if (rec_offs_nth_sql_null(offsets, col_no)) { if (rec_offs_nth_sql_null(offsets, col_no)) {

View file

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. 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 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 the terms of the GNU General Public License as published by the Free Software
@ -117,7 +117,8 @@ row_undo_ins_remove_clust_rec(
const rec_t* rec = btr_cur_get_rec(btr_cur); const rec_t* rec = btr_cur_get_rec(btr_cur);
mem_heap_t* heap = NULL; mem_heap_t* heap = NULL;
const rec_offs* offsets = rec_get_offsets( 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); row_log_table_delete(rec, index, offsets, NULL);
mem_heap_free(heap); mem_heap_free(heap);
} }

View file

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. 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 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 the terms of the GNU General Public License as published by the Free Software
@ -163,8 +163,9 @@ static ulint row_trx_id_offset(const rec_t* rec, const dict_index_t* index)
rec_offs_init(offsets_); rec_offs_init(offsets_);
mem_heap_t* heap = NULL; mem_heap_t* heap = NULL;
const ulint trx_id_pos = index->n_uniq ? index->n_uniq : 1; const ulint trx_id_pos = index->n_uniq ? index->n_uniq : 1;
rec_offs* offsets = rec_get_offsets(rec, index, offsets_, true, rec_offs* offsets = rec_get_offsets(rec, index, offsets_,
trx_id_pos + 1, &heap); index->n_core_fields,
trx_id_pos + 1, &heap);
ut_ad(!heap); ut_ad(!heap);
ulint len; ulint len;
trx_id_offset = rec_get_nth_field_offs( trx_id_offset = rec_get_nth_field_offs(
@ -409,7 +410,8 @@ row_undo_mod_clust(
rec_offs offsets_[REC_OFFS_HEADER_SIZE + MAX_REF_PARTS + 2]; rec_offs offsets_[REC_OFFS_HEADER_SIZE + MAX_REF_PARTS + 2];
rec_offs_init(offsets_); rec_offs_init(offsets_);
offsets = rec_get_offsets( 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);
ulint len; ulint len;
ulint trx_id_offset = rec_get_nth_field_offs( ulint trx_id_offset = rec_get_nth_field_offs(
offsets, trx_id_pos, &len); offsets, trx_id_pos, &len);
@ -794,7 +796,8 @@ try_again:
offsets_heap = NULL; offsets_heap = NULL;
offsets = rec_get_offsets( offsets = rec_get_offsets(
btr_cur_get_rec(btr_cur), btr_cur_get_rec(btr_cur),
index, NULL, true, ULINT_UNDEFINED, &offsets_heap); index, NULL, index->n_core_fields, ULINT_UNDEFINED,
&offsets_heap);
update = row_upd_build_sec_rec_difference_binary( update = row_upd_build_sec_rec_difference_binary(
btr_cur_get_rec(btr_cur), index, offsets, entry, heap); btr_cur_get_rec(btr_cur), index, offsets, entry, heap);
if (upd_get_n_fields(update) == 0) { if (upd_get_n_fields(update) == 0) {

View file

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1997, 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 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 the terms of the GNU General Public License as published by the Free Software
@ -187,7 +187,8 @@ row_undo_search_clust_to_pcur(
rec = btr_pcur_get_rec(&node->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); ULINT_UNDEFINED, &heap);
found = row_get_rec_roll_ptr(rec, clust_index, offsets) found = row_get_rec_roll_ptr(rec, clust_index, offsets)

View file

@ -1067,7 +1067,8 @@ row_upd_build_difference_binary(
== trx_id_pos + 1); == trx_id_pos + 1);
if (!offsets) { if (!offsets) {
offsets = rec_get_offsets(rec, index, offsets_, true, offsets = rec_get_offsets(rec, index, offsets_,
index->n_core_fields,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
} else { } else {
ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(rec_offs_validate(rec, index, offsets));
@ -2218,7 +2219,8 @@ row_upd_store_row(
rec = btr_pcur_get_rec(node->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); ULINT_UNDEFINED, &heap);
if (dict_table_has_atomic_blobs(node->table)) { if (dict_table_has_atomic_blobs(node->table)) {
@ -2451,7 +2453,7 @@ row_upd_sec_index_entry(
&& !wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { && !wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
rec_offs* offsets = rec_get_offsets( rec_offs* offsets = rec_get_offsets(
rec, index, NULL, true, rec, index, NULL, index->n_core_fields,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
err = wsrep_row_upd_check_foreign_constraints( err = wsrep_row_upd_check_foreign_constraints(
@ -2494,12 +2496,9 @@ row_upd_sec_index_entry(
ut_ad(err == DB_SUCCESS); ut_ad(err == DB_SUCCESS);
if (referenced) { if (referenced) {
rec_offs* offsets = rec_get_offsets(
rec_offs* offsets; rec, index, NULL, index->n_core_fields,
ULINT_UNDEFINED, &heap);
offsets = rec_get_offsets(
rec, index, NULL, true, ULINT_UNDEFINED,
&heap);
/* NOTE that the following call loses /* NOTE that the following call loses
the position of pcur ! */ the position of pcur ! */
@ -2741,7 +2740,8 @@ row_upd_clust_rec_by_insert(
we update the primary key. Delete-mark the old record we update the primary key. Delete-mark the old record
in the clustered index and prepare to insert a new entry. */ in the clustered index and prepare to insert a new entry. */
rec = btr_cur_get_rec(btr_cur); 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); ULINT_UNDEFINED, &heap);
ut_ad(page_rec_is_user_rec(rec)); ut_ad(page_rec_is_user_rec(rec));
@ -3152,7 +3152,7 @@ row_upd_clust_step(
} }
rec = btr_pcur_get_rec(pcur); 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); ULINT_UNDEFINED, &heap);
if (!flags && !node->has_clust_rec_x_lock) { if (!flags && !node->has_clust_rec_x_lock) {

View file

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. 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 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 the terms of the GNU General Public License as published by the Free Software
@ -116,7 +116,8 @@ row_vers_impl_x_locked_low(
heap = mem_heap_create(1024); heap = mem_heap_create(1024);
clust_offsets = rec_get_offsets(clust_rec, clust_index, clust_offsets_, 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); trx_id = row_get_rec_trx_id(clust_rec, clust_index, clust_offsets);
if (trx_id == 0) { if (trx_id == 0) {
@ -239,7 +240,8 @@ not_locked:
} }
clust_offsets = rec_get_offsets( 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); ULINT_UNDEFINED, &heap);
vers_del = rec_get_deleted_flag(prev_version, comp); vers_del = rec_get_deleted_flag(prev_version, comp);
@ -569,7 +571,8 @@ row_vers_build_cur_vrow_low(
clust_offsets = rec_get_offsets(prev_version, clust_index, clust_offsets = rec_get_offsets(prev_version, clust_index,
NULL, NULL,
true, ULINT_UNDEFINED, &heap); clust_index->n_core_fields,
ULINT_UNDEFINED, &heap);
ulint entry_len = dict_index_get_n_fields(index); ulint entry_len = dict_index_get_n_fields(index);
@ -711,7 +714,8 @@ row_vers_vc_matches_cluster(
clust_offsets = rec_get_offsets(prev_version, clust_index, clust_offsets = rec_get_offsets(prev_version, clust_index,
NULL, NULL,
true, ULINT_UNDEFINED, &heap); clust_index->n_core_fields,
ULINT_UNDEFINED, &heap);
ulint entry_len = dict_index_get_n_fields(index); ulint entry_len = dict_index_get_n_fields(index);
@ -849,7 +853,8 @@ row_vers_build_cur_vrow(
index, roll_ptr, trx_id, v_heap, &cur_vrow, mtr); 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); ULINT_UNDEFINED, &heap);
return(cur_vrow); return(cur_vrow);
} }
@ -906,7 +911,8 @@ row_vers_old_has_index_entry(
comp = page_rec_is_comp(rec); comp = page_rec_is_comp(rec);
ut_ad(!dict_table_is_comp(index->table) == !comp); ut_ad(!dict_table_is_comp(index->table) == !comp);
heap = mem_heap_create(1024); 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); ULINT_UNDEFINED, &heap);
if (dict_index_has_virtual(index)) { if (dict_index_has_virtual(index)) {
@ -995,7 +1001,8 @@ row_vers_old_has_index_entry(
} }
} }
clust_offsets = rec_get_offsets(rec, clust_index, NULL, clust_offsets = rec_get_offsets(rec, clust_index, NULL,
true, clust_index
->n_core_fields,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
} else { } else {
@ -1074,7 +1081,8 @@ unsafe_to_purge:
} }
clust_offsets = rec_get_offsets(prev_version, clust_index, clust_offsets = rec_get_offsets(prev_version, clust_index,
NULL, true, NULL,
clust_index->n_core_fields,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
if (dict_index_has_virtual(index)) { if (dict_index_has_virtual(index)) {
@ -1215,7 +1223,7 @@ row_vers_build_for_consistent_read(
*offsets = rec_get_offsets( *offsets = rec_get_offsets(
prev_version, index, *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 #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ut_a(!rec_offs_any_null_extern(prev_version, *offsets)); ut_a(!rec_offs_any_null_extern(prev_version, *offsets));
@ -1331,11 +1339,10 @@ committed_version_trx:
semi-consistent read. */ semi-consistent read. */
version = rec; version = rec;
*offsets = rec_get_offsets(version, *offsets = rec_get_offsets(
index, *offsets, version, index, *offsets,
true, index->n_core_fields, ULINT_UNDEFINED,
ULINT_UNDEFINED, offset_heap);
offset_heap);
} }
buf = static_cast<byte*>( buf = static_cast<byte*>(
@ -1378,7 +1385,8 @@ committed_version_trx:
} }
version = prev_version; 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); ULINT_UNDEFINED, offset_heap);
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ut_a(!rec_offs_any_null_extern(version, *offsets)); ut_a(!rec_offs_any_null_extern(version, *offsets));

View file

@ -713,7 +713,8 @@ fill_lock_data(
ut_a(n_fields > 0); ut_a(n_fields > 0);
heap = NULL; 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 */ /* format and store the data */

View file

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2019, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 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 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 the terms of the GNU General Public License as published by the Free Software
@ -2412,7 +2412,8 @@ trx_undo_prev_version_build(
rec_offs offsets_dbg[REC_OFFS_NORMAL_SIZE]; rec_offs offsets_dbg[REC_OFFS_NORMAL_SIZE];
rec_offs_init(offsets_dbg); rec_offs_init(offsets_dbg);
ut_a(!rec_offs_any_null_extern( 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))); ULINT_UNDEFINED, &heap)));
#endif // defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG #endif // defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG

View file

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1994, 2017, Oracle and/or its affiliates. All Rights Reserved. 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 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 the terms of the GNU General Public License as published by the Free Software
@ -667,7 +667,7 @@ const char * dbug_print_rec(const rec_t* rec, dict_index_t* index)
rec_offs* offsets = offsets_; rec_offs* offsets = offsets_;
rec_offs_init(offsets_); rec_offs_init(offsets_);
mem_heap_t* tmp_heap = NULL; 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); ULINT_UNDEFINED, &tmp_heap);
rec_printer r(rec, offsets); rec_printer r(rec, offsets);
strmake(dbug_print_buf, r.str().c_str(), sizeof(dbug_print_buf) - 1); strmake(dbug_print_buf, r.str().c_str(), sizeof(dbug_print_buf) - 1);