Skip to content

Commit 016cdc6

Browse files
author
Jippe Holwerda
committed
Use fully qualified database name when retrieving column definitions to support linked servers.
1 parent c39a781 commit 016cdc6

File tree

3 files changed

+21
-9
lines changed

3 files changed

+21
-9
lines changed

lib/active_record/connection_adapters/sqlserver/schema_statements.rb

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ def initialize_native_database_types
221221

222222
def column_definitions(table_name)
223223
identifier = SQLServer::Utils.extract_identifiers(table_name)
224-
database = "#{identifier.database_quoted}." if identifier.database_quoted
224+
database = identifier.fully_qualified_database_quoted
225225
view_exists = schema_cache.view_exists?(table_name)
226226
view_tblnm = table_name_or_views_table_name(table_name) if view_exists
227227
sql = %{
@@ -237,7 +237,7 @@ def column_definitions(table_name)
237237
columns.ordinal_position,
238238
CASE
239239
WHEN columns.DATA_TYPE IN ('nchar','nvarchar','char','varchar') THEN columns.CHARACTER_MAXIMUM_LENGTH
240-
ELSE COL_LENGTH('#{database}'+columns.TABLE_SCHEMA+'.'+columns.TABLE_NAME, columns.COLUMN_NAME)
240+
ELSE COL_LENGTH('#{database}.'+columns.TABLE_SCHEMA+'.'+columns.TABLE_NAME, columns.COLUMN_NAME)
241241
END AS [length],
242242
CASE
243243
WHEN columns.IS_NULLABLE = 'YES' THEN 1
@@ -248,24 +248,24 @@ def column_definitions(table_name)
248248
ELSE NULL
249249
END AS [is_primary],
250250
c.is_identity AS [is_identity]
251-
FROM #{database}INFORMATION_SCHEMA.COLUMNS columns
252-
LEFT OUTER JOIN #{database}INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC
251+
FROM #{database}.INFORMATION_SCHEMA.COLUMNS columns
252+
LEFT OUTER JOIN #{database}.INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC
253253
ON TC.TABLE_NAME = columns.TABLE_NAME
254254
AND TC.CONSTRAINT_TYPE = N'PRIMARY KEY'
255-
LEFT OUTER JOIN #{database}INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU
255+
LEFT OUTER JOIN #{database}.INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU
256256
ON KCU.COLUMN_NAME = columns.COLUMN_NAME
257257
AND KCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME
258258
AND KCU.CONSTRAINT_CATALOG = TC.CONSTRAINT_CATALOG
259259
AND KCU.CONSTRAINT_SCHEMA = TC.CONSTRAINT_SCHEMA
260-
INNER JOIN #{identifier.database_quoted}.sys.schemas AS s
260+
INNER JOIN #{database}.sys.schemas AS s
261261
ON s.name = columns.TABLE_SCHEMA
262262
AND s.schema_id = s.schema_id
263-
INNER JOIN #{identifier.database_quoted}.sys.objects AS o
263+
INNER JOIN #{database}.sys.objects AS o
264264
ON s.schema_id = o.schema_id
265265
AND o.is_ms_shipped = 0
266266
AND o.type IN ('U', 'V')
267267
AND o.name = columns.TABLE_NAME
268-
INNER JOIN #{identifier.database_quoted}.sys.columns AS c
268+
INNER JOIN #{database}.sys.columns AS c
269269
ON o.object_id = c.object_id
270270
AND c.name = columns.COLUMN_NAME
271271
WHERE columns.TABLE_NAME = @0
@@ -299,7 +299,7 @@ def column_definitions(table_name)
299299
if default.nil? && view_exists
300300
default = select_value "
301301
SELECT c.COLUMN_DEFAULT
302-
FROM #{database}INFORMATION_SCHEMA.COLUMNS c
302+
FROM #{database}.INFORMATION_SCHEMA.COLUMNS c
303303
WHERE c.TABLE_NAME = '#{view_tblnm}'
304304
AND c.COLUMN_NAME = '#{views_real_column_name(table_name, ci[:name])}'".squish, 'SCHEMA'
305305
end

lib/active_record/connection_adapters/sqlserver/utils.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ def server_quoted
3939
server ? quote(server) : server
4040
end
4141

42+
def fully_qualified_database_quoted
43+
[server_quoted, database_quoted].compact.join(SEPARATOR)
44+
end
45+
4246
def to_s
4347
quoted
4448
end

test/cases/utils_test_sqlserver.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,14 @@ class UtilsTestSQLServer < ActiveRecord::TestCase
8686
SQLServer::Utils.extract_identifiers('[obj.name].[foo]').quoted.must_equal '[obj.name].[foo]'
8787
end
8888

89+
it 'can return fully qualified quoted table name' do
90+
name = SQLServer::Utils.extract_identifiers('[server.name].[database].[schema].[object]')
91+
name.fully_qualified_database_quoted.must_equal '[server.name].[database]'
92+
93+
name = SQLServer::Utils.extract_identifiers('server.database.schema.object')
94+
name.fully_qualified_database_quoted.must_equal '[server].[database]'
95+
end
96+
8997
end
9098

9199
end

0 commit comments

Comments
 (0)