~ubuntu-branches/ubuntu/trusty/drizzle/trusty

« back to all changes in this revision

Viewing changes to drizzled/key.cc

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-10-02 14:17:48 UTC
  • mfrom: (1.1.1 upstream)
  • mto: (2.1.17 sid)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20101002141748-m6vbfbfjhrw1153e
Tags: 2010.09.1802-1
* New upstream release.
* Removed pid-file argument hack.
* Updated GPL-2 address to be new address.
* Directly copy in drizzledump.1 since debian doesn't have sphinx 1.0 yet.
* Link to jquery from libjs-jquery. Add it as a depend.
* Add drizzled.8 symlink to the install files.

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
  {
208
208
      field->setReadSet();
209
209
      from_key+= HA_KEY_BLOB_LENGTH;
210
210
      key_length-= HA_KEY_BLOB_LENGTH;
211
 
      field->set_ptr_offset(to_record - field->table->record[0],
 
211
      field->set_ptr_offset(to_record - field->getTable()->getInsertRecord(),
212
212
                            (ulong) blob_length, from_key);
213
213
      length= key_part->length;
214
214
    }
215
215
    else if (key_part->key_part_flag & HA_VAR_LENGTH_PART)
216
216
    {
217
217
      Field *field= key_part->field;
218
 
      ptrdiff_t ptrdiff= to_record - field->table->record[0];
 
218
      ptrdiff_t ptrdiff= to_record - field->getTable()->getInsertRecord();
219
219
 
220
220
      field->setReadSet();
221
221
      field->setWriteSet();
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;
274
274
 
275
275
    if (key_part->null_bit)
276
276
    {
277
 
      if (*key != test(table->record[0][key_part->null_offset] &
 
277
      if (*key != test(table->getInsertRecord()[key_part->null_offset] &
278
278
                       key_part->null_bit))
279
279
        return 1;
280
280
      if (*key)
294
294
    {
295
295
      const CHARSET_INFO * const cs= key_part->field->charset();
296
296
      uint32_t char_length= key_part->length / cs->mbmaxlen;
297
 
      const unsigned char *pos= table->record[0] + key_part->offset;
 
297
      const unsigned char *pos= table->getInsertRecord() + key_part->offset;
298
298
      if (length > char_length)
299
299
      {
300
300
        char_length= my_charpos(cs, pos, pos + length, char_length);
306
306
        return 1;
307
307
      continue;
308
308
    }
309
 
    if (memcmp(key,table->record[0]+key_part->offset,length))
 
309
    if (memcmp(key,table->getInsertRecord()+key_part->offset,length))
310
310
      return 1;
311
311
  }
312
312
  return 0;
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
 
342
342
      to->append('-');
343
343
    if (key_part->null_bit)
344
344
    {
345
 
      if (table->record[0][key_part->null_offset] & key_part->null_bit)
 
345
      if (table->getInsertRecord()[key_part->null_offset] & key_part->null_bit)
346
346
      {
347
347
        to->append(STRING_WITH_LEN("NULL"));
348
348
        continue;
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
 
421
423
  Compare key in row to a given key.
422
424
 
423
425
  @param key_part               Key part handler
424
 
  @param key                    Key to compare to value in table->record[0]
 
426
  @param key                    Key to compare to value in table->getInsertRecord()
425
427
  @param key_length             length of 'key'
426
428
 
427
429
  @return
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 */