4 * Copyright (c) 2002-2009, PostgreSQL Global Development Group
8 #include "postgres_fe.h"
11 #include "pqexpbuffer.h"
15 main(int argc
, char **argv
)
28 pk
; /* loop counters */
32 fprintf(stderr
, "Usage: %s database\n", argv
[0]);
36 initPQExpBuffer(&sql
);
38 appendPQExpBuffer(&sql
, "dbname=%s", argv
[1]);
40 conn
= PQconnectdb(sql
.data
);
41 if (PQstatus(conn
) == CONNECTION_BAD
)
43 fprintf(stderr
, "connection error: %s\n", PQerrorMessage(conn
));
47 /* Get a list of relations that have OIDs */
49 resetPQExpBuffer(&sql
);
51 appendPQExpBuffer(&sql
, "%s",
52 "SET search_path = public;"
53 "SELECT c.relname, (SELECT nspname FROM "
54 "pg_catalog.pg_namespace n WHERE n.oid = c.relnamespace) AS nspname "
55 "FROM pg_catalog.pg_class c "
56 "WHERE c.relkind = 'r' "
58 "ORDER BY nspname, c.relname"
61 res
= PQexec(conn
, sql
.data
);
62 if (!res
|| PQresultStatus(res
) != PGRES_TUPLES_OK
)
64 fprintf(stderr
, "sql error: %s\n", PQerrorMessage(conn
));
69 /* Get a list of columns of OID type (or any OID-alias type) */
71 resetPQExpBuffer(&sql
);
73 appendPQExpBuffer(&sql
, "%s",
75 "(SELECT nspname FROM pg_catalog.pg_namespace n WHERE n.oid = c.relnamespace) AS nspname, "
77 "FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a "
78 "WHERE a.attnum > 0 AND c.relkind = 'r' "
79 "AND a.attrelid = c.oid "
80 "AND a.atttypid IN ('pg_catalog.oid'::regtype, "
81 " 'pg_catalog.regclass'::regtype, "
82 " 'pg_catalog.regoper'::regtype, "
83 " 'pg_catalog.regoperator'::regtype, "
84 " 'pg_catalog.regproc'::regtype, "
85 " 'pg_catalog.regprocedure'::regtype, "
86 " 'pg_catalog.regtype'::regtype, "
87 " 'pg_catalog.regconfig'::regtype, "
88 " 'pg_catalog.regdictionary'::regtype) "
89 "ORDER BY nspname, c.relname, a.attnum"
92 res
= PQexec(conn
, sql
.data
);
93 if (!res
|| PQresultStatus(res
) != PGRES_TUPLES_OK
)
95 fprintf(stderr
, "sql error: %s\n", PQerrorMessage(conn
));
101 * For each column and each relation-having-OIDs, look to see if the
102 * column contains any values matching entries in the relation.
105 for (fk
= 0; fk
< PQntuples(fkrel_res
); fk
++)
107 fk_relname
= PQgetvalue(fkrel_res
, fk
, 0);
108 fk_nspname
= PQgetvalue(fkrel_res
, fk
, 1);
109 fk_attname
= PQgetvalue(fkrel_res
, fk
, 2);
111 for (pk
= 0; pk
< PQntuples(pkrel_res
); pk
++)
113 pk_relname
= PQgetvalue(pkrel_res
, pk
, 0);
114 pk_nspname
= PQgetvalue(pkrel_res
, pk
, 1);
116 resetPQExpBuffer(&sql
);
118 appendPQExpBuffer(&sql
,
120 "FROM \"%s\".\"%s\" t1, "
122 "WHERE t1.\"%s\"::pg_catalog.oid = t2.oid "
124 fk_nspname
, fk_relname
, pk_nspname
, pk_relname
, fk_attname
);
126 res
= PQexec(conn
, sql
.data
);
127 if (!res
|| PQresultStatus(res
) != PGRES_TUPLES_OK
)
129 fprintf(stderr
, "sql error: %s\n", PQerrorMessage(conn
));
133 if (PQntuples(res
) != 0)
134 printf("Join %s.%s.%s => %s.%s.oid\n",
135 fk_nspname
, fk_relname
, fk_attname
,
136 pk_nspname
, pk_relname
);
146 termPQExpBuffer(&sql
);