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