activerecord 6.1.2.1 → 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 +55 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +1 -1
- data/lib/active_record/connection_adapters/abstract_adapter.rb +2 -2
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +10 -6
- data/lib/active_record/connection_adapters/mysql/quoting.rb +17 -2
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -5
- data/lib/active_record/connection_handling.rb +9 -9
- data/lib/active_record/fixtures.rb +1 -1
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/migration.rb +1 -1
- data/lib/active_record/model_schema.rb +4 -4
- data/lib/active_record/relation.rb +1 -2
- data/lib/active_record/relation/finder_methods.rb +1 -1
- data/lib/active_record/relation/predicate_builder.rb +3 -1
- data/lib/active_record/relation/where_clause.rb +5 -5
- metadata +13 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6cdd6094f92ff2d3eef67e5ab7f2a8e2a327fbdffaa1f20182fb5bdb7c803685
|
4
|
+
data.tar.gz: 197e68aa68f0946e9fcd55c7f0c2f41c237777c893b20a3a00affddbcaa1f367
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4b9b18c89048afe658359cd16b4c13c3a1eb87c8dacae3beeaf99338e2e441f64fd96bf569697cd581ea35f3068f33ee7872f733570f621a774c92b04253dc5e
|
7
|
+
data.tar.gz: 4d47d251881e21878596707b1d759f40b8b83a02e759cb1af79d8293498251a6ff3f5b11e4ecdc004ac282c6fc84437bcc60469bf0ed0a880aae1e820e20d4a1
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,58 @@
|
|
1
|
+
## Rails 6.1.3 (February 17, 2021) ##
|
2
|
+
|
3
|
+
* Fix the MySQL adapter to always set the right collation and charset
|
4
|
+
to the connection session.
|
5
|
+
|
6
|
+
*Rafael Mendonça França*
|
7
|
+
|
8
|
+
* Fix MySQL adapter handling of time objects when prepared statements
|
9
|
+
are enabled.
|
10
|
+
|
11
|
+
*Rafael Mendonça França*
|
12
|
+
|
13
|
+
* Fix scoping in enum fields using conditions that would generate
|
14
|
+
an `IN` clause.
|
15
|
+
|
16
|
+
*Ryuta Kamizono*
|
17
|
+
|
18
|
+
* Skip optimised #exist? query when #include? is called on a relation
|
19
|
+
with a having clause
|
20
|
+
|
21
|
+
Relations that have aliased select values AND a having clause that
|
22
|
+
references an aliased select value would generate an error when
|
23
|
+
#include? was called, due to an optimisation that would generate
|
24
|
+
call #exists? on the relation instead, which effectively alters
|
25
|
+
the select values of the query (and thus removes the aliased select
|
26
|
+
values), but leaves the having clause intact. Because the having
|
27
|
+
clause is then referencing an aliased column that is no longer
|
28
|
+
present in the simplified query, an ActiveRecord::InvalidStatement
|
29
|
+
error was raised.
|
30
|
+
|
31
|
+
An sample query affected by this problem:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
Author.select('COUNT(*) as total_posts', 'authors.*')
|
35
|
+
.joins(:posts)
|
36
|
+
.group(:id)
|
37
|
+
.having('total_posts > 2')
|
38
|
+
.include?(Author.first)
|
39
|
+
```
|
40
|
+
|
41
|
+
This change adds an addition check to the condition that skips the
|
42
|
+
simplified #exists? query, which simply checks for the presence of
|
43
|
+
a having clause.
|
44
|
+
|
45
|
+
Fixes #41417
|
46
|
+
|
47
|
+
*Michael Smart*
|
48
|
+
|
49
|
+
* Increment postgres prepared statement counter before making a prepared statement, so if the statement is aborted
|
50
|
+
without Rails knowledge (e.g., if app gets kill -9d during long-running query or due to Rack::Timeout), app won't end
|
51
|
+
up in perpetual crash state for being inconsistent with Postgres.
|
52
|
+
|
53
|
+
*wbharding*, *Martin Tepper*
|
54
|
+
|
55
|
+
|
1
56
|
## Rails 6.1.2.1 (February 10, 2021) ##
|
2
57
|
|
3
58
|
* Fix possible DoS vector in PostgreSQL money type
|
@@ -395,7 +395,7 @@ module ActiveRecord
|
|
395
395
|
|
396
396
|
# Inserts the given fixture into the table. Overridden in adapters that require
|
397
397
|
# something beyond a simple insert (e.g. Oracle).
|
398
|
-
# Most of adapters should implement
|
398
|
+
# Most of adapters should implement +insert_fixtures_set+ that leverages bulk SQL insert.
|
399
399
|
# We keep this method to provide fallback
|
400
400
|
# for databases like sqlite that do not support bulk inserts.
|
401
401
|
def insert_fixture(fixture, table_name)
|
@@ -116,10 +116,10 @@ module ActiveRecord
|
|
116
116
|
# Returns true if the connection is a replica.
|
117
117
|
#
|
118
118
|
# If the application is using legacy handling, returns
|
119
|
-
# true if
|
119
|
+
# true if +connection_handler.prevent_writes+ is set.
|
120
120
|
#
|
121
121
|
# If the application is using the new connection handling
|
122
|
-
# will return true based on
|
122
|
+
# will return true based on +current_preventing_writes+.
|
123
123
|
def preventing_writes?
|
124
124
|
return true if replica?
|
125
125
|
return ActiveRecord::Base.connection_handler.prevent_writes if ActiveRecord::Base.legacy_connection_handling
|
@@ -751,11 +751,6 @@ module ActiveRecord
|
|
751
751
|
wait_timeout = 2147483 unless wait_timeout.is_a?(Integer)
|
752
752
|
variables["wait_timeout"] = wait_timeout
|
753
753
|
|
754
|
-
# Set the collation of the connection character set.
|
755
|
-
if @config[:collation]
|
756
|
-
variables["collation_connection"] = @config[:collation]
|
757
|
-
end
|
758
|
-
|
759
754
|
defaults = [":default", :default].to_set
|
760
755
|
|
761
756
|
# Make MySQL reject illegal values rather than truncating or blanking them, see
|
@@ -775,6 +770,15 @@ module ActiveRecord
|
|
775
770
|
end
|
776
771
|
sql_mode_assignment = "@@SESSION.sql_mode = #{sql_mode}, " if sql_mode
|
777
772
|
|
773
|
+
# NAMES does not have an equals sign, see
|
774
|
+
# https://dev.mysql.com/doc/refman/en/set-names.html
|
775
|
+
# (trailing comma because variable_assignments will always have content)
|
776
|
+
if @config[:encoding]
|
777
|
+
encoding = +"NAMES #{@config[:encoding]}"
|
778
|
+
encoding << " COLLATE #{@config[:collation]}" if @config[:collation]
|
779
|
+
encoding << ", "
|
780
|
+
end
|
781
|
+
|
778
782
|
# Gather up all of the SET variables...
|
779
783
|
variable_assignments = variables.map do |k, v|
|
780
784
|
if defaults.include?(v)
|
@@ -786,7 +790,7 @@ module ActiveRecord
|
|
786
790
|
end.compact.join(", ")
|
787
791
|
|
788
792
|
# ...and send them all in one query
|
789
|
-
execute("SET #{sql_mode_assignment} #{variable_assignments}", "SCHEMA")
|
793
|
+
execute("SET #{encoding} #{sql_mode_assignment} #{variable_assignments}", "SCHEMA")
|
790
794
|
end
|
791
795
|
|
792
796
|
def column_definitions(table_name) # :nodoc:
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support/time_with_zone"
|
4
|
+
|
3
5
|
module ActiveRecord
|
4
6
|
module ConnectionAdapters
|
5
7
|
module MySQL
|
@@ -69,10 +71,23 @@ module ActiveRecord
|
|
69
71
|
private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
|
70
72
|
|
71
73
|
private
|
74
|
+
# Override +_type_cast+ we pass to mysql2 Date and Time objects instead
|
75
|
+
# of Strings since mysql2 is able to handle those classes more efficiently.
|
72
76
|
def _type_cast(value)
|
73
77
|
case value
|
74
|
-
when
|
75
|
-
|
78
|
+
when ActiveSupport::TimeWithZone
|
79
|
+
# We need to check explicitly for ActiveSupport::TimeWithZone because
|
80
|
+
# we need to transform it to Time objects but we don't want to
|
81
|
+
# transform Time objects to themselves.
|
82
|
+
if ActiveRecord::Base.default_timezone == :utc
|
83
|
+
value.getutc
|
84
|
+
else
|
85
|
+
value.getlocal
|
86
|
+
end
|
87
|
+
when Date, Time
|
88
|
+
value
|
89
|
+
else
|
90
|
+
super
|
76
91
|
end
|
77
92
|
end
|
78
93
|
end
|
@@ -114,7 +114,7 @@ module ActiveRecord
|
|
114
114
|
#
|
115
115
|
# If only a role is passed, Active Record will look up the connection
|
116
116
|
# based on the requested role. If a non-established role is requested
|
117
|
-
# an
|
117
|
+
# an +ActiveRecord::ConnectionNotEstablished+ error will be raised:
|
118
118
|
#
|
119
119
|
# ActiveRecord::Base.connected_to(role: :writing) do
|
120
120
|
# Dog.create! # creates dog using dog writing connection
|
@@ -125,7 +125,7 @@ module ActiveRecord
|
|
125
125
|
# end
|
126
126
|
#
|
127
127
|
# When swapping to a shard, the role must be passed as well. If a non-existent
|
128
|
-
# shard is passed, an
|
128
|
+
# shard is passed, an +ActiveRecord::ConnectionNotEstablished+ error will be
|
129
129
|
# raised.
|
130
130
|
#
|
131
131
|
# When a shard and role is passed, Active Record will first lookup the role,
|
@@ -178,11 +178,11 @@ module ActiveRecord
|
|
178
178
|
end
|
179
179
|
end
|
180
180
|
|
181
|
-
# Connects a role and/or shard to the provided connection names. Optionally
|
182
|
-
# can be passed to block writes on a connection.
|
183
|
-
#
|
181
|
+
# Connects a role and/or shard to the provided connection names. Optionally +prevent_writes+
|
182
|
+
# can be passed to block writes on a connection. +reading+ will automatically set
|
183
|
+
# +prevent_writes+ to true.
|
184
184
|
#
|
185
|
-
#
|
185
|
+
# +connected_to_many+ is an alternative to deeply nested +connected_to+ blocks.
|
186
186
|
#
|
187
187
|
# Usage:
|
188
188
|
#
|
@@ -216,7 +216,7 @@ module ActiveRecord
|
|
216
216
|
# being used. For example, when booting a console in readonly mode.
|
217
217
|
#
|
218
218
|
# It is not recommended to use this method in a request since it
|
219
|
-
# does not yield to a block like
|
219
|
+
# does not yield to a block like +connected_to+.
|
220
220
|
def connecting_to(role: default_role, shard: default_shard, prevent_writes: false)
|
221
221
|
if legacy_connection_handling
|
222
222
|
raise NotImplementedError, "`connecting_to` is not available with `legacy_connection_handling`."
|
@@ -230,13 +230,13 @@ module ActiveRecord
|
|
230
230
|
# Prevent writing to the database regardless of role.
|
231
231
|
#
|
232
232
|
# In some cases you may want to prevent writes to the database
|
233
|
-
# even if you are on a database that can write.
|
233
|
+
# even if you are on a database that can write. +while_preventing_writes+
|
234
234
|
# will prevent writes to the database for the duration of the block.
|
235
235
|
#
|
236
236
|
# This method does not provide the same protection as a readonly
|
237
237
|
# user and is meant to be a safeguard against accidental writes.
|
238
238
|
#
|
239
|
-
# See
|
239
|
+
# See +READ_QUERY+ for the queries that are blocked by this
|
240
240
|
# method.
|
241
241
|
def while_preventing_writes(enabled = true, &block)
|
242
242
|
if legacy_connection_handling
|
@@ -181,7 +181,7 @@ module ActiveRecord
|
|
181
181
|
# end
|
182
182
|
# end
|
183
183
|
#
|
184
|
-
# If you preload your test database with all fixture data (probably by running
|
184
|
+
# If you preload your test database with all fixture data (probably by running <tt>bin/rails db:fixtures:load</tt>)
|
185
185
|
# and use transactional tests, then you may omit all fixtures declarations in your test cases since
|
186
186
|
# all the data's already there and every case rolls back its changes.
|
187
187
|
#
|
@@ -320,7 +320,7 @@ module ActiveRecord
|
|
320
320
|
# +table_name+. Passing a hash containing <tt>:from</tt> and <tt>:to</tt>
|
321
321
|
# as +default_or_changes+ will make this change reversible in the migration.
|
322
322
|
# * <tt>change_column_null(table_name, column_name, null, default = nil)</tt>:
|
323
|
-
# Sets or removes a
|
323
|
+
# Sets or removes a <tt>NOT NULL</tt> constraint on +column_name+. The +null+ flag
|
324
324
|
# indicates whether the value can be +NULL+. See
|
325
325
|
# ActiveRecord::ConnectionAdapters::SchemaStatements#change_column_null for
|
326
326
|
# details.
|
@@ -122,9 +122,9 @@ module ActiveRecord
|
|
122
122
|
# :singleton-method: immutable_strings_by_default=
|
123
123
|
# :call-seq: immutable_strings_by_default=(bool)
|
124
124
|
#
|
125
|
-
# Determines whether columns should infer their type as
|
126
|
-
#
|
127
|
-
#
|
125
|
+
# Determines whether columns should infer their type as +:string+ or
|
126
|
+
# +:immutable_string+. This setting does not affect the behavior of
|
127
|
+
# <tt>attribute :foo, :string</tt>. Defaults to false.
|
128
128
|
|
129
129
|
included do
|
130
130
|
mattr_accessor :primary_key_prefix_type, instance_writer: false
|
@@ -316,7 +316,7 @@ module ActiveRecord
|
|
316
316
|
# self.ignored_columns = [:category]
|
317
317
|
# end
|
318
318
|
#
|
319
|
-
# The schema still contains
|
319
|
+
# The schema still contains "category", but now the model omits it, so any meta-driven code or
|
320
320
|
# schema caching will not attempt to use the column:
|
321
321
|
#
|
322
322
|
# Project.columns_hash["category"] => nil
|
@@ -683,8 +683,7 @@ module ActiveRecord
|
|
683
683
|
end
|
684
684
|
|
685
685
|
def scope_for_create
|
686
|
-
hash =
|
687
|
-
hash.delete(klass.inheritance_column) if klass.finder_needs_type_condition?
|
686
|
+
hash = where_clause.to_h(klass.table_name, equality_only: true)
|
688
687
|
create_with_value.each { |k, v| hash[k.to_s] = v } unless create_with_value.empty?
|
689
688
|
hash
|
690
689
|
end
|
@@ -326,7 +326,7 @@ module ActiveRecord
|
|
326
326
|
# compared to the records in memory. If the relation is unloaded, an
|
327
327
|
# efficient existence query is performed, as in #exists?.
|
328
328
|
def include?(record)
|
329
|
-
if loaded? || offset_value || limit_value
|
329
|
+
if loaded? || offset_value || limit_value || having_clause.any?
|
330
330
|
records.include?(record)
|
331
331
|
else
|
332
332
|
record.is_a?(klass) && exists?(record.id)
|
@@ -103,7 +103,9 @@ module ActiveRecord
|
|
103
103
|
|
104
104
|
klass ||= AssociationQueryValue
|
105
105
|
queries = klass.new(associated_table, value).queries.map! do |query|
|
106
|
-
|
106
|
+
# If the query produced is identical to attributes don't go any deeper.
|
107
|
+
# Prevents stack level too deep errors when association and foreign_key are identical.
|
108
|
+
query == attributes ? self[key, value] : expand_from_hash(query)
|
107
109
|
end
|
108
110
|
|
109
111
|
grouping_queries(queries)
|
@@ -58,8 +58,8 @@ module ActiveRecord
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
def to_h(table_name = nil)
|
62
|
-
equalities(predicates).each_with_object({}) do |node, hash|
|
61
|
+
def to_h(table_name = nil, equality_only: false)
|
62
|
+
equalities(predicates, equality_only).each_with_object({}) do |node, hash|
|
63
63
|
next if table_name&.!= node.left.relation.name
|
64
64
|
name = node.left.name.to_s
|
65
65
|
value = extract_node_value(node.right)
|
@@ -134,14 +134,14 @@ module ActiveRecord
|
|
134
134
|
attr_node
|
135
135
|
end
|
136
136
|
|
137
|
-
def equalities(predicates)
|
137
|
+
def equalities(predicates, equality_only)
|
138
138
|
equalities = []
|
139
139
|
|
140
140
|
predicates.each do |node|
|
141
|
-
if equality_node?(node)
|
141
|
+
if equality_only ? Arel::Nodes::Equality === node : equality_node?(node)
|
142
142
|
equalities << node
|
143
143
|
elsif node.is_a?(Arel::Nodes::And)
|
144
|
-
equalities.concat equalities(node.children)
|
144
|
+
equalities.concat equalities(node.children, equality_only)
|
145
145
|
end
|
146
146
|
end
|
147
147
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.1.
|
4
|
+
version: 6.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-02-
|
11
|
+
date: 2021-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 6.1.
|
19
|
+
version: 6.1.3
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 6.1.
|
26
|
+
version: 6.1.3
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activemodel
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 6.1.
|
33
|
+
version: 6.1.3
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 6.1.
|
40
|
+
version: 6.1.3
|
41
41
|
description: Databases on Rails. Build a persistent domain model by mapping database
|
42
42
|
tables to Ruby classes. Strong conventions for associations, validations, aggregations,
|
43
43
|
migrations, and testing come baked-in.
|
@@ -390,11 +390,11 @@ licenses:
|
|
390
390
|
- MIT
|
391
391
|
metadata:
|
392
392
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
393
|
-
changelog_uri: https://github.com/rails/rails/blob/v6.1.
|
394
|
-
documentation_uri: https://api.rubyonrails.org/v6.1.
|
393
|
+
changelog_uri: https://github.com/rails/rails/blob/v6.1.3/activerecord/CHANGELOG.md
|
394
|
+
documentation_uri: https://api.rubyonrails.org/v6.1.3/
|
395
395
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
396
|
-
source_code_uri: https://github.com/rails/rails/tree/v6.1.
|
397
|
-
post_install_message:
|
396
|
+
source_code_uri: https://github.com/rails/rails/tree/v6.1.3/activerecord
|
397
|
+
post_install_message:
|
398
398
|
rdoc_options:
|
399
399
|
- "--main"
|
400
400
|
- README.rdoc
|
@@ -411,8 +411,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
411
411
|
- !ruby/object:Gem::Version
|
412
412
|
version: '0'
|
413
413
|
requirements: []
|
414
|
-
rubygems_version: 3.
|
415
|
-
signing_key:
|
414
|
+
rubygems_version: 3.2.3
|
415
|
+
signing_key:
|
416
416
|
specification_version: 4
|
417
417
|
summary: Object-relational mapper framework (part of Rails).
|
418
418
|
test_files: []
|