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