Skip to content

Commit 0a76dd3

Browse files
committed
Don't try to get table name in single regex
1 parent 5624f8f commit 0a76dd3

File tree

2 files changed

+65
-6
lines changed

2 files changed

+65
-6
lines changed

lib/active_record/connection_adapters/sqlserver/schema_statements.rb

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -674,13 +674,26 @@ def get_table_name(sql)
674674
# Parses the raw table name that is used in the SQL. Table name could include database/schema/etc.
675675
def get_raw_table_name(sql)
676676

677+
s = sql.gsub(/^\s*EXEC sp_executesql N'/i, "")
677678

678-
case sql
679-
when /^\s*(INSERT|EXEC sp_executesql N'INSERT)(\s+INTO)?\s+(\[[^\(\]]+\])\s*|^\s*update\s+([^\(\s]+)\s*/i
680-
Regexp.last_match[3] || Regexp.last_match[4]
681-
when /FROM\s+((\[[^\(\]]+\])|[^\(\s]+)\s*/i
682-
Regexp.last_match[1]
679+
# binding.pry
680+
681+
if s.match?(/^\s*INSERT INTO.*/i)
682+
s = s.split(/INSERT INTO/i)[1].split(/OUTPUT INSERTED/i)[0].split(/(DEFAULT)?\s+VALUES/i)[0]
683+
684+
s.match(/\s*([^(]*)/i)[0]
685+
else
686+
s.match(/FROM\s+((\[[^\(\]]+\])|[^\(\s]+)\s*/i)[1]
683687
end.strip
688+
689+
# table_name
690+
691+
# case sql
692+
# when /^\s*(INSERT|EXEC sp_executesql N'INSERT)(\s+INTO)?\s+(\[[^\(\]]+\])\s*|^\s*update\s+([^\(\s]+)\s*/i
693+
# Regexp.last_match[3] || Regexp.last_match[4]
694+
# when /FROM\s+((\[[^\(\]]+\])|[^\(\s]+)\s*/i
695+
# Regexp.last_match[1]
696+
# end.strip
684697
end
685698

686699
def default_constraint_name(table_name, column_name)

test/cases/schema_test_sqlserver.rb

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class SchemaTestSQLServer < ActiveRecord::TestCase
3939
assert_equal 1, columns.select { |c| c.is_identity? }.size
4040
end
4141

42-
it "return correct varchar and nvarchar column limit length when table is in non dbo schema" do
42+
it "return correct varchar and nvarchar column limit length when table is in non-dbo schema" do
4343
columns = connection.columns("test.sst_schema_columns")
4444

4545
assert_equal 255, columns.find { |c| c.name == "name" }.limit
@@ -48,4 +48,50 @@ class SchemaTestSQLServer < ActiveRecord::TestCase
4848
assert_equal 1000, columns.find { |c| c.name == "n_description" }.limit
4949
end
5050
end
51+
52+
describe "parsing table name from raw SQL" do
53+
describe 'SELECT statements' do
54+
it do
55+
assert_equal "[sst_schema_columns]", connection.send(:get_raw_table_name, "SELECT [sst_schema_columns].[id] FROM [sst_schema_columns]")
56+
end
57+
58+
it do
59+
assert_equal "sst_schema_columns", connection.send(:get_raw_table_name, "SELECT [sst_schema_columns].[id] FROM sst_schema_columns")
60+
end
61+
62+
it do
63+
assert_equal "[WITH - SPACES]", connection.send(:get_raw_table_name, "SELECT id FROM [WITH - SPACES]")
64+
end
65+
66+
it do
67+
assert_equal "[WITH - SPACES$DOLLAR]", connection.send(:get_raw_table_name, "SELECT id FROM [WITH - SPACES$DOLLAR]")
68+
end
69+
end
70+
71+
describe 'INSERT statements' do
72+
it do
73+
assert_equal "[dashboards]", connection.send(:get_raw_table_name, "INSERT INTO [dashboards] DEFAULT VALUES; SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident")
74+
end
75+
76+
it do
77+
assert_equal "lock_without_defaults", connection.send(:get_raw_table_name, "INSERT INTO lock_without_defaults(title) VALUES('title1')")
78+
end
79+
80+
it do
81+
assert_equal "json_data_type", connection.send(:get_raw_table_name, "insert into json_data_type (payload) VALUES ('null')")
82+
end
83+
84+
it do
85+
assert_equal "[auto_increments]", connection.send(:get_raw_table_name, "INSERT INTO [auto_increments] OUTPUT INSERTED.[id] DEFAULT VALUES")
86+
end
87+
88+
it do
89+
assert_equal "[WITH - SPACES]", connection.send(:get_raw_table_name, "EXEC sp_executesql N'INSERT INTO [WITH - SPACES] ([external_id]) OUTPUT INSERTED.[id] VALUES (@0)', N'@0 bigint', @0 = 10")
90+
end
91+
92+
it do
93+
assert_equal "[test].[aliens]", connection.send(:get_raw_table_name, "EXEC sp_executesql N'INSERT INTO [test].[aliens] ([name]) OUTPUT INSERTED.[id] VALUES (@0)', N'@0 varchar(255)', @0 = 'Trisolarans'")
94+
end
95+
end
96+
end
5197
end

0 commit comments

Comments
 (0)