null+****@clear*****
null+****@clear*****
2010年 10月 14日 (木) 01:40:32 JST
Kentoku SHIBA 2010-10-13 16:40:32 +0000 (Wed, 13 Oct 2010) New Revision: 65cf64f4955701dfc813c0bd58ebb5776dea3d4b Log: #446 add secondary key search feature Modified files: ha_mroonga.cc ha_mroonga.h Modified: ha_mroonga.cc (+173 -89) =================================================================== --- ha_mroonga.cc 2010-10-13 13:37:15 +0000 (196dc22) +++ ha_mroonga.cc 2010-10-13 16:40:32 +0000 (e7b1cd5) @@ -1090,7 +1090,7 @@ int ha_mroonga::rnd_next(uchar *buf) table->status = STATUS_NOT_FOUND; DBUG_RETURN(HA_ERR_END_OF_FILE); } - store_fields_from_primary_table(row_id); + store_fields_from_primary_table(buf, row_id); table->status = 0; DBUG_RETURN(0); } @@ -1099,7 +1099,7 @@ int ha_mroonga::rnd_pos(uchar *buf, uchar *pos) { DBUG_ENTER("ha_mroonga::rnd_pos"); row_id = *((grn_id*) pos); - store_fields_from_primary_table(row_id); + store_fields_from_primary_table(buf, row_id); DBUG_RETURN(0); } @@ -1273,78 +1273,69 @@ int ha_mroonga::index_end() DBUG_RETURN(0); } -int ha_mroonga::index_read_map(uchar * record_buffer, const uchar * key, +int ha_mroonga::index_read_map(uchar * buf, const uchar * key, key_part_map keypart_map, enum ha_rkey_function find_flag) { DBUG_ENTER("ha_mroonga::index_read_map"); - uint key_len = calculate_key_len(table, active_index, key, keypart_map); uint keynr = active_index; - uint pkeynr = table->s->primary_key; KEY key_info = table->key_info[keynr]; KEY_PART_INFO key_part = key_info.key_part[0]; check_count_skip(keypart_map, 0, FALSE); - if (count_skip) { - int flags = 0; - uint size_min = 0, size_max = 0; - void *val_min = NULL, *val_max = NULL; - Field *field = key_part.field; - - if (cur) { - grn_table_cursor_close(ctx, cur); - cur = NULL; - } - if (find_flag == HA_READ_KEY_EXACT) { - mrn_set_key_buf(ctx, field, key, key_min[keynr], &size_min); - val_min = key_min[keynr]; - val_max = key_min[keynr]; - size_max = size_min; - } else if ( - find_flag == HA_READ_BEFORE_KEY || - find_flag == HA_READ_PREFIX_LAST_OR_PREV - ) { - mrn_set_key_buf(ctx, field, key, key_max[keynr], &size_max); - val_max = key_max[keynr]; - if (find_flag == HA_READ_BEFORE_KEY) { - flags |= GRN_CURSOR_LT; - } - } else { - mrn_set_key_buf(ctx, field, key, key_min[keynr], &size_min); - val_min = key_min[keynr]; - if (find_flag == HA_READ_AFTER_KEY) { - flags |= GRN_CURSOR_GT; - } - } + int flags = 0; + uint size_min = 0, size_max = 0; + void *val_min = NULL, *val_max = NULL; + Field *field = key_part.field; - uint pkeynr = table->s->primary_key; + if (cur) { + grn_table_cursor_close(ctx, cur); + cur = NULL; + } - if (keynr == pkeynr) { // primary index - cur = - grn_table_cursor_open(ctx, tbl, val_min, size_min, val_max, size_max, - 0, -1, flags); - } else { // normal index - cur = - grn_table_cursor_open(ctx, idx_tbl[keynr], val_min, size_min, - val_max, size_max, 0, -1, flags); - } - row_id = grn_table_cursor_next(ctx, cur); - if (row_id == GRN_ID_NIL) { - grn_table_cursor_close(ctx, cur); - cur = NULL; - table->status = STATUS_NOT_FOUND; - DBUG_RETURN(HA_ERR_END_OF_FILE); - } - if (keynr == pkeynr) { // primary index - /* store only for first time */ - store_fields_from_primary_table(row_id); + if (find_flag == HA_READ_KEY_EXACT) { + mrn_set_key_buf(ctx, field, key, key_min[keynr], &size_min); + val_min = key_min[keynr]; + val_max = key_min[keynr]; + size_max = size_min; + } else if ( + find_flag == HA_READ_BEFORE_KEY || + find_flag == HA_READ_PREFIX_LAST_OR_PREV + ) { + mrn_set_key_buf(ctx, field, key, key_max[keynr], &size_max); + val_max = key_max[keynr]; + if (find_flag == HA_READ_BEFORE_KEY) { + flags |= GRN_CURSOR_LT; } } else { - if (keynr == pkeynr) { - row_id = grn_table_get(ctx, tbl, key, key_len); - store_fields_from_primary_table(row_id); + mrn_set_key_buf(ctx, field, key, key_min[keynr], &size_min); + val_min = key_min[keynr]; + if (find_flag == HA_READ_AFTER_KEY) { + flags |= GRN_CURSOR_GT; } } + + uint pkeynr = table->s->primary_key; + + if (keynr == pkeynr) { // primary index + DBUG_PRINT("info",("mroonga use primary key")); + cur = + grn_table_cursor_open(ctx, tbl, val_min, size_min, val_max, size_max, + 0, -1, flags); + } else { // normal index + DBUG_PRINT("info",("mroonga use key%u", keynr)); + cur = + grn_table_cursor_open(ctx, idx_tbl[keynr], val_min, size_min, + val_max, size_max, 0, -1, flags); + } + row_id = grn_table_cursor_next(ctx, cur); + if (row_id == GRN_ID_NIL) { + grn_table_cursor_close(ctx, cur); + cur = NULL; + table->status = STATUS_NOT_FOUND; + DBUG_RETURN(HA_ERR_END_OF_FILE); + } + store_fields_from_primary_table(buf, row_id); table->status = 0; DBUG_RETURN(0); } @@ -1353,6 +1344,47 @@ int ha_mroonga::index_read_last_map(uchar *buf, const uchar *key, key_part_map keypart_map) { DBUG_ENTER("ha_mroonga::index_read_last_map"); + uint keynr = active_index; + KEY key_info = table->key_info[keynr]; + KEY_PART_INFO key_part = key_info.key_part[0]; + + int flags = GRN_CURSOR_DESCENDING; + uint size_min = 0, size_max = 0; + void *val_min = NULL, *val_max = NULL; + Field *field = key_part.field; + + if (cur) { + grn_table_cursor_close(ctx, cur); + cur = NULL; + } + + mrn_set_key_buf(ctx, field, key, key_min[keynr], &size_min); + val_min = key_min[keynr]; + val_max = key_min[keynr]; + size_max = size_min; + + uint pkeynr = table->s->primary_key; + + if (keynr == pkeynr) { // primary index + DBUG_PRINT("info",("mroonga use primary key")); + cur = + grn_table_cursor_open(ctx, tbl, val_min, size_min, val_max, size_max, + 0, -1, flags); + } else { // normal index + DBUG_PRINT("info",("mroonga use key%u", keynr)); + cur = + grn_table_cursor_open(ctx, idx_tbl[keynr], val_min, size_min, + val_max, size_max, 0, -1, flags); + } + row_id = grn_table_cursor_next(ctx, cur); + if (row_id == GRN_ID_NIL) { + grn_table_cursor_close(ctx, cur); + cur = NULL; + table->status = STATUS_NOT_FOUND; + DBUG_RETURN(HA_ERR_END_OF_FILE); + } + store_fields_from_primary_table(buf, row_id); + table->status = 0; DBUG_RETURN(0); } @@ -1366,7 +1398,7 @@ int ha_mroonga::index_next(uchar *buf) table->status = STATUS_NOT_FOUND; DBUG_RETURN(HA_ERR_END_OF_FILE); } - store_fields_from_primary_table(row_id); + store_fields_from_primary_table(buf, row_id); table->status = 0; DBUG_RETURN(0); } @@ -1374,41 +1406,95 @@ int ha_mroonga::index_next(uchar *buf) int ha_mroonga::index_prev(uchar *buf) { DBUG_ENTER("ha_mroonga::index_prev"); - table->status = STATUS_NOT_FOUND; - DBUG_RETURN(HA_ERR_END_OF_FILE); + row_id = grn_table_cursor_next(ctx, cur); + if (row_id == GRN_ID_NIL) { + grn_table_cursor_close(ctx, cur); + cur = NULL; + table->status = STATUS_NOT_FOUND; + DBUG_RETURN(HA_ERR_END_OF_FILE); + } + store_fields_from_primary_table(buf, row_id); + table->status = 0; + DBUG_RETURN(0); } int ha_mroonga::index_first(uchar *buf) { DBUG_ENTER("ha_mroonga::index_first"); - table->status = STATUS_NOT_FOUND; - DBUG_RETURN(HA_ERR_END_OF_FILE); + if (cur) { + grn_table_cursor_close(ctx, cur); + cur = NULL; + } + uint pkeynr = table->s->primary_key; + if (active_index == pkeynr) { // primary index + DBUG_PRINT("info",("mroonga use primary key")); + cur = + grn_table_cursor_open(ctx, tbl, NULL, 0, NULL, 0, + 0, -1, 0); + } else { // normal index + DBUG_PRINT("info",("mroonga use key%u", active_index)); + cur = + grn_table_cursor_open(ctx, idx_tbl[active_index], NULL, 0, + NULL, 0, 0, -1, 0); + } + row_id = grn_table_cursor_next(ctx, cur); + if (row_id == GRN_ID_NIL) { + grn_table_cursor_close(ctx, cur); + cur = NULL; + table->status = STATUS_NOT_FOUND; + DBUG_RETURN(HA_ERR_END_OF_FILE); + } + store_fields_from_primary_table(buf, row_id); + table->status = 0; + DBUG_RETURN(0); } int ha_mroonga::index_last(uchar *buf) { DBUG_ENTER("ha_mroonga::index_last"); - table->status = STATUS_NOT_FOUND; - DBUG_RETURN(HA_ERR_END_OF_FILE); + if (cur) { + grn_table_cursor_close(ctx, cur); + cur = NULL; + } + int flags = GRN_CURSOR_DESCENDING; + uint pkeynr = table->s->primary_key; + if (active_index == pkeynr) { // primary index + DBUG_PRINT("info",("mroonga use primary key")); + cur = + grn_table_cursor_open(ctx, tbl, NULL, 0, NULL, 0, + 0, -1, flags); + } else { // normal index + DBUG_PRINT("info",("mroonga use key%u", active_index)); + cur = + grn_table_cursor_open(ctx, idx_tbl[active_index], NULL, 0, + NULL, 0, 0, -1, flags); + } + row_id = grn_table_cursor_next(ctx, cur); + if (row_id == GRN_ID_NIL) { + grn_table_cursor_close(ctx, cur); + cur = NULL; + table->status = STATUS_NOT_FOUND; + DBUG_RETURN(HA_ERR_END_OF_FILE); + } + store_fields_from_primary_table(buf, row_id); + table->status = 0; + DBUG_RETURN(0); } int ha_mroonga::index_next_same(uchar *buf, const uchar *key, uint keylen) { DBUG_ENTER("ha_mroonga::index_next_same"); - if (count_skip) { - row_id = grn_table_cursor_next(ctx, cur); - - if (row_id == GRN_ID_NIL) { - grn_table_cursor_close(ctx, cur); - cur = NULL; - table->status = STATUS_NOT_FOUND; - DBUG_RETURN(HA_ERR_END_OF_FILE); - } - table->status = 0; - DBUG_RETURN(0); - } else { - DBUG_RETURN(handler::index_next_same(buf, key, keylen)); + row_id = grn_table_cursor_next(ctx, cur); + if (row_id == GRN_ID_NIL) { + grn_table_cursor_close(ctx, cur); + cur = NULL; + table->status = STATUS_NOT_FOUND; + DBUG_RETURN(HA_ERR_END_OF_FILE); } + if (!count_skip) + store_fields_from_primary_table(buf, row_id); + table->status = 0; + DBUG_RETURN(0); } int ha_mroonga::read_range_first(const key_range *start_key, @@ -1466,9 +1552,7 @@ int ha_mroonga::read_range_first(const key_range *start_key, table->status = STATUS_NOT_FOUND; DBUG_RETURN(HA_ERR_END_OF_FILE); } - if (active_index == pkeynr) { // primary index - store_fields_from_primary_table(row_id); - } + store_fields_from_primary_table(table->record[0], row_id); table->status = 0; DBUG_RETURN(0); } @@ -1485,11 +1569,8 @@ int ha_mroonga::read_range_next() { } uint pkeynr = table->s->primary_key; - if (!count_skip) { - if (active_index == pkeynr) { // primary index - store_fields_from_primary_table(row_id); - } - } + if (!count_skip) + store_fields_from_primary_table(table->record[0], row_id); table->status = 0; DBUG_RETURN(0); } @@ -1548,7 +1629,7 @@ int ha_mroonga::ft_read(uchar *buf) } grn_table_get_key(ctx, res, rid, &row_id, sizeof(grn_id)); - store_fields_from_primary_table(row_id); + store_fields_from_primary_table(buf, row_id); DBUG_RETURN(0); } @@ -1662,9 +1743,10 @@ void ha_mroonga::check_count_skip(key_part_map start_key_part_map, DBUG_VOID_RETURN; } -void ha_mroonga::store_fields_from_primary_table(grn_id rid) +void ha_mroonga::store_fields_from_primary_table(uchar *buf, grn_id rid) { DBUG_ENTER("ha_mroonga::store_fields_from_primary_table"); + my_ptrdiff_t ptr_diff = PTR_BYTE_DIFF(buf, table->record[0]); int i; int n_columns = table->s->fields; for (i = 0; i < n_columns; i++) { @@ -1676,7 +1758,9 @@ void ha_mroonga::store_fields_from_primary_table(grn_id rid) table->write_set); #endif DBUG_PRINT("info",("mroonga store column %d(%d)",i,field->field_index)); + field->move_field_offset(ptr_diff); mrn_store_field(ctx, field, col[i], rid); + field->move_field_offset(-ptr_diff); #ifndef DBUG_OFF dbug_tmp_restore_column_map(table->write_set, tmp_map); #endif Modified: ha_mroonga.h (+2 -2) =================================================================== --- ha_mroonga.h 2010-10-13 13:37:15 +0000 (be3d713) +++ ha_mroonga.h 2010-10-13 16:40:32 +0000 (9a0fba8) @@ -107,7 +107,7 @@ public: ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key); int index_init(uint idx, bool sorted); int index_end(); - int index_read_map(uchar * record_buffer, const uchar * key, + int index_read_map(uchar * buf, const uchar * key, key_part_map keypart_map, enum ha_rkey_function find_flag); int index_read_last_map(uchar *buf, const uchar *key, @@ -135,7 +135,7 @@ public: private: void check_count_skip(key_part_map start_key_part_map, key_part_map end_key_part_map, bool fulltext); - void store_fields_from_primary_table(grn_id rid); + void store_fields_from_primary_table(uchar *buf, grn_id rid); }; #ifdef __cplusplus