From: Dimitri Fontaine <dimitri@2ndQuadrant.fr>
To: Robert Haas <robertmhaas@gmail.com>
Cc: Alvaro Herrera <alvherre@2ndquadrant.com>
Cc: PostgreSQL Hackers <pgsql-hackers@postgresql.org>
Subject: Re: Event Triggers: adding information
Date: Tue, 22 Jan 2013 13:29:26 +0100
Message-ID: <m2vcapl7tl.fsf@2ndQuadrant.fr> (raw)
In-Reply-To: <m2622pmnnn.fsf@2ndQuadrant.fr>
References: <m2txrsdzxa.fsf@2ndQuadrant.fr>
<m2zk1j9c44.fsf@2ndQuadrant.fr>
<CA+Tgmob6kmAySE5yXvd3uE9LifHunufMg9iU3GmbJ5bpGPiHjQ@mail.gmail.com>
<m2k3sbe51z.fsf@2ndQuadrant.fr>
<CA+TgmoZjOACnHOKrz-eucj3FJXrYJzA-_yjSqajOQR8qkjCi=w@mail.gmail.com>
<m2bodi55yn.fsf@2ndQuadrant.fr>
<CA+TgmoZTxXGAkoyQD0aNOyju1X19SnVfk7KV9fsJCv63bS-C4g@mail.gmail.com>
<m27go1ot1a.fsf@2ndQuadrant.fr>
<20130104205251.GB9191@alvh.no-ip.org>
<m28v88pqin.fsf@2ndQuadrant.fr>
<20130109165829.GB4490@alvh.no-ip.org>
<CA+TgmobykpymdGyfbCDEfS6+-50X-AKYTdK88fjMS4-mY5SBdw@mail.gmail.com>
<m2ehhkrfqk.fsf@2ndQuadrant.fr>
<CA+TgmobfeB_YpgMv5NjW52tG36Hg_DY=jq0XDkE5zwCstPQ4pg@mail.gmail.com>
<m2pq14m7sx.fsf@2ndQuadrant.fr>
<CA+TgmoYEW583z+oisToCYQMz2grzpavdXrCi3-W2D_+nucVhzQ@mail.gmail.com>
<m2k3rbhh79.fsf@2ndQuadrant.fr>
<CA+TgmoZYFhn=DyenBLr8KUZXYHtgjo-O8YE-7y61WKR6F05UQA@mail.gmail.com>
<m21udesaz3.fsf@2ndQuadrant.fr>
<CA+TgmoZPhj6Rw-DottwresCJnOmRewbOxp2AABwyxP2k7vZf-Q@mail.gmail.com>
<m2622pmnnn.fsf@2ndQuadrant.fr>
List-Unsubscribe: <mailto:majordomo@postgresql.org?body=unsub%20pgsql-hackers>
Dimitri Fontaine <dimitri@2ndQuadrant.fr> writes:
> I added some in the attached patch.
>
> doc/src/sgml/event-trigger.sgml | 10 ++
> src/backend/commands/event_trigger.c | 6 +-
> src/test/regress/expected/event_trigger.out | 106 +++++++++++++++++++
> src/test/regress/sql/event_trigger.sql | 47 ++++++++
> 4 files changed, 167 insertions(+), 2 deletions(-)
And I did drop a comment line I didn't mean to when trying things out,
so here's the update copy. There's a bug fix in there too, in both the
versions of the patch, that the new regression tests exercise.
Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackersAttachments:event_trigger_harness.v1.patch (text/x-patch, 10.7K) download
*** a/doc/src/sgml/event-trigger.sgml
--- b/doc/src/sgml/event-trigger.sgml
***************
*** 52,57 ****
--- 52,67 ----
</para>
<para>
+ Event Triggers themselves are not run in+ a <xref linkend="sql-savepoint">. That means that you can stop the+ execution of the current command by issuing a <command>RAISE+ EXCEPTION</command> command from anywhere in your trigger function, and+ that if an error occurs in the command itself (e.g.+ when <command>DROP</command> targets an object that does not exists),+ the <literal>ddl_command_end</> triggers will not get run.+ </para>+ + <para>
For a complete list of commands supported by the event trigger mechanism,
see <xref linkend="event-trigger-matrix">.
</para>
*** a/src/backend/commands/event_trigger.c
--- b/src/backend/commands/event_trigger.c
***************
*** 551,557 **** filter_event_trigger(const char **tag, EventTriggerCacheItem *item)
}
/* Filter by tags, if any were specified. */
! if (item->ntags != 0 && bsearch(&tag, item->tag,
item->ntags, sizeof(char *),
pg_qsort_strcmp) == NULL)
return false;
--- 551,557 ----
}
/* Filter by tags, if any were specified. */
! if (item->ntags != 0 && bsearch(tag, item->tag,
item->ntags, sizeof(char *),
pg_qsort_strcmp) == NULL)
return false;
***************
*** 752,757 **** EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata)
--- 752,760 ----
ListCell *lc;
bool first = true;
+ /* Guard against stack overflow due to recursive event trigger */+ check_stack_depth();+
/*
* Let's evaluate event triggers in their own memory context, so
* that any leaks get cleaned up promptly.
*** a/src/test/regress/expected/event_trigger.out
--- b/src/test/regress/expected/event_trigger.out
***************
*** 67,72 **** alter event trigger regress_event_trigger enable;
--- 67,73 ----
alter event trigger regress_event_trigger disable;
-- regress_event_trigger2 should fire, but not regress_event_trigger
create table event_trigger_fire1 (a int);
+ NOTICE: test_event_trigger: ddl_command_start CREATE TABLE
NOTICE: test_event_trigger: ddl_command_end CREATE TABLE
-- but nothing should fire here
drop table event_trigger_fire1;
***************
*** 90,95 **** ERROR: event trigger "regress_event_trigger" does not exist
--- 91,201 ----
drop role regression_bob;
ERROR: role "regression_bob" cannot be dropped because some objects depend on it
DETAIL: owner of event trigger regress_event_trigger3
+ -- now try something crazy to ensure we don't crash the backend+ create function test_event_trigger_drop_function()+ returns event_trigger+ set max_stack_depth to '100' -- limit the size of the stack trace we output+ as $$+ BEGIN+ drop function test_event_trigger2() cascade;+ END+ $$ language plpgsql;+ NOTICE: test_event_trigger: ddl_command_start CREATE FUNCTION+ NOTICE: test_event_trigger: ddl_command_end CREATE FUNCTION+ create function test_event_trigger2() returns event_trigger as $$+ BEGIN+ RAISE NOTICE 'test_event_trigger2: % %', tg_event, tg_tag;+ END+ $$ language plpgsql;+ NOTICE: test_event_trigger: ddl_command_start CREATE FUNCTION+ NOTICE: test_event_trigger: ddl_command_end CREATE FUNCTION+ create event trigger drop_test_a on "ddl_command_start"+ execute procedure test_event_trigger_drop_function();+ create event trigger drop_test_b on "ddl_command_start"+ execute procedure test_event_trigger2();+ -- now watch the fun+ create table event_trigger_fire1 (a int);+ ERROR: stack depth limit exceeded+ HINT: Increase the configuration parameter "max_stack_depth" (currently 100kB), after ensuring the platform's stack depth limit is adequate.+ CONTEXT: SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ SQL statement "drop function test_event_trigger2() cascade"+ PL/pgSQL function test_event_trigger_drop_function() line 3 at SQL statement+ -- now limit the event trigger to avoid infinite recursion+ drop event trigger drop_test_a;+ create event trigger drop_test_a on "ddl_command_start"+ when tag in ('create table')+ execute procedure test_event_trigger_drop_function();+ -- and try again, see if we crash+ --+ -- we want to avoid seeing the following in the regression tests:+ -- ERROR: cache lookup failed for function 30201+ -- because the OID of course changes each time+ --+ set client_min_messages to fatal;+ create table event_trigger_fire1 (a int);+ reset client_min_messages;+ -- then cleanup the crazy test+ drop event trigger drop_test_a;+ drop event trigger drop_test_b;+ drop function test_event_trigger_drop_function();+ NOTICE: test_event_trigger: ddl_command_end DROP FUNCTION
-- these are all OK; the second one should emit a NOTICE
drop event trigger if exists regress_event_trigger2;
drop event trigger if exists regress_event_trigger2;
*** a/src/test/regress/sql/event_trigger.sql
--- b/src/test/regress/sql/event_trigger.sql
***************
*** 95,100 **** drop event trigger regress_event_trigger;
--- 95,147 ----
-- should fail, regression_bob owns regress_event_trigger2/3
drop role regression_bob;
+ -- now try something crazy to ensure we don't crash the backend+ create function test_event_trigger_drop_function()+ returns event_trigger+ set max_stack_depth to '100' -- limit the size of the stack trace we output+ as $$+ BEGIN+ drop function test_event_trigger2() cascade;+ END+ $$ language plpgsql;+ + create function test_event_trigger2() returns event_trigger as $$+ BEGIN+ RAISE NOTICE 'test_event_trigger2: % %', tg_event, tg_tag;+ END+ $$ language plpgsql;+ + create event trigger drop_test_a on "ddl_command_start"+ execute procedure test_event_trigger_drop_function();+ + create event trigger drop_test_b on "ddl_command_start"+ execute procedure test_event_trigger2();+ + -- now watch the fun+ create table event_trigger_fire1 (a int);+ + -- now limit the event trigger to avoid infinite recursion+ drop event trigger drop_test_a;+ + create event trigger drop_test_a on "ddl_command_start"+ when tag in ('create table')+ execute procedure test_event_trigger_drop_function();+ + -- and try again, see if we crash+ --+ -- we want to avoid seeing the following in the regression tests:+ -- ERROR: cache lookup failed for function 30201+ -- because the OID of course changes each time+ --+ set client_min_messages to fatal;+ create table event_trigger_fire1 (a int);+ reset client_min_messages;+ + -- then cleanup the crazy test+ drop event trigger drop_test_a;+ drop event trigger drop_test_b;+ drop function test_event_trigger_drop_function();+
-- these are all OK; the second one should emit a NOTICE
drop event trigger if exists regress_event_trigger2;
drop event trigger if exists regress_event_trigger2;
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: dimitri@2ndQuadrant.fr, robertmhaas@gmail.com, alvherre@2ndquadrant.com
Subject: Re: Event Triggers: adding information
In-Reply-To: <m2vcapl7tl.fsf@2ndQuadrant.fr>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox