Subject Re: [firebird-support] Inconsistent database updates
Author masotti
Hi Alec,

On 28/10/2010 18:34, Alec Swan wrote:
> Create table MY_TAB ( id bigint, sibling_id bigint, age bigint );
>
> INSERT INTO MY_TAB (ID, SIBLING_ID, AGE) VALUES (1,2,10);
> INSERT INTO MY_TAB (ID, SIBLING_ID, AGE) VALUES (2,1,20);
>
> update MY_TAB set age = (select t.age from MY_TAB t where t.id =
> MY_TAB.sibling_id);

updates are applied for every fetch of records from inner subselect.
For my understanding of engine, you update statement is executed in this
manner:
for select id from MY_TAB into :w_id do begin
select age from MY_TAB where sibling_id = :w_id into w_age;
update MY_TAB set age = :w_age where id = :w_id;
end

You can check rapidly with three or more siblings, with
INSERT INTO MY_TAB (ID, SIBLING_ID, AGE) VALUES (1,2,10);
INSERT INTO MY_TAB (ID, SIBLING_ID, AGE) VALUES (2,3,20);
INSERT INTO MY_TAB (ID, SIBLING_ID, AGE) VALUES (3,4,30);
INSERT INTO MY_TAB (ID, SIBLING_ID, AGE) VALUES (4,5,40);
INSERT INTO MY_TAB (ID, SIBLING_ID, AGE) VALUES (5,6,50);
INSERT INTO MY_TAB (ID, SIBLING_ID, AGE) VALUES (6,1,60);
select * from MY_TAB;

/*
ID SIBLING_ID AGE
===================== ===================== =====================
1 2 10
2 3 20
3 4 30
4 5 40
5 6 50
6 1 60
****/
update MY_TAB set age = (select t.age from MY_TAB t where t.id =
MY_TAB.sibling_id);
commit;
select * from MY_TAB;

/*
ID SIBLING_ID AGE
===================== ===================== =====================
1 2 20
2 3 30
3 4 40
4 5 50
5 6 60
6 1 20

***/

Call it a feature. AFAIR standard doesn't defines as this type of
updates are to be implemented.

Ciao.
Mimmo.