activerecord 4.2.11.3 → 5.0.0.1
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 +5 -5
- data/CHANGELOG.md +1281 -1204
- 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/aggregations.rb +35 -24
- data/lib/active_record/association_relation.rb +3 -3
- data/lib/active_record/associations/alias_tracker.rb +19 -16
- data/lib/active_record/associations/association.rb +11 -9
- data/lib/active_record/associations/association_scope.rb +73 -102
- 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 +14 -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 +3 -10
- data/lib/active_record/associations/collection_association.rb +49 -41
- data/lib/active_record/associations/collection_proxy.rb +67 -27
- data/lib/active_record/associations/foreign_association.rb +1 -1
- data/lib/active_record/associations/has_many_association.rb +20 -71
- data/lib/active_record/associations/has_many_through_association.rb +8 -47
- data/lib/active_record/associations/has_one_association.rb +12 -5
- data/lib/active_record/associations/join_dependency/join_association.rb +16 -10
- data/lib/active_record/associations/join_dependency.rb +29 -19
- data/lib/active_record/associations/preloader/association.rb +46 -52
- data/lib/active_record/associations/preloader/collection_association.rb +0 -6
- 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/through_association.rb +27 -14
- data/lib/active_record/associations/preloader.rb +14 -4
- data/lib/active_record/associations/singular_association.rb +7 -1
- data/lib/active_record/associations/through_association.rb +11 -3
- data/lib/active_record/associations.rb +317 -209
- data/lib/active_record/attribute/user_provided_default.rb +28 -0
- data/lib/active_record/attribute.rb +68 -18
- data/lib/active_record/attribute_assignment.rb +19 -140
- data/lib/active_record/attribute_decorators.rb +6 -5
- 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 +2 -2
- 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_methods.rb +76 -47
- data/lib/active_record/attribute_mutation_tracker.rb +70 -0
- data/lib/active_record/attribute_set/builder.rb +6 -4
- data/lib/active_record/attribute_set.rb +30 -3
- data/lib/active_record/attributes.rb +199 -81
- data/lib/active_record/autosave_association.rb +49 -16
- 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 +40 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +452 -182
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +65 -61
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +2 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +74 -10
- 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 -185
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +72 -17
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +380 -141
- data/lib/active_record/connection_adapters/abstract/transaction.rb +51 -34
- data/lib/active_record/connection_adapters/abstract_adapter.rb +141 -59
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +401 -370
- 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 +125 -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 +29 -166
- data/lib/active_record/connection_adapters/postgresql/column.rb +5 -10
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +10 -72
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +42 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +27 -57
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +1 -1
- 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 +3 -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/oid.rb +1 -6
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +26 -18
- 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 +234 -148
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +35 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +248 -160
- 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 +149 -192
- 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 +89 -107
- data/lib/active_record/counter_cache.rb +13 -24
- data/lib/active_record/dynamic_matchers.rb +1 -20
- data/lib/active_record/enum.rb +113 -76
- data/lib/active_record/errors.rb +87 -48
- 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 +76 -40
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +32 -40
- data/lib/active_record/integration.rb +4 -4
- 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 +43 -21
- data/lib/active_record/migration/command_recorder.rb +59 -18
- data/lib/active_record/migration/compatibility.rb +126 -0
- data/lib/active_record/migration.rb +363 -133
- data/lib/active_record/model_schema.rb +129 -41
- data/lib/active_record/nested_attributes.rb +58 -29
- data/lib/active_record/null_relation.rb +16 -8
- data/lib/active_record/persistence.rb +121 -80
- data/lib/active_record/query_cache.rb +15 -18
- data/lib/active_record/querying.rb +10 -9
- 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 +69 -46
- data/lib/active_record/readonly_attributes.rb +1 -1
- data/lib/active_record/reflection.rb +282 -115
- data/lib/active_record/relation/batches/batch_enumerator.rb +67 -0
- data/lib/active_record/relation/batches.rb +139 -34
- data/lib/active_record/relation/calculations.rb +79 -108
- data/lib/active_record/relation/delegation.rb +7 -20
- data/lib/active_record/relation/finder_methods.rb +163 -81
- 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/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/predicate_builder.rb +120 -107
- 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/relation.rb +176 -116
- data/lib/active_record/result.rb +4 -3
- data/lib/active_record/runtime_registry.rb +1 -1
- data/lib/active_record/sanitization.rb +95 -66
- data/lib/active_record/schema.rb +26 -22
- data/lib/active_record/schema_dumper.rb +62 -38
- data/lib/active_record/schema_migration.rb +11 -14
- data/lib/active_record/scoping/default.rb +23 -9
- data/lib/active_record/scoping/named.rb +49 -28
- data/lib/active_record/scoping.rb +32 -15
- data/lib/active_record/secure_token.rb +38 -0
- data/lib/active_record/serialization.rb +2 -4
- data/lib/active_record/statement_cache.rb +16 -14
- data/lib/active_record/store.rb +8 -3
- data/lib/active_record/suppressor.rb +58 -0
- data/lib/active_record/table_metadata.rb +68 -0
- data/lib/active_record/tasks/database_tasks.rb +57 -43
- data/lib/active_record/tasks/mysql_database_tasks.rb +6 -14
- data/lib/active_record/tasks/postgresql_database_tasks.rb +11 -2
- 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 +58 -0
- data/lib/active_record/transactions.rb +138 -56
- 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 +29 -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.rb +66 -17
- data/lib/active_record/type_caster/connection.rb +29 -0
- data/lib/active_record/type_caster/map.rb +19 -0
- data/lib/active_record/type_caster.rb +7 -0
- 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 +30 -29
- data/lib/active_record/validations.rb +33 -32
- data/lib/active_record.rb +8 -4
- data/lib/rails/generators/active_record/migration/migration_generator.rb +7 -4
- 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/migration.rb +7 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +32 -15
- 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 +60 -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
| @@ -18,9 +18,9 @@ module ActiveRecord | |
| 18 18 | 
             
                  end
         | 
| 19 19 |  | 
| 20 20 | 
             
                  # Returns the maximum allowed length for an index name. This
         | 
| 21 | 
            -
                  # limit is enforced by  | 
| 22 | 
            -
                  #  | 
| 23 | 
            -
                  #  | 
| 21 | 
            +
                  # limit is enforced by \Rails and is less than or equal to
         | 
| 22 | 
            +
                  # #index_name_length. The gap between
         | 
| 23 | 
            +
                  # #index_name_length is to allow internal \Rails
         | 
| 24 24 | 
             
                  # operations to use prefixes in temporary operations.
         | 
| 25 25 | 
             
                  def allowed_index_name_length
         | 
| 26 26 | 
             
                    index_name_length
         | 
| @@ -27,9 +27,19 @@ module ActiveRecord | |
| 27 27 | 
             
                  end
         | 
| 28 28 |  | 
| 29 29 | 
             
                  # Returns an ActiveRecord::Result instance.
         | 
| 30 | 
            -
                  def select_all(arel, name = nil, binds = [])
         | 
| 30 | 
            +
                  def select_all(arel, name = nil, binds = [], preparable: nil)
         | 
| 31 31 | 
             
                    arel, binds = binds_from_relation arel, binds
         | 
| 32 | 
            -
                     | 
| 32 | 
            +
                    sql = to_sql(arel, binds)
         | 
| 33 | 
            +
                    if !prepared_statements || (arel.is_a?(String) && preparable.nil?)
         | 
| 34 | 
            +
                      preparable = false
         | 
| 35 | 
            +
                    else
         | 
| 36 | 
            +
                      preparable = visitor.preparable
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
                    if prepared_statements && preparable
         | 
| 39 | 
            +
                      select_prepared(sql, name, binds)
         | 
| 40 | 
            +
                    else
         | 
| 41 | 
            +
                      select(sql, name, binds)
         | 
| 42 | 
            +
                    end
         | 
| 33 43 | 
             
                  end
         | 
| 34 44 |  | 
| 35 45 | 
             
                  # Returns a record hash with the column names as keys and column values
         | 
| @@ -40,33 +50,39 @@ module ActiveRecord | |
| 40 50 |  | 
| 41 51 | 
             
                  # Returns a single value from a record
         | 
| 42 52 | 
             
                  def select_value(arel, name = nil, binds = [])
         | 
| 43 | 
            -
                     | 
| 44 | 
            -
             | 
| 53 | 
            +
                    arel, binds = binds_from_relation arel, binds
         | 
| 54 | 
            +
                    if result = select_rows(to_sql(arel, binds), name, binds).first
         | 
| 55 | 
            +
                      result.first
         | 
| 45 56 | 
             
                    end
         | 
| 46 57 | 
             
                  end
         | 
| 47 58 |  | 
| 48 59 | 
             
                  # Returns an array of the values of the first column in a select:
         | 
| 49 60 | 
             
                  #   select_values("SELECT id FROM companies LIMIT 3") => [1,2,3]
         | 
| 50 | 
            -
                  def select_values(arel, name = nil)
         | 
| 51 | 
            -
                    arel, binds = binds_from_relation arel,  | 
| 61 | 
            +
                  def select_values(arel, name = nil, binds = [])
         | 
| 62 | 
            +
                    arel, binds = binds_from_relation arel, binds
         | 
| 52 63 | 
             
                    select_rows(to_sql(arel, binds), name, binds).map(&:first)
         | 
| 53 64 | 
             
                  end
         | 
| 54 65 |  | 
| 55 66 | 
             
                  # Returns an array of arrays containing the field values.
         | 
| 56 67 | 
             
                  # Order is the same as that returned by +columns+.
         | 
| 57 68 | 
             
                  def select_rows(sql, name = nil, binds = [])
         | 
| 69 | 
            +
                    exec_query(sql, name, binds).rows
         | 
| 58 70 | 
             
                  end
         | 
| 59 | 
            -
                  undef_method :select_rows
         | 
| 60 71 |  | 
| 61 | 
            -
                  # Executes the SQL statement in the context of this connection | 
| 72 | 
            +
                  # Executes the SQL statement in the context of this connection and returns
         | 
| 73 | 
            +
                  # the raw result from the connection adapter.
         | 
| 74 | 
            +
                  # Note: depending on your database connector, the result returned by this
         | 
| 75 | 
            +
                  # method may be manually memory managed. Consider using the exec_query
         | 
| 76 | 
            +
                  # wrapper instead.
         | 
| 62 77 | 
             
                  def execute(sql, name = nil)
         | 
| 78 | 
            +
                    raise NotImplementedError
         | 
| 63 79 | 
             
                  end
         | 
| 64 | 
            -
                  undef_method :execute
         | 
| 65 80 |  | 
| 66 81 | 
             
                  # Executes +sql+ statement in the context of this connection using
         | 
| 67 82 | 
             
                  # +binds+ as the bind substitutes. +name+ is logged along with
         | 
| 68 83 | 
             
                  # the executed +sql+ statement.
         | 
| 69 | 
            -
                  def exec_query(sql, name = 'SQL', binds = [])
         | 
| 84 | 
            +
                  def exec_query(sql, name = 'SQL', binds = [], prepare: false)
         | 
| 85 | 
            +
                    raise NotImplementedError
         | 
| 70 86 | 
             
                  end
         | 
| 71 87 |  | 
| 72 88 | 
             
                  # Executes insert +sql+ statement in the context of this connection using
         | 
| @@ -95,7 +111,7 @@ module ActiveRecord | |
| 95 111 | 
             
                    exec_query(sql, name, binds)
         | 
| 96 112 | 
             
                  end
         | 
| 97 113 |  | 
| 98 | 
            -
                  #  | 
| 114 | 
            +
                  # Executes an INSERT query and returns the new record's ID
         | 
| 99 115 | 
             
                  #
         | 
| 100 116 | 
             
                  # +id_value+ will be returned unless the value is nil, in
         | 
| 101 117 | 
             
                  # which case the database will attempt to calculate the last inserted
         | 
| @@ -104,20 +120,27 @@ module ActiveRecord | |
| 104 120 | 
             
                  # If the next id was calculated in advance (as in Oracle), it should be
         | 
| 105 121 | 
             
                  # passed in as +id_value+.
         | 
| 106 122 | 
             
                  def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
         | 
| 107 | 
            -
                    sql, binds = sql_for_insert(to_sql(arel, binds), pk, id_value, sequence_name, binds)
         | 
| 108 | 
            -
                    value | 
| 123 | 
            +
                    sql, binds, pk, sequence_name = sql_for_insert(to_sql(arel, binds), pk, id_value, sequence_name, binds)
         | 
| 124 | 
            +
                    value = exec_insert(sql, name, binds, pk, sequence_name)
         | 
| 109 125 | 
             
                    id_value || last_inserted_id(value)
         | 
| 110 126 | 
             
                  end
         | 
| 127 | 
            +
                  alias create insert
         | 
| 128 | 
            +
                  alias insert_sql insert
         | 
| 129 | 
            +
                  deprecate insert_sql: :insert
         | 
| 111 130 |  | 
| 112 131 | 
             
                  # Executes the update statement and returns the number of rows affected.
         | 
| 113 132 | 
             
                  def update(arel, name = nil, binds = [])
         | 
| 114 133 | 
             
                    exec_update(to_sql(arel, binds), name, binds)
         | 
| 115 134 | 
             
                  end
         | 
| 135 | 
            +
                  alias update_sql update
         | 
| 136 | 
            +
                  deprecate update_sql: :update
         | 
| 116 137 |  | 
| 117 138 | 
             
                  # Executes the delete statement and returns the number of rows affected.
         | 
| 118 139 | 
             
                  def delete(arel, name = nil, binds = [])
         | 
| 119 140 | 
             
                    exec_delete(to_sql(arel, binds), name, binds)
         | 
| 120 141 | 
             
                  end
         | 
| 142 | 
            +
                  alias delete_sql delete
         | 
| 143 | 
            +
                  deprecate delete_sql: :delete
         | 
| 121 144 |  | 
| 122 145 | 
             
                  # Returns +true+ when the connection adapter supports prepared statement
         | 
| 123 146 | 
             
                  # caching, otherwise returns +false+
         | 
| @@ -136,7 +159,7 @@ module ActiveRecord | |
| 136 159 | 
             
                  #
         | 
| 137 160 | 
             
                  # In order to get around this problem, #transaction will emulate the effect
         | 
| 138 161 | 
             
                  # of nested transactions, by using savepoints:
         | 
| 139 | 
            -
                  # http://dev.mysql.com/doc/refman/5. | 
| 162 | 
            +
                  # http://dev.mysql.com/doc/refman/5.7/en/savepoint.html
         | 
| 140 163 | 
             
                  # Savepoints are supported by MySQL and PostgreSQL. SQLite3 version >= '3.6.8'
         | 
| 141 164 | 
             
                  # supports savepoints.
         | 
| 142 165 | 
             
                  #
         | 
| @@ -188,29 +211,25 @@ module ActiveRecord | |
| 188 211 | 
             
                  # You should consult the documentation for your database to understand the
         | 
| 189 212 | 
             
                  # semantics of these different levels:
         | 
| 190 213 | 
             
                  #
         | 
| 191 | 
            -
                  # * http://www.postgresql.org/docs/ | 
| 192 | 
            -
                  # * https://dev.mysql.com/doc/refman/5. | 
| 214 | 
            +
                  # * http://www.postgresql.org/docs/current/static/transaction-iso.html
         | 
| 215 | 
            +
                  # * https://dev.mysql.com/doc/refman/5.7/en/set-transaction.html
         | 
| 193 216 | 
             
                  #
         | 
| 194 | 
            -
                  # An  | 
| 217 | 
            +
                  # An ActiveRecord::TransactionIsolationError will be raised if:
         | 
| 195 218 | 
             
                  #
         | 
| 196 219 | 
             
                  # * The adapter does not support setting the isolation level
         | 
| 197 220 | 
             
                  # * You are joining an existing open transaction
         | 
| 198 221 | 
             
                  # * You are creating a nested (savepoint) transaction
         | 
| 199 222 | 
             
                  #
         | 
| 200 | 
            -
                  # The  | 
| 201 | 
            -
                  # isolation level. | 
| 202 | 
            -
                   | 
| 203 | 
            -
             | 
| 204 | 
            -
             | 
| 205 | 
            -
                    options.assert_valid_keys :requires_new, :joinable, :isolation
         | 
| 206 | 
            -
             | 
| 207 | 
            -
                    if !options[:requires_new] && current_transaction.joinable?
         | 
| 208 | 
            -
                      if options[:isolation]
         | 
| 223 | 
            +
                  # The mysql2 and postgresql adapters support setting the transaction
         | 
| 224 | 
            +
                  # isolation level.
         | 
| 225 | 
            +
                  def transaction(requires_new: nil, isolation: nil, joinable: true)
         | 
| 226 | 
            +
                    if !requires_new && current_transaction.joinable?
         | 
| 227 | 
            +
                      if isolation
         | 
| 209 228 | 
             
                        raise ActiveRecord::TransactionIsolationError, "cannot set isolation when joining a transaction"
         | 
| 210 229 | 
             
                      end
         | 
| 211 230 | 
             
                      yield
         | 
| 212 231 | 
             
                    else
         | 
| 213 | 
            -
                      transaction_manager.within_new_transaction( | 
| 232 | 
            +
                      transaction_manager.within_new_transaction(isolation: isolation, joinable: joinable) { yield }
         | 
| 214 233 | 
             
                    end
         | 
| 215 234 | 
             
                  rescue ActiveRecord::Rollback
         | 
| 216 235 | 
             
                    # rollbacks are silently swallowed
         | 
| @@ -272,9 +291,6 @@ module ActiveRecord | |
| 272 291 | 
             
                    exec_rollback_to_savepoint(name)
         | 
| 273 292 | 
             
                  end
         | 
| 274 293 |  | 
| 275 | 
            -
                  def exec_rollback_to_savepoint(name = nil) #:nodoc:
         | 
| 276 | 
            -
                  end
         | 
| 277 | 
            -
             | 
| 278 294 | 
             
                  def default_sequence_name(table, column)
         | 
| 279 295 | 
             
                    nil
         | 
| 280 296 | 
             
                  end
         | 
| @@ -288,17 +304,24 @@ module ActiveRecord | |
| 288 304 | 
             
                  # something beyond a simple insert (eg. Oracle).
         | 
| 289 305 | 
             
                  def insert_fixture(fixture, table_name)
         | 
| 290 306 | 
             
                    fixture = fixture.stringify_keys
         | 
| 291 | 
            -
                    columns = schema_cache.columns_hash(table_name)
         | 
| 292 307 |  | 
| 293 | 
            -
                     | 
| 294 | 
            -
                     | 
| 308 | 
            +
                    columns = schema_cache.columns_hash(table_name)
         | 
| 309 | 
            +
                    binds = fixture.map do |name, value|
         | 
| 295 310 | 
             
                      if column = columns[name]
         | 
| 296 | 
            -
                         | 
| 297 | 
            -
                         | 
| 311 | 
            +
                        type = lookup_cast_type_from_column(column)
         | 
| 312 | 
            +
                        Relation::QueryAttribute.new(name, value, type)
         | 
| 298 313 | 
             
                      else
         | 
| 299 314 | 
             
                        raise Fixture::FixtureError, %(table "#{table_name}" has no column named #{name.inspect}.)
         | 
| 300 315 | 
             
                      end
         | 
| 301 316 | 
             
                    end
         | 
| 317 | 
            +
                    key_list = fixture.keys.map { |name| quote_column_name(name) }
         | 
| 318 | 
            +
                    value_list = prepare_binds_for_database(binds).map do |value|
         | 
| 319 | 
            +
                      begin
         | 
| 320 | 
            +
                        quote(value)
         | 
| 321 | 
            +
                      rescue TypeError
         | 
| 322 | 
            +
                        quote(YAML.dump(value))
         | 
| 323 | 
            +
                      end
         | 
| 324 | 
            +
                    end
         | 
| 302 325 |  | 
| 303 326 | 
             
                    execute "INSERT INTO #{quote_table_name(table_name)} (#{key_list.join(', ')}) VALUES (#{value_list.join(', ')})", 'Fixture Insert'
         | 
| 304 327 | 
             
                  end
         | 
| @@ -329,18 +352,12 @@ module ActiveRecord | |
| 329 352 | 
             
                  # The default strategy for an UPDATE with joins is to use a subquery. This doesn't work
         | 
| 330 353 | 
             
                  # on MySQL (even when aliasing the tables), but MySQL allows using JOIN directly in
         | 
| 331 354 | 
             
                  # an UPDATE statement, so in the MySQL adapters we redefine this to do that.
         | 
| 332 | 
            -
                  def join_to_update(update, select)  | 
| 333 | 
            -
                    key = update.key
         | 
| 355 | 
            +
                  def join_to_update(update, select, key) # :nodoc:
         | 
| 334 356 | 
             
                    subselect = subquery_for(key, select)
         | 
| 335 357 |  | 
| 336 358 | 
             
                    update.where key.in(subselect)
         | 
| 337 359 | 
             
                  end
         | 
| 338 | 
            -
             | 
| 339 | 
            -
                  def join_to_delete(delete, select, key) #:nodoc:
         | 
| 340 | 
            -
                    subselect = subquery_for(key, select)
         | 
| 341 | 
            -
             | 
| 342 | 
            -
                    delete.where key.in(subselect)
         | 
| 343 | 
            -
                  end
         | 
| 360 | 
            +
                  alias join_to_delete join_to_update
         | 
| 344 361 |  | 
| 345 362 | 
             
                  protected
         | 
| 346 363 |  | 
| @@ -353,28 +370,15 @@ module ActiveRecord | |
| 353 370 |  | 
| 354 371 | 
             
                    # Returns an ActiveRecord::Result instance.
         | 
| 355 372 | 
             
                    def select(sql, name = nil, binds = [])
         | 
| 356 | 
            -
                      exec_query(sql, name, binds)
         | 
| 357 | 
            -
                    end
         | 
| 358 | 
            -
             | 
| 359 | 
            -
             | 
| 360 | 
            -
                    # Returns the last auto-generated ID from the affected table.
         | 
| 361 | 
            -
                    def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
         | 
| 362 | 
            -
                      execute(sql, name)
         | 
| 363 | 
            -
                      id_value
         | 
| 364 | 
            -
                    end
         | 
| 365 | 
            -
             | 
| 366 | 
            -
                    # Executes the update statement and returns the number of rows affected.
         | 
| 367 | 
            -
                    def update_sql(sql, name = nil)
         | 
| 368 | 
            -
                      execute(sql, name)
         | 
| 373 | 
            +
                      exec_query(sql, name, binds, prepare: false)
         | 
| 369 374 | 
             
                    end
         | 
| 370 375 |  | 
| 371 | 
            -
                     | 
| 372 | 
            -
             | 
| 373 | 
            -
                      update_sql(sql, name)
         | 
| 376 | 
            +
                    def select_prepared(sql, name = nil, binds = [])
         | 
| 377 | 
            +
                      exec_query(sql, name, binds, prepare: true)
         | 
| 374 378 | 
             
                    end
         | 
| 375 379 |  | 
| 376 380 | 
             
                    def sql_for_insert(sql, pk, id_value, sequence_name, binds)
         | 
| 377 | 
            -
                      [sql, binds]
         | 
| 381 | 
            +
                      [sql, binds, pk, sequence_name]
         | 
| 378 382 | 
             
                    end
         | 
| 379 383 |  | 
| 380 384 | 
             
                    def last_inserted_id(result)
         | 
| @@ -384,7 +388,7 @@ module ActiveRecord | |
| 384 388 |  | 
| 385 389 | 
             
                    def binds_from_relation(relation, binds)
         | 
| 386 390 | 
             
                      if relation.is_a?(Relation) && binds.empty?
         | 
| 387 | 
            -
                        relation, binds = relation.arel, relation. | 
| 391 | 
            +
                        relation, binds = relation.arel, relation.bound_attributes
         | 
| 388 392 | 
             
                      end
         | 
| 389 393 | 
             
                      [relation, binds]
         | 
| 390 394 | 
             
                    end
         | 
| @@ -61,11 +61,11 @@ module ActiveRecord | |
| 61 61 | 
             
                    @query_cache.clear
         | 
| 62 62 | 
             
                  end
         | 
| 63 63 |  | 
| 64 | 
            -
                  def select_all(arel, name = nil, binds = [])
         | 
| 64 | 
            +
                  def select_all(arel, name = nil, binds = [], preparable: nil)
         | 
| 65 65 | 
             
                    if @query_cache_enabled && !locked?(arel)
         | 
| 66 66 | 
             
                      arel, binds = binds_from_relation arel, binds
         | 
| 67 67 | 
             
                      sql = to_sql(arel, binds)
         | 
| 68 | 
            -
                      cache_sql(sql, binds) { super(sql, name, binds) }
         | 
| 68 | 
            +
                      cache_sql(sql, binds) { super(sql, name, binds, preparable: preparable) }
         | 
| 69 69 | 
             
                    else
         | 
| 70 70 | 
             
                      super
         | 
| 71 71 | 
             
                    end
         | 
| @@ -1,5 +1,4 @@ | |
| 1 1 | 
             
            require 'active_support/core_ext/big_decimal/conversions'
         | 
| 2 | 
            -
            require "active_support/multibyte/chars"
         | 
| 3 2 |  | 
| 4 3 | 
             
            module ActiveRecord
         | 
| 5 4 | 
             
              module ConnectionAdapters # :nodoc:
         | 
| @@ -11,7 +10,13 @@ module ActiveRecord | |
| 11 10 | 
             
                    return value.quoted_id if value.respond_to?(:quoted_id)
         | 
| 12 11 |  | 
| 13 12 | 
             
                    if column
         | 
| 14 | 
            -
                       | 
| 13 | 
            +
                      ActiveSupport::Deprecation.warn(<<-MSG.squish)
         | 
| 14 | 
            +
                        Passing a column to `quote` has been deprecated. It is only used
         | 
| 15 | 
            +
                        for type casting, which should be handled elsewhere. See
         | 
| 16 | 
            +
                        https://github.com/rails/arel/commit/6160bfbda1d1781c3b08a33ec4955f170e95be11
         | 
| 17 | 
            +
                        for more information.
         | 
| 18 | 
            +
                      MSG
         | 
| 19 | 
            +
                      value = type_cast_from_column(column, value)
         | 
| 15 20 | 
             
                    end
         | 
| 16 21 |  | 
| 17 22 | 
             
                    _quote(value)
         | 
| @@ -20,13 +25,13 @@ module ActiveRecord | |
| 20 25 | 
             
                  # Cast a +value+ to a type that the database understands. For example,
         | 
| 21 26 | 
             
                  # SQLite does not understand dates, so this method will convert a Date
         | 
| 22 27 | 
             
                  # to a String.
         | 
| 23 | 
            -
                  def type_cast(value, column)
         | 
| 28 | 
            +
                  def type_cast(value, column = nil)
         | 
| 24 29 | 
             
                    if value.respond_to?(:quoted_id) && value.respond_to?(:id)
         | 
| 25 30 | 
             
                      return value.id
         | 
| 26 31 | 
             
                    end
         | 
| 27 32 |  | 
| 28 33 | 
             
                    if column
         | 
| 29 | 
            -
                      value = column | 
| 34 | 
            +
                      value = type_cast_from_column(column, value)
         | 
| 30 35 | 
             
                    end
         | 
| 31 36 |  | 
| 32 37 | 
             
                    _type_cast(value)
         | 
| @@ -35,15 +40,49 @@ module ActiveRecord | |
| 35 40 | 
             
                    raise TypeError, "can't cast #{value.class}#{to_type}"
         | 
| 36 41 | 
             
                  end
         | 
| 37 42 |  | 
| 43 | 
            +
                  # If you are having to call this function, you are likely doing something
         | 
| 44 | 
            +
                  # wrong. The column does not have sufficient type information if the user
         | 
| 45 | 
            +
                  # provided a custom type on the class level either explicitly (via
         | 
| 46 | 
            +
                  # Attributes::ClassMethods#attribute) or implicitly (via
         | 
| 47 | 
            +
                  # AttributeMethods::Serialization::ClassMethods#serialize, +time_zone_aware_attributes+).
         | 
| 48 | 
            +
                  # In almost all cases, the sql type should only be used to change quoting behavior, when the primitive to
         | 
| 49 | 
            +
                  # represent the type doesn't sufficiently reflect the differences
         | 
| 50 | 
            +
                  # (varchar vs binary) for example. The type used to get this primitive
         | 
| 51 | 
            +
                  # should have been provided before reaching the connection adapter.
         | 
| 52 | 
            +
                  def type_cast_from_column(column, value) # :nodoc:
         | 
| 53 | 
            +
                    if column
         | 
| 54 | 
            +
                      type = lookup_cast_type_from_column(column)
         | 
| 55 | 
            +
                      type.serialize(value)
         | 
| 56 | 
            +
                    else
         | 
| 57 | 
            +
                      value
         | 
| 58 | 
            +
                    end
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  # See docs for #type_cast_from_column
         | 
| 62 | 
            +
                  def lookup_cast_type_from_column(column) # :nodoc:
         | 
| 63 | 
            +
                    lookup_cast_type(column.sql_type)
         | 
| 64 | 
            +
                  end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  def fetch_type_metadata(sql_type)
         | 
| 67 | 
            +
                    cast_type = lookup_cast_type(sql_type)
         | 
| 68 | 
            +
                    SqlTypeMetadata.new(
         | 
| 69 | 
            +
                      sql_type: sql_type,
         | 
| 70 | 
            +
                      type: cast_type.type,
         | 
| 71 | 
            +
                      limit: cast_type.limit,
         | 
| 72 | 
            +
                      precision: cast_type.precision,
         | 
| 73 | 
            +
                      scale: cast_type.scale,
         | 
| 74 | 
            +
                    )
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
             | 
| 38 77 | 
             
                  # Quotes a string, escaping any ' (single quote) and \ (backslash)
         | 
| 39 78 | 
             
                  # characters.
         | 
| 40 79 | 
             
                  def quote_string(s)
         | 
| 41 | 
            -
                    s.gsub( | 
| 80 | 
            +
                    s.gsub('\\'.freeze, '\&\&'.freeze).gsub("'".freeze, "''".freeze) # ' (for ruby-mode)
         | 
| 42 81 | 
             
                  end
         | 
| 43 82 |  | 
| 44 83 | 
             
                  # Quotes the column name. Defaults to no quoting.
         | 
| 45 84 | 
             
                  def quote_column_name(column_name)
         | 
| 46 | 
            -
                    column_name
         | 
| 85 | 
            +
                    column_name.to_s
         | 
| 47 86 | 
             
                  end
         | 
| 48 87 |  | 
| 49 88 | 
             
                  # Quotes the table name. Defaults to column name quoting.
         | 
| @@ -54,7 +93,7 @@ module ActiveRecord | |
| 54 93 | 
             
                  # Override to return the quoted table name for assignment. Defaults to
         | 
| 55 94 | 
             
                  # table quoting.
         | 
| 56 95 | 
             
                  #
         | 
| 57 | 
            -
                  # This works for  | 
| 96 | 
            +
                  # This works for mysql2 where table.column can be used to
         | 
| 58 97 | 
             
                  # resolve ambiguity.
         | 
| 59 98 | 
             
                  #
         | 
| 60 99 | 
             
                  # We override this in the sqlite3 and postgresql adapters to use only
         | 
| @@ -63,6 +102,15 @@ module ActiveRecord | |
| 63 102 | 
             
                    quote_table_name("#{table}.#{attr}")
         | 
| 64 103 | 
             
                  end
         | 
| 65 104 |  | 
| 105 | 
            +
                  def quote_default_expression(value, column) # :nodoc:
         | 
| 106 | 
            +
                    if value.is_a?(Proc)
         | 
| 107 | 
            +
                      value.call
         | 
| 108 | 
            +
                    else
         | 
| 109 | 
            +
                      value = lookup_cast_type(column.sql_type).serialize(value)
         | 
| 110 | 
            +
                      quote(value)
         | 
| 111 | 
            +
                    end
         | 
| 112 | 
            +
                  end
         | 
| 113 | 
            +
             | 
| 66 114 | 
             
                  def quoted_true
         | 
| 67 115 | 
             
                    "'t'"
         | 
| 68 116 | 
             
                  end
         | 
| @@ -79,6 +127,8 @@ module ActiveRecord | |
| 79 127 | 
             
                    'f'
         | 
| 80 128 | 
             
                  end
         | 
| 81 129 |  | 
| 130 | 
            +
                  # Quote date/time values for use in SQL input. Includes microseconds
         | 
| 131 | 
            +
                  # if the value is a Time responding to usec.
         | 
| 82 132 | 
             
                  def quoted_date(value)
         | 
| 83 133 | 
             
                    if value.acts_like?(:time)
         | 
| 84 134 | 
             
                      zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
         | 
| @@ -88,7 +138,20 @@ module ActiveRecord | |
| 88 138 | 
             
                      end
         | 
| 89 139 | 
             
                    end
         | 
| 90 140 |  | 
| 91 | 
            -
                    value.to_s(:db)
         | 
| 141 | 
            +
                    result = value.to_s(:db)
         | 
| 142 | 
            +
                    if value.respond_to?(:usec) && value.usec > 0
         | 
| 143 | 
            +
                      "#{result}.#{sprintf("%06d", value.usec)}"
         | 
| 144 | 
            +
                    else
         | 
| 145 | 
            +
                      result
         | 
| 146 | 
            +
                    end
         | 
| 147 | 
            +
                  end
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                  def quoted_time(value) # :nodoc:
         | 
| 150 | 
            +
                    quoted_date(value).sub(/\A2000-01-01 /, '')
         | 
| 151 | 
            +
                  end
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                  def prepare_binds_for_database(binds) # :nodoc:
         | 
| 154 | 
            +
                    binds.map(&:value_for_database)
         | 
| 92 155 | 
             
                  end
         | 
| 93 156 |  | 
| 94 157 | 
             
                  private
         | 
| @@ -107,11 +170,11 @@ module ActiveRecord | |
| 107 170 | 
             
                    # BigDecimals need to be put in a non-normalized form and quoted.
         | 
| 108 171 | 
             
                    when BigDecimal then value.to_s('F')
         | 
| 109 172 | 
             
                    when Numeric, ActiveSupport::Duration then value.to_s
         | 
| 173 | 
            +
                    when Type::Time::Value then "'#{quoted_time(value)}'"
         | 
| 110 174 | 
             
                    when Date, Time then "'#{quoted_date(value)}'"
         | 
| 111 175 | 
             
                    when Symbol     then "'#{quote_string(value.to_s)}'"
         | 
| 112 176 | 
             
                    when Class      then "'#{value}'"
         | 
| 113 | 
            -
                    else
         | 
| 114 | 
            -
                      "'#{quote_string(YAML.dump(value))}'"
         | 
| 177 | 
            +
                    else raise TypeError, "can't quote #{value.class.name}"
         | 
| 115 178 | 
             
                    end
         | 
| 116 179 | 
             
                  end
         | 
| 117 180 |  | 
| @@ -123,6 +186,7 @@ module ActiveRecord | |
| 123 186 | 
             
                    when false      then unquoted_false
         | 
| 124 187 | 
             
                    # BigDecimals need to be put in a non-normalized form and quoted.
         | 
| 125 188 | 
             
                    when BigDecimal then value.to_s('F')
         | 
| 189 | 
            +
                    when Type::Time::Value then quoted_time(value)
         | 
| 126 190 | 
             
                    when Date, Time then quoted_date(value)
         | 
| 127 191 | 
             
                    when *types_which_need_no_typecasting
         | 
| 128 192 | 
             
                      value
         | 
| @@ -14,38 +14,58 @@ module ActiveRecord | |
| 14 14 | 
             
                      send m, o
         | 
| 15 15 | 
             
                    end
         | 
| 16 16 |  | 
| 17 | 
            -
                     | 
| 18 | 
            -
                       | 
| 19 | 
            -
                     | 
| 17 | 
            +
                    delegate :quote_column_name, :quote_table_name, :quote_default_expression, :type_to_sql,
         | 
| 18 | 
            +
                      :options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys?, :foreign_key_options, to: :@conn
         | 
| 19 | 
            +
                    private :quote_column_name, :quote_table_name, :quote_default_expression, :type_to_sql,
         | 
| 20 | 
            +
                      :options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys?, :foreign_key_options
         | 
| 20 21 |  | 
| 21 22 | 
             
                    private
         | 
| 22 23 |  | 
| 23 24 | 
             
                      def visit_AlterTable(o)
         | 
| 24 25 | 
             
                        sql = "ALTER TABLE #{quote_table_name(o.name)} "
         | 
| 25 | 
            -
                        sql << o.adds.map { |col|  | 
| 26 | 
            +
                        sql << o.adds.map { |col| accept col }.join(' ')
         | 
| 26 27 | 
             
                        sql << o.foreign_key_adds.map { |fk| visit_AddForeignKey fk }.join(' ')
         | 
| 27 28 | 
             
                        sql << o.foreign_key_drops.map { |fk| visit_DropForeignKey fk }.join(' ')
         | 
| 28 29 | 
             
                      end
         | 
| 29 30 |  | 
| 30 31 | 
             
                      def visit_ColumnDefinition(o)
         | 
| 31 | 
            -
                        sql_type  | 
| 32 | 
            -
                        column_sql = "#{quote_column_name(o.name)} #{sql_type}"
         | 
| 33 | 
            -
                        add_column_options!(column_sql, column_options(o)) unless o.primary_key | 
| 32 | 
            +
                        o.sql_type ||= type_to_sql(o.type, o.limit, o.precision, o.scale)
         | 
| 33 | 
            +
                        column_sql = "#{quote_column_name(o.name)} #{o.sql_type}"
         | 
| 34 | 
            +
                        add_column_options!(column_sql, column_options(o)) unless o.type == :primary_key
         | 
| 34 35 | 
             
                        column_sql
         | 
| 35 36 | 
             
                      end
         | 
| 36 37 |  | 
| 38 | 
            +
                      def visit_AddColumnDefinition(o)
         | 
| 39 | 
            +
                        "ADD #{accept(o.column)}"
         | 
| 40 | 
            +
                      end
         | 
| 41 | 
            +
             | 
| 37 42 | 
             
                      def visit_TableDefinition(o)
         | 
| 38 | 
            -
                        create_sql = "CREATE#{' TEMPORARY' if o.temporary} TABLE "
         | 
| 39 | 
            -
             | 
| 40 | 
            -
                         | 
| 41 | 
            -
                         | 
| 43 | 
            +
                        create_sql = "CREATE#{' TEMPORARY' if o.temporary} TABLE #{quote_table_name(o.name)} "
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                        statements = o.columns.map { |c| accept c }
         | 
| 46 | 
            +
                        statements << accept(o.primary_keys) if o.primary_keys
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                        if supports_indexes_in_create?
         | 
| 49 | 
            +
                          statements.concat(o.indexes.map { |column_name, options| index_in_create(o.name, column_name, options) })
         | 
| 50 | 
            +
                        end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                        if supports_foreign_keys?
         | 
| 53 | 
            +
                          statements.concat(o.foreign_keys.map { |to_table, options| foreign_key_in_create(o.name, to_table, options) })
         | 
| 54 | 
            +
                        end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                        create_sql << "(#{statements.join(', ')})" if statements.present?
         | 
| 57 | 
            +
                        add_table_options!(create_sql, table_options(o))
         | 
| 42 58 | 
             
                        create_sql << " AS #{@conn.to_sql(o.as)}" if o.as
         | 
| 43 59 | 
             
                        create_sql
         | 
| 44 60 | 
             
                      end
         | 
| 45 61 |  | 
| 46 | 
            -
                      def  | 
| 62 | 
            +
                      def visit_PrimaryKeyDefinition(o)
         | 
| 63 | 
            +
                        "PRIMARY KEY (#{o.name.join(', ')})"
         | 
| 64 | 
            +
                      end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                      def visit_ForeignKeyDefinition(o)
         | 
| 47 67 | 
             
                        sql = <<-SQL.strip_heredoc
         | 
| 48 | 
            -
                           | 
| 68 | 
            +
                          CONSTRAINT #{quote_column_name(o.name)}
         | 
| 49 69 | 
             
                          FOREIGN KEY (#{quote_column_name(o.column)})
         | 
| 50 70 | 
             
                            REFERENCES #{quote_table_name(o.to_table)} (#{quote_column_name(o.primary_key)})
         | 
| 51 71 | 
             
                        SQL
         | 
| @@ -54,10 +74,27 @@ module ActiveRecord | |
| 54 74 | 
             
                        sql
         | 
| 55 75 | 
             
                      end
         | 
| 56 76 |  | 
| 77 | 
            +
                      def visit_AddForeignKey(o)
         | 
| 78 | 
            +
                        "ADD #{accept(o)}"
         | 
| 79 | 
            +
                      end
         | 
| 80 | 
            +
             | 
| 57 81 | 
             
                      def visit_DropForeignKey(name)
         | 
| 58 82 | 
             
                        "DROP CONSTRAINT #{quote_column_name(name)}"
         | 
| 59 83 | 
             
                      end
         | 
| 60 84 |  | 
| 85 | 
            +
                      def table_options(o)
         | 
| 86 | 
            +
                        table_options = {}
         | 
| 87 | 
            +
                        table_options[:comment] = o.comment
         | 
| 88 | 
            +
                        table_options[:options] = o.options
         | 
| 89 | 
            +
                        table_options
         | 
| 90 | 
            +
                      end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                      def add_table_options!(create_sql, options)
         | 
| 93 | 
            +
                        if options_sql = options[:options]
         | 
| 94 | 
            +
                          create_sql << " #{options_sql}"
         | 
| 95 | 
            +
                        end
         | 
| 96 | 
            +
                      end
         | 
| 97 | 
            +
             | 
| 61 98 | 
             
                      def column_options(o)
         | 
| 62 99 | 
             
                        column_options = {}
         | 
| 63 100 | 
             
                        column_options[:null] = o.null unless o.null.nil?
         | 
| @@ -65,23 +102,15 @@ module ActiveRecord | |
| 65 102 | 
             
                        column_options[:column] = o
         | 
| 66 103 | 
             
                        column_options[:first] = o.first
         | 
| 67 104 | 
             
                        column_options[:after] = o.after
         | 
| 105 | 
            +
                        column_options[:auto_increment] = o.auto_increment
         | 
| 106 | 
            +
                        column_options[:primary_key] = o.primary_key
         | 
| 107 | 
            +
                        column_options[:collation] = o.collation
         | 
| 108 | 
            +
                        column_options[:comment] = o.comment
         | 
| 68 109 | 
             
                        column_options
         | 
| 69 110 | 
             
                      end
         | 
| 70 111 |  | 
| 71 | 
            -
                      def quote_column_name(name)
         | 
| 72 | 
            -
                        @conn.quote_column_name name
         | 
| 73 | 
            -
                      end
         | 
| 74 | 
            -
             | 
| 75 | 
            -
                      def quote_table_name(name)
         | 
| 76 | 
            -
                        @conn.quote_table_name name
         | 
| 77 | 
            -
                      end
         | 
| 78 | 
            -
             | 
| 79 | 
            -
                      def type_to_sql(type, limit, precision, scale)
         | 
| 80 | 
            -
                        @conn.type_to_sql type.to_sym, limit, precision, scale
         | 
| 81 | 
            -
                      end
         | 
| 82 | 
            -
             | 
| 83 112 | 
             
                      def add_column_options!(sql, options)
         | 
| 84 | 
            -
                        sql << " DEFAULT #{ | 
| 113 | 
            +
                        sql << " DEFAULT #{quote_default_expression(options[:default], options[:column])}" if options_include_default?(options)
         | 
| 85 114 | 
             
                        # must explicitly check for :null to allow change_column to work on migrations
         | 
| 86 115 | 
             
                        if options[:null] == false
         | 
| 87 116 | 
             
                          sql << " NOT NULL"
         | 
| @@ -89,18 +118,15 @@ module ActiveRecord | |
| 89 118 | 
             
                        if options[:auto_increment] == true
         | 
| 90 119 | 
             
                          sql << " AUTO_INCREMENT"
         | 
| 91 120 | 
             
                        end
         | 
| 121 | 
            +
                        if options[:primary_key] == true
         | 
| 122 | 
            +
                          sql << " PRIMARY KEY"
         | 
| 123 | 
            +
                        end
         | 
| 92 124 | 
             
                        sql
         | 
| 93 125 | 
             
                      end
         | 
| 94 126 |  | 
| 95 | 
            -
                      def  | 
| 96 | 
            -
                         | 
| 97 | 
            -
                         | 
| 98 | 
            -
             | 
| 99 | 
            -
                        @conn.quote(value, column)
         | 
| 100 | 
            -
                      end
         | 
| 101 | 
            -
             | 
| 102 | 
            -
                      def options_include_default?(options)
         | 
| 103 | 
            -
                        options.include?(:default) && !(options[:null] == false && options[:default].nil?)
         | 
| 127 | 
            +
                      def foreign_key_in_create(from_table, to_table, options)
         | 
| 128 | 
            +
                        options = foreign_key_options(from_table, to_table, options)
         | 
| 129 | 
            +
                        accept ForeignKeyDefinition.new(from_table, to_table, options)
         | 
| 104 130 | 
             
                      end
         | 
| 105 131 |  | 
| 106 132 | 
             
                      def action_sql(action, dependency)
         | 
| @@ -115,10 +141,6 @@ module ActiveRecord | |
| 115 141 | 
             
                          MSG
         | 
| 116 142 | 
             
                        end
         | 
| 117 143 | 
             
                      end
         | 
| 118 | 
            -
             | 
| 119 | 
            -
                      def type_for_column(column)
         | 
| 120 | 
            -
                        @conn.lookup_cast_type(column.sql_type)
         | 
| 121 | 
            -
                      end
         | 
| 122 144 | 
             
                  end
         | 
| 123 145 | 
             
                end
         | 
| 124 146 | 
             
              end
         |