mirror of
https://github.com/MariaDB/server.git
synced 2025-12-13 20:03:16 +03:00
branches/zip: Clarify why certain calls of
btr_rec_copy_externally_stored_field() are safe. row_merge_copy_blobs(): Note that the table is locked during index creation. Therefore, none of its BLOBs can be freed. row_sel_fetch_columns(): Note that rec must be protected by a page latch. Add const qualifier to rec. row_sel_get_clust_rec(): Note that the clustered index record is protected by a page latch that was acquired when the persistent cursor was positioned and that the latch will be freed by mini-transaction commit. row_sel_try_search_shortcut(): Check the delete-mark flag before fetching the columns. Note that the clustered index record is protected by a page latch that was acquired when the persistent cursor was positioned and that the latch will be freed by mini-transaction commit. row_sel(), row_search_for_mysql(): Note that the clustered index record is protected by a page latch that was acquired when the persistent cursor was positioned and that the latch will be freed by mini-transaction commit. row_sel_field_store_in_mysql_format(): Add const qualifier to data. row_sel_store_mysql_rec(), row_sel_push_cache_row_for_mysql(): Add const qualifier to rec. Note that rec must be protected by a page latch.
This commit is contained in:
@@ -1511,6 +1511,11 @@ row_merge_copy_blobs(
|
|||||||
|
|
||||||
ut_ad(!dfield_is_null(field));
|
ut_ad(!dfield_is_null(field));
|
||||||
|
|
||||||
|
/* The table is locked during index creation.
|
||||||
|
Therefore, externally stored columns cannot possibly
|
||||||
|
be freed between the time the BLOB pointers are read
|
||||||
|
(row_merge_read_clustered_index()) and dereferenced
|
||||||
|
(below). */
|
||||||
data = btr_rec_copy_externally_stored_field(
|
data = btr_rec_copy_externally_stored_field(
|
||||||
mrec, offsets, zip_size, i, &len, heap);
|
mrec, offsets, zip_size, i, &len, heap);
|
||||||
|
|
||||||
|
|||||||
@@ -344,8 +344,8 @@ void
|
|||||||
row_sel_fetch_columns(
|
row_sel_fetch_columns(
|
||||||
/*==================*/
|
/*==================*/
|
||||||
dict_index_t* index, /* in: record index */
|
dict_index_t* index, /* in: record index */
|
||||||
rec_t* rec, /* in: record in a clustered or non-clustered
|
const rec_t* rec, /* in: record in a clustered or non-clustered
|
||||||
index */
|
index; must be protected by a page latch */
|
||||||
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
|
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
|
||||||
sym_node_t* column) /* in: first column in a column list, or
|
sym_node_t* column) /* in: first column in a column list, or
|
||||||
NULL */
|
NULL */
|
||||||
@@ -353,7 +353,7 @@ row_sel_fetch_columns(
|
|||||||
dfield_t* val;
|
dfield_t* val;
|
||||||
ulint index_type;
|
ulint index_type;
|
||||||
ulint field_no;
|
ulint field_no;
|
||||||
byte* data;
|
const byte* data;
|
||||||
ulint len;
|
ulint len;
|
||||||
|
|
||||||
ut_ad(rec_offs_validate(rec, index, offsets));
|
ut_ad(rec_offs_validate(rec, index, offsets));
|
||||||
@@ -879,7 +879,10 @@ row_sel_get_clust_rec(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fetch the columns needed in test conditions */
|
/* Fetch the columns needed in test conditions. The clustered
|
||||||
|
index record is protected by a page latch that was acquired
|
||||||
|
when plan->clust_pcur was positioned. The latch will not be
|
||||||
|
released until mtr_commit(mtr). */
|
||||||
|
|
||||||
row_sel_fetch_columns(index, clust_rec, offsets,
|
row_sel_fetch_columns(index, clust_rec, offsets,
|
||||||
UT_LIST_GET_FIRST(plan->columns));
|
UT_LIST_GET_FIRST(plan->columns));
|
||||||
@@ -1186,10 +1189,7 @@ row_sel_try_search_shortcut(
|
|||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test deleted flag. Fetch the columns needed in test conditions. */
|
/* Test the deleted flag. */
|
||||||
|
|
||||||
row_sel_fetch_columns(index, rec, offsets,
|
|
||||||
UT_LIST_GET_FIRST(plan->columns));
|
|
||||||
|
|
||||||
if (rec_get_deleted_flag(rec, dict_table_is_comp(plan->table))) {
|
if (rec_get_deleted_flag(rec, dict_table_is_comp(plan->table))) {
|
||||||
|
|
||||||
@@ -1197,6 +1197,14 @@ row_sel_try_search_shortcut(
|
|||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fetch the columns needed in test conditions. The index
|
||||||
|
record is protected by a page latch that was acquired when
|
||||||
|
plan->pcur was positioned. The latch will not be released
|
||||||
|
until mtr_commit(mtr). */
|
||||||
|
|
||||||
|
row_sel_fetch_columns(index, rec, offsets,
|
||||||
|
UT_LIST_GET_FIRST(plan->columns));
|
||||||
|
|
||||||
/* Test the rest of search conditions */
|
/* Test the rest of search conditions */
|
||||||
|
|
||||||
if (!row_sel_test_other_conds(plan)) {
|
if (!row_sel_test_other_conds(plan)) {
|
||||||
@@ -1584,6 +1592,16 @@ skip_lock:
|
|||||||
offsets = rec_get_offsets(
|
offsets = rec_get_offsets(
|
||||||
rec, index, offsets,
|
rec, index, offsets,
|
||||||
ULINT_UNDEFINED, &heap);
|
ULINT_UNDEFINED, &heap);
|
||||||
|
|
||||||
|
/* Fetch the columns needed in
|
||||||
|
test conditions. The clustered
|
||||||
|
index record is protected by a
|
||||||
|
page latch that was acquired
|
||||||
|
by row_sel_open_pcur() or
|
||||||
|
row_sel_restore_pcur_pos().
|
||||||
|
The latch will not be released
|
||||||
|
until mtr_commit(mtr). */
|
||||||
|
|
||||||
row_sel_fetch_columns(
|
row_sel_fetch_columns(
|
||||||
index, rec, offsets,
|
index, rec, offsets,
|
||||||
UT_LIST_GET_FIRST(
|
UT_LIST_GET_FIRST(
|
||||||
@@ -1607,7 +1625,10 @@ skip_lock:
|
|||||||
|
|
||||||
/* PHASE 4: Test search end conditions and deleted flag */
|
/* PHASE 4: Test search end conditions and deleted flag */
|
||||||
|
|
||||||
/* Fetch the columns needed in test conditions */
|
/* Fetch the columns needed in test conditions. The record is
|
||||||
|
protected by a page latch that was acquired by
|
||||||
|
row_sel_open_pcur() or row_sel_restore_pcur_pos(). The latch
|
||||||
|
will not be released until mtr_commit(mtr). */
|
||||||
|
|
||||||
row_sel_fetch_columns(index, rec, offsets,
|
row_sel_fetch_columns(index, rec, offsets,
|
||||||
UT_LIST_GET_FIRST(plan->columns));
|
UT_LIST_GET_FIRST(plan->columns));
|
||||||
@@ -2502,14 +2523,18 @@ static
|
|||||||
void
|
void
|
||||||
row_sel_field_store_in_mysql_format(
|
row_sel_field_store_in_mysql_format(
|
||||||
/*================================*/
|
/*================================*/
|
||||||
byte* dest, /* in/out: buffer where to store; NOTE that BLOBs
|
byte* dest, /* in/out: buffer where to store; NOTE
|
||||||
are not in themselves stored here: the caller must
|
that BLOBs are not in themselves
|
||||||
allocate and copy the BLOB into buffer before, and pass
|
stored here: the caller must allocate
|
||||||
the pointer to the BLOB in 'data' */
|
and copy the BLOB into buffer before,
|
||||||
const mysql_row_templ_t* templ, /* in: MySQL column template.
|
and pass the pointer to the BLOB in
|
||||||
|
'data' */
|
||||||
|
const mysql_row_templ_t* templ,
|
||||||
|
/* in: MySQL column template.
|
||||||
Its following fields are referenced:
|
Its following fields are referenced:
|
||||||
type, is_unsigned, mysql_col_len, mbminlen, mbmaxlen */
|
type, is_unsigned, mysql_col_len,
|
||||||
byte* data, /* in: data to store */
|
mbminlen, mbmaxlen */
|
||||||
|
const byte* data, /* in: data to store */
|
||||||
ulint len) /* in: length of the data */
|
ulint len) /* in: length of the data */
|
||||||
{
|
{
|
||||||
byte* ptr;
|
byte* ptr;
|
||||||
@@ -2661,16 +2686,17 @@ row_sel_store_mysql_rec(
|
|||||||
case) */
|
case) */
|
||||||
byte* mysql_rec, /* out: row in the MySQL format */
|
byte* mysql_rec, /* out: row in the MySQL format */
|
||||||
row_prebuilt_t* prebuilt, /* in: prebuilt struct */
|
row_prebuilt_t* prebuilt, /* in: prebuilt struct */
|
||||||
rec_t* rec, /* in: Innobase record in the index
|
const rec_t* rec, /* in: Innobase record in the index
|
||||||
which was described in prebuilt's
|
which was described in prebuilt's
|
||||||
template */
|
template; must be protected by
|
||||||
|
a page latch */
|
||||||
const ulint* offsets) /* in: array returned by
|
const ulint* offsets) /* in: array returned by
|
||||||
rec_get_offsets() */
|
rec_get_offsets() */
|
||||||
{
|
{
|
||||||
mysql_row_templ_t* templ;
|
mysql_row_templ_t* templ;
|
||||||
mem_heap_t* extern_field_heap = NULL;
|
mem_heap_t* extern_field_heap = NULL;
|
||||||
mem_heap_t* heap;
|
mem_heap_t* heap;
|
||||||
byte* data;
|
const byte* data;
|
||||||
ulint len;
|
ulint len;
|
||||||
ulint i;
|
ulint i;
|
||||||
|
|
||||||
@@ -2771,7 +2797,7 @@ row_sel_store_mysql_rec(
|
|||||||
BLOB, TEXT and true VARCHAR) with space. */
|
BLOB, TEXT and true VARCHAR) with space. */
|
||||||
if (UNIV_UNLIKELY(templ->mbminlen == 2)) {
|
if (UNIV_UNLIKELY(templ->mbminlen == 2)) {
|
||||||
/* Treat UCS2 as a special case. */
|
/* Treat UCS2 as a special case. */
|
||||||
data = mysql_rec
|
byte* d = mysql_rec
|
||||||
+ templ->mysql_col_offset;
|
+ templ->mysql_col_offset;
|
||||||
len = templ->mysql_col_len;
|
len = templ->mysql_col_len;
|
||||||
/* There are two UCS2 bytes per char,
|
/* There are two UCS2 bytes per char,
|
||||||
@@ -2779,8 +2805,8 @@ row_sel_store_mysql_rec(
|
|||||||
ut_a(!(len & 1));
|
ut_a(!(len & 1));
|
||||||
/* Pad with 0x0020. */
|
/* Pad with 0x0020. */
|
||||||
while (len) {
|
while (len) {
|
||||||
*data++ = 0x00;
|
*d++ = 0x00;
|
||||||
*data++ = 0x20;
|
*d++ = 0x20;
|
||||||
len -= 2;
|
len -= 2;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@@ -3146,7 +3172,8 @@ void
|
|||||||
row_sel_push_cache_row_for_mysql(
|
row_sel_push_cache_row_for_mysql(
|
||||||
/*=============================*/
|
/*=============================*/
|
||||||
row_prebuilt_t* prebuilt, /* in: prebuilt struct */
|
row_prebuilt_t* prebuilt, /* in: prebuilt struct */
|
||||||
rec_t* rec, /* in: record to push */
|
const rec_t* rec, /* in: record to push; must
|
||||||
|
be protected by a page latch */
|
||||||
const ulint* offsets) /* in: rec_get_offsets() */
|
const ulint* offsets) /* in: rec_get_offsets() */
|
||||||
{
|
{
|
||||||
byte* buf;
|
byte* buf;
|
||||||
@@ -3573,6 +3600,12 @@ row_search_for_mysql(
|
|||||||
ut_a(0 == cmp_dtuple_rec(search_tuple,
|
ut_a(0 == cmp_dtuple_rec(search_tuple,
|
||||||
rec, offsets));
|
rec, offsets));
|
||||||
#endif
|
#endif
|
||||||
|
/* At this point, rec is protected by
|
||||||
|
a page latch that was acquired by
|
||||||
|
row_sel_try_search_shortcut_for_mysql().
|
||||||
|
The latch will not be released until
|
||||||
|
mtr_commit(&mtr). */
|
||||||
|
|
||||||
if (!row_sel_store_mysql_rec(buf, prebuilt,
|
if (!row_sel_store_mysql_rec(buf, prebuilt,
|
||||||
rec, offsets)) {
|
rec, offsets)) {
|
||||||
err = DB_TOO_BIG_RECORD;
|
err = DB_TOO_BIG_RECORD;
|
||||||
@@ -4294,6 +4327,10 @@ requires_clust_rec:
|
|||||||
result_rec != rec ? clust_index : index,
|
result_rec != rec ? clust_index : index,
|
||||||
offsets));
|
offsets));
|
||||||
|
|
||||||
|
/* At this point, the clustered index record is protected
|
||||||
|
by a page latch that was acquired when pcur was positioned.
|
||||||
|
The latch will not be released until mtr_commit(&mtr). */
|
||||||
|
|
||||||
if ((match_mode == ROW_SEL_EXACT
|
if ((match_mode == ROW_SEL_EXACT
|
||||||
|| prebuilt->n_rows_fetched >= MYSQL_FETCH_CACHE_THRESHOLD)
|
|| prebuilt->n_rows_fetched >= MYSQL_FETCH_CACHE_THRESHOLD)
|
||||||
&& prebuilt->select_lock_type == LOCK_NONE
|
&& prebuilt->select_lock_type == LOCK_NONE
|
||||||
|
|||||||
Reference in New Issue
Block a user