2017-07-09 13:41:28 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2016-08-06 12:26:20 -04:00
|
|
|
require "cases/helper"
|
|
|
|
require "models/car"
|
2011-12-02 07:32:18 -05:00
|
|
|
|
|
|
|
if ActiveRecord::Base.connection.supports_explain?
|
|
|
|
class ExplainTest < ActiveRecord::TestCase
|
|
|
|
fixtures :cars
|
|
|
|
|
|
|
|
def base
|
|
|
|
ActiveRecord::Base
|
|
|
|
end
|
|
|
|
|
|
|
|
def connection
|
|
|
|
base.connection
|
|
|
|
end
|
|
|
|
|
2013-02-24 12:59:34 -05:00
|
|
|
def test_relation_explain
|
2016-08-06 13:37:57 -04:00
|
|
|
message = Car.where(name: "honda").explain
|
2013-02-24 12:59:34 -05:00
|
|
|
assert_match(/^EXPLAIN for:/, message)
|
2011-12-04 14:29:56 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_collecting_queries_for_explain
|
2013-03-05 10:35:55 -05:00
|
|
|
queries = ActiveRecord::Base.collecting_queries_for_explain do
|
2016-08-06 13:37:57 -04:00
|
|
|
Car.where(name: "honda").to_a
|
2011-12-02 07:32:18 -05:00
|
|
|
end
|
|
|
|
|
2011-12-04 14:29:56 -05:00
|
|
|
sql, binds = queries[0]
|
|
|
|
assert_match "SELECT", sql
|
2014-01-14 21:05:00 -05:00
|
|
|
if binds.any?
|
|
|
|
assert_equal 1, binds.length
|
2015-01-27 15:42:02 -05:00
|
|
|
assert_equal "honda", binds.last.value
|
2014-01-14 21:05:00 -05:00
|
|
|
else
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_match "honda", sql
|
2014-01-14 21:05:00 -05:00
|
|
|
end
|
2011-12-02 07:32:18 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_exec_explain_with_no_binds
|
2011-12-04 14:29:56 -05:00
|
|
|
sqls = %w(foo bar)
|
|
|
|
binds = [[], []]
|
|
|
|
queries = sqls.zip(binds)
|
2011-12-02 07:32:18 -05:00
|
|
|
|
2015-09-09 15:00:40 -04:00
|
|
|
stub_explain_for_query_plans do
|
2016-08-16 03:30:11 -04:00
|
|
|
expected = sqls.map { |sql| "EXPLAIN for: #{sql}\nquery plan #{sql}" }.join("\n")
|
2015-09-09 15:00:40 -04:00
|
|
|
assert_equal expected, base.exec_explain(queries)
|
|
|
|
end
|
2011-12-02 07:32:18 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_exec_explain_with_binds
|
2011-12-04 14:29:56 -05:00
|
|
|
sqls = %w(foo bar)
|
2017-07-21 13:55:24 -04:00
|
|
|
binds = [[bind_param("wadus", 1)], [bind_param("chaflan", 2)]]
|
2011-12-04 14:29:56 -05:00
|
|
|
queries = sqls.zip(binds)
|
2011-12-02 07:32:18 -05:00
|
|
|
|
2015-09-09 15:00:40 -04:00
|
|
|
stub_explain_for_query_plans(["query plan foo\n", "query plan bar\n"]) do
|
2018-02-16 19:28:30 -05:00
|
|
|
expected = <<~SQL
|
2015-09-09 15:00:40 -04:00
|
|
|
EXPLAIN for: #{sqls[0]} [["wadus", 1]]
|
|
|
|
query plan foo
|
2011-12-02 07:32:18 -05:00
|
|
|
|
2015-09-09 15:00:40 -04:00
|
|
|
EXPLAIN for: #{sqls[1]} [["chaflan", 2]]
|
|
|
|
query plan bar
|
|
|
|
SQL
|
|
|
|
assert_equal expected, base.exec_explain(queries)
|
|
|
|
end
|
2011-12-02 07:32:18 -05:00
|
|
|
end
|
|
|
|
|
2015-09-09 15:00:40 -04:00
|
|
|
private
|
2016-08-06 12:26:20 -04:00
|
|
|
def stub_explain_for_query_plans(query_plans = ["query plan foo", "query plan bar"])
|
2015-09-09 15:00:40 -04:00
|
|
|
explain_called = 0
|
|
|
|
|
2016-08-16 03:30:11 -04:00
|
|
|
connection.stub(:explain, proc { explain_called += 1; query_plans[explain_called - 1] }) do
|
2015-09-09 15:00:40 -04:00
|
|
|
yield
|
|
|
|
end
|
|
|
|
end
|
2017-07-21 13:55:24 -04:00
|
|
|
|
|
|
|
def bind_param(name, value)
|
|
|
|
ActiveRecord::Relation::QueryAttribute.new(name, value, ActiveRecord::Type::Value.new)
|
|
|
|
end
|
2011-12-02 07:32:18 -05:00
|
|
|
end
|
|
|
|
end
|