lib/axiom/optimizer/relation/operation/limit.rb
# encoding: utf-8
module Axiom
class Optimizer
module Relation
module Operation
# Abstract base class representing Limit optimizations
class Limit < Unary
private
# Return the operation limit
#
# @return [Integer]
#
# @api private
def limit
operation.limit
end
# Optimize when the limit is zero
class ZeroLimit < self
# Test if the limit is zero
#
# @return [Boolean]
#
# @api private
def optimizable?
limit.zero?
end
# A Limit with a limit of zero is empty
#
# @return [Relation::Empty]
#
# @api private
def optimize
Axiom::Relation::Empty.new(operation.header)
end
end # class ZeroLimit
# Optimize when the operand is a Limit and the limits are equal
class EqualLimitOperand < self
# Test if the operand is a Limit and the limits are equal
#
# @return [Boolean]
#
# @api private
def optimizable?
operand.kind_of?(operation.class) && equal_limit?
end
# Flatten equal Limit relations into a single relation
#
# @return [Projection]
#
# @api private
def optimize
operand
end
private
# Test if the operation and operand limits are equal
#
# @return [Boolean]
#
# @api private
def equal_limit?
limit == operand.limit
end
end # class EqualLimitOperand
# Optimize when the operand is a Limit
class LimitOperand < self
# Test if the operand is a Limit
#
# @return [Boolean]
#
# @api private
def optimizable?
operand.kind_of?(operation.class)
end
# Flatten Limit operations using the minimum limit
#
# @return [Boolean]
#
# @api private
def optimize
operand.operand.take(min_limit)
end
private
# Return the minimum limit between the operation and operand
#
# @return [Integer]
#
# @api private
def min_limit
[limit, operand.limit].min
end
end # class LimitOperand
# Optimize when operand is optimizable
class UnoptimizedOperand < self
include Function::Unary::UnoptimizedOperand
# Return a Limit with an optimized operand
#
# @return [Limit]
#
# @api private
def optimize
operand.take(limit)
end
end # class UnoptimizedOperand
Axiom::Relation::Operation::Limit.optimizer = chain(
ZeroLimit,
EqualLimitOperand,
LimitOperand,
EmptyOperand,
MaterializedOperand,
UnoptimizedOperand
)
end # class Limit
end # module Operation
end # module Relation
end # class Optimizer
end # module Axiom