aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/planner.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan/planner.c')
-rw-r--r--src/backend/optimizer/plan/planner.c65
1 files changed, 45 insertions, 20 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 41bb025e286..17ad449839b 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;
}