= New Features * Dataset#for_no_key_update and #for_key_share have been added on PostgreSQL. If you are not deleting a row or modifying a key column in a row, it is recommended to switch existing #for_update calls to #for_no_key_update, so they don't take stronger locks than necessary (#for_update will block concurrent INSERTs that reference a locked row). * Check and foreign key constraints now support a :not_enforced option on PostgreSQL 18+, for using NOT ENFORCED. Constraints that are not enforced serve mostly documentation purposes, but they can be enforced later by altering the constraint. * On PostgreSQL, alter_table blocks now support an alter_constraint method, which accepts the following options for altering the constraint: :deferrable :: Modify deferrable setting for constraint (PostgreSQL 9.4+): true :: DEFERRABLE INITIALLY DEFERRED false :: NOT DEFERRABLE :immediate :: DEFERRABLE INITIALLY IMMEDIATE :enforced :: Set true to use ENFORCED, or false to use NOT ENFORCED (PostgreSQL 18+) :inherit :: Set true to use INHERIT, or false to use NO INHERIT (PostgreSQL 18+) * Entries in Database#foreign_key_list, #reverse_foreign_key_list, and #check_constraint arrays on PostgreSQL now include :validated and :enforced entries to indicate whether the constraint is validated and enforced, respectively. * :primary_key and :unique column options now support hash values in the schema generators. Using a hash value allows you to provide column constraint-specific options in the hash. This currently supports the :name and :deferrable options for both constraint types. Additional options will be supported in the future. = Other Improvements * Dataset#for_share on PostgreSQL and MySQL now caches the returned dataset, similar to the caching done by #for_update. * Dataset#nolock on Microsoft SQL Server now caches the returned dataset, similar to the caching done by #for_update. * Many minor performance improvements have been applied, mostly fixed and/or flagged by rubocop-performance: * sort_by! instead of sort! * delete/tr instead of gsub * yield instead of block.call * start_with? accepts multiple arguments * Hash#[]= instead of merge! * Array.new instead of Integer#times.map * Hoist literal arrays inside loops to before the loop * Use block instead of Method#to_proc * Use start_with instead of regexp with \A * Use String#include? instead of =~ * In the jdbc adapter, Database#foreign_key_list has been optimized, reducing the number of allocations. * On DB2, multiple UNIQUE constraints on the same table are now handled when automatically marking columns as NOT NULL.