Re: proposal: PL/Pythonu - function ereport

From: Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com>
To: Catalin Iacob <iacobcatalin(at)gmail(dot)com>
Cc: Jim Nasby <Jim(dot)Nasby(at)bluetreble(dot)com>, Peter Eisentraut <peter_e(at)gmx(dot)net>, Craig Ringer <craig(at)2ndquadrant(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: proposal: PL/Pythonu - function ereport
Date: 2016-01-26 07:22:24
Message-ID: CAFj8pRBc1PxrkvoXRz+nk-R39b9W-+yvqCWvDSSbTEDmFG6BUg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

2016-01-26 7:31 GMT+01:00 Catalin Iacob <iacobcatalin(at)gmail(dot)com>:

> On 1/21/16, Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com> wrote:
> > 2016-01-14 17:16 GMT+01:00 Catalin Iacob <iacobcatalin(at)gmail(dot)com>:
> >> Consider this call chain: SQL code 1 -> PL/Python code 1 -> SPI (via
> >> plpy.execute) -> SQL code 2 -> PL/Python code 2
> >>
> >> If I'm writing PL/Python code 1 and I want to raise an error toward
> >> SQL code 1 I use raise plpy.Error. plpy.SPIError is what I get if I
> >> call into SQL code 2 and that has an error. That error could indeed
> >> come from a plpy.Error thrown by PL/Python code 2 or it could come
> >> from a SQL syntax error or whatever. But the symmetry holds:
> >> plpy.Error is what you raise to stop the query and return errors to
> >> your SQL caller and plpy.SPIError is what you get back if you use SPI
> >> to execute some other piece of SQL which has an error. I *think* (I'm
> >> an internals newbie though so I could be wrong) that SQL code 1
> >> doesn't call into PL/Python code 1 via SPI so why would the latter use
> >> something called SPIError to inform the former about an error?
> >>
> >
> > It is not correct - outside PLPython you got a Error (PostgreSQL error
> has
> > not any classes), and isn't important the raising class (Error or
> > SPIError). Inside PL/Python you will got SPIError or successors (based on
> > SQLcode).
>
> What exactly is not correct? Indeed, *outside* PLPython you don't get
> a Python exception because Postgres isn't Python, you get Postgres'
> way of representing an exception (error code, message, hint and so on
> that might go to the client or not etc.). But that's normal, it's just
> the impedance mismatch between the fact that you embed Python with its
> rules into Postgres with its other rules. It's normal that the "host"
> (Postgres) wins in the end and uses its mechanism to report errors.
> The "guest" (PLPython) is there only to give mechanisms to activate
> the "host".
>
> But *inside* PLPython what I wrote is true, see this example for what I
> mean:
>
> CREATE FUNCTION test()
> RETURNS int
> AS $$
> def a_func():
> raise plpy.Error('an error')
>
> try:
> a_func()
> except plpy.Error as exc:
> plpy.info('have exc {} of type {}'.format(exc, type(exc)))
> plpy.info('have spidata {}'.format(hasattr(exc, 'spidata')))
> $$ LANGUAGE plpython3u;
>
> Running this produces:
>
> DROP FUNCTION
> CREATE FUNCTION
> psql:plpy_demo:16: INFO: have exc an error of type <class 'plpy.Error'>
> psql:plpy_demo:16: INFO: have spidata False
>
> > Currently If I raise plpy.Error, then it is immediately trasformed to
> > PostgreSQL, and and then to SPIError and successors.
>
> Depends how you define immediately. I would say it's really not
> immediately, it's only at the Postgres boundary. Imagine in the
> example above that a_func could call lots of other Python code and
> somewhere deep down raise Error would be used. Within that whole
> execution the error stays Error and can be caught as such, it will
> have nothing to do with SPIError.
>
> But in my opinion this discussion shouldn't really even be about
> catching these things, most of the times you won't catch them and
> instead you'll let them go to Postgres. The discussion should be
> whether raise plpy.Error(...), plpy.raise_error, plpy.raise_info(,,,)
> etc. all with keyword argument support are a good PLPython interface
> to Postgres' ereport. I think they are.
>
> On a different note, I've explained what I think but I might be wrong
> and don't want to stall the patch just because I don't agree with the
> approach it takes.
>
> The waiting for author status is ok since, as far as I can see, Pavel
> also agrees that at least some of the issues raised in
>
> http://www.postgresql.org/message-id/CAHg_5grU=LVRbZDhfCiiYc9PhS=1X5f=Gd44-3JcuL-QAoRC-A@mail.gmail.com
> need to be fixed.
>
> Would it help maybe to remove myself as reviewer in the CF? Maybe that
> makes somebody else pick it up and move it further.
>
> I could also code the version I'm describing but that design would be
> contrary to what Jim and Pavel lean towards now. It could help to
> compare approaches side by side but I don't like the idea of dueling
> patches.
>

I would to reduce this patch and don't try to touch on buildin exceptions.
I hope, so there isn't any disagreement?

I though about it lot of, and I see a the core of problems in orthogonal
constructed exceptions in Python and Postgres. We working with statements
elog, ereport, RAISE EXCEPTION - and these statements are much more like
templates - can generate any possible exception. Python is based on working
with instances of predefined exceptions. And it is core of problem.
Template like class cannot be ancestor of instance oriented classes. This
is task for somebody who knows well OOP and meta OOP in Python - total
different chapter, different patch

Regards

Pavel

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tatsuo Ishii 2016-01-26 07:29:11 Re: Why format() adds double quote?
Previous Message Pavel Stehule 2016-01-26 07:05:00 Re: custom function for converting human readable sizes to bytes