Skip to content

Commit 42c46c0

Browse files
committed
[Rails51] Find #primary_keys propertly.
* Support proper ordinal order. * Bake in schema and full DB identifer support like #column_definitions.
1 parent 1faa855 commit 42c46c0

File tree

3 files changed

+35
-7
lines changed

3 files changed

+35
-7
lines changed

lib/active_record/connection_adapters/sqlserver/schema_statements.rb

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,34 @@ def new_column(name, default, sql_type_metadata, null, table_name, default_funct
8585
end
8686

8787
def primary_keys(table_name)
88-
primaries = schema_cache.columns(table_name).select(&:is_primary?).map(&:name)
88+
primaries = primary_keys_select(table_name)
8989
primaries.present? ? primaries : identity_columns(table_name).map(&:name)
9090
end
9191

92+
def primary_keys_select(table_name)
93+
identifier = database_prefix_identifier(table_name)
94+
database = identifier.fully_qualified_database_quoted
95+
sql = %{
96+
SELECT KCU.COLUMN_NAME AS [name]
97+
FROM #{database}.INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU
98+
LEFT OUTER JOIN #{database}.INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC
99+
ON KCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME
100+
AND KCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME
101+
AND KCU.CONSTRAINT_CATALOG = TC.CONSTRAINT_CATALOG
102+
AND KCU.CONSTRAINT_SCHEMA = TC.CONSTRAINT_SCHEMA
103+
AND TC.CONSTRAINT_TYPE = N'PRIMARY KEY'
104+
WHERE KCU.TABLE_NAME = #{prepared_statements ? '@0' : quote(identifier.object)}
105+
AND KCU.TABLE_SCHEMA = #{identifier.schema.blank? ? 'schema_name()' : (prepared_statements ? '@1' : quote(identifier.schema))}
106+
AND TC.CONSTRAINT_TYPE = N'PRIMARY KEY'
107+
ORDER BY KCU.ORDINAL_POSITION ASC
108+
}.gsub(/[[:space:]]/, ' ')
109+
binds = []
110+
nv128 = SQLServer::Type::UnicodeVarchar.new limit: 128
111+
binds << Relation::QueryAttribute.new('TABLE_NAME', identifier.object, nv128)
112+
binds << Relation::QueryAttribute.new('TABLE_SCHEMA', identifier.schema, nv128) unless identifier.schema.blank?
113+
sp_executesql(sql, 'SCHEMA', binds).map { |r| r['name'] }
114+
end
115+
92116
def rename_table(table_name, new_name)
93117
do_execute "EXEC sp_rename '#{table_name}', '#{new_name}'"
94118
rename_table_indexes(table_name, new_name)
@@ -290,11 +314,7 @@ def initialize_native_database_types
290314
end
291315

292316
def column_definitions(table_name)
293-
identifier = if database_prefix_remote_server?
294-
SQLServer::Utils.extract_identifiers("#{database_prefix}#{table_name}")
295-
else
296-
SQLServer::Utils.extract_identifiers(table_name)
297-
end
317+
identifier = database_prefix_identifier(table_name)
298318
database = identifier.fully_qualified_database_quoted
299319
view_exists = view_exists?(table_name)
300320
view_tblnm = view_table_name(table_name) if view_exists

lib/active_record/connection_adapters/sqlserver_adapter.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,14 @@ def database_prefix
226226
@connection_options[:database_prefix]
227227
end
228228

229+
def database_prefix_identifier(name)
230+
if database_prefix_remote_server?
231+
SQLServer::Utils.extract_identifiers("#{database_prefix}#{name}")
232+
else
233+
SQLServer::Utils.extract_identifiers(name)
234+
end
235+
end
236+
229237
def version
230238
self.class::VERSION
231239
end

test/support/sql_counter_sqlserver.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def capture_sql_ss
1313
end
1414

1515
ignored_sql = [
16-
/INFORMATION_SCHEMA\.(TABLES|VIEWS|COLUMNS)/im,
16+
/INFORMATION_SCHEMA\.(TABLES|VIEWS|COLUMNS|KEY_COLUMN_USAGE)/im,
1717
/SELECT @@version/,
1818
/SELECT @@TRANCOUNT/,
1919
/(BEGIN|COMMIT|ROLLBACK|SAVE) TRANSACTION/,

0 commit comments

Comments
 (0)