From 45cfe9f8b6a2aca1a7b88118654b7970874a08df Mon Sep 17 00:00:00 2001
From: bannzai <kingkong999yhirose@gmail.com>
Date: Mon, 7 Jan 2019 23:36:31 +0900
Subject: :recycle: Fix mysql type map for enum and set

---
 .../lib/active_record/connection_adapters/abstract_mysql_adapter.rb   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index 10961ed9c8..cccd6e2210 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -579,13 +579,13 @@ module ActiveRecord
           m.alias_type %r(bit)i,           "binary"
 
           m.register_type(%r(enum)i) do |sql_type|
-            limit = sql_type[/^enum\((.+)\)/i, 1]
+            limit = sql_type[/^enum\s*\((.+)\)/i, 1]
               .split(",").map { |enum| enum.strip.length - 2 }.max
             MysqlString.new(limit: limit)
           end
 
           m.register_type(%r(^set)i) do |sql_type|
-            limit = sql_type[/^set\((.+)\)/i, 1]
+            limit = sql_type[/^set\s*\((.+)\)/i, 1]
               .split(",").map { |set| set.strip.length - 1 }.sum - 1
             MysqlString.new(limit: limit)
           end
-- 
cgit v1.2.3


From 7f856c3c8db71e2600d6a84bbc6510eb4ddd0418 Mon Sep 17 00:00:00 2001
From: Ryuta Kamizono <kamipo@gmail.com>
Date: Thu, 3 Jan 2019 09:46:42 +0900
Subject: Consolidate the duplicated code that building range predicate

This slightly change the code in the Arel to allow +/-INFINITY as open
ended since the Active Record expects that behavior. See 5ecbeda.
---
 .../relation/predicate_builder/range_handler.rb    | 23 ++--------------------
 .../lib/active_record/relation/query_attribute.rb  |  6 +++---
 activerecord/lib/arel/nodes/bind_param.rb          |  4 ++++
 activerecord/lib/arel/nodes/casted.rb              |  4 ++++
 activerecord/lib/arel/predications.rb              | 20 ++++++++-----------
 5 files changed, 21 insertions(+), 36 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb
index 44bb2c7ab6..2ea27c8490 100644
--- a/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb
@@ -3,11 +3,7 @@
 module ActiveRecord
   class PredicateBuilder
     class RangeHandler # :nodoc:
-      class RangeWithBinds < Struct.new(:begin, :end)
-        def exclude_end?
-          false
-        end
-      end
+      RangeWithBinds = Struct.new(:begin, :end, :exclude_end?)
 
       def initialize(predicate_builder)
         @predicate_builder = predicate_builder
@@ -16,22 +12,7 @@ module ActiveRecord
       def call(attribute, value)
         begin_bind = predicate_builder.build_bind_attribute(attribute.name, value.begin)
         end_bind = predicate_builder.build_bind_attribute(attribute.name, value.end)
-
-        if begin_bind.value.infinity?
-          if end_bind.value.infinity?
-            attribute.not_in([])
-          elsif value.exclude_end?
-            attribute.lt(end_bind)
-          else
-            attribute.lteq(end_bind)
-          end
-        elsif end_bind.value.infinity?
-          attribute.gteq(begin_bind)
-        elsif value.exclude_end?
-          attribute.gteq(begin_bind).and(attribute.lt(end_bind))
-        else
-          attribute.between(RangeWithBinds.new(begin_bind, end_bind))
-        end
+        attribute.between(RangeWithBinds.new(begin_bind, end_bind, value.exclude_end?))
       end
 
       private
diff --git a/activerecord/lib/active_record/relation/query_attribute.rb b/activerecord/lib/active_record/relation/query_attribute.rb
index f64bd30d38..b45326bdda 100644
--- a/activerecord/lib/active_record/relation/query_attribute.rb
+++ b/activerecord/lib/active_record/relation/query_attribute.rb
@@ -30,12 +30,12 @@ module ActiveRecord
         @_boundable = false
       end
 
-      def infinity?
-        _infinity?(value_before_type_cast) || boundable? && _infinity?(value_for_database)
+      def infinite?
+        infinity?(value_before_type_cast) || boundable? && infinity?(value_for_database)
       end
 
       private
-        def _infinity?(value)
+        def infinity?(value)
           value.respond_to?(:infinite?) && value.infinite?
         end
     end
diff --git a/activerecord/lib/arel/nodes/bind_param.rb b/activerecord/lib/arel/nodes/bind_param.rb
index ba8340558a..f145e44ae3 100644
--- a/activerecord/lib/arel/nodes/bind_param.rb
+++ b/activerecord/lib/arel/nodes/bind_param.rb
@@ -24,6 +24,10 @@ module Arel # :nodoc: all
         value.nil?
       end
 
+      def infinite?
+        value.respond_to?(:infinite?) && value.infinite?
+      end
+
       def boundable?
         !value.respond_to?(:boundable?) || value.boundable?
       end
diff --git a/activerecord/lib/arel/nodes/casted.rb b/activerecord/lib/arel/nodes/casted.rb
index c1e6e97d6d..6e911b717d 100644
--- a/activerecord/lib/arel/nodes/casted.rb
+++ b/activerecord/lib/arel/nodes/casted.rb
@@ -27,6 +27,10 @@ module Arel # :nodoc: all
     class Quoted < Arel::Nodes::Unary # :nodoc:
       alias :val :value
       def nil?; val.nil?; end
+
+      def infinite?
+        value.respond_to?(:infinite?) && value.infinite?
+      end
     end
 
     def self.build_quoted(other, attribute = nil)
diff --git a/activerecord/lib/arel/predications.rb b/activerecord/lib/arel/predications.rb
index 77502dd199..28679ae892 100644
--- a/activerecord/lib/arel/predications.rb
+++ b/activerecord/lib/arel/predications.rb
@@ -35,15 +35,15 @@ module Arel # :nodoc: all
     end
 
     def between(other)
-      if equals_quoted?(other.begin, -Float::INFINITY)
-        if equals_quoted?(other.end, Float::INFINITY)
+      if infinity?(other.begin)
+        if infinity?(other.end)
           not_in([])
         elsif other.exclude_end?
           lt(other.end)
         else
           lteq(other.end)
         end
-      elsif equals_quoted?(other.end, Float::INFINITY)
+      elsif infinity?(other.end)
         gteq(other.begin)
       elsif other.exclude_end?
         gteq(other.begin).and(lt(other.end))
@@ -81,15 +81,15 @@ Passing a range to `#in` is deprecated. Call `#between`, instead.
     end
 
     def not_between(other)
-      if equals_quoted?(other.begin, -Float::INFINITY)
-        if equals_quoted?(other.end, Float::INFINITY)
+      if infinity?(other.begin)
+        if infinity?(other.end)
           self.in([])
         elsif other.exclude_end?
           gteq(other.end)
         else
           gt(other.end)
         end
-      elsif equals_quoted?(other.end, Float::INFINITY)
+      elsif infinity?(other.end)
         lt(other.begin)
       else
         left = lt(other.begin)
@@ -238,12 +238,8 @@ Passing a range to `#not_in` is deprecated. Call `#not_between`, instead.
         others.map { |v| quoted_node(v) }
       end
 
-      def equals_quoted?(maybe_quoted, value)
-        if maybe_quoted.is_a?(Nodes::Quoted)
-          maybe_quoted.val == value
-        else
-          maybe_quoted == value
-        end
+      def infinity?(value)
+        value.respond_to?(:infinite?) && value.infinite?
       end
   end
 end
-- 
cgit v1.2.3


From ea65d92f1924648e72f93bb0e8e5fc62a56d0bac Mon Sep 17 00:00:00 2001
From: Ryuta Kamizono <kamipo@gmail.com>
Date: Wed, 9 Jan 2019 18:09:01 +0900
Subject: Enable `Lint/UselessAssignment` cop to avoid unused variable warnings
 (#34904)

* Enable `Lint/UselessAssignment` cop to avoid unused variable warnings

Since we've addressed the warning "assigned but unused variable"
frequently.

370537de05092aeea552146b42042833212a1acc
3040446cece8e7a6d9e29219e636e13f180a1e03
5ed618e192e9788094bd92c51255dda1c4fd0eae
76ebafe594fc23abc3764acc7a3758ca473799e5

And also, I've found the unused args in c1b14ad which raises no warnings
by the cop, it shows the value of the cop.
---
 .../active_record/connection_adapters/postgresql/schema_statements.rb | 4 ++--
 activerecord/lib/active_record/timestamp.rb                           | 2 +-
 activerecord/lib/arel/visitors/informix.rb                            | 3 ++-
 activerecord/lib/arel/visitors/oracle12.rb                            | 2 +-
 activerecord/lib/arel/visitors/to_sql.rb                              | 4 +---
 5 files changed, 7 insertions(+), 8 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
index 16260fe565..3516bef75a 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
@@ -22,8 +22,8 @@ module ActiveRecord
         def create_database(name, options = {})
           options = { encoding: "utf8" }.merge!(options.symbolize_keys)
 
-          option_string = options.inject("") do |memo, (key, value)|
-            memo += case key
+          option_string = options.each_with_object(+"") do |(key, value), memo|
+            memo << case key
                     when :owner
                       " OWNER = \"#{value}\""
                     when :template
diff --git a/activerecord/lib/active_record/timestamp.rb b/activerecord/lib/active_record/timestamp.rb
index d32f971ad1..e19077eb88 100644
--- a/activerecord/lib/active_record/timestamp.rb
+++ b/activerecord/lib/active_record/timestamp.rb
@@ -56,7 +56,7 @@ module ActiveRecord
       def touch_attributes_with_time(*names, time: nil)
         attribute_names = timestamp_attributes_for_update_in_model
         attribute_names |= names.map(&:to_s)
-        attribute_names.index_with(time ||= current_time_from_proper_timezone)
+        attribute_names.index_with(time || current_time_from_proper_timezone)
       end
 
       private
diff --git a/activerecord/lib/arel/visitors/informix.rb b/activerecord/lib/arel/visitors/informix.rb
index 0a9713794e..208fa15aef 100644
--- a/activerecord/lib/arel/visitors/informix.rb
+++ b/activerecord/lib/arel/visitors/informix.rb
@@ -15,8 +15,9 @@ module Arel # :nodoc: all
             collector << "ORDER BY "
             collector = inject_join o.orders, collector, ", "
           end
-          collector = maybe_visit o.lock, collector
+          maybe_visit o.lock, collector
         end
+
         def visit_Arel_Nodes_SelectCore(o, collector)
           collector = inject_join o.projections, collector, ", "
           if o.source && !o.source.empty?
diff --git a/activerecord/lib/arel/visitors/oracle12.rb b/activerecord/lib/arel/visitors/oracle12.rb
index b092aa95e0..9a7fe4d626 100644
--- a/activerecord/lib/arel/visitors/oracle12.rb
+++ b/activerecord/lib/arel/visitors/oracle12.rb
@@ -20,7 +20,7 @@ module Arel # :nodoc: all
         def visit_Arel_Nodes_SelectOptions(o, collector)
           collector = maybe_visit o.offset, collector
           collector = maybe_visit o.limit, collector
-          collector = maybe_visit o.lock, collector
+          maybe_visit o.lock, collector
         end
 
         def visit_Arel_Nodes_Limit(o, collector)
diff --git a/activerecord/lib/arel/visitors/to_sql.rb b/activerecord/lib/arel/visitors/to_sql.rb
index f9fe4404eb..b5a960ce68 100644
--- a/activerecord/lib/arel/visitors/to_sql.rb
+++ b/activerecord/lib/arel/visitors/to_sql.rb
@@ -208,14 +208,12 @@ module Arel # :nodoc: all
           end
 
           visit_Arel_Nodes_SelectOptions(o, collector)
-
-          collector
         end
 
         def visit_Arel_Nodes_SelectOptions(o, collector)
           collector = maybe_visit o.limit, collector
           collector = maybe_visit o.offset, collector
-          collector = maybe_visit o.lock, collector
+          maybe_visit o.lock, collector
         end
 
         def visit_Arel_Nodes_SelectCore(o, collector)
-- 
cgit v1.2.3


From eb5fef554fde84d36b45191182ed98bd344dc967 Mon Sep 17 00:00:00 2001
From: Ryuta Kamizono <kamipo@gmail.com>
Date: Tue, 18 Sep 2018 07:23:38 +0900
Subject: Refactor `build_relation` in the uniqueness validator to avoid low
 level predicate construction

---
 .../connection_adapters/abstract_adapter.rb        | 17 +++++++----
 .../connection_adapters/abstract_mysql_adapter.rb  |  6 ++--
 .../lib/active_record/validations/uniqueness.rb    | 33 +++++++++-------------
 3 files changed, 29 insertions(+), 27 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index 346d4b067a..0d2d66f919 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -504,15 +504,17 @@ module ActiveRecord
         @connection
       end
 
-      def case_sensitive_comparison(table, attribute, column, value) # :nodoc:
-        table[attribute].eq(value)
+      def case_sensitive_comparison(attribute, value) # :nodoc:
+        attribute.eq(value)
       end
 
-      def case_insensitive_comparison(table, attribute, column, value) # :nodoc:
+      def case_insensitive_comparison(attribute, value) # :nodoc:
+        column = column_for_attribute(attribute)
+
         if can_perform_case_insensitive_comparison_for?(column)
-          table[attribute].lower.eq(table.lower(value))
+          attribute.lower.eq(attribute.relation.lower(value))
         else
-          table[attribute].eq(value)
+          attribute.eq(value)
         end
       end
 
@@ -659,6 +661,11 @@ module ActiveRecord
             raise(ActiveRecordError, "No such column: #{table_name}.#{column_name}")
         end
 
+        def column_for_attribute(attribute)
+          table_name = attribute.relation.name
+          schema_cache.columns_hash(table_name)[attribute.name.to_s]
+        end
+
         def collector
           if prepared_statements
             Arel::Collectors::Composite.new(
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index cccd6e2210..70d281b62b 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -476,9 +476,11 @@ module ActiveRecord
         SQL
       end
 
-      def case_sensitive_comparison(table, attribute, column, value) # :nodoc:
+      def case_sensitive_comparison(attribute, value) # :nodoc:
+        column = column_for_attribute(attribute)
+
         if column.collation && !column.case_sensitive?
-          table[attribute].eq(Arel::Nodes::Bin.new(value))
+          attribute.eq(Arel::Nodes::Bin.new(value))
         else
           super
         end
diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb
index 5a1dbc8e53..19ba2b8cd9 100644
--- a/activerecord/lib/active_record/validations/uniqueness.rb
+++ b/activerecord/lib/active_record/validations/uniqueness.rb
@@ -61,28 +61,21 @@ module ActiveRecord
           value = value.attributes[reflection.klass.primary_key] unless value.nil?
         end
 
-        if value.nil?
-          return klass.unscoped.where!(attribute => value)
-        end
-
-        # the attribute may be an aliased attribute
-        if klass.attribute_alias?(attribute)
-          attribute = klass.attribute_alias(attribute)
+        relation = klass.unscoped
+        comparison = relation.bind_attribute(attribute, value) do |attr, bind|
+          return relation.none! unless bind.boundable?
+
+          if bind.nil?
+            attr.eq(bind)
+          elsif options[:case_sensitive]
+            klass.connection.case_sensitive_comparison(attr, bind)
+          else
+            # will use SQL LOWER function before comparison, unless it detects a case insensitive collation
+            klass.connection.case_insensitive_comparison(attr, bind)
+          end
         end
 
-        attribute_name = attribute.to_s
-        value = klass.predicate_builder.build_bind_attribute(attribute_name, value)
-
-        table = klass.arel_table
-        column = klass.columns_hash[attribute_name]
-
-        comparison = if !options[:case_sensitive]
-          # will use SQL LOWER function before comparison, unless it detects a case insensitive collation
-          klass.connection.case_insensitive_comparison(table, attribute, column, value)
-        else
-          klass.connection.case_sensitive_comparison(table, attribute, column, value)
-        end
-        klass.unscoped.where!(comparison)
+        relation.where!(comparison)
       end
 
       def scope_relation(record, relation)
-- 
cgit v1.2.3


From 6c6c32463e71af4e3395a691052a89c4c1571acd Mon Sep 17 00:00:00 2001
From: Ryuta Kamizono <kamipo@gmail.com>
Date: Fri, 11 Jan 2019 18:01:55 +0900
Subject: Refactor `bind_attribute` to expand an association to actual
 attribute

---
 activerecord/lib/active_record/relation.rb               | 5 +++++
 activerecord/lib/active_record/validations/uniqueness.rb | 5 -----
 2 files changed, 5 insertions(+), 5 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index ba221a333b..a863227276 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -44,6 +44,11 @@ module ActiveRecord
     end
 
     def bind_attribute(name, value) # :nodoc:
+      if reflection = klass._reflect_on_association(name)
+        name = reflection.foreign_key
+        value = value.read_attribute(reflection.klass.primary_key) unless value.nil?
+      end
+
       attr = arel_attribute(name)
       bind = predicate_builder.build_bind_attribute(attr.name, value)
       yield attr, bind
diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb
index 19ba2b8cd9..111b6c9a64 100644
--- a/activerecord/lib/active_record/validations/uniqueness.rb
+++ b/activerecord/lib/active_record/validations/uniqueness.rb
@@ -56,11 +56,6 @@ module ActiveRecord
       end
 
       def build_relation(klass, attribute, value)
-        if reflection = klass._reflect_on_association(attribute)
-          attribute = reflection.foreign_key
-          value = value.attributes[reflection.klass.primary_key] unless value.nil?
-        end
-
         relation = klass.unscoped
         comparison = relation.bind_attribute(attribute, value) do |attr, bind|
           return relation.none! unless bind.boundable?
-- 
cgit v1.2.3


From 5f9e0f848e83688a7f7b5c0b2285144563d84f36 Mon Sep 17 00:00:00 2001
From: Ryuta Kamizono <kamipo@gmail.com>
Date: Fri, 11 Jan 2019 18:34:29 +0900
Subject: Remove `id_value` argument which is no longer passed to
 `sql_for_insert`

Since #26002, `id_value` is no longer passed to `sql_for_insert`.
---
 .../active_record/connection_adapters/abstract/database_statements.rb | 4 ++--
 .../connection_adapters/postgresql/database_statements.rb             | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
index 2299fc0214..79d71bfb5d 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -123,7 +123,7 @@ module ActiveRecord
       # +binds+ as the bind substitutes. +name+ is logged along with
       # the executed +sql+ statement.
       def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil)
-        sql, binds = sql_for_insert(sql, pk, nil, sequence_name, binds)
+        sql, binds = sql_for_insert(sql, pk, sequence_name, binds)
         exec_query(sql, name, binds)
       end
 
@@ -464,7 +464,7 @@ module ActiveRecord
           exec_query(sql, name, binds, prepare: true)
         end
 
-        def sql_for_insert(sql, pk, id_value, sequence_name, binds)
+        def sql_for_insert(sql, pk, sequence_name, binds)
           [sql, binds]
         end
 
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb
index c70a4fa875..41633872e2 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb
@@ -110,7 +110,7 @@ module ActiveRecord
         end
         alias :exec_update :exec_delete
 
-        def sql_for_insert(sql, pk, id_value, sequence_name, binds) # :nodoc:
+        def sql_for_insert(sql, pk, sequence_name, binds) # :nodoc:
           if pk.nil?
             # Extract the table from the insert sql. Yuck.
             table_ref = extract_table_ref_from_insert_sql(sql)
-- 
cgit v1.2.3


From 7110dbea008dd4b80d1764003935a3c97ab10f57 Mon Sep 17 00:00:00 2001
From: Greg Navis <contact@gregnavis.com>
Date: Wed, 9 Jan 2019 18:17:40 +0100
Subject: Support endless ranges in where

This commit adds support for endless ranges, e.g. (1..), that were added
in Ruby 2.6. They're functionally equivalent to explicitly specifying
Float::INFINITY as the end of the range.
---
 activerecord/lib/arel/predications.rb | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/arel/predications.rb b/activerecord/lib/arel/predications.rb
index 28679ae892..0c03e93138 100644
--- a/activerecord/lib/arel/predications.rb
+++ b/activerecord/lib/arel/predications.rb
@@ -36,14 +36,14 @@ module Arel # :nodoc: all
 
     def between(other)
       if infinity?(other.begin)
-        if infinity?(other.end)
+        if other.end.nil? || infinity?(other.end)
           not_in([])
         elsif other.exclude_end?
           lt(other.end)
         else
           lteq(other.end)
         end
-      elsif infinity?(other.end)
+      elsif other.end.nil? || infinity?(other.end)
         gteq(other.begin)
       elsif other.exclude_end?
         gteq(other.begin).and(lt(other.end))
-- 
cgit v1.2.3