1 /*****************************************************************************
2 
3 Copyright (c) 2006, 2020, 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, version 2.0, as published by the
7 Free Software Foundation.
8 
9 This program is also distributed with certain software (including but not
10 limited to OpenSSL) that is licensed under separate terms, as designated in a
11 particular file or component or in included license documentation. The authors
12 of MySQL hereby grant you an additional permission to link the program and
13 your derivative works with the separately licensed software that they have
14 included with MySQL.
15 
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19 for more details.
20 
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
24 
25 *****************************************************************************/
26 
27 /** @file include/row0ext.h
28  Caching of externally stored column prefixes
29 
30  Created September 2006 Marko Makela
31  *******************************************************/
32 
33 #ifndef row0ext_h
34 #define row0ext_h
35 
36 #include "data0types.h"
37 #include "dict0types.h"
38 #include "mem0mem.h"
39 #include "page0size.h"
40 #include "row0types.h"
41 #include "univ.i"
42 
43 #ifdef UNIV_DEBUG
44 #define row_ext_create(index, n_ext, ext, flags, tuple, is_sdi, heap) \
45   row_ext_create_func(index, n_ext, ext, flags, tuple, is_sdi, heap)
46 #else /* UNIV_DEBUG */
47 #define row_ext_create(index, n_ext, ext, flags, tuple, is_sdi, heap) \
48   row_ext_create_func(index, n_ext, ext, flags, tuple, heap)
49 #endif /* UNIV_DEBUG */
50 
51 /** Creates a cache of column prefixes of externally stored columns.
52 @param[in]	index	the index to which LOB belongs.
53 @param[in]	n_ext	number of externally stored columns
54 @param[in]	ext	col_no's of externally stored columns in the InnoDB
55 table object, as reported by dict_col_get_no(); NOT relative to the records
56 in the clustered index
57 @param[in]	flags	table->flags
58 @param[in]	tuple	data tuple containing the field references of the
59 externally stored columns; must be indexed by col_no; the clustered index record
60 must be covered by a lock or a page latch to prevent deletion (rollback
61 or purge) */
62 #ifdef UNIV_DEBUG
63 /**
64 @param[in]	is_sdi	true for SDI Indexes */
65 #endif /* UNIV_DEBUG */
66 /**
67 @param[in]	heap	heap where created
68 @return own: column prefix cache */
69 row_ext_t *row_ext_create_func(const dict_index_t *index, ulint n_ext,
70                                const ulint *ext, uint32_t flags,
71                                const dtuple_t *tuple,
72 #ifdef UNIV_DEBUG
73                                bool is_sdi,
74 #endif /* UNIV_DEBUG */
75                                mem_heap_t *heap);
76 
77 /** Looks up a column prefix of an externally stored column.
78 @param[in,out]	ext	column prefix cache
79 @param[in]	i	index of ext->ext[]
80 @param[out]	len	length of prefix, in bytes, at most the length
81                         determined by DICT_MAX_FIELD_LEN_BY_FORMAT()
82 @return column prefix, or NULL if the column is not stored externally,
83 or pointer to field_ref_zero if the BLOB pointer is unset */
84 UNIV_INLINE
85 const byte *row_ext_lookup_ith(const row_ext_t *ext, ulint i, ulint *len);
86 
87 /** Looks up a column prefix of an externally stored column.
88 @param[in]	ext	column prefix cache
89 @param[in]	col	column number in the InnoDB table object, as reported
90                         by dict_col_get_no(); NOT relative to the records in
91                         the clustered index
92 @param[out]	len	length of prefix, in bytes, at most the length
93                         determined by DICT_MAX_FIELD_LEN_BY_FORMAT()
94 @return column prefix, or NULL if the column is not stored externally,
95 or pointer to field_ref_zero if the BLOB pointer is unset */
96 UNIV_INLINE
97 const byte *row_ext_lookup(const row_ext_t *ext, ulint col, ulint *len);
98 
99 /** Prefixes of externally stored columns */
100 struct row_ext_t {
101   /** The clustered index from where LOB is fetched. */
102   const dict_index_t *index;
103 
104   ulint n_ext;      /*!< number of externally stored columns which are part of
105                     index */
106   const ulint *ext; /*!< col_no's of externally stored columns */
107   byte *buf;        /*!< backing store of the column prefix cache */
108   ulint max_len;    /*!< maximum prefix length, it could be
109                     REC_ANTELOPE_MAX_INDEX_COL_LEN or
110                     REC_VERSION_56_MAX_INDEX_COL_LEN depending
111                     on row format */
112   page_size_t page_size;
113   /*!< page size of the externally stored
114   columns */
115   ulint len[1]; /*!< prefix lengths; 0 if not cached */
116 
117   /* NOTE: Do NOT add new members here. */
118 
printrow_ext_t119   std::ostream &print(std::ostream &out) const {
120     out << "[row_ext_t:";
121     for (ulint i = 0; i < n_ext; i++) {
122       if (len[i] > 0) {
123         byte *ptr = (buf + i * max_len);
124         ut_print_buf(out, ptr, len[i]);
125       }
126     }
127     out << "]" << std::endl;
128     return (out);
129   }
130 };
131 
132 inline std::ostream &operator<<(std::ostream &out, const row_ext_t &obj) {
133   return (obj.print(out));
134 }
135 
136 #include "row0ext.ic"
137 
138 #endif
139