MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
key.cc
1 /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 
17 /* Functions to handle keys and fields in forms */
18 
19 #include "sql_priv.h"
20 #include "unireg.h" // REQUIRED: by includes later
21 #include "key.h" // key_rec_cmp
22 #include "field.h" // Field
23 
24 using std::min;
25 using std::max;
26 
27 /*
28  Search after a key that starts with 'field'
29 
30  SYNOPSIS
31  find_ref_key()
32  key First key to check
33  key_count How many keys to check
34  record Start of record
35  field Field to search after
36  key_length On partial match, contains length of fields before
37  field
38  keypart key part # of a field
39 
40  NOTES
41  Used when calculating key for NEXT_NUMBER
42 
43  IMPLEMENTATION
44  If no key starts with field test if field is part of some key. If we find
45  one, then return first key and set key_length to the number of bytes
46  preceding 'field'.
47 
48  RETURN
49  -1 field is not part of the key
50  # Key part for key matching key.
51  key_length is set to length of key before (not including) field
52 */
53 
54 int find_ref_key(KEY *key, uint key_count, uchar *record, Field *field,
55  uint *key_length, uint *keypart)
56 {
57  reg2 int i;
58  reg3 KEY *key_info;
59  uint fieldpos;
60 
61  fieldpos= field->offset(record);
62 
63  /* Test if some key starts as fieldpos */
64  for (i= 0, key_info= key ;
65  i < (int) key_count ;
66  i++, key_info++)
67  {
68  if (key_info->key_part[0].offset == fieldpos)
69  { /* Found key. Calc keylength */
70  *key_length= *keypart= 0;
71  return i; /* Use this key */
72  }
73  }
74 
75  /* Test if some key contains fieldpos */
76  for (i= 0, key_info= key;
77  i < (int) key_count ;
78  i++, key_info++)
79  {
80  uint j;
81  KEY_PART_INFO *key_part;
82  *key_length=0;
83  for (j=0, key_part=key_info->key_part ;
84  j < key_info->user_defined_key_parts ;
85  j++, key_part++)
86  {
87  if (key_part->offset == fieldpos)
88  {
89  *keypart= j;
90  return i; /* Use this key */
91  }
92  *key_length+= key_part->store_length;
93  }
94  }
95  return(-1); /* No key is ok */
96 }
97 
98 
114 void key_copy(uchar *to_key, uchar *from_record, KEY *key_info,
115  uint key_length)
116 {
117  uint length;
118  KEY_PART_INFO *key_part;
119 
120  if (key_length == 0)
121  key_length= key_info->key_length;
122  for (key_part= key_info->key_part; (int) key_length > 0; key_part++)
123  {
124  if (key_part->null_bit)
125  {
126  *to_key++= test(from_record[key_part->null_offset] &
127  key_part->null_bit);
128  key_length--;
129  }
130  if (key_part->key_part_flag & HA_BLOB_PART ||
131  key_part->key_part_flag & HA_VAR_LENGTH_PART)
132  {
133  key_length-= HA_KEY_BLOB_LENGTH;
134  length= min<uint>(key_length, key_part->length);
135  key_part->field->get_key_image(to_key, length, Field::itRAW);
136  to_key+= HA_KEY_BLOB_LENGTH;
137  }
138  else
139  {
140  length= min<uint>(key_length, key_part->length);
141  Field *field= key_part->field;
142  const CHARSET_INFO *cs= field->charset();
143  uint bytes= field->get_key_image(to_key, length, Field::itRAW);
144  if (bytes < length)
145  cs->cset->fill(cs, (char*) to_key + bytes, length - bytes, ' ');
146  }
147  to_key+= length;
148  key_length-= length;
149  }
150 }
151 
152 
163 void key_zero_nulls(uchar *tuple, KEY *key_info)
164 {
165  KEY_PART_INFO *key_part= key_info->key_part;
166  KEY_PART_INFO *key_part_end= key_part + key_info->user_defined_key_parts;
167  for (; key_part != key_part_end; key_part++)
168  {
169  if (key_part->null_bit && *tuple)
170  memset(tuple+1, 0, key_part->store_length-1);
171  tuple+= key_part->store_length;
172  }
173 }
174 
175 
188 void key_restore(uchar *to_record, uchar *from_key, KEY *key_info,
189  uint key_length)
190 {
191  uint length;
192  KEY_PART_INFO *key_part;
193 
194  if (key_length == 0)
195  {
196  key_length= key_info->key_length;
197  }
198  for (key_part= key_info->key_part ; (int) key_length > 0 ; key_part++)
199  {
200  uchar used_uneven_bits= 0;
201  if (key_part->null_bit)
202  {
203  if (*from_key++)
204  to_record[key_part->null_offset]|= key_part->null_bit;
205  else
206  to_record[key_part->null_offset]&= ~key_part->null_bit;
207  key_length--;
208  }
209  if (key_part->type == HA_KEYTYPE_BIT)
210  {
211  Field_bit *field= (Field_bit *) (key_part->field);
212  if (field->bit_len)
213  {
214  uchar bits= *(from_key + key_part->length -
215  field->pack_length_in_rec() - 1);
216  set_rec_bits(bits, to_record + key_part->null_offset +
217  (key_part->null_bit == 128),
218  field->bit_ofs, field->bit_len);
219  /* we have now used the byte with 'uneven' bits */
220  used_uneven_bits= 1;
221  }
222  }
223  if (key_part->key_part_flag & HA_BLOB_PART)
224  {
225  /*
226  This in fact never happens, as we have only partial BLOB
227  keys yet anyway, so it's difficult to find any sence to
228  restore the part of a record.
229  Maybe this branch is to be removed, but now we
230  have to ignore GCov compaining.
231  */
232  uint blob_length= uint2korr(from_key);
233  Field_blob *field= (Field_blob*) key_part->field;
234  from_key+= HA_KEY_BLOB_LENGTH;
235  key_length-= HA_KEY_BLOB_LENGTH;
236  field->set_ptr_offset(to_record - field->table->record[0],
237  (ulong) blob_length, from_key);
238  length= key_part->length;
239  }
240  else if (key_part->key_part_flag & HA_VAR_LENGTH_PART)
241  {
242  Field *field= key_part->field;
243  my_bitmap_map *old_map;
244  my_ptrdiff_t ptrdiff= to_record - field->table->record[0];
245  field->move_field_offset(ptrdiff);
246  key_length-= HA_KEY_BLOB_LENGTH;
247  length= min<uint>(key_length, key_part->length);
248  old_map= dbug_tmp_use_all_columns(field->table, field->table->write_set);
249  field->set_key_image(from_key, length);
250  dbug_tmp_restore_column_map(field->table->write_set, old_map);
251  from_key+= HA_KEY_BLOB_LENGTH;
252  field->move_field_offset(-ptrdiff);
253  }
254  else
255  {
256  length= min<uint>(key_length, key_part->length);
257  /* skip the byte with 'uneven' bits, if used */
258  memcpy(to_record + key_part->offset, from_key + used_uneven_bits
259  , (size_t) length - used_uneven_bits);
260  }
261  from_key+= length;
262  key_length-= length;
263  }
264 }
265 
266 
287 bool key_cmp_if_same(TABLE *table,const uchar *key,uint idx,uint key_length)
288 {
289  uint store_length;
290  KEY_PART_INFO *key_part;
291  const uchar *key_end= key + key_length;;
292 
293  for (key_part=table->key_info[idx].key_part;
294  key < key_end ;
295  key_part++, key+= store_length)
296  {
297  uint length;
298  store_length= key_part->store_length;
299 
300  if (key_part->null_bit)
301  {
302  if (*key != test(table->record[0][key_part->null_offset] &
303  key_part->null_bit))
304  return 1;
305  if (*key)
306  continue;
307  key++;
308  store_length--;
309  }
310  if (key_part->key_part_flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART |
311  HA_BIT_PART))
312  {
313  if (key_part->field->key_cmp(key, key_part->length))
314  return 1;
315  continue;
316  }
317  length= min((uint) (key_end-key), store_length);
318  if (!(key_part->key_type & (FIELDFLAG_NUMBER+FIELDFLAG_BINARY+
319  FIELDFLAG_PACK)))
320  {
321  const CHARSET_INFO *cs= key_part->field->charset();
322  uint char_length= key_part->length / cs->mbmaxlen;
323  const uchar *pos= table->record[0] + key_part->offset;
324  if (length > char_length)
325  {
326  char_length= my_charpos(cs, pos, pos + length, char_length);
327  set_if_smaller(char_length, length);
328  }
329  if (cs->coll->strnncollsp(cs,
330  (const uchar*) key, length,
331  (const uchar*) pos, char_length, 0))
332  return 1;
333  continue;
334  }
335  if (memcmp(key,table->record[0]+key_part->offset,length))
336  return 1;
337  }
338  return 0;
339 }
340 
341 
353 void field_unpack(String *to, Field *field, const uchar *rec, uint max_length,
354  bool prefix_key)
355 {
356  String tmp;
357  DBUG_ENTER("field_unpack");
358  if (!max_length)
359  max_length= field->pack_length();
360  if (field)
361  {
362  if (field->is_null())
363  {
364  to->append(STRING_WITH_LEN("NULL"));
365  DBUG_VOID_RETURN;
366  }
367  const CHARSET_INFO *cs= field->charset();
368  field->val_str(&tmp);
369  /*
370  For BINARY(N) strip trailing zeroes to make
371  the error message nice-looking
372  */
373  if (field->binary() && field->type() == MYSQL_TYPE_STRING && tmp.length())
374  {
375  const char *tmp_end= tmp.ptr() + tmp.length();
376  while (tmp_end > tmp.ptr() && !*--tmp_end) ;
377  tmp.length(tmp_end - tmp.ptr() + 1);
378  }
379  if (cs->mbmaxlen > 1 && prefix_key)
380  {
381  /*
382  Prefix key, multi-byte charset.
383  For the columns of type CHAR(N), the above val_str()
384  call will return exactly "key_part->length" bytes,
385  which can break a multi-byte characters in the middle.
386  Align, returning not more than "char_length" characters.
387  */
388  uint charpos, char_length= max_length / cs->mbmaxlen;
389  if ((charpos= my_charpos(cs, tmp.ptr(),
390  tmp.ptr() + tmp.length(),
391  char_length)) < tmp.length())
392  tmp.length(charpos);
393  }
394  if (max_length < field->pack_length())
395  tmp.length(min(tmp.length(),max_length));
396  ErrConvString err(&tmp);
397  to->append(err.ptr());
398  }
399  else
400  to->append(STRING_WITH_LEN("???"));
401  DBUG_VOID_RETURN;
402 }
403 
404 
405 /*
406  unpack key-fields from record to some buffer.
407 
408  This is used mainly to get a good error message. We temporary
409  change the column bitmap so that all columns are readable.
410 
411  @param
412  to Store value here in an easy to read form
413  @param
414  table Table to use
415  @param
416  key Key
417 */
418 
419 void key_unpack(String *to, TABLE *table, KEY *key)
420 {
421  my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
422  DBUG_ENTER("key_unpack");
423 
424  to->length(0);
425  KEY_PART_INFO *key_part_end= key->key_part + key->user_defined_key_parts;
426  for (KEY_PART_INFO *key_part= key->key_part;
427  key_part < key_part_end;
428  key_part++)
429  {
430  if (to->length())
431  to->append('-');
432  if (key_part->null_bit)
433  {
434  if (table->record[0][key_part->null_offset] & key_part->null_bit)
435  {
436  to->append(STRING_WITH_LEN("NULL"));
437  continue;
438  }
439  }
440  field_unpack(to, key_part->field, table->record[0], key_part->length,
441  test(key_part->key_part_flag & HA_PART_KEY_SEG));
442  }
443  dbug_tmp_restore_column_map(table->read_set, old_map);
444  DBUG_VOID_RETURN;
445 }
446 
447 
448 /*
449  Check if key uses field that is marked in passed field bitmap.
450 
451  SYNOPSIS
452  is_key_used()
453  table TABLE object with which keys and fields are associated.
454  idx Key to be checked.
455  fields Bitmap of fields to be checked.
456 
457  NOTE
458  This function uses TABLE::tmp_set bitmap so the caller should care
459  about saving/restoring its state if it also uses this bitmap.
460 
461  RETURN VALUE
462  TRUE Key uses field from bitmap
463  FALSE Otherwise
464 */
465 
466 bool is_key_used(TABLE *table, uint idx, const MY_BITMAP *fields)
467 {
468  bitmap_clear_all(&table->tmp_set);
469  table->mark_columns_used_by_index_no_reset(idx, &table->tmp_set);
470  if (bitmap_is_overlapping(&table->tmp_set, fields))
471  return 1;
472 
473  /*
474  If table handler has primary key as part of the index, check that primary
475  key is not updated
476  */
477  if (idx != table->s->primary_key && table->s->primary_key < MAX_KEY &&
478  (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX))
479  return is_key_used(table, table->s->primary_key, fields);
480  return 0;
481 }
482 
483 
498 int key_cmp(KEY_PART_INFO *key_part, const uchar *key, uint key_length)
499 {
500  uint store_length;
501 
502  for (const uchar *end=key + key_length;
503  key < end;
504  key+= store_length, key_part++)
505  {
506  int cmp;
507  store_length= key_part->store_length;
508  if (key_part->null_bit)
509  {
510  /* This key part allows null values; NULL is lower than everything */
511  register bool field_is_null= key_part->field->is_null();
512  if (*key) // If range key is null
513  {
514  /* the range is expecting a null value */
515  if (!field_is_null)
516  return 1; // Found key is > range
517  /* null -- exact match, go to next key part */
518  continue;
519  }
520  else if (field_is_null)
521  return -1; // NULL is less than any value
522  key++; // Skip null byte
523  store_length--;
524  }
525  if ((cmp=key_part->field->key_cmp(key, key_part->length)) < 0)
526  return -1;
527  if (cmp > 0)
528  return 1;
529  }
530  return 0; // Keys are equal
531 }
532 
533 
566 int key_rec_cmp(void *key_p, uchar *first_rec, uchar *second_rec)
567 {
568  KEY **key= (KEY**) key_p;
569  KEY *key_info= *(key++); // Start with first key
570  uint key_parts, key_part_num;
571  KEY_PART_INFO *key_part= key_info->key_part;
572  uchar *rec0= key_part->field->ptr - key_part->offset;
573  my_ptrdiff_t first_diff= first_rec - rec0, sec_diff= second_rec - rec0;
574  int result= 0;
575  Field *field;
576  DBUG_ENTER("key_rec_cmp");
577 
578  /* Assert that at least the first key part is read. */
579  DBUG_ASSERT(bitmap_is_set(key_info->table->read_set,
580  key_info->key_part->field->field_index));
581  /* loop over all given keys */
582  do
583  {
584  key_parts= key_info->user_defined_key_parts;
585  key_part= key_info->key_part;
586  key_part_num= 0;
587 
588  /* loop over every key part */
589  do
590  {
591  field= key_part->field;
592 
593  /* If not read, compare is done and equal! */
594  if (!bitmap_is_set(field->table->read_set, field->field_index))
595  DBUG_RETURN(0);
596 
597  if (key_part->null_bit)
598  {
599  /* The key_part can contain NULL values */
600  bool first_is_null= field->is_real_null(first_diff);
601  bool sec_is_null= field->is_real_null(sec_diff);
602  /*
603  NULL is smaller then everything so if first is NULL and the other
604  not then we know that we should return -1 and for the opposite
605  we should return +1. If both are NULL then we call it equality
606  although it is a strange form of equality, we have equally little
607  information of the real value.
608  */
609  if (!first_is_null)
610  {
611  if (!sec_is_null)
612  ; /* Fall through, no NULL fields */
613  else
614  {
615  DBUG_RETURN(+1);
616  }
617  }
618  else if (!sec_is_null)
619  {
620  DBUG_RETURN(-1);
621  }
622  else
623  goto next_loop; /* Both were NULL */
624  }
625  /*
626  No null values in the fields
627  We use the virtual method cmp_max with a max length parameter.
628  For most field types this translates into a cmp without
629  max length. The exceptions are the BLOB and VARCHAR field types
630  that take the max length into account.
631  */
632  if ((result= field->cmp_max(field->ptr+first_diff, field->ptr+sec_diff,
633  key_part->length)))
634  DBUG_RETURN(result);
635 next_loop:
636  key_part++;
637  key_part_num++;
638  } while (key_part_num < key_parts); /* this key is done */
639 
640  key_info= *(key++);
641  } while (key_info); /* no more keys to test */
642  DBUG_RETURN(0);
643 }