activerecord 5.0.0.beta1.1 → 5.0.0.beta2
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 +123 -15
- data/MIT-LICENSE +2 -2
- data/README.rdoc +1 -1
- data/lib/active_record.rb +2 -1
- data/lib/active_record/aggregations.rb +1 -1
- data/lib/active_record/associations.rb +3 -0
- data/lib/active_record/associations/builder/belongs_to.rb +1 -1
- data/lib/active_record/associations/builder/has_one.rb +1 -1
- data/lib/active_record/associations/builder/singular_association.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +5 -0
- data/lib/active_record/associations/join_dependency/join_association.rb +1 -2
- data/lib/active_record/associations/preloader/through_association.rb +7 -2
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +11 -7
- data/lib/active_record/autosave_association.rb +18 -3
- data/lib/active_record/base.rb +0 -3
- data/lib/active_record/collection_cache_key.rb +12 -3
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +21 -34
- data/lib/active_record/connection_adapters/abstract/quoting.rb +8 -4
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +7 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +36 -20
- data/lib/active_record/connection_adapters/abstract/transaction.rb +8 -2
- data/lib/active_record/connection_adapters/abstract_adapter.rb +8 -15
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +57 -198
- data/lib/active_record/connection_adapters/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/column.rb +50 -0
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +70 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +24 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +32 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +15 -34
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +7 -69
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +42 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +4 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +0 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +8 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +5 -4
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +3 -7
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +15 -23
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +19 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +2 -31
- data/lib/active_record/connection_handling.rb +1 -1
- data/lib/active_record/core.rb +1 -1
- data/lib/active_record/counter_cache.rb +4 -4
- data/lib/active_record/enum.rb +8 -5
- data/lib/active_record/errors.rb +6 -1
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/inheritance.rb +6 -1
- data/lib/active_record/internal_metadata.rb +56 -0
- data/lib/active_record/migration.rb +85 -20
- data/lib/active_record/migration/compatibility.rb +28 -2
- data/lib/active_record/model_schema.rb +25 -1
- data/lib/active_record/persistence.rb +11 -10
- data/lib/active_record/railtie.rb +6 -3
- data/lib/active_record/railties/databases.rake +20 -6
- data/lib/active_record/reflection.rb +39 -31
- data/lib/active_record/relation.rb +4 -4
- data/lib/active_record/relation/batches.rb +26 -41
- data/lib/active_record/relation/batches/batch_enumerator.rb +6 -6
- data/lib/active_record/relation/finder_methods.rb +35 -13
- data/lib/active_record/relation/from_clause.rb +1 -1
- data/lib/active_record/relation/merger.rb +3 -0
- data/lib/active_record/relation/predicate_builder.rb +19 -1
- data/lib/active_record/relation/predicate_builder/range_handler.rb +17 -1
- data/lib/active_record/relation/query_methods.rb +37 -19
- data/lib/active_record/relation/record_fetch_warning.rb +4 -6
- data/lib/active_record/relation/where_clause.rb +1 -1
- data/lib/active_record/relation/where_clause_factory.rb +1 -0
- data/lib/active_record/sanitization.rb +1 -1
- data/lib/active_record/schema.rb +3 -0
- data/lib/active_record/schema_dumper.rb +1 -1
- data/lib/active_record/schema_migration.rb +5 -14
- data/lib/active_record/scoping.rb +17 -11
- data/lib/active_record/scoping/default.rb +2 -2
- data/lib/active_record/tasks/database_tasks.rb +18 -0
- data/lib/active_record/timestamp.rb +5 -1
- data/lib/active_record/transactions.rb +3 -3
- data/lib/active_record/validations/uniqueness.rb +6 -3
- data/lib/rails/generators/active_record/migration/templates/migration.rb +4 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +7 -1
- metadata +14 -7
| @@ -3,11 +3,11 @@ module ActiveRecord | |
| 3 3 | 
             
                class BatchEnumerator
         | 
| 4 4 | 
             
                  include Enumerable
         | 
| 5 5 |  | 
| 6 | 
            -
                  def initialize(of: 1000,  | 
| 6 | 
            +
                  def initialize(of: 1000, start: nil, finish: nil, relation:) #:nodoc:
         | 
| 7 7 | 
             
                    @of       = of
         | 
| 8 8 | 
             
                    @relation = relation
         | 
| 9 | 
            -
                    @ | 
| 10 | 
            -
                    @ | 
| 9 | 
            +
                    @start = start
         | 
| 10 | 
            +
                    @finish   = finish
         | 
| 11 11 | 
             
                  end
         | 
| 12 12 |  | 
| 13 13 | 
             
                  # Looping through a collection of records from the database (using the
         | 
| @@ -34,7 +34,7 @@ module ActiveRecord | |
| 34 34 | 
             
                  def each_record
         | 
| 35 35 | 
             
                    return to_enum(:each_record) unless block_given?
         | 
| 36 36 |  | 
| 37 | 
            -
                    @relation.to_enum(:in_batches, of: @of,  | 
| 37 | 
            +
                    @relation.to_enum(:in_batches, of: @of, start: @start, finish: @finish, load: true).each do |relation|
         | 
| 38 38 | 
             
                      relation.to_a.each { |record| yield record }
         | 
| 39 39 | 
             
                    end
         | 
| 40 40 | 
             
                  end
         | 
| @@ -46,7 +46,7 @@ module ActiveRecord | |
| 46 46 | 
             
                  #   People.in_batches.update_all('age = age + 1')
         | 
| 47 47 | 
             
                  [:delete_all, :update_all, :destroy_all].each do |method|
         | 
| 48 48 | 
             
                    define_method(method) do |*args, &block|
         | 
| 49 | 
            -
                      @relation.to_enum(:in_batches, of: @of,  | 
| 49 | 
            +
                      @relation.to_enum(:in_batches, of: @of, start: @start, finish: @finish, load: false).each do |relation|
         | 
| 50 50 | 
             
                        relation.send(method, *args, &block)
         | 
| 51 51 | 
             
                      end
         | 
| 52 52 | 
             
                    end
         | 
| @@ -58,7 +58,7 @@ module ActiveRecord | |
| 58 58 | 
             
                  #     relation.update_all(awesome: true)
         | 
| 59 59 | 
             
                  #   end
         | 
| 60 60 | 
             
                  def each
         | 
| 61 | 
            -
                    enum = @relation.to_enum(:in_batches, of: @of,  | 
| 61 | 
            +
                    enum = @relation.to_enum(:in_batches, of: @of, start: @start, finish: @finish, load: false)
         | 
| 62 62 | 
             
                    return enum.each { |relation| yield relation } if block_given?
         | 
| 63 63 | 
             
                    enum
         | 
| 64 64 | 
             
                  end
         | 
| @@ -117,9 +117,9 @@ module ActiveRecord | |
| 117 117 | 
             
                #
         | 
| 118 118 | 
             
                def first(limit = nil)
         | 
| 119 119 | 
             
                  if limit
         | 
| 120 | 
            -
                     | 
| 120 | 
            +
                    find_nth_with_limit_and_offset(0, limit, offset: offset_index)
         | 
| 121 121 | 
             
                  else
         | 
| 122 | 
            -
                    find_nth | 
| 122 | 
            +
                    find_nth 0
         | 
| 123 123 | 
             
                  end
         | 
| 124 124 | 
             
                end
         | 
| 125 125 |  | 
| @@ -169,7 +169,7 @@ module ActiveRecord | |
| 169 169 | 
             
                #   Person.offset(3).second # returns the second object from OFFSET 3 (which is OFFSET 4)
         | 
| 170 170 | 
             
                #   Person.where(["user_name = :u", { u: user_name }]).second
         | 
| 171 171 | 
             
                def second
         | 
| 172 | 
            -
                  find_nth | 
| 172 | 
            +
                  find_nth 1
         | 
| 173 173 | 
             
                end
         | 
| 174 174 |  | 
| 175 175 | 
             
                # Same as #second but raises ActiveRecord::RecordNotFound if no record
         | 
| @@ -185,7 +185,7 @@ module ActiveRecord | |
| 185 185 | 
             
                #   Person.offset(3).third # returns the third object from OFFSET 3 (which is OFFSET 5)
         | 
| 186 186 | 
             
                #   Person.where(["user_name = :u", { u: user_name }]).third
         | 
| 187 187 | 
             
                def third
         | 
| 188 | 
            -
                  find_nth | 
| 188 | 
            +
                  find_nth 2
         | 
| 189 189 | 
             
                end
         | 
| 190 190 |  | 
| 191 191 | 
             
                # Same as #third but raises ActiveRecord::RecordNotFound if no record
         | 
| @@ -201,7 +201,7 @@ module ActiveRecord | |
| 201 201 | 
             
                #   Person.offset(3).fourth # returns the fourth object from OFFSET 3 (which is OFFSET 6)
         | 
| 202 202 | 
             
                #   Person.where(["user_name = :u", { u: user_name }]).fourth
         | 
| 203 203 | 
             
                def fourth
         | 
| 204 | 
            -
                  find_nth | 
| 204 | 
            +
                  find_nth 3
         | 
| 205 205 | 
             
                end
         | 
| 206 206 |  | 
| 207 207 | 
             
                # Same as #fourth but raises ActiveRecord::RecordNotFound if no record
         | 
| @@ -217,7 +217,7 @@ module ActiveRecord | |
| 217 217 | 
             
                #   Person.offset(3).fifth # returns the fifth object from OFFSET 3 (which is OFFSET 7)
         | 
| 218 218 | 
             
                #   Person.where(["user_name = :u", { u: user_name }]).fifth
         | 
| 219 219 | 
             
                def fifth
         | 
| 220 | 
            -
                  find_nth | 
| 220 | 
            +
                  find_nth 4
         | 
| 221 221 | 
             
                end
         | 
| 222 222 |  | 
| 223 223 | 
             
                # Same as #fifth but raises ActiveRecord::RecordNotFound if no record
         | 
| @@ -233,7 +233,7 @@ module ActiveRecord | |
| 233 233 | 
             
                #   Person.offset(3).forty_two # returns the forty-second object from OFFSET 3 (which is OFFSET 44)
         | 
| 234 234 | 
             
                #   Person.where(["user_name = :u", { u: user_name }]).forty_two
         | 
| 235 235 | 
             
                def forty_two
         | 
| 236 | 
            -
                  find_nth | 
| 236 | 
            +
                  find_nth 41
         | 
| 237 237 | 
             
                end
         | 
| 238 238 |  | 
| 239 239 | 
             
                # Same as #forty_two but raises ActiveRecord::RecordNotFound if no record
         | 
| @@ -488,27 +488,38 @@ module ActiveRecord | |
| 488 488 | 
             
                  end
         | 
| 489 489 | 
             
                end
         | 
| 490 490 |  | 
| 491 | 
            -
                def find_nth(index, offset)
         | 
| 491 | 
            +
                def find_nth(index, offset = nil)
         | 
| 492 | 
            +
                  # TODO: once the offset argument is removed we rely on offset_index
         | 
| 493 | 
            +
                  # within find_nth_with_limit, rather than pass it in via
         | 
| 494 | 
            +
                  # find_nth_with_limit_and_offset
         | 
| 495 | 
            +
                  if offset
         | 
| 496 | 
            +
                    ActiveSupport::Deprecation.warn(<<-MSG.squish)
         | 
| 497 | 
            +
                      Passing an offset argument to find_nth is deprecated,
         | 
| 498 | 
            +
                      please use Relation#offset instead.
         | 
| 499 | 
            +
                    MSG
         | 
| 500 | 
            +
                  end
         | 
| 492 501 | 
             
                  if loaded?
         | 
| 493 502 | 
             
                    @records[index]
         | 
| 494 503 | 
             
                  else
         | 
| 495 | 
            -
                    offset  | 
| 496 | 
            -
                    @offsets[offset] ||=  | 
| 504 | 
            +
                    offset ||= offset_index
         | 
| 505 | 
            +
                    @offsets[offset + index] ||= find_nth_with_limit_and_offset(index, 1, offset: offset).first
         | 
| 497 506 | 
             
                  end
         | 
| 498 507 | 
             
                end
         | 
| 499 508 |  | 
| 500 509 | 
             
                def find_nth!(index)
         | 
| 501 | 
            -
                  find_nth(index | 
| 510 | 
            +
                  find_nth(index) or raise RecordNotFound.new("Couldn't find #{@klass.name} with [#{arel.where_sql(@klass.arel_engine)}]")
         | 
| 502 511 | 
             
                end
         | 
| 503 512 |  | 
| 504 | 
            -
                def find_nth_with_limit( | 
| 513 | 
            +
                def find_nth_with_limit(index, limit)
         | 
| 514 | 
            +
                  # TODO: once the offset argument is removed from find_nth,
         | 
| 515 | 
            +
                  # find_nth_with_limit_and_offset can be merged into this method
         | 
| 505 516 | 
             
                  relation = if order_values.empty? && primary_key
         | 
| 506 517 | 
             
                               order(arel_table[primary_key].asc)
         | 
| 507 518 | 
             
                             else
         | 
| 508 519 | 
             
                               self
         | 
| 509 520 | 
             
                             end
         | 
| 510 521 |  | 
| 511 | 
            -
                  relation = relation.offset( | 
| 522 | 
            +
                  relation = relation.offset(index) unless index.zero?
         | 
| 512 523 | 
             
                  relation.limit(limit).to_a
         | 
| 513 524 | 
             
                end
         | 
| 514 525 |  | 
| @@ -524,5 +535,16 @@ module ActiveRecord | |
| 524 535 | 
             
                      end
         | 
| 525 536 | 
             
                  end
         | 
| 526 537 | 
             
                end
         | 
| 538 | 
            +
             | 
| 539 | 
            +
                private
         | 
| 540 | 
            +
             | 
| 541 | 
            +
                def find_nth_with_limit_and_offset(index, limit, offset:) # :nodoc:
         | 
| 542 | 
            +
                  if loaded?
         | 
| 543 | 
            +
                    @records[index, limit]
         | 
| 544 | 
            +
                  else
         | 
| 545 | 
            +
                    index += offset
         | 
| 546 | 
            +
                    find_nth_with_limit(index, limit)
         | 
| 547 | 
            +
                  end
         | 
| 548 | 
            +
                end
         | 
| 527 549 | 
             
              end
         | 
| 528 550 | 
             
            end
         | 
| @@ -18,6 +18,7 @@ module ActiveRecord | |
| 18 18 | 
             
                  register_handler(Class, ClassHandler.new(self))
         | 
| 19 19 | 
             
                  register_handler(Base, BaseHandler.new(self))
         | 
| 20 20 | 
             
                  register_handler(Range, RangeHandler.new(self))
         | 
| 21 | 
            +
                  register_handler(RangeHandler::RangeWithBinds, RangeHandler.new(self))
         | 
| 21 22 | 
             
                  register_handler(Relation, RelationHandler.new)
         | 
| 22 23 | 
             
                  register_handler(Array, ArrayHandler.new(self))
         | 
| 23 24 | 
             
                  register_handler(AssociationQueryValue, AssociationQueryHandler.new(self))
         | 
| @@ -105,10 +106,23 @@ module ActiveRecord | |
| 105 106 | 
             
                      binds += bvs
         | 
| 106 107 | 
             
                    when Relation
         | 
| 107 108 | 
             
                      binds += value.bound_attributes
         | 
| 109 | 
            +
                    when Range
         | 
| 110 | 
            +
                      first = value.begin
         | 
| 111 | 
            +
                      last = value.end
         | 
| 112 | 
            +
                      unless first.respond_to?(:infinite?) && first.infinite?
         | 
| 113 | 
            +
                        binds << build_bind_param(column_name, first)
         | 
| 114 | 
            +
                        first = Arel::Nodes::BindParam.new
         | 
| 115 | 
            +
                      end
         | 
| 116 | 
            +
                      unless last.respond_to?(:infinite?) && last.infinite?
         | 
| 117 | 
            +
                        binds << build_bind_param(column_name, last)
         | 
| 118 | 
            +
                        last = Arel::Nodes::BindParam.new
         | 
| 119 | 
            +
                      end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                      result[column_name] = RangeHandler::RangeWithBinds.new(first, last, value.exclude_end?)
         | 
| 108 122 | 
             
                    else
         | 
| 109 123 | 
             
                      if can_be_bound?(column_name, value)
         | 
| 110 124 | 
             
                        result[column_name] = Arel::Nodes::BindParam.new
         | 
| 111 | 
            -
                        binds <<  | 
| 125 | 
            +
                        binds << build_bind_param(column_name, value)
         | 
| 112 126 | 
             
                      end
         | 
| 113 127 | 
             
                    end
         | 
| 114 128 | 
             
                  end
         | 
| @@ -145,5 +159,9 @@ module ActiveRecord | |
| 145 159 | 
             
                    handler_for(value).is_a?(BasicObjectHandler) &&
         | 
| 146 160 | 
             
                    !table.associated_with?(column_name)
         | 
| 147 161 | 
             
                end
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                def build_bind_param(column_name, value)
         | 
| 164 | 
            +
                  Relation::QueryAttribute.new(column_name.to_s, value, table.type(column_name))
         | 
| 165 | 
            +
                end
         | 
| 148 166 | 
             
              end
         | 
| 149 167 | 
             
            end
         | 
| @@ -1,12 +1,28 @@ | |
| 1 1 | 
             
            module ActiveRecord
         | 
| 2 2 | 
             
              class PredicateBuilder
         | 
| 3 3 | 
             
                class RangeHandler # :nodoc:
         | 
| 4 | 
            +
                  RangeWithBinds = Struct.new(:begin, :end, :exclude_end?)
         | 
| 5 | 
            +
             | 
| 4 6 | 
             
                  def initialize(predicate_builder)
         | 
| 5 7 | 
             
                    @predicate_builder = predicate_builder
         | 
| 6 8 | 
             
                  end
         | 
| 7 9 |  | 
| 8 10 | 
             
                  def call(attribute, value)
         | 
| 9 | 
            -
                     | 
| 11 | 
            +
                    if value.begin.respond_to?(:infinite?) && value.begin.infinite?
         | 
| 12 | 
            +
                      if value.end.respond_to?(:infinite?) && value.end.infinite?
         | 
| 13 | 
            +
                        attribute.not_in([])
         | 
| 14 | 
            +
                      elsif value.exclude_end?
         | 
| 15 | 
            +
                        attribute.lt(value.end)
         | 
| 16 | 
            +
                      else
         | 
| 17 | 
            +
                        attribute.lteq(value.end)
         | 
| 18 | 
            +
                      end
         | 
| 19 | 
            +
                    elsif value.end.respond_to?(:infinite?) && value.end.infinite?
         | 
| 20 | 
            +
                      attribute.gteq(value.begin)
         | 
| 21 | 
            +
                    elsif value.exclude_end?
         | 
| 22 | 
            +
                      attribute.gteq(value.begin).and(attribute.lt(value.end))
         | 
| 23 | 
            +
                    else
         | 
| 24 | 
            +
                      attribute.between(value)
         | 
| 25 | 
            +
                    end
         | 
| 10 26 | 
             
                  end
         | 
| 11 27 |  | 
| 12 28 | 
             
                  protected
         | 
| @@ -54,16 +54,17 @@ module ActiveRecord | |
| 54 54 | 
             
                  end
         | 
| 55 55 | 
             
                end
         | 
| 56 56 |  | 
| 57 | 
            +
                FROZEN_EMPTY_ARRAY = [].freeze
         | 
| 57 58 | 
             
                Relation::MULTI_VALUE_METHODS.each do |name|
         | 
| 58 59 | 
             
                  class_eval <<-CODE, __FILE__, __LINE__ + 1
         | 
| 59 | 
            -
                    def #{name}_values | 
| 60 | 
            -
                      @values[:#{name}] ||  | 
| 61 | 
            -
                    end | 
| 62 | 
            -
             | 
| 63 | 
            -
                    def #{name}_values=(values) | 
| 64 | 
            -
                      assert_mutability! | 
| 65 | 
            -
                      @values[:#{name}] = values | 
| 66 | 
            -
                    end | 
| 60 | 
            +
                    def #{name}_values
         | 
| 61 | 
            +
                      @values[:#{name}] || FROZEN_EMPTY_ARRAY
         | 
| 62 | 
            +
                    end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                    def #{name}_values=(values)
         | 
| 65 | 
            +
                      assert_mutability!
         | 
| 66 | 
            +
                      @values[:#{name}] = values
         | 
| 67 | 
            +
                    end
         | 
| 67 68 | 
             
                  CODE
         | 
| 68 69 | 
             
                end
         | 
| 69 70 |  | 
| @@ -116,8 +117,9 @@ module ActiveRecord | |
| 116 117 | 
             
                  result
         | 
| 117 118 | 
             
                end
         | 
| 118 119 |  | 
| 120 | 
            +
                FROZEN_EMPTY_HASH = {}.freeze
         | 
| 119 121 | 
             
                def create_with_value # :nodoc:
         | 
| 120 | 
            -
                  @values[:create_with] ||  | 
| 122 | 
            +
                  @values[:create_with] || FROZEN_EMPTY_HASH
         | 
| 121 123 | 
             
                end
         | 
| 122 124 |  | 
| 123 125 | 
             
                alias extensions extending_values
         | 
| @@ -649,16 +651,18 @@ module ActiveRecord | |
| 649 651 | 
             
                # they must differ only by #where (if no #group has been defined) or #having (if a #group is
         | 
| 650 652 | 
             
                # present). Neither relation may have a #limit, #offset, or #distinct set.
         | 
| 651 653 | 
             
                #
         | 
| 652 | 
            -
                #    Post.where("id = 1").or(Post.where(" | 
| 653 | 
            -
                #    # SELECT `posts`.* FROM `posts`  WHERE (('id = 1' OR ' | 
| 654 | 
            +
                #    Post.where("id = 1").or(Post.where("author_id = 3"))
         | 
| 655 | 
            +
                #    # SELECT `posts`.* FROM `posts`  WHERE (('id = 1' OR 'author_id = 3'))
         | 
| 654 656 | 
             
                #
         | 
| 655 657 | 
             
                def or(other)
         | 
| 656 658 | 
             
                  spawn.or!(other)
         | 
| 657 659 | 
             
                end
         | 
| 658 660 |  | 
| 659 661 | 
             
                def or!(other) # :nodoc:
         | 
| 660 | 
            -
                   | 
| 661 | 
            -
             | 
| 662 | 
            +
                  incompatible_values = structurally_incompatible_values_for_or(other)
         | 
| 663 | 
            +
             | 
| 664 | 
            +
                  unless incompatible_values.empty?
         | 
| 665 | 
            +
                    raise ArgumentError, "Relation passed to #or must be structurally compatible. Incompatible values: #{incompatible_values}"
         | 
| 662 666 | 
             
                  end
         | 
| 663 667 |  | 
| 664 668 | 
             
                  self.where_clause = self.where_clause.or(other.where_clause)
         | 
| @@ -1100,14 +1104,21 @@ module ActiveRecord | |
| 1100 1104 | 
             
                end
         | 
| 1101 1105 |  | 
| 1102 1106 | 
             
                def reverse_sql_order(order_query)
         | 
| 1103 | 
            -
                   | 
| 1107 | 
            +
                  if order_query.empty?
         | 
| 1108 | 
            +
                    return [table[primary_key].desc] if primary_key
         | 
| 1109 | 
            +
                    raise IrreversibleOrderError,
         | 
| 1110 | 
            +
                      "Relation has no current order and table has no primary key to be used as default order"
         | 
| 1111 | 
            +
                  end
         | 
| 1104 1112 |  | 
| 1105 1113 | 
             
                  order_query.flat_map do |o|
         | 
| 1106 1114 | 
             
                    case o
         | 
| 1107 1115 | 
             
                    when Arel::Nodes::Ordering
         | 
| 1108 1116 | 
             
                      o.reverse
         | 
| 1109 1117 | 
             
                    when String
         | 
| 1110 | 
            -
                      o | 
| 1118 | 
            +
                      if does_not_support_reverse?(o)
         | 
| 1119 | 
            +
                        raise IrreversibleOrderError, "Order #{o.inspect} can not be reversed automatically"
         | 
| 1120 | 
            +
                      end
         | 
| 1121 | 
            +
                      o.split(',').map! do |s|
         | 
| 1111 1122 | 
             
                        s.strip!
         | 
| 1112 1123 | 
             
                        s.gsub!(/\sasc\Z/i, ' DESC') || s.gsub!(/\sdesc\Z/i, ' ASC') || s.concat(' DESC')
         | 
| 1113 1124 | 
             
                      end
         | 
| @@ -1117,6 +1128,13 @@ module ActiveRecord | |
| 1117 1128 | 
             
                  end
         | 
| 1118 1129 | 
             
                end
         | 
| 1119 1130 |  | 
| 1131 | 
            +
                def does_not_support_reverse?(order)
         | 
| 1132 | 
            +
                  #uses sql function with multiple arguments
         | 
| 1133 | 
            +
                  order =~ /\([^()]*,[^()]*\)/ ||
         | 
| 1134 | 
            +
                    # uses "nulls first" like construction
         | 
| 1135 | 
            +
                    order =~ /nulls (first|last)\Z/i
         | 
| 1136 | 
            +
                end
         | 
| 1137 | 
            +
             | 
| 1120 1138 | 
             
                def build_order(arel)
         | 
| 1121 1139 | 
             
                  orders = order_values.uniq
         | 
| 1122 1140 | 
             
                  orders.reject!(&:blank?)
         | 
| @@ -1187,10 +1205,10 @@ module ActiveRecord | |
| 1187 1205 | 
             
                  end
         | 
| 1188 1206 | 
             
                end
         | 
| 1189 1207 |  | 
| 1190 | 
            -
                def  | 
| 1191 | 
            -
                  Relation::SINGLE_VALUE_METHODS. | 
| 1192 | 
            -
                    (Relation::MULTI_VALUE_METHODS - [:extending]). | 
| 1193 | 
            -
                    (Relation::CLAUSE_METHODS - [:having, :where]). | 
| 1208 | 
            +
                def structurally_incompatible_values_for_or(other)
         | 
| 1209 | 
            +
                  Relation::SINGLE_VALUE_METHODS.reject { |m| send("#{m}_value") == other.send("#{m}_value") } +
         | 
| 1210 | 
            +
                    (Relation::MULTI_VALUE_METHODS - [:extending]).reject { |m| send("#{m}_values") == other.send("#{m}_values") } +
         | 
| 1211 | 
            +
                    (Relation::CLAUSE_METHODS - [:having, :where]).reject { |m| send("#{m}_clause") == other.send("#{m}_clause") }
         | 
| 1194 1212 | 
             
                end
         | 
| 1195 1213 |  | 
| 1196 1214 | 
             
                def new_where_clause
         | 
| @@ -24,9 +24,7 @@ module ActiveRecord | |
| 24 24 | 
             
                  end
         | 
| 25 25 |  | 
| 26 26 | 
             
                  # :stopdoc:
         | 
| 27 | 
            -
                  ActiveSupport::Notifications.subscribe("sql.active_record") do  | 
| 28 | 
            -
                    payload = args.last
         | 
| 29 | 
            -
             | 
| 27 | 
            +
                  ActiveSupport::Notifications.subscribe("sql.active_record") do |*, payload|
         | 
| 30 28 | 
             
                    QueryRegistry.queries << payload[:sql]
         | 
| 31 29 | 
             
                  end
         | 
| 32 30 | 
             
                  # :startdoc:
         | 
| @@ -34,14 +32,14 @@ module ActiveRecord | |
| 34 32 | 
             
                  class QueryRegistry # :nodoc:
         | 
| 35 33 | 
             
                    extend ActiveSupport::PerThreadRegistry
         | 
| 36 34 |  | 
| 37 | 
            -
                     | 
| 35 | 
            +
                    attr_reader :queries
         | 
| 38 36 |  | 
| 39 37 | 
             
                    def initialize
         | 
| 40 | 
            -
                       | 
| 38 | 
            +
                      @queries = []
         | 
| 41 39 | 
             
                    end
         | 
| 42 40 |  | 
| 43 41 | 
             
                    def reset
         | 
| 44 | 
            -
                      @queries | 
| 42 | 
            +
                      @queries.clear
         | 
| 45 43 | 
             
                    end
         | 
| 46 44 | 
             
                  end
         | 
| 47 45 | 
             
                end
         | 
    
        data/lib/active_record/schema.rb
    CHANGED
    
    | @@ -51,6 +51,9 @@ module ActiveRecord | |
| 51 51 | 
             
                    initialize_schema_migrations_table
         | 
| 52 52 | 
             
                    connection.assume_migrated_upto_version(info[:version], migrations_paths)
         | 
| 53 53 | 
             
                  end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  ActiveRecord::InternalMetadata.create_table
         | 
| 56 | 
            +
                  ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Migrator.current_environment
         | 
| 54 57 | 
             
                end
         | 
| 55 58 |  | 
| 56 59 | 
             
                private
         | 
| @@ -254,7 +254,7 @@ HEADER | |
| 254 254 | 
             
                  end
         | 
| 255 255 |  | 
| 256 256 | 
             
                  def ignored?(table_name)
         | 
| 257 | 
            -
                    [ActiveRecord::Base.schema_migrations_table_name, ignore_tables].flatten.any? do |ignored|
         | 
| 257 | 
            +
                    [ActiveRecord::Base.schema_migrations_table_name, ActiveRecord::Base.internal_metadata_table_name, ignore_tables].flatten.any? do |ignored|
         | 
| 258 258 | 
             
                      ignored === remove_prefix_and_suffix(table_name)
         | 
| 259 259 | 
             
                    end
         | 
| 260 260 | 
             
                  end
         | 
| @@ -9,38 +9,29 @@ module ActiveRecord | |
| 9 9 | 
             
              class SchemaMigration < ActiveRecord::Base # :nodoc:
         | 
| 10 10 | 
             
                class << self
         | 
| 11 11 | 
             
                  def primary_key
         | 
| 12 | 
            -
                     | 
| 12 | 
            +
                    "version"
         | 
| 13 13 | 
             
                  end
         | 
| 14 14 |  | 
| 15 15 | 
             
                  def table_name
         | 
| 16 16 | 
             
                    "#{table_name_prefix}#{ActiveRecord::Base.schema_migrations_table_name}#{table_name_suffix}"
         | 
| 17 17 | 
             
                  end
         | 
| 18 18 |  | 
| 19 | 
            -
                  def index_name
         | 
| 20 | 
            -
                    "#{table_name_prefix}unique_#{ActiveRecord::Base.schema_migrations_table_name}#{table_name_suffix}"
         | 
| 21 | 
            -
                  end
         | 
| 22 | 
            -
             | 
| 23 19 | 
             
                  def table_exists?
         | 
| 24 20 | 
             
                    ActiveSupport::Deprecation.silence { connection.table_exists?(table_name) }
         | 
| 25 21 | 
             
                  end
         | 
| 26 22 |  | 
| 27 | 
            -
                  def create_table | 
| 23 | 
            +
                  def create_table
         | 
| 28 24 | 
             
                    unless table_exists?
         | 
| 29 | 
            -
                      version_options =  | 
| 30 | 
            -
                      version_options[:limit] = limit if limit
         | 
| 25 | 
            +
                      version_options = connection.internal_string_options_for_primary_key
         | 
| 31 26 |  | 
| 32 27 | 
             
                      connection.create_table(table_name, id: false) do |t|
         | 
| 33 | 
            -
                        t. | 
| 28 | 
            +
                        t.string :version, version_options
         | 
| 34 29 | 
             
                      end
         | 
| 35 | 
            -
                      connection.add_index table_name, :version, unique: true, name: index_name
         | 
| 36 30 | 
             
                    end
         | 
| 37 31 | 
             
                  end
         | 
| 38 32 |  | 
| 39 33 | 
             
                  def drop_table
         | 
| 40 | 
            -
                     | 
| 41 | 
            -
                      connection.remove_index table_name, name: index_name
         | 
| 42 | 
            -
                      connection.drop_table(table_name)
         | 
| 43 | 
            -
                    end
         | 
| 34 | 
            +
                    connection.drop_table table_name, if_exists: true
         | 
| 44 35 | 
             
                  end
         | 
| 45 36 |  | 
| 46 37 | 
             
                  def normalize_migration_number(number)
         |