Class: NoSE::Plans::QueryState

Inherits:
Object
  • Object
show all
Defined in:
lib/nose/plans/query_planner.rb

Overview

Ongoing state of a query throughout the execution plan

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(query, model) ⇒ QueryState

Returns a new instance of QueryState.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 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

Instance Attribute Details

#cardinalityObject

Returns the value of attribute cardinality.



10
11
12
# File 'lib/nose/plans/query_planner.rb', line 10

def cardinality
  @cardinality
end

#eqObject

Returns the value of attribute eq.



10
11
12
# File 'lib/nose/plans/query_planner.rb', line 10

def eq
  @eq
end

#fieldsObject

Returns the value of attribute fields.



10
11
12
# File 'lib/nose/plans/query_planner.rb', line 10

def fields
  @fields
end

#given_fieldsObject

Returns the value of attribute given_fields.



10
11
12
# File 'lib/nose/plans/query_planner.rb', line 10

def given_fields
  @given_fields
end

#graphObject

Returns the value of attribute graph.



10
11
12
# File 'lib/nose/plans/query_planner.rb', line 10

def graph
  @graph
end

#hash_cardinalityObject

Returns the value of attribute hash_cardinality.



10
11
12
# File 'lib/nose/plans/query_planner.rb', line 10

def hash_cardinality
  @hash_cardinality
end

#joinsObject

Returns the value of attribute joins.



10
11
12
# File 'lib/nose/plans/query_planner.rb', line 10

def joins
  @joins
end

#modelObject (readonly)

Returns the value of attribute model.



12
13
14
# File 'lib/nose/plans/query_planner.rb', line 12

def model
  @model
end

#order_byObject

Returns the value of attribute order_by.



10
11
12
# File 'lib/nose/plans/query_planner.rb', line 10

def order_by
  @order_by
end

#queryObject (readonly)

Returns the value of attribute query.



12
13
14
# File 'lib/nose/plans/query_planner.rb', line 12

def query
  @query
end

#rangeObject

Returns the value of attribute range.



10
11
12
# File 'lib/nose/plans/query_planner.rb', line 10

def range
  @range
end

Instance Method Details

#all_fieldsObject

All the fields referenced anywhere in the query



34
35
36
37
38
# 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) ⇒ Boolean

Check if the query has been fully answered

Returns:

  • (Boolean)


53
54
55
56
57
58
59
60
61
62
# 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) ⇒ Array<Field>

Get all fields relevant for filtering in the given graph, optionally including selected fields

Returns:



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# 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_colorObject

:nocov:



41
42
43
44
45
46
47
48
# 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