20 #include <drizzled/table.h>
21 #include <drizzled/key.h>
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>
64 int find_ref_key(KeyInfo *key, uint32_t key_count,
unsigned char *record, Field *field,
65 uint32_t *key_length, uint32_t *keypart)
71 fieldpos= field->offset(record);
74 for (i= 0, key_info= key ;
78 if (key_info->key_part[0].offset == fieldpos)
80 *key_length= *keypart= 0;
86 for (i= 0, key_info= key;
91 KeyPartInfo *key_part;
93 for (j=0, key_part=key_info->key_part ;
94 j < key_info->key_parts ;
97 if (key_part->offset == fieldpos)
102 *key_length+= key_part->store_length;
109 void key_copy(
unsigned char *to_key,
unsigned char *from_record, KeyInfo *key_info,
110 unsigned int key_length)
113 KeyPartInfo *key_part;
116 key_length= key_info->key_length;
117 for (key_part= key_info->key_part; (
int) key_length > 0; key_part++)
119 if (key_part->null_bit)
121 *to_key++= test(from_record[key_part->null_offset] &
125 if (key_part->key_part_flag & HA_BLOB_PART ||
126 key_part->key_part_flag & HA_VAR_LENGTH_PART)
128 key_length-= HA_KEY_BLOB_LENGTH;
129 length= min((uint16_t)key_length, key_part->length);
130 key_part->field->get_key_image(to_key, length);
131 to_key+= HA_KEY_BLOB_LENGTH;
135 length= min((uint16_t)key_length, key_part->length);
136 Field *field= key_part->field;
137 const charset_info_st *
const cs= field->charset();
138 uint32_t bytes= field->get_key_image(to_key, length);
140 cs->cset->fill(cs, (
char*) to_key + bytes, length - bytes,
' ');
155 KeyPartInfo *key_part_end= key_part + key_info->key_parts;
156 for (; key_part != key_part_end; key_part++)
158 if (key_part->null_bit && *tuple)
159 memset(tuple+1, 0, key_part->store_length-1);
160 tuple+= key_part->store_length;
177 void key_restore(
unsigned char *to_record,
unsigned char *from_key, KeyInfo *key_info,
181 KeyPartInfo *key_part;
185 key_length= key_info->key_length;
187 for (key_part= key_info->key_part ; (
int) key_length > 0 ; key_part++)
189 unsigned char used_uneven_bits= 0;
190 if (key_part->null_bit)
193 to_record[key_part->null_offset]|= key_part->null_bit;
195 to_record[key_part->null_offset]&= ~key_part->null_bit;
198 if (key_part->key_part_flag & HA_BLOB_PART)
209 uint32_t blob_length= uint2korr(from_key);
210 Field_blob *field= (Field_blob*) key_part->field;
213 from_key+= HA_KEY_BLOB_LENGTH;
214 key_length-= HA_KEY_BLOB_LENGTH;
215 field->set_ptr_offset(to_record - field->getTable()->getInsertRecord(),
216 (ulong) blob_length, from_key);
217 length= key_part->length;
219 else if (key_part->key_part_flag & HA_VAR_LENGTH_PART)
221 Field *field= key_part->field;
222 ptrdiff_t ptrdiff= to_record - field->getTable()->getInsertRecord();
225 field->setWriteSet();
226 field->move_field_offset(ptrdiff);
227 key_length-= HA_KEY_BLOB_LENGTH;
228 length= min(key_length, key_part->length);
229 field->set_key_image(from_key, length);
230 from_key+= HA_KEY_BLOB_LENGTH;
231 field->move_field_offset(-ptrdiff);
235 length= min(key_length, key_part->length);
237 memcpy(to_record + key_part->offset, from_key + used_uneven_bits
238 , (
size_t) length - used_uneven_bits);
270 const unsigned char *key_end= key + key_length;;
272 for (key_part=table->
key_info[idx].key_part;
274 key_part++, key+= store_length)
277 store_length= key_part->store_length;
279 if (key_part->null_bit)
281 if (*key != test(table->getInsertRecord()[key_part->null_offset] &
289 if (key_part->key_part_flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART |
292 if (key_part->field->key_cmp(key, key_part->length))
296 length= min((uint32_t) (key_end-key), store_length);
297 if (key_part->field->type() == DRIZZLE_TYPE_VARCHAR)
300 uint32_t char_length= key_part->length / cs->mbmaxlen;
301 const unsigned char *pos= table->getInsertRecord() + key_part->offset;
302 if (length > char_length)
304 char_length= my_charpos(cs, pos, pos + length, char_length);
305 set_if_smaller(char_length, length);
307 if (cs->coll->strnncollsp(cs,
308 (
const unsigned char*) key, length,
309 (
const unsigned char*) pos, char_length, 0))
313 if (memcmp(key,table->getInsertRecord()+key_part->offset,length))
333 void key_unpack(String *to,
const Table *table, uint32_t idx)
335 KeyPartInfo *key_part,*key_part_end;
340 for (key_part=table->key_info[idx].key_part,key_part_end=key_part+
341 table->key_info[idx].key_parts ;
342 key_part < key_part_end;
347 if (key_part->null_bit)
349 if (table->getInsertRecord()[key_part->null_offset] & key_part->null_bit)
351 to->append(STRING_WITH_LEN(
"NULL"));
355 if ((field= key_part->field))
357 const charset_info_st *
const cs= field->charset();
359 field->val_str_internal(&tmp);
360 if (cs->mbmaxlen > 1 &&
361 table->getField(key_part->fieldnr - 1)->field_length !=
371 uint32_t charpos, char_length= key_part->length / cs->mbmaxlen;
372 if ((charpos= my_charpos(cs, tmp.c_ptr(), tmp.c_ptr() + tmp.length(), char_length)) < key_part->length)
376 if (key_part->length < field->pack_length())
377 tmp.length(min(tmp.length(),
static_cast<size_t>(key_part->length)));
381 to->append(STRING_WITH_LEN(
"???"));
404 bool is_key_used(Table *table, uint32_t idx,
const boost::dynamic_bitset<>& fields)
406 table->tmp_set.reset();
407 table->mark_columns_used_by_index_no_reset(idx, table->tmp_set);
408 if (table->tmp_set.is_subset_of(fields))
415 if (idx != table->getShare()->getPrimaryKey() && table->getShare()->hasPrimaryKey() &&
416 (table->cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)))
418 return is_key_used(table, table->getShare()->getPrimaryKey(), fields);
442 for (
const unsigned char *end=key + key_length;
447 store_length= key_part->store_length;
448 if (key_part->null_bit)
451 bool field_is_null= key_part->field->is_null();
460 else if (field_is_null)
465 if ((cmp=key_part->field->key_cmp(key, key_part->length)) < 0)
void key_zero_nulls(unsigned char *tuple, KeyInfo *key_info)
int key_cmp(KeyPartInfo *key_part, const unsigned char *key, uint32_t key_length)
static void store_length(unsigned char *to, uint32_t length, uint32_t pack_length)
bool key_cmp_if_same(Table *table, const unsigned char *key, uint32_t idx, uint32_t key_length)