diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index faee42ba103..ae9a6cfd8ec 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -1,4 +1,4 @@
-
+
@@ -1711,37 +1711,6 @@
-
- reltriggers
- int2
-
-
- Number of triggers on the table; see
- pg_trigger catalog
-
-
-
-
- relukeys
- int2
-
- Unused (not the number of unique keys)
-
-
-
- relfkeys
- int2
-
- Unused (not the number of foreign keys on the table)
-
-
-
- relrefs
- int2
-
- Unused
-
-
relhasoids
bool
@@ -1765,11 +1734,21 @@
bool
- True if table has rules; see
+ True if table has (or once had) rules; see
pg_rewrite catalog
+
+ relhastriggers
+ bool
+
+
+ True if table has (or once had) triggers; see
+ pg_trigger catalog
+
+
+
relhassubclass
bool
@@ -4499,13 +4478,6 @@
-
-
- pg_class.reltriggers needs to agree with the
- number of triggers found in this table for each relation.
-
-
-
@@ -6818,13 +6790,13 @@
hasrules
boolean
pg_class.relhasrules
- true if table has rules
+ true if table has (or once had) rules
hastriggers
boolean
- pg_class.reltriggers
- true if table has triggers
+ pg_class.relhastriggers
+ true if table has (or once had) triggers
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index f7585632e05..ad0dca13e1b 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.342 2008/11/02 01:45:27 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.343 2008/11/09 21:24:32 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -641,13 +641,10 @@ InsertPgClassTuple(Relation pg_class_desc,
values[Anum_pg_class_relkind - 1] = CharGetDatum(rd_rel->relkind);
values[Anum_pg_class_relnatts - 1] = Int16GetDatum(rd_rel->relnatts);
values[Anum_pg_class_relchecks - 1] = Int16GetDatum(rd_rel->relchecks);
- values[Anum_pg_class_reltriggers - 1] = Int16GetDatum(rd_rel->reltriggers);
- values[Anum_pg_class_relukeys - 1] = Int16GetDatum(rd_rel->relukeys);
- values[Anum_pg_class_relfkeys - 1] = Int16GetDatum(rd_rel->relfkeys);
- values[Anum_pg_class_relrefs - 1] = Int16GetDatum(rd_rel->relrefs);
values[Anum_pg_class_relhasoids - 1] = BoolGetDatum(rd_rel->relhasoids);
values[Anum_pg_class_relhaspkey - 1] = BoolGetDatum(rd_rel->relhaspkey);
values[Anum_pg_class_relhasrules - 1] = BoolGetDatum(rd_rel->relhasrules);
+ values[Anum_pg_class_relhastriggers - 1] = BoolGetDatum(rd_rel->relhastriggers);
values[Anum_pg_class_relhassubclass - 1] = BoolGetDatum(rd_rel->relhassubclass);
values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
/* start out with empty permissions */
@@ -2366,7 +2363,7 @@ heap_truncate_check_FKs(List *relations, bool tempTables)
{
Relation rel = lfirst(cell);
- if (rel->rd_rel->reltriggers != 0)
+ if (rel->rd_rel->relhastriggers)
oids = lappend_oid(oids, RelationGetRelid(rel));
}
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 46023c60b04..07c0809609d 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -3,7 +3,7 @@
*
* Copyright (c) 1996-2008, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.55 2008/09/21 19:38:56 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.56 2008/11/09 21:24:32 tgl Exp $
*/
CREATE VIEW pg_roles AS
@@ -84,7 +84,7 @@ CREATE VIEW pg_tables AS
T.spcname AS tablespace,
C.relhasindex AS hasindexes,
C.relhasrules AS hasrules,
- (C.reltriggers > 0) AS hastriggers
+ C.relhastriggers AS hastriggers
FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
WHERE C.relkind = 'r';
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 53fb1995fc8..07c686c91da 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.239 2008/11/02 01:45:28 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.240 2008/11/09 21:24:32 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -95,7 +95,6 @@ CreateTrigger(CreateTrigStmt *stmt, Oid constraintOid)
Oid funcoid;
Oid funcrettype;
Oid trigoid;
- int found = 0;
int i;
char constrtrigname[NAMEDATALEN];
char *trigname;
@@ -280,10 +279,9 @@ CreateTrigger(CreateTrigStmt *stmt, Oid constraintOid)
}
/*
- * Scan pg_trigger for existing triggers on relation. We do this mainly
- * because we must count them; a secondary benefit is to give a nice error
- * message if there's already a trigger of the same name. (The unique
- * index on tgrelid/tgname would complain anyway.)
+ * Scan pg_trigger for existing triggers on relation. We do this only
+ * to give a nice error message if there's already a trigger of the same
+ * name. (The unique index on tgrelid/tgname would complain anyway.)
*
* NOTE that this is cool only because we have AccessExclusiveLock on the
* relation, so the trigger set won't be changing underneath us.
@@ -303,7 +301,6 @@ CreateTrigger(CreateTrigStmt *stmt, Oid constraintOid)
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("trigger \"%s\" for relation \"%s\" already exists",
trigname, stmt->relation->relname)));
- found++;
}
systable_endscan(tgscan);
@@ -405,7 +402,7 @@ CreateTrigger(CreateTrigStmt *stmt, Oid constraintOid)
elog(ERROR, "cache lookup failed for relation %u",
RelationGetRelid(rel));
- ((Form_pg_class) GETSTRUCT(tuple))->reltriggers = found + 1;
+ ((Form_pg_class) GETSTRUCT(tuple))->relhastriggers = true;
simple_heap_update(pgrel, &tuple->t_self, tuple);
@@ -818,9 +815,6 @@ RemoveTriggerById(Oid trigOid)
HeapTuple tup;
Oid relid;
Relation rel;
- Relation pgrel;
- HeapTuple tuple;
- Form_pg_class classForm;
tgrel = heap_open(TriggerRelationId, RowExclusiveLock);
@@ -867,33 +861,15 @@ RemoveTriggerById(Oid trigOid)
heap_close(tgrel, RowExclusiveLock);
/*
- * Update relation's pg_class entry. Crucial side-effect: other backends
- * (and this one too!) are sent SI message to make them rebuild relcache
- * entries.
- *
- * Note this is OK only because we have AccessExclusiveLock on the rel, so
- * no one else is creating/deleting triggers on this rel at the same time.
+ * We do not bother to try to determine whether any other triggers remain,
+ * which would be needed in order to decide whether it's safe to clear
+ * the relation's relhastriggers. (In any case, there might be a
+ * concurrent process adding new triggers.) Instead, just force a
+ * relcache inval to make other backends (and this one too!) rebuild
+ * their relcache entries. There's no great harm in leaving relhastriggers
+ * true even if there are no triggers left.
*/
- pgrel = heap_open(RelationRelationId, RowExclusiveLock);
- tuple = SearchSysCacheCopy(RELOID,
- ObjectIdGetDatum(relid),
- 0, 0, 0);
- if (!HeapTupleIsValid(tuple))
- elog(ERROR, "cache lookup failed for relation %u", relid);
- classForm = (Form_pg_class) GETSTRUCT(tuple);
-
- if (classForm->reltriggers == 0) /* should not happen */
- elog(ERROR, "relation \"%s\" has reltriggers = 0",
- RelationGetRelationName(rel));
- classForm->reltriggers--;
-
- simple_heap_update(pgrel, &tuple->t_self, tuple);
-
- CatalogUpdateIndexes(pgrel, tuple);
-
- heap_freetuple(tuple);
-
- heap_close(pgrel, RowExclusiveLock);
+ CacheInvalidateRelcache(rel);
/* Keep lock on trigger's rel until end of xact */
heap_close(rel, NoLock);
@@ -1134,18 +1110,23 @@ void
RelationBuildTriggers(Relation relation)
{
TriggerDesc *trigdesc;
- int ntrigs = relation->rd_rel->reltriggers;
+ int numtrigs;
+ int maxtrigs;
Trigger *triggers;
- int found = 0;
Relation tgrel;
ScanKeyData skey;
SysScanDesc tgscan;
HeapTuple htup;
MemoryContext oldContext;
+ int i;
- Assert(ntrigs > 0); /* else I should not have been called */
-
- triggers = (Trigger *) palloc(ntrigs * sizeof(Trigger));
+ /*
+ * Allocate a working array to hold the triggers (the array is extended
+ * if necessary)
+ */
+ maxtrigs = 16;
+ triggers = (Trigger *) palloc(maxtrigs * sizeof(Trigger));
+ numtrigs = 0;
/*
* Note: since we scan the triggers using TriggerRelidNameIndexId, we will
@@ -1167,10 +1148,12 @@ RelationBuildTriggers(Relation relation)
Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(htup);
Trigger *build;
- if (found >= ntrigs)
- elog(ERROR, "too many trigger records found for relation \"%s\"",
- RelationGetRelationName(relation));
- build = &(triggers[found]);
+ if (numtrigs >= maxtrigs)
+ {
+ maxtrigs *= 2;
+ triggers = (Trigger *) repalloc(triggers, maxtrigs * sizeof(Trigger));
+ }
+ build = &(triggers[numtrigs]);
build->tgoid = HeapTupleGetOid(htup);
build->tgname = DatumGetCString(DirectFunctionCall1(nameout,
@@ -1199,7 +1182,6 @@ RelationBuildTriggers(Relation relation)
bytea *val;
bool isnull;
char *p;
- int i;
val = DatumGetByteaP(fastgetattr(htup,
Anum_pg_trigger_tgargs,
@@ -1218,23 +1200,25 @@ RelationBuildTriggers(Relation relation)
else
build->tgargs = NULL;
- found++;
+ numtrigs++;
}
systable_endscan(tgscan);
heap_close(tgrel, AccessShareLock);
- if (found != ntrigs)
- elog(ERROR, "%d trigger record(s) not found for relation \"%s\"",
- ntrigs - found,
- RelationGetRelationName(relation));
+ /* There might not be any triggers */
+ if (numtrigs == 0)
+ {
+ pfree(triggers);
+ return;
+ }
/* Build trigdesc */
trigdesc = (TriggerDesc *) palloc0(sizeof(TriggerDesc));
trigdesc->triggers = triggers;
- trigdesc->numtriggers = ntrigs;
- for (found = 0; found < ntrigs; found++)
- InsertTrigger(trigdesc, &(triggers[found]), found);
+ trigdesc->numtriggers = numtrigs;
+ for (i = 0; i < numtrigs; i++)
+ InsertTrigger(trigdesc, &(triggers[i]), i);
/* Copy completed trigdesc into cache storage */
oldContext = MemoryContextSwitchTo(CacheMemoryContext);
diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c
index 6f40944ef26..6212add6bcb 100644
--- a/src/backend/rewrite/rewriteDefine.c
+++ b/src/backend/rewrite/rewriteDefine.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/rewrite/rewriteDefine.c,v 1.131 2008/11/02 01:45:28 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/rewrite/rewriteDefine.c,v 1.132 2008/11/09 21:24:32 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -371,7 +371,11 @@ DefineQueryRewrite(char *rulename,
*
* If so, check that the relation is empty because the storage for the
* relation is going to be deleted. Also insist that the rel not have
- * any triggers, indexes, or child tables.
+ * any triggers, indexes, or child tables. (Note: these tests are
+ * too strict, because they will reject relations that once had such
+ * but don't anymore. But we don't really care, because this whole
+ * business of converting relations to views is just a kluge to allow
+ * loading ancient pg_dump files.)
*/
if (event_relation->rd_rel->relkind != RELKIND_VIEW)
{
@@ -385,7 +389,7 @@ DefineQueryRewrite(char *rulename,
RelationGetRelationName(event_relation))));
heap_endscan(scanDesc);
- if (event_relation->rd_rel->reltriggers != 0)
+ if (event_relation->rd_rel->relhastriggers)
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("could not convert table \"%s\" to a view because it has triggers",
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index cec75ada720..92adfd8300d 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.274 2008/09/30 10:52:13 heikki Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.275 2008/11/09 21:24:32 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -856,7 +856,7 @@ RelationBuildDesc(Oid targetRelId, Relation oldrelation)
relation->rd_rulescxt = NULL;
}
- if (relation->rd_rel->reltriggers > 0)
+ if (relation->rd_rel->relhastriggers)
RelationBuildTriggers(relation);
else
relation->trigdesc = NULL;
@@ -2641,7 +2641,7 @@ RelationCacheInitializePhase2(void)
*/
if (relation->rd_rel->relhasrules && relation->rd_rules == NULL)
RelationBuildRuleLock(relation);
- if (relation->rd_rel->reltriggers > 0 && relation->trigdesc == NULL)
+ if (relation->rd_rel->relhastriggers && relation->trigdesc == NULL)
RelationBuildTriggers(relation);
}
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 936ff42bb87..d6c0f304f07 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -12,7 +12,7 @@
* by PostgreSQL
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.504 2008/11/09 00:28:35 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.505 2008/11/09 21:24:32 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -3070,7 +3070,7 @@ getTables(int *numTables)
int i_relacl;
int i_rolname;
int i_relchecks;
- int i_reltriggers;
+ int i_relhastriggers;
int i_relhasindex;
int i_relhasrules;
int i_relhasoids;
@@ -3102,7 +3102,7 @@ getTables(int *numTables)
* we cannot correctly identify inherited columns, owned sequences, etc.
*/
- if (g_fout->remoteVersion >= 80200)
+ if (g_fout->remoteVersion >= 80400)
{
/*
* Left join to pick up dependency info linking sequences to their
@@ -3112,7 +3112,36 @@ getTables(int *numTables)
"SELECT c.tableoid, c.oid, relname, "
"relacl, relkind, relnamespace, "
"(%s relowner) as rolname, "
- "relchecks, reltriggers, "
+ "relchecks, relhastriggers, "
+ "relhasindex, relhasrules, relhasoids, "
+ "d.refobjid as owning_tab, "
+ "d.refobjsubid as owning_col, "
+ "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
+ "array_to_string(c.reloptions, ', ') as reloptions "
+ "from pg_class c "
+ "left join pg_depend d on "
+ "(c.relkind = '%c' and "
+ "d.classid = c.tableoid and d.objid = c.oid and "
+ "d.objsubid = 0 and "
+ "d.refclassid = c.tableoid and d.deptype = 'a') "
+ "where relkind in ('%c', '%c', '%c', '%c') "
+ "order by c.oid",
+ username_subquery,
+ RELKIND_SEQUENCE,
+ RELKIND_RELATION, RELKIND_SEQUENCE,
+ RELKIND_VIEW, RELKIND_COMPOSITE_TYPE);
+ }
+ else if (g_fout->remoteVersion >= 80200)
+ {
+ /*
+ * Left join to pick up dependency info linking sequences to their
+ * owning column, if any (note this dependency is AUTO as of 8.2)
+ */
+ appendPQExpBuffer(query,
+ "SELECT c.tableoid, c.oid, relname, "
+ "relacl, relkind, relnamespace, "
+ "(%s relowner) as rolname, "
+ "relchecks, (reltriggers <> 0) as relhastriggers, "
"relhasindex, relhasrules, relhasoids, "
"d.refobjid as owning_tab, "
"d.refobjsubid as owning_col, "
@@ -3141,7 +3170,7 @@ getTables(int *numTables)
"SELECT c.tableoid, c.oid, relname, "
"relacl, relkind, relnamespace, "
"(%s relowner) as rolname, "
- "relchecks, reltriggers, "
+ "relchecks, (reltriggers <> 0) as relhastriggers, "
"relhasindex, relhasrules, relhasoids, "
"d.refobjid as owning_tab, "
"d.refobjsubid as owning_col, "
@@ -3170,7 +3199,7 @@ getTables(int *numTables)
"SELECT c.tableoid, c.oid, relname, "
"relacl, relkind, relnamespace, "
"(%s relowner) as rolname, "
- "relchecks, reltriggers, "
+ "relchecks, (reltriggers <> 0) as relhastriggers, "
"relhasindex, relhasrules, relhasoids, "
"d.refobjid as owning_tab, "
"d.refobjsubid as owning_col, "
@@ -3195,7 +3224,7 @@ getTables(int *numTables)
"SELECT tableoid, oid, relname, relacl, relkind, "
"0::oid as relnamespace, "
"(%s relowner) as rolname, "
- "relchecks, reltriggers, "
+ "relchecks, (reltriggers <> 0) as relhastriggers, "
"relhasindex, relhasrules, relhasoids, "
"NULL::oid as owning_tab, "
"NULL::int4 as owning_col, "
@@ -3214,7 +3243,7 @@ getTables(int *numTables)
"SELECT tableoid, oid, relname, relacl, relkind, "
"0::oid as relnamespace, "
"(%s relowner) as rolname, "
- "relchecks, reltriggers, "
+ "relchecks, (reltriggers <> 0) as relhastriggers, "
"relhasindex, relhasrules, "
"'t'::bool as relhasoids, "
"NULL::oid as owning_tab, "
@@ -3244,7 +3273,7 @@ getTables(int *numTables)
"ELSE relkind END AS relkind,"
"0::oid as relnamespace, "
"(%s relowner) as rolname, "
- "relchecks, reltriggers, "
+ "relchecks, (reltriggers <> 0) as relhastriggers, "
"relhasindex, relhasrules, "
"'t'::bool as relhasoids, "
"NULL::oid as owning_tab, "
@@ -3285,7 +3314,7 @@ getTables(int *numTables)
i_relkind = PQfnumber(res, "relkind");
i_rolname = PQfnumber(res, "rolname");
i_relchecks = PQfnumber(res, "relchecks");
- i_reltriggers = PQfnumber(res, "reltriggers");
+ i_relhastriggers = PQfnumber(res, "relhastriggers");
i_relhasindex = PQfnumber(res, "relhasindex");
i_relhasrules = PQfnumber(res, "relhasrules");
i_relhasoids = PQfnumber(res, "relhasoids");
@@ -3323,9 +3352,9 @@ getTables(int *numTables)
tblinfo[i].relkind = *(PQgetvalue(res, i, i_relkind));
tblinfo[i].hasindex = (strcmp(PQgetvalue(res, i, i_relhasindex), "t") == 0);
tblinfo[i].hasrules = (strcmp(PQgetvalue(res, i, i_relhasrules), "t") == 0);
+ tblinfo[i].hastriggers = (strcmp(PQgetvalue(res, i, i_relhastriggers), "t") == 0);
tblinfo[i].hasoids = (strcmp(PQgetvalue(res, i, i_relhasoids), "t") == 0);
tblinfo[i].ncheck = atoi(PQgetvalue(res, i, i_relchecks));
- tblinfo[i].ntrig = atoi(PQgetvalue(res, i, i_reltriggers));
if (PQgetisnull(res, i, i_owning_tab))
{
tblinfo[i].owning_tab = InvalidOid;
@@ -3779,7 +3808,7 @@ getConstraints(TableInfo tblinfo[], int numTables)
{
TableInfo *tbinfo = &tblinfo[i];
- if (tbinfo->ntrig == 0 || !tbinfo->dobj.dump)
+ if (!tbinfo->hastriggers || !tbinfo->dobj.dump)
continue;
if (g_verbose)
@@ -4090,7 +4119,7 @@ getTriggers(TableInfo tblinfo[], int numTables)
{
TableInfo *tbinfo = &tblinfo[i];
- if (tbinfo->ntrig == 0 || !tbinfo->dobj.dump)
+ if (!tbinfo->hastriggers || !tbinfo->dobj.dump)
continue;
if (g_verbose)
@@ -4177,16 +4206,6 @@ getTriggers(TableInfo tblinfo[], int numTables)
ntups = PQntuples(res);
- /*
- * We may have less triggers than recorded due to having ignored
- * foreign-key triggers
- */
- if (ntups > tbinfo->ntrig)
- {
- write_msg(NULL, "expected %d triggers on table \"%s\" but found %d\n",
- tbinfo->ntrig, tbinfo->dobj.name, ntups);
- exit_nicely();
- }
i_tableoid = PQfnumber(res, "tableoid");
i_oid = PQfnumber(res, "oid");
i_tgname = PQfnumber(res, "tgname");
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 80f02efb2f1..9684163e3d5 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.142 2008/10/31 08:39:21 heikki Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.143 2008/11/09 21:24:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -240,9 +240,9 @@ typedef struct _tableInfo
char *reloptions; /* options specified by WITH (...) */
bool hasindex; /* does it have any indexes? */
bool hasrules; /* does it have any rules? */
+ bool hastriggers; /* does it have any triggers? */
bool hasoids; /* does it have OIDs? */
int ncheck; /* # of CHECK expressions */
- int ntrig; /* # of triggers */
/* these two are set only if table is a sequence owned by a column: */
Oid owning_tab; /* OID of table owning sequence */
int owning_col; /* attr # of column owning sequence */
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index d0ca9a034b6..53087771afd 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -8,7 +8,7 @@
*
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.187 2008/11/06 15:18:35 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.188 2008/11/09 21:24:33 tgl Exp $
*/
#include "postgres_fe.h"
@@ -840,10 +840,10 @@ describeOneTableDetails(const char *schemaname,
struct
{
int16 checks;
- int16 triggers;
char relkind;
bool hasindex;
bool hasrules;
+ bool hastriggers;
bool hasoids;
Oid tablespace;
} tableinfo;
@@ -861,9 +861,10 @@ describeOneTableDetails(const char *schemaname,
/* Get general table info */
printfPQExpBuffer(&buf,
- "SELECT relhasindex, relkind, relchecks, reltriggers, relhasrules, "
+ "SELECT relchecks, relkind, relhasindex, relhasrules, %s, "
"relhasoids%s\n"
"FROM pg_catalog.pg_class WHERE oid = '%s'",
+ (pset.sversion >= 80400 ? "relhastriggers" : "reltriggers <> 0"),
(pset.sversion >= 80000 ? ", reltablespace" : ""),
oid);
res = PSQLexec(buf.data, false);
@@ -879,11 +880,11 @@ describeOneTableDetails(const char *schemaname,
goto error_return;
}
- tableinfo.checks = atoi(PQgetvalue(res, 0, 2));
- tableinfo.triggers = atoi(PQgetvalue(res, 0, 3));
+ tableinfo.checks = atoi(PQgetvalue(res, 0, 0));
tableinfo.relkind = *(PQgetvalue(res, 0, 1));
- tableinfo.hasindex = strcmp(PQgetvalue(res, 0, 0), "t") == 0;
- tableinfo.hasrules = strcmp(PQgetvalue(res, 0, 4), "t") == 0;
+ tableinfo.hasindex = strcmp(PQgetvalue(res, 0, 2), "t") == 0;
+ tableinfo.hasrules = strcmp(PQgetvalue(res, 0, 3), "t") == 0;
+ tableinfo.hastriggers = strcmp(PQgetvalue(res, 0, 4), "t") == 0;
tableinfo.hasoids = strcmp(PQgetvalue(res, 0, 5), "t") == 0;
tableinfo.tablespace = (pset.sversion >= 80000) ?
atooid(PQgetvalue(res, 0, 6)) : 0;
@@ -1287,7 +1288,7 @@ describeOneTableDetails(const char *schemaname,
}
/* print foreign-key constraints (there are none if no triggers) */
- if (tableinfo.triggers)
+ if (tableinfo.hastriggers)
{
printfPQExpBuffer(&buf,
"SELECT conname,\n"
@@ -1318,7 +1319,7 @@ describeOneTableDetails(const char *schemaname,
}
/* print incoming foreign-key references (none if no triggers) */
- if (tableinfo.triggers)
+ if (tableinfo.hastriggers)
{
printfPQExpBuffer(&buf,
"SELECT conname, conrelid::pg_catalog.regclass,\n"
@@ -1446,7 +1447,7 @@ describeOneTableDetails(const char *schemaname,
}
/* print triggers (but ignore foreign-key triggers) */
- if (tableinfo.triggers)
+ if (tableinfo.hastriggers)
{
printfPQExpBuffer(&buf,
"SELECT t.tgname, "
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 58bda0f16d3..599e01db6a1 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.502 2008/11/04 14:49:11 petere Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.503 2008/11/09 21:24:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200811041
+#define CATALOG_VERSION_NO 200811091
#endif
diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h
index 365f45b3905..e816b3ce9ad 100644
--- a/src/include/catalog/pg_attribute.h
+++ b/src/include/catalog/pg_attribute.h
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.140 2008/07/30 17:05:05 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.141 2008/11/09 21:24:33 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@@ -409,17 +409,14 @@ DATA(insert ( 1249 tableoid 26 0 4 -7 0 -1 -1 t p i t f f t 0));
{ 1259, {"relkind"}, 18, -1, 1, 14, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
{ 1259, {"relnatts"}, 21, -1, 2, 15, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
{ 1259, {"relchecks"}, 21, -1, 2, 16, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
-{ 1259, {"reltriggers"}, 21, -1, 2, 17, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
-{ 1259, {"relukeys"}, 21, -1, 2, 18, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
-{ 1259, {"relfkeys"}, 21, -1, 2, 19, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
-{ 1259, {"relrefs"}, 21, -1, 2, 20, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
-{ 1259, {"relhasoids"}, 16, -1, 1, 21, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
-{ 1259, {"relhaspkey"}, 16, -1, 1, 22, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
-{ 1259, {"relhasrules"}, 16, -1, 1, 23, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
-{ 1259, {"relhassubclass"},16, -1, 1, 24, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
-{ 1259, {"relfrozenxid"}, 28, -1, 4, 25, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1259, {"relacl"}, 1034, -1, -1, 26, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
-{ 1259, {"reloptions"}, 1009, -1, -1, 27, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }
+{ 1259, {"relhasoids"}, 16, -1, 1, 17, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
+{ 1259, {"relhaspkey"}, 16, -1, 1, 18, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
+{ 1259, {"relhasrules"}, 16, -1, 1, 19, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
+{ 1259, {"relhastriggers"},16, -1, 1, 20, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
+{ 1259, {"relhassubclass"},16, -1, 1, 21, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
+{ 1259, {"relfrozenxid"}, 28, -1, 4, 22, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
+{ 1259, {"relacl"}, 1034, -1, -1, 23, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
+{ 1259, {"reloptions"}, 1009, -1, -1, 24, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }
DATA(insert ( 1259 relname 19 -1 NAMEDATALEN 1 0 -1 -1 f p c t f f t 0));
DATA(insert ( 1259 relnamespace 26 -1 4 2 0 -1 -1 t p i t f f t 0));
@@ -437,17 +434,14 @@ DATA(insert ( 1259 relisshared 16 -1 1 13 0 -1 -1 t p c t f f t 0));
DATA(insert ( 1259 relkind 18 -1 1 14 0 -1 -1 t p c t f f t 0));
DATA(insert ( 1259 relnatts 21 -1 2 15 0 -1 -1 t p s t f f t 0));
DATA(insert ( 1259 relchecks 21 -1 2 16 0 -1 -1 t p s t f f t 0));
-DATA(insert ( 1259 reltriggers 21 -1 2 17 0 -1 -1 t p s t f f t 0));
-DATA(insert ( 1259 relukeys 21 -1 2 18 0 -1 -1 t p s t f f t 0));
-DATA(insert ( 1259 relfkeys 21 -1 2 19 0 -1 -1 t p s t f f t 0));
-DATA(insert ( 1259 relrefs 21 -1 2 20 0 -1 -1 t p s t f f t 0));
-DATA(insert ( 1259 relhasoids 16 -1 1 21 0 -1 -1 t p c t f f t 0));
-DATA(insert ( 1259 relhaspkey 16 -1 1 22 0 -1 -1 t p c t f f t 0));
-DATA(insert ( 1259 relhasrules 16 -1 1 23 0 -1 -1 t p c t f f t 0));
-DATA(insert ( 1259 relhassubclass 16 -1 1 24 0 -1 -1 t p c t f f t 0));
-DATA(insert ( 1259 relfrozenxid 28 -1 4 25 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1259 relacl 1034 -1 -1 26 1 -1 -1 f x i f f f t 0));
-DATA(insert ( 1259 reloptions 1009 -1 -1 27 1 -1 -1 f x i f f f t 0));
+DATA(insert ( 1259 relhasoids 16 -1 1 17 0 -1 -1 t p c t f f t 0));
+DATA(insert ( 1259 relhaspkey 16 -1 1 18 0 -1 -1 t p c t f f t 0));
+DATA(insert ( 1259 relhasrules 16 -1 1 19 0 -1 -1 t p c t f f t 0));
+DATA(insert ( 1259 relhastriggers 16 -1 1 20 0 -1 -1 t p c t f f t 0));
+DATA(insert ( 1259 relhassubclass 16 -1 1 21 0 -1 -1 t p c t f f t 0));
+DATA(insert ( 1259 relfrozenxid 28 -1 4 22 0 -1 -1 t p i t f f t 0));
+DATA(insert ( 1259 relacl 1034 -1 -1 23 1 -1 -1 f x i f f f t 0));
+DATA(insert ( 1259 reloptions 1009 -1 -1 24 1 -1 -1 f x i f f f t 0));
DATA(insert ( 1259 ctid 27 0 6 -1 0 -1 -1 f p s t f f t 0));
DATA(insert ( 1259 oid 26 0 4 -2 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1259 xmin 28 0 4 -3 0 -1 -1 t p i t f f t 0));
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 7f418aa8478..32b633b55ad 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.107 2008/07/30 17:05:05 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.108 2008/11/09 21:24:33 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@@ -52,14 +52,11 @@ CATALOG(pg_class,1259) BKI_BOOTSTRAP
* contain entries with negative attnums for system attributes.
*/
int2 relchecks; /* # of CHECK constraints for class */
- int2 reltriggers; /* # of TRIGGERs */
- int2 relukeys; /* # of Unique keys (not used) */
- int2 relfkeys; /* # of FOREIGN KEYs (not used) */
- int2 relrefs; /* # of references to this rel (not used) */
bool relhasoids; /* T if we generate OIDs for rows of rel */
- bool relhaspkey; /* has PRIMARY KEY index */
- bool relhasrules; /* has associated rules */
- bool relhassubclass; /* has derived classes */
+ bool relhaspkey; /* has (or has had) PRIMARY KEY index */
+ bool relhasrules; /* has (or has had) any rules */
+ bool relhastriggers; /* has (or has had) any TRIGGERs */
+ bool relhassubclass; /* has (or has had) derived classes */
TransactionId relfrozenxid; /* all Xids < this are frozen in this rel */
/*
@@ -88,7 +85,7 @@ typedef FormData_pg_class *Form_pg_class;
* ----------------
*/
-#define Natts_pg_class 27
+#define Natts_pg_class 24
#define Anum_pg_class_relname 1
#define Anum_pg_class_relnamespace 2
#define Anum_pg_class_reltype 3
@@ -105,17 +102,14 @@ typedef FormData_pg_class *Form_pg_class;
#define Anum_pg_class_relkind 14
#define Anum_pg_class_relnatts 15
#define Anum_pg_class_relchecks 16
-#define Anum_pg_class_reltriggers 17
-#define Anum_pg_class_relukeys 18
-#define Anum_pg_class_relfkeys 19
-#define Anum_pg_class_relrefs 20
-#define Anum_pg_class_relhasoids 21
-#define Anum_pg_class_relhaspkey 22
-#define Anum_pg_class_relhasrules 23
-#define Anum_pg_class_relhassubclass 24
-#define Anum_pg_class_relfrozenxid 25
-#define Anum_pg_class_relacl 26
-#define Anum_pg_class_reloptions 27
+#define Anum_pg_class_relhasoids 17
+#define Anum_pg_class_relhaspkey 18
+#define Anum_pg_class_relhasrules 19
+#define Anum_pg_class_relhastriggers 20
+#define Anum_pg_class_relhassubclass 21
+#define Anum_pg_class_relfrozenxid 22
+#define Anum_pg_class_relacl 23
+#define Anum_pg_class_reloptions 24
/* ----------------
* initial contents of pg_class
@@ -127,13 +121,13 @@ typedef FormData_pg_class *Form_pg_class;
*/
/* Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId */
-DATA(insert OID = 1247 ( pg_type PGNSP 71 PGUID 0 1247 0 0 0 0 0 f f r 28 0 0 0 0 0 t f f f 3 _null_ _null_ ));
+DATA(insert OID = 1247 ( pg_type PGNSP 71 PGUID 0 1247 0 0 0 0 0 f f r 28 0 t f f f f 3 _null_ _null_ ));
DESCR("");
-DATA(insert OID = 1249 ( pg_attribute PGNSP 75 PGUID 0 1249 0 0 0 0 0 f f r 17 0 0 0 0 0 f f f f 3 _null_ _null_ ));
+DATA(insert OID = 1249 ( pg_attribute PGNSP 75 PGUID 0 1249 0 0 0 0 0 f f r 17 0 f f f f f 3 _null_ _null_ ));
DESCR("");
-DATA(insert OID = 1255 ( pg_proc PGNSP 81 PGUID 0 1255 0 0 0 0 0 f f r 22 0 0 0 0 0 t f f f 3 _null_ _null_ ));
+DATA(insert OID = 1255 ( pg_proc PGNSP 81 PGUID 0 1255 0 0 0 0 0 f f r 22 0 t f f f f 3 _null_ _null_ ));
DESCR("");
-DATA(insert OID = 1259 ( pg_class PGNSP 83 PGUID 0 1259 0 0 0 0 0 f f r 27 0 0 0 0 0 t f f f 3 _null_ _null_ ));
+DATA(insert OID = 1259 ( pg_class PGNSP 83 PGUID 0 1259 0 0 0 0 0 f f r 24 0 t f f f f 3 _null_ _null_ ));
DESCR("");
#define RELKIND_INDEX 'i' /* secondary index */
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 50abeb5b0e0..80b002d5388 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1309,7 +1309,7 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem
pg_statio_user_sequences | SELECT pg_statio_all_sequences.relid, pg_statio_all_sequences.schemaname, pg_statio_all_sequences.relname, pg_statio_all_sequences.blks_read, pg_statio_all_sequences.blks_hit FROM pg_statio_all_sequences WHERE ((pg_statio_all_sequences.schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (pg_statio_all_sequences.schemaname !~ '^pg_toast'::text));
pg_statio_user_tables | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.schemaname, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE ((pg_statio_all_tables.schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (pg_statio_all_tables.schemaname !~ '^pg_toast'::text));
pg_stats | SELECT n.nspname AS schemaname, c.relname AS tablename, a.attname, s.stanullfrac AS null_frac, s.stawidth AS avg_width, s.stadistinct AS n_distinct, CASE WHEN (s.stakind1 = ANY (ARRAY[1, 4])) THEN s.stavalues1 WHEN (s.stakind2 = ANY (ARRAY[1, 4])) THEN s.stavalues2 WHEN (s.stakind3 = ANY (ARRAY[1, 4])) THEN s.stavalues3 WHEN (s.stakind4 = ANY (ARRAY[1, 4])) THEN s.stavalues4 ELSE NULL::anyarray END AS most_common_vals, CASE WHEN (s.stakind1 = ANY (ARRAY[1, 4])) THEN s.stanumbers1 WHEN (s.stakind2 = ANY (ARRAY[1, 4])) THEN s.stanumbers2 WHEN (s.stakind3 = ANY (ARRAY[1, 4])) THEN s.stanumbers3 WHEN (s.stakind4 = ANY (ARRAY[1, 4])) THEN s.stanumbers4 ELSE NULL::real[] END AS most_common_freqs, CASE WHEN (s.stakind1 = 2) THEN s.stavalues1 WHEN (s.stakind2 = 2) THEN s.stavalues2 WHEN (s.stakind3 = 2) THEN s.stavalues3 WHEN (s.stakind4 = 2) THEN s.stavalues4 ELSE NULL::anyarray END AS histogram_bounds, CASE WHEN (s.stakind1 = 3) THEN s.stanumbers1[1] WHEN (s.stakind2 = 3) THEN s.stanumbers2[1] WHEN (s.stakind3 = 3) THEN s.stanumbers3[1] WHEN (s.stakind4 = 3) THEN s.stanumbers4[1] ELSE NULL::real END AS correlation FROM (((pg_statistic s JOIN pg_class c ON ((c.oid = s.starelid))) JOIN pg_attribute a ON (((c.oid = a.attrelid) AND (a.attnum = s.staattnum)))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE has_table_privilege(c.oid, 'select'::text);
- pg_tables | SELECT n.nspname AS schemaname, c.relname AS tablename, pg_get_userbyid(c.relowner) AS tableowner, t.spcname AS tablespace, c.relhasindex AS hasindexes, c.relhasrules AS hasrules, (c.reltriggers > 0) AS hastriggers FROM ((pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) LEFT JOIN pg_tablespace t ON ((t.oid = c.reltablespace))) WHERE (c.relkind = 'r'::"char");
+ pg_tables | SELECT n.nspname AS schemaname, c.relname AS tablename, pg_get_userbyid(c.relowner) AS tableowner, t.spcname AS tablespace, c.relhasindex AS hasindexes, c.relhasrules AS hasrules, c.relhastriggers AS hastriggers FROM ((pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) LEFT JOIN pg_tablespace t ON ((t.oid = c.reltablespace))) WHERE (c.relkind = 'r'::"char");
pg_timezone_abbrevs | SELECT pg_timezone_abbrevs.abbrev, pg_timezone_abbrevs.utc_offset, pg_timezone_abbrevs.is_dst FROM pg_timezone_abbrevs() pg_timezone_abbrevs(abbrev, utc_offset, is_dst);
pg_timezone_names | SELECT pg_timezone_names.name, pg_timezone_names.abbrev, pg_timezone_names.utc_offset, pg_timezone_names.is_dst FROM pg_timezone_names() pg_timezone_names(name, abbrev, utc_offset, is_dst);
pg_user | SELECT pg_shadow.usename, pg_shadow.usesysid, pg_shadow.usecreatedb, pg_shadow.usesuper, pg_shadow.usecatupd, '********'::text AS passwd, pg_shadow.valuntil, pg_shadow.useconfig FROM pg_shadow;