MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rpl_record_old.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
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 #include "sql_priv.h"
17 #include "unireg.h" // REQUIRED by other includes
18 #include "rpl_rli.h"
19 #include "rpl_record_old.h"
20 #include "log_event.h" // Log_event_type
21 
22 size_t
23 pack_row_old(TABLE *table, MY_BITMAP const* cols,
24  uchar *row_data, const uchar *record)
25 {
26  Field **p_field= table->field, *field;
27  int n_null_bytes= table->s->null_bytes;
28  uchar *ptr;
29  uint i;
30  my_ptrdiff_t const rec_offset= record - table->record[0];
31  my_ptrdiff_t const def_offset= table->s->default_values - table->record[0];
32  memcpy(row_data, record, n_null_bytes);
33  ptr= row_data+n_null_bytes;
34 
35  for (i= 0 ; (field= *p_field) ; i++, p_field++)
36  {
37  if (bitmap_is_set(cols,i))
38  {
39  my_ptrdiff_t const offset=
40  field->is_null(rec_offset) ? def_offset : rec_offset;
41  field->move_field_offset(offset);
42  ptr= field->pack(ptr, field->ptr);
43  field->move_field_offset(-offset);
44  }
45  }
46  return (static_cast<size_t>(ptr - row_data));
47 }
48 
49 
50 /*
51  Unpack a row into a record.
52 
53  SYNOPSIS
54  unpack_row()
55  rli Relay log info
56  table Table to unpack into
57  colcnt Number of columns to read from record
58  record Record where the data should be unpacked
59  row Packed row data
60  cols Pointer to columns data to fill in
61  row_end Pointer to variable that will hold the value of the
62  one-after-end position for the row
63  master_reclength
64  Pointer to variable that will be set to the length of the
65  record on the master side
66  rw_set Pointer to bitmap that holds either the read_set or the
67  write_set of the table
68 
69  DESCRIPTION
70 
71  The row is assumed to only consist of the fields for which the
72  bitset represented by 'arr' and 'bits'; the other parts of the
73  record are left alone.
74 
75  At most 'colcnt' columns are read: if the table is larger than
76  that, the remaining fields are not filled in.
77 
78  RETURN VALUE
79 
80  Error code, or zero if no error. The following error codes can
81  be returned:
82 
83  ER_NO_DEFAULT_FOR_FIELD
84  Returned if one of the fields existing on the slave but not on
85  the master does not have a default value (and isn't nullable)
86  */
87 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
88 int
89 unpack_row_old(Relay_log_info *rli,
90  TABLE *table, uint const colcnt, uchar *record,
91  uchar const *row, MY_BITMAP const *cols,
92  uchar const **row_end, ulong *master_reclength,
93  MY_BITMAP* const rw_set, Log_event_type const event_type)
94 {
95  DBUG_ASSERT(record && row);
96  my_ptrdiff_t const offset= record - (uchar*) table->record[0];
97  size_t master_null_bytes= table->s->null_bytes;
98 
99  if (colcnt != table->s->fields)
100  {
101  Field **fptr= &table->field[colcnt-1];
102  do
103  master_null_bytes= (*fptr)->last_null_byte();
104  while (master_null_bytes == Field::LAST_NULL_BYTE_UNDEF &&
105  fptr-- > table->field);
106 
107  /*
108  If master_null_bytes is LAST_NULL_BYTE_UNDEF (0) at this time,
109  there were no nullable fields nor BIT fields at all in the
110  columns that are common to the master and the slave. In that
111  case, there is only one null byte holding the X bit.
112 
113  OBSERVE! There might still be nullable columns following the
114  common columns, so table->s->null_bytes might be greater than 1.
115  */
116  if (master_null_bytes == Field::LAST_NULL_BYTE_UNDEF)
117  master_null_bytes= 1;
118  }
119 
120  DBUG_ASSERT(master_null_bytes <= table->s->null_bytes);
121  memcpy(record, row, master_null_bytes); // [1]
122  int error= 0;
123 
124  bitmap_set_all(rw_set);
125 
126  Field **const begin_ptr = table->field;
127  Field **field_ptr;
128  uchar const *ptr= row + master_null_bytes;
129  Field **const end_ptr= begin_ptr + colcnt;
130  for (field_ptr= begin_ptr ; field_ptr < end_ptr ; ++field_ptr)
131  {
132  Field *const f= *field_ptr;
133 
134  if (bitmap_is_set(cols, field_ptr - begin_ptr))
135  {
136  f->move_field_offset(offset);
137  ptr= f->unpack(f->ptr, ptr);
138  f->move_field_offset(-offset);
139  /* Field...::unpack() cannot return 0 */
140  DBUG_ASSERT(ptr != NULL);
141  }
142  else
143  bitmap_clear_bit(rw_set, field_ptr - begin_ptr);
144  }
145 
146  *row_end = ptr;
147  if (master_reclength)
148  {
149  if (*field_ptr)
150  *master_reclength = (*field_ptr)->ptr - table->record[0];
151  else
152  *master_reclength = table->s->reclength;
153  }
154 
155  /*
156  Set properties for remaining columns, if there are any. We let the
157  corresponding bit in the write_set be set, to write the value if
158  it was not there already. We iterate over all remaining columns,
159  even if there were an error, to get as many error messages as
160  possible. We are still able to return a pointer to the next row,
161  so redo that.
162 
163  This generation of error messages is only relevant when inserting
164  new rows.
165  */
166  for ( ; *field_ptr ; ++field_ptr)
167  {
168  uint32 const mask= NOT_NULL_FLAG | NO_DEFAULT_VALUE_FLAG;
169 
170  DBUG_PRINT("debug", ("flags = 0x%x, mask = 0x%x, flags & mask = 0x%x",
171  (*field_ptr)->flags, mask,
172  (*field_ptr)->flags & mask));
173 
174  if (event_type == WRITE_ROWS_EVENT &&
175  ((*field_ptr)->flags & mask) == mask)
176  {
177  rli->report(ERROR_LEVEL, ER_NO_DEFAULT_FOR_FIELD,
178  "Field `%s` of table `%s`.`%s` "
179  "has no default value and cannot be NULL",
180  (*field_ptr)->field_name, table->s->db.str,
181  table->s->table_name.str);
182  error = ER_NO_DEFAULT_FOR_FIELD;
183  }
184  else
185  (*field_ptr)->set_default();
186  }
187 
188  return error;
189 }
190 #endif