Re: [HACKERS] sql_drop Event Triggerg

2013-03-29 Thread Dimitri Fontaine
Alvaro Herrera alvhe...@2ndquadrant.com writes:
 Pushed, with some further minor changes.  One not-so-minor change I

Thanks a lot for all the work you did put into this patch!

 introduced was that pg_event_trigger_dropped_objects() now only works
 within a sql_drop event function.  The reason I decided to do this was
 that if we don't have that protection, then it is possible to have a
 ddl_command_end trigger calling pg_event_trigger_dropped_objects(); and
 if there is an sql_drop trigger, then it'd return the list of dropped
 objects, but if there's no sql_drop trigger, it'd raise an error.  That
 seemed surprising enough action-at-a-distance that some protection is
 warranted.

+1

I hope that we can add another such function for ddl_command_start and
ddl_command_end function to get at some object information from there,
now that the support code is in place.

That would allow making any use of the event trigger facility in 9.3
without having to write a C coded extension… which has been the goal for
the last two cycles…

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-hackers


Re: [HACKERS] sql_drop Event Triggerg

2013-03-28 Thread Alvaro Herrera
Pushed, with some further minor changes.  One not-so-minor change I
introduced was that pg_event_trigger_dropped_objects() now only works
within a sql_drop event function.  The reason I decided to do this was
that if we don't have that protection, then it is possible to have a
ddl_command_end trigger calling pg_event_trigger_dropped_objects(); and
if there is an sql_drop trigger, then it'd return the list of dropped
objects, but if there's no sql_drop trigger, it'd raise an error.  That
seemed surprising enough action-at-a-distance that some protection is
warranted.

Thanks for all the review.

-- 
Álvaro Herrerahttp://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training  Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] sql_drop Event Triggerg

2013-03-26 Thread Alvaro Herrera
Robert Haas escribió:
 On Wed, Mar 20, 2013 at 5:42 PM, Alvaro Herrera
 alvhe...@2ndquadrant.com wrote:
  Here's a new version of this patch, rebased on top of the new
  pg_identify_object() stuff.  Note that the regression test doesn't work
  yet, because I didn't adjust to the new identity output definition (the
  docs need work, too).  But that's a simple change to do.  I'm leaving
  that for later.
 
 I think this is getting there.  A few things to think about:

Thanks.

 - pg_event_trigger_dropped_objects seems to assume that
 currentEventTriggerState will be pointing to the same list on every
 call.  But is that necessarily true?  I'm thinking about a case where
 someone opens a cursor in an event trigger and then tries to read from
 that cursor later in the transaction.  I think you might be able to
 crash the server that way.

Well, no, because it uses materialized return mode, so there's no next
time --- the list is constructed completely before
pg_event_trigger_dropped_objects returns.  So there's no such hole.

 - I am not wild about the idea of propagating PG_TRY/PG_CATCH blocks
 into yet more places.  On Linux-x86 they are pretty cheap because
 Linux doesn't need a system call to change the signal mask and x86 has
 few registers that must be saved-and-restored, but elsewhere this can
 be a performance problem.  Now maybe ProcessUtility is not a
 sufficiently-frequently called function for this to matter... but I'm
 not sure.  The alternative is to teach the error handling pathways
 about this in somewhat greater detail, since the point of TRY/CATCH is
 to cleanup things that the regular error handling stuff doesn't now
 about.

I tried this and it doesn't work.  The error pathways you speak about
would be the xact.c entry points to commit and abort transactions;
however, there's a problem with that because some of the commands that
ProcessUtility() deals with have their own transaction management
calls internally; so those would call CommitTransaction() and the
event trigger state would go away, and then when control gets back to
ProcessUtility there would be nothing to clean up.  I think we could
ignore the problem, or install smarts in ProcessUtility to avoid calling
event_trigger.c when one of those commands is involved -- but this seems
to me a solution worse than the problem.  So all in all I feel like the
macro on top of PG_TRY is the way to go.

Now there *is* one rather big performance problem in this patch, which
is that it turns on collection of object dropped data regardless of
there being event triggers that use the info at all.  That's a serious
drawback and we're going to get complaints about it.  So we need to do
something to fix that.

One idea that comes to mind is to add some more things to the grammar,
CREATE EVENT TRIGGER name ... WITH ('DROPPED OBJECTS');
or some such, so that when events happen for which any triggers have
that flag enabled, *then* collecting is activated, otherwise not.  This
would be stored in a new column in pg_event_trigger (say evtsupport, a
char array much like proargmodes).  

The sequence of (ahem) events goes like this:

ProcessUtility()
  EventTriggerBeginCompleteQuery()
  EventTriggerDDLCommandStart()
EventCacheLookup()
EventTriggerInvoke()
  .. run whatever command we've been handed ...
  EventTriggerDDLCommandEnd()
EventCacheLookup()
EventTriggerInvoke()
  EventTriggerEndCompleteQuery()

So EventTriggerBeginCompleteQuery() will have to peek into the event
trigger cache for any ddl_command_end triggers that might apply, and see
if any of them has the flag for dropped objects.  If it's there, then
enable dropped object collection.

-- 
Álvaro Herrerahttp://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training  Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] sql_drop Event Triggerg

2013-03-26 Thread Tom Lane
Alvaro Herrera alvhe...@2ndquadrant.com writes:
 Now there *is* one rather big performance problem in this patch, which
 is that it turns on collection of object dropped data regardless of
 there being event triggers that use the info at all.  That's a serious
 drawback and we're going to get complaints about it.  So we need to do
 something to fix that.

 One idea that comes to mind is to add some more things to the grammar,
 CREATE EVENT TRIGGER name ... WITH ('DROPPED OBJECTS');

Uh ... surely we can just notice whether there's a trigger on the
object-drop event?  I don't understand why we need *yet more*
mechanism here.

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] sql_drop Event Triggerg

2013-03-26 Thread Alvaro Herrera
Tom Lane escribió:
 Alvaro Herrera alvhe...@2ndquadrant.com writes:
  Now there *is* one rather big performance problem in this patch, which
  is that it turns on collection of object dropped data regardless of
  there being event triggers that use the info at all.  That's a serious
  drawback and we're going to get complaints about it.  So we need to do
  something to fix that.
 
  One idea that comes to mind is to add some more things to the grammar,
  CREATE EVENT TRIGGER name ... WITH ('DROPPED OBJECTS');
 
 Uh ... surely we can just notice whether there's a trigger on the
 object-drop event?  I don't understand why we need *yet more*
 mechanism here.

There's no object-drop event, only ddl_command_end.  From previous
discussion I understood we didn't want a separate event, so that's what
we've been running with.

However, I think previous discussions have conflated many different
things, and we've been slowly fixing them one by one; so perhaps at this
point it does make sense to have a new object-drop event.  Let's discuss
it -- we would define it as taking place just before ddl_command_end,
and firing any time a command (with matching tag?) has called
performDeletion or performMultipleDeletions.  Does that sound okay?

-- 
Álvaro Herrerahttp://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training  Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] sql_drop Event Triggerg

2013-03-26 Thread Robert Haas
On Tue, Mar 26, 2013 at 3:02 PM, Alvaro Herrera
alvhe...@2ndquadrant.com wrote:
 I tried this and it doesn't work.  The error pathways you speak about
 would be the xact.c entry points to commit and abort transactions;
 however, there's a problem with that because some of the commands that
 ProcessUtility() deals with have their own transaction management
 calls internally; so those would call CommitTransaction() and the
 event trigger state would go away, and then when control gets back to
 ProcessUtility there would be nothing to clean up.  I think we could
 ignore the problem, or install smarts in ProcessUtility to avoid calling
 event_trigger.c when one of those commands is involved -- but this seems
 to me a solution worse than the problem.  So all in all I feel like the
 macro on top of PG_TRY is the way to go.

I see.  :-(

 Now there *is* one rather big performance problem in this patch, which
 is that it turns on collection of object dropped data regardless of
 there being event triggers that use the info at all.  That's a serious
 drawback and we're going to get complaints about it.  So we need to do
 something to fix that.

Really?  Who is going to care about that?  Surely that overhead is
quite trivial.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] sql_drop Event Triggerg

2013-03-26 Thread Alvaro Herrera
Robert Haas escribió:
 On Tue, Mar 26, 2013 at 3:02 PM, Alvaro Herrera
 alvhe...@2ndquadrant.com wrote:

  Now there *is* one rather big performance problem in this patch, which
  is that it turns on collection of object dropped data regardless of
  there being event triggers that use the info at all.  That's a serious
  drawback and we're going to get complaints about it.  So we need to do
  something to fix that.
 
 Really?  Who is going to care about that?  Surely that overhead is
 quite trivial.

I don't think it is, because it involves syscache lookups for each
object being dropped, many extra pallocs, etc.  Surely that's many times
bigger than the PG_TRY overhead you were worried about.

-- 
Álvaro Herrerahttp://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training  Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] sql_drop Event Triggerg

2013-03-21 Thread Robert Haas
On Wed, Mar 20, 2013 at 5:42 PM, Alvaro Herrera
alvhe...@2ndquadrant.com wrote:
 Here's a new version of this patch, rebased on top of the new
 pg_identify_object() stuff.  Note that the regression test doesn't work
 yet, because I didn't adjust to the new identity output definition (the
 docs need work, too).  But that's a simple change to do.  I'm leaving
 that for later.

I think this is getting there.  A few things to think about:

- pg_event_trigger_dropped_objects seems to assume that
currentEventTriggerState will be pointing to the same list on every
call.  But is that necessarily true?  I'm thinking about a case where
someone opens a cursor in an event trigger and then tries to read from
that cursor later in the transaction.  I think you might be able to
crash the server that way.

- I am not wild about the idea of propagating PG_TRY/PG_CATCH blocks
into yet more places.  On Linux-x86 they are pretty cheap because
Linux doesn't need a system call to change the signal mask and x86 has
few registers that must be saved-and-restored, but elsewhere this can
be a performance problem.  Now maybe ProcessUtility is not a
sufficiently-frequently called function for this to matter... but I'm
not sure.  The alternative is to teach the error handling pathways
about this in somewhat greater detail, since the point of TRY/CATCH is
to cleanup things that the regular error handling stuff doesn't now
about.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] sql_drop Event Triggerg

2013-03-20 Thread Alvaro Herrera
Here's a new version of this patch, rebased on top of the new
pg_identify_object() stuff.  Note that the regression test doesn't work
yet, because I didn't adjust to the new identity output definition (the
docs need work, too).  But that's a simple change to do.  I'm leaving
that for later.

-- 
Álvaro Herrerahttp://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training  Services
*** a/doc/src/sgml/event-trigger.sgml
--- b/doc/src/sgml/event-trigger.sgml
***
*** 36,43 
   The literalddl_command_start/ event occurs just before the
   execution of a literalCREATE/, literalALTER/, or literalDROP/
   command.  As an exception, however, this event does not occur for
!  DDL commands targeting shared objects - databases, roles, and tablespaces
!  - or for command targeting event triggers themselves.  The event trigger
   mechanism does not support these object types.
   literalddl_command_start/ also occurs just before the execution of a
   literalSELECT INTO/literal command, since this is equivalent to
--- 36,43 
   The literalddl_command_start/ event occurs just before the
   execution of a literalCREATE/, literalALTER/, or literalDROP/
   command.  As an exception, however, this event does not occur for
!  DDL commands targeting shared objects mdash; databases, roles, and tablespaces
!  mdash; or for command targeting event triggers themselves.  The event trigger
   mechanism does not support these object types.
   literalddl_command_start/ also occurs just before the execution of a
   literalSELECT INTO/literal command, since this is equivalent to
***
*** 46,51 
--- 46,61 
 /para
  
 para
+ To list all objects that have been deleted as part of executing a
+ command, use the set returning
+ function literalpg_event_trigger_dropped_objects()/ from
+ your literalddl_command_end/ event trigger code (see
+ xref linkend=functions-event-triggers). Note that
+ the trigger is executed after the objects have been deleted from the
+ system catalogs, so it's not possible to look them up anymore.
+/para
+ 
+para
   Event triggers (like other functions) cannot be executed in an aborted
   transaction.  Thus, if a DDL command fails with an error, any associated
   literalddl_command_end/ triggers will not be executed.  Conversely,
***
*** 433,438 
--- 443,453 
  entry align=centerliteralX/literal/entry
 /row
 row
+ entry align=leftliteralDROP OWNED/literal/entry
+ entry align=centerliteralX/literal/entry
+ entry align=centerliteralX/literal/entry
+/row
+row
  entry align=leftliteralDROP RULE/literal/entry
  entry align=centerliteralX/literal/entry
  entry align=centerliteralX/literal/entry
*** a/doc/src/sgml/func.sgml
--- b/doc/src/sgml/func.sgml
***
*** 15980,15983  FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger();
--- 15980,16033 
  xref linkend=SQL-CREATETRIGGER.
  /para
/sect1
+ 
+   sect1 id=functions-event-triggers
+titleEvent Trigger Functions/title
+ 
+indexterm
+  primarypg_event_trigger_dropped_objects/primary
+/indexterm
+ 
+para
+ Currently productnamePostgreSQL/ provides one built-in event trigger
+ helper function, functionpg_event_trigger_dropped_objects/, which
+ lists all object dropped by the command in whose literalddl_command_end/
+ event it is called.  If the function is run in a context other than a
+ literalddl_command_end/ event trigger function, or if it's run in the
+ literalddl_command_end/ event of a command that does not drop objects,
+ it will return the empty set.
+ /para
+ 
+para
+ The functionpg_event_trigger_dropped_objects/ function can be used
+ in an event trigger like this:
+ programlisting
+ CREATE FUNCTION test_event_trigger_for_drops()
+ RETURNS event_trigger LANGUAGE plpgsql AS $$
+ DECLARE
+ obj record;
+ BEGIN
+ FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects()
+ LOOP
+ RAISE NOTICE '% dropped object: % %.% %',
+  tg_tag,
+  obj.object_type,
+  obj.schema_name,
+  obj.object_name,
+  obj.subobject_name;
+ END LOOP;
+ END
+ $$;
+ CREATE EVENT TRIGGER test_event_trigger_for_drops
+ON ddl_command_end
+EXECUTE PROCEDURE test_event_trigger_for_drops();
+ /programlisting
+ /para
+ 
+  para
+For more information about event triggers,
+see xref linkend=event-triggers.
+ /para
+   /sect1
+ 
  /chapter
*** a/src/backend/catalog/dependency.c
--- b/src/backend/catalog/dependency.c
***
*** 257,262  performDeletion(const ObjectAddress *object,
--- 257,268 
  	{
  		ObjectAddress *thisobj = 

Re: [HACKERS] sql_drop Event Triggerg

2013-03-08 Thread Robert Haas
On Tue, Mar 5, 2013 at 12:45 PM, Alvaro Herrera
alvhe...@2ndquadrant.com wrote:
 Hmm, maybe I should be considering a pair of macros instead --
 UTILITY_START_DROP and UTILITY_END_DROP.  I'll give this a try.  Other
 ideas are welcome.

That seems like a possibly promising idea.  I do wonder how well any
of this is going to scale.  Presumably people are going to want
similar things for CREATE and (hardest) ALTER.  Seems like
ProcessUtility() could get pretty messy and confusing.  But I don't
have a better idea, either.  :-(

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] sql_drop Event Triggerg

2013-03-08 Thread Alvaro Herrera
Robert Haas escribió:
 On Tue, Mar 5, 2013 at 12:45 PM, Alvaro Herrera
 alvhe...@2ndquadrant.com wrote:
  Hmm, maybe I should be considering a pair of macros instead --
  UTILITY_START_DROP and UTILITY_END_DROP.  I'll give this a try.  Other
  ideas are welcome.
 
 That seems like a possibly promising idea.  I do wonder how well any
 of this is going to scale.

I did followup with a patch implementing that; did you see it?

 Presumably people are going to want
 similar things for CREATE and (hardest) ALTER.  Seems like
 ProcessUtility() could get pretty messy and confusing.  But I don't
 have a better idea, either.  :-(

Well, the first thing that we need to settle is the user interface.
Normalized command string don't seem to cut it; requiring users to write
SQL parsers is rather unfriendly IMHO.  The current idea of having a
function that returns objects affected by the command seems relatively
sensible.  For drops, it seems pretty straighforward so far.  For CREATE
it's probably somewhat more involved, but seems doable in principle (but
yes, we're going to have to sprinkle ProcessUtility() with a lot of
UTILITY_START/END_CREATE calls).

Not sure about ALTER; maybe we will need a completely different idea to
attack that.

-- 
Álvaro Herrerahttp://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training  Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] sql_drop Event Triggerg

2013-03-08 Thread Robert Haas
On Fri, Mar 8, 2013 at 9:18 AM, Alvaro Herrera alvhe...@2ndquadrant.com wrote:
 Robert Haas escribió:
 On Tue, Mar 5, 2013 at 12:45 PM, Alvaro Herrera
 alvhe...@2ndquadrant.com wrote:
  Hmm, maybe I should be considering a pair of macros instead --
  UTILITY_START_DROP and UTILITY_END_DROP.  I'll give this a try.  Other
  ideas are welcome.

 That seems like a possibly promising idea.  I do wonder how well any
 of this is going to scale.

 I did followup with a patch implementing that; did you see it?

No, sorry.  Which thread is it on?

 Presumably people are going to want
 similar things for CREATE and (hardest) ALTER.  Seems like
 ProcessUtility() could get pretty messy and confusing.  But I don't
 have a better idea, either.  :-(

 Well, the first thing that we need to settle is the user interface.
 Normalized command string don't seem to cut it; requiring users to write
 SQL parsers is rather unfriendly IMHO.

I could not agree more.  The format we're moving towards for dropped
objects can easily be converted back into SQL if you happen to want to
do that, but it's also much easier to process programatically than a
compared with a normalized command string.  So I think we get the best
of both worlds with this design.

 The current idea of having a
 function that returns objects affected by the command seems relatively
 sensible.  For drops, it seems pretty straighforward so far.  For CREATE
 it's probably somewhat more involved, but seems doable in principle (but
 yes, we're going to have to sprinkle ProcessUtility() with a lot of
 UTILITY_START/END_CREATE calls).

 Not sure about ALTER; maybe we will need a completely different idea to
 attack that.

I am inclined to think that putting this logic in ProcessUtility isn't
scalable, even for CREATE, and even moreso for ALTER, unless we can
put it around everything in that function, rather than each command
individually.  Suppose for example that on entry to that function we
simply did this:

if (isCompleteQuery)
++CompleteQueryNestingLevel;

...and at exit, we did the reverse.  This could work a bit like the
GUC nesting level.  When an object is dropped, we find the array slot
for the current nesting level, and it's, say, a List **, and we push a
new element onto that list.  When somebody asks for a list of dropped
objects, we pull from the list for the current nesting level.  When
decrementing the nesting level, we flush the list associated with the
old nesting level, if any.

if (isCompleteQuery)
{
list_free(dropped_objects_list[CompleteQueryNestingLevel];
dropped_objects_list[CompleteQueryNestingLevel] = NIL;
--CompleteQueryNestingLevel;
}

Now, if we want to support CREATE, we can just have a
created_objects_list array as well, and only minimal changes are
required here.  If we want to support ALTER we can have an
altered_objects_list, and the only decision is what data to stuff into
the list elements.

I think this is a lot better than decorating each individual command,
which is already unweildly and bound to get worse.  It is a bit of a
definitional change, because it implies that the list of dropped
objects is the list of objects dropped by the most-nearly-enclosing
DDL command, rather than the list of objects dropped by the
most-nearly-enclosing DDL command *that is capable of dropping
objects*.  However, I'm inclined to think that's a better definition
anyway.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] sql_drop Event Triggerg

2013-03-08 Thread Alvaro Herrera
Robert Haas escribió:
 On Fri, Mar 8, 2013 at 9:18 AM, Alvaro Herrera alvhe...@2ndquadrant.com 
 wrote:
  Robert Haas escribió:
  On Tue, Mar 5, 2013 at 12:45 PM, Alvaro Herrera
  alvhe...@2ndquadrant.com wrote:
   Hmm, maybe I should be considering a pair of macros instead --
   UTILITY_START_DROP and UTILITY_END_DROP.  I'll give this a try.  Other
   ideas are welcome.
 
  That seems like a possibly promising idea.  I do wonder how well any
  of this is going to scale.
 
  I did followup with a patch implementing that; did you see it?
 
 No, sorry.  Which thread is it on?

http://www.postgresql.org/message-id/20130305214218.gp9...@alvh.no-ip.org

I think Gmail's feature of breaking threads when subject changes is an
annoyance here.  I somehow added a g at the end and later dropped it.
I didn't remember that behavior of Gmail's.

  The current idea of having a
  function that returns objects affected by the command seems relatively
  sensible.  For drops, it seems pretty straighforward so far.  For CREATE
  it's probably somewhat more involved, but seems doable in principle (but
  yes, we're going to have to sprinkle ProcessUtility() with a lot of
  UTILITY_START/END_CREATE calls).
 
  Not sure about ALTER; maybe we will need a completely different idea to
  attack that.
 
 I am inclined to think that putting this logic in ProcessUtility isn't
 scalable, even for CREATE, and even moreso for ALTER, unless we can
 put it around everything in that function, rather than each command
 individually.  Suppose for example that on entry to that function we
 simply did this:
 
 if (isCompleteQuery)
 ++CompleteQueryNestingLevel;
 
 ...and at exit, we did the reverse.  This could work a bit like the
 GUC nesting level.

Hmm, this seems an interesting idea to explore.

-- 
Álvaro Herrerahttp://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training  Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] sql_drop Event Triggerg

2013-03-05 Thread Alvaro Herrera
Robert Haas escribió:
 On Mon, Mar 4, 2013 at 4:59 PM, Alvaro Herrera alvhe...@2ndquadrant.com 
 wrote:
  Alvaro Herrera escribió:
 
  I think this is mostly ready to go in.  I'll look at your docs, and
  unless there are more objections will commit later or early tomorrow.
 
  Actually it still needs a bit more work: the error messages in
  pg_event_trigger_dropped_object need to be reworked.  It's a bit
  annoying that the function throws an error if the function is called in
  a CREATE command, rather than returning an empty set; or is it just me?
 
 That seems like a reasonable thing to change.

I'm thinking just removing the check altogether, and if the list of
objects dropped is empty, then the empty set is returned.  That is, if
you call the function directly in user-invoked SQL, you get empty; if
you call the function in a CREATE event trigger function, you get empty.

Since this makes the boolean drop_in_progress useless, it'd be removed
as well.

 I do have
 a bit of concern about the save-and-restore logic for the
 dropped-object list -- it necessitates that the processing of every
 DDL command that can potentially drop objects be bracketed with a
 PG_TRY/PG_CATCH block.  While that's relatively easy to guarantee
 today (but doesn't ALTER TABLE need similar handling?), it seems to me
 that it might get broken in the future.  How hard would it be to pass
 this information up and down the call stack instead of doing it this
 way?

This would be rather messy, I think; there are too many layers, and too
many different functions.

 Or at least move the save/restore logic into something inside the
 deletion machinery itself so that new callers don't have to worry
 about it?

Hmm, maybe this can be made to work, I'll see about it.

-- 
Álvaro Herrerahttp://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training  Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] sql_drop Event Triggerg

2013-03-05 Thread Alvaro Herrera
 Robert Haas escribió:

  Or at least move the save/restore logic into something inside the
  deletion machinery itself so that new callers don't have to worry
  about it?

I don't think that works well; precisely the point of the
initialize/finalize pair of functions is to bracket the drop so that the
objects reported by the deletion machinery are stored in the right list.

I tried this macro:

/*
 * Wrap a code fragment that executes a command that may drop database objects,
 * so that the event trigger environment is appropriately setup.
 *
 * Note this macro will call EventTriggerDDLCommandEnd if the object type is
 * supported; caller must make sure to call EventTriggerDDLCommandStart by
 * itself.
 */
#define ExecuteDropCommand(isCompleteQuery, codeFragment, has_objtype, objtype) 
\
do { \
slist_head  _save_objlist; \
bool_supported; \
\
_supported = has_objtype ? 
EventTriggerSupportsObjectType(objtype) : true; \
\
if (isCompleteQuery) \
{ \
EventTriggerInitializeDrop(_save_objlist); \
} \
PG_TRY(); \
{ \
codeFragment; \
if (isCompleteQuery  _supported) \
{ \
EventTriggerDDLCommandEnd(parsetree); \
} \
} \
PG_CATCH(); \
{ \
if (isCompleteQuery  _supported) \
{ \
EventTriggerFinalizeDrop(_save_objlist); \
} \
PG_RE_THROW(); \
} \
PG_END_TRY(); \
EventTriggerFinalizeDrop(_save_objlist); \
} while (0)

This looks nice in DropOwned:

case T_DropOwnedStmt:
if (isCompleteQuery)
EventTriggerDDLCommandStart(parsetree);
ExecuteDropCommand(isCompleteQuery,
   DropOwnedObjects((DropOwnedStmt *) 
parsetree),
   false, 0);
break;

And it works for DropStmt too:

ExecuteDropCommand(isCompleteQuery,
switch (stmt-removeType)
{
case OBJECT_INDEX:
case OBJECT_TABLE:
case OBJECT_SEQUENCE:
case OBJECT_VIEW:
case OBJECT_MATVIEW:
case OBJECT_FOREIGN_TABLE:
RemoveRelations((DropStmt *) parsetree);
break;
default:
RemoveObjects((DropStmt *) parsetree);
break;
}, true, stmt-removeType);

but a rather serious problem is that pgindent refuses to work completely
on this (which is understandable, IMV).  My editor doesn't like the
braces inside something that looks like a function call, either.  We use
this pattern (a codeFragment being called by a macro) as
ProcessMessageList in inval.c, but the code fragments there are much
simpler.

And in AlterTable, using the macro would be much uglier because the code
fragment is more convoluted.

I'm not really sure if it's worth having the above macro if the only
caller is DropOwned.

Hmm, maybe I should be considering a pair of macros instead --
UTILITY_START_DROP and UTILITY_END_DROP.  I'll give this a try.  Other
ideas are welcome.

FWIW, I noticed that the AlterTable case lacks a call to DDLCommandEnd;
reporting that to Dimitri led to him noticing that DefineStmt also lacks
one.  This is a simple bug in the already-committed implementation which
should probably be fixed separately from this patch.

-- 
Álvaro Herrerahttp://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training  Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers