~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
        pack_ptr= field->pack(pack_ptr, field->ptr + offset,
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
100
                              field->max_data_length(), true);
1 by brian
clean slate
101
      }
102
103
      null_mask <<= 1;
104
      if ((null_mask & 0xFF) == 0)
105
      {
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
106
        assert(null_ptr < row_data + null_byte_count);
1 by brian
clean slate
107
        null_mask = 1U;
108
        *null_ptr++ = null_bits;
109
        null_bits= (1U << 8) - 1;
110
      }
111
    }
51.1.2 by Jay Pipes
Fixed unbalanced parentheses in pack_row due to merge conflict resolution mistake
112
  }
1 by brian
clean slate
113
114
  /*
115
    Write the last (partial) byte, if there is one
116
  */
117
  if ((null_mask & 0xFF) > 1)
118
  {
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
119
    assert(null_ptr < row_data + null_byte_count);
1 by brian
clean slate
120
    *null_ptr++ = null_bits;
121
  }
122
123
  /*
124
    The null pointer should now point to the first byte of the
125
    packed data. If it doesn't, something is very wrong.
126
  */
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
127
  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
128
  return(static_cast<size_t>(pack_ptr - row_data));
1 by brian
clean slate
129
}
130
#endif
131
132
133
/**
134
   Unpack a row into @c table->record[0].
135
136
   The function will always unpack into the @c table->record[0]
137
   record.  This is because there are too many dependencies on where
138
   the various member functions of Field and subclasses expect to
139
   write.
140
141
   The row is assumed to only consist of the fields for which the corresponding
142
   bit in bitset @c cols is set; the other parts of the record are left alone.
143
144
   At most @c colcnt columns are read: if the table is larger than
145
   that, the remaining fields are not filled in.
146
147
   @param rli     Relay log info
148
   @param table   Table to unpack into
149
   @param colcnt  Number of columns to read from record
150
   @param row_data
151
                  Packed row data
152
   @param cols    Pointer to bitset describing columns to fill in
153
   @param row_end Pointer to variable that will hold the value of the
154
                  one-after-end position for the row
155
   @param master_reclength
156
                  Pointer to variable that will be set to the length of the
157
                  record on the master side
158
159
   @retval 0 No error
160
161
   @retval ER_NO_DEFAULT_FOR_FIELD
162
   Returned if one of the fields existing on the slave but not on the
163
   master does not have a default value (and isn't nullable)
164
165
 */
166
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
167
int
168
unpack_row(Relay_log_info const *rli,
169
           TABLE *table, uint const colcnt,
170
           uchar const *const row_data, MY_BITMAP const *cols,
171
           uchar const **const row_end, ulong *const master_reclength)
172
{
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
173
  assert(row_data);
1 by brian
clean slate
174
  size_t const master_null_byte_count= (bitmap_bits_set(cols) + 7) / 8;
175
  int error= 0;
176
177
  uchar const *null_ptr= row_data;
178
  uchar const *pack_ptr= row_data + master_null_byte_count;
179
180
  Field **const begin_ptr = table->field;
181
  Field **field_ptr;
182
  Field **const end_ptr= begin_ptr + colcnt;
183
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
184
  assert(null_ptr < row_data + master_null_byte_count);
1 by brian
clean slate
185
186
  // Mask to mask out the correct bit among the null bits
187
  unsigned int null_mask= 1U;
188
  // The "current" null bits
189
  unsigned int null_bits= *null_ptr++;
190
  uint i= 0;
191
192
  /*
193
    Use the rli class to get the table's metadata. If tabledef is not NULL
194
    we are processing data from a master. If tabledef is NULL then it is
195
    assumed that the packed row comes from the table to which it is
196
    unpacked.
197
  */
198
  table_def *tabledef= rli ? ((Relay_log_info*)rli)->get_tabledef(table) : 0;
199
  for (field_ptr= begin_ptr ; field_ptr < end_ptr && *field_ptr ; ++field_ptr)
200
  {
201
    Field *const f= *field_ptr;
202
203
204
    /*
205
      No need to bother about columns that does not exist: they have
206
      gotten default values when being emptied above.
207
     */
208
    if (bitmap_is_set(cols, field_ptr -  begin_ptr))
209
    {
210
      if ((null_mask & 0xFF) == 0)
211
      {
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
212
        assert(null_ptr < row_data + master_null_byte_count);
1 by brian
clean slate
213
        null_mask= 1U;
214
        null_bits= *null_ptr++;
215
      }
216
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
217
      assert(null_mask & 0xFF); // One of the 8 LSB should be set
1 by brian
clean slate
218
219
      /* Field...::unpack() cannot return 0 */
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
220
      assert(pack_ptr != NULL);
1 by brian
clean slate
221
222
      if ((null_bits & null_mask) && f->maybe_null())
223
      {
224
        f->set_null();
225
      }
226
      else
227
      {
228
        f->set_notnull();
229
230
        /*
231
          We only unpack the field if it was non-null.
232
          Use the master's size information if available else call
233
          normal unpack operation.
234
        */
235
        /*
236
          Use the master's metadata if we are processing data from a slave
237
          (tabledef not NULL). If tabledef is NULL then it is assumed that
238
          the packed row comes from the table to which it is unpacked.
239
        */
206 by Brian Aker
Removed final uint dead types.
240
        uint16_t metadata= tabledef ? tabledef->field_metadata(i) : 0;
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
241
        pack_ptr= f->unpack(f->ptr, pack_ptr, metadata, true);
1 by brian
clean slate
242
      }
243
244
      null_mask <<= 1;
245
    }
246
    i++;
247
  }
248
249
  /*
250
    throw away master's extra fields
251
252
    Use the master's max_cols if we are processing data from a slave
253
    (tabledef not NULL). If tabledef is NULL then it is assumed that
254
    there are no extra columns.
255
  */
256
  uint max_cols= tabledef ? min(tabledef->size(), cols->n_bits) : 0;
257
  for (; i < max_cols; i++)
258
  {
259
    if (bitmap_is_set(cols, i))
260
    {
261
      if ((null_mask & 0xFF) == 0)
262
      {
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
263
        assert(null_ptr < row_data + master_null_byte_count);
1 by brian
clean slate
264
        null_mask= 1U;
265
        null_bits= *null_ptr++;
266
      }
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
267
      assert(null_mask & 0xFF); // One of the 8 LSB should be set
1 by brian
clean slate
268
269
      if (!((null_bits & null_mask) && tabledef->maybe_null(i)))
270
        pack_ptr+= tabledef->calc_field_size(i, (uchar *) pack_ptr);
271
      null_mask <<= 1;
272
    }
273
  }
274
275
  /*
276
    We should now have read all the null bytes, otherwise something is
277
    really wrong.
278
   */
51.1.40 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
279
  assert(null_ptr == row_data + master_null_byte_count);
1 by brian
clean slate
280
281
  *row_end = pack_ptr;
282
  if (master_reclength)
283
  {
284
    if (*field_ptr)
285
      *master_reclength = (*field_ptr)->ptr - table->record[0];
286
    else
287
      *master_reclength = table->s->reclength;
288
  }
289
  
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
290
  return(error);
1 by brian
clean slate
291
}
292
293
/**
294
  Fills @c table->record[0] with default values.
295
296
  First @c empty_record() is called and then, additionally, fields are
297
  initialized explicitly with a call to @c set_default().
298
299
  For optimization reasons, the explicit initialization can be skipped
300
  for fields that are not marked in the @c cols vector. These fields
301
  will be set later, and filling them with default values is
302
  unnecessary.
303
304
  If @c check is true, fields are explicitly initialized only if they
305
  have default value or can be NULL. Otherwise error is reported. If
306
  @c check is false, no error is reported and the field is not set to
307
  any value.
308
309
  @todo When flag is added to allow engine to handle default values
310
  itself, the record should not be emptied and default values not set.
311
312
  @param table[in,out] Table whose record[0] buffer is prepared. 
313
  @param cols[in]      Vector of bits denoting columns that will be set
314
                       elsewhere
315
  @param check[in]     Indicates if errors should be checked when setting default
316
                       values.
317
318
  @retval 0                       Success
319
  @retval ER_NO_DEFAULT_FOR_FIELD Default value could not be set for a field
77.1.45 by Monty Taylor
Warning fixes.
320
*/
321
int prepare_record(TABLE *const table,
322
                   const MY_BITMAP *cols,
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
323
                   uint width __attribute__((unused)),
77.1.45 by Monty Taylor
Warning fixes.
324
                   const bool check)
1 by brian
clean slate
325
{
326
327
  int error= 0;
328
  empty_record(table);
329
330
  /*
331
    Explicit initialization of fields. For fields that are not in the
332
    cols for the row, we set them to default. If the fields are in
333
    addition to what exists on the master, we give an error if the
334
    have no sensible default.
335
  */
336
337
  for (Field **field_ptr= table->field ; *field_ptr ; ++field_ptr)
338
  {
339
    if ((uint) (field_ptr - table->field) >= cols->n_bits ||
340
        !bitmap_is_set(cols, field_ptr - table->field))
341
    {
205 by Brian Aker
uint32 -> uin32_t
342
      uint32_t const mask= NOT_NULL_FLAG | NO_DEFAULT_VALUE_FLAG;
1 by brian
clean slate
343
      Field *const f= *field_ptr;
344
345
      if (check && ((f->flags & mask) == mask))
346
      {
347
        my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), f->field_name);
348
        error = HA_ERR_ROWS_EVENT_APPLY;
349
      }
350
      else
351
      {
352
        f->set_default();
353
      }
354
    }
355
  }
356
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
357
  return(error);
1 by brian
clean slate
358
}
359
360
#endif // HAVE_REPLICATION