Hi all,

In v6.5

       Prevent sorting if result is already sorted

was implemented by Jan Wieck.
His work is for ascending order cases.

Here is a patch to prevent sorting also in descending
order cases.
Because I had already changed _bt_first() to position
backward correctly before v6.5,this patch would work.

This patch needs "make clean" .

Regards.

Hiroshi Inoue
Inoue@tpf.co.jp

*** ../../head/pgcurrent/backend/optimizer/plan/planner.c	Mon Jul 26
12:44:55 1999
--- backend/optimizer/plan/planner.c	Mon Aug  9 11:01:49 1999
***************
*** 39,45 ****
  static Plan *make_groupplan(List *group_tlist, bool tuplePerGroup,
  			   List *groupClause, AttrNumber *grpColIdx,
  			   Plan *subplan);
! static bool need_sortplan(List *sortcls, Plan *plan);
  static Plan *make_sortplan(List *tlist, List *sortcls, Plan *plannode);


/***************************************************************************
**
--- 39,45 ----
  static Plan *make_groupplan(List *group_tlist, bool tuplePerGroup,
  			   List *groupClause, AttrNumber *grpColIdx,
  			   Plan *subplan);
! static ScanDirection get_dir_to_omit_sortplan(List *sortcls, Plan *plan);
  static Plan *make_sortplan(List *tlist, List *sortcls, Plan *plannode);


/***************************************************************************
**
***************
*** 303,310 ****
  	}
  	else
  	{
! 		if (parse->sortClause && need_sortplan(parse->sortClause,
result_plan))
! 			return (make_sortplan(tlist, parse->sortClause, result_plan));
  		else
  			return ((Plan *) result_plan);
  	}
--- 303,319 ----
  	}
  	else
  	{
! 		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,828 ****


  /* ----------
!  * Support function for need_sortplan
   * ----------
   */
  static TargetEntry *
--- 831,837 ----


  /* ----------
!  * Support function for get scan direction to omit sortplan
   * ----------
   */
  static TargetEntry *
***************
*** 845,855 ****
   * 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.
   * ----------
   */
! static bool
! need_sortplan(List *sortcls, Plan *plan)
  {
  	Relation	indexRel;
  	IndexScan  *indexScan;
--- 854,866 ----
   * Check if a user requested ORDER BY is already satisfied by
   * the choosen index scan.
   *
!  * Returns the direction of Index scan to omit sort,
!  * if sort is required returns NoMovementScanDirection
!  *
   * ----------
   */
! static ScanDirection
! get_dir_to_omit_sortplan(List *sortcls, Plan *plan)
  {
  	Relation	indexRel;
  	IndexScan  *indexScan;
***************
*** 858,870 ****
  	HeapTuple	htup;
  	Form_pg_index index_tup;
  	int			key_no = 0;

  	/* ----------
  	 * Must be an IndexScan
  	 * ----------
  	 */
  	if (nodeTag(plan) != T_IndexScan)
! 		return TRUE;

  	indexScan = (IndexScan *) plan;

--- 869,883 ----
  	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 nodir;

  	indexScan = (IndexScan *) plan;

***************
*** 873,881 ****
  	 * ----------
  	 */
  	if (plan->lefttree != NULL)
! 		return TRUE;
  	if (plan->righttree != NULL)
! 		return TRUE;

  	/* ----------
  	 * Must be a single index scan
--- 886,894 ----
  	 * ----------
  	 */
  	if (plan->lefttree != NULL)
! 		return nodir;
  	if (plan->righttree != NULL)
! 		return nodir;

  	/* ----------
  	 * Must be a single index scan
***************
*** 882,888 ****
  	 * ----------
  	 */
  	if (length(indexScan->indxid) != 1)
! 		return TRUE;

  	/* ----------
  	 * Indices can only have up to 8 attributes. So an ORDER BY using
--- 895,901 ----
  	 * ----------
  	 */
  	if (length(indexScan->indxid) != 1)
! 		return nodir;

  	/* ----------
  	 * Indices can only have up to 8 attributes. So an ORDER BY using
***************
*** 890,896 ****
  	 * ----------
  	 */
  	if (length(sortcls) > 8)
! 		return TRUE;

  	/* ----------
  	 * The choosen Index must be a btree
--- 903,909 ----
  	 * ----------
  	 */
  	if (length(sortcls) > 8)
! 		return nodir;

  	/* ----------
  	 * The choosen Index must be a btree
***************
*** 902,908 ****
  	if (strcmp(nameout(&(indexRel->rd_am->amname)), "btree") != 0)
  	{
  		heap_close(indexRel);
! 		return TRUE;
  	}
  	heap_close(indexRel);

--- 915,921 ----
  	if (strcmp(nameout(&(indexRel->rd_am->amname)), "btree") != 0)
  	{
  		heap_close(indexRel);
! 		return nodir;
  	}
  	heap_close(indexRel);

***************
*** 937,943 ****
  			 * Could this happen?
  			 * ----------
  			 */
! 			return TRUE;
  		}
  		if (nodeTag(tle->expr) != T_Var)
  		{
--- 950,956 ----
  			 * Could this happen?
  			 * ----------
  			 */
! 			return nodir;
  		}
  		if (nodeTag(tle->expr) != T_Var)
  		{
***************
*** 946,952 ****
  			 * cannot be the indexed attribute
  			 * ----------
  			 */
! 			return TRUE;
  		}
  		var = (Var *) (tle->expr);

--- 959,965 ----
  			 * cannot be the indexed attribute
  			 * ----------
  			 */
! 			return nodir;
  		}
  		var = (Var *) (tle->expr);

***************
*** 957,963 ****
  			 * that of the index
  			 * ----------
  			 */
! 			return TRUE;
  		}

  		if (var->varattno != index_tup->indkey[key_no])
--- 970,976 ----
  			 * that of the index
  			 * ----------
  			 */
! 			return nodir;
  		}

  		if (var->varattno != index_tup->indkey[key_no])
***************
*** 966,972 ****
  			 * It isn't the indexed attribute.
  			 * ----------
  			 */
! 			return TRUE;
  		}

  		if (oprid(oper("<", resdom->restype, resdom->restype, FALSE)) !=
sortcl->opoid)
--- 979,985 ----
  			 * It isn't the indexed attribute.
  			 * ----------
  			 */
! 			return nodir;
  		}

  		if (oprid(oper("<", resdom->restype, resdom->restype, FALSE)) !=
sortcl->opoid)
***************
*** 975,982 ****
  			 * Sort order isn't in ascending order.
  			 * ----------
  			 */
! 			return TRUE;
  		}

  		key_no++;
  	}
--- 988,1007 ----
  			 * Sort order isn't in ascending order.
  			 * ----------
  			 */
! 			if (ScanDirectionIsForward(dir))
! 				return nodir;
! 			dir = BackwardScanDirection;
  		}
+ 		else
+ 		{
+ 			/* ----------
+ 			 * Sort order is in ascending order.
+ 			 * ----------
+ 			*/
+ 			if (ScanDirectionIsBackward(dir))
+ 				return nodir;
+ 			dir = ForwardScanDirection;
+ 		}

  		key_no++;
  	}
***************
*** 985,989 ****
  	 * Index matches ORDER BY - sort not required
  	 * ----------
  	 */
! 	return FALSE;
  }
--- 1010,1014 ----
  	 * Index matches ORDER BY - sort not required
  	 * ----------
  	 */
! 	return dir;
  }
*** ../../head/pgcurrent/backend/executor/nodeIndexscan.c	Mon Jul 26
12:44:47 1999
--- backend/executor/nodeIndexscan.c	Mon Aug  9 10:54:23 1999
***************
*** 99,104 ****
--- 99,111 ----
  	 */
  	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,321 ****
--- 323,330 ----
  	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,971 ****
--- 975,982 ----
  	}

  	indexstate->iss_NumIndices = numIndices;
+ 	if (ScanDirectionIsBackward(node->indxorderdir))
+ 		indexPtr = numIndices;
  	indexstate->iss_IndexPtr = indexPtr;
  	indexstate->iss_ScanKeys = scanKeys;
  	indexstate->iss_NumScanKeys = numScanKeys;
*** ../../head/pgcurrent/backend/optimizer/plan/createplan.c	Mon Aug  9
11:31:33 1999
--- backend/optimizer/plan/createplan.c	Mon Aug  9 11:48:55 1999
***************
*** 1024,1029 ****
--- 1024,1030 ----
  	node->indxid = indxid;
  	node->indxqual = indxqual;
  	node->indxqualorig = indxqualorig;
+ 	node->indxorderdir = NoMovementScanDirection;
  	node->scan.scanstate = (CommonScanState *) NULL;

  	return node;
*** ../../head/pgcurrent/backend/nodes/copyfuncs.c	Wed Jul 28 15:25:51 1999
--- backend/nodes/copyfuncs.c	Mon Aug  9 10:55:00 1999
***************
*** 238,243 ****
--- 238,244 ----
  	newnode->indxid = listCopy(from->indxid);
  	Node_Copy(from, newnode, indxqual);
  	Node_Copy(from, newnode, indxqualorig);
+ 	newnode->indxorderdir = from->indxorderdir;

  	return newnode;
  }
*** ../../head/pgcurrent/backend/nodes/readfuncs.c	Mon Jul 26 14:45:56 1999
--- backend/nodes/readfuncs.c	Mon Aug  9 11:00:47 1999
***************
*** 532,537 ****
--- 532,542 ----
  	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;
  }

*** ../../head/pgcurrent/backend/nodes/outfuncs.c	Mon Jul 26 14:45:56 1999
--- backend/nodes/outfuncs.c	Mon Aug  9 10:55:28 1999
***************
*** 445,450 ****
--- 445,451 ----
  	appendStringInfo(str, " :indxqualorig ");
  	_outNode(str, node->indxqualorig);

+ 	appendStringInfo(str, " :indxorderdir %d ", node->indxorderdir);
  }

  /*
*** ../../head/pgcurrent/backend/nodes/equalfuncs.c	Fri Jul 30 17:29:37
1999
--- backend/nodes/equalfuncs.c	Mon Aug  9 10:55:08 1999
***************
*** 437,442 ****
--- 437,445 ----
  	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;
*** ../../head/pgcurrent/include/nodes/plannodes.h	Mon Jul 26 12:45:39 1999
--- include/nodes/plannodes.h	Mon Aug  9 10:52:54 1999
***************
*** 175,180 ****
--- 175,181 ----
  	List	   *indxid;
  	List	   *indxqual;
  	List	   *indxqualorig;
+ 	ScanDirection	indxorderdir;
  	IndexScanState *indxstate;
  } IndexScan;

*** ../../head/pgcurrent/backend/commands/explain.c	Mon Jul 26 12:44:46
1999
--- backend/commands/explain.c	Mon Aug  9 10:53:44 1999
***************
*** 200,205 ****
--- 200,207 ----
  	switch (nodeTag(plan))
  	{
  		case T_IndexScan:
+ 			if (ScanDirectionIsBackward(((IndexScan *)plan)->indxorderdir))
+ 				appendStringInfo(str, " Backward");
  			appendStringInfo(str, " using ");
  			i = 0;
  			foreach(l, ((IndexScan *) plan)->indxid)


Mon, 9 Aug 1999 12:01:28 +0900
"Hiroshi Inoue" <Inoue@tpf.co.jp>
Descending order Index scan patch
[Charset iso-8859-1 unsupported, filtering to ASCII...]
> Hi all,
> 
> In v6.5
> 
>        Prevent sorting if result is already sorted
> 
> was implemented by Jan Wieck.
> His work is for ascending order cases.
> 
> Here is a patch to prevent sorting also in descending
> order cases.
> Because I had already changed _bt_first() to position
> backward correctly before v6.5,this patch would work.
> 
> This patch needs "make clean" .
> 
> Regards.
> 
> Hiroshi Inoue
> Inoue@tpf.co.jp
> 


This patch is broken.  See the wrapping that happened to the /**** line.
Please resubmit.


> *** ../../head/pgcurrent/backend/optimizer/plan/planner.c	Mon Jul 26
> 12:44:55 1999
> --- backend/optimizer/plan/planner.c	Mon Aug  9 11:01:49 1999
> ***************
> *** 39,45 ****
>   static Plan *make_groupplan(List *group_tlist, bool tuplePerGroup,
>   			   List *groupClause, AttrNumber *grpColIdx,
>   			   Plan *subplan);
> ! static bool need_sortplan(List *sortcls, Plan *plan);
>   static Plan *make_sortplan(List *tlist, List *sortcls, Plan *plannode);
> 
> 
> /***************************************************************************
> **
> --- 39,45 ----
>   static Plan *make_groupplan(List *group_tlist, bool tuplePerGroup,
>   			   List *groupClause, AttrNumber *grpColIdx,
>   			   Plan *subplan);
> ! static ScanDirection get_dir_to_omit_sortplan(List *sortcls, Plan *plan);
>   static Plan *make_sortplan(List *tlist, List *sortcls, Plan *plannode);
> 
> 
> /***************************************************************************
> **
> ***************
> *** 303,310 ****
>   	}
>   	else
>   	{
> ! 		if (parse->sortClause && need_sortplan(parse->sortClause,
> result_plan))
> ! 			return (make_sortplan(tlist, parse->sortClause, result_plan));
>   		else
>   			return ((Plan *) result_plan);
>   	}
> --- 303,319 ----
>   	}
>   	else
>   	{
> ! 		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,828 ****
> 
> 
>   /* ----------
> !  * Support function for need_sortplan
>    * ----------
>    */
>   static TargetEntry *
> --- 831,837 ----
> 
> 
>   /* ----------
> !  * Support function for get scan direction to omit sortplan
>    * ----------
>    */
>   static TargetEntry *
> ***************
> *** 845,855 ****
>    * 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.
>    * ----------
>    */
> ! static bool
> ! need_sortplan(List *sortcls, Plan *plan)
>   {
>   	Relation	indexRel;
>   	IndexScan  *indexScan;
> --- 854,866 ----
>    * Check if a user requested ORDER BY is already satisfied by
>    * the choosen index scan.
>    *
> !  * Returns the direction of Index scan to omit sort,
> !  * if sort is required returns NoMovementScanDirection
> !  *
>    * ----------
>    */
> ! static ScanDirection
> ! get_dir_to_omit_sortplan(List *sortcls, Plan *plan)
>   {
>   	Relation	indexRel;
>   	IndexScan  *indexScan;
> ***************
> *** 858,870 ****
>   	HeapTuple	htup;
>   	Form_pg_index index_tup;
>   	int			key_no = 0;
> 
>   	/* ----------
>   	 * Must be an IndexScan
>   	 * ----------
>   	 */
>   	if (nodeTag(plan) != T_IndexScan)
> ! 		return TRUE;
> 
>   	indexScan = (IndexScan *) plan;
> 
> --- 869,883 ----
>   	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 nodir;
> 
>   	indexScan = (IndexScan *) plan;
> 
> ***************
> *** 873,881 ****
>   	 * ----------
>   	 */
>   	if (plan->lefttree != NULL)
> ! 		return TRUE;
>   	if (plan->righttree != NULL)
> ! 		return TRUE;
> 
>   	/* ----------
>   	 * Must be a single index scan
> --- 886,894 ----
>   	 * ----------
>   	 */
>   	if (plan->lefttree != NULL)
> ! 		return nodir;
>   	if (plan->righttree != NULL)
> ! 		return nodir;
> 
>   	/* ----------
>   	 * Must be a single index scan
> ***************
> *** 882,888 ****
>   	 * ----------
>   	 */
>   	if (length(indexScan->indxid) != 1)
> ! 		return TRUE;
> 
>   	/* ----------
>   	 * Indices can only have up to 8 attributes. So an ORDER BY using
> --- 895,901 ----
>   	 * ----------
>   	 */
>   	if (length(indexScan->indxid) != 1)
> ! 		return nodir;
> 
>   	/* ----------
>   	 * Indices can only have up to 8 attributes. So an ORDER BY using
> ***************
> *** 890,896 ****
>   	 * ----------
>   	 */
>   	if (length(sortcls) > 8)
> ! 		return TRUE;
> 
>   	/* ----------
>   	 * The choosen Index must be a btree
> --- 903,909 ----
>   	 * ----------
>   	 */
>   	if (length(sortcls) > 8)
> ! 		return nodir;
> 
>   	/* ----------
>   	 * The choosen Index must be a btree
> ***************
> *** 902,908 ****
>   	if (strcmp(nameout(&(indexRel->rd_am->amname)), "btree") != 0)
>   	{
>   		heap_close(indexRel);
> ! 		return TRUE;
>   	}
>   	heap_close(indexRel);
> 
> --- 915,921 ----
>   	if (strcmp(nameout(&(indexRel->rd_am->amname)), "btree") != 0)
>   	{
>   		heap_close(indexRel);
> ! 		return nodir;
>   	}
>   	heap_close(indexRel);
> 
> ***************
> *** 937,943 ****
>   			 * Could this happen?
>   			 * ----------
>   			 */
> ! 			return TRUE;
>   		}
>   		if (nodeTag(tle->expr) != T_Var)
>   		{
> --- 950,956 ----
>   			 * Could this happen?
>   			 * ----------
>   			 */
> ! 			return nodir;
>   		}
>   		if (nodeTag(tle->expr) != T_Var)
>   		{
> ***************
> *** 946,952 ****
>   			 * cannot be the indexed attribute
>   			 * ----------
>   			 */
> ! 			return TRUE;
>   		}
>   		var = (Var *) (tle->expr);
> 
> --- 959,965 ----
>   			 * cannot be the indexed attribute
>   			 * ----------
>   			 */
> ! 			return nodir;
>   		}
>   		var = (Var *) (tle->expr);
> 
> ***************
> *** 957,963 ****
>   			 * that of the index
>   			 * ----------
>   			 */
> ! 			return TRUE;
>   		}
> 
>   		if (var->varattno != index_tup->indkey[key_no])
> --- 970,976 ----
>   			 * that of the index
>   			 * ----------
>   			 */
> ! 			return nodir;
>   		}
> 
>   		if (var->varattno != index_tup->indkey[key_no])
> ***************
> *** 966,972 ****
>   			 * It isn't the indexed attribute.
>   			 * ----------
>   			 */
> ! 			return TRUE;
>   		}
> 
>   		if (oprid(oper("<", resdom->restype, resdom->restype, FALSE)) !=
> sortcl->opoid)
> --- 979,985 ----
>   			 * It isn't the indexed attribute.
>   			 * ----------
>   			 */
> ! 			return nodir;
>   		}
> 
>   		if (oprid(oper("<", resdom->restype, resdom->restype, FALSE)) !=
> sortcl->opoid)
> ***************
> *** 975,982 ****
>   			 * Sort order isn't in ascending order.
>   			 * ----------
>   			 */
> ! 			return TRUE;
>   		}
> 
>   		key_no++;
>   	}
> --- 988,1007 ----
>   			 * Sort order isn't in ascending order.
>   			 * ----------
>   			 */
> ! 			if (ScanDirectionIsForward(dir))
> ! 				return nodir;
> ! 			dir = BackwardScanDirection;
>   		}
> + 		else
> + 		{
> + 			/* ----------
> + 			 * Sort order is in ascending order.
> + 			 * ----------
> + 			*/
> + 			if (ScanDirectionIsBackward(dir))
> + 				return nodir;
> + 			dir = ForwardScanDirection;
> + 		}
> 
>   		key_no++;
>   	}
> ***************
> *** 985,989 ****
>   	 * Index matches ORDER BY - sort not required
>   	 * ----------
>   	 */
> ! 	return FALSE;
>   }
> --- 1010,1014 ----
>   	 * Index matches ORDER BY - sort not required
>   	 * ----------
>   	 */
> ! 	return dir;
>   }
> *** ../../head/pgcurrent/backend/executor/nodeIndexscan.c	Mon Jul 26
> 12:44:47 1999
> --- backend/executor/nodeIndexscan.c	Mon Aug  9 10:54:23 1999
> ***************
> *** 99,104 ****
> --- 99,111 ----
>   	 */
>   	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,321 ****
> --- 323,330 ----
>   	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,971 ****
> --- 975,982 ----
>   	}
> 
>   	indexstate->iss_NumIndices = numIndices;
> + 	if (ScanDirectionIsBackward(node->indxorderdir))
> + 		indexPtr = numIndices;
>   	indexstate->iss_IndexPtr = indexPtr;
>   	indexstate->iss_ScanKeys = scanKeys;
>   	indexstate->iss_NumScanKeys = numScanKeys;
> *** ../../head/pgcurrent/backend/optimizer/plan/createplan.c	Mon Aug  9
> 11:31:33 1999
> --- backend/optimizer/plan/createplan.c	Mon Aug  9 11:48:55 1999
> ***************
> *** 1024,1029 ****
> --- 1024,1030 ----
>   	node->indxid = indxid;
>   	node->indxqual = indxqual;
>   	node->indxqualorig = indxqualorig;
> + 	node->indxorderdir = NoMovementScanDirection;
>   	node->scan.scanstate = (CommonScanState *) NULL;
> 
>   	return node;
> *** ../../head/pgcurrent/backend/nodes/copyfuncs.c	Wed Jul 28 15:25:51 1999
> --- backend/nodes/copyfuncs.c	Mon Aug  9 10:55:00 1999
> ***************
> *** 238,243 ****
> --- 238,244 ----
>   	newnode->indxid = listCopy(from->indxid);
>   	Node_Copy(from, newnode, indxqual);
>   	Node_Copy(from, newnode, indxqualorig);
> + 	newnode->indxorderdir = from->indxorderdir;
> 
>   	return newnode;
>   }
> *** ../../head/pgcurrent/backend/nodes/readfuncs.c	Mon Jul 26 14:45:56 1999
> --- backend/nodes/readfuncs.c	Mon Aug  9 11:00:47 1999
> ***************
> *** 532,537 ****
> --- 532,542 ----
>   	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;
>   }
> 
> *** ../../head/pgcurrent/backend/nodes/outfuncs.c	Mon Jul 26 14:45:56 1999
> --- backend/nodes/outfuncs.c	Mon Aug  9 10:55:28 1999
> ***************
> *** 445,450 ****
> --- 445,451 ----
>   	appendStringInfo(str, " :indxqualorig ");
>   	_outNode(str, node->indxqualorig);
> 
> + 	appendStringInfo(str, " :indxorderdir %d ", node->indxorderdir);
>   }
> 
>   /*
> *** ../../head/pgcurrent/backend/nodes/equalfuncs.c	Fri Jul 30 17:29:37
> 1999
> --- backend/nodes/equalfuncs.c	Mon Aug  9 10:55:08 1999
> ***************
> *** 437,442 ****
> --- 437,445 ----
>   	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;
> *** ../../head/pgcurrent/include/nodes/plannodes.h	Mon Jul 26 12:45:39 1999
> --- include/nodes/plannodes.h	Mon Aug  9 10:52:54 1999
> ***************
> *** 175,180 ****
> --- 175,181 ----
>   	List	   *indxid;
>   	List	   *indxqual;
>   	List	   *indxqualorig;
> + 	ScanDirection	indxorderdir;
>   	IndexScanState *indxstate;
>   } IndexScan;
> 
> *** ../../head/pgcurrent/backend/commands/explain.c	Mon Jul 26 12:44:46
> 1999
> --- backend/commands/explain.c	Mon Aug  9 10:53:44 1999
> ***************
> *** 200,205 ****
> --- 200,207 ----
>   	switch (nodeTag(plan))
>   	{
>   		case T_IndexScan:
> + 			if (ScanDirectionIsBackward(((IndexScan *)plan)->indxorderdir))
> + 				appendStringInfo(str, " Backward");
>   			appendStringInfo(str, " using ");
>   			i = 0;
>   			foreach(l, ((IndexScan *) plan)->indxid)
> 
> 
> 


-- 
  Bruce Momjian                        |  http://www.op.net/~candle
  maillist@candle.pha.pa.us            |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

Mon, 9 Aug 1999 00:43:23 -0400 (EDT)
Bruce Momjian <maillist@candle.pha.pa.us>
Re: [PATCHES] Descending order Index scan patch