]> granicus.if.org Git - postgresql/commitdiff
> > Prevent sorting if result is already sorted
authorBruce Momjian <bruce@momjian.us>
Mon, 9 Aug 1999 06:20:27 +0000 (06:20 +0000)
committerBruce Momjian <bruce@momjian.us>
Mon, 9 Aug 1999 06:20:27 +0000 (06:20 +0000)
> >
> > 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.
> >
Hiroshi Inoue
Inoue@tpf.co.jp

src/backend/commands/explain.c
src/backend/executor/nodeIndexscan.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/nodes/outfuncs.c
src/backend/nodes/readfuncs.c
src/backend/optimizer/plan/createplan.c
src/backend/optimizer/plan/planner.c
src/include/nodes/plannodes.h

index 460fdcc1f91254bf14094acd438fc8910b8c1319..31a8d9d3679fb91cb3df4f22ad8d933364899785 100644 (file)
@@ -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)
index 0a35cf2cf8c360797476d3327452880533b57634..7be2f1b8c99a40f23929155a547fc513e061309b 100644 (file)
@@ -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;
index db97c2ed39bb57ef47f85492ca96d625286f55fa..ca2bd33a2c1c94348693202835cb0ad160180d2e 100644 (file)
@@ -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;
 }
index 576601faf57021958405b59fced01cada4c1496a..337e63a61561b67172763e65010ddd5a052099df 100644 (file)
@@ -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;
index 4272bf04cc5208e6e0b6d5858d18a5618761c850..5c9f4599deb7fd3df1ebb2b9ea37b961c6f75984 100644 (file)
@@ -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);
 }
 
 /*
index e16398fb85481b10b9dc20d3d162094bec38133e..c49ad053f1bcf12051111db5be6ad699ce1f40df 100644 (file)
@@ -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;
 }
 
index d3d79f6ef8a137369450f2ebc4d4b15748389d77..dbc6ac9d289e0b6feb4ac1f92a6357ae042d5370 100644 (file)
@@ -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;
index 41bb025e286f279b9c27d9633c056fe2e610b686..17ad449839b24496fe8efa6dc7b330d02afdc973 100644 (file)
@@ -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;
 }
index 3d319a66ff7c078d33b1b055025e9fab1a92fdc1..532be5196bf8f4a877972f537be7d831db8bb255 100644 (file)
@@ -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;