diff --git a/CHANGELOG b/CHANGELOG index 1a8e1460ec..94e3197859 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -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) diff --git a/lib/sequel/database/schema_generator.rb b/lib/sequel/database/schema_generator.rb index 27b95bdfb3..6e3345517f 100644 --- a/lib/sequel/database/schema_generator.rb +++ b/lib/sequel/database/schema_generator.rb @@ -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: # diff --git a/lib/sequel/database/schema_methods.rb b/lib/sequel/database/schema_methods.rb index 5444f808cc..d7e8e958d0 100644 --- a/lib/sequel/database/schema_methods.rb +++ b/lib/sequel/database/schema_methods.rb @@ -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 @@ -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 diff --git a/spec/adapters/postgres_spec.rb b/spec/adapters/postgres_spec.rb index 0a7f949aa9..1748b8ba08 100644 --- a/spec/adapters/postgres_spec.rb +++ b/spec/adapters/postgres_spec.rb @@ -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} diff --git a/spec/core/schema_spec.rb b/spec/core/schema_spec.rb index efd775cbc7..6fb47fc74b 100644 --- a/spec/core/schema_spec.rb +++ b/spec/core/schema_spec.rb @@ -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