Re: Questions about update, delete, ctid... - Mailing list pgsql-general

From Florian G. Pflug
Subject Re: Questions about update, delete, ctid...
Date
Msg-id 44CD451D.80607@phlo.org
Whole thread Raw
In response to Re: Questions about update, delete, ctid...  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: Questions about update, delete, ctid...  (Martijn van Oosterhout <kleptog@svana.org>)
List pgsql-general
Tom Lane wrote:
> "Florian G. Pflug" <fgp@phlo.org> writes:
>> Martijn van Oosterhout wrote:
>>> It's the t_ctid field of the tuple header. But I don't see what that
>>> has to do with "WHERE CURRENT OF". That expression should return the
>>> tuple visible to your transaction, not some updated version which you
>>> won't be able to fetch. If you end up updating the old version, the
>>> system will take care of finding the newer version if necessary.
>
>> The problem is that the ctid of the tuple that "fetch" returned
>> might not actually be the tuple that needs to be updated.
>
> Martijn's got a point though: it's not clear that that needs any special
> care on the part of WHERE CURRENT OF.  It may be that the existing
> EvalPlanQual machinery does everything that's needful.  Is the example
> you show really any different from updating a tuple that someone else
> updated while your UPDATE was in progress?  In both cases the EPQ
> machinery will take care of chaining forward to the right version to
> update.

I agree, at least for "for-update"-cursors. If the cursor was not
declared "for update", then it is not even cleaer to me what the
correct behaviour would be. Imagine that you declared a cursor, and fetched
a row. After fetching, but before you call "update table foo where current of
mycursor" someone updates the row (and commits), and the new version would have
never been returned by your select statement in the first place. Should that row be
updates, or not? What if the other transaction deleted the row - should your
update raise an error? fail silently?

Because of those problems, I'll always assume that the cursor was declared
"for update" from now on.

After reading backend code for the last hours, I've created the following plan for
implementing "where current of"

1) Allow "declare ... cursor .... for update of <field1>, <field2>, <table1>, ...".
    Since all locking is done on row, not on particular columns, specifying
    <field1> is really equivalent to specifying the table that this field came from.
2) For each table in "for update of ..." remember the ctid of the returned tuple when
    doing fetch.

Now, there are two possibilities
A) Implement a "<table-alias> current of <cursor>" predicate for usage in where clauses.
    It would get the last ctid from the cursor (for the table aliased by <table-alias),
    follow ctid-chain to get the newest version, and compare this ctid to the one found
    in <table-alias>.
    "update <table> where current of <cursor>" would then be an abbreviation for
    "update <table> where <table> current of <cursor>", and e.g.
    "update <table> where <table> current of <cursor> and data like '%whatever%'"
    would be allowed to.
B) Implement "update <table> where current of <cursor>" as a special case. The plan
    generated would be similar to the one generated by "update <table> where ctid = ...",
    but the ctid stored would only be used to find an initial tuple version, and ignored
    when rechecking if a newer version still matches.

A) sound like a little bit more work, but it would avoid special-casing "where current of"
somewhere in either the planner or the executor. I've googled around a bit, and it
seems as if at least oracle and db2 only support "where current of <cursor>", and
not a general "<table> current of <cursor>" predicate.

Since I'm new to postgres-backend-hacking, this has no chance to be ready until feature
freeze, so it's 8.3 material at best, I guess ;-)
Still, I'd be thankfull for any comments, especially the "This can't work because ..."
type of comments ;-)

greetings, Florian Pflug

pgsql-general by date:

Previous
From: Francisco Reyes
Date:
Subject: Re: Corrupted DB? could not open file pg_clog/####
Next
From: Ron Johnson
Date:
Subject: Practical maximums (was Re: PostgreSQL theoretical maximums.)