Skip to content

Commit b60793d

Browse files
BuonOmorafiss
authored andcommitted
fix(schema): render schema name when dumping foreign keys
In PostgreSQL, `oid::regclass::text` renders the schema name if it is not the current_schema. In CockroachDB, this is not the case, so we need to append the schema name manually.
1 parent e645a35 commit b60793d

File tree

3 files changed

+16
-8
lines changed

3 files changed

+16
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Ongoing
44

55
- Add support for [AOST](cockroachlabs.com/docs/stable/as-of-system-time) queries ([#284](https://github.com/cockroachdb/activerecord-cockroachdb-adapter/pull/284))
6+
- Dump schema name in foreign keys ([#289](https://github.com/cockroachdb/activerecord-cockroachdb-adapter/pull/289))
67

78
## 7.0.3 - 2023-08-23
89

bin/start-cockroachdb

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ cockroach start-single-node \
2121
--insecure --store=type=mem,size=0.25 --advertise-addr=localhost --pid-file "$pid_file" \
2222
&> "$log_file" &
2323

24-
cockroach_pid=$!
25-
2624
until [[ -f "$pid_file" ]]; do
2725
sleep 1
2826
done
@@ -47,6 +45,4 @@ SET CLUSTER SETTING sql.defaults.experimental_alter_column_type.enabled = 'true'
4745
SET CLUSTER SETTING sql.defaults.experimental_temporary_tables.enabled = 'true';
4846
SQL
4947

50-
tail -f "$log_file"
51-
52-
trap "kill $cockroach_pid" EXIT
48+
echo "CockroachDB started. PID: $(cat "$pid_file"). log: $log_file"

lib/active_record/connection_adapters/cockroachdb/schema_statements.rb

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,24 @@ def primary_key(table_name)
3636
# Modified version of the postgresql foreign_keys method.
3737
# Replaces t2.oid::regclass::text with t2.relname since this is
3838
# more efficient in CockroachDB.
39+
# Also, CockroachDB does not append the schema name in relname,
40+
# so we append it manually.
3941
def foreign_keys(table_name)
4042
scope = quoted_scope(table_name)
4143
fk_info = exec_query(<<~SQL, "SCHEMA")
42-
SELECT t2.relname 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
44+
SELECT CASE
45+
WHEN n2.nspname = current_schema()
46+
THEN ''
47+
ELSE n2.nspname || '.'
48+
END || t2.relname AS to_table,
49+
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
4350
FROM pg_constraint c
4451
JOIN pg_class t1 ON c.conrelid = t1.oid
4552
JOIN pg_class t2 ON c.confrelid = t2.oid
4653
JOIN pg_attribute a1 ON a1.attnum = c.conkey[1] AND a1.attrelid = t1.oid
4754
JOIN pg_attribute a2 ON a2.attnum = c.confkey[1] AND a2.attrelid = t2.oid
4855
JOIN pg_namespace t3 ON c.connamespace = t3.oid
56+
JOIN pg_namespace n2 ON t2.relnamespace = n2.oid
4957
WHERE c.contype = 'f'
5058
AND t1.relname = #{scope[:name]}
5159
AND t3.nspname = #{scope[:schema]}
@@ -54,16 +62,19 @@ def foreign_keys(table_name)
5462

5563
fk_info.map do |row|
5664
options = {
57-
column: row["column"],
65+
column: PostgreSQL::Utils.unquote_identifier(row["column"]),
5866
name: row["name"],
5967
primary_key: row["primary_key"]
6068
}
6169

6270
options[:on_delete] = extract_foreign_key_action(row["on_delete"])
6371
options[:on_update] = extract_foreign_key_action(row["on_update"])
72+
options[:deferrable] = extract_foreign_key_deferrable(row["deferrable"], row["deferred"])
73+
6474
options[:validate] = row["valid"]
75+
to_table = PostgreSQL::Utils.unquote_identifier(row["to_table"])
6576

66-
ForeignKeyDefinition.new(table_name, row["to_table"], options)
77+
ForeignKeyDefinition.new(table_name, to_table, options)
6778
end
6879
end
6980

0 commit comments

Comments
 (0)