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 "mariadb.h"
17#include "sql_priv.h"
18#include "rpl_rli.h"
19#include "rpl_record_old.h"
20#include "log_event.h" // Log_event_type
21
22size_t
23pack_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 ER_SLAVE_CORRUPT_EVENT
87 Wrong data for field found.
88 */
89#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
90int
91unpack_row_old(rpl_group_info *rgi,
92 TABLE *table, uint const colcnt, uchar *record,
93 uchar const *row, const uchar *row_buffer_end,
94 MY_BITMAP const *cols,
95 uchar const **row_end, ulong *master_reclength,
96 MY_BITMAP* const rw_set, Log_event_type const event_type)
97{
98 DBUG_ASSERT(record && row);
99 my_ptrdiff_t const offset= record - (uchar*) table->record[0];
100 size_t master_null_bytes= table->s->null_bytes;
101
102 if (colcnt != table->s->fields)
103 {
104 Field **fptr= &table->field[colcnt-1];
105 do
106 master_null_bytes= (*fptr)->last_null_byte();
107 while (master_null_bytes == Field::LAST_NULL_BYTE_UNDEF &&
108 fptr-- > table->field);
109
110 /*
111 If master_null_bytes is LAST_NULL_BYTE_UNDEF (0) at this time,
112 there were no nullable fields nor BIT fields at all in the
113 columns that are common to the master and the slave. In that
114 case, there is only one null byte holding the X bit.
115
116 OBSERVE! There might still be nullable columns following the
117 common columns, so table->s->null_bytes might be greater than 1.
118 */
119 if (master_null_bytes == Field::LAST_NULL_BYTE_UNDEF)
120 master_null_bytes= 1;
121 }
122
123 DBUG_ASSERT(master_null_bytes <= table->s->null_bytes);
124 memcpy(record, row, master_null_bytes); // [1]
125 int error= 0;
126
127 bitmap_set_all(rw_set);
128
129 Field **const begin_ptr = table->field;
130 Field **field_ptr;
131 uchar const *ptr= row + master_null_bytes;
132 Field **const end_ptr= begin_ptr + colcnt;
133 for (field_ptr= begin_ptr ; field_ptr < end_ptr ; ++field_ptr)
134 {
135 Field *const f= *field_ptr;
136
137 if (bitmap_is_set(cols, (uint)(field_ptr - begin_ptr)))
138 {
139 f->move_field_offset(offset);
140 ptr= f->unpack(f->ptr, ptr, row_buffer_end, 0);
141 f->move_field_offset(-offset);
142 if (!ptr)
143 {
144 rgi->rli->report(ERROR_LEVEL, ER_SLAVE_CORRUPT_EVENT, NULL,
145 "Could not read field `%s` of table `%s`.`%s`",
146 f->field_name.str, table->s->db.str,
147 table->s->table_name.str);
148 return(ER_SLAVE_CORRUPT_EVENT);
149 }
150 }
151 else
152 bitmap_clear_bit(rw_set, (uint)(field_ptr - begin_ptr));
153 }
154
155 *row_end = ptr;
156 if (master_reclength)
157 {
158 if (*field_ptr)
159 *master_reclength = (ulong)((*field_ptr)->ptr - table->record[0]);
160 else
161 *master_reclength = table->s->reclength;
162 }
163
164 /*
165 Set properties for remaining columns, if there are any. We let the
166 corresponding bit in the write_set be set, to write the value if
167 it was not there already. We iterate over all remaining columns,
168 even if there were an error, to get as many error messages as
169 possible. We are still able to return a pointer to the next row,
170 so redo that.
171
172 This generation of error messages is only relevant when inserting
173 new rows.
174 */
175 for ( ; *field_ptr ; ++field_ptr)
176 {
177 uint32 const mask= NOT_NULL_FLAG | NO_DEFAULT_VALUE_FLAG;
178
179 DBUG_PRINT("debug", ("flags = 0x%x, mask = 0x%x, flags & mask = 0x%x",
180 (*field_ptr)->flags, mask,
181 (*field_ptr)->flags & mask));
182
183 if (event_type == WRITE_ROWS_EVENT &&
184 ((*field_ptr)->flags & mask) == mask)
185 {
186 rgi->rli->report(ERROR_LEVEL, ER_NO_DEFAULT_FOR_FIELD, NULL,
187 "Field `%s` of table `%s`.`%s` "
188 "has no default value and cannot be NULL",
189 (*field_ptr)->field_name.str, table->s->db.str,
190 table->s->table_name.str);
191 error = ER_NO_DEFAULT_FOR_FIELD;
192 }
193 else
194 (*field_ptr)->set_default();
195 }
196
197 return error;
198}
199#endif
200