activerecord 7.0.0.rc3 → 7.0.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +200 -3
- data/MIT-LICENSE +1 -1
- data/lib/active_record/associations/join_dependency.rb +6 -2
- data/lib/active_record/associations.rb +29 -8
- data/lib/active_record/attribute_methods.rb +1 -1
- data/lib/active_record/autosave_association.rb +2 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +4 -4
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +9 -4
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +3 -1
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +7 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +1 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +9 -4
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +2 -2
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +13 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +12 -12
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +28 -0
- data/lib/active_record/database_configurations/connection_url_resolver.rb +1 -0
- data/lib/active_record/database_configurations.rb +1 -1
- data/lib/active_record/encryption/configurable.rb +2 -2
- data/lib/active_record/encryption/encryptable_record.rb +1 -1
- data/lib/active_record/encryption/extended_deterministic_queries.rb +28 -28
- data/lib/active_record/fixtures.rb +1 -1
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/integration.rb +2 -2
- data/lib/active_record/migration/compatibility.rb +24 -2
- data/lib/active_record/migration.rb +1 -1
- data/lib/active_record/railtie.rb +2 -2
- data/lib/active_record/reflection.rb +1 -1
- data/lib/active_record/relation/calculations.rb +3 -2
- data/lib/active_record/relation/delegation.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +19 -5
- data/lib/active_record/relation.rb +17 -4
- data/lib/active_record/schema.rb +38 -23
- data/lib/active_record/schema_dumper.rb +15 -16
- data/lib/active_record/schema_migration.rb +4 -0
- data/lib/active_record/tasks/database_tasks.rb +6 -2
- data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -1
- data/lib/active_record.rb +1 -1
- data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
- data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
- metadata +14 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b892baa52df60baaecc7813d5c9988f540289629ffcefdae8d83a40b9d9b3724
|
4
|
+
data.tar.gz: ec575b7c8f32e41bd93218735a0ca966bbcac5b9ff22bc503b63bf24b70081d3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e9d267301499c076f46c5bc4b131cb27e2b4039bb2926a275c0a43a7ca313e31c6e7b667ee27f9c9ec7954cc3bd3655788c0b20ab395dd43a64fdb5e7547bdf
|
7
|
+
data.tar.gz: 30a63818a8216ccf2a66e6e86563304009fa8195deb72c5052f10b00839df6eb4eb6cf4456dad9512b5a2497a08cc844a9acf9388b6df0bb44b6fb36aae24b71
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,194 @@
|
|
1
|
+
## Rails 7.0.2.1 (February 11, 2022) ##
|
2
|
+
|
3
|
+
* No changes.
|
4
|
+
|
5
|
+
|
6
|
+
## Rails 7.0.2 (February 08, 2022) ##
|
7
|
+
|
8
|
+
* Fix `PG.connect` keyword arguments deprecation warning on ruby 2.7.
|
9
|
+
|
10
|
+
*Nikita Vasilevsky*
|
11
|
+
|
12
|
+
* Fix the ability to exclude encryption params from being autofiltered.
|
13
|
+
|
14
|
+
*Mark Gangl*
|
15
|
+
|
16
|
+
* Dump the precision for datetime columns following the new defaults.
|
17
|
+
|
18
|
+
*Rafael Mendonça França*
|
19
|
+
|
20
|
+
* Make sure encrypted attributes are not being filtered twice.
|
21
|
+
|
22
|
+
*Nikita Vasilevsky*
|
23
|
+
|
24
|
+
* Dump the database schema containing the current Rails version.
|
25
|
+
|
26
|
+
Since https://github.com/rails/rails/pull/42297, Rails now generate datetime columns
|
27
|
+
with a default precision of 6. This means that users upgrading to Rails 7.0 from 6.1,
|
28
|
+
when loading the database schema, would get the new precision value, which would not match
|
29
|
+
the production schema.
|
30
|
+
|
31
|
+
To avoid this the schema dumper will generate the new format which will include the Rails
|
32
|
+
version and will look like this:
|
33
|
+
|
34
|
+
```
|
35
|
+
ActiveRecord::Schema[7.0].define
|
36
|
+
```
|
37
|
+
|
38
|
+
When upgrading from Rails 6.1 to Rails 7.0, you can run the `rails app:update` task that will
|
39
|
+
set the current schema version to 6.1.
|
40
|
+
|
41
|
+
*Rafael Mendonça França*
|
42
|
+
|
43
|
+
* Fix parsing expression for PostgreSQL generated column.
|
44
|
+
|
45
|
+
*fatkodima*
|
46
|
+
|
47
|
+
* Fix `Mysql2::Error: Commands out of sync; you can't run this command now`
|
48
|
+
when bulk-inserting fixtures that exceed `max_allowed_packet` configuration.
|
49
|
+
|
50
|
+
*Nikita Vasilevsky*
|
51
|
+
|
52
|
+
* Fix error when saving an association with a relation named `record`.
|
53
|
+
|
54
|
+
*Dorian Marié*
|
55
|
+
|
56
|
+
* Fix `MySQL::SchemaDumper` behavior about datetime precision value.
|
57
|
+
|
58
|
+
*y0t4*
|
59
|
+
|
60
|
+
* Improve associated with no reflection error.
|
61
|
+
|
62
|
+
*Nikolai*
|
63
|
+
|
64
|
+
* Fix PG.connect keyword arguments deprecation warning on ruby 2.7.
|
65
|
+
|
66
|
+
Fixes #44307.
|
67
|
+
|
68
|
+
*Nikita Vasilevsky*
|
69
|
+
|
70
|
+
* Fix passing options to `check_constraint` from `change_table`.
|
71
|
+
|
72
|
+
*Frederick Cheung*
|
73
|
+
|
74
|
+
|
75
|
+
## Rails 7.0.1 (January 06, 2022) ##
|
76
|
+
|
77
|
+
|
78
|
+
* Change `QueryMethods#in_order_of` to drop records not listed in values.
|
79
|
+
|
80
|
+
`in_order_of` now filters down to the values provided, to match the behavior of the `Enumerable` version.
|
81
|
+
|
82
|
+
*Kevin Newton*
|
83
|
+
|
84
|
+
* Allow named expression indexes to be revertible.
|
85
|
+
|
86
|
+
Previously, the following code would raise an error in a reversible migration executed while rolling back, due to the index name not being used in the index removal.
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
add_index(:settings, "(data->'property')", using: :gin, name: :index_settings_data_property)
|
90
|
+
```
|
91
|
+
|
92
|
+
Fixes #43331.
|
93
|
+
|
94
|
+
*Oliver Günther*
|
95
|
+
|
96
|
+
* Better error messages when association name is invalid in the argument of `ActiveRecord::QueryMethods::WhereChain#missing`.
|
97
|
+
|
98
|
+
*ykpythemind*
|
99
|
+
|
100
|
+
* Fix ordered migrations for single db in multi db environment.
|
101
|
+
|
102
|
+
*Himanshu*
|
103
|
+
|
104
|
+
* Extract `on update CURRENT_TIMESTAMP` for mysql2 adapter.
|
105
|
+
|
106
|
+
*Kazuhiro Masuda*
|
107
|
+
|
108
|
+
* Fix incorrect argument in PostgreSQL structure dump tasks.
|
109
|
+
|
110
|
+
Updating the `--no-comment` argument added in Rails 7 to the correct `--no-comments` argument.
|
111
|
+
|
112
|
+
*Alex Dent*
|
113
|
+
|
114
|
+
* Fix schema dumping column default SQL values for sqlite3.
|
115
|
+
|
116
|
+
*fatkodima*
|
117
|
+
|
118
|
+
* Correctly parse complex check constraint expressions for PostgreSQL.
|
119
|
+
|
120
|
+
*fatkodima*
|
121
|
+
|
122
|
+
* Fix `timestamptz` attributes on PostgreSQL handle blank inputs.
|
123
|
+
|
124
|
+
*Alex Ghiculescu*
|
125
|
+
|
126
|
+
* Fix migration compatibility to create SQLite references/belongs_to column as integer when migration version is 6.0.
|
127
|
+
|
128
|
+
Reference/belongs_to in migrations with version 6.0 were creating columns as
|
129
|
+
bigint instead of integer for the SQLite Adapter.
|
130
|
+
|
131
|
+
*Marcelo Lauxen*
|
132
|
+
|
133
|
+
* Fix joining through a polymorphic association.
|
134
|
+
|
135
|
+
*Alexandre Ruban*
|
136
|
+
|
137
|
+
* Fix `QueryMethods#in_order_of` to handle empty order list.
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
Post.in_order_of(:id, []).to_a
|
141
|
+
```
|
142
|
+
|
143
|
+
Also more explicitly set the column as secondary order, so that any other
|
144
|
+
value is still ordered.
|
145
|
+
|
146
|
+
*Jean Boussier*
|
147
|
+
|
148
|
+
* Fix `rails dbconsole` for 3-tier config.
|
149
|
+
|
150
|
+
*Eileen M. Uchitelle*
|
151
|
+
|
152
|
+
* Fix quoting of column aliases generated by calculation methods.
|
153
|
+
|
154
|
+
Since the alias is derived from the table name, we can't assume the result
|
155
|
+
is a valid identifier.
|
156
|
+
|
157
|
+
```ruby
|
158
|
+
class Test < ActiveRecord::Base
|
159
|
+
self.table_name = '1abc'
|
160
|
+
end
|
161
|
+
Test.group(:id).count
|
162
|
+
# syntax error at or near "1" (ActiveRecord::StatementInvalid)
|
163
|
+
# LINE 1: SELECT COUNT(*) AS count_all, "1abc"."id" AS 1abc_id FROM "1...
|
164
|
+
```
|
165
|
+
|
166
|
+
*Jean Boussier*
|
167
|
+
|
168
|
+
|
169
|
+
## Rails 7.0.0 (December 15, 2021) ##
|
170
|
+
|
171
|
+
* Better handle SQL queries with invalid encoding.
|
172
|
+
|
173
|
+
```ruby
|
174
|
+
Post.create(name: "broken \xC8 UTF-8")
|
175
|
+
```
|
176
|
+
|
177
|
+
Would cause all adapters to fail in a non controlled way in the code
|
178
|
+
responsible to detect write queries.
|
179
|
+
|
180
|
+
The query is now properly passed to the database connection, which might or might
|
181
|
+
not be able to handle it, but will either succeed or failed in a more correct way.
|
182
|
+
|
183
|
+
*Jean Boussier*
|
184
|
+
|
185
|
+
* Move database and shard selection config options to a generator.
|
186
|
+
|
187
|
+
Rather than generating the config options in `production.rb` when applications are created, applications can now run a generator to create an initializer and uncomment / update options as needed. All multi-db configuration can be implemented in this initializer.
|
188
|
+
|
189
|
+
*Eileen M. Uchitelle*
|
190
|
+
|
191
|
+
|
1
192
|
## Rails 7.0.0.rc3 (December 14, 2021) ##
|
2
193
|
|
3
194
|
* No changes.
|
@@ -5,6 +196,11 @@
|
|
5
196
|
|
6
197
|
## Rails 7.0.0.rc2 (December 14, 2021) ##
|
7
198
|
|
199
|
+
* No changes.
|
200
|
+
|
201
|
+
|
202
|
+
## Rails 7.0.0.rc1 (December 06, 2021) ##
|
203
|
+
|
8
204
|
* Remove deprecated `ActiveRecord::DatabaseConfigurations::DatabaseConfig#spec_name`.
|
9
205
|
|
10
206
|
*Rafael Mendonça França*
|
@@ -312,7 +508,6 @@
|
|
312
508
|
|
313
509
|
Applications may now set their the filename or path of the schema / structure dump file in their database configuration.
|
314
510
|
|
315
|
-
|
316
511
|
```yaml
|
317
512
|
production:
|
318
513
|
primary:
|
@@ -399,6 +594,8 @@
|
|
399
594
|
`#with_lock` now accepts transaction options like `requires_new:`,
|
400
595
|
`isolation:`, and `joinable:`
|
401
596
|
|
597
|
+
*John Mileham*
|
598
|
+
|
402
599
|
* Adds support for deferrable foreign key constraints in PostgreSQL.
|
403
600
|
|
404
601
|
By default, foreign key constraints in PostgreSQL are checked after each statement. This works for most use cases,
|
@@ -475,7 +672,7 @@
|
|
475
672
|
|
476
673
|
*Alex Ghiculescu*
|
477
674
|
|
478
|
-
*
|
675
|
+
* Avoid COMMENT statements in PostgreSQL structure dumps
|
479
676
|
|
480
677
|
COMMENT statements are now omitted from the output of `db:structure:dump` when using PostgreSQL >= 11.
|
481
678
|
This allows loading the dump without a pgsql superuser account.
|
@@ -528,7 +725,7 @@
|
|
528
725
|
|
529
726
|
*Sam Bostock*
|
530
727
|
|
531
|
-
*
|
728
|
+
* Add ssl support for postgresql database tasks
|
532
729
|
|
533
730
|
Add `PGSSLMODE`, `PGSSLCERT`, `PGSSLKEY` and `PGSSLROOTCERT` to pg_env from database config
|
534
731
|
when running postgresql database tasks.
|
data/MIT-LICENSE
CHANGED
@@ -3,8 +3,12 @@
|
|
3
3
|
module ActiveRecord
|
4
4
|
module Associations
|
5
5
|
class JoinDependency # :nodoc:
|
6
|
-
|
7
|
-
|
6
|
+
extend ActiveSupport::Autoload
|
7
|
+
|
8
|
+
eager_autoload do
|
9
|
+
autoload :JoinBase
|
10
|
+
autoload :JoinAssociation
|
11
|
+
end
|
8
12
|
|
9
13
|
class Aliases # :nodoc:
|
10
14
|
def initialize(tables)
|
@@ -290,6 +290,7 @@ module ActiveRecord
|
|
290
290
|
def self.eager_load!
|
291
291
|
super
|
292
292
|
Preloader.eager_load!
|
293
|
+
JoinDependency.eager_load!
|
293
294
|
end
|
294
295
|
|
295
296
|
# Returns the association instance for the given name, instantiating it if it doesn't already exist
|
@@ -594,19 +595,27 @@ module ActiveRecord
|
|
594
595
|
# you can also define callbacks that get triggered when you add an object to or remove an
|
595
596
|
# object from an association collection.
|
596
597
|
#
|
597
|
-
# class
|
598
|
-
#
|
598
|
+
# class Firm < ActiveRecord::Base
|
599
|
+
# has_many :clients,
|
600
|
+
# dependent: :destroy,
|
601
|
+
# after_add: :congratulate_client,
|
602
|
+
# after_remove: :log_after_remove
|
599
603
|
#
|
600
|
-
# def
|
601
|
-
# ...
|
604
|
+
# def congratulate_client(record)
|
605
|
+
# # ...
|
606
|
+
# end
|
607
|
+
#
|
608
|
+
# def log_after_remove(record)
|
609
|
+
# # ...
|
602
610
|
# end
|
603
|
-
# end
|
604
611
|
#
|
605
612
|
# It's possible to stack callbacks by passing them as an array. Example:
|
606
613
|
#
|
607
|
-
# class
|
608
|
-
#
|
609
|
-
#
|
614
|
+
# class Firm < ActiveRecord::Base
|
615
|
+
# has_many :clients,
|
616
|
+
# dependent: :destroy,
|
617
|
+
# after_add: [:congratulate_client, -> (firm, record) { firm.log << "after_adding#{record.id}" }],
|
618
|
+
# after_remove: :log_after_remove
|
610
619
|
# end
|
611
620
|
#
|
612
621
|
# Possible callbacks are: +before_add+, +after_add+, +before_remove+ and +after_remove+.
|
@@ -617,6 +626,18 @@ module ActiveRecord
|
|
617
626
|
# Similarly, if any of the +before_remove+ callbacks throw an exception, the object
|
618
627
|
# will not be removed from the collection.
|
619
628
|
#
|
629
|
+
# Note: To trigger remove callbacks, you must use +destroy+ / +destroy_all+ methods. For example:
|
630
|
+
#
|
631
|
+
# * <tt>firm.clients.destroy(client)</tt>
|
632
|
+
# * <tt>firm.clients.destroy(*clients)</tt>
|
633
|
+
# * <tt>firm.clients.destroy_all</tt>
|
634
|
+
#
|
635
|
+
# +delete+ / +delete_all+ methods like the following do *not* trigger remove callbacks:
|
636
|
+
#
|
637
|
+
# * <tt>firm.clients.delete(client)</tt>
|
638
|
+
# * <tt>firm.clients.delete(*clients)</tt>
|
639
|
+
# * <tt>firm.clients.delete_all</tt>
|
640
|
+
#
|
620
641
|
# == Association extensions
|
621
642
|
#
|
622
643
|
# The proxy objects that control the access to associations can be extended through anonymous
|
@@ -413,7 +413,7 @@ module ActiveRecord
|
|
413
413
|
inspected_value = if value.is_a?(String) && value.length > 50
|
414
414
|
"#{value[0, 50]}...".inspect
|
415
415
|
elsif value.is_a?(Date) || value.is_a?(Time)
|
416
|
-
%("#{value.
|
416
|
+
%("#{value.to_fs(:inspect)}")
|
417
417
|
else
|
418
418
|
value.inspect
|
419
419
|
end
|
@@ -446,7 +446,7 @@ module ActiveRecord
|
|
446
446
|
elsif autosave != false
|
447
447
|
key = reflection.options[:primary_key] ? public_send(reflection.options[:primary_key]) : id
|
448
448
|
|
449
|
-
if (autosave && record.changed_for_autosave?) ||
|
449
|
+
if (autosave && record.changed_for_autosave?) || _record_changed?(reflection, record, key)
|
450
450
|
unless reflection.through_reflection
|
451
451
|
record[reflection.foreign_key] = key
|
452
452
|
association.set_inverse_instance(record)
|
@@ -461,7 +461,7 @@ module ActiveRecord
|
|
461
461
|
end
|
462
462
|
|
463
463
|
# If the record is new or it has changed, returns true.
|
464
|
-
def
|
464
|
+
def _record_changed?(reflection, record, key)
|
465
465
|
record.new_record? ||
|
466
466
|
association_foreign_key_changed?(reflection, record, key) ||
|
467
467
|
record.will_save_change_to_attribute?(reflection.foreign_key)
|
@@ -810,8 +810,8 @@ module ActiveRecord
|
|
810
810
|
# t.check_constraint("price > 0", name: "price_check")
|
811
811
|
#
|
812
812
|
# See {connection.add_check_constraint}[rdoc-ref:SchemaStatements#add_check_constraint]
|
813
|
-
def check_constraint(*args)
|
814
|
-
@base.add_check_constraint(name, *args)
|
813
|
+
def check_constraint(*args, **options)
|
814
|
+
@base.add_check_constraint(name, *args, **options)
|
815
815
|
end
|
816
816
|
|
817
817
|
# Removes the given check constraint from the table.
|
@@ -819,8 +819,8 @@ module ActiveRecord
|
|
819
819
|
# t.remove_check_constraint(name: "price_check")
|
820
820
|
#
|
821
821
|
# See {connection.remove_check_constraint}[rdoc-ref:SchemaStatements#remove_check_constraint]
|
822
|
-
def remove_check_constraint(*args)
|
823
|
-
@base.remove_check_constraint(name, *args)
|
822
|
+
def remove_check_constraint(*args, **options)
|
823
|
+
@base.remove_check_constraint(name, *args, **options)
|
824
824
|
end
|
825
825
|
end
|
826
826
|
end
|
@@ -3,6 +3,8 @@
|
|
3
3
|
module ActiveRecord
|
4
4
|
module ConnectionAdapters # :nodoc:
|
5
5
|
class SchemaDumper < SchemaDumper # :nodoc:
|
6
|
+
DEFAULT_DATETIME_PRECISION = 6 # :nodoc:
|
7
|
+
|
6
8
|
def self.create(connection, options)
|
7
9
|
new(connection, options)
|
8
10
|
end
|
@@ -63,7 +65,18 @@ module ActiveRecord
|
|
63
65
|
end
|
64
66
|
|
65
67
|
def schema_precision(column)
|
66
|
-
column.
|
68
|
+
if column.type == :datetime
|
69
|
+
case column.precision
|
70
|
+
when nil
|
71
|
+
"nil"
|
72
|
+
when DEFAULT_DATETIME_PRECISION
|
73
|
+
nil
|
74
|
+
else
|
75
|
+
column.precision.inspect
|
76
|
+
end
|
77
|
+
elsif column.precision
|
78
|
+
column.precision.inspect
|
79
|
+
end
|
67
80
|
end
|
68
81
|
|
69
82
|
def schema_scale(column)
|
@@ -1438,7 +1438,7 @@ module ActiveRecord
|
|
1438
1438
|
|
1439
1439
|
checks = []
|
1440
1440
|
|
1441
|
-
if !options.key?(:name) &&
|
1441
|
+
if !options.key?(:name) && expression_column_name?(column_name)
|
1442
1442
|
options[:name] = index_name(table_name, column_name)
|
1443
1443
|
column_names = []
|
1444
1444
|
else
|
@@ -1447,7 +1447,7 @@ module ActiveRecord
|
|
1447
1447
|
|
1448
1448
|
checks << lambda { |i| i.name == options[:name].to_s } if options.key?(:name)
|
1449
1449
|
|
1450
|
-
if column_names.present?
|
1450
|
+
if column_names.present? && !(options.key?(:name) && expression_column_name?(column_names))
|
1451
1451
|
checks << lambda { |i| index_name(table_name, i.columns) == index_name(table_name, column_names) }
|
1452
1452
|
end
|
1453
1453
|
|
@@ -1515,7 +1515,7 @@ module ActiveRecord
|
|
1515
1515
|
end
|
1516
1516
|
|
1517
1517
|
def index_column_names(column_names)
|
1518
|
-
if
|
1518
|
+
if expression_column_name?(column_names)
|
1519
1519
|
column_names
|
1520
1520
|
else
|
1521
1521
|
Array(column_names)
|
@@ -1523,13 +1523,18 @@ module ActiveRecord
|
|
1523
1523
|
end
|
1524
1524
|
|
1525
1525
|
def index_name_options(column_names)
|
1526
|
-
if
|
1526
|
+
if expression_column_name?(column_names)
|
1527
1527
|
column_names = column_names.scan(/\w+/).join("_")
|
1528
1528
|
end
|
1529
1529
|
|
1530
1530
|
{ column: column_names }
|
1531
1531
|
end
|
1532
1532
|
|
1533
|
+
# Try to identify whether the given column name is an expression
|
1534
|
+
def expression_column_name?(column_name)
|
1535
|
+
column_name.is_a?(String) && /\W/.match?(column_name)
|
1536
|
+
end
|
1537
|
+
|
1533
1538
|
def strip_table_name_prefix_and_suffix(table_name)
|
1534
1539
|
prefix = Base.table_name_prefix
|
1535
1540
|
suffix = Base.table_name_suffix
|
@@ -197,7 +197,7 @@ module ActiveRecord
|
|
197
197
|
|
198
198
|
# Executes the SQL statement in the context of this connection.
|
199
199
|
def execute(sql, name = nil, async: false)
|
200
|
-
raw_execute(sql, name, async)
|
200
|
+
raw_execute(sql, name, async: async)
|
201
201
|
end
|
202
202
|
|
203
203
|
# Mysql2Adapter doesn't have to free a result after using it, but we use this method
|
@@ -26,6 +26,8 @@ module ActiveRecord
|
|
26
26
|
|
27
27
|
def write_query?(sql) # :nodoc:
|
28
28
|
!READ_QUERY.match?(sql)
|
29
|
+
rescue ArgumentError # Invalid encoding
|
30
|
+
!READ_QUERY.match?(sql.b)
|
29
31
|
end
|
30
32
|
|
31
33
|
def explain(arel, binds = [])
|
@@ -98,8 +100,8 @@ module ActiveRecord
|
|
98
100
|
statements = statements.map { |sql| transform_query(sql) }
|
99
101
|
combine_multi_statements(statements).each do |statement|
|
100
102
|
raw_execute(statement, name)
|
103
|
+
@connection.abandon_results!
|
101
104
|
end
|
102
|
-
@connection.abandon_results!
|
103
105
|
end
|
104
106
|
|
105
107
|
def default_insert_value(column)
|
@@ -53,7 +53,13 @@ module ActiveRecord
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def schema_precision(column)
|
56
|
-
|
56
|
+
if /\Atime(?:stamp)?\b/.match?(column.sql_type) && column.precision == 0
|
57
|
+
nil
|
58
|
+
elsif column.type == :datetime
|
59
|
+
column.precision == 0 ? "nil" : super
|
60
|
+
else
|
61
|
+
super
|
62
|
+
end
|
57
63
|
end
|
58
64
|
|
59
65
|
def schema_collation(column)
|
@@ -163,6 +163,7 @@ module ActiveRecord
|
|
163
163
|
default, default_function = field[:Default], nil
|
164
164
|
|
165
165
|
if type_metadata.type == :datetime && /\ACURRENT_TIMESTAMP(?:\([0-6]?\))?\z/i.match?(default)
|
166
|
+
default = "#{default} ON UPDATE #{default}" if /on update CURRENT_TIMESTAMP/i.match?(field[:Extra])
|
166
167
|
default, default_function = nil, default
|
167
168
|
elsif type_metadata.extra == "DEFAULT_GENERATED"
|
168
169
|
default = +"(#{default})" unless default.start_with?("(")
|
@@ -525,7 +525,7 @@ module ActiveRecord
|
|
525
525
|
scope = quoted_scope(table_name)
|
526
526
|
|
527
527
|
check_info = exec_query(<<-SQL, "SCHEMA")
|
528
|
-
SELECT conname, pg_get_constraintdef(c.oid) AS constraintdef, c.convalidated AS valid
|
528
|
+
SELECT conname, pg_get_constraintdef(c.oid, true) AS constraintdef, c.convalidated AS valid
|
529
529
|
FROM pg_constraint c
|
530
530
|
JOIN pg_class t ON c.conrelid = t.oid
|
531
531
|
WHERE c.contype = 'c'
|
@@ -537,7 +537,7 @@ module ActiveRecord
|
|
537
537
|
name: row["conname"],
|
538
538
|
validate: row["valid"]
|
539
539
|
}
|
540
|
-
expression = row["constraintdef"][/CHECK \(
|
540
|
+
expression = row["constraintdef"][/CHECK \((.+)\)/m, 1]
|
541
541
|
|
542
542
|
CheckConstraintDefinition.new(table_name, expression, options)
|
543
543
|
end
|
@@ -569,7 +569,7 @@ module ActiveRecord
|
|
569
569
|
else raise ArgumentError, "No integer type has byte size #{limit}. Use a numeric with scale 0 instead."
|
570
570
|
end
|
571
571
|
when "enum"
|
572
|
-
raise ArgumentError "enum_type is required for enums" if enum_type.nil?
|
572
|
+
raise ArgumentError, "enum_type is required for enums" if enum_type.nil?
|
573
573
|
|
574
574
|
enum_type
|
575
575
|
else
|
@@ -663,7 +663,12 @@ module ActiveRecord
|
|
663
663
|
column_name, type, default, notnull, oid, fmod, collation, comment, attgenerated = field
|
664
664
|
type_metadata = fetch_type_metadata(column_name, type, oid.to_i, fmod.to_i)
|
665
665
|
default_value = extract_value_from_default(default)
|
666
|
-
|
666
|
+
|
667
|
+
if attgenerated.present?
|
668
|
+
default_function = default
|
669
|
+
else
|
670
|
+
default_function = extract_default_function(default_value, default)
|
671
|
+
end
|
667
672
|
|
668
673
|
if match = default_function&.match(/\Anextval\('"?(?<sequence_name>.+_(?<suffix>seq\d*))"?'::regclass\)\z/)
|
669
674
|
serial = sequence_name_from_parts(table_name, column_name, match[:suffix]) == match[:sequence_name]
|
@@ -75,7 +75,7 @@ module ActiveRecord
|
|
75
75
|
|
76
76
|
class << self
|
77
77
|
def new_client(conn_params)
|
78
|
-
PG.connect(conn_params)
|
78
|
+
PG.connect(**conn_params)
|
79
79
|
rescue ::PG::Error => error
|
80
80
|
if conn_params && conn_params[:dbname] && error.message.include?(conn_params[:dbname])
|
81
81
|
raise ActiveRecord::NoDatabaseError.db_error(conn_params[:dbname])
|
@@ -281,7 +281,7 @@ module ActiveRecord
|
|
281
281
|
def initialize(connection, logger, connection_parameters, config)
|
282
282
|
super(connection, logger, config)
|
283
283
|
|
284
|
-
@connection_parameters = connection_parameters
|
284
|
+
@connection_parameters = connection_parameters || {}
|
285
285
|
|
286
286
|
# @local_tz is initialized as nil to avoid warnings when connect tries to use it
|
287
287
|
@local_tz = nil
|
@@ -45,6 +45,19 @@ module ActiveRecord
|
|
45
45
|
0
|
46
46
|
end
|
47
47
|
|
48
|
+
def quote_default_expression(value, column) # :nodoc:
|
49
|
+
if value.is_a?(Proc)
|
50
|
+
value = value.call
|
51
|
+
if value.match?(/\A\w+\(.*\)\z/)
|
52
|
+
"(#{value})"
|
53
|
+
else
|
54
|
+
value
|
55
|
+
end
|
56
|
+
else
|
57
|
+
super
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
48
61
|
def type_cast(value) # :nodoc:
|
49
62
|
case value
|
50
63
|
when BigDecimal
|
@@ -127,20 +127,20 @@ module ActiveRecord
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def new_column_from_field(table_name, field)
|
130
|
-
default =
|
131
|
-
case field["dflt_value"]
|
132
|
-
when /^null$/i
|
133
|
-
nil
|
134
|
-
when /^'(.*)'$/m
|
135
|
-
$1.gsub("''", "'")
|
136
|
-
when /^"(.*)"$/m
|
137
|
-
$1.gsub('""', '"')
|
138
|
-
else
|
139
|
-
field["dflt_value"]
|
140
|
-
end
|
130
|
+
default = field["dflt_value"]
|
141
131
|
|
142
132
|
type_metadata = fetch_type_metadata(field["type"])
|
143
|
-
|
133
|
+
default_value = extract_value_from_default(default)
|
134
|
+
default_function = extract_default_function(default_value, default)
|
135
|
+
|
136
|
+
Column.new(
|
137
|
+
field["name"],
|
138
|
+
default_value,
|
139
|
+
type_metadata,
|
140
|
+
field["notnull"].to_i == 0,
|
141
|
+
default_function,
|
142
|
+
collation: field["collation"]
|
143
|
+
)
|
144
144
|
end
|
145
145
|
|
146
146
|
def data_source_sql(name = nil, type: nil)
|