Descending order Index scan patch - Mailing list pgsql-hackers
From | Hiroshi Inoue |
---|---|
Subject | Descending order Index scan patch |
Date | |
Msg-id | 000401bee213$79888a40$2801007e@cadzone.tpf.co.jp Whole thread Raw |
Responses |
Re: [PATCHES] Descending order Index scan patch
|
List | pgsql-hackers |
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)
pgsql-hackers by date: