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 */
19
#include "drizzled/server_includes.h"
20
20
#include "drizzled/table.h"
21
21
#include "drizzled/key.h"
22
22
#include "drizzled/field/blob.h"
23
#include "drizzled/util/test.h"
24
#include "drizzled/plugin/storage_engine.h"
26
#include <boost/dynamic_bitset.hpp>
61
54
key_length is set to length of key before (not including) field
64
int find_ref_key(KeyInfo *key, uint32_t key_count, unsigned char *record, Field *field,
57
int find_ref_key(KEY *key, uint32_t key_count, unsigned char *record, Field *field,
65
58
uint32_t *key_length, uint32_t *keypart)
68
register KeyInfo *key_info;
61
register KEY *key_info;
71
64
fieldpos= field->offset(record);
149
142
Zero the null components of key tuple.
152
void key_zero_nulls(unsigned char *tuple, KeyInfo *key_info)
145
void key_zero_nulls(unsigned char *tuple, KEY *key_info)
154
KeyPartInfo *key_part= key_info->key_part;
155
KeyPartInfo *key_part_end= key_part + key_info->key_parts;
147
KEY_PART_INFO *key_part= key_info->key_part;
148
KEY_PART_INFO *key_part_end= key_part + key_info->key_parts;
156
149
for (; key_part != key_part_end; key_part++)
158
151
if (key_part->null_bit && *tuple)
174
167
@param key_length specifies length of all keyparts that will be restored
177
void key_restore(unsigned char *to_record, unsigned char *from_key, KeyInfo *key_info,
170
void key_restore(unsigned char *to_record, unsigned char *from_key, KEY *key_info,
178
171
uint16_t key_length)
181
KeyPartInfo *key_part;
174
KEY_PART_INFO *key_part;
183
176
if (key_length == 0)
212
205
field->setReadSet();
213
206
from_key+= HA_KEY_BLOB_LENGTH;
214
207
key_length-= HA_KEY_BLOB_LENGTH;
215
field->set_ptr_offset(to_record - field->getTable()->getInsertRecord(),
208
field->set_ptr_offset(to_record - field->table->record[0],
216
209
(ulong) blob_length, from_key);
217
210
length= key_part->length;
219
212
else if (key_part->key_part_flag & HA_VAR_LENGTH_PART)
221
214
Field *field= key_part->field;
222
ptrdiff_t ptrdiff= to_record - field->getTable()->getInsertRecord();
215
ptrdiff_t ptrdiff= to_record - field->table->record[0];
224
217
field->setReadSet();
225
218
field->setWriteSet();
299
292
const CHARSET_INFO * const cs= key_part->field->charset();
300
293
uint32_t char_length= key_part->length / cs->mbmaxlen;
301
const unsigned char *pos= table->getInsertRecord() + key_part->offset;
294
const unsigned char *pos= table->record[0] + key_part->offset;
302
295
if (length > char_length)
304
297
char_length= my_charpos(cs, pos, pos + length, char_length);
333
void key_unpack(String *to, const Table *table, uint32_t idx)
326
void key_unpack(String *to, Table *table, uint32_t idx)
335
KeyPartInfo *key_part,*key_part_end;
328
KEY_PART_INFO *key_part,*key_part_end;
406
bool is_key_used(Table *table, uint32_t idx, const boost::dynamic_bitset<>& fields)
399
bool is_key_used(Table *table, uint32_t idx, const MyBitmap *fields)
408
table->tmp_set.reset();
409
table->mark_columns_used_by_index_no_reset(idx, table->tmp_set);
410
if (table->tmp_set.is_subset_of(fields))
401
table->tmp_set.clearAll();
402
table->mark_columns_used_by_index_no_reset(idx, &table->tmp_set);
403
if (bitmap_is_overlapping(&table->tmp_set, fields))
414
407
If table handler has primary key as part of the index, check that primary
415
408
key is not updated
417
if (idx != table->getShare()->getPrimaryKey() && table->getShare()->hasPrimaryKey() &&
410
if (idx != table->s->primary_key && table->s->primary_key < MAX_KEY &&
418
411
(table->cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)))
420
return is_key_used(table, table->getShare()->getPrimaryKey(), fields);
412
return is_key_used(table, table->s->primary_key, fields);
476
} /* namespace drizzled */
468
Compare two records in index order
471
key Index information
472
rec0 Pointer to table->record[0]
473
first_rec Pointer to record compare with
474
second_rec Pointer to record compare against first_rec
477
This method is set-up such that it can be called directly from the
478
priority queue and it is attempted to be optimised as much as possible
479
since this will be called O(N * log N) times while performing a merge
480
sort in various places in the code.
482
We retrieve the pointer to table->record[0] using the fact that key_parts
483
have an offset making it possible to calculate the start of the record.
484
We need to get the diff to the compared record since none of the records
485
being compared are stored in table->record[0].
487
We first check for NULL values, if there are no NULL values we use
488
a compare method that gets two field pointers and a max length
489
and return the result of the comparison.
492
int key_rec_cmp(void *key, unsigned char *first_rec, unsigned char *second_rec)
494
KEY *key_info= (KEY*)key;
495
uint32_t key_parts= key_info->key_parts, i= 0;
496
KEY_PART_INFO *key_part= key_info->key_part;
497
unsigned char *rec0= key_part->field->ptr - key_part->offset;
498
ptrdiff_t first_diff= first_rec - rec0, sec_diff= second_rec - rec0;
503
Field *field= key_part->field;
505
if (key_part->null_bit)
507
/* The key_part can contain NULL values */
508
bool first_is_null= field->is_null_in_record_with_offset(first_diff);
509
bool sec_is_null= field->is_null_in_record_with_offset(sec_diff);
511
NULL is smaller then everything so if first is NULL and the other
512
not then we know that we should return -1 and for the opposite
513
we should return +1. If both are NULL then we call it equality
514
although it is a strange form of equality, we have equally little
515
information of the real value.
520
; /* Fall through, no NULL fields */
526
else if (!sec_is_null)
531
goto next_loop; /* Both were NULL */
534
No null values in the fields
535
We use the virtual method cmp_max with a max length parameter.
536
For most field types this translates into a cmp without
537
max length. The exceptions are the BLOB and VARCHAR field types
538
that take the max length into account.
540
result= field->cmp_max(field->ptr+first_diff, field->ptr+sec_diff,
544
} while (!result && ++i < key_parts);