Process a source for a modify statement. This can get a little tricky if the relation is a view.
| 6845 | |
| 6846 | // Process a source for a modify statement. This can get a little tricky if the relation is a view. |
| 6847 | void ModifyNode::pass1Modify(thread_db* tdbb, CompilerScratch* csb, ModifyNode* node) |
| 6848 | { |
| 6849 | // If updateable views with triggers are involved, there maybe a recursive call to be ignored. |
| 6850 | |
| 6851 | if (node->subMod) |
| 6852 | return; |
| 6853 | |
| 6854 | jrd_rel* parent = NULL; |
| 6855 | jrd_rel* view = NULL; |
| 6856 | StreamType parentStream, parentNewStream; |
| 6857 | |
| 6858 | // To support nested views, loop until we hit a table or a view with user-defined triggers |
| 6859 | // (which means no update). |
| 6860 | |
| 6861 | for (;;) |
| 6862 | { |
| 6863 | StreamType stream = node->orgStream; |
| 6864 | StreamType newStream = node->newStream; |
| 6865 | |
| 6866 | CompilerScratch::csb_repeat* const tail = &csb->csb_rpt[stream]; |
| 6867 | CompilerScratch::csb_repeat* const new_tail = &csb->csb_rpt[newStream]; |
| 6868 | new_tail->csb_flags |= csb_modify; |
| 6869 | |
| 6870 | jrd_rel* const relation = tail->csb_relation; |
| 6871 | |
| 6872 | //// TODO: LocalTableSourceNode |
| 6873 | if (!relation) |
| 6874 | { |
| 6875 | ERR_post( |
| 6876 | Arg::Gds(isc_wish_list) << |
| 6877 | Arg::Gds(isc_random) << "modify local_table"); |
| 6878 | } |
| 6879 | |
| 6880 | view = relation->rel_view_rse ? relation : view; |
| 6881 | |
| 6882 | if (!parent) |
| 6883 | { |
| 6884 | fb_assert(tail->csb_view == new_tail->csb_view); |
| 6885 | parent = new_tail->csb_view; |
| 6886 | parentStream = tail->csb_view_stream; |
| 6887 | parentNewStream = new_tail->csb_view_stream; |
| 6888 | } |
| 6889 | |
| 6890 | postTriggerAccess(csb, relation, ExternalAccess::exa_update, view); |
| 6891 | |
| 6892 | // Check out update. If this is an update thru a view, verify the view by checking for read |
| 6893 | // access on the base table. If field-level select privileges are implemented, this needs |
| 6894 | // to be enhanced. |
| 6895 | |
| 6896 | SecurityClass::flags_t priv = SCL_update; |
| 6897 | |
| 6898 | if (parent) |
| 6899 | priv |= SCL_select; |
| 6900 | |
| 6901 | RefPtr<TrigVector> trigger(relation->rel_pre_modify ? |
| 6902 | relation->rel_pre_modify : relation->rel_post_modify); |
| 6903 | |
| 6904 | // If we have a view with triggers, let's expand it. |
nothing calls this directly
no test coverage detected