summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/postgresql_fdw/postgresql_fdw.c56
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