Skip to content

Commit dc9a906

Browse files
committed
fix(schema): hidden columns
- update some outdated overrides. - update override comments to know when was the last override. - remove the `#column_names_from_column_numbers` method that was generating N+1 queries. - update related methods. See: - rails/rails@249c367 - rails/rails@4e0546c - rails/rails@c93d1b0
1 parent 0cf5c83 commit dc9a906

File tree

3 files changed

+217
-100
lines changed

3 files changed

+217
-100
lines changed

lib/active_record/connection_adapters/cockroachdb/referential_integrity.rb

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ def disable_referential_integrity
8585

8686
private
8787

88-
# Copy/paste of the `#foreign_keys(table)` method adapted to return every single
89-
# foreign key in the database.
88+
# NOTE: Copy/paste of the `#foreign_keys(table)` method adapted
89+
# to return every single foreign key in the database.
9090
def all_foreign_keys
9191
fk_info = internal_exec_query(<<~SQL, "SCHEMA")
9292
SELECT CASE
@@ -99,14 +99,30 @@ def all_foreign_keys
9999
THEN ''
100100
ELSE n2.nspname || '.'
101101
END || t2.relname AS to_table,
102-
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, c.condeferrable AS deferrable, c.condeferred AS deferred,
103-
c.conkey, c.confkey, c.conrelid, c.confrelid
102+
c.conname AS name, c.confupdtype AS on_update, c.confdeltype AS on_delete, c.convalidated AS valid, c.condeferrable AS deferrable, c.condeferred AS deferred, c.conrelid, c.confrelid,
103+
(
104+
SELECT array_agg(a.attname ORDER BY idx)
105+
FROM (
106+
SELECT idx, c.conkey[idx] AS conkey_elem
107+
FROM generate_subscripts(c.conkey, 1) AS idx
108+
) indexed_conkeys
109+
JOIN pg_attribute a ON a.attrelid = t1.oid
110+
AND a.attnum = indexed_conkeys.conkey_elem
111+
AND NOT a.attishidden
112+
) AS conkey_names,
113+
(
114+
SELECT array_agg(a.attname ORDER BY idx)
115+
FROM (
116+
SELECT idx, c.confkey[idx] AS confkey_elem
117+
FROM generate_subscripts(c.confkey, 1) AS idx
118+
) indexed_confkeys
119+
JOIN pg_attribute a ON a.attrelid = t2.oid
120+
AND a.attnum = indexed_confkeys.confkey_elem
121+
AND NOT a.attishidden
122+
) AS confkey_names
104123
FROM pg_constraint c
105124
JOIN pg_class t1 ON c.conrelid = t1.oid
106125
JOIN pg_class t2 ON c.confrelid = t2.oid
107-
JOIN pg_attribute a1 ON a1.attnum = c.conkey[1] AND a1.attrelid = t1.oid
108-
JOIN pg_attribute a2 ON a2.attnum = c.confkey[1] AND a2.attrelid = t2.oid
109-
JOIN pg_namespace t3 ON c.connamespace = t3.oid
110126
JOIN pg_namespace n1 ON t1.relnamespace = n1.oid
111127
JOIN pg_namespace n2 ON t2.relnamespace = n2.oid
112128
WHERE c.contype = 'f'
@@ -116,22 +132,16 @@ def all_foreign_keys
116132
fk_info.map do |row|
117133
from_table = PostgreSQL::Utils.unquote_identifier(row["from_table"])
118134
to_table = PostgreSQL::Utils.unquote_identifier(row["to_table"])
119-
conkey = row["conkey"].scan(/\d+/).map(&:to_i)
120-
confkey = row["confkey"].scan(/\d+/).map(&:to_i)
121-
122-
if conkey.size > 1
123-
column = column_names_from_column_numbers(row["conrelid"], conkey)
124-
primary_key = column_names_from_column_numbers(row["confrelid"], confkey)
125-
else
126-
column = PostgreSQL::Utils.unquote_identifier(row["column"])
127-
primary_key = row["primary_key"]
128-
end
135+
136+
column = decode_string_array(row["conkey_names"])
137+
primary_key = decode_string_array(row["confkey_names"])
129138

130139
options = {
131-
column: column,
140+
column: column.size == 1 ? column.first : column,
132141
name: row["name"],
133-
primary_key: primary_key
142+
primary_key: primary_key.size == 1 ? primary_key.first : primary_key
134143
}
144+
135145
options[:on_delete] = extract_foreign_key_action(row["on_delete"])
136146
options[:on_update] = extract_foreign_key_action(row["on_update"])
137147
options[:deferrable] = extract_constraint_deferrable(row["deferrable"], row["deferred"])

0 commit comments

Comments
 (0)