class NoSE::Plans::QueryState

Ongoing state of a query throughout the execution plan

Attributes

cardinality[RW]
eq[RW]
fields[RW]
given_fields[RW]
graph[RW]
hash_cardinality[RW]
joins[RW]
model[R]
order_by[RW]
query[R]
range[RW]

Public Class Methods

new(query, model) click to toggle source
# File lib/nose/plans/query_planner.rb, line 14
def initialize(query, model)
  @query = query
  @model = model
  @fields = query.select
  @eq = query.eq_fields.dup
  @range = query.range_field
  @graph = query.graph
  @joins = query.materialize_view.graph.join_order(@eq)
  @order_by = query.order.dup

  # We never need to order by fields listed in equality predicates
  # since we'll only ever have rows with a single value
  @order_by -= @eq.to_a

  @cardinality = 1 # this will be updated on the first index lookup
  @hash_cardinality = 1
  @given_fields = @eq.dup
end

Public Instance Methods

all_fields() click to toggle source

All the fields referenced anywhere in the query

# File lib/nose/plans/query_planner.rb, line 34
def all_fields
  all_fields = @fields + @eq
  all_fields << @range unless @range.nil?
  all_fields
end
answered?(check_limit: true) click to toggle source

Check if the query has been fully answered @return [Boolean]

# File lib/nose/plans/query_planner.rb, line 53
def answered?(check_limit: true)
  done = @fields.empty? && @eq.empty? && @range.nil? &&
         @order_by.empty? && @joins.empty? && @graph.empty?

  # Check if the limit has been applied
  done &&= @cardinality <= @query.limit unless @query.limit.nil? ||
                                               !check_limit

  done
end
fields_for_graph(graph, include_entity, select: false) click to toggle source

Get all fields relevant for filtering in the given graph, optionally including selected fields @return [Array<Field>]

# File lib/nose/plans/query_planner.rb, line 67
def fields_for_graph(graph, include_entity, select: false)
  graph_fields = @eq + @order_by
  graph_fields << @range unless @range.nil?

  # If necessary, include ALL the fields which should be selected,
  # otherwise we can exclude fields from leaf entity sets since
  # we may end up selecting these with a separate index lookup
  entities = graph.entities
  graph_fields += @fields.select do |field|
    entities.include?(field.parent) &&
      (select || !graph.leaf_entity?(field.parent) ||
       (field.parent == include_entity && graph.size > 1))
  end

  graph_fields.select { |field| entities.include? field.parent }
end
to_color() click to toggle source

:nocov:

# File lib/nose/plans/query_planner.rb, line 41
def to_color
  @query.text +
    "\n  fields: " + @fields.map(&:to_color).to_a.to_color +
    "\n      eq: " + @eq.map(&:to_color).to_a.to_color +
    "\n   range: " + (@range.nil? ? '(nil)' : @range.name) +
    "\n   order: " + @order_by.map(&:to_color).to_a.to_color +
    "\n    graph: " + @graph.inspect
end