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