1 | /* Copyright (c) 2007, 2013, Oracle and/or its affiliates. |
2 | Copyright (c) 2008, 2014, SkySQL Ab. |
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
16 | |
17 | #include "mariadb.h" |
18 | #include "sql_priv.h" |
19 | #include "unireg.h" |
20 | #include "rpl_rli.h" |
21 | #include "rpl_record.h" |
22 | #include "slave.h" // Need to pull in slave_print_msg |
23 | #include "rpl_utility.h" |
24 | #include "rpl_rli.h" |
25 | |
26 | /** |
27 | Pack a record of data for a table into a format suitable for |
28 | transfer via the binary log. |
29 | |
30 | The format for a row in transfer with N fields is the following: |
31 | |
32 | ceil(N/8) null bytes: |
33 | One null bit for every column *regardless of whether it can be |
34 | null or not*. This simplifies the decoding. Observe that the |
35 | number of null bits is equal to the number of set bits in the |
36 | @c cols bitmap. The number of null bytes is the smallest number |
37 | of bytes necessary to store the null bits. |
38 | |
39 | Padding bits are 1. |
40 | |
41 | N packets: |
42 | Each field is stored in packed format. |
43 | |
44 | |
45 | @param table Table describing the format of the record |
46 | |
47 | @param cols Bitmap with a set bit for each column that should |
48 | be stored in the row |
49 | |
50 | @param row_data Pointer to memory where row will be written |
51 | |
52 | @param record Pointer to record that should be packed. It is |
53 | assumed that the pointer refers to either @c |
54 | record[0] or @c record[1], but no such check is |
55 | made since the code does not rely on that. |
56 | |
57 | @return The number of bytes written at @c row_data. |
58 | */ |
59 | #if !defined(MYSQL_CLIENT) |
60 | size_t |
61 | pack_row(TABLE *table, MY_BITMAP const* cols, |
62 | uchar *row_data, const uchar *record) |
63 | { |
64 | Field **p_field= table->field, *field; |
65 | int const null_byte_count= (bitmap_bits_set(cols) + 7) / 8; |
66 | uchar *pack_ptr = row_data + null_byte_count; |
67 | uchar *null_ptr = row_data; |
68 | my_ptrdiff_t const rec_offset= record - table->record[0]; |
69 | my_ptrdiff_t const def_offset= table->s->default_values - table->record[0]; |
70 | |
71 | DBUG_ENTER("pack_row" ); |
72 | |
73 | /* |
74 | We write the null bits and the packed records using one pass |
75 | through all the fields. The null bytes are written little-endian, |
76 | i.e., the first fields are in the first byte. |
77 | */ |
78 | unsigned int null_bits= (1U << 8) - 1; |
79 | // Mask to mask out the correct but among the null bits |
80 | unsigned int null_mask= 1U; |
81 | for ( ; (field= *p_field) ; p_field++) |
82 | { |
83 | if (bitmap_is_set(cols, (uint)(p_field - table->field))) |
84 | { |
85 | my_ptrdiff_t offset; |
86 | if (field->is_null(rec_offset)) |
87 | { |
88 | offset= def_offset; |
89 | null_bits |= null_mask; |
90 | } |
91 | else |
92 | { |
93 | offset= rec_offset; |
94 | null_bits &= ~null_mask; |
95 | |
96 | /* |
97 | We only store the data of the field if it is non-null |
98 | |
99 | For big-endian machines, we have to make sure that the |
100 | length is stored in little-endian format, since this is the |
101 | format used for the binlog. |
102 | */ |
103 | #ifndef DBUG_OFF |
104 | const uchar *old_pack_ptr= pack_ptr; |
105 | #endif |
106 | pack_ptr= field->pack(pack_ptr, field->ptr + offset, |
107 | field->max_data_length()); |
108 | DBUG_PRINT("debug" , ("field: %s; real_type: %d, pack_ptr: %p;" |
109 | " pack_ptr':%p; bytes: %d" , |
110 | field->field_name.str, field->real_type(), |
111 | old_pack_ptr,pack_ptr, |
112 | (int) (pack_ptr - old_pack_ptr))); |
113 | DBUG_DUMP("packed_data" , old_pack_ptr, pack_ptr - old_pack_ptr); |
114 | } |
115 | |
116 | null_mask <<= 1; |
117 | if ((null_mask & 0xFF) == 0) |
118 | { |
119 | DBUG_ASSERT(null_ptr < row_data + null_byte_count); |
120 | null_mask = 1U; |
121 | *null_ptr++ = null_bits; |
122 | null_bits= (1U << 8) - 1; |
123 | } |
124 | } |
125 | } |
126 | |
127 | /* |
128 | Write the last (partial) byte, if there is one |
129 | */ |
130 | if ((null_mask & 0xFF) > 1) |
131 | { |
132 | DBUG_ASSERT(null_ptr < row_data + null_byte_count); |
133 | *null_ptr++ = null_bits; |
134 | } |
135 | |
136 | /* |
137 | The null pointer should now point to the first byte of the |
138 | packed data. If it doesn't, something is very wrong. |
139 | */ |
140 | DBUG_ASSERT(null_ptr == row_data + null_byte_count); |
141 | DBUG_DUMP("row_data" , row_data, pack_ptr - row_data); |
142 | DBUG_RETURN(static_cast<size_t>(pack_ptr - row_data)); |
143 | } |
144 | #endif |
145 | |
146 | |
147 | /** |
148 | Unpack a row into @c table->record[0]. |
149 | |
150 | The function will always unpack into the @c table->record[0] |
151 | record. This is because there are too many dependencies on where |
152 | the various member functions of Field and subclasses expect to |
153 | write. |
154 | |
155 | The row is assumed to only consist of the fields for which the |
156 | corresponding bit in bitset @c cols is set; the other parts of the |
157 | record are left alone. |
158 | |
159 | At most @c colcnt columns are read: if the table is larger than |
160 | that, the remaining fields are not filled in. |
161 | |
162 | @note The relay log information can be NULL, which means that no |
163 | checking or comparison with the source table is done, simply |
164 | because it is not used. This feature is used by MySQL Backup to |
165 | unpack a row from from the backup image, but can be used for other |
166 | purposes as well. |
167 | |
168 | @param rli Relay log info, which can be NULL |
169 | @param table Table to unpack into |
170 | @param colcnt Number of columns to read from record |
171 | @param row_data |
172 | Packed row data |
173 | @param cols Pointer to bitset describing columns to fill in |
174 | @param curr_row_end |
175 | Pointer to variable that will hold the value of the |
176 | one-after-end position for the current row |
177 | @param master_reclength |
178 | Pointer to variable that will be set to the length of the |
179 | record on the master side |
180 | @param row_end |
181 | Pointer to variable that will hold the value of the |
182 | end position for the data in the row event |
183 | |
184 | @retval 0 No error |
185 | |
186 | @retval HA_ERR_GENERIC |
187 | A generic, internal, error caused the unpacking to fail. |
188 | @retval HA_ERR_CORRUPT_EVENT |
189 | Found error when trying to unpack fields. |
190 | */ |
191 | #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) |
192 | int |
193 | unpack_row(rpl_group_info *rgi, |
194 | TABLE *table, uint const colcnt, |
195 | uchar const *const row_data, MY_BITMAP const *cols, |
196 | uchar const **const current_row_end, ulong *const master_reclength, |
197 | uchar const *const row_end) |
198 | { |
199 | int error; |
200 | DBUG_ENTER("unpack_row" ); |
201 | DBUG_ASSERT(row_data); |
202 | DBUG_ASSERT(table); |
203 | size_t const master_null_byte_count= (bitmap_bits_set(cols) + 7) / 8; |
204 | |
205 | uchar const *null_ptr= row_data; |
206 | uchar const *pack_ptr= row_data + master_null_byte_count; |
207 | |
208 | Field **const begin_ptr = table->field; |
209 | Field **field_ptr; |
210 | Field **const end_ptr= begin_ptr + colcnt; |
211 | |
212 | if (bitmap_is_clear_all(cols)) |
213 | { |
214 | /** |
215 | There was no data sent from the master, so there is |
216 | nothing to unpack. |
217 | */ |
218 | *current_row_end= pack_ptr; |
219 | *master_reclength= 0; |
220 | DBUG_RETURN(0); |
221 | } |
222 | DBUG_ASSERT(null_ptr < row_data + master_null_byte_count); |
223 | |
224 | // Mask to mask out the correct bit among the null bits |
225 | unsigned int null_mask= 1U; |
226 | // The "current" null bits |
227 | unsigned int null_bits= *null_ptr++; |
228 | uint i= 0; |
229 | table_def *tabledef= NULL; |
230 | TABLE *conv_table= NULL; |
231 | bool table_found= rgi && rgi->get_table_data(table, &tabledef, &conv_table); |
232 | DBUG_PRINT("debug" , ("Table data: table_found: %d, tabldef: %p, conv_table: %p" , |
233 | table_found, tabledef, conv_table)); |
234 | DBUG_ASSERT(table_found); |
235 | |
236 | /* |
237 | If rgi is NULL it means that there is no source table and that the |
238 | row shall just be unpacked without doing any checks. This feature |
239 | is used by MySQL Backup, but can be used for other purposes as |
240 | well. |
241 | */ |
242 | if (rgi && !table_found) |
243 | DBUG_RETURN(HA_ERR_GENERIC); |
244 | |
245 | for (field_ptr= begin_ptr ; field_ptr < end_ptr && *field_ptr ; ++field_ptr) |
246 | { |
247 | /* |
248 | If there is a conversion table, we pick up the field pointer to |
249 | the conversion table. If the conversion table or the field |
250 | pointer is NULL, no conversions are necessary. |
251 | */ |
252 | Field *conv_field= |
253 | conv_table ? conv_table->field[field_ptr - begin_ptr] : NULL; |
254 | Field *const f= |
255 | conv_field ? conv_field : *field_ptr; |
256 | DBUG_PRINT("debug" , ("Conversion %srequired for field '%s' (#%ld)" , |
257 | conv_field ? "" : "not " , |
258 | (*field_ptr)->field_name.str, |
259 | (long) (field_ptr - begin_ptr))); |
260 | DBUG_ASSERT(f != NULL); |
261 | |
262 | /* |
263 | No need to bother about columns that does not exist: they have |
264 | gotten default values when being emptied above. |
265 | */ |
266 | if (bitmap_is_set(cols, (uint)(field_ptr - begin_ptr))) |
267 | { |
268 | if ((null_mask & 0xFF) == 0) |
269 | { |
270 | DBUG_ASSERT(null_ptr < row_data + master_null_byte_count); |
271 | null_mask= 1U; |
272 | null_bits= *null_ptr++; |
273 | } |
274 | |
275 | DBUG_ASSERT(null_mask & 0xFF); // One of the 8 LSB should be set |
276 | |
277 | if (null_bits & null_mask) |
278 | { |
279 | if (f->maybe_null()) |
280 | { |
281 | DBUG_PRINT("debug" , ("Was NULL; null mask: 0x%x; null bits: 0x%x" , |
282 | null_mask, null_bits)); |
283 | /** |
284 | Calling reset just in case one is unpacking on top a |
285 | record with data. |
286 | |
287 | This could probably go into set_null() but doing so, |
288 | (i) triggers assertion in other parts of the code at |
289 | the moment; (ii) it would make us reset the field, |
290 | always when setting null, which right now doesn't seem |
291 | needed anywhere else except here. |
292 | |
293 | TODO: maybe in the future we should consider moving |
294 | the reset to make it part of set_null. But then |
295 | the assertions triggered need to be |
296 | addressed/revisited. |
297 | */ |
298 | f->reset(); |
299 | f->set_null(); |
300 | } |
301 | else |
302 | { |
303 | THD *thd= f->table->in_use; |
304 | |
305 | f->set_default(); |
306 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
307 | ER_BAD_NULL_ERROR, |
308 | ER_THD(thd, ER_BAD_NULL_ERROR), |
309 | f->field_name.str); |
310 | } |
311 | } |
312 | else |
313 | { |
314 | f->set_notnull(); |
315 | |
316 | /* |
317 | We only unpack the field if it was non-null. |
318 | Use the master's size information if available else call |
319 | normal unpack operation. |
320 | */ |
321 | uint16 const metadata= tabledef->field_metadata(i); |
322 | uchar const *const old_pack_ptr= pack_ptr; |
323 | |
324 | pack_ptr= f->unpack(f->ptr, pack_ptr, row_end, metadata); |
325 | DBUG_PRINT("debug" , ("field: %s; metadata: 0x%x;" |
326 | " pack_ptr: %p; pack_ptr': %p; bytes: %d" , |
327 | f->field_name.str, metadata, |
328 | old_pack_ptr, pack_ptr, |
329 | (int) (pack_ptr - old_pack_ptr))); |
330 | if (!pack_ptr) |
331 | { |
332 | if (WSREP_ON) |
333 | { |
334 | /* |
335 | Debug message to troubleshoot bug: |
336 | https://mariadb.atlassian.net/browse/MDEV-4404 |
337 | Galera Node throws "Could not read field" error and drops out of cluster |
338 | */ |
339 | WSREP_WARN("ROW event unpack field: %s metadata: 0x%x;" |
340 | " pack_ptr: %p; conv_table %p conv_field %p table %s" |
341 | " row_end: %p" , |
342 | f->field_name.str, metadata, |
343 | old_pack_ptr, conv_table, conv_field, |
344 | (table_found) ? "found" : "not found" , row_end |
345 | ); |
346 | } |
347 | |
348 | rgi->rli->report(ERROR_LEVEL, ER_SLAVE_CORRUPT_EVENT, |
349 | rgi->gtid_info(), |
350 | "Could not read field '%s' of table '%s.%s'" , |
351 | f->field_name.str, table->s->db.str, |
352 | table->s->table_name.str); |
353 | DBUG_RETURN(HA_ERR_CORRUPT_EVENT); |
354 | } |
355 | } |
356 | |
357 | /* |
358 | If conv_field is set, then we are doing a conversion. In this |
359 | case, we have unpacked the master data to the conversion |
360 | table, so we need to copy the value stored in the conversion |
361 | table into the final table and do the conversion at the same time. |
362 | */ |
363 | if (conv_field) |
364 | { |
365 | Copy_field copy; |
366 | #ifndef DBUG_OFF |
367 | char source_buf[MAX_FIELD_WIDTH]; |
368 | char value_buf[MAX_FIELD_WIDTH]; |
369 | String source_type(source_buf, sizeof(source_buf), system_charset_info); |
370 | String value_string(value_buf, sizeof(value_buf), system_charset_info); |
371 | conv_field->sql_type(source_type); |
372 | conv_field->val_str(&value_string); |
373 | DBUG_PRINT("debug" , ("Copying field '%s' of type '%s' with value '%s'" , |
374 | (*field_ptr)->field_name.str, |
375 | source_type.c_ptr_safe(), value_string.c_ptr_safe())); |
376 | #endif |
377 | copy.set(*field_ptr, f, TRUE); |
378 | (*copy.do_copy)(©); |
379 | #ifndef DBUG_OFF |
380 | char target_buf[MAX_FIELD_WIDTH]; |
381 | String target_type(target_buf, sizeof(target_buf), system_charset_info); |
382 | (*field_ptr)->sql_type(target_type); |
383 | (*field_ptr)->val_str(&value_string); |
384 | DBUG_PRINT("debug" , ("Value of field '%s' of type '%s' is now '%s'" , |
385 | (*field_ptr)->field_name.str, |
386 | target_type.c_ptr_safe(), value_string.c_ptr_safe())); |
387 | #endif |
388 | } |
389 | |
390 | null_mask <<= 1; |
391 | } |
392 | i++; |
393 | } |
394 | |
395 | /* |
396 | throw away master's extra fields |
397 | */ |
398 | uint max_cols= MY_MIN(tabledef->size(), cols->n_bits); |
399 | for (; i < max_cols; i++) |
400 | { |
401 | if (bitmap_is_set(cols, i)) |
402 | { |
403 | if ((null_mask & 0xFF) == 0) |
404 | { |
405 | DBUG_ASSERT(null_ptr < row_data + master_null_byte_count); |
406 | null_mask= 1U; |
407 | null_bits= *null_ptr++; |
408 | } |
409 | DBUG_ASSERT(null_mask & 0xFF); // One of the 8 LSB should be set |
410 | |
411 | if (!((null_bits & null_mask) && tabledef->maybe_null(i))) { |
412 | uint32 len= tabledef->calc_field_size(i, (uchar *) pack_ptr); |
413 | DBUG_DUMP("field_data" , pack_ptr, len); |
414 | pack_ptr+= len; |
415 | } |
416 | null_mask <<= 1; |
417 | } |
418 | } |
419 | |
420 | /* |
421 | Add Extra slave persistent columns |
422 | */ |
423 | if (unlikely(error= fill_extra_persistent_columns(table, cols->n_bits))) |
424 | DBUG_RETURN(error); |
425 | |
426 | /* |
427 | We should now have read all the null bytes, otherwise something is |
428 | really wrong. |
429 | */ |
430 | DBUG_ASSERT(null_ptr == row_data + master_null_byte_count); |
431 | |
432 | DBUG_DUMP("row_data" , row_data, pack_ptr - row_data); |
433 | |
434 | *current_row_end = pack_ptr; |
435 | if (master_reclength) |
436 | { |
437 | if (*field_ptr) |
438 | *master_reclength = (ulong)((*field_ptr)->ptr - table->record[0]); |
439 | else |
440 | *master_reclength = table->s->reclength; |
441 | } |
442 | |
443 | DBUG_RETURN(0); |
444 | } |
445 | |
446 | /** |
447 | Fills @c table->record[0] with default values. |
448 | |
449 | First @c restore_record() is called to restore the default values for |
450 | record concerning the given table. Then, if @c check is true, |
451 | a check is performed to see if fields are have default value or can |
452 | be NULL. Otherwise error is reported. |
453 | |
454 | @param table Table whose record[0] buffer is prepared. |
455 | @param skip Number of columns for which default/nullable check |
456 | should be skipped. |
457 | @param check Specifies if lack of default error needs checking. |
458 | |
459 | @returns 0 on success or a handler level error code |
460 | */ |
461 | int prepare_record(TABLE *const table, const uint skip, const bool check) |
462 | { |
463 | DBUG_ENTER("prepare_record" ); |
464 | |
465 | restore_record(table, s->default_values); |
466 | |
467 | /* |
468 | This skip should be revisited in 6.0, because in 6.0 RBR one |
469 | can have holes in the row (as the grain of the writeset is |
470 | the column and not the entire row). |
471 | */ |
472 | if (skip >= table->s->fields || !check) |
473 | DBUG_RETURN(0); |
474 | |
475 | /* |
476 | For fields the extra fields on the slave, we check if they have a default. |
477 | The check follows the same rules as the INSERT query without specifying an |
478 | explicit value for a field not having the explicit default |
479 | (@c check_that_all_fields_are_given_values()). |
480 | */ |
481 | for (Field **field_ptr= table->field+skip; *field_ptr; ++field_ptr) |
482 | { |
483 | Field *const f= *field_ptr; |
484 | if ((f->flags & NO_DEFAULT_VALUE_FLAG) && |
485 | (f->real_type() != MYSQL_TYPE_ENUM)) |
486 | { |
487 | THD *thd= f->table->in_use; |
488 | f->set_default(); |
489 | push_warning_printf(thd, |
490 | Sql_condition::WARN_LEVEL_WARN, |
491 | ER_NO_DEFAULT_FOR_FIELD, |
492 | ER_THD(thd, ER_NO_DEFAULT_FOR_FIELD), |
493 | f->field_name.str); |
494 | } |
495 | } |
496 | |
497 | DBUG_RETURN(0); |
498 | } |
499 | /** |
500 | Fills @c table->record[0] with computed values of extra persistent column which are present on slave but not on master. |
501 | @param table Table whose record[0] buffer is prepared. |
502 | @param master_cols No of columns on master |
503 | @returns 0 on success |
504 | */ |
505 | int fill_extra_persistent_columns(TABLE *table, int master_cols) |
506 | { |
507 | int error= 0; |
508 | Field **vfield_ptr, *vfield; |
509 | |
510 | if (!table->vfield) |
511 | return 0; |
512 | for (vfield_ptr= table->vfield; *vfield_ptr; ++vfield_ptr) |
513 | { |
514 | vfield= *vfield_ptr; |
515 | if (vfield->field_index >= master_cols && vfield->stored_in_db()) |
516 | { |
517 | /*Set bitmap for writing*/ |
518 | bitmap_set_bit(table->vcol_set, vfield->field_index); |
519 | error= vfield->vcol_info->expr->save_in_field(vfield,0); |
520 | bitmap_clear_bit(table->vcol_set, vfield->field_index); |
521 | } |
522 | } |
523 | return error; |
524 | } |
525 | #endif // HAVE_REPLICATION |
526 | |