Kouhei Sutou
null+****@clear*****
Tue Feb 5 16:12:49 JST 2013
Kouhei Sutou 2013-02-05 16:12:49 +0900 (Tue, 05 Feb 2013) New Revision: 8d8af5c0c99a04849363c3a8d18d552e72fbdc96 https://github.com/groonga/groonga/commit/8d8af5c0c99a04849363c3a8d18d552e72fbdc96 Log: Add missing min/max normalization to grn_table_cursor_open() min and max are key values. So we cannot find records without key normalization. Modified files: lib/db.c test/unit/core/test-table-cursor.c Modified: lib/db.c (+40 -10) =================================================================== --- lib/db.c 2013-02-04 15:28:30 +0900 (7dec07c) +++ lib/db.c 2013-02-05 16:12:49 +0900 (7173ad7) @@ -35,7 +35,7 @@ #define NEXT_ADDR(p) (((byte *)(p)) + sizeof *(p)) #define WITH_NORMALIZE(table,key,key_size,block) do {\ - if ((table)->normalizer) {\ + if ((table)->normalizer && key && key_size > 0) {\ grn_obj *nstr;\ if ((nstr = grn_string_open(ctx, key, key_size,\ (table)->normalizer, 0))) {\ @@ -1892,19 +1892,49 @@ grn_table_cursor_open(grn_ctx *ctx, grn_obj *table, if (table->header.type == GRN_DB) { table = ((grn_db *)table)->keys; } switch (table->header.type) { case GRN_TABLE_PAT_KEY : - tc = (grn_table_cursor *)grn_pat_cursor_open(ctx, (grn_pat *)table, - min, min_size, - max, max_size, offset, limit, flags); + { + grn_pat *pat = (grn_pat *)table; + WITH_NORMALIZE(pat, min, min_size, { + WITH_NORMALIZE(pat, max, max_size, { + grn_pat_cursor *pat_cursor; + pat_cursor = grn_pat_cursor_open(ctx, pat, + min, min_size, + max, max_size, + offset, limit, flags); + tc = (grn_table_cursor *)pat_cursor; + }); + }); + } break; case GRN_TABLE_DAT_KEY : - tc = (grn_table_cursor *)grn_dat_cursor_open(ctx, (grn_dat *)table, - min, min_size, - max, max_size, offset, limit, flags); + { + grn_dat *dat = (grn_dat *)table; + WITH_NORMALIZE(dat, min, min_size, { + WITH_NORMALIZE(dat, max, max_size, { + grn_dat_cursor *dat_cursor; + dat_cursor = grn_dat_cursor_open(ctx, dat, + min, min_size, + max, max_size, + offset, limit, flags); + tc = (grn_table_cursor *)dat_cursor; + }); + }); + } break; case GRN_TABLE_HASH_KEY : - tc = (grn_table_cursor *)grn_hash_cursor_open(ctx, (grn_hash *)table, - min, min_size, - max, max_size, offset, limit, flags); + { + grn_hash *hash = (grn_hash *)table; + WITH_NORMALIZE(hash, min, min_size, { + WITH_NORMALIZE(hash, max, max_size, { + grn_hash_cursor *hash_cursor; + hash_cursor = grn_hash_cursor_open(ctx, hash, + min, min_size, + max, max_size, + offset, limit, flags); + tc = (grn_table_cursor *)hash_cursor; + }); + }); + } break; case GRN_TABLE_NO_KEY : tc = (grn_table_cursor *)grn_array_cursor_open(ctx, (grn_array *)table, Modified: test/unit/core/test-table-cursor.c (+86 -2) =================================================================== --- test/unit/core/test-table-cursor.c 2013-02-04 15:28:30 +0900 (cd4173c) +++ test/unit/core/test-table-cursor.c 2013-02-05 16:12:49 +0900 (bbb500f) @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2; coding: utf-8 -*- */ /* - Copyright (C) 2010-2011 Kouhei Sutou <kou �� clear-code.com> + Copyright (C) 2010-2013 Kouhei Sutou <kou �� clear-code.com> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -25,14 +25,43 @@ void data_table(void); void test_table(gpointer data); +void data_normalize(void); +void test_normalize(gconstpointer data); static grn_logger_info *logger; + +static gchar *tmp_directory; +static const gchar *database_path; + static grn_ctx *context; static grn_obj *database; void +cut_startup(void) +{ + tmp_directory = g_build_filename(grn_test_get_tmp_dir(), + "table-cursor", + NULL); +} + +void +cut_shutdown(void) +{ + g_free(tmp_directory); +} + +static void +remove_tmp_directory(void) +{ + cut_remove_path(tmp_directory, NULL); +} + +void cut_setup(void) { + remove_tmp_directory(); + g_mkdir_with_parents(tmp_directory, 0700); + context = NULL; logger = setup_grn_logger(); @@ -40,7 +69,8 @@ cut_setup(void) context = g_new0(grn_ctx, 1); grn_ctx_init(context, 0); - database = grn_db_create(context, NULL, NULL); + database_path = cut_build_path(tmp_directory, "database.groonga", NULL); + database = grn_db_create(context, database_path, NULL); } void @@ -51,6 +81,8 @@ cut_teardown(void) g_free(context); teardown_grn_logger(logger); + + remove_tmp_directory(); } void @@ -81,3 +113,55 @@ test_table(gpointer data) /* FIXME: grn_test_assert_equal_object() */ cut_assert_equal_pointer(table, grn_table_cursor_table(context, cursor)); } + +void +data_normalize(void) +{ +#define ADD_DATA(label, key) \ + gcut_add_datum(label, \ + "key", G_TYPE_STRING, key, \ + NULL) + + ADD_DATA("lower", "alice"); + ADD_DATA("upper", "ALICE"); + ADD_DATA("mixed", "AlIcE"); + +#undef ADD_DATA +} + +void +test_normalize(gconstpointer data) +{ + grn_obj *table; + const gchar *search_key = gcut_data_get_string(data, "key"); + GList *actual_keys = NULL; + grn_table_cursor *cursor; + + assert_send_command("table_create Users TABLE_HASH_KEY ShortText " + "--normalizer NormalizerAuto"); + cut_assert_equal_string( + "2", + send_command("load --table Users --columns _key\n" + "[\n" + " [\"Alice\"],\n" + " [\"Bob\"]\n" + "]")); + + table = grn_ctx_get(context, "Users", -1); + cursor = grn_table_cursor_open(context, table, + search_key, strlen(search_key), + search_key, strlen(search_key), + 0, -1, 0); + while (grn_table_cursor_next(context, cursor) != GRN_ID_NIL) { + void *key; + int key_length; + key_length = grn_table_cursor_get_key(context, cursor, &key); + actual_keys = g_list_append(actual_keys, g_strndup(key, key_length)); + } + grn_table_cursor_close(context, cursor); + gcut_take_list(actual_keys, g_free); + + gcut_assert_equal_list_string(gcut_take_new_list_string("alice", NULL), + actual_keys); +} + -------------- next part -------------- HTML����������������������������...Download