Class: RuboCop::Isucon::GDA::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/rubocop/isucon/gda/client.rb

Overview

Client for GDA

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(sql, ast: nil) ⇒ Client

Note:

if sql is nil, ast is required

Returns a new instance of Client.

Parameters:

  • sql (String, nil)
  • ast (GDA::Nodes::Select) (defaults to: nil)


17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/rubocop/isucon/gda/client.rb', line 17

def initialize(sql, ast: nil)
  @sql = sql

  if ast
    # called from subquery AST
    @ast = ast
  else
    # called from root AST
    @ast = statement.ast
    RuboCop::Isucon::GDA::NodePatcher.new(sql).accept(@ast)
  end
end

Instance Attribute Details

#astGDA::Nodes::Select (readonly)

Returns:

  • (GDA::Nodes::Select)


9
10
11
# File 'lib/rubocop/isucon/gda/client.rb', line 9

def ast
  @ast
end

#sqlString (readonly)

Returns:

  • (String)


12
13
14
# File 'lib/rubocop/isucon/gda/client.rb', line 12

def sql
  @sql
end

Instance Method Details

#contains_aggregate_functions?Boolean

Whether SELECT clause contains aggregate functions (COUNT, MAX, MIN, SUM or AVG)

Returns:

  • (Boolean)


114
115
116
117
118
119
# File 'lib/rubocop/isucon/gda/client.rb', line 114

def contains_aggregate_functions?
  aggregate_function_names = %w[COUNT MAX MIN SUM AVG]
  ast.expr_list.any? do |select_field_node|
    aggregate_function_names.include?(select_field_node.expr.func&.function_name&.upcase)
  end
end

#from_joins?Boolean

Returns:

  • (Boolean)


134
135
136
# File 'lib/rubocop/isucon/gda/client.rb', line 134

def from_joins?
  ast.respond_to?(:from) && ast.from.respond_to?(:joins)
end

#from_targets?Boolean

Returns:

  • (Boolean)


139
140
141
# File 'lib/rubocop/isucon/gda/client.rb', line 139

def from_targets?
  ast.respond_to?(:from) && ast.from.respond_to?(:targets)
end

#group_by_clause?Boolean

Whether AST has GROUP BY clause

Returns:

  • (Boolean)


123
124
125
# File 'lib/rubocop/isucon/gda/client.rb', line 123

def group_by_clause?
  !ast.group_by.empty?
end

#join_conditionsArray<RuboCop::Isucon::GDA::JoinCondition>



58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/rubocop/isucon/gda/client.rb', line 58

def join_conditions
  return [] unless from_joins?

  ast.from.joins.map do |node|
    join_operands = node.expr.cond.operands.map do |operand|
      create_join_operand(operand)
    end

    JoinCondition.new(
      operator: node.expr.cond.operator,
      operands: join_operands,
    )
  end
end

#limit_clause?Boolean

Whether AST has LIMIT clause

Returns:

  • (Boolean)


129
130
131
# File 'lib/rubocop/isucon/gda/client.rb', line 129

def limit_clause?
  !!ast.limit_count
end

#select_query?Boolean

Returns:

  • (Boolean)


108
109
110
# File 'lib/rubocop/isucon/gda/client.rb', line 108

def select_query?
  ast.is_a?(::GDA::Nodes::Select)
end

#serialize_statementHash?

Returns:

  • (Hash, nil)


82
83
84
85
86
# File 'lib/rubocop/isucon/gda/client.rb', line 82

def serialize_statement
  return nil unless @sql

  JSON.parse(statement.serialize)
end

#table_namesArray<String>

Returns:

  • (Array<String>)


31
32
33
34
35
36
37
38
39
40
# File 'lib/rubocop/isucon/gda/client.rb', line 31

def table_names
  return @table_names if @table_names

  @table_names =
    if from_targets?
      ast.from.targets.filter_map(&:table_name).uniq
    else
      []
    end
end

#visit_all {|gda| ... } ⇒ Object

Yield Parameters:



102
103
104
105
# File 'lib/rubocop/isucon/gda/client.rb', line 102

def visit_all(&block)
  yield(self)
  visit_subquery_recursive(&block)
end

#visit_subquery_recursive {|gda| ... } ⇒ Object

Yield Parameters:



89
90
91
92
93
94
95
96
97
98
99
# File 'lib/rubocop/isucon/gda/client.rb', line 89

def visit_subquery_recursive(...)
  return unless from_targets?

  ast.from.targets.each do |target|
    next unless target.expr.select

    gda = Client.new(nil, ast: target.expr.select)
    yield(gda)
    gda.visit_subquery_recursive(...)
  end
end

#where_conditionsArray<RuboCop::Isucon::GDA::WhereCondition>



43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/rubocop/isucon/gda/client.rb', line 43

def where_conditions
  where_nodes.
    map do |node|
      where_operands = node.operands.map do |operand|
        create_where_operand(operand)
      end

      WhereCondition.new(
        operator: node.operator,
        operands: where_operands,
      )
    end
end

#where_nodesArray<GDA::Nodes::Operation>

Returns:

  • (Array<GDA::Nodes::Operation>)


74
75
76
77
78
79
# File 'lib/rubocop/isucon/gda/client.rb', line 74

def where_nodes
  return [] unless ast.respond_to?(:where_cond)

  ast.where_cond.to_a.
    select { |node| node.instance_of?(::GDA::Nodes::Operation) && node.operator }
end