1 /* 2 Copyright (c) 2018, Facebook, Inc. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; version 2 of the License. 7 8 This program is distributed in the hope that it will be useful, 9 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License 14 along with this program; if not, write to the Free Software 15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 16 17 #pragma once 18 19 // C++ standard header files 20 #include <string> 21 #include <vector> 22 23 // MySQL header files 24 #include "handler.h" // handler 25 #include "ib_ut0counter.h" 26 #include "my_global.h" // ulonglong 27 #include "sql_string.h" 28 29 // MyRocks header files 30 #include "./ha_rocksdb.h" 31 #include "./rdb_datadic.h" 32 33 namespace myrocks { 34 class Rdb_field_encoder; 35 36 /** 37 Describes instructions on how to decode the field for value slice 38 */ 39 struct READ_FIELD { 40 // Points to Rdb_field_encoder describing the field 41 Rdb_field_encoder *m_field_enc; 42 // if true, decode the field, otherwise skip it 43 bool m_decode; 44 // Skip this many bytes before reading (or skipping) this field 45 int m_skip; 46 }; 47 48 /** 49 Class to convert rocksdb value slice from storage format to mysql record 50 format. 51 */ 52 class Rdb_convert_to_record_value_decoder { 53 public: 54 Rdb_convert_to_record_value_decoder() = delete; 55 Rdb_convert_to_record_value_decoder( 56 const Rdb_convert_to_record_value_decoder &decoder) = delete; 57 Rdb_convert_to_record_value_decoder &operator=( 58 const Rdb_convert_to_record_value_decoder &decoder) = delete; 59 60 static int decode(uchar *const buf, TABLE *table, 61 Rdb_field_encoder *field_dec, Rdb_string_reader *reader, 62 bool decode, bool is_null); 63 64 private: 65 static int decode_blob(TABLE *table, uchar *const buf, 66 Rdb_field_encoder *field_dec, 67 Rdb_string_reader *reader, bool decode); 68 static int decode_fixed_length_field(uchar *const buf, 69 Rdb_field_encoder *field_dec, 70 Rdb_string_reader *const reader, 71 bool decode); 72 73 static int decode_varchar(uchar *const buf, Rdb_field_encoder *field_dec, 74 Rdb_string_reader *const reader, bool decode); 75 }; 76 77 /** 78 Class to iterator fields in RocksDB value slice 79 A template class instantiation represent a way to decode the data. 80 The reason to use template class instead of normal class is to elimate 81 virtual method call. 82 */ 83 template <typename value_field_decoder> 84 class Rdb_value_field_iterator { 85 private: 86 bool m_is_null; 87 std::vector<READ_FIELD>::const_iterator m_field_iter; 88 std::vector<READ_FIELD>::const_iterator m_field_end; 89 Rdb_string_reader *m_value_slice_reader; 90 // null value map 91 const char *m_null_bytes; 92 // The current open table 93 TABLE *m_table; 94 // The current field 95 Field *m_field; 96 Rdb_field_encoder *m_field_dec; 97 uchar *const m_buf; 98 uint m_offset; 99 100 public: 101 Rdb_value_field_iterator(TABLE *table, Rdb_string_reader *value_slice_reader, 102 const Rdb_converter *rdb_converter, 103 uchar *const buf); 104 Rdb_value_field_iterator(const Rdb_value_field_iterator &field_iterator) = 105 delete; 106 Rdb_value_field_iterator &operator=( 107 const Rdb_value_field_iterator &field_iterator) = delete; 108 109 /* 110 Move and decode next field 111 Run next() before accessing data 112 */ 113 int next(); 114 // Whether current field is the end of fields 115 bool end_of_fields() const; 116 void *get_dst() const; 117 // Whether the value of current field is null 118 bool is_null() const; 119 // get current field index 120 int get_field_index() const; 121 // get current field type 122 enum_field_types get_field_type() const; 123 }; 124 125 /** 126 Class to convert Mysql formats to rocksdb storage format, and vice versa. 127 */ 128 class Rdb_converter { 129 public: 130 /* 131 Initialize converter with table data 132 */ 133 Rdb_converter(const THD *thd, const Rdb_tbl_def *tbl_def, TABLE *table); 134 Rdb_converter(const Rdb_converter &decoder) = delete; 135 Rdb_converter &operator=(const Rdb_converter &decoder) = delete; 136 ~Rdb_converter(); 137 138 void setup_field_decoders(const MY_BITMAP *field_map, uint active_index, 139 bool keyread_only, bool decode_all_fields = false); 140 141 int decode(const std::shared_ptr<Rdb_key_def> &key_def, uchar *dst, 142 const rocksdb::Slice *key_slice, const rocksdb::Slice *value_slice, 143 bool decode_value = true); 144 145 int encode_value_slice(const std::shared_ptr<Rdb_key_def> &pk_def, 146 const rocksdb::Slice &pk_packed_slice, 147 Rdb_string_writer *pk_unpack_info, bool is_update_row, 148 bool store_row_debug_checksums, char *ttl_bytes, 149 bool *is_ttl_bytes_updated, 150 rocksdb::Slice *const value_slice); 151 get_row_checksums_checked()152 my_core::ha_rows get_row_checksums_checked() const { 153 return m_row_checksums_checked; 154 } get_verify_row_debug_checksums()155 bool get_verify_row_debug_checksums() const { 156 return m_verify_row_debug_checksums; 157 } set_verify_row_debug_checksums(bool verify_row_debug_checksums)158 void set_verify_row_debug_checksums(bool verify_row_debug_checksums) { 159 m_verify_row_debug_checksums = verify_row_debug_checksums; 160 } 161 get_encoder_arr()162 const Rdb_field_encoder *get_encoder_arr() const { return m_encoder_arr; } get_null_bytes_in_record()163 int get_null_bytes_in_record() { return m_null_bytes_length_in_record; } get_null_bytes()164 const char *get_null_bytes() const { return m_null_bytes; } set_is_key_requested(bool key_requested)165 void set_is_key_requested(bool key_requested) { 166 m_key_requested = key_requested; 167 } get_maybe_unpack_info()168 bool get_maybe_unpack_info() const { return m_maybe_unpack_info; } 169 get_ttl_bytes_buffer()170 char *get_ttl_bytes_buffer() { return m_ttl_bytes; } 171 get_decode_fields()172 const std::vector<READ_FIELD> *get_decode_fields() const { 173 return &m_decoders_vect; 174 } 175 get_lookup_bitmap()176 const MY_BITMAP *get_lookup_bitmap() { return &m_lookup_bitmap; } 177 178 private: 179 int decode_value_header(Rdb_string_reader *reader, 180 const std::shared_ptr<Rdb_key_def> &pk_def, 181 rocksdb::Slice *unpack_slice); 182 183 void setup_field_encoders(); 184 185 void get_storage_type(Rdb_field_encoder *const encoder, const uint kp); 186 187 int convert_record_from_storage_format( 188 const std::shared_ptr<Rdb_key_def> &pk_def, 189 const rocksdb::Slice *const key, const rocksdb::Slice *const value, 190 uchar *const buf, bool decode_value = true); 191 192 int verify_row_debug_checksum(const std::shared_ptr<Rdb_key_def> &pk_def, 193 Rdb_string_reader *reader, 194 const rocksdb::Slice *key, 195 const rocksdb::Slice *value); 196 197 private: 198 /* 199 This tells if any field which is part of the key needs to be unpacked and 200 decoded. 201 */ 202 bool m_key_requested; 203 /* 204 Controls whether verifying checksums during reading, This is updated from 205 the session variable at the start of each query. 206 */ 207 bool m_verify_row_debug_checksums; 208 // Thread handle 209 const THD *m_thd; 210 /* MyRocks table definition*/ 211 const Rdb_tbl_def *m_tbl_def; 212 /* The current open table */ 213 TABLE *m_table; 214 /* 215 Number of bytes in on-disk (storage) record format that are used for 216 storing SQL NULL flags. 217 */ 218 int m_null_bytes_length_in_record; 219 /* 220 Pointer to null bytes value 221 */ 222 const char *m_null_bytes; 223 /* 224 TRUE <=> Some fields in the PK may require unpack_info. 225 */ 226 bool m_maybe_unpack_info; 227 /* 228 Pointer to the original TTL timestamp value (8 bytes) during UPDATE. 229 */ 230 char m_ttl_bytes[ROCKSDB_SIZEOF_TTL_RECORD]; 231 /* 232 Array of table->s->fields elements telling how to store fields in the 233 record. 234 */ 235 Rdb_field_encoder *m_encoder_arr; 236 /* 237 Array of request fields telling how to decode data in RocksDB format 238 */ 239 std::vector<READ_FIELD> m_decoders_vect; 240 /* 241 A counter of how many row checksums were checked for this table. Note that 242 this does not include checksums for secondary index entries. 243 */ 244 my_core::ha_rows m_row_checksums_checked; 245 // buffer to hold data during encode_value_slice 246 String m_storage_record; 247 /* 248 For the active index, indicates which columns must be covered for the 249 current lookup to be covered. If the bitmap field is null, that means this 250 index does not cover the current lookup for any record. 251 */ 252 MY_BITMAP m_lookup_bitmap; 253 }; 254 } // namespace myrocks 255