* Execute a direct UPDATE/DELETE statement. */
| 4548 | * Execute a direct UPDATE/DELETE statement. |
| 4549 | */ |
| 4550 | static void |
| 4551 | execute_dml_stmt(ForeignScanState *node) |
| 4552 | { |
| 4553 | PgFdwDirectModifyState *dmstate = (PgFdwDirectModifyState *) node->fdw_state; |
| 4554 | ExprContext *econtext = node->ss.ps.ps_ExprContext; |
| 4555 | int numParams = dmstate->numParams; |
| 4556 | const char **values = dmstate->param_values; |
| 4557 | |
| 4558 | /* First, process a pending asynchronous request, if any. */ |
| 4559 | if (dmstate->conn_state->pendingAreq) |
| 4560 | process_pending_request(dmstate->conn_state->pendingAreq); |
| 4561 | |
| 4562 | /* |
| 4563 | * Construct array of query parameter values in text format. |
| 4564 | */ |
| 4565 | if (numParams > 0) |
| 4566 | process_query_params(econtext, |
| 4567 | dmstate->param_flinfo, |
| 4568 | dmstate->param_exprs, |
| 4569 | values); |
| 4570 | |
| 4571 | /* |
| 4572 | * Notice that we pass NULL for paramTypes, thus forcing the remote server |
| 4573 | * to infer types for all parameters. Since we explicitly cast every |
| 4574 | * parameter (see deparse.c), the "inference" is trivial and will produce |
| 4575 | * the desired result. This allows us to avoid assuming that the remote |
| 4576 | * server has the same OIDs we do for the parameters' types. |
| 4577 | */ |
| 4578 | if (!PQsendQueryParams(dmstate->conn, dmstate->query, numParams, |
| 4579 | NULL, values, NULL, NULL, 0)) |
| 4580 | pgfdw_report_error(ERROR, NULL, dmstate->conn, false, dmstate->query); |
| 4581 | |
| 4582 | /* |
| 4583 | * Get the result, and check for success. |
| 4584 | * |
| 4585 | * We don't use a PG_TRY block here, so be careful not to throw error |
| 4586 | * without releasing the PGresult. |
| 4587 | */ |
| 4588 | dmstate->result = pgfdw_get_result(dmstate->conn, dmstate->query); |
| 4589 | if (PQresultStatus(dmstate->result) != |
| 4590 | (dmstate->has_returning ? PGRES_TUPLES_OK : PGRES_COMMAND_OK)) |
| 4591 | pgfdw_report_error(ERROR, dmstate->result, dmstate->conn, true, |
| 4592 | dmstate->query); |
| 4593 | |
| 4594 | /* Get the number of rows affected. */ |
| 4595 | if (dmstate->has_returning) |
| 4596 | dmstate->num_tuples = PQntuples(dmstate->result); |
| 4597 | else |
| 4598 | dmstate->num_tuples = atoi(PQcmdTuples(dmstate->result)); |
| 4599 | } |
| 4600 | |
| 4601 | /* |
| 4602 | * Get the result of a RETURNING clause. |
no test coverage detected