You can not insert a child record if the parent record is locked, even if the foreign key target field is unchanged.
For example, using the Employee database and two instances of iSQL.
update employee set salary=salary+10 where emp_no=4;
[do not commit yet]
insert into employee_project (emp_no, proj_id) values (4, 'GUIDE');
In the first transaction, we do not modify the emp_no, so there is no reason why the second transaction should not be allowed to insert the record into employee_project. This behaviour can cause unnecessary bottlenecks.
Firebird is unable to identify which of the fields were changed, so pessimistically assumes that the emp_no may have changed. If you are in a WAIT transaction, it will succeed once the first transaction commits. If you are in a NOWAIT transaction, you will receive a lock conflict immediately.
Ideally, Firebird should only block the insert on the child if the foreign key target was involved in the update. I am also open to other possible solutions. For example, we could declare for Firebird whether a particular key field was a surrogate key. If so, Firebird could disallow updates for such fields and therefore would not need to check whether the field was locked or not.
If you need more information or further test cases, please let me know.