activerecord 4.2.11.3 → 5.0.7.2
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 +1638 -1132
 - data/MIT-LICENSE +2 -2
 - data/README.rdoc +7 -8
 - data/examples/performance.rb +2 -3
 - data/examples/simple.rb +0 -1
 - data/lib/active_record.rb +7 -2
 - data/lib/active_record/aggregations.rb +34 -21
 - data/lib/active_record/association_relation.rb +7 -4
 - data/lib/active_record/associations.rb +347 -218
 - data/lib/active_record/associations/alias_tracker.rb +19 -16
 - data/lib/active_record/associations/association.rb +22 -10
 - data/lib/active_record/associations/association_scope.rb +75 -104
 - data/lib/active_record/associations/belongs_to_association.rb +21 -32
 - data/lib/active_record/associations/builder/association.rb +28 -34
 - data/lib/active_record/associations/builder/belongs_to.rb +43 -18
 - data/lib/active_record/associations/builder/collection_association.rb +7 -19
 - data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +16 -11
 - data/lib/active_record/associations/builder/has_many.rb +4 -4
 - data/lib/active_record/associations/builder/has_one.rb +11 -6
 - data/lib/active_record/associations/builder/singular_association.rb +13 -11
 - data/lib/active_record/associations/collection_association.rb +85 -69
 - data/lib/active_record/associations/collection_proxy.rb +104 -46
 - data/lib/active_record/associations/foreign_association.rb +1 -1
 - data/lib/active_record/associations/has_many_association.rb +21 -78
 - data/lib/active_record/associations/has_many_through_association.rb +6 -47
 - data/lib/active_record/associations/has_one_association.rb +12 -5
 - data/lib/active_record/associations/join_dependency.rb +38 -22
 - data/lib/active_record/associations/join_dependency/join_association.rb +15 -14
 - data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
 - data/lib/active_record/associations/preloader.rb +14 -4
 - data/lib/active_record/associations/preloader/association.rb +52 -71
 - data/lib/active_record/associations/preloader/collection_association.rb +0 -7
 - data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
 - data/lib/active_record/associations/preloader/has_one.rb +0 -8
 - data/lib/active_record/associations/preloader/singular_association.rb +0 -1
 - data/lib/active_record/associations/preloader/through_association.rb +36 -17
 - data/lib/active_record/associations/singular_association.rb +13 -1
 - data/lib/active_record/associations/through_association.rb +12 -4
 - data/lib/active_record/attribute.rb +69 -19
 - data/lib/active_record/attribute/user_provided_default.rb +28 -0
 - data/lib/active_record/attribute_assignment.rb +19 -140
 - data/lib/active_record/attribute_decorators.rb +6 -5
 - data/lib/active_record/attribute_methods.rb +69 -44
 - data/lib/active_record/attribute_methods/before_type_cast.rb +1 -1
 - data/lib/active_record/attribute_methods/dirty.rb +46 -86
 - data/lib/active_record/attribute_methods/primary_key.rb +16 -3
 - data/lib/active_record/attribute_methods/query.rb +2 -2
 - data/lib/active_record/attribute_methods/read.rb +31 -59
 - data/lib/active_record/attribute_methods/serialization.rb +13 -16
 - data/lib/active_record/attribute_methods/time_zone_conversion.rb +61 -14
 - data/lib/active_record/attribute_methods/write.rb +13 -37
 - data/lib/active_record/attribute_mutation_tracker.rb +70 -0
 - data/lib/active_record/attribute_set.rb +32 -3
 - data/lib/active_record/attribute_set/builder.rb +42 -16
 - data/lib/active_record/attributes.rb +199 -81
 - data/lib/active_record/autosave_association.rb +54 -17
 - data/lib/active_record/base.rb +32 -23
 - data/lib/active_record/callbacks.rb +39 -43
 - data/lib/active_record/coders/json.rb +1 -1
 - data/lib/active_record/coders/yaml_column.rb +20 -8
 - data/lib/active_record/collection_cache_key.rb +50 -0
 - data/lib/active_record/connection_adapters/abstract/connection_pool.rb +467 -189
 - data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -3
 - data/lib/active_record/connection_adapters/abstract/database_statements.rb +66 -62
 - data/lib/active_record/connection_adapters/abstract/query_cache.rb +39 -4
 - data/lib/active_record/connection_adapters/abstract/quoting.rb +86 -13
 - data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
 - data/lib/active_record/connection_adapters/abstract/schema_creation.rb +61 -39
 - data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +236 -188
 - data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +72 -17
 - data/lib/active_record/connection_adapters/abstract/schema_statements.rb +407 -156
 - data/lib/active_record/connection_adapters/abstract/transaction.rb +51 -34
 - data/lib/active_record/connection_adapters/abstract_adapter.rb +177 -71
 - data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +433 -399
 - data/lib/active_record/connection_adapters/column.rb +28 -43
 - data/lib/active_record/connection_adapters/connection_specification.rb +15 -27
 - data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +22 -0
 - data/lib/active_record/connection_adapters/mysql/column.rb +50 -0
 - data/lib/active_record/connection_adapters/mysql/database_statements.rb +108 -0
 - data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +70 -0
 - data/lib/active_record/connection_adapters/mysql/quoting.rb +51 -0
 - data/lib/active_record/connection_adapters/mysql/schema_creation.rb +67 -0
 - data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +93 -0
 - data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +54 -0
 - data/lib/active_record/connection_adapters/mysql/type_metadata.rb +32 -0
 - data/lib/active_record/connection_adapters/mysql2_adapter.rb +25 -166
 - data/lib/active_record/connection_adapters/postgresql/column.rb +33 -11
 - data/lib/active_record/connection_adapters/postgresql/database_statements.rb +18 -72
 - data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +42 -0
 - data/lib/active_record/connection_adapters/postgresql/oid.rb +1 -6
 - data/lib/active_record/connection_adapters/postgresql/oid/array.rb +37 -57
 - data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +3 -3
 - data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +7 -22
 - data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +13 -3
 - data/lib/active_record/connection_adapters/postgresql/oid/json.rb +1 -26
 - data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/money.rb +0 -4
 - data/lib/active_record/connection_adapters/postgresql/oid/point.rb +4 -4
 - data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +50 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/range.rb +31 -17
 - data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +0 -4
 - data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/quoting.rb +56 -19
 - data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +29 -10
 - data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -79
 - data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +47 -0
 - data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +250 -154
 - data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +35 -0
 - data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql_adapter.rb +264 -170
 - data/lib/active_record/connection_adapters/schema_cache.rb +36 -23
 - data/lib/active_record/connection_adapters/sql_type_metadata.rb +32 -0
 - data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +19 -0
 - data/lib/active_record/connection_adapters/sqlite3/quoting.rb +48 -0
 - data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
 - data/lib/active_record/connection_adapters/sqlite3_adapter.rb +151 -194
 - data/lib/active_record/connection_adapters/statement_pool.rb +31 -12
 - data/lib/active_record/connection_handling.rb +37 -14
 - data/lib/active_record/core.rb +92 -108
 - data/lib/active_record/counter_cache.rb +13 -24
 - data/lib/active_record/dynamic_matchers.rb +1 -20
 - data/lib/active_record/enum.rb +116 -76
 - data/lib/active_record/errors.rb +87 -48
 - data/lib/active_record/explain.rb +20 -9
 - data/lib/active_record/explain_registry.rb +1 -1
 - data/lib/active_record/explain_subscriber.rb +1 -1
 - data/lib/active_record/fixture_set/file.rb +26 -5
 - data/lib/active_record/fixtures.rb +77 -41
 - data/lib/active_record/gem_version.rb +4 -4
 - data/lib/active_record/inheritance.rb +32 -40
 - data/lib/active_record/integration.rb +17 -14
 - data/lib/active_record/internal_metadata.rb +56 -0
 - data/lib/active_record/legacy_yaml_adapter.rb +18 -2
 - data/lib/active_record/locale/en.yml +3 -2
 - data/lib/active_record/locking/optimistic.rb +15 -15
 - data/lib/active_record/locking/pessimistic.rb +1 -1
 - data/lib/active_record/log_subscriber.rb +48 -24
 - data/lib/active_record/migration.rb +362 -111
 - data/lib/active_record/migration/command_recorder.rb +59 -18
 - data/lib/active_record/migration/compatibility.rb +126 -0
 - data/lib/active_record/model_schema.rb +270 -73
 - data/lib/active_record/nested_attributes.rb +58 -29
 - data/lib/active_record/no_touching.rb +4 -0
 - data/lib/active_record/null_relation.rb +16 -8
 - data/lib/active_record/persistence.rb +152 -90
 - data/lib/active_record/query_cache.rb +18 -23
 - data/lib/active_record/querying.rb +12 -11
 - data/lib/active_record/railtie.rb +23 -16
 - data/lib/active_record/railties/controller_runtime.rb +1 -1
 - data/lib/active_record/railties/databases.rake +52 -41
 - data/lib/active_record/readonly_attributes.rb +1 -1
 - data/lib/active_record/reflection.rb +302 -115
 - data/lib/active_record/relation.rb +187 -120
 - data/lib/active_record/relation/batches.rb +141 -36
 - data/lib/active_record/relation/batches/batch_enumerator.rb +67 -0
 - data/lib/active_record/relation/calculations.rb +92 -117
 - data/lib/active_record/relation/delegation.rb +8 -20
 - data/lib/active_record/relation/finder_methods.rb +173 -89
 - data/lib/active_record/relation/from_clause.rb +32 -0
 - data/lib/active_record/relation/merger.rb +16 -42
 - data/lib/active_record/relation/predicate_builder.rb +120 -107
 - data/lib/active_record/relation/predicate_builder/array_handler.rb +11 -16
 - data/lib/active_record/relation/predicate_builder/association_query_handler.rb +88 -0
 - data/lib/active_record/relation/predicate_builder/base_handler.rb +17 -0
 - data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +17 -0
 - data/lib/active_record/relation/predicate_builder/class_handler.rb +27 -0
 - data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +57 -0
 - data/lib/active_record/relation/predicate_builder/range_handler.rb +33 -0
 - data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
 - data/lib/active_record/relation/query_attribute.rb +19 -0
 - data/lib/active_record/relation/query_methods.rb +308 -244
 - data/lib/active_record/relation/record_fetch_warning.rb +49 -0
 - data/lib/active_record/relation/spawn_methods.rb +4 -7
 - data/lib/active_record/relation/where_clause.rb +174 -0
 - data/lib/active_record/relation/where_clause_factory.rb +38 -0
 - data/lib/active_record/result.rb +11 -4
 - data/lib/active_record/runtime_registry.rb +1 -1
 - data/lib/active_record/sanitization.rb +105 -66
 - data/lib/active_record/schema.rb +26 -22
 - data/lib/active_record/schema_dumper.rb +54 -37
 - data/lib/active_record/schema_migration.rb +11 -14
 - data/lib/active_record/scoping.rb +34 -16
 - data/lib/active_record/scoping/default.rb +28 -10
 - data/lib/active_record/scoping/named.rb +59 -26
 - data/lib/active_record/secure_token.rb +38 -0
 - data/lib/active_record/serialization.rb +3 -5
 - data/lib/active_record/statement_cache.rb +17 -15
 - data/lib/active_record/store.rb +8 -3
 - data/lib/active_record/suppressor.rb +58 -0
 - data/lib/active_record/table_metadata.rb +69 -0
 - data/lib/active_record/tasks/database_tasks.rb +66 -49
 - data/lib/active_record/tasks/mysql_database_tasks.rb +6 -14
 - data/lib/active_record/tasks/postgresql_database_tasks.rb +12 -3
 - data/lib/active_record/tasks/sqlite_database_tasks.rb +5 -1
 - data/lib/active_record/timestamp.rb +20 -9
 - data/lib/active_record/touch_later.rb +63 -0
 - data/lib/active_record/transactions.rb +139 -57
 - data/lib/active_record/type.rb +66 -17
 - data/lib/active_record/type/adapter_specific_registry.rb +130 -0
 - data/lib/active_record/type/date.rb +2 -45
 - data/lib/active_record/type/date_time.rb +2 -49
 - data/lib/active_record/type/internal/abstract_json.rb +33 -0
 - data/lib/active_record/type/internal/timezone.rb +15 -0
 - data/lib/active_record/type/serialized.rb +15 -14
 - data/lib/active_record/type/time.rb +10 -16
 - data/lib/active_record/type/type_map.rb +4 -4
 - data/lib/active_record/type_caster.rb +7 -0
 - data/lib/active_record/type_caster/connection.rb +29 -0
 - data/lib/active_record/type_caster/map.rb +19 -0
 - data/lib/active_record/validations.rb +33 -32
 - data/lib/active_record/validations/absence.rb +23 -0
 - data/lib/active_record/validations/associated.rb +10 -3
 - data/lib/active_record/validations/length.rb +24 -0
 - data/lib/active_record/validations/presence.rb +11 -12
 - data/lib/active_record/validations/uniqueness.rb +33 -33
 - data/lib/rails/generators/active_record/migration.rb +15 -0
 - data/lib/rails/generators/active_record/migration/migration_generator.rb +8 -5
 - data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +8 -3
 - data/lib/rails/generators/active_record/migration/templates/migration.rb +8 -1
 - data/lib/rails/generators/active_record/model/model_generator.rb +33 -16
 - data/lib/rails/generators/active_record/model/templates/application_record.rb +5 -0
 - data/lib/rails/generators/active_record/model/templates/model.rb +3 -0
 - metadata +58 -34
 - data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
 - data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
 - data/lib/active_record/connection_adapters/postgresql/oid/date.rb +0 -11
 - data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
 - data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
 - data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
 - data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
 - data/lib/active_record/serializers/xml_serializer.rb +0 -193
 - data/lib/active_record/type/big_integer.rb +0 -13
 - data/lib/active_record/type/binary.rb +0 -50
 - data/lib/active_record/type/boolean.rb +0 -31
 - data/lib/active_record/type/decimal.rb +0 -64
 - data/lib/active_record/type/decimal_without_scale.rb +0 -11
 - data/lib/active_record/type/decorator.rb +0 -14
 - data/lib/active_record/type/float.rb +0 -19
 - data/lib/active_record/type/integer.rb +0 -59
 - data/lib/active_record/type/mutable.rb +0 -16
 - data/lib/active_record/type/numeric.rb +0 -36
 - data/lib/active_record/type/string.rb +0 -40
 - data/lib/active_record/type/text.rb +0 -11
 - data/lib/active_record/type/time_value.rb +0 -38
 - data/lib/active_record/type/unsigned_integer.rb +0 -15
 - data/lib/active_record/type/value.rb +0 -110
 
| 
         @@ -1,184 +1,93 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require ' 
     | 
| 
      
 1 
     | 
    
         
            +
            require 'active_record/connection_adapters/abstract_adapter'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'active_record/connection_adapters/statement_pool'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'active_record/connection_adapters/mysql/column'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'active_record/connection_adapters/mysql/explain_pretty_printer'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'active_record/connection_adapters/mysql/quoting'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'active_record/connection_adapters/mysql/schema_creation'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'active_record/connection_adapters/mysql/schema_definitions'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require 'active_record/connection_adapters/mysql/schema_dumper'
         
     | 
| 
      
 9 
     | 
    
         
            +
            require 'active_record/connection_adapters/mysql/type_metadata'
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
       2 
11 
     | 
    
         
             
            require 'active_support/core_ext/string/strip'
         
     | 
| 
       3 
12 
     | 
    
         | 
| 
       4 
13 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       5 
14 
     | 
    
         
             
              module ConnectionAdapters
         
     | 
| 
       6 
15 
     | 
    
         
             
                class AbstractMysqlAdapter < AbstractAdapter
         
     | 
| 
       7 
     | 
    
         
            -
                  include  
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
                  class SchemaCreation < AbstractAdapter::SchemaCreation
         
     | 
| 
       10 
     | 
    
         
            -
                    def visit_AddColumn(o)
         
     | 
| 
       11 
     | 
    
         
            -
                      add_column_position!(super, column_options(o))
         
     | 
| 
       12 
     | 
    
         
            -
                    end
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
                    private
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
                    def visit_DropForeignKey(name)
         
     | 
| 
       17 
     | 
    
         
            -
                      "DROP FOREIGN KEY #{name}"
         
     | 
| 
       18 
     | 
    
         
            -
                    end
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                    def visit_TableDefinition(o)
         
     | 
| 
       21 
     | 
    
         
            -
                      name = o.name
         
     | 
| 
       22 
     | 
    
         
            -
                      create_sql = "CREATE#{' TEMPORARY' if o.temporary} TABLE #{quote_table_name(name)} "
         
     | 
| 
      
 16 
     | 
    
         
            +
                  include MySQL::Quoting
         
     | 
| 
      
 17 
     | 
    
         
            +
                  include MySQL::ColumnDumper
         
     | 
| 
       23 
18 
     | 
    
         | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                      create_sql << "(#{statements.join(', ')}) " if statements.present?
         
     | 
| 
       28 
     | 
    
         
            -
                      create_sql << "#{o.options}"
         
     | 
| 
       29 
     | 
    
         
            -
                      create_sql << " AS #{@conn.to_sql(o.as)}" if o.as
         
     | 
| 
       30 
     | 
    
         
            -
                      create_sql
         
     | 
| 
       31 
     | 
    
         
            -
                    end
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
                    def visit_ChangeColumnDefinition(o)
         
     | 
| 
       34 
     | 
    
         
            -
                      column = o.column
         
     | 
| 
       35 
     | 
    
         
            -
                      options = o.options
         
     | 
| 
       36 
     | 
    
         
            -
                      sql_type = type_to_sql(o.type, options[:limit], options[:precision], options[:scale])
         
     | 
| 
       37 
     | 
    
         
            -
                      change_column_sql = "CHANGE #{quote_column_name(column.name)} #{quote_column_name(options[:name])} #{sql_type}"
         
     | 
| 
       38 
     | 
    
         
            -
                      add_column_options!(change_column_sql, options.merge(column: column))
         
     | 
| 
       39 
     | 
    
         
            -
                      add_column_position!(change_column_sql, options)
         
     | 
| 
       40 
     | 
    
         
            -
                    end
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
                    def add_column_position!(sql, options)
         
     | 
| 
       43 
     | 
    
         
            -
                      if options[:first]
         
     | 
| 
       44 
     | 
    
         
            -
                        sql << " FIRST"
         
     | 
| 
       45 
     | 
    
         
            -
                      elsif options[:after]
         
     | 
| 
       46 
     | 
    
         
            -
                        sql << " AFTER #{quote_column_name(options[:after])}"
         
     | 
| 
       47 
     | 
    
         
            -
                      end
         
     | 
| 
       48 
     | 
    
         
            -
                      sql
         
     | 
| 
       49 
     | 
    
         
            -
                    end
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
                    def index_in_create(table_name, column_name, options)
         
     | 
| 
       52 
     | 
    
         
            -
                      index_name, index_type, index_columns, index_options, index_algorithm, index_using = @conn.add_index_options(table_name, column_name, options)
         
     | 
| 
       53 
     | 
    
         
            -
                      "#{index_type} INDEX #{quote_column_name(index_name)} #{index_using} (#{index_columns})#{index_options} #{index_algorithm}"
         
     | 
| 
       54 
     | 
    
         
            -
                    end
         
     | 
| 
       55 
     | 
    
         
            -
                  end
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
                  def schema_creation
         
     | 
| 
       58 
     | 
    
         
            -
                    SchemaCreation.new self
         
     | 
| 
      
 19 
     | 
    
         
            +
                  def update_table_definition(table_name, base) # :nodoc:
         
     | 
| 
      
 20 
     | 
    
         
            +
                    MySQL::Table.new(table_name, base)
         
     | 
| 
       59 
21 
     | 
    
         
             
                  end
         
     | 
| 
       60 
22 
     | 
    
         | 
| 
       61 
     | 
    
         
            -
                  def  
     | 
| 
       62 
     | 
    
         
            -
                     
     | 
| 
       63 
     | 
    
         
            -
                    spec.delete(:limit) if :boolean === column.type
         
     | 
| 
       64 
     | 
    
         
            -
                    spec
         
     | 
| 
      
 23 
     | 
    
         
            +
                  def schema_creation # :nodoc:
         
     | 
| 
      
 24 
     | 
    
         
            +
                    MySQL::SchemaCreation.new(self)
         
     | 
| 
       65 
25 
     | 
    
         
             
                  end
         
     | 
| 
       66 
26 
     | 
    
         | 
| 
       67 
     | 
    
         
            -
                   
     | 
| 
       68 
     | 
    
         
            -
                     
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
                    def initialize(name, default, cast_type, sql_type = nil, null = true, collation = nil, strict = false, extra = "")
         
     | 
| 
       71 
     | 
    
         
            -
                      @strict    = strict
         
     | 
| 
       72 
     | 
    
         
            -
                      @collation = collation
         
     | 
| 
       73 
     | 
    
         
            -
                      @extra     = extra
         
     | 
| 
       74 
     | 
    
         
            -
                      super(name, default, cast_type, sql_type, null)
         
     | 
| 
       75 
     | 
    
         
            -
                      assert_valid_default(default)
         
     | 
| 
       76 
     | 
    
         
            -
                      extract_default
         
     | 
| 
       77 
     | 
    
         
            -
                    end
         
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
                    def extract_default
         
     | 
| 
       80 
     | 
    
         
            -
                      if blob_or_text_column?
         
     | 
| 
       81 
     | 
    
         
            -
                        @default = null || strict ? nil : ''
         
     | 
| 
       82 
     | 
    
         
            -
                      elsif missing_default_forged_as_empty_string?(@default)
         
     | 
| 
       83 
     | 
    
         
            -
                        @default = nil
         
     | 
| 
       84 
     | 
    
         
            -
                      end
         
     | 
| 
       85 
     | 
    
         
            -
                    end
         
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
                    def has_default?
         
     | 
| 
       88 
     | 
    
         
            -
                      return false if blob_or_text_column? # MySQL forbids defaults on blob and text columns
         
     | 
| 
       89 
     | 
    
         
            -
                      super
         
     | 
| 
       90 
     | 
    
         
            -
                    end
         
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
                    def blob_or_text_column?
         
     | 
| 
       93 
     | 
    
         
            -
                      sql_type =~ /blob/i || type == :text
         
     | 
| 
       94 
     | 
    
         
            -
                    end
         
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
                    def case_sensitive?
         
     | 
| 
       97 
     | 
    
         
            -
                      collation && !collation.match(/_ci$/)
         
     | 
| 
       98 
     | 
    
         
            -
                    end
         
     | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
       100 
     | 
    
         
            -
                    def ==(other)
         
     | 
| 
       101 
     | 
    
         
            -
                      super &&
         
     | 
| 
       102 
     | 
    
         
            -
                        collation == other.collation &&
         
     | 
| 
       103 
     | 
    
         
            -
                        strict == other.strict &&
         
     | 
| 
       104 
     | 
    
         
            -
                        extra == other.extra
         
     | 
| 
       105 
     | 
    
         
            -
                    end
         
     | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
       107 
     | 
    
         
            -
                    private
         
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
                    # MySQL misreports NOT NULL column default when none is given.
         
     | 
| 
       110 
     | 
    
         
            -
                    # We can't detect this for columns which may have a legitimate ''
         
     | 
| 
       111 
     | 
    
         
            -
                    # default (string) but we can for others (integer, datetime, boolean,
         
     | 
| 
       112 
     | 
    
         
            -
                    # and the rest).
         
     | 
| 
       113 
     | 
    
         
            -
                    #
         
     | 
| 
       114 
     | 
    
         
            -
                    # Test whether the column has default '', is not null, and is not
         
     | 
| 
       115 
     | 
    
         
            -
                    # a type allowing default ''.
         
     | 
| 
       116 
     | 
    
         
            -
                    def missing_default_forged_as_empty_string?(default)
         
     | 
| 
       117 
     | 
    
         
            -
                      type != :string && !null && default == ''
         
     | 
| 
       118 
     | 
    
         
            -
                    end
         
     | 
| 
       119 
     | 
    
         
            -
             
     | 
| 
       120 
     | 
    
         
            -
                    def assert_valid_default(default)
         
     | 
| 
       121 
     | 
    
         
            -
                      if blob_or_text_column? && default.present?
         
     | 
| 
       122 
     | 
    
         
            -
                        raise ArgumentError, "#{type} columns cannot have a default value: #{default.inspect}"
         
     | 
| 
       123 
     | 
    
         
            -
                      end
         
     | 
| 
       124 
     | 
    
         
            -
                    end
         
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
                    def attributes_for_hash
         
     | 
| 
       127 
     | 
    
         
            -
                      super + [collation, strict, extra]
         
     | 
| 
       128 
     | 
    
         
            -
                    end
         
     | 
| 
      
 27 
     | 
    
         
            +
                  def arel_visitor # :nodoc:
         
     | 
| 
      
 28 
     | 
    
         
            +
                    Arel::Visitors::MySQL.new(self)
         
     | 
| 
       129 
29 
     | 
    
         
             
                  end
         
     | 
| 
       130 
30 
     | 
    
         | 
| 
       131 
31 
     | 
    
         
             
                  ##
         
     | 
| 
       132 
32 
     | 
    
         
             
                  # :singleton-method:
         
     | 
| 
       133 
     | 
    
         
            -
                  # By default, the  
     | 
| 
       134 
     | 
    
         
            -
                  # as boolean. If you wish to disable this emulation  
     | 
| 
       135 
     | 
    
         
            -
                  # behavior in versions 0.13.1 and earlier) you can add the following line
         
     | 
| 
      
 33 
     | 
    
         
            +
                  # By default, the Mysql2Adapter will consider all columns of type <tt>tinyint(1)</tt>
         
     | 
| 
      
 34 
     | 
    
         
            +
                  # as boolean. If you wish to disable this emulation you can add the following line
         
     | 
| 
       136 
35 
     | 
    
         
             
                  # to your application.rb file:
         
     | 
| 
       137 
36 
     | 
    
         
             
                  #
         
     | 
| 
       138 
     | 
    
         
            -
                  #   ActiveRecord::ConnectionAdapters:: 
     | 
| 
      
 37 
     | 
    
         
            +
                  #   ActiveRecord::ConnectionAdapters::Mysql2Adapter.emulate_booleans = false
         
     | 
| 
       139 
38 
     | 
    
         
             
                  class_attribute :emulate_booleans
         
     | 
| 
       140 
39 
     | 
    
         
             
                  self.emulate_booleans = true
         
     | 
| 
       141 
40 
     | 
    
         | 
| 
       142 
     | 
    
         
            -
                  LOST_CONNECTION_ERROR_MESSAGES = [
         
     | 
| 
       143 
     | 
    
         
            -
                    "Server shutdown in progress",
         
     | 
| 
       144 
     | 
    
         
            -
                    "Broken pipe",
         
     | 
| 
       145 
     | 
    
         
            -
                    "Lost connection to MySQL server during query",
         
     | 
| 
       146 
     | 
    
         
            -
                    "MySQL server has gone away" ]
         
     | 
| 
       147 
     | 
    
         
            -
             
     | 
| 
       148 
     | 
    
         
            -
                  QUOTED_TRUE, QUOTED_FALSE = '1', '0'
         
     | 
| 
       149 
     | 
    
         
            -
             
     | 
| 
       150 
41 
     | 
    
         
             
                  NATIVE_DATABASE_TYPES = {
         
     | 
| 
       151 
     | 
    
         
            -
                    : 
     | 
| 
       152 
     | 
    
         
            -
                    : 
     | 
| 
       153 
     | 
    
         
            -
                    : 
     | 
| 
       154 
     | 
    
         
            -
                    : 
     | 
| 
       155 
     | 
    
         
            -
                    : 
     | 
| 
       156 
     | 
    
         
            -
                    : 
     | 
| 
       157 
     | 
    
         
            -
                    : 
     | 
| 
       158 
     | 
    
         
            -
                    : 
     | 
| 
       159 
     | 
    
         
            -
                    : 
     | 
| 
       160 
     | 
    
         
            -
                    : 
     | 
| 
       161 
     | 
    
         
            -
                    : 
     | 
| 
      
 42 
     | 
    
         
            +
                    primary_key: "int auto_increment PRIMARY KEY",
         
     | 
| 
      
 43 
     | 
    
         
            +
                    string:      { name: "varchar", limit: 255 },
         
     | 
| 
      
 44 
     | 
    
         
            +
                    text:        { name: "text" },
         
     | 
| 
      
 45 
     | 
    
         
            +
                    integer:     { name: "int", limit: 4 },
         
     | 
| 
      
 46 
     | 
    
         
            +
                    float:       { name: "float" },
         
     | 
| 
      
 47 
     | 
    
         
            +
                    decimal:     { name: "decimal" },
         
     | 
| 
      
 48 
     | 
    
         
            +
                    datetime:    { name: "datetime" },
         
     | 
| 
      
 49 
     | 
    
         
            +
                    time:        { name: "time" },
         
     | 
| 
      
 50 
     | 
    
         
            +
                    date:        { name: "date" },
         
     | 
| 
      
 51 
     | 
    
         
            +
                    binary:      { name: "blob" },
         
     | 
| 
      
 52 
     | 
    
         
            +
                    boolean:     { name: "tinyint", limit: 1 },
         
     | 
| 
      
 53 
     | 
    
         
            +
                    json:        { name: "json" },
         
     | 
| 
       162 
54 
     | 
    
         
             
                  }
         
     | 
| 
       163 
55 
     | 
    
         | 
| 
       164 
56 
     | 
    
         
             
                  INDEX_TYPES  = [:fulltext, :spatial]
         
     | 
| 
       165 
57 
     | 
    
         
             
                  INDEX_USINGS = [:btree, :hash]
         
     | 
| 
       166 
58 
     | 
    
         | 
| 
       167 
     | 
    
         
            -
                   
     | 
| 
      
 59 
     | 
    
         
            +
                  class StatementPool < ConnectionAdapters::StatementPool
         
     | 
| 
      
 60 
     | 
    
         
            +
                    private def dealloc(stmt)
         
     | 
| 
      
 61 
     | 
    
         
            +
                      stmt[:stmt].close
         
     | 
| 
      
 62 
     | 
    
         
            +
                    end
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
       168 
65 
     | 
    
         
             
                  def initialize(connection, logger, connection_options, config)
         
     | 
| 
       169 
     | 
    
         
            -
                    super(connection, logger)
         
     | 
| 
       170 
     | 
    
         
            -
                    @connection_options, @config = connection_options, config
         
     | 
| 
       171 
     | 
    
         
            -
                    @quoted_column_names, @quoted_table_names = {}, {}
         
     | 
| 
      
 66 
     | 
    
         
            +
                    super(connection, logger, config)
         
     | 
| 
       172 
67 
     | 
    
         | 
| 
       173 
     | 
    
         
            -
                    @ 
     | 
| 
      
 68 
     | 
    
         
            +
                    @statements = StatementPool.new(self.class.type_cast_config_to_integer(config[:statement_limit]))
         
     | 
| 
       174 
69 
     | 
    
         | 
| 
       175 
     | 
    
         
            -
                    if  
     | 
| 
       176 
     | 
    
         
            -
                       
     | 
| 
       177 
     | 
    
         
            -
                    else
         
     | 
| 
       178 
     | 
    
         
            -
                      @prepared_statements = false
         
     | 
| 
      
 70 
     | 
    
         
            +
                    if version < '5.0.0'
         
     | 
| 
      
 71 
     | 
    
         
            +
                      raise "Your version of MySQL (#{version_string}) is too old. Active Record supports MySQL >= 5.0."
         
     | 
| 
       179 
72 
     | 
    
         
             
                    end
         
     | 
| 
       180 
73 
     | 
    
         
             
                  end
         
     | 
| 
       181 
74 
     | 
    
         | 
| 
      
 75 
     | 
    
         
            +
                  CHARSETS_OF_4BYTES_MAXLEN = ['utf8mb4', 'utf16', 'utf16le', 'utf32']
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                  def internal_string_options_for_primary_key # :nodoc:
         
     | 
| 
      
 78 
     | 
    
         
            +
                    super.tap { |options|
         
     | 
| 
      
 79 
     | 
    
         
            +
                      options[:collation] = collation.sub(/\A[^_]+/, 'utf8') if CHARSETS_OF_4BYTES_MAXLEN.include?(charset)
         
     | 
| 
      
 80 
     | 
    
         
            +
                    }
         
     | 
| 
      
 81 
     | 
    
         
            +
                  end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                  def version #:nodoc:
         
     | 
| 
      
 84 
     | 
    
         
            +
                    @version ||= Version.new(version_string)
         
     | 
| 
      
 85 
     | 
    
         
            +
                  end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                  def mariadb? # :nodoc:
         
     | 
| 
      
 88 
     | 
    
         
            +
                    full_version =~ /mariadb/i
         
     | 
| 
      
 89 
     | 
    
         
            +
                  end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
       182 
91 
     | 
    
         
             
                  # Returns true, since this connection adapter supports migrations.
         
     | 
| 
       183 
92 
     | 
    
         
             
                  def supports_migrations?
         
     | 
| 
       184 
93 
     | 
    
         
             
                    true
         
     | 
| 
         @@ -192,18 +101,24 @@ module ActiveRecord 
     | 
|
| 
       192 
101 
     | 
    
         
             
                    true
         
     | 
| 
       193 
102 
     | 
    
         
             
                  end
         
     | 
| 
       194 
103 
     | 
    
         | 
| 
      
 104 
     | 
    
         
            +
                  # Returns true, since this connection adapter supports prepared statement
         
     | 
| 
      
 105 
     | 
    
         
            +
                  # caching.
         
     | 
| 
      
 106 
     | 
    
         
            +
                  def supports_statement_cache?
         
     | 
| 
      
 107 
     | 
    
         
            +
                    true
         
     | 
| 
      
 108 
     | 
    
         
            +
                  end
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
       195 
110 
     | 
    
         
             
                  # Technically MySQL allows to create indexes with the sort order syntax
         
     | 
| 
       196 
111 
     | 
    
         
             
                  # but at the moment (5.5) it doesn't yet implement them
         
     | 
| 
       197 
112 
     | 
    
         
             
                  def supports_index_sort_order?
         
     | 
| 
       198 
113 
     | 
    
         
             
                    true
         
     | 
| 
       199 
114 
     | 
    
         
             
                  end
         
     | 
| 
       200 
115 
     | 
    
         | 
| 
       201 
     | 
    
         
            -
                  # MySQL 4 technically support transaction isolation, but it is affected by a bug
         
     | 
| 
       202 
     | 
    
         
            -
                  # where the transaction level gets persisted for the whole session:
         
     | 
| 
       203 
     | 
    
         
            -
                  #
         
     | 
| 
       204 
     | 
    
         
            -
                  # http://bugs.mysql.com/bug.php?id=39170
         
     | 
| 
       205 
116 
     | 
    
         
             
                  def supports_transaction_isolation?
         
     | 
| 
       206 
     | 
    
         
            -
                     
     | 
| 
      
 117 
     | 
    
         
            +
                    true
         
     | 
| 
      
 118 
     | 
    
         
            +
                  end
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
                  def supports_explain?
         
     | 
| 
      
 121 
     | 
    
         
            +
                    true
         
     | 
| 
       207 
122 
     | 
    
         
             
                  end
         
     | 
| 
       208 
123 
     | 
    
         | 
| 
       209 
124 
     | 
    
         
             
                  def supports_indexes_in_create?
         
     | 
| 
         @@ -215,11 +130,27 @@ module ActiveRecord 
     | 
|
| 
       215 
130 
     | 
    
         
             
                  end
         
     | 
| 
       216 
131 
     | 
    
         | 
| 
       217 
132 
     | 
    
         
             
                  def supports_views?
         
     | 
| 
       218 
     | 
    
         
            -
                     
     | 
| 
      
 133 
     | 
    
         
            +
                    true
         
     | 
| 
       219 
134 
     | 
    
         
             
                  end
         
     | 
| 
       220 
135 
     | 
    
         | 
| 
       221 
136 
     | 
    
         
             
                  def supports_datetime_with_precision?
         
     | 
| 
       222 
     | 
    
         
            -
                     
     | 
| 
      
 137 
     | 
    
         
            +
                    if mariadb?
         
     | 
| 
      
 138 
     | 
    
         
            +
                      version >= '5.3.0'
         
     | 
| 
      
 139 
     | 
    
         
            +
                    else
         
     | 
| 
      
 140 
     | 
    
         
            +
                      version >= '5.6.4'
         
     | 
| 
      
 141 
     | 
    
         
            +
                    end
         
     | 
| 
      
 142 
     | 
    
         
            +
                  end
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
                  def supports_advisory_locks?
         
     | 
| 
      
 145 
     | 
    
         
            +
                    true
         
     | 
| 
      
 146 
     | 
    
         
            +
                  end
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                  def get_advisory_lock(lock_name, timeout = 0) # :nodoc:
         
     | 
| 
      
 149 
     | 
    
         
            +
                    select_value("SELECT GET_LOCK('#{lock_name}', #{timeout});").to_s == '1'
         
     | 
| 
      
 150 
     | 
    
         
            +
                  end
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
                  def release_advisory_lock(lock_name) # :nodoc:
         
     | 
| 
      
 153 
     | 
    
         
            +
                    select_value("SELECT RELEASE_LOCK('#{lock_name}')").to_s == '1'
         
     | 
| 
       223 
154 
     | 
    
         
             
                  end
         
     | 
| 
       224 
155 
     | 
    
         | 
| 
       225 
156 
     | 
    
         
             
                  def native_database_types
         
     | 
| 
         @@ -238,8 +169,8 @@ module ActiveRecord 
     | 
|
| 
       238 
169 
     | 
    
         
             
                    raise NotImplementedError
         
     | 
| 
       239 
170 
     | 
    
         
             
                  end
         
     | 
| 
       240 
171 
     | 
    
         | 
| 
       241 
     | 
    
         
            -
                  def new_column( 
     | 
| 
       242 
     | 
    
         
            -
                    Column.new( 
     | 
| 
      
 172 
     | 
    
         
            +
                  def new_column(*args) #:nodoc:
         
     | 
| 
      
 173 
     | 
    
         
            +
                    MySQL::Column.new(*args)
         
     | 
| 
       243 
174 
     | 
    
         
             
                  end
         
     | 
| 
       244 
175 
     | 
    
         | 
| 
       245 
176 
     | 
    
         
             
                  # Must return the MySQL error number from the exception, if the exception has an
         
     | 
| 
         @@ -248,48 +179,6 @@ module ActiveRecord 
     | 
|
| 
       248 
179 
     | 
    
         
             
                    raise NotImplementedError
         
     | 
| 
       249 
180 
     | 
    
         
             
                  end
         
     | 
| 
       250 
181 
     | 
    
         | 
| 
       251 
     | 
    
         
            -
                  # QUOTING ==================================================
         
     | 
| 
       252 
     | 
    
         
            -
             
     | 
| 
       253 
     | 
    
         
            -
                  def _quote(value) # :nodoc:
         
     | 
| 
       254 
     | 
    
         
            -
                    if value.is_a?(Type::Binary::Data)
         
     | 
| 
       255 
     | 
    
         
            -
                      "x'#{value.hex}'"
         
     | 
| 
       256 
     | 
    
         
            -
                    else
         
     | 
| 
       257 
     | 
    
         
            -
                      super
         
     | 
| 
       258 
     | 
    
         
            -
                    end
         
     | 
| 
       259 
     | 
    
         
            -
                  end
         
     | 
| 
       260 
     | 
    
         
            -
             
     | 
| 
       261 
     | 
    
         
            -
                  def quote_column_name(name) #:nodoc:
         
     | 
| 
       262 
     | 
    
         
            -
                    @quoted_column_names[name] ||= "`#{name.to_s.gsub('`', '``')}`"
         
     | 
| 
       263 
     | 
    
         
            -
                  end
         
     | 
| 
       264 
     | 
    
         
            -
             
     | 
| 
       265 
     | 
    
         
            -
                  def quote_table_name(name) #:nodoc:
         
     | 
| 
       266 
     | 
    
         
            -
                    @quoted_table_names[name] ||= quote_column_name(name).gsub('.', '`.`')
         
     | 
| 
       267 
     | 
    
         
            -
                  end
         
     | 
| 
       268 
     | 
    
         
            -
             
     | 
| 
       269 
     | 
    
         
            -
                  def quoted_true
         
     | 
| 
       270 
     | 
    
         
            -
                    QUOTED_TRUE
         
     | 
| 
       271 
     | 
    
         
            -
                  end
         
     | 
| 
       272 
     | 
    
         
            -
             
     | 
| 
       273 
     | 
    
         
            -
                  def unquoted_true
         
     | 
| 
       274 
     | 
    
         
            -
                    1
         
     | 
| 
       275 
     | 
    
         
            -
                  end
         
     | 
| 
       276 
     | 
    
         
            -
             
     | 
| 
       277 
     | 
    
         
            -
                  def quoted_false
         
     | 
| 
       278 
     | 
    
         
            -
                    QUOTED_FALSE
         
     | 
| 
       279 
     | 
    
         
            -
                  end
         
     | 
| 
       280 
     | 
    
         
            -
             
     | 
| 
       281 
     | 
    
         
            -
                  def unquoted_false
         
     | 
| 
       282 
     | 
    
         
            -
                    0
         
     | 
| 
       283 
     | 
    
         
            -
                  end
         
     | 
| 
       284 
     | 
    
         
            -
             
     | 
| 
       285 
     | 
    
         
            -
                  def quoted_date(value)
         
     | 
| 
       286 
     | 
    
         
            -
                    if supports_datetime_with_precision? && value.acts_like?(:time) && value.respond_to?(:usec)
         
     | 
| 
       287 
     | 
    
         
            -
                      "#{super}.#{sprintf("%06d", value.usec)}"
         
     | 
| 
       288 
     | 
    
         
            -
                    else
         
     | 
| 
       289 
     | 
    
         
            -
                      super
         
     | 
| 
       290 
     | 
    
         
            -
                    end
         
     | 
| 
       291 
     | 
    
         
            -
                  end
         
     | 
| 
       292 
     | 
    
         
            -
             
     | 
| 
       293 
182 
     | 
    
         
             
                  # REFERENTIAL INTEGRITY ====================================
         
     | 
| 
       294 
183 
     | 
    
         | 
| 
       295 
184 
     | 
    
         
             
                  def disable_referential_integrity #:nodoc:
         
     | 
| 
         @@ -303,13 +192,25 @@ module ActiveRecord 
     | 
|
| 
       303 
192 
     | 
    
         
             
                    end
         
     | 
| 
       304 
193 
     | 
    
         
             
                  end
         
     | 
| 
       305 
194 
     | 
    
         | 
| 
      
 195 
     | 
    
         
            +
                  # CONNECTION MANAGEMENT ====================================
         
     | 
| 
      
 196 
     | 
    
         
            +
             
     | 
| 
      
 197 
     | 
    
         
            +
                  # Clears the prepared statements cache.
         
     | 
| 
      
 198 
     | 
    
         
            +
                  def clear_cache!
         
     | 
| 
      
 199 
     | 
    
         
            +
                    reload_type_map
         
     | 
| 
      
 200 
     | 
    
         
            +
                    @statements.clear
         
     | 
| 
      
 201 
     | 
    
         
            +
                  end
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
       306 
203 
     | 
    
         
             
                  #--
         
     | 
| 
       307 
204 
     | 
    
         
             
                  # DATABASE STATEMENTS ======================================
         
     | 
| 
       308 
205 
     | 
    
         
             
                  #++
         
     | 
| 
       309 
206 
     | 
    
         | 
| 
       310 
     | 
    
         
            -
                  def  
     | 
| 
       311 
     | 
    
         
            -
                     
     | 
| 
       312 
     | 
    
         
            -
                     
     | 
| 
      
 207 
     | 
    
         
            +
                  def explain(arel, binds = [])
         
     | 
| 
      
 208 
     | 
    
         
            +
                    sql     = "EXPLAIN #{to_sql(arel, binds)}"
         
     | 
| 
      
 209 
     | 
    
         
            +
                    start   = Time.now
         
     | 
| 
      
 210 
     | 
    
         
            +
                    result  = exec_query(sql, 'EXPLAIN', binds)
         
     | 
| 
      
 211 
     | 
    
         
            +
                    elapsed = Time.now - start
         
     | 
| 
      
 212 
     | 
    
         
            +
             
     | 
| 
      
 213 
     | 
    
         
            +
                    MySQL::ExplainPrettyPrinter.new.pp(result, elapsed)
         
     | 
| 
       313 
214 
     | 
    
         
             
                  end
         
     | 
| 
       314 
215 
     | 
    
         | 
| 
       315 
216 
     | 
    
         
             
                  # Executes the SQL statement in the context of this connection.
         
     | 
| 
         @@ -317,18 +218,13 @@ module ActiveRecord 
     | 
|
| 
       317 
218 
     | 
    
         
             
                    log(sql, name) { @connection.query(sql) }
         
     | 
| 
       318 
219 
     | 
    
         
             
                  end
         
     | 
| 
       319 
220 
     | 
    
         | 
| 
       320 
     | 
    
         
            -
                  #  
     | 
| 
       321 
     | 
    
         
            -
                  # stuff in an abstract way without concerning ourselves about whether it 
     | 
| 
       322 
     | 
    
         
            -
                  # explicitly freed or not.
         
     | 
| 
       323 
     | 
    
         
            -
                  def execute_and_free(sql, name = nil)  
     | 
| 
      
 221 
     | 
    
         
            +
                  # Mysql2Adapter doesn't have to free a result after using it, but we use this method
         
     | 
| 
      
 222 
     | 
    
         
            +
                  # to write stuff in an abstract way without concerning ourselves about whether it
         
     | 
| 
      
 223 
     | 
    
         
            +
                  # needs to be explicitly freed or not.
         
     | 
| 
      
 224 
     | 
    
         
            +
                  def execute_and_free(sql, name = nil) # :nodoc:
         
     | 
| 
       324 
225 
     | 
    
         
             
                    yield execute(sql, name)
         
     | 
| 
       325 
226 
     | 
    
         
             
                  end
         
     | 
| 
       326 
227 
     | 
    
         | 
| 
       327 
     | 
    
         
            -
                  def update_sql(sql, name = nil) #:nodoc:
         
     | 
| 
       328 
     | 
    
         
            -
                    super
         
     | 
| 
       329 
     | 
    
         
            -
                    @connection.affected_rows
         
     | 
| 
       330 
     | 
    
         
            -
                  end
         
     | 
| 
       331 
     | 
    
         
            -
             
     | 
| 
       332 
228 
     | 
    
         
             
                  def begin_db_transaction
         
     | 
| 
       333 
229 
     | 
    
         
             
                    execute "BEGIN"
         
     | 
| 
       334 
230 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -349,7 +245,7 @@ module ActiveRecord 
     | 
|
| 
       349 
245 
     | 
    
         
             
                  # In the simple case, MySQL allows us to place JOINs directly into the UPDATE
         
     | 
| 
       350 
246 
     | 
    
         
             
                  # query. However, this does not allow for LIMIT, OFFSET and ORDER. To support
         
     | 
| 
       351 
247 
     | 
    
         
             
                  # these, we must use a subquery.
         
     | 
| 
       352 
     | 
    
         
            -
                  def join_to_update(update, select)  
     | 
| 
      
 248 
     | 
    
         
            +
                  def join_to_update(update, select, key) # :nodoc:
         
     | 
| 
       353 
249 
     | 
    
         
             
                    if select.limit || select.offset || select.orders.any?
         
     | 
| 
       354 
250 
     | 
    
         
             
                      super
         
     | 
| 
       355 
251 
     | 
    
         
             
                    else
         
     | 
| 
         @@ -382,9 +278,9 @@ module ActiveRecord 
     | 
|
| 
       382 
278 
     | 
    
         
             
                  #   create_database 'matt_development', charset: :big5
         
     | 
| 
       383 
279 
     | 
    
         
             
                  def create_database(name, options = {})
         
     | 
| 
       384 
280 
     | 
    
         
             
                    if options[:collation]
         
     | 
| 
       385 
     | 
    
         
            -
                      execute "CREATE DATABASE  
     | 
| 
      
 281 
     | 
    
         
            +
                      execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT CHARACTER SET #{quote_table_name(options[:charset] || 'utf8')} COLLATE #{quote_table_name(options[:collation])}"
         
     | 
| 
       386 
282 
     | 
    
         
             
                    else
         
     | 
| 
       387 
     | 
    
         
            -
                      execute "CREATE DATABASE  
     | 
| 
      
 283 
     | 
    
         
            +
                      execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT CHARACTER SET #{quote_table_name(options[:charset] || 'utf8')}"
         
     | 
| 
       388 
284 
     | 
    
         
             
                    end
         
     | 
| 
       389 
285 
     | 
    
         
             
                  end
         
     | 
| 
       390 
286 
     | 
    
         | 
| 
         @@ -393,7 +289,7 @@ module ActiveRecord 
     | 
|
| 
       393 
289 
     | 
    
         
             
                  # Example:
         
     | 
| 
       394 
290 
     | 
    
         
             
                  #   drop_database('sebastian_development')
         
     | 
| 
       395 
291 
     | 
    
         
             
                  def drop_database(name) #:nodoc:
         
     | 
| 
       396 
     | 
    
         
            -
                    execute "DROP DATABASE IF EXISTS  
     | 
| 
      
 292 
     | 
    
         
            +
                    execute "DROP DATABASE IF EXISTS #{quote_table_name(name)}"
         
     | 
| 
       397 
293 
     | 
    
         
             
                  end
         
     | 
| 
       398 
294 
     | 
    
         | 
| 
       399 
295 
     | 
    
         
             
                  def current_database
         
     | 
| 
         @@ -410,36 +306,69 @@ module ActiveRecord 
     | 
|
| 
       410 
306 
     | 
    
         
             
                    show_variable 'collation_database'
         
     | 
| 
       411 
307 
     | 
    
         
             
                  end
         
     | 
| 
       412 
308 
     | 
    
         | 
| 
       413 
     | 
    
         
            -
                  def tables(name = nil 
     | 
| 
       414 
     | 
    
         
            -
                     
     | 
| 
       415 
     | 
    
         
            -
             
     | 
| 
       416 
     | 
    
         
            -
             
     | 
| 
      
 309 
     | 
    
         
            +
                  def tables(name = nil) # :nodoc:
         
     | 
| 
      
 310 
     | 
    
         
            +
                    ActiveSupport::Deprecation.warn(<<-MSG.squish)
         
     | 
| 
      
 311 
     | 
    
         
            +
                      #tables currently returns both tables and views.
         
     | 
| 
      
 312 
     | 
    
         
            +
                      This behavior is deprecated and will be changed with Rails 5.1 to only return tables.
         
     | 
| 
      
 313 
     | 
    
         
            +
                      Use #data_sources instead.
         
     | 
| 
      
 314 
     | 
    
         
            +
                    MSG
         
     | 
| 
       417 
315 
     | 
    
         | 
| 
       418 
     | 
    
         
            -
                     
     | 
| 
       419 
     | 
    
         
            -
                       
     | 
| 
      
 316 
     | 
    
         
            +
                    if name
         
     | 
| 
      
 317 
     | 
    
         
            +
                      ActiveSupport::Deprecation.warn(<<-MSG.squish)
         
     | 
| 
      
 318 
     | 
    
         
            +
                        Passing arguments to #tables is deprecated without replacement.
         
     | 
| 
      
 319 
     | 
    
         
            +
                      MSG
         
     | 
| 
       420 
320 
     | 
    
         
             
                    end
         
     | 
| 
      
 321 
     | 
    
         
            +
             
     | 
| 
      
 322 
     | 
    
         
            +
                    data_sources
         
     | 
| 
      
 323 
     | 
    
         
            +
                  end
         
     | 
| 
      
 324 
     | 
    
         
            +
             
     | 
| 
      
 325 
     | 
    
         
            +
                  def data_sources
         
     | 
| 
      
 326 
     | 
    
         
            +
                    sql = "SELECT table_name FROM information_schema.tables "
         
     | 
| 
      
 327 
     | 
    
         
            +
                    sql << "WHERE table_schema = DATABASE()"
         
     | 
| 
      
 328 
     | 
    
         
            +
             
     | 
| 
      
 329 
     | 
    
         
            +
                    select_values(sql, 'SCHEMA')
         
     | 
| 
       421 
330 
     | 
    
         
             
                  end
         
     | 
| 
       422 
     | 
    
         
            -
                  alias data_sources tables
         
     | 
| 
       423 
331 
     | 
    
         | 
| 
       424 
332 
     | 
    
         
             
                  def truncate(table_name, name = nil)
         
     | 
| 
       425 
333 
     | 
    
         
             
                    execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
         
     | 
| 
       426 
334 
     | 
    
         
             
                  end
         
     | 
| 
       427 
335 
     | 
    
         | 
| 
       428 
     | 
    
         
            -
                  def table_exists?( 
     | 
| 
       429 
     | 
    
         
            -
                     
     | 
| 
       430 
     | 
    
         
            -
                     
     | 
| 
      
 336 
     | 
    
         
            +
                  def table_exists?(table_name)
         
     | 
| 
      
 337 
     | 
    
         
            +
                    # Update lib/active_record/internal_metadata.rb when this gets removed
         
     | 
| 
      
 338 
     | 
    
         
            +
                    ActiveSupport::Deprecation.warn(<<-MSG.squish)
         
     | 
| 
      
 339 
     | 
    
         
            +
                      #table_exists? currently checks both tables and views.
         
     | 
| 
      
 340 
     | 
    
         
            +
                      This behavior is deprecated and will be changed with Rails 5.1 to only check tables.
         
     | 
| 
      
 341 
     | 
    
         
            +
                      Use #data_source_exists? instead.
         
     | 
| 
      
 342 
     | 
    
         
            +
                    MSG
         
     | 
| 
      
 343 
     | 
    
         
            +
             
     | 
| 
      
 344 
     | 
    
         
            +
                    data_source_exists?(table_name)
         
     | 
| 
      
 345 
     | 
    
         
            +
                  end
         
     | 
| 
      
 346 
     | 
    
         
            +
             
     | 
| 
      
 347 
     | 
    
         
            +
                  def data_source_exists?(table_name)
         
     | 
| 
      
 348 
     | 
    
         
            +
                    return false unless table_name.present?
         
     | 
| 
       431 
349 
     | 
    
         | 
| 
       432 
     | 
    
         
            -
                    name 
     | 
| 
       433 
     | 
    
         
            -
                    schema, table = name.split('.', 2)
         
     | 
| 
      
 350 
     | 
    
         
            +
                    schema, name = extract_schema_qualified_name(table_name)
         
     | 
| 
       434 
351 
     | 
    
         | 
| 
       435 
     | 
    
         
            -
                     
     | 
| 
       436 
     | 
    
         
            -
             
     | 
| 
       437 
     | 
    
         
            -
             
     | 
| 
       438 
     | 
    
         
            -
                     
     | 
| 
      
 352 
     | 
    
         
            +
                    sql = "SELECT table_name FROM information_schema.tables "
         
     | 
| 
      
 353 
     | 
    
         
            +
                    sql << "WHERE table_schema = #{schema} AND table_name = #{name}"
         
     | 
| 
      
 354 
     | 
    
         
            +
             
     | 
| 
      
 355 
     | 
    
         
            +
                    select_values(sql, 'SCHEMA').any?
         
     | 
| 
      
 356 
     | 
    
         
            +
                  end
         
     | 
| 
       439 
357 
     | 
    
         | 
| 
       440 
     | 
    
         
            -
             
     | 
| 
      
 358 
     | 
    
         
            +
                  def views # :nodoc:
         
     | 
| 
      
 359 
     | 
    
         
            +
                    select_values("SHOW FULL TABLES WHERE table_type = 'VIEW'", 'SCHEMA')
         
     | 
| 
      
 360 
     | 
    
         
            +
                  end
         
     | 
| 
      
 361 
     | 
    
         
            +
             
     | 
| 
      
 362 
     | 
    
         
            +
                  def view_exists?(view_name) # :nodoc:
         
     | 
| 
      
 363 
     | 
    
         
            +
                    return false unless view_name.present?
         
     | 
| 
      
 364 
     | 
    
         
            +
             
     | 
| 
      
 365 
     | 
    
         
            +
                    schema, name = extract_schema_qualified_name(view_name)
         
     | 
| 
      
 366 
     | 
    
         
            +
             
     | 
| 
      
 367 
     | 
    
         
            +
                    sql = "SELECT table_name FROM information_schema.tables WHERE table_type = 'VIEW'"
         
     | 
| 
      
 368 
     | 
    
         
            +
                    sql << " AND table_schema = #{schema} AND table_name = #{name}"
         
     | 
| 
      
 369 
     | 
    
         
            +
             
     | 
| 
      
 370 
     | 
    
         
            +
                    select_values(sql, 'SCHEMA').any?
         
     | 
| 
       441 
371 
     | 
    
         
             
                  end
         
     | 
| 
       442 
     | 
    
         
            -
                  alias data_source_exists? table_exists?
         
     | 
| 
       443 
372 
     | 
    
         | 
| 
       444 
373 
     | 
    
         
             
                  # Returns an array of indexes for the given table.
         
     | 
| 
       445 
374 
     | 
    
         
             
                  def indexes(table_name, name = nil) #:nodoc:
         
     | 
| 
         @@ -454,11 +383,11 @@ module ActiveRecord 
     | 
|
| 
       454 
383 
     | 
    
         
             
                          mysql_index_type = row[:Index_type].downcase.to_sym
         
     | 
| 
       455 
384 
     | 
    
         
             
                          index_type  = INDEX_TYPES.include?(mysql_index_type)  ? mysql_index_type : nil
         
     | 
| 
       456 
385 
     | 
    
         
             
                          index_using = INDEX_USINGS.include?(mysql_index_type) ? mysql_index_type : nil
         
     | 
| 
       457 
     | 
    
         
            -
                          indexes << IndexDefinition.new(row[:Table], row[:Key_name], row[:Non_unique].to_i == 0, [],  
     | 
| 
      
 386 
     | 
    
         
            +
                          indexes << IndexDefinition.new(row[:Table], row[:Key_name], row[:Non_unique].to_i == 0, [], {}, nil, nil, index_type, index_using, row[:Index_comment].presence)
         
     | 
| 
       458 
387 
     | 
    
         
             
                        end
         
     | 
| 
       459 
388 
     | 
    
         | 
| 
       460 
389 
     | 
    
         
             
                        indexes.last.columns << row[:Column_name]
         
     | 
| 
       461 
     | 
    
         
            -
                        indexes.last.lengths  
     | 
| 
      
 390 
     | 
    
         
            +
                        indexes.last.lengths.merge!(row[:Column_name] => row[:Sub_part].to_i) if row[:Sub_part]
         
     | 
| 
       462 
391 
     | 
    
         
             
                      end
         
     | 
| 
       463 
392 
     | 
    
         
             
                    end
         
     | 
| 
       464 
393 
     | 
    
         | 
| 
         @@ -466,20 +395,32 @@ module ActiveRecord 
     | 
|
| 
       466 
395 
     | 
    
         
             
                  end
         
     | 
| 
       467 
396 
     | 
    
         | 
| 
       468 
397 
     | 
    
         
             
                  # Returns an array of +Column+ objects for the table specified by +table_name+.
         
     | 
| 
       469 
     | 
    
         
            -
                  def columns(table_name) 
     | 
| 
       470 
     | 
    
         
            -
                     
     | 
| 
       471 
     | 
    
         
            -
                     
     | 
| 
       472 
     | 
    
         
            -
                       
     | 
| 
       473 
     | 
    
         
            -
             
     | 
| 
       474 
     | 
    
         
            -
                         
     | 
| 
       475 
     | 
    
         
            -
             
     | 
| 
       476 
     | 
    
         
            -
                         
     | 
| 
      
 398 
     | 
    
         
            +
                  def columns(table_name) # :nodoc:
         
     | 
| 
      
 399 
     | 
    
         
            +
                    table_name = table_name.to_s
         
     | 
| 
      
 400 
     | 
    
         
            +
                    column_definitions(table_name).map do |field|
         
     | 
| 
      
 401 
     | 
    
         
            +
                      type_metadata = fetch_type_metadata(field[:Type], field[:Extra])
         
     | 
| 
      
 402 
     | 
    
         
            +
                      if type_metadata.type == :datetime && field[:Default] =~ /\ACURRENT_TIMESTAMP(?:\(\))?\z/i
         
     | 
| 
      
 403 
     | 
    
         
            +
                        default, default_function = nil, "CURRENT_TIMESTAMP"
         
     | 
| 
      
 404 
     | 
    
         
            +
                      else
         
     | 
| 
      
 405 
     | 
    
         
            +
                        default, default_function = field[:Default], nil
         
     | 
| 
       477 
406 
     | 
    
         
             
                      end
         
     | 
| 
      
 407 
     | 
    
         
            +
                      new_column(field[:Field], default, type_metadata, field[:Null] == "YES", table_name, default_function, field[:Collation], comment: field[:Comment].presence)
         
     | 
| 
       478 
408 
     | 
    
         
             
                    end
         
     | 
| 
       479 
409 
     | 
    
         
             
                  end
         
     | 
| 
       480 
410 
     | 
    
         | 
| 
       481 
     | 
    
         
            -
                  def  
     | 
| 
       482 
     | 
    
         
            -
                     
     | 
| 
      
 411 
     | 
    
         
            +
                  def table_comment(table_name) # :nodoc:
         
     | 
| 
      
 412 
     | 
    
         
            +
                    schema, name = extract_schema_qualified_name(table_name)
         
     | 
| 
      
 413 
     | 
    
         
            +
             
     | 
| 
      
 414 
     | 
    
         
            +
                    select_value(<<-SQL.strip_heredoc, 'SCHEMA')
         
     | 
| 
      
 415 
     | 
    
         
            +
                      SELECT table_comment
         
     | 
| 
      
 416 
     | 
    
         
            +
                      FROM information_schema.tables
         
     | 
| 
      
 417 
     | 
    
         
            +
                      WHERE table_schema = #{schema}
         
     | 
| 
      
 418 
     | 
    
         
            +
                        AND table_name = #{name}
         
     | 
| 
      
 419 
     | 
    
         
            +
                    SQL
         
     | 
| 
      
 420 
     | 
    
         
            +
                  end
         
     | 
| 
      
 421 
     | 
    
         
            +
             
     | 
| 
      
 422 
     | 
    
         
            +
                  def create_table(table_name, **options) #:nodoc:
         
     | 
| 
      
 423 
     | 
    
         
            +
                    super(table_name, options: 'ENGINE=InnoDB', **options)
         
     | 
| 
       483 
424 
     | 
    
         
             
                  end
         
     | 
| 
       484 
425 
     | 
    
         | 
| 
       485 
426 
     | 
    
         
             
                  def bulk_change_table(table_name, operations) #:nodoc:
         
     | 
| 
         @@ -506,8 +447,23 @@ module ActiveRecord 
     | 
|
| 
       506 
447 
     | 
    
         
             
                    rename_table_indexes(table_name, new_name)
         
     | 
| 
       507 
448 
     | 
    
         
             
                  end
         
     | 
| 
       508 
449 
     | 
    
         | 
| 
      
 450 
     | 
    
         
            +
                  # Drops a table from the database.
         
     | 
| 
      
 451 
     | 
    
         
            +
                  #
         
     | 
| 
      
 452 
     | 
    
         
            +
                  # [<tt>:force</tt>]
         
     | 
| 
      
 453 
     | 
    
         
            +
                  #   Set to +:cascade+ to drop dependent objects as well.
         
     | 
| 
      
 454 
     | 
    
         
            +
                  #   Defaults to false.
         
     | 
| 
      
 455 
     | 
    
         
            +
                  # [<tt>:if_exists</tt>]
         
     | 
| 
      
 456 
     | 
    
         
            +
                  #   Set to +true+ to only drop the table if it exists.
         
     | 
| 
      
 457 
     | 
    
         
            +
                  #   Defaults to false.
         
     | 
| 
      
 458 
     | 
    
         
            +
                  # [<tt>:temporary</tt>]
         
     | 
| 
      
 459 
     | 
    
         
            +
                  #   Set to +true+ to drop temporary table.
         
     | 
| 
      
 460 
     | 
    
         
            +
                  #   Defaults to false.
         
     | 
| 
      
 461 
     | 
    
         
            +
                  #
         
     | 
| 
      
 462 
     | 
    
         
            +
                  # Although this command ignores most +options+ and the block if one is given,
         
     | 
| 
      
 463 
     | 
    
         
            +
                  # it can be helpful to provide these in a migration's +change+ method so it can be reverted.
         
     | 
| 
      
 464 
     | 
    
         
            +
                  # In that case, +options+ and the block will be used by create_table.
         
     | 
| 
       509 
465 
     | 
    
         
             
                  def drop_table(table_name, options = {})
         
     | 
| 
       510 
     | 
    
         
            -
                    execute "DROP#{' TEMPORARY' if options[:temporary]} TABLE #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}"
         
     | 
| 
      
 466 
     | 
    
         
            +
                    execute "DROP#{' TEMPORARY' if options[:temporary]} TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}"
         
     | 
| 
       511 
467 
     | 
    
         
             
                  end
         
     | 
| 
       512 
468 
     | 
    
         | 
| 
       513 
469 
     | 
    
         
             
                  def rename_index(table_name, old_name, new_name)
         
     | 
| 
         @@ -520,12 +476,13 @@ module ActiveRecord 
     | 
|
| 
       520 
476 
     | 
    
         
             
                    end
         
     | 
| 
       521 
477 
     | 
    
         
             
                  end
         
     | 
| 
       522 
478 
     | 
    
         | 
| 
       523 
     | 
    
         
            -
                  def change_column_default(table_name, column_name,  
     | 
| 
      
 479 
     | 
    
         
            +
                  def change_column_default(table_name, column_name, default_or_changes) #:nodoc:
         
     | 
| 
      
 480 
     | 
    
         
            +
                    default = extract_new_default_value(default_or_changes)
         
     | 
| 
       524 
481 
     | 
    
         
             
                    column = column_for(table_name, column_name)
         
     | 
| 
       525 
482 
     | 
    
         
             
                    change_column table_name, column_name, column.sql_type, :default => default
         
     | 
| 
       526 
483 
     | 
    
         
             
                  end
         
     | 
| 
       527 
484 
     | 
    
         | 
| 
       528 
     | 
    
         
            -
                  def change_column_null(table_name, column_name, null, default = nil)
         
     | 
| 
      
 485 
     | 
    
         
            +
                  def change_column_null(table_name, column_name, null, default = nil) #:nodoc:
         
     | 
| 
       529 
486 
     | 
    
         
             
                    column = column_for(table_name, column_name)
         
     | 
| 
       530 
487 
     | 
    
         | 
| 
       531 
488 
     | 
    
         
             
                    unless null || default.nil?
         
     | 
| 
         @@ -545,24 +502,37 @@ module ActiveRecord 
     | 
|
| 
       545 
502 
     | 
    
         
             
                  end
         
     | 
| 
       546 
503 
     | 
    
         | 
| 
       547 
504 
     | 
    
         
             
                  def add_index(table_name, column_name, options = {}) #:nodoc:
         
     | 
| 
       548 
     | 
    
         
            -
                    index_name, index_type, index_columns,  
     | 
| 
       549 
     | 
    
         
            -
                     
     | 
| 
      
 505 
     | 
    
         
            +
                    index_name, index_type, index_columns, _, index_algorithm, index_using, comment = add_index_options(table_name, column_name, options)
         
     | 
| 
      
 506 
     | 
    
         
            +
                    sql = "CREATE #{index_type} INDEX #{quote_column_name(index_name)} #{index_using} ON #{quote_table_name(table_name)} (#{index_columns}) #{index_algorithm}"
         
     | 
| 
      
 507 
     | 
    
         
            +
                    execute add_sql_comment!(sql, comment)
         
     | 
| 
      
 508 
     | 
    
         
            +
                  end
         
     | 
| 
      
 509 
     | 
    
         
            +
             
     | 
| 
      
 510 
     | 
    
         
            +
                  def add_sql_comment!(sql, comment) # :nodoc:
         
     | 
| 
      
 511 
     | 
    
         
            +
                    sql << " COMMENT #{quote(comment)}" if comment.present?
         
     | 
| 
      
 512 
     | 
    
         
            +
                    sql
         
     | 
| 
       550 
513 
     | 
    
         
             
                  end
         
     | 
| 
       551 
514 
     | 
    
         | 
| 
       552 
515 
     | 
    
         
             
                  def foreign_keys(table_name)
         
     | 
| 
       553 
     | 
    
         
            -
                     
     | 
| 
       554 
     | 
    
         
            -
             
     | 
| 
       555 
     | 
    
         
            -
             
     | 
| 
       556 
     | 
    
         
            -
             
     | 
| 
       557 
     | 
    
         
            -
             
     | 
| 
      
 516 
     | 
    
         
            +
                    raise ArgumentError unless table_name.present?
         
     | 
| 
      
 517 
     | 
    
         
            +
             
     | 
| 
      
 518 
     | 
    
         
            +
                    schema, name = extract_schema_qualified_name(table_name)
         
     | 
| 
      
 519 
     | 
    
         
            +
             
     | 
| 
      
 520 
     | 
    
         
            +
                    fk_info = select_all(<<-SQL.strip_heredoc, 'SCHEMA')
         
     | 
| 
      
 521 
     | 
    
         
            +
                      SELECT fk.referenced_table_name AS 'to_table',
         
     | 
| 
      
 522 
     | 
    
         
            +
                             fk.referenced_column_name AS 'primary_key',
         
     | 
| 
      
 523 
     | 
    
         
            +
                             fk.column_name AS 'column',
         
     | 
| 
      
 524 
     | 
    
         
            +
                             fk.constraint_name AS 'name',
         
     | 
| 
      
 525 
     | 
    
         
            +
                             rc.update_rule AS 'on_update',
         
     | 
| 
      
 526 
     | 
    
         
            +
                             rc.delete_rule AS 'on_delete'
         
     | 
| 
       558 
527 
     | 
    
         
             
                      FROM information_schema.key_column_usage fk
         
     | 
| 
       559 
     | 
    
         
            -
                       
     | 
| 
       560 
     | 
    
         
            -
             
     | 
| 
       561 
     | 
    
         
            -
             
     | 
| 
      
 528 
     | 
    
         
            +
                      JOIN information_schema.referential_constraints rc
         
     | 
| 
      
 529 
     | 
    
         
            +
                      USING (constraint_schema, constraint_name)
         
     | 
| 
      
 530 
     | 
    
         
            +
                      WHERE fk.referenced_column_name IS NOT NULL
         
     | 
| 
      
 531 
     | 
    
         
            +
                        AND fk.table_schema = #{schema}
         
     | 
| 
      
 532 
     | 
    
         
            +
                        AND fk.table_name = #{name}
         
     | 
| 
      
 533 
     | 
    
         
            +
                        AND rc.table_name = #{name}
         
     | 
| 
       562 
534 
     | 
    
         
             
                    SQL
         
     | 
| 
       563 
535 
     | 
    
         | 
| 
       564 
     | 
    
         
            -
                    create_table_info = select_one("SHOW CREATE TABLE #{quote_table_name(table_name)}")["Create Table"]
         
     | 
| 
       565 
     | 
    
         
            -
             
     | 
| 
       566 
536 
     | 
    
         
             
                    fk_info.map do |row|
         
     | 
| 
       567 
537 
     | 
    
         
             
                      options = {
         
     | 
| 
       568 
538 
     | 
    
         
             
                        column: row['column'],
         
     | 
| 
         @@ -570,99 +540,91 @@ module ActiveRecord 
     | 
|
| 
       570 
540 
     | 
    
         
             
                        primary_key: row['primary_key']
         
     | 
| 
       571 
541 
     | 
    
         
             
                      }
         
     | 
| 
       572 
542 
     | 
    
         | 
| 
       573 
     | 
    
         
            -
                      options[:on_update] = extract_foreign_key_action( 
     | 
| 
       574 
     | 
    
         
            -
                      options[:on_delete] = extract_foreign_key_action( 
     | 
| 
      
 543 
     | 
    
         
            +
                      options[:on_update] = extract_foreign_key_action(row['on_update'])
         
     | 
| 
      
 544 
     | 
    
         
            +
                      options[:on_delete] = extract_foreign_key_action(row['on_delete'])
         
     | 
| 
       575 
545 
     | 
    
         | 
| 
       576 
546 
     | 
    
         
             
                      ForeignKeyDefinition.new(table_name, row['to_table'], options)
         
     | 
| 
       577 
547 
     | 
    
         
             
                    end
         
     | 
| 
       578 
548 
     | 
    
         
             
                  end
         
     | 
| 
       579 
549 
     | 
    
         | 
| 
      
 550 
     | 
    
         
            +
                  def table_options(table_name) # :nodoc:
         
     | 
| 
      
 551 
     | 
    
         
            +
                    table_options = {}
         
     | 
| 
      
 552 
     | 
    
         
            +
             
     | 
| 
      
 553 
     | 
    
         
            +
                    create_table_info = create_table_info(table_name)
         
     | 
| 
      
 554 
     | 
    
         
            +
             
     | 
| 
      
 555 
     | 
    
         
            +
                    # strip create_definitions and partition_options
         
     | 
| 
      
 556 
     | 
    
         
            +
                    raw_table_options = create_table_info.sub(/\A.*\n\) /m, '').sub(/\n\/\*!.*\*\/\n\z/m, '').strip
         
     | 
| 
      
 557 
     | 
    
         
            +
             
     | 
| 
      
 558 
     | 
    
         
            +
                    # strip AUTO_INCREMENT
         
     | 
| 
      
 559 
     | 
    
         
            +
                    raw_table_options.sub!(/(ENGINE=\w+)(?: AUTO_INCREMENT=\d+)/, '\1')
         
     | 
| 
      
 560 
     | 
    
         
            +
             
     | 
| 
      
 561 
     | 
    
         
            +
                    table_options[:options] = raw_table_options
         
     | 
| 
      
 562 
     | 
    
         
            +
             
     | 
| 
      
 563 
     | 
    
         
            +
                    # strip COMMENT
         
     | 
| 
      
 564 
     | 
    
         
            +
                    if raw_table_options.sub!(/ COMMENT='.+'/, '')
         
     | 
| 
      
 565 
     | 
    
         
            +
                      table_options[:comment] = table_comment(table_name)
         
     | 
| 
      
 566 
     | 
    
         
            +
                    end
         
     | 
| 
      
 567 
     | 
    
         
            +
             
     | 
| 
      
 568 
     | 
    
         
            +
                    table_options
         
     | 
| 
      
 569 
     | 
    
         
            +
                  end
         
     | 
| 
      
 570 
     | 
    
         
            +
             
     | 
| 
       580 
571 
     | 
    
         
             
                  # Maps logical Rails types to MySQL-specific data types.
         
     | 
| 
       581 
     | 
    
         
            -
                  def type_to_sql(type, limit = nil, precision = nil, scale = nil)
         
     | 
| 
       582 
     | 
    
         
            -
                    case type.to_s
         
     | 
| 
       583 
     | 
    
         
            -
                    when 'binary'
         
     | 
| 
       584 
     | 
    
         
            -
                      case limit
         
     | 
| 
       585 
     | 
    
         
            -
                      when 0..0xfff;           "varbinary(#{limit})"
         
     | 
| 
       586 
     | 
    
         
            -
                      when nil;                "blob"
         
     | 
| 
       587 
     | 
    
         
            -
                      when 0x1000..0xffffffff; "blob(#{limit})"
         
     | 
| 
       588 
     | 
    
         
            -
                      else raise(ActiveRecordError, "No binary type has character length #{limit}")
         
     | 
| 
       589 
     | 
    
         
            -
                      end
         
     | 
| 
      
 572 
     | 
    
         
            +
                  def type_to_sql(type, limit = nil, precision = nil, scale = nil, unsigned = nil)
         
     | 
| 
      
 573 
     | 
    
         
            +
                    sql = case type.to_s
         
     | 
| 
       590 
574 
     | 
    
         
             
                    when 'integer'
         
     | 
| 
       591 
     | 
    
         
            -
                       
     | 
| 
       592 
     | 
    
         
            -
                      when 1; 'tinyint'
         
     | 
| 
       593 
     | 
    
         
            -
                      when 2; 'smallint'
         
     | 
| 
       594 
     | 
    
         
            -
                      when 3; 'mediumint'
         
     | 
| 
       595 
     | 
    
         
            -
                      when nil, 4, 11; 'int(11)'  # compatibility with MySQL default
         
     | 
| 
       596 
     | 
    
         
            -
                      when 5..8; 'bigint'
         
     | 
| 
       597 
     | 
    
         
            -
                      else raise(ActiveRecordError, "No integer type has byte size #{limit}")
         
     | 
| 
       598 
     | 
    
         
            -
                      end
         
     | 
| 
      
 575 
     | 
    
         
            +
                      integer_to_sql(limit)
         
     | 
| 
       599 
576 
     | 
    
         
             
                    when 'text'
         
     | 
| 
       600 
     | 
    
         
            -
                       
     | 
| 
       601 
     | 
    
         
            -
             
     | 
| 
       602 
     | 
    
         
            -
                       
     | 
| 
       603 
     | 
    
         
            -
             
     | 
| 
       604 
     | 
    
         
            -
                       
     | 
| 
       605 
     | 
    
         
            -
             
     | 
| 
       606 
     | 
    
         
            -
                       
     | 
| 
       607 
     | 
    
         
            -
             
     | 
| 
       608 
     | 
    
         
            -
                      return super unless precision
         
     | 
| 
       609 
     | 
    
         
            -
             
     | 
| 
       610 
     | 
    
         
            -
                      case precision
         
     | 
| 
       611 
     | 
    
         
            -
                        when 0..6; "datetime(#{precision})"
         
     | 
| 
       612 
     | 
    
         
            -
                        else raise(ActiveRecordError, "No datetime type has precision of #{precision}. The allowed range of precision is from 0 to 6.")
         
     | 
| 
      
 577 
     | 
    
         
            +
                      text_to_sql(limit)
         
     | 
| 
      
 578 
     | 
    
         
            +
                    when 'blob'
         
     | 
| 
      
 579 
     | 
    
         
            +
                      binary_to_sql(limit)
         
     | 
| 
      
 580 
     | 
    
         
            +
                    when 'binary'
         
     | 
| 
      
 581 
     | 
    
         
            +
                      if (0..0xfff) === limit
         
     | 
| 
      
 582 
     | 
    
         
            +
                        "varbinary(#{limit})"
         
     | 
| 
      
 583 
     | 
    
         
            +
                      else
         
     | 
| 
      
 584 
     | 
    
         
            +
                        binary_to_sql(limit)
         
     | 
| 
       613 
585 
     | 
    
         
             
                      end
         
     | 
| 
       614 
586 
     | 
    
         
             
                    else
         
     | 
| 
       615 
     | 
    
         
            -
                      super
         
     | 
| 
      
 587 
     | 
    
         
            +
                      super(type, limit, precision, scale)
         
     | 
| 
       616 
588 
     | 
    
         
             
                    end
         
     | 
| 
      
 589 
     | 
    
         
            +
             
     | 
| 
      
 590 
     | 
    
         
            +
                    sql << ' unsigned' if unsigned && type != :primary_key
         
     | 
| 
      
 591 
     | 
    
         
            +
                    sql
         
     | 
| 
       617 
592 
     | 
    
         
             
                  end
         
     | 
| 
       618 
593 
     | 
    
         | 
| 
       619 
594 
     | 
    
         
             
                  # SHOW VARIABLES LIKE 'name'
         
     | 
| 
       620 
595 
     | 
    
         
             
                  def show_variable(name)
         
     | 
| 
       621 
     | 
    
         
            -
                     
     | 
| 
       622 
     | 
    
         
            -
                    variables.first['Value'] unless variables.empty?
         
     | 
| 
      
 596 
     | 
    
         
            +
                    select_value("SELECT @@#{name}", 'SCHEMA')
         
     | 
| 
       623 
597 
     | 
    
         
             
                  rescue ActiveRecord::StatementInvalid
         
     | 
| 
       624 
598 
     | 
    
         
             
                    nil
         
     | 
| 
       625 
599 
     | 
    
         
             
                  end
         
     | 
| 
       626 
600 
     | 
    
         | 
| 
       627 
     | 
    
         
            -
                   
     | 
| 
       628 
     | 
    
         
            -
             
     | 
| 
       629 
     | 
    
         
            -
                    execute_and_free("SHOW CREATE TABLE #{quote_table_name(table)}", 'SCHEMA') do |result|
         
     | 
| 
       630 
     | 
    
         
            -
                      create_table = each_hash(result).first[:"Create Table"]
         
     | 
| 
       631 
     | 
    
         
            -
                      if create_table.to_s =~ /PRIMARY KEY\s+(?:USING\s+\w+\s+)?\((.+)\)/
         
     | 
| 
       632 
     | 
    
         
            -
                        keys = $1.split(",").map { |key| key.delete('`"') }
         
     | 
| 
       633 
     | 
    
         
            -
                        keys.length == 1 ? [keys.first, nil] : nil
         
     | 
| 
       634 
     | 
    
         
            -
                      else
         
     | 
| 
       635 
     | 
    
         
            -
                        nil
         
     | 
| 
       636 
     | 
    
         
            -
                      end
         
     | 
| 
       637 
     | 
    
         
            -
                    end
         
     | 
| 
       638 
     | 
    
         
            -
                  end
         
     | 
| 
      
 601 
     | 
    
         
            +
                  def primary_keys(table_name) # :nodoc:
         
     | 
| 
      
 602 
     | 
    
         
            +
                    raise ArgumentError unless table_name.present?
         
     | 
| 
       639 
603 
     | 
    
         | 
| 
       640 
     | 
    
         
            -
             
     | 
| 
       641 
     | 
    
         
            -
                  def primary_key(table)
         
     | 
| 
       642 
     | 
    
         
            -
                    pk_and_sequence = pk_and_sequence_for(table)
         
     | 
| 
       643 
     | 
    
         
            -
                    pk_and_sequence && pk_and_sequence.first
         
     | 
| 
       644 
     | 
    
         
            -
                  end
         
     | 
| 
      
 604 
     | 
    
         
            +
                    schema, name = extract_schema_qualified_name(table_name)
         
     | 
| 
       645 
605 
     | 
    
         | 
| 
       646 
     | 
    
         
            -
             
     | 
| 
       647 
     | 
    
         
            -
             
     | 
| 
       648 
     | 
    
         
            -
             
     | 
| 
      
 606 
     | 
    
         
            +
                    select_values(<<-SQL.strip_heredoc, 'SCHEMA')
         
     | 
| 
      
 607 
     | 
    
         
            +
                      SELECT column_name
         
     | 
| 
      
 608 
     | 
    
         
            +
                      FROM information_schema.key_column_usage
         
     | 
| 
      
 609 
     | 
    
         
            +
                      WHERE constraint_name = 'PRIMARY'
         
     | 
| 
      
 610 
     | 
    
         
            +
                        AND table_schema = #{schema}
         
     | 
| 
      
 611 
     | 
    
         
            +
                        AND table_name = #{name}
         
     | 
| 
      
 612 
     | 
    
         
            +
                      ORDER BY ordinal_position
         
     | 
| 
      
 613 
     | 
    
         
            +
                    SQL
         
     | 
| 
       649 
614 
     | 
    
         
             
                  end
         
     | 
| 
       650 
615 
     | 
    
         | 
| 
       651 
616 
     | 
    
         
             
                  def case_sensitive_comparison(table, attribute, column, value)
         
     | 
| 
       652 
     | 
    
         
            -
                    if column.case_sensitive?
         
     | 
| 
       653 
     | 
    
         
            -
                      table[attribute].eq( 
     | 
| 
      
 617 
     | 
    
         
            +
                    if !value.nil? && column.collation && !column.case_sensitive?
         
     | 
| 
      
 618 
     | 
    
         
            +
                      table[attribute].eq(Arel::Nodes::Bin.new(Arel::Nodes::BindParam.new))
         
     | 
| 
       654 
619 
     | 
    
         
             
                    else
         
     | 
| 
       655 
620 
     | 
    
         
             
                      super
         
     | 
| 
       656 
621 
     | 
    
         
             
                    end
         
     | 
| 
       657 
622 
     | 
    
         
             
                  end
         
     | 
| 
       658 
623 
     | 
    
         | 
| 
       659 
     | 
    
         
            -
                  def  
     | 
| 
       660 
     | 
    
         
            -
                     
     | 
| 
       661 
     | 
    
         
            -
                      super
         
     | 
| 
       662 
     | 
    
         
            -
                    else
         
     | 
| 
       663 
     | 
    
         
            -
                      table[attribute].eq(value)
         
     | 
| 
       664 
     | 
    
         
            -
                    end
         
     | 
| 
      
 624 
     | 
    
         
            +
                  def can_perform_case_insensitive_comparison_for?(column)
         
     | 
| 
      
 625 
     | 
    
         
            +
                    column.case_sensitive?
         
     | 
| 
       665 
626 
     | 
    
         
             
                  end
         
     | 
| 
      
 627 
     | 
    
         
            +
                  private :can_perform_case_insensitive_comparison_for?
         
     | 
| 
       666 
628 
     | 
    
         | 
| 
       667 
629 
     | 
    
         
             
                  # In MySQL 5.7.5 and up, ONLY_FULL_GROUP_BY affects handling of queries that use
         
     | 
| 
       668 
630 
     | 
    
         
             
                  # DISTINCT and ORDER BY. It requires the ORDER BY columns in the select list for
         
     | 
| 
         @@ -704,6 +666,7 @@ module ActiveRecord 
     | 
|
| 
       704 
666 
     | 
    
         
             
                    m.register_type %r(longblob)i,   Type::Binary.new(limit: 2**32 - 1)
         
     | 
| 
       705 
667 
     | 
    
         
             
                    m.register_type %r(^float)i,     Type::Float.new(limit: 24)
         
     | 
| 
       706 
668 
     | 
    
         
             
                    m.register_type %r(^double)i,    Type::Float.new(limit: 53)
         
     | 
| 
      
 669 
     | 
    
         
            +
                    m.register_type %r(^json)i,      MysqlJson.new
         
     | 
| 
       707 
670 
     | 
    
         | 
| 
       708 
671 
     | 
    
         
             
                    register_integer_type m, %r(^bigint)i,    limit: 8
         
     | 
| 
       709 
672 
     | 
    
         
             
                    register_integer_type m, %r(^int)i,       limit: 4
         
     | 
| 
         @@ -711,26 +674,26 @@ module ActiveRecord 
     | 
|
| 
       711 
674 
     | 
    
         
             
                    register_integer_type m, %r(^smallint)i,  limit: 2
         
     | 
| 
       712 
675 
     | 
    
         
             
                    register_integer_type m, %r(^tinyint)i,   limit: 1
         
     | 
| 
       713 
676 
     | 
    
         | 
| 
       714 
     | 
    
         
            -
                    m. 
     | 
| 
       715 
     | 
    
         
            -
                    m.alias_type %r(set)i,           'varchar'
         
     | 
| 
      
 677 
     | 
    
         
            +
                    m.register_type %r(^tinyint\(1\))i, Type::Boolean.new if emulate_booleans
         
     | 
| 
       716 
678 
     | 
    
         
             
                    m.alias_type %r(year)i,          'integer'
         
     | 
| 
       717 
679 
     | 
    
         
             
                    m.alias_type %r(bit)i,           'binary'
         
     | 
| 
       718 
680 
     | 
    
         | 
| 
       719 
     | 
    
         
            -
                    m.register_type(%r(datetime)i) do |sql_type|
         
     | 
| 
       720 
     | 
    
         
            -
                      precision = extract_precision(sql_type)
         
     | 
| 
       721 
     | 
    
         
            -
                      MysqlDateTime.new(precision: precision)
         
     | 
| 
       722 
     | 
    
         
            -
                    end
         
     | 
| 
       723 
     | 
    
         
            -
             
     | 
| 
       724 
681 
     | 
    
         
             
                    m.register_type(%r(enum)i) do |sql_type|
         
     | 
| 
       725 
682 
     | 
    
         
             
                      limit = sql_type[/^enum\((.+)\)/i, 1]
         
     | 
| 
       726 
683 
     | 
    
         
             
                        .split(',').map{|enum| enum.strip.length - 2}.max
         
     | 
| 
       727 
684 
     | 
    
         
             
                      MysqlString.new(limit: limit)
         
     | 
| 
       728 
685 
     | 
    
         
             
                    end
         
     | 
| 
      
 686 
     | 
    
         
            +
             
     | 
| 
      
 687 
     | 
    
         
            +
                    m.register_type(%r(^set)i) do |sql_type|
         
     | 
| 
      
 688 
     | 
    
         
            +
                      limit = sql_type[/^set\((.+)\)/i, 1]
         
     | 
| 
      
 689 
     | 
    
         
            +
                        .split(',').map{|set| set.strip.length - 1}.sum - 1
         
     | 
| 
      
 690 
     | 
    
         
            +
                      MysqlString.new(limit: limit)
         
     | 
| 
      
 691 
     | 
    
         
            +
                    end
         
     | 
| 
       729 
692 
     | 
    
         
             
                  end
         
     | 
| 
       730 
693 
     | 
    
         | 
| 
       731 
694 
     | 
    
         
             
                  def register_integer_type(mapping, key, options) # :nodoc:
         
     | 
| 
       732 
695 
     | 
    
         
             
                    mapping.register_type(key) do |sql_type|
         
     | 
| 
       733 
     | 
    
         
            -
                      if / 
     | 
| 
      
 696 
     | 
    
         
            +
                      if /\bunsigned\b/ === sql_type
         
     | 
| 
       734 
697 
     | 
    
         
             
                        Type::UnsignedInteger.new(options)
         
     | 
| 
       735 
698 
     | 
    
         
             
                      else
         
     | 
| 
       736 
699 
     | 
    
         
             
                        Type::Integer.new(options)
         
     | 
| 
         @@ -738,61 +701,54 @@ module ActiveRecord 
     | 
|
| 
       738 
701 
     | 
    
         
             
                    end
         
     | 
| 
       739 
702 
     | 
    
         
             
                  end
         
     | 
| 
       740 
703 
     | 
    
         | 
| 
       741 
     | 
    
         
            -
                   
     | 
| 
       742 
     | 
    
         
            -
             
     | 
| 
       743 
     | 
    
         
            -
             
     | 
| 
       744 
     | 
    
         
            -
                     
     | 
| 
       745 
     | 
    
         
            -
             
     | 
| 
       746 
     | 
    
         
            -
             
     | 
| 
       747 
     | 
    
         
            -
             
     | 
| 
       748 
     | 
    
         
            -
                    # to work with MySQL 5.7.6 which sets optimizer_switch='derived_merge=on'
         
     | 
| 
       749 
     | 
    
         
            -
                    subsubselect.distinct unless select.limit || select.offset || select.orders.any?
         
     | 
| 
      
 704 
     | 
    
         
            +
                  def extract_precision(sql_type)
         
     | 
| 
      
 705 
     | 
    
         
            +
                    if /time/ === sql_type
         
     | 
| 
      
 706 
     | 
    
         
            +
                      super || 0
         
     | 
| 
      
 707 
     | 
    
         
            +
                    else
         
     | 
| 
      
 708 
     | 
    
         
            +
                      super
         
     | 
| 
      
 709 
     | 
    
         
            +
                    end
         
     | 
| 
      
 710 
     | 
    
         
            +
                  end
         
     | 
| 
       750 
711 
     | 
    
         | 
| 
       751 
     | 
    
         
            -
             
     | 
| 
       752 
     | 
    
         
            -
                     
     | 
| 
       753 
     | 
    
         
            -
                    subselect.from subsubselect.as('__active_record_temp')
         
     | 
| 
      
 712 
     | 
    
         
            +
                  def fetch_type_metadata(sql_type, extra = "")
         
     | 
| 
      
 713 
     | 
    
         
            +
                    MySQL::TypeMetadata.new(super(sql_type), extra: extra, strict: strict_mode?)
         
     | 
| 
       754 
714 
     | 
    
         
             
                  end
         
     | 
| 
       755 
715 
     | 
    
         | 
| 
       756 
     | 
    
         
            -
                  def add_index_length( 
     | 
| 
       757 
     | 
    
         
            -
                    if  
     | 
| 
      
 716 
     | 
    
         
            +
                  def add_index_length(quoted_columns, **options)
         
     | 
| 
      
 717 
     | 
    
         
            +
                    if length = options[:length]
         
     | 
| 
       758 
718 
     | 
    
         
             
                      case length
         
     | 
| 
       759 
719 
     | 
    
         
             
                      when Hash
         
     | 
| 
       760 
     | 
    
         
            -
                         
     | 
| 
      
 720 
     | 
    
         
            +
                        length = length.symbolize_keys
         
     | 
| 
      
 721 
     | 
    
         
            +
                        quoted_columns.each { |name, column| column << "(#{length[name]})" if length[name].present? }
         
     | 
| 
       761 
722 
     | 
    
         
             
                      when Integer
         
     | 
| 
       762 
     | 
    
         
            -
                         
     | 
| 
      
 723 
     | 
    
         
            +
                        quoted_columns.each { |name, column| column << "(#{length})" }
         
     | 
| 
       763 
724 
     | 
    
         
             
                      end
         
     | 
| 
       764 
725 
     | 
    
         
             
                    end
         
     | 
| 
       765 
726 
     | 
    
         | 
| 
       766 
     | 
    
         
            -
                     
     | 
| 
      
 727 
     | 
    
         
            +
                    quoted_columns
         
     | 
| 
       767 
728 
     | 
    
         
             
                  end
         
     | 
| 
       768 
729 
     | 
    
         | 
| 
       769 
     | 
    
         
            -
                  def  
     | 
| 
       770 
     | 
    
         
            -
                     
     | 
| 
       771 
     | 
    
         
            -
             
     | 
| 
       772 
     | 
    
         
            -
                    # add index length
         
     | 
| 
       773 
     | 
    
         
            -
                    option_strings = add_index_length(option_strings, column_names, options)
         
     | 
| 
       774 
     | 
    
         
            -
             
     | 
| 
       775 
     | 
    
         
            -
                    # add index sort order
         
     | 
| 
       776 
     | 
    
         
            -
                    option_strings = add_index_sort_order(option_strings, column_names, options)
         
     | 
| 
       777 
     | 
    
         
            -
             
     | 
| 
       778 
     | 
    
         
            -
                    column_names.map {|name| quote_column_name(name) + option_strings[name]}
         
     | 
| 
      
 730 
     | 
    
         
            +
                  def add_options_for_index_columns(quoted_columns, **options)
         
     | 
| 
      
 731 
     | 
    
         
            +
                    quoted_columns = add_index_length(quoted_columns, options)
         
     | 
| 
      
 732 
     | 
    
         
            +
                    super
         
     | 
| 
       779 
733 
     | 
    
         
             
                  end
         
     | 
| 
       780 
734 
     | 
    
         | 
| 
       781 
735 
     | 
    
         
             
                  def translate_exception(exception, message)
         
     | 
| 
       782 
736 
     | 
    
         
             
                    case error_number(exception)
         
     | 
| 
       783 
737 
     | 
    
         
             
                    when 1062
         
     | 
| 
       784 
     | 
    
         
            -
                      RecordNotUnique.new(message 
     | 
| 
      
 738 
     | 
    
         
            +
                      RecordNotUnique.new(message)
         
     | 
| 
       785 
739 
     | 
    
         
             
                    when 1452
         
     | 
| 
       786 
     | 
    
         
            -
                      InvalidForeignKey.new(message 
     | 
| 
      
 740 
     | 
    
         
            +
                      InvalidForeignKey.new(message)
         
     | 
| 
      
 741 
     | 
    
         
            +
                    when 1406
         
     | 
| 
      
 742 
     | 
    
         
            +
                      ValueTooLong.new(message)
         
     | 
| 
       787 
743 
     | 
    
         
             
                    else
         
     | 
| 
       788 
744 
     | 
    
         
             
                      super
         
     | 
| 
       789 
745 
     | 
    
         
             
                    end
         
     | 
| 
       790 
746 
     | 
    
         
             
                  end
         
     | 
| 
       791 
747 
     | 
    
         | 
| 
       792 
748 
     | 
    
         
             
                  def add_column_sql(table_name, column_name, type, options = {})
         
     | 
| 
       793 
     | 
    
         
            -
                    td = create_table_definition 
     | 
| 
      
 749 
     | 
    
         
            +
                    td = create_table_definition(table_name)
         
     | 
| 
       794 
750 
     | 
    
         
             
                    cd = td.new_column_definition(column_name, type, options)
         
     | 
| 
       795 
     | 
    
         
            -
                    schema_creation. 
     | 
| 
      
 751 
     | 
    
         
            +
                    schema_creation.accept(AddColumnDefinition.new(cd))
         
     | 
| 
       796 
752 
     | 
    
         
             
                  end
         
     | 
| 
       797 
753 
     | 
    
         | 
| 
       798 
754 
     | 
    
         
             
                  def change_column_sql(table_name, column_name, type, options = {})
         
     | 
| 
         @@ -806,21 +762,23 @@ module ActiveRecord 
     | 
|
| 
       806 
762 
     | 
    
         
             
                      options[:null] = column.null
         
     | 
| 
       807 
763 
     | 
    
         
             
                    end
         
     | 
| 
       808 
764 
     | 
    
         | 
| 
       809 
     | 
    
         
            -
                     
     | 
| 
       810 
     | 
    
         
            -
                     
     | 
| 
      
 765 
     | 
    
         
            +
                    td = create_table_definition(table_name)
         
     | 
| 
      
 766 
     | 
    
         
            +
                    cd = td.new_column_definition(column.name, type, options)
         
     | 
| 
      
 767 
     | 
    
         
            +
                    schema_creation.accept(ChangeColumnDefinition.new(cd, column.name))
         
     | 
| 
       811 
768 
     | 
    
         
             
                  end
         
     | 
| 
       812 
769 
     | 
    
         | 
| 
       813 
770 
     | 
    
         
             
                  def rename_column_sql(table_name, column_name, new_column_name)
         
     | 
| 
       814 
771 
     | 
    
         
             
                    column  = column_for(table_name, column_name)
         
     | 
| 
       815 
772 
     | 
    
         
             
                    options = {
         
     | 
| 
       816 
     | 
    
         
            -
                      name: new_column_name,
         
     | 
| 
       817 
773 
     | 
    
         
             
                      default: column.default,
         
     | 
| 
       818 
774 
     | 
    
         
             
                      null: column.null,
         
     | 
| 
       819 
     | 
    
         
            -
                      auto_increment: column. 
     | 
| 
      
 775 
     | 
    
         
            +
                      auto_increment: column.auto_increment?
         
     | 
| 
       820 
776 
     | 
    
         
             
                    }
         
     | 
| 
       821 
777 
     | 
    
         | 
| 
       822 
778 
     | 
    
         
             
                    current_type = select_one("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE '#{column_name}'", 'SCHEMA')["Type"]
         
     | 
| 
       823 
     | 
    
         
            -
                     
     | 
| 
      
 779 
     | 
    
         
            +
                    td = create_table_definition(table_name)
         
     | 
| 
      
 780 
     | 
    
         
            +
                    cd = td.new_column_definition(new_column_name, current_type, options)
         
     | 
| 
      
 781 
     | 
    
         
            +
                    schema_creation.accept(ChangeColumnDefinition.new(cd, column.name))
         
     | 
| 
       824 
782 
     | 
    
         
             
                  end
         
     | 
| 
       825 
783 
     | 
    
         | 
| 
       826 
784 
     | 
    
         
             
                  def remove_column_sql(table_name, column_name, type = nil, options = {})
         
     | 
| 
         @@ -832,8 +790,9 @@ module ActiveRecord 
     | 
|
| 
       832 
790 
     | 
    
         
             
                  end
         
     | 
| 
       833 
791 
     | 
    
         | 
| 
       834 
792 
     | 
    
         
             
                  def add_index_sql(table_name, column_name, options = {})
         
     | 
| 
       835 
     | 
    
         
            -
                    index_name, index_type, index_columns = add_index_options(table_name, column_name, options)
         
     | 
| 
       836 
     | 
    
         
            -
                     
     | 
| 
      
 793 
     | 
    
         
            +
                    index_name, index_type, index_columns, _, index_algorithm, index_using = add_index_options(table_name, column_name, options)
         
     | 
| 
      
 794 
     | 
    
         
            +
                    index_algorithm[0, 0] = ", " if index_algorithm.present?
         
     | 
| 
      
 795 
     | 
    
         
            +
                    "ADD #{index_type} INDEX #{quote_column_name(index_name)} #{index_using} (#{index_columns})#{index_algorithm}"
         
     | 
| 
       837 
796 
     | 
    
         
             
                  end
         
     | 
| 
       838 
797 
     | 
    
         | 
| 
       839 
798 
     | 
    
         
             
                  def remove_index_sql(table_name, options = {})
         
     | 
| 
         @@ -851,12 +810,19 @@ module ActiveRecord 
     | 
|
| 
       851 
810 
     | 
    
         | 
| 
       852 
811 
     | 
    
         
             
                  private
         
     | 
| 
       853 
812 
     | 
    
         | 
| 
       854 
     | 
    
         
            -
                   
     | 
| 
       855 
     | 
    
         
            -
             
     | 
| 
       856 
     | 
    
         
            -
                   
     | 
| 
      
 813 
     | 
    
         
            +
                  # MySQL is too stupid to create a temporary table for use subquery, so we have
         
     | 
| 
      
 814 
     | 
    
         
            +
                  # to give it some prompting in the form of a subsubquery. Ugh!
         
     | 
| 
      
 815 
     | 
    
         
            +
                  def subquery_for(key, select)
         
     | 
| 
      
 816 
     | 
    
         
            +
                    subsubselect = select.clone
         
     | 
| 
      
 817 
     | 
    
         
            +
                    subsubselect.projections = [key]
         
     | 
| 
       857 
818 
     | 
    
         | 
| 
       858 
     | 
    
         
            -
             
     | 
| 
       859 
     | 
    
         
            -
                     
     | 
| 
      
 819 
     | 
    
         
            +
                    # Materialize subquery by adding distinct
         
     | 
| 
      
 820 
     | 
    
         
            +
                    # to work with MySQL 5.7.6 which sets optimizer_switch='derived_merge=on'
         
     | 
| 
      
 821 
     | 
    
         
            +
                    subsubselect.distinct unless select.limit || select.offset || select.orders.any?
         
     | 
| 
      
 822 
     | 
    
         
            +
             
     | 
| 
      
 823 
     | 
    
         
            +
                    subselect = Arel::SelectManager.new(select.engine)
         
     | 
| 
      
 824 
     | 
    
         
            +
                    subselect.project Arel.sql(key.name)
         
     | 
| 
      
 825 
     | 
    
         
            +
                    subselect.from subsubselect.as('__active_record_temp')
         
     | 
| 
       860 
826 
     | 
    
         
             
                  end
         
     | 
| 
       861 
827 
     | 
    
         | 
| 
       862 
828 
     | 
    
         
             
                  def supports_rename_index?
         
     | 
| 
         @@ -866,8 +832,7 @@ module ActiveRecord 
     | 
|
| 
       866 
832 
     | 
    
         
             
                  def configure_connection
         
     | 
| 
       867 
833 
     | 
    
         
             
                    variables = @config.fetch(:variables, {}).stringify_keys
         
     | 
| 
       868 
834 
     | 
    
         | 
| 
       869 
     | 
    
         
            -
                    # By default, MySQL 'where id is null' selects the last inserted id.
         
     | 
| 
       870 
     | 
    
         
            -
                    # Turn this off. http://dev.rubyonrails.org/ticket/6778
         
     | 
| 
      
 835 
     | 
    
         
            +
                    # By default, MySQL 'where id is null' selects the last inserted id; Turn this off.
         
     | 
| 
       871 
836 
     | 
    
         
             
                    variables['sql_auto_is_null'] = 0
         
     | 
| 
       872 
837 
     | 
    
         | 
| 
       873 
838 
     | 
    
         
             
                    # Increase timeout so the server doesn't disconnect us.
         
     | 
| 
         @@ -875,15 +840,27 @@ module ActiveRecord 
     | 
|
| 
       875 
840 
     | 
    
         
             
                    wait_timeout = 2147483 unless wait_timeout.is_a?(Integer)
         
     | 
| 
       876 
841 
     | 
    
         
             
                    variables["wait_timeout"] = wait_timeout
         
     | 
| 
       877 
842 
     | 
    
         | 
| 
      
 843 
     | 
    
         
            +
                    defaults = [':default', :default].to_set
         
     | 
| 
      
 844 
     | 
    
         
            +
             
     | 
| 
       878 
845 
     | 
    
         
             
                    # Make MySQL reject illegal values rather than truncating or blanking them, see
         
     | 
| 
       879 
     | 
    
         
            -
                    # http://dev.mysql.com/doc/refman/5. 
     | 
| 
      
 846 
     | 
    
         
            +
                    # http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_strict_all_tables
         
     | 
| 
       880 
847 
     | 
    
         
             
                    # If the user has provided another value for sql_mode, don't replace it.
         
     | 
| 
       881 
     | 
    
         
            -
                     
     | 
| 
       882 
     | 
    
         
            -
                       
     | 
| 
      
 848 
     | 
    
         
            +
                    if sql_mode = variables.delete('sql_mode')
         
     | 
| 
      
 849 
     | 
    
         
            +
                      sql_mode = quote(sql_mode)
         
     | 
| 
      
 850 
     | 
    
         
            +
                    elsif !defaults.include?(strict_mode?)
         
     | 
| 
      
 851 
     | 
    
         
            +
                      if strict_mode?
         
     | 
| 
      
 852 
     | 
    
         
            +
                        sql_mode = "CONCAT(@@sql_mode, ',STRICT_ALL_TABLES')"
         
     | 
| 
      
 853 
     | 
    
         
            +
                      else
         
     | 
| 
      
 854 
     | 
    
         
            +
                        sql_mode = "REPLACE(@@sql_mode, 'STRICT_TRANS_TABLES', '')"
         
     | 
| 
      
 855 
     | 
    
         
            +
                        sql_mode = "REPLACE(#{sql_mode}, 'STRICT_ALL_TABLES', '')"
         
     | 
| 
      
 856 
     | 
    
         
            +
                        sql_mode = "REPLACE(#{sql_mode}, 'TRADITIONAL', '')"
         
     | 
| 
      
 857 
     | 
    
         
            +
                      end
         
     | 
| 
      
 858 
     | 
    
         
            +
                      sql_mode = "CONCAT(#{sql_mode}, ',NO_AUTO_VALUE_ON_ZERO')"
         
     | 
| 
       883 
859 
     | 
    
         
             
                    end
         
     | 
| 
      
 860 
     | 
    
         
            +
                    sql_mode_assignment = "@@SESSION.sql_mode = #{sql_mode}, " if sql_mode
         
     | 
| 
       884 
861 
     | 
    
         | 
| 
       885 
862 
     | 
    
         
             
                    # NAMES does not have an equals sign, see
         
     | 
| 
       886 
     | 
    
         
            -
                    # http://dev.mysql.com/doc/refman/5. 
     | 
| 
      
 863 
     | 
    
         
            +
                    # http://dev.mysql.com/doc/refman/5.7/en/set-statement.html#id944430
         
     | 
| 
       887 
864 
     | 
    
         
             
                    # (trailing comma because variable_assignments will always have content)
         
     | 
| 
       888 
865 
     | 
    
         
             
                    if @config[:encoding]
         
     | 
| 
       889 
866 
     | 
    
         
             
                      encoding = "NAMES #{@config[:encoding]}"
         
     | 
| 
         @@ -893,7 +870,7 @@ module ActiveRecord 
     | 
|
| 
       893 
870 
     | 
    
         | 
| 
       894 
871 
     | 
    
         
             
                    # Gather up all of the SET variables...
         
     | 
| 
       895 
872 
     | 
    
         
             
                    variable_assignments = variables.map do |k, v|
         
     | 
| 
       896 
     | 
    
         
            -
                      if v 
     | 
| 
      
 873 
     | 
    
         
            +
                      if defaults.include?(v)
         
     | 
| 
       897 
874 
     | 
    
         
             
                        "@@SESSION.#{k} = DEFAULT" # Sets the value to the global or compile default
         
     | 
| 
       898 
875 
     | 
    
         
             
                      elsif !v.nil?
         
     | 
| 
       899 
876 
     | 
    
         
             
                        "@@SESSION.#{k} = #{quote(v)}"
         
     | 
| 
         @@ -902,31 +879,84 @@ module ActiveRecord 
     | 
|
| 
       902 
879 
     | 
    
         
             
                    end.compact.join(', ')
         
     | 
| 
       903 
880 
     | 
    
         | 
| 
       904 
881 
     | 
    
         
             
                    # ...and send them all in one query
         
     | 
| 
       905 
     | 
    
         
            -
                    @connection.query  "SET #{encoding} #{variable_assignments}"
         
     | 
| 
      
 882 
     | 
    
         
            +
                    @connection.query  "SET #{encoding} #{sql_mode_assignment} #{variable_assignments}"
         
     | 
| 
       906 
883 
     | 
    
         
             
                  end
         
     | 
| 
       907 
884 
     | 
    
         | 
| 
       908 
     | 
    
         
            -
                  def  
     | 
| 
       909 
     | 
    
         
            -
                     
     | 
| 
       910 
     | 
    
         
            -
                       
     | 
| 
       911 
     | 
    
         
            -
                      when 'CASCADE'; :cascade
         
     | 
| 
       912 
     | 
    
         
            -
                      when 'SET NULL'; :nullify
         
     | 
| 
       913 
     | 
    
         
            -
                      end
         
     | 
| 
      
 885 
     | 
    
         
            +
                  def column_definitions(table_name) # :nodoc:
         
     | 
| 
      
 886 
     | 
    
         
            +
                    execute_and_free("SHOW FULL FIELDS FROM #{quote_table_name(table_name)}", 'SCHEMA') do |result|
         
     | 
| 
      
 887 
     | 
    
         
            +
                      each_hash(result)
         
     | 
| 
       914 
888 
     | 
    
         
             
                    end
         
     | 
| 
       915 
889 
     | 
    
         
             
                  end
         
     | 
| 
       916 
890 
     | 
    
         | 
| 
       917 
     | 
    
         
            -
                   
     | 
| 
       918 
     | 
    
         
            -
                     
     | 
| 
      
 891 
     | 
    
         
            +
                  def extract_foreign_key_action(specifier) # :nodoc:
         
     | 
| 
      
 892 
     | 
    
         
            +
                    case specifier
         
     | 
| 
      
 893 
     | 
    
         
            +
                    when 'CASCADE'; :cascade
         
     | 
| 
      
 894 
     | 
    
         
            +
                    when 'SET NULL'; :nullify
         
     | 
| 
      
 895 
     | 
    
         
            +
                    end
         
     | 
| 
      
 896 
     | 
    
         
            +
                  end
         
     | 
| 
      
 897 
     | 
    
         
            +
             
     | 
| 
      
 898 
     | 
    
         
            +
                  def create_table_info(table_name) # :nodoc:
         
     | 
| 
      
 899 
     | 
    
         
            +
                    select_one("SHOW CREATE TABLE #{quote_table_name(table_name)}")["Create Table"]
         
     | 
| 
      
 900 
     | 
    
         
            +
                  end
         
     | 
| 
      
 901 
     | 
    
         
            +
             
     | 
| 
      
 902 
     | 
    
         
            +
                  def create_table_definition(*args) # :nodoc:
         
     | 
| 
      
 903 
     | 
    
         
            +
                    MySQL::TableDefinition.new(*args)
         
     | 
| 
      
 904 
     | 
    
         
            +
                  end
         
     | 
| 
       919 
905 
     | 
    
         | 
| 
       920 
     | 
    
         
            -
             
     | 
| 
       921 
     | 
    
         
            -
             
     | 
| 
      
 906 
     | 
    
         
            +
                  def extract_schema_qualified_name(string) # :nodoc:
         
     | 
| 
      
 907 
     | 
    
         
            +
                    schema, name = string.to_s.scan(/[^`.\s]+|`[^`]*`/).map { |s| quote(s) }
         
     | 
| 
      
 908 
     | 
    
         
            +
                    schema, name = "DATABASE()", schema unless name
         
     | 
| 
      
 909 
     | 
    
         
            +
                    [schema, name]
         
     | 
| 
      
 910 
     | 
    
         
            +
                  end
         
     | 
| 
      
 911 
     | 
    
         
            +
             
     | 
| 
      
 912 
     | 
    
         
            +
                  def integer_to_sql(limit) # :nodoc:
         
     | 
| 
      
 913 
     | 
    
         
            +
                    case limit
         
     | 
| 
      
 914 
     | 
    
         
            +
                    when 1; 'tinyint'
         
     | 
| 
      
 915 
     | 
    
         
            +
                    when 2; 'smallint'
         
     | 
| 
      
 916 
     | 
    
         
            +
                    when 3; 'mediumint'
         
     | 
| 
      
 917 
     | 
    
         
            +
                    when nil, 4; 'int'
         
     | 
| 
      
 918 
     | 
    
         
            +
                    when 5..8; 'bigint'
         
     | 
| 
      
 919 
     | 
    
         
            +
                    else raise(ActiveRecordError, "No integer type has byte size #{limit}")
         
     | 
| 
      
 920 
     | 
    
         
            +
                    end
         
     | 
| 
      
 921 
     | 
    
         
            +
                  end
         
     | 
| 
      
 922 
     | 
    
         
            +
             
     | 
| 
      
 923 
     | 
    
         
            +
                  def text_to_sql(limit) # :nodoc:
         
     | 
| 
      
 924 
     | 
    
         
            +
                    case limit
         
     | 
| 
      
 925 
     | 
    
         
            +
                    when 0..0xff;               'tinytext'
         
     | 
| 
      
 926 
     | 
    
         
            +
                    when nil, 0x100..0xffff;    'text'
         
     | 
| 
      
 927 
     | 
    
         
            +
                    when 0x10000..0xffffff;     'mediumtext'
         
     | 
| 
      
 928 
     | 
    
         
            +
                    when 0x1000000..0xffffffff; 'longtext'
         
     | 
| 
      
 929 
     | 
    
         
            +
                    else raise(ActiveRecordError, "No text type has byte length #{limit}")
         
     | 
| 
      
 930 
     | 
    
         
            +
                    end
         
     | 
| 
      
 931 
     | 
    
         
            +
                  end
         
     | 
| 
      
 932 
     | 
    
         
            +
             
     | 
| 
      
 933 
     | 
    
         
            +
                  def binary_to_sql(limit) # :nodoc:
         
     | 
| 
      
 934 
     | 
    
         
            +
                    case limit
         
     | 
| 
      
 935 
     | 
    
         
            +
                    when 0..0xff;               'tinyblob'
         
     | 
| 
      
 936 
     | 
    
         
            +
                    when nil, 0x100..0xffff;    'blob'
         
     | 
| 
      
 937 
     | 
    
         
            +
                    when 0x10000..0xffffff;     'mediumblob'
         
     | 
| 
      
 938 
     | 
    
         
            +
                    when 0x1000000..0xffffffff; 'longblob'
         
     | 
| 
      
 939 
     | 
    
         
            +
                    else raise(ActiveRecordError, "No binary type has byte length #{limit}")
         
     | 
| 
      
 940 
     | 
    
         
            +
                    end
         
     | 
| 
      
 941 
     | 
    
         
            +
                  end
         
     | 
| 
      
 942 
     | 
    
         
            +
             
     | 
| 
      
 943 
     | 
    
         
            +
                  def version_string
         
     | 
| 
      
 944 
     | 
    
         
            +
                    full_version.match(/^(?:5\.5\.5-)?(\d+\.\d+\.\d+)/)[1]
         
     | 
| 
      
 945 
     | 
    
         
            +
                  end
         
     | 
| 
      
 946 
     | 
    
         
            +
             
     | 
| 
      
 947 
     | 
    
         
            +
                  class MysqlJson < Type::Internal::AbstractJson # :nodoc:
         
     | 
| 
      
 948 
     | 
    
         
            +
                    def changed_in_place?(raw_old_value, new_value)
         
     | 
| 
      
 949 
     | 
    
         
            +
                      # Normalization is required because MySQL JSON data format includes
         
     | 
| 
      
 950 
     | 
    
         
            +
                      # the space between the elements.
         
     | 
| 
      
 951 
     | 
    
         
            +
                      super(serialize(deserialize(raw_old_value)), new_value)
         
     | 
| 
       922 
952 
     | 
    
         
             
                    end
         
     | 
| 
       923 
953 
     | 
    
         
             
                  end
         
     | 
| 
       924 
954 
     | 
    
         | 
| 
       925 
955 
     | 
    
         
             
                  class MysqlString < Type::String # :nodoc:
         
     | 
| 
       926 
     | 
    
         
            -
                    def  
     | 
| 
      
 956 
     | 
    
         
            +
                    def serialize(value)
         
     | 
| 
       927 
957 
     | 
    
         
             
                      case value
         
     | 
| 
       928 
     | 
    
         
            -
                      when true then  
     | 
| 
       929 
     | 
    
         
            -
                      when false then  
     | 
| 
      
 958 
     | 
    
         
            +
                      when true then MySQL::Quoting::QUOTED_TRUE
         
     | 
| 
      
 959 
     | 
    
         
            +
                      when false then MySQL::Quoting::QUOTED_FALSE
         
     | 
| 
       930 
960 
     | 
    
         
             
                      else super
         
     | 
| 
       931 
961 
     | 
    
         
             
                      end
         
     | 
| 
       932 
962 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -935,12 +965,16 @@ module ActiveRecord 
     | 
|
| 
       935 
965 
     | 
    
         | 
| 
       936 
966 
     | 
    
         
             
                    def cast_value(value)
         
     | 
| 
       937 
967 
     | 
    
         
             
                      case value
         
     | 
| 
       938 
     | 
    
         
            -
                      when true then  
     | 
| 
       939 
     | 
    
         
            -
                      when false then  
     | 
| 
      
 968 
     | 
    
         
            +
                      when true then MySQL::Quoting::QUOTED_TRUE
         
     | 
| 
      
 969 
     | 
    
         
            +
                      when false then MySQL::Quoting::QUOTED_FALSE
         
     | 
| 
       940 
970 
     | 
    
         
             
                      else super
         
     | 
| 
       941 
971 
     | 
    
         
             
                      end
         
     | 
| 
       942 
972 
     | 
    
         
             
                    end
         
     | 
| 
       943 
973 
     | 
    
         
             
                  end
         
     | 
| 
      
 974 
     | 
    
         
            +
             
     | 
| 
      
 975 
     | 
    
         
            +
                  ActiveRecord::Type.register(:json, MysqlJson, adapter: :mysql2)
         
     | 
| 
      
 976 
     | 
    
         
            +
                  ActiveRecord::Type.register(:string, MysqlString, adapter: :mysql2)
         
     | 
| 
      
 977 
     | 
    
         
            +
                  ActiveRecord::Type.register(:unsigned_integer, Type::UnsignedInteger, adapter: :mysql2)
         
     | 
| 
       944 
978 
     | 
    
         
             
                end
         
     | 
| 
       945 
979 
     | 
    
         
             
              end
         
     | 
| 
       946 
980 
     | 
    
         
             
            end
         
     |