*** a/src/backend/executor/nodeNestloop.c
--- b/src/backend/executor/nodeNestloop.c
***************
*** 26,31 ****
--- 26,141 ----
  #include "utils/memutils.h"
  
  
+ TupleTableSlot *
+ ExecNewMergeJoin(NestLoopState *node)
+ {
+ 	List	   *joinqual;
+ 	List	   *otherqual;
+ 	bool		qualResult;
+ 	int			compareResult;
+ 	PlanState  *innerPlan;
+ 	TupleTableSlot *innerTupleSlot;
+ 	PlanState  *outerPlan;
+ 	TupleTableSlot *outerTupleSlot;
+ 	ExprContext *econtext;
+ 	static	bool	newOuter = true;
+ 	static bool markpos = true;
+ 
+ 
+ 	/*
+ 	 * get information from node
+ 	 */
+ 	innerPlan = innerPlanState(node);
+ 	outerPlan = outerPlanState(node);
+ 	econtext = node->js.ps.ps_ExprContext;
+ 	joinqual = node->js.joinqual;
+ 	otherqual = node->js.ps.qual;
+ 
+ 	/*
+ 	 * Check to see if we're still projecting out tuples from a previous join
+ 	 * tuple (because there is a function-returning-set in the projection
+ 	 * expressions).  If so, try to project another one.
+ 	 */
+ 	if (node->js.ps.ps_TupFromTlist)
+ 	{
+ 		TupleTableSlot *result;
+ 		ExprDoneCond isDone;
+ 
+ 		result = ExecProject(node->js.ps.ps_ProjInfo, &isDone);
+ 		if (isDone == ExprMultipleResult)
+ 			return result;
+ 		/* Done with that source tuple... */
+ 		node->js.ps.ps_TupFromTlist = false;
+ 	}
+ 
+ 	/*
+ 	 * Reset per-tuple memory context to free any expression evaluation
+ 	 * storage allocated in the previous tuple cycle.  Note this can't happen
+ 	 * until we're done projecting out tuples from a join tuple.
+ 	 */
+ 	ResetExprContext(econtext);
+ 
+ 	/*
+ 	 * ok, everything is setup.. let's go to work
+ 	 */
+ 	for (;;)
+ 	{
+ 		if (newOuter)
+ 		{
+ 			outerTupleSlot = ExecProcNode(outerPlan);
+ 			node->nl_OuterTupleSlot = outerTupleSlot;
+ 			if (TupIsNull(outerTupleSlot))
+ 			{
+ 				return NULL;
+ 			}
+ 
+ 			newOuter = false;
+ 			markpos = true;
+ 
+ 			ExecRestrPos(innerPlan);
+ 		}
+ 
+ 		innerTupleSlot = ExecProcNode(innerPlan);
+ 		node->nl_InnerTupleSlot = innerTupleSlot;
+ 		if (TupIsNull(innerTupleSlot))
+ 		{
+ 			newOuter = true;
+ 			continue;
+ 
+ 		}
+ 
+ 		outerTupleSlot = node->nl_OuterTupleSlot;
+ 		innerTupleSlot = node->nl_InnerTupleSlot;
+ 		econtext->ecxt_outertuple = outerTupleSlot;
+ 		econtext->ecxt_innertuple = innerTupleSlot;
+ 
+ 		qualResult = ExecQual(joinqual, econtext, false);
+ 		if (qualResult)
+ 		{
+ 			TupleTableSlot *result;
+ 			ExprDoneCond isDone;
+ 
+ 			if (markpos)
+ 			{
+ 				ExecMarkPos(innerPlan);
+ 				//MarkInnerTuple(node->nl_InnerTupleSlot, node);
+ 				ExecCopySlot(node->nl_MarkedTupleSlot, innerTupleSlot);
+ 				markpos = false;
+ 			}
+ 
+ 			result = ExecProject(node->js.ps.ps_ProjInfo,
+ 								 &isDone);
+ 			if (isDone != ExprEndResult)
+ 			{
+ 				node->js.ps.ps_TupFromTlist =
+ 					(isDone == ExprMultipleResult);
+ 				return result;
+ 			}
+ 		}
+ 	}
+ }
+ 
+ 
  /* ----------------------------------------------------------------
   *		ExecNestLoop(node)
   *
***************
*** 69,74 **** ExecNestLoop(NestLoopState *node)
--- 179,187 ----
  	ExprContext *econtext;
  	ListCell   *lc;
  
+ 	if (node->sorted_child)
+ 		return ExecNewMergeJoin(node);
+ 
  	/*
  	 * get information from the node
  	 */
***************
*** 381,386 **** ExecInitNestLoop(NestLoop *node, EState *estate, int eflags)
--- 494,507 ----
  	nlstate->nl_NeedNewOuter = true;
  	nlstate->nl_MatchedOuter = false;
  
+ 	if (node->sorted_child)
+ 	{
+ 		nlstate->nl_MarkedTupleSlot = ExecInitExtraTupleSlot(estate);
+ 		nlstate->nl_InnerTupleSlot = ExecInitExtraTupleSlot(estate);
+ 		nlstate->nl_OuterTupleSlot = ExecInitExtraTupleSlot(estate);
+ 		nlstate->sorted_child = true;
+ 	}
+ 
  	NL1_printf("ExecInitNestLoop: %s\n",
  			   "node initialized");
  
*** a/src/backend/optimizer/plan/createplan.c
--- b/src/backend/optimizer/plan/createplan.c
***************
*** 1252,1277 **** create_indexscan_plan(PlannerInfo *root,
  			replace_nestloop_params(root, (Node *) indexorderbys);
  	}
  
! 	/* Finally ready to build the plan node */
! 	if (indexonly)
! 		scan_plan = (Scan *) make_indexonlyscan(tlist,
  												qpqual,
  												baserelid,
  												indexoid,
  												fixed_indexquals,
  												fixed_indexorderbys,
! 											best_path->indexinfo->indextlist,
  												best_path->indexscandir);
! 	else
! 		scan_plan = (Scan *) make_indexscan(tlist,
! 											qpqual,
! 											baserelid,
! 											indexoid,
! 											fixed_indexquals,
! 											stripped_indexquals,
! 											fixed_indexorderbys,
! 											indexorderbys,
! 											best_path->indexscandir);
  
  	copy_path_costsize(&scan_plan->plan, &best_path->path);
  
--- 1252,1292 ----
  			replace_nestloop_params(root, (Node *) indexorderbys);
  	}
  
! 	if (!enable_material)
! 	{
! 		scan_plan = (Scan *) make_indexscan(tlist,
! 											NULL,
! 											baserelid,
! 											indexoid,
! 											NULL,
! 											NULL,
! 											NULL,
! 											NULL,
! 											best_path->indexscandir);
! 	}
! 	else
! 	{
! 		/* Finally ready to build the plan node */
! 		if (indexonly)
! 			scan_plan = (Scan *) make_indexonlyscan(tlist,
! 													qpqual,
! 													baserelid,
! 													indexoid,
! 													fixed_indexquals,
! 													fixed_indexorderbys,
! 												best_path->indexinfo->indextlist,
! 													best_path->indexscandir);
! 		else
! 			scan_plan = (Scan *) make_indexscan(tlist,
  												qpqual,
  												baserelid,
  												indexoid,
  												fixed_indexquals,
+ 												stripped_indexquals,
  												fixed_indexorderbys,
! 												indexorderbys,
  												best_path->indexscandir);
! 	}
  
  	copy_path_costsize(&scan_plan->plan, &best_path->path);
  
***************
*** 2091,2096 **** create_nestloop_plan(PlannerInfo *root,
--- 2106,2153 ----
  			prev = cell;
  	}
  
+ 	if (!enable_material)
+ 	{
+ 		int 		numsortkeys = 1;
+ 		AttrNumber *sortColIdx = palloc(sizeof(AttrNumber));
+ 		Oid 	   *sortOperators = palloc(sizeof(Oid));
+ 		Oid 	   *collations = palloc(sizeof(Oid));
+ 		bool	   *nullsFirst = palloc(sizeof(bool));
+ 		double limit_tuples = -1;
+ 
+ 		sortColIdx[0] = 1;
+ 		sortOperators[0] = 97;
+ 		collations[0] = 0;
+ 		nullsFirst[0] = 0;
+ 
+ 
+ 		if (outer_plan->type != T_IndexScan)
+ 		{
+ 			outer_plan = make_sort(root,
+ 								outer_plan,
+ 								numsortkeys,
+ 								sortColIdx,
+ 								sortOperators,
+ 								collations,
+ 								nullsFirst,
+ 								limit_tuples);
+ 		}
+ 
+ 		if (inner_plan->type != T_IndexScan)
+ 		{
+ 			inner_plan = make_sort(root,
+ 								inner_plan,
+ 								numsortkeys,
+ 								sortColIdx,
+ 								sortOperators,
+ 								collations,
+ 								nullsFirst,
+ 								limit_tuples);
+ 		}
+ 
+ 	}
+ 
+ 
  	join_plan = make_nestloop(tlist,
  							  joinclauses,
  							  otherclauses,
***************
*** 2101,2106 **** create_nestloop_plan(PlannerInfo *root,
--- 2158,2168 ----
  
  	copy_path_costsize(&join_plan->join.plan, &best_path->path);
  
+ 	if (!enable_material)
+ 		join_plan->sorted_child = true;
+ 	else
+ 		join_plan->sorted_child = false;
+ 
  	return join_plan;
  }
  
*** a/src/include/nodes/execnodes.h
--- b/src/include/nodes/execnodes.h
***************
*** 1533,1538 **** typedef struct NestLoopState
--- 1533,1542 ----
  	bool		nl_NeedNewOuter;
  	bool		nl_MatchedOuter;
  	TupleTableSlot *nl_NullInnerTupleSlot;
+ 	bool		sorted_child;
+ 	TupleTableSlot *nl_InnerTupleSlot;
+ 	TupleTableSlot *nl_OuterTupleSlot;
+ 	TupleTableSlot *nl_MarkedTupleSlot;
  } NestLoopState;
  
  /* ----------------
*** a/src/include/nodes/plannodes.h
--- b/src/include/nodes/plannodes.h
***************
*** 524,529 **** typedef struct NestLoop
--- 524,530 ----
  {
  	Join		join;
  	List	   *nestParams;		/* list of NestLoopParam nodes */
+ 	bool		sorted_child;
  } NestLoop;
  
  typedef struct NestLoopParam
