* postgresPlanForeignModify * Plan an insert/update/delete operation on a foreign table */
| 1762 | * Plan an insert/update/delete operation on a foreign table |
| 1763 | */ |
| 1764 | static List * |
| 1765 | postgresPlanForeignModify(PlannerInfo *root, |
| 1766 | ModifyTable *plan, |
| 1767 | Index resultRelation, |
| 1768 | int subplan_index) |
| 1769 | { |
| 1770 | CmdType operation = plan->operation; |
| 1771 | RangeTblEntry *rte = planner_rt_fetch(resultRelation, root); |
| 1772 | Relation rel; |
| 1773 | StringInfoData sql; |
| 1774 | List *targetAttrs = NIL; |
| 1775 | List *withCheckOptionList = NIL; |
| 1776 | List *returningList = NIL; |
| 1777 | List *retrieved_attrs = NIL; |
| 1778 | bool doNothing = false; |
| 1779 | int values_end_len = -1; |
| 1780 | |
| 1781 | initStringInfo(&sql); |
| 1782 | |
| 1783 | /* |
| 1784 | * Core code already has some lock on each rel being planned, so we can |
| 1785 | * use NoLock here. |
| 1786 | */ |
| 1787 | rel = table_open(rte->relid, NoLock); |
| 1788 | |
| 1789 | /* |
| 1790 | * In an INSERT, we transmit all columns that are defined in the foreign |
| 1791 | * table. In an UPDATE, if there are BEFORE ROW UPDATE triggers on the |
| 1792 | * foreign table, we transmit all columns like INSERT; else we transmit |
| 1793 | * only columns that were explicitly targets of the UPDATE, so as to avoid |
| 1794 | * unnecessary data transmission. (We can't do that for INSERT since we |
| 1795 | * would miss sending default values for columns not listed in the source |
| 1796 | * statement, and for UPDATE if there are BEFORE ROW UPDATE triggers since |
| 1797 | * those triggers might change values for non-target columns, in which |
| 1798 | * case we would miss sending changed values for those columns.) |
| 1799 | */ |
| 1800 | if (operation == CMD_INSERT || |
| 1801 | (operation == CMD_UPDATE && |
| 1802 | rel->trigdesc && |
| 1803 | rel->trigdesc->trig_update_before_row)) |
| 1804 | { |
| 1805 | TupleDesc tupdesc = RelationGetDescr(rel); |
| 1806 | int attnum; |
| 1807 | |
| 1808 | for (attnum = 1; attnum <= tupdesc->natts; attnum++) |
| 1809 | { |
| 1810 | Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum - 1); |
| 1811 | |
| 1812 | if (!attr->attisdropped) |
| 1813 | targetAttrs = lappend_int(targetAttrs, attnum); |
| 1814 | } |
| 1815 | } |
| 1816 | else if (operation == CMD_UPDATE) |
| 1817 | { |
| 1818 | int col; |
| 1819 | Bitmapset *allUpdatedCols = bms_union(rte->updatedCols, rte->extraUpdatedCols); |
| 1820 | |
| 1821 | col = -1; |
nothing calls this directly
no test coverage detected