Thread: INSERT/UPDATE ... RETURNING

INSERT/UPDATE ... RETURNING

From
Gavin Sherry
Date:
Hi all,

I am working on a project which requires INSERT/UPDATE ... RETURNING
functionality. As far as I can tell, Oracle is one of the only commercial
databases supporting this functionality. I checked DB2, Informix 7.2
(which is the most recent release for which I have a manual), Sybase and
Interbase. I also checked Firebird and MySQL.

Oracle returns data into binded variables, which we do not support. It
returns multiple rows into bind arrays, ie, an array of instances of 
binded variables.


Why is RETURNING useful?

1) It simplifies the use of sequences

2) Situations where applications don't know about the data which is being
stored. Eg:

i) INSERT .. VALUES(DEFAULT,...)
ii) UPDATE ... set col=col+X

and variations there of.


Issues with implementing this under Postgres:

1) Returning multiple rows

I see no read why multiple rows should not be returned if multiple rows
are affected. I cannot see any technical reason why this should not be the
case.

2) Same row affected multiple times

UPDATEs can affect rows multiple times. It would be very easy to just
return every tuple affected but that seems broken to me. The logical
solution is to return that tuple which eventually results from the
UPDATE. Unfortunately, that means that we cannot just printtup(). It'll
add a bit of overhead to traverse already UPDATEd tuples for every tuple
-- particularly if we hit disk. Ideas?

3) Inherited updates affecting multiple tables

Seems that it would be the right thing to do to allow returning of
inherited rows, but it might be a bit painful to implement. Ideas?

4) Handling rule cases

Seems reasonable to allow RETURNING when the query is re-written to a
single query and that the operation is not transformed.

5) Permissions

To use RETURNING, the user must have select privileges on the
table(s) being affected

6) Protocol changes

I don't see that this will affect the FE/BE protocol.

7) Zero affected rows

Return zero rows.

Comments, ideas?

Thanks,

Gavin



Re: INSERT/UPDATE ... RETURNING

From
Jan Wieck
Date:
Gavin Sherry wrote:
> 
> Hi all,
> 
> I am working on a project which requires INSERT/UPDATE ... RETURNING
> functionality. As far as I can tell, Oracle is one of the only commercial
> [...]
> 
> 2) Same row affected multiple times
> 
> UPDATEs can affect rows multiple times. It would be very easy to just
> return every tuple affected but that seems broken to me. The logical
> solution is to return that tuple which eventually results from the
> UPDATE. Unfortunately, that means that we cannot just printtup(). It'll
> add a bit of overhead to traverse already UPDATEd tuples for every tuple
> -- particularly if we hit disk. Ideas?

The same statement should not be able to affect the same row multiple
times. If it happens, this would be a bug in the tuple visibility.

> 
> 3) Inherited updates affecting multiple tables
> 
> Seems that it would be the right thing to do to allow returning of
> inherited rows, but it might be a bit painful to implement. Ideas?

If they get affected, yes.

> 
> 4) Handling rule cases
> 
> Seems reasonable to allow RETURNING when the query is re-written to a
> single query and that the operation is not transformed.

This might need some deeper look. It sounds plausible, but the rule
rewriting system has it's own meaning for gravity.

> 
> 5) Permissions
> 
> To use RETURNING, the user must have select privileges on the
> table(s) being affected

Agreed.

> 
> 6) Protocol changes
> 
> I don't see that this will affect the FE/BE protocol.

Agreed.

> 
> 7) Zero affected rows
> 
> Return zero rows.
> 
> Comments, ideas?

I don't see a reason why not to allow DELETE ... RETURNING as well.

With some restriction it could be far simpler than you think. If the
targetlist after RETURNING is allowed to contain Var nodes referencing
NEW or OLD only, then the executor could build a result tuple right
where the heap operation is done and use printtup() to send it to the
client.


Jan

-- 
#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#================================================== JanWieck@Yahoo.com #



Re: INSERT/UPDATE ... RETURNING

From
Philip Warner
Date:
At 07:37 PM 28/04/2003 +1000, Gavin Sherry wrote:
>Oracle is one of the only commercial
>databases supporting this functionality.

DecRDB does too; it restricts update...returning to only return one row, 
and throws an error if more than one row is updated. It covers 95% of 
cases, but returning multiple rows might be nice.


>3) Inherited updates affecting multiple tables
>
>Seems that it would be the right thing to do to allow returning of
>inherited rows, but it might be a bit painful to implement. Ideas?

My preference would be to return all rows that were affected.


>4) Handling rule cases
>
>Seems reasonable to allow RETURNING when the query is re-written to a
>single query and that the operation is not transformed.

The main thing that I think you need to cover is to ensure that common 
implementations of updateable views are supported in a reasonable way. 
Which this sounds like it does.




----------------------------------------------------------------
Philip Warner                    |     __---_____
Albatross Consulting Pty. Ltd.   |----/       -  \
(A.B.N. 75 008 659 498)          |          /(@)   ______---_
Tel: (+61) 0500 83 82 81         |                 _________  \
Fax: (+61) 03 5330 3172          |                 ___________ |
Http://www.rhyme.com.au          |                /           \|                                 |    --________--
PGP key available upon request,  |  /
and from pgp5.ai.mit.edu:11371   |/



Re: INSERT/UPDATE ... RETURNING

From
Tom Lane
Date:
Gavin Sherry <swm@linuxworld.com.au> writes:
> I am working on a project which requires INSERT/UPDATE ... RETURNING
> functionality.

This would be good to have.

> Oracle returns data into binded variables, which we do not support. It
> returns multiple rows into bind arrays, ie, an array of instances of 
> binded variables.

Right.  I think it would be better to return the result just like a
SELECT result.

> 2) Same row affected multiple times

> UPDATEs can affect rows multiple times.

No they can't.  Study the MVCC rules.

> 3) Inherited updates affecting multiple tables

> Seems that it would be the right thing to do to allow returning of
> inherited rows, but it might be a bit painful to implement. Ideas?

Why does this matter?  The RETURNING clause can only name columns of the
topmost table, and so these expressions can surely be computed for every
row of every child table too.

> 4) Handling rule cases

> Seems reasonable to allow RETURNING when the query is re-written to a
> single query and that the operation is not transformed.

In principle I think you could rewrite the RETURNING clause too, but
certainly it'd be okay to punt on this for a first implementation.
        regards, tom lane