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));
|
||||
|
||||
/* 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(
|
||||
mrec, offsets, zip_size, i, &len, heap);
|
||||
|
||||
|
||||
@@ -344,8 +344,8 @@ void
|
||||
row_sel_fetch_columns(
|
||||
/*==================*/
|
||||
dict_index_t* index, /* in: record index */
|
||||
rec_t* rec, /* in: record in a clustered or non-clustered
|
||||
index */
|
||||
const rec_t* rec, /* in: record in a clustered or non-clustered
|
||||
index; must be protected by a page latch */
|
||||
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
|
||||
sym_node_t* column) /* in: first column in a column list, or
|
||||
NULL */
|
||||
@@ -353,7 +353,7 @@ row_sel_fetch_columns(
|
||||
dfield_t* val;
|
||||
ulint index_type;
|
||||
ulint field_no;
|
||||
byte* data;
|
||||
const byte* data;
|
||||
ulint len;
|
||||
|
||||
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,
|
||||
UT_LIST_GET_FIRST(plan->columns));
|
||||
@@ -1186,10 +1189,7 @@ row_sel_try_search_shortcut(
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
/* Test deleted flag. Fetch the columns needed in test conditions. */
|
||||
|
||||
row_sel_fetch_columns(index, rec, offsets,
|
||||
UT_LIST_GET_FIRST(plan->columns));
|
||||
/* Test the deleted flag. */
|
||||
|
||||
if (rec_get_deleted_flag(rec, dict_table_is_comp(plan->table))) {
|
||||
|
||||
@@ -1197,6 +1197,14 @@ row_sel_try_search_shortcut(
|
||||
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 */
|
||||
|
||||
if (!row_sel_test_other_conds(plan)) {
|
||||
@@ -1584,6 +1592,16 @@ skip_lock:
|
||||
offsets = rec_get_offsets(
|
||||
rec, index, offsets,
|
||||
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(
|
||||
index, rec, offsets,
|
||||
UT_LIST_GET_FIRST(
|
||||
@@ -1607,7 +1625,10 @@ skip_lock:
|
||||
|
||||
/* 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,
|
||||
UT_LIST_GET_FIRST(plan->columns));
|
||||
@@ -2502,14 +2523,18 @@ static
|
||||
void
|
||||
row_sel_field_store_in_mysql_format(
|
||||
/*================================*/
|
||||
byte* dest, /* in/out: buffer where to store; NOTE that BLOBs
|
||||
are not in themselves stored here: the caller must
|
||||
allocate and copy the BLOB into buffer before, and pass
|
||||
the pointer to the BLOB in 'data' */
|
||||
const mysql_row_templ_t* templ, /* in: MySQL column template.
|
||||
byte* dest, /* in/out: buffer where to store; NOTE
|
||||
that BLOBs are not in themselves
|
||||
stored here: the caller must allocate
|
||||
and copy the BLOB into buffer before,
|
||||
and pass the pointer to the BLOB in
|
||||
'data' */
|
||||
const mysql_row_templ_t* templ,
|
||||
/* in: MySQL column template.
|
||||
Its following fields are referenced:
|
||||
type, is_unsigned, mysql_col_len, mbminlen, mbmaxlen */
|
||||
byte* data, /* in: data to store */
|
||||
type, is_unsigned, mysql_col_len,
|
||||
mbminlen, mbmaxlen */
|
||||
const byte* data, /* in: data to store */
|
||||
ulint len) /* in: length of the data */
|
||||
{
|
||||
byte* ptr;
|
||||
@@ -2661,16 +2686,17 @@ row_sel_store_mysql_rec(
|
||||
case) */
|
||||
byte* mysql_rec, /* out: row in the MySQL format */
|
||||
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
|
||||
template */
|
||||
template; must be protected by
|
||||
a page latch */
|
||||
const ulint* offsets) /* in: array returned by
|
||||
rec_get_offsets() */
|
||||
{
|
||||
mysql_row_templ_t* templ;
|
||||
mem_heap_t* extern_field_heap = NULL;
|
||||
mem_heap_t* heap;
|
||||
byte* data;
|
||||
const byte* data;
|
||||
ulint len;
|
||||
ulint i;
|
||||
|
||||
@@ -2771,7 +2797,7 @@ row_sel_store_mysql_rec(
|
||||
BLOB, TEXT and true VARCHAR) with space. */
|
||||
if (UNIV_UNLIKELY(templ->mbminlen == 2)) {
|
||||
/* Treat UCS2 as a special case. */
|
||||
data = mysql_rec
|
||||
byte* d = mysql_rec
|
||||
+ templ->mysql_col_offset;
|
||||
len = templ->mysql_col_len;
|
||||
/* There are two UCS2 bytes per char,
|
||||
@@ -2779,8 +2805,8 @@ row_sel_store_mysql_rec(
|
||||
ut_a(!(len & 1));
|
||||
/* Pad with 0x0020. */
|
||||
while (len) {
|
||||
*data++ = 0x00;
|
||||
*data++ = 0x20;
|
||||
*d++ = 0x00;
|
||||
*d++ = 0x20;
|
||||
len -= 2;
|
||||
}
|
||||
continue;
|
||||
@@ -3146,7 +3172,8 @@ void
|
||||
row_sel_push_cache_row_for_mysql(
|
||||
/*=============================*/
|
||||
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() */
|
||||
{
|
||||
byte* buf;
|
||||
@@ -3573,6 +3600,12 @@ row_search_for_mysql(
|
||||
ut_a(0 == cmp_dtuple_rec(search_tuple,
|
||||
rec, offsets));
|
||||
#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,
|
||||
rec, offsets)) {
|
||||
err = DB_TOO_BIG_RECORD;
|
||||
@@ -4294,6 +4327,10 @@ requires_clust_rec:
|
||||
result_rec != rec ? clust_index : index,
|
||||
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
|
||||
|| prebuilt->n_rows_fetched >= MYSQL_FETCH_CACHE_THRESHOLD)
|
||||
&& prebuilt->select_lock_type == LOCK_NONE
|
||||
|
||||
Reference in New Issue
Block a user