* execute_foreign_modify * Perform foreign-table modification as required, and fetch RETURNING * result if any. (This is the shared guts of postgresExecForeignInsert, * postgresExecForeignBatchInsert, postgresExecForeignUpdate, and * postgresExecForeignDelete.) */
| 4086 | * postgresExecForeignDelete.) |
| 4087 | */ |
| 4088 | static TupleTableSlot ** |
| 4089 | execute_foreign_modify(EState *estate, |
| 4090 | ResultRelInfo *resultRelInfo, |
| 4091 | CmdType operation, |
| 4092 | TupleTableSlot **slots, |
| 4093 | TupleTableSlot **planSlots, |
| 4094 | int *numSlots) |
| 4095 | { |
| 4096 | PgFdwModifyState *fmstate = (PgFdwModifyState *) resultRelInfo->ri_FdwState; |
| 4097 | ItemPointer ctid = NULL; |
| 4098 | const char **p_values; |
| 4099 | PGresult *res; |
| 4100 | int n_rows; |
| 4101 | StringInfoData sql; |
| 4102 | |
| 4103 | /* The operation should be INSERT, UPDATE, or DELETE */ |
| 4104 | Assert(operation == CMD_INSERT || |
| 4105 | operation == CMD_UPDATE || |
| 4106 | operation == CMD_DELETE); |
| 4107 | |
| 4108 | /* First, process a pending asynchronous request, if any. */ |
| 4109 | if (fmstate->conn_state->pendingAreq) |
| 4110 | process_pending_request(fmstate->conn_state->pendingAreq); |
| 4111 | |
| 4112 | /* |
| 4113 | * If the existing query was deparsed and prepared for a different number |
| 4114 | * of rows, rebuild it for the proper number. |
| 4115 | */ |
| 4116 | if (operation == CMD_INSERT && fmstate->num_slots != *numSlots) |
| 4117 | { |
| 4118 | /* Destroy the prepared statement created previously */ |
| 4119 | if (fmstate->p_name) |
| 4120 | deallocate_query(fmstate); |
| 4121 | |
| 4122 | /* Build INSERT string with numSlots records in its VALUES clause. */ |
| 4123 | initStringInfo(&sql); |
| 4124 | rebuildInsertSql(&sql, fmstate->rel, |
| 4125 | fmstate->orig_query, fmstate->target_attrs, |
| 4126 | fmstate->values_end, fmstate->p_nums, |
| 4127 | *numSlots - 1); |
| 4128 | pfree(fmstate->query); |
| 4129 | fmstate->query = sql.data; |
| 4130 | fmstate->num_slots = *numSlots; |
| 4131 | } |
| 4132 | |
| 4133 | /* Set up the prepared statement on the remote server, if we didn't yet */ |
| 4134 | if (!fmstate->p_name) |
| 4135 | prepare_foreign_modify(fmstate); |
| 4136 | |
| 4137 | /* |
| 4138 | * For UPDATE/DELETE, get the ctid that was passed up as a resjunk column |
| 4139 | */ |
| 4140 | if (operation == CMD_UPDATE || operation == CMD_DELETE) |
| 4141 | { |
| 4142 | Datum datum; |
| 4143 | bool isNull; |
| 4144 | |
| 4145 | datum = ExecGetJunkAttribute(planSlots[0], |
no test coverage detected