activerecord 5.2.8.1 → 6.1.6.1

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 (316) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1255 -596
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +7 -5
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record/aggregations.rb +9 -8
  7. data/lib/active_record/association_relation.rb +30 -10
  8. data/lib/active_record/associations/alias_tracker.rb +19 -16
  9. data/lib/active_record/associations/association.rb +100 -41
  10. data/lib/active_record/associations/association_scope.rb +23 -21
  11. data/lib/active_record/associations/belongs_to_association.rb +55 -48
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +7 -6
  13. data/lib/active_record/associations/builder/association.rb +45 -22
  14. data/lib/active_record/associations/builder/belongs_to.rb +29 -59
  15. data/lib/active_record/associations/builder/collection_association.rb +8 -17
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -41
  17. data/lib/active_record/associations/builder/has_many.rb +8 -2
  18. data/lib/active_record/associations/builder/has_one.rb +33 -2
  19. data/lib/active_record/associations/builder/singular_association.rb +3 -1
  20. data/lib/active_record/associations/collection_association.rb +44 -34
  21. data/lib/active_record/associations/collection_proxy.rb +25 -21
  22. data/lib/active_record/associations/foreign_association.rb +20 -0
  23. data/lib/active_record/associations/has_many_association.rb +26 -13
  24. data/lib/active_record/associations/has_many_through_association.rb +24 -18
  25. data/lib/active_record/associations/has_one_association.rb +43 -31
  26. data/lib/active_record/associations/has_one_through_association.rb +5 -5
  27. data/lib/active_record/associations/join_dependency/join_association.rb +44 -22
  28. data/lib/active_record/associations/join_dependency/join_part.rb +5 -5
  29. data/lib/active_record/associations/join_dependency.rb +91 -60
  30. data/lib/active_record/associations/preloader/association.rb +69 -43
  31. data/lib/active_record/associations/preloader/through_association.rb +49 -40
  32. data/lib/active_record/associations/preloader.rb +47 -34
  33. data/lib/active_record/associations/singular_association.rb +3 -17
  34. data/lib/active_record/associations/through_association.rb +1 -1
  35. data/lib/active_record/associations.rb +137 -25
  36. data/lib/active_record/attribute_assignment.rb +17 -19
  37. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -7
  38. data/lib/active_record/attribute_methods/dirty.rb +101 -40
  39. data/lib/active_record/attribute_methods/primary_key.rb +20 -25
  40. data/lib/active_record/attribute_methods/query.rb +4 -8
  41. data/lib/active_record/attribute_methods/read.rb +14 -56
  42. data/lib/active_record/attribute_methods/serialization.rb +12 -7
  43. data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
  44. data/lib/active_record/attribute_methods/write.rb +18 -34
  45. data/lib/active_record/attribute_methods.rb +81 -143
  46. data/lib/active_record/attributes.rb +46 -9
  47. data/lib/active_record/autosave_association.rb +57 -42
  48. data/lib/active_record/base.rb +4 -17
  49. data/lib/active_record/callbacks.rb +158 -43
  50. data/lib/active_record/coders/yaml_column.rb +1 -2
  51. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +272 -130
  52. data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -36
  53. data/lib/active_record/connection_adapters/abstract/database_statements.rb +167 -146
  54. data/lib/active_record/connection_adapters/abstract/query_cache.rb +18 -14
  55. data/lib/active_record/connection_adapters/abstract/quoting.rb +98 -47
  56. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  57. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -110
  58. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +211 -90
  59. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +2 -4
  60. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +385 -144
  61. data/lib/active_record/connection_adapters/abstract/transaction.rb +167 -69
  62. data/lib/active_record/connection_adapters/abstract_adapter.rb +229 -99
  63. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +243 -275
  64. data/lib/active_record/connection_adapters/column.rb +30 -12
  65. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  66. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  67. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  68. data/lib/active_record/connection_adapters/mysql/database_statements.rb +88 -32
  69. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
  70. data/lib/active_record/connection_adapters/mysql/quoting.rb +59 -7
  71. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +34 -10
  72. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +48 -32
  73. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +18 -7
  74. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +142 -19
  75. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +14 -9
  76. data/lib/active_record/connection_adapters/mysql2_adapter.rb +53 -18
  77. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  78. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  79. data/lib/active_record/connection_adapters/postgresql/column.rb +37 -28
  80. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +40 -54
  81. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
  82. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  83. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
  84. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
  85. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
  86. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  87. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +3 -4
  90. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +3 -4
  93. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
  94. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  95. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  96. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +15 -3
  97. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  98. data/lib/active_record/connection_adapters/postgresql/quoting.rb +47 -10
  99. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
  100. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +19 -4
  101. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
  102. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
  103. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +120 -100
  104. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +31 -26
  105. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  106. data/lib/active_record/connection_adapters/postgresql_adapter.rb +224 -120
  107. data/lib/active_record/connection_adapters/schema_cache.rb +159 -21
  108. data/lib/active_record/connection_adapters/sql_type_metadata.rb +17 -6
  109. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +146 -0
  110. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
  111. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  112. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +77 -13
  113. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +174 -186
  114. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  115. data/lib/active_record/connection_adapters.rb +52 -0
  116. data/lib/active_record/connection_handling.rb +293 -33
  117. data/lib/active_record/core.rb +333 -98
  118. data/lib/active_record/counter_cache.rb +8 -30
  119. data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -0
  120. data/lib/active_record/database_configurations/database_config.rb +80 -0
  121. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  122. data/lib/active_record/database_configurations/url_config.rb +53 -0
  123. data/lib/active_record/database_configurations.rb +273 -0
  124. data/lib/active_record/delegated_type.rb +209 -0
  125. data/lib/active_record/destroy_association_async_job.rb +36 -0
  126. data/lib/active_record/dynamic_matchers.rb +3 -4
  127. data/lib/active_record/enum.rb +108 -36
  128. data/lib/active_record/errors.rb +62 -19
  129. data/lib/active_record/explain.rb +10 -6
  130. data/lib/active_record/explain_subscriber.rb +1 -1
  131. data/lib/active_record/fixture_set/file.rb +10 -17
  132. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  133. data/lib/active_record/fixture_set/render_context.rb +17 -0
  134. data/lib/active_record/fixture_set/table_row.rb +152 -0
  135. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  136. data/lib/active_record/fixtures.rb +200 -481
  137. data/lib/active_record/gem_version.rb +3 -3
  138. data/lib/active_record/inheritance.rb +53 -24
  139. data/lib/active_record/insert_all.rb +212 -0
  140. data/lib/active_record/integration.rb +67 -17
  141. data/lib/active_record/internal_metadata.rb +28 -9
  142. data/lib/active_record/legacy_yaml_adapter.rb +7 -3
  143. data/lib/active_record/locking/optimistic.rb +37 -23
  144. data/lib/active_record/locking/pessimistic.rb +9 -5
  145. data/lib/active_record/log_subscriber.rb +35 -35
  146. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  147. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  148. data/lib/active_record/middleware/database_selector.rb +77 -0
  149. data/lib/active_record/migration/command_recorder.rb +96 -44
  150. data/lib/active_record/migration/compatibility.rb +145 -64
  151. data/lib/active_record/migration/join_table.rb +0 -1
  152. data/lib/active_record/migration.rb +206 -157
  153. data/lib/active_record/model_schema.rb +148 -22
  154. data/lib/active_record/nested_attributes.rb +4 -7
  155. data/lib/active_record/no_touching.rb +8 -1
  156. data/lib/active_record/null_relation.rb +0 -1
  157. data/lib/active_record/persistence.rb +267 -59
  158. data/lib/active_record/query_cache.rb +21 -4
  159. data/lib/active_record/querying.rb +40 -23
  160. data/lib/active_record/railtie.rb +116 -59
  161. data/lib/active_record/railties/console_sandbox.rb +2 -4
  162. data/lib/active_record/railties/controller_runtime.rb +30 -35
  163. data/lib/active_record/railties/databases.rake +411 -80
  164. data/lib/active_record/readonly_attributes.rb +4 -0
  165. data/lib/active_record/reflection.rb +109 -93
  166. data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
  167. data/lib/active_record/relation/batches.rb +44 -35
  168. data/lib/active_record/relation/calculations.rb +157 -90
  169. data/lib/active_record/relation/delegation.rb +35 -50
  170. data/lib/active_record/relation/finder_methods.rb +64 -39
  171. data/lib/active_record/relation/from_clause.rb +5 -1
  172. data/lib/active_record/relation/merger.rb +32 -40
  173. data/lib/active_record/relation/predicate_builder/array_handler.rb +13 -13
  174. data/lib/active_record/relation/predicate_builder/association_query_value.rb +5 -9
  175. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  176. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +11 -10
  177. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  178. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  179. data/lib/active_record/relation/predicate_builder.rb +62 -45
  180. data/lib/active_record/relation/query_attribute.rb +13 -8
  181. data/lib/active_record/relation/query_methods.rb +476 -187
  182. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  183. data/lib/active_record/relation/spawn_methods.rb +9 -9
  184. data/lib/active_record/relation/where_clause.rb +115 -62
  185. data/lib/active_record/relation.rb +379 -115
  186. data/lib/active_record/result.rb +64 -38
  187. data/lib/active_record/runtime_registry.rb +2 -2
  188. data/lib/active_record/sanitization.rb +22 -41
  189. data/lib/active_record/schema.rb +2 -11
  190. data/lib/active_record/schema_dumper.rb +54 -9
  191. data/lib/active_record/schema_migration.rb +7 -9
  192. data/lib/active_record/scoping/default.rb +4 -8
  193. data/lib/active_record/scoping/named.rb +17 -24
  194. data/lib/active_record/scoping.rb +8 -9
  195. data/lib/active_record/secure_token.rb +16 -8
  196. data/lib/active_record/serialization.rb +5 -3
  197. data/lib/active_record/signed_id.rb +116 -0
  198. data/lib/active_record/statement_cache.rb +49 -6
  199. data/lib/active_record/store.rb +88 -9
  200. data/lib/active_record/suppressor.rb +2 -2
  201. data/lib/active_record/table_metadata.rb +42 -43
  202. data/lib/active_record/tasks/database_tasks.rb +277 -81
  203. data/lib/active_record/tasks/mysql_database_tasks.rb +37 -39
  204. data/lib/active_record/tasks/postgresql_database_tasks.rb +27 -32
  205. data/lib/active_record/tasks/sqlite_database_tasks.rb +14 -17
  206. data/lib/active_record/test_databases.rb +24 -0
  207. data/lib/active_record/test_fixtures.rb +287 -0
  208. data/lib/active_record/timestamp.rb +43 -32
  209. data/lib/active_record/touch_later.rb +23 -22
  210. data/lib/active_record/transactions.rb +62 -118
  211. data/lib/active_record/translation.rb +1 -1
  212. data/lib/active_record/type/adapter_specific_registry.rb +3 -13
  213. data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
  214. data/lib/active_record/type/serialized.rb +6 -3
  215. data/lib/active_record/type/time.rb +10 -0
  216. data/lib/active_record/type/type_map.rb +0 -1
  217. data/lib/active_record/type/unsigned_integer.rb +0 -1
  218. data/lib/active_record/type.rb +10 -5
  219. data/lib/active_record/type_caster/connection.rb +15 -15
  220. data/lib/active_record/type_caster/map.rb +8 -8
  221. data/lib/active_record/validations/associated.rb +1 -2
  222. data/lib/active_record/validations/numericality.rb +35 -0
  223. data/lib/active_record/validations/uniqueness.rb +38 -30
  224. data/lib/active_record/validations.rb +4 -3
  225. data/lib/active_record.rb +13 -12
  226. data/lib/arel/alias_predication.rb +9 -0
  227. data/lib/arel/attributes/attribute.rb +41 -0
  228. data/lib/arel/collectors/bind.rb +29 -0
  229. data/lib/arel/collectors/composite.rb +39 -0
  230. data/lib/arel/collectors/plain_string.rb +20 -0
  231. data/lib/arel/collectors/sql_string.rb +27 -0
  232. data/lib/arel/collectors/substitute_binds.rb +35 -0
  233. data/lib/arel/crud.rb +42 -0
  234. data/lib/arel/delete_manager.rb +18 -0
  235. data/lib/arel/errors.rb +9 -0
  236. data/lib/arel/expressions.rb +29 -0
  237. data/lib/arel/factory_methods.rb +49 -0
  238. data/lib/arel/insert_manager.rb +49 -0
  239. data/lib/arel/math.rb +45 -0
  240. data/lib/arel/nodes/and.rb +32 -0
  241. data/lib/arel/nodes/ascending.rb +23 -0
  242. data/lib/arel/nodes/binary.rb +126 -0
  243. data/lib/arel/nodes/bind_param.rb +44 -0
  244. data/lib/arel/nodes/case.rb +55 -0
  245. data/lib/arel/nodes/casted.rb +62 -0
  246. data/lib/arel/nodes/comment.rb +29 -0
  247. data/lib/arel/nodes/count.rb +12 -0
  248. data/lib/arel/nodes/delete_statement.rb +45 -0
  249. data/lib/arel/nodes/descending.rb +23 -0
  250. data/lib/arel/nodes/equality.rb +15 -0
  251. data/lib/arel/nodes/extract.rb +24 -0
  252. data/lib/arel/nodes/false.rb +16 -0
  253. data/lib/arel/nodes/full_outer_join.rb +8 -0
  254. data/lib/arel/nodes/function.rb +44 -0
  255. data/lib/arel/nodes/grouping.rb +11 -0
  256. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  257. data/lib/arel/nodes/in.rb +15 -0
  258. data/lib/arel/nodes/infix_operation.rb +92 -0
  259. data/lib/arel/nodes/inner_join.rb +8 -0
  260. data/lib/arel/nodes/insert_statement.rb +37 -0
  261. data/lib/arel/nodes/join_source.rb +20 -0
  262. data/lib/arel/nodes/matches.rb +18 -0
  263. data/lib/arel/nodes/named_function.rb +23 -0
  264. data/lib/arel/nodes/node.rb +51 -0
  265. data/lib/arel/nodes/node_expression.rb +13 -0
  266. data/lib/arel/nodes/ordering.rb +27 -0
  267. data/lib/arel/nodes/outer_join.rb +8 -0
  268. data/lib/arel/nodes/over.rb +15 -0
  269. data/lib/arel/nodes/regexp.rb +16 -0
  270. data/lib/arel/nodes/right_outer_join.rb +8 -0
  271. data/lib/arel/nodes/select_core.rb +67 -0
  272. data/lib/arel/nodes/select_statement.rb +41 -0
  273. data/lib/arel/nodes/sql_literal.rb +19 -0
  274. data/lib/arel/nodes/string_join.rb +11 -0
  275. data/lib/arel/nodes/table_alias.rb +31 -0
  276. data/lib/arel/nodes/terminal.rb +16 -0
  277. data/lib/arel/nodes/true.rb +16 -0
  278. data/lib/arel/nodes/unary.rb +44 -0
  279. data/lib/arel/nodes/unary_operation.rb +20 -0
  280. data/lib/arel/nodes/unqualified_column.rb +22 -0
  281. data/lib/arel/nodes/update_statement.rb +41 -0
  282. data/lib/arel/nodes/values_list.rb +9 -0
  283. data/lib/arel/nodes/window.rb +126 -0
  284. data/lib/arel/nodes/with.rb +11 -0
  285. data/lib/arel/nodes.rb +70 -0
  286. data/lib/arel/order_predications.rb +13 -0
  287. data/lib/arel/predications.rb +250 -0
  288. data/lib/arel/select_manager.rb +270 -0
  289. data/lib/arel/table.rb +118 -0
  290. data/lib/arel/tree_manager.rb +72 -0
  291. data/lib/arel/update_manager.rb +34 -0
  292. data/lib/arel/visitors/dot.rb +308 -0
  293. data/lib/arel/visitors/mysql.rb +93 -0
  294. data/lib/arel/visitors/postgresql.rb +120 -0
  295. data/lib/arel/visitors/sqlite.rb +38 -0
  296. data/lib/arel/visitors/to_sql.rb +899 -0
  297. data/lib/arel/visitors/visitor.rb +45 -0
  298. data/lib/arel/visitors.rb +13 -0
  299. data/lib/arel/window_predications.rb +9 -0
  300. data/lib/arel.rb +54 -0
  301. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  302. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -5
  303. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +3 -1
  304. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +7 -5
  305. data/lib/rails/generators/active_record/migration.rb +19 -2
  306. data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
  307. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  308. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  309. metadata +116 -30
  310. data/lib/active_record/attribute_decorators.rb +0 -90
  311. data/lib/active_record/collection_cache_key.rb +0 -53
  312. data/lib/active_record/connection_adapters/connection_specification.rb +0 -287
  313. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -33
  314. data/lib/active_record/define_callbacks.rb +0 -22
  315. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -19
  316. data/lib/active_record/relation/where_clause_factory.rb +0 -34
@@ -0,0 +1,308 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Visitors
5
+ class Dot < Arel::Visitors::Visitor
6
+ class Node # :nodoc:
7
+ attr_accessor :name, :id, :fields
8
+
9
+ def initialize(name, id, fields = [])
10
+ @name = name
11
+ @id = id
12
+ @fields = fields
13
+ end
14
+ end
15
+
16
+ class Edge < Struct.new :name, :from, :to # :nodoc:
17
+ end
18
+
19
+ def initialize
20
+ super()
21
+ @nodes = []
22
+ @edges = []
23
+ @node_stack = []
24
+ @edge_stack = []
25
+ @seen = {}
26
+ end
27
+
28
+ def accept(object, collector)
29
+ visit object
30
+ collector << to_dot
31
+ end
32
+
33
+ private
34
+ def visit_Arel_Nodes_Ordering(o)
35
+ visit_edge o, "expr"
36
+ end
37
+
38
+ def visit_Arel_Nodes_TableAlias(o)
39
+ visit_edge o, "name"
40
+ visit_edge o, "relation"
41
+ end
42
+
43
+ def visit_Arel_Nodes_Count(o)
44
+ visit_edge o, "expressions"
45
+ visit_edge o, "distinct"
46
+ end
47
+
48
+ def visit_Arel_Nodes_ValuesList(o)
49
+ visit_edge o, "rows"
50
+ end
51
+
52
+ def visit_Arel_Nodes_StringJoin(o)
53
+ visit_edge o, "left"
54
+ end
55
+
56
+ def visit_Arel_Nodes_InnerJoin(o)
57
+ visit_edge o, "left"
58
+ visit_edge o, "right"
59
+ end
60
+ alias :visit_Arel_Nodes_FullOuterJoin :visit_Arel_Nodes_InnerJoin
61
+ alias :visit_Arel_Nodes_OuterJoin :visit_Arel_Nodes_InnerJoin
62
+ alias :visit_Arel_Nodes_RightOuterJoin :visit_Arel_Nodes_InnerJoin
63
+
64
+ def visit_Arel_Nodes_DeleteStatement(o)
65
+ visit_edge o, "relation"
66
+ visit_edge o, "wheres"
67
+ end
68
+
69
+ def unary(o)
70
+ visit_edge o, "expr"
71
+ end
72
+ alias :visit_Arel_Nodes_Group :unary
73
+ alias :visit_Arel_Nodes_Cube :unary
74
+ alias :visit_Arel_Nodes_RollUp :unary
75
+ alias :visit_Arel_Nodes_GroupingSet :unary
76
+ alias :visit_Arel_Nodes_GroupingElement :unary
77
+ alias :visit_Arel_Nodes_Grouping :unary
78
+ alias :visit_Arel_Nodes_Having :unary
79
+ alias :visit_Arel_Nodes_Limit :unary
80
+ alias :visit_Arel_Nodes_Not :unary
81
+ alias :visit_Arel_Nodes_Offset :unary
82
+ alias :visit_Arel_Nodes_On :unary
83
+ alias :visit_Arel_Nodes_UnqualifiedColumn :unary
84
+ alias :visit_Arel_Nodes_OptimizerHints :unary
85
+ alias :visit_Arel_Nodes_Preceding :unary
86
+ alias :visit_Arel_Nodes_Following :unary
87
+ alias :visit_Arel_Nodes_Rows :unary
88
+ alias :visit_Arel_Nodes_Range :unary
89
+
90
+ def window(o)
91
+ visit_edge o, "partitions"
92
+ visit_edge o, "orders"
93
+ visit_edge o, "framing"
94
+ end
95
+ alias :visit_Arel_Nodes_Window :window
96
+
97
+ def named_window(o)
98
+ visit_edge o, "partitions"
99
+ visit_edge o, "orders"
100
+ visit_edge o, "framing"
101
+ visit_edge o, "name"
102
+ end
103
+ alias :visit_Arel_Nodes_NamedWindow :named_window
104
+
105
+ def function(o)
106
+ visit_edge o, "expressions"
107
+ visit_edge o, "distinct"
108
+ visit_edge o, "alias"
109
+ end
110
+ alias :visit_Arel_Nodes_Exists :function
111
+ alias :visit_Arel_Nodes_Min :function
112
+ alias :visit_Arel_Nodes_Max :function
113
+ alias :visit_Arel_Nodes_Avg :function
114
+ alias :visit_Arel_Nodes_Sum :function
115
+
116
+ def extract(o)
117
+ visit_edge o, "expressions"
118
+ visit_edge o, "alias"
119
+ end
120
+ alias :visit_Arel_Nodes_Extract :extract
121
+
122
+ def visit_Arel_Nodes_NamedFunction(o)
123
+ visit_edge o, "name"
124
+ visit_edge o, "expressions"
125
+ visit_edge o, "distinct"
126
+ visit_edge o, "alias"
127
+ end
128
+
129
+ def visit_Arel_Nodes_InsertStatement(o)
130
+ visit_edge o, "relation"
131
+ visit_edge o, "columns"
132
+ visit_edge o, "values"
133
+ end
134
+
135
+ def visit_Arel_Nodes_SelectCore(o)
136
+ visit_edge o, "source"
137
+ visit_edge o, "projections"
138
+ visit_edge o, "wheres"
139
+ visit_edge o, "windows"
140
+ end
141
+
142
+ def visit_Arel_Nodes_SelectStatement(o)
143
+ visit_edge o, "cores"
144
+ visit_edge o, "limit"
145
+ visit_edge o, "orders"
146
+ visit_edge o, "offset"
147
+ end
148
+
149
+ def visit_Arel_Nodes_UpdateStatement(o)
150
+ visit_edge o, "relation"
151
+ visit_edge o, "wheres"
152
+ visit_edge o, "values"
153
+ end
154
+
155
+ def visit_Arel_Table(o)
156
+ visit_edge o, "name"
157
+ end
158
+
159
+ def visit_Arel_Nodes_Casted(o)
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"
167
+ visit_edge o, "attribute"
168
+ end
169
+
170
+ def visit_Arel_Attribute(o)
171
+ visit_edge o, "relation"
172
+ visit_edge o, "name"
173
+ end
174
+ alias :visit_Arel_Attributes_Integer :visit_Arel_Attribute
175
+ alias :visit_Arel_Attributes_Float :visit_Arel_Attribute
176
+ alias :visit_Arel_Attributes_String :visit_Arel_Attribute
177
+ alias :visit_Arel_Attributes_Time :visit_Arel_Attribute
178
+ alias :visit_Arel_Attributes_Boolean :visit_Arel_Attribute
179
+ alias :visit_Arel_Attributes_Attribute :visit_Arel_Attribute
180
+
181
+ def nary(o)
182
+ o.children.each_with_index do |x, i|
183
+ edge(i) { visit x }
184
+ end
185
+ end
186
+ alias :visit_Arel_Nodes_And :nary
187
+
188
+ def binary(o)
189
+ visit_edge o, "left"
190
+ visit_edge o, "right"
191
+ end
192
+ alias :visit_Arel_Nodes_As :binary
193
+ alias :visit_Arel_Nodes_Assignment :binary
194
+ alias :visit_Arel_Nodes_Between :binary
195
+ alias :visit_Arel_Nodes_Concat :binary
196
+ alias :visit_Arel_Nodes_DoesNotMatch :binary
197
+ alias :visit_Arel_Nodes_Equality :binary
198
+ alias :visit_Arel_Nodes_GreaterThan :binary
199
+ alias :visit_Arel_Nodes_GreaterThanOrEqual :binary
200
+ alias :visit_Arel_Nodes_In :binary
201
+ alias :visit_Arel_Nodes_JoinSource :binary
202
+ alias :visit_Arel_Nodes_LessThan :binary
203
+ alias :visit_Arel_Nodes_LessThanOrEqual :binary
204
+ alias :visit_Arel_Nodes_IsNotDistinctFrom :binary
205
+ alias :visit_Arel_Nodes_IsDistinctFrom :binary
206
+ alias :visit_Arel_Nodes_Matches :binary
207
+ alias :visit_Arel_Nodes_NotEqual :binary
208
+ alias :visit_Arel_Nodes_NotIn :binary
209
+ alias :visit_Arel_Nodes_Or :binary
210
+ alias :visit_Arel_Nodes_Over :binary
211
+
212
+ def visit_String(o)
213
+ @node_stack.last.fields << o
214
+ end
215
+ alias :visit_Time :visit_String
216
+ alias :visit_Date :visit_String
217
+ alias :visit_DateTime :visit_String
218
+ alias :visit_NilClass :visit_String
219
+ alias :visit_TrueClass :visit_String
220
+ alias :visit_FalseClass :visit_String
221
+ alias :visit_Integer :visit_String
222
+ alias :visit_BigDecimal :visit_String
223
+ alias :visit_Float :visit_String
224
+ alias :visit_Symbol :visit_String
225
+ alias :visit_Arel_Nodes_SqlLiteral :visit_String
226
+
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
234
+
235
+ def visit_Hash(o)
236
+ o.each_with_index do |pair, i|
237
+ edge("pair_#{i}") { visit pair }
238
+ end
239
+ end
240
+
241
+ def visit_Array(o)
242
+ o.each_with_index do |x, i|
243
+ edge(i) { visit x }
244
+ end
245
+ end
246
+ alias :visit_Set :visit_Array
247
+
248
+ def visit_Arel_Nodes_Comment(o)
249
+ visit_edge(o, "values")
250
+ end
251
+
252
+ def visit_edge(o, method)
253
+ edge(method) { visit o.send(method) }
254
+ end
255
+
256
+ def visit(o)
257
+ if node = @seen[o.object_id]
258
+ @edge_stack.last.to = node
259
+ return
260
+ end
261
+
262
+ node = Node.new(o.class.name, o.object_id)
263
+ @seen[node.id] = node
264
+ @nodes << node
265
+ with_node node do
266
+ super
267
+ end
268
+ end
269
+
270
+ def edge(name)
271
+ edge = Edge.new(name, @node_stack.last)
272
+ @edge_stack.push edge
273
+ @edges << edge
274
+ yield
275
+ @edge_stack.pop
276
+ end
277
+
278
+ def with_node(node)
279
+ if edge = @edge_stack.last
280
+ edge.to = node
281
+ end
282
+
283
+ @node_stack.push node
284
+ yield
285
+ @node_stack.pop
286
+ end
287
+
288
+ def quote(string)
289
+ string.to_s.gsub('"', '\"')
290
+ end
291
+
292
+ def to_dot
293
+ "digraph \"Arel\" {\nnode [width=0.375,height=0.25,shape=record];\n" +
294
+ @nodes.map { |node|
295
+ label = "<f0>#{node.name}"
296
+
297
+ node.fields.each_with_index do |field, i|
298
+ label += "|<f#{i + 1}>#{quote field}"
299
+ end
300
+
301
+ "#{node.id} [label=\"#{label}\"];"
302
+ }.join("\n") + "\n" + @edges.map { |edge|
303
+ "#{edge.from.id} -> #{edge.to.id} [label=\"#{edge.name}\"];"
304
+ }.join("\n") + "\n}"
305
+ end
306
+ end
307
+ end
308
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Visitors
5
+ class MySQL < Arel::Visitors::ToSql
6
+ private
7
+ def visit_Arel_Nodes_Bin(o, collector)
8
+ collector << "BINARY "
9
+ visit o.expr, collector
10
+ end
11
+
12
+ def visit_Arel_Nodes_UnqualifiedColumn(o, collector)
13
+ visit o.expr, collector
14
+ end
15
+
16
+ ###
17
+ # :'(
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
21
+ def visit_Arel_Nodes_SelectStatement(o, collector)
22
+ if o.offset && !o.limit
23
+ o.limit = Arel::Nodes::Limit.new(18446744073709551615)
24
+ end
25
+ super
26
+ end
27
+
28
+ def visit_Arel_Nodes_SelectCore(o, collector)
29
+ o.froms ||= Arel.sql("DUAL")
30
+ super
31
+ end
32
+
33
+ def visit_Arel_Nodes_Concat(o, collector)
34
+ collector << " CONCAT("
35
+ visit o.left, collector
36
+ collector << ", "
37
+ visit o.right, collector
38
+ collector << ") "
39
+ collector
40
+ end
41
+
42
+ def visit_Arel_Nodes_IsNotDistinctFrom(o, collector)
43
+ collector = visit o.left, collector
44
+ collector << " <=> "
45
+ visit o.right, collector
46
+ end
47
+
48
+ def visit_Arel_Nodes_IsDistinctFrom(o, collector)
49
+ collector << "NOT "
50
+ visit_Arel_Nodes_IsNotDistinctFrom o, collector
51
+ end
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
+
61
+ # In the simple case, MySQL allows us to place JOINs directly into the UPDATE
62
+ # query. However, this does not allow for LIMIT, OFFSET and ORDER. To support
63
+ # these, we must use a subquery.
64
+ def prepare_update_statement(o)
65
+ if o.offset || has_join_sources?(o) && has_limit_or_offset_or_orders?(o)
66
+ super
67
+ else
68
+ o
69
+ end
70
+ end
71
+ alias :prepare_delete_statement :prepare_update_statement
72
+
73
+ # MySQL is too stupid to create a temporary table for use subquery, so we have
74
+ # to give it some prompting in the form of a subsubquery.
75
+ def build_subselect(key, o)
76
+ subselect = super
77
+
78
+ # Materialize subquery by adding distinct
79
+ # to work with MySQL 5.7.6 which sets optimizer_switch='derived_merge=on'
80
+ unless has_limit_or_offset_or_orders?(subselect)
81
+ core = subselect.cores.last
82
+ core.set_quantifier = Arel::Nodes::Distinct.new
83
+ end
84
+
85
+ Nodes::SelectStatement.new.tap do |stmt|
86
+ core = stmt.cores.last
87
+ core.froms = Nodes::Grouping.new(subselect).as("__active_record_temp")
88
+ core.projections = [Arel.sql(quote_column_name(key.name))]
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Visitors
5
+ class PostgreSQL < Arel::Visitors::ToSql
6
+ private
7
+ def visit_Arel_Nodes_Matches(o, collector)
8
+ op = o.case_sensitive ? " LIKE " : " ILIKE "
9
+ collector = infix_value o, collector, op
10
+ if o.escape
11
+ collector << " ESCAPE "
12
+ visit o.escape, collector
13
+ else
14
+ collector
15
+ end
16
+ end
17
+
18
+ def visit_Arel_Nodes_DoesNotMatch(o, collector)
19
+ op = o.case_sensitive ? " NOT LIKE " : " NOT ILIKE "
20
+ collector = infix_value o, collector, op
21
+ if o.escape
22
+ collector << " ESCAPE "
23
+ visit o.escape, collector
24
+ else
25
+ collector
26
+ end
27
+ end
28
+
29
+ def visit_Arel_Nodes_Regexp(o, collector)
30
+ op = o.case_sensitive ? " ~ " : " ~* "
31
+ infix_value o, collector, op
32
+ end
33
+
34
+ def visit_Arel_Nodes_NotRegexp(o, collector)
35
+ op = o.case_sensitive ? " !~ " : " !~* "
36
+ infix_value o, collector, op
37
+ end
38
+
39
+ def visit_Arel_Nodes_DistinctOn(o, collector)
40
+ collector << "DISTINCT ON ( "
41
+ visit(o.expr, collector) << " )"
42
+ end
43
+
44
+ def visit_Arel_Nodes_GroupingElement(o, collector)
45
+ collector << "( "
46
+ visit(o.expr, collector) << " )"
47
+ end
48
+
49
+ def visit_Arel_Nodes_Cube(o, collector)
50
+ collector << "CUBE"
51
+ grouping_array_or_grouping_element o, collector
52
+ end
53
+
54
+ def visit_Arel_Nodes_RollUp(o, collector)
55
+ collector << "ROLLUP"
56
+ grouping_array_or_grouping_element o, collector
57
+ end
58
+
59
+ def visit_Arel_Nodes_GroupingSet(o, collector)
60
+ collector << "GROUPING SETS"
61
+ grouping_array_or_grouping_element o, collector
62
+ end
63
+
64
+ def visit_Arel_Nodes_Lateral(o, collector)
65
+ collector << "LATERAL "
66
+ grouping_parentheses o, collector
67
+ end
68
+
69
+ def visit_Arel_Nodes_IsNotDistinctFrom(o, collector)
70
+ collector = visit o.left, collector
71
+ collector << " IS NOT DISTINCT FROM "
72
+ visit o.right, collector
73
+ end
74
+
75
+ def visit_Arel_Nodes_IsDistinctFrom(o, collector)
76
+ collector = visit o.left, collector
77
+ collector << " IS DISTINCT FROM "
78
+ visit o.right, collector
79
+ end
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
+
96
+ # Used by Lateral visitor to enclose select queries in parentheses
97
+ def grouping_parentheses(o, collector)
98
+ if o.expr.is_a? Nodes::SelectStatement
99
+ collector << "("
100
+ visit o.expr, collector
101
+ collector << ")"
102
+ else
103
+ visit o.expr, collector
104
+ end
105
+ end
106
+
107
+ # Utilized by GroupingSet, Cube & RollUp visitors to
108
+ # handle grouping aggregation semantics
109
+ def grouping_array_or_grouping_element(o, collector)
110
+ if o.expr.is_a? Array
111
+ collector << "( "
112
+ visit o.expr, collector
113
+ collector << " )"
114
+ else
115
+ visit o.expr, collector
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Visitors
5
+ class SQLite < Arel::Visitors::ToSql
6
+ private
7
+ # Locks are not supported in SQLite
8
+ def visit_Arel_Nodes_Lock(o, collector)
9
+ collector
10
+ end
11
+
12
+ def visit_Arel_Nodes_SelectStatement(o, collector)
13
+ o.limit = Arel::Nodes::Limit.new(-1) if o.offset && !o.limit
14
+ super
15
+ end
16
+
17
+ def visit_Arel_Nodes_True(o, collector)
18
+ collector << "1"
19
+ end
20
+
21
+ def visit_Arel_Nodes_False(o, collector)
22
+ collector << "0"
23
+ end
24
+
25
+ def visit_Arel_Nodes_IsNotDistinctFrom(o, collector)
26
+ collector = visit o.left, collector
27
+ collector << " IS "
28
+ visit o.right, collector
29
+ end
30
+
31
+ def visit_Arel_Nodes_IsDistinctFrom(o, collector)
32
+ collector = visit o.left, collector
33
+ collector << " IS NOT "
34
+ visit o.right, collector
35
+ end
36
+ end
37
+ end
38
+ end