class NoSE::Plans::QueryExecutionPlan

DSL to construct query execution plans

Attributes

group[R]
index[R]
name[R]
params[R]
query_plans[RW]
select_fields[R]
steps[R]
update_steps[R]

Public Class Methods

new(group, name, schema, plans) click to toggle source
# File lib/nose/plans/execution_plan.rb, line 151
def initialize(group, name, schema, plans)
  @group = group
  @name = name
  @schema = schema
  @plans = plans
  @select_fields = []
  @params = {}
  @steps = []
  @update_steps = []
  @query_plans = []
end

Public Instance Methods

Delete(index_key) click to toggle source

Add a new deletion step from an index @return [void]

# File lib/nose/plans/execution_plan.rb, line 265
def Delete(index_key)
  @index = @schema.indexes[index_key]

  step = Plans::DeletePlanStep.new @index

  # Get cardinality from last step of each support query plan
  # as in UpdatePlanner#find_plans_for_update
  cardinalities = @query_plans.map { |p| p.steps.last.state.cardinality }
  cardinality = cardinalities.inject(1, &:*)
  step.state = OpenStruct.new cardinality: cardinality

  @update_steps << step
end
Insert(index_key, *fields) click to toggle source

Add a new insertion step into an index @return [void]

# File lib/nose/plans/execution_plan.rb, line 248
def Insert(index_key, *fields)
  @index = @schema.indexes[index_key]

  # Get cardinality from last step of each support query plan
  # as in UpdatePlanner#find_plans_for_update
  cardinalities = @query_plans.map { |p| p.steps.last.state.cardinality }
  cardinality = cardinalities.inject(1, &:*)
  state = OpenStruct.new cardinality: cardinality

  fields = @index.all_fields if fields.empty?
  step = Plans::InsertPlanStep.new @index, state, fields

  @update_steps << step
end
Lookup(index_key, *conditions, limit: nil) click to toggle source

Create a new index lookup step with a particular set of conditions @return [void]

# File lib/nose/plans/execution_plan.rb, line 206
def Lookup(index_key, *conditions, limit: nil)
  index = @schema.indexes[index_key]

  step = Plans::IndexLookupPlanStep.new index
  eq_fields = Set.new
  range_field = nil
  conditions.each do |field, operator|
    if operator == :==
      eq_fields.add field
    else
      range_field = field
    end
  end

  step.instance_variable_set :@eq_filter, eq_fields
  step.instance_variable_set :@range_filter, range_field

  # XXX No ordering supported for now
  step.instance_variable_set :@order_by, []

  step.instance_variable_set :@limit, limit unless limit.nil?

  # Cardinality calculations adapted from
  # IndexLookupPlanStep#update_state
  state = OpenStruct.new
  if @steps.empty?
    state.hash_cardinality = 1
  else
    state.hash_cardinality = @steps.last.state.cardinality
  end
  cardinality = index.per_hash_count * state.hash_cardinality
  state.cardinality = Cardinality.filter cardinality,
                                         eq_fields - index.hash_fields,
                                         range_field

  step.state = state

  @steps << step
end
Param(field, operator, value = nil) click to toggle source

Add parameters which are used as input to the plan @return [void]

# File lib/nose/plans/execution_plan.rb, line 194
def Param(field, operator, value = nil)
  operator = :'=' if operator == :==
  @params[field.id] = Condition.new(field, operator, value)
end
Select(*fields) click to toggle source

Identify fields to be selected @return [void]

# File lib/nose/plans/execution_plan.rb, line 188
def Select(*fields)
  @select_fields = fields.flatten.to_set
end
Support(&block) click to toggle source

Pass the support query up to the parent

# File lib/nose/plans/execution_plan.rb, line 200
def Support(&block)
  @plans.Support(&block)
end
cost() click to toggle source

The estimated cost of executing this plan @return [Integer]

# File lib/nose/plans/execution_plan.rb, line 177
def cost
  costs = @steps.map(&:cost) + @update_steps.map(&:cost)
  costs += @query_plans.map(&:steps).flatten.map(&:cost)

  costs.inject(0, &:+)
end
query() click to toggle source

These plans have no associated query @return [nil]

# File lib/nose/plans/execution_plan.rb, line 171
def query
  nil
end
update_fields() click to toggle source

Produce the fields updated by this plan @return [Array<Fields::Field>]

# File lib/nose/plans/execution_plan.rb, line 165
def update_fields
  @update_steps.last.fields
end