Hello community,
here is the log from the commit of package rubygem-activerecord-5.2 for openSUSE:Factory checked in at 2019-04-01 12:36:14
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-activerecord-5.2 (Old)
and /work/SRC/openSUSE:Factory/.rubygem-activerecord-5.2.new.25356 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-activerecord-5.2"
Mon Apr 1 12:36:14 2019 rev:6 rq:689685 version:5.2.3
Changes:
--------
--- /work/SRC/openSUSE:Factory/rubygem-activerecord-5.2/rubygem-activerecord-5.2.changes 2019-03-14 15:03:33.907641714 +0100
+++ /work/SRC/openSUSE:Factory/.rubygem-activerecord-5.2.new.25356/rubygem-activerecord-5.2.changes 2019-04-01 12:36:19.533855187 +0200
@@ -1,0 +2,42 @@
+Fri Mar 29 05:53:31 UTC 2019 - Stephan Kulow
+
+- updated to version 5.2.3
+ see installed CHANGELOG.md
+
+ ## Rails 5.2.3 (March 27, 2019) ##
+
+ * Fix different `count` calculation when using `size` with manual `select` with DISTINCT.
+
+ Fixes #35214.
+
+ *Juani Villarejo*
+
+ * Fix prepared statements caching to be enabled even when query caching is enabled.
+
+ *Ryuta Kamizono*
+
+ * Don't allow `where` with invalid value matches to nil values.
+
+ Fixes #33624.
+
+ *Ryuta Kamizono*
+
+ * Restore an ability that class level `update` without giving ids.
+
+ Fixes #34743.
+
+ *Ryuta Kamizono*
+
+ * Fix join table column quoting with SQLite.
+
+ *Gannon McGibbon*
+
+ * Ensure that `delete_all` on collection proxy returns affected count.
+
+ *Ryuta Kamizono*
+
+ * Reset scope after delete on collection association to clear stale offsets of removed records.
+
+ *Gannon McGibbon*
+
+-------------------------------------------------------------------
Old:
----
activerecord-5.2.2.1.gem
New:
----
activerecord-5.2.3.gem
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ rubygem-activerecord-5.2.spec ++++++
--- /var/tmp/diff_new_pack.25Il9E/_old 2019-04-01 12:36:20.333855578 +0200
+++ /var/tmp/diff_new_pack.25Il9E/_new 2019-04-01 12:36:20.333855578 +0200
@@ -12,7 +12,7 @@
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
@@ -24,7 +24,7 @@
#
Name: rubygem-activerecord-5.2
-Version: 5.2.2.1
+Version: 5.2.3
Release: 0
%define mod_name activerecord
%define mod_full_name %{mod_name}-%{version}
@@ -36,10 +36,10 @@
%endif
# /MANUAL
BuildRoot: %{_tmppath}/%{name}-%{version}-build
-BuildRequires: ruby-macros >= 5
BuildRequires: %{ruby >= 2.2.2}
BuildRequires: %{rubygem gem2rpm}
BuildRequires: %{rubygem rdoc > 3.10}
+BuildRequires: ruby-macros >= 5
Url: http://rubyonrails.org
Source: https://rubygems.org/gems/%{mod_full_name}.gem
Source1: gem2rpm.yml
++++++ activerecord-5.2.2.1.gem -> activerecord-5.2.3.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/CHANGELOG.md new/CHANGELOG.md
--- old/CHANGELOG.md 2019-03-13 17:47:01.000000000 +0100
+++ new/CHANGELOG.md 2019-03-28 03:59:25.000000000 +0100
@@ -1,3 +1,40 @@
+## Rails 5.2.3 (March 27, 2019) ##
+
+* Fix different `count` calculation when using `size` with manual `select` with DISTINCT.
+
+ Fixes #35214.
+
+ *Juani Villarejo*
+
+* Fix prepared statements caching to be enabled even when query caching is enabled.
+
+ *Ryuta Kamizono*
+
+* Don't allow `where` with invalid value matches to nil values.
+
+ Fixes #33624.
+
+ *Ryuta Kamizono*
+
+* Restore an ability that class level `update` without giving ids.
+
+ Fixes #34743.
+
+ *Ryuta Kamizono*
+
+* Fix join table column quoting with SQLite.
+
+ *Gannon McGibbon*
+
+* Ensure that `delete_all` on collection proxy returns affected count.
+
+ *Ryuta Kamizono*
+
+* Reset scope after delete on collection association to clear stale offsets of removed records.
+
+ *Gannon McGibbon*
+
+
## Rails 5.2.2.1 (March 11, 2019) ##
* No changes.
Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/associations/collection_association.rb new/lib/active_record/associations/collection_association.rb
--- old/lib/active_record/associations/collection_association.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/associations/collection_association.rb 2019-03-28 03:59:25.000000000 +0100
@@ -109,9 +109,8 @@
end
end
- # Add +records+ to this association. Returns +self+ so method calls may
- # be chained. Since << flattens its argument list and inserts each record,
- # +push+ and +concat+ behave identically.
+ # Add +records+ to this association. Since +<<+ flattens its argument list
+ # and inserts each record, +push+ and +concat+ behave identically.
def concat(*records)
records = records.flatten
if owner.new_record?
@@ -362,7 +361,6 @@
add_to_target(record) do
result = insert_record(record, true, raise) {
@_was_loaded = loaded?
- @association_ids = nil
}
end
raise ActiveRecord::Rollback unless result
@@ -399,6 +397,7 @@
delete_records(existing_records, method) if existing_records.any?
records.each { |record| target.delete(record) }
+ @association_ids = nil
records.each { |record| callback(:after_remove, record) }
end
@@ -439,7 +438,6 @@
unless owner.new_record?
result &&= insert_record(record, true, raise) {
@_was_loaded = loaded?
- @association_ids = nil
}
end
end
@@ -462,6 +460,7 @@
if index
target[index] = record
elsif @_was_loaded || !loaded?
+ @association_ids = nil
target << record
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/associations/collection_proxy.rb new/lib/active_record/associations/collection_proxy.rb
--- old/lib/active_record/associations/collection_proxy.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/associations/collection_proxy.rb 2019-03-28 03:59:25.000000000 +0100
@@ -366,34 +366,6 @@
@association.create!(attributes, &block)
end
- # Add one or more records to the collection by setting their foreign keys
- # to the association's primary key. Since #<< flattens its argument list and
- # inserts each record, +push+ and #concat behave identically. Returns +self+
- # so method calls may be chained.
- #
- # class Person < ActiveRecord::Base
- # has_many :pets
- # end
- #
- # person.pets.size # => 0
- # person.pets.concat(Pet.new(name: 'Fancy-Fancy'))
- # person.pets.concat(Pet.new(name: 'Spook'), Pet.new(name: 'Choo-Choo'))
- # person.pets.size # => 3
- #
- # person.id # => 1
- # person.pets
- # # => [
- # # #,
- # # #,
- # # #
- # # ]
- #
- # person.pets.concat([Pet.new(name: 'Brain'), Pet.new(name: 'Benny')])
- # person.pets.size # => 5
- def concat(*records)
- @association.concat(*records)
- end
-
# Replaces this collection with +other_array+. This will perform a diff
# and delete/add only records that have changed.
#
@@ -500,7 +472,7 @@
# Pet.find(1, 2, 3)
# # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
def delete_all(dependent = nil)
- @association.delete_all(dependent)
+ @association.delete_all(dependent).tap { reset_scope }
end
# Deletes the records of the collection directly from the database
@@ -527,7 +499,7 @@
#
# Pet.find(1) # => Couldn't find Pet with id=1
def destroy_all
- @association.destroy_all
+ @association.destroy_all.tap { reset_scope }
end
# Deletes the +records+ supplied from the collection according to the strategy
@@ -646,7 +618,7 @@
# # #
# # ]
def delete(*records)
- @association.delete(*records)
+ @association.delete(*records).tap { reset_scope }
end
# Destroys the +records+ supplied and removes them from the collection.
@@ -718,7 +690,7 @@
#
# Pet.find(4, 5, 6) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (4, 5, 6)
def destroy(*records)
- @association.destroy(*records)
+ @association.destroy(*records).tap { reset_scope }
end
##
@@ -1033,8 +1005,9 @@
end
# Adds one or more +records+ to the collection by setting their foreign keys
- # to the association's primary key. Returns +self+, so several appends may be
- # chained together.
+ # to the association's primary key. Since +<<+ flattens its argument list and
+ # inserts each record, +push+ and +concat+ behave identically. Returns +self+
+ # so several appends may be chained together.
#
# class Person < ActiveRecord::Base
# has_many :pets
@@ -1057,6 +1030,7 @@
end
alias_method :push, :<<
alias_method :append, :<<
+ alias_method :concat, :<<
def prepend(*args)
raise NoMethodError, "prepend on association is not defined. Please use <<, push or append"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/associations/has_many_association.rb new/lib/active_record/associations/has_many_association.rb
--- old/lib/active_record/associations/has_many_association.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/associations/has_many_association.rb 2019-03-28 03:59:25.000000000 +0100
@@ -99,6 +99,7 @@
def delete_or_nullify_all_records(method)
count = delete_count(method, scope)
update_counter(-count)
+ count
end
# Deletes the records according to the <tt>:dependent</tt> option.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/associations/has_many_through_association.rb new/lib/active_record/associations/has_many_through_association.rb
--- old/lib/active_record/associations/has_many_through_association.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/associations/has_many_through_association.rb 2019-03-28 03:59:25.000000000 +0100
@@ -161,6 +161,8 @@
else
update_counter(-count)
end
+
+ count
end
def difference(a, b)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/abstract/connection_pool.rb new/lib/active_record/connection_adapters/abstract/connection_pool.rb
--- old/lib/active_record/connection_adapters/abstract/connection_pool.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/connection_adapters/abstract/connection_pool.rb 2019-03-28 03:59:25.000000000 +0100
@@ -915,6 +915,16 @@
# about the model. The model needs to pass a specification name to the handler,
# in order to look up the correct connection pool.
class ConnectionHandler
+ def self.create_owner_to_pool # :nodoc:
+ Concurrent::Map.new(initial_capacity: 2) do |h, k|
+ # Discard the parent's connection pools immediately; we have no need
+ # of them
+ discard_unowned_pools(h)
+
+ h[k] = Concurrent::Map.new(initial_capacity: 2)
+ end
+ end
+
def self.unowned_pool_finalizer(pid_map) # :nodoc:
lambda do |_|
discard_unowned_pools(pid_map)
@@ -929,13 +939,7 @@
def initialize
# These caches are keyed by spec.name (ConnectionSpecification#name).
- @owner_to_pool = Concurrent::Map.new(initial_capacity: 2) do |h, k|
- # Discard the parent's connection pools immediately; we have no need
- # of them
- ConnectionHandler.discard_unowned_pools(h)
-
- h[k] = Concurrent::Map.new(initial_capacity: 2)
- end
+ @owner_to_pool = ConnectionHandler.create_owner_to_pool
# Backup finalizer: if the forked child never needed a pool, the above
# early discard has not occurred
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/abstract/database_statements.rb new/lib/active_record/connection_adapters/abstract/database_statements.rb
--- old/lib/active_record/connection_adapters/abstract/database_statements.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/connection_adapters/abstract/database_statements.rb 2019-03-28 03:59:25.000000000 +0100
@@ -20,9 +20,22 @@
raise "Passing bind parameters with an arel AST is forbidden. " \
"The values must be stored on the AST directly"
end
- sql, binds = visitor.accept(arel_or_sql_string.ast, collector).value
- [sql.freeze, binds || []]
+
+ if prepared_statements
+ sql, binds = visitor.accept(arel_or_sql_string.ast, collector).value
+
+ if binds.length > bind_params_length
+ unprepared_statement do
+ sql, binds = to_sql_and_binds(arel_or_sql_string)
+ visitor.preparable = false
+ end
+ end
+ else
+ sql = visitor.accept(arel_or_sql_string.ast, collector).value
+ end
+ [sql.freeze, binds]
else
+ visitor.preparable = false if prepared_statements
[arel_or_sql_string.dup.freeze, binds]
end
end
@@ -47,13 +60,8 @@
arel = arel_from_relation(arel)
sql, binds = to_sql_and_binds(arel, binds)
- if !prepared_statements || (arel.is_a?(String) && preparable.nil?)
- preparable = false
- elsif binds.length > bind_params_length
- sql, binds = unprepared_statement { to_sql_and_binds(arel) }
- preparable = false
- else
- preparable = visitor.preparable
+ if preparable.nil?
+ preparable = prepared_statements ? visitor.preparable : false
end
if prepared_statements && preparable
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/abstract/query_cache.rb new/lib/active_record/connection_adapters/abstract/query_cache.rb
--- old/lib/active_record/connection_adapters/abstract/query_cache.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/connection_adapters/abstract/query_cache.rb 2019-03-28 03:59:25.000000000 +0100
@@ -96,6 +96,11 @@
if @query_cache_enabled && !locked?(arel)
arel = arel_from_relation(arel)
sql, binds = to_sql_and_binds(arel, binds)
+
+ if preparable.nil?
+ preparable = prepared_statements ? visitor.preparable : false
+ end
+
cache_sql(sql, name, binds) { super(sql, name, binds, preparable: preparable) }
else
super
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/abstract/schema_statements.rb new/lib/active_record/connection_adapters/abstract/schema_statements.rb
--- old/lib/active_record/connection_adapters/abstract/schema_statements.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/connection_adapters/abstract/schema_statements.rb 2019-03-28 03:59:25.000000000 +0100
@@ -305,7 +305,7 @@
yield td if block_given?
if options[:force]
- drop_table(table_name, **options, if_exists: true)
+ drop_table(table_name, options.merge(if_exists: true))
end
result = execute schema_creation.accept td
@@ -899,7 +899,7 @@
foreign_key_options = { to_table: reference_name }
end
foreign_key_options[:column] ||= "#{ref_name}_id"
- remove_foreign_key(table_name, **foreign_key_options)
+ remove_foreign_key(table_name, foreign_key_options)
end
remove_column(table_name, "#{ref_name}_id")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/abstract_adapter.rb new/lib/active_record/connection_adapters/abstract_adapter.rb
--- old/lib/active_record/connection_adapters/abstract_adapter.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/connection_adapters/abstract_adapter.rb 2019-03-28 03:59:25.000000000 +0100
@@ -81,7 +81,9 @@
alias :in_use? :owner
def self.type_cast_config_to_integer(config)
- if config =~ SIMPLE_INT
+ if config.is_a?(Integer)
+ config
+ elsif config =~ SIMPLE_INT
config.to_i
else
config
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/abstract_mysql_adapter.rb new/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
--- old/lib/active_record/connection_adapters/abstract_mysql_adapter.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/connection_adapters/abstract_mysql_adapter.rb 2019-03-28 03:59:25.000000000 +0100
@@ -804,15 +804,25 @@
end
def mismatched_foreign_key(message)
- parts = message.scan(/`(\w+)`[ $)]/).flatten
- MismatchedForeignKey.new(
- self,
+ match = %r/
+ (?:CREATE|ALTER)\s+TABLE\s*(?:`?\w+`?\.)?`?(?<table>\w+)`?.+?
+ FOREIGN\s+KEY\s*\(`?(?\w+)`?\)\s*
+ REFERENCES\s*(`?(?\w+)`?)\s*\(`?(?\w+)`?\)
+ /xmi.match(message)
+
+ options = {
message: message,
- table: parts[0],
- foreign_key: parts[1],
- target_table: parts[2],
- primary_key: parts[3],
- )
+ }
+
+ if match
+ options[:table] = match[:table]
+ options[:foreign_key] = match[:foreign_key]
+ options[:target_table] = match[:target_table]
+ options[:primary_key] = match[:primary_key]
+ options[:primary_key_column] = column_for(match[:target_table], match[:primary_key])
+ end
+
+ MismatchedForeignKey.new(options)
end
def integer_to_sql(limit) # :nodoc:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb new/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb
--- old/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb 2019-03-28 03:59:25.000000000 +0100
@@ -3,7 +3,7 @@
module ActiveRecord
module ConnectionAdapters
module DetermineIfPreparableVisitor
- attr_reader :preparable
+ attr_accessor :preparable
def accept(*)
@preparable = true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/postgresql/schema_creation.rb new/lib/active_record/connection_adapters/postgresql/schema_creation.rb
--- old/lib/active_record/connection_adapters/postgresql/schema_creation.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/connection_adapters/postgresql/schema_creation.rb 2019-03-28 03:59:25.000000000 +0100
@@ -17,6 +17,42 @@
"VALIDATE CONSTRAINT #{quote_column_name(name)}"
end
+ def visit_ChangeColumnDefinition(o)
+ column = o.column
+ column.sql_type = type_to_sql(column.type, column.options)
+ quoted_column_name = quote_column_name(o.name)
+
+ change_column_sql = "ALTER COLUMN #{quoted_column_name} TYPE #{column.sql_type}".dup
+
+ options = column_options(column)
+
+ if options[:collation]
+ change_column_sql << " COLLATE \"#{options[:collation]}\""
+ end
+
+ if options[:using]
+ change_column_sql << " USING #{options[:using]}"
+ elsif options[:cast_as]
+ cast_as_type = type_to_sql(options[:cast_as], options)
+ change_column_sql << " USING CAST(#{quoted_column_name} AS #{cast_as_type})"
+ end
+
+ if options.key?(:default)
+ if options[:default].nil?
+ change_column_sql << ", ALTER COLUMN #{quoted_column_name} DROP DEFAULT"
+ else
+ quoted_default = quote_default_expression(options[:default], column)
+ change_column_sql << ", ALTER COLUMN #{quoted_column_name} SET DEFAULT #{quoted_default}"
+ end
+ end
+
+ if options.key?(:null)
+ change_column_sql << ", ALTER COLUMN #{quoted_column_name} #{options[:null] ? 'DROP' : 'SET'} NOT NULL"
+ end
+
+ change_column_sql
+ end
+
def add_column_options!(sql, options)
if options[:collation]
sql << " COLLATE \"#{options[:collation]}\""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/postgresql/schema_statements.rb new/lib/active_record/connection_adapters/postgresql/schema_statements.rb
--- old/lib/active_record/connection_adapters/postgresql/schema_statements.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/connection_adapters/postgresql/schema_statements.rb 2019-03-28 03:59:25.000000000 +0100
@@ -683,38 +683,20 @@
end
end
- def change_column_sql(table_name, column_name, type, options = {})
- quoted_column_name = quote_column_name(column_name)
- sql_type = type_to_sql(type, options)
- sql = "ALTER COLUMN #{quoted_column_name} TYPE #{sql_type}".dup
- if options[:collation]
- sql << " COLLATE \"#{options[:collation]}\""
- end
- if options[:using]
- sql << " USING #{options[:using]}"
- elsif options[:cast_as]
- cast_as_type = type_to_sql(options[:cast_as], options)
- sql << " USING CAST(#{quoted_column_name} AS #{cast_as_type})"
- end
-
- sql
- end
-
def add_column_for_alter(table_name, column_name, type, options = {})
return super unless options.key?(:comment)
[super, Proc.new { change_column_comment(table_name, column_name, options[:comment]) }]
end
def change_column_for_alter(table_name, column_name, type, options = {})
- sqls = [change_column_sql(table_name, column_name, type, options)]
- sqls << change_column_default_for_alter(table_name, column_name, options[:default]) if options.key?(:default)
- sqls << change_column_null_for_alter(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
+ td = create_table_definition(table_name)
+ cd = td.new_column_definition(column_name, type, options)
+ sqls = [schema_creation.accept(ChangeColumnDefinition.new(cd, column_name))]
sqls << Proc.new { change_column_comment(table_name, column_name, options[:comment]) } if options.key?(:comment)
sqls
end
- # Changes the default value of a table column.
- def change_column_default_for_alter(table_name, column_name, default_or_changes) # :nodoc:
+ def change_column_default_for_alter(table_name, column_name, default_or_changes)
column = column_for(table_name, column_name)
return unless column
@@ -729,8 +711,8 @@
end
end
- def change_column_null_for_alter(table_name, column_name, null, default = nil) #:nodoc:
- "ALTER #{quote_column_name(column_name)} #{null ? 'DROP' : 'SET'} NOT NULL"
+ def change_column_null_for_alter(table_name, column_name, null, default = nil)
+ "ALTER COLUMN #{quote_column_name(column_name)} #{null ? 'DROP' : 'SET'} NOT NULL"
end
def add_timestamps_for_alter(table_name, options = {})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/sqlite3/quoting.rb new/lib/active_record/connection_adapters/sqlite3/quoting.rb
--- old/lib/active_record/connection_adapters/sqlite3/quoting.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/connection_adapters/sqlite3/quoting.rb 2019-03-28 03:59:25.000000000 +0100
@@ -12,6 +12,10 @@
quote_column_name(attr)
end
+ def quote_table_name(name)
+ @quoted_table_names[name] ||= super.gsub(".", "\".\"").freeze
+ end
+
def quote_column_name(name)
@quoted_column_names[name] ||= %Q("#{super.gsub('"', '""')}").freeze
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/connection_adapters/sqlite3_adapter.rb new/lib/active_record/connection_adapters/sqlite3_adapter.rb
--- old/lib/active_record/connection_adapters/sqlite3_adapter.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/connection_adapters/sqlite3_adapter.rb 2019-03-28 03:59:25.000000000 +0100
@@ -9,7 +9,7 @@
require "active_record/connection_adapters/sqlite3/schema_dumper"
require "active_record/connection_adapters/sqlite3/schema_statements"
-gem "sqlite3", "~> 1.3.6"
+gem "sqlite3", "~> 1.3", ">= 1.3.6"
require "sqlite3"
module ActiveRecord
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/core.rb new/lib/active_record/core.rb
--- old/lib/active_record/core.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/core.rb 2019-03-28 03:59:25.000000000 +0100
@@ -184,7 +184,8 @@
end
def find_by(*args) # :nodoc:
- return super if scope_attributes? || reflect_on_all_aggregations.any?
+ return super if scope_attributes? || reflect_on_all_aggregations.any? ||
+ columns_hash.key?(inheritance_column) && base_class != self
hash = args.first
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/errors.rb new/lib/active_record/errors.rb
--- old/lib/active_record/errors.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/errors.rb 2019-03-28 03:59:25.000000000 +0100
@@ -117,16 +117,27 @@
# Raised when a foreign key constraint cannot be added because the column type does not match the referenced column type.
class MismatchedForeignKey < StatementInvalid
- def initialize(adapter = nil, message: nil, table: nil, foreign_key: nil, target_table: nil, primary_key: nil)
- @adapter = adapter
+ def initialize(
+ adapter = nil,
+ message: nil,
+ sql: nil,
+ binds: nil,
+ table: nil,
+ foreign_key: nil,
+ target_table: nil,
+ primary_key: nil,
+ primary_key_column: nil
+ )
if table
- msg = <<-EOM.strip_heredoc
- Column `#{foreign_key}` on table `#{table}` has a type of `#{column_type(table, foreign_key)}`.
- This does not match column `#{primary_key}` on `#{target_table}`, which has type `#{column_type(target_table, primary_key)}`.
- To resolve this issue, change the type of the `#{foreign_key}` column on `#{table}` to be :integer. (For example `t.integer #{foreign_key}`).
+ type = primary_key_column.bigint? ? :bigint : primary_key_column.type
+ msg = <<-EOM.squish
+ Column `#{foreign_key}` on table `#{table}` does not match column `#{primary_key}` on `#{target_table}`,
+ which has type `#{primary_key_column.sql_type}`.
+ To resolve this issue, change the type of the `#{foreign_key}` column on `#{table}` to be :#{type}.
+ (For example `t.#{type} :#{foreign_key}`).
EOM
else
- msg = <<-EOM.strip_heredoc
+ msg = <<-EOM.squish
There is a mismatch between the foreign key and primary key column types.
Verify that the foreign key column type and the primary key of the associated table match types.
EOM
@@ -136,11 +147,6 @@
end
super(msg)
end
-
- private
- def column_type(table, column)
- @adapter.columns(table).detect { |c| c.name == column }.sql_type
- end
end
# Raised when a record cannot be inserted or updated because it would violate a not null constraint.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/gem_version.rb new/lib/active_record/gem_version.rb
--- old/lib/active_record/gem_version.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/gem_version.rb 2019-03-28 03:59:25.000000000 +0100
@@ -9,8 +9,8 @@
module VERSION
MAJOR = 5
MINOR = 2
- TINY = 2
- PRE = "1"
+ TINY = 3
+ PRE = nil
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/migration/compatibility.rb new/lib/active_record/migration/compatibility.rb
--- old/lib/active_record/migration/compatibility.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/migration/compatibility.rb 2019-03-28 03:59:25.000000000 +0100
@@ -17,20 +17,18 @@
class V5_1 < V5_2
def change_column(table_name, column_name, type, options = {})
- if adapter_name == "PostgreSQL"
- clear_cache!
- sql = connection.send(:change_column_sql, table_name, column_name, type, options)
- execute "ALTER TABLE #{quote_table_name(table_name)} #{sql}"
- change_column_default(table_name, column_name, options[:default]) if options.key?(:default)
- change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
- change_column_comment(table_name, column_name, options[:comment]) if options.key?(:comment)
+ if connection.adapter_name == "PostgreSQL"
+ super(table_name, column_name, type, options.except(:default, :null, :comment))
+ connection.change_column_default(table_name, column_name, options[:default]) if options.key?(:default)
+ connection.change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
+ connection.change_column_comment(table_name, column_name, options[:comment]) if options.key?(:comment)
else
super
end
end
def create_table(table_name, options = {})
- if adapter_name == "Mysql2"
+ if connection.adapter_name == "Mysql2"
super(table_name, options: "ENGINE=InnoDB", **options)
else
super
@@ -52,13 +50,13 @@
end
def create_table(table_name, options = {})
- if adapter_name == "PostgreSQL"
+ if connection.adapter_name == "PostgreSQL"
if options[:id] == :uuid && !options.key?(:default)
options[:default] = "uuid_generate_v4()"
end
end
- unless adapter_name == "Mysql2" && options[:id] == :bigint
+ unless connection.adapter_name == "Mysql2" && options[:id] == :bigint
if [:integer, :bigint].include?(options[:id]) && !options.key?(:default)
options[:default] = nil
end
@@ -175,7 +173,7 @@
if options[:name].present?
options[:name].to_s
else
- index_name(table_name, column: column_names)
+ connection.index_name(table_name, column: column_names)
end
super
end
@@ -195,15 +193,17 @@
end
def index_name_for_remove(table_name, options = {})
- index_name = index_name(table_name, options)
+ index_name = connection.index_name(table_name, options)
- unless index_name_exists?(table_name, index_name)
+ unless connection.index_name_exists?(table_name, index_name)
if options.is_a?(Hash) && options.has_key?(:name)
options_without_column = options.dup
options_without_column.delete :column
- index_name_without_column = index_name(table_name, options_without_column)
+ index_name_without_column = connection.index_name(table_name, options_without_column)
- return index_name_without_column if index_name_exists?(table_name, index_name_without_column)
+ if connection.index_name_exists?(table_name, index_name_without_column)
+ return index_name_without_column
+ end
end
raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' does not exist"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/persistence.rb new/lib/active_record/persistence.rb
--- old/lib/active_record/persistence.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/persistence.rb 2019-03-28 03:59:25.000000000 +0100
@@ -97,11 +97,13 @@
# When running callbacks is not needed for each record update,
# it is preferred to use {update_all}[rdoc-ref:Relation#update_all]
# for updating all records in a single query.
- def update(id, attributes)
+ def update(id = :all, attributes)
if id.is_a?(Array)
id.map { |one_id| find(one_id) }.each_with_index { |object, idx|
object.update(attributes[idx])
}
+ elsif id == :all
+ all.each { |record| record.update(attributes) }
else
if ActiveRecord::Base === id
raise ArgumentError,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/querying.rb new/lib/active_record/querying.rb
--- old/lib/active_record/querying.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/querying.rb 2019-03-28 03:59:25.000000000 +0100
@@ -40,8 +40,7 @@
def find_by_sql(sql, binds = [], preparable: nil, &block)
result_set = connection.select_all(sanitize_sql(sql), "#{name} Load", binds, preparable: preparable)
column_types = result_set.column_types.dup
- cached_columns_hash = connection.schema_cache.columns_hash(table_name)
- cached_columns_hash.each_key { |k| column_types.delete k }
+ attribute_types.each_key { |k| column_types.delete k }
message_bus = ActiveSupport::Notifications.instrumenter
payload = {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/relation/calculations.rb new/lib/active_record/relation/calculations.rb
--- old/lib/active_record/relation/calculations.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/relation/calculations.rb 2019-03-28 03:59:25.000000000 +0100
@@ -190,11 +190,9 @@
relation = apply_join_dependency
relation.pluck(*column_names)
else
- enforce_raw_sql_whitelist(column_names)
+ klass.enforce_raw_sql_whitelist(column_names)
relation = spawn
- relation.select_values = column_names.map { |cn|
- @klass.has_attribute?(cn) || @klass.attribute_alias?(cn) ? arel_attribute(cn) : cn
- }
+ relation.select_values = column_names
result = skip_query_cache_if_necessary { klass.connection.select_all(relation.arel, nil) }
result.cast_values(klass.attribute_types)
end
@@ -209,7 +207,6 @@
end
private
-
def has_include?(column_name)
eager_loading? || (includes_values.present? && column_name && column_name != :all)
end
@@ -224,10 +221,12 @@
if operation == "count"
column_name ||= select_for_count
if column_name == :all
- if distinct && (group_values.any? || select_values.empty? && order_values.empty?)
+ if !distinct
+ distinct = distinct_select?(select_for_count) if group_values.empty?
+ elsif group_values.any? || select_values.empty? && order_values.empty?
column_name = primary_key
end
- elsif column_name =~ /\s*DISTINCT[\s(]+/i
+ elsif distinct_select?(column_name)
distinct = nil
end
end
@@ -239,6 +238,10 @@
end
end
+ def distinct_select?(column_name)
+ column_name.is_a?(::String) && /\bDISTINCT[\s(]/i.match?(column_name)
+ end
+
def aggregate_column(column_name)
return column_name if Arel::Expressions === column_name
@@ -383,7 +386,7 @@
case operation
when "count" then value.to_i
when "sum" then type.deserialize(value || 0)
- when "average" then value.respond_to?(:to_d) ? value.to_d : value
+ when "average" then value && value.respond_to?(:to_d) ? value.to_d : value
else type.deserialize(value)
end
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/relation/finder_methods.rb new/lib/active_record/relation/finder_methods.rb
--- old/lib/active_record/relation/finder_methods.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/relation/finder_methods.rb 2019-03-28 03:59:25.000000000 +0100
@@ -319,7 +319,7 @@
relation = construct_relation_for_exists(conditions)
- skip_query_cache_if_necessary { connection.select_value(relation.arel, "#{name} Exists") } ? true : false
+ skip_query_cache_if_necessary { connection.select_one(relation.arel, "#{name} Exists") } ? true : false
rescue ::RangeError
false
end
@@ -359,7 +359,11 @@
end
def construct_relation_for_exists(conditions)
- relation = except(:select, :distinct, :order)._select!(ONE_AS_ONE).limit!(1)
+ if distinct_value && offset_value
+ relation = limit(1)
+ else
+ relation = except(:select, :distinct, :order)._select!(ONE_AS_ONE).limit!(1)
+ end
case conditions
when Array, Hash
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/relation/merger.rb new/lib/active_record/relation/merger.rb
--- old/lib/active_record/relation/merger.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/relation/merger.rb 2019-03-28 03:59:25.000000000 +0100
@@ -175,9 +175,7 @@
end
def merge_clauses
- if relation.from_clause.empty? && !other.from_clause.empty?
- relation.from_clause = other.from_clause
- end
+ relation.from_clause = other.from_clause if replace_from_clause?
where_clause = relation.where_clause.merge(other.where_clause)
relation.where_clause = where_clause unless where_clause.empty?
@@ -185,6 +183,11 @@
having_clause = relation.having_clause.merge(other.having_clause)
relation.having_clause = having_clause unless having_clause.empty?
end
+
+ def replace_from_clause?
+ relation.from_clause.empty? && !other.from_clause.empty? &&
+ relation.klass.base_class == other.klass.base_class
+ end
end
end
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/relation/predicate_builder.rb new/lib/active_record/relation/predicate_builder.rb
--- old/lib/active_record/relation/predicate_builder.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/relation/predicate_builder.rb 2019-03-28 03:59:25.000000000 +0100
@@ -93,16 +93,21 @@
queries.reduce(&:or)
elsif table.aggregated_with?(key)
mapping = table.reflect_on_aggregation(key).mapping
- queries = Array.wrap(value).map do |object|
- mapping.map do |field_attr, aggregate_attr|
- if mapping.size == 1 && !object.respond_to?(aggregate_attr)
- build(table.arel_attribute(field_attr), object)
- else
- build(table.arel_attribute(field_attr), object.send(aggregate_attr))
- end
- end.reduce(&:and)
+ values = value.nil? ? [nil] : Array.wrap(value)
+ if mapping.length == 1 || values.empty?
+ column_name, aggr_attr = mapping.first
+ values = values.map do |object|
+ object.respond_to?(aggr_attr) ? object.public_send(aggr_attr) : object
+ end
+ build(table.arel_attribute(column_name), values)
+ else
+ queries = values.map do |object|
+ mapping.map do |field_attr, aggregate_attr|
+ build(table.arel_attribute(field_attr), object.try!(aggregate_attr))
+ end.reduce(&:and)
+ end
+ queries.reduce(&:or)
end
- queries.reduce(&:or)
else
build(table.arel_attribute(key), value)
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/relation/query_attribute.rb new/lib/active_record/relation/query_attribute.rb
--- old/lib/active_record/relation/query_attribute.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/relation/query_attribute.rb 2019-03-28 03:59:25.000000000 +0100
@@ -18,13 +18,15 @@
end
def nil?
- !value_before_type_cast.is_a?(StatementCache::Substitute) &&
- (value_before_type_cast.nil? || value_for_database.nil?)
+ unless value_before_type_cast.is_a?(StatementCache::Substitute)
+ value_before_type_cast.nil? ||
+ type.respond_to?(:subtype, true) && value_for_database.nil?
+ end
end
def boundable?
return @_boundable if defined?(@_boundable)
- nil?
+ value_for_database unless value_before_type_cast.is_a?(StatementCache::Substitute)
@_boundable = true
rescue ::RangeError
@_boundable = false
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_record/relation/query_methods.rb new/lib/active_record/relation/query_methods.rb
--- old/lib/active_record/relation/query_methods.rb 2019-03-13 17:47:01.000000000 +0100
+++ new/lib/active_record/relation/query_methods.rb 2019-03-28 03:59:25.000000000 +0100
@@ -1051,11 +1051,13 @@
def arel_columns(columns)
columns.flat_map do |field|
- if (Symbol === field || String === field) && (klass.has_attribute?(field) || klass.attribute_alias?(field)) && !from_clause.value
- arel_attribute(field)
- elsif Symbol === field
- connection.quote_table_name(field.to_s)
- elsif Proc === field
+ case field
+ when Symbol
+ field = field.to_s
+ arel_column(field) { connection.quote_table_name(field) }
+ when String
+ arel_column(field) { field }
+ when Proc
field.call
else
field
@@ -1063,6 +1065,21 @@
end
end
+ def arel_column(field)
+ field = klass.attribute_alias(field) if klass.attribute_alias?(field)
+ from = from_clause.name || from_clause.value
+
+ if klass.columns_hash.key?(field) && (!from || table_name_matches?(from))
+ arel_attribute(field)
+ else
+ yield
+ end
+ end
+
+ def table_name_matches?(from)
+ /(?:\A|(?https://github.com/rails/rails/tree/v5.2.2.1/activerecord
- changelog_uri: https://github.com/rails/rails/blob/v5.2.2.1/activerecord/CHANGELOG.md
+ source_code_uri: https://github.com/rails/rails/tree/v5.2.3/activerecord
+ changelog_uri: https://github.com/rails/rails/blob/v5.2.3/activerecord/CHANGELOG.md
post_install_message:
rdoc_options:
- "--main"