Skip to content

Commit 158fd5f

Browse files
committed
> > 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. > > Hiroshi Inoue Inoue@tpf.co.jp
1 parent 5efe312 commit 158fd5f

File tree

9 files changed

+78
-28
lines changed

9 files changed

+78
-28
lines changed

src/backend/commands/explain.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*
55
* Copyright (c) 1994-5, Regents of the University of California
66
*
7-
* $Id: explain.c,v 1.43 1999/07/17 20:16:52 momjian Exp $
7+
* $Id: explain.c,v 1.44 1999/08/09 06:20:21 momjian Exp $
88
*
99
*/
1010

@@ -200,6 +200,8 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
200200
switch (nodeTag(plan))
201201
{
202202
case T_IndexScan:
203+
if (ScanDirectionIsBackward(((IndexScan *)plan)->indxorderdir))
204+
appendStringInfo(str, " Backward");
203205
appendStringInfo(str, " using ");
204206
i = 0;
205207
foreach(l, ((IndexScan *) plan)->indxid)

src/backend/executor/nodeIndexscan.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.40 1999/07/16 04:58:50 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.41 1999/08/09 06:20:22 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -99,6 +99,13 @@ IndexNext(IndexScan *node)
9999
*/
100100
estate = node->scan.plan.state;
101101
direction = estate->es_direction;
102+
if (ScanDirectionIsBackward(node->indxorderdir))
103+
{
104+
if (ScanDirectionIsForward(direction))
105+
direction = BackwardScanDirection;
106+
else if (ScanDirectionIsBackward(direction))
107+
direction = ForwardScanDirection;
108+
}
102109
snapshot = estate->es_snapshot;
103110
scanstate = node->scan.scanstate;
104111
indexstate = node->indxstate;
@@ -316,6 +323,8 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
316323
indxqual = node->indxqual;
317324
numScanKeys = indexstate->iss_NumScanKeys;
318325
indexstate->iss_IndexPtr = -1;
326+
if (ScanDirectionIsBackward(node->indxorderdir))
327+
indexstate->iss_IndexPtr = numIndices;
319328

320329
/* If this is re-scanning of PlanQual ... */
321330
if (estate->es_evTuple != NULL &&
@@ -966,6 +975,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
966975
}
967976

968977
indexstate->iss_NumIndices = numIndices;
978+
if (ScanDirectionIsBackward(node->indxorderdir))
979+
indexPtr = numIndices;
969980
indexstate->iss_IndexPtr = indexPtr;
970981
indexstate->iss_ScanKeys = scanKeys;
971982
indexstate->iss_NumScanKeys = numScanKeys;

src/backend/nodes/copyfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.89 1999/07/27 03:51:07 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.90 1999/08/09 06:20:23 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -238,6 +238,7 @@ _copyIndexScan(IndexScan *from)
238238
newnode->indxid = listCopy(from->indxid);
239239
Node_Copy(from, newnode, indxqual);
240240
Node_Copy(from, newnode, indxqualorig);
241+
newnode->indxorderdir = from->indxorderdir;
241242

242243
return newnode;
243244
}

src/backend/nodes/equalfuncs.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.45 1999/07/29 02:45:36 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.46 1999/08/09 06:20:24 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -437,6 +437,9 @@ _equalIndexScan(IndexScan *a, IndexScan *b)
437437
if (a->scan.scanrelid != b->scan.scanrelid)
438438
return false;
439439

440+
if (a->indxorderdir != b->indxorderdir)
441+
return false;
442+
440443
if (!equali(a->indxid, b->indxid))
441444
return false;
442445
return true;

src/backend/nodes/outfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*
66
* Copyright (c) 1994, Regents of the University of California
77
*
8-
* $Id: outfuncs.c,v 1.91 1999/07/24 23:21:07 tgl Exp $
8+
* $Id: outfuncs.c,v 1.92 1999/08/09 06:20:24 momjian Exp $
99
*
1010
* NOTES
1111
* Every (plan) node in POSTGRES has an associated "out" routine which
@@ -445,6 +445,7 @@ _outIndexScan(StringInfo str, IndexScan *node)
445445
appendStringInfo(str, " :indxqualorig ");
446446
_outNode(str, node->indxqualorig);
447447

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

450451
/*

src/backend/nodes/readfuncs.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.70 1999/07/24 23:21:08 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.71 1999/08/09 06:20:24 momjian Exp $
1111
*
1212
* NOTES
1313
* Most of the read functions for plan nodes are tested. (In fact, they
@@ -532,6 +532,11 @@ _readIndexScan()
532532
token = lsptok(NULL, &length); /* eat :indxqualorig */
533533
local_node->indxqualorig = nodeRead(true); /* now read it */
534534

535+
token = lsptok(NULL, &length); /* eat :indxorderdir */
536+
token = lsptok(NULL, &length); /* get indxorderdir */
537+
538+
local_node->indxorderdir = atoi(token);
539+
535540
return local_node;
536541
}
537542

src/backend/optimizer/plan/createplan.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.67 1999/08/09 01:01:42 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.68 1999/08/09 06:20:26 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -1024,6 +1024,7 @@ make_indexscan(List *qptlist,
10241024
node->indxid = indxid;
10251025
node->indxqual = indxqual;
10261026
node->indxqualorig = indxqualorig;
1027+
node->indxorderdir = NoMovementScanDirection;
10271028
node->scan.scanstate = (CommonScanState *) NULL;
10281029

10291030
return node;

src/backend/optimizer/plan/planner.c

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
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,
3939
static Plan *make_groupplan(List *group_tlist, bool tuplePerGroup,
4040
List *groupClause, AttrNumber *grpColIdx,
4141
Plan *subplan);
42-
static bool need_sortplan(List *sortcls, Plan *plan);
42+
static ScanDirection get_dir_to_omit_sortplan(List *sortcls, Plan *plan);
4343
static Plan *make_sortplan(List *tlist, List *sortcls, Plan *plannode);
4444

4545
/*****************************************************************************
@@ -303,8 +303,17 @@ union_planner(Query *parse)
303303
}
304304
else
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+
}
308317
else
309318
return ((Plan *) result_plan);
310319
}
@@ -822,7 +831,7 @@ pg_checkretval(Oid rettype, List *queryTreeList)
822831

823832

824833
/* ----------
825-
* Support function for need_sortplan
834+
* Support function for get scan direction to omit sortplan
826835
* ----------
827836
*/
828837
static 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
{
854865
Relation indexRel;
855866
IndexScan *indexScan;
@@ -858,13 +869,15 @@ need_sortplan(List *sortcls, Plan *plan)
858869
HeapTuple htup;
859870
Form_pg_index index_tup;
860871
int key_no = 0;
872+
ScanDirection dir, nodir = NoMovementScanDirection;
861873

874+
dir = nodir;
862875
/* ----------
863876
* Must be an IndexScan
864877
* ----------
865878
*/
866879
if (nodeTag(plan) != T_IndexScan)
867-
return TRUE;
880+
return nodir;
868881

869882
indexScan = (IndexScan *) plan;
870883

@@ -873,24 +886,24 @@ need_sortplan(List *sortcls, Plan *plan)
873886
* ----------
874887
*/
875888
if (plan->lefttree != NULL)
876-
return TRUE;
889+
return nodir;
877890
if (plan->righttree != NULL)
878-
return TRUE;
891+
return nodir;
879892

880893
/* ----------
881894
* Must be a single index scan
882895
* ----------
883896
*/
884897
if (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
*/
892905
if (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)
902915
if (strcmp(nameout(&(indexRel->rd_am->amname)), "btree") != 0)
903916
{
904917
heap_close(indexRel);
905-
return TRUE;
918+
return nodir;
906919
}
907920
heap_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
}
942955
if (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
}
951964
var = (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

963976
if (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

972985
if (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

9811006
key_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
}

src/include/nodes/plannodes.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Id: plannodes.h,v 1.28 1999/07/15 23:03:55 momjian Exp $
9+
* $Id: plannodes.h,v 1.29 1999/08/09 06:20:27 momjian Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -175,6 +175,7 @@ typedef struct IndexScan
175175
List *indxid;
176176
List *indxqual;
177177
List *indxqualorig;
178+
ScanDirection indxorderdir;
178179
IndexScanState *indxstate;
179180
} IndexScan;
180181

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy