activerecord 5.2.4.3 → 6.0.0
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 +614 -588
 - data/MIT-LICENSE +3 -1
 - data/README.rdoc +4 -2
 - data/examples/performance.rb +1 -1
 - data/lib/active_record.rb +9 -2
 - data/lib/active_record/aggregations.rb +4 -2
 - data/lib/active_record/associations.rb +19 -14
 - data/lib/active_record/associations/association.rb +52 -19
 - data/lib/active_record/associations/association_scope.rb +4 -6
 - data/lib/active_record/associations/belongs_to_association.rb +36 -42
 - data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
 - data/lib/active_record/associations/builder/association.rb +14 -18
 - data/lib/active_record/associations/builder/belongs_to.rb +19 -52
 - data/lib/active_record/associations/builder/collection_association.rb +3 -13
 - data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -38
 - data/lib/active_record/associations/builder/has_many.rb +2 -0
 - data/lib/active_record/associations/builder/has_one.rb +35 -1
 - data/lib/active_record/associations/builder/singular_association.rb +2 -0
 - data/lib/active_record/associations/collection_association.rb +6 -21
 - data/lib/active_record/associations/collection_proxy.rb +12 -15
 - data/lib/active_record/associations/foreign_association.rb +7 -0
 - data/lib/active_record/associations/has_many_association.rb +2 -10
 - data/lib/active_record/associations/has_many_through_association.rb +14 -14
 - data/lib/active_record/associations/has_one_association.rb +28 -30
 - data/lib/active_record/associations/has_one_through_association.rb +5 -5
 - data/lib/active_record/associations/join_dependency.rb +24 -28
 - data/lib/active_record/associations/join_dependency/join_association.rb +9 -10
 - data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
 - data/lib/active_record/associations/preloader.rb +40 -32
 - data/lib/active_record/associations/preloader/association.rb +38 -36
 - data/lib/active_record/associations/preloader/through_association.rb +48 -39
 - data/lib/active_record/associations/singular_association.rb +2 -16
 - data/lib/active_record/attribute_assignment.rb +7 -10
 - data/lib/active_record/attribute_methods.rb +28 -100
 - data/lib/active_record/attribute_methods/before_type_cast.rb +4 -1
 - data/lib/active_record/attribute_methods/dirty.rb +111 -40
 - data/lib/active_record/attribute_methods/primary_key.rb +15 -22
 - data/lib/active_record/attribute_methods/query.rb +2 -3
 - data/lib/active_record/attribute_methods/read.rb +15 -53
 - data/lib/active_record/attribute_methods/serialization.rb +1 -1
 - data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
 - data/lib/active_record/attribute_methods/write.rb +17 -24
 - data/lib/active_record/attributes.rb +13 -0
 - data/lib/active_record/autosave_association.rb +5 -9
 - data/lib/active_record/base.rb +2 -3
 - data/lib/active_record/callbacks.rb +5 -19
 - data/lib/active_record/connection_adapters/abstract/connection_pool.rb +94 -16
 - data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -4
 - data/lib/active_record/connection_adapters/abstract/database_statements.rb +95 -123
 - data/lib/active_record/connection_adapters/abstract/query_cache.rb +17 -8
 - data/lib/active_record/connection_adapters/abstract/quoting.rb +68 -17
 - data/lib/active_record/connection_adapters/abstract/schema_creation.rb +19 -12
 - data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +76 -48
 - data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -3
 - data/lib/active_record/connection_adapters/abstract/schema_statements.rb +132 -53
 - data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -56
 - data/lib/active_record/connection_adapters/abstract_adapter.rb +180 -47
 - data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +128 -194
 - data/lib/active_record/connection_adapters/column.rb +17 -13
 - data/lib/active_record/connection_adapters/connection_specification.rb +52 -42
 - data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +6 -10
 - data/lib/active_record/connection_adapters/mysql/database_statements.rb +73 -13
 - data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
 - data/lib/active_record/connection_adapters/mysql/schema_creation.rb +3 -4
 - data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
 - data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
 - data/lib/active_record/connection_adapters/mysql/schema_statements.rb +129 -13
 - data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
 - data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -9
 - data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
 - data/lib/active_record/connection_adapters/postgresql/database_statements.rb +20 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
 - data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
 - data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +6 -3
 - data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -7
 - data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +12 -1
 - data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
 - data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +55 -53
 - data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
 - data/lib/active_record/connection_adapters/postgresql_adapter.rb +160 -74
 - data/lib/active_record/connection_adapters/schema_cache.rb +37 -14
 - data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
 - data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
 - data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -6
 - data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +42 -11
 - data/lib/active_record/connection_adapters/sqlite3_adapter.rb +125 -141
 - data/lib/active_record/connection_handling.rb +149 -27
 - data/lib/active_record/core.rb +100 -60
 - data/lib/active_record/counter_cache.rb +4 -29
 - data/lib/active_record/database_configurations.rb +233 -0
 - data/lib/active_record/database_configurations/database_config.rb +37 -0
 - data/lib/active_record/database_configurations/hash_config.rb +50 -0
 - data/lib/active_record/database_configurations/url_config.rb +79 -0
 - data/lib/active_record/dynamic_matchers.rb +1 -1
 - data/lib/active_record/enum.rb +37 -7
 - data/lib/active_record/errors.rb +15 -7
 - data/lib/active_record/explain.rb +1 -1
 - data/lib/active_record/fixture_set/model_metadata.rb +33 -0
 - data/lib/active_record/fixture_set/render_context.rb +17 -0
 - data/lib/active_record/fixture_set/table_row.rb +153 -0
 - data/lib/active_record/fixture_set/table_rows.rb +47 -0
 - data/lib/active_record/fixtures.rb +145 -472
 - data/lib/active_record/gem_version.rb +4 -4
 - data/lib/active_record/inheritance.rb +13 -3
 - data/lib/active_record/insert_all.rb +179 -0
 - data/lib/active_record/integration.rb +68 -16
 - data/lib/active_record/internal_metadata.rb +10 -2
 - data/lib/active_record/locking/optimistic.rb +5 -6
 - data/lib/active_record/locking/pessimistic.rb +3 -3
 - data/lib/active_record/log_subscriber.rb +7 -26
 - data/lib/active_record/middleware/database_selector.rb +75 -0
 - data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
 - data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
 - data/lib/active_record/migration.rb +100 -81
 - data/lib/active_record/migration/command_recorder.rb +50 -6
 - data/lib/active_record/migration/compatibility.rb +76 -49
 - data/lib/active_record/model_schema.rb +30 -9
 - data/lib/active_record/nested_attributes.rb +2 -2
 - data/lib/active_record/no_touching.rb +7 -0
 - data/lib/active_record/persistence.rb +228 -24
 - data/lib/active_record/query_cache.rb +11 -4
 - data/lib/active_record/querying.rb +32 -20
 - data/lib/active_record/railtie.rb +80 -43
 - data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
 - data/lib/active_record/railties/controller_runtime.rb +30 -35
 - data/lib/active_record/railties/databases.rake +196 -46
 - data/lib/active_record/reflection.rb +32 -30
 - data/lib/active_record/relation.rb +310 -80
 - data/lib/active_record/relation/batches.rb +13 -10
 - data/lib/active_record/relation/calculations.rb +53 -47
 - data/lib/active_record/relation/delegation.rb +26 -43
 - data/lib/active_record/relation/finder_methods.rb +13 -26
 - data/lib/active_record/relation/merger.rb +11 -20
 - data/lib/active_record/relation/predicate_builder.rb +4 -6
 - data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
 - data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
 - data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
 - data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
 - data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
 - data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
 - data/lib/active_record/relation/query_attribute.rb +13 -8
 - data/lib/active_record/relation/query_methods.rb +189 -63
 - data/lib/active_record/relation/spawn_methods.rb +1 -1
 - data/lib/active_record/relation/where_clause.rb +14 -10
 - data/lib/active_record/relation/where_clause_factory.rb +1 -2
 - data/lib/active_record/result.rb +30 -11
 - data/lib/active_record/sanitization.rb +32 -40
 - data/lib/active_record/schema.rb +2 -11
 - data/lib/active_record/schema_dumper.rb +22 -7
 - data/lib/active_record/schema_migration.rb +5 -1
 - data/lib/active_record/scoping.rb +8 -8
 - data/lib/active_record/scoping/default.rb +4 -5
 - data/lib/active_record/scoping/named.rb +19 -15
 - data/lib/active_record/statement_cache.rb +30 -3
 - data/lib/active_record/store.rb +87 -8
 - data/lib/active_record/table_metadata.rb +10 -17
 - data/lib/active_record/tasks/database_tasks.rb +194 -25
 - data/lib/active_record/tasks/mysql_database_tasks.rb +5 -5
 - data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -7
 - data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -8
 - data/lib/active_record/test_databases.rb +23 -0
 - data/lib/active_record/test_fixtures.rb +224 -0
 - data/lib/active_record/timestamp.rb +39 -25
 - data/lib/active_record/touch_later.rb +4 -2
 - data/lib/active_record/transactions.rb +57 -66
 - data/lib/active_record/translation.rb +1 -1
 - data/lib/active_record/type.rb +3 -4
 - data/lib/active_record/type/adapter_specific_registry.rb +1 -8
 - data/lib/active_record/type_caster/connection.rb +15 -14
 - data/lib/active_record/type_caster/map.rb +1 -4
 - data/lib/active_record/validations.rb +1 -0
 - data/lib/active_record/validations/uniqueness.rb +15 -27
 - data/lib/arel.rb +51 -0
 - data/lib/arel/alias_predication.rb +9 -0
 - data/lib/arel/attributes.rb +22 -0
 - data/lib/arel/attributes/attribute.rb +37 -0
 - data/lib/arel/collectors/bind.rb +24 -0
 - data/lib/arel/collectors/composite.rb +31 -0
 - data/lib/arel/collectors/plain_string.rb +20 -0
 - data/lib/arel/collectors/sql_string.rb +20 -0
 - data/lib/arel/collectors/substitute_binds.rb +28 -0
 - data/lib/arel/crud.rb +42 -0
 - data/lib/arel/delete_manager.rb +18 -0
 - data/lib/arel/errors.rb +9 -0
 - data/lib/arel/expressions.rb +29 -0
 - data/lib/arel/factory_methods.rb +49 -0
 - data/lib/arel/insert_manager.rb +49 -0
 - data/lib/arel/math.rb +45 -0
 - data/lib/arel/nodes.rb +68 -0
 - data/lib/arel/nodes/and.rb +32 -0
 - data/lib/arel/nodes/ascending.rb +23 -0
 - data/lib/arel/nodes/binary.rb +52 -0
 - data/lib/arel/nodes/bind_param.rb +36 -0
 - data/lib/arel/nodes/case.rb +55 -0
 - data/lib/arel/nodes/casted.rb +50 -0
 - data/lib/arel/nodes/comment.rb +29 -0
 - data/lib/arel/nodes/count.rb +12 -0
 - data/lib/arel/nodes/delete_statement.rb +45 -0
 - data/lib/arel/nodes/descending.rb +23 -0
 - data/lib/arel/nodes/equality.rb +18 -0
 - data/lib/arel/nodes/extract.rb +24 -0
 - data/lib/arel/nodes/false.rb +16 -0
 - data/lib/arel/nodes/full_outer_join.rb +8 -0
 - data/lib/arel/nodes/function.rb +44 -0
 - data/lib/arel/nodes/grouping.rb +8 -0
 - data/lib/arel/nodes/in.rb +8 -0
 - data/lib/arel/nodes/infix_operation.rb +80 -0
 - data/lib/arel/nodes/inner_join.rb +8 -0
 - data/lib/arel/nodes/insert_statement.rb +37 -0
 - data/lib/arel/nodes/join_source.rb +20 -0
 - data/lib/arel/nodes/matches.rb +18 -0
 - data/lib/arel/nodes/named_function.rb +23 -0
 - data/lib/arel/nodes/node.rb +50 -0
 - data/lib/arel/nodes/node_expression.rb +13 -0
 - data/lib/arel/nodes/outer_join.rb +8 -0
 - data/lib/arel/nodes/over.rb +15 -0
 - data/lib/arel/nodes/regexp.rb +16 -0
 - data/lib/arel/nodes/right_outer_join.rb +8 -0
 - data/lib/arel/nodes/select_core.rb +67 -0
 - data/lib/arel/nodes/select_statement.rb +41 -0
 - data/lib/arel/nodes/sql_literal.rb +16 -0
 - data/lib/arel/nodes/string_join.rb +11 -0
 - data/lib/arel/nodes/table_alias.rb +27 -0
 - data/lib/arel/nodes/terminal.rb +16 -0
 - data/lib/arel/nodes/true.rb +16 -0
 - data/lib/arel/nodes/unary.rb +45 -0
 - data/lib/arel/nodes/unary_operation.rb +20 -0
 - data/lib/arel/nodes/unqualified_column.rb +22 -0
 - data/lib/arel/nodes/update_statement.rb +41 -0
 - data/lib/arel/nodes/values_list.rb +9 -0
 - data/lib/arel/nodes/window.rb +126 -0
 - data/lib/arel/nodes/with.rb +11 -0
 - data/lib/arel/order_predications.rb +13 -0
 - data/lib/arel/predications.rb +257 -0
 - data/lib/arel/select_manager.rb +271 -0
 - data/lib/arel/table.rb +110 -0
 - data/lib/arel/tree_manager.rb +72 -0
 - data/lib/arel/update_manager.rb +34 -0
 - data/lib/arel/visitors.rb +20 -0
 - data/lib/arel/visitors/depth_first.rb +204 -0
 - data/lib/arel/visitors/dot.rb +297 -0
 - data/lib/arel/visitors/ibm_db.rb +34 -0
 - data/lib/arel/visitors/informix.rb +62 -0
 - data/lib/arel/visitors/mssql.rb +157 -0
 - data/lib/arel/visitors/mysql.rb +83 -0
 - data/lib/arel/visitors/oracle.rb +159 -0
 - data/lib/arel/visitors/oracle12.rb +66 -0
 - data/lib/arel/visitors/postgresql.rb +110 -0
 - data/lib/arel/visitors/sqlite.rb +39 -0
 - data/lib/arel/visitors/to_sql.rb +889 -0
 - data/lib/arel/visitors/visitor.rb +46 -0
 - data/lib/arel/visitors/where_sql.rb +23 -0
 - data/lib/arel/window_predications.rb +9 -0
 - data/lib/rails/generators/active_record/migration.rb +14 -1
 - data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
 - data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
 - data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
 - data/lib/rails/generators/active_record/model/model_generator.rb +1 -0
 - data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
 - metadata +108 -26
 - data/lib/active_record/collection_cache_key.rb +0 -53
 
| 
         @@ -117,18 +117,16 @@ module ActiveRecord 
     | 
|
| 
       117 
117 
     | 
    
         
             
                      if other.klass == relation.klass
         
     | 
| 
       118 
118 
     | 
    
         
             
                        relation.joins!(*other.joins_values)
         
     | 
| 
       119 
119 
     | 
    
         
             
                      else
         
     | 
| 
       120 
     | 
    
         
            -
                         
     | 
| 
      
 120 
     | 
    
         
            +
                        associations, others = other.joins_values.partition do |join|
         
     | 
| 
       121 
121 
     | 
    
         
             
                          case join
         
     | 
| 
       122 
     | 
    
         
            -
                          when Hash, Symbol, Array
         
     | 
| 
       123 
     | 
    
         
            -
                            ActiveRecord::Associations::JoinDependency.new(
         
     | 
| 
       124 
     | 
    
         
            -
                              other.klass, other.table, join
         
     | 
| 
       125 
     | 
    
         
            -
                            )
         
     | 
| 
       126 
     | 
    
         
            -
                          else
         
     | 
| 
       127 
     | 
    
         
            -
                            join
         
     | 
| 
      
 122 
     | 
    
         
            +
                          when Hash, Symbol, Array; true
         
     | 
| 
       128 
123 
     | 
    
         
             
                          end
         
     | 
| 
       129 
124 
     | 
    
         
             
                        end
         
     | 
| 
       130 
125 
     | 
    
         | 
| 
       131 
     | 
    
         
            -
                         
     | 
| 
      
 126 
     | 
    
         
            +
                        join_dependency = other.construct_join_dependency(
         
     | 
| 
      
 127 
     | 
    
         
            +
                          associations, Arel::Nodes::InnerJoin
         
     | 
| 
      
 128 
     | 
    
         
            +
                        )
         
     | 
| 
      
 129 
     | 
    
         
            +
                        relation.joins!(join_dependency, *others)
         
     | 
| 
       132 
130 
     | 
    
         
             
                      end
         
     | 
| 
       133 
131 
     | 
    
         
             
                    end
         
     | 
| 
       134 
132 
     | 
    
         | 
| 
         @@ -138,18 +136,11 @@ module ActiveRecord 
     | 
|
| 
       138 
136 
     | 
    
         
             
                      if other.klass == relation.klass
         
     | 
| 
       139 
137 
     | 
    
         
             
                        relation.left_outer_joins!(*other.left_outer_joins_values)
         
     | 
| 
       140 
138 
     | 
    
         
             
                      else
         
     | 
| 
       141 
     | 
    
         
            -
                         
     | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
       143 
     | 
    
         
            -
                           
     | 
| 
       144 
     | 
    
         
            -
             
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
                            )
         
     | 
| 
       147 
     | 
    
         
            -
                          else
         
     | 
| 
       148 
     | 
    
         
            -
                            join
         
     | 
| 
       149 
     | 
    
         
            -
                          end
         
     | 
| 
       150 
     | 
    
         
            -
                        end
         
     | 
| 
       151 
     | 
    
         
            -
             
     | 
| 
       152 
     | 
    
         
            -
                        relation.left_outer_joins!(*joins_dependency)
         
     | 
| 
      
 139 
     | 
    
         
            +
                        associations = other.left_outer_joins_values
         
     | 
| 
      
 140 
     | 
    
         
            +
                        join_dependency = other.construct_join_dependency(
         
     | 
| 
      
 141 
     | 
    
         
            +
                          associations, Arel::Nodes::OuterJoin
         
     | 
| 
      
 142 
     | 
    
         
            +
                        )
         
     | 
| 
      
 143 
     | 
    
         
            +
                        relation.joins!(join_dependency)
         
     | 
| 
       153 
144 
     | 
    
         
             
                      end
         
     | 
| 
       154 
145 
     | 
    
         
             
                    end
         
     | 
| 
       155 
146 
     | 
    
         | 
| 
         @@ -27,7 +27,7 @@ module ActiveRecord 
     | 
|
| 
       27 
27 
     | 
    
         
             
                      key
         
     | 
| 
       28 
28 
     | 
    
         
             
                    else
         
     | 
| 
       29 
29 
     | 
    
         
             
                      key = key.to_s
         
     | 
| 
       30 
     | 
    
         
            -
                      key.split("." 
     | 
| 
      
 30 
     | 
    
         
            +
                      key.split(".").first if key.include?(".")
         
     | 
| 
       31 
31 
     | 
    
         
             
                    end
         
     | 
| 
       32 
32 
     | 
    
         
             
                  end.compact
         
     | 
| 
       33 
33 
     | 
    
         
             
                end
         
     | 
| 
         @@ -62,9 +62,6 @@ module ActiveRecord 
     | 
|
| 
       62 
62 
     | 
    
         
             
                end
         
     | 
| 
       63 
63 
     | 
    
         | 
| 
       64 
64 
     | 
    
         
             
                protected
         
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
                  attr_reader :table
         
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
65 
     | 
    
         
             
                  def expand_from_hash(attributes)
         
     | 
| 
       69 
66 
     | 
    
         
             
                    return ["1=0"] if attributes.empty?
         
     | 
| 
       70 
67 
     | 
    
         | 
| 
         @@ -115,6 +112,7 @@ module ActiveRecord 
     | 
|
| 
       115 
112 
     | 
    
         
             
                  end
         
     | 
| 
       116 
113 
     | 
    
         | 
| 
       117 
114 
     | 
    
         
             
                private
         
     | 
| 
      
 115 
     | 
    
         
            +
                  attr_reader :table
         
     | 
| 
       118 
116 
     | 
    
         | 
| 
       119 
117 
     | 
    
         
             
                  def associated_predicate_builder(association_name)
         
     | 
| 
       120 
118 
     | 
    
         
             
                    self.class.new(table.associated_table(association_name))
         
     | 
| 
         @@ -122,11 +120,11 @@ module ActiveRecord 
     | 
|
| 
       122 
120 
     | 
    
         | 
| 
       123 
121 
     | 
    
         
             
                  def convert_dot_notation_to_hash(attributes)
         
     | 
| 
       124 
122 
     | 
    
         
             
                    dot_notation = attributes.select do |k, v|
         
     | 
| 
       125 
     | 
    
         
            -
                      k.include?("." 
     | 
| 
      
 123 
     | 
    
         
            +
                      k.include?(".") && !v.is_a?(Hash)
         
     | 
| 
       126 
124 
     | 
    
         
             
                    end
         
     | 
| 
       127 
125 
     | 
    
         | 
| 
       128 
126 
     | 
    
         
             
                    dot_notation.each_key do |key|
         
     | 
| 
       129 
     | 
    
         
            -
                      table_name, column_name = key.split("." 
     | 
| 
      
 127 
     | 
    
         
            +
                      table_name, column_name = key.split(".")
         
     | 
| 
       130 
128 
     | 
    
         
             
                      value = attributes.delete(key)
         
     | 
| 
       131 
129 
     | 
    
         
             
                      attributes[table_name] ||= {}
         
     | 
| 
       132 
130 
     | 
    
         | 
| 
         @@ -1,5 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            require "active_support/core_ext/array/extract"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
       3 
5 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       4 
6 
     | 
    
         
             
              class PredicateBuilder
         
     | 
| 
       5 
7 
     | 
    
         
             
                class ArrayHandler # :nodoc:
         
     | 
| 
         @@ -11,8 +13,8 @@ module ActiveRecord 
     | 
|
| 
       11 
13 
     | 
    
         
             
                    return attribute.in([]) if value.empty?
         
     | 
| 
       12 
14 
     | 
    
         | 
| 
       13 
15 
     | 
    
         
             
                    values = value.map { |x| x.is_a?(Base) ? x.id : x }
         
     | 
| 
       14 
     | 
    
         
            -
                    nils 
     | 
| 
       15 
     | 
    
         
            -
                    ranges 
     | 
| 
      
 16 
     | 
    
         
            +
                    nils = values.extract!(&:nil?)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    ranges = values.extract! { |v| v.is_a?(Range) }
         
     | 
| 
       16 
18 
     | 
    
         | 
| 
       17 
19 
     | 
    
         
             
                    values_predicate =
         
     | 
| 
       18 
20 
     | 
    
         
             
                      case values.length
         
     | 
| 
         @@ -34,8 +36,7 @@ module ActiveRecord 
     | 
|
| 
       34 
36 
     | 
    
         
             
                    array_predicates.inject(&:or)
         
     | 
| 
       35 
37 
     | 
    
         
             
                  end
         
     | 
| 
       36 
38 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
                   
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
      
 39 
     | 
    
         
            +
                  private
         
     | 
| 
       39 
40 
     | 
    
         
             
                    attr_reader :predicate_builder
         
     | 
| 
       40 
41 
     | 
    
         | 
| 
       41 
42 
     | 
    
         
             
                    module NullPredicate # :nodoc:
         
     | 
| 
         @@ -12,12 +12,9 @@ module ActiveRecord 
     | 
|
| 
       12 
12 
     | 
    
         
             
                    [associated_table.association_join_foreign_key.to_s => ids]
         
     | 
| 
       13 
13 
     | 
    
         
             
                  end
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
                   
     | 
| 
       16 
     | 
    
         
            -
                  # Workaround for Ruby 2.2 "private attribute?" warning.
         
     | 
| 
       17 
     | 
    
         
            -
                  protected
         
     | 
| 
      
 15 
     | 
    
         
            +
                  private
         
     | 
| 
       18 
16 
     | 
    
         
             
                    attr_reader :associated_table, :value
         
     | 
| 
       19 
17 
     | 
    
         | 
| 
       20 
     | 
    
         
            -
                  private
         
     | 
| 
       21 
18 
     | 
    
         
             
                    def ids
         
     | 
| 
       22 
19 
     | 
    
         
             
                      case value
         
     | 
| 
       23 
20 
     | 
    
         
             
                      when Relation
         
     | 
| 
         @@ -17,12 +17,9 @@ module ActiveRecord 
     | 
|
| 
       17 
17 
     | 
    
         
             
                    end
         
     | 
| 
       18 
18 
     | 
    
         
             
                  end
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
     | 
    
         
            -
                   
     | 
| 
       21 
     | 
    
         
            -
                  # Workaround for Ruby 2.2 "private attribute?" warning.
         
     | 
| 
       22 
     | 
    
         
            -
                  protected
         
     | 
| 
      
 20 
     | 
    
         
            +
                  private
         
     | 
| 
       23 
21 
     | 
    
         
             
                    attr_reader :associated_table, :values
         
     | 
| 
       24 
22 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
                  private
         
     | 
| 
       26 
23 
     | 
    
         
             
                    def type_to_ids_mapping
         
     | 
| 
       27 
24 
     | 
    
         
             
                      default_hash = Hash.new { |hsh, key| hsh[key] = [] }
         
     | 
| 
       28 
25 
     | 
    
         
             
                      values.each_with_object(default_hash) do |value, hash|
         
     | 
| 
         @@ -3,11 +3,7 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       4 
4 
     | 
    
         
             
              class PredicateBuilder
         
     | 
| 
       5 
5 
     | 
    
         
             
                class RangeHandler # :nodoc:
         
     | 
| 
       6 
     | 
    
         
            -
                   
     | 
| 
       7 
     | 
    
         
            -
                    def exclude_end?
         
     | 
| 
       8 
     | 
    
         
            -
                      false
         
     | 
| 
       9 
     | 
    
         
            -
                    end
         
     | 
| 
       10 
     | 
    
         
            -
                  end
         
     | 
| 
      
 6 
     | 
    
         
            +
                  RangeWithBinds = Struct.new(:begin, :end, :exclude_end?)
         
     | 
| 
       11 
7 
     | 
    
         | 
| 
       12 
8 
     | 
    
         
             
                  def initialize(predicate_builder)
         
     | 
| 
       13 
9 
     | 
    
         
             
                    @predicate_builder = predicate_builder
         
     | 
| 
         @@ -16,26 +12,10 @@ module ActiveRecord 
     | 
|
| 
       16 
12 
     | 
    
         
             
                  def call(attribute, value)
         
     | 
| 
       17 
13 
     | 
    
         
             
                    begin_bind = predicate_builder.build_bind_attribute(attribute.name, value.begin)
         
     | 
| 
       18 
14 
     | 
    
         
             
                    end_bind = predicate_builder.build_bind_attribute(attribute.name, value.end)
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                    if begin_bind.value.infinity?
         
     | 
| 
       21 
     | 
    
         
            -
                      if end_bind.value.infinity?
         
     | 
| 
       22 
     | 
    
         
            -
                        attribute.not_in([])
         
     | 
| 
       23 
     | 
    
         
            -
                      elsif value.exclude_end?
         
     | 
| 
       24 
     | 
    
         
            -
                        attribute.lt(end_bind)
         
     | 
| 
       25 
     | 
    
         
            -
                      else
         
     | 
| 
       26 
     | 
    
         
            -
                        attribute.lteq(end_bind)
         
     | 
| 
       27 
     | 
    
         
            -
                      end
         
     | 
| 
       28 
     | 
    
         
            -
                    elsif end_bind.value.infinity?
         
     | 
| 
       29 
     | 
    
         
            -
                      attribute.gteq(begin_bind)
         
     | 
| 
       30 
     | 
    
         
            -
                    elsif value.exclude_end?
         
     | 
| 
       31 
     | 
    
         
            -
                      attribute.gteq(begin_bind).and(attribute.lt(end_bind))
         
     | 
| 
       32 
     | 
    
         
            -
                    else
         
     | 
| 
       33 
     | 
    
         
            -
                      attribute.between(RangeWithBinds.new(begin_bind, end_bind))
         
     | 
| 
       34 
     | 
    
         
            -
                    end
         
     | 
| 
      
 15 
     | 
    
         
            +
                    attribute.between(RangeWithBinds.new(begin_bind, end_bind, value.exclude_end?))
         
     | 
| 
       35 
16 
     | 
    
         
             
                  end
         
     | 
| 
       36 
17 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
                   
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
      
 18 
     | 
    
         
            +
                  private
         
     | 
| 
       39 
19 
     | 
    
         
             
                    attr_reader :predicate_builder
         
     | 
| 
       40 
20 
     | 
    
         
             
                end
         
     | 
| 
       41 
21 
     | 
    
         
             
              end
         
     | 
| 
         @@ -22,22 +22,27 @@ module ActiveRecord 
     | 
|
| 
       22 
22 
     | 
    
         
             
                      value_before_type_cast.nil? ||
         
     | 
| 
       23 
23 
     | 
    
         
             
                        type.respond_to?(:subtype, true) && value_for_database.nil?
         
     | 
| 
       24 
24 
     | 
    
         
             
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
                  rescue ::RangeError
         
     | 
| 
       25 
26 
     | 
    
         
             
                  end
         
     | 
| 
       26 
27 
     | 
    
         | 
| 
       27 
     | 
    
         
            -
                  def  
     | 
| 
       28 
     | 
    
         
            -
                     
     | 
| 
       29 
     | 
    
         
            -
                    value_for_database unless value_before_type_cast.is_a?(StatementCache::Substitute)
         
     | 
| 
       30 
     | 
    
         
            -
                    @_boundable = true
         
     | 
| 
      
 28 
     | 
    
         
            +
                  def infinite?
         
     | 
| 
      
 29 
     | 
    
         
            +
                    infinity?(value_before_type_cast) || infinity?(value_for_database)
         
     | 
| 
       31 
30 
     | 
    
         
             
                  rescue ::RangeError
         
     | 
| 
       32 
     | 
    
         
            -
                    @_boundable = false
         
     | 
| 
       33 
31 
     | 
    
         
             
                  end
         
     | 
| 
       34 
32 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
                  def  
     | 
| 
       36 
     | 
    
         
            -
                     
     | 
| 
      
 33 
     | 
    
         
            +
                  def unboundable?
         
     | 
| 
      
 34 
     | 
    
         
            +
                    if defined?(@_unboundable)
         
     | 
| 
      
 35 
     | 
    
         
            +
                      @_unboundable
         
     | 
| 
      
 36 
     | 
    
         
            +
                    else
         
     | 
| 
      
 37 
     | 
    
         
            +
                      value_for_database unless value_before_type_cast.is_a?(StatementCache::Substitute)
         
     | 
| 
      
 38 
     | 
    
         
            +
                      @_unboundable = nil
         
     | 
| 
      
 39 
     | 
    
         
            +
                    end
         
     | 
| 
      
 40 
     | 
    
         
            +
                  rescue ::RangeError
         
     | 
| 
      
 41 
     | 
    
         
            +
                    @_unboundable = type.cast(value_before_type_cast) <=> 0
         
     | 
| 
       37 
42 
     | 
    
         
             
                  end
         
     | 
| 
       38 
43 
     | 
    
         | 
| 
       39 
44 
     | 
    
         
             
                  private
         
     | 
| 
       40 
     | 
    
         
            -
                    def  
     | 
| 
      
 45 
     | 
    
         
            +
                    def infinity?(value)
         
     | 
| 
       41 
46 
     | 
    
         
             
                      value.respond_to?(:infinite?) && value.infinite?
         
     | 
| 
       42 
47 
     | 
    
         
             
                    end
         
     | 
| 
       43 
48 
     | 
    
         
             
                end
         
     | 
| 
         @@ -41,18 +41,31 @@ module ActiveRecord 
     | 
|
| 
       41 
41 
     | 
    
         
             
                  #
         
     | 
| 
       42 
42 
     | 
    
         
             
                  #    User.where.not(name: %w(Ko1 Nobu))
         
     | 
| 
       43 
43 
     | 
    
         
             
                  #    # SELECT * FROM users WHERE name NOT IN ('Ko1', 'Nobu')
         
     | 
| 
       44 
     | 
    
         
            -
                  #
         
     | 
| 
       45 
     | 
    
         
            -
                  #    User.where.not(name: "Jon", role: "admin")
         
     | 
| 
       46 
     | 
    
         
            -
                  #    # SELECT * FROM users WHERE name != 'Jon' AND role != 'admin'
         
     | 
| 
       47 
44 
     | 
    
         
             
                  def not(opts, *rest)
         
     | 
| 
       48 
45 
     | 
    
         
             
                    opts = sanitize_forbidden_attributes(opts)
         
     | 
| 
       49 
46 
     | 
    
         | 
| 
       50 
47 
     | 
    
         
             
                    where_clause = @scope.send(:where_clause_factory).build(opts, rest)
         
     | 
| 
       51 
48 
     | 
    
         | 
| 
       52 
49 
     | 
    
         
             
                    @scope.references!(PredicateBuilder.references(opts)) if Hash === opts
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                    if not_behaves_as_nor?(opts)
         
     | 
| 
      
 52 
     | 
    
         
            +
                      ActiveSupport::Deprecation.warn(<<~MSG.squish)
         
     | 
| 
      
 53 
     | 
    
         
            +
                        NOT conditions will no longer behave as NOR in Rails 6.1.
         
     | 
| 
      
 54 
     | 
    
         
            +
                        To continue using NOR conditions, NOT each conditions manually
         
     | 
| 
      
 55 
     | 
    
         
            +
                        (`#{ opts.keys.map { |key| ".where.not(#{key.inspect} => ...)" }.join }`).
         
     | 
| 
      
 56 
     | 
    
         
            +
                      MSG
         
     | 
| 
      
 57 
     | 
    
         
            +
                      @scope.where_clause += where_clause.invert(:nor)
         
     | 
| 
      
 58 
     | 
    
         
            +
                    else
         
     | 
| 
      
 59 
     | 
    
         
            +
                      @scope.where_clause += where_clause.invert
         
     | 
| 
      
 60 
     | 
    
         
            +
                    end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
       54 
62 
     | 
    
         
             
                    @scope
         
     | 
| 
       55 
63 
     | 
    
         
             
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  private
         
     | 
| 
      
 66 
     | 
    
         
            +
                    def not_behaves_as_nor?(opts)
         
     | 
| 
      
 67 
     | 
    
         
            +
                      opts.is_a?(Hash) && opts.size > 1
         
     | 
| 
      
 68 
     | 
    
         
            +
                    end
         
     | 
| 
       56 
69 
     | 
    
         
             
                end
         
     | 
| 
       57 
70 
     | 
    
         | 
| 
       58 
71 
     | 
    
         
             
                FROZEN_EMPTY_ARRAY = [].freeze
         
     | 
| 
         @@ -67,11 +80,13 @@ module ActiveRecord 
     | 
|
| 
       67 
80 
     | 
    
         
             
                    end
         
     | 
| 
       68 
81 
     | 
    
         
             
                  class_eval <<-CODE, __FILE__, __LINE__ + 1
         
     | 
| 
       69 
82 
     | 
    
         
             
                    def #{method_name}                   # def includes_values
         
     | 
| 
       70 
     | 
    
         
            -
                       
     | 
| 
      
 83 
     | 
    
         
            +
                      default = DEFAULT_VALUES[:#{name}] #   default = DEFAULT_VALUES[:includes]
         
     | 
| 
      
 84 
     | 
    
         
            +
                      @values.fetch(:#{name}, default)   #   @values.fetch(:includes, default)
         
     | 
| 
       71 
85 
     | 
    
         
             
                    end                                  # end
         
     | 
| 
       72 
86 
     | 
    
         | 
| 
       73 
87 
     | 
    
         
             
                    def #{method_name}=(value)           # def includes_values=(value)
         
     | 
| 
       74 
     | 
    
         
            -
                       
     | 
| 
      
 88 
     | 
    
         
            +
                      assert_mutability!                 #   assert_mutability!
         
     | 
| 
      
 89 
     | 
    
         
            +
                      @values[:#{name}] = value          #   @values[:includes] = value
         
     | 
| 
       75 
90 
     | 
    
         
             
                    end                                  # end
         
     | 
| 
       76 
91 
     | 
    
         
             
                  CODE
         
     | 
| 
       77 
92 
     | 
    
         
             
                end
         
     | 
| 
         @@ -100,7 +115,7 @@ module ActiveRecord 
     | 
|
| 
       100 
115 
     | 
    
         
             
                #
         
     | 
| 
       101 
116 
     | 
    
         
             
                # === conditions
         
     | 
| 
       102 
117 
     | 
    
         
             
                #
         
     | 
| 
       103 
     | 
    
         
            -
                # If you want to add conditions to your included models you'll have
         
     | 
| 
      
 118 
     | 
    
         
            +
                # If you want to add string conditions to your included models, you'll have
         
     | 
| 
       104 
119 
     | 
    
         
             
                # to explicitly reference them. For example:
         
     | 
| 
       105 
120 
     | 
    
         
             
                #
         
     | 
| 
       106 
121 
     | 
    
         
             
                #   User.includes(:posts).where('posts.name = ?', 'example')
         
     | 
| 
         @@ -111,6 +126,12 @@ module ActiveRecord 
     | 
|
| 
       111 
126 
     | 
    
         
             
                #
         
     | 
| 
       112 
127 
     | 
    
         
             
                # Note that #includes works with association names while #references needs
         
     | 
| 
       113 
128 
     | 
    
         
             
                # the actual table name.
         
     | 
| 
      
 129 
     | 
    
         
            +
                #
         
     | 
| 
      
 130 
     | 
    
         
            +
                # If you pass the conditions via hash, you don't need to call #references
         
     | 
| 
      
 131 
     | 
    
         
            +
                # explicitly, as #where references the tables for you. For example, this
         
     | 
| 
      
 132 
     | 
    
         
            +
                # will work correctly:
         
     | 
| 
      
 133 
     | 
    
         
            +
                #
         
     | 
| 
      
 134 
     | 
    
         
            +
                #   User.includes(:posts).where(posts: { name: 'example' })
         
     | 
| 
       114 
135 
     | 
    
         
             
                def includes(*args)
         
     | 
| 
       115 
136 
     | 
    
         
             
                  check_if_method_has_arguments!(:includes, args)
         
     | 
| 
       116 
137 
     | 
    
         
             
                  spawn.includes!(*args)
         
     | 
| 
         @@ -154,6 +175,19 @@ module ActiveRecord 
     | 
|
| 
       154 
175 
     | 
    
         
             
                  self
         
     | 
| 
       155 
176 
     | 
    
         
             
                end
         
     | 
| 
       156 
177 
     | 
    
         | 
| 
      
 178 
     | 
    
         
            +
                # Extracts a named +association+ from the relation. The named association is first preloaded,
         
     | 
| 
      
 179 
     | 
    
         
            +
                # then the individual association records are collected from the relation. Like so:
         
     | 
| 
      
 180 
     | 
    
         
            +
                #
         
     | 
| 
      
 181 
     | 
    
         
            +
                #   account.memberships.extract_associated(:user)
         
     | 
| 
      
 182 
     | 
    
         
            +
                #   # => Returns collection of User records
         
     | 
| 
      
 183 
     | 
    
         
            +
                #
         
     | 
| 
      
 184 
     | 
    
         
            +
                # This is short-hand for:
         
     | 
| 
      
 185 
     | 
    
         
            +
                #
         
     | 
| 
      
 186 
     | 
    
         
            +
                #   account.memberships.preload(:user).collect(&:user)
         
     | 
| 
      
 187 
     | 
    
         
            +
                def extract_associated(association)
         
     | 
| 
      
 188 
     | 
    
         
            +
                  preload(association).collect(&association)
         
     | 
| 
      
 189 
     | 
    
         
            +
                end
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
       157 
191 
     | 
    
         
             
                # Use to indicate that the given +table_names+ are referenced by an SQL string,
         
     | 
| 
       158 
192 
     | 
    
         
             
                # and should therefore be JOINed in any query rather than loaded separately.
         
     | 
| 
       159 
193 
     | 
    
         
             
                # This method only works in conjunction with #includes.
         
     | 
| 
         @@ -231,11 +265,33 @@ module ActiveRecord 
     | 
|
| 
       231 
265 
     | 
    
         
             
                end
         
     | 
| 
       232 
266 
     | 
    
         | 
| 
       233 
267 
     | 
    
         
             
                def _select!(*fields) # :nodoc:
         
     | 
| 
      
 268 
     | 
    
         
            +
                  fields.reject!(&:blank?)
         
     | 
| 
       234 
269 
     | 
    
         
             
                  fields.flatten!
         
     | 
| 
       235 
270 
     | 
    
         
             
                  self.select_values += fields
         
     | 
| 
       236 
271 
     | 
    
         
             
                  self
         
     | 
| 
       237 
272 
     | 
    
         
             
                end
         
     | 
| 
       238 
273 
     | 
    
         | 
| 
      
 274 
     | 
    
         
            +
                # Allows you to change a previously set select statement.
         
     | 
| 
      
 275 
     | 
    
         
            +
                #
         
     | 
| 
      
 276 
     | 
    
         
            +
                #   Post.select(:title, :body)
         
     | 
| 
      
 277 
     | 
    
         
            +
                #   # SELECT `posts`.`title`, `posts`.`body` FROM `posts`
         
     | 
| 
      
 278 
     | 
    
         
            +
                #
         
     | 
| 
      
 279 
     | 
    
         
            +
                #   Post.select(:title, :body).reselect(:created_at)
         
     | 
| 
      
 280 
     | 
    
         
            +
                #   # SELECT `posts`.`created_at` FROM `posts`
         
     | 
| 
      
 281 
     | 
    
         
            +
                #
         
     | 
| 
      
 282 
     | 
    
         
            +
                # This is short-hand for <tt>unscope(:select).select(fields)</tt>.
         
     | 
| 
      
 283 
     | 
    
         
            +
                # Note that we're unscoping the entire select statement.
         
     | 
| 
      
 284 
     | 
    
         
            +
                def reselect(*args)
         
     | 
| 
      
 285 
     | 
    
         
            +
                  check_if_method_has_arguments!(:reselect, args)
         
     | 
| 
      
 286 
     | 
    
         
            +
                  spawn.reselect!(*args)
         
     | 
| 
      
 287 
     | 
    
         
            +
                end
         
     | 
| 
      
 288 
     | 
    
         
            +
             
     | 
| 
      
 289 
     | 
    
         
            +
                # Same as #reselect but operates on relation in-place instead of copying.
         
     | 
| 
      
 290 
     | 
    
         
            +
                def reselect!(*args) # :nodoc:
         
     | 
| 
      
 291 
     | 
    
         
            +
                  self.select_values = args
         
     | 
| 
      
 292 
     | 
    
         
            +
                  self
         
     | 
| 
      
 293 
     | 
    
         
            +
                end
         
     | 
| 
      
 294 
     | 
    
         
            +
             
     | 
| 
       239 
295 
     | 
    
         
             
                # Allows to specify a group attribute:
         
     | 
| 
       240 
296 
     | 
    
         
             
                #
         
     | 
| 
       241 
297 
     | 
    
         
             
                #   User.group(:name)
         
     | 
| 
         @@ -316,7 +372,7 @@ module ActiveRecord 
     | 
|
| 
       316 
372 
     | 
    
         | 
| 
       317 
373 
     | 
    
         
             
                # Same as #reorder but operates on relation in-place instead of copying.
         
     | 
| 
       318 
374 
     | 
    
         
             
                def reorder!(*args) # :nodoc:
         
     | 
| 
       319 
     | 
    
         
            -
                  preprocess_order_args(args)
         
     | 
| 
      
 375 
     | 
    
         
            +
                  preprocess_order_args(args) unless args.all?(&:blank?)
         
     | 
| 
       320 
376 
     | 
    
         | 
| 
       321 
377 
     | 
    
         
             
                  self.reordering_value = true
         
     | 
| 
       322 
378 
     | 
    
         
             
                  self.order_values = args
         
     | 
| 
         @@ -324,8 +380,8 @@ module ActiveRecord 
     | 
|
| 
       324 
380 
     | 
    
         
             
                end
         
     | 
| 
       325 
381 
     | 
    
         | 
| 
       326 
382 
     | 
    
         
             
                VALID_UNSCOPING_VALUES = Set.new([:where, :select, :group, :order, :lock,
         
     | 
| 
       327 
     | 
    
         
            -
                                                 :limit, :offset, :joins, :left_outer_joins,
         
     | 
| 
       328 
     | 
    
         
            -
                                                 :includes, :from, :readonly, :having])
         
     | 
| 
      
 383 
     | 
    
         
            +
                                                 :limit, :offset, :joins, :left_outer_joins, :annotate,
         
     | 
| 
      
 384 
     | 
    
         
            +
                                                 :includes, :from, :readonly, :having, :optimizer_hints])
         
     | 
| 
       329 
385 
     | 
    
         | 
| 
       330 
386 
     | 
    
         
             
                # Removes an unwanted relation that is already defined on a chain of relations.
         
     | 
| 
       331 
387 
     | 
    
         
             
                # This is useful when passing around chains of relations and would like to
         
     | 
| 
         @@ -376,7 +432,8 @@ module ActiveRecord 
     | 
|
| 
       376 
432 
     | 
    
         
             
                      if !VALID_UNSCOPING_VALUES.include?(scope)
         
     | 
| 
       377 
433 
     | 
    
         
             
                        raise ArgumentError, "Called unscope() with invalid unscoping argument ':#{scope}'. Valid arguments are :#{VALID_UNSCOPING_VALUES.to_a.join(", :")}."
         
     | 
| 
       378 
434 
     | 
    
         
             
                      end
         
     | 
| 
       379 
     | 
    
         
            -
                       
     | 
| 
      
 435 
     | 
    
         
            +
                      assert_mutability!
         
     | 
| 
      
 436 
     | 
    
         
            +
                      @values[scope] = DEFAULT_VALUES[scope]
         
     | 
| 
       380 
437 
     | 
    
         
             
                    when Hash
         
     | 
| 
       381 
438 
     | 
    
         
             
                      scope.each do |key, target_value|
         
     | 
| 
       382 
439 
     | 
    
         
             
                        if key != :where
         
     | 
| 
         @@ -876,6 +933,29 @@ module ActiveRecord 
     | 
|
| 
       876 
933 
     | 
    
         
             
                  self
         
     | 
| 
       877 
934 
     | 
    
         
             
                end
         
     | 
| 
       878 
935 
     | 
    
         | 
| 
      
 936 
     | 
    
         
            +
                # Specify optimizer hints to be used in the SELECT statement.
         
     | 
| 
      
 937 
     | 
    
         
            +
                #
         
     | 
| 
      
 938 
     | 
    
         
            +
                # Example (for MySQL):
         
     | 
| 
      
 939 
     | 
    
         
            +
                #
         
     | 
| 
      
 940 
     | 
    
         
            +
                #   Topic.optimizer_hints("MAX_EXECUTION_TIME(50000)", "NO_INDEX_MERGE(topics)")
         
     | 
| 
      
 941 
     | 
    
         
            +
                #   # SELECT /*+ MAX_EXECUTION_TIME(50000) NO_INDEX_MERGE(topics) */ `topics`.* FROM `topics`
         
     | 
| 
      
 942 
     | 
    
         
            +
                #
         
     | 
| 
      
 943 
     | 
    
         
            +
                # Example (for PostgreSQL with pg_hint_plan):
         
     | 
| 
      
 944 
     | 
    
         
            +
                #
         
     | 
| 
      
 945 
     | 
    
         
            +
                #   Topic.optimizer_hints("SeqScan(topics)", "Parallel(topics 8)")
         
     | 
| 
      
 946 
     | 
    
         
            +
                #   # SELECT /*+ SeqScan(topics) Parallel(topics 8) */ "topics".* FROM "topics"
         
     | 
| 
      
 947 
     | 
    
         
            +
                def optimizer_hints(*args)
         
     | 
| 
      
 948 
     | 
    
         
            +
                  check_if_method_has_arguments!(:optimizer_hints, args)
         
     | 
| 
      
 949 
     | 
    
         
            +
                  spawn.optimizer_hints!(*args)
         
     | 
| 
      
 950 
     | 
    
         
            +
                end
         
     | 
| 
      
 951 
     | 
    
         
            +
             
     | 
| 
      
 952 
     | 
    
         
            +
                def optimizer_hints!(*args) # :nodoc:
         
     | 
| 
      
 953 
     | 
    
         
            +
                  args.flatten!
         
     | 
| 
      
 954 
     | 
    
         
            +
             
     | 
| 
      
 955 
     | 
    
         
            +
                  self.optimizer_hints_values |= args
         
     | 
| 
      
 956 
     | 
    
         
            +
                  self
         
     | 
| 
      
 957 
     | 
    
         
            +
                end
         
     | 
| 
      
 958 
     | 
    
         
            +
             
     | 
| 
       879 
959 
     | 
    
         
             
                # Reverse the existing order clause on the relation.
         
     | 
| 
       880 
960 
     | 
    
         
             
                #
         
     | 
| 
       881 
961 
     | 
    
         
             
                #   User.order('name ASC').reverse_order # generated SQL has 'ORDER BY name DESC'
         
     | 
| 
         @@ -895,26 +975,52 @@ module ActiveRecord 
     | 
|
| 
       895 
975 
     | 
    
         
             
                  self
         
     | 
| 
       896 
976 
     | 
    
         
             
                end
         
     | 
| 
       897 
977 
     | 
    
         | 
| 
      
 978 
     | 
    
         
            +
                def skip_preloading! # :nodoc:
         
     | 
| 
      
 979 
     | 
    
         
            +
                  self.skip_preloading_value = true
         
     | 
| 
      
 980 
     | 
    
         
            +
                  self
         
     | 
| 
      
 981 
     | 
    
         
            +
                end
         
     | 
| 
      
 982 
     | 
    
         
            +
             
     | 
| 
      
 983 
     | 
    
         
            +
                # Adds an SQL comment to queries generated from this relation. For example:
         
     | 
| 
      
 984 
     | 
    
         
            +
                #
         
     | 
| 
      
 985 
     | 
    
         
            +
                #   User.annotate("selecting user names").select(:name)
         
     | 
| 
      
 986 
     | 
    
         
            +
                #   # SELECT "users"."name" FROM "users" /* selecting user names */
         
     | 
| 
      
 987 
     | 
    
         
            +
                #
         
     | 
| 
      
 988 
     | 
    
         
            +
                #   User.annotate("selecting", "user", "names").select(:name)
         
     | 
| 
      
 989 
     | 
    
         
            +
                #   # SELECT "users"."name" FROM "users" /* selecting */ /* user */ /* names */
         
     | 
| 
      
 990 
     | 
    
         
            +
                #
         
     | 
| 
      
 991 
     | 
    
         
            +
                # The SQL block comment delimiters, "/*" and "*/", will be added automatically.
         
     | 
| 
      
 992 
     | 
    
         
            +
                def annotate(*args)
         
     | 
| 
      
 993 
     | 
    
         
            +
                  check_if_method_has_arguments!(:annotate, args)
         
     | 
| 
      
 994 
     | 
    
         
            +
                  spawn.annotate!(*args)
         
     | 
| 
      
 995 
     | 
    
         
            +
                end
         
     | 
| 
      
 996 
     | 
    
         
            +
             
     | 
| 
      
 997 
     | 
    
         
            +
                # Like #annotate, but modifies relation in place.
         
     | 
| 
      
 998 
     | 
    
         
            +
                def annotate!(*args) # :nodoc:
         
     | 
| 
      
 999 
     | 
    
         
            +
                  self.annotate_values += args
         
     | 
| 
      
 1000 
     | 
    
         
            +
                  self
         
     | 
| 
      
 1001 
     | 
    
         
            +
                end
         
     | 
| 
      
 1002 
     | 
    
         
            +
             
     | 
| 
       898 
1003 
     | 
    
         
             
                # Returns the Arel object associated with the relation.
         
     | 
| 
       899 
1004 
     | 
    
         
             
                def arel(aliases = nil) # :nodoc:
         
     | 
| 
       900 
1005 
     | 
    
         
             
                  @arel ||= build_arel(aliases)
         
     | 
| 
       901 
1006 
     | 
    
         
             
                end
         
     | 
| 
       902 
1007 
     | 
    
         | 
| 
       903 
     | 
    
         
            -
                 
     | 
| 
       904 
     | 
    
         
            -
             
     | 
| 
       905 
     | 
    
         
            -
             
     | 
| 
      
 1008 
     | 
    
         
            +
                def construct_join_dependency(associations, join_type) # :nodoc:
         
     | 
| 
      
 1009 
     | 
    
         
            +
                  ActiveRecord::Associations::JoinDependency.new(
         
     | 
| 
      
 1010 
     | 
    
         
            +
                    klass, table, associations, join_type
         
     | 
| 
      
 1011 
     | 
    
         
            +
                  )
         
     | 
| 
       906 
1012 
     | 
    
         
             
                end
         
     | 
| 
       907 
1013 
     | 
    
         | 
| 
       908 
1014 
     | 
    
         
             
                protected
         
     | 
| 
      
 1015 
     | 
    
         
            +
                  def build_subquery(subquery_alias, select_value) # :nodoc:
         
     | 
| 
      
 1016 
     | 
    
         
            +
                    subquery = except(:optimizer_hints).arel.as(subquery_alias)
         
     | 
| 
       909 
1017 
     | 
    
         | 
| 
       910 
     | 
    
         
            -
             
     | 
| 
       911 
     | 
    
         
            -
             
     | 
| 
       912 
     | 
    
         
            -
                     
     | 
| 
       913 
     | 
    
         
            -
                    @values[name] = value
         
     | 
| 
      
 1018 
     | 
    
         
            +
                    Arel::SelectManager.new(subquery).project(select_value).tap do |arel|
         
     | 
| 
      
 1019 
     | 
    
         
            +
                      arel.optimizer_hints(*optimizer_hints_values) unless optimizer_hints_values.empty?
         
     | 
| 
      
 1020 
     | 
    
         
            +
                    end
         
     | 
| 
       914 
1021 
     | 
    
         
             
                  end
         
     | 
| 
       915 
1022 
     | 
    
         | 
| 
       916 
1023 
     | 
    
         
             
                private
         
     | 
| 
       917 
     | 
    
         
            -
             
     | 
| 
       918 
1024 
     | 
    
         
             
                  def assert_mutability!
         
     | 
| 
       919 
1025 
     | 
    
         
             
                    raise ImmutableRelation if @loaded
         
     | 
| 
       920 
1026 
     | 
    
         
             
                    raise ImmutableRelation if defined?(@arel) && @arel
         
     | 
| 
         @@ -923,14 +1029,17 @@ module ActiveRecord 
     | 
|
| 
       923 
1029 
     | 
    
         
             
                  def build_arel(aliases)
         
     | 
| 
       924 
1030 
     | 
    
         
             
                    arel = Arel::SelectManager.new(table)
         
     | 
| 
       925 
1031 
     | 
    
         | 
| 
       926 
     | 
    
         
            -
                     
     | 
| 
       927 
     | 
    
         
            -
             
     | 
| 
      
 1032 
     | 
    
         
            +
                    if !joins_values.empty?
         
     | 
| 
      
 1033 
     | 
    
         
            +
                      build_joins(arel, joins_values.flatten, aliases)
         
     | 
| 
      
 1034 
     | 
    
         
            +
                    elsif !left_outer_joins_values.empty?
         
     | 
| 
      
 1035 
     | 
    
         
            +
                      build_left_outer_joins(arel, left_outer_joins_values.flatten, aliases)
         
     | 
| 
      
 1036 
     | 
    
         
            +
                    end
         
     | 
| 
       928 
1037 
     | 
    
         | 
| 
       929 
1038 
     | 
    
         
             
                    arel.where(where_clause.ast) unless where_clause.empty?
         
     | 
| 
       930 
1039 
     | 
    
         
             
                    arel.having(having_clause.ast) unless having_clause.empty?
         
     | 
| 
       931 
1040 
     | 
    
         
             
                    if limit_value
         
     | 
| 
       932 
1041 
     | 
    
         
             
                      limit_attribute = ActiveModel::Attribute.with_cast_value(
         
     | 
| 
       933 
     | 
    
         
            -
                        "LIMIT" 
     | 
| 
      
 1042 
     | 
    
         
            +
                        "LIMIT",
         
     | 
| 
       934 
1043 
     | 
    
         
             
                        connection.sanitize_limit(limit_value),
         
     | 
| 
       935 
1044 
     | 
    
         
             
                        Type.default_value,
         
     | 
| 
       936 
1045 
     | 
    
         
             
                      )
         
     | 
| 
         @@ -938,7 +1047,7 @@ module ActiveRecord 
     | 
|
| 
       938 
1047 
     | 
    
         
             
                    end
         
     | 
| 
       939 
1048 
     | 
    
         
             
                    if offset_value
         
     | 
| 
       940 
1049 
     | 
    
         
             
                      offset_attribute = ActiveModel::Attribute.with_cast_value(
         
     | 
| 
       941 
     | 
    
         
            -
                        "OFFSET" 
     | 
| 
      
 1050 
     | 
    
         
            +
                        "OFFSET",
         
     | 
| 
       942 
1051 
     | 
    
         
             
                        offset_value.to_i,
         
     | 
| 
       943 
1052 
     | 
    
         
             
                        Type.default_value,
         
     | 
| 
       944 
1053 
     | 
    
         
             
                      )
         
     | 
| 
         @@ -950,9 +1059,11 @@ module ActiveRecord 
     | 
|
| 
       950 
1059 
     | 
    
         | 
| 
       951 
1060 
     | 
    
         
             
                    build_select(arel)
         
     | 
| 
       952 
1061 
     | 
    
         | 
| 
      
 1062 
     | 
    
         
            +
                    arel.optimizer_hints(*optimizer_hints_values) unless optimizer_hints_values.empty?
         
     | 
| 
       953 
1063 
     | 
    
         
             
                    arel.distinct(distinct_value)
         
     | 
| 
       954 
1064 
     | 
    
         
             
                    arel.from(build_from) unless from_clause.empty?
         
     | 
| 
       955 
1065 
     | 
    
         
             
                    arel.lock(lock_value) if lock_value
         
     | 
| 
      
 1066 
     | 
    
         
            +
                    arel.comment(*annotate_values) unless annotate_values.empty?
         
     | 
| 
       956 
1067 
     | 
    
         | 
| 
       957 
1068 
     | 
    
         
             
                    arel
         
     | 
| 
       958 
1069 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -972,32 +1083,56 @@ module ActiveRecord 
     | 
|
| 
       972 
1083 
     | 
    
         
             
                    end
         
     | 
| 
       973 
1084 
     | 
    
         
             
                  end
         
     | 
| 
       974 
1085 
     | 
    
         | 
| 
       975 
     | 
    
         
            -
                  def  
     | 
| 
       976 
     | 
    
         
            -
                     
     | 
| 
       977 
     | 
    
         
            -
                      case  
     | 
| 
      
 1086 
     | 
    
         
            +
                  def valid_association_list(associations)
         
     | 
| 
      
 1087 
     | 
    
         
            +
                    associations.each do |association|
         
     | 
| 
      
 1088 
     | 
    
         
            +
                      case association
         
     | 
| 
       978 
1089 
     | 
    
         
             
                      when Hash, Symbol, Array
         
     | 
| 
       979 
     | 
    
         
            -
                         
     | 
| 
       980 
     | 
    
         
            -
                      when ActiveRecord::Associations::JoinDependency
         
     | 
| 
       981 
     | 
    
         
            -
                        :stashed_join
         
     | 
| 
      
 1090 
     | 
    
         
            +
                        # valid
         
     | 
| 
       982 
1091 
     | 
    
         
             
                      else
         
     | 
| 
       983 
1092 
     | 
    
         
             
                        raise ArgumentError, "only Hash, Symbol and Array are allowed"
         
     | 
| 
       984 
1093 
     | 
    
         
             
                      end
         
     | 
| 
       985 
1094 
     | 
    
         
             
                    end
         
     | 
| 
      
 1095 
     | 
    
         
            +
                  end
         
     | 
| 
       986 
1096 
     | 
    
         | 
| 
      
 1097 
     | 
    
         
            +
                  def build_left_outer_joins(manager, outer_joins, aliases)
         
     | 
| 
      
 1098 
     | 
    
         
            +
                    buckets = Hash.new { |h, k| h[k] = [] }
         
     | 
| 
      
 1099 
     | 
    
         
            +
                    buckets[:association_join] = valid_association_list(outer_joins)
         
     | 
| 
       987 
1100 
     | 
    
         
             
                    build_join_query(manager, buckets, Arel::Nodes::OuterJoin, aliases)
         
     | 
| 
       988 
1101 
     | 
    
         
             
                  end
         
     | 
| 
       989 
1102 
     | 
    
         | 
| 
       990 
1103 
     | 
    
         
             
                  def build_joins(manager, joins, aliases)
         
     | 
| 
       991 
     | 
    
         
            -
                    buckets =  
     | 
| 
      
 1104 
     | 
    
         
            +
                    buckets = Hash.new { |h, k| h[k] = [] }
         
     | 
| 
      
 1105 
     | 
    
         
            +
             
     | 
| 
      
 1106 
     | 
    
         
            +
                    unless left_outer_joins_values.empty?
         
     | 
| 
      
 1107 
     | 
    
         
            +
                      left_joins = valid_association_list(left_outer_joins_values.flatten)
         
     | 
| 
      
 1108 
     | 
    
         
            +
                      buckets[:stashed_join] << construct_join_dependency(left_joins, Arel::Nodes::OuterJoin)
         
     | 
| 
      
 1109 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1110 
     | 
    
         
            +
             
     | 
| 
      
 1111 
     | 
    
         
            +
                    joins.map! do |join|
         
     | 
| 
      
 1112 
     | 
    
         
            +
                      if join.is_a?(String)
         
     | 
| 
      
 1113 
     | 
    
         
            +
                        table.create_string_join(Arel.sql(join.strip)) unless join.blank?
         
     | 
| 
      
 1114 
     | 
    
         
            +
                      else
         
     | 
| 
      
 1115 
     | 
    
         
            +
                        join
         
     | 
| 
      
 1116 
     | 
    
         
            +
                      end
         
     | 
| 
      
 1117 
     | 
    
         
            +
                    end.delete_if(&:blank?).uniq!
         
     | 
| 
      
 1118 
     | 
    
         
            +
             
     | 
| 
      
 1119 
     | 
    
         
            +
                    while joins.first.is_a?(Arel::Nodes::Join)
         
     | 
| 
      
 1120 
     | 
    
         
            +
                      join_node = joins.shift
         
     | 
| 
      
 1121 
     | 
    
         
            +
                      if join_node.is_a?(Arel::Nodes::StringJoin) && !buckets[:stashed_join].empty?
         
     | 
| 
      
 1122 
     | 
    
         
            +
                        buckets[:join_node] << join_node
         
     | 
| 
      
 1123 
     | 
    
         
            +
                      else
         
     | 
| 
      
 1124 
     | 
    
         
            +
                        buckets[:leading_join] << join_node
         
     | 
| 
      
 1125 
     | 
    
         
            +
                      end
         
     | 
| 
      
 1126 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1127 
     | 
    
         
            +
             
     | 
| 
      
 1128 
     | 
    
         
            +
                    joins.each do |join|
         
     | 
| 
       992 
1129 
     | 
    
         
             
                      case join
         
     | 
| 
       993 
     | 
    
         
            -
                      when String
         
     | 
| 
       994 
     | 
    
         
            -
                        :string_join
         
     | 
| 
       995 
1130 
     | 
    
         
             
                      when Hash, Symbol, Array
         
     | 
| 
       996 
     | 
    
         
            -
                        :association_join
         
     | 
| 
      
 1131 
     | 
    
         
            +
                        buckets[:association_join] << join
         
     | 
| 
       997 
1132 
     | 
    
         
             
                      when ActiveRecord::Associations::JoinDependency
         
     | 
| 
       998 
     | 
    
         
            -
                        :stashed_join
         
     | 
| 
      
 1133 
     | 
    
         
            +
                        buckets[:stashed_join] << join
         
     | 
| 
       999 
1134 
     | 
    
         
             
                      when Arel::Nodes::Join
         
     | 
| 
       1000 
     | 
    
         
            -
                        :join_node
         
     | 
| 
      
 1135 
     | 
    
         
            +
                        buckets[:join_node] << join
         
     | 
| 
       1001 
1136 
     | 
    
         
             
                      else
         
     | 
| 
       1002 
1137 
     | 
    
         
             
                        raise "unknown class: %s" % join.class.name
         
     | 
| 
       1003 
1138 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -1007,33 +1142,21 @@ module ActiveRecord 
     | 
|
| 
       1007 
1142 
     | 
    
         
             
                  end
         
     | 
| 
       1008 
1143 
     | 
    
         | 
| 
       1009 
1144 
     | 
    
         
             
                  def build_join_query(manager, buckets, join_type, aliases)
         
     | 
| 
       1010 
     | 
    
         
            -
                    buckets.default = []
         
     | 
| 
       1011 
     | 
    
         
            -
             
     | 
| 
       1012 
1145 
     | 
    
         
             
                    association_joins = buckets[:association_join]
         
     | 
| 
       1013 
1146 
     | 
    
         
             
                    stashed_joins     = buckets[:stashed_join]
         
     | 
| 
       1014 
     | 
    
         
            -
                     
     | 
| 
       1015 
     | 
    
         
            -
                     
     | 
| 
       1016 
     | 
    
         
            -
             
     | 
| 
       1017 
     | 
    
         
            -
                    join_list = join_nodes + convert_join_strings_to_ast(string_joins)
         
     | 
| 
       1018 
     | 
    
         
            -
                    alias_tracker = alias_tracker(join_list, aliases)
         
     | 
| 
       1019 
     | 
    
         
            -
             
     | 
| 
       1020 
     | 
    
         
            -
                    join_dependency = ActiveRecord::Associations::JoinDependency.new(
         
     | 
| 
       1021 
     | 
    
         
            -
                      klass, table, association_joins
         
     | 
| 
       1022 
     | 
    
         
            -
                    )
         
     | 
| 
       1023 
     | 
    
         
            -
             
     | 
| 
       1024 
     | 
    
         
            -
                    joins = join_dependency.join_constraints(stashed_joins, join_type, alias_tracker)
         
     | 
| 
       1025 
     | 
    
         
            -
                    joins.each { |join| manager.from(join) }
         
     | 
| 
      
 1147 
     | 
    
         
            +
                    leading_joins     = buckets[:leading_join]
         
     | 
| 
      
 1148 
     | 
    
         
            +
                    join_nodes        = buckets[:join_node]
         
     | 
| 
       1026 
1149 
     | 
    
         | 
| 
       1027 
     | 
    
         
            -
                    manager.join_sources 
     | 
| 
      
 1150 
     | 
    
         
            +
                    join_sources = manager.join_sources
         
     | 
| 
      
 1151 
     | 
    
         
            +
                    join_sources.concat(leading_joins) unless leading_joins.empty?
         
     | 
| 
       1028 
1152 
     | 
    
         | 
| 
       1029 
     | 
    
         
            -
                     
     | 
| 
       1030 
     | 
    
         
            -
             
     | 
| 
      
 1153 
     | 
    
         
            +
                    unless association_joins.empty? && stashed_joins.empty?
         
     | 
| 
      
 1154 
     | 
    
         
            +
                      alias_tracker = alias_tracker(leading_joins + join_nodes, aliases)
         
     | 
| 
      
 1155 
     | 
    
         
            +
                      join_dependency = construct_join_dependency(association_joins, join_type)
         
     | 
| 
      
 1156 
     | 
    
         
            +
                      join_sources.concat(join_dependency.join_constraints(stashed_joins, alias_tracker))
         
     | 
| 
      
 1157 
     | 
    
         
            +
                    end
         
     | 
| 
       1031 
1158 
     | 
    
         | 
| 
       1032 
     | 
    
         
            -
             
     | 
| 
       1033 
     | 
    
         
            -
                    joins
         
     | 
| 
       1034 
     | 
    
         
            -
                      .flatten
         
     | 
| 
       1035 
     | 
    
         
            -
                      .reject(&:blank?)
         
     | 
| 
       1036 
     | 
    
         
            -
                      .map { |join| table.create_string_join(Arel.sql(join)) }
         
     | 
| 
      
 1159 
     | 
    
         
            +
                    join_sources.concat(join_nodes) unless join_nodes.empty?
         
     | 
| 
       1037 
1160 
     | 
    
         
             
                  end
         
     | 
| 
       1038 
1161 
     | 
    
         | 
| 
       1039 
1162 
     | 
    
         
             
                  def build_select(arel)
         
     | 
| 
         @@ -1064,7 +1187,7 @@ module ActiveRecord 
     | 
|
| 
       1064 
1187 
     | 
    
         
             
                  end
         
     | 
| 
       1065 
1188 
     | 
    
         | 
| 
       1066 
1189 
     | 
    
         
             
                  def arel_column(field)
         
     | 
| 
       1067 
     | 
    
         
            -
                    field = klass. 
     | 
| 
      
 1190 
     | 
    
         
            +
                    field = klass.attribute_aliases[field] || field
         
     | 
| 
       1068 
1191 
     | 
    
         
             
                    from = from_clause.name || from_clause.value
         
     | 
| 
       1069 
1192 
     | 
    
         | 
| 
       1070 
1193 
     | 
    
         
             
                    if klass.columns_hash.key?(field) && (!from || table_name_matches?(from))
         
     | 
| 
         @@ -1093,7 +1216,7 @@ module ActiveRecord 
     | 
|
| 
       1093 
1216 
     | 
    
         
             
                        o.reverse
         
     | 
| 
       1094 
1217 
     | 
    
         
             
                      when String
         
     | 
| 
       1095 
1218 
     | 
    
         
             
                        if does_not_support_reverse?(o)
         
     | 
| 
       1096 
     | 
    
         
            -
                          raise IrreversibleOrderError, "Order #{o.inspect}  
     | 
| 
      
 1219 
     | 
    
         
            +
                          raise IrreversibleOrderError, "Order #{o.inspect} cannot be reversed automatically"
         
     | 
| 
       1097 
1220 
     | 
    
         
             
                        end
         
     | 
| 
       1098 
1221 
     | 
    
         
             
                        o.split(",").map! do |s|
         
     | 
| 
       1099 
1222 
     | 
    
         
             
                          s.strip!
         
     | 
| 
         @@ -1113,7 +1236,7 @@ module ActiveRecord 
     | 
|
| 
       1113 
1236 
     | 
    
         
             
                    # Uses SQL function with multiple arguments.
         
     | 
| 
       1114 
1237 
     | 
    
         
             
                    (order.include?(",") && order.split(",").find { |section| section.count("(") != section.count(")") }) ||
         
     | 
| 
       1115 
1238 
     | 
    
         
             
                      # Uses "nulls first" like construction.
         
     | 
| 
       1116 
     | 
    
         
            -
                       
     | 
| 
      
 1239 
     | 
    
         
            +
                      /\bnulls\s+(?:first|last)\b/i.match?(order)
         
     | 
| 
       1117 
1240 
     | 
    
         
             
                  end
         
     | 
| 
       1118 
1241 
     | 
    
         | 
| 
       1119 
1242 
     | 
    
         
             
                  def build_order(arel)
         
     | 
| 
         @@ -1139,14 +1262,15 @@ module ActiveRecord 
     | 
|
| 
       1139 
1262 
     | 
    
         
             
                  end
         
     | 
| 
       1140 
1263 
     | 
    
         | 
| 
       1141 
1264 
     | 
    
         
             
                  def preprocess_order_args(order_args)
         
     | 
| 
      
 1265 
     | 
    
         
            +
                    order_args.reject!(&:blank?)
         
     | 
| 
       1142 
1266 
     | 
    
         
             
                    order_args.map! do |arg|
         
     | 
| 
       1143 
1267 
     | 
    
         
             
                      klass.sanitize_sql_for_order(arg)
         
     | 
| 
       1144 
1268 
     | 
    
         
             
                    end
         
     | 
| 
       1145 
1269 
     | 
    
         
             
                    order_args.flatten!
         
     | 
| 
       1146 
1270 
     | 
    
         | 
| 
       1147 
     | 
    
         
            -
                    @klass. 
     | 
| 
      
 1271 
     | 
    
         
            +
                    @klass.disallow_raw_sql!(
         
     | 
| 
       1148 
1272 
     | 
    
         
             
                      order_args.flat_map { |a| a.is_a?(Hash) ? a.keys : a },
         
     | 
| 
       1149 
     | 
    
         
            -
                       
     | 
| 
      
 1273 
     | 
    
         
            +
                      permit: connection.column_name_with_order_matcher
         
     | 
| 
       1150 
1274 
     | 
    
         
             
                    )
         
     | 
| 
       1151 
1275 
     | 
    
         | 
| 
       1152 
1276 
     | 
    
         
             
                    validate_order_args(order_args)
         
     | 
| 
         @@ -1209,8 +1333,10 @@ module ActiveRecord 
     | 
|
| 
       1209 
1333 
     | 
    
         | 
| 
       1210 
1334 
     | 
    
         
             
                  STRUCTURAL_OR_METHODS = Relation::VALUE_METHODS - [:extending, :where, :having, :unscope, :references]
         
     | 
| 
       1211 
1335 
     | 
    
         
             
                  def structurally_incompatible_values_for_or(other)
         
     | 
| 
      
 1336 
     | 
    
         
            +
                    values = other.values
         
     | 
| 
       1212 
1337 
     | 
    
         
             
                    STRUCTURAL_OR_METHODS.reject do |method|
         
     | 
| 
       1213 
     | 
    
         
            -
                       
     | 
| 
      
 1338 
     | 
    
         
            +
                      default = DEFAULT_VALUES[method]
         
     | 
| 
      
 1339 
     | 
    
         
            +
                      @values.fetch(method, default) == values.fetch(method, default)
         
     | 
| 
       1214 
1340 
     | 
    
         
             
                    end
         
     | 
| 
       1215 
1341 
     | 
    
         
             
                  end
         
     | 
| 
       1216 
1342 
     | 
    
         |