~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/key.cc

  • Committer: Brian Aker
  • Date: 2010-07-09 20:51:34 UTC
  • mfrom: (1643.4.3 drizzle)
  • Revision ID: brian@gaz-20100709205134-ru4s0889youfrmm5
Merge of Patrick

Show diffs side-by-side

added added

removed removed

Lines of Context:
57
57
       key_length is set to length of key before (not including) field
58
58
*/
59
59
 
60
 
int find_ref_key(KEY *key, uint32_t key_count, unsigned char *record, Field *field,
 
60
int find_ref_key(KeyInfo *key, uint32_t key_count, unsigned char *record, Field *field,
61
61
                 uint32_t *key_length, uint32_t *keypart)
62
62
{
63
63
  register int i;
64
 
  register KEY *key_info;
 
64
  register KeyInfo *key_info;
65
65
  uint32_t fieldpos;
66
66
 
67
67
  fieldpos= field->offset(record);
84
84
       i++, key_info++)
85
85
  {
86
86
    uint32_t j;
87
 
    KEY_PART_INFO *key_part;
 
87
    KeyPartInfo *key_part;
88
88
    *key_length=0;
89
89
    for (j=0, key_part=key_info->key_part ;
90
90
         j < key_info->key_parts ;
102
102
}
103
103
 
104
104
 
105
 
void key_copy(unsigned char *to_key, unsigned char *from_record, KEY *key_info,
 
105
void key_copy(unsigned char *to_key, unsigned char *from_record, KeyInfo *key_info,
106
106
              unsigned int key_length)
107
107
{
108
108
  uint32_t length;
109
 
  KEY_PART_INFO *key_part;
 
109
  KeyPartInfo *key_part;
110
110
 
111
111
  if (key_length == 0)
112
112
    key_length= key_info->key_length;
145
145
  Zero the null components of key tuple.
146
146
*/
147
147
 
148
 
void key_zero_nulls(unsigned char *tuple, KEY *key_info)
 
148
void key_zero_nulls(unsigned char *tuple, KeyInfo *key_info)
149
149
{
150
 
  KEY_PART_INFO *key_part= key_info->key_part;
151
 
  KEY_PART_INFO *key_part_end= key_part + key_info->key_parts;
 
150
  KeyPartInfo *key_part= key_info->key_part;
 
151
  KeyPartInfo *key_part_end= key_part + key_info->key_parts;
152
152
  for (; key_part != key_part_end; key_part++)
153
153
  {
154
154
    if (key_part->null_bit && *tuple)
170
170
  @param key_length  specifies length of all keyparts that will be restored
171
171
*/
172
172
 
173
 
void key_restore(unsigned char *to_record, unsigned char *from_key, KEY *key_info,
 
173
void key_restore(unsigned char *to_record, unsigned char *from_key, KeyInfo *key_info,
174
174
                 uint16_t key_length)
175
175
{
176
176
  uint32_t length;
177
 
  KEY_PART_INFO *key_part;
 
177
  KeyPartInfo *key_part;
178
178
 
179
179
  if (key_length == 0)
180
180
  {
262
262
bool key_cmp_if_same(Table *table,const unsigned char *key,uint32_t idx,uint32_t key_length)
263
263
{
264
264
  uint32_t store_length;
265
 
  KEY_PART_INFO *key_part;
 
265
  KeyPartInfo *key_part;
266
266
  const unsigned char *key_end= key + key_length;;
267
267
 
268
268
  for (key_part=table->key_info[idx].key_part;
328
328
 
329
329
void key_unpack(String *to, Table *table, uint32_t idx)
330
330
{
331
 
  KEY_PART_INFO *key_part,*key_part_end;
 
331
  KeyPartInfo *key_part,*key_part_end;
332
332
  Field *field;
333
333
  String tmp;
334
334
 
354
354
      field->setReadSet();
355
355
      field->val_str(&tmp);
356
356
      if (cs->mbmaxlen > 1 &&
357
 
          table->field[key_part->fieldnr - 1]->field_length !=
 
357
          table->getField(key_part->fieldnr - 1)->field_length !=
358
358
          key_part->length)
359
359
      {
360
360
        /*
410
410
    If table handler has primary key as part of the index, check that primary
411
411
    key is not updated
412
412
  */
413
 
  if (idx != table->s->primary_key && table->s->primary_key < MAX_KEY &&
 
413
  if (idx != table->getShare()->getPrimaryKey() && table->getShare()->hasPrimaryKey() &&
414
414
      (table->cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)))
415
 
    return is_key_used(table, table->s->primary_key, fields);
 
415
  {
 
416
    return is_key_used(table, table->getShare()->getPrimaryKey(), fields);
 
417
  }
416
418
  return 0;
417
419
}
418
420
 
431
433
    -   1               Key is larger than range
432
434
*/
433
435
 
434
 
int key_cmp(KEY_PART_INFO *key_part, const unsigned char *key, uint32_t key_length)
 
436
int key_cmp(KeyPartInfo *key_part, const unsigned char *key, uint32_t key_length)
435
437
{
436
438
  uint32_t store_length;
437
439
 
467
469
}
468
470
 
469
471
 
470
 
/*
471
 
  Compare two records in index order
472
 
  SYNOPSIS
473
 
    key_rec_cmp()
474
 
    key                         Index information
475
 
    rec0                        Pointer to table->record[0]
476
 
    first_rec                   Pointer to record compare with
477
 
    second_rec                  Pointer to record compare against first_rec
478
 
 
479
 
  DESCRIPTION
480
 
    This method is set-up such that it can be called directly from the
481
 
    priority queue and it is attempted to be optimised as much as possible
482
 
    since this will be called O(N * log N) times while performing a merge
483
 
    sort in various places in the code.
484
 
 
485
 
    We retrieve the pointer to table->record[0] using the fact that key_parts
486
 
    have an offset making it possible to calculate the start of the record.
487
 
    We need to get the diff to the compared record since none of the records
488
 
    being compared are stored in table->record[0].
489
 
 
490
 
    We first check for NULL values, if there are no NULL values we use
491
 
    a compare method that gets two field pointers and a max length
492
 
    and return the result of the comparison.
493
 
*/
494
 
 
495
 
int key_rec_cmp(void *key, unsigned char *first_rec, unsigned char *second_rec)
496
 
{
497
 
  KEY *key_info= (KEY*)key;
498
 
  uint32_t key_parts= key_info->key_parts, i= 0;
499
 
  KEY_PART_INFO *key_part= key_info->key_part;
500
 
  unsigned char *rec0= key_part->field->ptr - key_part->offset;
501
 
  ptrdiff_t first_diff= first_rec - rec0, sec_diff= second_rec - rec0;
502
 
  int result= 0;
503
 
 
504
 
  do
505
 
  {
506
 
    Field *field= key_part->field;
507
 
 
508
 
    if (key_part->null_bit)
509
 
    {
510
 
      /* The key_part can contain NULL values */
511
 
      bool first_is_null= field->is_null_in_record_with_offset(first_diff);
512
 
      bool sec_is_null= field->is_null_in_record_with_offset(sec_diff);
513
 
      /*
514
 
        NULL is smaller then everything so if first is NULL and the other
515
 
        not then we know that we should return -1 and for the opposite
516
 
        we should return +1. If both are NULL then we call it equality
517
 
        although it is a strange form of equality, we have equally little
518
 
        information of the real value.
519
 
      */
520
 
      if (!first_is_null)
521
 
      {
522
 
        if (!sec_is_null)
523
 
          ; /* Fall through, no NULL fields */
524
 
        else
525
 
        {
526
 
          return(1);
527
 
        }
528
 
      }
529
 
      else if (!sec_is_null)
530
 
      {
531
 
        return(-1);
532
 
      }
533
 
      else
534
 
        goto next_loop; /* Both were NULL */
535
 
    }
536
 
    /*
537
 
      No null values in the fields
538
 
      We use the virtual method cmp_max with a max length parameter.
539
 
      For most field types this translates into a cmp without
540
 
      max length. The exceptions are the BLOB and VARCHAR field types
541
 
      that take the max length into account.
542
 
    */
543
 
    result= field->cmp_max(field->ptr+first_diff, field->ptr+sec_diff,
544
 
                           key_part->length);
545
 
next_loop:
546
 
    key_part++;
547
 
  } while (!result && ++i < key_parts);
548
 
  return(result);
549
 
}
550
 
 
551
472
} /* namespace drizzled */