/**********************************************************************//** Fetch a prefix of an externally stored column, for writing to the undo log of an update or delete marking of a clustered index record. @return ext_buf */ static byte* trx_undo_page_fetch_ext( /*====================*/ byte* ext_buf, /*!< in: a buffer of REC_MAX_INDEX_COL_LEN + BTR_EXTERN_FIELD_REF_SIZE */ ulint zip_size, /*!< compressed page size in bytes, or 0 for uncompressed BLOB */ const byte* field, /*!< in: an externally stored column */ ulint* len) /*!< in: length of field; out: used length of ext_buf */ { /* Fetch the BLOB. */ ulint ext_len = btr_copy_externally_stored_field_prefix( ext_buf, REC_MAX_INDEX_COL_LEN, zip_size, field, *len); /* BLOBs should always be nonempty. */ ut_a(ext_len); /* Append the BLOB pointer to the prefix. */ memcpy(ext_buf + ext_len, field + *len - BTR_EXTERN_FIELD_REF_SIZE, BTR_EXTERN_FIELD_REF_SIZE); *len = ext_len + BTR_EXTERN_FIELD_REF_SIZE; return(ext_buf); }
/********************************************************************//** Fills the column prefix cache of an externally stored column. */ static void row_ext_cache_fill( /*===============*/ row_ext_t* ext, /*!< in/out: column prefix cache */ ulint i, /*!< in: index of ext->ext[] */ ulint zip_size,/*!< compressed page size in bytes, or 0 */ const dfield_t* dfield) /*!< in: data field */ { const byte* field = dfield_get_data(dfield); ulint f_len = dfield_get_len(dfield); byte* buf = ext->buf + i * ext->max_len; ut_ad(ext->max_len > 0); ut_ad(i < ext->n_ext); ut_ad(dfield_is_ext(dfield)); ut_a(f_len >= BTR_EXTERN_FIELD_REF_SIZE); if (UNIV_UNLIKELY(!memcmp(field_ref_zero, field + f_len - BTR_EXTERN_FIELD_REF_SIZE, BTR_EXTERN_FIELD_REF_SIZE))) { /* The BLOB pointer is not set: we cannot fetch it */ ext->len[i] = 0; } else { /* Fetch at most ext->max_len of the column. The column should be non-empty. However, trx_rollback_or_clean_all_recovered() may try to access a half-deleted BLOB if the server previously crashed during the execution of btr_free_externally_stored_field(). */ ext->len[i] = btr_copy_externally_stored_field_prefix( buf, ext->max_len, zip_size, field, f_len); } }