Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#### Fixed

- [#1424](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1424) Fix table name parsing for `INSERT INTO <table> WITH (<hints>)`.

## v8.1.4

#### Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ def query_requires_identity_insert?(sql)
id_column = identity_columns(raw_table_name).first

if id_column && (
sql =~ /^\s*(INSERT|EXEC sp_executesql N'INSERT)[^(]+\([^)]*\b(#{id_column.name})\b,?[^)]*\)/i ||
sql =~ /^\s*(INSERT|EXEC sp_executesql N'INSERT)[^(]+(?:WITH\s*\([^)]*\)\s*)?\([^)]*\b(#{id_column.name})\b,?[^)]*\)/i ||
sql =~ /^\s*MERGE INTO.+THEN INSERT \([^)]*\b(#{id_column.name})\b,?[^)]*\)/im
)
SQLServer::Utils.extract_identifiers(raw_table_name).quoted
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,7 @@ def get_raw_table_name(sql)
.split(/OUTPUT INSERTED/i)[0]
.split(/(DEFAULT)?\s+VALUES/i)[0]
.split(/\bSELECT\b(?![^\[]*\])/i)[0]
.split(/\s+WITH\s*\(/i)[0] # Strip table hints (eg: "INSERT INTO books WITH (TABLOCK) (title)")
.match(/\s*([^(]*)/i)[0]
elsif s.match?(/^\s*UPDATE\s+.*/i)
s.match(/UPDATE\s+([^(\s]+)\s*/i)[1]
Expand Down
8 changes: 8 additions & 0 deletions test/cases/adapter_test_sqlserver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,14 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
assert_equal "customers", connection.send(:get_table_name, basic_select_sql)
end

it "execute INSERT statements with table hints" do
assert_difference -> { connection.select_value("SELECT COUNT(*) FROM [funny_jokes]") }, 2 do
connection.execute("INSERT INTO [funny_jokes] WITH (TABLOCK) ([name]) VALUES ('Knock knock')")
connection.execute("INSERT INTO [funny_jokes] WITH (TABLOCK) ([id], [name]) VALUES (420, 'Knock knock')")
end
assert_equal "Knock knock", connection.select_value("SELECT [name] FROM [funny_jokes] WHERE [id] = 420")
end

it "test bad connection" do
assert_raise ActiveRecord::NoDatabaseError do
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
Expand Down
Loading