Kouhei Sutou
null+****@clear*****
Thu Apr 7 17:23:46 JST 2016
Kouhei Sutou 2016-04-07 17:23:46 +0900 (Thu, 07 Apr 2016) New Revision: 76d26e8b647066530fdcfccf1f61480130c4b41b https://github.com/groonga/groonga/commit/76d26e8b647066530fdcfccf1f61480130c4b41b Message: Support index used search even if value only term exists Without this change, "true || column > 0" doesn't use index even if "column" has index. With this change, "true || column > 0" uses index if "column" has index. Added files: test/command/suite/select/filter/index/with_constant_term/after.expected test/command/suite/select/filter/index/with_constant_term/after.test test/command/suite/select/filter/index/with_constant_term/before.expected test/command/suite/select/filter/index/with_constant_term/before.test Modified files: lib/expr.c lib/mrb/scripts/scan_info_builder.rb Modified: lib/expr.c (+64 -4) =================================================================== --- lib/expr.c 2016-04-07 16:09:35 +0900 (a37502a) +++ lib/expr.c 2016-04-07 17:23:46 +0900 (45c2dc2) @@ -4558,12 +4558,45 @@ grn_scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n, case GRN_OP_OR : case GRN_OP_AND_NOT : case GRN_OP_ADJUST : - if (stat != SCAN_START) { return NULL; } - o++; - if (o >= m) { return NULL; } + switch (stat) { + case SCAN_START : + o++; + if (o >= m) { return NULL; } + break; + case SCAN_CONST : + o++; + m++; + if (o >= m) { return NULL; } + stat = SCAN_START; + break; + default : + return NULL; + break; + } break; case GRN_OP_PUSH : - stat = (c->value == var) ? SCAN_VAR : SCAN_CONST; + { + grn_bool is_completed_term = GRN_FALSE; + if (c->modify > 0) { + switch ((c + c->modify)->op) { + case GRN_OP_AND : + case GRN_OP_OR : + case GRN_OP_AND_NOT : + case GRN_OP_ADJUST : + is_completed_term = GRN_TRUE; + break; + default : + is_completed_term = GRN_FALSE; + break; + } + } + if (is_completed_term) { + m++; + stat = SCAN_START; + } else { + stat = (c->value == var) ? SCAN_VAR : SCAN_CONST; + } + } break; case GRN_OP_GET_VALUE : switch (stat) { @@ -4660,6 +4693,12 @@ grn_scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n, case GRN_OP_OR : case GRN_OP_AND_NOT : case GRN_OP_ADJUST : + if (stat == SCAN_CONST) { + si->op = GRN_OP_PUSH; + si->end = si->start; + sis[i++] = si; + si = NULL; + } if (!put_logical_op(ctx, sis, &i, c->op, c - e->codes)) { return NULL; } stat = SCAN_START; break; @@ -4674,6 +4713,27 @@ grn_scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n, if (stat == SCAN_START) { si->flags |= SCAN_PRE_CONST; } stat = SCAN_CONST; } + if (c->modify > 0) { + grn_bool is_completed_term = GRN_FALSE; + switch ((c + c->modify)->op) { + case GRN_OP_AND : + case GRN_OP_OR : + case GRN_OP_AND_NOT : + case GRN_OP_ADJUST : + is_completed_term = GRN_TRUE; + break; + default : + is_completed_term = GRN_FALSE; + break; + } + if (is_completed_term) { + si->op = GRN_OP_PUSH; + si->end = si->start; + sis[i++] = si; + si = NULL; + stat = SCAN_START; + } + } break; case GRN_OP_GET_VALUE : switch (stat) { Modified: lib/mrb/scripts/scan_info_builder.rb (+35 -6) =================================================================== --- lib/mrb/scripts/scan_info_builder.rb 2016-04-07 16:09:35 +0900 (93b3d2d) +++ lib/mrb/scripts/scan_info_builder.rb 2016-04-07 17:23:46 +0900 (2e21f9f) @@ -76,6 +76,12 @@ module Groonga @data_list << data data = nil when *LOGICAL_OPERATORS + if status == Status::CONST + data.op = Operator::PUSH + data.end = data.start + @data_list << data + data = nil + end put_logical_op(code.op, i) # TODO: rescue and return nil status = Status::START @@ -90,6 +96,14 @@ module Groonga end status = Status::CONST end + if code.modify > 0 and + LOGICAL_OPERATORS.include?(codes[i + code.modify].op) + data.op = Operator::PUSH + data.end = data.start + @data_list << data + data = nil + status = Status::START + end when Operator::GET_VALUE case status when Status::START @@ -169,14 +183,29 @@ module Groonga status = Status::START return false if n_relation_expressions != (n_logical_expressions + 1) when *LOGICAL_OPERATORS - return false if status != Status::START - n_logical_expressions += 1 - return false if n_logical_expressions >= n_relation_expressions + case status + when Status::START + n_logical_expressions += 1 + return false if n_logical_expressions >= n_relation_expressions + when Status::CONST + n_logical_expressions += 1 + n_relation_expressions += 1 + return false if n_logical_expressions >= n_relation_expressions + status = Status::START + else + return false + end when Operator::PUSH - if code.value == variable - status = Status::VAR + if code.modify > 0 and + LOGICAL_OPERATORS.include?(codes[i + code.modify].op) + n_relation_expressions += 1 + status = Status::START else - status = Status::CONST + if code.value == variable + status = Status::VAR + else + status = Status::CONST + end end when Operator::GET_VALUE case status Added: test/command/suite/select/filter/index/with_constant_term/after.expected (+22 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/filter/index/with_constant_term/after.expected 2016-04-07 17:23:46 +0900 (cf99117) @@ -0,0 +1,22 @@ +table_create Values TABLE_NO_KEY +[[0,0.0,0.0],true] +column_create Values number COLUMN_SCALAR Int32 +[[0,0.0,0.0],true] +table_create Numbers TABLE_PAT_KEY Int32 +[[0,0.0,0.0],true] +column_create Numbers values_number COLUMN_INDEX Values number +[[0,0.0,0.0],true] +load --table Values +[ +{"number": 1}, +{"number": 3}, +{"number": -1} +] +[[0,0.0,0.0],3] +log_level --level info +[[0,0.0,0.0],true] +select Values --filter 'number == -1 || true' --output_columns 'number' +[[0,0.0,0.0],[[[3],[["number","Int32"]],[-1],[1],[3]]]] +#|i| [table][select][index][equal] <Numbers.values_number> +log_level --level notice +[[0,0.0,0.0],true] Added: test/command/suite/select/filter/index/with_constant_term/after.test (+20 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/filter/index/with_constant_term/after.test 2016-04-07 17:23:46 +0900 (be014e3) @@ -0,0 +1,20 @@ +table_create Values TABLE_NO_KEY +column_create Values number COLUMN_SCALAR Int32 + +table_create Numbers TABLE_PAT_KEY Int32 +column_create Numbers values_number COLUMN_INDEX Values number + +load --table Values +[ +{"number": 1}, +{"number": 3}, +{"number": -1} +] + +log_level --level info +#@add-important-log-levels info +select Values \ + --filter 'number == -1 || true' \ + --output_columns 'number' +#@remove-important-log-levels info +log_level --level notice Added: test/command/suite/select/filter/index/with_constant_term/before.expected (+22 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/filter/index/with_constant_term/before.expected 2016-04-07 17:23:46 +0900 (106de7c) @@ -0,0 +1,22 @@ +table_create Values TABLE_NO_KEY +[[0,0.0,0.0],true] +column_create Values number COLUMN_SCALAR Int32 +[[0,0.0,0.0],true] +table_create Numbers TABLE_PAT_KEY Int32 +[[0,0.0,0.0],true] +column_create Numbers values_number COLUMN_INDEX Values number +[[0,0.0,0.0],true] +load --table Values +[ +{"number": 1}, +{"number": 3}, +{"number": -1} +] +[[0,0.0,0.0],3] +log_level --level info +[[0,0.0,0.0],true] +select Values --filter 'true || number == -1' --output_columns 'number' +[[0,0.0,0.0],[[[3],[["number","Int32"]],[1],[3],[-1]]]] +#|i| [table][select][index][equal] <Numbers.values_number> +log_level --level notice +[[0,0.0,0.0],true] Added: test/command/suite/select/filter/index/with_constant_term/before.test (+20 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/filter/index/with_constant_term/before.test 2016-04-07 17:23:46 +0900 (ad09ab3) @@ -0,0 +1,20 @@ +table_create Values TABLE_NO_KEY +column_create Values number COLUMN_SCALAR Int32 + +table_create Numbers TABLE_PAT_KEY Int32 +column_create Numbers values_number COLUMN_INDEX Values number + +load --table Values +[ +{"number": 1}, +{"number": 3}, +{"number": -1} +] + +log_level --level info +#@add-important-log-levels info +select Values \ + --filter 'true || number == -1' \ + --output_columns 'number' +#@remove-important-log-levels info +log_level --level notice -------------- next part -------------- HTML����������������������������...다운로드