MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rpl_record.cc
1 /* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software Foundation,
14  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15 
16 #include "sql_priv.h"
17 #include "unireg.h"
18 #include "rpl_rli.h"
19 #include "rpl_record.h"
20 #include "rpl_slave.h" // Need to pull in slave_print_msg
21 #include "rpl_utility.h"
22 #include "rpl_rli.h"
23 
24 using std::min;
25 using std::max;
26 
60 #if !defined(MYSQL_CLIENT)
61 size_t
62 pack_row(TABLE *table, MY_BITMAP const* cols,
63  uchar *row_data, const uchar *record)
64 {
65  Field **p_field= table->field, *field;
66  int const null_byte_count= (bitmap_bits_set(cols) + 7) / 8;
67  uchar *pack_ptr = row_data + null_byte_count;
68  uchar *null_ptr = row_data;
69  my_ptrdiff_t const rec_offset= record - table->record[0];
70  my_ptrdiff_t const def_offset= table->s->default_values - table->record[0];
71 
72  DBUG_ENTER("pack_row");
73 
74  /*
75  We write the null bits and the packed records using one pass
76  through all the fields. The null bytes are written little-endian,
77  i.e., the first fields are in the first byte.
78  */
79  unsigned int null_bits= (1U << 8) - 1;
80  // Mask to mask out the correct but among the null bits
81  unsigned int null_mask= 1U;
82  DBUG_PRINT("debug", ("null ptr: 0x%lx; row start: %p; null bytes: %d",
83  (ulong) null_ptr, row_data, null_byte_count));
84  DBUG_DUMP("cols", (uchar*) cols->bitmap, cols->last_word_ptr - cols->bitmap + 1);
85  for ( ; (field= *p_field) ; p_field++)
86  {
87  if (bitmap_is_set(cols, p_field - table->field))
88  {
89  my_ptrdiff_t offset;
90  if (field->is_null(rec_offset))
91  {
92  DBUG_PRINT("debug", ("Is NULL; null_mask: 0x%x; null_bits: 0x%x",
93  null_mask, null_bits));
94  offset= def_offset;
95  null_bits |= null_mask;
96  }
97  else
98  {
99  offset= rec_offset;
100  null_bits &= ~null_mask;
101 
102  /*
103  We only store the data of the field if it is non-null
104 
105  For big-endian machines, we have to make sure that the
106  length is stored in little-endian format, since this is the
107  format used for the binlog.
108  */
109 #ifndef DBUG_OFF
110  const uchar *old_pack_ptr= pack_ptr;
111 #endif
112  pack_ptr= field->pack(pack_ptr, field->ptr + offset,
113  field->max_data_length(), TRUE);
114  DBUG_PRINT("debug", ("field: %s; real_type: %d, pack_ptr: 0x%lx;"
115  " pack_ptr':0x%lx; bytes: %d",
116  field->field_name, field->real_type(),
117  (ulong) old_pack_ptr, (ulong) pack_ptr,
118  (int) (pack_ptr - old_pack_ptr)));
119  DBUG_DUMP("packed_data", old_pack_ptr, pack_ptr - old_pack_ptr);
120  }
121 
122  null_mask <<= 1;
123  if ((null_mask & 0xFF) == 0)
124  {
125  DBUG_ASSERT(null_ptr < row_data + null_byte_count);
126  null_mask = 1U;
127  *null_ptr++ = null_bits;
128  null_bits= (1U << 8) - 1;
129  }
130  }
131 #ifndef DBUG_OFF
132  else
133  {
134  DBUG_PRINT("debug", ("Skipped"));
135  }
136 #endif
137  }
138 
139  /*
140  Write the last (partial) byte, if there is one
141  */
142  if ((null_mask & 0xFF) > 1)
143  {
144  DBUG_ASSERT(null_ptr < row_data + null_byte_count);
145  *null_ptr++ = null_bits;
146  }
147 
148  /*
149  The null pointer should now point to the first byte of the
150  packed data. If it doesn't, something is very wrong.
151  */
152  DBUG_ASSERT(null_ptr == row_data + null_byte_count);
153  DBUG_DUMP("row_data", row_data, pack_ptr - row_data);
154  DBUG_RETURN(static_cast<size_t>(pack_ptr - row_data));
155 }
156 #endif
157 
158 
197 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
198 int
199 unpack_row(Relay_log_info const *rli,
200  TABLE *table, uint const colcnt,
201  uchar const *const row_data, MY_BITMAP const *cols,
202  uchar const **const row_end, ulong *const master_reclength)
203 {
204  DBUG_ENTER("unpack_row");
205  DBUG_ASSERT(row_data);
206  DBUG_ASSERT(table);
207  size_t const master_null_byte_count= (bitmap_bits_set(cols) + 7) / 8;
208  int error= 0;
209 
210  uchar const *null_ptr= row_data;
211  uchar const *pack_ptr= row_data + master_null_byte_count;
212 
213  if (bitmap_is_clear_all(cols))
214  {
219  *row_end= pack_ptr;
220  *master_reclength= 0;
221  DBUG_RETURN(error);
222  }
223 
224 
225  Field **const begin_ptr = table->field;
226  Field **field_ptr;
227  Field **const end_ptr= begin_ptr + colcnt;
228 
229  DBUG_ASSERT(null_ptr < row_data + master_null_byte_count);
230 
231  // Mask to mask out the correct bit among the null bits
232  unsigned int null_mask= 1U;
233  // The "current" null bits
234  unsigned int null_bits= *null_ptr++;
235  uint i= 0;
236  table_def *tabledef= NULL;
237  TABLE *conv_table= NULL;
238  bool table_found= rli && rli->get_table_data(table, &tabledef, &conv_table);
239  DBUG_PRINT("debug", ("Table data: table_found: %d, tabldef: %p, conv_table: %p",
240  table_found, tabledef, conv_table));
241  DBUG_ASSERT(table_found);
242 
243  /*
244  If rli is NULL it means that there is no source table and that the
245  row shall just be unpacked without doing any checks. This feature
246  is used by MySQL Backup, but can be used for other purposes as
247  well.
248  */
249  if (rli && !table_found)
250  DBUG_RETURN(HA_ERR_GENERIC);
251 
252  for (field_ptr= begin_ptr ; field_ptr < end_ptr && *field_ptr ; ++field_ptr)
253  {
254  /*
255  If there is a conversion table, we pick up the field pointer to
256  the conversion table. If the conversion table or the field
257  pointer is NULL, no conversions are necessary.
258  */
259  Field *conv_field=
260  conv_table ? conv_table->field[field_ptr - begin_ptr] : NULL;
261  Field *const f=
262  conv_field ? conv_field : *field_ptr;
263  DBUG_PRINT("debug", ("Conversion %srequired for field '%s' (#%ld)",
264  conv_field ? "" : "not ",
265  (*field_ptr)->field_name,
266  (long) (field_ptr - begin_ptr)));
267  DBUG_ASSERT(f != NULL);
268 
269  DBUG_PRINT("debug", ("field: %s; null mask: 0x%x; null bits: 0x%lx;"
270  " row start: %p; null bytes: %ld",
271  f->field_name, null_mask, (ulong) null_bits,
272  pack_ptr, (ulong) master_null_byte_count));
273 
274  /*
275  No need to bother about columns that does not exist: they have
276  gotten default values when being emptied above.
277  */
278  if (bitmap_is_set(cols, field_ptr - begin_ptr))
279  {
280  if ((null_mask & 0xFF) == 0)
281  {
282  DBUG_ASSERT(null_ptr < row_data + master_null_byte_count);
283  null_mask= 1U;
284  null_bits= *null_ptr++;
285  }
286 
287  DBUG_ASSERT(null_mask & 0xFF); // One of the 8 LSB should be set
288 
289  /* Field...::unpack() cannot return 0 */
290  DBUG_ASSERT(pack_ptr != NULL);
291 
292  if (null_bits & null_mask)
293  {
294  if (f->maybe_null())
295  {
296  DBUG_PRINT("debug", ("Was NULL; null mask: 0x%x; null bits: 0x%x",
297  null_mask, null_bits));
313  f->reset();
314  f->set_null();
315  }
316  else
317  {
318  f->set_default();
319  push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
320  ER_BAD_NULL_ERROR, ER(ER_BAD_NULL_ERROR),
321  f->field_name);
322  }
323  }
324  else
325  {
326  f->set_notnull();
327 
328  /*
329  We only unpack the field if it was non-null.
330  Use the master's size information if available else call
331  normal unpack operation.
332  */
333  uint16 const metadata= tabledef->field_metadata(i);
334 #ifndef DBUG_OFF
335  uchar const *const old_pack_ptr= pack_ptr;
336 #endif
337  pack_ptr= f->unpack(f->ptr, pack_ptr, metadata, TRUE);
338  DBUG_PRINT("debug", ("Unpacked; metadata: 0x%x;"
339  " pack_ptr: 0x%lx; pack_ptr': 0x%lx; bytes: %d",
340  metadata, (ulong) old_pack_ptr, (ulong) pack_ptr,
341  (int) (pack_ptr - old_pack_ptr)));
342 
343  /*
344  The raw size of the field, as calculated in calc_field_size,
345  should match the one reported by Field_*::unpack unless it is
346  a old decimal data type which is unsupported datatype in
347  RBR mode.
348  */
349  DBUG_ASSERT(tabledef->type(i) == MYSQL_TYPE_DECIMAL ||
350  tabledef->calc_field_size(i, (uchar *) old_pack_ptr) ==
351  (uint32) (pack_ptr - old_pack_ptr));
352  }
353 
354  /*
355  If conv_field is set, then we are doing a conversion. In this
356  case, we have unpacked the master data to the conversion
357  table, so we need to copy the value stored in the conversion
358  table into the final table and do the conversion at the same time.
359  */
360  if (conv_field)
361  {
362  Copy_field copy;
363 #ifndef DBUG_OFF
364  char source_buf[MAX_FIELD_WIDTH];
365  char value_buf[MAX_FIELD_WIDTH];
366  String source_type(source_buf, sizeof(source_buf), system_charset_info);
367  String value_string(value_buf, sizeof(value_buf), system_charset_info);
368  conv_field->sql_type(source_type);
369  conv_field->val_str(&value_string);
370  DBUG_PRINT("debug", ("Copying field '%s' of type '%s' with value '%s'",
371  (*field_ptr)->field_name,
372  source_type.c_ptr_safe(), value_string.c_ptr_safe()));
373 #endif
374  copy.set(*field_ptr, f, TRUE);
375  (*copy.do_copy)(&copy);
376 #ifndef DBUG_OFF
377  char target_buf[MAX_FIELD_WIDTH];
378  String target_type(target_buf, sizeof(target_buf), system_charset_info);
379  (*field_ptr)->sql_type(target_type);
380  (*field_ptr)->val_str(&value_string);
381  DBUG_PRINT("debug", ("Value of field '%s' of type '%s' is now '%s'",
382  (*field_ptr)->field_name,
383  target_type.c_ptr_safe(), value_string.c_ptr_safe()));
384 #endif
385  }
386 
387  null_mask <<= 1;
388  }
389 #ifndef DBUG_OFF
390  else
391  {
392  DBUG_PRINT("debug", ("Non-existent: skipped"));
393  }
394 #endif
395  i++;
396  }
397 
398  /*
399  throw away master's extra fields
400  */
401  uint max_cols= min<ulong>(tabledef->size(), cols->n_bits);
402  for (; i < max_cols; i++)
403  {
404  if (bitmap_is_set(cols, i))
405  {
406  if ((null_mask & 0xFF) == 0)
407  {
408  DBUG_ASSERT(null_ptr < row_data + master_null_byte_count);
409  null_mask= 1U;
410  null_bits= *null_ptr++;
411  }
412  DBUG_ASSERT(null_mask & 0xFF); // One of the 8 LSB should be set
413 
414  if (!((null_bits & null_mask) && tabledef->maybe_null(i))) {
415  uint32 len= tabledef->calc_field_size(i, (uchar *) pack_ptr);
416  DBUG_DUMP("field_data", pack_ptr, len);
417  pack_ptr+= len;
418  }
419  null_mask <<= 1;
420  }
421  }
422 
423  /*
424  We should now have read all the null bytes, otherwise something is
425  really wrong.
426  */
427  DBUG_ASSERT(null_ptr == row_data + master_null_byte_count);
428 
429  DBUG_DUMP("row_data", row_data, pack_ptr - row_data);
430 
431  *row_end = pack_ptr;
432  if (master_reclength)
433  {
434  if (*field_ptr)
435  *master_reclength = (*field_ptr)->ptr - table->record[0];
436  else
437  *master_reclength = table->s->reclength;
438  }
439 
440  DBUG_RETURN(error);
441 }
442 
456 int prepare_record(TABLE *const table, const MY_BITMAP *cols, const bool check)
457 {
458  DBUG_ENTER("prepare_record");
459 
460  restore_record(table, s->default_values);
461 
462  if (!check)
463  DBUG_RETURN(0);
464 
465  /*
466  For fields the extra fields on the slave, we check if they have a default.
467  The check follows the same rules as the INSERT query without specifying an
468  explicit value for a field not having the explicit default
469  (@c check_that_all_fields_are_given_values()).
470  */
471 
472  DBUG_PRINT_BITSET("debug", "cols: %s", cols);
473  for (Field **field_ptr= table->field; *field_ptr; ++field_ptr)
474  {
475  if ((uint) (field_ptr - table->field) >= cols->n_bits ||
476  !bitmap_is_set(cols, field_ptr - table->field))
477  {
478  Field *const f= *field_ptr;
479  if ((f->flags & NO_DEFAULT_VALUE_FLAG) &&
480  (f->real_type() != MYSQL_TYPE_ENUM))
481  {
482  f->set_default();
483  push_warning_printf(current_thd,
484  Sql_condition::WARN_LEVEL_WARN,
485  ER_NO_DEFAULT_FOR_FIELD,
486  ER(ER_NO_DEFAULT_FOR_FIELD),
487  f->field_name);
488  }
489  }
490  }
491 
492  DBUG_RETURN(0);
493 }
494 
495 #endif // HAVE_REPLICATION