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"
25
#include <boost/dynamic_bitset.hpp>
60
54
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,
57
int find_ref_key(KEY *key, uint32_t key_count, unsigned char *record, Field *field,
64
58
uint32_t *key_length, uint32_t *keypart)
67
register KeyInfo *key_info;
61
register KEY *key_info;
70
64
fieldpos= field->offset(record);
148
142
Zero the null components of key tuple.
151
void key_zero_nulls(unsigned char *tuple, KeyInfo *key_info)
145
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;
147
KEY_PART_INFO *key_part= key_info->key_part;
148
KEY_PART_INFO *key_part_end= key_part + key_info->key_parts;
155
149
for (; key_part != key_part_end; key_part++)
157
151
if (key_part->null_bit && *tuple)
211
205
field->setReadSet();
212
206
from_key+= HA_KEY_BLOB_LENGTH;
213
207
key_length-= HA_KEY_BLOB_LENGTH;
214
field->set_ptr_offset(to_record - field->getTable()->getInsertRecord(),
208
field->set_ptr_offset(to_record - field->table->record[0],
215
209
(ulong) blob_length, from_key);
216
210
length= key_part->length;
218
212
else if (key_part->key_part_flag & HA_VAR_LENGTH_PART)
220
214
Field *field= key_part->field;
221
ptrdiff_t ptrdiff= to_record - field->getTable()->getInsertRecord();
215
ptrdiff_t ptrdiff= to_record - field->table->record[0];
223
217
field->setReadSet();
224
218
field->setWriteSet();
298
292
const CHARSET_INFO * const cs= key_part->field->charset();
299
293
uint32_t char_length= key_part->length / cs->mbmaxlen;
300
const unsigned char *pos= table->getInsertRecord() + key_part->offset;
294
const unsigned char *pos= table->record[0] + key_part->offset;
301
295
if (length > char_length)
303
297
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)
399
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))
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))
413
407
If table handler has primary key as part of the index, check that primary
414
408
key is not updated
416
if (idx != table->getShare()->getPrimaryKey() && table->getShare()->hasPrimaryKey() &&
417
(table->cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)))
419
return is_key_used(table, table->getShare()->getPrimaryKey(), fields);
410
if (idx != table->s->primary_key && table->s->primary_key < MAX_KEY &&
411
(table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX))
412
return is_key_used(table, table->s->primary_key, fields);
475
} /* 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);
548
Key::Key(const Key &rhs, MEM_ROOT *mem_root)
550
key_create_info(rhs.key_create_info),
551
columns(rhs.columns, mem_root),
553
generated(rhs.generated)
555
list_copy_and_replace_each_value(columns, mem_root);