code0-zero_track 0.0.9 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b7bc699d8f0bb3f1237eeb8ff75493624930bc8cce4b97ba1666709c494d4d04
|
|
4
|
+
data.tar.gz: aac0a33b9d880e0fd9f5a6297b76f0dd32c5f42f6beccad0afeea412caa78bd9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 60edef2bb7d288aeb3127068d6d58099cb409b659a5401a62db2844317cd4aa7048f7b8146ae59234f0e2c3c20e4af1a2e94ef91ac0561c62987f9977193e1c6
|
|
7
|
+
data.tar.gz: 02f209d8121437c829735e11bb9896c0991f2927d484da5c5f8f1f52c1cb7dd6d2363581f4d9886f285052339685ae942972666d497db6e03e6f25a0ed5b0c86
|
data/README.md
CHANGED
|
@@ -189,6 +189,9 @@ When tables have foreign key relationships, registration order and retention con
|
|
|
189
189
|
- A child table's `retain_for` must be less than or equal to the parent table's `retain_for`.
|
|
190
190
|
If a child retains partitions longer than its parent, dropping the parent partition will
|
|
191
191
|
fail because the child's foreign key still references it.
|
|
192
|
+
- Foreign keys between the partitioned tables must be declared with `drop_foreign_keys_on_detach`
|
|
193
|
+
on the model. Otherwise, the foreign key of a detached partition will block detaching partitions
|
|
194
|
+
of the referenced table.
|
|
192
195
|
|
|
193
196
|
#### Schema Cleaner Integration
|
|
194
197
|
|
|
@@ -64,6 +64,8 @@ module Code0
|
|
|
64
64
|
model.partitioning_strategy.partitions_to_detach.each do |partition|
|
|
65
65
|
detach_partition(partition, connection)
|
|
66
66
|
end
|
|
67
|
+
|
|
68
|
+
drop_declared_foreign_keys_from_detached_partitions(connection)
|
|
67
69
|
end
|
|
68
70
|
end
|
|
69
71
|
|
|
@@ -109,6 +111,73 @@ module Code0
|
|
|
109
111
|
)
|
|
110
112
|
end
|
|
111
113
|
|
|
114
|
+
def drop_declared_foreign_keys_from_detached_partitions(connection)
|
|
115
|
+
constraint_names = model.foreign_keys_to_drop_on_detach || []
|
|
116
|
+
return if constraint_names.empty?
|
|
117
|
+
|
|
118
|
+
warn_about_unknown_foreign_keys(constraint_names, connection)
|
|
119
|
+
|
|
120
|
+
detached_foreign_keys(constraint_names, connection).each do |qualified_table, constraint_name|
|
|
121
|
+
connection.execute(
|
|
122
|
+
"ALTER TABLE #{qualified_table} " \
|
|
123
|
+
"DROP CONSTRAINT #{connection.quote_column_name(constraint_name)}"
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
logger.info(
|
|
127
|
+
message: 'Dropped foreign key from detached partition',
|
|
128
|
+
table_name: model.table_name,
|
|
129
|
+
partition_name: qualified_table,
|
|
130
|
+
constraint_name: constraint_name
|
|
131
|
+
)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# We check the parent table because we drop the FK from the partition
|
|
136
|
+
# when detaching. A missing FK on the detached partition is an expected state
|
|
137
|
+
def warn_about_unknown_foreign_keys(constraint_names, connection)
|
|
138
|
+
existing = parent_foreign_key_names(connection)
|
|
139
|
+
unknown = constraint_names - existing
|
|
140
|
+
return if unknown.empty?
|
|
141
|
+
|
|
142
|
+
logger.warn(
|
|
143
|
+
message: 'Configured foreign keys to drop on detach do not exist on the partitioned table',
|
|
144
|
+
table_name: model.table_name,
|
|
145
|
+
constraint_names: unknown
|
|
146
|
+
)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def parent_foreign_key_names(connection)
|
|
150
|
+
connection.select_values(<<~SQL.squish)
|
|
151
|
+
SELECT con.conname
|
|
152
|
+
FROM pg_catalog.pg_constraint con
|
|
153
|
+
WHERE con.contype = 'f'
|
|
154
|
+
AND con.conrelid = #{connection.quote(model.table_name)}::regclass
|
|
155
|
+
SQL
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def detached_foreign_keys(constraint_names, connection)
|
|
159
|
+
schema = Rails.application.config.zero_track.db_partitioning.dynamic_partition_schema
|
|
160
|
+
quoted_names = constraint_names.map { |name| connection.quote(name) }.join(', ')
|
|
161
|
+
|
|
162
|
+
rows = connection.select_rows(<<~SQL.squish)
|
|
163
|
+
SELECT (quote_ident(n.nspname) || '.' || quote_ident(c.relname)) AS qualified_table,
|
|
164
|
+
con.conname AS constraint_name
|
|
165
|
+
FROM pg_catalog.pg_constraint con
|
|
166
|
+
JOIN pg_catalog.pg_class c ON c.oid = con.conrelid
|
|
167
|
+
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
|
168
|
+
WHERE con.contype = 'f'
|
|
169
|
+
AND con.conname IN (#{quoted_names})
|
|
170
|
+
AND n.nspname = #{connection.quote(schema)}
|
|
171
|
+
AND c.relkind = 'r'
|
|
172
|
+
AND NOT c.relispartition
|
|
173
|
+
AND NOT EXISTS (
|
|
174
|
+
SELECT 1 FROM pg_catalog.pg_inherits i WHERE i.inhrelid = c.oid
|
|
175
|
+
)
|
|
176
|
+
SQL
|
|
177
|
+
|
|
178
|
+
rows.map { |qualified_table, constraint_name| [qualified_table, constraint_name] }
|
|
179
|
+
end
|
|
180
|
+
|
|
112
181
|
def drop_partition(detached_partition, connection)
|
|
113
182
|
schema_name = connection.quote_table_name(detached_partition.schema)
|
|
114
183
|
partition_name = connection.quote_table_name(detached_partition.name)
|
|
@@ -25,6 +25,16 @@ module Code0
|
|
|
25
25
|
|
|
26
26
|
@partitioning_strategy = strategy_class.new(self, column, **kwargs)
|
|
27
27
|
end
|
|
28
|
+
|
|
29
|
+
def drop_foreign_keys_on_detach(*constraint_names)
|
|
30
|
+
@foreign_keys_to_drop_on_detach ||= []
|
|
31
|
+
@foreign_keys_to_drop_on_detach.concat(constraint_names.flatten.map(&:to_s))
|
|
32
|
+
@foreign_keys_to_drop_on_detach
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def foreign_keys_to_drop_on_detach
|
|
36
|
+
@foreign_keys_to_drop_on_detach || []
|
|
37
|
+
end
|
|
28
38
|
end
|
|
29
39
|
end
|
|
30
40
|
end
|