summaryrefslogtreecommitdiff
path: root/innobase/page/page0page.c
diff options
context:
space:
mode:
Diffstat (limited to 'innobase/page/page0page.c')
-rw-r--r--innobase/page/page0page.c656
1 files changed, 431 insertions, 225 deletions
diff --git a/innobase/page/page0page.c b/innobase/page/page0page.c
index 343f300fc77..7e09cdf073e 100644
--- a/innobase/page/page0page.c
+++ b/innobase/page/page0page.c
@@ -18,6 +18,8 @@ Created 2/2/1994 Heikki Tuuri
#include "fut0lst.h"
#include "btr0sea.h"
#include "buf0buf.h"
+#include "srv0srv.h"
+#include "btr0btr.h"
/* THE INDEX PAGE
==============
@@ -70,53 +72,70 @@ page_dir_find_owner_slot(
/* out: the directory slot number */
rec_t* rec) /* in: the physical record */
{
- ulint i;
- ulint steps = 0;
- page_t* page;
- page_dir_slot_t* slot;
- rec_t* original_rec = rec;
-
+ page_t* page;
+ register uint16 rec_offs_bytes;
+ register page_dir_slot_t* slot;
+ register const page_dir_slot_t* first_slot;
+ register rec_t* r = rec;
+
ut_ad(page_rec_check(rec));
- while (rec_get_n_owned(rec) == 0) {
- steps++;
- rec = page_rec_get_next(rec);
- }
-
page = buf_frame_align(rec);
+ first_slot = page_dir_get_nth_slot(page, 0);
+ slot = page_dir_get_nth_slot(page, page_dir_get_n_slots(page) - 1);
+
+ if (page_is_comp(page)) {
+ while (rec_get_n_owned(r, TRUE) == 0) {
+ r = page + rec_get_next_offs(r, TRUE);
+ ut_ad(r >= page + PAGE_NEW_SUPREMUM);
+ ut_ad(r < page + (UNIV_PAGE_SIZE - PAGE_DIR));
+ }
+ } else {
+ while (rec_get_n_owned(r, FALSE) == 0) {
+ r = page + rec_get_next_offs(r, FALSE);
+ ut_ad(r >= page + PAGE_OLD_SUPREMUM);
+ ut_ad(r < page + (UNIV_PAGE_SIZE - PAGE_DIR));
+ }
+ }
- i = page_dir_get_n_slots(page) - 1;
- slot = page_dir_get_nth_slot(page, i);
+ rec_offs_bytes = mach_encode_2(r - page);
- while (page_dir_slot_get_rec(slot) != rec) {
+ while (UNIV_LIKELY(*(uint16*) slot != rec_offs_bytes)) {
- if (i == 0) {
+ if (UNIV_UNLIKELY(slot == first_slot)) {
fprintf(stderr,
"InnoDB: Probable data corruption on page %lu\n"
"InnoDB: Original record ",
(ulong) buf_frame_get_page_no(page));
- rec_print(stderr, original_rec);
+ if (page_is_comp(page)) {
+ fputs("(compact record)", stderr);
+ } else {
+ rec_print_old(stderr, rec);
+ }
- fprintf(stderr, "\n"
- "InnoDB: on that page. Steps %lu.\n", (ulong) steps);
- fputs(
+ fputs("\n"
+ "InnoDB: on that page.\n"
"InnoDB: Cannot find the dir slot for record ",
stderr);
- rec_print(stderr, rec);
+ if (page_is_comp(page)) {
+ fputs("(compact record)", stderr);
+ } else {
+ rec_print_old(stderr, page
+ + mach_decode_2(rec_offs_bytes));
+ }
fputs("\n"
"InnoDB: on that page!\n", stderr);
buf_page_print(page);
- ut_error;
- }
+ ut_error;
+ }
- i--;
- slot = page_dir_get_nth_slot(page, i);
+ slot += PAGE_DIR_SLOT_SIZE;
}
- return(i);
+ return(((ulint) (first_slot - slot)) / PAGE_DIR_SLOT_SIZE);
}
/******************************************************************
@@ -136,14 +155,15 @@ page_dir_slot_check(
page = buf_frame_align(slot);
- n_slots = page_header_get_field(page, PAGE_N_DIR_SLOTS);
+ n_slots = page_dir_get_n_slots(page);
ut_a(slot <= page_dir_get_nth_slot(page, 0));
ut_a(slot >= page_dir_get_nth_slot(page, n_slots - 1));
- ut_a(page_rec_check(page + mach_read_from_2(slot)));
+ ut_a(page_rec_check(page_dir_slot_get_rec(slot)));
- n_owned = rec_get_n_owned(page + mach_read_from_2(slot));
+ n_owned = rec_get_n_owned(page_dir_slot_get_rec(slot),
+ page_is_comp(page));
if (slot == page_dir_get_nth_slot(page, 0)) {
ut_a(n_owned == 1);
@@ -194,12 +214,14 @@ Allocates a block of memory from an index page. */
byte*
page_mem_alloc(
/*===========*/
- /* out: pointer to start of allocated
- buffer, or NULL if allocation fails */
- page_t* page, /* in: index page */
- ulint need, /* in: number of bytes needed */
- ulint* heap_no)/* out: this contains the heap number
- of the allocated record if allocation succeeds */
+ /* out: pointer to start of allocated
+ buffer, or NULL if allocation fails */
+ page_t* page, /* in: index page */
+ ulint need, /* in: number of bytes needed */
+ dict_index_t* index, /* in: record descriptor */
+ ulint* heap_no)/* out: this contains the heap number
+ of the allocated record
+ if allocation succeeds */
{
rec_t* rec;
byte* block;
@@ -213,18 +235,37 @@ page_mem_alloc(
rec = page_header_get_ptr(page, PAGE_FREE);
- if (rec && (rec_get_size(rec) >= need)) {
+ if (rec) {
+ mem_heap_t* heap = NULL;
+ ulint offsets_[REC_OFFS_NORMAL_SIZE];
+ ulint* offsets = offsets_;
+ *offsets_ = (sizeof offsets_) / sizeof *offsets_;
- page_header_set_ptr(page, PAGE_FREE, page_rec_get_next(rec));
+ offsets = rec_get_offsets(rec, index, offsets,
+ ULINT_UNDEFINED, &heap);
- garbage = page_header_get_field(page, PAGE_GARBAGE);
- ut_ad(garbage >= need);
+ if (rec_offs_size(offsets) >= need) {
+ page_header_set_ptr(page, PAGE_FREE,
+ page_rec_get_next(rec));
- page_header_set_field(page, PAGE_GARBAGE, garbage - need);
+ garbage = page_header_get_field(page, PAGE_GARBAGE);
+ ut_ad(garbage >= need);
- *heap_no = rec_get_heap_no(rec);
+ page_header_set_field(page, PAGE_GARBAGE,
+ garbage - need);
- return(rec_get_start(rec));
+ *heap_no = rec_get_heap_no(rec, page_is_comp(page));
+
+ block = rec_get_start(rec, offsets);
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_free(heap);
+ }
+ return(block);
+ }
+
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_free(heap);
+ }
}
/* Could not find space from the free list, try top of heap */
@@ -235,9 +276,9 @@ page_mem_alloc(
block = page_header_get_ptr(page, PAGE_HEAP_TOP);
page_header_set_ptr(page, PAGE_HEAP_TOP, block + need);
- *heap_no = page_header_get_field(page, PAGE_N_HEAP);
+ *heap_no = page_dir_get_n_heap(page);
- page_header_set_field(page, PAGE_N_HEAP, 1 + *heap_no);
+ page_dir_set_n_heap(page, 1 + *heap_no);
return(block);
}
@@ -253,9 +294,11 @@ page_create_write_log(
/*==================*/
buf_frame_t* frame, /* in: a buffer frame where the page is
created */
- mtr_t* mtr) /* in: mini-transaction handle */
+ mtr_t* mtr, /* in: mini-transaction handle */
+ ulint comp) /* in: nonzero=compact page format */
{
- mlog_write_initial_log_record(frame, MLOG_PAGE_CREATE, mtr);
+ mlog_write_initial_log_record(frame,
+ comp ? MLOG_COMP_PAGE_CREATE : MLOG_PAGE_CREATE, mtr);
}
/***************************************************************
@@ -267,6 +310,7 @@ page_parse_create(
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
byte* end_ptr __attribute__((unused)), /* in: buffer end */
+ ulint comp, /* in: nonzero=compact page format */
page_t* page, /* in: page or NULL */
mtr_t* mtr) /* in: mtr or NULL */
{
@@ -275,7 +319,7 @@ page_parse_create(
/* The record is empty, except for the record initial part */
if (page) {
- page_create(page, mtr);
+ page_create(page, mtr, comp);
}
return(ptr);
@@ -290,7 +334,8 @@ page_create(
/* out: pointer to the page */
buf_frame_t* frame, /* in: a buffer frame where the page is
created */
- mtr_t* mtr) /* in: mini-transaction handle */
+ mtr_t* mtr, /* in: mini-transaction handle */
+ ulint comp) /* in: nonzero=compact page format */
{
page_dir_slot_t* slot;
mem_heap_t* heap;
@@ -300,6 +345,10 @@ page_create(
rec_t* infimum_rec;
rec_t* supremum_rec;
page_t* page;
+ dict_index_t* index;
+ ulint* offsets;
+
+ index = comp ? srv_sys->dummy_ind2 : srv_sys->dummy_ind1;
ut_ad(frame && mtr);
ut_ad(PAGE_BTR_IBUF_FREE_LIST + FLST_BASE_NODE_SIZE
@@ -311,7 +360,7 @@ page_create(
buf_frame_modify_clock_inc(frame);
/* 2. WRITE LOG INFORMATION */
- page_create_write_log(frame, mtr);
+ page_create_write_log(frame, mtr, comp);
page = frame;
@@ -323,51 +372,61 @@ page_create(
/* Create first a data tuple for infimum record */
tuple = dtuple_create(heap, 1);
+ dtuple_set_info_bits(tuple, REC_STATUS_INFIMUM);
field = dtuple_get_nth_field(tuple, 0);
- dfield_set_data(field, "infimum", sizeof "infimum");
- dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 20, 0);
-
+ dfield_set_data(field, "infimum", 8);
+ dtype_set(dfield_get_type(field),
+ DATA_VARCHAR, DATA_ENGLISH | DATA_NOT_NULL, 8, 0);
/* Set the corresponding physical record to its place in the page
record heap */
heap_top = page + PAGE_DATA;
- infimum_rec = rec_convert_dtuple_to_rec(heap_top, tuple);
+ infimum_rec = rec_convert_dtuple_to_rec(heap_top, index, tuple);
+
+ ut_a(infimum_rec ==
+ page + (comp ? PAGE_NEW_INFIMUM : PAGE_OLD_INFIMUM));
+
+ rec_set_n_owned(infimum_rec, comp, 1);
+ rec_set_heap_no(infimum_rec, comp, 0);
+ offsets = rec_get_offsets(infimum_rec, index, NULL,
+ ULINT_UNDEFINED, &heap);
+
+ heap_top = rec_get_end(infimum_rec, offsets);
- ut_a(infimum_rec == page + PAGE_INFIMUM);
-
- rec_set_n_owned(infimum_rec, 1);
- rec_set_heap_no(infimum_rec, 0);
-
- heap_top = rec_get_end(infimum_rec);
-
/* Create then a tuple for supremum */
tuple = dtuple_create(heap, 1);
+ dtuple_set_info_bits(tuple, REC_STATUS_SUPREMUM);
field = dtuple_get_nth_field(tuple, 0);
- dfield_set_data(field, "supremum", sizeof "supremum");
- dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 20, 0);
+ dfield_set_data(field, "supremum", comp ? 8 : 9);
+ dtype_set(dfield_get_type(field),
+ DATA_VARCHAR, DATA_ENGLISH | DATA_NOT_NULL, comp ? 8 : 9, 0);
- supremum_rec = rec_convert_dtuple_to_rec(heap_top, tuple);
+ supremum_rec = rec_convert_dtuple_to_rec(heap_top, index, tuple);
- ut_a(supremum_rec == page + PAGE_SUPREMUM);
+ ut_a(supremum_rec ==
+ page + (comp ? PAGE_NEW_SUPREMUM : PAGE_OLD_SUPREMUM));
- rec_set_n_owned(supremum_rec, 1);
- rec_set_heap_no(supremum_rec, 1);
-
- heap_top = rec_get_end(supremum_rec);
+ rec_set_n_owned(supremum_rec, comp, 1);
+ rec_set_heap_no(supremum_rec, comp, 1);
+
+ offsets = rec_get_offsets(supremum_rec, index, offsets,
+ ULINT_UNDEFINED, &heap);
+ heap_top = rec_get_end(supremum_rec, offsets);
- ut_ad(heap_top == page + PAGE_SUPREMUM_END);
+ ut_ad(heap_top ==
+ page + (comp ? PAGE_NEW_SUPREMUM_END : PAGE_OLD_SUPREMUM_END));
mem_heap_free(heap);
- /* 4. INITIALIZE THE PAGE HEADER */
+ /* 4. INITIALIZE THE PAGE */
page_header_set_field(page, PAGE_N_DIR_SLOTS, 2);
page_header_set_ptr(page, PAGE_HEAP_TOP, heap_top);
- page_header_set_field(page, PAGE_N_HEAP, 2);
+ page_header_set_field(page, PAGE_N_HEAP, comp ? 0x8002 : 2);
page_header_set_ptr(page, PAGE_FREE, NULL);
page_header_set_field(page, PAGE_GARBAGE, 0);
page_header_set_ptr(page, PAGE_LAST_INSERT, NULL);
@@ -375,7 +434,9 @@ page_create(
page_header_set_field(page, PAGE_N_DIRECTION, 0);
page_header_set_field(page, PAGE_N_RECS, 0);
page_set_max_trx_id(page, ut_dulint_zero);
-
+ memset(heap_top, 0, UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START
+ - (heap_top - page));
+
/* 5. SET POINTERS IN RECORDS AND DIR SLOTS */
/* Set the slots to point to infimum and supremum. */
@@ -388,8 +449,8 @@ page_create(
/* Set the next pointers in infimum and supremum */
- rec_set_next_offs(infimum_rec, (ulint)(supremum_rec - page));
- rec_set_next_offs(supremum_rec, 0);
+ rec_set_next_offs(infimum_rec, comp, (ulint)(supremum_rec - page));
+ rec_set_next_offs(supremum_rec, comp, 0);
return(page);
}
@@ -401,14 +462,19 @@ touch the lock table and max trx id on page. */
void
page_copy_rec_list_end_no_locks(
/*============================*/
- page_t* new_page, /* in: index page to copy to */
- page_t* page, /* in: index page */
- rec_t* rec, /* in: record on page */
- mtr_t* mtr) /* in: mtr */
+ page_t* new_page, /* in: index page to copy to */
+ page_t* page, /* in: index page */
+ rec_t* rec, /* in: record on page */
+ dict_index_t* index, /* in: record descriptor */
+ mtr_t* mtr) /* in: mtr */
{
page_cur_t cur1;
page_cur_t cur2;
rec_t* sup;
+ mem_heap_t* heap = NULL;
+ ulint offsets_[REC_OFFS_NORMAL_SIZE];
+ ulint* offsets = offsets_;
+ *offsets_ = (sizeof offsets_) / sizeof *offsets_;
page_cur_position(rec, &cur1);
@@ -416,8 +482,12 @@ page_copy_rec_list_end_no_locks(
page_cur_move_to_next(&cur1);
}
-
- ut_a(mach_read_from_2(new_page + UNIV_PAGE_SIZE - 10) == PAGE_INFIMUM);
+
+ ut_a((ibool)!!page_is_comp(new_page) == index->table->comp);
+ ut_a(page_is_comp(new_page) == page_is_comp(page));
+ ut_a(mach_read_from_2(new_page + UNIV_PAGE_SIZE - 10) == (ulint)
+ (page_is_comp(new_page)
+ ? PAGE_NEW_INFIMUM : PAGE_OLD_INFIMUM));
page_cur_set_before_first(new_page, &cur2);
@@ -425,9 +495,15 @@ page_copy_rec_list_end_no_locks(
sup = page_get_supremum_rec(page);
- while (sup != page_cur_get_rec(&cur1)) {
- if (!page_cur_rec_insert(&cur2,
- page_cur_get_rec(&cur1), mtr)) {
+ for (;;) {
+ rec_t* cur1_rec = page_cur_get_rec(&cur1);
+ if (cur1_rec == sup) {
+ break;
+ }
+ offsets = rec_get_offsets(cur1_rec, index, offsets,
+ ULINT_UNDEFINED, &heap);
+ if (UNIV_UNLIKELY(!page_cur_rec_insert(&cur2, cur1_rec, index,
+ offsets, mtr))) {
/* Track an assertion failure reported on the mailing
list on June 18th, 2003 */
@@ -446,7 +522,11 @@ page_copy_rec_list_end_no_locks(
page_cur_move_to_next(&cur1);
page_cur_move_to_next(&cur2);
}
-}
+
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_free(heap);
+ }
+}
/*****************************************************************
Copies records from page to new_page, from a given record onward,
@@ -456,16 +536,18 @@ The records are copied to the start of the record list on new_page. */
void
page_copy_rec_list_end(
/*===================*/
- page_t* new_page, /* in: index page to copy to */
- page_t* page, /* in: index page */
- rec_t* rec, /* in: record on page */
- mtr_t* mtr) /* in: mtr */
+ page_t* new_page, /* in: index page to copy to */
+ page_t* page, /* in: index page */
+ rec_t* rec, /* in: record on page */
+ dict_index_t* index, /* in: record descriptor */
+ mtr_t* mtr) /* in: mtr */
{
- if (page_header_get_field(new_page, PAGE_N_HEAP) == 2) {
+ if (page_dir_get_n_heap(new_page) == 2) {
page_copy_rec_list_end_to_created_page(new_page, page, rec,
- mtr);
+ index, mtr);
} else {
- page_copy_rec_list_end_no_locks(new_page, page, rec, mtr);
+ page_copy_rec_list_end_no_locks(new_page, page, rec,
+ index, mtr);
}
/* Update the lock table, MAX_TRX_ID, and possible hash index */
@@ -474,7 +556,7 @@ page_copy_rec_list_end(
page_update_max_trx_id(new_page, page_get_max_trx_id(page));
- btr_search_move_or_delete_hash_entries(new_page, page);
+ btr_search_move_or_delete_hash_entries(new_page, page, index);
}
/*****************************************************************
@@ -485,14 +567,19 @@ The records are copied to the end of the record list on new_page. */
void
page_copy_rec_list_start(
/*=====================*/
- page_t* new_page, /* in: index page to copy to */
- page_t* page, /* in: index page */
- rec_t* rec, /* in: record on page */
- mtr_t* mtr) /* in: mtr */
+ page_t* new_page, /* in: index page to copy to */
+ page_t* page, /* in: index page */
+ rec_t* rec, /* in: record on page */
+ dict_index_t* index, /* in: record descriptor */
+ mtr_t* mtr) /* in: mtr */
{
page_cur_t cur1;
page_cur_t cur2;
rec_t* old_end;
+ mem_heap_t* heap = NULL;
+ ulint offsets_[REC_OFFS_NORMAL_SIZE];
+ ulint* offsets = offsets_;
+ *offsets_ = (sizeof offsets_) / sizeof *offsets_;
page_cur_set_before_first(page, &cur1);
@@ -510,8 +597,13 @@ page_copy_rec_list_start(
/* Copy records from the original page to the new page */
while (page_cur_get_rec(&cur1) != rec) {
- ut_a(
- page_cur_rec_insert(&cur2, page_cur_get_rec(&cur1), mtr));
+ rec_t* ins_rec;
+ rec_t* cur1_rec = page_cur_get_rec(&cur1);
+ offsets = rec_get_offsets(cur1_rec, index, offsets,
+ ULINT_UNDEFINED, &heap);
+ ins_rec = page_cur_rec_insert(&cur2, cur1_rec, index,
+ offsets, mtr);
+ ut_a(ins_rec);
page_cur_move_to_next(&cur1);
page_cur_move_to_next(&cur2);
@@ -523,8 +615,12 @@ page_copy_rec_list_start(
page_update_max_trx_id(new_page, page_get_max_trx_id(page));
- btr_search_move_or_delete_hash_entries(new_page, page);
-}
+ btr_search_move_or_delete_hash_entries(new_page, page, index);
+
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_free(heap);
+ }
+}
/**************************************************************
Writes a log record of a record list end or start deletion. */
@@ -532,18 +628,24 @@ UNIV_INLINE
void
page_delete_rec_list_write_log(
/*===========================*/
- page_t* page, /* in: index page */
- rec_t* rec, /* in: record on page */
- byte type, /* in: operation type: MLOG_LIST_END_DELETE, ... */
- mtr_t* mtr) /* in: mtr */
+ rec_t* rec, /* in: record on page */
+ dict_index_t* index, /* in: record descriptor */
+ byte type, /* in: operation type:
+ MLOG_LIST_END_DELETE, ... */
+ mtr_t* mtr) /* in: mtr */
{
- ut_ad((type == MLOG_LIST_END_DELETE)
- || (type == MLOG_LIST_START_DELETE));
-
- mlog_write_initial_log_record(page, type, mtr);
-
- /* Write the parameter as a 2-byte ulint */
- mlog_catenate_ulint(mtr, rec - page, MLOG_2BYTES);
+ byte* log_ptr;
+ ut_ad(type == MLOG_LIST_END_DELETE
+ || type == MLOG_LIST_START_DELETE
+ || type == MLOG_COMP_LIST_END_DELETE
+ || type == MLOG_COMP_LIST_START_DELETE);
+
+ log_ptr = mlog_open_and_write_index(mtr, rec, index, type, 2);
+ if (log_ptr) {
+ /* Write the parameter as a 2-byte ulint */
+ mach_write_to_2(log_ptr, ut_align_offset(rec, UNIV_PAGE_SIZE));
+ mlog_close(mtr, log_ptr + 2);
+ }
}
/**************************************************************
@@ -552,18 +654,23 @@ Parses a log record of a record list end or start deletion. */
byte*
page_parse_delete_rec_list(
/*=======================*/
- /* out: end of log record or NULL */
- byte type, /* in: MLOG_LIST_END_DELETE or
- MLOG_LIST_START_DELETE */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr) /* in: mtr or NULL */
+ /* out: end of log record or NULL */
+ byte type, /* in: MLOG_LIST_END_DELETE,
+ MLOG_LIST_START_DELETE,
+ MLOG_COMP_LIST_END_DELETE or
+ MLOG_COMP_LIST_START_DELETE */
+ byte* ptr, /* in: buffer */
+ byte* end_ptr,/* in: buffer end */
+ dict_index_t* index, /* in: record descriptor */
+ page_t* page, /* in: page or NULL */
+ mtr_t* mtr) /* in: mtr or NULL */
{
ulint offset;
- ut_ad((type == MLOG_LIST_END_DELETE)
- || (type == MLOG_LIST_START_DELETE));
+ ut_ad(type == MLOG_LIST_END_DELETE
+ || type == MLOG_LIST_START_DELETE
+ || type == MLOG_COMP_LIST_END_DELETE
+ || type == MLOG_COMP_LIST_START_DELETE);
/* Read the record offset as a 2-byte ulint */
@@ -580,11 +687,14 @@ page_parse_delete_rec_list(
return(ptr);
}
- if (type == MLOG_LIST_END_DELETE) {
- page_delete_rec_list_end(page, page + offset, ULINT_UNDEFINED,
- ULINT_UNDEFINED, mtr);
+ ut_ad(!!page_is_comp(page) == index->table->comp);
+
+ if (type == MLOG_LIST_END_DELETE
+ || type == MLOG_COMP_LIST_END_DELETE) {
+ page_delete_rec_list_end(page, page + offset, index,
+ ULINT_UNDEFINED, ULINT_UNDEFINED, mtr);
} else {
- page_delete_rec_list_start(page, page + offset, mtr);
+ page_delete_rec_list_start(page, page + offset, index, mtr);
}
return(ptr);
@@ -597,14 +707,15 @@ The infimum and supremum records are not deleted. */
void
page_delete_rec_list_end(
/*=====================*/
- page_t* page, /* in: index page */
- rec_t* rec, /* in: record on page */
- ulint n_recs, /* in: number of records to delete, or ULINT_UNDEFINED
- if not known */
- ulint size, /* in: the sum of the sizes of the records in the end
- of the chain to delete, or ULINT_UNDEFINED if not
- known */
- mtr_t* mtr) /* in: mtr */
+ page_t* page, /* in: index page */
+ rec_t* rec, /* in: record on page */
+ dict_index_t* index, /* in: record descriptor */
+ ulint n_recs, /* in: number of records to delete,
+ or ULINT_UNDEFINED if not known */
+ ulint size, /* in: the sum of the sizes of the
+ records in the end of the chain to
+ delete, or ULINT_UNDEFINED if not known */
+ mtr_t* mtr) /* in: mtr */
{
page_dir_slot_t* slot;
ulint slot_index;
@@ -615,10 +726,12 @@ page_delete_rec_list_end(
ulint count;
ulint n_owned;
rec_t* sup;
+ ulint comp;
/* Reset the last insert info in the page header and increment
the modify clock for the frame */
+ ut_ad(size == ULINT_UNDEFINED || size < UNIV_PAGE_SIZE);
page_header_set_ptr(page, PAGE_LAST_INSERT, NULL);
/* The page gets invalid for optimistic searches: increment the
@@ -628,11 +741,13 @@ page_delete_rec_list_end(
sup = page_get_supremum_rec(page);
- if (rec == page_get_infimum_rec(page)) {
+ comp = page_is_comp(page);
+ if (page_rec_is_infimum_low(rec - page)) {
rec = page_rec_get_next(rec);
}
- page_delete_rec_list_write_log(page, rec, MLOG_LIST_END_DELETE, mtr);
+ page_delete_rec_list_write_log(rec, index,
+ comp ? MLOG_COMP_LIST_END_DELETE : MLOG_LIST_END_DELETE, mtr);
if (rec == sup) {
@@ -644,19 +759,36 @@ page_delete_rec_list_end(
last_rec = page_rec_get_prev(sup);
if ((size == ULINT_UNDEFINED) || (n_recs == ULINT_UNDEFINED)) {
+ mem_heap_t* heap = NULL;
+ ulint offsets_[REC_OFFS_NORMAL_SIZE];
+ ulint* offsets = offsets_;
+ *offsets_ = (sizeof offsets_) / sizeof *offsets_;
/* Calculate the sum of sizes and the number of records */
size = 0;
n_recs = 0;
rec2 = rec;
while (rec2 != sup) {
- size += rec_get_size(rec2);
+ ulint s;
+ offsets = rec_get_offsets(rec2, index, offsets,
+ ULINT_UNDEFINED, &heap);
+ s = rec_offs_size(offsets);
+ ut_ad(rec2 - page + s - rec_offs_extra_size(offsets)
+ < UNIV_PAGE_SIZE);
+ ut_ad(size + s < UNIV_PAGE_SIZE);
+ size += s;
n_recs++;
rec2 = page_rec_get_next(rec2);
}
+
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_free(heap);
+ }
}
+ ut_ad(size < UNIV_PAGE_SIZE);
+
/* Update the page directory; there is no need to balance the number
of the records owned by the supremum record, as it is allowed to be
less than PAGE_DIR_SLOT_MIN_N_OWNED */
@@ -664,15 +796,15 @@ page_delete_rec_list_end(
rec2 = rec;
count = 0;
- while (rec_get_n_owned(rec2) == 0) {
+ while (rec_get_n_owned(rec2, comp) == 0) {
count++;
rec2 = page_rec_get_next(rec2);
}
- ut_ad(rec_get_n_owned(rec2) - count > 0);
+ ut_ad(rec_get_n_owned(rec2, comp) - count > 0);
- n_owned = rec_get_n_owned(rec2) - count;
+ n_owned = rec_get_n_owned(rec2, comp) - count;
slot_index = page_dir_find_owner_slot(rec2);
slot = page_dir_get_nth_slot(page, slot_index);
@@ -680,7 +812,7 @@ page_delete_rec_list_end(
page_dir_slot_set_rec(slot, sup);
page_dir_slot_set_n_owned(slot, n_owned);
- page_header_set_field(page, PAGE_N_DIR_SLOTS, slot_index + 1);
+ page_dir_set_n_slots(page, slot_index + 1);
/* Remove the record chain segment from the record chain */
page_rec_set_next(prev_rec, page_get_supremum_rec(page));
@@ -706,14 +838,28 @@ that record. Infimum and supremum records are not deleted. */
void
page_delete_rec_list_start(
/*=======================*/
- page_t* page, /* in: index page */
- rec_t* rec, /* in: record on page */
- mtr_t* mtr) /* in: mtr */
+ page_t* page, /* in: index page */
+ rec_t* rec, /* in: record on page */
+ dict_index_t* index, /* in: record descriptor */
+ mtr_t* mtr) /* in: mtr */
{
page_cur_t cur1;
ulint log_mode;
+ ulint offsets_[REC_OFFS_NORMAL_SIZE];
+ ulint* offsets = offsets_;
+ mem_heap_t* heap = NULL;
+ byte type;
+ *offsets_ = (sizeof offsets_) / sizeof *offsets_;
+
+ ut_ad(!!page_is_comp(page) == index->table->comp);
+
+ if (page_is_comp(page)) {
+ type = MLOG_COMP_LIST_START_DELETE;
+ } else {
+ type = MLOG_LIST_START_DELETE;
+ }
- page_delete_rec_list_write_log(page, rec, MLOG_LIST_START_DELETE, mtr);
+ page_delete_rec_list_write_log(rec, index, type, mtr);
page_cur_set_before_first(page, &cur1);
@@ -729,8 +875,13 @@ page_delete_rec_list_start(
log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE);
while (page_cur_get_rec(&cur1) != rec) {
+ offsets = rec_get_offsets(page_cur_get_rec(&cur1), index,
+ offsets, ULINT_UNDEFINED, &heap);
+ page_cur_delete_rec(&cur1, index, offsets, mtr);
+ }
- page_cur_delete_rec(&cur1, mtr);
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_free(heap);
}
/* Restore log mode */
@@ -745,10 +896,11 @@ split_rec. */
void
page_move_rec_list_end(
/*===================*/
- page_t* new_page, /* in: index page where to move */
- page_t* page, /* in: index page */
- rec_t* split_rec, /* in: first record to move */
- mtr_t* mtr) /* in: mtr */
+ page_t* new_page, /* in: index page where to move */
+ page_t* page, /* in: index page */
+ rec_t* split_rec, /* in: first record to move */
+ dict_index_t* index, /* in: record descriptor */
+ mtr_t* mtr) /* in: mtr */
{
ulint old_data_size;
ulint new_data_size;
@@ -758,15 +910,15 @@ page_move_rec_list_end(
old_data_size = page_get_data_size(new_page);
old_n_recs = page_get_n_recs(new_page);
- page_copy_rec_list_end(new_page, page, split_rec, mtr);
+ page_copy_rec_list_end(new_page, page, split_rec, index, mtr);
new_data_size = page_get_data_size(new_page);
new_n_recs = page_get_n_recs(new_page);
ut_ad(new_data_size >= old_data_size);
- page_delete_rec_list_end(page, split_rec, new_n_recs - old_n_recs,
- new_data_size - old_data_size, mtr);
+ page_delete_rec_list_end(page, split_rec, index,
+ new_n_recs - old_n_recs, new_data_size - old_data_size, mtr);
}
/*****************************************************************
@@ -776,14 +928,15 @@ split_rec. */
void
page_move_rec_list_start(
/*=====================*/
- page_t* new_page, /* in: index page where to move */
- page_t* page, /* in: index page */
- rec_t* split_rec, /* in: first record not to move */
- mtr_t* mtr) /* in: mtr */
+ page_t* new_page, /* in: index page where to move */
+ page_t* page, /* in: index page */
+ rec_t* split_rec, /* in: first record not to move */
+ dict_index_t* index, /* in: record descriptor */
+ mtr_t* mtr) /* in: mtr */
{
- page_copy_rec_list_start(new_page, page, split_rec, mtr);
+ page_copy_rec_list_start(new_page, page, split_rec, index, mtr);
- page_delete_rec_list_start(page, split_rec, mtr);
+ page_delete_rec_list_start(page, split_rec, index, mtr);
}
/***************************************************************************
@@ -801,7 +954,7 @@ page_rec_write_index_page_no(
byte* data;
ulint len;
- data = rec_get_nth_field(rec, i, &len);
+ data = rec_get_nth_field_old(rec, i, &len);
ut_ad(len == 4);
@@ -885,7 +1038,7 @@ page_dir_add_slots(
ut_ad(start < n_slots - 1);
/* Update the page header */
- page_header_set_field(page, PAGE_N_DIR_SLOTS, n_slots + n);
+ page_dir_set_n_slots(page, n_slots + n);
/* Move slots up */
@@ -1006,8 +1159,8 @@ page_dir_balance_slot(
old_rec = page_dir_slot_get_rec(slot);
new_rec = page_rec_get_next(old_rec);
- rec_set_n_owned(old_rec, 0);
- rec_set_n_owned(new_rec, n_owned + 1);
+ rec_set_n_owned(old_rec, page_is_comp(page), 0);
+ rec_set_n_owned(new_rec, page_is_comp(page), n_owned + 1);
page_dir_slot_set_rec(slot, new_rec);
@@ -1080,13 +1233,15 @@ page_rec_get_n_recs_before(
rec_t* slot_rec;
page_t* page;
ulint i;
+ ulint comp;
lint n = 0;
ut_ad(page_rec_check(rec));
page = buf_frame_align(rec);
-
- while (rec_get_n_owned(rec) == 0) {
+ comp = page_is_comp(page);
+
+ while (rec_get_n_owned(rec, comp) == 0) {
rec = page_rec_get_next(rec);
n--;
@@ -1096,7 +1251,7 @@ page_rec_get_n_recs_before(
slot = page_dir_get_nth_slot(page, i);
slot_rec = page_dir_slot_get_rec(slot);
- n += rec_get_n_owned(slot_rec);
+ n += rec_get_n_owned(slot_rec, comp);
if (rec == slot_rec) {
@@ -1118,17 +1273,21 @@ the index page context. */
void
page_rec_print(
/*===========*/
- rec_t* rec)
+ rec_t* rec, /* in: physical record */
+ const ulint* offsets)/* in: record descriptor */
{
- rec_print(stderr, rec);
+ ulint comp = page_is_comp(buf_frame_align(rec));
+
+ ut_a(!comp == !rec_offs_comp(offsets));
+ rec_print_new(stderr, rec, offsets);
fprintf(stderr,
" n_owned: %lu; heap_no: %lu; next rec: %lu\n",
- (ulong) rec_get_n_owned(rec),
- (ulong) rec_get_heap_no(rec),
- (ulong) rec_get_next_offs(rec));
+ (ulong) rec_get_n_owned(rec, comp),
+ (ulong) rec_get_heap_no(rec, comp),
+ (ulong) rec_get_next_offs(rec, comp));
page_rec_check(rec);
- rec_validate(rec);
+ rec_validate(rec, offsets);
}
/*******************************************************************
@@ -1176,12 +1335,19 @@ debugging purposes. */
void
page_print_list(
/*============*/
- page_t* page, /* in: index page */
- ulint pr_n) /* in: print n first and n last entries */
+ page_t* page, /* in: index page */
+ dict_index_t* index, /* in: dictionary index of the page */
+ ulint pr_n) /* in: print n first and n last entries */
{
page_cur_t cur;
ulint count;
ulint n_recs;
+ mem_heap_t* heap = NULL;
+ ulint offsets_[REC_OFFS_NORMAL_SIZE];
+ ulint* offsets = offsets_;
+ *offsets_ = (sizeof offsets_) / sizeof *offsets_;
+
+ ut_a((ibool)!!page_is_comp(page) == index->table->comp);
fprintf(stderr,
"--------------------------------\n"
@@ -1193,7 +1359,9 @@ page_print_list(
page_cur_set_before_first(page, &cur);
count = 0;
for (;;) {
- page_rec_print(cur.rec);
+ offsets = rec_get_offsets(cur.rec, index, offsets,
+ ULINT_UNDEFINED, &heap);
+ page_rec_print(cur.rec, offsets);
if (count == pr_n) {
break;
@@ -1213,7 +1381,9 @@ page_print_list(
page_cur_move_to_next(&cur);
if (count + pr_n >= n_recs) {
- page_rec_print(cur.rec);
+ offsets = rec_get_offsets(cur.rec, index, offsets,
+ ULINT_UNDEFINED, &heap);
+ page_rec_print(cur.rec, offsets);
}
count++;
}
@@ -1222,6 +1392,10 @@ page_print_list(
"Total of %lu records \n"
"--------------------------------\n",
(ulong) (count + 1));
+
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_free(heap);
+ }
}
/*******************************************************************
@@ -1235,14 +1409,15 @@ page_header_print(
fprintf(stderr,
"--------------------------------\n"
"PAGE HEADER INFO\n"
- "Page address %p, n records %lu\n"
+ "Page address %p, n records %lu (%s)\n"
"n dir slots %lu, heap top %lu\n"
"Page n heap %lu, free %lu, garbage %lu\n"
"Page last insert %lu, direction %lu, n direction %lu\n",
page, (ulong) page_header_get_field(page, PAGE_N_RECS),
+ page_is_comp(page) ? "compact format" : "original format",
(ulong) page_header_get_field(page, PAGE_N_DIR_SLOTS),
(ulong) page_header_get_field(page, PAGE_HEAP_TOP),
- (ulong) page_header_get_field(page, PAGE_N_HEAP),
+ (ulong) page_dir_get_n_heap(page),
(ulong) page_header_get_field(page, PAGE_FREE),
(ulong) page_header_get_field(page, PAGE_GARBAGE),
(ulong) page_header_get_field(page, PAGE_LAST_INSERT),
@@ -1257,13 +1432,16 @@ debugging purposes. */
void
page_print(
/*======*/
- page_t* page, /* in: index page */
- ulint dn, /* in: print dn first and last entries in directory */
- ulint rn) /* in: print rn first and last records on page */
+ page_t* page, /* in: index page */
+ dict_index_t* index, /* in: dictionary index of the page */
+ ulint dn, /* in: print dn first and last entries
+ in directory */
+ ulint rn) /* in: print rn first and last records
+ in directory */
{
page_header_print(page);
page_dir_print(page, dn);
- page_print_list(page, rn);
+ page_print_list(page, index, rn);
}
/*******************************************************************
@@ -1274,20 +1452,24 @@ the heap_no field. */
ibool
page_rec_validate(
/*==============*/
- /* out: TRUE if ok */
- rec_t* rec) /* in: record on the page */
+ /* out: TRUE if ok */
+ rec_t* rec, /* in: physical record */
+ const ulint* offsets)/* in: array returned by rec_get_offsets() */
{
ulint n_owned;
ulint heap_no;
- page_t* page;
+ page_t* page;
+ ulint comp;
page = buf_frame_align(rec);
+ comp = page_is_comp(page);
+ ut_a(!comp == !rec_offs_comp(offsets));
page_rec_check(rec);
- rec_validate(rec);
+ rec_validate(rec, offsets);
- n_owned = rec_get_n_owned(rec);
- heap_no = rec_get_heap_no(rec);
+ n_owned = rec_get_n_owned(rec, comp);
+ heap_no = rec_get_heap_no(rec, comp);
if (!(n_owned <= PAGE_DIR_SLOT_MAX_N_OWNED)) {
fprintf(stderr,
@@ -1296,11 +1478,11 @@ page_rec_validate(
return(FALSE);
}
- if (!(heap_no < page_header_get_field(page, PAGE_N_HEAP))) {
+ if (!(heap_no < page_dir_get_n_heap(page))) {
fprintf(stderr,
"InnoDB: Heap no of rec %lu too big %lu %lu\n",
(ulong)(rec - page), (ulong) heap_no,
- (ulong) page_header_get_field(page, PAGE_N_HEAP));
+ (ulong) page_dir_get_n_heap(page));
return(FALSE);
}
@@ -1358,6 +1540,7 @@ page_simple_validate(
ulint count;
ulint own_count;
ibool ret = FALSE;
+ ulint comp = page_is_comp(page);
/* Check first that the record heap and the directory do not
overlap. */
@@ -1404,13 +1587,13 @@ page_simple_validate(
goto func_exit;
}
- if (rec_get_n_owned(rec) != 0) {
+ if (rec_get_n_owned(rec, comp) != 0) {
/* This is a record pointed to by a dir slot */
- if (rec_get_n_owned(rec) != own_count) {
+ if (rec_get_n_owned(rec, comp) != own_count) {
fprintf(stderr,
"InnoDB: Wrong owned count %lu, %lu, rec %lu\n",
- (ulong) rec_get_n_owned(rec),
+ (ulong) rec_get_n_owned(rec, comp),
(ulong) own_count,
(ulong)(rec - page));
@@ -1438,11 +1621,11 @@ page_simple_validate(
break;
}
- if (rec_get_next_offs(rec) < FIL_PAGE_DATA
- || rec_get_next_offs(rec) >= UNIV_PAGE_SIZE) {
+ if (rec_get_next_offs(rec, comp) < FIL_PAGE_DATA
+ || rec_get_next_offs(rec, comp) >= UNIV_PAGE_SIZE) {
fprintf(stderr,
"InnoDB: Next record offset nonsensical %lu for rec %lu\n",
- (ulong) rec_get_next_offs(rec),
+ (ulong) rec_get_next_offs(rec, comp),
(ulong)(rec - page));
goto func_exit;
@@ -1461,7 +1644,7 @@ page_simple_validate(
own_count++;
}
- if (rec_get_n_owned(rec) == 0) {
+ if (rec_get_n_owned(rec, comp) == 0) {
fprintf(stderr, "InnoDB: n owned is zero in a supremum rec\n");
goto func_exit;
@@ -1514,10 +1697,10 @@ page_simple_validate(
rec = page_rec_get_next(rec);
}
- if (page_header_get_field(page, PAGE_N_HEAP) != count + 1) {
+ if (page_dir_get_n_heap(page) != count + 1) {
fprintf(stderr, "InnoDB: N heap is wrong %lu, %lu\n",
- (ulong) page_header_get_field(page, PAGE_N_HEAP),
+ (ulong) page_dir_get_n_heap(page),
(ulong) (count + 1));
goto func_exit;
@@ -1549,25 +1732,30 @@ page_validate(
ulint slot_no;
ulint data_size;
rec_t* rec;
- rec_t* old_rec = NULL;
+ rec_t* old_rec = NULL;
ulint offs;
ulint n_slots;
- ibool ret = FALSE;
+ ibool ret = FALSE;
ulint i;
-
+ ulint comp = page_is_comp(page);
+ ulint* offsets = NULL;
+ ulint* old_offsets = NULL;
+
+ if ((ibool)!!comp != index->table->comp) {
+ fputs("InnoDB: 'compact format' flag mismatch\n", stderr);
+ goto func_exit2;
+ }
if (!page_simple_validate(page)) {
goto func_exit2;
}
- heap = mem_heap_create(UNIV_PAGE_SIZE);
+ heap = mem_heap_create(UNIV_PAGE_SIZE + 200);
/* The following buffer is used to check that the
records in the page record heap do not overlap */
buf = mem_heap_alloc(heap, UNIV_PAGE_SIZE);
- for (i = 0; i < UNIV_PAGE_SIZE; i++) {
- buf[i] = 0;
- }
+ memset(buf, 0, UNIV_PAGE_SIZE);
/* Check first that the record heap and the directory do not
overlap. */
@@ -1599,37 +1787,47 @@ page_validate(
for (;;) {
rec = cur.rec;
+ offsets = rec_get_offsets(rec, index, offsets,
+ ULINT_UNDEFINED, &heap);
+
+ if (comp && page_rec_is_user_rec(rec)
+ && rec_get_node_ptr_flag(rec)
+ != (ibool)
+ (btr_page_get_level_low(page) != 0)) {
+ fputs("InnoDB: node_ptr flag mismatch\n", stderr);
+ goto func_exit;
+ }
- if (!page_rec_validate(rec)) {
+ if (!page_rec_validate(rec, offsets)) {
goto func_exit;
}
/* Check that the records are in the ascending order */
if ((count >= 2) && (!page_cur_is_after_last(&cur))) {
- if (!(1 == cmp_rec_rec(rec, old_rec, index))) {
+ if (!(1 == cmp_rec_rec(rec, old_rec,
+ offsets, old_offsets, index))) {
fprintf(stderr,
"InnoDB: Records in wrong order on page %lu",
(ulong) buf_frame_get_page_no(page));
dict_index_name_print(stderr, NULL, index);
fputs("\nInnoDB: previous record ", stderr);
- rec_print(stderr, old_rec);
+ rec_print_new(stderr, old_rec, old_offsets);
fputs("\nInnoDB: record ", stderr);
- rec_print(stderr, rec);
+ rec_print_new(stderr, rec, offsets);
putc('\n', stderr);
goto func_exit;
}
}
- if ((rec != page_get_supremum_rec(page))
- && (rec != page_get_infimum_rec(page))) {
+ if (page_rec_is_user_rec(rec)) {
- data_size += rec_get_size(rec);
+ data_size += rec_offs_size(offsets);
}
- offs = rec_get_start(rec) - page;
+ offs = rec_get_start(rec, offsets) - page;
- for (i = 0; i < rec_get_size(rec); i++) {
+ for (i = 0; i < rec_offs_size(offsets); i++) {
if (!buf[offs + i] == 0) {
/* No other record may overlap this */
@@ -1641,12 +1839,12 @@ page_validate(
buf[offs + i] = 1;
}
- if (rec_get_n_owned(rec) != 0) {
+ if (rec_get_n_owned(rec, comp) != 0) {
/* This is a record pointed to by a dir slot */
- if (rec_get_n_owned(rec) != own_count) {
+ if (rec_get_n_owned(rec, comp) != own_count) {
fprintf(stderr,
"InnoDB: Wrong owned count %lu, %lu\n",
- (ulong) rec_get_n_owned(rec),
+ (ulong) rec_get_n_owned(rec, comp),
(ulong) own_count);
goto func_exit;
}
@@ -1671,11 +1869,11 @@ page_validate(
break;
}
- if (rec_get_next_offs(rec) < FIL_PAGE_DATA
- || rec_get_next_offs(rec) >= UNIV_PAGE_SIZE) {
+ if (rec_get_next_offs(rec, comp) < FIL_PAGE_DATA
+ || rec_get_next_offs(rec, comp) >= UNIV_PAGE_SIZE) {
fprintf(stderr,
"InnoDB: Next record offset wrong %lu\n",
- (ulong) rec_get_next_offs(rec));
+ (ulong) rec_get_next_offs(rec, comp));
goto func_exit;
}
@@ -1683,9 +1881,15 @@ page_validate(
page_cur_move_to_next(&cur);
own_count++;
old_rec = rec;
+ /* set old_offsets to offsets; recycle offsets */
+ {
+ ulint* offs = old_offsets;
+ old_offsets = offsets;
+ offsets = offs;
+ }
}
- if (rec_get_n_owned(rec) == 0) {
+ if (rec_get_n_owned(rec, comp) == 0) {
fputs("InnoDB: n owned is zero\n", stderr);
goto func_exit;
}
@@ -1714,15 +1918,17 @@ page_validate(
rec = page_header_get_ptr(page, PAGE_FREE);
while (rec != NULL) {
- if (!page_rec_validate(rec)) {
+ offsets = rec_get_offsets(rec, index, offsets,
+ ULINT_UNDEFINED, &heap);
+ if (!page_rec_validate(rec, offsets)) {
goto func_exit;
}
count++;
- offs = rec_get_start(rec) - page;
+ offs = rec_get_start(rec, offsets) - page;
- for (i = 0; i < rec_get_size(rec); i++) {
+ for (i = 0; i < rec_offs_size(offsets); i++) {
if (buf[offs + i] != 0) {
fputs(
@@ -1736,9 +1942,9 @@ page_validate(
rec = page_rec_get_next(rec);
}
- if (page_header_get_field(page, PAGE_N_HEAP) != count + 1) {
+ if (page_dir_get_n_heap(page) != count + 1) {
fprintf(stderr, "InnoDB: N heap is wrong %lu %lu\n",
- (ulong) page_header_get_field(page, PAGE_N_HEAP),
+ (ulong) page_dir_get_n_heap(page),
(ulong) count + 1);
goto func_exit;
}
@@ -1775,7 +1981,7 @@ page_find_rec_with_heap_no(
page_cur_set_before_first(page, &cur);
for (;;) {
- if (rec_get_heap_no(cur.rec) == heap_no) {
+ if (rec_get_heap_no(cur.rec, page_is_comp(page)) == heap_no) {
return(cur.rec);
}