diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 460fdcc1f91254bf14094acd438fc8910b8c1319..31a8d9d3679fb91cb3df4f22ad8d933364899785 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -4,7 +4,7 @@
  *
  * Copyright (c) 1994-5, Regents of the University of California
  *
- *	  $Id: explain.c,v 1.43 1999/07/17 20:16:52 momjian Exp $
+ *	  $Id: explain.c,v 1.44 1999/08/09 06:20:21 momjian Exp $
  *
  */
 
@@ -200,6 +200,8 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
 	switch (nodeTag(plan))
 	{
 		case T_IndexScan:
+			if (ScanDirectionIsBackward(((IndexScan *)plan)->indxorderdir))
+				appendStringInfo(str, " Backward");
 			appendStringInfo(str, " using ");
 			i = 0;
 			foreach(l, ((IndexScan *) plan)->indxid)
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c
index 0a35cf2cf8c360797476d3327452880533b57634..7be2f1b8c99a40f23929155a547fc513e061309b 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.40 1999/07/16 04:58:50 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.41 1999/08/09 06:20:22 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -99,6 +99,13 @@ IndexNext(IndexScan *node)
 	 */
 	estate = node->scan.plan.state;
 	direction = estate->es_direction;
+	if (ScanDirectionIsBackward(node->indxorderdir))
+	{
+		if (ScanDirectionIsForward(direction))
+			direction = BackwardScanDirection;
+		else if (ScanDirectionIsBackward(direction))
+			direction = ForwardScanDirection;
+	}  
 	snapshot = estate->es_snapshot;
 	scanstate = node->scan.scanstate;
 	indexstate = node->indxstate;
@@ -316,6 +323,8 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
 	indxqual = node->indxqual;
 	numScanKeys = indexstate->iss_NumScanKeys;
 	indexstate->iss_IndexPtr = -1;
+	if (ScanDirectionIsBackward(node->indxorderdir))
+		indexstate->iss_IndexPtr = numIndices;
 
 	/* If this is re-scanning of PlanQual ... */
 	if (estate->es_evTuple != NULL &&
@@ -966,6 +975,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
 	}
 
 	indexstate->iss_NumIndices = numIndices;
+	if (ScanDirectionIsBackward(node->indxorderdir))
+		indexPtr = numIndices;
 	indexstate->iss_IndexPtr = indexPtr;
 	indexstate->iss_ScanKeys = scanKeys;
 	indexstate->iss_NumScanKeys = numScanKeys;
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index db97c2ed39bb57ef47f85492ca96d625286f55fa..ca2bd33a2c1c94348693202835cb0ad160180d2e 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.89 1999/07/27 03:51:07 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.90 1999/08/09 06:20:23 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -238,6 +238,7 @@ _copyIndexScan(IndexScan *from)
 	newnode->indxid = listCopy(from->indxid);
 	Node_Copy(from, newnode, indxqual);
 	Node_Copy(from, newnode, indxqualorig);
+	newnode->indxorderdir = from->indxorderdir;
 
 	return newnode;
 }
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 576601faf57021958405b59fced01cada4c1496a..337e63a61561b67172763e65010ddd5a052099df 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.45 1999/07/29 02:45:36 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.46 1999/08/09 06:20:24 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -437,6 +437,9 @@ _equalIndexScan(IndexScan *a, IndexScan *b)
 	if (a->scan.scanrelid != b->scan.scanrelid)
 		return false;
 
+	if (a->indxorderdir != b->indxorderdir)
+		return false;
+
 	if (!equali(a->indxid, b->indxid))
 		return false;
 	return true;
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 4272bf04cc5208e6e0b6d5858d18a5618761c850..5c9f4599deb7fd3df1ebb2b9ea37b961c6f75984 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- *	$Id: outfuncs.c,v 1.91 1999/07/24 23:21:07 tgl Exp $
+ *	$Id: outfuncs.c,v 1.92 1999/08/09 06:20:24 momjian Exp $
  *
  * NOTES
  *	  Every (plan) node in POSTGRES has an associated "out" routine which
@@ -445,6 +445,7 @@ _outIndexScan(StringInfo str, IndexScan *node)
 	appendStringInfo(str, " :indxqualorig ");
 	_outNode(str, node->indxqualorig);
 
+	appendStringInfo(str, " :indxorderdir %d ", node->indxorderdir);
 }
 
 /*
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index e16398fb85481b10b9dc20d3d162094bec38133e..c49ad053f1bcf12051111db5be6ad699ce1f40df 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.70 1999/07/24 23:21:08 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.71 1999/08/09 06:20:24 momjian Exp $
  *
  * NOTES
  *	  Most of the read functions for plan nodes are tested. (In fact, they
@@ -532,6 +532,11 @@ _readIndexScan()
 	token = lsptok(NULL, &length);		/* eat :indxqualorig */
 	local_node->indxqualorig = nodeRead(true);	/* now read it */
 
+	token = lsptok(NULL, &length);		/* eat :indxorderdir */
+	token = lsptok(NULL, &length);		/* get indxorderdir */
+
+	local_node->indxorderdir = atoi(token);
+
 	return local_node;
 }
 
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index d3d79f6ef8a137369450f2ebc4d4b15748389d77..dbc6ac9d289e0b6feb4ac1f92a6357ae042d5370 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.67 1999/08/09 01:01:42 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.68 1999/08/09 06:20:26 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1024,6 +1024,7 @@ make_indexscan(List *qptlist,
 	node->indxid = indxid;
 	node->indxqual = indxqual;
 	node->indxqualorig = indxqualorig;
+	node->indxorderdir = NoMovementScanDirection;
 	node->scan.scanstate = (CommonScanState *) NULL;
 
 	return node;
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 41bb025e286f279b9c27d9633c056fe2e610b686..17ad449839b24496fe8efa6dc7b330d02afdc973 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.61 1999/07/17 20:17:15 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.62 1999/08/09 06:20:26 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -39,7 +39,7 @@ static List *make_subplanTargetList(Query *parse, List *tlist,
 static Plan *make_groupplan(List *group_tlist, bool tuplePerGroup,
 			   List *groupClause, AttrNumber *grpColIdx,
 			   Plan *subplan);
-static bool need_sortplan(List *sortcls, Plan *plan);
+static ScanDirection get_dir_to_omit_sortplan(List *sortcls, Plan *plan);
 static Plan *make_sortplan(List *tlist, List *sortcls, Plan *plannode);
 
 /*****************************************************************************
@@ -303,8 +303,17 @@ union_planner(Query *parse)
 	}
 	else
 	{
-		if (parse->sortClause && need_sortplan(parse->sortClause, result_plan))
-			return (make_sortplan(tlist, parse->sortClause, result_plan));
+		if (parse->sortClause)
+		{
+			ScanDirection	dir = get_dir_to_omit_sortplan(parse->sortClause, result_plan);
+			if (ScanDirectionIsNoMovement(dir))
+				return (make_sortplan(tlist, parse->sortClause, result_plan));
+			else
+			{ 
+				((IndexScan *)result_plan)->indxorderdir = dir;
+				return ((Plan *) result_plan);
+			}
+		}
 		else
 			return ((Plan *) result_plan);
 	}
@@ -822,7 +831,7 @@ pg_checkretval(Oid rettype, List *queryTreeList)
 
 
 /* ----------
- * Support function for need_sortplan
+ * Support function for get scan direction to omit sortplan
  * ----------
  */
 static TargetEntry *
@@ -845,11 +854,13 @@ get_matching_tle(Plan *plan, Resdom *resdom)
  * Check if a user requested ORDER BY is already satisfied by
  * the choosen index scan.
  *
- * Returns TRUE if sort is required, FALSE if can be omitted.
+ * Returns the direction of Index scan to omit sort,
+ * if sort is required returns NoMovementScanDirection  
+ *
  * ----------
  */
-static bool
-need_sortplan(List *sortcls, Plan *plan)
+static ScanDirection
+get_dir_to_omit_sortplan(List *sortcls, Plan *plan)
 {
 	Relation	indexRel;
 	IndexScan  *indexScan;
@@ -858,13 +869,15 @@ need_sortplan(List *sortcls, Plan *plan)
 	HeapTuple	htup;
 	Form_pg_index index_tup;
 	int			key_no = 0;
+	ScanDirection   dir, nodir = NoMovementScanDirection;
 
+	dir = nodir;
 	/* ----------
 	 * Must be an IndexScan
 	 * ----------
 	 */
 	if (nodeTag(plan) != T_IndexScan)
-		return TRUE;
+		return nodir;
 
 	indexScan = (IndexScan *) plan;
 
@@ -873,16 +886,16 @@ need_sortplan(List *sortcls, Plan *plan)
 	 * ----------
 	 */
 	if (plan->lefttree != NULL)
-		return TRUE;
+		return nodir;
 	if (plan->righttree != NULL)
-		return TRUE;
+		return nodir;
 
 	/* ----------
 	 * Must be a single index scan
 	 * ----------
 	 */
 	if (length(indexScan->indxid) != 1)
-		return TRUE;
+		return nodir;
 
 	/* ----------
 	 * Indices can only have up to 8 attributes. So an ORDER BY using
@@ -890,7 +903,7 @@ need_sortplan(List *sortcls, Plan *plan)
 	 * ----------
 	 */
 	if (length(sortcls) > 8)
-		return TRUE;
+		return nodir;
 
 	/* ----------
 	 * The choosen Index must be a btree
@@ -902,7 +915,7 @@ need_sortplan(List *sortcls, Plan *plan)
 	if (strcmp(nameout(&(indexRel->rd_am->amname)), "btree") != 0)
 	{
 		heap_close(indexRel);
-		return TRUE;
+		return nodir;
 	}
 	heap_close(indexRel);
 
@@ -937,7 +950,7 @@ need_sortplan(List *sortcls, Plan *plan)
 			 * Could this happen?
 			 * ----------
 			 */
-			return TRUE;
+			return nodir;
 		}
 		if (nodeTag(tle->expr) != T_Var)
 		{
@@ -946,7 +959,7 @@ need_sortplan(List *sortcls, Plan *plan)
 			 * cannot be the indexed attribute
 			 * ----------
 			 */
-			return TRUE;
+			return nodir;
 		}
 		var = (Var *) (tle->expr);
 
@@ -957,7 +970,7 @@ need_sortplan(List *sortcls, Plan *plan)
 			 * that of the index
 			 * ----------
 			 */
-			return TRUE;
+			return nodir;
 		}
 
 		if (var->varattno != index_tup->indkey[key_no])
@@ -966,7 +979,7 @@ need_sortplan(List *sortcls, Plan *plan)
 			 * It isn't the indexed attribute.
 			 * ----------
 			 */
-			return TRUE;
+			return nodir;
 		}
 
 		if (oprid(oper("<", resdom->restype, resdom->restype, FALSE)) != sortcl->opoid)
@@ -975,7 +988,19 @@ need_sortplan(List *sortcls, Plan *plan)
 			 * Sort order isn't in ascending order.
 			 * ----------
 			 */
-			return TRUE;
+			if (ScanDirectionIsForward(dir))
+				return nodir;
+			dir = BackwardScanDirection;
+		}
+		else
+		{
+			/* ----------
+			 * Sort order is in ascending order.
+			 * ----------
+			*/
+			if (ScanDirectionIsBackward(dir))
+				return nodir;
+			dir = ForwardScanDirection;
 		}
 
 		key_no++;
@@ -985,5 +1010,5 @@ need_sortplan(List *sortcls, Plan *plan)
 	 * Index matches ORDER BY - sort not required
 	 * ----------
 	 */
-	return FALSE;
+	return dir;
 }
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index 3d319a66ff7c078d33b1b055025e9fab1a92fdc1..532be5196bf8f4a877972f537be7d831db8bb255 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: plannodes.h,v 1.28 1999/07/15 23:03:55 momjian Exp $
+ * $Id: plannodes.h,v 1.29 1999/08/09 06:20:27 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -175,6 +175,7 @@ typedef struct IndexScan
 	List	   *indxid;
 	List	   *indxqual;
 	List	   *indxqualorig;
+	ScanDirection	indxorderdir;
 	IndexScanState *indxstate;
 } IndexScan;