Writeable CTEs

Lists: pgsql-hackers
From: Marko Tiikkaja <marko(dot)tiikkaja(at)cs(dot)helsinki(dot)fi>
To: PostgreSQL development <pgsql-hackers(at)postgresql(dot)org>
Subject: Writeable CTEs
Date: 2010-01-05 16:42:27
Message-ID: 4B436BF3.1060707@cs.helsinki.fi
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Hi,

Attached is a patch where I've taken into account the problems Tom
pointed out in his review [1]. It still needs a bit cleaning up, but
I'm not planning on any big changes. Any feedback welcome.

One thing I only noticed now is this:

=> select * from foo;
a
---
0
(1 row)

=> with t as (delete from foo returning *)
-> insert into bar
-> select * from t;
INSERT 0 2

It correctly reports 2 affected rows (one deleted and one inserted), but
is this the answer we want? It doesn't seem all that useful to know the
total amount of affected rows.

Regards,
Marko Tiikkaja

[1] http://archives.postgresql.org/pgsql-hackers/2009-11/msg01860.php

Attachment Content-Type Size
writeable4.patch text/plain 60.0 KB

From: Greg Stark <gsstark(at)mit(dot)edu>
To: Marko Tiikkaja <marko(dot)tiikkaja(at)cs(dot)helsinki(dot)fi>
Cc: PostgreSQL development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Writeable CTEs
Date: 2010-01-05 17:21:12
Message-ID: 407d949e1001050921s20dbea72nee846c27da29bcaa@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, Jan 5, 2010 at 4:42 PM, Marko Tiikkaja
<marko(dot)tiikkaja(at)cs(dot)helsinki(dot)fi> wrote:
> => with t as (delete from foo returning *)
> -> insert into bar
> -> select * from t;
> INSERT 0 2
>
> It correctly reports 2 affected rows (one deleted and one inserted), but is
> this the answer we want?  It doesn't seem all that useful to know the total
> amount of affected rows.

My first thought is that the number should correspond to the INSERT.
It didn't INSERT two rows so it seems wrong. More importantly in a
case like

with t as (delete from foo returning *)
select * from t where x=?

applications will almost certainly expect the number to match the
actual number of rows returned and may well misbehave if they don't.

--
greg


From: David Fetter <david(at)fetter(dot)org>
To: Greg Stark <gsstark(at)mit(dot)edu>
Cc: Marko Tiikkaja <marko(dot)tiikkaja(at)cs(dot)helsinki(dot)fi>, PostgreSQL development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Writeable CTEs
Date: 2010-01-05 17:34:47
Message-ID: 20100105173447.GD24648@fetter.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, Jan 05, 2010 at 05:21:12PM +0000, Greg Stark wrote:
> On Tue, Jan 5, 2010 at 4:42 PM, Marko Tiikkaja
> <marko(dot)tiikkaja(at)cs(dot)helsinki(dot)fi> wrote:
> > => with t as (delete from foo returning *)
> > -> insert into bar
> > -> select * from t;
> > INSERT 0 2
> >
> > It correctly reports 2 affected rows (one deleted and one
> > inserted), but is this the answer we want?  It doesn't seem all
> > that useful to know the total amount of affected rows.
>
> My first thought is that the number should correspond to the INSERT.
> It didn't INSERT two rows so it seems wrong. More importantly in a
> case like
>
> with t as (delete from foo returning *) select * from t where x=?
>
> applications will almost certainly expect the number to match the
> actual number of rows returned and may well misbehave if they don't.

I'm not sure how relevant this could be, as existing apps can't use
future functionality. We have precedents with RULEs, which can make
the arguments pretty meaningless.

In some future version, we may want to redo the infrastructure to
support "modified" values for multiple statements, but for now, that
seems like an unnecessary frill.

Cheers,
David.
--
David Fetter <david(at)fetter(dot)org> http://fetter.org/
Phone: +1 415 235 3778 AIM: dfetter666 Yahoo!: dfetter
Skype: davidfetter XMPP: david(dot)fetter(at)gmail(dot)com
iCal: webcal://www.tripit.com/feed/ical/people/david74/tripit.ics

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate


From: Marko Tiikkaja <marko(dot)tiikkaja(at)cs(dot)helsinki(dot)fi>
To: Greg Stark <gsstark(at)mit(dot)edu>
Cc: PostgreSQL development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Writeable CTEs
Date: 2010-01-05 17:45:30
Message-ID: 4B437ABA.6000405@cs.helsinki.fi
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On 2010-01-05 19:21 +0200, Greg Stark wrote:
> with t as (delete from foo returning *)
> select * from t where x=?
>
> applications will almost certainly expect the number to match the
> actual number of rows returned and may well misbehave if they don't.

I probably wasn't clear about the actual problem in the original post.
The problem only affects INSERT, UDPATE and DELETE where you are
actually counting affected rows (i.e. PQcmdTuples(), not PQntuples()) so
the this example would work as expected.

Regards,
Marko Tiikkaja


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Marko Tiikkaja <marko(dot)tiikkaja(at)cs(dot)helsinki(dot)fi>
Cc: PostgreSQL development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Writeable CTEs
Date: 2010-01-05 18:40:28
Message-ID: 12968.1262716828@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Marko Tiikkaja <marko(dot)tiikkaja(at)cs(dot)helsinki(dot)fi> writes:
> => with t as (delete from foo returning *)
> -> insert into bar
> -> select * from t;
> INSERT 0 2

> It correctly reports 2 affected rows (one deleted and one inserted), but
> is this the answer we want?

No. The returned tag should consider only the top-level operation,
not what happened inside any CTEs.

regards, tom lane


From: Josh Berkus <josh(at)agliodbs(dot)com>
To: Marko Tiikkaja <marko(dot)tiikkaja(at)cs(dot)helsinki(dot)fi>
Cc: Greg Stark <gsstark(at)mit(dot)edu>, PostgreSQL development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Writeable CTEs
Date: 2010-01-05 21:20:52
Message-ID: 4B43AD34.5060101@agliodbs.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On 1/5/10 9:45 AM, Marko Tiikkaja wrote:
> On 2010-01-05 19:21 +0200, Greg Stark wrote:
>> with t as (delete from foo returning *)
>> select * from t where x=?
>>
>> applications will almost certainly expect the number to match the
>> actual number of rows returned and may well misbehave if they don't.
>
> I probably wasn't clear about the actual problem in the original post.
> The problem only affects INSERT, UDPATE and DELETE where you are
> actually counting affected rows (i.e. PQcmdTuples(), not PQntuples()) so
> the this example would work as expected.

I don't think there is an "as expected" for this situation; people won't
know what to expect. So what do we think is resonable? The current
behavior, which reports the total count of rows expected, works for me.

--Josh Berkus


From: Robert Haas <robertmhaas(at)gmail(dot)com>
To: Josh Berkus <josh(at)agliodbs(dot)com>
Cc: Marko Tiikkaja <marko(dot)tiikkaja(at)cs(dot)helsinki(dot)fi>, Greg Stark <gsstark(at)mit(dot)edu>, PostgreSQL development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Writeable CTEs
Date: 2010-01-05 21:46:48
Message-ID: 603c8f071001051346q643aa537xa9253029e1f9a69b@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, Jan 5, 2010 at 4:20 PM, Josh Berkus <josh(at)agliodbs(dot)com> wrote:
> On 1/5/10 9:45 AM, Marko Tiikkaja wrote:
>> On 2010-01-05 19:21 +0200, Greg Stark wrote:
>>> with t as (delete from foo returning *)
>>> select * from t where x=?
>>>
>>> applications will almost certainly expect the number to match the
>>> actual number of rows returned and may well misbehave if they don't.
>>
>> I probably wasn't clear about the actual problem in the original post.
>> The problem only affects INSERT, UDPATE and DELETE where you are
>> actually counting affected rows (i.e. PQcmdTuples(), not PQntuples()) so
>> the this example would work as expected.
>
> I don't think there is an "as expected" for this situation; people won't
> know what to expect. So what do we think is resonable?  The current
> behavior, which reports the total count of rows expected, works for me.

I agree with Tom's statement upthread that we should only count the
rows affected by the top-level query. Anything else seems extremely
counter-intuitive.

...Robert


From: Josh Berkus <josh(at)agliodbs(dot)com>
To: Robert Haas <robertmhaas(at)gmail(dot)com>
Cc: Marko Tiikkaja <marko(dot)tiikkaja(at)cs(dot)helsinki(dot)fi>, Greg Stark <gsstark(at)mit(dot)edu>, PostgreSQL development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Writeable CTEs
Date: 2010-01-05 21:58:37
Message-ID: 4B43B60D.6040904@agliodbs.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers


> I agree with Tom's statement upthread that we should only count the
> rows affected by the top-level query. Anything else seems extremely
> counter-intuitive.

I'm ok with that. I don't think there is any kind of intuitive behavior
in this situation, and we just need to pick something and document it.

--Josh


From: Marko Tiikkaja <marko(dot)tiikkaja(at)cs(dot)helsinki(dot)fi>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: PostgreSQL development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Writeable CTEs
Date: 2010-01-12 18:55:54
Message-ID: 4B4CC5BA.4020901@cs.helsinki.fi
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On 2010-01-05 20:40 +0200, Tom Lane wrote:
> Marko Tiikkaja <marko(dot)tiikkaja(at)cs(dot)helsinki(dot)fi> writes:
>> => with t as (delete from foo returning *)
>> -> insert into bar
>> -> select * from t;
>> INSERT 0 2
>
>> It correctly reports 2 affected rows (one deleted and one inserted), but
>> is this the answer we want?
>
> No. The returned tag should consider only the top-level operation,
> not what happened inside any CTEs.

Attached is the latest version of the patch. This fixes all issues I'm
aware of. This one also allows forward-referencing and recursive CTEs
in the same CTE list with writeable CTEs, using the RECURSIVE keyword.

Regards,
Marko Tiikkaja

Attachment Content-Type Size
writeable5.patch text/plain 67.6 KB