| 6606 | |
| 6607 | |
| 6608 | static void refresh_changed_fields(thread_db* tdbb, Record* old_rec, record_param* cur_rpb, |
| 6609 | record_param* new_rpb) |
| 6610 | { |
| 6611 | /************************************** |
| 6612 | * |
| 6613 | * r e f r e s h _ c h a n g e d _ f i e l d s |
| 6614 | * |
| 6615 | ************************************** |
| 6616 | * |
| 6617 | * Functional description |
| 6618 | * Update new_rpb with foreign key fields values changed by cascade triggers. |
| 6619 | * Consider self-referenced foreign keys only. |
| 6620 | * Also, if AllowUpdateOverwrite is set to false, raise error when non |
| 6621 | * self-referenced foreign key fields were changed by user triggers. |
| 6622 | * |
| 6623 | * old_rec - old record before modify |
| 6624 | * cur_rpb - just read record with possibly changed fields |
| 6625 | * new_rpb - new record evaluated by modify statement and before-triggers |
| 6626 | * |
| 6627 | **************************************/ |
| 6628 | const Database* dbb = tdbb->getDatabase(); |
| 6629 | const auto allowOverwrite = dbb->dbb_config->getAllowUpdateOverwrite(); |
| 6630 | |
| 6631 | jrd_rel* relation = cur_rpb->rpb_relation; |
| 6632 | |
| 6633 | MET_scan_partners(tdbb, relation); |
| 6634 | |
| 6635 | const FB_SIZE_T frgnCount = relation->rel_foreign_refs.frgn_relations ? |
| 6636 | relation->rel_foreign_refs.frgn_relations->count() : 0; |
| 6637 | |
| 6638 | RelationPages* relPages = cur_rpb->rpb_relation->getPages(tdbb); |
| 6639 | |
| 6640 | // Collect all fields of self-referenced foreign keys |
| 6641 | SortedArray<int, InlineStorage<int, 16> > fields; |
| 6642 | |
| 6643 | for (FB_SIZE_T i = 0; i < frgnCount; i++) |
| 6644 | { |
| 6645 | if ((*relation->rel_foreign_refs.frgn_relations)[i] == relation->rel_id) |
| 6646 | { |
| 6647 | index_desc idx; |
| 6648 | idx.idx_id = idx_invalid; |
| 6649 | |
| 6650 | if (BTR_lookup(tdbb, relation, (*relation->rel_foreign_refs.frgn_reference_ids)[i], |
| 6651 | &idx, relPages)) |
| 6652 | { |
| 6653 | fb_assert(idx.idx_flags & idx_foreign); |
| 6654 | |
| 6655 | for (int fld = 0; fld < idx.idx_count; fld++) |
| 6656 | { |
| 6657 | const int fldNum = idx.idx_rpt[fld].idx_field; |
| 6658 | if (!fields.exist(fldNum)) |
| 6659 | fields.add(fldNum); |
| 6660 | } |
| 6661 | } |
| 6662 | } |
| 6663 | } |
| 6664 | |
| 6665 | if (fields.isEmpty()) |
no test coverage detected