~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/key.cc

  • Committer: Monty Taylor
  • Date: 2008-07-05 17:07:46 UTC
  • mto: This revision was merged to the branch mainline in revision 63.
  • Revision ID: monty@inaugust.com-20080705170746-8aq11u9fuwtfwy85
Removed my_alarm. Made my_lock only do the non-alarm version. Moved my_lock to MyISAM where it belongs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
/* Functions to handle keys and fields in forms */
18
18
 
19
 
#include <drizzled/server_includes.h>
 
19
#include "mysql_priv.h"
20
20
 
21
21
/*
22
22
  Search after a key that starts with 'field'
45
45
       key_length is set to length of key before (not including) field
46
46
*/
47
47
 
48
 
int find_ref_key(KEY *key, uint32_t key_count, unsigned char *record, Field *field,
49
 
                 uint32_t *key_length, uint32_t *keypart)
 
48
int find_ref_key(KEY *key, uint key_count, uchar *record, Field *field,
 
49
                 uint *key_length, uint *keypart)
50
50
{
51
51
  register int i;
52
52
  register KEY *key_info;
53
 
  uint32_t fieldpos;
 
53
  uint fieldpos;
54
54
 
55
55
  fieldpos= field->offset(record);
56
56
 
71
71
       i < (int) key_count ;
72
72
       i++, key_info++)
73
73
  {
74
 
    uint32_t j;
 
74
    uint j;
75
75
    KEY_PART_INFO *key_part;
76
76
    *key_length=0;
77
77
    for (j=0, key_part=key_info->key_part ;
105
105
  @param key_length  specifies length of all keyparts that will be copied
106
106
*/
107
107
 
108
 
void key_copy(unsigned char *to_key, unsigned char *from_record, KEY *key_info,
109
 
              unsigned int key_length)
 
108
void key_copy(uchar *to_key, uchar *from_record, KEY *key_info,
 
109
              uint key_length)
110
110
{
111
 
  uint32_t length;
 
111
  uint length;
112
112
  KEY_PART_INFO *key_part;
113
113
 
114
114
  if (key_length == 0)
125
125
        key_part->key_part_flag & HA_VAR_LENGTH_PART)
126
126
    {
127
127
      key_length-= HA_KEY_BLOB_LENGTH;
128
 
      length= cmin((uint16_t)key_length, key_part->length);
 
128
      length= min(key_length, key_part->length);
129
129
      key_part->field->get_key_image(to_key, length, Field::itRAW);
130
130
      to_key+= HA_KEY_BLOB_LENGTH;
131
131
    }
132
132
    else
133
133
    {
134
 
      length= cmin((uint16_t)key_length, key_part->length);
 
134
      length= min(key_length, key_part->length);
135
135
      Field *field= key_part->field;
136
 
      const CHARSET_INFO * const cs= field->charset();
137
 
      uint32_t bytes= field->get_key_image(to_key, length, Field::itRAW);
 
136
      CHARSET_INFO *cs= field->charset();
 
137
      uint bytes= field->get_key_image(to_key, length, Field::itRAW);
138
138
      if (bytes < length)
139
139
        cs->cset->fill(cs, (char*) to_key + bytes, length - bytes, ' ');
140
140
    }
148
148
  Zero the null components of key tuple.
149
149
*/
150
150
 
151
 
void key_zero_nulls(unsigned char *tuple, KEY *key_info)
 
151
void key_zero_nulls(uchar *tuple, KEY *key_info)
152
152
{
153
153
  KEY_PART_INFO *key_part= key_info->key_part;
154
154
  KEY_PART_INFO *key_part_end= key_part + key_info->key_parts;
155
155
  for (; key_part != key_part_end; key_part++)
156
156
  {
157
157
    if (key_part->null_bit && *tuple)
158
 
      memset(tuple+1, 0, key_part->store_length-1);
 
158
      bzero(tuple+1, key_part->store_length-1);
159
159
    tuple+= key_part->store_length;
160
160
  }
161
161
}
173
173
  @param key_length  specifies length of all keyparts that will be restored
174
174
*/
175
175
 
176
 
void key_restore(unsigned char *to_record, unsigned char *from_key, KEY *key_info,
177
 
                 uint16_t key_length)
 
176
void key_restore(uchar *to_record, uchar *from_key, KEY *key_info,
 
177
                 uint key_length)
178
178
{
179
 
  uint32_t length;
 
179
  uint length;
180
180
  KEY_PART_INFO *key_part;
181
181
 
182
182
  if (key_length == 0)
185
185
  }
186
186
  for (key_part= key_info->key_part ; (int) key_length > 0 ; key_part++)
187
187
  {
188
 
    unsigned char used_uneven_bits= 0;
 
188
    uchar used_uneven_bits= 0;
189
189
    if (key_part->null_bit)
190
190
    {
191
191
      if (*from_key++)
194
194
        to_record[key_part->null_offset]&= ~key_part->null_bit;
195
195
      key_length--;
196
196
    }
 
197
    if (key_part->type == HA_KEYTYPE_BIT)
 
198
    {
 
199
      Field_bit *field= (Field_bit *) (key_part->field);
 
200
      if (field->bit_len)
 
201
      {
 
202
        uchar bits= *(from_key + key_part->length -
 
203
                      field->pack_length_in_rec() - 1);
 
204
        set_rec_bits(bits, to_record + key_part->null_offset +
 
205
                     (key_part->null_bit == 128),
 
206
                     field->bit_ofs, field->bit_len);
 
207
        /* we have now used the byte with 'uneven' bits */
 
208
        used_uneven_bits= 1;
 
209
      }
 
210
    }
197
211
    if (key_part->key_part_flag & HA_BLOB_PART)
198
212
    {
199
213
      /*
203
217
        Maybe this branch is to be removed, but now we
204
218
        have to ignore GCov compaining.
205
219
      */
206
 
      uint32_t blob_length= uint2korr(from_key);
 
220
      uint blob_length= uint2korr(from_key);
207
221
      Field_blob *field= (Field_blob*) key_part->field;
208
222
      from_key+= HA_KEY_BLOB_LENGTH;
209
223
      key_length-= HA_KEY_BLOB_LENGTH;
214
228
    else if (key_part->key_part_flag & HA_VAR_LENGTH_PART)
215
229
    {
216
230
      Field *field= key_part->field;
 
231
      my_bitmap_map *old_map;
217
232
      my_ptrdiff_t ptrdiff= to_record - field->table->record[0];
218
233
      field->move_field_offset(ptrdiff);
219
234
      key_length-= HA_KEY_BLOB_LENGTH;
220
 
      length= cmin(key_length, key_part->length);
 
235
      length= min(key_length, key_part->length);
 
236
      old_map= dbug_tmp_use_all_columns(field->table, field->table->write_set);
221
237
      field->set_key_image(from_key, length);
 
238
      dbug_tmp_restore_column_map(field->table->write_set, old_map);
222
239
      from_key+= HA_KEY_BLOB_LENGTH;
223
240
      field->move_field_offset(-ptrdiff);
224
241
    }
225
242
    else
226
243
    {
227
 
      length= cmin(key_length, key_part->length);
 
244
      length= min(key_length, key_part->length);
228
245
      /* skip the byte with 'uneven' bits, if used */
229
246
      memcpy(to_record + key_part->offset, from_key + used_uneven_bits
230
247
             , (size_t) length - used_uneven_bits);
238
255
/**
239
256
  Compare if a key has changed.
240
257
 
241
 
  @param table          Table
 
258
  @param table          TABLE
242
259
  @param key            key to compare to row
243
260
  @param idx            Index used
244
261
  @param key_length     Length of key
255
272
    1   Key has changed
256
273
*/
257
274
 
258
 
bool key_cmp_if_same(Table *table,const unsigned char *key,uint32_t idx,uint32_t key_length)
 
275
bool key_cmp_if_same(TABLE *table,const uchar *key,uint idx,uint key_length)
259
276
{
260
 
  uint32_t store_length;
 
277
  uint store_length;
261
278
  KEY_PART_INFO *key_part;
262
 
  const unsigned char *key_end= key + key_length;;
 
279
  const uchar *key_end= key + key_length;;
263
280
 
264
281
  for (key_part=table->key_info[idx].key_part;
265
282
       key < key_end ; 
266
283
       key_part++, key+= store_length)
267
284
  {
268
 
    uint32_t length;
 
285
    uint length;
269
286
    store_length= key_part->store_length;
270
287
 
271
288
    if (key_part->null_bit)
285
302
        return 1;
286
303
      continue;
287
304
    }
288
 
    length= cmin((uint) (key_end-key), store_length);
 
305
    length= min((uint) (key_end-key), store_length);
289
306
    if (!(key_part->key_type & (FIELDFLAG_NUMBER+FIELDFLAG_BINARY+
290
307
                                FIELDFLAG_PACK)))
291
308
    {
292
 
      const CHARSET_INFO * const cs= key_part->field->charset();
293
 
      uint32_t char_length= key_part->length / cs->mbmaxlen;
294
 
      const unsigned char *pos= table->record[0] + key_part->offset;
 
309
      CHARSET_INFO *cs= key_part->field->charset();
 
310
      uint char_length= key_part->length / cs->mbmaxlen;
 
311
      const uchar *pos= table->record[0] + key_part->offset;
295
312
      if (length > char_length)
296
313
      {
297
314
        char_length= my_charpos(cs, pos, pos + length, char_length);
298
315
        set_if_smaller(char_length, length);
299
316
      }
300
317
      if (cs->coll->strnncollsp(cs,
301
 
                                (const unsigned char*) key, length,
302
 
                                (const unsigned char*) pos, char_length, 0))
 
318
                                (const uchar*) key, length,
 
319
                                (const uchar*) pos, char_length, 0))
303
320
        return 1;
304
321
      continue;
305
322
    }
323
340
     idx        Key number
324
341
*/
325
342
 
326
 
void key_unpack(String *to,Table *table,uint32_t idx)
 
343
void key_unpack(String *to,TABLE *table,uint idx)
327
344
{
328
345
  KEY_PART_INFO *key_part,*key_part_end;
329
346
  Field *field;
330
347
  String tmp;
 
348
  my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
 
349
  DBUG_ENTER("key_unpack");
331
350
 
332
351
  to->length(0);
333
352
  for (key_part=table->key_info[idx].key_part,key_part_end=key_part+
347
366
    }
348
367
    if ((field=key_part->field))
349
368
    {
350
 
      const CHARSET_INFO * const cs= field->charset();
 
369
      CHARSET_INFO *cs= field->charset();
351
370
      field->val_str(&tmp);
352
371
      if (cs->mbmaxlen > 1 &&
353
372
          table->field[key_part->fieldnr - 1]->field_length !=
360
379
          which can break a multi-byte characters in the middle.
361
380
          Align, returning not more than "char_length" characters.
362
381
        */
363
 
        uint32_t charpos, char_length= key_part->length / cs->mbmaxlen;
 
382
        uint charpos, char_length= key_part->length / cs->mbmaxlen;
364
383
        if ((charpos= my_charpos(cs, tmp.ptr(),
365
384
                                 tmp.ptr() + tmp.length(),
366
385
                                 char_length)) < key_part->length)
368
387
      }
369
388
      
370
389
      if (key_part->length < field->pack_length())
371
 
        tmp.length(cmin(tmp.length(),(uint32_t)key_part->length));
 
390
        tmp.length(min(tmp.length(),key_part->length));
372
391
      to->append(tmp);
373
392
    }
374
393
    else
375
394
      to->append(STRING_WITH_LEN("???"));
376
395
  }
377
 
 
378
 
  return;
 
396
  dbug_tmp_restore_column_map(table->read_set, old_map);
 
397
  DBUG_VOID_RETURN;
379
398
}
380
399
 
381
400
 
384
403
 
385
404
  SYNOPSIS
386
405
    is_key_used()
387
 
      table   Table object with which keys and fields are associated.
 
406
      table   TABLE object with which keys and fields are associated.
388
407
      idx     Key to be checked.
389
408
      fields  Bitmap of fields to be checked.
390
409
 
391
410
  NOTE
392
 
    This function uses Table::tmp_set bitmap so the caller should care
 
411
    This function uses TABLE::tmp_set bitmap so the caller should care
393
412
    about saving/restoring its state if it also uses this bitmap.
394
413
 
395
414
  RETURN VALUE
397
416
    FALSE  Otherwise
398
417
*/
399
418
 
400
 
bool is_key_used(Table *table, uint32_t idx, const MY_BITMAP *fields)
 
419
bool is_key_used(TABLE *table, uint idx, const MY_BITMAP *fields)
401
420
{
402
421
  bitmap_clear_all(&table->tmp_set);
403
422
  table->mark_columns_used_by_index_no_reset(idx, &table->tmp_set);
429
448
    -   1               Key is larger than range
430
449
*/
431
450
 
432
 
int key_cmp(KEY_PART_INFO *key_part, const unsigned char *key, uint32_t key_length)
 
451
int key_cmp(KEY_PART_INFO *key_part, const uchar *key, uint key_length)
433
452
{
434
 
  uint32_t store_length;
 
453
  uint store_length;
435
454
 
436
 
  for (const unsigned char *end=key + key_length;
 
455
  for (const uchar *end=key + key_length;
437
456
       key < end;
438
457
       key+= store_length, key_part++)
439
458
  {
490
509
    and return the result of the comparison.
491
510
*/
492
511
 
493
 
int key_rec_cmp(void *key, unsigned char *first_rec, unsigned char *second_rec)
 
512
int key_rec_cmp(void *key, uchar *first_rec, uchar *second_rec)
494
513
{
495
514
  KEY *key_info= (KEY*)key;
496
 
  uint32_t key_parts= key_info->key_parts, i= 0;
 
515
  uint key_parts= key_info->key_parts, i= 0;
497
516
  KEY_PART_INFO *key_part= key_info->key_part;
498
 
  unsigned char *rec0= key_part->field->ptr - key_part->offset;
 
517
  uchar *rec0= key_part->field->ptr - key_part->offset;
499
518
  my_ptrdiff_t first_diff= first_rec - rec0, sec_diff= second_rec - rec0;
500
519
  int result= 0;
 
520
  DBUG_ENTER("key_rec_cmp");
501
521
 
502
522
  do
503
523
  {
521
541
          ; /* Fall through, no NULL fields */
522
542
        else
523
543
        {
524
 
          return(1);
 
544
          DBUG_RETURN(+1);
525
545
        }
526
546
      }
527
547
      else if (!sec_is_null)
528
548
      {
529
 
        return(-1);
 
549
        DBUG_RETURN(-1);
530
550
      }
531
551
      else
532
552
        goto next_loop; /* Both were NULL */
543
563
next_loop:
544
564
    key_part++;
545
565
  } while (!result && ++i < key_parts);
546
 
  return(result);
 
566
  DBUG_RETURN(result);
547
567
}