Hi, Thom Brown <t...@linux.com> writes: > The message returned by creating a command trigger after create index > is still problematic:
Fixed. I'm attaching an incremental patch here, the github branch is updated too. > CREATE VIEW doesn't return schema: Fixed, and as an added bonus I fixed the CREATE SEQUENCE oddity about that too. > No specific triggers fire when altering a conversion: Couldn't reproduce, works here, added tests. > No specific triggers fire when altering the properties of a function: Fixed. > No specific triggers fire when altering a sequence: Couldn't reproduce, added tests. > No specific triggers when altering a view: Same again. > The object name shown in specific triggers when dropping aggregates > shows the schema name: > Same for collations: > Dropping functions shows the object name as the schema name: > Same with dropping operators: > ...and operator family: > … and the same for dropping text search > configuration/dictionary/parser/template. Fixed in the attached (all of those where located at exactly the same place, by the way, that's one fix). > When dropping domains, the name of the domain includes the schema name: I'm using format_type_be(objectId) so that int4 is integer and int8 bigint etc, but that's adding the schemaname. I didn't have time to look for another API that wouldn't add the schemaname nor to add one myself, will do that soon. > I hadn't previously tested triggers against CLUSTER, REINDEX, VACUUM > and LOAD, but have tested them now. Cool :) > When creating a trigger on REINDEX, I get the following message: Fixed. > Creating AFTER CLUSTER command triggers produce an error (as expected > since it's not supported), but AFTER REINDEX only produces a warning. > These should be the same, probably both an error. Fixed. > VACUUM doesn't fire a specific command trigger: I though it was better this way, I changed my mind and completed the code. > REINDEX on a table seems to show no schema name but an object name for > specific triggers: Still on the TODO. > When REINDEXing an index rather than a table, the table's details are > shown in the trigger. Is this expected?: Yeah well. Will see about how much damage needs to be done in the current APIs, running out of steam for tonight's batch. > REINDEXing the whole database doesn't fire specific command triggers: We don't want to because REINDEX DATABASE is managing transactions on its own, same limitation as with AFTER VACUUM and all. Will have a look at what it takes to document that properly. > Documentation: Fixed. Thom Brown <t...@linux.com> writes: > I've also since found that if I issue a VACUUM, CLUSTER or REINDEX on > a read-only standby, the BEFORE ANY COMMAND trigger fires. I don't > think any trigger should fire on a read-only standby. Well I'm not sold on that myself (think pl/untrusted that would reach out to the OS and do whatever is needed there). You can even set the session_replication_role GUC to replica and only have the replica command triggers fired. Regards, -- Dimitri Fontaine http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support
*** a/doc/src/sgml/ref/create_command_trigger.sgml --- b/doc/src/sgml/ref/create_command_trigger.sgml *************** *** 41,48 **** CREATE COMMAND TRIGGER <replaceable class="PARAMETER">name</replaceable> { BEFOR ALTER LANGUAGE ALTER OPERATOR ALTER OPERATOR CLASS - ALTER OPERATOR CLASS - ALTER OPERATOR FAMILY ALTER OPERATOR FAMILY ALTER SCHEMA ALTER SEQUENCE --- 41,46 ---- *************** *** 137,146 **** CREATE COMMAND TRIGGER <replaceable class="PARAMETER">name</replaceable> { BEFOR </para> <para> ! Note that objects dropped by effect of <literal>DROP CASCADE</literal> ! will not provoque firing a command trigger, only the top-level command ! for the main object will fire a command trigger. That also applis to ! other dependencies following, as in <literal>DROP OWNED BY</literal>. </para> <para> --- 135,145 ---- </para> <para> ! Note that objects dropped by the effect of <literal>DROP ! CASCADE</literal> will not result in a command trigger firing, only the ! top-level command for the main object will fire a command trigger. That ! also applies to other dependencies following, as in <literal>DROP OWNED ! BY</literal>. </para> <para> *************** *** 192,198 **** CREATE COMMAND TRIGGER <replaceable class="PARAMETER">name</replaceable> { BEFOR you are connected to. </para> <para> ! Commands that exercize their own transaction control are only supported in <literal>BEFORE</literal> command triggers, that's the case for <literal>VACUUM</literal>, <literal>CLUSTER</literal> <literal>CREATE INDEX CONCURRENTLY</literal>, and <literal>REINDEX --- 191,197 ---- you are connected to. </para> <para> ! Commands that exercise their own transaction control are only supported in <literal>BEFORE</literal> command triggers, that's the case for <literal>VACUUM</literal>, <literal>CLUSTER</literal> <literal>CREATE INDEX CONCURRENTLY</literal>, and <literal>REINDEX *************** *** 215,220 **** CREATE COMMAND TRIGGER <replaceable class="PARAMETER">name</replaceable> { BEFOR --- 214,224 ---- not to be able to take over control from a superuser. </para> <para> + Triggers on ANY command support more commands than just this list, and + will provide NULL values for every argument except for the argument + that determines whether the trigger was before or after the command + event, and the command tag. + Triggers on <literal>ANY</literal> command support more commands than just this list, and will only provide the <literal>command tag</literal> argument as <literal>NOT NULL</literal>. Supporting more *************** *** 244,257 **** CREATE COMMAND TRIGGER <replaceable class="PARAMETER">name</replaceable> { BEFOR tag</literal>, <literal>objectid</literal> (can be null in case of a BEFORE CREATE or an AFTER DROP command trigger timing), <literal>schemaname</literal> (can be null for objects not ! living in a schema, and for sequences due to an implementation limit) ! and <literal>object name</literal> (can be null for any command ! triggers). ! </para> ! <para> ! The command <literal>CREATE SEQUENCE</literal> lacks support for ! the <literal>schemaname</literal> command trigger argument, it ! provides <literal>NULL</literal> in all cases. </para> </listitem> </varlistentry> --- 248,255 ---- tag</literal>, <literal>objectid</literal> (can be null in case of a BEFORE CREATE or an AFTER DROP command trigger timing), <literal>schemaname</literal> (can be null for objects not ! living in a schema) and <literal>object name</literal> (can be null ! for any command triggers). </para> </listitem> </varlistentry> *** a/src/backend/commands/cmdtrigger.c --- b/src/backend/commands/cmdtrigger.c *************** *** 185,197 **** CreateCmdTrigger(CreateCmdTrigStmt *stmt, const char *queryString) ereport(WARNING, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("AFTER CREATE INDEX CONCURRENTLY triggers are not supported"), ! errdetail("The command trigger will not get fired."))); if (strcmp(stmt->command, "REINDEX") == 0) ereport(WARNING, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("REINDEX DATABASE is not supported"), ! errdetail("The command trigger will not get fired."))); if (funcrettype != VOIDOID) ereport(ERROR, --- 185,197 ---- ereport(WARNING, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("AFTER CREATE INDEX CONCURRENTLY triggers are not supported"), ! errdetail("The command trigger will not fire on concurrently-created indexes."))); if (strcmp(stmt->command, "REINDEX") == 0) ereport(WARNING, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("REINDEX DATABASE is not supported"), ! errdetail("The command trigger will not fire on REINDEX DATABASE."))); if (funcrettype != VOIDOID) ereport(ERROR, *** a/src/backend/commands/dropcmds.c --- b/src/backend/commands/dropcmds.c *************** *** 316,323 **** get_object_name(CommandContext cmd, ObjectType objtype, case OBJECT_FOREIGN_SERVER: case OBJECT_OPCLASS: case OBJECT_OPFAMILY: ! cmd->objectname = strVal(linitial(objname)); break; default: elog(ERROR, "unexpected object type (%d)", (int)objtype); break; --- 316,331 ---- case OBJECT_FOREIGN_SERVER: case OBJECT_OPCLASS: case OBJECT_OPFAMILY: ! { ! int len = list_length(objname); ! if (len == 1) ! cmd->objectname = strVal(linitial(objname)); ! else if (len == 2) ! cmd->objectname = strVal(lsecond(objname)); ! else ! elog(ERROR, "unexpected name list length (%d)", len); break; + } default: elog(ERROR, "unexpected object type (%d)", (int)objtype); break; *** a/src/backend/commands/functioncmds.c --- b/src/backend/commands/functioncmds.c *************** *** 1324,1329 **** AlterFunction(AlterFunctionStmt *stmt) --- 1324,1330 ---- List *set_items = NIL; DefElem *cost_item = NULL; DefElem *rows_item = NULL; + CommandContextData cmd; rel = heap_open(ProcedureRelationId, RowExclusiveLock); *************** *** 1433,1444 **** AlterFunction(AlterFunctionStmt *stmt) --- 1434,1461 ---- repl_val, repl_null, repl_repl); } + /* Call BEFORE ALTER FUNCTION command triggers */ + InitCommandContext(&cmd, (Node *)stmt, false); + + if (CommandFiresTriggers(&cmd)) + { + cmd.objectId = InvalidOid; + cmd.objectname = pstrdup(NameStr(procForm->proname)); + cmd.schemaname = get_namespace_name(procForm->pronamespace); + + ExecBeforeCommandTriggers(&cmd); + } + /* Do the update */ simple_heap_update(rel, &tup->t_self, tup); CatalogUpdateIndexes(rel, tup); heap_close(rel, NoLock); heap_freetuple(tup); + + /* Call AFTER ALTER FUNCTION command triggers */ + if (CommandFiresAfterTriggers(&cmd)) + ExecAfterCommandTriggers(&cmd); } /* *** a/src/backend/commands/sequence.c --- b/src/backend/commands/sequence.c *************** *** 213,233 **** DefineSequence(CreateSeqStmt *seq) stmt->tablespacename = NULL; stmt->if_not_exists = false; ! /* ! * Call BEFORE CREATE SEQUENCE triggers ! */ InitCommandContext(&cmd, (Node *)seq, false); ! if (CommandFiresTriggers(&cmd)) ! { ! cmd.objectId = InvalidOid; ! cmd.objectname = NameStr(name); ! cmd.schemaname = NULL; /* can't publish it easily enough here */ ! ! ExecBeforeCommandTriggers(&cmd); ! } ! ! seqoid = DefineRelation(stmt, RELKIND_SEQUENCE, seq->ownerId); Assert(seqoid != InvalidOid); rel = heap_open(seqoid, AccessExclusiveLock); --- 213,222 ---- stmt->tablespacename = NULL; stmt->if_not_exists = false; ! /* Prepare BEFORE CREATE SEQUENCE triggers */ InitCommandContext(&cmd, (Node *)seq, false); ! seqoid = DefineRelation(stmt, RELKIND_SEQUENCE, seq->ownerId, &cmd); Assert(seqoid != InvalidOid); rel = heap_open(seqoid, AccessExclusiveLock); *** a/src/backend/commands/tablecmds.c --- b/src/backend/commands/tablecmds.c *************** *** 415,421 **** static void RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid, * ---------------------------------------------------------------- */ Oid ! DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId) { char relname[NAMEDATALEN]; Oid namespaceId; --- 415,421 ---- * ---------------------------------------------------------------- */ Oid ! DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, CommandContext cmd) { char relname[NAMEDATALEN]; Oid namespaceId; *************** *** 608,613 **** DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId) --- 608,623 ---- } } + /* Exec BEFORE CREATE view|sequence|table|type command triggers */ + if (CommandFiresTriggers(cmd)) + { + cmd->objectId = InvalidOid; + cmd->objectname = pstrdup(relname); + cmd->schemaname = get_namespace_name(namespaceId); + + ExecBeforeCommandTriggers(cmd); + } + /* * Create the relation. Inherited defaults and constraints are passed in * for immediate handling --- since they don't need parsing, they can be *************** *** 670,675 **** DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId) --- 680,686 ---- */ relation_close(rel, NoLock); + /* AFTER command triggers are fired from well outside this function */ return relationId; } *** a/src/backend/commands/typecmds.c --- b/src/backend/commands/typecmds.c *************** *** 2110,2130 **** DefineCompositeType(RangeVar *typevar, List *coldeflist, } /* - * Call BEFORE CREATE (composite) TYPE triggers - */ - if (CommandFiresTriggers(cmd)) - { - cmd->objectId = InvalidOid; - cmd->objectname = createStmt->relation->relname; - cmd->schemaname = get_namespace_name(typeNamespace); - - ExecBeforeCommandTriggers(cmd); - } - - /* * Finally create the relation. This also creates the type. */ ! relid = DefineRelation(createStmt, RELKIND_COMPOSITE_TYPE, InvalidOid); Assert(relid != InvalidOid); /* Call AFTER CREATE (composite) TYPE triggers */ --- 2110,2118 ---- } /* * Finally create the relation. This also creates the type. */ ! relid = DefineRelation(createStmt, RELKIND_COMPOSITE_TYPE, InvalidOid, cmd); Assert(relid != InvalidOid); /* Call AFTER CREATE (composite) TYPE triggers */ *** a/src/backend/commands/vacuum.c --- b/src/backend/commands/vacuum.c *************** *** 123,130 **** vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast, else in_outer_xact = IsInTransactionChain(isTopLevel); ! /* CAll BEFORE VACUUM command triggers */ ! if (!IsAutoVacuumWorkerProcess() && vacstmt->relation != NULL) { CommandContextData cmd; InitCommandContext(&cmd, (Node *)vacstmt, false); --- 123,130 ---- else in_outer_xact = IsInTransactionChain(isTopLevel); ! /* Call BEFORE VACUUM command triggers */ ! if (!IsAutoVacuumWorkerProcess()) { CommandContextData cmd; InitCommandContext(&cmd, (Node *)vacstmt, false); *************** *** 132,140 **** vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast, if (CommandFiresTriggers(&cmd)) { cmd.objectId = relid; - cmd.objectname = vacstmt->relation->relname; - cmd.schemaname = vacstmt->relation->schemaname; ExecBeforeCommandTriggers(&cmd); } } --- 132,143 ---- if (CommandFiresTriggers(&cmd)) { cmd.objectId = relid; + if (vacstmt->relation != NULL) + { + cmd.objectname = vacstmt->relation->relname; + cmd.schemaname = vacstmt->relation->schemaname; + } ExecBeforeCommandTriggers(&cmd); } } *** a/src/backend/commands/view.c --- b/src/backend/commands/view.c *************** *** 169,186 **** DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace, lockmode = replace ? AccessExclusiveLock : NoLock; (void) RangeVarGetAndCheckCreationNamespace(relation, lockmode, &viewOid); - /* - * Call BEFORE CREATE VIEW triggers - */ - if (CommandFiresTriggers(cmd)) - { - cmd->objectId = InvalidOid; - cmd->objectname = relation->relname; - cmd->schemaname = relation->schemaname; - - ExecBeforeCommandTriggers(cmd); - } - if (OidIsValid(viewOid) && replace) { Relation rel; --- 169,174 ---- *************** *** 208,213 **** DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace, --- 196,211 ---- */ Assert(relation->relpersistence == rel->rd_rel->relpersistence); + /* Call BEFORE CREATE VIEW triggers */ + if (CommandFiresTriggers(cmd)) + { + cmd->objectId = viewOid; + cmd->objectname = RelationGetRelationName(rel); + cmd->schemaname = get_namespace_name(RelationGetNamespace(rel)); + + ExecBeforeCommandTriggers(cmd); + } + /* * Create a tuple descriptor to compare against the existing view, and * verify that the old column list is an initial prefix of the new *************** *** 282,288 **** DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace, * existing view, so we don't need more code to complain if "replace" * is false). */ ! relid = DefineRelation(createStmt, RELKIND_VIEW, InvalidOid); Assert(relid != InvalidOid); return relid; } --- 280,286 ---- * existing view, so we don't need more code to complain if "replace" * is false). */ ! relid = DefineRelation(createStmt, RELKIND_VIEW, InvalidOid, cmd); Assert(relid != InvalidOid); return relid; } *** a/src/backend/tcop/utility.c --- b/src/backend/tcop/utility.c *************** *** 691,706 **** standard_ProcessUtility(Node *parsetree, */ InitCommandContext(&cmd, parsetree, false); - if (CommandFiresTriggers(&cmd)) - { - cmd.objectId = InvalidOid; - cmd.objectname = stmt->relation->relname; - cmd.schemaname = get_namespace_name( - RangeVarGetCreationNamespace(stmt->relation)); - - ExecBeforeCommandTriggers(&cmd); - } - /* Run parse analysis ... */ stmts = transformCreateStmt(stmt, queryString); --- 691,696 ---- *************** *** 717,723 **** standard_ProcessUtility(Node *parsetree, /* Create the table itself */ relOid = DefineRelation((CreateStmt *) stmt, RELKIND_RELATION, ! InvalidOid); /* * Let AlterTableCreateToastTable decide if this one --- 707,714 ---- /* Create the table itself */ relOid = DefineRelation((CreateStmt *) stmt, RELKIND_RELATION, ! InvalidOid, ! &cmd); /* * Let AlterTableCreateToastTable decide if this one *************** *** 741,747 **** standard_ProcessUtility(Node *parsetree, /* Create the table itself */ relOid = DefineRelation((CreateStmt *) stmt, RELKIND_FOREIGN_TABLE, ! InvalidOid); CreateForeignTable((CreateForeignTableStmt *) stmt, relOid); } --- 732,739 ---- /* Create the table itself */ relOid = DefineRelation((CreateStmt *) stmt, RELKIND_FOREIGN_TABLE, ! InvalidOid, ! &cmd); CreateForeignTable((CreateForeignTableStmt *) stmt, relOid); } *** a/src/include/commands/tablecmds.h --- b/src/include/commands/tablecmds.h *************** *** 21,27 **** #include "utils/relcache.h" ! extern Oid DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId); extern void RemoveRelations(DropStmt *drop); --- 21,28 ---- #include "utils/relcache.h" ! extern Oid DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ! CommandContext cmd); extern void RemoveRelations(DropStmt *drop); *** a/src/test/regress/expected/cmdtriggers.out --- b/src/test/regress/expected/cmdtriggers.out *************** *** 26,31 **** alter command trigger snitch_before set disable; --- 26,32 ---- alter command trigger snitch_before set enable; alter command trigger snitch_after_ rename to snitch_after; create command trigger snitch_create_table after create table execute procedure snitch(); + create command trigger snitch_create_seq after create sequence execute procedure snitch(); create command trigger snitch_create_view after create view execute procedure snitch(); create command trigger snitch_alter_table after alter table execute procedure snitch(); create command trigger snitch_alter_seq after alter sequence execute procedure snitch(); *************** *** 54,59 **** create command trigger snitch_alter_domain before alter domain execute procedure --- 55,70 ---- create command trigger snitch_create_type before create type execute procedure snitch(); create command trigger snitch_alter_type before alter type execute procedure snitch(); create command trigger snitch_before_alter_function before alter function execute procedure snitch(); + create command trigger snitch_alter_conversion before alter conversion execute procedure snitch(); + create command trigger snitch_drop_agg before drop aggregate execute procedure snitch(); + create command trigger snitch_before_drop_tsconf before drop text search configuration execute procedure snitch(); + create command trigger snitch_before_drop_tsdict before drop text search dictionary execute procedure snitch(); + create command trigger snitch_before_drop_tsparser before drop text search parser execute procedure snitch(); + create command trigger snitch_before_drop_tstmpl before drop text search template execute procedure snitch(); + create command trigger snitch_vacuum before vacuum execute procedure snitch(); + create command trigger snitch_reindex before reindex execute procedure snitch(); + WARNING: REINDEX DATABASE is not supported + DETAIL: The command trigger will not fire on REINDEX DATABASE. create schema cmd; NOTICE: snitch: BEFORE any CREATE SCHEMA NOTICE: snitch: BEFORE CREATE SCHEMA <NULL> cmd *************** *** 63,72 **** NOTICE: snitch: BEFORE any CREATE SCHEMA --- 74,85 ---- NOTICE: snitch: BEFORE CREATE SCHEMA <NULL> cmd2 NOTICE: snitch: AFTER any CREATE SCHEMA create role regbob; + ERROR: role "regbob" already exists create table cmd.foo(id bigserial primary key); NOTICE: snitch: BEFORE any CREATE TABLE NOTICE: CREATE TABLE will create implicit sequence "foo_id_seq" for serial column "foo.id" NOTICE: snitch: BEFORE any CREATE SEQUENCE + NOTICE: snitch: AFTER CREATE SEQUENCE cmd foo_id_seq NOTICE: snitch: AFTER any CREATE SEQUENCE NOTICE: snitch: BEFORE any CREATE INDEX NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "foo_pkey" for table "foo" *************** *** 166,171 **** NOTICE: snitch: AFTER ALTER TABLE cmd test --- 179,185 ---- NOTICE: snitch: AFTER any ALTER TABLE create sequence test_seq_; NOTICE: snitch: BEFORE any CREATE SEQUENCE + NOTICE: snitch: AFTER CREATE SEQUENCE public test_seq_ NOTICE: snitch: AFTER any CREATE SEQUENCE alter sequence test_seq_ owner to regbob; NOTICE: snitch: BEFORE any ALTER SEQUENCE *************** *** 217,223 **** NOTICE: snitch: AFTER ALTER SEQUENCE cmd test_seq NOTICE: snitch: AFTER any ALTER SEQUENCE create view view_test as select id, things from cmd.test; NOTICE: snitch: BEFORE any CREATE VIEW ! NOTICE: snitch: AFTER CREATE VIEW <NULL> view_test NOTICE: snitch: AFTER any CREATE VIEW alter view view_test owner to regbob; NOTICE: snitch: BEFORE any ALTER VIEW --- 231,237 ---- NOTICE: snitch: AFTER any ALTER SEQUENCE create view view_test as select id, things from cmd.test; NOTICE: snitch: BEFORE any CREATE VIEW ! NOTICE: snitch: AFTER CREATE VIEW public view_test NOTICE: snitch: AFTER any CREATE VIEW alter view view_test owner to regbob; NOTICE: snitch: BEFORE any ALTER VIEW *************** *** 243,250 **** cluster cmd.foo using foo_pkey; --- 257,270 ---- NOTICE: snitch: BEFORE any CLUSTER vacuum cmd.foo; NOTICE: snitch: BEFORE any VACUUM + NOTICE: snitch: BEFORE VACUUM cmd foo vacuum; NOTICE: snitch: BEFORE any VACUUM + NOTICE: snitch: BEFORE VACUUM <NULL> <NULL> + reindex table cmd.foo; + NOTICE: snitch: BEFORE any REINDEX + NOTICE: snitch: BEFORE REINDEX <NULL> cmd + NOTICE: snitch: AFTER any REINDEX set session_replication_role to replica; create table cmd.bar(); reset session_replication_role; *************** *** 254,278 **** NOTICE: snitch: AFTER any CREATE INDEX drop index cmd.idx_foo; NOTICE: snitch: BEFORE any DROP INDEX NOTICE: snitch: AFTER any DROP INDEX ! create function cmd.fun(int) returns text language sql as $$ select t from cmd.foo where id = $1; $$; NOTICE: snitch: BEFORE any CREATE FUNCTION ! NOTICE: snitch: AFTER CREATE FUNCTION cmd fun NOTICE: snitch: AFTER any CREATE FUNCTION ! alter function cmd.fun(int) strict; NOTICE: snitch: BEFORE any ALTER FUNCTION NOTICE: snitch: AFTER any ALTER FUNCTION ! alter function cmd.fun(int) rename to notfun; NOTICE: snitch: BEFORE any ALTER FUNCTION ! NOTICE: snitch: BEFORE ALTER FUNCTION cmd fun NOTICE: snitch: AFTER ALTER FUNCTION cmd notfun NOTICE: snitch: AFTER any ALTER FUNCTION ! alter function cmd.notfun(int) set schema public; NOTICE: snitch: BEFORE any ALTER FUNCTION NOTICE: snitch: BEFORE ALTER FUNCTION cmd notfun ! NOTICE: snitch: AFTER ALTER FUNCTION public notfun NOTICE: snitch: AFTER any ALTER FUNCTION ! drop function public.notfun(int); NOTICE: snitch: BEFORE any DROP FUNCTION NOTICE: snitch: AFTER any DROP FUNCTION create function cmd.plus1(int) returns bigint language sql --- 274,310 ---- drop index cmd.idx_foo; NOTICE: snitch: BEFORE any DROP INDEX NOTICE: snitch: AFTER any DROP INDEX ! create function fun(int) returns text language sql as $$ select t from cmd.foo where id = $1; $$; NOTICE: snitch: BEFORE any CREATE FUNCTION ! NOTICE: snitch: AFTER CREATE FUNCTION public fun NOTICE: snitch: AFTER any CREATE FUNCTION ! alter function fun(int) strict; NOTICE: snitch: BEFORE any ALTER FUNCTION + NOTICE: snitch: BEFORE ALTER FUNCTION public fun + NOTICE: snitch: AFTER ALTER FUNCTION public fun NOTICE: snitch: AFTER any ALTER FUNCTION ! alter function fun(int) rename to notfun; NOTICE: snitch: BEFORE any ALTER FUNCTION ! NOTICE: snitch: BEFORE ALTER FUNCTION public fun ! NOTICE: snitch: AFTER ALTER FUNCTION public notfun ! NOTICE: snitch: AFTER any ALTER FUNCTION ! alter function notfun(int) set schema cmd; ! NOTICE: snitch: BEFORE any ALTER FUNCTION ! NOTICE: snitch: BEFORE ALTER FUNCTION public notfun NOTICE: snitch: AFTER ALTER FUNCTION cmd notfun NOTICE: snitch: AFTER any ALTER FUNCTION ! alter function cmd.notfun(int) owner to regbob; NOTICE: snitch: BEFORE any ALTER FUNCTION NOTICE: snitch: BEFORE ALTER FUNCTION cmd notfun ! NOTICE: snitch: AFTER ALTER FUNCTION cmd notfun ! NOTICE: snitch: AFTER any ALTER FUNCTION ! alter function cmd.notfun(int) cost 77; ! NOTICE: snitch: BEFORE any ALTER FUNCTION ! NOTICE: snitch: BEFORE ALTER FUNCTION cmd notfun ! NOTICE: snitch: AFTER ALTER FUNCTION cmd notfun NOTICE: snitch: AFTER any ALTER FUNCTION ! drop function cmd.notfun(int); NOTICE: snitch: BEFORE any DROP FUNCTION NOTICE: snitch: AFTER any DROP FUNCTION create function cmd.plus1(int) returns bigint language sql *************** *** 306,311 **** NOTICE: snitch: BEFORE any ALTER AGGREGATE --- 338,344 ---- NOTICE: snitch: AFTER any ALTER AGGREGATE drop aggregate public.avg(float8); NOTICE: snitch: BEFORE any DROP AGGREGATE + NOTICE: snitch: BEFORE DROP AGGREGATE public avg NOTICE: snitch: AFTER any DROP AGGREGATE create collation cmd.french (LOCALE = 'fr_FR'); NOTICE: snitch: BEFORE any CREATE COLLATION *************** *** 423,430 **** NOTICE: snitch: BEFORE ALTER TRIGGER cmd footg NOTICE: snitch: AFTER any ALTER TRIGGER drop trigger foo_trigger on cmd.foo; NOTICE: snitch: BEFORE any DROP TRIGGER ! NOTICE: snitch: BEFORE DROP TRIGGER <NULL> cmd ! NOTICE: snitch: AFTER any DROP TRIGGER create text search configuration test (parser = "default"); NOTICE: snitch: BEFORE any CREATE TEXT SEARCH CONFIGURATION NOTICE: snitch: AFTER CREATE TEXT SEARCH CONFIGURATION public test --- 456,478 ---- NOTICE: snitch: AFTER any ALTER TRIGGER drop trigger foo_trigger on cmd.foo; NOTICE: snitch: BEFORE any DROP TRIGGER ! ERROR: unexpected name list length (3) ! create conversion test for 'utf8' to 'sjis' from utf8_to_sjis; ! NOTICE: snitch: BEFORE any CREATE CONVERSION ! NOTICE: snitch: AFTER any CREATE CONVERSION ! create default conversion test2 for 'utf8' to 'sjis' from utf8_to_sjis; ! NOTICE: snitch: BEFORE any CREATE CONVERSION ! NOTICE: snitch: AFTER any CREATE CONVERSION ! alter conversion test2 rename to test3; ! NOTICE: snitch: BEFORE any ALTER CONVERSION ! NOTICE: snitch: BEFORE ALTER CONVERSION public test2 ! NOTICE: snitch: AFTER any ALTER CONVERSION ! drop conversion test3; ! NOTICE: snitch: BEFORE any DROP CONVERSION ! NOTICE: snitch: AFTER any DROP CONVERSION ! drop conversion test; ! NOTICE: snitch: BEFORE any DROP CONVERSION ! NOTICE: snitch: AFTER any DROP CONVERSION create text search configuration test (parser = "default"); NOTICE: snitch: BEFORE any CREATE TEXT SEARCH CONFIGURATION NOTICE: snitch: AFTER CREATE TEXT SEARCH CONFIGURATION public test *************** *** 453,458 **** create text search template test_template ( --- 501,522 ---- NOTICE: snitch: BEFORE any CREATE TEXT SEARCH TEMPLATE NOTICE: snitch: AFTER CREATE TEXT SEARCH TEMPLATE public test_template NOTICE: snitch: AFTER any CREATE TEXT SEARCH TEMPLATE + drop text search configuration test; + NOTICE: snitch: BEFORE any DROP TEXT SEARCH CONFIGURATION + NOTICE: snitch: BEFORE DROP TEXT SEARCH CONFIGURATION public test + NOTICE: snitch: AFTER any DROP TEXT SEARCH CONFIGURATION + drop text search dictionary test_stem; + NOTICE: snitch: BEFORE any DROP TEXT SEARCH DICTIONARY + NOTICE: snitch: BEFORE DROP TEXT SEARCH DICTIONARY public test_stem + NOTICE: snitch: AFTER any DROP TEXT SEARCH DICTIONARY + drop text search parser test_parser; + NOTICE: snitch: BEFORE any DROP TEXT SEARCH PARSER + NOTICE: snitch: BEFORE DROP TEXT SEARCH PARSER public test_parser + NOTICE: snitch: AFTER any DROP TEXT SEARCH PARSER + drop text search template test_template; + NOTICE: snitch: BEFORE any DROP TEXT SEARCH TEMPLATE + NOTICE: snitch: BEFORE DROP TEXT SEARCH TEMPLATE public test_template + NOTICE: snitch: AFTER any DROP TEXT SEARCH TEMPLATE create function cmd.testcast(text) returns int4 language plpgsql as $$begin return 4::int4;end;$$; NOTICE: snitch: BEFORE any CREATE FUNCTION NOTICE: snitch: AFTER CREATE FUNCTION cmd testcast *************** *** 489,498 **** NOTICE: drop cascades to type cmd2.us_postal_code NOTICE: snitch: AFTER any DROP SCHEMA drop role regbob; NOTICE: snitch: BEFORE any DROP ROLE ! NOTICE: snitch: AFTER any DROP ROLE drop command trigger snitch_before; drop command trigger snitch_after; drop command trigger snitch_create_table; drop command trigger snitch_create_view; drop command trigger snitch_alter_table; drop command trigger snitch_alter_seq; --- 553,564 ---- NOTICE: snitch: AFTER any DROP SCHEMA drop role regbob; NOTICE: snitch: BEFORE any DROP ROLE ! ERROR: role "regbob" cannot be dropped because some objects depend on it ! DETAIL: 3 objects in database foo drop command trigger snitch_before; drop command trigger snitch_after; drop command trigger snitch_create_table; + drop command trigger snitch_create_seq; drop command trigger snitch_create_view; drop command trigger snitch_alter_table; drop command trigger snitch_alter_seq; *************** *** 521,523 **** drop command trigger snitch_alter_domain; --- 587,597 ---- drop command trigger snitch_create_type; drop command trigger snitch_alter_type; drop command trigger snitch_before_alter_function; + drop command trigger snitch_alter_conversion; + drop command trigger snitch_drop_agg; + drop command trigger snitch_before_drop_tsconf; + drop command trigger snitch_before_drop_tsdict; + drop command trigger snitch_before_drop_tsparser; + drop command trigger snitch_before_drop_tstmpl; + drop command trigger snitch_vacuum; + drop command trigger snitch_reindex; *** a/src/test/regress/sql/cmdtriggers.sql --- b/src/test/regress/sql/cmdtriggers.sql *************** *** 30,35 **** alter command trigger snitch_before set enable; --- 30,36 ---- alter command trigger snitch_after_ rename to snitch_after; create command trigger snitch_create_table after create table execute procedure snitch(); + create command trigger snitch_create_seq after create sequence execute procedure snitch(); create command trigger snitch_create_view after create view execute procedure snitch(); create command trigger snitch_alter_table after alter table execute procedure snitch(); create command trigger snitch_alter_seq after alter sequence execute procedure snitch(); *************** *** 59,64 **** create command trigger snitch_alter_domain before alter domain execute procedure --- 60,75 ---- create command trigger snitch_create_type before create type execute procedure snitch(); create command trigger snitch_alter_type before alter type execute procedure snitch(); create command trigger snitch_before_alter_function before alter function execute procedure snitch(); + create command trigger snitch_alter_conversion before alter conversion execute procedure snitch(); + create command trigger snitch_drop_agg before drop aggregate execute procedure snitch(); + + create command trigger snitch_before_drop_tsconf before drop text search configuration execute procedure snitch(); + create command trigger snitch_before_drop_tsdict before drop text search dictionary execute procedure snitch(); + create command trigger snitch_before_drop_tsparser before drop text search parser execute procedure snitch(); + create command trigger snitch_before_drop_tstmpl before drop text search template execute procedure snitch(); + + create command trigger snitch_vacuum before vacuum execute procedure snitch(); + create command trigger snitch_reindex before reindex execute procedure snitch(); create schema cmd; create schema cmd2; *************** *** 113,118 **** alter view cmd.view_test2 alter column id drop default; --- 124,130 ---- cluster cmd.foo using foo_pkey; vacuum cmd.foo; vacuum; + reindex table cmd.foo; set session_replication_role to replica; create table cmd.bar(); *************** *** 121,133 **** reset session_replication_role; create index idx_foo on cmd.foo(t); drop index cmd.idx_foo; ! create function cmd.fun(int) returns text language sql as $$ select t from cmd.foo where id = $1; $$; ! alter function cmd.fun(int) strict; ! alter function cmd.fun(int) rename to notfun; ! alter function cmd.notfun(int) set schema public; ! drop function public.notfun(int); create function cmd.plus1(int) returns bigint language sql as $$ select $1::bigint + 1; $$; --- 133,147 ---- create index idx_foo on cmd.foo(t); drop index cmd.idx_foo; ! create function fun(int) returns text language sql as $$ select t from cmd.foo where id = $1; $$; ! alter function fun(int) strict; ! alter function fun(int) rename to notfun; ! alter function notfun(int) set schema cmd; ! alter function cmd.notfun(int) owner to regbob; ! alter function cmd.notfun(int) cost 77; ! drop function cmd.notfun(int); create function cmd.plus1(int) returns bigint language sql as $$ select $1::bigint + 1; $$; *************** *** 185,190 **** create trigger footg before update on cmd.foo for each row execute procedure cmd --- 199,210 ---- alter trigger footg on cmd.foo rename to foo_trigger; drop trigger foo_trigger on cmd.foo; + create conversion test for 'utf8' to 'sjis' from utf8_to_sjis; + create default conversion test2 for 'utf8' to 'sjis' from utf8_to_sjis; + alter conversion test2 rename to test3; + drop conversion test3; + drop conversion test; + create text search configuration test (parser = "default"); create text search dictionary test_stem ( *************** *** 205,210 **** create text search template test_template ( --- 225,235 ---- lexize = dsimple_lexize ); + drop text search configuration test; + drop text search dictionary test_stem; + drop text search parser test_parser; + drop text search template test_template; + create function cmd.testcast(text) returns int4 language plpgsql as $$begin return 4::int4;end;$$; create cast (text as int4) with function cmd.testcast(text) as assignment; *************** *** 218,223 **** drop command trigger snitch_before; --- 243,249 ---- drop command trigger snitch_after; drop command trigger snitch_create_table; + drop command trigger snitch_create_seq; drop command trigger snitch_create_view; drop command trigger snitch_alter_table; drop command trigger snitch_alter_seq; *************** *** 247,249 **** drop command trigger snitch_alter_domain; --- 273,285 ---- drop command trigger snitch_create_type; drop command trigger snitch_alter_type; drop command trigger snitch_before_alter_function; + drop command trigger snitch_alter_conversion; + drop command trigger snitch_drop_agg; + + drop command trigger snitch_before_drop_tsconf; + drop command trigger snitch_before_drop_tsdict; + drop command trigger snitch_before_drop_tsparser; + drop command trigger snitch_before_drop_tstmpl; + + drop command trigger snitch_vacuum; + drop command trigger snitch_reindex;
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers