class NoSE::Plans::UpdatePlan
A plan for executing an update
Attributes
Public Class Methods
# File lib/nose/plans/update_planner.rb, line 29 def initialize(statement, index, trees, update_steps, cost_model) @statement = statement @index = index @trees = trees @query_plans = nil # these will be set later when we pick indexes update_steps.each { |step| step.calculate_cost cost_model } @update_steps = update_steps @cost_model = cost_model # Update with fields specified in the settings and conditions # (rewrite from foreign keys to IDs if needed) @update_fields = if statement.is_a?(Connection) || statement.is_a?(Delete) [] else statement.settings.map(&:field) end @update_fields += statement.conditions.each_value.map(&:field) @update_fields.map! do |field| field.is_a?(Fields::ForeignKeyField) ? field.entity.id_field : field end end
Public Instance Methods
Two plans are compared by their execution cost @return [Boolean]
# File lib/nose/plans/update_planner.rb, line 143 def <=>(other) cost <=> other.cost end
The cost is the sum of all the query costs plus the update costs @return [Integer]
# File lib/nose/plans/update_planner.rb, line 155 def cost @query_plans.sum_by(&:cost) + update_cost end
Compare all the fields for the plan for equality @return [Boolean]
# File lib/nose/plans/update_planner.rb, line 119 def eql?(other) return false unless other.is_a? UpdatePlan fail 'plans must be resolved before checking equality' \ if @query_plans.nil? || other.query_plans.nil? @statement == other.statement && @index == other.index && @query_plans == other.query_plans && @update_steps == other.update_steps && @cost_model == other.cost_model end
The group of the associated statement @return [String]
# File lib/nose/plans/update_planner.rb, line 62 def group @statement.group end
Name the plan by the statement @return [String]
# File lib/nose/plans/update_planner.rb, line 68 def name "#{@statement.text} for #{@index.key}" end
Parameters to this update plan @return [Hash]
# File lib/nose/plans/update_planner.rb, line 80 def params conditions = if @statement.respond_to?(:conditions) @statement.conditions else {} end settings = if @statement.respond_to?(:settings) @statement.settings else [] end params = conditions.merge Hash[settings.map do |setting| [setting.field.id, Condition.new(setting.field, :'=', setting.value)] end] convert_param_keys params end
Select query plans to actually use here @return [void]
# File lib/nose/plans/update_planner.rb, line 101 def select_query_plans(indexes = nil, &block) if block_given? @query_plans = @trees.map(&block) else @query_plans = @trees.map do |tree| plan = tree.select_using_indexes(indexes).min_by(&:cost) fail if plan.nil? plan end end update_support_fields @trees = nil end
The steps for this plan are the update steps @return [Array<UpdatePlanStep>]
# File lib/nose/plans/update_planner.rb, line 74 def steps @update_steps end
:nocov:
# File lib/nose/plans/update_planner.rb, line 132 def to_color "\n statement: " + @statement.to_color + "\n index: " + @index.to_color + "\n query_plans: " + @query_plans.to_color + "\nupdate_steps: " + @update_steps.to_color + "\n cost_model: " + @cost_model.to_color end
The cost of performing the update on this index @return [Integer]
# File lib/nose/plans/update_planner.rb, line 149 def update_cost @update_steps.sum_by(&:cost) end
The weight of this query for a given workload @return [Integer]
# File lib/nose/plans/update_planner.rb, line 54 def weight return 1 if @workload.nil? @workload.statement_weights[@statement] end
Private Instance Methods
Ensure we only use primary keys for conditions @return [Hash]
# File lib/nose/plans/update_planner.rb, line 172 def convert_param_keys(params) Hash[params.each_value.map do |condition| field = condition.field if field.is_a?(Fields::ForeignKeyField) field = field.entity.id_field condition = Condition.new field, condition.operator, condition.value end [field.id, condition] end] end
Add fields from support queries to those which should be updated @return [void]
# File lib/nose/plans/update_planner.rb, line 163 def update_support_fields # Add fields fetched from support queries @update_fields += @query_plans.flat_map do |query_plan| query_plan.query.select.to_a end.compact end