Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite4718f2

Browse files
committed
Replace pg_class.reltriggers with relhastriggers, which is just a boolean hint
("there might be triggers") rather than an exact count. This is necessarycatalog infrastructure for the upcoming patch to reduce the strength oflocking needed for trigger addition/removal. Split out and committedseparately for ease of reviewing/testing.In passing, also get rid of the unused pg_class columns relukeys, relfkeys,and relrefs, which haven't been maintained in many years and now have nochance of ever being maintained (because of wishing to avoid locking).Simon Riggs
1 parent1d577f5 commite4718f2

File tree

13 files changed

+162
-197
lines changed

13 files changed

+162
-197
lines changed

‎doc/src/sgml/catalogs.sgml

Lines changed: 15 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.180 2008/10/31 08:39:19 heikki Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.181 2008/11/09 21:24:32 tgl Exp $ -->
22
<!--
33
Documentation of the system catalogs, directed toward PostgreSQL developers
44
-->
@@ -1711,37 +1711,6 @@
17111711
</entry>
17121712
</row>
17131713

1714-
<row>
1715-
<entry><structfield>reltriggers</structfield></entry>
1716-
<entry><type>int2</type></entry>
1717-
<entry></entry>
1718-
<entry>
1719-
Number of triggers on the table; see
1720-
<link linkend="catalog-pg-trigger"><structname>pg_trigger</structname></link> catalog
1721-
</entry>
1722-
</row>
1723-
1724-
<row>
1725-
<entry><structfield>relukeys</structfield></entry>
1726-
<entry><type>int2</type></entry>
1727-
<entry></entry>
1728-
<entry>Unused (<emphasis>not</emphasis> the number of unique keys)</entry>
1729-
</row>
1730-
1731-
<row>
1732-
<entry><structfield>relfkeys</structfield></entry>
1733-
<entry><type>int2</type></entry>
1734-
<entry></entry>
1735-
<entry>Unused (<emphasis>not</emphasis> the number of foreign keys on the table)</entry>
1736-
</row>
1737-
1738-
<row>
1739-
<entry><structfield>relrefs</structfield></entry>
1740-
<entry><type>int2</type></entry>
1741-
<entry></entry>
1742-
<entry>Unused</entry>
1743-
</row>
1744-
17451714
<row>
17461715
<entry><structfield>relhasoids</structfield></entry>
17471716
<entry><type>bool</type></entry>
@@ -1765,11 +1734,21 @@
17651734
<entry><type>bool</type></entry>
17661735
<entry></entry>
17671736
<entry>
1768-
True if table has rules; see
1737+
True if table has(or once had)rules; see
17691738
<link linkend="catalog-pg-rewrite"><structname>pg_rewrite</structname></link> catalog
17701739
</entry>
17711740
</row>
17721741

1742+
<row>
1743+
<entry><structfield>relhastriggers</structfield></entry>
1744+
<entry><type>bool</type></entry>
1745+
<entry></entry>
1746+
<entry>
1747+
True if table has (or once had) triggers; see
1748+
<link linkend="catalog-pg-trigger"><structname>pg_trigger</structname></link> catalog
1749+
</entry>
1750+
</row>
1751+
17731752
<row>
17741753
<entry><structfield>relhassubclass</structfield></entry>
17751754
<entry><type>bool</type></entry>
@@ -4499,13 +4478,6 @@
44994478
</para>
45004479
</note>
45014480

4502-
<note>
4503-
<para>
4504-
<literal>pg_class.reltriggers</literal> needs to agree with the
4505-
number of triggers found in this table for each relation.
4506-
</para>
4507-
</note>
4508-
45094481
</sect1>
45104482

45114483

@@ -6818,13 +6790,13 @@
68186790
<entry><structfield>hasrules</structfield></entry>
68196791
<entry><type>boolean</type></entry>
68206792
<entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.relhasrules</literal></entry>
6821-
<entry>true if table has rules</entry>
6793+
<entry>true if table has(or once had)rules</entry>
68226794
</row>
68236795
<row>
68246796
<entry><structfield>hastriggers</structfield></entry>
68256797
<entry><type>boolean</type></entry>
6826-
<entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.reltriggers</literal></entry>
6827-
<entry>true if table has triggers</entry>
6798+
<entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.relhastriggers</literal></entry>
6799+
<entry>true if table has(or once had)triggers</entry>
68286800
</row>
68296801
</tbody>
68306802
</tgroup>

‎src/backend/catalog/heap.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.342 2008/11/02 01:45:27 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.343 2008/11/09 21:24:32 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -641,13 +641,10 @@ InsertPgClassTuple(Relation pg_class_desc,
641641
values[Anum_pg_class_relkind-1]=CharGetDatum(rd_rel->relkind);
642642
values[Anum_pg_class_relnatts-1]=Int16GetDatum(rd_rel->relnatts);
643643
values[Anum_pg_class_relchecks-1]=Int16GetDatum(rd_rel->relchecks);
644-
values[Anum_pg_class_reltriggers-1]=Int16GetDatum(rd_rel->reltriggers);
645-
values[Anum_pg_class_relukeys-1]=Int16GetDatum(rd_rel->relukeys);
646-
values[Anum_pg_class_relfkeys-1]=Int16GetDatum(rd_rel->relfkeys);
647-
values[Anum_pg_class_relrefs-1]=Int16GetDatum(rd_rel->relrefs);
648644
values[Anum_pg_class_relhasoids-1]=BoolGetDatum(rd_rel->relhasoids);
649645
values[Anum_pg_class_relhaspkey-1]=BoolGetDatum(rd_rel->relhaspkey);
650646
values[Anum_pg_class_relhasrules-1]=BoolGetDatum(rd_rel->relhasrules);
647+
values[Anum_pg_class_relhastriggers-1]=BoolGetDatum(rd_rel->relhastriggers);
651648
values[Anum_pg_class_relhassubclass-1]=BoolGetDatum(rd_rel->relhassubclass);
652649
values[Anum_pg_class_relfrozenxid-1]=TransactionIdGetDatum(rd_rel->relfrozenxid);
653650
/* start out with empty permissions */
@@ -2366,7 +2363,7 @@ heap_truncate_check_FKs(List *relations, bool tempTables)
23662363
{
23672364
Relationrel=lfirst(cell);
23682365

2369-
if (rel->rd_rel->reltriggers!=0)
2366+
if (rel->rd_rel->relhastriggers)
23702367
oids=lappend_oid(oids,RelationGetRelid(rel));
23712368
}
23722369

‎src/backend/catalog/system_views.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* Copyright (c) 1996-2008, PostgreSQL Global Development Group
55
*
6-
* $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.55 2008/09/21 19:38:56 tgl Exp $
6+
* $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.56 2008/11/09 21:24:32 tgl Exp $
77
*/
88

99
CREATEVIEWpg_rolesAS
@@ -84,7 +84,7 @@ CREATE VIEW pg_tables AS
8484
T.spcnameAS tablespace,
8585
C.relhasindexAS hasindexes,
8686
C.relhasrulesAS hasrules,
87-
(C.reltriggers>0)AS hastriggers
87+
C.relhastriggersAS hastriggers
8888
FROM pg_class CLEFT JOIN pg_namespace NON (N.oid=C.relnamespace)
8989
LEFT JOIN pg_tablespace TON (T.oid=C.reltablespace)
9090
WHEREC.relkind='r';

‎src/backend/commands/trigger.c

Lines changed: 39 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.239 2008/11/02 01:45:28 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.240 2008/11/09 21:24:32 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -95,7 +95,6 @@ CreateTrigger(CreateTrigStmt *stmt, Oid constraintOid)
9595
Oidfuncoid;
9696
Oidfuncrettype;
9797
Oidtrigoid;
98-
intfound=0;
9998
inti;
10099
charconstrtrigname[NAMEDATALEN];
101100
char*trigname;
@@ -280,10 +279,9 @@ CreateTrigger(CreateTrigStmt *stmt, Oid constraintOid)
280279
}
281280

282281
/*
283-
* Scan pg_trigger for existing triggers on relation. We do this mainly
284-
* because we must count them; a secondary benefit is to give a nice error
285-
* message if there's already a trigger of the same name. (The unique
286-
* index on tgrelid/tgname would complain anyway.)
282+
* Scan pg_trigger for existing triggers on relation. We do this only
283+
* to give a nice error message if there's already a trigger of the same
284+
* name. (The unique index on tgrelid/tgname would complain anyway.)
287285
*
288286
* NOTE that this is cool only because we have AccessExclusiveLock on the
289287
* relation, so the trigger set won't be changing underneath us.
@@ -303,7 +301,6 @@ CreateTrigger(CreateTrigStmt *stmt, Oid constraintOid)
303301
(errcode(ERRCODE_DUPLICATE_OBJECT),
304302
errmsg("trigger \"%s\" for relation \"%s\" already exists",
305303
trigname,stmt->relation->relname)));
306-
found++;
307304
}
308305
systable_endscan(tgscan);
309306

@@ -405,7 +402,7 @@ CreateTrigger(CreateTrigStmt *stmt, Oid constraintOid)
405402
elog(ERROR,"cache lookup failed for relation %u",
406403
RelationGetRelid(rel));
407404

408-
((Form_pg_class)GETSTRUCT(tuple))->reltriggers=found+1;
405+
((Form_pg_class)GETSTRUCT(tuple))->relhastriggers=true;
409406

410407
simple_heap_update(pgrel,&tuple->t_self,tuple);
411408

@@ -818,9 +815,6 @@ RemoveTriggerById(Oid trigOid)
818815
HeapTupletup;
819816
Oidrelid;
820817
Relationrel;
821-
Relationpgrel;
822-
HeapTupletuple;
823-
Form_pg_classclassForm;
824818

825819
tgrel=heap_open(TriggerRelationId,RowExclusiveLock);
826820

@@ -867,33 +861,15 @@ RemoveTriggerById(Oid trigOid)
867861
heap_close(tgrel,RowExclusiveLock);
868862

869863
/*
870-
* Update relation's pg_class entry. Crucial side-effect: other backends
871-
* (and this one too!) are sent SI message to make them rebuild relcache
872-
* entries.
873-
*
874-
* Note this is OK only because we have AccessExclusiveLock on the rel, so
875-
* no one else is creating/deleting triggers on this rel at the same time.
864+
* We do not bother to try to determine whether any other triggers remain,
865+
* which would be needed in order to decide whether it's safe to clear
866+
* the relation's relhastriggers. (In any case, there might be a
867+
* concurrent process adding new triggers.) Instead, just force a
868+
* relcache inval to make other backends (and this one too!) rebuild
869+
* their relcache entries. There's no great harm in leaving relhastriggers
870+
* true even if there are no triggers left.
876871
*/
877-
pgrel=heap_open(RelationRelationId,RowExclusiveLock);
878-
tuple=SearchSysCacheCopy(RELOID,
879-
ObjectIdGetDatum(relid),
880-
0,0,0);
881-
if (!HeapTupleIsValid(tuple))
882-
elog(ERROR,"cache lookup failed for relation %u",relid);
883-
classForm= (Form_pg_class)GETSTRUCT(tuple);
884-
885-
if (classForm->reltriggers==0)/* should not happen */
886-
elog(ERROR,"relation \"%s\" has reltriggers = 0",
887-
RelationGetRelationName(rel));
888-
classForm->reltriggers--;
889-
890-
simple_heap_update(pgrel,&tuple->t_self,tuple);
891-
892-
CatalogUpdateIndexes(pgrel,tuple);
893-
894-
heap_freetuple(tuple);
895-
896-
heap_close(pgrel,RowExclusiveLock);
872+
CacheInvalidateRelcache(rel);
897873

898874
/* Keep lock on trigger's rel until end of xact */
899875
heap_close(rel,NoLock);
@@ -1134,18 +1110,23 @@ void
11341110
RelationBuildTriggers(Relationrelation)
11351111
{
11361112
TriggerDesc*trigdesc;
1137-
intntrigs=relation->rd_rel->reltriggers;
1113+
intnumtrigs;
1114+
intmaxtrigs;
11381115
Trigger*triggers;
1139-
intfound=0;
11401116
Relationtgrel;
11411117
ScanKeyDataskey;
11421118
SysScanDesctgscan;
11431119
HeapTuplehtup;
11441120
MemoryContextoldContext;
1121+
inti;
11451122

1146-
Assert(ntrigs>0);/* else I should not have been called */
1147-
1148-
triggers= (Trigger*)palloc(ntrigs*sizeof(Trigger));
1123+
/*
1124+
* Allocate a working array to hold the triggers (the array is extended
1125+
* if necessary)
1126+
*/
1127+
maxtrigs=16;
1128+
triggers= (Trigger*)palloc(maxtrigs*sizeof(Trigger));
1129+
numtrigs=0;
11491130

11501131
/*
11511132
* Note: since we scan the triggers using TriggerRelidNameIndexId, we will
@@ -1167,10 +1148,12 @@ RelationBuildTriggers(Relation relation)
11671148
Form_pg_triggerpg_trigger= (Form_pg_trigger)GETSTRUCT(htup);
11681149
Trigger*build;
11691150

1170-
if (found >=ntrigs)
1171-
elog(ERROR,"too many trigger records found for relation \"%s\"",
1172-
RelationGetRelationName(relation));
1173-
build=&(triggers[found]);
1151+
if (numtrigs >=maxtrigs)
1152+
{
1153+
maxtrigs *=2;
1154+
triggers= (Trigger*)repalloc(triggers,maxtrigs*sizeof(Trigger));
1155+
}
1156+
build=&(triggers[numtrigs]);
11741157

11751158
build->tgoid=HeapTupleGetOid(htup);
11761159
build->tgname=DatumGetCString(DirectFunctionCall1(nameout,
@@ -1199,7 +1182,6 @@ RelationBuildTriggers(Relation relation)
11991182
bytea*val;
12001183
boolisnull;
12011184
char*p;
1202-
inti;
12031185

12041186
val=DatumGetByteaP(fastgetattr(htup,
12051187
Anum_pg_trigger_tgargs,
@@ -1218,23 +1200,25 @@ RelationBuildTriggers(Relation relation)
12181200
else
12191201
build->tgargs=NULL;
12201202

1221-
found++;
1203+
numtrigs++;
12221204
}
12231205

12241206
systable_endscan(tgscan);
12251207
heap_close(tgrel,AccessShareLock);
12261208

1227-
if (found!=ntrigs)
1228-
elog(ERROR,"%d trigger record(s) not found for relation \"%s\"",
1229-
ntrigs-found,
1230-
RelationGetRelationName(relation));
1209+
/* There might not be any triggers */
1210+
if (numtrigs==0)
1211+
{
1212+
pfree(triggers);
1213+
return;
1214+
}
12311215

12321216
/* Build trigdesc */
12331217
trigdesc= (TriggerDesc*)palloc0(sizeof(TriggerDesc));
12341218
trigdesc->triggers=triggers;
1235-
trigdesc->numtriggers=ntrigs;
1236-
for (found=0;found<ntrigs;found++)
1237-
InsertTrigger(trigdesc,&(triggers[found]),found);
1219+
trigdesc->numtriggers=numtrigs;
1220+
for (i=0;i<numtrigs;i++)
1221+
InsertTrigger(trigdesc,&(triggers[i]),i);
12381222

12391223
/* Copy completed trigdesc into cache storage */
12401224
oldContext=MemoryContextSwitchTo(CacheMemoryContext);

‎src/backend/rewrite/rewriteDefine.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteDefine.c,v 1.131 2008/11/02 01:45:28 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteDefine.c,v 1.132 2008/11/09 21:24:32 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -371,7 +371,11 @@ DefineQueryRewrite(char *rulename,
371371
*
372372
* If so, check that the relation is empty because the storage for the
373373
* relation is going to be deleted. Also insist that the rel not have
374-
* any triggers, indexes, or child tables.
374+
* any triggers, indexes, or child tables. (Note: these tests are
375+
* too strict, because they will reject relations that once had such
376+
* but don't anymore. But we don't really care, because this whole
377+
* business of converting relations to views is just a kluge to allow
378+
* loading ancient pg_dump files.)
375379
*/
376380
if (event_relation->rd_rel->relkind!=RELKIND_VIEW)
377381
{
@@ -385,7 +389,7 @@ DefineQueryRewrite(char *rulename,
385389
RelationGetRelationName(event_relation))));
386390
heap_endscan(scanDesc);
387391

388-
if (event_relation->rd_rel->reltriggers!=0)
392+
if (event_relation->rd_rel->relhastriggers)
389393
ereport(ERROR,
390394
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
391395
errmsg("could not convert table \"%s\" to a view because it has triggers",

‎src/backend/utils/cache/relcache.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.274 2008/09/30 10:52:13 heikki Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.275 2008/11/09 21:24:32 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -856,7 +856,7 @@ RelationBuildDesc(Oid targetRelId, Relation oldrelation)
856856
relation->rd_rulescxt=NULL;
857857
}
858858

859-
if (relation->rd_rel->reltriggers>0)
859+
if (relation->rd_rel->relhastriggers)
860860
RelationBuildTriggers(relation);
861861
else
862862
relation->trigdesc=NULL;
@@ -2641,7 +2641,7 @@ RelationCacheInitializePhase2(void)
26412641
*/
26422642
if (relation->rd_rel->relhasrules&&relation->rd_rules==NULL)
26432643
RelationBuildRuleLock(relation);
2644-
if (relation->rd_rel->reltriggers>0&&relation->trigdesc==NULL)
2644+
if (relation->rd_rel->relhastriggers&&relation->trigdesc==NULL)
26452645
RelationBuildTriggers(relation);
26462646
}
26472647

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp