~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to sql/rpl_record.cc

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
  DBUG_ENTER("pack_row");
 
69
 
 
70
  /*
 
71
    We write the null bits and the packed records using one pass
 
72
    through all the fields. The null bytes are written little-endian,
 
73
    i.e., the first fields are in the first byte.
 
74
   */
 
75
  unsigned int null_bits= (1U << 8) - 1;
 
76
  // Mask to mask out the correct but among the null bits
 
77
  unsigned int null_mask= 1U;
 
78
  for ( ; (field= *p_field) ; p_field++)
 
79
  {
 
80
    DBUG_PRINT("debug", ("null_mask=%d; null_ptr=%p; row_data=%p; null_byte_count=%d",
 
81
                         null_mask, null_ptr, row_data, null_byte_count));
 
82
    if (bitmap_is_set(cols, p_field - table->field))
 
83
    {
 
84
      my_ptrdiff_t offset;
 
85
      if (field->is_null(rec_offset))
 
86
      {
 
87
        offset= def_offset;
 
88
        null_bits |= null_mask;
 
89
      }
 
90
      else
 
91
      {
 
92
        offset= rec_offset;
 
93
        null_bits &= ~null_mask;
 
94
 
 
95
        /*
 
96
          We only store the data of the field if it is non-null
 
97
 
 
98
          For big-endian machines, we have to make sure that the
 
99
          length is stored in little-endian format, since this is the
 
100
          format used for the binlog.
 
101
        */
 
102
#ifndef DBUG_OFF
 
103
        const uchar *old_pack_ptr= pack_ptr;
 
104
#endif
 
105
        pack_ptr= field->pack(pack_ptr, field->ptr + offset,
 
106
                              field->max_data_length(), TRUE);
 
107
        DBUG_PRINT("debug", ("field: %s; pack_ptr: 0x%lx;"
 
108
                             " pack_ptr':0x%lx; bytes: %d",
 
109
                             field->field_name, (ulong) old_pack_ptr,
 
110
                             (ulong) pack_ptr,
 
111
                             (int) (pack_ptr - old_pack_ptr)));
 
112
      }
 
113
 
 
114
      null_mask <<= 1;
 
115
      if ((null_mask & 0xFF) == 0)
 
116
      {
 
117
        DBUG_ASSERT(null_ptr < row_data + null_byte_count);
 
118
        null_mask = 1U;
 
119
        *null_ptr++ = null_bits;
 
120
        null_bits= (1U << 8) - 1;
 
121
      }
 
122
    }
 
123
  }
 
124
 
 
125
  /*
 
126
    Write the last (partial) byte, if there is one
 
127
  */
 
128
  if ((null_mask & 0xFF) > 1)
 
129
  {
 
130
    DBUG_ASSERT(null_ptr < row_data + null_byte_count);
 
131
    *null_ptr++ = null_bits;
 
132
  }
 
133
 
 
134
  /*
 
135
    The null pointer should now point to the first byte of the
 
136
    packed data. If it doesn't, something is very wrong.
 
137
  */
 
138
  DBUG_ASSERT(null_ptr == row_data + null_byte_count);
 
139
  DBUG_DUMP("row_data", row_data, pack_ptr - row_data);
 
140
  DBUG_RETURN(static_cast<size_t>(pack_ptr - row_data));
 
141
}
 
142
#endif
 
143
 
 
144
 
 
145
/**
 
146
   Unpack a row into @c table->record[0].
 
147
 
 
148
   The function will always unpack into the @c table->record[0]
 
149
   record.  This is because there are too many dependencies on where
 
150
   the various member functions of Field and subclasses expect to
 
151
   write.
 
152
 
 
153
   The row is assumed to only consist of the fields for which the corresponding
 
154
   bit in bitset @c cols is set; the other parts of the record are left alone.
 
155
 
 
156
   At most @c colcnt columns are read: if the table is larger than
 
157
   that, the remaining fields are not filled in.
 
158
 
 
159
   @param rli     Relay log info
 
160
   @param table   Table to unpack into
 
161
   @param colcnt  Number of columns to read from record
 
162
   @param row_data
 
163
                  Packed row data
 
164
   @param cols    Pointer to bitset describing columns to fill in
 
165
   @param row_end Pointer to variable that will hold the value of the
 
166
                  one-after-end position for the row
 
167
   @param master_reclength
 
168
                  Pointer to variable that will be set to the length of the
 
169
                  record on the master side
 
170
 
 
171
   @retval 0 No error
 
172
 
 
173
   @retval ER_NO_DEFAULT_FOR_FIELD
 
174
   Returned if one of the fields existing on the slave but not on the
 
175
   master does not have a default value (and isn't nullable)
 
176
 
 
177
 */
 
178
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
 
179
int
 
180
unpack_row(Relay_log_info const *rli,
 
181
           TABLE *table, uint const colcnt,
 
182
           uchar const *const row_data, MY_BITMAP const *cols,
 
183
           uchar const **const row_end, ulong *const master_reclength,
 
184
           const bool abort_on_warning, const bool first_row)
 
185
{
 
186
  DBUG_ENTER("unpack_row");
 
187
  DBUG_ASSERT(row_data);
 
188
  size_t const master_null_byte_count= (bitmap_bits_set(cols) + 7) / 8;
 
189
  int error= 0;
 
190
 
 
191
  uchar const *null_ptr= row_data;
 
192
  uchar const *pack_ptr= row_data + master_null_byte_count;
 
193
 
 
194
  Field **const begin_ptr = table->field;
 
195
  Field **field_ptr;
 
196
  Field **const end_ptr= begin_ptr + colcnt;
 
197
 
 
198
  DBUG_ASSERT(null_ptr < row_data + master_null_byte_count);
 
199
 
 
200
  // Mask to mask out the correct bit among the null bits
 
201
  unsigned int null_mask= 1U;
 
202
  // The "current" null bits
 
203
  unsigned int null_bits= *null_ptr++;
 
204
  uint i= 0;
 
205
  table_def *tabledef= ((Relay_log_info*)rli)->get_tabledef(table);
 
206
  for (field_ptr= begin_ptr ; field_ptr < end_ptr && *field_ptr ; ++field_ptr)
 
207
  {
 
208
    Field *const f= *field_ptr;
 
209
 
 
210
    /*
 
211
      No need to bother about columns that does not exist: they have
 
212
      gotten default values when being emptied above.
 
213
     */
 
214
    if (bitmap_is_set(cols, field_ptr -  begin_ptr))
 
215
    {
 
216
      if ((null_mask & 0xFF) == 0)
 
217
      {
 
218
        DBUG_ASSERT(null_ptr < row_data + master_null_byte_count);
 
219
        null_mask= 1U;
 
220
        null_bits= *null_ptr++;
 
221
      }
 
222
 
 
223
      DBUG_ASSERT(null_mask & 0xFF); // One of the 8 LSB should be set
 
224
 
 
225
      /* Field...::unpack() cannot return 0 */
 
226
      DBUG_ASSERT(pack_ptr != NULL);
 
227
 
 
228
      if (null_bits & null_mask)
 
229
      {
 
230
        if (f->maybe_null())
 
231
        {
 
232
          DBUG_PRINT("debug", ("Was NULL; null mask: 0x%x; null bits: 0x%x",
 
233
                               null_mask, null_bits));
 
234
          /** 
 
235
            Calling reset just in case one is unpacking on top a 
 
236
            record with data. 
 
237
 
 
238
            This could probably go into set_null() but doing so, 
 
239
            (i) triggers assertion in other parts of the code at 
 
240
            the moment; (ii) it would make us reset the field,
 
241
            always when setting null, which right now doesn't seem 
 
242
            needed anywhere else except here.
 
243
 
 
244
            TODO: maybe in the future we should consider moving 
 
245
                  the reset to make it part of set_null. But then
 
246
                  the assertions triggered need to be 
 
247
                  addressed/revisited.
 
248
           */
 
249
          f->reset();
 
250
          f->set_null();
 
251
        }
 
252
        else
 
253
        {
 
254
          MYSQL_ERROR::enum_warning_level error_type=
 
255
            MYSQL_ERROR::WARN_LEVEL_NOTE;
 
256
          if (abort_on_warning && (table->file->has_transactions() ||
 
257
                                   first_row))
 
258
          {
 
259
            error = HA_ERR_ROWS_EVENT_APPLY;
 
260
            error_type= MYSQL_ERROR::WARN_LEVEL_ERROR;
 
261
          }
 
262
          else
 
263
          {
 
264
            f->set_default();
 
265
            error_type= MYSQL_ERROR::WARN_LEVEL_WARN;
 
266
          }
 
267
          push_warning_printf(current_thd, error_type,
 
268
                              ER_BAD_NULL_ERROR,
 
269
                              ER(ER_BAD_NULL_ERROR),
 
270
                              f->field_name);
 
271
        }
 
272
      }
 
273
      else
 
274
      {
 
275
        f->set_notnull();
 
276
 
 
277
        /*
 
278
          We only unpack the field if it was non-null.
 
279
          Use the master's size information if available else call
 
280
          normal unpack operation.
 
281
        */
 
282
        uint16 const metadata= tabledef->field_metadata(i);
 
283
#ifndef DBUG_OFF
 
284
        uchar const *const old_pack_ptr= pack_ptr;
 
285
#endif
 
286
        pack_ptr= f->unpack(f->ptr, pack_ptr, metadata, TRUE);
 
287
        DBUG_PRINT("debug", ("field: %s; metadata: 0x%x;"
 
288
                             " pack_ptr: 0x%lx; pack_ptr': 0x%lx; bytes: %d",
 
289
                             f->field_name, metadata,
 
290
                             (ulong) old_pack_ptr, (ulong) pack_ptr,
 
291
                             (int) (pack_ptr - old_pack_ptr)));
 
292
      }
 
293
 
 
294
      null_mask <<= 1;
 
295
    }
 
296
    i++;
 
297
  }
 
298
 
 
299
  /*
 
300
    throw away master's extra fields
 
301
  */
 
302
  uint max_cols= min(tabledef->size(), cols->n_bits);
 
303
  for (; i < max_cols; i++)
 
304
  {
 
305
    if (bitmap_is_set(cols, i))
 
306
    {
 
307
      if ((null_mask & 0xFF) == 0)
 
308
      {
 
309
        DBUG_ASSERT(null_ptr < row_data + master_null_byte_count);
 
310
        null_mask= 1U;
 
311
        null_bits= *null_ptr++;
 
312
      }
 
313
      DBUG_ASSERT(null_mask & 0xFF); // One of the 8 LSB should be set
 
314
 
 
315
      if (!((null_bits & null_mask) && tabledef->maybe_null(i)))
 
316
        pack_ptr+= tabledef->calc_field_size(i, (uchar *) pack_ptr);
 
317
      null_mask <<= 1;
 
318
    }
 
319
  }
 
320
 
 
321
  /*
 
322
    We should now have read all the null bytes, otherwise something is
 
323
    really wrong.
 
324
   */
 
325
  DBUG_ASSERT(null_ptr == row_data + master_null_byte_count);
 
326
 
 
327
  DBUG_DUMP("row_data", row_data, pack_ptr - row_data);
 
328
 
 
329
  *row_end = pack_ptr;
 
330
  if (master_reclength)
 
331
  {
 
332
    if (*field_ptr)
 
333
      *master_reclength = (*field_ptr)->ptr - table->record[0];
 
334
    else
 
335
      *master_reclength = table->s->reclength;
 
336
  }
 
337
  
 
338
  DBUG_RETURN(error);
 
339
}
 
340
 
 
341
/**
 
342
  Fills @c table->record[0] with default values.
 
343
 
 
344
  First @c restore_record() is called to restore the default values for
 
345
  record concerning the given table. Then, if @c check is true, 
 
346
  a check is performed to see if fields are have default value or can 
 
347
  be NULL. Otherwise error is reported.
 
348
 
 
349
  @param table  Table whose record[0] buffer is prepared. 
 
350
  @param skip   Number of columns for which default/nullable check 
 
351
                should be skipped.
 
352
  @param check  Specifies if lack of default error needs checking.
 
353
  @param abort_on_warning
 
354
                Controls how to react on lack of a field's default.
 
355
                The parameter mimics the master side one for
 
356
                @c check_that_all_fields_are_given_values.
 
357
                
 
358
  @returns 0 on success or a handler level error code
 
359
 */ 
 
360
int prepare_record(TABLE *const table, 
 
361
                   const uint skip, const bool check,
 
362
                   const bool abort_on_warning, const bool first_row)
 
363
{
 
364
  DBUG_ENTER("prepare_record");
 
365
 
 
366
  int error= 0;
 
367
  restore_record(table, s->default_values);
 
368
 
 
369
  /*
 
370
     This skip should be revisited in 6.0, because in 6.0 RBR one 
 
371
     can have holes in the row (as the grain of the writeset is 
 
372
     the column and not the entire row).
 
373
   */
 
374
  if (skip >= table->s->fields || !check)
 
375
    DBUG_RETURN(0);
 
376
 
 
377
  /*
 
378
    For fields the extra fields on the slave, we check if they have a default.
 
379
    The check follows the same rules as the INSERT query without specifying an
 
380
    explicit value for a field not having the explicit default 
 
381
    (@c check_that_all_fields_are_given_values()).
 
382
  */
 
383
  for (Field **field_ptr= table->field+skip; *field_ptr; ++field_ptr)
 
384
  {
 
385
    Field *const f= *field_ptr;
 
386
    if ((f->flags &  NO_DEFAULT_VALUE_FLAG) &&
 
387
        (f->real_type() != MYSQL_TYPE_ENUM))
 
388
    {
 
389
 
 
390
      MYSQL_ERROR::enum_warning_level error_type=
 
391
        MYSQL_ERROR::WARN_LEVEL_NOTE;
 
392
      if (abort_on_warning && (table->file->has_transactions() ||
 
393
                               first_row))
 
394
      {
 
395
        error= HA_ERR_ROWS_EVENT_APPLY;
 
396
        error_type= MYSQL_ERROR::WARN_LEVEL_ERROR;
 
397
      }
 
398
      else
 
399
      {
 
400
        f->set_default();
 
401
        error_type= MYSQL_ERROR::WARN_LEVEL_WARN;
 
402
      }
 
403
      push_warning_printf(current_thd, error_type,
 
404
                          ER_NO_DEFAULT_FOR_FIELD,
 
405
                          ER(ER_NO_DEFAULT_FOR_FIELD),
 
406
                          f->field_name);
 
407
    }
 
408
  }
 
409
 
 
410
  DBUG_RETURN(error);
 
411
}
 
412
 
 
413
#endif // HAVE_REPLICATION