Commit 39788439 authored by marko's avatar marko

branches/zip: Fix a bug in fast index creation that was introduced in r2131

when row_build() was changed to prefetch all externally stored column
prefixes that occur in ordering fields of an index.

row_build(): Add the parameter col_table for determining which
externally stored columns need to be fetched.

row_merge_read_clustered_index(): Pass new_table as the said parameter,
so that newly added indexes containing column prefix indexes of externally
stored columns will work.
parent 71cf1edf
...@@ -77,27 +77,42 @@ record in a clustered index. */ ...@@ -77,27 +77,42 @@ record in a clustered index. */
dtuple_t* dtuple_t*
row_build( row_build(
/*======*/ /*======*/
/* out, own: row built; see the NOTE below! */ /* out, own: row built;
ulint type, /* in: ROW_COPY_POINTERS or ROW_COPY_DATA; see the NOTE below! */
the latter copies also the data fields to ulint type, /* in: ROW_COPY_POINTERS or
heap while the first only places pointers to ROW_COPY_DATA; the latter
data fields on the index page, and thus is copies also the data fields to
more efficient */ heap while the first only
dict_index_t* index, /* in: clustered index */ places pointers to data fields
const rec_t* rec, /* in: record in the clustered index; on the index page, and thus is
NOTE: in the case ROW_COPY_POINTERS more efficient */
the data fields in the row will point const dict_index_t* index, /* in: clustered index */
directly into this record, therefore, const rec_t* rec, /* in: record in the clustered
the buffer page of this record must be index; NOTE: in the case
at least s-latched and the latch held ROW_COPY_POINTERS the data
as long as the row dtuple is used! */ fields in the row will point
const ulint* offsets,/* in: rec_get_offsets(rec, index) directly into this record,
or NULL, in which case this function therefore, the buffer page of
will invoke rec_get_offsets() */ this record must be at least
row_ext_t** ext, /* out, own: cache of externally stored s-latched and the latch held
column prefixes, or NULL */ as long as the row dtuple is used! */
mem_heap_t* heap); /* in: memory heap from which the memory const ulint* offsets,/* in: rec_get_offsets(rec,index)
needed is allocated */ or NULL, in which case this function
will invoke rec_get_offsets() */
const dict_table_t* col_table,
/* in: table, to check which
externally stored columns
occur in the ordering columns
of an index, or NULL if
index->table should be
consulted instead; the user
columns in this table should be
the same columns as in index->table */
row_ext_t** ext, /* out, own: cache of
externally stored column
prefixes, or NULL */
mem_heap_t* heap); /* in: memory heap from which
the memory needed is allocated */
/*********************************************************************** /***********************************************************************
Converts an index record to a typed data tuple. */ Converts an index record to a typed data tuple. */
......
...@@ -1154,7 +1154,8 @@ row_merge_read_clustered_index( ...@@ -1154,7 +1154,8 @@ row_merge_read_clustered_index(
/* Build a row based on the clustered index. */ /* Build a row based on the clustered index. */
row = row_build(ROW_COPY_POINTERS, clust_index, row = row_build(ROW_COPY_POINTERS, clust_index,
rec, offsets, &ext, row_heap); rec, offsets,
new_table, &ext, row_heap);
if (UNIV_LIKELY_NULL(nonnull)) { if (UNIV_LIKELY_NULL(nonnull)) {
for (i = 0; i < n_nonnull; i++) { for (i = 0; i < n_nonnull; i++) {
......
...@@ -153,40 +153,53 @@ record in a clustered index. */ ...@@ -153,40 +153,53 @@ record in a clustered index. */
dtuple_t* dtuple_t*
row_build( row_build(
/*======*/ /*======*/
/* out, own: row built; see the NOTE below! */ /* out, own: row built;
ulint type, /* in: ROW_COPY_POINTERS or ROW_COPY_DATA; see the NOTE below! */
the latter copies also the data fields to ulint type, /* in: ROW_COPY_POINTERS or
heap while the first only places pointers to ROW_COPY_DATA; the latter
data fields on the index page, and thus is copies also the data fields to
more efficient */ heap while the first only
dict_index_t* index, /* in: clustered index */ places pointers to data fields
const rec_t* rec, /* in: record in the clustered index; on the index page, and thus is
NOTE: in the case ROW_COPY_POINTERS more efficient */
the data fields in the row will point const dict_index_t* index, /* in: clustered index */
directly into this record, therefore, const rec_t* rec, /* in: record in the clustered
the buffer page of this record must be index; NOTE: in the case
at least s-latched and the latch held ROW_COPY_POINTERS the data
as long as the row dtuple is used! */ fields in the row will point
const ulint* offsets,/* in: rec_get_offsets(rec, index) directly into this record,
or NULL, in which case this function therefore, the buffer page of
will invoke rec_get_offsets() */ this record must be at least
row_ext_t** ext, /* out, own: cache of externally stored s-latched and the latch held
column prefixes, or NULL */ as long as the row dtuple is used! */
mem_heap_t* heap) /* in: memory heap from which the memory const ulint* offsets,/* in: rec_get_offsets(rec,index)
needed is allocated */ or NULL, in which case this function
will invoke rec_get_offsets() */
const dict_table_t* col_table,
/* in: table, to check which
externally stored columns
occur in the ordering columns
of an index, or NULL if
index->table should be
consulted instead */
row_ext_t** ext, /* out, own: cache of
externally stored column
prefixes, or NULL */
mem_heap_t* heap) /* in: memory heap from which
the memory needed is allocated */
{ {
dtuple_t* row; dtuple_t* row;
dict_table_t* table; const dict_table_t* table;
ulint n_fields; ulint n_fields;
ulint n_ext_cols; ulint n_ext_cols;
ulint* ext_cols = NULL; /* remove bogus warning */ ulint* ext_cols = NULL; /* remove warning */
ulint len; ulint len;
ulint row_len; ulint row_len;
byte* buf; byte* buf;
ulint i; ulint i;
ulint j; ulint j;
mem_heap_t* tmp_heap = NULL; mem_heap_t* tmp_heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs_init(offsets_); rec_offs_init(offsets_);
ut_ad(index && rec && heap); ut_ad(index && rec && heap);
...@@ -243,6 +256,14 @@ row_build( ...@@ -243,6 +256,14 @@ row_build(
if (rec_offs_nth_extern(offsets, i)) { if (rec_offs_nth_extern(offsets, i)) {
dfield_set_ext(dfield); dfield_set_ext(dfield);
if (UNIV_LIKELY_NULL(col_table)) {
ut_a(col_no
< dict_table_get_n_cols(col_table));
col = dict_table_get_nth_col(
col_table, col_no);
}
if (col->ord_part) { if (col->ord_part) {
/* We will have to fetch prefixes of /* We will have to fetch prefixes of
externally stored columns that are externally stored columns that are
......
...@@ -184,7 +184,7 @@ row_undo_search_clust_to_pcur( ...@@ -184,7 +184,7 @@ row_undo_search_clust_to_pcur(
ret = FALSE; ret = FALSE;
} else { } else {
node->row = row_build(ROW_COPY_DATA, clust_index, rec, node->row = row_build(ROW_COPY_DATA, clust_index, rec,
offsets, &node->ext, node->heap); offsets, NULL, &node->ext, node->heap);
btr_pcur_store_position(&(node->pcur), &mtr); btr_pcur_store_position(&(node->pcur), &mtr);
ret = TRUE; ret = TRUE;
......
...@@ -1332,7 +1332,7 @@ row_upd_store_row( ...@@ -1332,7 +1332,7 @@ row_upd_store_row(
offsets = rec_get_offsets(rec, clust_index, offsets_, offsets = rec_get_offsets(rec, clust_index, offsets_,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
node->row = row_build(ROW_COPY_DATA, clust_index, rec, offsets, node->row = row_build(ROW_COPY_DATA, clust_index, rec, offsets,
&node->ext, node->heap); NULL, &node->ext, node->heap);
if (UNIV_LIKELY_NULL(node->ext)) { if (UNIV_LIKELY_NULL(node->ext)) {
node->n_ext = node->ext->n_ext; node->n_ext = node->ext->n_ext;
} else { } else {
......
...@@ -165,7 +165,7 @@ row_vers_impl_x_locked_off_kernel( ...@@ -165,7 +165,7 @@ row_vers_impl_x_locked_off_kernel(
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
row = row_build(ROW_COPY_POINTERS, clust_index, row = row_build(ROW_COPY_POINTERS, clust_index,
prev_version, clust_offsets, prev_version, clust_offsets,
&ext, heap); NULL, &ext, heap);
entry = row_build_index_entry(row, ext, index, heap); entry = row_build_index_entry(row, ext, index, heap);
/* entry may be NULL if a record was inserted /* entry may be NULL if a record was inserted
in place of a deleted record, and the BLOB in place of a deleted record, and the BLOB
...@@ -340,7 +340,7 @@ row_vers_old_has_index_entry( ...@@ -340,7 +340,7 @@ row_vers_old_has_index_entry(
row_ext_t* ext; row_ext_t* ext;
row = row_build(ROW_COPY_POINTERS, clust_index, row = row_build(ROW_COPY_POINTERS, clust_index,
rec, clust_offsets, &ext, heap); rec, clust_offsets, NULL, &ext, heap);
entry = row_build_index_entry(row, ext, index, heap); entry = row_build_index_entry(row, ext, index, heap);
/* If entry == NULL, the record contains unset BLOB /* If entry == NULL, the record contains unset BLOB
...@@ -398,7 +398,7 @@ row_vers_old_has_index_entry( ...@@ -398,7 +398,7 @@ row_vers_old_has_index_entry(
row = row_build(ROW_COPY_POINTERS, clust_index, row = row_build(ROW_COPY_POINTERS, clust_index,
prev_version, clust_offsets, prev_version, clust_offsets,
&ext, heap); NULL, &ext, heap);
entry = row_build_index_entry(row, ext, index, heap); entry = row_build_index_entry(row, ext, index, heap);
/* If entry == NULL, the record contains unset /* If entry == NULL, the record contains unset
......
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