Navigation Menu

Skip to content

Commit

Permalink
expression_rewriter: add optimize rewriter
Browse files Browse the repository at this point in the history
It just supports between() optimization for now.
  • Loading branch information
kou committed Oct 7, 2015
1 parent 964af3b commit 63bdb36
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 0 deletions.
38 changes: 38 additions & 0 deletions plugins/expression_rewriters/optimize.rb
@@ -0,0 +1,38 @@
module Groonga
module ExpressionRewriters
class Opitmize < ExpressionRewriter
register "optimize"

def rewrite
codes = @expression.codes
n_codes = codes.size

# (A >= x && A < y) -> between(A, x, "include", y, "exclude")
return nil if n_codes != 7

return nil if codes[6].op != Operator::AND

return nil if codes[0].op != Operator::GET_VALUE
return nil if codes[1].op != Operator::PUSH
return nil if codes[2].op != Operator::GREATER_EQUAL

return nil if codes[3].op != Operator::GET_VALUE
return nil if codes[4].op != Operator::PUSH
return nil if codes[5].op != Operator::LESS

return nil if codes[3].value != codes[0].value

variable = @expression.get_var_by_offset(0)
rewritten = Expression.create(context[variable.domain])
rewritten.append_object(Context.instance["between"], Operator::PUSH, 1)
rewritten.append_object(codes[0].value, Operator::GET_VALUE, 1)
rewritten.append_constant(codes[1].value.value, Operator::PUSH, 1)
rewritten.append_constant("include", Operator::PUSH, 1)
rewritten.append_constant(codes[4].value.value, Operator::PUSH, 1)
rewritten.append_constant("exclude", Operator::PUSH, 1)
rewritten.append_operator(Operator::CALL, 5)
rewritten
end
end
end
end
43 changes: 43 additions & 0 deletions test/mruby/suite/expression_rewriter/test_between.rb
@@ -0,0 +1,43 @@
class TestBetween < ExpressionRewriterTestCase
def setup
Groonga::Schema.define do |schema|
schema.create_table("rewriters",
:type => :hash,
:key_type => :short_text) do |table|
table.text("plugin_name")
end

schema.create_table("Logs") do |table|
table.time("timestamp")
end
end

@rewriters = Groonga["rewriters"]
@rewriters.add("optimize", :plugin_name => "expression_rewriters/optimize")

@logs = Groonga["Logs"]
setup_expression(@logs)
end

def teardown
teardown_expression
end

def test_optimizable
code =
"timestamp >= '2015-10-01 00:00:00' && " +
"timestamp < '2015-11-00 00:00:00'"
assert_equal(<<-DUMP, dump_rewritten_plan(code))
[0]
op: <call>
logical_op: <or>
args[0]: <#<proc:function between arguments:[]>>
args[1]: <#<column:fix_size Logs.timestamp range:Time type:scalar compress:none>>
args[2]: <"2015-10-01 00:00:00">
args[3]: <"include">
args[4]: <"2015-11-00 00:00:00">
args[5]: <"exclude">
expr: <0..6>
DUMP
end
end

0 comments on commit 63bdb36

Please sign in to comment.