Commit dd489539 authored by marko@hundin.mysql.fi's avatar marko@hundin.mysql.fi

Many files:

  Implement more compact InnoDB record format.
  Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC.
parent 3ca8c79e
This diff is collapsed.
This diff is collapsed.
......@@ -45,12 +45,12 @@ btr_pcur_free_for_mysql(
mem_free(cursor->old_rec_buf);
cursor->old_rec = NULL;
cursor->old_rec_buf = NULL;
}
cursor->btr_cur.page_cur.rec = NULL;
cursor->old_rec = NULL;
cursor->old_n_fields = 0;
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
cursor->latch_mode = BTR_NO_LATCHES;
......@@ -133,9 +133,10 @@ btr_pcur_store_position(
cursor->old_stored = BTR_PCUR_OLD_STORED;
cursor->old_rec = dict_tree_copy_rec_order_prefix(tree, rec,
&(cursor->old_rec_buf),
&(cursor->buf_size));
&cursor->old_n_fields,
&cursor->old_rec_buf,
&cursor->buf_size);
cursor->block_when_stored = buf_block_align(page);
cursor->modify_clock = buf_frame_get_modify_clock(page);
}
......@@ -166,6 +167,8 @@ btr_pcur_copy_stored_position(
pcur_receive->old_rec = pcur_receive->old_rec_buf
+ (pcur_donate->old_rec - pcur_donate->old_rec_buf);
}
pcur_receive->old_n_fields = pcur_donate->old_n_fields;
}
/******************************************************************
......@@ -228,6 +231,7 @@ btr_pcur_restore_position(
}
ut_a(cursor->old_rec);
ut_a(cursor->old_n_fields);
page = btr_cur_get_page(btr_pcur_get_btr_cur(cursor));
......@@ -242,17 +246,32 @@ btr_pcur_restore_position(
buf_page_dbg_add_level(page, SYNC_TREE_NODE);
#endif /* UNIV_SYNC_DEBUG */
if (cursor->rel_pos == BTR_PCUR_ON) {
#ifdef UNIV_DEBUG
rec_t* rec;
ulint* offsets1;
ulint* offsets2;
dict_index_t* index;
#endif /* UNIV_DEBUG */
cursor->latch_mode = latch_mode;
ut_ad(cmp_rec_rec(cursor->old_rec,
btr_pcur_get_rec(cursor),
dict_tree_find_index(
btr_cur_get_tree(
#ifdef UNIV_DEBUG
rec = btr_pcur_get_rec(cursor);
index = dict_tree_find_index(
btr_cur_get_tree(
btr_pcur_get_btr_cur(cursor)),
btr_pcur_get_rec(cursor)))
== 0);
rec);
heap = mem_heap_create(256);
offsets1 = rec_get_offsets(cursor->old_rec,
index, ULINT_UNDEFINED, heap);
offsets2 = rec_get_offsets(rec,
index, ULINT_UNDEFINED, heap);
ut_ad(cmp_rec_rec(cursor->old_rec,
rec, offsets1, offsets2,
cursor->old_n_fields,
index) == 0);
mem_heap_free(heap);
#endif /* UNIV_DEBUG */
return(TRUE);
}
......@@ -265,7 +284,8 @@ btr_pcur_restore_position(
heap = mem_heap_create(256);
tree = btr_cur_get_tree(btr_pcur_get_btr_cur(cursor));
tuple = dict_tree_build_data_tuple(tree, cursor->old_rec, heap);
tuple = dict_tree_build_data_tuple(tree, cursor->old_rec,
cursor->old_n_fields, heap);
/* Save the old search mode of the cursor */
old_mode = cursor->search_mode;
......@@ -287,7 +307,10 @@ btr_pcur_restore_position(
if (cursor->rel_pos == BTR_PCUR_ON
&& btr_pcur_is_on_user_rec(cursor, mtr)
&& 0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor))) {
&& 0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor),
rec_get_offsets(btr_pcur_get_rec(cursor),
btr_pcur_get_btr_cur(cursor)->index,
ULINT_UNDEFINED, heap))) {
/* We have to store the NEW value for the modify clock, since
the cursor can now be on a different page! But we can retain
......@@ -376,6 +399,7 @@ btr_pcur_move_to_next_page(
ut_ad(next_page_no != FIL_NULL);
next_page = btr_page_get(space, next_page_no, cursor->latch_mode, mtr);
ut_a(page_is_comp(next_page) == page_is_comp(page));
buf_block_align(next_page)->check_index_page_at_flush = TRUE;
btr_leaf_page_release(page, cursor->latch_mode, mtr);
......
This diff is collapsed.
......@@ -500,7 +500,7 @@ dtuple_convert_big_rec(
ut_a(dtuple_check_typed_no_assert(entry));
size = rec_get_converted_size(entry);
size = rec_get_converted_size(index, entry);
if (size > 1000000000) {
fprintf(stderr,
......@@ -524,9 +524,10 @@ dtuple_convert_big_rec(
n_fields = 0;
while ((rec_get_converted_size(entry)
>= page_get_free_space_of_empty() / 2)
|| rec_get_converted_size(entry) >= REC_MAX_DATA_SIZE) {
while (rec_get_converted_size(index, entry)
>= ut_min(page_get_free_space_of_empty(
index->table->comp) / 2,
REC_MAX_DATA_SIZE)) {
longest = 0;
for (i = dict_index_get_n_unique_in_tree(index);
......
......@@ -195,7 +195,7 @@ dtype_validate(
ut_a((type->mtype >= DATA_VARCHAR) && (type->mtype <= DATA_MYSQL));
if (type->mtype == DATA_SYS) {
ut_a(type->prtype <= DATA_MIX_ID);
ut_a((type->prtype & DATA_MYSQL_TYPE_MASK) < DATA_N_SYS_COLS);
}
return(TRUE);
......
......@@ -158,7 +158,7 @@ dict_hdr_create(
/*--------------------------*/
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
DICT_HDR_SPACE, DICT_TABLES_ID, mtr);
DICT_HDR_SPACE, DICT_TABLES_ID, FALSE, mtr);
if (root_page_no == FIL_NULL) {
return(FALSE);
......@@ -168,7 +168,7 @@ dict_hdr_create(
MLOG_4BYTES, mtr);
/*--------------------------*/
root_page_no = btr_create(DICT_UNIQUE, DICT_HDR_SPACE,
DICT_TABLE_IDS_ID, mtr);
DICT_TABLE_IDS_ID, FALSE, mtr);
if (root_page_no == FIL_NULL) {
return(FALSE);
......@@ -178,7 +178,7 @@ dict_hdr_create(
MLOG_4BYTES, mtr);
/*--------------------------*/
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
DICT_HDR_SPACE, DICT_COLUMNS_ID, mtr);
DICT_HDR_SPACE, DICT_COLUMNS_ID, FALSE, mtr);
if (root_page_no == FIL_NULL) {
return(FALSE);
......@@ -188,7 +188,7 @@ dict_hdr_create(
MLOG_4BYTES, mtr);
/*--------------------------*/
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
DICT_HDR_SPACE, DICT_INDEXES_ID, mtr);
DICT_HDR_SPACE, DICT_INDEXES_ID, FALSE, mtr);
if (root_page_no == FIL_NULL) {
return(FALSE);
......@@ -198,7 +198,7 @@ dict_hdr_create(
MLOG_4BYTES, mtr);
/*--------------------------*/
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
DICT_HDR_SPACE, DICT_FIELDS_ID, mtr);
DICT_HDR_SPACE, DICT_FIELDS_ID, FALSE, mtr);
if (root_page_no == FIL_NULL) {
return(FALSE);
......@@ -254,7 +254,7 @@ dict_boot(void)
/* Insert into the dictionary cache the descriptions of the basic
system tables */
/*-------------------------*/
table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE,8);
table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8, FALSE);
dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0);
dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0);
......@@ -290,7 +290,7 @@ dict_boot(void)
index->id = DICT_TABLE_IDS_ID;
ut_a(dict_index_add_to_cache(table, index));
/*-------------------------*/
table = dict_mem_table_create("SYS_COLUMNS",DICT_HDR_SPACE,7);
table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, FALSE);
dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY,0,0,0);
dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0);
......@@ -316,7 +316,7 @@ dict_boot(void)
index->id = DICT_COLUMNS_ID;
ut_a(dict_index_add_to_cache(table, index));
/*-------------------------*/
table = dict_mem_table_create("SYS_INDEXES",DICT_HDR_SPACE,7);
table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, FALSE);
dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY, 0,0,0);
dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0);
......@@ -349,7 +349,7 @@ dict_boot(void)
index->id = DICT_INDEXES_ID;
ut_a(dict_index_add_to_cache(table, index));
/*-------------------------*/
table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE,3);
table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, FALSE);
dict_mem_table_add_col(table, "INDEX_ID", DATA_BINARY, 0,0,0);
dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0);
......
......@@ -84,7 +84,8 @@ dict_create_sys_tables_tuple(
dfield = dtuple_get_nth_field(entry, 5);
ptr = mem_heap_alloc(heap, 4);
mach_write_to_4(ptr, table->mix_len);
mach_write_to_4(ptr, (table->mix_len & 0x7fffffff) |
((ulint) table->comp << 31));
dfield_set_data(dfield, ptr, 4);
/* 8: CLUSTER_NAME ---------------------*/
......@@ -624,7 +625,7 @@ dict_create_index_tree_step(
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
index->page_no = btr_create(index->type, index->space, index->id,
&mtr);
table->comp, &mtr);
/* printf("Created a new index tree in space %lu root page %lu\n",
index->space, index->page_no); */
......@@ -660,8 +661,9 @@ dict_drop_index_tree(
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */
ptr = rec_get_nth_field(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len);
ut_a(!dict_sys->sys_indexes->comp);
ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len);
ut_ad(len == 4);
......@@ -673,8 +675,9 @@ dict_drop_index_tree(
return;
}
ptr = rec_get_nth_field(rec, DICT_SYS_INDEXES_SPACE_NO_FIELD, &len);
ptr = rec_get_nth_field_old(rec,
DICT_SYS_INDEXES_SPACE_NO_FIELD, &len);
ut_ad(len == 4);
space = mtr_read_ulint(ptr, MLOG_4BYTES, mtr);
......@@ -699,8 +702,8 @@ dict_drop_index_tree(
root_page_no); */
btr_free_root(space, root_page_no, mtr);
page_rec_write_index_page_no(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD,
FIL_NULL, mtr);
page_rec_write_index_page_no(rec,
DICT_SYS_INDEXES_PAGE_NO_FIELD, FIL_NULL, mtr);
}
/*************************************************************************
......
......@@ -814,23 +814,22 @@ dict_table_add_to_cache(
system columns. */
dict_mem_table_add_col(table, "DB_ROW_ID", DATA_SYS,
DATA_ROW_ID, 0, 0);
DATA_ROW_ID | DATA_NOT_NULL, DATA_ROW_ID_LEN, 0);
#if DATA_ROW_ID != 0
#error "DATA_ROW_ID != 0"
#endif
dict_mem_table_add_col(table, "DB_TRX_ID", DATA_SYS,
DATA_TRX_ID, 0, 0);
DATA_TRX_ID | DATA_NOT_NULL, DATA_TRX_ID_LEN, 0);
#if DATA_TRX_ID != 1
#error "DATA_TRX_ID != 1"
#endif
dict_mem_table_add_col(table, "DB_ROLL_PTR", DATA_SYS,
DATA_ROLL_PTR, 0, 0);
DATA_ROLL_PTR | DATA_NOT_NULL, DATA_ROLL_PTR_LEN, 0);
#if DATA_ROLL_PTR != 2
#error "DATA_ROLL_PTR != 2"
#endif
dict_mem_table_add_col(table, "DB_MIX_ID", DATA_SYS,
DATA_MIX_ID, 0, 0);
DATA_MIX_ID | DATA_NOT_NULL, DATA_MIX_ID_LEN, 0);
#if DATA_MIX_ID != 3
#error "DATA_MIX_ID != 3"
#endif
......@@ -1588,7 +1587,7 @@ dict_index_find_cols(
/***********************************************************************
Adds a column to index. */
UNIV_INLINE
void
dict_index_add_col(
/*===============*/
......@@ -1604,6 +1603,34 @@ dict_index_add_col(
field = dict_index_get_nth_field(index, index->n_def - 1);
field->col = col;
field->fixed_len = dtype_get_fixed_size(&col->type);
if (prefix_len && field->fixed_len > prefix_len) {
field->fixed_len = prefix_len;
}
/* Long fixed-length fields that need external storage are treated as
variable-length fields, so that the extern flag can be embedded in
the length word. */
if (field->fixed_len > DICT_MAX_COL_PREFIX_LEN) {
field->fixed_len = 0;
}
if (!(dtype_get_prtype(&col->type) & DATA_NOT_NULL)) {
index->n_nullable++;
}
if (index->n_def > 1) {
const dict_field_t* field2 =
dict_index_get_nth_field(index, index->n_def - 2);
field->fixed_offs = (!field2->fixed_len ||
field2->fixed_offs == ULINT_UNDEFINED)
? ULINT_UNDEFINED
: field2->fixed_len + field2->fixed_offs;
} else {
field->fixed_offs = 0;
}
}
/***********************************************************************
......@@ -3580,9 +3607,10 @@ dict_tree_find_index_low(
&& (table->type != DICT_TABLE_ORDINARY)) {
/* Get the mix id of the record */
ut_a(!table->comp);
mix_id = mach_dulint_read_compressed(
rec_get_nth_field(rec, table->mix_len, &len));
rec_get_nth_field_old(rec, table->mix_len, &len));
while (ut_dulint_cmp(table->mix_id, mix_id) != 0) {
......@@ -3715,7 +3743,8 @@ dict_tree_build_node_ptr(
on non-leaf levels we remove the last field, which
contains the page number of the child page */
n_unique = rec_get_n_fields(rec);
ut_a(!ind->table->comp);
n_unique = rec_get_n_fields_old(rec);
if (level > 0) {
ut_a(n_unique > 1);
......@@ -3744,9 +3773,11 @@ dict_tree_build_node_ptr(
field = dtuple_get_nth_field(tuple, n_unique);
dfield_set_data(field, buf, 4);
dtype_set(dfield_get_type(field), DATA_SYS_CHILD, 0, 0, 0);
dtype_set(dfield_get_type(field), DATA_SYS_CHILD, DATA_NOT_NULL, 4, 0);
rec_copy_prefix_to_dtuple(tuple, rec, n_unique, heap);
rec_copy_prefix_to_dtuple(tuple, rec, ind, n_unique, heap);
dtuple_set_info_bits(tuple, dtuple_get_info_bits(tuple) |
REC_STATUS_NODE_PTR);
ut_ad(dtuple_check_typed(tuple));
......@@ -3763,27 +3794,26 @@ dict_tree_copy_rec_order_prefix(
/* out: pointer to the prefix record */
dict_tree_t* tree, /* in: index tree */
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 */
{
dict_index_t* ind;
rec_t* order_rec;
ulint n_fields;
ind = dict_tree_find_index_low(tree, rec);
dict_index_t* index;
ulint n;
n_fields = dict_index_get_n_unique_in_tree(ind);
if (tree->type & DICT_UNIVERSAL) {
index = dict_tree_find_index_low(tree, rec);
n_fields = rec_get_n_fields(rec);
if (tree->type & DICT_UNIVERSAL) {
ut_a(!index->table->comp);
n = rec_get_n_fields_old(rec);
} else {
n = dict_index_get_n_unique_in_tree(index);
}
order_rec = rec_copy_prefix_to_buf(rec, n_fields, buf, buf_size);
return(order_rec);
}
*n_fields = n;
return(rec_copy_prefix_to_buf(rec, index, n, buf, buf_size));
}
/**************************************************************************
Builds a typed data tuple out of a physical record. */
......@@ -3794,21 +3824,21 @@ dict_tree_build_data_tuple(
/* out, own: data tuple */
dict_tree_t* tree, /* in: index tree */
rec_t* rec, /* in: record for which to build data tuple */
ulint n_fields,/* in: number of data fields */
mem_heap_t* heap) /* in: memory heap where tuple created */
{
dtuple_t* tuple;
dict_index_t* ind;
ulint n_fields;
ind = dict_tree_find_index_low(tree, rec);
n_fields = rec_get_n_fields(rec);
ut_ad(ind->table->comp || n_fields <= rec_get_n_fields_old(rec));
tuple = dtuple_create(heap, n_fields);
dict_index_copy_types(tuple, ind, n_fields);
rec_copy_prefix_to_dtuple(tuple, rec, n_fields, heap);
rec_copy_prefix_to_dtuple(tuple, rec, ind, n_fields, heap);
ut_ad(dtuple_check_typed(tuple));
......@@ -3826,6 +3856,27 @@ dict_index_calc_min_rec_len(
ulint sum = 0;
ulint i;
if (index->table->comp) {
ulint nullable = 0;
sum = REC_N_NEW_EXTRA_BYTES;
for (i = 0; i < dict_index_get_n_fields(index); i++) {
dtype_t*t = dict_index_get_nth_type(index, i);
ulint size = dtype_get_fixed_size(t);
sum += size;
if (!size) {
size = dtype_get_len(t);
sum += size < 128 ? 1 : 2;
}
if (!(dtype_get_prtype(t) & DATA_NOT_NULL))
nullable++;
}
/* round the NULL flags up to full bytes */
sum += (nullable + 7) / 8;
return(sum);
}
for (i = 0; i < dict_index_get_n_fields(index); i++) {
sum += dtype_get_fixed_size(dict_index_get_nth_type(index, i));
}
......@@ -3836,7 +3887,7 @@ dict_index_calc_min_rec_len(
sum += dict_index_get_n_fields(index);
}
sum += REC_N_EXTRA_BYTES;
sum += REC_N_OLD_EXTRA_BYTES;
return(sum);
}
......
This diff is collapsed.
......@@ -35,7 +35,8 @@ dict_mem_table_create(
the table is placed; this parameter is
ignored if the table is made a member of
a cluster */
ulint n_cols) /* in: number of columns */
ulint n_cols, /* in: number of columns */
ibool comp) /* in: TRUE=compact page format */
{
dict_table_t* table;
mem_heap_t* heap;
......@@ -54,6 +55,7 @@ dict_mem_table_create(
table->space = space;
table->ibd_file_missing = FALSE;
table->tablespace_discarded = FALSE;
table->comp = comp;
table->n_def = 0;
table->n_cols = n_cols + DATA_N_SYS_COLS;
table->mem_fix = 0;
......@@ -110,7 +112,8 @@ dict_mem_cluster_create(
{
dict_table_t* cluster;
cluster = dict_mem_table_create(name, space, n_cols);
/* Clustered tables cannot work with the compact record format. */
cluster = dict_mem_table_create(name, space, n_cols, FALSE);
cluster->type = DICT_TABLE_CLUSTER;
cluster->mix_len = mix_len;
......@@ -197,7 +200,7 @@ dict_mem_index_create(
index->name = mem_heap_strdup(heap, index_name);
index->table_name = table_name;
index->table = NULL;
index->n_def = 0;
index->n_def = index->n_nullable = 0;
index->n_fields = n_fields;
index->fields = mem_heap_alloc(heap, 1 + n_fields
* sizeof(dict_field_t));
......
......@@ -1579,30 +1579,38 @@ fil_op_write_log(
mtr_t* mtr) /* in: mini-transaction handle */
{
byte* log_ptr;
ulint len;
log_ptr = mlog_open(mtr, 11 + 2);
if (!log_ptr) {
/* Logging in mtr is switched off during crash recovery:
in that case mlog_open returns NULL */
return;
}
log_ptr = mlog_open(mtr, 30);
log_ptr = mlog_write_initial_log_record_for_file_op(type, space_id, 0,
log_ptr, mtr);
/* Let us store the strings as null-terminated for easier readability
and handling */
mach_write_to_2(log_ptr, ut_strlen(name) + 1);
len = strlen(name) + 1;
mach_write_to_2(log_ptr, len);
log_ptr += 2;
mlog_close(mtr, log_ptr);
mlog_catenate_string(mtr, (byte*) name, ut_strlen(name) + 1);
mlog_catenate_string(mtr, (byte*) name, len);
if (type == MLOG_FILE_RENAME) {
log_ptr = mlog_open(mtr, 30);
mach_write_to_2(log_ptr, ut_strlen(new_name) + 1);
ulint len = strlen(new_name) + 1;
log_ptr = mlog_open(mtr, 2 + len);
ut_a(log_ptr);
mach_write_to_2(log_ptr, len);
log_ptr += 2;
mlog_close(mtr, log_ptr);
mlog_catenate_string(mtr, (byte*) new_name,
ut_strlen(new_name) + 1);
mlog_catenate_string(mtr, (byte*) new_name, len);
}
}
#endif
......
......@@ -910,7 +910,7 @@ fsp_header_init(
if (space == 0) {
fsp_fill_free_list(FALSE, space, header, mtr);
btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, space,
ut_dulint_add(DICT_IBUF_ID_MIN, space), mtr);
ut_dulint_add(DICT_IBUF_ID_MIN, space), FALSE, mtr);
} else {
fsp_fill_free_list(TRUE, space, header, mtr);
}
......
This diff is collapsed.
......@@ -155,7 +155,8 @@ ulint
btr_node_ptr_get_child_page_no(
/*===========================*/
/* out: child node address */
rec_t* rec); /* in: node pointer record */
rec_t* rec, /* in: node pointer record */
const ulint* offsets);/* in: array returned by rec_get_offsets() */
/****************************************************************
Creates the root node for a new index tree. */
......@@ -167,6 +168,7 @@ btr_create(
ulint type, /* in: type of the index */
ulint space, /* in: space where created */
dulint index_id,/* in: index id */
ibool comp, /* in: TRUE=compact page format */
mtr_t* mtr); /* in: mini-transaction handle */
/****************************************************************
Frees a B-tree except the root page, which MUST be freed after this
......@@ -210,8 +212,9 @@ Reorganizes an index page. */
void
btr_page_reorganize(
/*================*/
page_t* page, /* in: page to be reorganized */
mtr_t* mtr); /* in: mtr */
page_t* page, /* in: page to be reorganized */
dict_index_t* index, /* in: record descriptor */
mtr_t* mtr); /* in: mtr */
/*****************************************************************
Decides if the page should be split at the convergence point of
inserts converging to left. */
......@@ -273,6 +276,7 @@ void
btr_set_min_rec_mark(
/*=================*/
rec_t* rec, /* in: record */
ibool comp, /* in: TRUE=compact page format */
mtr_t* mtr); /* in: mtr */
/*****************************************************************
Deletes on the upper level the node pointer to a page. */
......@@ -332,6 +336,7 @@ btr_parse_set_min_rec_mark(
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
byte* end_ptr,/* in: buffer end */
ibool comp, /* in: TRUE=compact page format */
page_t* page, /* in: page or NULL */
mtr_t* mtr); /* in: mtr or NULL */
/***************************************************************
......@@ -340,11 +345,12 @@ Parses a redo log record of reorganizing a page. */
byte*
btr_parse_page_reorganize(
/*======================*/
/* out: end of log record or NULL */
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* 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 */
/******************************************************************
Gets the number of pages in a B-tree. */
......
......@@ -183,17 +183,18 @@ ulint
btr_node_ptr_get_child_page_no(
/*===========================*/
/* out: child node address */
rec_t* rec) /* in: node pointer record */
rec_t* rec, /* in: node pointer record */
const ulint* offsets)/* in: array returned by rec_get_offsets() */
{
ulint n_fields;
byte* field;
ulint len;
ulint page_no;
n_fields = rec_get_n_fields(rec);
ut_ad(!rec_offs_comp(offsets) || rec_get_node_ptr_flag(rec));
/* The child address is in the last field */
field = rec_get_nth_field(rec, n_fields - 1, &len);
field = rec_get_nth_field(rec, offsets,
rec_offs_n_fields(offsets) - 1, &len);
ut_ad(len == 4);
......
......@@ -34,7 +34,7 @@ page_cur_t*
btr_cur_get_page_cur(
/*=================*/
/* out: pointer to page cursor component */
btr_cur_t* cursor); /* in: tree cursor */
btr_cur_t* cursor);/* in: tree cursor */
/*************************************************************
Returns the record pointer of a tree cursor. */
UNIV_INLINE
......@@ -42,14 +42,14 @@ rec_t*
btr_cur_get_rec(
/*============*/
/* out: pointer to record */
btr_cur_t* cursor); /* in: tree cursor */
btr_cur_t* cursor);/* in: tree cursor */
/*************************************************************
Invalidates a tree cursor by setting record pointer to NULL. */
UNIV_INLINE
void
btr_cur_invalidate(
/*===============*/
btr_cur_t* cursor); /* in: tree cursor */
btr_cur_t* cursor);/* in: tree cursor */
/*************************************************************
Returns the page of a tree cursor. */
UNIV_INLINE
......@@ -57,7 +57,7 @@ page_t*
btr_cur_get_page(
/*=============*/
/* out: pointer to page */
btr_cur_t* cursor); /* in: tree cursor */
btr_cur_t* cursor);/* in: tree cursor */
/*************************************************************
Returns the tree of a cursor. */
UNIV_INLINE
......@@ -65,7 +65,7 @@ dict_tree_t*
btr_cur_get_tree(
/*=============*/
/* out: tree */
btr_cur_t* cursor); /* in: tree cursor */
btr_cur_t* cursor);/* in: tree cursor */
/*************************************************************
Positions a tree cursor at a given record. */
UNIV_INLINE
......@@ -283,8 +283,9 @@ only used by the insert buffer insert merge mechanism. */
void
btr_cur_del_unmark_for_ibuf(
/*========================*/
rec_t* rec, /* in: record to delete unmark */
mtr_t* mtr); /* in: mtr */
rec_t* rec, /* in: record to delete unmark */
dict_index_t* index, /* in: record descriptor */
mtr_t* mtr); /* in: mtr */
/*****************************************************************
Tries to compress a page of the tree on the leaf level. It is assumed
that mtr holds an x-latch on the tree and on the cursor page. To avoid
......@@ -361,10 +362,11 @@ Parses a redo log record of updating a record in-place. */
byte*
btr_cur_parse_update_in_place(
/*==========================*/
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
byte* end_ptr,/* in: buffer end */
page_t* page); /* in: page or NULL */
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
byte* end_ptr,/* in: buffer end */
page_t* page, /* in: page or NULL */
dict_index_t* index); /* in: index corresponding to page */
/********************************************************************
Parses the redo log record for delete marking or unmarking of a clustered
index record. */
......@@ -372,10 +374,11 @@ index record. */
byte*
btr_cur_parse_del_mark_set_clust_rec(
/*=================================*/
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
byte* end_ptr,/* in: buffer end */
page_t* page); /* in: page or NULL */
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
byte* end_ptr,/* in: buffer end */
dict_index_t* index, /* in: index corresponding to page */
page_t* page); /* in: page or NULL */
/********************************************************************
Parses the redo log record for delete marking or unmarking of a secondary
index record. */
......@@ -383,10 +386,11 @@ index record. */
byte*
btr_cur_parse_del_mark_set_sec_rec(
/*===============================*/
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
byte* end_ptr,/* in: buffer end */
page_t* page); /* in: page or NULL */
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
byte* end_ptr,/* in: buffer end */
dict_index_t* index, /* in: index corresponding to page */
page_t* page); /* in: page or NULL */
/***********************************************************************
Estimates the number of rows in a given index range. */
......@@ -417,9 +421,10 @@ to free the field. */
void
btr_cur_mark_extern_inherited_fields(
/*=================================*/
rec_t* rec, /* in: record in a clustered index */
upd_t* update, /* in: update vector */
mtr_t* mtr); /* in: mtr */
rec_t* rec, /* in: record in a clustered index */
const ulint* offsets,/* in: array returned by rec_get_offsets() */
upd_t* update, /* in: update vector */
mtr_t* mtr); /* in: mtr */
/***********************************************************************
The complement of the previous function: in an update entry may inherit
some externally stored fields from a record. We must mark them as inherited
......@@ -456,6 +461,7 @@ btr_store_big_rec_extern_fields(
dict_index_t* index, /* in: index of rec; the index tree
MUST be X-latched */
rec_t* rec, /* in: record */
const ulint* offsets, /* in: rec_get_offsets(rec, index) */
big_rec_t* big_rec_vec, /* in: vector containing fields
to be stored externally */
mtr_t* local_mtr); /* in: mtr containing the latch to
......@@ -496,6 +502,7 @@ btr_rec_free_externally_stored_fields(
dict_index_t* index, /* in: index of the data, the index
tree MUST be X-latched */
rec_t* rec, /* in: record */
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
ibool do_not_free_inherited,/* in: TRUE if called in a
rollback and we do not want to free
inherited fields */
......@@ -510,6 +517,7 @@ btr_rec_copy_externally_stored_field(
/*=================================*/
/* out: the field copied to heap */
rec_t* rec, /* in: record */
const ulint* offsets,/* in: array returned by rec_get_offsets() */
ulint no, /* in: field number */
ulint* len, /* out: length of the field */
mem_heap_t* heap); /* in: mem heap */
......@@ -540,10 +548,10 @@ ulint
btr_push_update_extern_fields(
/*==========================*/
/* out: number of values stored in ext_vect */
ulint* ext_vect, /* in: array of ulints, must be preallocated
to have place for all fields in rec */
rec_t* rec, /* in: record */
upd_t* update); /* in: update vector */
ulint* ext_vect,/* in: array of ulints, must be preallocated
to have space for all fields in rec */
const ulint* offsets,/* in: array returned by rec_get_offsets() */
upd_t* update);/* in: update vector or NULL */
/*######################################################################*/
......
......@@ -134,17 +134,15 @@ btr_cur_can_delete_without_compress(
/* out: TRUE if can be deleted without
recommended compression */
btr_cur_t* cursor, /* in: btr cursor */
ulint rec_size,/* in: rec_get_size(btr_cur_get_rec(cursor))*/
mtr_t* mtr) /* in: mtr */
{
ulint rec_size;
page_t* page;
ut_ad(mtr_memo_contains(mtr, buf_block_align(
btr_cur_get_page(cursor)),
MTR_MEMO_PAGE_X_FIX));
rec_size = rec_get_size(btr_cur_get_rec(cursor));
page = btr_cur_get_page(cursor);
if ((page_get_data_size(page) - rec_size < BTR_CUR_PAGE_COMPRESS_LIMIT)
......
......@@ -462,6 +462,7 @@ struct btr_pcur_struct{
contains an initial segment of the
latest record cursor was positioned
either on, before, or after */
ulint old_n_fields; /* number of fields in old_rec */
ulint rel_pos; /* BTR_PCUR_ON, BTR_PCUR_BEFORE, or
BTR_PCUR_AFTER, depending on whether
cursor was on, before, or after the
......
......@@ -77,8 +77,10 @@ parameters as page (this often happens when a page is split). */
void
btr_search_move_or_delete_hash_entries(
/*===================================*/
page_t* new_page, /* in: records are copied to this page */
page_t* page); /* in: index page */
page_t* new_page, /* in: records are copied
to this page */
page_t* page, /* in: index page */
dict_index_t* index); /* in: record descriptor */
/************************************************************************
Drops a page hash index. */
......@@ -128,9 +130,10 @@ btr_search_update_hash_on_delete(
Validates the search system. */
ibool
btr_search_validate(void);
/*=====================*/
btr_search_validate(
/*================*/
/* out: TRUE if ok */
dict_index_t* index); /* in: record descriptor */
/* Search info directions */
#define BTR_SEA_NO_DIRECTION 1
......
......@@ -149,8 +149,10 @@ dtype_new_store_for_order_and_null_size(
bytes where we store the info */
dtype_t* type) /* in: type struct */
{
ut_ad(6 == DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
#if 6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
#error "6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE"
#endif
buf[0] = (byte)(type->mtype & 0xFFUL);
if (type->prtype & DATA_BINARY_TYPE) {
......@@ -166,10 +168,12 @@ dtype_new_store_for_order_and_null_size(
mach_write_to_2(buf + 2, type->len & 0xFFFFUL);
ut_ad(dtype_get_charset_coll(type->prtype) < 256);
mach_write_to_2(buf + 4, dtype_get_charset_coll(type->prtype));
/* Note that the second last byte is left unused, because the
charset-collation code is always < 256 */
if (type->prtype & DATA_NOT_NULL) {
buf[4] |= 128;
}
}
/**************************************************************************
......@@ -211,20 +215,26 @@ dtype_new_read_for_order_and_null_size(
{
ulint charset_coll;
ut_ad(6 == DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
#if 6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
#error "6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE"
#endif
type->mtype = buf[0] & 63;
type->prtype = buf[1];
if (buf[0] & 128) {
type->prtype = type->prtype | DATA_BINARY_TYPE;
type->prtype |= DATA_BINARY_TYPE;
}
if (buf[4] & 128) {
type->prtype |= DATA_NOT_NULL;
}
type->len = mach_read_from_2(buf + 2);
mach_read_from_2(buf + 4);
charset_coll = mach_read_from_2(buf + 4);
charset_coll = mach_read_from_2(buf + 4) & 0x7fff;
if (dtype_is_string_type(type->mtype)) {
ut_a(charset_coll < 256);
......@@ -257,6 +267,26 @@ dtype_get_fixed_size(
mtype = dtype_get_mtype(type);
switch (mtype) {
case DATA_SYS:
#ifdef UNIV_DEBUG
switch (type->prtype & DATA_MYSQL_TYPE_MASK) {
default:
ut_ad(0);
return(0);
case DATA_ROW_ID:
ut_ad(type->len == DATA_ROW_ID_LEN);
break;
case DATA_TRX_ID:
ut_ad(type->len == DATA_TRX_ID_LEN);
break;
case DATA_ROLL_PTR:
ut_ad(type->len == DATA_ROLL_PTR_LEN);
break;
case DATA_MIX_ID:
ut_ad(type->len == DATA_MIX_ID_LEN);
break;
}
#endif /* UNIV_DEBUG */
case DATA_CHAR:
case DATA_FIXBINARY:
case DATA_INT:
......@@ -264,16 +294,6 @@ dtype_get_fixed_size(
case DATA_DOUBLE:
case DATA_MYSQL:
return(dtype_get_len(type));
case DATA_SYS: if (type->prtype == DATA_ROW_ID) {
return(DATA_ROW_ID_LEN);
} else if (type->prtype == DATA_TRX_ID) {
return(DATA_TRX_ID_LEN);
} else if (type->prtype == DATA_ROLL_PTR) {
return(DATA_ROLL_PTR_LEN);
} else {
return(0);
}
case DATA_VARCHAR:
case DATA_BINARY:
case DATA_DECIMAL:
......
......@@ -639,6 +639,16 @@ dict_index_get_sys_col_pos(
dict_index_t* index, /* in: index */
ulint type); /* in: DATA_ROW_ID, ... */
/***********************************************************************
Adds a column to index. */
void
dict_index_add_col(
/*===============*/
dict_index_t* index, /* in: index */
dict_col_t* col, /* in: column */
ulint order, /* in: order criterion */
ulint prefix_len); /* in: column prefix length */
/***********************************************************************
Copies types of fields contained in index to tuple. */
void
......@@ -657,6 +667,7 @@ dict_index_rec_get_sys_col(
/*=======================*/
/* out: system column value */
dict_index_t* index, /* in: clustered index describing the record */
const ulint* offsets,/* in: offsets returned by rec_get_offsets() */
ulint type, /* in: column type: DATA_ROLL_PTR, ... */
rec_t* rec); /* in: record */
/*************************************************************************
......@@ -770,6 +781,7 @@ dict_tree_copy_rec_order_prefix(
/* out: pointer to the prefix record */
dict_tree_t* tree, /* in: index tree */
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 */
......@@ -782,6 +794,7 @@ dict_tree_build_data_tuple(
/* out, own: data tuple */
dict_tree_t* tree, /* in: index tree */
rec_t* rec, /* in: record for which to build data tuple */
ulint n_fields,/* in: number of data fields */
mem_heap_t* heap); /* in: memory heap where tuple created */
/*************************************************************************
Gets the space id of the root of the index tree. */
......
......@@ -168,7 +168,7 @@ dict_table_get_sys_col(
col = dict_table_get_nth_col(table, table->n_cols
- DATA_N_SYS_COLS + sys);
ut_ad(col->type.mtype == DATA_SYS);
ut_ad(col->type.prtype == sys);
ut_ad(col->type.prtype == (sys | DATA_NOT_NULL));
return(col);
}
......@@ -322,6 +322,7 @@ dict_index_rec_get_sys_col(
/*=======================*/
/* out: system column value */
dict_index_t* index, /* in: clustered index describing the record */
const ulint* offsets,/* in: offsets returned by rec_get_offsets() */
ulint type, /* in: column type: DATA_ROLL_PTR, ... */
rec_t* rec) /* in: record */
{
......@@ -331,12 +332,13 @@ dict_index_rec_get_sys_col(
ut_ad(index);
ut_ad(index->type & DICT_CLUSTERED);
ut_ad(rec_offs_validate(rec, index, offsets));
pos = dict_index_get_sys_col_pos(index, type);
ut_ad(pos != ULINT_UNDEFINED);
field = rec_get_nth_field(rec, pos, &len);
field = rec_get_nth_field(rec, offsets, pos, &len);
if (type == DATA_ROLL_PTR) {
ut_ad(len == 7);
......@@ -677,7 +679,10 @@ dict_is_mixed_table_rec(
byte* mix_id_field;
ulint len;
mix_id_field = rec_get_nth_field(rec, table->mix_len, &len);
ut_ad(!table->comp);
mix_id_field = rec_get_nth_field_old(rec,
table->mix_len, &len);
if ((len != table->mix_id_len)
|| (0 != ut_memcmp(table->mix_id_buf, mix_id_field, len))) {
......
......@@ -54,7 +54,8 @@ dict_mem_table_create(
of the table is placed; this parameter
is ignored if the table is made
a member of a cluster */
ulint n_cols); /* in: number of columns */
ulint n_cols, /* in: number of columns */
ibool comp); /* in: TRUE=compact page format */
/**************************************************************************
Creates a cluster memory object. */
......@@ -171,6 +172,13 @@ struct dict_field_struct{
DICT_MAX_COL_PREFIX_LEN; NOTE that
in the UTF-8 charset, MySQL sets this
to 3 * the prefix len in UTF-8 chars */
ulint fixed_len; /* 0 or the fixed length of the
column if smaller than
DICT_MAX_COL_PREFIX_LEN */
ulint fixed_offs; /* offset to the field, or
ULINT_UNDEFINED if it is not fixed
within the record (due to preceding
variable-length fields) */
};
/* Data structure for an index tree */
......@@ -225,6 +233,7 @@ struct dict_index_struct{
ulint n_def; /* number of fields defined so far */
ulint n_fields;/* number of fields in the index */
dict_field_t* fields; /* array of field descriptions */
ulint n_nullable;/* number of nullable fields */
UT_LIST_NODE_T(dict_index_t)
indexes;/* list of indexes of the table */
dict_tree_t* tree; /* index tree struct */
......@@ -320,6 +329,7 @@ struct dict_table_struct{
ibool tablespace_discarded;/* this flag is set TRUE when the
user calls DISCARD TABLESPACE on this table,
and reset to FALSE in IMPORT TABLESPACE */
ibool comp; /* flag: TRUE=compact page format */
hash_node_t name_hash; /* hash chain node */
hash_node_t id_hash; /* hash chain node */
ulint n_def; /* number of columns defined so far */
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -246,6 +246,7 @@ trx_undo_prev_version_build(
index_rec page and purge_view */
rec_t* rec, /* in: version of a clustered index record */
dict_index_t* index, /* in: clustered index */
ulint* offsets,/* in: rec_get_offsets(rec, index) */
mem_heap_t* heap, /* in: memory heap from which the memory
needed is allocated */
rec_t** old_vers);/* out, own: previous version, or NULL if
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment