Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf3a6b38

Browse files
Jan WieckJan Wieck
Jan Wieck
authored and
Jan Wieck
committed
Sort node for ORDER BY is suppressed if choosen index scan will
allways present tuples in the requested order.Jan
1 parent724119a commitf3a6b38

File tree

1 file changed

+175
-2
lines changed

1 file changed

+175
-2
lines changed

‎src/backend/optimizer/plan/planner.c

Lines changed: 175 additions & 2 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.39 1999/02/02 17:46:14 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.40 1999/02/03 19:31:24 wieck Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -50,6 +50,12 @@
5050

5151
#include"executor/executor.h"
5252

53+
#include"utils/builtins.h"
54+
#include"utils/syscache.h"
55+
#include"access/genam.h"
56+
#include"parser/parse_oper.h"
57+
58+
staticboolneed_sortplan(List*sortcls,Plan*plan);
5359
staticPlan*make_sortplan(List*tlist,List*sortcls,Plan*plannode);
5460
externPlan*make_groupPlan(List**tlist,booltuplePerGroup,
5561
List*groupClause,Plan*subplan);
@@ -344,7 +350,7 @@ union_planner(Query *parse)
344350
}
345351
else
346352
{
347-
if (parse->sortClause)
353+
if (parse->sortClause&&need_sortplan(parse->sortClause,result_plan))
348354
return (make_sortplan(tlist,parse->sortClause,result_plan));
349355
else
350356
return ((Plan*)result_plan);
@@ -572,3 +578,170 @@ pg_checkretval(Oid rettype, QueryTreeList *queryTreeList)
572578
/* success */
573579
return;
574580
}
581+
582+
583+
/* ----------
584+
* Support function for need_sortplan
585+
* ----------
586+
*/
587+
staticTargetEntry*
588+
get_matching_tle(Plan*plan,Resdom*resdom)
589+
{
590+
List*i;
591+
TargetEntry*tle;
592+
593+
foreach (i,plan->targetlist) {
594+
tle= (TargetEntry*)lfirst(i);
595+
if (tle->resdom->resno==resdom->resno)
596+
returntle;
597+
}
598+
returnNULL;
599+
}
600+
601+
602+
/* ----------
603+
* Check if a user requested ORDER BY is already satisfied by
604+
* the choosen index scan.
605+
*
606+
* Returns TRUE if sort is required, FALSE if can be omitted.
607+
* ----------
608+
*/
609+
staticbool
610+
need_sortplan(List*sortcls,Plan*plan)
611+
{
612+
RelationindexRel;
613+
IndexScan*indexScan;
614+
OidindexId;
615+
List*i;
616+
HeapTuplehtup;
617+
Form_pg_indexindex_tup;
618+
intkey_no=0;
619+
620+
/* ----------
621+
* Must be an IndexScan
622+
* ----------
623+
*/
624+
if (nodeTag(plan)!=T_IndexScan) {
625+
return TRUE;
626+
}
627+
628+
indexScan= (IndexScan*)plan;
629+
630+
/* ----------
631+
* Should not have left- or righttree
632+
* ----------
633+
*/
634+
if (plan->lefttree!=NULL) {
635+
return TRUE;
636+
}
637+
if (plan->righttree!=NULL) {
638+
return TRUE;
639+
}
640+
641+
/* ----------
642+
* Must be a single index scan
643+
* ----------
644+
*/
645+
if (length(indexScan->indxid)!=1) {
646+
return TRUE;
647+
}
648+
649+
/* ----------
650+
* Indices can only have up to 8 attributes. So an ORDER BY using
651+
* more that 8 attributes could never be satisfied by an index.
652+
* ----------
653+
*/
654+
if (length(sortcls)>8) {
655+
return TRUE;
656+
}
657+
658+
/* ----------
659+
* The choosen Index must be a btree
660+
* ----------
661+
*/
662+
indexId=lfirsti(indexScan->indxid);
663+
664+
indexRel=index_open(indexId);
665+
if (strcmp(nameout(&(indexRel->rd_am->amname)),"btree")!=0) {
666+
heap_close(indexRel);
667+
return TRUE;
668+
}
669+
heap_close(indexRel);
670+
671+
/* ----------
672+
* Fetch the index tuple
673+
* ----------
674+
*/
675+
htup=SearchSysCacheTuple(INDEXRELID,
676+
ObjectIdGetDatum(indexId),0,0,0);
677+
if (!HeapTupleIsValid(htup)) {
678+
elog(ERROR,"cache lookup for index %d failed",indexId);
679+
}
680+
index_tup= (Form_pg_index)GETSTRUCT(htup);
681+
682+
/* ----------
683+
* Check if all the sort clauses match the attributes in the index
684+
* ----------
685+
*/
686+
foreach (i,sortcls) {
687+
SortClause*sortcl;
688+
Resdom*resdom;
689+
TargetEntry*tle;
690+
Var*var;
691+
692+
sortcl= (SortClause*)lfirst(i);
693+
694+
resdom=sortcl->resdom;
695+
tle=get_matching_tle(plan,resdom);
696+
if (tle==NULL) {
697+
/* ----------
698+
* Could this happen?
699+
* ----------
700+
*/
701+
return TRUE;
702+
}
703+
if (nodeTag(tle->expr)!=T_Var) {
704+
/* ----------
705+
* The target list expression isn't a var, so it
706+
* cannot be the indexed attribute
707+
* ----------
708+
*/
709+
return TRUE;
710+
}
711+
var= (Var*)(tle->expr);
712+
713+
if (var->varno!=indexScan->scan.scanrelid) {
714+
/* ----------
715+
* This Var isn't from the scan relation. So it isn't
716+
* that of the index
717+
* ----------
718+
*/
719+
return TRUE;
720+
}
721+
722+
if (var->varattno!=index_tup->indkey[key_no]) {
723+
/* ----------
724+
* It isn't the indexed attribute.
725+
* ----------
726+
*/
727+
return TRUE;
728+
}
729+
730+
if (oprid(oper("<",resdom->restype,resdom->restype, FALSE))!=sortcl->opoid) {
731+
/* ----------
732+
* Sort order isn't in ascending order.
733+
* ----------
734+
*/
735+
return TRUE;
736+
}
737+
738+
key_no++;
739+
}
740+
741+
/* ----------
742+
* Index matches ORDER BY - sort not required
743+
* ----------
744+
*/
745+
return FALSE;
746+
}
747+

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp