activerecord 6.0.0 → 6.1.4

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 (270) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1178 -600
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -4
  5. data/lib/active_record/aggregations.rb +5 -6
  6. data/lib/active_record/association_relation.rb +30 -10
  7. data/lib/active_record/associations/alias_tracker.rb +19 -16
  8. data/lib/active_record/associations/association.rb +55 -29
  9. data/lib/active_record/associations/association_scope.rb +19 -15
  10. data/lib/active_record/associations/belongs_to_association.rb +23 -10
  11. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -3
  12. data/lib/active_record/associations/builder/association.rb +32 -5
  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 -3
  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 +25 -8
  20. data/lib/active_record/associations/collection_proxy.rb +14 -7
  21. data/lib/active_record/associations/foreign_association.rb +13 -0
  22. data/lib/active_record/associations/has_many_association.rb +24 -3
  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 +39 -16
  26. data/lib/active_record/associations/join_dependency/join_part.rb +3 -3
  27. data/lib/active_record/associations/join_dependency.rb +77 -42
  28. data/lib/active_record/associations/preloader/association.rb +51 -25
  29. data/lib/active_record/associations/preloader/through_association.rb +2 -2
  30. data/lib/active_record/associations/preloader.rb +13 -8
  31. data/lib/active_record/associations/singular_association.rb +1 -1
  32. data/lib/active_record/associations/through_association.rb +1 -1
  33. data/lib/active_record/associations.rb +120 -13
  34. data/lib/active_record/attribute_assignment.rb +10 -9
  35. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -10
  36. data/lib/active_record/attribute_methods/dirty.rb +3 -13
  37. data/lib/active_record/attribute_methods/primary_key.rb +6 -4
  38. data/lib/active_record/attribute_methods/query.rb +3 -6
  39. data/lib/active_record/attribute_methods/read.rb +8 -12
  40. data/lib/active_record/attribute_methods/serialization.rb +11 -6
  41. data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
  42. data/lib/active_record/attribute_methods/write.rb +12 -21
  43. data/lib/active_record/attribute_methods.rb +64 -54
  44. data/lib/active_record/attributes.rb +33 -9
  45. data/lib/active_record/autosave_association.rb +63 -44
  46. data/lib/active_record/base.rb +2 -14
  47. data/lib/active_record/callbacks.rb +153 -24
  48. data/lib/active_record/coders/yaml_column.rb +12 -3
  49. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +202 -138
  50. data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
  51. data/lib/active_record/connection_adapters/abstract/database_statements.rb +87 -38
  52. data/lib/active_record/connection_adapters/abstract/query_cache.rb +5 -10
  53. data/lib/active_record/connection_adapters/abstract/quoting.rb +34 -34
  54. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  55. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +152 -116
  56. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +141 -52
  57. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
  58. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +267 -105
  59. data/lib/active_record/connection_adapters/abstract/transaction.rb +94 -36
  60. data/lib/active_record/connection_adapters/abstract_adapter.rb +76 -79
  61. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +149 -115
  62. data/lib/active_record/connection_adapters/column.rb +15 -1
  63. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  64. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  65. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  66. data/lib/active_record/connection_adapters/mysql/database_statements.rb +30 -36
  67. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
  68. data/lib/active_record/connection_adapters/mysql/quoting.rb +18 -3
  69. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +32 -7
  70. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
  71. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +5 -2
  72. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +17 -13
  73. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
  74. data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -13
  75. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  76. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  77. data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
  78. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +21 -56
  79. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +0 -1
  80. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
  81. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
  82. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
  83. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  84. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +0 -1
  85. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -3
  87. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -3
  91. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +24 -6
  92. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -2
  94. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
  96. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
  97. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +7 -3
  98. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -1
  99. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
  100. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +72 -54
  101. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
  102. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  103. data/lib/active_record/connection_adapters/postgresql_adapter.rb +83 -65
  104. data/lib/active_record/connection_adapters/schema_cache.rb +106 -15
  105. data/lib/active_record/connection_adapters/sql_type_metadata.rb +8 -0
  106. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +38 -12
  107. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -2
  108. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  109. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +38 -5
  110. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -57
  111. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  112. data/lib/active_record/connection_adapters.rb +52 -0
  113. data/lib/active_record/connection_handling.rb +219 -81
  114. data/lib/active_record/core.rb +268 -71
  115. data/lib/active_record/counter_cache.rb +4 -1
  116. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  117. data/lib/active_record/database_configurations/database_config.rb +52 -9
  118. data/lib/active_record/database_configurations/hash_config.rb +54 -8
  119. data/lib/active_record/database_configurations/url_config.rb +15 -41
  120. data/lib/active_record/database_configurations.rb +124 -85
  121. data/lib/active_record/delegated_type.rb +209 -0
  122. data/lib/active_record/destroy_association_async_job.rb +36 -0
  123. data/lib/active_record/dynamic_matchers.rb +2 -3
  124. data/lib/active_record/enum.rb +80 -38
  125. data/lib/active_record/errors.rb +47 -12
  126. data/lib/active_record/explain.rb +9 -5
  127. data/lib/active_record/explain_subscriber.rb +1 -1
  128. data/lib/active_record/fixture_set/file.rb +10 -17
  129. data/lib/active_record/fixture_set/model_metadata.rb +1 -2
  130. data/lib/active_record/fixture_set/render_context.rb +1 -1
  131. data/lib/active_record/fixture_set/table_row.rb +2 -3
  132. data/lib/active_record/fixture_set/table_rows.rb +0 -1
  133. data/lib/active_record/fixtures.rb +58 -12
  134. data/lib/active_record/gem_version.rb +2 -2
  135. data/lib/active_record/inheritance.rb +40 -21
  136. data/lib/active_record/insert_all.rb +43 -10
  137. data/lib/active_record/integration.rb +3 -5
  138. data/lib/active_record/internal_metadata.rb +16 -7
  139. data/lib/active_record/legacy_yaml_adapter.rb +7 -3
  140. data/lib/active_record/locking/optimistic.rb +33 -18
  141. data/lib/active_record/locking/pessimistic.rb +6 -2
  142. data/lib/active_record/log_subscriber.rb +28 -9
  143. data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
  144. data/lib/active_record/middleware/database_selector/resolver.rb +14 -14
  145. data/lib/active_record/middleware/database_selector.rb +4 -2
  146. data/lib/active_record/migration/command_recorder.rb +53 -45
  147. data/lib/active_record/migration/compatibility.rb +71 -20
  148. data/lib/active_record/migration/join_table.rb +0 -1
  149. data/lib/active_record/migration.rb +115 -85
  150. data/lib/active_record/model_schema.rb +120 -15
  151. data/lib/active_record/nested_attributes.rb +2 -5
  152. data/lib/active_record/no_touching.rb +1 -1
  153. data/lib/active_record/null_relation.rb +0 -1
  154. data/lib/active_record/persistence.rb +50 -46
  155. data/lib/active_record/query_cache.rb +15 -5
  156. data/lib/active_record/querying.rb +12 -7
  157. data/lib/active_record/railtie.rb +65 -45
  158. data/lib/active_record/railties/console_sandbox.rb +2 -4
  159. data/lib/active_record/railties/databases.rake +280 -99
  160. data/lib/active_record/readonly_attributes.rb +4 -0
  161. data/lib/active_record/reflection.rb +77 -63
  162. data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
  163. data/lib/active_record/relation/batches.rb +38 -32
  164. data/lib/active_record/relation/calculations.rb +106 -45
  165. data/lib/active_record/relation/delegation.rb +9 -7
  166. data/lib/active_record/relation/finder_methods.rb +55 -17
  167. data/lib/active_record/relation/from_clause.rb +5 -1
  168. data/lib/active_record/relation/merger.rb +27 -26
  169. data/lib/active_record/relation/predicate_builder/array_handler.rb +8 -9
  170. data/lib/active_record/relation/predicate_builder/association_query_value.rb +4 -5
  171. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -6
  172. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  173. data/lib/active_record/relation/predicate_builder.rb +59 -40
  174. data/lib/active_record/relation/query_methods.rb +344 -181
  175. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  176. data/lib/active_record/relation/spawn_methods.rb +8 -8
  177. data/lib/active_record/relation/where_clause.rb +111 -62
  178. data/lib/active_record/relation.rb +116 -82
  179. data/lib/active_record/result.rb +41 -34
  180. data/lib/active_record/runtime_registry.rb +2 -2
  181. data/lib/active_record/sanitization.rb +6 -17
  182. data/lib/active_record/schema_dumper.rb +34 -4
  183. data/lib/active_record/schema_migration.rb +2 -8
  184. data/lib/active_record/scoping/default.rb +1 -4
  185. data/lib/active_record/scoping/named.rb +7 -18
  186. data/lib/active_record/scoping.rb +0 -1
  187. data/lib/active_record/secure_token.rb +16 -8
  188. data/lib/active_record/serialization.rb +5 -3
  189. data/lib/active_record/signed_id.rb +116 -0
  190. data/lib/active_record/statement_cache.rb +20 -4
  191. data/lib/active_record/store.rb +3 -3
  192. data/lib/active_record/suppressor.rb +2 -2
  193. data/lib/active_record/table_metadata.rb +42 -36
  194. data/lib/active_record/tasks/database_tasks.rb +140 -113
  195. data/lib/active_record/tasks/mysql_database_tasks.rb +34 -36
  196. data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -27
  197. data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -10
  198. data/lib/active_record/test_databases.rb +5 -4
  199. data/lib/active_record/test_fixtures.rb +79 -16
  200. data/lib/active_record/timestamp.rb +4 -7
  201. data/lib/active_record/touch_later.rb +20 -21
  202. data/lib/active_record/transactions.rb +26 -73
  203. data/lib/active_record/type/adapter_specific_registry.rb +2 -5
  204. data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
  205. data/lib/active_record/type/serialized.rb +6 -3
  206. data/lib/active_record/type/time.rb +10 -0
  207. data/lib/active_record/type/type_map.rb +0 -1
  208. data/lib/active_record/type/unsigned_integer.rb +0 -1
  209. data/lib/active_record/type.rb +8 -2
  210. data/lib/active_record/type_caster/connection.rb +0 -1
  211. data/lib/active_record/type_caster/map.rb +8 -5
  212. data/lib/active_record/validations/associated.rb +1 -2
  213. data/lib/active_record/validations/numericality.rb +35 -0
  214. data/lib/active_record/validations/uniqueness.rb +24 -4
  215. data/lib/active_record/validations.rb +3 -3
  216. data/lib/active_record.rb +7 -13
  217. data/lib/arel/attributes/attribute.rb +4 -0
  218. data/lib/arel/collectors/bind.rb +5 -0
  219. data/lib/arel/collectors/composite.rb +8 -0
  220. data/lib/arel/collectors/sql_string.rb +7 -0
  221. data/lib/arel/collectors/substitute_binds.rb +7 -0
  222. data/lib/arel/nodes/binary.rb +82 -8
  223. data/lib/arel/nodes/bind_param.rb +8 -0
  224. data/lib/arel/nodes/casted.rb +21 -9
  225. data/lib/arel/nodes/equality.rb +6 -9
  226. data/lib/arel/nodes/grouping.rb +3 -0
  227. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  228. data/lib/arel/nodes/in.rb +8 -1
  229. data/lib/arel/nodes/infix_operation.rb +13 -1
  230. data/lib/arel/nodes/join_source.rb +1 -1
  231. data/lib/arel/nodes/node.rb +7 -6
  232. data/lib/arel/nodes/ordering.rb +27 -0
  233. data/lib/arel/nodes/sql_literal.rb +3 -0
  234. data/lib/arel/nodes/table_alias.rb +7 -3
  235. data/lib/arel/nodes/unary.rb +0 -1
  236. data/lib/arel/nodes.rb +3 -1
  237. data/lib/arel/predications.rb +17 -24
  238. data/lib/arel/select_manager.rb +1 -2
  239. data/lib/arel/table.rb +13 -5
  240. data/lib/arel/visitors/dot.rb +14 -3
  241. data/lib/arel/visitors/mysql.rb +11 -1
  242. data/lib/arel/visitors/postgresql.rb +15 -5
  243. data/lib/arel/visitors/sqlite.rb +0 -1
  244. data/lib/arel/visitors/to_sql.rb +89 -79
  245. data/lib/arel/visitors/visitor.rb +0 -1
  246. data/lib/arel/visitors.rb +0 -7
  247. data/lib/arel.rb +15 -12
  248. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  249. data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
  250. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +2 -0
  251. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -4
  252. data/lib/rails/generators/active_record/migration.rb +6 -2
  253. data/lib/rails/generators/active_record/model/model_generator.rb +38 -2
  254. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  255. metadata +27 -24
  256. data/lib/active_record/attribute_decorators.rb +0 -90
  257. data/lib/active_record/connection_adapters/connection_specification.rb +0 -297
  258. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
  259. data/lib/active_record/define_callbacks.rb +0 -22
  260. data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
  261. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
  262. data/lib/active_record/relation/where_clause_factory.rb +0 -33
  263. data/lib/arel/attributes.rb +0 -22
  264. data/lib/arel/visitors/depth_first.rb +0 -204
  265. data/lib/arel/visitors/ibm_db.rb +0 -34
  266. data/lib/arel/visitors/informix.rb +0 -62
  267. data/lib/arel/visitors/mssql.rb +0 -157
  268. data/lib/arel/visitors/oracle.rb +0 -159
  269. data/lib/arel/visitors/oracle12.rb +0 -66
  270. data/lib/arel/visitors/where_sql.rb +0 -23
@@ -0,0 +1,76 @@
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 proc_for_binds
59
+ -> value { ActiveModel::Attribute.with_cast_value(attribute.name, value, attribute.type_caster) }
60
+ end
61
+
62
+ def fetch_attribute(&block)
63
+ if attribute
64
+ yield attribute
65
+ else
66
+ expr.fetch_attribute(&block)
67
+ end
68
+ end
69
+
70
+ protected
71
+ def ivars
72
+ [@attribute, @values, @type]
73
+ end
74
+ end
75
+ end
76
+ 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"
@@ -38,14 +38,14 @@ module Arel # :nodoc: all
38
38
  if unboundable?(other.begin) == 1 || unboundable?(other.end) == -1
39
39
  self.in([])
40
40
  elsif open_ended?(other.begin)
41
- if other.end.nil? || open_ended?(other.end)
41
+ if open_ended?(other.end)
42
42
  not_in([])
43
43
  elsif other.exclude_end?
44
44
  lt(other.end)
45
45
  else
46
46
  lteq(other.end)
47
47
  end
48
- elsif other.end.nil? || open_ended?(other.end)
48
+ elsif open_ended?(other.end)
49
49
  gteq(other.begin)
50
50
  elsif other.exclude_end?
51
51
  gteq(other.begin).and(lt(other.end))
@@ -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
@@ -86,14 +79,14 @@ Passing a range to `#in` is deprecated. Call `#between`, instead.
86
79
  if unboundable?(other.begin) == 1 || unboundable?(other.end) == -1
87
80
  not_in([])
88
81
  elsif open_ended?(other.begin)
89
- if other.end.nil? || open_ended?(other.end)
82
+ if open_ended?(other.end)
90
83
  self.in([])
91
84
  elsif other.exclude_end?
92
85
  gteq(other.end)
93
86
  else
94
87
  gt(other.end)
95
88
  end
96
- elsif other.end.nil? || open_ended?(other.end)
89
+ elsif open_ended?(other.end)
97
90
  lt(other.begin)
98
91
  else
99
92
  left = lt(other.begin)
@@ -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,8 +206,19 @@ Passing a range to `#not_in` is deprecated. Call `#not_between`, instead.
220
206
  Nodes::Concat.new self, other
221
207
  end
222
208
 
223
- private
209
+ def contains(other)
210
+ Arel::Nodes::Contains.new self, quoted_node(other)
211
+ end
212
+
213
+ def overlaps(other)
214
+ Arel::Nodes::Overlaps.new self, quoted_node(other)
215
+ end
224
216
 
217
+ def quoted_array(others)
218
+ others.map { |v| quoted_node(v) }
219
+ end
220
+
221
+ private
225
222
  def grouping_any(method_id, others, *extras)
226
223
  nodes = others.map { |expr| send(method_id, expr, *extras) }
227
224
  Nodes::Grouping.new nodes.inject { |memo, node|
@@ -238,10 +235,6 @@ Passing a range to `#not_in` is deprecated. Call `#not_between`, instead.
238
235
  Nodes.build_quoted(other, self)
239
236
  end
240
237
 
241
- def quoted_array(others)
242
- others.map { |v| quoted_node(v) }
243
- end
244
-
245
238
  def infinity?(value)
246
239
  value.respond_to?(:infinite?) && value.infinite?
247
240
  end
@@ -251,7 +244,7 @@ Passing a range to `#not_in` is deprecated. Call `#not_between`, instead.
251
244
  end
252
245
 
253
246
  def open_ended?(value)
254
- infinity?(value) || unboundable?(value)
247
+ value.nil? || infinity?(value) || unboundable?(value)
255
248
  end
256
249
  end
257
250
  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?
@@ -31,7 +31,6 @@ module Arel # :nodoc: all
31
31
  end
32
32
 
33
33
  private
34
-
35
34
  def visit_Arel_Nodes_Ordering(o)
36
35
  visit_edge o, "expr"
37
36
  end
@@ -158,7 +157,13 @@ module Arel # :nodoc: all
158
157
  end
159
158
 
160
159
  def visit_Arel_Nodes_Casted(o)
161
- 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"
162
167
  visit_edge o, "attribute"
163
168
  end
164
169
 
@@ -219,7 +224,13 @@ module Arel # :nodoc: all
219
224
  alias :visit_Symbol :visit_String
220
225
  alias :visit_Arel_Nodes_SqlLiteral :visit_String
221
226
 
222
- 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
223
234
 
224
235
  def visit_Hash(o)
225
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.
@@ -4,7 +4,6 @@ module Arel # :nodoc: all
4
4
  module Visitors
5
5
  class PostgreSQL < Arel::Visitors::ToSql
6
6
  private
7
-
8
7
  def visit_Arel_Nodes_Matches(o, collector)
9
8
  op = o.case_sensitive ? " LIKE " : " ILIKE "
10
9
  collector = infix_value o, collector, op
@@ -42,10 +41,6 @@ module Arel # :nodoc: all
42
41
  visit(o.expr, collector) << " )"
43
42
  end
44
43
 
45
- def visit_Arel_Nodes_BindParam(o, collector)
46
- collector.add_bind(o.value) { |i| "$#{i}" }
47
- end
48
-
49
44
  def visit_Arel_Nodes_GroupingElement(o, collector)
50
45
  collector << "( "
51
46
  visit(o.expr, collector) << " )"
@@ -83,6 +78,21 @@ module Arel # :nodoc: all
83
78
  visit o.right, collector
84
79
  end
85
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
+
86
96
  # Used by Lateral visitor to enclose select queries in parentheses
87
97
  def grouping_parentheses(o, collector)
88
98
  if o.expr.is_a? Nodes::SelectStatement
@@ -4,7 +4,6 @@ module Arel # :nodoc: all
4
4
  module Visitors
5
5
  class SQLite < Arel::Visitors::ToSql
6
6
  private
7
-
8
7
  # Locks are not supported in SQLite
9
8
  def visit_Arel_Nodes_Lock(o, collector)
10
9
  collector