Kouhei Sutou
null+****@clear*****
Wed Sep 5 16:25:25 JST 2012
Kouhei Sutou 2012-09-05 16:25:25 +0900 (Wed, 05 Sep 2012) New Revision: 58b1b787c6cbba74e133c8f88fe7e5fe486fbccd https://github.com/groonga/groonga/commit/58b1b787c6cbba74e133c8f88fe7e5fe486fbccd Merged f2c89a6: Merge pull request #31 from groonga/support-score-respected-merge-by-set-operation Log: Support score respected merge by set operation --filter '(A || B) && C &! D' assign 3 (A + B + C) as score when a record that matches A, B and C. --filter '(A || B) && (C &! D)' assign 2 (A + B) as score when a record that matches A, B and C. Both of them should assign 3 as score. This change fixes the problem. Added files: test/function/suite/select/score/need_temporary_table/and.expected test/function/suite/select/score/need_temporary_table/and.test test/function/suite/select/score/need_temporary_table/or.expected test/function/suite/select/score/need_temporary_table/or.test Modified files: lib/db.c Modified: lib/db.c (+40 -10) =================================================================== --- lib/db.c 2012-09-04 18:03:26 +0900 (81b7df1) +++ lib/db.c 2012-09-05 16:25:25 +0900 (065c567) @@ -3172,6 +3172,7 @@ grn_table_setoperation(grn_ctx *ctx, grn_obj *table1, grn_obj *table2, grn_obj * void *key = NULL, *value1 = NULL, *value2 = NULL; uint32_t value_size = 0; uint32_t key_size = 0; + grn_bool have_subrec; if (table1 != res) { if (table2 == res) { grn_obj *t = table1; @@ -3181,6 +3182,8 @@ grn_table_setoperation(grn_ctx *ctx, grn_obj *table1, grn_obj *table2, grn_obj * return GRN_INVALID_ARGUMENT; } } + have_subrec = ((DB_OBJ(table1)->header.flags & GRN_OBJ_WITH_SUBREC) && + (DB_OBJ(table2)->header.flags & GRN_OBJ_WITH_SUBREC)); switch (table1->header.type) { case GRN_TABLE_HASH_KEY : value_size = ((grn_hash *)table1)->value_size; @@ -3217,18 +3220,45 @@ grn_table_setoperation(grn_ctx *ctx, grn_obj *table1, grn_obj *table2, grn_obj * } switch (op) { case GRN_OP_OR : - GRN_TABLE_EACH(ctx, table2, 0, 0, id, &key, &key_size, &value2, { - if (grn_table_add_v_inline(ctx, table1, key, key_size, &value1, NULL)) { - memcpy(value1, value2, value_size); - } - }); + if (have_subrec) { + int added; + GRN_TABLE_EACH(ctx, table2, 0, 0, id, &key, &key_size, &value2, { + if (grn_table_add_v_inline(ctx, table1, key, key_size, &value1, &added)) { + if (added) { + memcpy(value1, value2, value_size); + } else { + grn_rset_recinfo *ri1 = value1; + grn_rset_recinfo *ri2 = value2; + grn_table_add_subrec_inline(table1, ri1, ri2->score, NULL, 0); + } + } + }); + } else { + GRN_TABLE_EACH(ctx, table2, 0, 0, id, &key, &key_size, &value2, { + if (grn_table_add_v_inline(ctx, table1, key, key_size, &value1, NULL)) { + memcpy(value1, value2, value_size); + } + }); + } break; case GRN_OP_AND : - GRN_TABLE_EACH(ctx, table1, 0, 0, id, &key, &key_size, &value1, { - if (!grn_table_get_v(ctx, table2, key, key_size, &value2)) { - _grn_table_delete_by_id(ctx, table1, id, NULL); - } - }); + if (have_subrec) { + GRN_TABLE_EACH(ctx, table1, 0, 0, id, &key, &key_size, &value1, { + if (grn_table_get_v(ctx, table2, key, key_size, &value2)) { + grn_rset_recinfo *ri1 = value1; + grn_rset_recinfo *ri2 = value2; + ri1->score += ri2->score; + } else { + _grn_table_delete_by_id(ctx, table1, id, NULL); + } + }); + } else { + GRN_TABLE_EACH(ctx, table1, 0, 0, id, &key, &key_size, &value1, { + if (!grn_table_get_v(ctx, table2, key, key_size, &value2)) { + _grn_table_delete_by_id(ctx, table1, id, NULL); + } + }); + } break; case GRN_OP_AND_NOT : GRN_TABLE_EACH(ctx, table2, 0, 0, id, &key, &key_size, &value2, { Added: test/function/suite/select/score/need_temporary_table/and.expected (+18 -0) 100644 =================================================================== --- /dev/null +++ test/function/suite/select/score/need_temporary_table/and.expected 2012-09-05 16:25:25 +0900 (b05d3bb) @@ -0,0 +1,18 @@ +table_create Tags TABLE_HASH_KEY ShortText +[[0,0.0,0.0],true] +table_create Movies TABLE_HASH_KEY ShortText +[[0,0.0,0.0],true] +column_create Movies tags COLUMN_VECTOR Tags +[[0,0.0,0.0],true] +column_create Tags index COLUMN_INDEX Movies tags +[[0,0.0,0.0],true] +load --table Movies +[ +{"_key": "Seven Samurai", tags: ["Samurai", "Japanese", "Kurosawa Akira"]}, +{"_key": "The Last Samurai", tags: ["Samurai", "English", "Tom Cruise"]}, +{"_key": "The Matrix", tags: ["Keanu Reeves", "SF", "English"]}, +{"_key": "Star Wars", tags: ["George Lucas", "SF", "English"]} +] +[[0,0.0,0.0],4] +select Movies --output_columns "_key, _score" --filter '(tags @ "English" || tags @ "Samurai") && (tags @ "SF" &! tags @ "Keanu Reeves")' +[[0,0.0,0.0],[[[1],[["_key","ShortText"],["_score","Int32"]],["Star Wars",2]]]] Added: test/function/suite/select/score/need_temporary_table/and.test (+18 -0) 100644 =================================================================== --- /dev/null +++ test/function/suite/select/score/need_temporary_table/and.test 2012-09-05 16:25:25 +0900 (ecf42ae) @@ -0,0 +1,18 @@ +table_create Tags TABLE_HASH_KEY ShortText + +table_create Movies TABLE_HASH_KEY ShortText +column_create Movies tags COLUMN_VECTOR Tags + +column_create Tags index COLUMN_INDEX Movies tags + +load --table Movies +[ +{"_key": "Seven Samurai", tags: ["Samurai", "Japanese", "Kurosawa Akira"]}, +{"_key": "The Last Samurai", tags: ["Samurai", "English", "Tom Cruise"]}, +{"_key": "The Matrix", tags: ["Keanu Reeves", "SF", "English"]}, +{"_key": "Star Wars", tags: ["George Lucas", "SF", "English"]} +] + +select Movies \ + --output_columns "_key, _score" \ + --filter '(tags @ "English" || tags @ "Samurai") && (tags @ "SF" &! tags @ "Keanu Reeves")' Added: test/function/suite/select/score/need_temporary_table/or.expected (+53 -0) 100644 =================================================================== --- /dev/null +++ test/function/suite/select/score/need_temporary_table/or.expected 2012-09-05 16:25:25 +0900 (27d78fb) @@ -0,0 +1,53 @@ +table_create Tags TABLE_HASH_KEY ShortText +[[0,0.0,0.0],true] +table_create Movies TABLE_HASH_KEY ShortText +[[0,0.0,0.0],true] +column_create Movies tags COLUMN_VECTOR Tags +[[0,0.0,0.0],true] +column_create Tags index COLUMN_INDEX Movies tags +[[0,0.0,0.0],true] +load --table Movies +[ +{"_key": "Seven Samurai", tags: ["Samurai", "Japanese", "Japan", "Kurosawa Akira"]}, +{"_key": "The Last Samurai", tags: ["Samurai", "English", "Japanese", "US", "Japan", "Tom Cruise"]}, +{"_key": "The Matrix", tags: ["Keanu Reeves", "SF", "English", "US"]}, +{"_key": "Star Wars", tags: ["George Lucas", "SF", "English", "US"]} +] +[[0,0.0,0.0],4] +select Movies --output_columns "_key, _score" --filter '(tags @ "English" && tags @ "SF") || (tags @ "US" &! tags @ "Keanu Reeves")' +[ + [ + 0, + 0.0, + 0.0 + ], + [ + [ + [ + 3 + ], + [ + [ + "_key", + "ShortText" + ], + [ + "_score", + "Int32" + ] + ], + [ + "The Last Samurai", + 1 + ], + [ + "The Matrix", + 2 + ], + [ + "Star Wars", + 3 + ] + ] + ] +] Added: test/function/suite/select/score/need_temporary_table/or.test (+18 -0) 100644 =================================================================== --- /dev/null +++ test/function/suite/select/score/need_temporary_table/or.test 2012-09-05 16:25:25 +0900 (a913000) @@ -0,0 +1,18 @@ +table_create Tags TABLE_HASH_KEY ShortText + +table_create Movies TABLE_HASH_KEY ShortText +column_create Movies tags COLUMN_VECTOR Tags + +column_create Tags index COLUMN_INDEX Movies tags + +load --table Movies +[ +{"_key": "Seven Samurai", tags: ["Samurai", "Japanese", "Japan", "Kurosawa Akira"]}, +{"_key": "The Last Samurai", tags: ["Samurai", "English", "Japanese", "US", "Japan", "Tom Cruise"]}, +{"_key": "The Matrix", tags: ["Keanu Reeves", "SF", "English", "US"]}, +{"_key": "Star Wars", tags: ["George Lucas", "SF", "English", "US"]} +] + +select Movies \ + --output_columns "_key, _score" \ + --filter '(tags @ "English" && tags @ "SF") || (tags @ "US" &! tags @ "Keanu Reeves")' -------------- next part -------------- HTML����������������������������... ダウンロード