Skip to content

Commit

Permalink
Support :unique_deferrable and :primary_key_deferrable column options
Browse files Browse the repository at this point in the history
These are supported by PostgreSQL 9+ and Oracle. It was already possible
to specify such constraints as table constraints, but previously
there was not a way to specify deferrability for primary_key or
unique column constraints.
  • Loading branch information
jeremyevans committed Aug 2, 2019
1 parent dd29c6c commit df686c5
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
=== master

* Support :unique_deferrable and :primary_key_deferrable column options (jeremyevans)

* Support :generated_always_as column option on PostgreSQL 12+ (jeremyevans)

=== 5.23.0 (2019-08-01)
Expand Down
4 changes: 4 additions & 0 deletions lib/sequel/database/schema_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,15 @@ def check(*args, &block)
# be used if you have a single, nonautoincrementing primary key column
# (use the primary_key method in that case).
# :primary_key_constraint_name :: The name to give the primary key constraint
# :primary_key_deferrable :: Similar to :deferrable, but for the primary key constraint
# if :primary_key is used.
# :type :: Overrides the type given as the argument. Generally not used by column
# itself, but can be passed as an option to other methods that call column.
# :unique :: Mark the column as unique, generally has the same effect as
# creating a unique index on the column.
# :unique_constraint_name :: The name to give the unique key constraint
# :unique_deferrable :: Similar to :deferrable, but for the unique constraint if :unique
# is used.
#
# PostgreSQL specific options:
#
Expand Down
2 changes: 2 additions & 0 deletions lib/sequel/database/schema_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,7 @@ def column_definition_primary_key_sql(sql, column)
sql << " CONSTRAINT #{quote_identifier(name)}"
end
sql << ' PRIMARY KEY'
constraint_deferrable_sql_append(sql, column[:primary_key_deferrable])
end
end

Expand All @@ -606,6 +607,7 @@ def column_definition_unique_sql(sql, column)
sql << " CONSTRAINT #{quote_identifier(name)}"
end
sql << ' UNIQUE'
constraint_deferrable_sql_append(sql, column[:unique_deferrable])
end
end

Expand Down
12 changes: 12 additions & 0 deletions spec/adapters/postgres_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,18 @@
@db[:tmp_dolls].select_order_map([:a, :b, :c]).must_equal [[100, 10, 211]]
end if DB.server_version >= 120000

it "should support deferred primary key and unique constraints on columns" do
@db.create_table(:tmp_dolls){primary_key :id, :primary_key_deferrable=>true; Integer :i, :unique=>true, :unique_deferrable=>true}
@db[:tmp_dolls].insert(:i=>10)
DB.transaction do
@db[:tmp_dolls].insert(:id=>1, :i=>1)
@db[:tmp_dolls].insert(:id=>10, :i=>10)
@db[:tmp_dolls].where(:i=>1).update(:id=>2)
@db[:tmp_dolls].where(:id=>10).update(:i=>2)
end
@db[:tmp_dolls].select_order_map([:id, :i]).must_equal [[1, 10], [2, 1], [10, 2]]
end if DB.server_version >= 90000

it "should support pg_loose_count extension" do
@db.extension :pg_loose_count
@db.create_table(:tmp_dolls){text :name}
Expand Down
18 changes: 18 additions & 0 deletions spec/core/schema_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,24 @@ def @db.supports_named_column_constraints?; false end
@db.sqls.must_equal ["CREATE TABLE cats (id integer, name text, UNIQUE (name) DEFERRABLE INITIALLY IMMEDIATE)"]
end

it "should handle deferred unique column constraints" do
@db.create_table(:cats) do
integer :id, :unique=>true, :unique_deferrable=>true
integer :i, :unique=>true, :unique_deferrable=>:immediate
integer :j, :unique=>true, :unique_deferrable=>false
end
@db.sqls.must_equal ["CREATE TABLE cats (id integer UNIQUE DEFERRABLE INITIALLY DEFERRED, i integer UNIQUE DEFERRABLE INITIALLY IMMEDIATE, j integer UNIQUE NOT DEFERRABLE)"]
end

it "should handle deferred primary key column constraints" do
@db.create_table(:cats) do
integer :id, :primary_key=>true, :primary_key_deferrable=>true
integer :i, :primary_key=>true, :primary_key_deferrable=>:immediate
integer :j, :primary_key=>true, :primary_key_deferrable=>false
end
@db.sqls.must_equal ["CREATE TABLE cats (id integer PRIMARY KEY DEFERRABLE INITIALLY DEFERRED, i integer PRIMARY KEY DEFERRABLE INITIALLY IMMEDIATE, j integer PRIMARY KEY NOT DEFERRABLE)"]
end

it "should accept unsigned definition" do
@db.create_table(:cats) do
integer :value, :unsigned => true
Expand Down

0 comments on commit df686c5

Please sign in to comment.