Thread: proposal: catch warnings

proposal: catch warnings

From
"Pavel Stehule"
Date:
Hello,

PostgreSQL allow only catch exception (elevel ERROR). SQL/PSM requires that 
warnings are catchable too. Simply solution's is adding one callback  to 
error's processing of errors on level WARNING.

typedef struct WarningHandlerCallback
{       bool            (*callback) (void *arg, ErrorData *edata);       void       *arg;
} WarningHandlerCallback;

extern DLLIMPORT WarningHandlerCallback *warning_handler;

Callback function returns true if accept warning and process it. This 
function is called from errfinish()
      /*        * Emit the message to the right places. If warning_handler is 
defined,        * try use warning_handler. Emit message only if handler don't 
accept        * message (returns false). Warning handlers are used in PL/pgPSM 
language.       */       if (elevel == WARNING)       {               bool handled = false;
               if (warning_handler)               handled = 
(*warning_handler->callback)(warning_handler->arg,edata);
               if (!handled)                       EmitErrorReport();       }       else
EmitErrorReport();

It's propably usable only for SQL/PSM implementation, and it's one from two 
necessery hacks to core for this PL (second is scrollable cursor's support). 
But without this hook I cannot simply distribute plpgpsm.

Any comments?

Best regards

Pavel Stehule

_________________________________________________________________
Chcete sdilet sve obrazky a hudbu s prateli? http://messenger.msn.cz/



Re: proposal: catch warnings

From
"Simon Riggs"
Date:
On Sun, 2007-01-07 at 09:59 +0100, Pavel Stehule wrote:

> PostgreSQL allow only catch exception (elevel ERROR). SQL/PSM requires that 
> warnings are catchable too. Simply solution's is adding one callback  to 
> error's processing of errors on level WARNING.

Exceptions are run within their own subtransaction, so the exception
handling code runs separately.

Does the PSM warning error handler run in the same transaction or a
separate subtransaction? Can transaction execution continue afterwards?

--  Simon Riggs              EnterpriseDB   http://www.enterprisedb.com




Re: proposal: catch warnings

From
"Pavel Stehule"
Date:
>
>On Sun, 2007-01-07 at 09:59 +0100, Pavel Stehule wrote:
>
> > PostgreSQL allow only catch exception (elevel ERROR). SQL/PSM requires 
>that
> > warnings are catchable too. Simply solution's is adding one callback  to
> > error's processing of errors on level WARNING.
>
>Exceptions are run within their own subtransaction, so the exception
>handling code runs separately.
>
>Does the PSM warning error handler run in the same transaction or a
>separate subtransaction? Can transaction execution continue afterwards?
>

It's depend. Continue and exit warning handlers run in the same transaction, 
undo handler has separate subtransaction. It works well. For patterns used 
in SQL/PSM is important fast continue handler for SQLSTATE '02000' (not 
found). Transactions are controlled in plpgpsm code (like plpgsql). This 
patch allows detecting signalled warning (after processing and finishing any 
statement).

Pavel Stehule

_________________________________________________________________
Find sales, coupons, and free shipping, all in one place! �MSN Shopping 
Sales & Deals 
http://shopping.msn.com/content/shp/?ctid=198,ptnrid=176,ptnrdata=200639



Re: proposal: catch warnings

From
"Simon Riggs"
Date:
On Sun, 2007-01-07 at 11:20 +0100, Pavel Stehule wrote:
> >
> >On Sun, 2007-01-07 at 09:59 +0100, Pavel Stehule wrote:
> >
> > > PostgreSQL allow only catch exception (elevel ERROR). SQL/PSM requires 
> >that
> > > warnings are catchable too. Simply solution's is adding one callback  to
> > > error's processing of errors on level WARNING.
> >
> >Exceptions are run within their own subtransaction, so the exception
> >handling code runs separately.
> >
> >Does the PSM warning error handler run in the same transaction or a
> >separate subtransaction? Can transaction execution continue afterwards?
> >
> 
> It's depend. Continue and exit warning handlers run in the same transaction, 
> undo handler has separate subtransaction. It works well. For patterns used 
> in SQL/PSM is important fast continue handler for SQLSTATE '02000' (not 
> found). 

Hmmm. SQLSTATE 02000 NO_DATA doesn't seem to be raised anywhere by the
backend, though it is listed by ECPG.

Are you thinking of the special variable FOUND, which doesn't raise an
exception in PL/pgSQL, or the PostgreSQL PL/pgSQL exception:
NO_DATA_FOUND (SQLSTATE P0002) which isn't actually an SQL ERROR at all.
(Definitely an exception in PL/SQL?)

ISTM that if we have an exception defined like this in PL/pgSQL
EXCEPTION     WHEN NO_DATA_FOUND THEN        blockEND;

that we wouldn't need to wrap it in a sub-transaction, because the
earlier statements need not be rolled back when it occurs. Perhaps you
can scan for this condition in the PSM code, rather than getting the
backend to throw a different kind of error?

--  Simon Riggs              EnterpriseDB   http://www.enterprisedb.com




Re: proposal: catch warnings

From
"Pavel Stehule"
Date:
> > >
> > >Does the PSM warning error handler run in the same transaction or a
> > >separate subtransaction? Can transaction execution continue afterwards?
> > >
> >
> > It's depend. Continue and exit warning handlers run in the same 
>transaction,
> > undo handler has separate subtransaction. It works well. For patterns 
>used
> > in SQL/PSM is important fast continue handler for SQLSTATE '02000' (not
> > found).
>
>Hmmm. SQLSTATE 02000 NO_DATA doesn't seem to be raised anywhere by the
>backend, though it is listed by ECPG.
>
>Are you thinking of the special variable FOUND, which doesn't raise an
>exception in PL/pgSQL, or the PostgreSQL PL/pgSQL exception:
>NO_DATA_FOUND (SQLSTATE P0002) which isn't actually an SQL ERROR at all.
>(Definitely an exception in PL/SQL?)
>
>ISTM that if we have an exception defined like this in PL/pgSQL
>
>    EXCEPTION
>        WHEN NO_DATA_FOUND THEN
>            block
>    END;
>
>that we wouldn't need to wrap it in a sub-transaction, because the
>earlier statements need not be rolled back when it occurs. Perhaps you
>can scan for this condition in the PSM code, rather than getting the
>backend to throw a different kind of error?
>

FOUND is only one value, but I have to detect all values from sqlstate 
classes '02' and '01'. Without backend change I am not able catch warnings 
from other PL. Hook is general solution.

Pavel

_________________________________________________________________
Emotikony a pozadi programu MSN Messenger ozivi vasi konverzaci. 
http://messenger.msn.cz/



Re: proposal: catch warnings

From
Tom Lane
Date:
"Pavel Stehule" <pavel.stehule@hotmail.com> writes:
> PostgreSQL allow only catch exception (elevel ERROR). SQL/PSM requires that 
> warnings are catchable too.

What in the world does it mean to "catch" a warning?  If your intention
is to process arbitrary user-defined code while inside the error
subsystem, I can tell you right now that it's unlikely to work.

> Simply solution's is adding one callback  to 
> error's processing of errors on level WARNING.

I can't get excited about hooks that are defined in such a way that
there can be only one user of the hook ... if it's useful to you,
it's probably useful to someone else too.
        regards, tom lane


Re: proposal: catch warnings

From
"Pavel Stehule"
Date:
What is problem? ANSI SQL has different model of handling exception than 
postgresql. It doesn't distinguishes between warnings and exception. Simply 
some sqlstate clases are reservated for warnings and other's for exception. 
But all sqlstate's (without '00000') can be handled via any CONTINUE, EXIT 
or UNDO handler. Exceptions are not problem. But I cannot map sqlstates 
'01xxx' and '02xxx' to exception because they internally do rollback. I have 
to use different elevel. I cannot trap warnings on plpgpsm level, because in 
this moment I will lost an possibility of traping warnings from others PL. I 
can use warning for signaling any safe event (don't need rollaback) from 
this PL. Currently I save only last warning, but it is possible safe 
warnings info to any queue.
>
>What in the world does it mean to "catch" a warning?  If your intention
>is to process arbitrary user-defined code while inside the error
>subsystem, I can tell you right now that it's unlikely to work.
>
No, it means, it process user-defined code related to some compound 
statement immediate after some statement which signals sqlstate '01xxx' or 
'02xxx'. Exceptions are diffrent, they do rollback before call exception's 
handle. I use callback function only for decision if there is any possible 
warning handler and for saving struct edata. After excecuton any statement I 
check this struct and call handler statement.
> > Simply solution's is adding one callback  to
> > error's processing of errors on level WARNING.
>

>I can't get excited about hooks that are defined in such a way that
>there can be only one user of the hook ... if it's useful to you,
>it's probably useful to someone else too.
>

Propably we can use it for faster catch no_data in plpgsql or for enhancing 
of statement RAISE in future. Any SQL/PSM implementation have to solve this 
task.

Regards
Pavel Stehule

_________________________________________________________________
Emotikony a pozadi programu MSN Messenger ozivi vasi konverzaci. 
http://messenger.msn.cz/



Re: proposal: catch warnings

From
Tom Lane
Date:
"Pavel Stehule" <pavel.stehule@hotmail.com> writes:
> What is problem? ANSI SQL has different model of handling exception than 
> postgresql. It doesn't distinguishes between warnings and exception. Simply 
> some sqlstate clases are reservated for warnings and other's for exception. 
> But all sqlstate's (without '00000') can be handled via any CONTINUE, EXIT 
> or UNDO handler. Exceptions are not problem.

Really?  If an EXIT handler fires on a warning, does that mean the
statement giving the warning is aborted midstream, instead of being
allowed to complete?

I think that the model the SQL spec has in mind is that a warning
condition is raised only after the statement has run to completion
(which implies only one such condition per statement BTW).  This is
quite at variance with our notion of WARNING.  AFAICS you are not going
to be able to implement anything that works sanely if you try to take
control away at the instant of elog(WARNING).  You would need to create
some infrastructure for making this happen after the statement giving
the warning is otherwise done --- which will take *much* more extensive
revisions than just hooking into elog.
        regards, tom lane


Re: proposal: catch warnings

From
"Pavel Stehule"
Date:
>
>"Pavel Stehule" <pavel.stehule@hotmail.com> writes:
> > What is problem? ANSI SQL has different model of handling exception than
> > postgresql. It doesn't distinguishes between warnings and exception. 
>Simply
> > some sqlstate clases are reservated for warnings and other's for 
>exception.
> > But all sqlstate's (without '00000') can be handled via any CONTINUE, 
>EXIT
> > or UNDO handler. Exceptions are not problem.
>
>Really?  If an EXIT handler fires on a warning, does that mean the
>statement giving the warning is aborted midstream, instead of being
>allowed to complete?
>
Propably I have too bad english. I wrote it. I am sorry. Any warning 
handlers are executed after statements. With exit handler it executes 
handler statement and leave block. That's all.

>I think that the model the SQL spec has in mind is that a warning
>condition is raised only after the statement has run to completion
>(which implies only one such condition per statement BTW).  This is
>quite at variance with our notion of WARNING.  AFAICS you are not going
>to be able to implement anything that works sanely if you try to take
>control away at the instant of elog(WARNING).  You would need to create
>some infrastructure for making this happen after the statement giving
>the warning is otherwise done --- which will take *much* more extensive
>revisions than just hooking into elog.
>

I understand. Warning infrastructure is implemented in plpgpsm code now. 
There is one interest of hook - compatibility. I can simply set if warning 
is processed on server side or is sended to client. This decision depends on 
application (not only application, it depend on used language).

Do you thing  API like?

ErrorData *edata;

push_catch_warning_state(); // new handler and set catching to on
  .... EXEC statement ....

if ((edata = catched_warning() != NULL)
{
if (I know warning)   process it;   clean_warning();
else   distribute_warning(); // doesn't mean directly sending to client, maybe 
others handlers wait for it
}

pop_catch_warning_state();  // prev. handler and set catch to prev. value

Pavel

_________________________________________________________________
Najdete si svou lasku a nove pratele na Match.com. http://www.msn.cz/