Skip to content

Commit 7062496

Browse files
committed
Don't require an active connection for table and column quoting
See rails/rails#51174
1 parent c85e862 commit 7062496

File tree

2 files changed

+48
-50
lines changed

2 files changed

+48
-50
lines changed

lib/active_record/connection_adapters/sqlserver/database_statements.rb

+4-4
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,10 @@ def build_insert_sql(insert) # :nodoc:
153153

154154
if returning = insert.send(:insert_all).returning
155155
returning_sql = if returning.is_a?(String)
156-
returning
157-
else
158-
returning.map { |column| "INSERTED.#{quote_column_name(column)}" }.join(", ")
159-
end
156+
returning
157+
else
158+
returning.map { |column| "INSERTED.#{quote_column_name(column)}" }.join(", ")
159+
end
160160
sql << " OUTPUT #{returning_sql}"
161161
end
162162

lib/active_record/connection_adapters/sqlserver/quoting.rb

+44-46
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,53 @@ module ActiveRecord
44
module ConnectionAdapters
55
module SQLServer
66
module Quoting
7+
extend ActiveSupport::Concern
8+
79
QUOTED_COLUMN_NAMES = Concurrent::Map.new # :nodoc:
810
QUOTED_TABLE_NAMES = Concurrent::Map.new # :nodoc:
911

12+
module ClassMethods
13+
def column_name_matcher
14+
/
15+
\A
16+
(
17+
(?:
18+
# [database_name].[database_owner].[table_name].[column_name] | function(one or no argument)
19+
((?:\w+\.|\[\w+\]\.)?(?:\w+\.|\[\w+\]\.)?(?:\w+\.|\[\w+\]\.)?(?:\w+|\[\w+\]) | \w+\((?:|\g<2>)\))
20+
)
21+
(?:\s+AS\s+(?:\w+|\[\w+\]))?
22+
)
23+
(?:\s*,\s*\g<1>)*
24+
\z
25+
/ix
26+
end
27+
28+
def column_name_with_order_matcher
29+
/
30+
\A
31+
(
32+
(?:
33+
# [database_name].[database_owner].[table_name].[column_name] | function(one or no argument)
34+
((?:\w+\.|\[\w+\]\.)?(?:\w+\.|\[\w+\]\.)?(?:\w+\.|\[\w+\]\.)?(?:\w+|\[\w+\]) | \w+\((?:|\g<2>)\))
35+
)
36+
(?:\s+COLLATE\s+\w+)?
37+
(?:\s+ASC|\s+DESC)?
38+
(?:\s+NULLS\s+(?:FIRST|LAST))?
39+
)
40+
(?:\s*,\s*\g<1>)*
41+
\z
42+
/ix
43+
end
44+
45+
def quote_column_name(name)
46+
QUOTED_COLUMN_NAMES[name] ||= SQLServer::Utils.extract_identifiers(name).quoted
47+
end
48+
49+
def quote_table_name(name)
50+
QUOTED_TABLE_NAMES[name] ||= SQLServer::Utils.extract_identifiers(name).quoted
51+
end
52+
end
53+
1054
def fetch_type_metadata(sql_type, sqlserver_options = {})
1155
cast_type = lookup_cast_type(sql_type)
1256

@@ -33,14 +77,6 @@ def quote_string_single_national(s)
3377
SQLServer::Utils.quote_string_single_national(s)
3478
end
3579

36-
def quote_column_name(name)
37-
QUOTED_COLUMN_NAMES[name] ||= SQLServer::Utils.extract_identifiers(name).quoted
38-
end
39-
40-
def quote_table_name(name)
41-
QUOTED_TABLE_NAMES[name] ||= SQLServer::Utils.extract_identifiers(name).quoted
42-
end
43-
4480
def quote_default_expression(value, column)
4581
cast_type = lookup_cast_type(column.sql_type)
4682
if cast_type.type == :uuid && value.is_a?(String) && value.include?('()')
@@ -76,44 +112,6 @@ def quoted_date(value)
76112
end
77113
end
78114

79-
def column_name_matcher
80-
COLUMN_NAME
81-
end
82-
83-
def column_name_with_order_matcher
84-
COLUMN_NAME_WITH_ORDER
85-
end
86-
87-
COLUMN_NAME = /
88-
\A
89-
(
90-
(?:
91-
# [database_name].[database_owner].[table_name].[column_name] | function(one or no argument)
92-
((?:\w+\.|\[\w+\]\.)?(?:\w+\.|\[\w+\]\.)?(?:\w+\.|\[\w+\]\.)?(?:\w+|\[\w+\]) | \w+\((?:|\g<2>)\))
93-
)
94-
(?:\s+AS\s+(?:\w+|\[\w+\]))?
95-
)
96-
(?:\s*,\s*\g<1>)*
97-
\z
98-
/ix
99-
100-
COLUMN_NAME_WITH_ORDER = /
101-
\A
102-
(
103-
(?:
104-
# [database_name].[database_owner].[table_name].[column_name] | function(one or no argument)
105-
((?:\w+\.|\[\w+\]\.)?(?:\w+\.|\[\w+\]\.)?(?:\w+\.|\[\w+\]\.)?(?:\w+|\[\w+\]) | \w+\((?:|\g<2>)\))
106-
)
107-
(?:\s+COLLATE\s+\w+)?
108-
(?:\s+ASC|\s+DESC)?
109-
(?:\s+NULLS\s+(?:FIRST|LAST))?
110-
)
111-
(?:\s*,\s*\g<1>)*
112-
\z
113-
/ix
114-
115-
private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
116-
117115
def quote(value)
118116
case value
119117
when Type::Binary::Data

0 commit comments

Comments
 (0)