findoidjoins.c 2.22 KB
Newer Older
1 2 3 4 5 6
/*
 * findoidjoins.c, required pgsql/contrib/pginterface
 *
 */

#include <stdio.h>
7
#include <string.h>
8 9 10 11 12 13 14 15 16 17 18 19 20
#include "halt.h"
#include <libpq-fe.h>
#include "pginterface.h"

PGresult *attres, *relres;

int
main(int argc, char **argv)
{
	char		query[4000];
	char		relname[256];
	char		relname2[256];
	char		attname[256];
21
	char		typname[256];
22 23 24 25 26 27 28 29 30 31 32 33
	int			count;

	if (argc != 2)
		halt("Usage:  %s database\n", argv[0]);

	connectdb(argv[1], NULL, NULL, NULL, NULL);
	on_error_continue();
	on_error_stop();

	doquery("BEGIN WORK");
	doquery("\
		DECLARE c_attributes BINARY CURSOR FOR \
34
		SELECT typname, relname, a.attname \
35 36 37
		FROM pg_class c, pg_attribute a, pg_type t \
		WHERE a.attnum > 0 AND \
			  relkind = 'r' AND \
38
			  relhasrules = 'f' AND \
39 40
			  (typname = 'oid' OR \
			   typname = 'regproc') AND \
41 42
			  a.attrelid = c.oid AND \
			  a.atttypid = t.oid \
43
		ORDER BY 2, a.attnum ; \
44 45 46 47 48 49 50 51 52
		");
	doquery("FETCH ALL IN c_attributes");
	attres = get_result();

	doquery("\
		DECLARE c_relations BINARY CURSOR FOR \
		SELECT relname \
		FROM pg_class c \
		WHERE relkind = 'r' AND \
53
			  relhasrules = 'f' AND \
54 55 56 57 58 59 60
			  relname != 'pg_user' \
		ORDER BY 1; \
		");
	doquery("FETCH ALL IN c_relations");
	relres = get_result();
	
	set_result(attres);
61
	while (fetch(typname, relname, attname) != END_OF_TUPLES)
62 63 64 65 66 67
	{
		set_result(relres);
		reset_fetch();
		while (fetch(relname2) != END_OF_TUPLES)
		{
			unset_result(relres);
68 69 70 71 72 73 74 75 76 77 78 79
			if (strcmp(typname, "oid") == 0)
				sprintf(query,"\
					DECLARE c_matches BINARY CURSOR FOR \
					SELECT	count(*)
					FROM	%s t1, %s t2 \
					WHERE	t1.%s = t2.oid", relname, relname2, attname);
			else
				sprintf(query,"\
					DECLARE c_matches BINARY CURSOR FOR \
					SELECT	count(*)
					FROM	%s t1, %s t2 \
					WHERE	RegprocToOid(t1.%s) = t2.oid", relname, relname2, attname);
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105

			doquery(query);
			doquery("FETCH ALL IN c_matches");
			fetch(&count);
			if (count != 0)
				printf("Join %s.%s => %s.oid\n", relname, attname, relname2);
			doquery("CLOSE c_matches");
			set_result(relres);
		}
		set_result(attres);
	}

	set_result(relres);
	doquery("CLOSE c_relations");
	PQclear(relres);

	set_result(attres);
	doquery("CLOSE c_attributes");
	PQclear(attres);
	unset_result(attres);
	
	doquery("COMMIT WORK");

	disconnectdb();
	return 0;
}