* postgresBeginDirectModify * Prepare a direct foreign table modification */
| 2632 | * Prepare a direct foreign table modification |
| 2633 | */ |
| 2634 | static void |
| 2635 | postgresBeginDirectModify(ForeignScanState *node, int eflags) |
| 2636 | { |
| 2637 | ForeignScan *fsplan = (ForeignScan *) node->ss.ps.plan; |
| 2638 | EState *estate = node->ss.ps.state; |
| 2639 | PgFdwDirectModifyState *dmstate; |
| 2640 | Index rtindex; |
| 2641 | RangeTblEntry *rte; |
| 2642 | Oid userid; |
| 2643 | ForeignTable *table; |
| 2644 | UserMapping *user; |
| 2645 | int numParams; |
| 2646 | |
| 2647 | /* |
| 2648 | * Do nothing in EXPLAIN (no ANALYZE) case. node->fdw_state stays NULL. |
| 2649 | */ |
| 2650 | if (eflags & EXEC_FLAG_EXPLAIN_ONLY) |
| 2651 | return; |
| 2652 | |
| 2653 | /* |
| 2654 | * We'll save private state in node->fdw_state. |
| 2655 | */ |
| 2656 | dmstate = (PgFdwDirectModifyState *) palloc0(sizeof(PgFdwDirectModifyState)); |
| 2657 | node->fdw_state = (void *) dmstate; |
| 2658 | |
| 2659 | /* |
| 2660 | * Identify which user to do the remote access as. This should match what |
| 2661 | * ExecCheckRTEPerms() does. |
| 2662 | */ |
| 2663 | rtindex = node->resultRelInfo->ri_RangeTableIndex; |
| 2664 | rte = exec_rt_fetch(rtindex, estate); |
| 2665 | userid = rte->checkAsUser ? rte->checkAsUser : GetUserId(); |
| 2666 | |
| 2667 | /* Get info about foreign table. */ |
| 2668 | if (fsplan->scan.scanrelid == 0) |
| 2669 | dmstate->rel = ExecOpenScanRelation(estate, rtindex, eflags); |
| 2670 | else |
| 2671 | dmstate->rel = node->ss.ss_currentRelation; |
| 2672 | table = GetForeignTable(RelationGetRelid(dmstate->rel)); |
| 2673 | user = GetUserMapping(userid, table->serverid); |
| 2674 | |
| 2675 | /* |
| 2676 | * Get connection to the foreign server. Connection manager will |
| 2677 | * establish new connection if necessary. |
| 2678 | */ |
| 2679 | dmstate->conn = GetConnection(user, false, &dmstate->conn_state); |
| 2680 | |
| 2681 | /* Update the foreign-join-related fields. */ |
| 2682 | if (fsplan->scan.scanrelid == 0) |
| 2683 | { |
| 2684 | /* Save info about foreign table. */ |
| 2685 | dmstate->resultRel = dmstate->rel; |
| 2686 | |
| 2687 | /* |
| 2688 | * Set dmstate->rel to NULL to teach get_returning_data() and |
| 2689 | * make_tuple_from_result_row() that columns fetched from the remote |
| 2690 | * server are described by fdw_scan_tlist of the foreign-scan plan |
| 2691 | * node, not the tuple descriptor for the target relation. |
nothing calls this directly
no test coverage detected