[Groonga-commit] groonga/groonga at 76d26e8 [master] Support index used search even if value only term exists

Back to archive index

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����������������������������...
다운로드 



More information about the Groonga-commit mailing list
Back to archive index