Re: [PATCHES] Descending order Index scan patch

Поиск
Список
Период
Сортировка
От Bruce Momjian
Тема Re: [PATCHES] Descending order Index scan patch
Дата
Msg-id 199908090443.AAA14719@candle.pha.pa.us
обсуждение исходный текст
Ответ на Descending order Index scan patch  ("Hiroshi Inoue" <Inoue@tpf.co.jp>)
Список pgsql-hackers
[Charset iso-8859-1 unsupported, filtering to ASCII...]
> 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
> 


This patch is broken.  See the wrapping that happened to the /**** line.
Please resubmit.


> *** ../../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)
> 
> 
> 


--  Bruce Momjian                        |  http://www.op.net/~candle maillist@candle.pha.pa.us            |  (610)
853-3000+  If your life is a hard drive,     |  830 Blythe Avenue +  Christ can be your backup.        |  Drexel Hill,
Pennsylvania19026
 


В списке pgsql-hackers по дате отправления:

Предыдущее
От: "Hub.Org News Admin"
Дата:
Сообщение: ...
Следующее
От: wieck@debis.com (Jan Wieck)
Дата:
Сообщение: Re: plpgsql requires bison