activerecord 6.0.3 → 6.1.3
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +968 -682
- data/MIT-LICENSE +1 -1
- data/README.rdoc +3 -3
- data/lib/active_record.rb +7 -14
- data/lib/active_record/aggregations.rb +5 -5
- data/lib/active_record/association_relation.rb +30 -12
- data/lib/active_record/associations.rb +118 -11
- data/lib/active_record/associations/alias_tracker.rb +19 -15
- data/lib/active_record/associations/association.rb +44 -28
- data/lib/active_record/associations/association_scope.rb +19 -15
- data/lib/active_record/associations/belongs_to_association.rb +22 -8
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -3
- data/lib/active_record/associations/builder/association.rb +32 -5
- data/lib/active_record/associations/builder/belongs_to.rb +10 -7
- data/lib/active_record/associations/builder/collection_association.rb +5 -4
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +0 -1
- data/lib/active_record/associations/builder/has_many.rb +6 -2
- data/lib/active_record/associations/builder/has_one.rb +11 -14
- data/lib/active_record/associations/builder/singular_association.rb +1 -1
- data/lib/active_record/associations/collection_association.rb +19 -6
- data/lib/active_record/associations/collection_proxy.rb +13 -5
- data/lib/active_record/associations/foreign_association.rb +13 -0
- data/lib/active_record/associations/has_many_association.rb +24 -2
- data/lib/active_record/associations/has_many_through_association.rb +10 -4
- data/lib/active_record/associations/has_one_association.rb +15 -1
- data/lib/active_record/associations/join_dependency.rb +72 -50
- data/lib/active_record/associations/join_dependency/join_association.rb +39 -16
- data/lib/active_record/associations/join_dependency/join_part.rb +3 -3
- data/lib/active_record/associations/preloader.rb +11 -5
- data/lib/active_record/associations/preloader/association.rb +51 -25
- data/lib/active_record/associations/preloader/through_association.rb +2 -2
- data/lib/active_record/associations/singular_association.rb +1 -1
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/attribute_assignment.rb +10 -8
- data/lib/active_record/attribute_methods.rb +64 -54
- data/lib/active_record/attribute_methods/before_type_cast.rb +13 -9
- data/lib/active_record/attribute_methods/dirty.rb +1 -11
- data/lib/active_record/attribute_methods/primary_key.rb +6 -2
- data/lib/active_record/attribute_methods/query.rb +3 -6
- data/lib/active_record/attribute_methods/read.rb +8 -11
- data/lib/active_record/attribute_methods/serialization.rb +11 -5
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -13
- data/lib/active_record/attribute_methods/write.rb +12 -20
- data/lib/active_record/attributes.rb +33 -8
- data/lib/active_record/autosave_association.rb +57 -40
- data/lib/active_record/base.rb +2 -14
- data/lib/active_record/callbacks.rb +152 -22
- data/lib/active_record/coders/yaml_column.rb +1 -1
- data/lib/active_record/connection_adapters.rb +50 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +191 -134
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +66 -23
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +3 -8
- data/lib/active_record/connection_adapters/abstract/quoting.rb +34 -34
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -116
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +116 -27
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +228 -83
- data/lib/active_record/connection_adapters/abstract/transaction.rb +80 -32
- data/lib/active_record/connection_adapters/abstract_adapter.rb +54 -72
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +129 -88
- data/lib/active_record/connection_adapters/column.rb +15 -1
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +23 -25
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/quoting.rb +18 -3
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +32 -6
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +5 -2
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +11 -7
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -12
- data/lib/active_record/connection_adapters/pool_config.rb +73 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +13 -54
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +24 -5
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +61 -29
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +74 -63
- data/lib/active_record/connection_adapters/schema_cache.rb +98 -15
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +10 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +31 -6
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +37 -4
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +49 -50
- data/lib/active_record/connection_handling.rb +218 -71
- data/lib/active_record/core.rb +245 -61
- data/lib/active_record/database_configurations.rb +124 -85
- data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
- data/lib/active_record/database_configurations/database_config.rb +52 -9
- data/lib/active_record/database_configurations/hash_config.rb +54 -8
- data/lib/active_record/database_configurations/url_config.rb +15 -40
- data/lib/active_record/delegated_type.rb +209 -0
- data/lib/active_record/destroy_association_async_job.rb +36 -0
- data/lib/active_record/enum.rb +82 -38
- data/lib/active_record/errors.rb +47 -12
- data/lib/active_record/explain.rb +9 -4
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +10 -17
- data/lib/active_record/fixture_set/model_metadata.rb +1 -2
- data/lib/active_record/fixture_set/render_context.rb +1 -1
- data/lib/active_record/fixture_set/table_row.rb +2 -2
- data/lib/active_record/fixtures.rb +58 -9
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/inheritance.rb +40 -18
- data/lib/active_record/insert_all.rb +35 -6
- data/lib/active_record/integration.rb +3 -5
- data/lib/active_record/internal_metadata.rb +16 -7
- data/lib/active_record/legacy_yaml_adapter.rb +7 -3
- data/lib/active_record/locking/optimistic.rb +33 -17
- data/lib/active_record/locking/pessimistic.rb +6 -2
- data/lib/active_record/log_subscriber.rb +27 -8
- data/lib/active_record/middleware/database_selector.rb +4 -1
- data/lib/active_record/middleware/database_selector/resolver.rb +5 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
- data/lib/active_record/migration.rb +114 -84
- data/lib/active_record/migration/command_recorder.rb +47 -27
- data/lib/active_record/migration/compatibility.rb +68 -17
- data/lib/active_record/model_schema.rb +117 -13
- data/lib/active_record/nested_attributes.rb +2 -3
- data/lib/active_record/no_touching.rb +1 -1
- data/lib/active_record/persistence.rb +50 -45
- data/lib/active_record/query_cache.rb +15 -5
- data/lib/active_record/querying.rb +11 -6
- data/lib/active_record/railtie.rb +64 -44
- data/lib/active_record/railties/console_sandbox.rb +2 -4
- data/lib/active_record/railties/databases.rake +276 -99
- data/lib/active_record/readonly_attributes.rb +4 -0
- data/lib/active_record/reflection.rb +71 -57
- data/lib/active_record/relation.rb +95 -67
- data/lib/active_record/relation/batches.rb +38 -31
- data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
- data/lib/active_record/relation/calculations.rb +101 -44
- data/lib/active_record/relation/delegation.rb +2 -1
- data/lib/active_record/relation/finder_methods.rb +45 -15
- data/lib/active_record/relation/from_clause.rb +1 -1
- data/lib/active_record/relation/merger.rb +27 -25
- data/lib/active_record/relation/predicate_builder.rb +61 -38
- data/lib/active_record/relation/predicate_builder/array_handler.rb +8 -9
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +4 -5
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -6
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +333 -195
- data/lib/active_record/relation/record_fetch_warning.rb +3 -3
- data/lib/active_record/relation/spawn_methods.rb +8 -7
- data/lib/active_record/relation/where_clause.rb +107 -60
- data/lib/active_record/result.rb +41 -33
- data/lib/active_record/runtime_registry.rb +2 -2
- data/lib/active_record/sanitization.rb +6 -17
- data/lib/active_record/schema_dumper.rb +34 -4
- data/lib/active_record/schema_migration.rb +2 -8
- data/lib/active_record/scoping/named.rb +6 -17
- data/lib/active_record/secure_token.rb +16 -8
- data/lib/active_record/serialization.rb +5 -3
- data/lib/active_record/signed_id.rb +116 -0
- data/lib/active_record/statement_cache.rb +20 -4
- data/lib/active_record/store.rb +2 -2
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +42 -51
- data/lib/active_record/tasks/database_tasks.rb +140 -113
- data/lib/active_record/tasks/mysql_database_tasks.rb +34 -35
- data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -26
- data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -9
- data/lib/active_record/test_databases.rb +5 -4
- data/lib/active_record/test_fixtures.rb +37 -16
- data/lib/active_record/timestamp.rb +4 -6
- data/lib/active_record/touch_later.rb +21 -21
- data/lib/active_record/transactions.rb +19 -66
- data/lib/active_record/type.rb +8 -1
- data/lib/active_record/type/serialized.rb +6 -2
- data/lib/active_record/type/time.rb +10 -0
- data/lib/active_record/type_caster/connection.rb +0 -1
- data/lib/active_record/type_caster/map.rb +8 -5
- data/lib/active_record/validations.rb +1 -0
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/uniqueness.rb +24 -4
- data/lib/arel.rb +5 -13
- data/lib/arel/attributes/attribute.rb +4 -0
- data/lib/arel/collectors/bind.rb +5 -0
- data/lib/arel/collectors/composite.rb +8 -0
- data/lib/arel/collectors/sql_string.rb +7 -0
- data/lib/arel/collectors/substitute_binds.rb +7 -0
- data/lib/arel/nodes.rb +3 -1
- data/lib/arel/nodes/binary.rb +82 -8
- data/lib/arel/nodes/bind_param.rb +8 -0
- data/lib/arel/nodes/casted.rb +21 -9
- data/lib/arel/nodes/equality.rb +6 -9
- data/lib/arel/nodes/grouping.rb +3 -0
- data/lib/arel/nodes/homogeneous_in.rb +72 -0
- data/lib/arel/nodes/in.rb +8 -1
- data/lib/arel/nodes/infix_operation.rb +13 -1
- data/lib/arel/nodes/join_source.rb +1 -1
- data/lib/arel/nodes/node.rb +7 -6
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/sql_literal.rb +3 -0
- data/lib/arel/nodes/table_alias.rb +7 -3
- data/lib/arel/nodes/unary.rb +0 -1
- data/lib/arel/predications.rb +12 -18
- data/lib/arel/select_manager.rb +1 -2
- data/lib/arel/table.rb +13 -5
- data/lib/arel/visitors.rb +0 -7
- data/lib/arel/visitors/dot.rb +14 -2
- data/lib/arel/visitors/mysql.rb +11 -1
- data/lib/arel/visitors/postgresql.rb +15 -4
- data/lib/arel/visitors/to_sql.rb +89 -78
- data/lib/rails/generators/active_record/migration.rb +6 -1
- data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +2 -0
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +3 -3
- data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- metadata +28 -29
- data/lib/active_record/advisory_lock_base.rb +0 -18
- data/lib/active_record/attribute_decorators.rb +0 -88
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -296
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
- data/lib/active_record/define_callbacks.rb +0 -22
- data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
- data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
- data/lib/active_record/relation/where_clause_factory.rb +0 -33
- data/lib/arel/attributes.rb +0 -22
- data/lib/arel/visitors/depth_first.rb +0 -203
- data/lib/arel/visitors/ibm_db.rb +0 -34
- data/lib/arel/visitors/informix.rb +0 -62
- data/lib/arel/visitors/mssql.rb +0 -156
- data/lib/arel/visitors/oracle.rb +0 -158
- data/lib/arel/visitors/oracle12.rb +0 -65
- data/lib/arel/visitors/where_sql.rb +0 -22
@@ -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
|
@@ -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(
|
19
|
-
relation.type_cast_for_database(
|
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?
|
data/lib/arel/nodes/unary.rb
CHANGED
data/lib/arel/predications.rb
CHANGED
@@ -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
|
data/lib/arel/select_manager.rb
CHANGED
@@ -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
|
-
|
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:
|
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
|
-
|
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(
|
100
|
-
type_caster.type_cast_for_database(
|
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?
|
data/lib/arel/visitors.rb
CHANGED
@@ -1,18 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "arel/visitors/visitor"
|
4
|
-
require "arel/visitors/depth_first"
|
5
4
|
require "arel/visitors/to_sql"
|
6
5
|
require "arel/visitors/sqlite"
|
7
6
|
require "arel/visitors/postgresql"
|
8
7
|
require "arel/visitors/mysql"
|
9
|
-
require "arel/visitors/mssql"
|
10
|
-
require "arel/visitors/oracle"
|
11
|
-
require "arel/visitors/oracle12"
|
12
|
-
require "arel/visitors/where_sql"
|
13
8
|
require "arel/visitors/dot"
|
14
|
-
require "arel/visitors/ibm_db"
|
15
|
-
require "arel/visitors/informix"
|
16
9
|
|
17
10
|
module Arel # :nodoc: all
|
18
11
|
module Visitors
|
data/lib/arel/visitors/dot.rb
CHANGED
@@ -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, "
|
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)
|
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|
|
data/lib/arel/visitors/mysql.rb
CHANGED
@@ -15,7 +15,9 @@ module Arel # :nodoc: all
|
|
15
15
|
|
16
16
|
###
|
17
17
|
# :'(
|
18
|
-
#
|
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
|
data/lib/arel/visitors/to_sql.rb
CHANGED
@@ -82,12 +82,9 @@ module Arel # :nodoc: all
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def visit_Arel_Nodes_Casted(o, collector)
|
85
|
-
collector <<
|
86
|
-
end
|
87
|
-
|
88
|
-
def visit_Arel_Nodes_Quoted(o, collector)
|
89
|
-
collector << quoted(o.expr, nil).to_s
|
85
|
+
collector << quote(o.value_for_database).to_s
|
90
86
|
end
|
87
|
+
alias :visit_Arel_Nodes_Quoted :visit_Arel_Nodes_Casted
|
91
88
|
|
92
89
|
def visit_Arel_Nodes_True(o, collector)
|
93
90
|
collector << "TRUE"
|
@@ -195,12 +192,12 @@ module Arel # :nodoc: all
|
|
195
192
|
|
196
193
|
def visit_Arel_Nodes_With(o, collector)
|
197
194
|
collector << "WITH "
|
198
|
-
|
195
|
+
collect_ctes(o.children, collector)
|
199
196
|
end
|
200
197
|
|
201
198
|
def visit_Arel_Nodes_WithRecursive(o, collector)
|
202
199
|
collector << "WITH RECURSIVE "
|
203
|
-
|
200
|
+
collect_ctes(o.children, collector)
|
204
201
|
end
|
205
202
|
|
206
203
|
def visit_Arel_Nodes_Union(o, collector)
|
@@ -324,6 +321,29 @@ module Arel # :nodoc: all
|
|
324
321
|
end
|
325
322
|
end
|
326
323
|
|
324
|
+
def visit_Arel_Nodes_HomogeneousIn(o, collector)
|
325
|
+
collector.preparable = false
|
326
|
+
|
327
|
+
collector << quote_table_name(o.table_name) << "." << quote_column_name(o.column_name)
|
328
|
+
|
329
|
+
if o.type == :in
|
330
|
+
collector << " IN ("
|
331
|
+
else
|
332
|
+
collector << " NOT IN ("
|
333
|
+
end
|
334
|
+
|
335
|
+
values = o.casted_values
|
336
|
+
|
337
|
+
if values.empty?
|
338
|
+
collector << @connection.quote(nil)
|
339
|
+
else
|
340
|
+
collector.add_binds(values, &bind_block)
|
341
|
+
end
|
342
|
+
|
343
|
+
collector << ")"
|
344
|
+
collector
|
345
|
+
end
|
346
|
+
|
327
347
|
def visit_Arel_SelectManager(o, collector)
|
328
348
|
collector << "("
|
329
349
|
visit(o.ast, collector) << ")"
|
@@ -513,64 +533,35 @@ module Arel # :nodoc: all
|
|
513
533
|
end
|
514
534
|
|
515
535
|
def visit_Arel_Nodes_In(o, collector)
|
516
|
-
|
517
|
-
|
518
|
-
end
|
519
|
-
|
520
|
-
unless o.right.empty?
|
521
|
-
o.right.delete_if { |value| unboundable?(value) }
|
522
|
-
end
|
536
|
+
collector.preparable = false
|
537
|
+
attr, values = o.left, o.right
|
523
538
|
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
if !in_clause_length || o.right.length <= in_clause_length
|
529
|
-
collect_in_clause(o.left, o.right, collector)
|
530
|
-
else
|
531
|
-
collector << "("
|
532
|
-
o.right.each_slice(in_clause_length).each_with_index do |right, i|
|
533
|
-
collector << " OR " unless i == 0
|
534
|
-
collect_in_clause(o.left, right, collector)
|
539
|
+
if Array === values
|
540
|
+
unless values.empty?
|
541
|
+
values.delete_if { |value| unboundable?(value) }
|
535
542
|
end
|
536
|
-
|
543
|
+
|
544
|
+
return collector << "1=0" if values.empty?
|
537
545
|
end
|
538
|
-
end
|
539
546
|
|
540
|
-
|
541
|
-
|
542
|
-
collector << " IN ("
|
543
|
-
visit(right, collector) << ")"
|
547
|
+
visit(attr, collector) << " IN ("
|
548
|
+
visit(values, collector) << ")"
|
544
549
|
end
|
545
550
|
|
546
551
|
def visit_Arel_Nodes_NotIn(o, collector)
|
547
|
-
|
548
|
-
|
549
|
-
end
|
550
|
-
|
551
|
-
unless o.right.empty?
|
552
|
-
o.right.delete_if { |value| unboundable?(value) }
|
553
|
-
end
|
552
|
+
collector.preparable = false
|
553
|
+
attr, values = o.left, o.right
|
554
554
|
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
if !in_clause_length || o.right.length <= in_clause_length
|
560
|
-
collect_not_in_clause(o.left, o.right, collector)
|
561
|
-
else
|
562
|
-
o.right.each_slice(in_clause_length).each_with_index do |right, i|
|
563
|
-
collector << " AND " unless i == 0
|
564
|
-
collect_not_in_clause(o.left, right, collector)
|
555
|
+
if Array === values
|
556
|
+
unless values.empty?
|
557
|
+
values.delete_if { |value| unboundable?(value) }
|
565
558
|
end
|
566
|
-
|
559
|
+
|
560
|
+
return collector << "1=1" if values.empty?
|
567
561
|
end
|
568
|
-
end
|
569
562
|
|
570
|
-
|
571
|
-
|
572
|
-
collector << " NOT IN ("
|
573
|
-
visit(right, collector) << ")"
|
563
|
+
visit(attr, collector) << " NOT IN ("
|
564
|
+
visit(values, collector) << ")"
|
574
565
|
end
|
575
566
|
|
576
567
|
def visit_Arel_Nodes_And(o, collector)
|
@@ -578,9 +569,18 @@ module Arel # :nodoc: all
|
|
578
569
|
end
|
579
570
|
|
580
571
|
def visit_Arel_Nodes_Or(o, collector)
|
581
|
-
|
582
|
-
|
583
|
-
|
572
|
+
stack = [o.right, o.left]
|
573
|
+
|
574
|
+
while o = stack.pop
|
575
|
+
if o.is_a?(Arel::Nodes::Or)
|
576
|
+
stack.push o.right, o.left
|
577
|
+
else
|
578
|
+
visit o, collector
|
579
|
+
collector << " OR " unless stack.empty?
|
580
|
+
end
|
581
|
+
end
|
582
|
+
|
583
|
+
collector
|
584
584
|
end
|
585
585
|
|
586
586
|
def visit_Arel_Nodes_Assignment(o, collector)
|
@@ -689,28 +689,23 @@ module Arel # :nodoc: all
|
|
689
689
|
join_name = o.relation.table_alias || o.relation.name
|
690
690
|
collector << quote_table_name(join_name) << "." << quote_column_name(o.name)
|
691
691
|
end
|
692
|
-
alias :visit_Arel_Attributes_Integer :visit_Arel_Attributes_Attribute
|
693
|
-
alias :visit_Arel_Attributes_Float :visit_Arel_Attributes_Attribute
|
694
|
-
alias :visit_Arel_Attributes_Decimal :visit_Arel_Attributes_Attribute
|
695
|
-
alias :visit_Arel_Attributes_String :visit_Arel_Attributes_Attribute
|
696
|
-
alias :visit_Arel_Attributes_Time :visit_Arel_Attributes_Attribute
|
697
|
-
alias :visit_Arel_Attributes_Boolean :visit_Arel_Attributes_Attribute
|
698
692
|
|
699
|
-
|
693
|
+
BIND_BLOCK = proc { "?" }
|
694
|
+
private_constant :BIND_BLOCK
|
695
|
+
|
696
|
+
def bind_block; BIND_BLOCK; end
|
700
697
|
|
701
698
|
def visit_Arel_Nodes_BindParam(o, collector)
|
702
|
-
collector.add_bind(o.value)
|
699
|
+
collector.add_bind(o.value, &bind_block)
|
703
700
|
end
|
704
701
|
|
705
|
-
|
706
|
-
|
702
|
+
def visit_Arel_Nodes_SqlLiteral(o, collector)
|
703
|
+
collector.preparable = false
|
704
|
+
collector << o.to_s
|
705
|
+
end
|
707
706
|
|
708
|
-
def
|
709
|
-
|
710
|
-
quote(a.type_cast_for_database(o))
|
711
|
-
else
|
712
|
-
quote(o)
|
713
|
-
end
|
707
|
+
def visit_Integer(o, collector)
|
708
|
+
collector << o.to_s
|
714
709
|
end
|
715
710
|
|
716
711
|
def unsupported(o, collector)
|
@@ -738,11 +733,6 @@ module Arel # :nodoc: all
|
|
738
733
|
visit o.right, collector
|
739
734
|
end
|
740
735
|
|
741
|
-
alias :visit_Arel_Nodes_Addition :visit_Arel_Nodes_InfixOperation
|
742
|
-
alias :visit_Arel_Nodes_Subtraction :visit_Arel_Nodes_InfixOperation
|
743
|
-
alias :visit_Arel_Nodes_Multiplication :visit_Arel_Nodes_InfixOperation
|
744
|
-
alias :visit_Arel_Nodes_Division :visit_Arel_Nodes_InfixOperation
|
745
|
-
|
746
736
|
def visit_Arel_Nodes_UnaryOperation(o, collector)
|
747
737
|
collector << " #{o.operator} "
|
748
738
|
visit o.expr, collector
|
@@ -883,6 +873,27 @@ module Arel # :nodoc: all
|
|
883
873
|
collector << " IS NULL)"
|
884
874
|
collector << " THEN 0 ELSE 1 END"
|
885
875
|
end
|
876
|
+
|
877
|
+
def collect_ctes(children, collector)
|
878
|
+
children.each_with_index do |child, i|
|
879
|
+
collector << ", " unless i == 0
|
880
|
+
|
881
|
+
case child
|
882
|
+
when Arel::Nodes::As
|
883
|
+
name = child.left.name
|
884
|
+
relation = child.right
|
885
|
+
when Arel::Nodes::TableAlias
|
886
|
+
name = child.name
|
887
|
+
relation = child.relation
|
888
|
+
end
|
889
|
+
|
890
|
+
collector << quote_table_name(name)
|
891
|
+
collector << " AS "
|
892
|
+
visit relation, collector
|
893
|
+
end
|
894
|
+
|
895
|
+
collector
|
896
|
+
end
|
886
897
|
end
|
887
898
|
end
|
888
899
|
end
|