diff options
Diffstat (limited to 'storage/innobase/row/row0sel.cc')
-rw-r--r-- | storage/innobase/row/row0sel.cc | 85 |
1 files changed, 62 insertions, 23 deletions
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 1b57e0d56fd..f691009d6e3 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Copyright (c) 2015, 2017, MariaDB Corporation. @@ -2558,34 +2558,32 @@ row_sel_store_row_id_to_prebuilt( row_sel_field_store_in_mysql_format_func(dest,templ,src,len) #endif /* UNIV_DEBUG */ -/**************************************************************//** -Stores a non-SQL-NULL field in the MySQL format. The counterpart of this -function is row_mysql_store_col_in_innobase_format() in row0mysql.cc. */ +/** Stores a non-SQL-NULL field in the MySQL format. The counterpart of this +function is row_mysql_store_col_in_innobase_format() in row0mysql.cc. +@param[in,out] dest 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' +@param[in] templ MySQL column template. Its following fields + are referenced: type, is_unsigned, mysql_col_len, + mbminlen, mbmaxlen +@param[in] index InnoDB index +@param[in] field_no templ->rec_field_no or templ->clust_rec_field_no + or templ->icp_rec_field_no +@param[in] data data to store +@param[in] len length of the data */ static MY_ATTRIBUTE((nonnull)) void row_sel_field_store_in_mysql_format_func( -/*=====================================*/ - 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' */ + byte* dest, const mysql_row_templ_t* templ, - /*!< in: MySQL column template. - Its following fields are referenced: - type, is_unsigned, mysql_col_len, - mbminlen, mbmaxlen */ #ifdef UNIV_DEBUG const dict_index_t* index, - /*!< in: InnoDB index */ ulint field_no, - /*!< in: templ->rec_field_no or - templ->clust_rec_field_no or - templ->icp_rec_field_no */ #endif /* UNIV_DEBUG */ - const byte* data, /*!< in: data to store */ - ulint len) /*!< in: length of the data */ + const byte* data, + ulint len) { byte* ptr; #ifdef UNIV_DEBUG @@ -3339,6 +3337,36 @@ row_sel_copy_cached_field_for_mysql( ut_memcpy(buf, cache, len); } +/** Copy used fields from cached row. +Copy cache record field by field, don't touch fields that +are not covered by current key. +@param[out] buf Where to copy the MySQL row. +@param[in] cached_rec What to copy (in MySQL row format). +@param[in] prebuilt prebuilt struct. */ +void +row_sel_copy_cached_fields_for_mysql( + byte* buf, + const byte* cached_rec, + row_prebuilt_t* prebuilt) +{ + const mysql_row_templ_t*templ; + ulint i; + for (i = 0; i < prebuilt->n_template; i++) { + templ = prebuilt->mysql_template + i; + + row_sel_copy_cached_field_for_mysql( + buf, cached_rec, templ); + /* Copy NULL bit of the current field from cached_rec + to buf */ + if (templ->mysql_null_bit_mask) { + buf[templ->mysql_null_byte_offset] + ^= (buf[templ->mysql_null_byte_offset] + ^ cached_rec[templ->mysql_null_byte_offset]) + & (byte) templ->mysql_null_bit_mask; + } + } +} + /********************************************************************//** Pops a cached row for MySQL from the fetch cache. */ UNIV_INLINE @@ -5068,8 +5096,19 @@ idx_cond_failed: btr_pcur_store_position(pcur, &mtr); - if (prebuilt->innodb_api) { - prebuilt->innodb_api_rec = result_rec; + if (prebuilt->innodb_api + && (btr_pcur_get_rec(pcur) != result_rec)) { + ulint rec_size = rec_offs_size(offsets); + if (!prebuilt->innodb_api_rec_size || + (prebuilt->innodb_api_rec_size < rec_size)) { + prebuilt->innodb_api_buf = + static_cast<byte*> + (mem_heap_alloc(prebuilt->cursor_heap,rec_size)); + prebuilt->innodb_api_rec_size = rec_size; + } + prebuilt->innodb_api_rec = + rec_copy( + prebuilt->innodb_api_buf, result_rec, offsets); } } |