From f9edbcaa2bbdc293574929b23c401e90c23e87ae Mon Sep 17 00:00:00 2001 From: Rafi Shamim Date: Thu, 11 May 2023 20:12:59 +0000 Subject: [PATCH] pg_catalog: use 0 for pg_constraint.conparentid The Postgres docs say this is: > The corresponding constraint of the parent partitioned table, if this is a constraint on a partition; else zero. Since we don't support partitioning like Postgres, we should always make this zero. This fixes a query that a tool was using to identify foreign key relationships. Release note (bug fix): Stopped using a NULL value for pg_constraint.conparentid. Now the value is hard-coded to 0, since CockroachDB does not support constraints on partitions. --- pkg/sql/logictest/testdata/logic_test/orms | 56 ++++++++++++++++++++++ pkg/sql/pg_catalog.go | 3 +- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/pkg/sql/logictest/testdata/logic_test/orms b/pkg/sql/logictest/testdata/logic_test/orms index b0f049eef2f0..e94a9485969a 100644 --- a/pkg/sql/logictest/testdata/logic_test/orms +++ b/pkg/sql/logictest/testdata/logic_test/orms @@ -379,3 +379,59 @@ query T SELECT relname FROM pg_class WHERE oid = $oid ---- regression_66576 + +# Regression test for #103135 - ensure that the Postgrest query to find +# FK relationships works. + +statement ok +CREATE TABLE dst (a int primary key, b int) + +statement ok +create table src (c int primary key, d int references dst(a)) + +query TTTTBTTB +WITH +pks_uniques_cols AS ( + SELECT + connamespace, + conrelid, + jsonb_agg(column_info.cols) as cols + FROM pg_constraint + JOIN lateral ( + SELECT array_agg(cols.attname order by cols.attnum) as cols + FROM ( select unnest(conkey) as col) _ + JOIN pg_attribute cols on cols.attrelid = conrelid and cols.attnum = col + ) column_info ON TRUE + WHERE + contype IN ('p', 'u') and + connamespace::regnamespace::text <> 'pg_catalog' + GROUP BY connamespace, conrelid +) +SELECT + ns1.nspname AS table_schema, + tab.relname AS table_name, + ns2.nspname AS foreign_table_schema, + other.relname AS foreign_table_name, + (ns1.nspname, tab.relname) = (ns2.nspname, other.relname) AS is_self, + traint.conname AS constraint_name, + column_info.cols_and_fcols, + (column_info.cols IN (SELECT * FROM jsonb_array_elements(pks_uqs.cols))) AS one_to_one +FROM pg_constraint traint +JOIN LATERAL ( + SELECT + array_agg(row(cols.attname, refs.attname) order by ord) AS cols_and_fcols, + jsonb_agg(cols.attname order by ord) AS cols + FROM unnest(traint.conkey, traint.confkey) WITH ORDINALITY AS _(col, ref, ord) + JOIN pg_attribute cols ON cols.attrelid = traint.conrelid AND cols.attnum = col + JOIN pg_attribute refs ON refs.attrelid = traint.confrelid AND refs.attnum = ref +) AS column_info ON TRUE +JOIN pg_namespace ns1 ON ns1.oid = traint.connamespace +JOIN pg_class tab ON tab.oid = traint.conrelid +JOIN pg_class other ON other.oid = traint.confrelid +JOIN pg_namespace ns2 ON ns2.oid = other.relnamespace +LEFT JOIN pks_uniques_cols pks_uqs ON pks_uqs.connamespace = traint.connamespace AND pks_uqs.conrelid = traint.conrelid +WHERE traint.contype = 'f' +and traint.conparentid = 0 ORDER BY traint.conrelid, traint.conname +---- +public b public a false b_a_id_fkey {"(a_id,id)"} false +public src public dst false src_d_fkey {"(d,a)"} false diff --git a/pkg/sql/pg_catalog.go b/pkg/sql/pg_catalog.go index 83dbcd2e9b30..8d315a4c1142 100644 --- a/pkg/sql/pg_catalog.go +++ b/pkg/sql/pg_catalog.go @@ -1050,8 +1050,7 @@ func populateTableConstraints( conbin, // conbin consrc, // consrc condef, // condef - // These columns were automatically created by pg_catalog_test's missing column generator. - tree.DNull, // conparentid + oidZero, // conparentid ); err != nil { return err }