Completed
Push — master ( c799e3...82ed7c )
by Michael
04:10
created

NoSECLI.plan_schema_results()   A

Complexity

Conditions 1

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1.7865

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
dl 0
loc 16
ccs 1
cts 13
cp 0.0769
crap 1.7865
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.model = workload.model
54
        results.indexes = indexes
55
        results.enumerated_indexes = []
56
        results.plans = plans
57
        results.update_plans = update_plans
58
        results.cost_model = cost_model
59
        results.weights = workload.statement_weights
60
        results.total_size = results.indexes.sum_by(&:size)
61
        results.total_cost = plans.sum_by { |plan| plan.cost * plan.weight }
62
63
        results
64
      end
65
66
      # Produce all update plans for the schema
67
      # @return [Array<Plans::UpdatePlan>]
68 1
      def build_update_plans(statements, indexes, model, trees, cost_model)
69
        planner = Plans::UpdatePlanner.new model, trees, cost_model
70
        update_plans = []
71
        statements.each do |statement|
72
          next if statement.is_a? Query
73
74
          planner.find_plans_for_update(statement, indexes).each do |plan|
75
            plan.select_query_plans(indexes)
76
            update_plans << plan
77
          end
78
        end
79
80
        update_plans
81
      end
82
    end
83
  end
84
end
85