Commit 188c7c8c authored by Tom Lane's avatar Tom Lane

Add ALTER TABLE ENABLE/DISABLE TRIGGER commands. Change pg_dump to

use these instead of its previous hack of changing pg_class.reltriggers.
Documentation is lacking, will add that later.
Patch by Satoshi Nagayasu, review and some extra work by Tom Lane.
parent d086da4b
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.168 2005/08/22 19:40:09 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.169 2005/08/23 22:40:07 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -246,6 +246,8 @@ static void ATExecDropCluster(Relation rel); ...@@ -246,6 +246,8 @@ static void ATExecDropCluster(Relation rel);
static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel,
char *tablespacename); char *tablespacename);
static void ATExecSetTableSpace(Oid tableOid, Oid newTableSpace); static void ATExecSetTableSpace(Oid tableOid, Oid newTableSpace);
static void ATExecEnableDisableTrigger(Relation rel, char *trigname,
bool enable, bool skip_system);
static void copy_relation_data(Relation rel, SMgrRelation dst); static void copy_relation_data(Relation rel, SMgrRelation dst);
static void update_ri_trigger_args(Oid relid, static void update_ri_trigger_args(Oid relid,
const char *oldname, const char *oldname,
...@@ -2005,6 +2007,17 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, ...@@ -2005,6 +2007,17 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
ATPrepSetTableSpace(tab, rel, cmd->name); ATPrepSetTableSpace(tab, rel, cmd->name);
pass = AT_PASS_MISC; /* doesn't actually matter */ pass = AT_PASS_MISC; /* doesn't actually matter */
break; break;
case AT_EnableTrig: /* ENABLE TRIGGER variants */
case AT_EnableTrigAll:
case AT_EnableTrigUser:
case AT_DisableTrig: /* DISABLE TRIGGER variants */
case AT_DisableTrigAll:
case AT_DisableTrigUser:
ATSimplePermissions(rel, false);
/* These commands never recurse */
/* No command-specific prep needed */
pass = AT_PASS_MISC;
break;
default: /* oops */ default: /* oops */
elog(ERROR, "unrecognized alter table type: %d", elog(ERROR, "unrecognized alter table type: %d",
(int) cmd->subtype); (int) cmd->subtype);
...@@ -2163,6 +2176,24 @@ ATExecCmd(AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd) ...@@ -2163,6 +2176,24 @@ ATExecCmd(AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd)
* Nothing to do here; Phase 3 does the work * Nothing to do here; Phase 3 does the work
*/ */
break; break;
case AT_EnableTrig: /* ENABLE TRIGGER name */
ATExecEnableDisableTrigger(rel, cmd->name, true, false);
break;
case AT_DisableTrig: /* DISABLE TRIGGER name */
ATExecEnableDisableTrigger(rel, cmd->name, false, false);
break;
case AT_EnableTrigAll: /* ENABLE TRIGGER ALL */
ATExecEnableDisableTrigger(rel, NULL, true, false);
break;
case AT_DisableTrigAll: /* DISABLE TRIGGER ALL */
ATExecEnableDisableTrigger(rel, NULL, false, false);
break;
case AT_EnableTrigUser: /* ENABLE TRIGGER USER */
ATExecEnableDisableTrigger(rel, NULL, true, true);
break;
case AT_DisableTrigUser: /* DISABLE TRIGGER USER */
ATExecEnableDisableTrigger(rel, NULL, false, true);
break;
default: /* oops */ default: /* oops */
elog(ERROR, "unrecognized alter table type: %d", elog(ERROR, "unrecognized alter table type: %d",
(int) cmd->subtype); (int) cmd->subtype);
...@@ -5778,6 +5809,18 @@ copy_relation_data(Relation rel, SMgrRelation dst) ...@@ -5778,6 +5809,18 @@ copy_relation_data(Relation rel, SMgrRelation dst)
smgrimmedsync(dst); smgrimmedsync(dst);
} }
/*
* ALTER TABLE ENABLE/DISABLE TRIGGER
*
* We just pass this off to trigger.c.
*/
static void
ATExecEnableDisableTrigger(Relation rel, char *trigname,
bool enable, bool skip_system)
{
EnableDisableTrigger(rel, trigname, enable, skip_system);
}
/* /*
* ALTER TABLE CREATE TOAST TABLE * ALTER TABLE CREATE TOAST TABLE
* *
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.192 2005/08/20 00:39:54 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.193 2005/08/23 22:40:08 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -712,6 +712,114 @@ renametrig(Oid relid, ...@@ -712,6 +712,114 @@ renametrig(Oid relid,
heap_close(targetrel, NoLock); heap_close(targetrel, NoLock);
} }
/*
* EnableDisableTrigger()
*
* Called by ALTER TABLE ENABLE/DISABLE TRIGGER
* to change 'tgenabled' flag for the specified trigger(s)
*
* rel: relation to process (caller must hold suitable lock on it)
* tgname: trigger to process, or NULL to scan all triggers
* enable: new value for tgenabled flag
* skip_system: if true, skip "system" triggers (constraint triggers)
*
* Caller should have checked permissions for the table; here we also
* enforce that superuser privilege is required to alter the state of
* system triggers
*/
void
EnableDisableTrigger(Relation rel, const char *tgname,
bool enable, bool skip_system)
{
Relation tgrel;
int nkeys;
ScanKeyData keys[2];
SysScanDesc tgscan;
HeapTuple tuple;
bool found;
bool changed;
/* Scan the relevant entries in pg_triggers */
tgrel = heap_open(TriggerRelationId, RowExclusiveLock);
ScanKeyInit(&keys[0],
Anum_pg_trigger_tgrelid,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(RelationGetRelid(rel)));
if (tgname)
{
ScanKeyInit(&keys[1],
Anum_pg_trigger_tgname,
BTEqualStrategyNumber, F_NAMEEQ,
CStringGetDatum(tgname));
nkeys = 2;
}
else
nkeys = 1;
tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
SnapshotNow, nkeys, keys);
found = changed = false;
while (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
{
Form_pg_trigger oldtrig = (Form_pg_trigger) GETSTRUCT(tuple);
if (oldtrig->tgisconstraint)
{
/* system trigger ... ok to process? */
if (skip_system)
continue;
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied: \"%s\" is a system trigger",
NameStr(oldtrig->tgname))));
}
found = true;
if (oldtrig->tgenabled != enable)
{
/* need to change this one ... make a copy to scribble on */
HeapTuple newtup = heap_copytuple(tuple);
Form_pg_trigger newtrig = (Form_pg_trigger) GETSTRUCT(newtup);
newtrig->tgenabled = enable;
simple_heap_update(tgrel, &newtup->t_self, newtup);
/* Keep catalog indexes current */
CatalogUpdateIndexes(tgrel, newtup);
heap_freetuple(newtup);
changed = true;
}
}
systable_endscan(tgscan);
heap_close(tgrel, RowExclusiveLock);
if (tgname && !found)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("trigger \"%s\" for table \"%s\" does not exist",
tgname, RelationGetRelationName(rel))));
/*
* If we changed anything, broadcast a SI inval message to force each
* backend (including our own!) to rebuild relation's relcache entry.
* Otherwise they will fail to apply the change promptly.
*/
if (changed)
CacheInvalidateRelcache(rel);
}
/* /*
* Build trigger data to attach to the given relcache entry. * Build trigger data to attach to the given relcache entry.
* *
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.507 2005/08/01 20:31:09 tgl Exp $ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.508 2005/08/23 22:40:20 tgl Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -350,9 +350,9 @@ static void doNegateFloat(Value *v); ...@@ -350,9 +350,9 @@ static void doNegateFloat(Value *v);
DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS
DESC DISTINCT DO DOMAIN_P DOUBLE_P DROP DESC DISABLE_P DISTINCT DO DOMAIN_P DOUBLE_P DROP
EACH ELSE ENCODING ENCRYPTED END_P ESCAPE EXCEPT EXCLUDING EACH ELSE ENABLE_P ENCODING ENCRYPTED END_P ESCAPE EXCEPT EXCLUDING
EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
FALSE_P FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD FALSE_P FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD
...@@ -1415,6 +1415,50 @@ alter_table_cmd: ...@@ -1415,6 +1415,50 @@ alter_table_cmd:
n->name = NULL; n->name = NULL;
$$ = (Node *)n; $$ = (Node *)n;
} }
/* ALTER TABLE <name> ENABLE TRIGGER <trig> */
| ENABLE_P TRIGGER name
{
AlterTableCmd *n = makeNode(AlterTableCmd);
n->subtype = AT_EnableTrig;
n->name = $3;
$$ = (Node *)n;
}
/* ALTER TABLE <name> ENABLE TRIGGER ALL */
| ENABLE_P TRIGGER ALL
{
AlterTableCmd *n = makeNode(AlterTableCmd);
n->subtype = AT_EnableTrigAll;
$$ = (Node *)n;
}
/* ALTER TABLE <name> ENABLE TRIGGER USER */
| ENABLE_P TRIGGER USER
{
AlterTableCmd *n = makeNode(AlterTableCmd);
n->subtype = AT_EnableTrigUser;
$$ = (Node *)n;
}
/* ALTER TABLE <name> DISABLE TRIGGER <trig> */
| DISABLE_P TRIGGER name
{
AlterTableCmd *n = makeNode(AlterTableCmd);
n->subtype = AT_DisableTrig;
n->name = $3;
$$ = (Node *)n;
}
/* ALTER TABLE <name> DISABLE TRIGGER ALL */
| DISABLE_P TRIGGER ALL
{
AlterTableCmd *n = makeNode(AlterTableCmd);
n->subtype = AT_DisableTrigAll;
$$ = (Node *)n;
}
/* ALTER TABLE <name> DISABLE TRIGGER USER */
| DISABLE_P TRIGGER USER
{
AlterTableCmd *n = makeNode(AlterTableCmd);
n->subtype = AT_DisableTrigUser;
$$ = (Node *)n;
}
| alter_rel_cmd | alter_rel_cmd
{ {
$$ = $1; $$ = $1;
...@@ -8067,10 +8111,12 @@ unreserved_keyword: ...@@ -8067,10 +8111,12 @@ unreserved_keyword:
| DELETE_P | DELETE_P
| DELIMITER | DELIMITER
| DELIMITERS | DELIMITERS
| DISABLE_P
| DOMAIN_P | DOMAIN_P
| DOUBLE_P | DOUBLE_P
| DROP | DROP
| EACH | EACH
| ENABLE_P
| ENCODING | ENCODING
| ENCRYPTED | ENCRYPTED
| ESCAPE | ESCAPE
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.164 2005/07/31 17:19:18 tgl Exp $ * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.165 2005/08/23 22:40:27 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -117,6 +117,7 @@ static const ScanKeyword ScanKeywords[] = { ...@@ -117,6 +117,7 @@ static const ScanKeyword ScanKeywords[] = {
{"delimiter", DELIMITER}, {"delimiter", DELIMITER},
{"delimiters", DELIMITERS}, {"delimiters", DELIMITERS},
{"desc", DESC}, {"desc", DESC},
{"disable", DISABLE_P},
{"distinct", DISTINCT}, {"distinct", DISTINCT},
{"do", DO}, {"do", DO},
{"domain", DOMAIN_P}, {"domain", DOMAIN_P},
...@@ -124,6 +125,7 @@ static const ScanKeyword ScanKeywords[] = { ...@@ -124,6 +125,7 @@ static const ScanKeyword ScanKeywords[] = {
{"drop", DROP}, {"drop", DROP},
{"each", EACH}, {"each", EACH},
{"else", ELSE}, {"else", ELSE},
{"enable", ENABLE_P},
{"encoding", ENCODING}, {"encoding", ENCODING},
{"encrypted", ENCRYPTED}, {"encrypted", ENCRYPTED},
{"end", END_P}, {"end", END_P},
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.113 2005/08/22 19:40:37 tgl Exp $ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.114 2005/08/23 22:40:31 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -413,32 +413,23 @@ _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *rop ...@@ -413,32 +413,23 @@ _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *rop
if (!ropt->dataOnly || !ropt->disable_triggers) if (!ropt->dataOnly || !ropt->disable_triggers)
return; return;
ahlog(AH, 1, "disabling triggers for %s\n", te->tag);
/* /*
* Become superuser if possible, since they are the only ones who can * Become superuser if possible, since they are the only ones who can
* update pg_class. If -S was not given, assume the initial user * disable constraint triggers. If -S was not given, assume the initial
* identity is a superuser. * user identity is a superuser. (XXX would it be better to become the
* table owner?)
*/ */
_becomeUser(AH, ropt->superuser); _becomeUser(AH, ropt->superuser);
ahlog(AH, 1, "disabling triggers\n");
/* /*
* Disable them. This is a hack. Needs to be done via an appropriate * Disable them.
* 'SET' command when one is available.
*/ */
ahprintf(AH, "-- Disable triggers\n"); _selectOutputSchema(AH, te->namespace);
/* ahprintf(AH, "ALTER TABLE %s DISABLE TRIGGER ALL;\n\n",
* Just update the AFFECTED table, if known. Otherwise update all fmtId(te->tag));
* non-system tables.
*/
if (te && te->tag && strlen(te->tag) > 0)
ahprintf(AH, "UPDATE pg_catalog.pg_class SET reltriggers = 0 "
"WHERE oid = '%s'::pg_catalog.regclass;\n\n",
fmtId(te->tag));
else
ahprintf(AH, "UPDATE pg_catalog.pg_class SET reltriggers = 0 FROM pg_catalog.pg_namespace "
"WHERE relnamespace = pg_namespace.oid AND nspname !~ '^pg_';\n\n");
} }
static void static void
...@@ -448,35 +439,23 @@ _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt ...@@ -448,35 +439,23 @@ _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt
if (!ropt->dataOnly || !ropt->disable_triggers) if (!ropt->dataOnly || !ropt->disable_triggers)
return; return;
ahlog(AH, 1, "enabling triggers for %s\n", te->tag);
/* /*
* Become superuser if possible, since they are the only ones who can * Become superuser if possible, since they are the only ones who can
* update pg_class. If -S was not given, assume the initial user * disable constraint triggers. If -S was not given, assume the initial
* identity is a superuser. * user identity is a superuser. (XXX would it be better to become the
* table owner?)
*/ */
_becomeUser(AH, ropt->superuser); _becomeUser(AH, ropt->superuser);
ahlog(AH, 1, "enabling triggers\n");
/* /*
* Enable them. This is a hack. Needs to be done via an appropriate * Enable them.
* 'SET' command when one is available.
*/ */
ahprintf(AH, "-- Enable triggers\n"); _selectOutputSchema(AH, te->namespace);
/* ahprintf(AH, "ALTER TABLE %s ENABLE TRIGGER ALL;\n\n",
* Just update the AFFECTED table, if known. Otherwise update all fmtId(te->tag));
* non-system tables.
*/
if (te && te->tag && strlen(te->tag) > 0)
ahprintf(AH, "UPDATE pg_catalog.pg_class SET reltriggers = "
"(SELECT pg_catalog.count(*) FROM pg_catalog.pg_trigger where pg_class.oid = tgrelid) "
"WHERE oid = '%s'::pg_catalog.regclass;\n\n",
fmtId(te->tag));
else
ahprintf(AH, "UPDATE pg_catalog.pg_class SET reltriggers = "
"(SELECT pg_catalog.count(*) FROM pg_catalog.pg_trigger where pg_class.oid = tgrelid) "
"FROM pg_catalog.pg_namespace "
"WHERE relnamespace = pg_namespace.oid AND nspname !~ '^pg_';\n\n");
} }
/* /*
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* by PostgreSQL * by PostgreSQL
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.418 2005/08/15 21:50:15 tgl Exp $ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.419 2005/08/23 22:40:31 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -3350,6 +3350,7 @@ getTriggers(TableInfo tblinfo[], int numTables) ...@@ -3350,6 +3350,7 @@ getTriggers(TableInfo tblinfo[], int numTables)
i_tgconstrname, i_tgconstrname,
i_tgconstrrelid, i_tgconstrrelid,
i_tgconstrrelname, i_tgconstrrelname,
i_tgenabled,
i_tgdeferrable, i_tgdeferrable,
i_tginitdeferred; i_tginitdeferred;
int ntups; int ntups;
...@@ -3381,7 +3382,7 @@ getTriggers(TableInfo tblinfo[], int numTables) ...@@ -3381,7 +3382,7 @@ getTriggers(TableInfo tblinfo[], int numTables)
appendPQExpBuffer(query, appendPQExpBuffer(query,
"SELECT tgname, " "SELECT tgname, "
"tgfoid::pg_catalog.regproc as tgfname, " "tgfoid::pg_catalog.regproc as tgfname, "
"tgtype, tgnargs, tgargs, " "tgtype, tgnargs, tgargs, tgenabled, "
"tgisconstraint, tgconstrname, tgdeferrable, " "tgisconstraint, tgconstrname, tgdeferrable, "
"tgconstrrelid, tginitdeferred, tableoid, oid, " "tgconstrrelid, tginitdeferred, tableoid, oid, "
"tgconstrrelid::pg_catalog.regclass as tgconstrrelname " "tgconstrrelid::pg_catalog.regclass as tgconstrrelname "
...@@ -3398,7 +3399,7 @@ getTriggers(TableInfo tblinfo[], int numTables) ...@@ -3398,7 +3399,7 @@ getTriggers(TableInfo tblinfo[], int numTables)
{ {
appendPQExpBuffer(query, appendPQExpBuffer(query,
"SELECT tgname, tgfoid::regproc as tgfname, " "SELECT tgname, tgfoid::regproc as tgfname, "
"tgtype, tgnargs, tgargs, " "tgtype, tgnargs, tgargs, tgenabled, "
"tgisconstraint, tgconstrname, tgdeferrable, " "tgisconstraint, tgconstrname, tgdeferrable, "
"tgconstrrelid, tginitdeferred, tableoid, oid, " "tgconstrrelid, tginitdeferred, tableoid, oid, "
"(select relname from pg_class where oid = tgconstrrelid) " "(select relname from pg_class where oid = tgconstrrelid) "
...@@ -3411,7 +3412,7 @@ getTriggers(TableInfo tblinfo[], int numTables) ...@@ -3411,7 +3412,7 @@ getTriggers(TableInfo tblinfo[], int numTables)
{ {
appendPQExpBuffer(query, appendPQExpBuffer(query,
"SELECT tgname, tgfoid::regproc as tgfname, " "SELECT tgname, tgfoid::regproc as tgfname, "
"tgtype, tgnargs, tgargs, " "tgtype, tgnargs, tgargs, tgenabled, "
"tgisconstraint, tgconstrname, tgdeferrable, " "tgisconstraint, tgconstrname, tgdeferrable, "
"tgconstrrelid, tginitdeferred, " "tgconstrrelid, tginitdeferred, "
"(SELECT oid FROM pg_class WHERE relname = 'pg_trigger') AS tableoid, " "(SELECT oid FROM pg_class WHERE relname = 'pg_trigger') AS tableoid, "
...@@ -3449,6 +3450,7 @@ getTriggers(TableInfo tblinfo[], int numTables) ...@@ -3449,6 +3450,7 @@ getTriggers(TableInfo tblinfo[], int numTables)
i_tgconstrname = PQfnumber(res, "tgconstrname"); i_tgconstrname = PQfnumber(res, "tgconstrname");
i_tgconstrrelid = PQfnumber(res, "tgconstrrelid"); i_tgconstrrelid = PQfnumber(res, "tgconstrrelid");
i_tgconstrrelname = PQfnumber(res, "tgconstrrelname"); i_tgconstrrelname = PQfnumber(res, "tgconstrrelname");
i_tgenabled = PQfnumber(res, "tgenabled");
i_tgdeferrable = PQfnumber(res, "tgdeferrable"); i_tgdeferrable = PQfnumber(res, "tgdeferrable");
i_tginitdeferred = PQfnumber(res, "tginitdeferred"); i_tginitdeferred = PQfnumber(res, "tginitdeferred");
...@@ -3468,6 +3470,7 @@ getTriggers(TableInfo tblinfo[], int numTables) ...@@ -3468,6 +3470,7 @@ getTriggers(TableInfo tblinfo[], int numTables)
tginfo[j].tgnargs = atoi(PQgetvalue(res, j, i_tgnargs)); tginfo[j].tgnargs = atoi(PQgetvalue(res, j, i_tgnargs));
tginfo[j].tgargs = strdup(PQgetvalue(res, j, i_tgargs)); tginfo[j].tgargs = strdup(PQgetvalue(res, j, i_tgargs));
tginfo[j].tgisconstraint = *(PQgetvalue(res, j, i_tgisconstraint)) == 't'; tginfo[j].tgisconstraint = *(PQgetvalue(res, j, i_tgisconstraint)) == 't';
tginfo[j].tgenabled = *(PQgetvalue(res, j, i_tgenabled)) == 't';
tginfo[j].tgdeferrable = *(PQgetvalue(res, j, i_tgdeferrable)) == 't'; tginfo[j].tgdeferrable = *(PQgetvalue(res, j, i_tgdeferrable)) == 't';
tginfo[j].tginitdeferred = *(PQgetvalue(res, j, i_tginitdeferred)) == 't'; tginfo[j].tginitdeferred = *(PQgetvalue(res, j, i_tginitdeferred)) == 't';
...@@ -7874,6 +7877,14 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo) ...@@ -7874,6 +7877,14 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
} }
appendPQExpBuffer(query, ");\n"); appendPQExpBuffer(query, ");\n");
if (!tginfo->tgenabled)
{
appendPQExpBuffer(query, "\nALTER TABLE %s ",
fmtId(tbinfo->dobj.name));
appendPQExpBuffer(query, "DISABLE TRIGGER %s;\n",
fmtId(tginfo->dobj.name));
}
ArchiveEntry(fout, tginfo->dobj.catId, tginfo->dobj.dumpId, ArchiveEntry(fout, tginfo->dobj.catId, tginfo->dobj.dumpId,
tginfo->dobj.name, tginfo->dobj.name,
tbinfo->dobj.namespace->dobj.name, tbinfo->dobj.namespace->dobj.name,
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.119 2005/08/15 21:50:15 tgl Exp $ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.120 2005/08/23 22:40:35 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -270,6 +270,7 @@ typedef struct _triggerInfo ...@@ -270,6 +270,7 @@ typedef struct _triggerInfo
char *tgconstrname; char *tgconstrname;
Oid tgconstrrelid; Oid tgconstrrelid;
char *tgconstrrelname; char *tgconstrrelname;
bool tgenabled;
bool tgdeferrable; bool tgdeferrable;
bool tginitdeferred; bool tginitdeferred;
} TriggerInfo; } TriggerInfo;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/commands/trigger.h,v 1.54 2005/05/30 07:20:58 neilc Exp $ * $PostgreSQL: pgsql/src/include/commands/trigger.h,v 1.55 2005/08/23 22:40:40 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -113,6 +113,9 @@ extern void RemoveTriggerById(Oid trigOid); ...@@ -113,6 +113,9 @@ extern void RemoveTriggerById(Oid trigOid);
extern void renametrig(Oid relid, const char *oldname, const char *newname); extern void renametrig(Oid relid, const char *oldname, const char *newname);
extern void EnableDisableTrigger(Relation rel, const char *tgname,
bool enable, bool skip_system);
extern void RelationBuildTriggers(Relation relation); extern void RelationBuildTriggers(Relation relation);
extern TriggerDesc *CopyTriggerDesc(TriggerDesc *trigdesc); extern TriggerDesc *CopyTriggerDesc(TriggerDesc *trigdesc);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.289 2005/08/01 20:31:15 tgl Exp $ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.290 2005/08/23 22:40:47 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -837,15 +837,21 @@ typedef enum AlterTableType ...@@ -837,15 +837,21 @@ typedef enum AlterTableType
AT_ClusterOn, /* CLUSTER ON */ AT_ClusterOn, /* CLUSTER ON */
AT_DropCluster, /* SET WITHOUT CLUSTER */ AT_DropCluster, /* SET WITHOUT CLUSTER */
AT_DropOids, /* SET WITHOUT OIDS */ AT_DropOids, /* SET WITHOUT OIDS */
AT_SetTableSpace /* SET TABLESPACE */ AT_SetTableSpace, /* SET TABLESPACE */
AT_EnableTrig, /* ENABLE TRIGGER name */
AT_DisableTrig, /* DISABLE TRIGGER name */
AT_EnableTrigAll, /* ENABLE TRIGGER ALL */
AT_DisableTrigAll, /* DISABLE TRIGGER ALL */
AT_EnableTrigUser, /* ENABLE TRIGGER USER */
AT_DisableTrigUser /* DISABLE TRIGGER USER */
} AlterTableType; } AlterTableType;
typedef struct AlterTableCmd /* one subcommand of an ALTER TABLE */ typedef struct AlterTableCmd /* one subcommand of an ALTER TABLE */
{ {
NodeTag type; NodeTag type;
AlterTableType subtype; /* Type of table alteration to apply */ AlterTableType subtype; /* Type of table alteration to apply */
char *name; /* column or constraint name to act on, or char *name; /* column, constraint, or trigger to act on,
* new owner or tablespace */ * or new owner or tablespace */
Node *def; /* definition of new column, column type, Node *def; /* definition of new column, column type,
* index, or constraint */ * index, or constraint */
Node *transform; /* transformation expr for ALTER TYPE */ Node *transform; /* transformation expr for ALTER TYPE */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment