Class: NoSE::Plans::QueryExecutionPlan

Inherits:
AbstractPlan show all
Extended by:
Forwardable
Defined in:
lib/nose/plans/execution_plan.rb

Overview

DSL to construct query execution plans

Instance Attribute Summary collapse

Attributes inherited from AbstractPlan

#weight

Instance Method Summary collapse

Constructor Details

#initialize(group, name, schema, plans) ⇒ QueryExecutionPlan

Returns a new instance of QueryExecutionPlan.



151
152
153
154
155
156
157
158
159
160
161
# 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

Instance Attribute Details

#groupObject (readonly)

Returns the value of attribute group.



142
143
144
# File 'lib/nose/plans/execution_plan.rb', line 142

def group
  @group
end

#indexObject (readonly)

Returns the value of attribute index.



142
143
144
# File 'lib/nose/plans/execution_plan.rb', line 142

def index
  @index
end

#nameObject (readonly)

Returns the value of attribute name.



142
143
144
# File 'lib/nose/plans/execution_plan.rb', line 142

def name
  @name
end

#paramsObject (readonly)

Returns the value of attribute params.



142
143
144
# File 'lib/nose/plans/execution_plan.rb', line 142

def params
  @params
end

#query_plansObject

Returns the value of attribute query_plans.



144
145
146
# File 'lib/nose/plans/execution_plan.rb', line 144

def query_plans
  @query_plans
end

#select_fieldsObject (readonly)

Returns the value of attribute select_fields.



142
143
144
# File 'lib/nose/plans/execution_plan.rb', line 142

def select_fields
  @select_fields
end

#stepsObject (readonly)

Returns the value of attribute steps.



142
143
144
# File 'lib/nose/plans/execution_plan.rb', line 142

def steps
  @steps
end

#update_stepsObject (readonly)

Returns the value of attribute update_steps.



142
143
144
# File 'lib/nose/plans/execution_plan.rb', line 142

def update_steps
  @update_steps
end

Instance Method Details

#costFixnum

The estimated cost of executing this plan

Returns:

  • (Fixnum)


177
178
179
180
181
182
# 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

#Delete(index_key) ⇒ void

This method returns an undefined value.

Add a new deletion step from an index



265
266
267
268
269
270
271
272
273
274
275
276
277
# 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) ⇒ void

This method returns an undefined value.

Add a new insertion step into an index



248
249
250
251
252
253
254
255
256
257
258
259
260
261
# 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) ⇒ void

This method returns an undefined value.

Create a new index lookup step with a particular set of conditions



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# 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) ⇒ void

This method returns an undefined value.

Add parameters which are used as input to the plan



194
195
196
197
# 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

#querynil

These plans have no associated query

Returns:

  • (nil)


171
172
173
# File 'lib/nose/plans/execution_plan.rb', line 171

def query
  nil
end

#Select(*fields) ⇒ void

This method returns an undefined value.

Identify fields to be selected



188
189
190
# File 'lib/nose/plans/execution_plan.rb', line 188

def Select(*fields)
  @select_fields = fields.flatten.to_set
end

#Support(&block) ⇒ Object

Pass the support query up to the parent



200
201
202
# File 'lib/nose/plans/execution_plan.rb', line 200

def Support(&block)
  @plans.Support(&block)
end

#update_fieldsArray<Fields::Field>

Produce the fields updated by this plan

Returns:



165
166
167
# File 'lib/nose/plans/execution_plan.rb', line 165

def update_fields
  @update_steps.last.fields
end