mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / sql / rpl_record_old.cc
blobf861ffb10f7f7d0365d3a3c61ed35e4acfdebc62
1 /* Copyright (c) 2007 MySQL AB
2 Use is subject to license terms.
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.
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.
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 */
17 #include "mysql_priv.h"
18 #include "rpl_rli.h"
19 #include "rpl_record_old.h"
21 size_t
22 pack_row_old(TABLE *table, MY_BITMAP const* cols,
23 uchar *row_data, const uchar *record)
25 Field **p_field= table->field, *field;
26 int n_null_bytes= table->s->null_bytes;
27 uchar *ptr;
28 uint i;
29 my_ptrdiff_t const rec_offset= record - table->record[0];
30 my_ptrdiff_t const def_offset= table->s->default_values - table->record[0];
31 memcpy(row_data, record, n_null_bytes);
32 ptr= row_data+n_null_bytes;
34 for (i= 0 ; (field= *p_field) ; i++, p_field++)
36 if (bitmap_is_set(cols,i))
38 my_ptrdiff_t const offset=
39 field->is_null(rec_offset) ? def_offset : rec_offset;
40 field->move_field_offset(offset);
41 ptr= field->pack(ptr, field->ptr);
42 field->move_field_offset(-offset);
45 return (static_cast<size_t>(ptr - row_data));
50 Unpack a row into a record.
52 SYNOPSIS
53 unpack_row()
54 rli Relay log info
55 table Table to unpack into
56 colcnt Number of columns to read from record
57 record Record where the data should be unpacked
58 row Packed row data
59 cols Pointer to columns data to fill in
60 row_end Pointer to variable that will hold the value of the
61 one-after-end position for the row
62 master_reclength
63 Pointer to variable that will be set to the length of the
64 record on the master side
65 rw_set Pointer to bitmap that holds either the read_set or the
66 write_set of the table
68 DESCRIPTION
70 The row is assumed to only consist of the fields for which the
71 bitset represented by 'arr' and 'bits'; the other parts of the
72 record are left alone.
74 At most 'colcnt' columns are read: if the table is larger than
75 that, the remaining fields are not filled in.
77 RETURN VALUE
79 Error code, or zero if no error. The following error codes can
80 be returned:
82 ER_NO_DEFAULT_FOR_FIELD
83 Returned if one of the fields existing on the slave but not on
84 the master does not have a default value (and isn't nullable)
86 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
87 int
88 unpack_row_old(Relay_log_info *rli,
89 TABLE *table, uint const colcnt, uchar *record,
90 uchar const *row, MY_BITMAP const *cols,
91 uchar const **row_end, ulong *master_reclength,
92 MY_BITMAP* const rw_set, Log_event_type const event_type)
94 DBUG_ASSERT(record && row);
95 my_ptrdiff_t const offset= record - (uchar*) table->record[0];
96 size_t master_null_bytes= table->s->null_bytes;
98 if (colcnt != table->s->fields)
100 Field **fptr= &table->field[colcnt-1];
102 master_null_bytes= (*fptr)->last_null_byte();
103 while (master_null_bytes == Field::LAST_NULL_BYTE_UNDEF &&
104 fptr-- > table->field);
107 If master_null_bytes is LAST_NULL_BYTE_UNDEF (0) at this time,
108 there were no nullable fields nor BIT fields at all in the
109 columns that are common to the master and the slave. In that
110 case, there is only one null byte holding the X bit.
112 OBSERVE! There might still be nullable columns following the
113 common columns, so table->s->null_bytes might be greater than 1.
115 if (master_null_bytes == Field::LAST_NULL_BYTE_UNDEF)
116 master_null_bytes= 1;
119 DBUG_ASSERT(master_null_bytes <= table->s->null_bytes);
120 memcpy(record, row, master_null_bytes); // [1]
121 int error= 0;
123 bitmap_set_all(rw_set);
125 Field **const begin_ptr = table->field;
126 Field **field_ptr;
127 uchar const *ptr= row + master_null_bytes;
128 Field **const end_ptr= begin_ptr + colcnt;
129 for (field_ptr= begin_ptr ; field_ptr < end_ptr ; ++field_ptr)
131 Field *const f= *field_ptr;
133 if (bitmap_is_set(cols, field_ptr - begin_ptr))
135 f->move_field_offset(offset);
136 ptr= f->unpack(f->ptr, ptr);
137 f->move_field_offset(-offset);
138 /* Field...::unpack() cannot return 0 */
139 DBUG_ASSERT(ptr != NULL);
141 else
142 bitmap_clear_bit(rw_set, field_ptr - begin_ptr);
145 *row_end = ptr;
146 if (master_reclength)
148 if (*field_ptr)
149 *master_reclength = (*field_ptr)->ptr - table->record[0];
150 else
151 *master_reclength = table->s->reclength;
155 Set properties for remaining columns, if there are any. We let the
156 corresponding bit in the write_set be set, to write the value if
157 it was not there already. We iterate over all remaining columns,
158 even if there were an error, to get as many error messages as
159 possible. We are still able to return a pointer to the next row,
160 so redo that.
162 This generation of error messages is only relevant when inserting
163 new rows.
165 for ( ; *field_ptr ; ++field_ptr)
167 uint32 const mask= NOT_NULL_FLAG | NO_DEFAULT_VALUE_FLAG;
169 DBUG_PRINT("debug", ("flags = 0x%x, mask = 0x%x, flags & mask = 0x%x",
170 (*field_ptr)->flags, mask,
171 (*field_ptr)->flags & mask));
173 if (event_type == WRITE_ROWS_EVENT &&
174 ((*field_ptr)->flags & mask) == mask)
176 rli->report(ERROR_LEVEL, ER_NO_DEFAULT_FOR_FIELD,
177 "Field `%s` of table `%s`.`%s` "
178 "has no default value and cannot be NULL",
179 (*field_ptr)->field_name, table->s->db.str,
180 table->s->table_name.str);
181 error = ER_NO_DEFAULT_FOR_FIELD;
183 else
184 (*field_ptr)->set_default();
187 return error;
189 #endif