diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index f2dd4a5a47d0ffe6bccacc50f63350c3542e398e..91f5eaecd9506ecb09de9e6c9a39df0c2797c284 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -8,7 +8,7 @@ * * * 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); static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, char *tablespacename); 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 update_ri_trigger_args(Oid relid, const char *oldname, @@ -2005,6 +2007,17 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, ATPrepSetTableSpace(tab, rel, cmd->name); pass = AT_PASS_MISC; /* doesn't actually matter */ 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 */ elog(ERROR, "unrecognized alter table type: %d", (int) cmd->subtype); @@ -2163,6 +2176,24 @@ ATExecCmd(AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd) * Nothing to do here; Phase 3 does the work */ 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 */ elog(ERROR, "unrecognized alter table type: %d", (int) cmd->subtype); @@ -5778,6 +5809,18 @@ copy_relation_data(Relation rel, SMgrRelation 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 * diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 562f676f4b8b4f91919f794681544cf5a0a68bd1..b1d2f4ce0dbe66a7222a1f4184f1d1c64364eab2 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.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, 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. * diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 768fb4ada7511d4cad7755d0ffcddd3b2c9013d0..0799200bb5d2daf9a6ee55045374ccfa4a9a42e9 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * 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 * AUTHOR DATE MAJOR EVENT @@ -350,9 +350,9 @@ static void doNegateFloat(Value *v); DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS 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 FALSE_P FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD @@ -1415,6 +1415,50 @@ alter_table_cmd: n->name = NULL; $$ = (Node *)n; } + /* ALTER TABLE ENABLE TRIGGER */ + | ENABLE_P TRIGGER name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_EnableTrig; + n->name = $3; + $$ = (Node *)n; + } + /* ALTER TABLE ENABLE TRIGGER ALL */ + | ENABLE_P TRIGGER ALL + { + AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_EnableTrigAll; + $$ = (Node *)n; + } + /* ALTER TABLE ENABLE TRIGGER USER */ + | ENABLE_P TRIGGER USER + { + AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_EnableTrigUser; + $$ = (Node *)n; + } + /* ALTER TABLE DISABLE TRIGGER */ + | DISABLE_P TRIGGER name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DisableTrig; + n->name = $3; + $$ = (Node *)n; + } + /* ALTER TABLE DISABLE TRIGGER ALL */ + | DISABLE_P TRIGGER ALL + { + AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DisableTrigAll; + $$ = (Node *)n; + } + /* ALTER TABLE DISABLE TRIGGER USER */ + | DISABLE_P TRIGGER USER + { + AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DisableTrigUser; + $$ = (Node *)n; + } | alter_rel_cmd { $$ = $1; @@ -8067,10 +8111,12 @@ unreserved_keyword: | DELETE_P | DELIMITER | DELIMITERS + | DISABLE_P | DOMAIN_P | DOUBLE_P | DROP | EACH + | ENABLE_P | ENCODING | ENCRYPTED | ESCAPE diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c index 9c09dc5bf3b90510a3875c522eb5ca504dd22f9d..6733d1b12407462d33389359d5ff11325b2bbc8a 100644 --- a/src/backend/parser/keywords.c +++ b/src/backend/parser/keywords.c @@ -8,7 +8,7 @@ * * * 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[] = { {"delimiter", DELIMITER}, {"delimiters", DELIMITERS}, {"desc", DESC}, + {"disable", DISABLE_P}, {"distinct", DISTINCT}, {"do", DO}, {"domain", DOMAIN_P}, @@ -124,6 +125,7 @@ static const ScanKeyword ScanKeywords[] = { {"drop", DROP}, {"each", EACH}, {"else", ELSE}, + {"enable", ENABLE_P}, {"encoding", ENCODING}, {"encrypted", ENCRYPTED}, {"end", END_P}, diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index a8fb1d70f77801167dc4c22e4cbde7c52a7c26ef..e956bac46515ef0c8e1ee6955e4421468f1ea65e 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -15,7 +15,7 @@ * * * 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 if (!ropt->dataOnly || !ropt->disable_triggers) return; + ahlog(AH, 1, "disabling triggers for %s\n", te->tag); + /* * Become superuser if possible, since they are the only ones who can - * update pg_class. If -S was not given, assume the initial user - * identity is a superuser. + * disable constraint triggers. If -S was not given, assume the initial + * user identity is a superuser. (XXX would it be better to become the + * table owner?) */ _becomeUser(AH, ropt->superuser); - ahlog(AH, 1, "disabling triggers\n"); - /* - * Disable them. This is a hack. Needs to be done via an appropriate - * 'SET' command when one is available. + * Disable them. */ - ahprintf(AH, "-- Disable triggers\n"); + _selectOutputSchema(AH, te->namespace); - /* - * Just update the AFFECTED table, if known. Otherwise update all - * 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"); + ahprintf(AH, "ALTER TABLE %s DISABLE TRIGGER ALL;\n\n", + fmtId(te->tag)); } static void @@ -448,35 +439,23 @@ _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt if (!ropt->dataOnly || !ropt->disable_triggers) return; + ahlog(AH, 1, "enabling triggers for %s\n", te->tag); + /* * Become superuser if possible, since they are the only ones who can - * update pg_class. If -S was not given, assume the initial user - * identity is a superuser. + * disable constraint triggers. If -S was not given, assume the initial + * user identity is a superuser. (XXX would it be better to become the + * table owner?) */ _becomeUser(AH, ropt->superuser); - ahlog(AH, 1, "enabling triggers\n"); - /* - * Enable them. This is a hack. Needs to be done via an appropriate - * 'SET' command when one is available. + * Enable them. */ - ahprintf(AH, "-- Enable triggers\n"); + _selectOutputSchema(AH, te->namespace); - /* - * Just update the AFFECTED table, if known. Otherwise update all - * 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"); + ahprintf(AH, "ALTER TABLE %s ENABLE TRIGGER ALL;\n\n", + fmtId(te->tag)); } /* diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 6e2a5f5493c4f92914bb780cde5ae417789e10c5..59aa3cd905833b775f367870d82e1bc5de11c75e 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.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) i_tgconstrname, i_tgconstrrelid, i_tgconstrrelname, + i_tgenabled, i_tgdeferrable, i_tginitdeferred; int ntups; @@ -3381,7 +3382,7 @@ getTriggers(TableInfo tblinfo[], int numTables) appendPQExpBuffer(query, "SELECT tgname, " "tgfoid::pg_catalog.regproc as tgfname, " - "tgtype, tgnargs, tgargs, " + "tgtype, tgnargs, tgargs, tgenabled, " "tgisconstraint, tgconstrname, tgdeferrable, " "tgconstrrelid, tginitdeferred, tableoid, oid, " "tgconstrrelid::pg_catalog.regclass as tgconstrrelname " @@ -3398,7 +3399,7 @@ getTriggers(TableInfo tblinfo[], int numTables) { appendPQExpBuffer(query, "SELECT tgname, tgfoid::regproc as tgfname, " - "tgtype, tgnargs, tgargs, " + "tgtype, tgnargs, tgargs, tgenabled, " "tgisconstraint, tgconstrname, tgdeferrable, " "tgconstrrelid, tginitdeferred, tableoid, oid, " "(select relname from pg_class where oid = tgconstrrelid) " @@ -3411,7 +3412,7 @@ getTriggers(TableInfo tblinfo[], int numTables) { appendPQExpBuffer(query, "SELECT tgname, tgfoid::regproc as tgfname, " - "tgtype, tgnargs, tgargs, " + "tgtype, tgnargs, tgargs, tgenabled, " "tgisconstraint, tgconstrname, tgdeferrable, " "tgconstrrelid, tginitdeferred, " "(SELECT oid FROM pg_class WHERE relname = 'pg_trigger') AS tableoid, " @@ -3449,6 +3450,7 @@ getTriggers(TableInfo tblinfo[], int numTables) i_tgconstrname = PQfnumber(res, "tgconstrname"); i_tgconstrrelid = PQfnumber(res, "tgconstrrelid"); i_tgconstrrelname = PQfnumber(res, "tgconstrrelname"); + i_tgenabled = PQfnumber(res, "tgenabled"); i_tgdeferrable = PQfnumber(res, "tgdeferrable"); i_tginitdeferred = PQfnumber(res, "tginitdeferred"); @@ -3468,6 +3470,7 @@ getTriggers(TableInfo tblinfo[], int numTables) tginfo[j].tgnargs = atoi(PQgetvalue(res, j, i_tgnargs)); tginfo[j].tgargs = strdup(PQgetvalue(res, j, i_tgargs)); 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].tginitdeferred = *(PQgetvalue(res, j, i_tginitdeferred)) == 't'; @@ -7874,6 +7877,14 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo) } 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, tginfo->dobj.name, tbinfo->dobj.namespace->dobj.name, diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index 4f4bb0c19827bba18ad334e1bc5230ebf08a8a4e..9d17a93fc552e49fe7fa7d37b50713c4ec31e7bc 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-2005, 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.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 char *tgconstrname; Oid tgconstrrelid; char *tgconstrrelname; + bool tgenabled; bool tgdeferrable; bool tginitdeferred; } TriggerInfo; diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h index f6c1f88480b96450ce724038c47657422a32f70b..25c0019518c2d6da8944a913370d46046057cd47 100644 --- a/src/include/commands/trigger.h +++ b/src/include/commands/trigger.h @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * 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); 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 TriggerDesc *CopyTriggerDesc(TriggerDesc *trigdesc); diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 90a282e16321d9ef6b9680984895fcd988084001..70c6743ac122e4aa53571e90f2e573522889685a 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * 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 AT_ClusterOn, /* CLUSTER ON */ AT_DropCluster, /* SET WITHOUT CLUSTER */ 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; typedef struct AlterTableCmd /* one subcommand of an ALTER TABLE */ { NodeTag type; AlterTableType subtype; /* Type of table alteration to apply */ - char *name; /* column or constraint name to act on, or - * new owner or tablespace */ + char *name; /* column, constraint, or trigger to act on, + * or new owner or tablespace */ Node *def; /* definition of new column, column type, * index, or constraint */ Node *transform; /* transformation expr for ALTER TYPE */