enable/disable trigger (Re: Fwd: [HACKERS] Open items) - Mailing list pgsql-patches
From | Satoshi Nagayasu |
---|---|
Subject | enable/disable trigger (Re: Fwd: [HACKERS] Open items) |
Date | |
Msg-id | 42C4EDA6.8000407@nttdata.co.jp Whole thread Raw |
Responses |
Re: enable/disable trigger (Re: Fwd: [HACKERS] Open items)
Re: enable/disable trigger (Re: Fwd: [HACKERS] Open items) Re: enable/disable trigger (Re: Fwd: [HACKERS] Open items) Re: enable/disable trigger (Re: Fwd: [HACKERS] Open items) Re: enable/disable trigger (Re: Fwd: [HACKERS] Open items) |
List | pgsql-patches |
Hi all, Here is a first patch to allow these commands. > ALTER TABLE <table> ENABLE TRIGGER <trigname> > ALTER TABLE <table> DISABLE TRIGGER <trigname> Bruce said to allow them only super-user, but currently this patch allows also the table owner. If we need to restrict these operations, we have to add more user checks. > From: Bruce Momjian <pgman@candle.pha.pa.us> > Date: 2005/06/29 20:49 > Subject: Re: [HACKERS] Open items > To: Satoshi Nagayasu <nagayasus@nttdata.co.jp> > Cc: PostgreSQL-development <pgsql-hackers@postgresql.org> > > > Satoshi Nagayasu wrote: > >>How about enable/disable triggers? >> >>>From TODO: >> >>>Allow triggers to be disabled. >> >>http://momjian.postgresql.org/cgi-bin/pgtodo?trigger >> >>I think this is good for COPY performance improvement. >> >>Now I have user functions to enable/disable triggers, not DDL. >>It modifies system tables. >>But I can rewrite this as a DDL. (ALTER TABLE?) > > > Yea, it is a TODO item, and should be pretty straight-forward to code, > so sure, go ahead. > > It has to be something that is super-user-only. > > -- > Bruce Momjian | http://candle.pha.pa.us > pgman@candle.pha.pa.us | (610) 359-1001 > + If your life is a hard drive, | 13 Roberts Road > + Christ can be your backup. | Newtown Square, Pennsylvania 19073 > > ---------------------------(end of broadcast)--------------------------- > TIP 4: Don't 'kill -9' the postmaster > -- NAGAYASU Satoshi <nagayasus@nttdata.co.jp> diff -ru pgsql.orig/src/backend/commands/tablecmds.c pgsql/src/backend/commands/tablecmds.c --- pgsql.orig/src/backend/commands/tablecmds.c 2005-06-28 14:08:54.000000000 +0900 +++ pgsql/src/backend/commands/tablecmds.c 2005-07-01 15:50:27.000000000 +0900 @@ -236,6 +236,8 @@ Oid newOwnerId); static void ATExecClusterOn(Relation rel, const char *indexName); static void ATExecDropCluster(Relation rel); +static void ATExecEnableDisableTrigger(Relation rel, char *trigname, + bool enable); static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, char *tablespacename); static void ATExecSetTableSpace(Oid tableOid, Oid newTableSpace); @@ -1993,6 +1995,11 @@ } pass = AT_PASS_DROP; break; + case AT_EnableTrig: /* ENABLE TRIGGER */ + case AT_DisableTrig: /* DISABLE TRIGGER */ + ATSimplePermissions(rel, false); + pass = AT_PASS_MISC; + break; case AT_SetTableSpace: /* SET TABLESPACE */ /* This command never recurses */ ATPrepSetTableSpace(tab, rel, cmd->name); @@ -2155,6 +2162,12 @@ * Nothing to do here; Phase 3 does the work */ break; + case AT_EnableTrig: /* ENABLE TRIGGER */ + ATExecEnableDisableTrigger(rel, cmd->name, true); + break; + case AT_DisableTrig: /* DISABLE TRIGGER */ + ATExecEnableDisableTrigger(rel, cmd->name, false); + break; default: /* oops */ elog(ERROR, "unrecognized alter table type: %d", (int) cmd->subtype); @@ -5465,6 +5478,15 @@ } /* + * ALTER TABLE ENABLE/DISABLE TRIGGER + */ +static void +ATExecEnableDisableTrigger(Relation rel, char *trigname, bool enable) +{ + EnableDisableTrigger(rel, trigname, enable); +} + +/* * ALTER TABLE SET TABLESPACE */ static void diff -ru pgsql.orig/src/backend/commands/trigger.c pgsql/src/backend/commands/trigger.c --- pgsql.orig/src/backend/commands/trigger.c 2005-05-30 16:20:58.000000000 +0900 +++ pgsql/src/backend/commands/trigger.c 2005-07-01 15:53:45.000000000 +0900 @@ -3063,3 +3063,74 @@ afterTriggerAddEvent(new_event); } } + +/* ---------- + * EnableDisableTrigger() + * + * Called by ALTER TABLE ENABLE/DISABLE TRIGGER + * to change 'tgenabled' flag in the pg_trigger. + * ---------- + */ +void +EnableDisableTrigger(Relation rel, const char *tgname, bool enable) +{ + Relation tgrel; + SysScanDesc tgscan; + ScanKeyData keys[2]; + HeapTuple tuple; + + /* Permissions checks */ + if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId())) + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, + RelationGetRelationName(rel)); + + if (!allowSystemTableMods && IsSystemRelation(rel)) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("permission denied: \"%s\" is a system catalog", + RelationGetRelationName(rel)))); + + tgrel = heap_open(TriggerRelationId, RowExclusiveLock); + + ScanKeyInit(&keys[0], + Anum_pg_trigger_tgrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(rel))); + ScanKeyInit(&keys[1], + Anum_pg_trigger_tgname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(tgname)); + + tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true, + SnapshotNow, 1, keys); + + while (HeapTupleIsValid(tuple = systable_getnext(tgscan))) + { + HeapTuple newtup = heap_copytuple(tuple); + Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(newtup); + + if ( pg_trigger->tgenabled==true && enable==false ) + { + pg_trigger->tgenabled = false; + } + else if ( pg_trigger->tgenabled==false && enable==true ) + { + pg_trigger->tgenabled = true; + } + + simple_heap_update(tgrel, &newtup->t_self, newtup); + + /* Keep catalog indexes current */ + CatalogUpdateIndexes(tgrel, newtup); + + heap_freetuple(newtup); + } + systable_endscan(tgscan); + + heap_close(tgrel, RowExclusiveLock); + + CommandCounterIncrement(); + + FreeTriggerDesc(rel->trigdesc); + RelationBuildTriggers(rel); +} diff -ru pgsql.orig/src/backend/parser/gram.y pgsql/src/backend/parser/gram.y --- pgsql.orig/src/backend/parser/gram.y 2005-06-30 05:34:13.000000000 +0900 +++ pgsql/src/backend/parser/gram.y 2005-07-01 14:21:25.000000000 +0900 @@ -348,9 +348,9 @@ 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 DISTINCT DO DOMAIN_P DOUBLE_P DROP - EACH ELSE ENCODING ENCRYPTED END_P ESCAPE EXCEPT EXCLUDING + EACH ELSE ENABLE ENCODING ENCRYPTED END_P ESCAPE EXCEPT EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT FALSE_P FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD @@ -1389,6 +1389,22 @@ n->name = NULL; $$ = (Node *)n; } + /* ALTER TABLE <name> ENABLE TRIGGER <trig> */ + | ENABLE TRIGGER name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_EnableTrig; + n->name = $3; + $$ = (Node *)n; + } + /* ALTER TABLE <name> DISABLE TRIGGER <trig> */ + | DISABLE TRIGGER name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DisableTrig; + n->name = $3; + $$ = (Node *)n; + } | alter_rel_cmd { $$ = $1; diff -ru pgsql.orig/src/backend/parser/keywords.c pgsql/src/backend/parser/keywords.c --- pgsql.orig/src/backend/parser/keywords.c 2005-06-30 05:34:14.000000000 +0900 +++ pgsql/src/backend/parser/keywords.c 2005-07-01 14:38:13.000000000 +0900 @@ -116,6 +116,7 @@ {"delimiter", DELIMITER}, {"delimiters", DELIMITERS}, {"desc", DESC}, + {"disable", DISABLE}, {"distinct", DISTINCT}, {"do", DO}, {"domain", DOMAIN_P}, @@ -123,6 +124,7 @@ {"drop", DROP}, {"each", EACH}, {"else", ELSE}, + {"enable", ENABLE}, {"encoding", ENCODING}, {"encrypted", ENCRYPTED}, {"end", END_P}, diff -ru pgsql.orig/src/include/commands/trigger.h pgsql/src/include/commands/trigger.h --- pgsql.orig/src/include/commands/trigger.h 2005-05-30 16:20:58.000000000 +0900 +++ pgsql/src/include/commands/trigger.h 2005-07-01 15:50:09.000000000 +0900 @@ -164,6 +164,7 @@ extern void AfterTriggerSetState(ConstraintsSetStmt *stmt); +void EnableDisableTrigger(Relation rel, const char *tgname, bool enable); /* * in utils/adt/ri_triggers.c diff -ru pgsql.orig/src/include/nodes/parsenodes.h pgsql/src/include/nodes/parsenodes.h --- pgsql.orig/src/include/nodes/parsenodes.h 2005-06-29 04:51:24.000000000 +0900 +++ pgsql/src/include/nodes/parsenodes.h 2005-07-01 14:20:14.000000000 +0900 @@ -822,6 +822,8 @@ AT_ClusterOn, /* CLUSTER ON */ AT_DropCluster, /* SET WITHOUT CLUSTER */ AT_DropOids, /* SET WITHOUT OIDS */ + AT_EnableTrig, /* ENABLE TRIGGER */ + AT_DisableTrig, /* DISABLE TRIGGER */ AT_SetTableSpace /* SET TABLESPACE */ } AlterTableType;
pgsql-patches by date: