diff options
Diffstat (limited to 'storage/mroonga/vendor/groonga/plugins/sharding/range_expression_builder.rb')
-rw-r--r-- | storage/mroonga/vendor/groonga/plugins/sharding/range_expression_builder.rb | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/storage/mroonga/vendor/groonga/plugins/sharding/range_expression_builder.rb b/storage/mroonga/vendor/groonga/plugins/sharding/range_expression_builder.rb new file mode 100644 index 00000000..cc80735d --- /dev/null +++ b/storage/mroonga/vendor/groonga/plugins/sharding/range_expression_builder.rb @@ -0,0 +1,88 @@ +module Groonga + module Sharding + class RangeExpressionBuilder + attr_reader :match_columns_expression + + attr_writer :match_columns + attr_writer :query + attr_writer :filter + + def initialize(key, target_range) + @key = key + @target_range = target_range + @match_columns_expression = nil + @match_columns = nil + @query = nil + @filter = nil + end + + def build_all(expression) + build_condition(expression) + end + + def build_partial_min(expression) + expression.append_object(@key, Operator::PUSH, 1) + expression.append_operator(Operator::GET_VALUE, 1) + expression.append_constant(@target_range.min, Operator::PUSH, 1) + if @target_range.min_border == :include + expression.append_operator(Operator::GREATER_EQUAL, 2) + else + expression.append_operator(Operator::GREATER, 2) + end + build_condition(expression) + end + + def build_partial_max(expression) + expression.append_object(@key, Operator::PUSH, 1) + expression.append_operator(Operator::GET_VALUE, 1) + expression.append_constant(@target_range.max, Operator::PUSH, 1) + if @target_range.max_border == :include + expression.append_operator(Operator::LESS_EQUAL, 2) + else + expression.append_operator(Operator::LESS, 2) + end + build_condition(expression) + end + + def build_partial_min_and_max(expression) + between = Groonga::Context.instance["between"] + expression.append_object(between, Operator::PUSH, 1) + expression.append_object(@key, Operator::PUSH, 1) + expression.append_operator(Operator::GET_VALUE, 1) + expression.append_constant(@target_range.min, Operator::PUSH, 1) + expression.append_constant(@target_range.min_border, + Operator::PUSH, 1) + expression.append_constant(@target_range.max, Operator::PUSH, 1) + expression.append_constant(@target_range.max_border, + Operator::PUSH, 1) + expression.append_operator(Operator::CALL, 5) + build_condition(expression) + end + + private + def build_condition(expression) + if @query + is_empty = expression.empty? + if @match_columns + table = Context.instance[expression[0].domain] + @match_columns_expression = Expression.create(table) + @match_columns_expression.parse(@match_columns) + end + flags = Expression::SYNTAX_QUERY | + Expression::ALLOW_PRAGMA | + Expression::ALLOW_COLUMN + expression.parse(@query, + default_column: @match_columns_expression, + flags: flags) + expression.append_operator(Operator::AND, 2) unless is_empty + end + + if @filter + is_empty = expression.empty? + expression.parse(@filter) + expression.append_operator(Operator::AND, 2) unless is_empty + end + end + end + end +end |