class NoSE::Serialize::QueryPlanBuilder
Reconstruct the steps of a query plan
Public Instance Methods
call(_, represented:, fragment:, **)
click to toggle source
# File lib/nose/serialize.rb, line 557 def call(_, represented:, fragment:, **) workload = represented.workload if fragment['query'].nil? query = OpenStruct.new group: fragment['group'] state = nil else query = Statement.parse fragment['query'], workload.model, group: fragment['group'] state = Plans::QueryState.new query, workload end plan = build_plan query, represented.cost_model, fragment add_plan_steps plan, workload, fragment['steps'], represented.indexes, state plan end
Private Instance Methods
add_index_lookup_filters(step, step_hash, f)
click to toggle source
Add filters to a constructed index lookup step @return [void]
# File lib/nose/serialize.rb, line 653 def add_index_lookup_filters(step, step_hash, f) eq_filter = (step_hash['eq_filter'] || []).map(&f) step.instance_variable_set(:@eq_filter, eq_filter) range_filter = step_hash['range_filter'] range_filter = f.call(range_filter) unless range_filter.nil? step.instance_variable_set(:@range_filter, range_filter) end
add_plan_steps(plan, workload, steps_fragment, indexes, state)
click to toggle source
Loop over all steps in the plan and reconstruct them @return [void]
# File lib/nose/serialize.rb, line 592 def add_plan_steps(plan, workload, steps_fragment, indexes, state) parent = Plans::RootPlanStep.new state f = ->(field) { workload.model[field['parent']][field['name']] } steps_fragment.each do |step_hash| step = build_step step_hash, state, parent, indexes, f rebuild_step_state step, step_hash plan << step parent = step end end
build_filter_step(step_hash, _state, parent, _indexes, f)
click to toggle source
Rebuild a filter step @return [Plans::FilterPlanStep]
# File lib/nose/serialize.rb, line 628 def build_filter_step(step_hash, _state, parent, _indexes, f) eq = step_hash['eq'].map(&f) range = f.call(step_hash['range']) if step_hash['range'] Plans::FilterPlanStep.new eq, range, parent.state end
build_index_lookup_step(step_hash, state, parent, indexes, f)
click to toggle source
Rebuild an index lookup step @return [Plans::IndexLookupPlanStep]
# File lib/nose/serialize.rb, line 636 def build_index_lookup_step(step_hash, state, parent, indexes, f) index_key = step_hash['index']['key'] step_index = indexes.find { |i| i.key == index_key } step = Plans::IndexLookupPlanStep.new step_index, state, parent add_index_lookup_filters step, step_hash, f order_by = (step_hash['order_by'] || []).map(&f) step.instance_variable_set(:@order_by, order_by) limit = step_hash['limit'] step.instance_variable_set(:@limit, limit.to_i) unless limit.nil? step end
build_limit_step(step_hash, _state, parent, _indexes, _f)
click to toggle source
Rebuild a limit step @return [Plans::LimitPlanStep]
# File lib/nose/serialize.rb, line 614 def build_limit_step(step_hash, _state, parent, _indexes, _f) limit = step_hash['limit'].to_i Plans::LimitPlanStep.new limit, parent.state end
build_plan(query, cost_model, fragment)
click to toggle source
Build a new query plan @return [Plans::QueryPlan]
# File lib/nose/serialize.rb, line 580 def build_plan(query, cost_model, fragment) plan = Plans::QueryPlan.new query, cost_model plan.instance_variable_set(:@name, fragment['name']) \ unless fragment['name'].nil? plan.instance_variable_set(:@weight, fragment['weight']) plan end
build_sort_step(step_hash, _state, parent, _indexes, f)
click to toggle source
Rebuild a sort step @return [Plans::SortPlanStep]
# File lib/nose/serialize.rb, line 621 def build_sort_step(step_hash, _state, parent, _indexes, f) sort_fields = step_hash['sort_fields'].map(&f) Plans::SortPlanStep.new sort_fields, parent.state end
build_step(step_hash, state, parent, indexes, f)
click to toggle source
Rebuild a step from a hash using the given set of indexes The final parameter is a function which maps field names to instances @return [Plans::PlanStep]
# File lib/nose/serialize.rb, line 607 def build_step(step_hash, state, parent, indexes, f) send "build_#{step_hash['type']}_step".to_sym, step_hash, state, parent, indexes, f end
rebuild_step_state(step, step_hash)
click to toggle source
Rebuild the state of the step from the provided hash @return [void]
# File lib/nose/serialize.rb, line 664 def rebuild_step_state(step, step_hash) return if step.state.nil? # Copy the correct cardinality # XXX This may not preserve all the necessary state state = step.state.dup state.instance_variable_set :@cardinality, step_hash['cardinality'] step.instance_variable_set :@cost, step_hash['cost'] step.state = state.freeze end