Skip to content

Commit 33556af

Browse files
committed
Fix errors in key_column_usage.position_in_unique_constraint column recently
added to information_schema (per a SQL2003 addition). The original coding failed if a referenced column participated in more than one pg_constraint entry. Also, it did not work if an FK relied directly on a unique index without any constraint syntactic sugar --- this case is outside the SQL spec, but PG has always supported it, so it's reasonable for our information_schema to handle it too. Per bug#2750 from Stephen Haberman. Although this patch changes the initial catalog contents, I didn't force initdb. Any beta3 testers who need the fix can install it via CREATE OR REPLACE VIEW, so forcing them to initdb seems an unnecessary imposition.
1 parent 87a5016 commit 33556af

File tree

1 file changed

+32
-11
lines changed

1 file changed

+32
-11
lines changed

src/backend/catalog/information_schema.sql

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*
55
* Copyright (c) 2003-2006, PostgreSQL Global Development Group
66
*
7-
* $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.37 2006/09/14 22:05:06 tgl Exp $
7+
* $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.38 2006/11/10 18:10:10 tgl Exp $
88
*/
99

1010
/*
@@ -52,6 +52,28 @@ CREATE FUNCTION _pg_keysequal(smallint[], smallint[]) RETURNS boolean
5252
RETURNS NULL ON NULL INPUT
5353
AS 'select information_schema._pg_keyissubset($1, $2) and information_schema._pg_keyissubset($2, $1)';
5454

55+
/* Get the OID of the unique index that an FK constraint depends on */
56+
CREATE FUNCTION _pg_underlying_index(oid) RETURNS oid
57+
LANGUAGE sql STRICT STABLE
58+
AS $$
59+
SELECT refobjid FROM pg_catalog.pg_depend
60+
WHERE classid = 'pg_catalog.pg_constraint'::pg_catalog.regclass AND
61+
objid = $1 AND
62+
refclassid = 'pg_catalog.pg_class'::pg_catalog.regclass AND
63+
refobjsubid = 0 AND deptype = 'n'
64+
$$;
65+
66+
/* Given an index's OID and an underlying-table column number, return the
67+
* column's position in the index (NULL if not there) */
68+
CREATE FUNCTION _pg_index_position(oid, smallint) RETURNS int
69+
LANGUAGE sql STRICT STABLE
70+
AS $$
71+
SELECT (ss.a).n FROM
72+
(SELECT information_schema._pg_expandarray(indkey) AS a
73+
FROM pg_catalog.pg_index WHERE indexrelid = $1) ss
74+
WHERE (ss.a).x = $2;
75+
$$;
76+
5577
CREATE FUNCTION _pg_truetypid(pg_attribute, pg_type) RETURNS oid
5678
LANGUAGE sql
5779
IMMUTABLE
@@ -922,17 +944,16 @@ CREATE VIEW key_column_usage AS
922944
CAST(relname AS sql_identifier) AS table_name,
923945
CAST(a.attname AS sql_identifier) AS column_name,
924946
CAST((ss.x).n AS cardinal_number) AS ordinal_position,
925-
(
926-
SELECT CAST(a AS cardinal_number)
927-
FROM pg_constraint,
928-
(SELECT a FROM generate_series(1, array_upper(ss.confkey,1)) a) AS foo
929-
WHERE conrelid = ss.confrelid
930-
AND conkey[foo.a] = ss.confkey[(ss.x).n]
931-
) AS position_in_unique_constraint
947+
CAST(CASE WHEN contype = 'f' THEN
948+
_pg_index_position(_pg_underlying_index(ss.coid),
949+
ss.confkey[(ss.x).n])
950+
ELSE NULL
951+
END AS cardinal_number)
952+
AS position_in_unique_constraint
932953
FROM pg_attribute a,
933-
(SELECT r.oid, r.relname, nc.nspname AS nc_nspname,
954+
(SELECT r.oid AS roid, r.relname, nc.nspname AS nc_nspname,
934955
nr.nspname AS nr_nspname,
935-
c.conname, c.confkey, c.confrelid,
956+
c.oid AS coid, c.conname, c.contype, c.confkey, c.confrelid,
936957
_pg_expandarray(c.conkey) AS x
937958
FROM pg_namespace nr, pg_class r, pg_namespace nc,
938959
pg_constraint c
@@ -947,7 +968,7 @@ CREATE VIEW key_column_usage AS
947968
OR has_table_privilege(c.oid, 'INSERT')
948969
OR has_table_privilege(c.oid, 'UPDATE')
949970
OR has_table_privilege(c.oid, 'REFERENCES')) ) AS ss
950-
WHERE ss.oid = a.attrelid
971+
WHERE ss.roid = a.attrelid
951972
AND a.attnum = (ss.x).x
952973
AND NOT a.attisdropped;
953974

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy