* MakeTransitionCaptureState * * Make a TransitionCaptureState object for the given TriggerDesc, target * relation, and operation type. The TCS object holds all the state needed * to decide whether to capture tuples in transition tables. * * If there are no triggers in 'trigdesc' that request relevant transition * tables, then return NULL. * * The resulting object can be passed to the Ex
| 4623 | * the TransitionCaptureState objects we hand out to callers. |
| 4624 | */ |
| 4625 | TransitionCaptureState * |
| 4626 | MakeTransitionCaptureState(TriggerDesc *trigdesc, Oid relid, CmdType cmdType) |
| 4627 | { |
| 4628 | TransitionCaptureState *state; |
| 4629 | bool need_old, |
| 4630 | need_new; |
| 4631 | AfterTriggersTableData *table; |
| 4632 | MemoryContext oldcxt; |
| 4633 | ResourceOwner saveResourceOwner; |
| 4634 | |
| 4635 | if (trigdesc == NULL) |
| 4636 | return NULL; |
| 4637 | |
| 4638 | /* Detect which table(s) we need. */ |
| 4639 | switch (cmdType) |
| 4640 | { |
| 4641 | case CMD_INSERT: |
| 4642 | need_old = false; |
| 4643 | need_new = trigdesc->trig_insert_new_table; |
| 4644 | break; |
| 4645 | case CMD_UPDATE: |
| 4646 | need_old = trigdesc->trig_update_old_table; |
| 4647 | need_new = trigdesc->trig_update_new_table; |
| 4648 | break; |
| 4649 | case CMD_DELETE: |
| 4650 | need_old = trigdesc->trig_delete_old_table; |
| 4651 | need_new = false; |
| 4652 | break; |
| 4653 | default: |
| 4654 | elog(ERROR, "unexpected CmdType: %d", (int) cmdType); |
| 4655 | need_old = need_new = false; /* keep compiler quiet */ |
| 4656 | break; |
| 4657 | } |
| 4658 | if (!need_old && !need_new) |
| 4659 | return NULL; |
| 4660 | |
| 4661 | /* Check state, like AfterTriggerSaveEvent. */ |
| 4662 | if (afterTriggers.query_depth < 0) |
| 4663 | elog(ERROR, "MakeTransitionCaptureState() called outside of query"); |
| 4664 | |
| 4665 | /* Be sure we have enough space to record events at this query depth. */ |
| 4666 | if (afterTriggers.query_depth >= afterTriggers.maxquerydepth) |
| 4667 | AfterTriggerEnlargeQueryState(); |
| 4668 | |
| 4669 | /* |
| 4670 | * Find or create an AfterTriggersTableData struct to hold the |
| 4671 | * tuplestore(s). If there's a matching struct but it's marked closed, |
| 4672 | * ignore it; we need a newer one. |
| 4673 | * |
| 4674 | * Note: the AfterTriggersTableData list, as well as the tuplestores, are |
| 4675 | * allocated in the current (sub)transaction's CurTransactionContext, and |
| 4676 | * the tuplestores are managed by the (sub)transaction's resource owner. |
| 4677 | * This is sufficient lifespan because we do not allow triggers using |
| 4678 | * transition tables to be deferrable; they will be fired during |
| 4679 | * AfterTriggerEndQuery, after which it's okay to delete the data. |
| 4680 | */ |
| 4681 | table = GetAfterTriggersTableData(relid, cmdType); |
| 4682 |
no test coverage detected