activerecord 6.0.4.7 → 6.1.7.3
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 +1199 -777
 - data/MIT-LICENSE +1 -1
 - data/README.rdoc +2 -2
 - data/lib/active_record/aggregations.rb +5 -5
 - data/lib/active_record/association_relation.rb +30 -12
 - data/lib/active_record/associations/alias_tracker.rb +19 -15
 - data/lib/active_record/associations/association.rb +49 -26
 - data/lib/active_record/associations/association_scope.rb +18 -20
 - data/lib/active_record/associations/belongs_to_association.rb +23 -10
 - data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -3
 - data/lib/active_record/associations/builder/association.rb +32 -5
 - data/lib/active_record/associations/builder/belongs_to.rb +10 -7
 - data/lib/active_record/associations/builder/collection_association.rb +5 -4
 - data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +0 -1
 - data/lib/active_record/associations/builder/has_many.rb +6 -2
 - data/lib/active_record/associations/builder/has_one.rb +11 -14
 - data/lib/active_record/associations/builder/singular_association.rb +1 -1
 - data/lib/active_record/associations/collection_association.rb +32 -18
 - data/lib/active_record/associations/collection_proxy.rb +12 -5
 - data/lib/active_record/associations/foreign_association.rb +13 -0
 - data/lib/active_record/associations/has_many_association.rb +24 -2
 - data/lib/active_record/associations/has_many_through_association.rb +10 -4
 - data/lib/active_record/associations/has_one_association.rb +15 -1
 - data/lib/active_record/associations/join_dependency/join_association.rb +37 -21
 - data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
 - data/lib/active_record/associations/join_dependency.rb +63 -49
 - data/lib/active_record/associations/preloader/association.rb +14 -8
 - data/lib/active_record/associations/preloader/through_association.rb +1 -1
 - data/lib/active_record/associations/preloader.rb +5 -3
 - data/lib/active_record/associations/singular_association.rb +1 -1
 - data/lib/active_record/associations.rb +118 -11
 - data/lib/active_record/attribute_assignment.rb +10 -8
 - data/lib/active_record/attribute_methods/before_type_cast.rb +13 -9
 - data/lib/active_record/attribute_methods/dirty.rb +1 -11
 - data/lib/active_record/attribute_methods/primary_key.rb +6 -2
 - data/lib/active_record/attribute_methods/query.rb +3 -6
 - data/lib/active_record/attribute_methods/read.rb +8 -11
 - data/lib/active_record/attribute_methods/serialization.rb +11 -5
 - data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -13
 - data/lib/active_record/attribute_methods/write.rb +12 -20
 - data/lib/active_record/attribute_methods.rb +64 -54
 - data/lib/active_record/attributes.rb +33 -8
 - data/lib/active_record/autosave_association.rb +47 -30
 - data/lib/active_record/base.rb +2 -14
 - data/lib/active_record/callbacks.rb +152 -22
 - data/lib/active_record/coders/yaml_column.rb +24 -2
 - data/lib/active_record/connection_adapters/abstract/connection_pool.rb +185 -134
 - data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
 - data/lib/active_record/connection_adapters/abstract/database_statements.rb +66 -23
 - data/lib/active_record/connection_adapters/abstract/query_cache.rb +3 -8
 - data/lib/active_record/connection_adapters/abstract/quoting.rb +44 -35
 - data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
 - data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -116
 - data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +114 -26
 - data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
 - data/lib/active_record/connection_adapters/abstract/schema_statements.rb +228 -83
 - data/lib/active_record/connection_adapters/abstract/transaction.rb +92 -33
 - data/lib/active_record/connection_adapters/abstract_adapter.rb +52 -76
 - data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +123 -87
 - data/lib/active_record/connection_adapters/column.rb +15 -1
 - data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
 - data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
 - data/lib/active_record/connection_adapters/mysql/database_statements.rb +24 -24
 - data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -1
 - data/lib/active_record/connection_adapters/mysql/quoting.rb +18 -3
 - data/lib/active_record/connection_adapters/mysql/schema_creation.rb +32 -6
 - data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
 - data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +5 -2
 - data/lib/active_record/connection_adapters/mysql/schema_statements.rb +7 -4
 - data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
 - data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -12
 - data/lib/active_record/connection_adapters/pool_config.rb +73 -0
 - data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
 - data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
 - data/lib/active_record/connection_adapters/postgresql/database_statements.rb +14 -53
 - data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
 - data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -1
 - data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
 - data/lib/active_record/connection_adapters/postgresql/quoting.rb +30 -4
 - data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +5 -1
 - data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +61 -29
 - data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
 - data/lib/active_record/connection_adapters/postgresql_adapter.rb +75 -64
 - data/lib/active_record/connection_adapters/schema_cache.rb +130 -15
 - data/lib/active_record/connection_adapters/sql_type_metadata.rb +8 -0
 - data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +32 -5
 - data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -1
 - data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
 - data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +36 -3
 - data/lib/active_record/connection_adapters/sqlite3_adapter.rb +48 -50
 - data/lib/active_record/connection_adapters.rb +52 -0
 - data/lib/active_record/connection_handling.rb +218 -71
 - data/lib/active_record/core.rb +271 -60
 - data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -0
 - data/lib/active_record/database_configurations/database_config.rb +52 -9
 - data/lib/active_record/database_configurations/hash_config.rb +54 -8
 - data/lib/active_record/database_configurations/url_config.rb +15 -40
 - data/lib/active_record/database_configurations.rb +125 -85
 - data/lib/active_record/delegated_type.rb +209 -0
 - data/lib/active_record/destroy_association_async_job.rb +36 -0
 - data/lib/active_record/enum.rb +69 -34
 - data/lib/active_record/errors.rb +47 -12
 - data/lib/active_record/explain.rb +9 -4
 - data/lib/active_record/explain_subscriber.rb +1 -1
 - data/lib/active_record/fixture_set/file.rb +10 -17
 - data/lib/active_record/fixture_set/model_metadata.rb +1 -2
 - data/lib/active_record/fixture_set/render_context.rb +1 -1
 - data/lib/active_record/fixture_set/table_row.rb +2 -2
 - data/lib/active_record/fixtures.rb +58 -9
 - data/lib/active_record/gem_version.rb +3 -3
 - data/lib/active_record/inheritance.rb +40 -18
 - data/lib/active_record/insert_all.rb +38 -5
 - data/lib/active_record/integration.rb +3 -5
 - data/lib/active_record/internal_metadata.rb +18 -7
 - data/lib/active_record/legacy_yaml_adapter.rb +7 -3
 - data/lib/active_record/locking/optimistic.rb +24 -17
 - data/lib/active_record/locking/pessimistic.rb +6 -2
 - data/lib/active_record/log_subscriber.rb +27 -8
 - data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
 - data/lib/active_record/middleware/database_selector/resolver.rb +5 -0
 - data/lib/active_record/middleware/database_selector.rb +4 -1
 - data/lib/active_record/migration/command_recorder.rb +47 -27
 - data/lib/active_record/migration/compatibility.rb +72 -18
 - data/lib/active_record/migration.rb +114 -84
 - data/lib/active_record/model_schema.rb +89 -14
 - data/lib/active_record/nested_attributes.rb +2 -3
 - data/lib/active_record/no_touching.rb +1 -1
 - data/lib/active_record/persistence.rb +50 -45
 - data/lib/active_record/query_cache.rb +15 -5
 - data/lib/active_record/querying.rb +11 -6
 - data/lib/active_record/railtie.rb +64 -44
 - data/lib/active_record/railties/console_sandbox.rb +2 -4
 - data/lib/active_record/railties/databases.rake +279 -101
 - data/lib/active_record/readonly_attributes.rb +4 -0
 - data/lib/active_record/reflection.rb +60 -44
 - data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
 - data/lib/active_record/relation/batches.rb +38 -31
 - data/lib/active_record/relation/calculations.rb +104 -43
 - data/lib/active_record/relation/finder_methods.rb +44 -14
 - data/lib/active_record/relation/from_clause.rb +1 -1
 - data/lib/active_record/relation/merger.rb +20 -23
 - data/lib/active_record/relation/predicate_builder/array_handler.rb +8 -9
 - data/lib/active_record/relation/predicate_builder/association_query_value.rb +4 -5
 - data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -6
 - data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
 - data/lib/active_record/relation/predicate_builder.rb +61 -38
 - data/lib/active_record/relation/query_methods.rb +324 -196
 - data/lib/active_record/relation/record_fetch_warning.rb +3 -3
 - data/lib/active_record/relation/spawn_methods.rb +8 -7
 - data/lib/active_record/relation/where_clause.rb +111 -61
 - data/lib/active_record/relation.rb +100 -81
 - data/lib/active_record/result.rb +41 -33
 - data/lib/active_record/runtime_registry.rb +2 -2
 - data/lib/active_record/sanitization.rb +6 -17
 - data/lib/active_record/schema_dumper.rb +34 -4
 - data/lib/active_record/schema_migration.rb +2 -8
 - data/lib/active_record/scoping/default.rb +1 -3
 - data/lib/active_record/scoping/named.rb +1 -17
 - data/lib/active_record/secure_token.rb +16 -8
 - data/lib/active_record/serialization.rb +5 -3
 - data/lib/active_record/signed_id.rb +116 -0
 - data/lib/active_record/statement_cache.rb +20 -4
 - data/lib/active_record/store.rb +8 -3
 - data/lib/active_record/suppressor.rb +2 -2
 - data/lib/active_record/table_metadata.rb +42 -51
 - data/lib/active_record/tasks/database_tasks.rb +140 -113
 - data/lib/active_record/tasks/mysql_database_tasks.rb +34 -35
 - data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -26
 - data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -9
 - data/lib/active_record/test_databases.rb +5 -4
 - data/lib/active_record/test_fixtures.rb +79 -31
 - data/lib/active_record/timestamp.rb +4 -6
 - data/lib/active_record/touch_later.rb +21 -21
 - data/lib/active_record/transactions.rb +19 -66
 - data/lib/active_record/type/serialized.rb +6 -2
 - data/lib/active_record/type.rb +8 -1
 - data/lib/active_record/type_caster/connection.rb +0 -1
 - data/lib/active_record/type_caster/map.rb +8 -5
 - data/lib/active_record/validations/associated.rb +1 -1
 - data/lib/active_record/validations/numericality.rb +35 -0
 - data/lib/active_record/validations/uniqueness.rb +24 -4
 - data/lib/active_record/validations.rb +1 -0
 - data/lib/active_record.rb +7 -14
 - data/lib/arel/attributes/attribute.rb +4 -0
 - data/lib/arel/collectors/bind.rb +5 -0
 - data/lib/arel/collectors/composite.rb +8 -0
 - data/lib/arel/collectors/sql_string.rb +7 -0
 - data/lib/arel/collectors/substitute_binds.rb +7 -0
 - data/lib/arel/nodes/binary.rb +82 -8
 - data/lib/arel/nodes/bind_param.rb +8 -0
 - data/lib/arel/nodes/casted.rb +21 -9
 - data/lib/arel/nodes/equality.rb +6 -9
 - data/lib/arel/nodes/grouping.rb +3 -0
 - data/lib/arel/nodes/homogeneous_in.rb +76 -0
 - data/lib/arel/nodes/in.rb +8 -1
 - data/lib/arel/nodes/infix_operation.rb +13 -1
 - data/lib/arel/nodes/join_source.rb +1 -1
 - data/lib/arel/nodes/node.rb +7 -6
 - data/lib/arel/nodes/ordering.rb +27 -0
 - data/lib/arel/nodes/sql_literal.rb +3 -0
 - data/lib/arel/nodes/table_alias.rb +7 -3
 - data/lib/arel/nodes/unary.rb +0 -1
 - data/lib/arel/nodes.rb +3 -1
 - data/lib/arel/predications.rb +12 -18
 - data/lib/arel/select_manager.rb +1 -2
 - data/lib/arel/table.rb +13 -5
 - data/lib/arel/visitors/dot.rb +14 -2
 - data/lib/arel/visitors/mysql.rb +11 -1
 - data/lib/arel/visitors/postgresql.rb +15 -4
 - data/lib/arel/visitors/to_sql.rb +89 -78
 - data/lib/arel/visitors.rb +0 -7
 - data/lib/arel.rb +5 -13
 - data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
 - data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +2 -0
 - data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +3 -3
 - data/lib/rails/generators/active_record/migration.rb +6 -1
 - data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
 - data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
 - metadata +26 -26
 - data/lib/active_record/advisory_lock_base.rb +0 -18
 - data/lib/active_record/attribute_decorators.rb +0 -88
 - data/lib/active_record/connection_adapters/connection_specification.rb +0 -296
 - data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
 - data/lib/active_record/define_callbacks.rb +0 -22
 - data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
 - data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
 - data/lib/active_record/relation/where_clause_factory.rb +0 -33
 - data/lib/arel/attributes.rb +0 -22
 - data/lib/arel/visitors/depth_first.rb +0 -203
 - data/lib/arel/visitors/ibm_db.rb +0 -34
 - data/lib/arel/visitors/informix.rb +0 -62
 - data/lib/arel/visitors/mssql.rb +0 -156
 - data/lib/arel/visitors/oracle.rb +0 -158
 - data/lib/arel/visitors/oracle12.rb +0 -65
 - data/lib/arel/visitors/where_sql.rb +0 -22
 
| 
         @@ -92,6 +92,14 @@ module ActiveRecord 
     | 
|
| 
       92 
92 
     | 
    
         
             
                    true
         
     | 
| 
       93 
93 
     | 
    
         
             
                  end
         
     | 
| 
       94 
94 
     | 
    
         | 
| 
      
 95 
     | 
    
         
            +
                  def supports_check_constraints?
         
     | 
| 
      
 96 
     | 
    
         
            +
                    if mariadb?
         
     | 
| 
      
 97 
     | 
    
         
            +
                      database_version >= "10.2.1"
         
     | 
| 
      
 98 
     | 
    
         
            +
                    else
         
     | 
| 
      
 99 
     | 
    
         
            +
                      database_version >= "8.0.16"
         
     | 
| 
      
 100 
     | 
    
         
            +
                    end
         
     | 
| 
      
 101 
     | 
    
         
            +
                  end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
       95 
103 
     | 
    
         
             
                  def supports_views?
         
     | 
| 
       96 
104 
     | 
    
         
             
                    true
         
     | 
| 
       97 
105 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -104,7 +112,7 @@ module ActiveRecord 
     | 
|
| 
       104 
112 
     | 
    
         
             
                    mariadb? || database_version >= "5.7.5"
         
     | 
| 
       105 
113 
     | 
    
         
             
                  end
         
     | 
| 
       106 
114 
     | 
    
         | 
| 
       107 
     | 
    
         
            -
                  # See https://dev.mysql.com/doc/refman/ 
     | 
| 
      
 115 
     | 
    
         
            +
                  # See https://dev.mysql.com/doc/refman/en/optimizer-hints.html for more details.
         
     | 
| 
       108 
116 
     | 
    
         
             
                  def supports_optimizer_hints?
         
     | 
| 
       109 
117 
     | 
    
         
             
                    !mariadb? && database_version >= "5.7.7"
         
     | 
| 
       110 
118 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -142,7 +150,12 @@ module ActiveRecord 
     | 
|
| 
       142 
150 
     | 
    
         
             
                  end
         
     | 
| 
       143 
151 
     | 
    
         | 
| 
       144 
152 
     | 
    
         
             
                  def index_algorithms
         
     | 
| 
       145 
     | 
    
         
            -
                    { 
     | 
| 
      
 153 
     | 
    
         
            +
                    {
         
     | 
| 
      
 154 
     | 
    
         
            +
                      default: "ALGORITHM = DEFAULT",
         
     | 
| 
      
 155 
     | 
    
         
            +
                      copy:    "ALGORITHM = COPY",
         
     | 
| 
      
 156 
     | 
    
         
            +
                      inplace: "ALGORITHM = INPLACE",
         
     | 
| 
      
 157 
     | 
    
         
            +
                      instant: "ALGORITHM = INSTANT",
         
     | 
| 
      
 158 
     | 
    
         
            +
                    }
         
     | 
| 
       146 
159 
     | 
    
         
             
                  end
         
     | 
| 
       147 
160 
     | 
    
         | 
| 
       148 
161 
     | 
    
         
             
                  # HELPER METHODS ===========================================
         
     | 
| 
         @@ -183,18 +196,10 @@ module ActiveRecord 
     | 
|
| 
       183 
196 
     | 
    
         
             
                  # DATABASE STATEMENTS ======================================
         
     | 
| 
       184 
197 
     | 
    
         
             
                  #++
         
     | 
| 
       185 
198 
     | 
    
         | 
| 
       186 
     | 
    
         
            -
                  def explain(arel, binds = [])
         
     | 
| 
       187 
     | 
    
         
            -
                    sql     = "EXPLAIN #{to_sql(arel, binds)}"
         
     | 
| 
       188 
     | 
    
         
            -
                    start   = Concurrent.monotonic_time
         
     | 
| 
       189 
     | 
    
         
            -
                    result  = exec_query(sql, "EXPLAIN", binds)
         
     | 
| 
       190 
     | 
    
         
            -
                    elapsed = Concurrent.monotonic_time - start
         
     | 
| 
       191 
     | 
    
         
            -
             
     | 
| 
       192 
     | 
    
         
            -
                    MySQL::ExplainPrettyPrinter.new.pp(result, elapsed)
         
     | 
| 
       193 
     | 
    
         
            -
                  end
         
     | 
| 
       194 
     | 
    
         
            -
             
     | 
| 
       195 
199 
     | 
    
         
             
                  # Executes the SQL statement in the context of this connection.
         
     | 
| 
       196 
200 
     | 
    
         
             
                  def execute(sql, name = nil)
         
     | 
| 
       197 
201 
     | 
    
         
             
                    materialize_transactions
         
     | 
| 
      
 202 
     | 
    
         
            +
                    mark_transaction_written_if_write(sql)
         
     | 
| 
       198 
203 
     | 
    
         | 
| 
       199 
204 
     | 
    
         
             
                    log(sql, name) do
         
     | 
| 
       200 
205 
     | 
    
         
             
                      ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
         
     | 
| 
         @@ -211,7 +216,7 @@ module ActiveRecord 
     | 
|
| 
       211 
216 
     | 
    
         
             
                  end
         
     | 
| 
       212 
217 
     | 
    
         | 
| 
       213 
218 
     | 
    
         
             
                  def begin_db_transaction
         
     | 
| 
       214 
     | 
    
         
            -
                    execute 
     | 
| 
      
 219 
     | 
    
         
            +
                    execute("BEGIN", "TRANSACTION")
         
     | 
| 
       215 
220 
     | 
    
         
             
                  end
         
     | 
| 
       216 
221 
     | 
    
         | 
| 
       217 
222 
     | 
    
         
             
                  def begin_isolated_db_transaction(isolation)
         
     | 
| 
         @@ -220,11 +225,11 @@ module ActiveRecord 
     | 
|
| 
       220 
225 
     | 
    
         
             
                  end
         
     | 
| 
       221 
226 
     | 
    
         | 
| 
       222 
227 
     | 
    
         
             
                  def commit_db_transaction #:nodoc:
         
     | 
| 
       223 
     | 
    
         
            -
                    execute 
     | 
| 
      
 228 
     | 
    
         
            +
                    execute("COMMIT", "TRANSACTION")
         
     | 
| 
       224 
229 
     | 
    
         
             
                  end
         
     | 
| 
       225 
230 
     | 
    
         | 
| 
       226 
231 
     | 
    
         
             
                  def exec_rollback_db_transaction #:nodoc:
         
     | 
| 
       227 
     | 
    
         
            -
                    execute 
     | 
| 
      
 232 
     | 
    
         
            +
                    execute("ROLLBACK", "TRANSACTION")
         
     | 
| 
       228 
233 
     | 
    
         
             
                  end
         
     | 
| 
       229 
234 
     | 
    
         | 
| 
       230 
235 
     | 
    
         
             
                  def empty_insert_statement_value(primary_key = nil)
         
     | 
| 
         @@ -305,6 +310,8 @@ module ActiveRecord 
     | 
|
| 
       305 
310 
     | 
    
         
             
                  # Example:
         
     | 
| 
       306 
311 
     | 
    
         
             
                  #   rename_table('octopuses', 'octopi')
         
     | 
| 
       307 
312 
     | 
    
         
             
                  def rename_table(table_name, new_name)
         
     | 
| 
      
 313 
     | 
    
         
            +
                    schema_cache.clear_data_source_cache!(table_name.to_s)
         
     | 
| 
      
 314 
     | 
    
         
            +
                    schema_cache.clear_data_source_cache!(new_name.to_s)
         
     | 
| 
       308 
315 
     | 
    
         
             
                    execute "RENAME TABLE #{quote_table_name(table_name)} TO #{quote_table_name(new_name)}"
         
     | 
| 
       309 
316 
     | 
    
         
             
                    rename_table_indexes(table_name, new_name)
         
     | 
| 
       310 
317 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -324,7 +331,8 @@ module ActiveRecord 
     | 
|
| 
       324 
331 
     | 
    
         
             
                  # Although this command ignores most +options+ and the block if one is given,
         
     | 
| 
       325 
332 
     | 
    
         
             
                  # it can be helpful to provide these in a migration's +change+ method so it can be reverted.
         
     | 
| 
       326 
333 
     | 
    
         
             
                  # In that case, +options+ and the block will be used by create_table.
         
     | 
| 
       327 
     | 
    
         
            -
                  def drop_table(table_name, options 
     | 
| 
      
 334 
     | 
    
         
            +
                  def drop_table(table_name, **options)
         
     | 
| 
      
 335 
     | 
    
         
            +
                    schema_cache.clear_data_source_cache!(table_name.to_s)
         
     | 
| 
       328 
336 
     | 
    
         
             
                    execute "DROP#{' TEMPORARY' if options[:temporary]} TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}"
         
     | 
| 
       329 
337 
     | 
    
         
             
                  end
         
     | 
| 
       330 
338 
     | 
    
         | 
| 
         @@ -356,8 +364,8 @@ module ActiveRecord 
     | 
|
| 
       356 
364 
     | 
    
         
             
                    change_column table_name, column_name, nil, comment: comment
         
     | 
| 
       357 
365 
     | 
    
         
             
                  end
         
     | 
| 
       358 
366 
     | 
    
         | 
| 
       359 
     | 
    
         
            -
                  def change_column(table_name, column_name, type, options 
     | 
| 
       360 
     | 
    
         
            -
                    execute("ALTER TABLE #{quote_table_name(table_name)} #{change_column_for_alter(table_name, column_name, type, options)}")
         
     | 
| 
      
 367 
     | 
    
         
            +
                  def change_column(table_name, column_name, type, **options) #:nodoc:
         
     | 
| 
      
 368 
     | 
    
         
            +
                    execute("ALTER TABLE #{quote_table_name(table_name)} #{change_column_for_alter(table_name, column_name, type, **options)}")
         
     | 
| 
       361 
369 
     | 
    
         
             
                  end
         
     | 
| 
       362 
370 
     | 
    
         | 
| 
       363 
371 
     | 
    
         
             
                  def rename_column(table_name, column_name, new_column_name) #:nodoc:
         
     | 
| 
         @@ -365,10 +373,13 @@ module ActiveRecord 
     | 
|
| 
       365 
373 
     | 
    
         
             
                    rename_column_indexes(table_name, column_name, new_column_name)
         
     | 
| 
       366 
374 
     | 
    
         
             
                  end
         
     | 
| 
       367 
375 
     | 
    
         | 
| 
       368 
     | 
    
         
            -
                  def add_index(table_name, column_name, options 
     | 
| 
       369 
     | 
    
         
            -
                     
     | 
| 
       370 
     | 
    
         
            -
             
     | 
| 
       371 
     | 
    
         
            -
                     
     | 
| 
      
 376 
     | 
    
         
            +
                  def add_index(table_name, column_name, **options) #:nodoc:
         
     | 
| 
      
 377 
     | 
    
         
            +
                    index, algorithm, if_not_exists = add_index_options(table_name, column_name, **options)
         
     | 
| 
      
 378 
     | 
    
         
            +
             
     | 
| 
      
 379 
     | 
    
         
            +
                    return if if_not_exists && index_exists?(table_name, column_name, name: index.name)
         
     | 
| 
      
 380 
     | 
    
         
            +
             
     | 
| 
      
 381 
     | 
    
         
            +
                    create_index = CreateIndexDefinition.new(index, algorithm)
         
     | 
| 
      
 382 
     | 
    
         
            +
                    execute schema_creation.accept(create_index)
         
     | 
| 
       372 
383 
     | 
    
         
             
                  end
         
     | 
| 
       373 
384 
     | 
    
         | 
| 
       374 
385 
     | 
    
         
             
                  def add_sql_comment!(sql, comment) # :nodoc:
         
     | 
| 
         @@ -412,25 +423,60 @@ module ActiveRecord 
     | 
|
| 
       412 
423 
     | 
    
         
             
                    end
         
     | 
| 
       413 
424 
     | 
    
         
             
                  end
         
     | 
| 
       414 
425 
     | 
    
         | 
| 
       415 
     | 
    
         
            -
                  def  
     | 
| 
       416 
     | 
    
         
            -
                     
     | 
| 
      
 426 
     | 
    
         
            +
                  def check_constraints(table_name)
         
     | 
| 
      
 427 
     | 
    
         
            +
                    if supports_check_constraints?
         
     | 
| 
      
 428 
     | 
    
         
            +
                      scope = quoted_scope(table_name)
         
     | 
| 
      
 429 
     | 
    
         
            +
             
     | 
| 
      
 430 
     | 
    
         
            +
                      chk_info = exec_query(<<~SQL, "SCHEMA")
         
     | 
| 
      
 431 
     | 
    
         
            +
                        SELECT cc.constraint_name AS 'name',
         
     | 
| 
      
 432 
     | 
    
         
            +
                              cc.check_clause AS 'expression'
         
     | 
| 
      
 433 
     | 
    
         
            +
                        FROM information_schema.check_constraints cc
         
     | 
| 
      
 434 
     | 
    
         
            +
                        JOIN information_schema.table_constraints tc
         
     | 
| 
      
 435 
     | 
    
         
            +
                        USING (constraint_schema, constraint_name)
         
     | 
| 
      
 436 
     | 
    
         
            +
                        WHERE tc.table_schema = #{scope[:schema]}
         
     | 
| 
      
 437 
     | 
    
         
            +
                          AND tc.table_name = #{scope[:name]}
         
     | 
| 
      
 438 
     | 
    
         
            +
                          AND cc.constraint_schema = #{scope[:schema]}
         
     | 
| 
      
 439 
     | 
    
         
            +
                      SQL
         
     | 
| 
      
 440 
     | 
    
         
            +
             
     | 
| 
      
 441 
     | 
    
         
            +
                      chk_info.map do |row|
         
     | 
| 
      
 442 
     | 
    
         
            +
                        options = {
         
     | 
| 
      
 443 
     | 
    
         
            +
                          name: row["name"]
         
     | 
| 
      
 444 
     | 
    
         
            +
                        }
         
     | 
| 
      
 445 
     | 
    
         
            +
                        expression = row["expression"]
         
     | 
| 
      
 446 
     | 
    
         
            +
                        expression = expression[1..-2] unless mariadb? # remove parentheses added by mysql
         
     | 
| 
      
 447 
     | 
    
         
            +
                        CheckConstraintDefinition.new(table_name, expression, options)
         
     | 
| 
      
 448 
     | 
    
         
            +
                      end
         
     | 
| 
      
 449 
     | 
    
         
            +
                    else
         
     | 
| 
      
 450 
     | 
    
         
            +
                      raise NotImplementedError
         
     | 
| 
      
 451 
     | 
    
         
            +
                    end
         
     | 
| 
      
 452 
     | 
    
         
            +
                  end
         
     | 
| 
       417 
453 
     | 
    
         | 
| 
      
 454 
     | 
    
         
            +
                  def table_options(table_name) # :nodoc:
         
     | 
| 
       418 
455 
     | 
    
         
             
                    create_table_info = create_table_info(table_name)
         
     | 
| 
       419 
456 
     | 
    
         | 
| 
       420 
457 
     | 
    
         
             
                    # strip create_definitions and partition_options
         
     | 
| 
       421 
458 
     | 
    
         
             
                    # Be aware that `create_table_info` might not include any table options due to `NO_TABLE_OPTIONS` sql mode.
         
     | 
| 
       422 
459 
     | 
    
         
             
                    raw_table_options = create_table_info.sub(/\A.*\n\) ?/m, "").sub(/\n\/\*!.*\*\/\n\z/m, "").strip
         
     | 
| 
       423 
460 
     | 
    
         | 
| 
      
 461 
     | 
    
         
            +
                    return if raw_table_options.empty?
         
     | 
| 
      
 462 
     | 
    
         
            +
             
     | 
| 
      
 463 
     | 
    
         
            +
                    table_options = {}
         
     | 
| 
      
 464 
     | 
    
         
            +
             
     | 
| 
      
 465 
     | 
    
         
            +
                    if / DEFAULT CHARSET=(?<charset>\w+)(?: COLLATE=(?<collation>\w+))?/ =~ raw_table_options
         
     | 
| 
      
 466 
     | 
    
         
            +
                      raw_table_options = $` + $' # before part + after part
         
     | 
| 
      
 467 
     | 
    
         
            +
                      table_options[:charset] = charset
         
     | 
| 
      
 468 
     | 
    
         
            +
                      table_options[:collation] = collation if collation
         
     | 
| 
      
 469 
     | 
    
         
            +
                    end
         
     | 
| 
      
 470 
     | 
    
         
            +
             
     | 
| 
       424 
471 
     | 
    
         
             
                    # strip AUTO_INCREMENT
         
     | 
| 
       425 
472 
     | 
    
         
             
                    raw_table_options.sub!(/(ENGINE=\w+)(?: AUTO_INCREMENT=\d+)/, '\1')
         
     | 
| 
       426 
473 
     | 
    
         | 
| 
       427 
     | 
    
         
            -
                    table_options[:options] = raw_table_options unless raw_table_options.blank?
         
     | 
| 
       428 
     | 
    
         
            -
             
     | 
| 
       429 
474 
     | 
    
         
             
                    # strip COMMENT
         
     | 
| 
       430 
475 
     | 
    
         
             
                    if raw_table_options.sub!(/ COMMENT='.+'/, "")
         
     | 
| 
       431 
476 
     | 
    
         
             
                      table_options[:comment] = table_comment(table_name)
         
     | 
| 
       432 
477 
     | 
    
         
             
                    end
         
     | 
| 
       433 
478 
     | 
    
         | 
| 
      
 479 
     | 
    
         
            +
                    table_options[:options] = raw_table_options unless raw_table_options == "ENGINE=InnoDB"
         
     | 
| 
       434 
480 
     | 
    
         
             
                    table_options
         
     | 
| 
       435 
481 
     | 
    
         
             
                  end
         
     | 
| 
       436 
482 
     | 
    
         | 
| 
         @@ -456,21 +502,6 @@ module ActiveRecord 
     | 
|
| 
       456 
502 
     | 
    
         
             
                    SQL
         
     | 
| 
       457 
503 
     | 
    
         
             
                  end
         
     | 
| 
       458 
504 
     | 
    
         | 
| 
       459 
     | 
    
         
            -
                  def default_uniqueness_comparison(attribute, value, klass) # :nodoc:
         
     | 
| 
       460 
     | 
    
         
            -
                    column = column_for_attribute(attribute)
         
     | 
| 
       461 
     | 
    
         
            -
             
     | 
| 
       462 
     | 
    
         
            -
                    if column.collation && !column.case_sensitive? && !value.nil?
         
     | 
| 
       463 
     | 
    
         
            -
                      ActiveSupport::Deprecation.warn(<<~MSG.squish)
         
     | 
| 
       464 
     | 
    
         
            -
                        Uniqueness validator will no longer enforce case sensitive comparison in Rails 6.1.
         
     | 
| 
       465 
     | 
    
         
            -
                        To continue case sensitive comparison on the :#{attribute.name} attribute in #{klass} model,
         
     | 
| 
       466 
     | 
    
         
            -
                        pass `case_sensitive: true` option explicitly to the uniqueness validator.
         
     | 
| 
       467 
     | 
    
         
            -
                      MSG
         
     | 
| 
       468 
     | 
    
         
            -
                      attribute.eq(Arel::Nodes::Bin.new(value))
         
     | 
| 
       469 
     | 
    
         
            -
                    else
         
     | 
| 
       470 
     | 
    
         
            -
                      super
         
     | 
| 
       471 
     | 
    
         
            -
                    end
         
     | 
| 
       472 
     | 
    
         
            -
                  end
         
     | 
| 
       473 
     | 
    
         
            -
             
     | 
| 
       474 
505 
     | 
    
         
             
                  def case_sensitive_comparison(attribute, value) # :nodoc:
         
     | 
| 
       475 
506 
     | 
    
         
             
                    column = column_for_attribute(attribute)
         
     | 
| 
       476 
507 
     | 
    
         | 
| 
         @@ -489,14 +520,14 @@ module ActiveRecord 
     | 
|
| 
       489 
520 
     | 
    
         
             
                  # In MySQL 5.7.5 and up, ONLY_FULL_GROUP_BY affects handling of queries that use
         
     | 
| 
       490 
521 
     | 
    
         
             
                  # DISTINCT and ORDER BY. It requires the ORDER BY columns in the select list for
         
     | 
| 
       491 
522 
     | 
    
         
             
                  # distinct queries, and requires that the ORDER BY include the distinct column.
         
     | 
| 
       492 
     | 
    
         
            -
                  # See https://dev.mysql.com/doc/refman/ 
     | 
| 
      
 523 
     | 
    
         
            +
                  # See https://dev.mysql.com/doc/refman/en/group-by-handling.html
         
     | 
| 
       493 
524 
     | 
    
         
             
                  def columns_for_distinct(columns, orders) # :nodoc:
         
     | 
| 
       494 
     | 
    
         
            -
                    order_columns = orders. 
     | 
| 
      
 525 
     | 
    
         
            +
                    order_columns = orders.compact_blank.map { |s|
         
     | 
| 
       495 
526 
     | 
    
         
             
                      # Convert Arel node to string
         
     | 
| 
       496 
527 
     | 
    
         
             
                      s = visitor.compile(s) unless s.is_a?(String)
         
     | 
| 
       497 
528 
     | 
    
         
             
                      # Remove any ASC/DESC modifiers
         
     | 
| 
       498 
529 
     | 
    
         
             
                      s.gsub(/\s+(?:ASC|DESC)\b/i, "")
         
     | 
| 
       499 
     | 
    
         
            -
                    }. 
     | 
| 
      
 530 
     | 
    
         
            +
                    }.compact_blank.map.with_index { |column, i| "#{column} AS alias_#{i}" }
         
     | 
| 
       500 
531 
     | 
    
         | 
| 
       501 
532 
     | 
    
         
             
                    (order_columns << super).join(", ")
         
     | 
| 
       502 
533 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -517,6 +548,7 @@ module ActiveRecord 
     | 
|
| 
       517 
548 
     | 
    
         
             
                      sql << " ON DUPLICATE KEY UPDATE #{no_op_column}=#{no_op_column}"
         
     | 
| 
       518 
549 
     | 
    
         
             
                    elsif insert.update_duplicates?
         
     | 
| 
       519 
550 
     | 
    
         
             
                      sql << " ON DUPLICATE KEY UPDATE "
         
     | 
| 
      
 551 
     | 
    
         
            +
                      sql << insert.touch_model_timestamps_unless { |column| "#{column}<=>VALUES(#{column})" }
         
     | 
| 
       520 
552 
     | 
    
         
             
                      sql << insert.updatable_columns.map { |column| "#{column}=VALUES(#{column})" }.join(",")
         
     | 
| 
       521 
553 
     | 
    
         
             
                    end
         
     | 
| 
       522 
554 
     | 
    
         | 
| 
         @@ -533,7 +565,10 @@ module ActiveRecord 
     | 
|
| 
       533 
565 
     | 
    
         
             
                    def initialize_type_map(m = type_map)
         
     | 
| 
       534 
566 
     | 
    
         
             
                      super
         
     | 
| 
       535 
567 
     | 
    
         | 
| 
       536 
     | 
    
         
            -
                       
     | 
| 
      
 568 
     | 
    
         
            +
                      m.register_type(%r(char)i) do |sql_type|
         
     | 
| 
      
 569 
     | 
    
         
            +
                        limit = extract_limit(sql_type)
         
     | 
| 
      
 570 
     | 
    
         
            +
                        Type.lookup(:string, adapter: :mysql2, limit: limit)
         
     | 
| 
      
 571 
     | 
    
         
            +
                      end
         
     | 
| 
       537 
572 
     | 
    
         | 
| 
       538 
573 
     | 
    
         
             
                      m.register_type %r(tinytext)i,   Type::Text.new(limit: 2**8 - 1)
         
     | 
| 
       539 
574 
     | 
    
         
             
                      m.register_type %r(tinyblob)i,   Type::Binary.new(limit: 2**8 - 1)
         
     | 
| 
         @@ -553,20 +588,11 @@ module ActiveRecord 
     | 
|
| 
       553 
588 
     | 
    
         
             
                      register_integer_type m, %r(^tinyint)i,   limit: 1
         
     | 
| 
       554 
589 
     | 
    
         | 
| 
       555 
590 
     | 
    
         
             
                      m.register_type %r(^tinyint\(1\))i, Type::Boolean.new if emulate_booleans
         
     | 
| 
       556 
     | 
    
         
            -
                      m.alias_type %r(year)i, 
     | 
| 
       557 
     | 
    
         
            -
                      m.alias_type %r(bit)i, 
     | 
| 
      
 591 
     | 
    
         
            +
                      m.alias_type %r(year)i, "integer"
         
     | 
| 
      
 592 
     | 
    
         
            +
                      m.alias_type %r(bit)i,  "binary"
         
     | 
| 
       558 
593 
     | 
    
         | 
| 
       559 
     | 
    
         
            -
                      m.register_type 
     | 
| 
       560 
     | 
    
         
            -
             
     | 
| 
       561 
     | 
    
         
            -
                          .split(",").map { |enum| enum.strip.length - 2 }.max
         
     | 
| 
       562 
     | 
    
         
            -
                        MysqlString.new(limit: limit)
         
     | 
| 
       563 
     | 
    
         
            -
                      end
         
     | 
| 
       564 
     | 
    
         
            -
             
     | 
| 
       565 
     | 
    
         
            -
                      m.register_type(%r(^set)i) do |sql_type|
         
     | 
| 
       566 
     | 
    
         
            -
                        limit = sql_type[/^set\s*\((.+)\)/i, 1]
         
     | 
| 
       567 
     | 
    
         
            -
                          .split(",").map { |set| set.strip.length - 1 }.sum - 1
         
     | 
| 
       568 
     | 
    
         
            -
                        MysqlString.new(limit: limit)
         
     | 
| 
       569 
     | 
    
         
            -
                      end
         
     | 
| 
      
 594 
     | 
    
         
            +
                      m.register_type %r(^enum)i, Type.lookup(:string, adapter: :mysql2)
         
     | 
| 
      
 595 
     | 
    
         
            +
                      m.register_type %r(^set)i,  Type.lookup(:string, adapter: :mysql2)
         
     | 
| 
       570 
596 
     | 
    
         
             
                    end
         
     | 
| 
       571 
597 
     | 
    
         | 
| 
       572 
598 
     | 
    
         
             
                    def register_integer_type(mapping, key, **options)
         
     | 
| 
         @@ -587,7 +613,8 @@ module ActiveRecord 
     | 
|
| 
       587 
613 
     | 
    
         
             
                      end
         
     | 
| 
       588 
614 
     | 
    
         
             
                    end
         
     | 
| 
       589 
615 
     | 
    
         | 
| 
       590 
     | 
    
         
            -
                    # See https://dev.mysql.com/doc/ 
     | 
| 
      
 616 
     | 
    
         
            +
                    # See https://dev.mysql.com/doc/mysql-errors/en/server-error-reference.html
         
     | 
| 
      
 617 
     | 
    
         
            +
                    ER_DB_CREATE_EXISTS     = 1007
         
     | 
| 
       591 
618 
     | 
    
         
             
                    ER_FILSORT_ABORT        = 1028
         
     | 
| 
       592 
619 
     | 
    
         
             
                    ER_DUP_ENTRY            = 1062
         
     | 
| 
       593 
620 
     | 
    
         
             
                    ER_NOT_NULL_VIOLATION   = 1048
         
     | 
| 
         @@ -608,6 +635,14 @@ module ActiveRecord 
     | 
|
| 
       608 
635 
     | 
    
         | 
| 
       609 
636 
     | 
    
         
             
                    def translate_exception(exception, message:, sql:, binds:)
         
     | 
| 
       610 
637 
     | 
    
         
             
                      case error_number(exception)
         
     | 
| 
      
 638 
     | 
    
         
            +
                      when nil
         
     | 
| 
      
 639 
     | 
    
         
            +
                        if exception.message.match?(/MySQL client is not connected/i)
         
     | 
| 
      
 640 
     | 
    
         
            +
                          ConnectionNotEstablished.new(exception)
         
     | 
| 
      
 641 
     | 
    
         
            +
                        else
         
     | 
| 
      
 642 
     | 
    
         
            +
                          super
         
     | 
| 
      
 643 
     | 
    
         
            +
                        end
         
     | 
| 
      
 644 
     | 
    
         
            +
                      when ER_DB_CREATE_EXISTS
         
     | 
| 
      
 645 
     | 
    
         
            +
                        DatabaseAlreadyExists.new(message, sql: sql, binds: binds)
         
     | 
| 
       611 
646 
     | 
    
         
             
                      when ER_DUP_ENTRY
         
     | 
| 
       612 
647 
     | 
    
         
             
                        RecordNotUnique.new(message, sql: sql, binds: binds)
         
     | 
| 
       613 
648 
     | 
    
         
             
                      when ER_NO_REFERENCED_ROW, ER_ROW_IS_REFERENCED, ER_ROW_IS_REFERENCED_2, ER_NO_REFERENCED_ROW_2
         
     | 
| 
         @@ -639,7 +674,7 @@ module ActiveRecord 
     | 
|
| 
       639 
674 
     | 
    
         
             
                      end
         
     | 
| 
       640 
675 
     | 
    
         
             
                    end
         
     | 
| 
       641 
676 
     | 
    
         | 
| 
       642 
     | 
    
         
            -
                    def change_column_for_alter(table_name, column_name, type, options 
     | 
| 
      
 677 
     | 
    
         
            +
                    def change_column_for_alter(table_name, column_name, type, **options)
         
     | 
| 
       643 
678 
     | 
    
         
             
                      column = column_for(table_name, column_name)
         
     | 
| 
       644 
679 
     | 
    
         
             
                      type ||= column.sql_type
         
     | 
| 
       645 
680 
     | 
    
         | 
| 
         @@ -661,11 +696,14 @@ module ActiveRecord 
     | 
|
| 
       661 
696 
     | 
    
         
             
                    end
         
     | 
| 
       662 
697 
     | 
    
         | 
| 
       663 
698 
     | 
    
         
             
                    def rename_column_for_alter(table_name, column_name, new_column_name)
         
     | 
| 
      
 699 
     | 
    
         
            +
                      return rename_column_sql(table_name, column_name, new_column_name) if supports_rename_column?
         
     | 
| 
      
 700 
     | 
    
         
            +
             
     | 
| 
       664 
701 
     | 
    
         
             
                      column  = column_for(table_name, column_name)
         
     | 
| 
       665 
702 
     | 
    
         
             
                      options = {
         
     | 
| 
       666 
703 
     | 
    
         
             
                        default: column.default,
         
     | 
| 
       667 
704 
     | 
    
         
             
                        null: column.null,
         
     | 
| 
       668 
     | 
    
         
            -
                        auto_increment: column.auto_increment 
     | 
| 
      
 705 
     | 
    
         
            +
                        auto_increment: column.auto_increment?,
         
     | 
| 
      
 706 
     | 
    
         
            +
                        comment: column.comment
         
     | 
| 
       669 
707 
     | 
    
         
             
                      }
         
     | 
| 
       670 
708 
     | 
    
         | 
| 
       671 
709 
     | 
    
         
             
                      current_type = exec_query("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE #{quote(column_name)}", "SCHEMA").first["Type"]
         
     | 
| 
         @@ -674,15 +712,15 @@ module ActiveRecord 
     | 
|
| 
       674 
712 
     | 
    
         
             
                      schema_creation.accept(ChangeColumnDefinition.new(cd, column.name))
         
     | 
| 
       675 
713 
     | 
    
         
             
                    end
         
     | 
| 
       676 
714 
     | 
    
         | 
| 
       677 
     | 
    
         
            -
                    def add_index_for_alter(table_name, column_name, options 
     | 
| 
       678 
     | 
    
         
            -
                       
     | 
| 
       679 
     | 
    
         
            -
                       
     | 
| 
       680 
     | 
    
         
            -
             
     | 
| 
       681 
     | 
    
         
            -
                       
     | 
| 
      
 715 
     | 
    
         
            +
                    def add_index_for_alter(table_name, column_name, **options)
         
     | 
| 
      
 716 
     | 
    
         
            +
                      index, algorithm, _ = add_index_options(table_name, column_name, **options)
         
     | 
| 
      
 717 
     | 
    
         
            +
                      algorithm = ", #{algorithm}" if algorithm
         
     | 
| 
      
 718 
     | 
    
         
            +
             
     | 
| 
      
 719 
     | 
    
         
            +
                      "ADD #{schema_creation.accept(index)}#{algorithm}"
         
     | 
| 
       682 
720 
     | 
    
         
             
                    end
         
     | 
| 
       683 
721 
     | 
    
         | 
| 
       684 
     | 
    
         
            -
                    def remove_index_for_alter(table_name,  
     | 
| 
       685 
     | 
    
         
            -
                      index_name = index_name_for_remove(table_name, options)
         
     | 
| 
      
 722 
     | 
    
         
            +
                    def remove_index_for_alter(table_name, column_name = nil, **options)
         
     | 
| 
      
 723 
     | 
    
         
            +
                      index_name = index_name_for_remove(table_name, column_name, options)
         
     | 
| 
       686 
724 
     | 
    
         
             
                      "DROP INDEX #{quote_column_name(index_name)}"
         
     | 
| 
       687 
725 
     | 
    
         
             
                    end
         
     | 
| 
       688 
726 
     | 
    
         | 
| 
         @@ -694,6 +732,14 @@ module ActiveRecord 
     | 
|
| 
       694 
732 
     | 
    
         
             
                      end
         
     | 
| 
       695 
733 
     | 
    
         
             
                    end
         
     | 
| 
       696 
734 
     | 
    
         | 
| 
      
 735 
     | 
    
         
            +
                    def supports_rename_column?
         
     | 
| 
      
 736 
     | 
    
         
            +
                      if mariadb?
         
     | 
| 
      
 737 
     | 
    
         
            +
                        database_version >= "10.5.2"
         
     | 
| 
      
 738 
     | 
    
         
            +
                      else
         
     | 
| 
      
 739 
     | 
    
         
            +
                        database_version >= "8.0.3"
         
     | 
| 
      
 740 
     | 
    
         
            +
                      end
         
     | 
| 
      
 741 
     | 
    
         
            +
                    end
         
     | 
| 
      
 742 
     | 
    
         
            +
             
     | 
| 
       697 
743 
     | 
    
         
             
                    def configure_connection
         
     | 
| 
       698 
744 
     | 
    
         
             
                      variables = @config.fetch(:variables, {}).stringify_keys
         
     | 
| 
       699 
745 
     | 
    
         | 
| 
         @@ -708,7 +754,7 @@ module ActiveRecord 
     | 
|
| 
       708 
754 
     | 
    
         
             
                      defaults = [":default", :default].to_set
         
     | 
| 
       709 
755 
     | 
    
         | 
| 
       710 
756 
     | 
    
         
             
                      # Make MySQL reject illegal values rather than truncating or blanking them, see
         
     | 
| 
       711 
     | 
    
         
            -
                      # https://dev.mysql.com/doc/refman/ 
     | 
| 
      
 757 
     | 
    
         
            +
                      # https://dev.mysql.com/doc/refman/en/sql-mode.html#sqlmode_strict_all_tables
         
     | 
| 
       712 
758 
     | 
    
         
             
                      # If the user has provided another value for sql_mode, don't replace it.
         
     | 
| 
       713 
759 
     | 
    
         
             
                      if sql_mode = variables.delete("sql_mode")
         
     | 
| 
       714 
760 
     | 
    
         
             
                        sql_mode = quote(sql_mode)
         
     | 
| 
         @@ -725,7 +771,7 @@ module ActiveRecord 
     | 
|
| 
       725 
771 
     | 
    
         
             
                      sql_mode_assignment = "@@SESSION.sql_mode = #{sql_mode}, " if sql_mode
         
     | 
| 
       726 
772 
     | 
    
         | 
| 
       727 
773 
     | 
    
         
             
                      # NAMES does not have an equals sign, see
         
     | 
| 
       728 
     | 
    
         
            -
                      # https://dev.mysql.com/doc/refman/ 
     | 
| 
      
 774 
     | 
    
         
            +
                      # https://dev.mysql.com/doc/refman/en/set-names.html
         
     | 
| 
       729 
775 
     | 
    
         
             
                      # (trailing comma because variable_assignments will always have content)
         
     | 
| 
       730 
776 
     | 
    
         
             
                      if @config[:encoding]
         
     | 
| 
       731 
777 
     | 
    
         
             
                        encoding = +"NAMES #{@config[:encoding]}"
         
     | 
| 
         @@ -793,26 +839,16 @@ module ActiveRecord 
     | 
|
| 
       793 
839 
     | 
    
         
             
                      full_version_string.match(/^(?:5\.5\.5-)?(\d+\.\d+\.\d+)/)[1]
         
     | 
| 
       794 
840 
     | 
    
         
             
                    end
         
     | 
| 
       795 
841 
     | 
    
         | 
| 
       796 
     | 
    
         
            -
                     
     | 
| 
       797 
     | 
    
         
            -
             
     | 
| 
       798 
     | 
    
         
            -
             
     | 
| 
       799 
     | 
    
         
            -
                        when true then "1"
         
     | 
| 
       800 
     | 
    
         
            -
                        when false then "0"
         
     | 
| 
       801 
     | 
    
         
            -
                        else super
         
     | 
| 
       802 
     | 
    
         
            -
                        end
         
     | 
| 
       803 
     | 
    
         
            -
                      end
         
     | 
| 
      
 842 
     | 
    
         
            +
                    # Alias MysqlString to work Mashal.load(File.read("legacy_record.dump")).
         
     | 
| 
      
 843 
     | 
    
         
            +
                    # TODO: Remove the constant alias once Rails 6.1 has released.
         
     | 
| 
      
 844 
     | 
    
         
            +
                    MysqlString = Type::String # :nodoc:
         
     | 
| 
       804 
845 
     | 
    
         | 
| 
       805 
     | 
    
         
            -
             
     | 
| 
       806 
     | 
    
         
            -
             
     | 
| 
       807 
     | 
    
         
            -
             
     | 
| 
       808 
     | 
    
         
            -
             
     | 
| 
       809 
     | 
    
         
            -
             
     | 
| 
       810 
     | 
    
         
            -
                          else super
         
     | 
| 
       811 
     | 
    
         
            -
                          end
         
     | 
| 
       812 
     | 
    
         
            -
                        end
         
     | 
| 
      
 846 
     | 
    
         
            +
                    ActiveRecord::Type.register(:immutable_string, adapter: :mysql2) do |_, **args|
         
     | 
| 
      
 847 
     | 
    
         
            +
                      Type::ImmutableString.new(true: "1", false: "0", **args)
         
     | 
| 
      
 848 
     | 
    
         
            +
                    end
         
     | 
| 
      
 849 
     | 
    
         
            +
                    ActiveRecord::Type.register(:string, adapter: :mysql2) do |_, **args|
         
     | 
| 
      
 850 
     | 
    
         
            +
                      Type::String.new(true: "1", false: "0", **args)
         
     | 
| 
       813 
851 
     | 
    
         
             
                    end
         
     | 
| 
       814 
     | 
    
         
            -
             
     | 
| 
       815 
     | 
    
         
            -
                    ActiveRecord::Type.register(:string, MysqlString, adapter: :mysql2)
         
     | 
| 
       816 
852 
     | 
    
         
             
                    ActiveRecord::Type.register(:unsigned_integer, Type::UnsignedInteger, adapter: :mysql2)
         
     | 
| 
       817 
853 
     | 
    
         
             
                end
         
     | 
| 
       818 
854 
     | 
    
         
             
              end
         
     | 
| 
         @@ -5,6 +5,8 @@ module ActiveRecord 
     | 
|
| 
       5 
5 
     | 
    
         
             
              module ConnectionAdapters
         
     | 
| 
       6 
6 
     | 
    
         
             
                # An abstract definition of a column in a table.
         
     | 
| 
       7 
7 
     | 
    
         
             
                class Column
         
     | 
| 
      
 8 
     | 
    
         
            +
                  include Deduplicable
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
       8 
10 
     | 
    
         
             
                  attr_reader :name, :default, :sql_type_metadata, :null, :default_function, :collation, :comment
         
     | 
| 
       9 
11 
     | 
    
         | 
| 
       10 
12 
     | 
    
         
             
                  delegate :precision, :scale, :limit, :type, :sql_type, to: :sql_type_metadata, allow_nil: true
         
     | 
| 
         @@ -76,6 +78,7 @@ module ActiveRecord 
     | 
|
| 
       76 
78 
     | 
    
         
             
                  def hash
         
     | 
| 
       77 
79 
     | 
    
         
             
                    Column.hash ^
         
     | 
| 
       78 
80 
     | 
    
         
             
                      name.hash ^
         
     | 
| 
      
 81 
     | 
    
         
            +
                      name.encoding.hash ^
         
     | 
| 
       79 
82 
     | 
    
         
             
                      default.hash ^
         
     | 
| 
       80 
83 
     | 
    
         
             
                      sql_type_metadata.hash ^
         
     | 
| 
       81 
84 
     | 
    
         
             
                      null.hash ^
         
     | 
| 
         @@ -83,10 +86,21 @@ module ActiveRecord 
     | 
|
| 
       83 
86 
     | 
    
         
             
                      collation.hash ^
         
     | 
| 
       84 
87 
     | 
    
         
             
                      comment.hash
         
     | 
| 
       85 
88 
     | 
    
         
             
                  end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                  private
         
     | 
| 
      
 91 
     | 
    
         
            +
                    def deduplicated
         
     | 
| 
      
 92 
     | 
    
         
            +
                      @name = -name
         
     | 
| 
      
 93 
     | 
    
         
            +
                      @sql_type_metadata = sql_type_metadata.deduplicate if sql_type_metadata
         
     | 
| 
      
 94 
     | 
    
         
            +
                      @default = -default if default
         
     | 
| 
      
 95 
     | 
    
         
            +
                      @default_function = -default_function if default_function
         
     | 
| 
      
 96 
     | 
    
         
            +
                      @collation = -collation if collation
         
     | 
| 
      
 97 
     | 
    
         
            +
                      @comment = -comment if comment
         
     | 
| 
      
 98 
     | 
    
         
            +
                      super
         
     | 
| 
      
 99 
     | 
    
         
            +
                    end
         
     | 
| 
       86 
100 
     | 
    
         
             
                end
         
     | 
| 
       87 
101 
     | 
    
         | 
| 
       88 
102 
     | 
    
         
             
                class NullColumn < Column
         
     | 
| 
       89 
     | 
    
         
            -
                  def initialize(name)
         
     | 
| 
      
 103 
     | 
    
         
            +
                  def initialize(name, **)
         
     | 
| 
       90 
104 
     | 
    
         
             
                    super(name, nil)
         
     | 
| 
       91 
105 
     | 
    
         
             
                  end
         
     | 
| 
       92 
106 
     | 
    
         
             
                end
         
     | 
| 
         @@ -0,0 +1,29 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module ActiveRecord
         
     | 
| 
      
 4 
     | 
    
         
            +
              module ConnectionAdapters # :nodoc:
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Deduplicable
         
     | 
| 
      
 6 
     | 
    
         
            +
                  extend ActiveSupport::Concern
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  module ClassMethods
         
     | 
| 
      
 9 
     | 
    
         
            +
                    def registry
         
     | 
| 
      
 10 
     | 
    
         
            +
                      @registry ||= {}
         
     | 
| 
      
 11 
     | 
    
         
            +
                    end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                    def new(*, **)
         
     | 
| 
      
 14 
     | 
    
         
            +
                      super.deduplicate
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  def deduplicate
         
     | 
| 
      
 19 
     | 
    
         
            +
                    self.class.registry[self] ||= deduplicated
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  alias :-@ :deduplicate
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                  private
         
     | 
| 
      
 24 
     | 
    
         
            +
                    def deduplicated
         
     | 
| 
      
 25 
     | 
    
         
            +
                      freeze
         
     | 
| 
      
 26 
     | 
    
         
            +
                    end
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module ActiveRecord
         
     | 
| 
      
 4 
     | 
    
         
            +
              module ConnectionAdapters
         
     | 
| 
      
 5 
     | 
    
         
            +
                class LegacyPoolManager # :nodoc:
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def initialize
         
     | 
| 
      
 7 
     | 
    
         
            +
                    @name_to_pool_config = {}
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def shard_names
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @name_to_pool_config.keys
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def pool_configs(_ = nil)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @name_to_pool_config.values
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  def remove_pool_config(_, shard)
         
     | 
| 
      
 19 
     | 
    
         
            +
                    @name_to_pool_config.delete(shard)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  def get_pool_config(_, shard)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    @name_to_pool_config[shard]
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  def set_pool_config(role, shard, pool_config)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    if pool_config
         
     | 
| 
      
 28 
     | 
    
         
            +
                      @name_to_pool_config[shard] = pool_config
         
     | 
| 
      
 29 
     | 
    
         
            +
                    else
         
     | 
| 
      
 30 
     | 
    
         
            +
                      raise ArgumentError, "The `pool_config` for the :#{role} role and :#{shard} shard was `nil`. Please check your configuration. If you want your writing role to be something other than `:writing` set `config.active_record.writing_role` in your application configuration. The same setting should be applied for the `reading_role` if applicable."
         
     | 
| 
      
 31 
     | 
    
         
            +
                    end
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -26,6 +26,17 @@ module ActiveRecord 
     | 
|
| 
       26 
26 
     | 
    
         | 
| 
       27 
27 
     | 
    
         
             
                    def write_query?(sql) # :nodoc:
         
     | 
| 
       28 
28 
     | 
    
         
             
                      !READ_QUERY.match?(sql)
         
     | 
| 
      
 29 
     | 
    
         
            +
                    rescue ArgumentError # Invalid encoding
         
     | 
| 
      
 30 
     | 
    
         
            +
                      !READ_QUERY.match?(sql.b)
         
     | 
| 
      
 31 
     | 
    
         
            +
                    end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                    def explain(arel, binds = [])
         
     | 
| 
      
 34 
     | 
    
         
            +
                      sql     = "EXPLAIN #{to_sql(arel, binds)}"
         
     | 
| 
      
 35 
     | 
    
         
            +
                      start   = Concurrent.monotonic_time
         
     | 
| 
      
 36 
     | 
    
         
            +
                      result  = exec_query(sql, "EXPLAIN", binds)
         
     | 
| 
      
 37 
     | 
    
         
            +
                      elapsed = Concurrent.monotonic_time - start
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                      MySQL::ExplainPrettyPrinter.new.pp(result, elapsed)
         
     | 
| 
       29 
40 
     | 
    
         
             
                    end
         
     | 
| 
       30 
41 
     | 
    
         | 
| 
       31 
42 
     | 
    
         
             
                    # Executes the SQL statement in the context of this connection.
         
     | 
| 
         @@ -45,17 +56,17 @@ module ActiveRecord 
     | 
|
| 
       45 
56 
     | 
    
         
             
                      if without_prepared_statement?(binds)
         
     | 
| 
       46 
57 
     | 
    
         
             
                        execute_and_free(sql, name) do |result|
         
     | 
| 
       47 
58 
     | 
    
         
             
                          if result
         
     | 
| 
       48 
     | 
    
         
            -
                             
     | 
| 
      
 59 
     | 
    
         
            +
                            build_result(columns: result.fields, rows: result.to_a)
         
     | 
| 
       49 
60 
     | 
    
         
             
                          else
         
     | 
| 
       50 
     | 
    
         
            -
                             
     | 
| 
      
 61 
     | 
    
         
            +
                            build_result(columns: [], rows: [])
         
     | 
| 
       51 
62 
     | 
    
         
             
                          end
         
     | 
| 
       52 
63 
     | 
    
         
             
                        end
         
     | 
| 
       53 
64 
     | 
    
         
             
                      else
         
     | 
| 
       54 
65 
     | 
    
         
             
                        exec_stmt_and_free(sql, name, binds, cache_stmt: prepare) do |_, result|
         
     | 
| 
       55 
66 
     | 
    
         
             
                          if result
         
     | 
| 
       56 
     | 
    
         
            -
                             
     | 
| 
      
 67 
     | 
    
         
            +
                            build_result(columns: result.fields, rows: result.to_a)
         
     | 
| 
       57 
68 
     | 
    
         
             
                          else
         
     | 
| 
       58 
     | 
    
         
            -
                             
     | 
| 
      
 69 
     | 
    
         
            +
                            build_result(columns: [], rows: [])
         
     | 
| 
       59 
70 
     | 
    
         
             
                          end
         
     | 
| 
       60 
71 
     | 
    
         
             
                        end
         
     | 
| 
       61 
72 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -88,39 +99,27 @@ module ActiveRecord 
     | 
|
| 
       88 
99 
     | 
    
         
             
                        @connection.last_id
         
     | 
| 
       89 
100 
     | 
    
         
             
                      end
         
     | 
| 
       90 
101 
     | 
    
         | 
| 
       91 
     | 
    
         
            -
                      def  
     | 
| 
       92 
     | 
    
         
            -
                        @ 
     | 
| 
       93 
     | 
    
         
            -
                      end
         
     | 
| 
      
 102 
     | 
    
         
            +
                      def multi_statements_enabled?
         
     | 
| 
      
 103 
     | 
    
         
            +
                        flags = @config[:flags]
         
     | 
| 
       94 
104 
     | 
    
         | 
| 
       95 
     | 
    
         
            -
                      def multi_statements_enabled?(flags)
         
     | 
| 
       96 
105 
     | 
    
         
             
                        if flags.is_a?(Array)
         
     | 
| 
       97 
106 
     | 
    
         
             
                          flags.include?("MULTI_STATEMENTS")
         
     | 
| 
       98 
107 
     | 
    
         
             
                        else
         
     | 
| 
       99 
     | 
    
         
            -
                          ( 
     | 
| 
      
 108 
     | 
    
         
            +
                          flags.anybits?(Mysql2::Client::MULTI_STATEMENTS)
         
     | 
| 
       100 
109 
     | 
    
         
             
                        end
         
     | 
| 
       101 
110 
     | 
    
         
             
                      end
         
     | 
| 
       102 
111 
     | 
    
         | 
| 
       103 
112 
     | 
    
         
             
                      def with_multi_statements
         
     | 
| 
       104 
     | 
    
         
            -
                         
     | 
| 
      
 113 
     | 
    
         
            +
                        multi_statements_was = multi_statements_enabled?
         
     | 
| 
       105 
114 
     | 
    
         | 
| 
       106 
     | 
    
         
            -
                        unless  
     | 
| 
       107 
     | 
    
         
            -
                           
     | 
| 
       108 
     | 
    
         
            -
                            @connection.set_server_option(Mysql2::Client::OPTION_MULTI_STATEMENTS_ON)
         
     | 
| 
       109 
     | 
    
         
            -
                          else
         
     | 
| 
       110 
     | 
    
         
            -
                            @config[:flags] = Mysql2::Client::MULTI_STATEMENTS
         
     | 
| 
       111 
     | 
    
         
            -
                            reconnect!
         
     | 
| 
       112 
     | 
    
         
            -
                          end
         
     | 
| 
      
 115 
     | 
    
         
            +
                        unless multi_statements_was
         
     | 
| 
      
 116 
     | 
    
         
            +
                          @connection.set_server_option(Mysql2::Client::OPTION_MULTI_STATEMENTS_ON)
         
     | 
| 
       113 
117 
     | 
    
         
             
                        end
         
     | 
| 
       114 
118 
     | 
    
         | 
| 
       115 
119 
     | 
    
         
             
                        yield
         
     | 
| 
       116 
120 
     | 
    
         
             
                      ensure
         
     | 
| 
       117 
     | 
    
         
            -
                        unless  
     | 
| 
       118 
     | 
    
         
            -
                           
     | 
| 
       119 
     | 
    
         
            -
                            @connection.set_server_option(Mysql2::Client::OPTION_MULTI_STATEMENTS_OFF)
         
     | 
| 
       120 
     | 
    
         
            -
                          else
         
     | 
| 
       121 
     | 
    
         
            -
                            @config[:flags] = previous_flags
         
     | 
| 
       122 
     | 
    
         
            -
                            reconnect!
         
     | 
| 
       123 
     | 
    
         
            -
                          end
         
     | 
| 
      
 121 
     | 
    
         
            +
                        unless multi_statements_was
         
     | 
| 
      
 122 
     | 
    
         
            +
                          @connection.set_server_option(Mysql2::Client::OPTION_MULTI_STATEMENTS_OFF)
         
     | 
| 
       124 
123 
     | 
    
         
             
                        end
         
     | 
| 
       125 
124 
     | 
    
         
             
                      end
         
     | 
| 
       126 
125 
     | 
    
         | 
| 
         @@ -157,6 +156,7 @@ module ActiveRecord 
     | 
|
| 
       157 
156 
     | 
    
         
             
                        end
         
     | 
| 
       158 
157 
     | 
    
         | 
| 
       159 
158 
     | 
    
         
             
                        materialize_transactions
         
     | 
| 
      
 159 
     | 
    
         
            +
                        mark_transaction_written_if_write(sql)
         
     | 
| 
       160 
160 
     | 
    
         | 
| 
       161 
161 
     | 
    
         
             
                        # make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been
         
     | 
| 
       162 
162 
     | 
    
         
             
                        # made since we established the connection
         
     | 
| 
         @@ -56,7 +56,7 @@ module ActiveRecord 
     | 
|
| 
       56 
56 
     | 
    
         
             
                        items.each_with_index do |item, i|
         
     | 
| 
       57 
57 
     | 
    
         
             
                          item = "NULL" if item.nil?
         
     | 
| 
       58 
58 
     | 
    
         
             
                          justifier = item.is_a?(Numeric) ? "rjust" : "ljust"
         
     | 
| 
       59 
     | 
    
         
            -
                          cells << item.to_s. 
     | 
| 
      
 59 
     | 
    
         
            +
                          cells << item.to_s.public_send(justifier, widths[i])
         
     | 
| 
       60 
60 
     | 
    
         
             
                        end
         
     | 
| 
       61 
61 
     | 
    
         
             
                        "| " + cells.join(" | ") + " |"
         
     | 
| 
       62 
62 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -1,5 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            require "active_support/time_with_zone"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
       3 
5 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       4 
6 
     | 
    
         
             
              module ConnectionAdapters
         
     | 
| 
       5 
7 
     | 
    
         
             
                module MySQL
         
     | 
| 
         @@ -47,7 +49,7 @@ module ActiveRecord 
     | 
|
| 
       47 
49 
     | 
    
         
             
                          # `table_name`.`column_name` | function(one or no argument)
         
     | 
| 
       48 
50 
     | 
    
         
             
                          ((?:\w+\.|`\w+`\.)?(?:\w+|`\w+`)) | \w+\((?:|\g<2>)\)
         
     | 
| 
       49 
51 
     | 
    
         
             
                        )
         
     | 
| 
       50 
     | 
    
         
            -
                        (?:\s+AS 
     | 
| 
      
 52 
     | 
    
         
            +
                        (?:(?:\s+AS)?\s+(?:\w+|`\w+`))?
         
     | 
| 
       51 
53 
     | 
    
         
             
                      )
         
     | 
| 
       52 
54 
     | 
    
         
             
                      (?:\s*,\s*\g<1>)*
         
     | 
| 
       53 
55 
     | 
    
         
             
                      \z
         
     | 
| 
         @@ -69,10 +71,23 @@ module ActiveRecord 
     | 
|
| 
       69 
71 
     | 
    
         
             
                    private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
         
     | 
| 
       70 
72 
     | 
    
         | 
| 
       71 
73 
     | 
    
         
             
                    private
         
     | 
| 
      
 74 
     | 
    
         
            +
                      # Override +_type_cast+ we pass to mysql2 Date and Time objects instead
         
     | 
| 
      
 75 
     | 
    
         
            +
                      # of Strings since mysql2 is able to handle those classes more efficiently.
         
     | 
| 
       72 
76 
     | 
    
         
             
                      def _type_cast(value)
         
     | 
| 
       73 
77 
     | 
    
         
             
                        case value
         
     | 
| 
       74 
     | 
    
         
            -
                        when  
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
      
 78 
     | 
    
         
            +
                        when ActiveSupport::TimeWithZone
         
     | 
| 
      
 79 
     | 
    
         
            +
                          # We need to check explicitly for ActiveSupport::TimeWithZone because
         
     | 
| 
      
 80 
     | 
    
         
            +
                          # we need to transform it to Time objects but we don't want to
         
     | 
| 
      
 81 
     | 
    
         
            +
                          # transform Time objects to themselves.
         
     | 
| 
      
 82 
     | 
    
         
            +
                          if ActiveRecord::Base.default_timezone == :utc
         
     | 
| 
      
 83 
     | 
    
         
            +
                            value.getutc
         
     | 
| 
      
 84 
     | 
    
         
            +
                          else
         
     | 
| 
      
 85 
     | 
    
         
            +
                            value.getlocal
         
     | 
| 
      
 86 
     | 
    
         
            +
                          end
         
     | 
| 
      
 87 
     | 
    
         
            +
                        when Date, Time
         
     | 
| 
      
 88 
     | 
    
         
            +
                          value
         
     | 
| 
      
 89 
     | 
    
         
            +
                        else
         
     | 
| 
      
 90 
     | 
    
         
            +
                          super
         
     | 
| 
       76 
91 
     | 
    
         
             
                        end
         
     | 
| 
       77 
92 
     | 
    
         
             
                      end
         
     | 
| 
       78 
93 
     | 
    
         
             
                  end
         
     |