Re: Damn bug!
От | Tom Lane |
---|---|
Тема | Re: Damn bug! |
Дата | |
Msg-id | 5696.964160339@sss.pgh.pa.us обсуждение исходный текст |
Ответ на | Re: Damn bug! (Tom Lane <tgl@sss.pgh.pa.us>) |
Список | 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 по дате отправления: