MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
row0ext.cc
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (c) 2006, 2013, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free Software
7 Foundation; version 2 of the License.
8 
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
16 
17 *****************************************************************************/
18 
19 /**************************************************/
26 #include "row0ext.h"
27 
28 #ifdef UNIV_NONINL
29 #include "row0ext.ic"
30 #endif
31 
32 #include "btr0cur.h"
33 
34 /********************************************************************/
36 static
37 void
38 row_ext_cache_fill(
39 /*===============*/
40  row_ext_t* ext,
41  ulint i,
42  ulint zip_size,
43  const dfield_t* dfield)
44 {
45  const byte* field = static_cast<const byte*>(
46  dfield_get_data(dfield));
47  ulint f_len = dfield_get_len(dfield);
48  byte* buf = ext->buf + i * ext->max_len;
49 
50  ut_ad(ext->max_len > 0);
51  ut_ad(i < ext->n_ext);
52  ut_ad(dfield_is_ext(dfield));
54 
55  if (UNIV_UNLIKELY(!memcmp(field_ref_zero,
56  field + f_len - BTR_EXTERN_FIELD_REF_SIZE,
58  /* The BLOB pointer is not set: we cannot fetch it */
59  ext->len[i] = 0;
60  } else {
62  && f_len > BTR_EXTERN_FIELD_REF_SIZE) {
63  /* In this case, the field is in B format or beyond,
64  (refer to the definition of row_ext_t.max_len)
65  and the field is already fill with prefix, otherwise
66  f_len would be BTR_EXTERN_FIELD_REF_SIZE.
67  So there is no need to re-read the prefix externally,
68  but just copy the local prefix to buf. Please note
69  if the ext->len[i] is zero, it means an error
70  as above. */
71  memcpy(buf, field, f_len - BTR_EXTERN_FIELD_REF_SIZE);
72  ext->len[i] = f_len - BTR_EXTERN_FIELD_REF_SIZE;
73  } else {
74  /* Fetch at most ext->max_len of the column.
75  The column should be non-empty. However,
76  trx_rollback_or_clean_all_recovered() may try to
77  access a half-deleted BLOB if the server previously
78  crashed during the execution of
79  btr_free_externally_stored_field(). */
81  buf, ext->max_len, zip_size, field, f_len);
82  }
83  }
84 }
85 
86 /********************************************************************/
89 UNIV_INTERN
90 row_ext_t*
92 /*===========*/
93  ulint n_ext,
94  const ulint* ext,
98  ulint flags,
99  const dtuple_t* tuple,
105  mem_heap_t* heap)
106 {
107  ulint i;
108  ulint zip_size = dict_tf_get_zip_size(flags);
109 
110  row_ext_t* ret;
111 
112  ut_ad(n_ext > 0);
113 
114  ret = static_cast<row_ext_t*>(
115  mem_heap_alloc(heap,
116  (sizeof *ret) + (n_ext - 1) * sizeof ret->len));
117 
118  ut_ad(ut_is_2pow(zip_size));
119  ut_ad(zip_size <= UNIV_ZIP_SIZE_MAX);
120 
121  ret->n_ext = n_ext;
122  ret->ext = ext;
123  ret->max_len = DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(flags);
124 
125  ret->buf = static_cast<byte*>(
126  mem_heap_alloc(heap, n_ext * ret->max_len));
127 
128 #ifdef UNIV_DEBUG
129  memset(ret->buf, 0xaa, n_ext * ret->max_len);
130  UNIV_MEM_ALLOC(ret->buf, n_ext * ret->max_len);
131 #endif
132 
133  /* Fetch the BLOB prefixes */
134  for (i = 0; i < n_ext; i++) {
135  const dfield_t* dfield;
136 
137  dfield = dtuple_get_nth_field(tuple, ext[i]);
138  row_ext_cache_fill(ret, i, zip_size, dfield);
139  }
140 
141  return(ret);
142 }