activerecord 5.2.6 → 6.0.0
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 +609 -622
- data/MIT-LICENSE +3 -1
- data/README.rdoc +4 -2
- data/examples/performance.rb +1 -1
- data/lib/active_record/aggregations.rb +4 -2
- data/lib/active_record/associations/association.rb +52 -19
- data/lib/active_record/associations/association_scope.rb +4 -6
- data/lib/active_record/associations/belongs_to_association.rb +36 -42
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
- data/lib/active_record/associations/builder/association.rb +14 -18
- data/lib/active_record/associations/builder/belongs_to.rb +19 -52
- data/lib/active_record/associations/builder/collection_association.rb +3 -13
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -38
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +35 -1
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_association.rb +6 -21
- data/lib/active_record/associations/collection_proxy.rb +12 -15
- data/lib/active_record/associations/foreign_association.rb +7 -0
- data/lib/active_record/associations/has_many_association.rb +2 -10
- data/lib/active_record/associations/has_many_through_association.rb +14 -14
- data/lib/active_record/associations/has_one_association.rb +28 -30
- data/lib/active_record/associations/has_one_through_association.rb +5 -5
- data/lib/active_record/associations/join_dependency/join_association.rb +9 -10
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
- data/lib/active_record/associations/join_dependency.rb +24 -28
- data/lib/active_record/associations/preloader/association.rb +38 -36
- data/lib/active_record/associations/preloader/through_association.rb +48 -39
- data/lib/active_record/associations/preloader.rb +40 -32
- data/lib/active_record/associations/singular_association.rb +2 -16
- data/lib/active_record/associations.rb +19 -14
- data/lib/active_record/attribute_assignment.rb +7 -10
- data/lib/active_record/attribute_methods/before_type_cast.rb +4 -1
- data/lib/active_record/attribute_methods/dirty.rb +111 -40
- data/lib/active_record/attribute_methods/primary_key.rb +15 -22
- data/lib/active_record/attribute_methods/query.rb +2 -3
- data/lib/active_record/attribute_methods/read.rb +15 -53
- data/lib/active_record/attribute_methods/serialization.rb +1 -1
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
- data/lib/active_record/attribute_methods/write.rb +17 -24
- data/lib/active_record/attribute_methods.rb +28 -100
- data/lib/active_record/attributes.rb +13 -0
- data/lib/active_record/autosave_association.rb +5 -9
- data/lib/active_record/base.rb +2 -3
- data/lib/active_record/callbacks.rb +5 -19
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +94 -16
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -4
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +95 -123
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +17 -8
- data/lib/active_record/connection_adapters/abstract/quoting.rb +68 -17
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +19 -12
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +76 -48
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +132 -53
- data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -56
- data/lib/active_record/connection_adapters/abstract_adapter.rb +180 -47
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +128 -194
- data/lib/active_record/connection_adapters/column.rb +17 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +52 -42
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +6 -10
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +73 -13
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +3 -4
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +129 -13
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -9
- data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +20 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +6 -3
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +12 -1
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +55 -53
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +160 -74
- data/lib/active_record/connection_adapters/schema_cache.rb +37 -14
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -6
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +42 -11
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +125 -141
- data/lib/active_record/connection_handling.rb +149 -27
- data/lib/active_record/core.rb +100 -60
- data/lib/active_record/counter_cache.rb +4 -29
- data/lib/active_record/database_configurations/database_config.rb +37 -0
- data/lib/active_record/database_configurations/hash_config.rb +50 -0
- data/lib/active_record/database_configurations/url_config.rb +79 -0
- data/lib/active_record/database_configurations.rb +233 -0
- data/lib/active_record/dynamic_matchers.rb +1 -1
- data/lib/active_record/enum.rb +37 -7
- data/lib/active_record/errors.rb +15 -7
- data/lib/active_record/explain.rb +1 -1
- data/lib/active_record/fixture_set/model_metadata.rb +33 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +153 -0
- data/lib/active_record/fixture_set/table_rows.rb +47 -0
- data/lib/active_record/fixtures.rb +145 -472
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +13 -3
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +68 -16
- data/lib/active_record/internal_metadata.rb +10 -2
- data/lib/active_record/locking/optimistic.rb +5 -6
- data/lib/active_record/locking/pessimistic.rb +3 -3
- data/lib/active_record/log_subscriber.rb +7 -26
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector.rb +75 -0
- data/lib/active_record/migration/command_recorder.rb +50 -6
- data/lib/active_record/migration/compatibility.rb +76 -49
- data/lib/active_record/migration.rb +100 -81
- data/lib/active_record/model_schema.rb +30 -9
- data/lib/active_record/nested_attributes.rb +2 -2
- data/lib/active_record/no_touching.rb +7 -0
- data/lib/active_record/persistence.rb +228 -24
- data/lib/active_record/query_cache.rb +11 -4
- data/lib/active_record/querying.rb +32 -20
- data/lib/active_record/railtie.rb +80 -43
- data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
- data/lib/active_record/railties/controller_runtime.rb +30 -35
- data/lib/active_record/railties/databases.rake +196 -46
- data/lib/active_record/reflection.rb +32 -30
- data/lib/active_record/relation/batches.rb +13 -10
- data/lib/active_record/relation/calculations.rb +53 -47
- data/lib/active_record/relation/delegation.rb +26 -43
- data/lib/active_record/relation/finder_methods.rb +13 -26
- data/lib/active_record/relation/merger.rb +11 -20
- data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
- data/lib/active_record/relation/predicate_builder.rb +4 -6
- data/lib/active_record/relation/query_attribute.rb +13 -8
- data/lib/active_record/relation/query_methods.rb +189 -63
- data/lib/active_record/relation/spawn_methods.rb +1 -1
- data/lib/active_record/relation/where_clause.rb +14 -10
- data/lib/active_record/relation/where_clause_factory.rb +1 -2
- data/lib/active_record/relation.rb +310 -80
- data/lib/active_record/result.rb +30 -11
- data/lib/active_record/sanitization.rb +32 -40
- data/lib/active_record/schema.rb +2 -11
- data/lib/active_record/schema_dumper.rb +22 -7
- data/lib/active_record/schema_migration.rb +5 -1
- data/lib/active_record/scoping/default.rb +4 -5
- data/lib/active_record/scoping/named.rb +19 -15
- data/lib/active_record/scoping.rb +8 -8
- data/lib/active_record/statement_cache.rb +30 -3
- data/lib/active_record/store.rb +87 -8
- data/lib/active_record/table_metadata.rb +10 -17
- data/lib/active_record/tasks/database_tasks.rb +194 -25
- data/lib/active_record/tasks/mysql_database_tasks.rb +5 -5
- data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -7
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -8
- data/lib/active_record/test_databases.rb +23 -0
- data/lib/active_record/test_fixtures.rb +224 -0
- data/lib/active_record/timestamp.rb +39 -25
- data/lib/active_record/touch_later.rb +4 -2
- data/lib/active_record/transactions.rb +57 -66
- data/lib/active_record/translation.rb +1 -1
- data/lib/active_record/type/adapter_specific_registry.rb +1 -8
- data/lib/active_record/type.rb +3 -4
- data/lib/active_record/type_caster/connection.rb +15 -14
- data/lib/active_record/type_caster/map.rb +1 -4
- data/lib/active_record/validations/uniqueness.rb +15 -27
- data/lib/active_record/validations.rb +1 -0
- data/lib/active_record.rb +9 -2
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +37 -0
- data/lib/arel/attributes.rb +22 -0
- data/lib/arel/collectors/bind.rb +24 -0
- data/lib/arel/collectors/composite.rb +31 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +20 -0
- data/lib/arel/collectors/substitute_binds.rb +28 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/errors.rb +9 -0
- data/lib/arel/expressions.rb +29 -0
- data/lib/arel/factory_methods.rb +49 -0
- data/lib/arel/insert_manager.rb +49 -0
- data/lib/arel/math.rb +45 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +52 -0
- data/lib/arel/nodes/bind_param.rb +36 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +50 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +18 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +8 -0
- data/lib/arel/nodes/in.rb +8 -0
- data/lib/arel/nodes/infix_operation.rb +80 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/node.rb +50 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +67 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +16 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +27 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +45 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +41 -0
- data/lib/arel/nodes/values_list.rb +9 -0
- data/lib/arel/nodes/window.rb +126 -0
- data/lib/arel/nodes/with.rb +11 -0
- data/lib/arel/nodes.rb +68 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +257 -0
- data/lib/arel/select_manager.rb +271 -0
- data/lib/arel/table.rb +110 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors/depth_first.rb +204 -0
- data/lib/arel/visitors/dot.rb +297 -0
- data/lib/arel/visitors/ibm_db.rb +34 -0
- data/lib/arel/visitors/informix.rb +62 -0
- data/lib/arel/visitors/mssql.rb +157 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +159 -0
- data/lib/arel/visitors/oracle12.rb +66 -0
- data/lib/arel/visitors/postgresql.rb +110 -0
- data/lib/arel/visitors/sqlite.rb +39 -0
- data/lib/arel/visitors/to_sql.rb +889 -0
- data/lib/arel/visitors/visitor.rb +46 -0
- data/lib/arel/visitors/where_sql.rb +23 -0
- data/lib/arel/visitors.rb +20 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +51 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
- data/lib/rails/generators/active_record/migration.rb +14 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +1 -0
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
- metadata +108 -26
- data/lib/active_record/collection_cache_key.rb +0 -53
@@ -22,7 +22,7 @@ module ActiveRecord
|
|
22
22
|
column.sql_type = type_to_sql(column.type, column.options)
|
23
23
|
quoted_column_name = quote_column_name(o.name)
|
24
24
|
|
25
|
-
change_column_sql = "ALTER COLUMN #{quoted_column_name} TYPE #{column.sql_type}"
|
25
|
+
change_column_sql = +"ALTER COLUMN #{quoted_column_name} TYPE #{column.sql_type}"
|
26
26
|
|
27
27
|
options = column_options(column)
|
28
28
|
|
@@ -59,6 +59,17 @@ module ActiveRecord
|
|
59
59
|
end
|
60
60
|
super
|
61
61
|
end
|
62
|
+
|
63
|
+
# Returns any SQL string to go between CREATE and TABLE. May be nil.
|
64
|
+
def table_modifier_in_create(o)
|
65
|
+
# A table cannot be both TEMPORARY and UNLOGGED, since all TEMPORARY
|
66
|
+
# tables are already UNLOGGED.
|
67
|
+
if o.temporary
|
68
|
+
" TEMPORARY"
|
69
|
+
elsif o.unlogged
|
70
|
+
" UNLOGGED"
|
71
|
+
end
|
72
|
+
end
|
62
73
|
end
|
63
74
|
end
|
64
75
|
end
|
@@ -4,6 +4,8 @@ module ActiveRecord
|
|
4
4
|
module ConnectionAdapters
|
5
5
|
module PostgreSQL
|
6
6
|
module ColumnMethods
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
7
9
|
# Defines the primary key field.
|
8
10
|
# Use of the native PostgreSQL UUID type is supported, and can be used
|
9
11
|
# by defining your tables as such:
|
@@ -13,10 +15,10 @@ module ActiveRecord
|
|
13
15
|
# t.timestamps
|
14
16
|
# end
|
15
17
|
#
|
16
|
-
# By default, this will use the
|
18
|
+
# By default, this will use the <tt>gen_random_uuid()</tt> function from the
|
17
19
|
# +pgcrypto+ extension. As that extension is only available in
|
18
20
|
# PostgreSQL 9.4+, for earlier versions an explicit default can be set
|
19
|
-
# to use
|
21
|
+
# to use <tt>uuid_generate_v4()</tt> from the +uuid-ossp+ extension instead:
|
20
22
|
#
|
21
23
|
# create_table :stuffs, id: false do |t|
|
22
24
|
# t.primary_key :id, :uuid, default: "uuid_generate_v4()"
|
@@ -51,130 +53,144 @@ module ActiveRecord
|
|
51
53
|
super
|
52
54
|
end
|
53
55
|
|
54
|
-
|
55
|
-
|
56
|
-
|
56
|
+
##
|
57
|
+
# :method: bigserial
|
58
|
+
# :call-seq: bigserial(*names, **options)
|
57
59
|
|
58
|
-
|
59
|
-
|
60
|
-
|
60
|
+
##
|
61
|
+
# :method: bit
|
62
|
+
# :call-seq: bit(*names, **options)
|
61
63
|
|
62
|
-
|
63
|
-
|
64
|
-
|
64
|
+
##
|
65
|
+
# :method: bit_varying
|
66
|
+
# :call-seq: bit_varying(*names, **options)
|
65
67
|
|
66
|
-
|
67
|
-
|
68
|
-
|
68
|
+
##
|
69
|
+
# :method: cidr
|
70
|
+
# :call-seq: cidr(*names, **options)
|
69
71
|
|
70
|
-
|
71
|
-
|
72
|
-
|
72
|
+
##
|
73
|
+
# :method: citext
|
74
|
+
# :call-seq: citext(*names, **options)
|
73
75
|
|
74
|
-
|
75
|
-
|
76
|
-
|
76
|
+
##
|
77
|
+
# :method: daterange
|
78
|
+
# :call-seq: daterange(*names, **options)
|
77
79
|
|
78
|
-
|
79
|
-
|
80
|
-
|
80
|
+
##
|
81
|
+
# :method: hstore
|
82
|
+
# :call-seq: hstore(*names, **options)
|
81
83
|
|
82
|
-
|
83
|
-
|
84
|
-
|
84
|
+
##
|
85
|
+
# :method: inet
|
86
|
+
# :call-seq: inet(*names, **options)
|
85
87
|
|
86
|
-
|
87
|
-
|
88
|
-
|
88
|
+
##
|
89
|
+
# :method: interval
|
90
|
+
# :call-seq: interval(*names, **options)
|
89
91
|
|
90
|
-
|
91
|
-
|
92
|
-
|
92
|
+
##
|
93
|
+
# :method: int4range
|
94
|
+
# :call-seq: int4range(*names, **options)
|
93
95
|
|
94
|
-
|
95
|
-
|
96
|
-
|
96
|
+
##
|
97
|
+
# :method: int8range
|
98
|
+
# :call-seq: int8range(*names, **options)
|
97
99
|
|
98
|
-
|
99
|
-
|
100
|
-
|
100
|
+
##
|
101
|
+
# :method: jsonb
|
102
|
+
# :call-seq: jsonb(*names, **options)
|
101
103
|
|
102
|
-
|
103
|
-
|
104
|
-
|
104
|
+
##
|
105
|
+
# :method: ltree
|
106
|
+
# :call-seq: ltree(*names, **options)
|
105
107
|
|
106
|
-
|
107
|
-
|
108
|
-
|
108
|
+
##
|
109
|
+
# :method: macaddr
|
110
|
+
# :call-seq: macaddr(*names, **options)
|
109
111
|
|
110
|
-
|
111
|
-
|
112
|
-
|
112
|
+
##
|
113
|
+
# :method: money
|
114
|
+
# :call-seq: money(*names, **options)
|
113
115
|
|
114
|
-
|
115
|
-
|
116
|
-
|
116
|
+
##
|
117
|
+
# :method: numrange
|
118
|
+
# :call-seq: numrange(*names, **options)
|
117
119
|
|
118
|
-
|
119
|
-
|
120
|
-
|
120
|
+
##
|
121
|
+
# :method: oid
|
122
|
+
# :call-seq: oid(*names, **options)
|
121
123
|
|
122
|
-
|
123
|
-
|
124
|
-
|
124
|
+
##
|
125
|
+
# :method: point
|
126
|
+
# :call-seq: point(*names, **options)
|
125
127
|
|
126
|
-
|
127
|
-
|
128
|
-
|
128
|
+
##
|
129
|
+
# :method: line
|
130
|
+
# :call-seq: line(*names, **options)
|
129
131
|
|
130
|
-
|
131
|
-
|
132
|
-
|
132
|
+
##
|
133
|
+
# :method: lseg
|
134
|
+
# :call-seq: lseg(*names, **options)
|
133
135
|
|
134
|
-
|
135
|
-
|
136
|
-
|
136
|
+
##
|
137
|
+
# :method: box
|
138
|
+
# :call-seq: box(*names, **options)
|
137
139
|
|
138
|
-
|
139
|
-
|
140
|
-
|
140
|
+
##
|
141
|
+
# :method: path
|
142
|
+
# :call-seq: path(*names, **options)
|
141
143
|
|
142
|
-
|
143
|
-
|
144
|
-
|
144
|
+
##
|
145
|
+
# :method: polygon
|
146
|
+
# :call-seq: polygon(*names, **options)
|
145
147
|
|
146
|
-
|
147
|
-
|
148
|
-
|
148
|
+
##
|
149
|
+
# :method: circle
|
150
|
+
# :call-seq: circle(*names, **options)
|
149
151
|
|
150
|
-
|
151
|
-
|
152
|
-
|
152
|
+
##
|
153
|
+
# :method: serial
|
154
|
+
# :call-seq: serial(*names, **options)
|
153
155
|
|
154
|
-
|
155
|
-
|
156
|
-
|
156
|
+
##
|
157
|
+
# :method: tsrange
|
158
|
+
# :call-seq: tsrange(*names, **options)
|
157
159
|
|
158
|
-
|
159
|
-
|
160
|
-
|
160
|
+
##
|
161
|
+
# :method: tstzrange
|
162
|
+
# :call-seq: tstzrange(*names, **options)
|
161
163
|
|
162
|
-
|
163
|
-
|
164
|
-
|
164
|
+
##
|
165
|
+
# :method: tsvector
|
166
|
+
# :call-seq: tsvector(*names, **options)
|
165
167
|
|
166
|
-
|
167
|
-
|
168
|
-
|
168
|
+
##
|
169
|
+
# :method: uuid
|
170
|
+
# :call-seq: uuid(*names, **options)
|
171
|
+
|
172
|
+
##
|
173
|
+
# :method: xml
|
174
|
+
# :call-seq: xml(*names, **options)
|
169
175
|
|
170
|
-
|
171
|
-
|
176
|
+
included do
|
177
|
+
define_column_methods :bigserial, :bit, :bit_varying, :cidr, :citext, :daterange,
|
178
|
+
:hstore, :inet, :interval, :int4range, :int8range, :jsonb, :ltree, :macaddr,
|
179
|
+
:money, :numrange, :oid, :point, :line, :lseg, :box, :path, :polygon, :circle,
|
180
|
+
:serial, :tsrange, :tstzrange, :tsvector, :uuid, :xml
|
172
181
|
end
|
173
182
|
end
|
174
183
|
|
175
184
|
class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
|
176
185
|
include ColumnMethods
|
177
186
|
|
187
|
+
attr_reader :unlogged
|
188
|
+
|
189
|
+
def initialize(*)
|
190
|
+
super
|
191
|
+
@unlogged = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.create_unlogged_tables
|
192
|
+
end
|
193
|
+
|
178
194
|
private
|
179
195
|
def integer_like_primary_key_type(type, options)
|
180
196
|
if type == :bigint || options[:limit] == 8
|
@@ -22,8 +22,8 @@ module ActiveRecord
|
|
22
22
|
def create_database(name, options = {})
|
23
23
|
options = { encoding: "utf8" }.merge!(options.symbolize_keys)
|
24
24
|
|
25
|
-
option_string = options.
|
26
|
-
memo
|
25
|
+
option_string = options.each_with_object(+"") do |(key, value), memo|
|
26
|
+
memo << case key
|
27
27
|
when :owner
|
28
28
|
" OWNER = \"#{value}\""
|
29
29
|
when :template
|
@@ -68,7 +68,7 @@ module ActiveRecord
|
|
68
68
|
table = quoted_scope(table_name)
|
69
69
|
index = quoted_scope(index_name)
|
70
70
|
|
71
|
-
query_value(
|
71
|
+
query_value(<<~SQL, "SCHEMA").to_i > 0
|
72
72
|
SELECT COUNT(*)
|
73
73
|
FROM pg_class t
|
74
74
|
INNER JOIN pg_index d ON t.oid = d.indrelid
|
@@ -85,7 +85,7 @@ module ActiveRecord
|
|
85
85
|
def indexes(table_name) # :nodoc:
|
86
86
|
scope = quoted_scope(table_name)
|
87
87
|
|
88
|
-
result = query(
|
88
|
+
result = query(<<~SQL, "SCHEMA")
|
89
89
|
SELECT distinct i.relname, d.indisunique, d.indkey, pg_get_indexdef(d.indexrelid), t.oid,
|
90
90
|
pg_catalog.obj_description(i.oid, 'pg_class') AS comment
|
91
91
|
FROM pg_class t
|
@@ -115,7 +115,7 @@ module ActiveRecord
|
|
115
115
|
if indkey.include?(0)
|
116
116
|
columns = expressions
|
117
117
|
else
|
118
|
-
columns = Hash[query(
|
118
|
+
columns = Hash[query(<<~SQL, "SCHEMA")].values_at(*indkey).compact
|
119
119
|
SELECT a.attnum, a.attname
|
120
120
|
FROM pg_attribute a
|
121
121
|
WHERE a.attrelid = #{oid}
|
@@ -158,7 +158,7 @@ module ActiveRecord
|
|
158
158
|
def table_comment(table_name) # :nodoc:
|
159
159
|
scope = quoted_scope(table_name, type: "BASE TABLE")
|
160
160
|
if scope[:name]
|
161
|
-
query_value(
|
161
|
+
query_value(<<~SQL, "SCHEMA")
|
162
162
|
SELECT pg_catalog.obj_description(c.oid, 'pg_class')
|
163
163
|
FROM pg_catalog.pg_class c
|
164
164
|
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
|
@@ -196,7 +196,7 @@ module ActiveRecord
|
|
196
196
|
|
197
197
|
# Returns an array of schema names.
|
198
198
|
def schema_names
|
199
|
-
query_values(
|
199
|
+
query_values(<<~SQL, "SCHEMA")
|
200
200
|
SELECT nspname
|
201
201
|
FROM pg_namespace
|
202
202
|
WHERE nspname !~ '^pg_.*'
|
@@ -287,7 +287,7 @@ module ActiveRecord
|
|
287
287
|
quoted_sequence = quote_table_name(sequence)
|
288
288
|
max_pk = query_value("SELECT MAX(#{quote_column_name pk}) FROM #{quote_table_name(table)}", "SCHEMA")
|
289
289
|
if max_pk.nil?
|
290
|
-
if
|
290
|
+
if database_version >= 100000
|
291
291
|
minvalue = query_value("SELECT seqmin FROM pg_sequence WHERE seqrelid = #{quote(quoted_sequence)}::regclass", "SCHEMA")
|
292
292
|
else
|
293
293
|
minvalue = query_value("SELECT min_value FROM #{quoted_sequence}", "SCHEMA")
|
@@ -302,7 +302,7 @@ module ActiveRecord
|
|
302
302
|
def pk_and_sequence_for(table) #:nodoc:
|
303
303
|
# First try looking for a sequence with a dependency on the
|
304
304
|
# given table's primary key.
|
305
|
-
result = query(
|
305
|
+
result = query(<<~SQL, "SCHEMA")[0]
|
306
306
|
SELECT attr.attname, nsp.nspname, seq.relname
|
307
307
|
FROM pg_class seq,
|
308
308
|
pg_attribute attr,
|
@@ -319,10 +319,10 @@ module ActiveRecord
|
|
319
319
|
AND cons.contype = 'p'
|
320
320
|
AND dep.classid = 'pg_class'::regclass
|
321
321
|
AND dep.refobjid = #{quote(quote_table_name(table))}::regclass
|
322
|
-
|
322
|
+
SQL
|
323
323
|
|
324
324
|
if result.nil? || result.empty?
|
325
|
-
result = query(
|
325
|
+
result = query(<<~SQL, "SCHEMA")[0]
|
326
326
|
SELECT attr.attname, nsp.nspname,
|
327
327
|
CASE
|
328
328
|
WHEN pg_get_expr(def.adbin, def.adrelid) !~* 'nextval' THEN NULL
|
@@ -339,7 +339,7 @@ module ActiveRecord
|
|
339
339
|
WHERE t.oid = #{quote(quote_table_name(table))}::regclass
|
340
340
|
AND cons.contype = 'p'
|
341
341
|
AND pg_get_expr(def.adbin, def.adrelid) ~* 'nextval|uuid_generate'
|
342
|
-
|
342
|
+
SQL
|
343
343
|
end
|
344
344
|
|
345
345
|
pk = result.shift
|
@@ -353,7 +353,7 @@ module ActiveRecord
|
|
353
353
|
end
|
354
354
|
|
355
355
|
def primary_keys(table_name) # :nodoc:
|
356
|
-
query_values(
|
356
|
+
query_values(<<~SQL, "SCHEMA")
|
357
357
|
SELECT a.attname
|
358
358
|
FROM (
|
359
359
|
SELECT indrelid, indkey, generate_subscripts(indkey, 1) idx
|
@@ -368,31 +368,6 @@ module ActiveRecord
|
|
368
368
|
SQL
|
369
369
|
end
|
370
370
|
|
371
|
-
def bulk_change_table(table_name, operations)
|
372
|
-
sql_fragments = []
|
373
|
-
non_combinable_operations = []
|
374
|
-
|
375
|
-
operations.each do |command, args|
|
376
|
-
table, arguments = args.shift, args
|
377
|
-
method = :"#{command}_for_alter"
|
378
|
-
|
379
|
-
if respond_to?(method, true)
|
380
|
-
sqls, procs = Array(send(method, table, *arguments)).partition { |v| v.is_a?(String) }
|
381
|
-
sql_fragments << sqls
|
382
|
-
non_combinable_operations.concat(procs)
|
383
|
-
else
|
384
|
-
execute "ALTER TABLE #{quote_table_name(table_name)} #{sql_fragments.join(", ")}" unless sql_fragments.empty?
|
385
|
-
non_combinable_operations.each(&:call)
|
386
|
-
sql_fragments = []
|
387
|
-
non_combinable_operations = []
|
388
|
-
send(command, table, *arguments)
|
389
|
-
end
|
390
|
-
end
|
391
|
-
|
392
|
-
execute "ALTER TABLE #{quote_table_name(table_name)} #{sql_fragments.join(", ")}" unless sql_fragments.empty?
|
393
|
-
non_combinable_operations.each(&:call)
|
394
|
-
end
|
395
|
-
|
396
371
|
# Renames a table.
|
397
372
|
# Also renames a table's primary key sequence if the sequence name exists and
|
398
373
|
# matches the Active Record default.
|
@@ -443,14 +418,16 @@ module ActiveRecord
|
|
443
418
|
end
|
444
419
|
|
445
420
|
# Adds comment for given table column or drops it if +comment+ is a +nil+
|
446
|
-
def change_column_comment(table_name, column_name,
|
421
|
+
def change_column_comment(table_name, column_name, comment_or_changes) # :nodoc:
|
447
422
|
clear_cache!
|
423
|
+
comment = extract_new_comment_value(comment_or_changes)
|
448
424
|
execute "COMMENT ON COLUMN #{quote_table_name(table_name)}.#{quote_column_name(column_name)} IS #{quote(comment)}"
|
449
425
|
end
|
450
426
|
|
451
427
|
# Adds comment for given table or drops it if +comment+ is a +nil+
|
452
|
-
def change_table_comment(table_name,
|
428
|
+
def change_table_comment(table_name, comment_or_changes) # :nodoc:
|
453
429
|
clear_cache!
|
430
|
+
comment = extract_new_comment_value(comment_or_changes)
|
454
431
|
execute "COMMENT ON TABLE #{quote_table_name(table_name)} IS #{quote(comment)}"
|
455
432
|
end
|
456
433
|
|
@@ -502,7 +479,7 @@ module ActiveRecord
|
|
502
479
|
|
503
480
|
def foreign_keys(table_name)
|
504
481
|
scope = quoted_scope(table_name)
|
505
|
-
fk_info = exec_query(
|
482
|
+
fk_info = exec_query(<<~SQL, "SCHEMA")
|
506
483
|
SELECT t2.oid::regclass::text AS to_table, a1.attname AS column, a2.attname AS primary_key, c.conname AS name, c.confupdtype AS on_update, c.confdeltype AS on_delete, c.convalidated AS valid
|
507
484
|
FROM pg_constraint c
|
508
485
|
JOIN pg_class t1 ON c.conrelid = t1.oid
|
@@ -548,21 +525,21 @@ module ActiveRecord
|
|
548
525
|
# The hard limit is 1GB, because of a 32-bit size field, and TOAST.
|
549
526
|
case limit
|
550
527
|
when nil, 0..0x3fffffff; super(type)
|
551
|
-
else raise
|
528
|
+
else raise ArgumentError, "No binary type has byte size #{limit}. The limit on binary can be at most 1GB - 1byte."
|
552
529
|
end
|
553
530
|
when "text"
|
554
531
|
# PostgreSQL doesn't support limits on text columns.
|
555
532
|
# The hard limit is 1GB, according to section 8.3 in the manual.
|
556
533
|
case limit
|
557
534
|
when nil, 0..0x3fffffff; super(type)
|
558
|
-
else raise
|
535
|
+
else raise ArgumentError, "No text type has byte size #{limit}. The limit on text can be at most 1GB - 1byte."
|
559
536
|
end
|
560
537
|
when "integer"
|
561
538
|
case limit
|
562
539
|
when 1, 2; "smallint"
|
563
540
|
when nil, 3, 4; "integer"
|
564
541
|
when 5..8; "bigint"
|
565
|
-
else raise
|
542
|
+
else raise ArgumentError, "No integer type has byte size #{limit}. Use a numeric with scale 0 instead."
|
566
543
|
end
|
567
544
|
else
|
568
545
|
super
|
@@ -623,10 +600,10 @@ module ActiveRecord
|
|
623
600
|
# validate_foreign_key :accounts, name: :special_fk_name
|
624
601
|
#
|
625
602
|
# The +options+ hash accepts the same keys as SchemaStatements#add_foreign_key.
|
626
|
-
def validate_foreign_key(from_table,
|
603
|
+
def validate_foreign_key(from_table, to_table = nil, **options)
|
627
604
|
return unless supports_validate_constraints?
|
628
605
|
|
629
|
-
fk_name_to_validate = foreign_key_for!(from_table,
|
606
|
+
fk_name_to_validate = foreign_key_for!(from_table, to_table: to_table, **options).name
|
630
607
|
|
631
608
|
validate_constraint from_table, fk_name_to_validate
|
632
609
|
end
|
@@ -637,7 +614,7 @@ module ActiveRecord
|
|
637
614
|
end
|
638
615
|
|
639
616
|
def create_table_definition(*args)
|
640
|
-
PostgreSQL::TableDefinition.new(*args)
|
617
|
+
PostgreSQL::TableDefinition.new(self, *args)
|
641
618
|
end
|
642
619
|
|
643
620
|
def create_alter_table(name)
|
@@ -650,16 +627,19 @@ module ActiveRecord
|
|
650
627
|
default_value = extract_value_from_default(default)
|
651
628
|
default_function = extract_default_function(default_value, default)
|
652
629
|
|
653
|
-
|
630
|
+
if match = default_function&.match(/\Anextval\('"?(?<sequence_name>.+_(?<suffix>seq\d*))"?'::regclass\)\z/)
|
631
|
+
serial = sequence_name_from_parts(table_name, column_name, match[:suffix]) == match[:sequence_name]
|
632
|
+
end
|
633
|
+
|
634
|
+
PostgreSQL::Column.new(
|
654
635
|
column_name,
|
655
636
|
default_value,
|
656
637
|
type_metadata,
|
657
638
|
!notnull,
|
658
|
-
table_name,
|
659
639
|
default_function,
|
660
|
-
collation,
|
640
|
+
collation: collation,
|
661
641
|
comment: comment.presence,
|
662
|
-
|
642
|
+
serial: serial
|
663
643
|
)
|
664
644
|
end
|
665
645
|
|
@@ -672,7 +652,23 @@ module ActiveRecord
|
|
672
652
|
precision: cast_type.precision,
|
673
653
|
scale: cast_type.scale,
|
674
654
|
)
|
675
|
-
|
655
|
+
PostgreSQL::TypeMetadata.new(simple_type, oid: oid, fmod: fmod)
|
656
|
+
end
|
657
|
+
|
658
|
+
def sequence_name_from_parts(table_name, column_name, suffix)
|
659
|
+
over_length = [table_name, column_name, suffix].sum(&:length) + 2 - max_identifier_length
|
660
|
+
|
661
|
+
if over_length > 0
|
662
|
+
column_name_length = [(max_identifier_length - suffix.length - 2) / 2, column_name.length].min
|
663
|
+
over_length -= column_name.length - column_name_length
|
664
|
+
column_name = column_name[0, column_name_length - [over_length, 0].min]
|
665
|
+
end
|
666
|
+
|
667
|
+
if over_length > 0
|
668
|
+
table_name = table_name[0, table_name.length - over_length]
|
669
|
+
end
|
670
|
+
|
671
|
+
"#{table_name}_#{column_name}_#{suffix}"
|
676
672
|
end
|
677
673
|
|
678
674
|
def extract_foreign_key_action(specifier)
|
@@ -716,6 +712,12 @@ module ActiveRecord
|
|
716
712
|
end
|
717
713
|
|
718
714
|
def add_timestamps_for_alter(table_name, options = {})
|
715
|
+
options[:null] = false if options[:null].nil?
|
716
|
+
|
717
|
+
if !options.key?(:precision) && supports_datetime_with_precision?
|
718
|
+
options[:precision] = 6
|
719
|
+
end
|
720
|
+
|
719
721
|
[add_column_for_alter(table_name, :created_at, :datetime, options), add_column_for_alter(table_name, :updated_at, :datetime, options)]
|
720
722
|
end
|
721
723
|
|
@@ -739,7 +741,7 @@ module ActiveRecord
|
|
739
741
|
scope = quoted_scope(name, type: type)
|
740
742
|
scope[:type] ||= "'r','v','m','p','f'" # (r)elation/table, (v)iew, (m)aterialized view, (p)artitioned table, (f)oreign table
|
741
743
|
|
742
|
-
sql = "SELECT c.relname FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = c.relnamespace"
|
744
|
+
sql = +"SELECT c.relname FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = c.relnamespace"
|
743
745
|
sql << " WHERE n.nspname = #{scope[:schema]}"
|
744
746
|
sql << " AND c.relname = #{scope[:name]}" if scope[:name]
|
745
747
|
sql << " AND c.relkind IN (#{scope[:type]})"
|
@@ -1,39 +1,36 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
|
+
# :stopdoc:
|
4
5
|
module ConnectionAdapters
|
5
|
-
|
6
|
-
|
6
|
+
module PostgreSQL
|
7
|
+
class TypeMetadata < DelegateClass(SqlTypeMetadata)
|
8
|
+
undef to_yaml if method_defined?(:to_yaml)
|
7
9
|
|
8
|
-
|
10
|
+
attr_reader :oid, :fmod
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
@array = /\[\]$/.match?(type_metadata.sql_type)
|
16
|
-
end
|
17
|
-
|
18
|
-
def sql_type
|
19
|
-
super.gsub(/\[\]$/, "".freeze)
|
20
|
-
end
|
21
|
-
|
22
|
-
def ==(other)
|
23
|
-
other.is_a?(PostgreSQLTypeMetadata) &&
|
24
|
-
attributes_for_hash == other.attributes_for_hash
|
25
|
-
end
|
26
|
-
alias eql? ==
|
27
|
-
|
28
|
-
def hash
|
29
|
-
attributes_for_hash.hash
|
30
|
-
end
|
12
|
+
def initialize(type_metadata, oid: nil, fmod: nil)
|
13
|
+
super(type_metadata)
|
14
|
+
@oid = oid
|
15
|
+
@fmod = fmod
|
16
|
+
end
|
31
17
|
|
32
|
-
|
18
|
+
def ==(other)
|
19
|
+
other.is_a?(TypeMetadata) &&
|
20
|
+
__getobj__ == other.__getobj__ &&
|
21
|
+
oid == other.oid &&
|
22
|
+
fmod == other.fmod
|
23
|
+
end
|
24
|
+
alias eql? ==
|
33
25
|
|
34
|
-
def
|
35
|
-
|
26
|
+
def hash
|
27
|
+
TypeMetadata.hash ^
|
28
|
+
__getobj__.hash ^
|
29
|
+
oid.hash ^
|
30
|
+
fmod.hash
|
36
31
|
end
|
32
|
+
end
|
37
33
|
end
|
34
|
+
PostgreSQLTypeMetadata = PostgreSQL::TypeMetadata
|
38
35
|
end
|
39
36
|
end
|