diff --git a/lib/rubocop/cop/isucon/mixin/mysql2_methods.rb b/lib/rubocop/cop/isucon/mixin/mysql2_methods.rb index 0c0f7440..8c5d6221 100644 --- a/lib/rubocop/cop/isucon/mixin/mysql2_methods.rb +++ b/lib/rubocop/cop/isucon/mixin/mysql2_methods.rb @@ -9,17 +9,19 @@ module Mysql2Methods extend NodePattern::Macros def_node_search :find_xquery, <<~PATTERN - (send (send nil? _) {:xquery | :query} (${str dstr} $...) ...) + (send (send nil? _) {:xquery | :query} (${str dstr lvar ivar cvar} $...) ...) PATTERN # @param node [RuboCop::AST::Node] # @yieldparam type [Symbol] Node type. one of `:str`, `:dstr` - # @yieldparam root_gda [RuboCop::Isucon::GDA::Client] + # @yieldparam root_gda [RuboCop::Isucon::GDA::Client,nil] + # + # @note If arguments of `db.xquery` isn't string, `root_gda` is `nil` def with_xquery(node) find_xquery(node) do |type, params| sql = xquery_param(type: type, params: params) - root_gda = RuboCop::Isucon::GDA::Client.new(sql) + root_gda = sql ? RuboCop::Isucon::GDA::Client.new(sql) : nil yield type, root_gda end diff --git a/lib/rubocop/cop/isucon/mysql2/n_plus_one_query.rb b/lib/rubocop/cop/isucon/mysql2/n_plus_one_query.rb index 5d3e62aa..f0d81034 100644 --- a/lib/rubocop/cop/isucon/mysql2/n_plus_one_query.rb +++ b/lib/rubocop/cop/isucon/mysql2/n_plus_one_query.rb @@ -31,6 +31,8 @@ module Mysql2 # SQL # class NPlusOneQuery < Base + include Mixin::Mysql2Methods + MSG = "This looks like N+1 query." # @see https://github.com/rubocop/rubocop-performance/blob/v1.11.5/lib/rubocop/cop/performance/collection_literal_in_loop.rb#L38 @@ -42,10 +44,6 @@ class NPlusOneQuery < Base # @see https://github.com/rubocop/rubocop-performance/blob/v1.11.5/lib/rubocop/cop/performance/collection_literal_in_loop.rb#L41 ENUMERABLE_METHOD_NAMES = (Enumerable.instance_methods + [:each]).to_set.freeze - def_node_search :find_xquery, <<-PATTERN - (send (send nil? _) {:xquery | :query} ...) - PATTERN - def_node_matcher :csv_loop?, <<~PATTERN (block (send (const nil? :CSV) :parse ...) @@ -68,7 +66,7 @@ class NPlusOneQuery < Base # @param node [RuboCop::AST::Node] def on_send(node) - find_xquery(node) do + with_xquery(node) do |_type, _root_gda| receiver, = *node.children next if !receiver.send_type? || !parent_is_loop?(receiver)