activerecord 6.0.5.1 → 6.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (242) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +764 -916
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +3 -3
  5. data/lib/active_record/aggregations.rb +1 -1
  6. data/lib/active_record/association_relation.rb +22 -14
  7. data/lib/active_record/associations/alias_tracker.rb +19 -15
  8. data/lib/active_record/associations/association.rb +39 -27
  9. data/lib/active_record/associations/association_scope.rb +11 -15
  10. data/lib/active_record/associations/belongs_to_association.rb +15 -5
  11. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
  12. data/lib/active_record/associations/builder/association.rb +9 -3
  13. data/lib/active_record/associations/builder/belongs_to.rb +10 -7
  14. data/lib/active_record/associations/builder/collection_association.rb +5 -4
  15. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +0 -1
  16. data/lib/active_record/associations/builder/has_many.rb +6 -2
  17. data/lib/active_record/associations/builder/has_one.rb +11 -14
  18. data/lib/active_record/associations/builder/singular_association.rb +1 -1
  19. data/lib/active_record/associations/collection_association.rb +19 -13
  20. data/lib/active_record/associations/collection_proxy.rb +12 -5
  21. data/lib/active_record/associations/foreign_association.rb +13 -0
  22. data/lib/active_record/associations/has_many_association.rb +24 -2
  23. data/lib/active_record/associations/has_many_through_association.rb +10 -4
  24. data/lib/active_record/associations/has_one_association.rb +15 -1
  25. data/lib/active_record/associations/join_dependency/join_association.rb +29 -14
  26. data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
  27. data/lib/active_record/associations/join_dependency.rb +63 -49
  28. data/lib/active_record/associations/preloader/association.rb +13 -5
  29. data/lib/active_record/associations/preloader/through_association.rb +1 -1
  30. data/lib/active_record/associations/preloader.rb +5 -3
  31. data/lib/active_record/associations/singular_association.rb +1 -1
  32. data/lib/active_record/associations.rb +114 -11
  33. data/lib/active_record/attribute_assignment.rb +10 -8
  34. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -9
  35. data/lib/active_record/attribute_methods/dirty.rb +1 -11
  36. data/lib/active_record/attribute_methods/primary_key.rb +6 -2
  37. data/lib/active_record/attribute_methods/query.rb +3 -6
  38. data/lib/active_record/attribute_methods/read.rb +8 -11
  39. data/lib/active_record/attribute_methods/serialization.rb +4 -4
  40. data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -13
  41. data/lib/active_record/attribute_methods/write.rb +12 -20
  42. data/lib/active_record/attribute_methods.rb +52 -48
  43. data/lib/active_record/attributes.rb +27 -7
  44. data/lib/active_record/autosave_association.rb +47 -30
  45. data/lib/active_record/base.rb +2 -14
  46. data/lib/active_record/callbacks.rb +32 -22
  47. data/lib/active_record/coders/yaml_column.rb +2 -14
  48. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +180 -134
  49. data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
  50. data/lib/active_record/connection_adapters/abstract/database_statements.rb +65 -22
  51. data/lib/active_record/connection_adapters/abstract/query_cache.rb +2 -7
  52. data/lib/active_record/connection_adapters/abstract/quoting.rb +34 -34
  53. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  54. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -116
  55. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +110 -30
  56. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
  57. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +224 -85
  58. data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -24
  59. data/lib/active_record/connection_adapters/abstract_adapter.rb +31 -70
  60. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +123 -87
  61. data/lib/active_record/connection_adapters/column.rb +15 -1
  62. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  63. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
  64. data/lib/active_record/connection_adapters/mysql/database_statements.rb +22 -24
  65. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -1
  66. data/lib/active_record/connection_adapters/mysql/quoting.rb +1 -1
  67. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +33 -6
  68. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
  69. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
  70. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +3 -3
  71. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
  72. data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -12
  73. data/lib/active_record/connection_adapters/pool_config.rb +63 -0
  74. data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
  75. data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
  76. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +12 -53
  77. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
  78. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
  79. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -10
  80. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  81. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -2
  82. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  83. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  84. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -2
  85. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -1
  86. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  87. data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
  88. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
  89. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +5 -1
  90. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +61 -29
  91. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
  92. data/lib/active_record/connection_adapters/postgresql_adapter.rb +72 -55
  93. data/lib/active_record/connection_adapters/schema_cache.rb +98 -15
  94. data/lib/active_record/connection_adapters/sql_type_metadata.rb +10 -0
  95. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +30 -5
  96. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -1
  97. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  98. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +36 -3
  99. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +48 -50
  100. data/lib/active_record/connection_adapters.rb +50 -0
  101. data/lib/active_record/connection_handling.rb +210 -71
  102. data/lib/active_record/core.rb +214 -58
  103. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  104. data/lib/active_record/database_configurations/database_config.rb +52 -9
  105. data/lib/active_record/database_configurations/hash_config.rb +54 -8
  106. data/lib/active_record/database_configurations/url_config.rb +15 -40
  107. data/lib/active_record/database_configurations.rb +124 -85
  108. data/lib/active_record/delegated_type.rb +209 -0
  109. data/lib/active_record/destroy_association_async_job.rb +36 -0
  110. data/lib/active_record/enum.rb +33 -23
  111. data/lib/active_record/errors.rb +47 -12
  112. data/lib/active_record/explain.rb +9 -4
  113. data/lib/active_record/explain_subscriber.rb +1 -1
  114. data/lib/active_record/fixture_set/file.rb +10 -17
  115. data/lib/active_record/fixture_set/model_metadata.rb +1 -2
  116. data/lib/active_record/fixture_set/render_context.rb +1 -1
  117. data/lib/active_record/fixture_set/table_row.rb +2 -2
  118. data/lib/active_record/fixtures.rb +54 -8
  119. data/lib/active_record/gem_version.rb +3 -3
  120. data/lib/active_record/inheritance.rb +40 -18
  121. data/lib/active_record/insert_all.rb +32 -5
  122. data/lib/active_record/integration.rb +3 -5
  123. data/lib/active_record/internal_metadata.rb +15 -4
  124. data/lib/active_record/legacy_yaml_adapter.rb +7 -3
  125. data/lib/active_record/locking/optimistic.rb +13 -16
  126. data/lib/active_record/locking/pessimistic.rb +6 -2
  127. data/lib/active_record/log_subscriber.rb +26 -8
  128. data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
  129. data/lib/active_record/middleware/database_selector/resolver.rb +5 -0
  130. data/lib/active_record/middleware/database_selector.rb +4 -1
  131. data/lib/active_record/migration/command_recorder.rb +47 -27
  132. data/lib/active_record/migration/compatibility.rb +67 -17
  133. data/lib/active_record/migration.rb +113 -83
  134. data/lib/active_record/model_schema.rb +88 -42
  135. data/lib/active_record/nested_attributes.rb +2 -3
  136. data/lib/active_record/no_touching.rb +1 -1
  137. data/lib/active_record/persistence.rb +50 -45
  138. data/lib/active_record/query_cache.rb +15 -5
  139. data/lib/active_record/querying.rb +11 -6
  140. data/lib/active_record/railtie.rb +61 -59
  141. data/lib/active_record/railties/databases.rake +253 -98
  142. data/lib/active_record/readonly_attributes.rb +4 -0
  143. data/lib/active_record/reflection.rb +59 -44
  144. data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
  145. data/lib/active_record/relation/batches.rb +38 -31
  146. data/lib/active_record/relation/calculations.rb +100 -43
  147. data/lib/active_record/relation/finder_methods.rb +44 -14
  148. data/lib/active_record/relation/from_clause.rb +1 -1
  149. data/lib/active_record/relation/merger.rb +20 -23
  150. data/lib/active_record/relation/predicate_builder/array_handler.rb +8 -9
  151. data/lib/active_record/relation/predicate_builder/association_query_value.rb +2 -2
  152. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +3 -3
  153. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  154. data/lib/active_record/relation/predicate_builder.rb +57 -33
  155. data/lib/active_record/relation/query_methods.rb +319 -196
  156. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  157. data/lib/active_record/relation/spawn_methods.rb +6 -5
  158. data/lib/active_record/relation/where_clause.rb +104 -57
  159. data/lib/active_record/relation.rb +90 -64
  160. data/lib/active_record/result.rb +41 -33
  161. data/lib/active_record/runtime_registry.rb +2 -2
  162. data/lib/active_record/sanitization.rb +6 -17
  163. data/lib/active_record/schema_dumper.rb +34 -4
  164. data/lib/active_record/schema_migration.rb +0 -4
  165. data/lib/active_record/scoping/named.rb +1 -17
  166. data/lib/active_record/secure_token.rb +16 -8
  167. data/lib/active_record/serialization.rb +5 -3
  168. data/lib/active_record/signed_id.rb +116 -0
  169. data/lib/active_record/statement_cache.rb +20 -4
  170. data/lib/active_record/store.rb +2 -2
  171. data/lib/active_record/suppressor.rb +2 -2
  172. data/lib/active_record/table_metadata.rb +36 -52
  173. data/lib/active_record/tasks/database_tasks.rb +139 -113
  174. data/lib/active_record/tasks/mysql_database_tasks.rb +34 -35
  175. data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -26
  176. data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -9
  177. data/lib/active_record/test_databases.rb +5 -4
  178. data/lib/active_record/test_fixtures.rb +36 -33
  179. data/lib/active_record/timestamp.rb +4 -6
  180. data/lib/active_record/touch_later.rb +21 -21
  181. data/lib/active_record/transactions.rb +15 -64
  182. data/lib/active_record/type/serialized.rb +6 -2
  183. data/lib/active_record/type.rb +8 -1
  184. data/lib/active_record/type_caster/connection.rb +0 -1
  185. data/lib/active_record/type_caster/map.rb +8 -5
  186. data/lib/active_record/validations/associated.rb +1 -1
  187. data/lib/active_record/validations/numericality.rb +35 -0
  188. data/lib/active_record/validations/uniqueness.rb +24 -4
  189. data/lib/active_record/validations.rb +1 -0
  190. data/lib/active_record.rb +7 -14
  191. data/lib/arel/attributes/attribute.rb +4 -0
  192. data/lib/arel/collectors/bind.rb +5 -0
  193. data/lib/arel/collectors/composite.rb +8 -0
  194. data/lib/arel/collectors/sql_string.rb +7 -0
  195. data/lib/arel/collectors/substitute_binds.rb +7 -0
  196. data/lib/arel/nodes/binary.rb +82 -8
  197. data/lib/arel/nodes/bind_param.rb +8 -0
  198. data/lib/arel/nodes/casted.rb +21 -9
  199. data/lib/arel/nodes/equality.rb +6 -9
  200. data/lib/arel/nodes/grouping.rb +3 -0
  201. data/lib/arel/nodes/homogeneous_in.rb +72 -0
  202. data/lib/arel/nodes/in.rb +8 -1
  203. data/lib/arel/nodes/infix_operation.rb +13 -1
  204. data/lib/arel/nodes/join_source.rb +1 -1
  205. data/lib/arel/nodes/node.rb +7 -6
  206. data/lib/arel/nodes/ordering.rb +27 -0
  207. data/lib/arel/nodes/sql_literal.rb +3 -0
  208. data/lib/arel/nodes/table_alias.rb +7 -3
  209. data/lib/arel/nodes/unary.rb +0 -1
  210. data/lib/arel/nodes.rb +3 -1
  211. data/lib/arel/predications.rb +12 -18
  212. data/lib/arel/select_manager.rb +1 -2
  213. data/lib/arel/table.rb +13 -5
  214. data/lib/arel/visitors/dot.rb +14 -2
  215. data/lib/arel/visitors/mysql.rb +11 -1
  216. data/lib/arel/visitors/postgresql.rb +15 -4
  217. data/lib/arel/visitors/to_sql.rb +89 -78
  218. data/lib/arel/visitors.rb +0 -7
  219. data/lib/arel.rb +5 -13
  220. data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
  221. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +2 -0
  222. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +3 -3
  223. data/lib/rails/generators/active_record/migration.rb +6 -1
  224. data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
  225. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  226. metadata +30 -32
  227. data/lib/active_record/advisory_lock_base.rb +0 -18
  228. data/lib/active_record/attribute_decorators.rb +0 -88
  229. data/lib/active_record/connection_adapters/connection_specification.rb +0 -296
  230. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
  231. data/lib/active_record/define_callbacks.rb +0 -22
  232. data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
  233. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
  234. data/lib/active_record/relation/where_clause_factory.rb +0 -33
  235. data/lib/arel/attributes.rb +0 -22
  236. data/lib/arel/visitors/depth_first.rb +0 -203
  237. data/lib/arel/visitors/ibm_db.rb +0 -34
  238. data/lib/arel/visitors/informix.rb +0 -62
  239. data/lib/arel/visitors/mssql.rb +0 -156
  240. data/lib/arel/visitors/oracle.rb +0 -158
  241. data/lib/arel/visitors/oracle12.rb +0 -65
  242. data/lib/arel/visitors/where_sql.rb +0 -22
@@ -3,30 +3,42 @@
3
3
  module Arel # :nodoc: all
4
4
  module Nodes
5
5
  class Casted < Arel::Nodes::NodeExpression # :nodoc:
6
- attr_reader :val, :attribute
7
- def initialize(val, attribute)
8
- @val = val
6
+ attr_reader :value, :attribute
7
+ alias :value_before_type_cast :value
8
+
9
+ def initialize(value, attribute)
10
+ @value = value
9
11
  @attribute = attribute
10
12
  super()
11
13
  end
12
14
 
13
- def nil?; @val.nil?; end
15
+ def nil?; value.nil?; end
16
+
17
+ def value_for_database
18
+ if attribute.able_to_type_cast?
19
+ attribute.type_cast_for_database(value)
20
+ else
21
+ value
22
+ end
23
+ end
14
24
 
15
25
  def hash
16
- [self.class, val, attribute].hash
26
+ [self.class, value, attribute].hash
17
27
  end
18
28
 
19
29
  def eql?(other)
20
30
  self.class == other.class &&
21
- self.val == other.val &&
22
- self.attribute == other.attribute
31
+ self.value == other.value &&
32
+ self.attribute == other.attribute
23
33
  end
24
34
  alias :== :eql?
25
35
  end
26
36
 
27
37
  class Quoted < Arel::Nodes::Unary # :nodoc:
28
- alias :val :value
29
- def nil?; val.nil?; end
38
+ alias :value_for_database :value
39
+ alias :value_before_type_cast :value
40
+
41
+ def nil?; value.nil?; end
30
42
 
31
43
  def infinite?
32
44
  value.respond_to?(:infinite?) && value.infinite?
@@ -3,16 +3,13 @@
3
3
  module Arel # :nodoc: all
4
4
  module Nodes
5
5
  class Equality < Arel::Nodes::Binary
6
- def operator; :== end
7
- alias :operand1 :left
8
- alias :operand2 :right
9
- end
6
+ include FetchAttribute
7
+
8
+ def equality?; true; end
10
9
 
11
- %w{
12
- IsDistinctFrom
13
- IsNotDistinctFrom
14
- }.each do |name|
15
- const_set name, Class.new(Equality)
10
+ def invert
11
+ Arel::Nodes::NotEqual.new(left, right)
12
+ end
16
13
  end
17
14
  end
18
15
  end
@@ -3,6 +3,9 @@
3
3
  module Arel # :nodoc: all
4
4
  module Nodes
5
5
  class Grouping < Unary
6
+ def fetch_attribute(&block)
7
+ expr.fetch_attribute(&block)
8
+ end
6
9
  end
7
10
  end
8
11
  end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Nodes
5
+ class HomogeneousIn < Node
6
+ attr_reader :attribute, :values, :type
7
+
8
+ def initialize(values, attribute, type)
9
+ @values = values
10
+ @attribute = attribute
11
+ @type = type
12
+ end
13
+
14
+ def hash
15
+ ivars.hash
16
+ end
17
+
18
+ def eql?(other)
19
+ super || (self.class == other.class && self.ivars == other.ivars)
20
+ end
21
+ alias :== :eql?
22
+
23
+ def equality?
24
+ type == :in
25
+ end
26
+
27
+ def invert
28
+ Arel::Nodes::HomogeneousIn.new(values, attribute, type == :in ? :notin : :in)
29
+ end
30
+
31
+ def left
32
+ attribute
33
+ end
34
+
35
+ def right
36
+ attribute.quoted_array(values)
37
+ end
38
+
39
+ def table_name
40
+ attribute.relation.table_alias || attribute.relation.name
41
+ end
42
+
43
+ def column_name
44
+ attribute.name
45
+ end
46
+
47
+ def casted_values
48
+ type = attribute.type_caster
49
+
50
+ casted_values = values.map do |raw_value|
51
+ type.serialize(raw_value) if type.serializable?(raw_value)
52
+ end
53
+
54
+ casted_values.compact!
55
+ casted_values
56
+ end
57
+
58
+ def fetch_attribute(&block)
59
+ if attribute
60
+ yield attribute
61
+ else
62
+ expr.fetch_attribute(&block)
63
+ end
64
+ end
65
+
66
+ protected
67
+ def ivars
68
+ [@attribute, @values, @type]
69
+ end
70
+ end
71
+ end
72
+ end
data/lib/arel/nodes/in.rb CHANGED
@@ -2,7 +2,14 @@
2
2
 
3
3
  module Arel # :nodoc: all
4
4
  module Nodes
5
- class In < Equality
5
+ class In < Arel::Nodes::Binary
6
+ include FetchAttribute
7
+
8
+ def equality?; true; end
9
+
10
+ def invert
11
+ Arel::Nodes::NotIn.new(left, right)
12
+ end
6
13
  end
7
14
  end
8
15
  end
@@ -43,7 +43,19 @@ module Arel # :nodoc: all
43
43
 
44
44
  class Concat < InfixOperation
45
45
  def initialize(left, right)
46
- super("||", left, right)
46
+ super(:"||", left, right)
47
+ end
48
+ end
49
+
50
+ class Contains < InfixOperation
51
+ def initialize(left, right)
52
+ super(:"@>", left, right)
53
+ end
54
+ end
55
+
56
+ class Overlaps < InfixOperation
57
+ def initialize(left, right)
58
+ super(:"&&", left, right)
47
59
  end
48
60
  end
49
61
 
@@ -5,7 +5,7 @@ module Arel # :nodoc: all
5
5
  ###
6
6
  # Class that represents a join source
7
7
  #
8
- # http://www.sqlite.org/syntaxdiagrams.html#join-source
8
+ # https://www.sqlite.org/syntaxdiagrams.html#join-source
9
9
 
10
10
  class JoinSource < Arel::Nodes::Binary
11
11
  def initialize(single_source, joinop = [])
@@ -6,7 +6,6 @@ module Arel # :nodoc: all
6
6
  # Abstract base class for all AST nodes
7
7
  class Node
8
8
  include Arel::FactoryMethods
9
- include Enumerable
10
9
 
11
10
  ###
12
11
  # Factory method to create a Nodes::Not node that has the recipient of
@@ -28,6 +27,10 @@ module Arel # :nodoc: all
28
27
  Nodes::And.new [self, right]
29
28
  end
30
29
 
30
+ def invert
31
+ Arel::Nodes::Not.new(self)
32
+ end
33
+
31
34
  # FIXME: this method should go away. I don't like people calling
32
35
  # to_sql on non-head nodes. This forces us to walk the AST until we
33
36
  # can find a node that has a "relation" member.
@@ -39,12 +42,10 @@ module Arel # :nodoc: all
39
42
  collector.value
40
43
  end
41
44
 
42
- # Iterate through AST, nodes will be yielded depth-first
43
- def each(&block)
44
- return enum_for(:each) unless block_given?
45
-
46
- ::Arel::Visitors::DepthFirst.new(block).accept self
45
+ def fetch_attribute
47
46
  end
47
+
48
+ def equality?; false; end
48
49
  end
49
50
  end
50
51
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Nodes
5
+ class Ordering < Unary
6
+ def nulls_first
7
+ NullsFirst.new(self)
8
+ end
9
+
10
+ def nulls_last
11
+ NullsLast.new(self)
12
+ end
13
+ end
14
+
15
+ class NullsFirst < Ordering
16
+ def reverse
17
+ NullsLast.new(expr.reverse)
18
+ end
19
+ end
20
+
21
+ class NullsLast < Ordering
22
+ def reverse
23
+ NullsFirst.new(expr.reverse)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -11,6 +11,9 @@ module Arel # :nodoc: all
11
11
  def encode_with(coder)
12
12
  coder.scalar = self.to_s
13
13
  end
14
+
15
+ def fetch_attribute
16
+ end
14
17
  end
15
18
  end
16
19
  end
@@ -8,15 +8,19 @@ module Arel # :nodoc: all
8
8
  alias :table_alias :name
9
9
 
10
10
  def [](name)
11
- Attribute.new(self, name)
11
+ relation.is_a?(Table) ? relation[name, self] : Attribute.new(self, name)
12
12
  end
13
13
 
14
14
  def table_name
15
15
  relation.respond_to?(:name) ? relation.name : name
16
16
  end
17
17
 
18
- def type_cast_for_database(*args)
19
- relation.type_cast_for_database(*args)
18
+ def type_cast_for_database(attr_name, value)
19
+ relation.type_cast_for_database(attr_name, value)
20
+ end
21
+
22
+ def type_for_attribute(name)
23
+ relation.type_for_attribute(name)
20
24
  end
21
25
 
22
26
  def able_to_type_cast?
@@ -36,7 +36,6 @@ module Arel # :nodoc: all
36
36
  Offset
37
37
  On
38
38
  OptimizerHints
39
- Ordering
40
39
  RollUp
41
40
  }.each do |name|
42
41
  const_set(name, Class.new(Unary))
data/lib/arel/nodes.rb CHANGED
@@ -18,6 +18,8 @@ require "arel/nodes/false"
18
18
  # unary
19
19
  require "arel/nodes/unary"
20
20
  require "arel/nodes/grouping"
21
+ require "arel/nodes/homogeneous_in"
22
+ require "arel/nodes/ordering"
21
23
  require "arel/nodes/ascending"
22
24
  require "arel/nodes/descending"
23
25
  require "arel/nodes/unqualified_column"
@@ -26,7 +28,7 @@ require "arel/nodes/with"
26
28
  # binary
27
29
  require "arel/nodes/binary"
28
30
  require "arel/nodes/equality"
29
- require "arel/nodes/in" # Why is this subclassed from equality?
31
+ require "arel/nodes/in"
30
32
  require "arel/nodes/join_source"
31
33
  require "arel/nodes/delete_statement"
32
34
  require "arel/nodes/table_alias"
@@ -60,13 +60,6 @@ module Arel # :nodoc: all
60
60
  case other
61
61
  when Arel::SelectManager
62
62
  Arel::Nodes::In.new(self, other.ast)
63
- when Range
64
- if $VERBOSE
65
- warn <<-eowarn
66
- Passing a range to `#in` is deprecated. Call `#between`, instead.
67
- eowarn
68
- end
69
- between(other)
70
63
  when Enumerable
71
64
  Nodes::In.new self, quoted_array(other)
72
65
  else
@@ -110,13 +103,6 @@ Passing a range to `#in` is deprecated. Call `#between`, instead.
110
103
  case other
111
104
  when Arel::SelectManager
112
105
  Arel::Nodes::NotIn.new(self, other.ast)
113
- when Range
114
- if $VERBOSE
115
- warn <<-eowarn
116
- Passing a range to `#not_in` is deprecated. Call `#not_between`, instead.
117
- eowarn
118
- end
119
- not_between(other)
120
106
  when Enumerable
121
107
  Nodes::NotIn.new self, quoted_array(other)
122
108
  else
@@ -220,6 +206,18 @@ Passing a range to `#not_in` is deprecated. Call `#not_between`, instead.
220
206
  Nodes::Concat.new self, other
221
207
  end
222
208
 
209
+ def contains(other)
210
+ Arel::Nodes::Contains.new(self, other)
211
+ end
212
+
213
+ def overlaps(other)
214
+ Arel::Nodes::Overlaps.new(self, other)
215
+ end
216
+
217
+ def quoted_array(others)
218
+ others.map { |v| quoted_node(v) }
219
+ end
220
+
223
221
  private
224
222
  def grouping_any(method_id, others, *extras)
225
223
  nodes = others.map { |expr| send(method_id, expr, *extras) }
@@ -237,10 +235,6 @@ Passing a range to `#not_in` is deprecated. Call `#not_between`, instead.
237
235
  Nodes.build_quoted(other, self)
238
236
  end
239
237
 
240
- def quoted_array(others)
241
- others.map { |v| quoted_node(v) }
242
- end
243
-
244
238
  def infinity?(value)
245
239
  value.respond_to?(:infinite?) && value.infinite?
246
240
  end
@@ -186,8 +186,7 @@ module Arel # :nodoc: all
186
186
  def where_sql(engine = Table.engine)
187
187
  return if @ctx.wheres.empty?
188
188
 
189
- viz = Visitors::WhereSql.new(engine.connection.visitor, engine.connection)
190
- Nodes::SqlLiteral.new viz.accept(@ctx, Collectors::SQLString.new).value
189
+ Nodes::SqlLiteral.new("WHERE #{Nodes::And.new(@ctx.wheres).to_sql(engine)}")
191
190
  end
192
191
 
193
192
  def union(operation, other = nil)
data/lib/arel/table.rb CHANGED
@@ -4,6 +4,7 @@ module Arel # :nodoc: all
4
4
  class Table
5
5
  include Arel::Crud
6
6
  include Arel::FactoryMethods
7
+ include Arel::AliasPredication
7
8
 
8
9
  @engine = nil
9
10
  class << self; attr_accessor :engine; end
@@ -13,8 +14,9 @@ module Arel # :nodoc: all
13
14
  # TableAlias and Table both have a #table_name which is the name of the underlying table
14
15
  alias :table_name :name
15
16
 
16
- def initialize(name, as: nil, type_caster: nil)
17
+ def initialize(name, as: nil, klass: nil, type_caster: klass&.type_caster)
17
18
  @name = name.to_s
19
+ @klass = klass
18
20
  @type_caster = type_caster
19
21
 
20
22
  # Sometime AR sends an :as parameter to table, to let the table know
@@ -78,8 +80,10 @@ module Arel # :nodoc: all
78
80
  from.having expr
79
81
  end
80
82
 
81
- def [](name)
82
- ::Arel::Attribute.new self, name
83
+ def [](name, table = self)
84
+ name = name.to_s if name.is_a?(Symbol)
85
+ name = @klass.attribute_aliases[name] || name if @klass
86
+ Attribute.new(table, name)
83
87
  end
84
88
 
85
89
  def hash
@@ -96,8 +100,12 @@ module Arel # :nodoc: all
96
100
  end
97
101
  alias :== :eql?
98
102
 
99
- def type_cast_for_database(attribute_name, value)
100
- type_caster.type_cast_for_database(attribute_name, value)
103
+ def type_cast_for_database(attr_name, value)
104
+ type_caster.type_cast_for_database(attr_name, value)
105
+ end
106
+
107
+ def type_for_attribute(name)
108
+ type_caster.type_for_attribute(name)
101
109
  end
102
110
 
103
111
  def able_to_type_cast?
@@ -157,7 +157,13 @@ module Arel # :nodoc: all
157
157
  end
158
158
 
159
159
  def visit_Arel_Nodes_Casted(o)
160
- visit_edge o, "val"
160
+ visit_edge o, "value"
161
+ visit_edge o, "attribute"
162
+ end
163
+
164
+ def visit_Arel_Nodes_HomogeneousIn(o)
165
+ visit_edge o, "values"
166
+ visit_edge o, "type"
161
167
  visit_edge o, "attribute"
162
168
  end
163
169
 
@@ -218,7 +224,13 @@ module Arel # :nodoc: all
218
224
  alias :visit_Symbol :visit_String
219
225
  alias :visit_Arel_Nodes_SqlLiteral :visit_String
220
226
 
221
- def visit_Arel_Nodes_BindParam(o); end
227
+ def visit_Arel_Nodes_BindParam(o)
228
+ edge("value") { visit o.value }
229
+ end
230
+
231
+ def visit_ActiveModel_Attribute(o)
232
+ edge("value_before_type_cast") { visit o.value_before_type_cast }
233
+ end
222
234
 
223
235
  def visit_Hash(o)
224
236
  o.each_with_index do |pair, i|
@@ -15,7 +15,9 @@ module Arel # :nodoc: all
15
15
 
16
16
  ###
17
17
  # :'(
18
- # http://dev.mysql.com/doc/refman/5.0/en/select.html#id3482214
18
+ # To retrieve all rows from a certain offset up to the end of the result set,
19
+ # you can use some large number for the second parameter.
20
+ # https://dev.mysql.com/doc/refman/en/select.html
19
21
  def visit_Arel_Nodes_SelectStatement(o, collector)
20
22
  if o.offset && !o.limit
21
23
  o.limit = Arel::Nodes::Limit.new(18446744073709551615)
@@ -48,6 +50,14 @@ module Arel # :nodoc: all
48
50
  visit_Arel_Nodes_IsNotDistinctFrom o, collector
49
51
  end
50
52
 
53
+ def visit_Arel_Nodes_Regexp(o, collector)
54
+ infix_value o, collector, " REGEXP "
55
+ end
56
+
57
+ def visit_Arel_Nodes_NotRegexp(o, collector)
58
+ infix_value o, collector, " NOT REGEXP "
59
+ end
60
+
51
61
  # In the simple case, MySQL allows us to place JOINs directly into the UPDATE
52
62
  # query. However, this does not allow for LIMIT, OFFSET and ORDER. To support
53
63
  # these, we must use a subquery.
@@ -41,10 +41,6 @@ module Arel # :nodoc: all
41
41
  visit(o.expr, collector) << " )"
42
42
  end
43
43
 
44
- def visit_Arel_Nodes_BindParam(o, collector)
45
- collector.add_bind(o.value) { |i| "$#{i}" }
46
- end
47
-
48
44
  def visit_Arel_Nodes_GroupingElement(o, collector)
49
45
  collector << "( "
50
46
  visit(o.expr, collector) << " )"
@@ -82,6 +78,21 @@ module Arel # :nodoc: all
82
78
  visit o.right, collector
83
79
  end
84
80
 
81
+ def visit_Arel_Nodes_NullsFirst(o, collector)
82
+ visit o.expr, collector
83
+ collector << " NULLS FIRST"
84
+ end
85
+
86
+ def visit_Arel_Nodes_NullsLast(o, collector)
87
+ visit o.expr, collector
88
+ collector << " NULLS LAST"
89
+ end
90
+
91
+ BIND_BLOCK = proc { |i| "$#{i}" }
92
+ private_constant :BIND_BLOCK
93
+
94
+ def bind_block; BIND_BLOCK; end
95
+
85
96
  # Used by Lateral visitor to enclose select queries in parentheses
86
97
  def grouping_parentheses(o, collector)
87
98
  if o.expr.is_a? Nodes::SelectStatement