>From 92596ee8cda043cbc37cd27d4ec668f624a49d6e Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horiguchi.kyotaro@lab.ntt.co.jp>
Date: Tue, 30 Jun 2015 15:29:46 +0900
Subject: [PATCH] Add foreign table option to set fetch size.

---
 contrib/postgres_fdw/option.c       |  2 ++
 contrib/postgres_fdw/postgres_fdw.c | 31 +++++++++++++++++++++++++++----
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/contrib/postgres_fdw/option.c b/contrib/postgres_fdw/option.c
index 7547ec2..793239d 100644
--- a/contrib/postgres_fdw/option.c
+++ b/contrib/postgres_fdw/option.c
@@ -153,6 +153,8 @@ InitPgFdwOptions(void)
 		/* updatable is available on both server and table */
 		{"updatable", ForeignServerRelationId, false},
 		{"updatable", ForeignTableRelationId, false},
+		/* fetch_size is available on table (XXX: also server may have it.) */
+		{"fetch_size", ForeignTableRelationId, false},
 		{NULL, InvalidOid, false}
 	};
 
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
index 40cac3b..e01213e 100644
--- a/contrib/postgres_fdw/postgres_fdw.c
+++ b/contrib/postgres_fdw/postgres_fdw.c
@@ -152,6 +152,7 @@ typedef struct PgFdwScanState
 	FmgrInfo   *param_flinfo;	/* output conversion functions for them */
 	List	   *param_exprs;	/* executable expressions for param values */
 	const char **param_values;	/* textual values of query parameters */
+	int			fetch_size;		/* number of tuples to request by one fetch */
 
 	/* for storing result tuples */
 	HeapTuple  *tuples;			/* array of currently-retrieved tuples */
@@ -945,6 +946,31 @@ postgresBeginForeignScan(ForeignScanState *node, int eflags)
 	server = GetForeignServer(table->serverid);
 	user = GetUserMapping(userid, server->serverid);
 
+	fsstate->fetch_size = -1;
+	foreach(lc, table->options)
+	{
+		DefElem    *def = (DefElem *) lfirst(lc);
+
+		/* Does anyone specify negatives? Who cares? */
+		if (strcmp(def->defname, "fetch_size") == 0)
+		{
+			char *ep = NULL;
+			char *defstr = defGetString(def);
+
+			fsstate->fetch_size = strtol(defstr, &ep, 10);
+			if (*ep || ep == defstr)
+			{
+				elog(WARNING,
+					 "Option \"%s\" must be a positive integer (foreign table \"%s\") : \"%s\"",
+					 def->defname, get_rel_name(table->relid), defstr);
+				fsstate->fetch_size = -1;		/* Use default */
+			}
+			break;
+		}
+	}
+	if (fsstate->fetch_size < 1)
+		fsstate->fetch_size = 100;		/* default size */
+
 	/*
 	 * Get connection to the foreign server.  Connection manager will
 	 * establish new connection if necessary.
@@ -2092,15 +2118,12 @@ fetch_more_data(PgFdwScanState *fsstate, fetch_mode cmd)
 	{
 		PgFdwConn  *conn = fsstate->conn;
 		char		sql[64];
-		int			fetch_size;
+		int			fetch_size = fsstate->fetch_size;
 		int			numrows, addrows, restrows;
 		HeapTuple  *tmptuples;
 		int			i;
 		int			fetch_buf_size;
 
-		/* The fetch size is arbitrary, but shouldn't be enormous. */
-		fetch_size = 100;
-
 		/* Make the query to fetch tuples */
 		snprintf(sql, sizeof(sql), "FETCH %d FROM c%u",
 				 fetch_size, fsstate->cursor_number);
-- 
1.8.3.1

