~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright 2007 MySQL AB. 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
#include "mysql_priv.h"
17
#include "rpl_rli.h"
18
#include "rpl_record.h"
19
#include "slave.h"                  // Need to pull in slave_print_msg
20
#include "rpl_utility.h"
21
#include "rpl_rli.h"
22
23
/**
24
   Pack a record of data for a table into a format suitable for
25
   transfer via the binary log.
26
27
   The format for a row in transfer with N fields is the following:
28
29
   ceil(N/8) null bytes:
30
       One null bit for every column *regardless of whether it can be
31
       null or not*. This simplifies the decoding. Observe that the
32
       number of null bits is equal to the number of set bits in the
33
       @c cols bitmap. The number of null bytes is the smallest number
34
       of bytes necessary to store the null bits.
35
36
       Padding bits are 1.
37
38
   N packets:
39
       Each field is stored in packed format.
40
41
42
   @param table    Table describing the format of the record
43
44
   @param cols     Bitmap with a set bit for each column that should
45
                   be stored in the row
46
47
   @param row_data Pointer to memory where row will be written
48
49
   @param record   Pointer to record that should be packed. It is
50
                   assumed that the pointer refers to either @c
51
                   record[0] or @c record[1], but no such check is
52
                   made since the code does not rely on that.
53
54
   @return The number of bytes written at @c row_data.
55
 */
56
#if !defined(MYSQL_CLIENT)
57
size_t
58
pack_row(TABLE *table, MY_BITMAP const* cols,
59
         uchar *row_data, const uchar *record)
60
{
61
  Field **p_field= table->field, *field;
62
  int const null_byte_count= (bitmap_bits_set(cols) + 7) / 8;
63
  uchar *pack_ptr = row_data + null_byte_count;
64
  uchar *null_ptr = row_data;
65
  my_ptrdiff_t const rec_offset= record - table->record[0];
66
  my_ptrdiff_t const def_offset= table->s->default_values - table->record[0];
67
68
69
  /*
70
    We write the null bits and the packed records using one pass
71
    through all the fields. The null bytes are written little-endian,
72
    i.e., the first fields are in the first byte.
73
   */
74
  unsigned int null_bits= (1U << 8) - 1;
75
  // Mask to mask out the correct but among the null bits
76
  unsigned int null_mask= 1U;
77
  for ( ; (field= *p_field) ; p_field++)
78
  {
79
    if (bitmap_is_set(cols, p_field - table->field))
80
    {
81
      my_ptrdiff_t offset;
82
      if (field->is_null(rec_offset))
83
      {
84
        offset= def_offset;
85
        null_bits |= null_mask;
86
      }
87
      else
88
      {
89
        offset= rec_offset;
90
        null_bits &= ~null_mask;
91
92
        /*
93
          We only store the data of the field if it is non-null
94
95
          For big-endian machines, we have to make sure that the
96
          length is stored in little-endian format, since this is the
97
          format used for the binlog.
98
        */
99
        const uchar *old_pack_ptr= pack_ptr;
100
        pack_ptr= field->pack(pack_ptr, field->ptr + offset,
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
101
                              field->max_data_length(), true);
1 by brian
clean slate
102
      }
103
104
      null_mask <<= 1;
105
      if ((null_mask & 0xFF) == 0)
106
      {
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
107
        assert(null_ptr < row_data + null_byte_count);
1 by brian
clean slate
108
        null_mask = 1U;
109
        *null_ptr++ = null_bits;
110
        null_bits= (1U << 8) - 1;
111
      }
112
    }
51.1.2 by Jay Pipes
Fixed unbalanced parentheses in pack_row due to merge conflict resolution mistake
113
  }
1 by brian
clean slate
114
115
  /*
116
    Write the last (partial) byte, if there is one
117
  */
118
  if ((null_mask & 0xFF) > 1)
119
  {
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
120
    assert(null_ptr < row_data + null_byte_count);
1 by brian
clean slate
121
    *null_ptr++ = null_bits;
122
  }
123
124
  /*
125
    The null pointer should now point to the first byte of the
126
    packed data. If it doesn't, something is very wrong.
127
  */
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
128
  assert(null_ptr == row_data + null_byte_count);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
129
  return(static_cast<size_t>(pack_ptr - row_data));
1 by brian
clean slate
130
}
131
#endif
132
133
134
/**
135
   Unpack a row into @c table->record[0].
136
137
   The function will always unpack into the @c table->record[0]
138
   record.  This is because there are too many dependencies on where
139
   the various member functions of Field and subclasses expect to
140
   write.
141
142
   The row is assumed to only consist of the fields for which the corresponding
143
   bit in bitset @c cols is set; the other parts of the record are left alone.
144
145
   At most @c colcnt columns are read: if the table is larger than
146
   that, the remaining fields are not filled in.
147
148
   @param rli     Relay log info
149
   @param table   Table to unpack into
150
   @param colcnt  Number of columns to read from record
151
   @param row_data
152
                  Packed row data
153
   @param cols    Pointer to bitset describing columns to fill in
154
   @param row_end Pointer to variable that will hold the value of the
155
                  one-after-end position for the row
156
   @param master_reclength
157
                  Pointer to variable that will be set to the length of the
158
                  record on the master side
159
160
   @retval 0 No error
161
162
   @retval ER_NO_DEFAULT_FOR_FIELD
163
   Returned if one of the fields existing on the slave but not on the
164
   master does not have a default value (and isn't nullable)
165
166
 */
167
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
168
int
169
unpack_row(Relay_log_info const *rli,
170
           TABLE *table, uint const colcnt,
171
           uchar const *const row_data, MY_BITMAP const *cols,
172
           uchar const **const row_end, ulong *const master_reclength)
173
{
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
174
  assert(row_data);
1 by brian
clean slate
175
  size_t const master_null_byte_count= (bitmap_bits_set(cols) + 7) / 8;
176
  int error= 0;
177
178
  uchar const *null_ptr= row_data;
179
  uchar const *pack_ptr= row_data + master_null_byte_count;
180
181
  Field **const begin_ptr = table->field;
182
  Field **field_ptr;
183
  Field **const end_ptr= begin_ptr + colcnt;
184
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
185
  assert(null_ptr < row_data + master_null_byte_count);
1 by brian
clean slate
186
187
  // Mask to mask out the correct bit among the null bits
188
  unsigned int null_mask= 1U;
189
  // The "current" null bits
190
  unsigned int null_bits= *null_ptr++;
191
  uint i= 0;
192
193
  /*
194
    Use the rli class to get the table's metadata. If tabledef is not NULL
195
    we are processing data from a master. If tabledef is NULL then it is
196
    assumed that the packed row comes from the table to which it is
197
    unpacked.
198
  */
199
  table_def *tabledef= rli ? ((Relay_log_info*)rli)->get_tabledef(table) : 0;
200
  for (field_ptr= begin_ptr ; field_ptr < end_ptr && *field_ptr ; ++field_ptr)
201
  {
202
    Field *const f= *field_ptr;
203
204
205
    /*
206
      No need to bother about columns that does not exist: they have
207
      gotten default values when being emptied above.
208
     */
209
    if (bitmap_is_set(cols, field_ptr -  begin_ptr))
210
    {
211
      if ((null_mask & 0xFF) == 0)
212
      {
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
213
        assert(null_ptr < row_data + master_null_byte_count);
1 by brian
clean slate
214
        null_mask= 1U;
215
        null_bits= *null_ptr++;
216
      }
217
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
218
      assert(null_mask & 0xFF); // One of the 8 LSB should be set
1 by brian
clean slate
219
220
      /* Field...::unpack() cannot return 0 */
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
221
      assert(pack_ptr != NULL);
1 by brian
clean slate
222
223
      if ((null_bits & null_mask) && f->maybe_null())
224
      {
225
        f->set_null();
226
      }
227
      else
228
      {
229
        f->set_notnull();
230
231
        /*
232
          We only unpack the field if it was non-null.
233
          Use the master's size information if available else call
234
          normal unpack operation.
235
        */
236
        /*
237
          Use the master's metadata if we are processing data from a slave
238
          (tabledef not NULL). If tabledef is NULL then it is assumed that
239
          the packed row comes from the table to which it is unpacked.
240
        */
241
        uint16 metadata= tabledef ? tabledef->field_metadata(i) : 0;
242
        uchar const *const old_pack_ptr= pack_ptr;
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
243
        pack_ptr= f->unpack(f->ptr, pack_ptr, metadata, true);
1 by brian
clean slate
244
      }
245
246
      null_mask <<= 1;
247
    }
248
    i++;
249
  }
250
251
  /*
252
    throw away master's extra fields
253
254
    Use the master's max_cols if we are processing data from a slave
255
    (tabledef not NULL). If tabledef is NULL then it is assumed that
256
    there are no extra columns.
257
  */
258
  uint max_cols= tabledef ? min(tabledef->size(), cols->n_bits) : 0;
259
  for (; i < max_cols; i++)
260
  {
261
    if (bitmap_is_set(cols, i))
262
    {
263
      if ((null_mask & 0xFF) == 0)
264
      {
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
265
        assert(null_ptr < row_data + master_null_byte_count);
1 by brian
clean slate
266
        null_mask= 1U;
267
        null_bits= *null_ptr++;
268
      }
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
269
      assert(null_mask & 0xFF); // One of the 8 LSB should be set
1 by brian
clean slate
270
271
      if (!((null_bits & null_mask) && tabledef->maybe_null(i)))
272
        pack_ptr+= tabledef->calc_field_size(i, (uchar *) pack_ptr);
273
      null_mask <<= 1;
274
    }
275
  }
276
277
  /*
278
    We should now have read all the null bytes, otherwise something is
279
    really wrong.
280
   */
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
281
  assert(null_ptr == row_data + master_null_byte_count);
1 by brian
clean slate
282
283
  *row_end = pack_ptr;
284
  if (master_reclength)
285
  {
286
    if (*field_ptr)
287
      *master_reclength = (*field_ptr)->ptr - table->record[0];
288
    else
289
      *master_reclength = table->s->reclength;
290
  }
291
  
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
292
  return(error);
1 by brian
clean slate
293
}
294
295
/**
296
  Fills @c table->record[0] with default values.
297
298
  First @c empty_record() is called and then, additionally, fields are
299
  initialized explicitly with a call to @c set_default().
300
301
  For optimization reasons, the explicit initialization can be skipped
302
  for fields that are not marked in the @c cols vector. These fields
303
  will be set later, and filling them with default values is
304
  unnecessary.
305
306
  If @c check is true, fields are explicitly initialized only if they
307
  have default value or can be NULL. Otherwise error is reported. If
308
  @c check is false, no error is reported and the field is not set to
309
  any value.
310
311
  @todo When flag is added to allow engine to handle default values
312
  itself, the record should not be emptied and default values not set.
313
314
  @param table[in,out] Table whose record[0] buffer is prepared. 
315
  @param cols[in]      Vector of bits denoting columns that will be set
316
                       elsewhere
317
  @param check[in]     Indicates if errors should be checked when setting default
318
                       values.
319
320
  @retval 0                       Success
321
  @retval ER_NO_DEFAULT_FOR_FIELD Default value could not be set for a field
77.1.45 by Monty Taylor
Warning fixes.
322
*/
323
int prepare_record(TABLE *const table,
324
                   const MY_BITMAP *cols,
325
                   uint width __attribute__((__unused__)),
326
                   const bool check)
1 by brian
clean slate
327
{
328
329
  int error= 0;
330
  empty_record(table);
331
332
  /*
333
    Explicit initialization of fields. For fields that are not in the
334
    cols for the row, we set them to default. If the fields are in
335
    addition to what exists on the master, we give an error if the
336
    have no sensible default.
337
  */
338
339
  for (Field **field_ptr= table->field ; *field_ptr ; ++field_ptr)
340
  {
341
    if ((uint) (field_ptr - table->field) >= cols->n_bits ||
342
        !bitmap_is_set(cols, field_ptr - table->field))
343
    {
344
      uint32 const mask= NOT_NULL_FLAG | NO_DEFAULT_VALUE_FLAG;
345
      Field *const f= *field_ptr;
346
347
      if (check && ((f->flags & mask) == mask))
348
      {
349
        my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), f->field_name);
350
        error = HA_ERR_ROWS_EVENT_APPLY;
351
      }
352
      else
353
      {
354
        f->set_default();
355
      }
356
    }
357
  }
358
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
359
  return(error);
1 by brian
clean slate
360
}
361
362
#endif // HAVE_REPLICATION