1module Groonga 2 module ExpressionTree 3 class BinaryOperation 4 attr_reader :operator 5 attr_reader :left 6 attr_reader :right 7 def initialize(operator, left, right) 8 @operator = operator 9 @left = left 10 @right = right 11 end 12 13 def build(expression) 14 @left.build(expression) 15 @right.build(expression) 16 expression.append_operator(@operator, 2) 17 end 18 19 RANGE_OPERATORS = [ 20 Operator::LESS, 21 Operator::GREATER, 22 Operator::LESS_EQUAL, 23 Operator::GREATER_EQUAL, 24 ] 25 def estimate_size(table) 26 case @operator 27 when *RANGE_OPERATORS 28 estimate_size_range(table) 29 else 30 table.size 31 end 32 end 33 34 private 35 def estimate_size_range(table) 36 return table.size unless @left.is_a?(Variable) 37 return table.size unless @right.is_a?(Constant) 38 39 column = @left.column 40 value = @right.value 41 index_info = column.find_index(@operator) 42 return table.size if index_info.nil? 43 44 index_column = index_info.index 45 lexicon = index_column.lexicon 46 options = {} 47 case @operator 48 when Operator::LESS 49 options[:max] = value 50 options[:flags] = TableCursorFlags::LT 51 when Operator::LESS_EQUAL 52 options[:max] = value 53 options[:flags] = TableCursorFlags::LE 54 when Operator::GREATER 55 options[:min] = value 56 options[:flags] = TableCursorFlags::GT 57 when Operator::GREATER_EQUAL 58 options[:min] = value 59 options[:flags] = TableCursorFlags::GE 60 end 61 TableCursor.open(lexicon, options) do |cursor| 62 index_column.estimate_size(:lexicon_cursor => cursor) 63 end 64 end 65 end 66 end 67end 68