# encoding: utf-8 module Veritas class Optimizer module Algebra # Abstract base class representing Projection optimizations class Projection < Relation::Operation::Unary private # Wrap the operand's operand in a Projection # # @return [Projection] # # @api private def wrap_operand(operand = operand.operand) operand.project(header) end # Optimize when the operand is a Projection class ProjectionOperand < self # Test if the operand is a Projection # # @return [Boolean] # # @api private def optimizable? operand.kind_of?(operation.class) end # Flatten nested Projections into a single Projection # # @return [Projection] # # @api private def optimize wrap_operand end end # class ProjectionOperand # Optimize when the operand is a Union class UnionOperand < self # Test if the operand is a Union # # @return [Boolean] # # @api private def optimizable? operand.kind_of?(Veritas::Algebra::Union) end # Wrap each operand in the Union in a Projection # # @return [Set] # # @api private def optimize wrap_left.union(wrap_right) end private # Utility method to wrap the left operand in a Projection # # @return [Projection] # # @api private def wrap_left wrap_operand(operand.left) end # Utility method to wrap the right operand in a Projection # # @return [Projection] # # @api private def wrap_right wrap_operand(operand.right) end end # class UnionOperand # Optimize when the operand is an Order class OrderOperand < self include Relation::Operation::Unary::OrderOperand end # class OrderOperand # Optimize when the operand is Empty class EmptyOperand < self # Test if the operand is empty # # @return [Boolean] # # @api private def optimizable? operand.kind_of?(Veritas::Relation::Empty) end # Return a new Empty relation with the operation's headers # # @return [Empty] # # @api private def optimize Veritas::Relation::Empty.new(header, operation) end end # class EmptyOperand # Optimize when operand is optimizable class UnoptimizedOperand < self include Function::Unary::UnoptimizedOperand # Return a Projection with an optimized operand # # @return [Projection] # # @api private def optimize wrap_operand(operand) end end # class UnoptimizedOperand Veritas::Algebra::Projection.optimizer = chain( UnchangedHeader, ProjectionOperand, UnionOperand, OrderOperand, EmptyOperand, MaterializedOperand, UnoptimizedOperand ) end # class Projection end # module Algebra end # class Optimizer end # module Veritas