Completed
Push — master ( d0441d...d0185c )
by Michael
03:35
created

NoSECLI.build_update_plans()   A

Complexity

Conditions 1

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1.7023

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
dl 0
loc 14
ccs 1
cts 9
cp 0.1111
crap 1.7023
rs 9.4285
c 1
b 0
f 0
1
# frozen_string_literal: true
2
3 1
module NoSE
4 1
  module CLI
5
    # Add a command to generate a graphic of the schema from a workload
6 1
    class NoSECLI < Thor
7 1
      desc 'plan-schema WORKLOAD SCHEMA',
8
           'output plans for the given WORKLOAD using SCHEMA'
9
10 1
      long_desc <<-LONGDESC
11
        `nose plan-schema` produces a set of plans for the given WORKLOAD
12
        using the manually-defined SCHEMA.
13
14
        This is useful to compare manually-defined execution plans with the
15
        plans that NoSE would produce for the same schema.
16
      LONGDESC
17
18 1
      shared_option :format
19 1
      shared_option :mix
20
21 1 View Code Duplication
      def plan_schema(workload_name, schema_name)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
Coding Style introduced by
The Assignment, Branch, Condition size for plan_schema is considered too high. [29.8/20]. The ABC size is based on assignments, branches (method calls), and conditions.
Loading history...
22
        workload = Workload.load workload_name
23
        workload.mix = options[:mix].to_sym \
24
          unless options[:mix] == 'default' && workload.mix != :default
25
        schema = Schema.load schema_name
26
        indexes = schema.indexes.values
27
28
        # Build the statement plans
29
        cost_model = get_class_from_config options, 'cost', :cost_model
30
        planner = Plans::QueryPlanner.new workload, indexes, cost_model
31
        trees = workload.queries.map { |q| planner.find_plans_for_query q }
32
        plans = trees.map(&:min)
33
34
        update_plans = build_update_plans workload.statements, indexes,
35
                                          workload.model, trees, cost_model
36
37
        # Construct a result set
38
        results = plan_schema_results workload, indexes, plans, update_plans,
39
                                      cost_model
40
41
        # Output the results in the specified format
42
        send(('output_' + options[:format]).to_sym, results)
43
      end
44
45 1
      private
46
47
      # Construct a result set
48
      # @return [OpenStruct]
49 1
      def plan_schema_results(workload, indexes, plans, update_plans,
50
                              cost_model)
51
        results = OpenStruct.new
52
        results.workload = workload
53
        results.indexes = indexes
54
        results.enumerated_indexes = []
55
        results.plans = plans
56
        results.update_plans = update_plans
57
        results.cost_model = cost_model
58
        results.weights = workload.statement_weights
59
        results.total_size = results.indexes.sum_by(&:size)
60
        results.total_cost = plans.sum_by { |plan| plan.cost * plan.weight }
61
62
        results
63
      end
64
65
      # Produce all update plans for the schema
66
      # @return [Array<Plans::UpdatePlan>]
67 1
      def build_update_plans(statements, indexes, model, trees, cost_model)
68
        planner = Plans::UpdatePlanner.new model, trees, cost_model
69
        update_plans = []
70
        statements.each do |statement|
71
          next if statement.is_a? Query
72
73
          planner.find_plans_for_update(statement, indexes).each do |plan|
74
            plan.select_query_plans(indexes)
75
            update_plans << plan
76
          end
77
        end
78
79
        update_plans
80
      end
81
    end
82
  end
83
end
84