Skip to content

Commit 1cc444b

Browse files
authored
Rails 6.1: change schema dumper condition to only dump explicit default for non identity integers (#902)
* coerse test to change binding syntax to @n * add default option to pk dump * Revert "coerse test to change binding syntax to @n" This reverts commit 63eddd4. * remove test coercion * set primary_key_nonclustered type to bigint seems this was missing when primary_key changed from integer to bigint (620baf2#diff-86264ef1995b0800604b26d64ede427e8a3ed59347993bfb409c596e83f4b86f) * remove redundat set of primary_key option. AbstractAdapter already does this Absctract SchemaDefinition sets primary_key option (https://github.com/rails/rails/blob/v6.1.0/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb#L234). There is no point in doing this * remove unnecesary primary check. default_primary_key is called on columns that return true to is_primary? * rewrite 'explicit_primary_key_default?'. String primary keys should not have explicit default * specs about primary keys * fix typo
1 parent 36cf7ce commit 1cc444b

File tree

4 files changed

+106
-4
lines changed

4 files changed

+106
-4
lines changed

lib/active_record/connection_adapters/sqlserver/schema_dumper.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class SchemaDumper < ConnectionAdapters::SchemaDumper
1515
private
1616

1717
def explicit_primary_key_default?(column)
18-
column.is_primary? && !column.is_identity?
18+
column.type == :integer && !column.is_identity?
1919
end
2020

2121
def schema_limit(column)
@@ -37,7 +37,7 @@ def schema_collation(column)
3737
end
3838

3939
def default_primary_key?(column)
40-
super && column.is_primary? && column.is_identity?
40+
super && column.is_identity?
4141
end
4242
end
4343
end

lib/active_record/connection_adapters/sqlserver/schema_statements.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ def quoted_scope(name = nil, type: nil)
332332
def initialize_native_database_types
333333
{
334334
primary_key: "bigint NOT NULL IDENTITY(1,1) PRIMARY KEY",
335-
primary_key_nonclustered: "int NOT NULL IDENTITY(1,1) PRIMARY KEY NONCLUSTERED",
335+
primary_key_nonclustered: "bigint NOT NULL IDENTITY(1,1) PRIMARY KEY NONCLUSTERED",
336336
integer: { name: "int", limit: 4 },
337337
bigint: { name: "bigint" },
338338
boolean: { name: "bit" },

lib/active_record/connection_adapters/sqlserver/table_definition.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ def primary_key(name, type = :primary_key, **options)
99
options[:is_identity] = true unless options.key?(:default)
1010
elsif type == :uuid
1111
options[:default] = options.fetch(:default, "NEWID()")
12-
options[:primary_key] = true
1312
end
1413
super
1514
end
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# frozen_string_literal: true
2+
3+
require "cases/helper_sqlserver"
4+
require "support/schema_dumping_helper"
5+
6+
class PrimaryKeyUuidTypeTest < ActiveRecord::TestCase
7+
include SchemaDumpingHelper
8+
9+
self.use_transactional_tests = false
10+
11+
class Barcode < ActiveRecord::Base
12+
end
13+
14+
setup do
15+
@connection = ActiveRecord::Base.connection
16+
@connection.create_table(:barcodes, primary_key: "code", id: :uuid, force: true)
17+
end
18+
19+
teardown do
20+
@connection.drop_table(:barcodes, if_exists: true)
21+
end
22+
23+
def test_any_type_primary_key
24+
assert_equal "code", Barcode.primary_key
25+
26+
column = Barcode.column_for_attribute(Barcode.primary_key)
27+
assert_not column.null
28+
assert_equal :uuid, column.type
29+
assert_not_predicate column, :is_identity?
30+
assert_predicate column, :is_primary?
31+
ensure
32+
Barcode.reset_column_information
33+
end
34+
35+
test "schema dump primary key includes default" do
36+
schema = dump_table_schema "barcodes"
37+
assert_match %r/create_table "barcodes", primary_key: "code", id: :uuid, default: -> { "newid\(\)" }/, schema
38+
end
39+
end
40+
41+
class PrimaryKeyIntegerTest < ActiveRecord::TestCase
42+
include SchemaDumpingHelper
43+
44+
self.use_transactional_tests = false
45+
46+
class Barcode < ActiveRecord::Base
47+
end
48+
49+
class Widget < ActiveRecord::Base
50+
end
51+
52+
setup do
53+
@connection = ActiveRecord::Base.connection
54+
end
55+
56+
teardown do
57+
@connection.drop_table :barcodes, if_exists: true
58+
@connection.drop_table :widgets, if_exists: true
59+
end
60+
61+
test "integer primary key without default" do
62+
@connection.create_table(:widgets, id: :integer, force: true)
63+
column = @connection.columns(:widgets).find { |c| c.name == "id" }
64+
assert_predicate column, :is_primary?
65+
assert_predicate column, :is_identity?
66+
assert_equal :integer, column.type
67+
assert_not_predicate column, :bigint?
68+
69+
schema = dump_table_schema "widgets"
70+
assert_match %r/create_table "widgets", id: :integer, force: :cascade do/, schema
71+
end
72+
73+
test "bigint primary key without default" do
74+
@connection.create_table(:widgets, id: :bigint, force: true)
75+
column = @connection.columns(:widgets).find { |c| c.name == "id" }
76+
assert_predicate column, :is_primary?
77+
assert_predicate column, :is_identity?
78+
assert_equal :integer, column.type
79+
assert_predicate column, :bigint?
80+
81+
schema = dump_table_schema "widgets"
82+
assert_match %r/create_table "widgets", force: :cascade do/, schema
83+
end
84+
85+
test "don't set identity to integer and bigint when there is a default" do
86+
@connection.create_table(:barcodes, id: :integer, default: nil, force: true)
87+
@connection.create_table(:widgets, id: :bigint, default: nil, force: true)
88+
89+
column = @connection.columns(:widgets).find { |c| c.name == "id" }
90+
assert_predicate column, :is_primary?
91+
assert_not_predicate column, :is_identity?
92+
93+
schema = dump_table_schema "widgets"
94+
assert_match %r/create_table "widgets", id: :bigint, default: nil, force: :cascade do/, schema
95+
96+
column = @connection.columns(:barcodes).find { |c| c.name == "id" }
97+
assert_predicate column, :is_primary?
98+
assert_not_predicate column, :is_identity?
99+
100+
schema = dump_table_schema "barcodes"
101+
assert_match %r/create_table "barcodes", id: :integer, default: nil, force: :cascade do/, schema
102+
end
103+
end

0 commit comments

Comments
 (0)