Check out a prospective update to a relation. If it fails security check, bounce it. If it's a view update, make sure the view is updatable, and return the view source for redirection. If it's a simple relation, return NULL.
| 10823 | // If it's a view update, make sure the view is updatable, and return the view source for redirection. |
| 10824 | // If it's a simple relation, return NULL. |
| 10825 | static RelationSourceNode* pass1Update(thread_db* tdbb, CompilerScratch* csb, jrd_rel* relation, |
| 10826 | const TrigVector* trigger, StreamType stream, StreamType updateStream, SecurityClass::flags_t priv, |
| 10827 | jrd_rel* view, StreamType viewStream, StreamType viewUpdateStream) |
| 10828 | { |
| 10829 | SET_TDBB(tdbb); |
| 10830 | |
| 10831 | DEV_BLKCHK(csb, type_csb); |
| 10832 | DEV_BLKCHK(relation, type_rel); |
| 10833 | DEV_BLKCHK(view, type_rel); |
| 10834 | |
| 10835 | // unless this is an internal request, check access permission |
| 10836 | |
| 10837 | CMP_post_access(tdbb, csb, relation->rel_security_name, (view ? view->rel_id : 0), |
| 10838 | priv, obj_relations, relation->rel_name); |
| 10839 | |
| 10840 | // ensure that the view is set for the input streams, |
| 10841 | // so that access to views can be checked at the field level |
| 10842 | |
| 10843 | fb_assert(viewStream <= MAX_STREAMS); |
| 10844 | CMP_csb_element(csb, stream)->csb_view = view; |
| 10845 | CMP_csb_element(csb, stream)->csb_view_stream = viewStream; |
| 10846 | |
| 10847 | if (stream != updateStream) |
| 10848 | { |
| 10849 | fb_assert(viewUpdateStream <= MAX_STREAMS); |
| 10850 | CMP_csb_element(csb, updateStream)->csb_view = view; |
| 10851 | CMP_csb_element(csb, updateStream)->csb_view_stream = viewUpdateStream; |
| 10852 | } |
| 10853 | |
| 10854 | // if we're not a view, everything's cool |
| 10855 | |
| 10856 | RseNode* rse = relation->rel_view_rse; |
| 10857 | if (!rse) |
| 10858 | return NULL; |
| 10859 | |
| 10860 | // a view with triggers is always updatable |
| 10861 | |
| 10862 | if (trigger) |
| 10863 | { |
| 10864 | bool userTriggers = false; |
| 10865 | |
| 10866 | for (FB_SIZE_T i = 0; i < trigger->getCount(); i++) |
| 10867 | { |
| 10868 | if (!(*trigger)[i].sysTrigger) |
| 10869 | { |
| 10870 | userTriggers = true; |
| 10871 | break; |
| 10872 | } |
| 10873 | } |
| 10874 | |
| 10875 | if (userTriggers) |
| 10876 | { |
| 10877 | csb->csb_rpt[updateStream].csb_flags |= csb_view_update; |
| 10878 | return NULL; |
| 10879 | } |
| 10880 | } |
| 10881 | |
| 10882 | // we've got a view without triggers, let's check whether it's updateable |
no test coverage detected