mirror of
https://github.com/postgres/postgres.git
synced 2025-06-27 23:21:58 +03:00
patch to deal with unique foreign keys in 7.4 from Kris Jurka
This commit is contained in:
@ -2966,7 +2966,59 @@ public abstract class AbstractJdbc1DatabaseMetaData
|
|||||||
* the PK_NAME field.
|
* the PK_NAME field.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (connection.haveMinimumServerVersion("7.3")) {
|
if (connection.haveMinimumServerVersion("7.4")) {
|
||||||
|
String sql = "SELECT NULL::text AS PKTABLE_CAT, pkn.nspname AS PKTABLE_SCHEMA, pkc.relname AS PKTABLE_NAME, pka.attname AS PKCOLUMN_NAME, "+
|
||||||
|
"NULL::text AS FK_TABLE_CAT, fkn.nspname AS FKTABLE_SCHEMA, fkc.relname AS FKTABLE_NAME, fka.attname AS FKCOLUMN_NAME, "+
|
||||||
|
"pos.n AS KEY_SEQ, "+
|
||||||
|
"CASE con.confupdtype "+
|
||||||
|
" WHEN 'c' THEN " + DatabaseMetaData.importedKeyCascade +
|
||||||
|
" WHEN 'n' THEN " + DatabaseMetaData.importedKeySetNull +
|
||||||
|
" WHEN 'd' THEN " + DatabaseMetaData.importedKeySetDefault +
|
||||||
|
" WHEN 'r' THEN " + DatabaseMetaData.importedKeyRestrict +
|
||||||
|
" WHEN 'a' THEN " + DatabaseMetaData.importedKeyNoAction +
|
||||||
|
" ELSE NULL END AS UPDATE_RULE, "+
|
||||||
|
"CASE con.confdeltype "+
|
||||||
|
" WHEN 'c' THEN " + DatabaseMetaData.importedKeyCascade +
|
||||||
|
" WHEN 'n' THEN " + DatabaseMetaData.importedKeySetNull +
|
||||||
|
" WHEN 'd' THEN " + DatabaseMetaData.importedKeySetDefault +
|
||||||
|
" WHEN 'r' THEN " + DatabaseMetaData.importedKeyRestrict +
|
||||||
|
" WHEN 'a' THEN " + DatabaseMetaData.importedKeyNoAction +
|
||||||
|
" ELSE NULL END AS DELETE_RULE, "+
|
||||||
|
"con.conname AS FK_NAME, pkic.relname AS PK_NAME, "+
|
||||||
|
"CASE "+
|
||||||
|
" WHEN con.condeferrable AND con.condeferred THEN " + DatabaseMetaData.importedKeyInitiallyDeferred +
|
||||||
|
" WHEN con.condeferrable THEN " + DatabaseMetaData.importedKeyInitiallyImmediate +
|
||||||
|
" ELSE " + DatabaseMetaData.importedKeyNotDeferrable+
|
||||||
|
" END AS DEFERRABILITY "+
|
||||||
|
" FROM "+
|
||||||
|
" pg_catalog.pg_namespace pkn, pg_catalog.pg_class pkc, pg_catalog.pg_attribute pka, "+
|
||||||
|
" pg_catalog.pg_namespace fkn, pg_catalog.pg_class fkc, pg_catalog.pg_attribute fka, "+
|
||||||
|
" pg_catalog.pg_constraint con, information_schema._pg_keypositions() pos(n), "+
|
||||||
|
" pg_catalog.pg_depend dep, pg_catalog.pg_class pkic "+
|
||||||
|
" WHERE pkn.oid = pkc.relnamespace AND pkc.oid = pka.attrelid AND pka.attnum = con.confkey[pos.n] AND con.confrelid = pkc.oid "+
|
||||||
|
" AND fkn.oid = fkc.relnamespace AND fkc.oid = fka.attrelid AND fka.attnum = con.conkey[pos.n] AND con.conrelid = fkc.oid "+
|
||||||
|
" AND con.contype = 'f' AND con.oid = dep.objid AND pkic.oid = dep.refobjid AND pkic.relkind = 'i' AND dep.classid = 'pg_constraint'::regclass::oid AND dep.refclassid = 'pg_class'::regclass::oid ";
|
||||||
|
if (primarySchema != null && !"".equals(primarySchema)) {
|
||||||
|
sql += " AND pkn.nspname = '"+escapeQuotes(primarySchema)+"' ";
|
||||||
|
}
|
||||||
|
if (foreignSchema != null && !"".equals(foreignSchema)) {
|
||||||
|
sql += " AND fkn.nspname = '"+escapeQuotes(foreignSchema)+"' ";
|
||||||
|
}
|
||||||
|
if (primaryTable != null && !"".equals(primaryTable)) {
|
||||||
|
sql += " AND pkc.relname = '"+escapeQuotes(primaryTable)+"' ";
|
||||||
|
}
|
||||||
|
if (foreignTable != null && !"".equals(foreignTable)) {
|
||||||
|
sql += " AND fkc.relname = '"+escapeQuotes(foreignTable)+"' ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (primaryTable != null) {
|
||||||
|
sql += " ORDER BY fkn.nspname,fkc.relname,pos.n";
|
||||||
|
} else {
|
||||||
|
sql += " ORDER BY pkn.nspname,pkc.relname,pos.n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return connection.createStatement().executeQuery(sql);
|
||||||
|
} else if (connection.haveMinimumServerVersion("7.3")) {
|
||||||
select = "SELECT DISTINCT n1.nspname as pnspname,n2.nspname as fnspname, ";
|
select = "SELECT DISTINCT n1.nspname as pnspname,n2.nspname as fnspname, ";
|
||||||
from = " FROM pg_catalog.pg_namespace n1 "+
|
from = " FROM pg_catalog.pg_namespace n1 "+
|
||||||
" JOIN pg_catalog.pg_class c1 ON (c1.relnamespace = n1.oid) "+
|
" JOIN pg_catalog.pg_class c1 ON (c1.relnamespace = n1.oid) "+
|
||||||
|
@ -9,7 +9,7 @@ import java.sql.*;
|
|||||||
*
|
*
|
||||||
* PS: Do you know how difficult it is to type on a train? ;-)
|
* PS: Do you know how difficult it is to type on a train? ;-)
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java,v 1.20 2003/11/29 22:41:23 pgsql Exp $
|
* $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java,v 1.21 2003/12/11 15:50:20 davec Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class DatabaseMetaDataTest extends TestCase
|
public class DatabaseMetaDataTest extends TestCase
|
||||||
@ -169,6 +169,75 @@ public class DatabaseMetaDataTest extends TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testForeignKeysToUniqueIndexes()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!TestUtil.haveMinimumServerVersion(con,"7.4"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Connection con1 = TestUtil.openDB();
|
||||||
|
TestUtil.createTable( con1, "pkt", "a int not null, b int not null, CONSTRAINT pkt_pk_a PRIMARY KEY (a), CONSTRAINT pkt_un_b UNIQUE (b)");
|
||||||
|
TestUtil.createTable( con1, "fkt", "c int, d int, CONSTRAINT fkt_fk_c FOREIGN KEY (c) REFERENCES pkt(b)");
|
||||||
|
|
||||||
|
DatabaseMetaData dbmd = con.getMetaData();
|
||||||
|
ResultSet rs = dbmd.getImportedKeys("","","fkt");
|
||||||
|
int j = 0;
|
||||||
|
for (; rs.next(); j++)
|
||||||
|
{
|
||||||
|
assertTrue("pkt".equals(rs.getString("PKTABLE_NAME")));
|
||||||
|
assertTrue("fkt".equals(rs.getString("FKTABLE_NAME")));
|
||||||
|
assertTrue("pkt_un_b".equals(rs.getString("PK_NAME")));
|
||||||
|
assertTrue("b".equals(rs.getString("PKCOLUMN_NAME")));
|
||||||
|
}
|
||||||
|
assertTrue(j == 1);
|
||||||
|
|
||||||
|
TestUtil.dropTable(con1, "fkt");
|
||||||
|
TestUtil.dropTable(con1, "pkt");
|
||||||
|
con1.close();
|
||||||
|
}
|
||||||
|
catch (SQLException ex)
|
||||||
|
{
|
||||||
|
fail(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMultiColumnForeignKeys()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Connection con1 = TestUtil.openDB();
|
||||||
|
TestUtil.createTable( con1, "pkt", "a int not null, b int not null, CONSTRAINT pkt_pk PRIMARY KEY (a,b)");
|
||||||
|
TestUtil.createTable( con1, "fkt", "c int, d int, CONSTRAINT fkt_fk_pkt FOREIGN KEY (c,d) REFERENCES pkt(b,a)");
|
||||||
|
|
||||||
|
DatabaseMetaData dbmd = con.getMetaData();
|
||||||
|
ResultSet rs = dbmd.getImportedKeys("","","fkt");
|
||||||
|
int j = 0;
|
||||||
|
for (; rs.next(); j++)
|
||||||
|
{
|
||||||
|
assertTrue("pkt".equals(rs.getString("PKTABLE_NAME")));
|
||||||
|
assertTrue("fkt".equals(rs.getString("FKTABLE_NAME")));
|
||||||
|
assertTrue(j+1 == rs.getInt("KEY_SEQ"));
|
||||||
|
if (j == 0) {
|
||||||
|
assertTrue("b".equals(rs.getString("PKCOLUMN_NAME")));
|
||||||
|
assertTrue("c".equals(rs.getString("FKCOLUMN_NAME")));
|
||||||
|
} else {
|
||||||
|
assertTrue("a".equals(rs.getString("PKCOLUMN_NAME")));
|
||||||
|
assertTrue("d".equals(rs.getString("FKCOLUMN_NAME")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue(j == 2);
|
||||||
|
|
||||||
|
TestUtil.dropTable(con1, "fkt");
|
||||||
|
TestUtil.dropTable(con1, "pkt");
|
||||||
|
con1.close();
|
||||||
|
}
|
||||||
|
catch (SQLException ex)
|
||||||
|
{
|
||||||
|
fail(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void testForeignKeys()
|
public void testForeignKeys()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
Reference in New Issue
Block a user