diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 06be922..635f47b 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -135,6 +135,171 @@ static Plan *build_grouping_chain(PlannerInfo *root,
 					 long numGroups,
 					 Plan *result_plan);
 
+/*
+ * fix_node_funcids
+ *		Set the opfuncid (procedure OID) in an OpExpr node,
+ *		for plan tree.
+ *
+ * We need it mainly to fix the opfuncid in nodes of plantree
+ * after reading the planned statement by worker backend.
+ */
+static void
+fix_node_funcids(Plan *node)
+{
+	ListCell   *temp;
+
+	/*
+	 * do nothing when we get to the end of a leaf on tree.
+	 */
+	if (node == NULL)
+		return;
+
+	fix_opfuncids((Node*) node->qual);
+	fix_opfuncids((Node*) node->targetlist);
+
+	switch (nodeTag(node))
+	{
+		case T_Result:
+			fix_opfuncids((Node*) (((Result *) node)->resconstantqual));
+			break;
+		case T_ModifyTable:
+			foreach(temp, (List *) ((ModifyTable *) node)->plans)
+				fix_node_funcids((Plan *) lfirst(temp));
+
+			fix_opfuncids((Node*) (((ModifyTable *) node)->withCheckOptionLists));
+			fix_opfuncids((Node*) (((ModifyTable *) node)->returningLists));
+			/*
+			 * we should fix funcids for fdwPrivLists, but it is not
+			 * clear what kind of expressions it can contain.
+			 */
+			fix_opfuncids((Node*) (((ModifyTable *) node)->onConflictSet));
+			fix_opfuncids((Node*) (((ModifyTable *) node)->onConflictWhere));
+			fix_opfuncids((Node*) (((ModifyTable *) node)->exclRelTlist));
+			break;
+		case T_Append:
+			foreach(temp, (List *) ((Append *) node)->appendplans)
+				fix_node_funcids((Plan *) lfirst(temp));
+			break;
+		case T_MergeAppend:
+			foreach(temp, (List *) ((MergeAppend *) node)->mergeplans)
+				fix_node_funcids((Plan *) lfirst(temp));
+			break;
+		case T_RecursiveUnion:
+			break;
+		case T_BitmapAnd:
+			foreach(temp, (List *) ((BitmapAnd *) node)->bitmapplans)
+				fix_node_funcids((Plan *) lfirst(temp));
+			break;
+		case T_BitmapOr:
+			foreach(temp, (List *) ((BitmapOr *) node)->bitmapplans)
+				fix_node_funcids((Plan *) lfirst(temp));
+			break;
+		case T_Scan:
+			break;
+		case T_SeqScan:
+			break;
+		case T_SampleScan:
+			fix_opfuncids((Node*) (((SampleScan *) node)->tablesample));
+			break;
+		case T_IndexScan:
+			fix_opfuncids((Node*) (((IndexScan *) node)->indexqual));
+			fix_opfuncids((Node*) (((IndexScan *) node)->indexqualorig));
+			fix_opfuncids((Node*) (((IndexScan *) node)->indexorderby));
+			fix_opfuncids((Node*) (((IndexScan *) node)->indexorderbyorig));
+			break;
+		case T_IndexOnlyScan:
+			fix_opfuncids((Node*) (((IndexOnlyScan *) node)->indexqual));
+			fix_opfuncids((Node*) (((IndexOnlyScan *) node)->indexorderby));
+			fix_opfuncids((Node*) (((IndexOnlyScan *) node)->indextlist));
+			break;
+		case T_BitmapIndexScan:
+			fix_opfuncids((Node*) (((BitmapIndexScan *) node)->indexqual));
+			fix_opfuncids((Node*) (((BitmapIndexScan *) node)->indexqualorig));
+			break;
+		case T_BitmapHeapScan:
+			fix_opfuncids((Node*) (((BitmapHeapScan *) node)->bitmapqualorig));
+			break;
+		case T_TidScan:
+			fix_opfuncids((Node*) (((TidScan *) node)->tidquals));
+			break;
+		case T_SubqueryScan:
+			fix_node_funcids((Plan *) ((SubqueryScan *) node)->subplan);
+			break;
+		case T_FunctionScan:
+			fix_opfuncids((Node*) (((FunctionScan *) node)->functions));
+			break;
+		case T_ValuesScan:
+			fix_opfuncids((Node*) (((ValuesScan *) node)->values_lists));
+			break;
+		case T_CteScan:
+			break;
+		case T_WorkTableScan:
+			break;
+		case T_ForeignScan:
+			fix_opfuncids((Node*) (((ForeignScan *) node)->fdw_exprs));
+			/*
+			 * we should fix funcids for fdw_private, but it is not
+			 * clear what kind of expressions it can contain.
+			 */
+			fix_opfuncids((Node*) (((ForeignScan *) node)->fdw_scan_tlist));
+			break;
+		case T_Join:
+			fix_opfuncids((Node*) (((Join *) node)->joinqual));
+			break;
+		case T_NestLoop:
+			fix_opfuncids((Node*) (((NestLoop *) node)->join.joinqual));
+			foreach(temp, (List *) ((NestLoop*) node)->nestParams)
+				fix_opfuncids((Node*) ((NestLoopParam *) lfirst(temp))->paramval);
+			break;
+		case T_MergeJoin:
+			fix_opfuncids((Node*) (((MergeJoin *) node)->join.joinqual));
+			fix_opfuncids((Node*) (((MergeJoin *) node)->mergeclauses));
+			break;
+		case T_HashJoin:
+			fix_opfuncids((Node*) (((HashJoin *) node)->join.joinqual));
+			fix_opfuncids((Node*) (((HashJoin *) node)->hashclauses));
+			break;
+		case T_Material:
+			break;
+		case T_Sort:
+			break;
+		case T_Group:
+			break;
+		case T_Agg:
+			foreach(temp, (List *) ((Agg *) node)->chain)
+				fix_node_funcids((Plan *) lfirst(temp));
+			break;
+		case T_WindowAgg:
+			fix_opfuncids((Node*) (((WindowAgg *) node)->startOffset));
+			fix_opfuncids((Node*) (((WindowAgg *) node)->endOffset));
+			break;
+		case T_Unique:
+			break;
+		case T_Hash:
+			break;
+		case T_SetOp:
+			break;
+		case T_LockRows:
+			break;
+		case T_Limit:
+			fix_opfuncids((Node*) (((Limit *) node)->limitOffset));
+			fix_opfuncids((Node*) (((Limit *) node)->limitCount));
+			break;
+		case T_SubPlan:
+			fix_opfuncids((Node*) ((SubPlan *) node));
+			break;
+		case T_AlternativeSubPlan:
+			fix_opfuncids((Node*) ((AlternativeSubPlan *) node));
+			break;
+		default:
+			elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
+			break;
+	}
+
+	fix_node_funcids(node->lefttree);
+	fix_node_funcids(node->righttree);
+}
+
 /*****************************************************************************
  *
  *	   Query optimizer entry point
@@ -152,12 +317,25 @@ PlannedStmt *
 planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
 {
 	PlannedStmt *result;
+	PlannedStmt *verify_plannedstmt;
+	char		*plannedstmt_str;
+	ListCell   *temp;
 
 	if (planner_hook)
 		result = (*planner_hook) (parse, cursorOptions, boundParams);
 	else
 		result = standard_planner(parse, cursorOptions, boundParams);
-	return result;
+
+	plannedstmt_str = nodeToString(result);
+
+	verify_plannedstmt = (PlannedStmt *) stringToNode(plannedstmt_str);
+
+	fix_node_funcids(verify_plannedstmt->planTree);
+
+	foreach(temp, (List *) verify_plannedstmt->subplans)
+		fix_node_funcids((Plan *) lfirst(temp));
+
+	return verify_plannedstmt;
 }
 
 PlannedStmt *
