>From 096769d7670713f7b7c91920be84a04392b9846b Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horiguchi.kyotaro@lab.ntt.co.jp>
Date: Thu, 9 Jul 2015 20:21:14 +0900
Subject: [PATCH 4/6] Add StartForeignScan to FdwRoutine

Add new entry function in FdwRoutineStart so that fdw can be started
using asynchornous execution infrastructure.
---
 src/backend/executor/execProcnode.c    |  4 +++-
 src/backend/executor/nodeForeignscan.c | 24 ++++++++++++++++++++++++
 src/include/executor/nodeForeignscan.h |  1 +
 src/include/foreign/fdwapi.h           |  3 +++
 4 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c
index 2b282ca..6d7ad51 100644
--- a/src/backend/executor/execProcnode.c
+++ b/src/backend/executor/execProcnode.c
@@ -848,8 +848,10 @@ StartProcNode(PlanState *node)
 	case T_LimitState:
 		return StartLimit((LimitState *)node);
 
-	/* These nodes cannot run asynchronously */
 	case T_ForeignScanState:
+		return StartForeignScan((ForeignScanState *)node);
+
+	/* These nodes cannot run asynchronously */
 	case T_WorkTableScanState:
 	case T_CustomScanState:
 	case T_FunctionScanState:
diff --git a/src/backend/executor/nodeForeignscan.c b/src/backend/executor/nodeForeignscan.c
index 5d39c85..de19bf9 100644
--- a/src/backend/executor/nodeForeignscan.c
+++ b/src/backend/executor/nodeForeignscan.c
@@ -101,6 +101,30 @@ ExecForeignScan(ForeignScanState *node)
 	return slot;
 }
 
+/* ----------------------------------------------------------------
+ *		StartForeignScan
+ *
+ * Try to start asynchronously.
+ * Returns true if any of underlying nodes started asynchronously
+ * ----------------------------------------------------------------
+ */
+bool
+StartForeignScan(ForeignScanState *node)
+{
+	StartForeginScan_function StartForeignScanFunc =
+		node->fdwroutine->StartForeignScan;
+
+	if (!ExecNode_is(node, Inited))
+		return false;
+
+	if (StartForeignScanFunc && StartForeignScanFunc(node))
+	{
+		SetNodeRunState(node, Started);
+		return true;
+	}
+
+	return false;
+}
 
 /* ----------------------------------------------------------------
  *		ExecInitForeignScan
diff --git a/src/include/executor/nodeForeignscan.h b/src/include/executor/nodeForeignscan.h
index 45e0e9c..39802a3 100644
--- a/src/include/executor/nodeForeignscan.h
+++ b/src/include/executor/nodeForeignscan.h
@@ -18,6 +18,7 @@
 
 extern ForeignScanState *ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags);
 extern TupleTableSlot *ExecForeignScan(ForeignScanState *node);
+extern bool StartForeignScan(ForeignScanState *node);
 extern void ExecEndForeignScan(ForeignScanState *node);
 extern void ExecReScanForeignScan(ForeignScanState *node);
 
diff --git a/src/include/foreign/fdwapi.h b/src/include/foreign/fdwapi.h
index 69b48b4..9f4234a 100644
--- a/src/include/foreign/fdwapi.h
+++ b/src/include/foreign/fdwapi.h
@@ -118,6 +118,8 @@ typedef bool (*AnalyzeForeignTable_function) (Relation relation,
 typedef List *(*ImportForeignSchema_function) (ImportForeignSchemaStmt *stmt,
 														   Oid serverOid);
 
+typedef bool (*StartForeginScan_function) (ForeignScanState *node);
+
 /*
  * FdwRoutine is the struct returned by a foreign-data wrapper's handler
  * function.  It provides pointers to the callback functions needed by the
@@ -140,6 +142,7 @@ typedef struct FdwRoutine
 	IterateForeignScan_function IterateForeignScan;
 	ReScanForeignScan_function ReScanForeignScan;
 	EndForeignScan_function EndForeignScan;
+	StartForeginScan_function StartForeignScan;
 
 	/*
 	 * Remaining functions are optional.  Set the pointer to NULL for any that
-- 
1.8.3.1

