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