77 *
88 *
99 * IDENTIFICATION
10- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.61 1999/07/17 20:17:15 momjian Exp $
10+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.62 1999/08/09 06: 20:26 momjian Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
@@ -39,7 +39,7 @@ static List *make_subplanTargetList(Query *parse, List *tlist,
3939static Plan * make_groupplan (List * group_tlist ,bool tuplePerGroup ,
4040List * groupClause ,AttrNumber * grpColIdx ,
4141Plan * subplan );
42- static bool need_sortplan (List * sortcls ,Plan * plan );
42+ static ScanDirection get_dir_to_omit_sortplan (List * sortcls ,Plan * plan );
4343static Plan * make_sortplan (List * tlist ,List * sortcls ,Plan * plannode );
4444
4545/*****************************************************************************
@@ -303,8 +303,17 @@ union_planner(Query *parse)
303303}
304304else
305305{
306- if (parse -> sortClause && need_sortplan (parse -> sortClause ,result_plan ))
307- return (make_sortplan (tlist ,parse -> sortClause ,result_plan ));
306+ if (parse -> sortClause )
307+ {
308+ ScanDirection dir = get_dir_to_omit_sortplan (parse -> sortClause ,result_plan );
309+ if (ScanDirectionIsNoMovement (dir ))
310+ return (make_sortplan (tlist ,parse -> sortClause ,result_plan ));
311+ else
312+ {
313+ ((IndexScan * )result_plan )-> indxorderdir = dir ;
314+ return ((Plan * )result_plan );
315+ }
316+ }
308317else
309318return ((Plan * )result_plan );
310319}
@@ -822,7 +831,7 @@ pg_checkretval(Oid rettype, List *queryTreeList)
822831
823832
824833/* ----------
825- * Support function forneed_sortplan
834+ * Support function forget scan direction to omit sortplan
826835 * ----------
827836 */
828837static TargetEntry *
@@ -845,11 +854,13 @@ get_matching_tle(Plan *plan, Resdom *resdom)
845854 * Check if a user requested ORDER BY is already satisfied by
846855 * the choosen index scan.
847856 *
848- * Returns TRUE if sort is required, FALSE if can be omitted.
857+ * Returns the direction of Index scan to omit sort,
858+ * if sort is required returns NoMovementScanDirection
859+ *
849860 * ----------
850861 */
851- static bool
852- need_sortplan (List * sortcls ,Plan * plan )
862+ static ScanDirection
863+ get_dir_to_omit_sortplan (List * sortcls ,Plan * plan )
853864{
854865Relation indexRel ;
855866IndexScan * indexScan ;
@@ -858,13 +869,15 @@ need_sortplan(List *sortcls, Plan *plan)
858869HeapTuple htup ;
859870Form_pg_index index_tup ;
860871int key_no = 0 ;
872+ ScanDirection dir ,nodir = NoMovementScanDirection ;
861873
874+ dir = nodir ;
862875/* ----------
863876 * Must be an IndexScan
864877 * ----------
865878 */
866879if (nodeTag (plan )!= T_IndexScan )
867- return TRUE ;
880+ return nodir ;
868881
869882indexScan = (IndexScan * )plan ;
870883
@@ -873,24 +886,24 @@ need_sortplan(List *sortcls, Plan *plan)
873886 * ----------
874887 */
875888if (plan -> lefttree != NULL )
876- return TRUE ;
889+ return nodir ;
877890if (plan -> righttree != NULL )
878- return TRUE ;
891+ return nodir ;
879892
880893/* ----------
881894 * Must be a single index scan
882895 * ----------
883896 */
884897if (length (indexScan -> indxid )!= 1 )
885- return TRUE ;
898+ return nodir ;
886899
887900/* ----------
888901 * Indices can only have up to 8 attributes. So an ORDER BY using
889902 * more that 8 attributes could never be satisfied by an index.
890903 * ----------
891904 */
892905if (length (sortcls )> 8 )
893- return TRUE ;
906+ return nodir ;
894907
895908/* ----------
896909 * The choosen Index must be a btree
@@ -902,7 +915,7 @@ need_sortplan(List *sortcls, Plan *plan)
902915if (strcmp (nameout (& (indexRel -> rd_am -> amname )),"btree" )!= 0 )
903916{
904917heap_close (indexRel );
905- return TRUE ;
918+ return nodir ;
906919}
907920heap_close (indexRel );
908921
@@ -937,7 +950,7 @@ need_sortplan(List *sortcls, Plan *plan)
937950 * Could this happen?
938951 * ----------
939952 */
940- return TRUE ;
953+ return nodir ;
941954}
942955if (nodeTag (tle -> expr )!= T_Var )
943956{
@@ -946,7 +959,7 @@ need_sortplan(List *sortcls, Plan *plan)
946959 * cannot be the indexed attribute
947960 * ----------
948961 */
949- return TRUE ;
962+ return nodir ;
950963}
951964var = (Var * ) (tle -> expr );
952965
@@ -957,7 +970,7 @@ need_sortplan(List *sortcls, Plan *plan)
957970 * that of the index
958971 * ----------
959972 */
960- return TRUE ;
973+ return nodir ;
961974}
962975
963976if (var -> varattno != index_tup -> indkey [key_no ])
@@ -966,7 +979,7 @@ need_sortplan(List *sortcls, Plan *plan)
966979 * It isn't the indexed attribute.
967980 * ----------
968981 */
969- return TRUE ;
982+ return nodir ;
970983}
971984
972985if (oprid (oper ("<" ,resdom -> restype ,resdom -> restype , FALSE))!= sortcl -> opoid )
@@ -975,7 +988,19 @@ need_sortplan(List *sortcls, Plan *plan)
975988 * Sort order isn't in ascending order.
976989 * ----------
977990 */
978- return TRUE;
991+ if (ScanDirectionIsForward (dir ))
992+ return nodir ;
993+ dir = BackwardScanDirection ;
994+ }
995+ else
996+ {
997+ /* ----------
998+ * Sort order is in ascending order.
999+ * ----------
1000+ */
1001+ if (ScanDirectionIsBackward (dir ))
1002+ return nodir ;
1003+ dir = ForwardScanDirection ;
9791004}
9801005
9811006key_no ++ ;
@@ -985,5 +1010,5 @@ need_sortplan(List *sortcls, Plan *plan)
9851010 * Index matches ORDER BY - sort not required
9861011 * ----------
9871012 */
988- return FALSE ;
1013+ return dir ;
9891014}