activerecord 5.2.4.3 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +614 -588
 - data/MIT-LICENSE +3 -1
 - data/README.rdoc +4 -2
 - data/examples/performance.rb +1 -1
 - data/lib/active_record.rb +9 -2
 - data/lib/active_record/aggregations.rb +4 -2
 - data/lib/active_record/associations.rb +19 -14
 - data/lib/active_record/associations/association.rb +52 -19
 - data/lib/active_record/associations/association_scope.rb +4 -6
 - data/lib/active_record/associations/belongs_to_association.rb +36 -42
 - data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
 - data/lib/active_record/associations/builder/association.rb +14 -18
 - data/lib/active_record/associations/builder/belongs_to.rb +19 -52
 - data/lib/active_record/associations/builder/collection_association.rb +3 -13
 - data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -38
 - data/lib/active_record/associations/builder/has_many.rb +2 -0
 - data/lib/active_record/associations/builder/has_one.rb +35 -1
 - data/lib/active_record/associations/builder/singular_association.rb +2 -0
 - data/lib/active_record/associations/collection_association.rb +6 -21
 - data/lib/active_record/associations/collection_proxy.rb +12 -15
 - data/lib/active_record/associations/foreign_association.rb +7 -0
 - data/lib/active_record/associations/has_many_association.rb +2 -10
 - data/lib/active_record/associations/has_many_through_association.rb +14 -14
 - data/lib/active_record/associations/has_one_association.rb +28 -30
 - data/lib/active_record/associations/has_one_through_association.rb +5 -5
 - data/lib/active_record/associations/join_dependency.rb +24 -28
 - data/lib/active_record/associations/join_dependency/join_association.rb +9 -10
 - data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
 - data/lib/active_record/associations/preloader.rb +40 -32
 - data/lib/active_record/associations/preloader/association.rb +38 -36
 - data/lib/active_record/associations/preloader/through_association.rb +48 -39
 - data/lib/active_record/associations/singular_association.rb +2 -16
 - data/lib/active_record/attribute_assignment.rb +7 -10
 - data/lib/active_record/attribute_methods.rb +28 -100
 - data/lib/active_record/attribute_methods/before_type_cast.rb +4 -1
 - data/lib/active_record/attribute_methods/dirty.rb +111 -40
 - data/lib/active_record/attribute_methods/primary_key.rb +15 -22
 - data/lib/active_record/attribute_methods/query.rb +2 -3
 - data/lib/active_record/attribute_methods/read.rb +15 -53
 - data/lib/active_record/attribute_methods/serialization.rb +1 -1
 - data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
 - data/lib/active_record/attribute_methods/write.rb +17 -24
 - data/lib/active_record/attributes.rb +13 -0
 - data/lib/active_record/autosave_association.rb +5 -9
 - data/lib/active_record/base.rb +2 -3
 - data/lib/active_record/callbacks.rb +5 -19
 - data/lib/active_record/connection_adapters/abstract/connection_pool.rb +94 -16
 - data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -4
 - data/lib/active_record/connection_adapters/abstract/database_statements.rb +95 -123
 - data/lib/active_record/connection_adapters/abstract/query_cache.rb +17 -8
 - data/lib/active_record/connection_adapters/abstract/quoting.rb +68 -17
 - data/lib/active_record/connection_adapters/abstract/schema_creation.rb +19 -12
 - data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +76 -48
 - data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -3
 - data/lib/active_record/connection_adapters/abstract/schema_statements.rb +132 -53
 - data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -56
 - data/lib/active_record/connection_adapters/abstract_adapter.rb +180 -47
 - data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +128 -194
 - data/lib/active_record/connection_adapters/column.rb +17 -13
 - data/lib/active_record/connection_adapters/connection_specification.rb +52 -42
 - data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +6 -10
 - data/lib/active_record/connection_adapters/mysql/database_statements.rb +73 -13
 - data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
 - data/lib/active_record/connection_adapters/mysql/schema_creation.rb +3 -4
 - data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
 - data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
 - data/lib/active_record/connection_adapters/mysql/schema_statements.rb +129 -13
 - data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
 - data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -9
 - data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
 - data/lib/active_record/connection_adapters/postgresql/database_statements.rb +20 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
 - data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
 - data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +6 -3
 - data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -7
 - data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +12 -1
 - data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
 - data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +55 -53
 - data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
 - data/lib/active_record/connection_adapters/postgresql_adapter.rb +160 -74
 - data/lib/active_record/connection_adapters/schema_cache.rb +37 -14
 - data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
 - data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
 - data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -6
 - data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +42 -11
 - data/lib/active_record/connection_adapters/sqlite3_adapter.rb +125 -141
 - data/lib/active_record/connection_handling.rb +149 -27
 - data/lib/active_record/core.rb +100 -60
 - data/lib/active_record/counter_cache.rb +4 -29
 - data/lib/active_record/database_configurations.rb +233 -0
 - data/lib/active_record/database_configurations/database_config.rb +37 -0
 - data/lib/active_record/database_configurations/hash_config.rb +50 -0
 - data/lib/active_record/database_configurations/url_config.rb +79 -0
 - data/lib/active_record/dynamic_matchers.rb +1 -1
 - data/lib/active_record/enum.rb +37 -7
 - data/lib/active_record/errors.rb +15 -7
 - data/lib/active_record/explain.rb +1 -1
 - data/lib/active_record/fixture_set/model_metadata.rb +33 -0
 - data/lib/active_record/fixture_set/render_context.rb +17 -0
 - data/lib/active_record/fixture_set/table_row.rb +153 -0
 - data/lib/active_record/fixture_set/table_rows.rb +47 -0
 - data/lib/active_record/fixtures.rb +145 -472
 - data/lib/active_record/gem_version.rb +4 -4
 - data/lib/active_record/inheritance.rb +13 -3
 - data/lib/active_record/insert_all.rb +179 -0
 - data/lib/active_record/integration.rb +68 -16
 - data/lib/active_record/internal_metadata.rb +10 -2
 - data/lib/active_record/locking/optimistic.rb +5 -6
 - data/lib/active_record/locking/pessimistic.rb +3 -3
 - data/lib/active_record/log_subscriber.rb +7 -26
 - data/lib/active_record/middleware/database_selector.rb +75 -0
 - data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
 - data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
 - data/lib/active_record/migration.rb +100 -81
 - data/lib/active_record/migration/command_recorder.rb +50 -6
 - data/lib/active_record/migration/compatibility.rb +76 -49
 - data/lib/active_record/model_schema.rb +30 -9
 - data/lib/active_record/nested_attributes.rb +2 -2
 - data/lib/active_record/no_touching.rb +7 -0
 - data/lib/active_record/persistence.rb +228 -24
 - data/lib/active_record/query_cache.rb +11 -4
 - data/lib/active_record/querying.rb +32 -20
 - data/lib/active_record/railtie.rb +80 -43
 - data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
 - data/lib/active_record/railties/controller_runtime.rb +30 -35
 - data/lib/active_record/railties/databases.rake +196 -46
 - data/lib/active_record/reflection.rb +32 -30
 - data/lib/active_record/relation.rb +310 -80
 - data/lib/active_record/relation/batches.rb +13 -10
 - data/lib/active_record/relation/calculations.rb +53 -47
 - data/lib/active_record/relation/delegation.rb +26 -43
 - data/lib/active_record/relation/finder_methods.rb +13 -26
 - data/lib/active_record/relation/merger.rb +11 -20
 - data/lib/active_record/relation/predicate_builder.rb +4 -6
 - data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
 - data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
 - data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
 - data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
 - data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
 - data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
 - data/lib/active_record/relation/query_attribute.rb +13 -8
 - data/lib/active_record/relation/query_methods.rb +189 -63
 - data/lib/active_record/relation/spawn_methods.rb +1 -1
 - data/lib/active_record/relation/where_clause.rb +14 -10
 - data/lib/active_record/relation/where_clause_factory.rb +1 -2
 - data/lib/active_record/result.rb +30 -11
 - data/lib/active_record/sanitization.rb +32 -40
 - data/lib/active_record/schema.rb +2 -11
 - data/lib/active_record/schema_dumper.rb +22 -7
 - data/lib/active_record/schema_migration.rb +5 -1
 - data/lib/active_record/scoping.rb +8 -8
 - data/lib/active_record/scoping/default.rb +4 -5
 - data/lib/active_record/scoping/named.rb +19 -15
 - data/lib/active_record/statement_cache.rb +30 -3
 - data/lib/active_record/store.rb +87 -8
 - data/lib/active_record/table_metadata.rb +10 -17
 - data/lib/active_record/tasks/database_tasks.rb +194 -25
 - data/lib/active_record/tasks/mysql_database_tasks.rb +5 -5
 - data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -7
 - data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -8
 - data/lib/active_record/test_databases.rb +23 -0
 - data/lib/active_record/test_fixtures.rb +224 -0
 - data/lib/active_record/timestamp.rb +39 -25
 - data/lib/active_record/touch_later.rb +4 -2
 - data/lib/active_record/transactions.rb +57 -66
 - data/lib/active_record/translation.rb +1 -1
 - data/lib/active_record/type.rb +3 -4
 - data/lib/active_record/type/adapter_specific_registry.rb +1 -8
 - data/lib/active_record/type_caster/connection.rb +15 -14
 - data/lib/active_record/type_caster/map.rb +1 -4
 - data/lib/active_record/validations.rb +1 -0
 - data/lib/active_record/validations/uniqueness.rb +15 -27
 - data/lib/arel.rb +51 -0
 - data/lib/arel/alias_predication.rb +9 -0
 - data/lib/arel/attributes.rb +22 -0
 - data/lib/arel/attributes/attribute.rb +37 -0
 - data/lib/arel/collectors/bind.rb +24 -0
 - data/lib/arel/collectors/composite.rb +31 -0
 - data/lib/arel/collectors/plain_string.rb +20 -0
 - data/lib/arel/collectors/sql_string.rb +20 -0
 - data/lib/arel/collectors/substitute_binds.rb +28 -0
 - data/lib/arel/crud.rb +42 -0
 - data/lib/arel/delete_manager.rb +18 -0
 - data/lib/arel/errors.rb +9 -0
 - data/lib/arel/expressions.rb +29 -0
 - data/lib/arel/factory_methods.rb +49 -0
 - data/lib/arel/insert_manager.rb +49 -0
 - data/lib/arel/math.rb +45 -0
 - data/lib/arel/nodes.rb +68 -0
 - data/lib/arel/nodes/and.rb +32 -0
 - data/lib/arel/nodes/ascending.rb +23 -0
 - data/lib/arel/nodes/binary.rb +52 -0
 - data/lib/arel/nodes/bind_param.rb +36 -0
 - data/lib/arel/nodes/case.rb +55 -0
 - data/lib/arel/nodes/casted.rb +50 -0
 - data/lib/arel/nodes/comment.rb +29 -0
 - data/lib/arel/nodes/count.rb +12 -0
 - data/lib/arel/nodes/delete_statement.rb +45 -0
 - data/lib/arel/nodes/descending.rb +23 -0
 - data/lib/arel/nodes/equality.rb +18 -0
 - data/lib/arel/nodes/extract.rb +24 -0
 - data/lib/arel/nodes/false.rb +16 -0
 - data/lib/arel/nodes/full_outer_join.rb +8 -0
 - data/lib/arel/nodes/function.rb +44 -0
 - data/lib/arel/nodes/grouping.rb +8 -0
 - data/lib/arel/nodes/in.rb +8 -0
 - data/lib/arel/nodes/infix_operation.rb +80 -0
 - data/lib/arel/nodes/inner_join.rb +8 -0
 - data/lib/arel/nodes/insert_statement.rb +37 -0
 - data/lib/arel/nodes/join_source.rb +20 -0
 - data/lib/arel/nodes/matches.rb +18 -0
 - data/lib/arel/nodes/named_function.rb +23 -0
 - data/lib/arel/nodes/node.rb +50 -0
 - data/lib/arel/nodes/node_expression.rb +13 -0
 - data/lib/arel/nodes/outer_join.rb +8 -0
 - data/lib/arel/nodes/over.rb +15 -0
 - data/lib/arel/nodes/regexp.rb +16 -0
 - data/lib/arel/nodes/right_outer_join.rb +8 -0
 - data/lib/arel/nodes/select_core.rb +67 -0
 - data/lib/arel/nodes/select_statement.rb +41 -0
 - data/lib/arel/nodes/sql_literal.rb +16 -0
 - data/lib/arel/nodes/string_join.rb +11 -0
 - data/lib/arel/nodes/table_alias.rb +27 -0
 - data/lib/arel/nodes/terminal.rb +16 -0
 - data/lib/arel/nodes/true.rb +16 -0
 - data/lib/arel/nodes/unary.rb +45 -0
 - data/lib/arel/nodes/unary_operation.rb +20 -0
 - data/lib/arel/nodes/unqualified_column.rb +22 -0
 - data/lib/arel/nodes/update_statement.rb +41 -0
 - data/lib/arel/nodes/values_list.rb +9 -0
 - data/lib/arel/nodes/window.rb +126 -0
 - data/lib/arel/nodes/with.rb +11 -0
 - data/lib/arel/order_predications.rb +13 -0
 - data/lib/arel/predications.rb +257 -0
 - data/lib/arel/select_manager.rb +271 -0
 - data/lib/arel/table.rb +110 -0
 - data/lib/arel/tree_manager.rb +72 -0
 - data/lib/arel/update_manager.rb +34 -0
 - data/lib/arel/visitors.rb +20 -0
 - data/lib/arel/visitors/depth_first.rb +204 -0
 - data/lib/arel/visitors/dot.rb +297 -0
 - data/lib/arel/visitors/ibm_db.rb +34 -0
 - data/lib/arel/visitors/informix.rb +62 -0
 - data/lib/arel/visitors/mssql.rb +157 -0
 - data/lib/arel/visitors/mysql.rb +83 -0
 - data/lib/arel/visitors/oracle.rb +159 -0
 - data/lib/arel/visitors/oracle12.rb +66 -0
 - data/lib/arel/visitors/postgresql.rb +110 -0
 - data/lib/arel/visitors/sqlite.rb +39 -0
 - data/lib/arel/visitors/to_sql.rb +889 -0
 - data/lib/arel/visitors/visitor.rb +46 -0
 - data/lib/arel/visitors/where_sql.rb +23 -0
 - data/lib/arel/window_predications.rb +9 -0
 - data/lib/rails/generators/active_record/migration.rb +14 -1
 - data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
 - data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
 - data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
 - data/lib/rails/generators/active_record/model/model_generator.rb +1 -0
 - data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
 - metadata +108 -26
 - data/lib/active_record/collection_cache_key.rb +0 -53
 
| 
         @@ -1,7 +1,5 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            require "active_support/core_ext/string/strip"
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
3 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       6 
4 
     | 
    
         
             
              module ConnectionAdapters
         
     | 
| 
       7 
5 
     | 
    
         
             
                class AbstractAdapter
         
     | 
| 
         @@ -17,14 +15,13 @@ module ActiveRecord 
     | 
|
| 
       17 
15 
     | 
    
         
             
                    end
         
     | 
| 
       18 
16 
     | 
    
         | 
| 
       19 
17 
     | 
    
         
             
                    delegate :quote_column_name, :quote_table_name, :quote_default_expression, :type_to_sql,
         
     | 
| 
       20 
     | 
    
         
            -
                      :options_include_default?, :supports_indexes_in_create?, : 
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                      :options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys_in_create?, :foreign_key_options
         
     | 
| 
      
 18 
     | 
    
         
            +
                      :options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys?, :foreign_key_options,
         
     | 
| 
      
 19 
     | 
    
         
            +
                      to: :@conn, private: true
         
     | 
| 
       23 
20 
     | 
    
         | 
| 
       24 
21 
     | 
    
         
             
                    private
         
     | 
| 
       25 
22 
     | 
    
         | 
| 
       26 
23 
     | 
    
         
             
                      def visit_AlterTable(o)
         
     | 
| 
       27 
     | 
    
         
            -
                        sql = "ALTER TABLE #{quote_table_name(o.name)} " 
     | 
| 
      
 24 
     | 
    
         
            +
                        sql = +"ALTER TABLE #{quote_table_name(o.name)} "
         
     | 
| 
       28 
25 
     | 
    
         
             
                        sql << o.adds.map { |col| accept col }.join(" ")
         
     | 
| 
       29 
26 
     | 
    
         
             
                        sql << o.foreign_key_adds.map { |fk| visit_AddForeignKey fk }.join(" ")
         
     | 
| 
       30 
27 
     | 
    
         
             
                        sql << o.foreign_key_drops.map { |fk| visit_DropForeignKey fk }.join(" ")
         
     | 
| 
         @@ -32,17 +29,19 @@ module ActiveRecord 
     | 
|
| 
       32 
29 
     | 
    
         | 
| 
       33 
30 
     | 
    
         
             
                      def visit_ColumnDefinition(o)
         
     | 
| 
       34 
31 
     | 
    
         
             
                        o.sql_type = type_to_sql(o.type, o.options)
         
     | 
| 
       35 
     | 
    
         
            -
                        column_sql = "#{quote_column_name(o.name)} #{o.sql_type}" 
     | 
| 
      
 32 
     | 
    
         
            +
                        column_sql = +"#{quote_column_name(o.name)} #{o.sql_type}"
         
     | 
| 
       36 
33 
     | 
    
         
             
                        add_column_options!(column_sql, column_options(o)) unless o.type == :primary_key
         
     | 
| 
       37 
34 
     | 
    
         
             
                        column_sql
         
     | 
| 
       38 
35 
     | 
    
         
             
                      end
         
     | 
| 
       39 
36 
     | 
    
         | 
| 
       40 
37 
     | 
    
         
             
                      def visit_AddColumnDefinition(o)
         
     | 
| 
       41 
     | 
    
         
            -
                        "ADD #{accept(o.column)}" 
     | 
| 
      
 38 
     | 
    
         
            +
                        +"ADD #{accept(o.column)}"
         
     | 
| 
       42 
39 
     | 
    
         
             
                      end
         
     | 
| 
       43 
40 
     | 
    
         | 
| 
       44 
41 
     | 
    
         
             
                      def visit_TableDefinition(o)
         
     | 
| 
       45 
     | 
    
         
            -
                        create_sql = "CREATE#{ 
     | 
| 
      
 42 
     | 
    
         
            +
                        create_sql = +"CREATE#{table_modifier_in_create(o)} TABLE "
         
     | 
| 
      
 43 
     | 
    
         
            +
                        create_sql << "IF NOT EXISTS " if o.if_not_exists
         
     | 
| 
      
 44 
     | 
    
         
            +
                        create_sql << "#{quote_table_name(o.name)} "
         
     | 
| 
       46 
45 
     | 
    
         | 
| 
       47 
46 
     | 
    
         
             
                        statements = o.columns.map { |c| accept c }
         
     | 
| 
       48 
47 
     | 
    
         
             
                        statements << accept(o.primary_keys) if o.primary_keys
         
     | 
| 
         @@ -51,7 +50,7 @@ module ActiveRecord 
     | 
|
| 
       51 
50 
     | 
    
         
             
                          statements.concat(o.indexes.map { |column_name, options| index_in_create(o.name, column_name, options) })
         
     | 
| 
       52 
51 
     | 
    
         
             
                        end
         
     | 
| 
       53 
52 
     | 
    
         | 
| 
       54 
     | 
    
         
            -
                        if  
     | 
| 
      
 53 
     | 
    
         
            +
                        if supports_foreign_keys?
         
     | 
| 
       55 
54 
     | 
    
         
             
                          statements.concat(o.foreign_keys.map { |to_table, options| foreign_key_in_create(o.name, to_table, options) })
         
     | 
| 
       56 
55 
     | 
    
         
             
                        end
         
     | 
| 
       57 
56 
     | 
    
         | 
| 
         @@ -66,7 +65,7 @@ module ActiveRecord 
     | 
|
| 
       66 
65 
     | 
    
         
             
                      end
         
     | 
| 
       67 
66 
     | 
    
         | 
| 
       68 
67 
     | 
    
         
             
                      def visit_ForeignKeyDefinition(o)
         
     | 
| 
       69 
     | 
    
         
            -
                        sql =  
     | 
| 
      
 68 
     | 
    
         
            +
                        sql = +<<~SQL
         
     | 
| 
       70 
69 
     | 
    
         
             
                          CONSTRAINT #{quote_column_name(o.name)}
         
     | 
| 
       71 
70 
     | 
    
         
             
                          FOREIGN KEY (#{quote_column_name(o.column)})
         
     | 
| 
       72 
71 
     | 
    
         
             
                            REFERENCES #{quote_table_name(o.to_table)} (#{quote_column_name(o.primary_key)})
         
     | 
| 
         @@ -122,7 +121,15 @@ module ActiveRecord 
     | 
|
| 
       122 
121 
     | 
    
         
             
                        sql
         
     | 
| 
       123 
122 
     | 
    
         
             
                      end
         
     | 
| 
       124 
123 
     | 
    
         | 
| 
      
 124 
     | 
    
         
            +
                      # Returns any SQL string to go between CREATE and TABLE. May be nil.
         
     | 
| 
      
 125 
     | 
    
         
            +
                      def table_modifier_in_create(o)
         
     | 
| 
      
 126 
     | 
    
         
            +
                        " TEMPORARY" if o.temporary
         
     | 
| 
      
 127 
     | 
    
         
            +
                      end
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
       125 
129 
     | 
    
         
             
                      def foreign_key_in_create(from_table, to_table, options)
         
     | 
| 
      
 130 
     | 
    
         
            +
                        prefix = ActiveRecord::Base.table_name_prefix
         
     | 
| 
      
 131 
     | 
    
         
            +
                        suffix = ActiveRecord::Base.table_name_suffix
         
     | 
| 
      
 132 
     | 
    
         
            +
                        to_table = "#{prefix}#{to_table}#{suffix}"
         
     | 
| 
       126 
133 
     | 
    
         
             
                        options = foreign_key_options(from_table, to_table, options)
         
     | 
| 
       127 
134 
     | 
    
         
             
                        accept ForeignKeyDefinition.new(from_table, to_table, options)
         
     | 
| 
       128 
135 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -133,7 +140,7 @@ module ActiveRecord 
     | 
|
| 
       133 
140 
     | 
    
         
             
                        when :cascade  then "ON #{action} CASCADE"
         
     | 
| 
       134 
141 
     | 
    
         
             
                        when :restrict then "ON #{action} RESTRICT"
         
     | 
| 
       135 
142 
     | 
    
         
             
                        else
         
     | 
| 
       136 
     | 
    
         
            -
                          raise ArgumentError,  
     | 
| 
      
 143 
     | 
    
         
            +
                          raise ArgumentError, <<~MSG
         
     | 
| 
       137 
144 
     | 
    
         
             
                            '#{dependency}' is not supported for :on_update or :on_delete.
         
     | 
| 
       138 
145 
     | 
    
         
             
                            Supported values are: :nullify, :cascade, :restrict
         
     | 
| 
       139 
146 
     | 
    
         
             
                          MSG
         
     | 
| 
         @@ -101,13 +101,13 @@ module ActiveRecord 
     | 
|
| 
       101 
101 
     | 
    
         
             
                  end
         
     | 
| 
       102 
102 
     | 
    
         
             
                  alias validated? validate?
         
     | 
| 
       103 
103 
     | 
    
         | 
| 
       104 
     | 
    
         
            -
                  def  
     | 
| 
       105 
     | 
    
         
            -
                    if  
     | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
       107 
     | 
    
         
            -
             
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
             
     | 
| 
       110 
     | 
    
         
            -
             
     | 
| 
      
 104 
     | 
    
         
            +
                  def export_name_on_schema_dump?
         
     | 
| 
      
 105 
     | 
    
         
            +
                    !ActiveRecord::SchemaDumper.fk_ignore_pattern.match?(name) if name
         
     | 
| 
      
 106 
     | 
    
         
            +
                  end
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                  def defined_for?(to_table: nil, **options)
         
     | 
| 
      
 109 
     | 
    
         
            +
                    (to_table.nil? || to_table.to_s == self.to_table) &&
         
     | 
| 
      
 110 
     | 
    
         
            +
                      options.all? { |k, v| self.options[k].to_s == v.to_s }
         
     | 
| 
       111 
111 
     | 
    
         
             
                  end
         
     | 
| 
       112 
112 
     | 
    
         | 
| 
       113 
113 
     | 
    
         
             
                  private
         
     | 
| 
         @@ -151,13 +151,8 @@ module ActiveRecord 
     | 
|
| 
       151 
151 
     | 
    
         
             
                    end
         
     | 
| 
       152 
152 
     | 
    
         
             
                  end
         
     | 
| 
       153 
153 
     | 
    
         | 
| 
       154 
     | 
    
         
            -
                  # TODO Change this to private once we've dropped Ruby 2.2 support.
         
     | 
| 
       155 
     | 
    
         
            -
                  # Workaround for Ruby 2.2 "private attribute?" warning.
         
     | 
| 
       156 
     | 
    
         
            -
                  protected
         
     | 
| 
       157 
     | 
    
         
            -
             
     | 
| 
       158 
     | 
    
         
            -
                    attr_reader :name, :polymorphic, :index, :foreign_key, :type, :options
         
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
       160 
154 
     | 
    
         
             
                  private
         
     | 
| 
      
 155 
     | 
    
         
            +
                    attr_reader :name, :polymorphic, :index, :foreign_key, :type, :options
         
     | 
| 
       161 
156 
     | 
    
         | 
| 
       162 
157 
     | 
    
         
             
                    def as_options(value)
         
     | 
| 
       163 
158 
     | 
    
         
             
                      value.is_a?(Hash) ? value : {}
         
     | 
| 
         @@ -199,41 +194,44 @@ module ActiveRecord 
     | 
|
| 
       199 
194 
     | 
    
         
             
                end
         
     | 
| 
       200 
195 
     | 
    
         | 
| 
       201 
196 
     | 
    
         
             
                module ColumnMethods
         
     | 
| 
      
 197 
     | 
    
         
            +
                  extend ActiveSupport::Concern
         
     | 
| 
      
 198 
     | 
    
         
            +
             
     | 
| 
       202 
199 
     | 
    
         
             
                  # Appends a primary key definition to the table definition.
         
     | 
| 
       203 
200 
     | 
    
         
             
                  # Can be called multiple times, but this is probably not a good idea.
         
     | 
| 
       204 
201 
     | 
    
         
             
                  def primary_key(name, type = :primary_key, **options)
         
     | 
| 
       205 
202 
     | 
    
         
             
                    column(name, type, options.merge(primary_key: true))
         
     | 
| 
       206 
203 
     | 
    
         
             
                  end
         
     | 
| 
       207 
204 
     | 
    
         | 
| 
      
 205 
     | 
    
         
            +
                  ##
         
     | 
| 
      
 206 
     | 
    
         
            +
                  # :method: column
         
     | 
| 
      
 207 
     | 
    
         
            +
                  # :call-seq: column(name, type, **options)
         
     | 
| 
      
 208 
     | 
    
         
            +
                  #
         
     | 
| 
       208 
209 
     | 
    
         
             
                  # Appends a column or columns of a specified type.
         
     | 
| 
       209 
210 
     | 
    
         
             
                  #
         
     | 
| 
       210 
211 
     | 
    
         
             
                  #  t.string(:goat)
         
     | 
| 
       211 
212 
     | 
    
         
             
                  #  t.string(:goat, :sheep)
         
     | 
| 
       212 
213 
     | 
    
         
             
                  #
         
     | 
| 
       213 
214 
     | 
    
         
             
                  # See TableDefinition#column
         
     | 
| 
       214 
     | 
    
         
            -
             
     | 
| 
       215 
     | 
    
         
            -
             
     | 
| 
       216 
     | 
    
         
            -
                    :binary,
         
     | 
| 
       217 
     | 
    
         
            -
             
     | 
| 
       218 
     | 
    
         
            -
             
     | 
| 
       219 
     | 
    
         
            -
                    : 
     | 
| 
       220 
     | 
    
         
            -
             
     | 
| 
       221 
     | 
    
         
            -
             
     | 
| 
       222 
     | 
    
         
            -
             
     | 
| 
       223 
     | 
    
         
            -
                    : 
     | 
| 
       224 
     | 
    
         
            -
             
     | 
| 
       225 
     | 
    
         
            -
             
     | 
| 
       226 
     | 
    
         
            -
             
     | 
| 
       227 
     | 
    
         
            -
             
     | 
| 
       228 
     | 
    
         
            -
             
     | 
| 
       229 
     | 
    
         
            -
             
     | 
| 
       230 
     | 
    
         
            -
             
     | 
| 
       231 
     | 
    
         
            -
                      def #{column_type}(*args, **options)
         
     | 
| 
       232 
     | 
    
         
            -
                        args.each { |name| column(name, :#{column_type}, options) }
         
     | 
| 
      
 215 
     | 
    
         
            +
             
     | 
| 
      
 216 
     | 
    
         
            +
                  included do
         
     | 
| 
      
 217 
     | 
    
         
            +
                    define_column_methods :bigint, :binary, :boolean, :date, :datetime, :decimal,
         
     | 
| 
      
 218 
     | 
    
         
            +
                      :float, :integer, :json, :string, :text, :time, :timestamp, :virtual
         
     | 
| 
      
 219 
     | 
    
         
            +
             
     | 
| 
      
 220 
     | 
    
         
            +
                    alias :numeric :decimal
         
     | 
| 
      
 221 
     | 
    
         
            +
                  end
         
     | 
| 
      
 222 
     | 
    
         
            +
             
     | 
| 
      
 223 
     | 
    
         
            +
                  class_methods do
         
     | 
| 
      
 224 
     | 
    
         
            +
                    private def define_column_methods(*column_types) # :nodoc:
         
     | 
| 
      
 225 
     | 
    
         
            +
                      column_types.each do |column_type|
         
     | 
| 
      
 226 
     | 
    
         
            +
                        module_eval <<-RUBY, __FILE__, __LINE__ + 1
         
     | 
| 
      
 227 
     | 
    
         
            +
                          def #{column_type}(*names, **options)
         
     | 
| 
      
 228 
     | 
    
         
            +
                            raise ArgumentError, "Missing column name(s) for #{column_type}" if names.empty?
         
     | 
| 
      
 229 
     | 
    
         
            +
                            names.each { |name| column(name, :#{column_type}, options) }
         
     | 
| 
      
 230 
     | 
    
         
            +
                          end
         
     | 
| 
      
 231 
     | 
    
         
            +
                        RUBY
         
     | 
| 
       233 
232 
     | 
    
         
             
                      end
         
     | 
| 
       234 
     | 
    
         
            -
                     
     | 
| 
      
 233 
     | 
    
         
            +
                    end
         
     | 
| 
       235 
234 
     | 
    
         
             
                  end
         
     | 
| 
       236 
     | 
    
         
            -
                  alias_method :numeric, :decimal
         
     | 
| 
       237 
235 
     | 
    
         
             
                end
         
     | 
| 
       238 
236 
     | 
    
         | 
| 
       239 
237 
     | 
    
         
             
                # Represents the schema of an SQL table in an abstract way. This class
         
     | 
| 
         @@ -257,15 +255,25 @@ module ActiveRecord 
     | 
|
| 
       257 
255 
     | 
    
         
             
                class TableDefinition
         
     | 
| 
       258 
256 
     | 
    
         
             
                  include ColumnMethods
         
     | 
| 
       259 
257 
     | 
    
         | 
| 
       260 
     | 
    
         
            -
                   
     | 
| 
       261 
     | 
    
         
            -
                  attr_reader :name, :temporary, :options, :as, :foreign_keys, :comment
         
     | 
| 
      
 258 
     | 
    
         
            +
                  attr_reader :name, :temporary, :if_not_exists, :options, :as, :comment, :indexes, :foreign_keys
         
     | 
| 
       262 
259 
     | 
    
         | 
| 
       263 
     | 
    
         
            -
                  def initialize( 
     | 
| 
      
 260 
     | 
    
         
            +
                  def initialize(
         
     | 
| 
      
 261 
     | 
    
         
            +
                    conn,
         
     | 
| 
      
 262 
     | 
    
         
            +
                    name,
         
     | 
| 
      
 263 
     | 
    
         
            +
                    temporary: false,
         
     | 
| 
      
 264 
     | 
    
         
            +
                    if_not_exists: false,
         
     | 
| 
      
 265 
     | 
    
         
            +
                    options: nil,
         
     | 
| 
      
 266 
     | 
    
         
            +
                    as: nil,
         
     | 
| 
      
 267 
     | 
    
         
            +
                    comment: nil,
         
     | 
| 
      
 268 
     | 
    
         
            +
                    **
         
     | 
| 
      
 269 
     | 
    
         
            +
                  )
         
     | 
| 
      
 270 
     | 
    
         
            +
                    @conn = conn
         
     | 
| 
       264 
271 
     | 
    
         
             
                    @columns_hash = {}
         
     | 
| 
       265 
272 
     | 
    
         
             
                    @indexes = []
         
     | 
| 
       266 
273 
     | 
    
         
             
                    @foreign_keys = []
         
     | 
| 
       267 
274 
     | 
    
         
             
                    @primary_keys = nil
         
     | 
| 
       268 
275 
     | 
    
         
             
                    @temporary = temporary
         
     | 
| 
      
 276 
     | 
    
         
            +
                    @if_not_exists = if_not_exists
         
     | 
| 
       269 
277 
     | 
    
         
             
                    @options = options
         
     | 
| 
       270 
278 
     | 
    
         
             
                    @as = as
         
     | 
| 
       271 
279 
     | 
    
         
             
                    @name = name
         
     | 
| 
         @@ -349,16 +357,20 @@ module ActiveRecord 
     | 
|
| 
       349 
357 
     | 
    
         
             
                  #
         
     | 
| 
       350 
358 
     | 
    
         
             
                  #   create_table :taggings do |t|
         
     | 
| 
       351 
359 
     | 
    
         
             
                  #     t.references :tag, index: { name: 'index_taggings_on_tag_id' }
         
     | 
| 
       352 
     | 
    
         
            -
                  #     t.references :tagger, polymorphic: true 
     | 
| 
       353 
     | 
    
         
            -
                  #     t.references :taggable, polymorphic: { default: 'Photo' }
         
     | 
| 
      
 360 
     | 
    
         
            +
                  #     t.references :tagger, polymorphic: true
         
     | 
| 
      
 361 
     | 
    
         
            +
                  #     t.references :taggable, polymorphic: { default: 'Photo' }, index: false
         
     | 
| 
       354 
362 
     | 
    
         
             
                  #   end
         
     | 
| 
       355 
     | 
    
         
            -
                  def column(name, type, options 
     | 
| 
      
 363 
     | 
    
         
            +
                  def column(name, type, **options)
         
     | 
| 
       356 
364 
     | 
    
         
             
                    name = name.to_s
         
     | 
| 
       357 
365 
     | 
    
         
             
                    type = type.to_sym if type
         
     | 
| 
       358 
366 
     | 
    
         
             
                    options = options.dup
         
     | 
| 
       359 
367 
     | 
    
         | 
| 
       360 
     | 
    
         
            -
                    if @columns_hash[name] 
     | 
| 
       361 
     | 
    
         
            -
                       
     | 
| 
      
 368 
     | 
    
         
            +
                    if @columns_hash[name]
         
     | 
| 
      
 369 
     | 
    
         
            +
                      if @columns_hash[name].primary_key?
         
     | 
| 
      
 370 
     | 
    
         
            +
                        raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table."
         
     | 
| 
      
 371 
     | 
    
         
            +
                      else
         
     | 
| 
      
 372 
     | 
    
         
            +
                        raise ArgumentError, "you can't define an already defined column '#{name}'."
         
     | 
| 
      
 373 
     | 
    
         
            +
                      end
         
     | 
| 
       362 
374 
     | 
    
         
             
                    end
         
     | 
| 
       363 
375 
     | 
    
         | 
| 
       364 
376 
     | 
    
         
             
                    index_options = options.delete(:index)
         
     | 
| 
         @@ -382,10 +394,7 @@ module ActiveRecord 
     | 
|
| 
       382 
394 
     | 
    
         
             
                  end
         
     | 
| 
       383 
395 
     | 
    
         | 
| 
       384 
396 
     | 
    
         
             
                  def foreign_key(table_name, options = {}) # :nodoc:
         
     | 
| 
       385 
     | 
    
         
            -
                     
     | 
| 
       386 
     | 
    
         
            -
                    table_name_suffix = ActiveRecord::Base.table_name_suffix
         
     | 
| 
       387 
     | 
    
         
            -
                    table_name = "#{table_name_prefix}#{table_name}#{table_name_suffix}"
         
     | 
| 
       388 
     | 
    
         
            -
                    foreign_keys.push([table_name, options])
         
     | 
| 
      
 397 
     | 
    
         
            +
                    foreign_keys << [table_name, options]
         
     | 
| 
       389 
398 
     | 
    
         
             
                  end
         
     | 
| 
       390 
399 
     | 
    
         | 
| 
       391 
400 
     | 
    
         
             
                  # Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
         
     | 
| 
         @@ -395,6 +404,10 @@ module ActiveRecord 
     | 
|
| 
       395 
404 
     | 
    
         
             
                  def timestamps(**options)
         
     | 
| 
       396 
405 
     | 
    
         
             
                    options[:null] = false if options[:null].nil?
         
     | 
| 
       397 
406 
     | 
    
         | 
| 
      
 407 
     | 
    
         
            +
                    if !options.key?(:precision) && @conn.supports_datetime_with_precision?
         
     | 
| 
      
 408 
     | 
    
         
            +
                      options[:precision] = 6
         
     | 
| 
      
 409 
     | 
    
         
            +
                    end
         
     | 
| 
      
 410 
     | 
    
         
            +
             
     | 
| 
       398 
411 
     | 
    
         
             
                    column(:created_at, :datetime, options)
         
     | 
| 
       399 
412 
     | 
    
         
             
                    column(:updated_at, :datetime, options)
         
     | 
| 
       400 
413 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -403,6 +416,7 @@ module ActiveRecord 
     | 
|
| 
       403 
416 
     | 
    
         
             
                  #
         
     | 
| 
       404 
417 
     | 
    
         
             
                  #  t.references(:user)
         
     | 
| 
       405 
418 
     | 
    
         
             
                  #  t.belongs_to(:supplier, foreign_key: true)
         
     | 
| 
      
 419 
     | 
    
         
            +
                  #  t.belongs_to(:supplier, foreign_key: true, type: :integer)
         
     | 
| 
       406 
420 
     | 
    
         
             
                  #
         
     | 
| 
       407 
421 
     | 
    
         
             
                  # See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
         
     | 
| 
       408 
422 
     | 
    
         
             
                  def references(*args, **options)
         
     | 
| 
         @@ -502,6 +516,7 @@ module ActiveRecord 
     | 
|
| 
       502 
516 
     | 
    
         
             
                #     t.json
         
     | 
| 
       503 
517 
     | 
    
         
             
                #     t.virtual
         
     | 
| 
       504 
518 
     | 
    
         
             
                #     t.remove
         
     | 
| 
      
 519 
     | 
    
         
            +
                #     t.remove_foreign_key
         
     | 
| 
       505 
520 
     | 
    
         
             
                #     t.remove_references
         
     | 
| 
       506 
521 
     | 
    
         
             
                #     t.remove_belongs_to
         
     | 
| 
       507 
522 
     | 
    
         
             
                #     t.remove_index
         
     | 
| 
         @@ -523,8 +538,10 @@ module ActiveRecord 
     | 
|
| 
       523 
538 
     | 
    
         
             
                  #  t.column(:name, :string)
         
     | 
| 
       524 
539 
     | 
    
         
             
                  #
         
     | 
| 
       525 
540 
     | 
    
         
             
                  # See TableDefinition#column for details of the options you can use.
         
     | 
| 
       526 
     | 
    
         
            -
                  def column(column_name, type, options 
     | 
| 
      
 541 
     | 
    
         
            +
                  def column(column_name, type, **options)
         
     | 
| 
      
 542 
     | 
    
         
            +
                    index_options = options.delete(:index)
         
     | 
| 
       527 
543 
     | 
    
         
             
                    @base.add_column(name, column_name, type, options)
         
     | 
| 
      
 544 
     | 
    
         
            +
                    index(column_name, index_options.is_a?(Hash) ? index_options : {}) if index_options
         
     | 
| 
       528 
545 
     | 
    
         
             
                  end
         
     | 
| 
       529 
546 
     | 
    
         | 
| 
       530 
547 
     | 
    
         
             
                  # Checks to see if a column exists.
         
     | 
| 
         @@ -663,15 +680,26 @@ module ActiveRecord 
     | 
|
| 
       663 
680 
     | 
    
         
             
                  end
         
     | 
| 
       664 
681 
     | 
    
         
             
                  alias :remove_belongs_to :remove_references
         
     | 
| 
       665 
682 
     | 
    
         | 
| 
       666 
     | 
    
         
            -
                  # Adds a foreign key.
         
     | 
| 
      
 683 
     | 
    
         
            +
                  # Adds a foreign key to the table using a supplied table name.
         
     | 
| 
       667 
684 
     | 
    
         
             
                  #
         
     | 
| 
       668 
685 
     | 
    
         
             
                  #  t.foreign_key(:authors)
         
     | 
| 
      
 686 
     | 
    
         
            +
                  #  t.foreign_key(:authors, column: :author_id, primary_key: "id")
         
     | 
| 
       669 
687 
     | 
    
         
             
                  #
         
     | 
| 
       670 
688 
     | 
    
         
             
                  # See {connection.add_foreign_key}[rdoc-ref:SchemaStatements#add_foreign_key]
         
     | 
| 
       671 
689 
     | 
    
         
             
                  def foreign_key(*args)
         
     | 
| 
       672 
690 
     | 
    
         
             
                    @base.add_foreign_key(name, *args)
         
     | 
| 
       673 
691 
     | 
    
         
             
                  end
         
     | 
| 
       674 
692 
     | 
    
         | 
| 
      
 693 
     | 
    
         
            +
                  # Removes the given foreign key from the table.
         
     | 
| 
      
 694 
     | 
    
         
            +
                  #
         
     | 
| 
      
 695 
     | 
    
         
            +
                  #  t.remove_foreign_key(:authors)
         
     | 
| 
      
 696 
     | 
    
         
            +
                  #  t.remove_foreign_key(column: :author_id)
         
     | 
| 
      
 697 
     | 
    
         
            +
                  #
         
     | 
| 
      
 698 
     | 
    
         
            +
                  # See {connection.remove_foreign_key}[rdoc-ref:SchemaStatements#remove_foreign_key]
         
     | 
| 
      
 699 
     | 
    
         
            +
                  def remove_foreign_key(*args)
         
     | 
| 
      
 700 
     | 
    
         
            +
                    @base.remove_foreign_key(name, *args)
         
     | 
| 
      
 701 
     | 
    
         
            +
                  end
         
     | 
| 
      
 702 
     | 
    
         
            +
             
     | 
| 
       675 
703 
     | 
    
         
             
                  # Checks to see if a foreign key exists.
         
     | 
| 
       676 
704 
     | 
    
         
             
                  #
         
     | 
| 
       677 
705 
     | 
    
         
             
                  #  t.foreign_key(:authors) unless t.foreign_key_exists?(:authors)
         
     | 
| 
         @@ -1,7 +1,5 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            require "active_support/core_ext/hash/compact"
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
3 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       6 
4 
     | 
    
         
             
              module ConnectionAdapters # :nodoc:
         
     | 
| 
       7 
5 
     | 
    
         
             
                class SchemaDumper < SchemaDumper # :nodoc:
         
     | 
| 
         @@ -17,7 +15,7 @@ module ActiveRecord 
     | 
|
| 
       17 
15 
     | 
    
         
             
                    def column_spec_for_primary_key(column)
         
     | 
| 
       18 
16 
     | 
    
         
             
                      return {} if default_primary_key?(column)
         
     | 
| 
       19 
17 
     | 
    
         
             
                      spec = { id: schema_type(column).inspect }
         
     | 
| 
       20 
     | 
    
         
            -
                      spec.merge!(prepare_column_options(column).except!(:null))
         
     | 
| 
      
 18 
     | 
    
         
            +
                      spec.merge!(prepare_column_options(column).except!(:null, :comment))
         
     | 
| 
       21 
19 
     | 
    
         
             
                      spec[:default] ||= "nil" if explicit_primary_key_default?(column)
         
     | 
| 
       22 
20 
     | 
    
         
             
                      spec
         
     | 
| 
       23 
21 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -2,6 +2,7 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            require "active_record/migration/join_table"
         
     | 
| 
       4 
4 
     | 
    
         
             
            require "active_support/core_ext/string/access"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "active_support/deprecation"
         
     | 
| 
       5 
6 
     | 
    
         
             
            require "digest/sha2"
         
     | 
| 
       6 
7 
     | 
    
         | 
| 
       7 
8 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
         @@ -129,11 +130,11 @@ module ActiveRecord 
     | 
|
| 
       129 
130 
     | 
    
         
             
                  #   column_exists?(:suppliers, :name, :string, null: false)
         
     | 
| 
       130 
131 
     | 
    
         
             
                  #   column_exists?(:suppliers, :tax, :decimal, precision: 8, scale: 2)
         
     | 
| 
       131 
132 
     | 
    
         
             
                  #
         
     | 
| 
       132 
     | 
    
         
            -
                  def column_exists?(table_name, column_name, type = nil, options 
     | 
| 
      
 133 
     | 
    
         
            +
                  def column_exists?(table_name, column_name, type = nil, **options)
         
     | 
| 
       133 
134 
     | 
    
         
             
                    column_name = column_name.to_s
         
     | 
| 
       134 
135 
     | 
    
         
             
                    checks = []
         
     | 
| 
       135 
136 
     | 
    
         
             
                    checks << lambda { |c| c.name == column_name }
         
     | 
| 
       136 
     | 
    
         
            -
                    checks << lambda { |c| c.type == type } if type
         
     | 
| 
      
 137 
     | 
    
         
            +
                    checks << lambda { |c| c.type == type.to_sym rescue nil } if type
         
     | 
| 
       137 
138 
     | 
    
         
             
                    column_options_keys.each do |attr|
         
     | 
| 
       138 
139 
     | 
    
         
             
                      checks << lambda { |c| c.send(attr) == options[attr] } if options.key?(attr)
         
     | 
| 
       139 
140 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -205,19 +206,22 @@ module ActiveRecord 
     | 
|
| 
       205 
206 
     | 
    
         
             
                  #   Set to true to drop the table before creating it.
         
     | 
| 
       206 
207 
     | 
    
         
             
                  #   Set to +:cascade+ to drop dependent objects as well.
         
     | 
| 
       207 
208 
     | 
    
         
             
                  #   Defaults to false.
         
     | 
| 
      
 209 
     | 
    
         
            +
                  # [<tt>:if_not_exists</tt>]
         
     | 
| 
      
 210 
     | 
    
         
            +
                  #   Set to true to avoid raising an error when the table already exists.
         
     | 
| 
      
 211 
     | 
    
         
            +
                  #   Defaults to false.
         
     | 
| 
       208 
212 
     | 
    
         
             
                  # [<tt>:as</tt>]
         
     | 
| 
       209 
213 
     | 
    
         
             
                  #   SQL to use to generate the table. When this option is used, the block is
         
     | 
| 
       210 
214 
     | 
    
         
             
                  #   ignored, as are the <tt>:id</tt> and <tt>:primary_key</tt> options.
         
     | 
| 
       211 
215 
     | 
    
         
             
                  #
         
     | 
| 
       212 
216 
     | 
    
         
             
                  # ====== Add a backend specific option to the generated SQL (MySQL)
         
     | 
| 
       213 
217 
     | 
    
         
             
                  #
         
     | 
| 
       214 
     | 
    
         
            -
                  #   create_table(:suppliers, options: 'ENGINE=InnoDB DEFAULT CHARSET= 
     | 
| 
      
 218 
     | 
    
         
            +
                  #   create_table(:suppliers, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8mb4')
         
     | 
| 
       215 
219 
     | 
    
         
             
                  #
         
     | 
| 
       216 
220 
     | 
    
         
             
                  # generates:
         
     | 
| 
       217 
221 
     | 
    
         
             
                  #
         
     | 
| 
       218 
222 
     | 
    
         
             
                  #   CREATE TABLE suppliers (
         
     | 
| 
       219 
223 
     | 
    
         
             
                  #     id bigint auto_increment PRIMARY KEY
         
     | 
| 
       220 
     | 
    
         
            -
                  #   ) ENGINE=InnoDB DEFAULT CHARSET= 
     | 
| 
      
 224 
     | 
    
         
            +
                  #   ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
         
     | 
| 
       221 
225 
     | 
    
         
             
                  #
         
     | 
| 
       222 
226 
     | 
    
         
             
                  # ====== Rename the primary key column
         
     | 
| 
       223 
227 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -287,8 +291,8 @@ module ActiveRecord 
     | 
|
| 
       287 
291 
     | 
    
         
             
                  #     SELECT * FROM orders INNER JOIN line_items ON order_id=orders.id
         
     | 
| 
       288 
292 
     | 
    
         
             
                  #
         
     | 
| 
       289 
293 
     | 
    
         
             
                  # See also TableDefinition#column for details on how to create columns.
         
     | 
| 
       290 
     | 
    
         
            -
                  def create_table(table_name,  
     | 
| 
       291 
     | 
    
         
            -
                    td = create_table_definition 
     | 
| 
      
 294 
     | 
    
         
            +
                  def create_table(table_name, **options)
         
     | 
| 
      
 295 
     | 
    
         
            +
                    td = create_table_definition(table_name, options)
         
     | 
| 
       292 
296 
     | 
    
         | 
| 
       293 
297 
     | 
    
         
             
                    if options[:id] != false && !options[:as]
         
     | 
| 
       294 
298 
     | 
    
         
             
                      pk = options.fetch(:primary_key) do
         
     | 
| 
         @@ -298,7 +302,7 @@ module ActiveRecord 
     | 
|
| 
       298 
302 
     | 
    
         
             
                      if pk.is_a?(Array)
         
     | 
| 
       299 
303 
     | 
    
         
             
                        td.primary_keys pk
         
     | 
| 
       300 
304 
     | 
    
         
             
                      else
         
     | 
| 
       301 
     | 
    
         
            -
                        td.primary_key pk, options.fetch(:id, :primary_key), options
         
     | 
| 
      
 305 
     | 
    
         
            +
                        td.primary_key pk, options.fetch(:id, :primary_key), options.except(:comment)
         
     | 
| 
       302 
306 
     | 
    
         
             
                      end
         
     | 
| 
       303 
307 
     | 
    
         
             
                    end
         
     | 
| 
       304 
308 
     | 
    
         | 
| 
         @@ -317,7 +321,9 @@ module ActiveRecord 
     | 
|
| 
       317 
321 
     | 
    
         
             
                    end
         
     | 
| 
       318 
322 
     | 
    
         | 
| 
       319 
323 
     | 
    
         
             
                    if supports_comments? && !supports_comments_in_create?
         
     | 
| 
       320 
     | 
    
         
            -
                       
     | 
| 
      
 324 
     | 
    
         
            +
                      if table_comment = options[:comment].presence
         
     | 
| 
      
 325 
     | 
    
         
            +
                        change_table_comment(table_name, table_comment)
         
     | 
| 
      
 326 
     | 
    
         
            +
                      end
         
     | 
| 
       321 
327 
     | 
    
         | 
| 
       322 
328 
     | 
    
         
             
                      td.columns.each do |column|
         
     | 
| 
       323 
329 
     | 
    
         
             
                        change_column_comment(table_name, column.name, column.comment) if column.comment.present?
         
     | 
| 
         @@ -512,16 +518,20 @@ module ActiveRecord 
     | 
|
| 
       512 
518 
     | 
    
         
             
                  # Available options are (none of these exists by default):
         
     | 
| 
       513 
519 
     | 
    
         
             
                  # * <tt>:limit</tt> -
         
     | 
| 
       514 
520 
     | 
    
         
             
                  #   Requests a maximum column length. This is the number of characters for a <tt>:string</tt> column
         
     | 
| 
       515 
     | 
    
         
            -
                  #   and number of bytes for <tt>:text</tt>, <tt>:binary</tt 
     | 
| 
      
 521 
     | 
    
         
            +
                  #   and number of bytes for <tt>:text</tt>, <tt>:binary</tt>, and <tt>:integer</tt> columns.
         
     | 
| 
       516 
522 
     | 
    
         
             
                  #   This option is ignored by some backends.
         
     | 
| 
       517 
523 
     | 
    
         
             
                  # * <tt>:default</tt> -
         
     | 
| 
       518 
524 
     | 
    
         
             
                  #   The column's default value. Use +nil+ for +NULL+.
         
     | 
| 
       519 
525 
     | 
    
         
             
                  # * <tt>:null</tt> -
         
     | 
| 
       520 
526 
     | 
    
         
             
                  #   Allows or disallows +NULL+ values in the column.
         
     | 
| 
       521 
527 
     | 
    
         
             
                  # * <tt>:precision</tt> -
         
     | 
| 
       522 
     | 
    
         
            -
                  #   Specifies the precision for the <tt>:decimal</tt 
     | 
| 
      
 528 
     | 
    
         
            +
                  #   Specifies the precision for the <tt>:decimal</tt>, <tt>:numeric</tt>,
         
     | 
| 
      
 529 
     | 
    
         
            +
                  #   <tt>:datetime</tt>, and <tt>:time</tt> columns.
         
     | 
| 
       523 
530 
     | 
    
         
             
                  # * <tt>:scale</tt> -
         
     | 
| 
       524 
531 
     | 
    
         
             
                  #   Specifies the scale for the <tt>:decimal</tt> and <tt>:numeric</tt> columns.
         
     | 
| 
      
 532 
     | 
    
         
            +
                  # * <tt>:collation</tt> -
         
     | 
| 
      
 533 
     | 
    
         
            +
                  #   Specifies the collation for a <tt>:string</tt> or <tt>:text</tt> column. If not specified, the
         
     | 
| 
      
 534 
     | 
    
         
            +
                  #   column will have the same collation as the table.
         
     | 
| 
       525 
535 
     | 
    
         
             
                  # * <tt>:comment</tt> -
         
     | 
| 
       526 
536 
     | 
    
         
             
                  #   Specifies the comment for the column. This option is ignored by some backends.
         
     | 
| 
       527 
537 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -575,7 +585,7 @@ module ActiveRecord 
     | 
|
| 
       575 
585 
     | 
    
         
             
                  #  # Defines a column with a database-specific type.
         
     | 
| 
       576 
586 
     | 
    
         
             
                  #  add_column(:shapes, :triangle, 'polygon')
         
     | 
| 
       577 
587 
     | 
    
         
             
                  #  # ALTER TABLE "shapes" ADD "triangle" polygon
         
     | 
| 
       578 
     | 
    
         
            -
                  def add_column(table_name, column_name, type, options 
     | 
| 
      
 588 
     | 
    
         
            +
                  def add_column(table_name, column_name, type, **options)
         
     | 
| 
       579 
589 
     | 
    
         
             
                    at = create_alter_table table_name
         
     | 
| 
       580 
590 
     | 
    
         
             
                    at.add_column(column_name, type, options)
         
     | 
| 
       581 
591 
     | 
    
         
             
                    execute schema_creation.accept at
         
     | 
| 
         @@ -599,6 +609,7 @@ module ActiveRecord 
     | 
|
| 
       599 
609 
     | 
    
         
             
                  # The +type+ and +options+ parameters will be ignored if present. It can be helpful
         
     | 
| 
       600 
610 
     | 
    
         
             
                  # to provide these in a migration's +change+ method so it can be reverted.
         
     | 
| 
       601 
611 
     | 
    
         
             
                  # In that case, +type+ and +options+ will be used by #add_column.
         
     | 
| 
      
 612 
     | 
    
         
            +
                  # Indexes on the column are automatically removed.
         
     | 
| 
       602 
613 
     | 
    
         
             
                  def remove_column(table_name, column_name, type = nil, options = {})
         
     | 
| 
       603 
614 
     | 
    
         
             
                    execute "ALTER TABLE #{quote_table_name(table_name)} #{remove_column_for_alter(table_name, column_name, type, options)}"
         
     | 
| 
       604 
615 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -760,6 +771,17 @@ module ActiveRecord 
     | 
|
| 
       760 
771 
     | 
    
         
             
                  #   CREATE FULLTEXT INDEX index_developers_on_name ON developers (name) -- MySQL
         
     | 
| 
       761 
772 
     | 
    
         
             
                  #
         
     | 
| 
       762 
773 
     | 
    
         
             
                  # Note: only supported by MySQL.
         
     | 
| 
      
 774 
     | 
    
         
            +
                  #
         
     | 
| 
      
 775 
     | 
    
         
            +
                  # ====== Creating an index with a specific algorithm
         
     | 
| 
      
 776 
     | 
    
         
            +
                  #
         
     | 
| 
      
 777 
     | 
    
         
            +
                  #  add_index(:developers, :name, algorithm: :concurrently)
         
     | 
| 
      
 778 
     | 
    
         
            +
                  #  # CREATE INDEX CONCURRENTLY developers_on_name on developers (name)
         
     | 
| 
      
 779 
     | 
    
         
            +
                  #
         
     | 
| 
      
 780 
     | 
    
         
            +
                  # Note: only supported by PostgreSQL.
         
     | 
| 
      
 781 
     | 
    
         
            +
                  #
         
     | 
| 
      
 782 
     | 
    
         
            +
                  # Concurrently adding an index is not supported in a transaction.
         
     | 
| 
      
 783 
     | 
    
         
            +
                  #
         
     | 
| 
      
 784 
     | 
    
         
            +
                  # For more information see the {"Transactional Migrations" section}[rdoc-ref:Migration].
         
     | 
| 
       763 
785 
     | 
    
         
             
                  def add_index(table_name, column_name, options = {})
         
     | 
| 
       764 
786 
     | 
    
         
             
                    index_name, index_type, index_columns, index_options = add_index_options(table_name, column_name, options)
         
     | 
| 
       765 
787 
     | 
    
         
             
                    execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{index_columns})#{index_options}"
         
     | 
| 
         @@ -783,6 +805,15 @@ module ActiveRecord 
     | 
|
| 
       783 
805 
     | 
    
         
             
                  #
         
     | 
| 
       784 
806 
     | 
    
         
             
                  #   remove_index :accounts, name: :by_branch_party
         
     | 
| 
       785 
807 
     | 
    
         
             
                  #
         
     | 
| 
      
 808 
     | 
    
         
            +
                  # Removes the index named +by_branch_party+ in the +accounts+ table +concurrently+.
         
     | 
| 
      
 809 
     | 
    
         
            +
                  #
         
     | 
| 
      
 810 
     | 
    
         
            +
                  #   remove_index :accounts, name: :by_branch_party, algorithm: :concurrently
         
     | 
| 
      
 811 
     | 
    
         
            +
                  #
         
     | 
| 
      
 812 
     | 
    
         
            +
                  # Note: only supported by PostgreSQL.
         
     | 
| 
      
 813 
     | 
    
         
            +
                  #
         
     | 
| 
      
 814 
     | 
    
         
            +
                  # Concurrently removing an index is not supported in a transaction.
         
     | 
| 
      
 815 
     | 
    
         
            +
                  #
         
     | 
| 
      
 816 
     | 
    
         
            +
                  # For more information see the {"Transactional Migrations" section}[rdoc-ref:Migration].
         
     | 
| 
       786 
817 
     | 
    
         
             
                  def remove_index(table_name, options = {})
         
     | 
| 
       787 
818 
     | 
    
         
             
                    index_name = index_name_for_remove(table_name, options)
         
     | 
| 
       788 
819 
     | 
    
         
             
                    execute "DROP INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)}"
         
     | 
| 
         @@ -842,17 +873,17 @@ module ActiveRecord 
     | 
|
| 
       842 
873 
     | 
    
         
             
                  # [<tt>:null</tt>]
         
     | 
| 
       843 
874 
     | 
    
         
             
                  #   Whether the column allows nulls. Defaults to true.
         
     | 
| 
       844 
875 
     | 
    
         
             
                  #
         
     | 
| 
       845 
     | 
    
         
            -
                  # ====== Create a user_id bigint column
         
     | 
| 
      
 876 
     | 
    
         
            +
                  # ====== Create a user_id bigint column without an index
         
     | 
| 
       846 
877 
     | 
    
         
             
                  #
         
     | 
| 
       847 
     | 
    
         
            -
                  #   add_reference(:products, :user)
         
     | 
| 
      
 878 
     | 
    
         
            +
                  #   add_reference(:products, :user, index: false)
         
     | 
| 
       848 
879 
     | 
    
         
             
                  #
         
     | 
| 
       849 
880 
     | 
    
         
             
                  # ====== Create a user_id string column
         
     | 
| 
       850 
881 
     | 
    
         
             
                  #
         
     | 
| 
       851 
882 
     | 
    
         
             
                  #   add_reference(:products, :user, type: :string)
         
     | 
| 
       852 
883 
     | 
    
         
             
                  #
         
     | 
| 
       853 
     | 
    
         
            -
                  # ====== Create supplier_id, supplier_type columns 
     | 
| 
      
 884 
     | 
    
         
            +
                  # ====== Create supplier_id, supplier_type columns
         
     | 
| 
       854 
885 
     | 
    
         
             
                  #
         
     | 
| 
       855 
     | 
    
         
            -
                  #   add_reference(:products, :supplier, polymorphic: true 
     | 
| 
      
 886 
     | 
    
         
            +
                  #   add_reference(:products, :supplier, polymorphic: true)
         
     | 
| 
       856 
887 
     | 
    
         
             
                  #
         
     | 
| 
       857 
888 
     | 
    
         
             
                  # ====== Create a supplier_id column with a unique index
         
     | 
| 
       858 
889 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -880,7 +911,7 @@ module ActiveRecord 
     | 
|
| 
       880 
911 
     | 
    
         
             
                  #
         
     | 
| 
       881 
912 
     | 
    
         
             
                  # ====== Remove the reference
         
     | 
| 
       882 
913 
     | 
    
         
             
                  #
         
     | 
| 
       883 
     | 
    
         
            -
                  #   remove_reference(:products, :user, index:  
     | 
| 
      
 914 
     | 
    
         
            +
                  #   remove_reference(:products, :user, index: false)
         
     | 
| 
       884 
915 
     | 
    
         
             
                  #
         
     | 
| 
       885 
916 
     | 
    
         
             
                  # ====== Remove polymorphic reference
         
     | 
| 
       886 
917 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -888,7 +919,7 @@ module ActiveRecord 
     | 
|
| 
       888 
919 
     | 
    
         
             
                  #
         
     | 
| 
       889 
920 
     | 
    
         
             
                  # ====== Remove the reference with a foreign key
         
     | 
| 
       890 
921 
     | 
    
         
             
                  #
         
     | 
| 
       891 
     | 
    
         
            -
                  #   remove_reference(:products, :user,  
     | 
| 
      
 922 
     | 
    
         
            +
                  #   remove_reference(:products, :user, foreign_key: true)
         
     | 
| 
       892 
923 
     | 
    
         
             
                  #
         
     | 
| 
       893 
924 
     | 
    
         
             
                  def remove_reference(table_name, ref_name, foreign_key: false, polymorphic: false, **options)
         
     | 
| 
       894 
925 
     | 
    
         
             
                    if foreign_key
         
     | 
| 
         @@ -956,7 +987,7 @@ module ActiveRecord 
     | 
|
| 
       956 
987 
     | 
    
         
             
                  # [<tt>:on_update</tt>]
         
     | 
| 
       957 
988 
     | 
    
         
             
                  #   Action that happens <tt>ON UPDATE</tt>. Valid values are +:nullify+, +:cascade+ and +:restrict+
         
     | 
| 
       958 
989 
     | 
    
         
             
                  # [<tt>:validate</tt>]
         
     | 
| 
       959 
     | 
    
         
            -
                  #   ( 
     | 
| 
      
 990 
     | 
    
         
            +
                  #   (PostgreSQL only) Specify whether or not the constraint should be validated. Defaults to +true+.
         
     | 
| 
       960 
991 
     | 
    
         
             
                  def add_foreign_key(from_table, to_table, options = {})
         
     | 
| 
       961 
992 
     | 
    
         
             
                    return unless supports_foreign_keys?
         
     | 
| 
       962 
993 
     | 
    
         | 
| 
         @@ -980,15 +1011,22 @@ module ActiveRecord 
     | 
|
| 
       980 
1011 
     | 
    
         
             
                  #
         
     | 
| 
       981 
1012 
     | 
    
         
             
                  #   remove_foreign_key :accounts, column: :owner_id
         
     | 
| 
       982 
1013 
     | 
    
         
             
                  #
         
     | 
| 
      
 1014 
     | 
    
         
            +
                  # Removes the foreign key on +accounts.owner_id+.
         
     | 
| 
      
 1015 
     | 
    
         
            +
                  #
         
     | 
| 
      
 1016 
     | 
    
         
            +
                  #   remove_foreign_key :accounts, to_table: :owners
         
     | 
| 
      
 1017 
     | 
    
         
            +
                  #
         
     | 
| 
       983 
1018 
     | 
    
         
             
                  # Removes the foreign key named +special_fk_name+ on the +accounts+ table.
         
     | 
| 
       984 
1019 
     | 
    
         
             
                  #
         
     | 
| 
       985 
1020 
     | 
    
         
             
                  #   remove_foreign_key :accounts, name: :special_fk_name
         
     | 
| 
       986 
1021 
     | 
    
         
             
                  #
         
     | 
| 
       987 
     | 
    
         
            -
                  # The +options+ hash accepts the same keys as SchemaStatements#add_foreign_key 
     | 
| 
       988 
     | 
    
         
            -
                   
     | 
| 
      
 1022 
     | 
    
         
            +
                  # The +options+ hash accepts the same keys as SchemaStatements#add_foreign_key
         
     | 
| 
      
 1023 
     | 
    
         
            +
                  # with an addition of
         
     | 
| 
      
 1024 
     | 
    
         
            +
                  # [<tt>:to_table</tt>]
         
     | 
| 
      
 1025 
     | 
    
         
            +
                  #   The name of the table that contains the referenced primary key.
         
     | 
| 
      
 1026 
     | 
    
         
            +
                  def remove_foreign_key(from_table, to_table = nil, **options)
         
     | 
| 
       989 
1027 
     | 
    
         
             
                    return unless supports_foreign_keys?
         
     | 
| 
       990 
1028 
     | 
    
         | 
| 
       991 
     | 
    
         
            -
                    fk_name_to_delete = foreign_key_for!(from_table,  
     | 
| 
      
 1029 
     | 
    
         
            +
                    fk_name_to_delete = foreign_key_for!(from_table, to_table: to_table, **options).name
         
     | 
| 
       992 
1030 
     | 
    
         | 
| 
       993 
1031 
     | 
    
         
             
                    at = create_alter_table from_table
         
     | 
| 
       994 
1032 
     | 
    
         
             
                    at.drop_foreign_key fk_name_to_delete
         
     | 
| 
         @@ -1007,14 +1045,12 @@ module ActiveRecord 
     | 
|
| 
       1007 
1045 
     | 
    
         
             
                  #   # Checks to see if a foreign key with a custom name exists.
         
     | 
| 
       1008 
1046 
     | 
    
         
             
                  #   foreign_key_exists?(:accounts, name: "special_fk_name")
         
     | 
| 
       1009 
1047 
     | 
    
         
             
                  #
         
     | 
| 
       1010 
     | 
    
         
            -
                  def foreign_key_exists?(from_table,  
     | 
| 
       1011 
     | 
    
         
            -
                    foreign_key_for(from_table,  
     | 
| 
      
 1048 
     | 
    
         
            +
                  def foreign_key_exists?(from_table, to_table = nil, **options)
         
     | 
| 
      
 1049 
     | 
    
         
            +
                    foreign_key_for(from_table, to_table: to_table, **options).present?
         
     | 
| 
       1012 
1050 
     | 
    
         
             
                  end
         
     | 
| 
       1013 
1051 
     | 
    
         | 
| 
       1014 
1052 
     | 
    
         
             
                  def foreign_key_column_for(table_name) # :nodoc:
         
     | 
| 
       1015 
     | 
    
         
            -
                     
     | 
| 
       1016 
     | 
    
         
            -
                    suffix = Base.table_name_suffix
         
     | 
| 
       1017 
     | 
    
         
            -
                    name = table_name.to_s =~ /#{prefix}(.+)#{suffix}/ ? $1 : table_name.to_s
         
     | 
| 
      
 1053 
     | 
    
         
            +
                    name = strip_table_name_prefix_and_suffix(table_name)
         
     | 
| 
       1018 
1054 
     | 
    
         
             
                    "#{name.singularize}_id"
         
     | 
| 
       1019 
1055 
     | 
    
         
             
                  end
         
     | 
| 
       1020 
1056 
     | 
    
         | 
| 
         @@ -1025,8 +1061,8 @@ module ActiveRecord 
     | 
|
| 
       1025 
1061 
     | 
    
         
             
                    options
         
     | 
| 
       1026 
1062 
     | 
    
         
             
                  end
         
     | 
| 
       1027 
1063 
     | 
    
         | 
| 
       1028 
     | 
    
         
            -
                  def dump_schema_information  
     | 
| 
       1029 
     | 
    
         
            -
                    versions =  
     | 
| 
      
 1064 
     | 
    
         
            +
                  def dump_schema_information # :nodoc:
         
     | 
| 
      
 1065 
     | 
    
         
            +
                    versions = schema_migration.all_versions
         
     | 
| 
       1030 
1066 
     | 
    
         
             
                    insert_versions_sql(versions) if versions.any?
         
     | 
| 
       1031 
1067 
     | 
    
         
             
                  end
         
     | 
| 
       1032 
1068 
     | 
    
         | 
| 
         @@ -1034,15 +1070,18 @@ module ActiveRecord 
     | 
|
| 
       1034 
1070 
     | 
    
         
             
                    { primary_key: true }
         
     | 
| 
       1035 
1071 
     | 
    
         
             
                  end
         
     | 
| 
       1036 
1072 
     | 
    
         | 
| 
       1037 
     | 
    
         
            -
                  def assume_migrated_upto_version(version, migrations_paths)
         
     | 
| 
       1038 
     | 
    
         
            -
                     
     | 
| 
      
 1073 
     | 
    
         
            +
                  def assume_migrated_upto_version(version, migrations_paths = nil)
         
     | 
| 
      
 1074 
     | 
    
         
            +
                    unless migrations_paths.nil?
         
     | 
| 
      
 1075 
     | 
    
         
            +
                      ActiveSupport::Deprecation.warn(<<~MSG.squish)
         
     | 
| 
      
 1076 
     | 
    
         
            +
                        Passing migrations_paths to #assume_migrated_upto_version is deprecated and will be removed in Rails 6.1.
         
     | 
| 
      
 1077 
     | 
    
         
            +
                      MSG
         
     | 
| 
      
 1078 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1079 
     | 
    
         
            +
             
     | 
| 
       1039 
1080 
     | 
    
         
             
                    version = version.to_i
         
     | 
| 
       1040 
     | 
    
         
            -
                    sm_table = quote_table_name( 
     | 
| 
      
 1081 
     | 
    
         
            +
                    sm_table = quote_table_name(schema_migration.table_name)
         
     | 
| 
       1041 
1082 
     | 
    
         | 
| 
       1042 
     | 
    
         
            -
                    migrated =  
     | 
| 
       1043 
     | 
    
         
            -
                    versions = migration_context. 
     | 
| 
       1044 
     | 
    
         
            -
                      migration_context.parse_migration_filename(file).first.to_i
         
     | 
| 
       1045 
     | 
    
         
            -
                    end
         
     | 
| 
      
 1083 
     | 
    
         
            +
                    migrated = migration_context.get_all_versions
         
     | 
| 
      
 1084 
     | 
    
         
            +
                    versions = migration_context.migrations.map(&:version)
         
     | 
| 
       1046 
1085 
     | 
    
         | 
| 
       1047 
1086 
     | 
    
         
             
                    unless migrated.include?(version)
         
     | 
| 
       1048 
1087 
     | 
    
         
             
                      execute "INSERT INTO #{sm_table} (version) VALUES (#{quote(version)})"
         
     | 
| 
         @@ -1053,13 +1092,7 @@ module ActiveRecord 
     | 
|
| 
       1053 
1092 
     | 
    
         
             
                      if (duplicate = inserting.detect { |v| inserting.count(v) > 1 })
         
     | 
| 
       1054 
1093 
     | 
    
         
             
                        raise "Duplicate migration #{duplicate}. Please renumber your migrations to resolve the conflict."
         
     | 
| 
       1055 
1094 
     | 
    
         
             
                      end
         
     | 
| 
       1056 
     | 
    
         
            -
                       
     | 
| 
       1057 
     | 
    
         
            -
                        execute insert_versions_sql(inserting)
         
     | 
| 
       1058 
     | 
    
         
            -
                      else
         
     | 
| 
       1059 
     | 
    
         
            -
                        inserting.each do |v|
         
     | 
| 
       1060 
     | 
    
         
            -
                          execute insert_versions_sql(v)
         
     | 
| 
       1061 
     | 
    
         
            -
                        end
         
     | 
| 
       1062 
     | 
    
         
            -
                      end
         
     | 
| 
      
 1095 
     | 
    
         
            +
                      execute insert_versions_sql(inserting)
         
     | 
| 
       1063 
1096 
     | 
    
         
             
                    end
         
     | 
| 
       1064 
1097 
     | 
    
         
             
                  end
         
     | 
| 
       1065 
1098 
     | 
    
         | 
| 
         @@ -1085,7 +1118,7 @@ module ActiveRecord 
     | 
|
| 
       1085 
1118 
     | 
    
         
             
                        if (0..6) === precision
         
     | 
| 
       1086 
1119 
     | 
    
         
             
                          column_type_sql << "(#{precision})"
         
     | 
| 
       1087 
1120 
     | 
    
         
             
                        else
         
     | 
| 
       1088 
     | 
    
         
            -
                          raise 
     | 
| 
      
 1121 
     | 
    
         
            +
                          raise ArgumentError, "No #{native[:name]} type has precision of #{precision}. The allowed range of precision is from 0 to 6"
         
     | 
| 
       1089 
1122 
     | 
    
         
             
                        end
         
     | 
| 
       1090 
1123 
     | 
    
         
             
                      elsif (type != :primary_key) && (limit ||= native.is_a?(Hash) && native[:limit])
         
     | 
| 
       1091 
1124 
     | 
    
         
             
                        column_type_sql << "(#{limit})"
         
     | 
| 
         @@ -1115,6 +1148,10 @@ module ActiveRecord 
     | 
|
| 
       1115 
1148 
     | 
    
         
             
                  def add_timestamps(table_name, options = {})
         
     | 
| 
       1116 
1149 
     | 
    
         
             
                    options[:null] = false if options[:null].nil?
         
     | 
| 
       1117 
1150 
     | 
    
         | 
| 
      
 1151 
     | 
    
         
            +
                    if !options.key?(:precision) && supports_datetime_with_precision?
         
     | 
| 
      
 1152 
     | 
    
         
            +
                      options[:precision] = 6
         
     | 
| 
      
 1153 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1154 
     | 
    
         
            +
             
     | 
| 
       1118 
1155 
     | 
    
         
             
                    add_column table_name, :created_at, :datetime, options
         
     | 
| 
       1119 
1156 
     | 
    
         
             
                    add_column table_name, :updated_at, :datetime, options
         
     | 
| 
       1120 
1157 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -1169,12 +1206,22 @@ module ActiveRecord 
     | 
|
| 
       1169 
1206 
     | 
    
         
             
                  end
         
     | 
| 
       1170 
1207 
     | 
    
         | 
| 
       1171 
1208 
     | 
    
         
             
                  # Changes the comment for a table or removes it if +nil+.
         
     | 
| 
       1172 
     | 
    
         
            -
                   
     | 
| 
      
 1209 
     | 
    
         
            +
                  #
         
     | 
| 
      
 1210 
     | 
    
         
            +
                  # Passing a hash containing +:from+ and +:to+ will make this change
         
     | 
| 
      
 1211 
     | 
    
         
            +
                  # reversible in migration:
         
     | 
| 
      
 1212 
     | 
    
         
            +
                  #
         
     | 
| 
      
 1213 
     | 
    
         
            +
                  #   change_table_comment(:posts, from: "old_comment", to: "new_comment")
         
     | 
| 
      
 1214 
     | 
    
         
            +
                  def change_table_comment(table_name, comment_or_changes)
         
     | 
| 
       1173 
1215 
     | 
    
         
             
                    raise NotImplementedError, "#{self.class} does not support changing table comments"
         
     | 
| 
       1174 
1216 
     | 
    
         
             
                  end
         
     | 
| 
       1175 
1217 
     | 
    
         | 
| 
       1176 
1218 
     | 
    
         
             
                  # Changes the comment for a column or removes it if +nil+.
         
     | 
| 
       1177 
     | 
    
         
            -
                   
     | 
| 
      
 1219 
     | 
    
         
            +
                  #
         
     | 
| 
      
 1220 
     | 
    
         
            +
                  # Passing a hash containing +:from+ and +:to+ will make this change
         
     | 
| 
      
 1221 
     | 
    
         
            +
                  # reversible in migration:
         
     | 
| 
      
 1222 
     | 
    
         
            +
                  #
         
     | 
| 
      
 1223 
     | 
    
         
            +
                  #   change_column_comment(:posts, :state, from: "old_comment", to: "new_comment")
         
     | 
| 
      
 1224 
     | 
    
         
            +
                  def change_column_comment(table_name, column_name, comment_or_changes)
         
     | 
| 
       1178 
1225 
     | 
    
         
             
                    raise NotImplementedError, "#{self.class} does not support changing column comments"
         
     | 
| 
       1179 
1226 
     | 
    
         
             
                  end
         
     | 
| 
       1180 
1227 
     | 
    
         | 
| 
         @@ -1276,7 +1323,7 @@ module ActiveRecord 
     | 
|
| 
       1276 
1323 
     | 
    
         
             
                    end
         
     | 
| 
       1277 
1324 
     | 
    
         | 
| 
       1278 
1325 
     | 
    
         
             
                    def create_table_definition(*args)
         
     | 
| 
       1279 
     | 
    
         
            -
                      TableDefinition.new(*args)
         
     | 
| 
      
 1326 
     | 
    
         
            +
                      TableDefinition.new(self, *args)
         
     | 
| 
       1280 
1327 
     | 
    
         
             
                    end
         
     | 
| 
       1281 
1328 
     | 
    
         | 
| 
       1282 
1329 
     | 
    
         
             
                    def create_alter_table(name)
         
     | 
| 
         @@ -1310,6 +1357,12 @@ module ActiveRecord 
     | 
|
| 
       1310 
1357 
     | 
    
         
             
                      { column: column_names }
         
     | 
| 
       1311 
1358 
     | 
    
         
             
                    end
         
     | 
| 
       1312 
1359 
     | 
    
         | 
| 
      
 1360 
     | 
    
         
            +
                    def strip_table_name_prefix_and_suffix(table_name)
         
     | 
| 
      
 1361 
     | 
    
         
            +
                      prefix = Base.table_name_prefix
         
     | 
| 
      
 1362 
     | 
    
         
            +
                      suffix = Base.table_name_suffix
         
     | 
| 
      
 1363 
     | 
    
         
            +
                      table_name.to_s =~ /#{prefix}(.+)#{suffix}/ ? $1 : table_name.to_s
         
     | 
| 
      
 1364 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1365 
     | 
    
         
            +
             
     | 
| 
       1313 
1366 
     | 
    
         
             
                    def foreign_key_name(table_name, options)
         
     | 
| 
       1314 
1367 
     | 
    
         
             
                      options.fetch(:name) do
         
     | 
| 
       1315 
1368 
     | 
    
         
             
                        identifier = "#{table_name}_#{options.fetch(:column)}_fk"
         
     | 
| 
         @@ -1319,14 +1372,14 @@ module ActiveRecord 
     | 
|
| 
       1319 
1372 
     | 
    
         
             
                      end
         
     | 
| 
       1320 
1373 
     | 
    
         
             
                    end
         
     | 
| 
       1321 
1374 
     | 
    
         | 
| 
       1322 
     | 
    
         
            -
                    def foreign_key_for(from_table,  
     | 
| 
      
 1375 
     | 
    
         
            +
                    def foreign_key_for(from_table, **options)
         
     | 
| 
       1323 
1376 
     | 
    
         
             
                      return unless supports_foreign_keys?
         
     | 
| 
       1324 
     | 
    
         
            -
                      foreign_keys(from_table).detect { |fk| fk.defined_for?  
     | 
| 
      
 1377 
     | 
    
         
            +
                      foreign_keys(from_table).detect { |fk| fk.defined_for?(options) }
         
     | 
| 
       1325 
1378 
     | 
    
         
             
                    end
         
     | 
| 
       1326 
1379 
     | 
    
         | 
| 
       1327 
     | 
    
         
            -
                    def foreign_key_for!(from_table,  
     | 
| 
       1328 
     | 
    
         
            -
                      foreign_key_for(from_table,  
     | 
| 
       1329 
     | 
    
         
            -
                        raise(ArgumentError, "Table '#{from_table}' has no foreign key for #{ 
     | 
| 
      
 1380 
     | 
    
         
            +
                    def foreign_key_for!(from_table, to_table: nil, **options)
         
     | 
| 
      
 1381 
     | 
    
         
            +
                      foreign_key_for(from_table, to_table: to_table, **options) ||
         
     | 
| 
      
 1382 
     | 
    
         
            +
                        raise(ArgumentError, "Table '#{from_table}' has no foreign key for #{to_table || options}")
         
     | 
| 
       1330 
1383 
     | 
    
         
             
                    end
         
     | 
| 
       1331 
1384 
     | 
    
         | 
| 
       1332 
1385 
     | 
    
         
             
                    def extract_foreign_key_action(specifier)
         
     | 
| 
         @@ -1352,11 +1405,37 @@ module ActiveRecord 
     | 
|
| 
       1352 
1405 
     | 
    
         
             
                        default_or_changes
         
     | 
| 
       1353 
1406 
     | 
    
         
             
                      end
         
     | 
| 
       1354 
1407 
     | 
    
         
             
                    end
         
     | 
| 
      
 1408 
     | 
    
         
            +
                    alias :extract_new_comment_value :extract_new_default_value
         
     | 
| 
       1355 
1409 
     | 
    
         | 
| 
       1356 
1410 
     | 
    
         
             
                    def can_remove_index_by_name?(options)
         
     | 
| 
       1357 
1411 
     | 
    
         
             
                      options.is_a?(Hash) && options.key?(:name) && options.except(:name, :algorithm).empty?
         
     | 
| 
       1358 
1412 
     | 
    
         
             
                    end
         
     | 
| 
       1359 
1413 
     | 
    
         | 
| 
      
 1414 
     | 
    
         
            +
                    def bulk_change_table(table_name, operations)
         
     | 
| 
      
 1415 
     | 
    
         
            +
                      sql_fragments = []
         
     | 
| 
      
 1416 
     | 
    
         
            +
                      non_combinable_operations = []
         
     | 
| 
      
 1417 
     | 
    
         
            +
             
     | 
| 
      
 1418 
     | 
    
         
            +
                      operations.each do |command, args|
         
     | 
| 
      
 1419 
     | 
    
         
            +
                        table, arguments = args.shift, args
         
     | 
| 
      
 1420 
     | 
    
         
            +
                        method = :"#{command}_for_alter"
         
     | 
| 
      
 1421 
     | 
    
         
            +
             
     | 
| 
      
 1422 
     | 
    
         
            +
                        if respond_to?(method, true)
         
     | 
| 
      
 1423 
     | 
    
         
            +
                          sqls, procs = Array(send(method, table, *arguments)).partition { |v| v.is_a?(String) }
         
     | 
| 
      
 1424 
     | 
    
         
            +
                          sql_fragments << sqls
         
     | 
| 
      
 1425 
     | 
    
         
            +
                          non_combinable_operations.concat(procs)
         
     | 
| 
      
 1426 
     | 
    
         
            +
                        else
         
     | 
| 
      
 1427 
     | 
    
         
            +
                          execute "ALTER TABLE #{quote_table_name(table_name)} #{sql_fragments.join(", ")}" unless sql_fragments.empty?
         
     | 
| 
      
 1428 
     | 
    
         
            +
                          non_combinable_operations.each(&:call)
         
     | 
| 
      
 1429 
     | 
    
         
            +
                          sql_fragments = []
         
     | 
| 
      
 1430 
     | 
    
         
            +
                          non_combinable_operations = []
         
     | 
| 
      
 1431 
     | 
    
         
            +
                          send(command, table, *arguments)
         
     | 
| 
      
 1432 
     | 
    
         
            +
                        end
         
     | 
| 
      
 1433 
     | 
    
         
            +
                      end
         
     | 
| 
      
 1434 
     | 
    
         
            +
             
     | 
| 
      
 1435 
     | 
    
         
            +
                      execute "ALTER TABLE #{quote_table_name(table_name)} #{sql_fragments.join(", ")}" unless sql_fragments.empty?
         
     | 
| 
      
 1436 
     | 
    
         
            +
                      non_combinable_operations.each(&:call)
         
     | 
| 
      
 1437 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1438 
     | 
    
         
            +
             
     | 
| 
       1360 
1439 
     | 
    
         
             
                    def add_column_for_alter(table_name, column_name, type, options = {})
         
     | 
| 
       1361 
1440 
     | 
    
         
             
                      td = create_table_definition(table_name)
         
     | 
| 
       1362 
1441 
     | 
    
         
             
                      cd = td.new_column_definition(column_name, type, options)
         
     | 
| 
         @@ -1372,10 +1451,10 @@ module ActiveRecord 
     | 
|
| 
       1372 
1451 
     | 
    
         
             
                    end
         
     | 
| 
       1373 
1452 
     | 
    
         | 
| 
       1374 
1453 
     | 
    
         
             
                    def insert_versions_sql(versions)
         
     | 
| 
       1375 
     | 
    
         
            -
                      sm_table = quote_table_name( 
     | 
| 
      
 1454 
     | 
    
         
            +
                      sm_table = quote_table_name(schema_migration.table_name)
         
     | 
| 
       1376 
1455 
     | 
    
         | 
| 
       1377 
1456 
     | 
    
         
             
                      if versions.is_a?(Array)
         
     | 
| 
       1378 
     | 
    
         
            -
                        sql = "INSERT INTO #{sm_table} (version) VALUES\n" 
     | 
| 
      
 1457 
     | 
    
         
            +
                        sql = +"INSERT INTO #{sm_table} (version) VALUES\n"
         
     | 
| 
       1379 
1458 
     | 
    
         
             
                        sql << versions.map { |v| "(#{quote(v)})" }.join(",\n")
         
     | 
| 
       1380 
1459 
     | 
    
         
             
                        sql << ";\n\n"
         
     | 
| 
       1381 
1460 
     | 
    
         
             
                        sql
         
     |