* ExecGetTriggerResultRel * Get a ResultRelInfo for a trigger target relation. * * Most of the time, triggers are fired on one of the result relations of the * query, and so we can just return a member of the es_result_relations array, * or the es_tuple_routing_result_relations list (if any). (Note: in self-join * situations there might be multiple members with the same OID; if so it * doe
| 2465 | * in es_trig_target_relations. |
| 2466 | */ |
| 2467 | ResultRelInfo * |
| 2468 | ExecGetTriggerResultRel(EState *estate, Oid relid) |
| 2469 | { |
| 2470 | ResultRelInfo *rInfo; |
| 2471 | ListCell *l; |
| 2472 | Relation rel; |
| 2473 | MemoryContext oldcontext; |
| 2474 | |
| 2475 | /* Search through the query result relations */ |
| 2476 | foreach(l, estate->es_opened_result_relations) |
| 2477 | { |
| 2478 | rInfo = lfirst(l); |
| 2479 | if (RelationGetRelid(rInfo->ri_RelationDesc) == relid) |
| 2480 | return rInfo; |
| 2481 | } |
| 2482 | |
| 2483 | /* |
| 2484 | * Search through the result relations that were created during tuple |
| 2485 | * routing, if any. |
| 2486 | */ |
| 2487 | foreach(l, estate->es_tuple_routing_result_relations) |
| 2488 | { |
| 2489 | rInfo = (ResultRelInfo *) lfirst(l); |
| 2490 | if (RelationGetRelid(rInfo->ri_RelationDesc) == relid) |
| 2491 | return rInfo; |
| 2492 | } |
| 2493 | |
| 2494 | /* Nope, but maybe we already made an extra ResultRelInfo for it */ |
| 2495 | foreach(l, estate->es_trig_target_relations) |
| 2496 | { |
| 2497 | rInfo = (ResultRelInfo *) lfirst(l); |
| 2498 | if (RelationGetRelid(rInfo->ri_RelationDesc) == relid) |
| 2499 | return rInfo; |
| 2500 | } |
| 2501 | /* Nope, so we need a new one */ |
| 2502 | |
| 2503 | /* |
| 2504 | * Open the target relation's relcache entry. We assume that an |
| 2505 | * appropriate lock is still held by the backend from whenever the trigger |
| 2506 | * event got queued, so we need take no new lock here. Also, we need not |
| 2507 | * recheck the relkind, so no need for CheckValidResultRel. |
| 2508 | */ |
| 2509 | rel = table_open(relid, NoLock); |
| 2510 | |
| 2511 | /* |
| 2512 | * Make the new entry in the right context. |
| 2513 | */ |
| 2514 | oldcontext = MemoryContextSwitchTo(estate->es_query_cxt); |
| 2515 | rInfo = makeNode(ResultRelInfo); |
| 2516 | InitResultRelInfo(rInfo, |
| 2517 | rel, |
| 2518 | 0, /* dummy rangetable index */ |
| 2519 | NULL, |
| 2520 | estate->es_instrument); |
| 2521 | estate->es_trig_target_relations = |
| 2522 | lappend(estate->es_trig_target_relations, rInfo); |
| 2523 | MemoryContextSwitchTo(oldcontext); |
| 2524 |
no test coverage detected