diff options
-rw-r--r-- | contrib/postgresql_fdw/postgresql_fdw.c | 56 |
1 files changed, 44 insertions, 12 deletions
diff --git a/contrib/postgresql_fdw/postgresql_fdw.c b/contrib/postgresql_fdw/postgresql_fdw.c index 39bd1be49f..3f030b91ac 100644 --- a/contrib/postgresql_fdw/postgresql_fdw.c +++ b/contrib/postgresql_fdw/postgresql_fdw.c @@ -503,11 +503,11 @@ pgBeginForeignScan(ForeignScanState *node, int eflags) FdwPlan *fdwplan; const char *sql; PGconn *conn; - PGresult *res; ParamListInfo params = node->ss.ps.state->es_param_list_info; int numParams = params ? params->numParams : 0; Oid *types = NULL; const char **values = NULL; + int ret; elog(DEBUG3, "%s() called", __FUNCTION__); @@ -562,34 +562,32 @@ pgBeginForeignScan(ForeignScanState *node, int eflags) */ fdwplan = ((ForeignScan *) node->ss.ps.plan)->fdwplan; sql = strVal(list_nth(fdwplan->fdw_private, 0)); - res = PQexecParams(conn, sql, numParams, types, values, NULL, NULL, 0); + ret = PQsendQueryParams(conn, sql, numParams, types, values, NULL, NULL, 0); + + /* Free parameters */ if (numParams > 0) { - int i; + int i; + pfree(types); for (i = 0; i < numParams; i++) pfree((char *) values[i]); pfree(values); } - /* - * If the query has failed, reporting details is enough here. - * Connections which are used by this query (including other scans) will - * be cleaned up by the foreign connection manager. - */ - if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) + if (ret != 1) { char *msg; msg = pstrdup(PQerrorMessage(conn)); - PQclear(res); ereport(ERROR, - (errmsg("could not execute foreign query"), + (errmsg("could not send foreign query"), errdetail("%s", msg), errhint("%s", sql))); } - festate->res = res; + /* The result has not been retrieved yet. */ + festate->res = NULL; festate->nextrow = 0; node->fdw_state = (void *) festate; @@ -612,6 +610,40 @@ pgIterateForeignScan(ForeignScanState *node) elog(DEBUG3, "%s() called", __FUNCTION__); + /* + * If this was the first call for this foreign query, retrieve the results. + */ + if (festate->res == NULL) + { + PGresult *res; + + res = PQgetResult(festate->conn); + + /* + * If the query has failed, reporting details is enough here. + * Connections which are used by this query (including other scans) will + * be cleaned up by the foreign connection manager. + */ + if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) + { + FdwPlan *fdwplan; + char *sql; + char *msg; + + fdwplan = ((ForeignScan *) node->ss.ps.plan)->fdwplan; + sql = strVal(list_nth(fdwplan->fdw_private, 0)); + + msg = pstrdup(PQerrorMessage(festate->conn)); + PQclear(res); + ereport(ERROR, + (errmsg("could not execute foreign query"), + errdetail("%s", msg), + errhint("%s", sql))); + } + + festate->res = res; + } + if (festate->nextrow == PQntuples(festate->res)) ExecClearTuple(slot); else |