Re: Damn bug! - Mailing list pgsql-bugs

From Tom Lane
Subject Re: Damn bug!
Date
Msg-id 5696.964160339@sss.pgh.pa.us
Whole thread Raw
In response to Re: Damn bug!  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-bugs
I wrote:
> I think what we're seeing here is evidence that it really doesn't work.
> Possibly there's some hack in array_set that overwrites the source
> data (which it shouldn't be doing, in any case!) when the data length
> doesn't need to change.  Needs more digging to understand in detail...

Indeed, it looks like that's exactly what's happening.  Try this on
for size:

regression=# select * from t1;
       a
----------------
 {"foo1","bar"}
(1 row)

regression=# begin;
BEGIN
regression=# update t1 set a[1] = 'foot';
UPDATE 1
regression=# abort;
ROLLBACK
regression=# select * from t1;
       a
----------------
 {"foot","bar"}
(1 row)

<Dana Carvey> My, isn't *that* special ... </Dana Carvey>

Evidently, array_set scribbles on its source object when the size
of the object isn't changed by the element assignment.  This is why
it's possible for more than one element assignment to appear to work;
when the later assignments are executed with the same old source
datum, they see the other fields as updated.  Too bad scribbling on
disk buffers is verboten.

I have to hack on the array support soon for TOAST anyway, and I'll
make sure that this idiocy goes away then.  That will mean that
in fact you don't get more than one array update per UPDATE.  Don't
see any easy way around that, unless we want to hack on the parser
to convert

    UPDATE table SET a[1] = foo, a[2] = bar

into

    UPDATE table SET a = array_set(array_set(a, 1, foo), 2, bar)

That might not be totally impractical but it looks ugly... Thomas,
what do you think about it?

            regards, tom lane

pgsql-bugs by date:

Previous
From: Tom Lane
Date:
Subject: Re: Damn bug!
Next
From: Ange Michel POZZO
Date:
Subject: problem with view and case - please help