Skip to content

Commit c9f341a

Browse files
Fixed query logging so that filter parameters are respected (#1370)
1 parent 3e3cf0a commit c9f341a

File tree

7 files changed

+74
-201
lines changed

7 files changed

+74
-201
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## Unreleased
2+
3+
#### Fixed
4+
5+
- [#1370](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1370) Fixed query logging so that filter parameters are respected.
6+
17
## v8.0.9
28

39
#### Fixed

lib/active_record/connection_adapters/sqlserver/database_statements.rb

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ def write_query?(sql) # :nodoc:
1414
end
1515

1616
def perform_query(raw_connection, sql, binds, type_casted_binds, prepare:, notification_payload:, batch:)
17+
unless binds.nil? || binds.empty?
18+
types, params = sp_executesql_types_and_parameters(binds)
19+
sql = sp_executesql_sql(sql, types, params, notification_payload[:name])
20+
end
21+
1722
result = if id_insert_table_name = query_requires_identity_insert?(sql)
1823
with_identity_insert_enabled(id_insert_table_name, raw_connection) do
1924
internal_exec_sql_query(sql, raw_connection)
@@ -40,15 +45,6 @@ def affected_rows(raw_result)
4045
raw_result.first[column_name]
4146
end
4247

43-
def raw_execute(sql, name = nil, binds = [], prepare: false, async: false, allow_retry: false, materialize_transactions: true, batch: false)
44-
unless binds.nil? || binds.empty?
45-
types, params = sp_executesql_types_and_parameters(binds)
46-
sql = sp_executesql_sql(sql, types, params, name)
47-
end
48-
49-
super
50-
end
51-
5248
def internal_exec_sql_query(sql, conn)
5349
handle = internal_raw_execute(sql, conn)
5450
handle_to_names_and_values(handle, ar_result: true)

test/cases/coerced_tests.rb

Lines changed: 32 additions & 183 deletions
Large diffs are not rendered by default.

test/cases/optimizer_hints_test_sqlserver.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class OptimizerHitsTestSQLServer < ActiveRecord::TestCase
2929
end
3030

3131
it "support subqueries" do
32-
assert_queries_match(%r{.*'SELECT COUNT\(count_column\) FROM \(SELECT .*\) subquery_for_count OPTION \(MAXDOP 2\)'.*}) do
32+
assert_queries_match(%r{SELECT COUNT\(count_column\) FROM \(SELECT .*\) subquery_for_count OPTION \(MAXDOP 2\)}) do
3333
companies = Company.optimizer_hints("MAXDOP 2")
3434
companies = companies.select(:id).where(firm_id: [0, 1]).limit(3)
3535
assert_equal 3, companies.count

test/cases/showplan_test_sqlserver.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ class ShowplanTestSQLServer < ActiveRecord::TestCase
2828

2929
it "from array condition using index" do
3030
plan = Car.where(id: [1, 2]).explain.inspect
31-
_(plan).must_include "SELECT [cars].* FROM [cars] WHERE [cars].[id] IN (1, 2)"
31+
_(plan).must_include "SELECT [cars].* FROM [cars] WHERE [cars].[id] IN (@0, @1)"
3232
_(plan).must_include "Clustered Index Seek", "make sure we do not showplan the sp_executesql"
3333
end
3434

3535
it "from array condition" do
3636
plan = Car.where(name: ["honda", "zyke"]).explain.inspect
37-
_(plan).must_include " SELECT [cars].* FROM [cars] WHERE [cars].[name] IN (N'honda', N'zyke')"
37+
_(plan).must_include " SELECT [cars].* FROM [cars] WHERE [cars].[name] IN (@0, @1)"
3838
_(plan).must_include "Clustered Index Scan", "make sure we do not showplan the sp_executesql"
3939
end
4040
end

test/cases/specific_schema_test_sqlserver.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,16 +116,16 @@ def quoted_id
116116
end
117117
end
118118
# Using ActiveRecord's quoted_id feature for objects.
119-
assert_queries_match(/@0 = 'T'/) { SSTestDatatypeMigration.where(char_col: value.new).first }
120-
assert_queries_match(/@0 = 'T'/) { SSTestDatatypeMigration.where(varchar_col: value.new).first }
119+
assert_queries_and_values_match(/.*/, ["'T'", 1]) { SSTestDatatypeMigration.where(char_col: value.new).first }
120+
assert_queries_and_values_match(/.*/, ["'T'", 1]) { SSTestDatatypeMigration.where(varchar_col: value.new).first }
121121
# Using our custom char type data.
122122
type = ActiveRecord::Type::SQLServer::Char
123123
data = ActiveRecord::Type::SQLServer::Data
124-
assert_queries_match(/@0 = 'T'/) { SSTestDatatypeMigration.where(char_col: data.new("T", type.new)).first }
125-
assert_queries_match(/@0 = 'T'/) { SSTestDatatypeMigration.where(varchar_col: data.new("T", type.new)).first }
124+
assert_queries_and_values_match(/.*/, ["'T'", 1]) { SSTestDatatypeMigration.where(char_col: data.new("T", type.new)).first }
125+
assert_queries_and_values_match(/.*/, ["'T'", 1]) { SSTestDatatypeMigration.where(varchar_col: data.new("T", type.new)).first }
126126
# Taking care of everything.
127-
assert_queries_match(/@0 = 'T'/) { SSTestDatatypeMigration.where(char_col: "T").first }
128-
assert_queries_match(/@0 = 'T'/) { SSTestDatatypeMigration.where(varchar_col: "T").first }
127+
assert_queries_and_values_match(/.*/, ["'T'", 1]) { SSTestDatatypeMigration.where(char_col: "T").first }
128+
assert_queries_and_values_match(/.*/, ["'T'", 1]) { SSTestDatatypeMigration.where(varchar_col: "T").first }
129129
end
130130

131131
it "can update and hence properly quoted non-national char/varchar columns" do

test/support/query_assertions.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,28 @@ def assert_queries_count(count = nil, include_schema: false, &block)
2222
end
2323
end
2424

25+
def assert_queries_and_values_match(match, bound_values=[], count: nil, &block)
26+
ActiveRecord::Base.lease_connection.materialize_transactions
27+
28+
counter = ActiveRecord::Assertions::QueryAssertions::SQLCounter.new
29+
ActiveSupport::Notifications.subscribed(counter, "sql.active_record") do
30+
result = _assert_nothing_raised_or_warn("assert_queries_match", &block)
31+
queries = counter.log_full
32+
matched_queries = queries.select do |query, values|
33+
values = values.map { |v| v.respond_to?(:quoted) ? v.quoted : v }
34+
match === query && bound_values === values
35+
end
36+
37+
if count
38+
assert_equal count, matched_queries.size, "#{matched_queries.size} instead of #{count} queries were executed.#{count.log.empty? ? '' : "\nQueries:\n#{counter.log.join("\n")}"}"
39+
else
40+
assert_operator matched_queries.size, :>=, 1, "1 or more queries expected, but none were executed.#{counter.log.empty? ? '' : "\nQueries:\n#{counter.log.join("\n")}"}"
41+
end
42+
43+
result
44+
end
45+
end
46+
2547
private
2648

2749
# Rails tests expect a save-point to be created and released. SQL Server does not release

0 commit comments

Comments
 (0)