proposal: catch warnings

Started by Pavel Stehuleabout 19 years ago9 messages
#1Pavel Stehule
pavel.stehule@hotmail.com

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/

#2Simon Riggs
simon@2ndquadrant.com
In reply to: Pavel Stehule (#1)
Re: proposal: catch warnings

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

#3Pavel Stehule
pavel.stehule@hotmail.com
In reply to: Simon Riggs (#2)
Re: proposal: catch warnings

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

#4Simon Riggs
simon@2ndquadrant.com
In reply to: Pavel Stehule (#3)
Re: proposal: catch warnings

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

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

#5Pavel Stehule
pavel.stehule@hotmail.com
In reply to: Simon Riggs (#4)
Re: proposal: catch warnings

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/

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Pavel Stehule (#1)
Re: proposal: catch warnings

"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

#7Pavel Stehule
pavel.stehule@hotmail.com
In reply to: Tom Lane (#6)
Re: proposal: catch warnings

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/

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Pavel Stehule (#7)
Re: proposal: catch warnings

"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

#9Pavel Stehule
pavel.stehule@hotmail.com
In reply to: Tom Lane (#8)
Re: proposal: catch warnings

"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/