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-1335 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 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 ER_SLAVE_CORRUPT_EVENT 87 Wrong data for field found. 88 */ 89 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) 90 int 91 unpack_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