12
12
You should have received a copy of the GNU General Public License
13
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 */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
17
/* Functions to handle keys and fields in forms */
60
57
key_length is set to length of key before (not including) field
63
int find_ref_key(KeyInfo *key, uint32_t key_count, unsigned char *record, Field *field,
60
int find_ref_key(KEY *key, uint32_t key_count, unsigned char *record, Field *field,
64
61
uint32_t *key_length, uint32_t *keypart)
67
register KeyInfo *key_info;
64
register KEY *key_info;
70
67
fieldpos= field->offset(record);
148
145
Zero the null components of key tuple.
151
void key_zero_nulls(unsigned char *tuple, KeyInfo *key_info)
148
void key_zero_nulls(unsigned char *tuple, KEY *key_info)
153
KeyPartInfo *key_part= key_info->key_part;
154
KeyPartInfo *key_part_end= key_part + key_info->key_parts;
150
KEY_PART_INFO *key_part= key_info->key_part;
151
KEY_PART_INFO *key_part_end= key_part + key_info->key_parts;
155
152
for (; key_part != key_part_end; key_part++)
157
154
if (key_part->null_bit && *tuple)
173
170
@param key_length specifies length of all keyparts that will be restored
176
void key_restore(unsigned char *to_record, unsigned char *from_key, KeyInfo *key_info,
173
void key_restore(unsigned char *to_record, unsigned char *from_key, KEY *key_info,
177
174
uint16_t key_length)
180
KeyPartInfo *key_part;
177
KEY_PART_INFO *key_part;
182
179
if (key_length == 0)
211
208
field->setReadSet();
212
209
from_key+= HA_KEY_BLOB_LENGTH;
213
210
key_length-= HA_KEY_BLOB_LENGTH;
214
field->set_ptr_offset(to_record - field->getTable()->getInsertRecord(),
211
field->set_ptr_offset(to_record - field->table->record[0],
215
212
(ulong) blob_length, from_key);
216
213
length= key_part->length;
218
215
else if (key_part->key_part_flag & HA_VAR_LENGTH_PART)
220
217
Field *field= key_part->field;
221
ptrdiff_t ptrdiff= to_record - field->getTable()->getInsertRecord();
218
ptrdiff_t ptrdiff= to_record - field->table->record[0];
223
220
field->setReadSet();
224
221
field->setWriteSet();
298
295
const CHARSET_INFO * const cs= key_part->field->charset();
299
296
uint32_t char_length= key_part->length / cs->mbmaxlen;
300
const unsigned char *pos= table->getInsertRecord() + key_part->offset;
297
const unsigned char *pos= table->record[0] + key_part->offset;
301
298
if (length > char_length)
303
300
char_length= my_charpos(cs, pos, pos + length, char_length);
405
bool is_key_used(Table *table, uint32_t idx, const boost::dynamic_bitset<>& fields)
402
bool is_key_used(Table *table, uint32_t idx, const MyBitmap *fields)
407
table->tmp_set.reset();
408
table->mark_columns_used_by_index_no_reset(idx, table->tmp_set);
409
if (table->tmp_set.is_subset_of(fields))
404
table->tmp_set.clearAll();
405
table->mark_columns_used_by_index_no_reset(idx, &table->tmp_set);
406
if (bitmap_is_overlapping(&table->tmp_set, fields))
413
410
If table handler has primary key as part of the index, check that primary
414
411
key is not updated
416
if (idx != table->getShare()->getPrimaryKey() && table->getShare()->hasPrimaryKey() &&
413
if (idx != table->s->primary_key && table->s->primary_key < MAX_KEY &&
417
414
(table->cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)))
419
return is_key_used(table, table->getShare()->getPrimaryKey(), fields);
415
return is_key_used(table, table->s->primary_key, fields);
471
Compare two records in index order
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
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.
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].
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.
495
int key_rec_cmp(void *key, unsigned char *first_rec, unsigned char *second_rec)
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;
506
Field *field= key_part->field;
508
if (key_part->null_bit)
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);
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.
523
; /* Fall through, no NULL fields */
529
else if (!sec_is_null)
534
goto next_loop; /* Both were NULL */
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.
543
result= field->cmp_max(field->ptr+first_diff, field->ptr+sec_diff,
547
} while (!result && ++i < key_parts);
475
551
} /* namespace drizzled */