* afterTriggerMarkEvents() * * Scan the given event list for not yet invoked events. Mark the ones * that can be invoked now with the current firing ID. * * If move_list isn't NULL, events that are not to be invoked now are * transferred to move_list. * * When immediate_only is true, do not invoke currently-deferred triggers. * (This will be false only at main transaction exit.) * * Re
| 4197 | * Returns true if any invokable events were found. |
| 4198 | */ |
| 4199 | static bool |
| 4200 | afterTriggerMarkEvents(AfterTriggerEventList *events, |
| 4201 | AfterTriggerEventList *move_list, |
| 4202 | bool immediate_only) |
| 4203 | { |
| 4204 | bool found = false; |
| 4205 | bool deferred_found = false; |
| 4206 | AfterTriggerEvent event; |
| 4207 | AfterTriggerEventChunk *chunk; |
| 4208 | |
| 4209 | for_each_event_chunk(event, chunk, *events) |
| 4210 | { |
| 4211 | AfterTriggerShared evtshared = GetTriggerSharedData(event); |
| 4212 | bool defer_it = false; |
| 4213 | |
| 4214 | if (!(event->ate_flags & |
| 4215 | (AFTER_TRIGGER_DONE | AFTER_TRIGGER_IN_PROGRESS))) |
| 4216 | { |
| 4217 | /* |
| 4218 | * This trigger hasn't been called or scheduled yet. Check if we |
| 4219 | * should call it now. |
| 4220 | */ |
| 4221 | if (immediate_only && afterTriggerCheckState(evtshared)) |
| 4222 | { |
| 4223 | defer_it = true; |
| 4224 | } |
| 4225 | else |
| 4226 | { |
| 4227 | /* |
| 4228 | * Mark it as to be fired in this firing cycle. |
| 4229 | */ |
| 4230 | evtshared->ats_firing_id = afterTriggers.firing_counter; |
| 4231 | event->ate_flags |= AFTER_TRIGGER_IN_PROGRESS; |
| 4232 | found = true; |
| 4233 | } |
| 4234 | } |
| 4235 | |
| 4236 | /* |
| 4237 | * If it's deferred, move it to move_list, if requested. |
| 4238 | */ |
| 4239 | if (defer_it && move_list != NULL) |
| 4240 | { |
| 4241 | deferred_found = true; |
| 4242 | /* add it to move_list */ |
| 4243 | afterTriggerAddEvent(move_list, event, evtshared); |
| 4244 | /* mark original copy "done" so we don't do it again */ |
| 4245 | event->ate_flags |= AFTER_TRIGGER_DONE; |
| 4246 | } |
| 4247 | } |
| 4248 | |
| 4249 | /* |
| 4250 | * We could allow deferred triggers if, before the end of the |
| 4251 | * security-restricted operation, we were to verify that a SET CONSTRAINTS |
| 4252 | * ... IMMEDIATE has fired all such triggers. For now, don't bother. |
| 4253 | */ |
| 4254 | if (deferred_found && InSecurityRestrictedOperation()) |
| 4255 | ereport(ERROR, |
| 4256 | (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), |
no test coverage detected