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

Commit91f82de

Browse files
committed
Assign sort keys properly when there are duplicate entries in
pathkey list --- corrects misbehavior seen with multiple mergejoin clausesmentioning same variable.
1 parent5517938 commit91f82de

File tree

1 file changed

+63
-35
lines changed

1 file changed

+63
-35
lines changed

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

Lines changed: 63 additions & 35 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/createplan.c,v 1.71 1999/08/1602:17:53 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.72 1999/08/1623:07:20 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -28,7 +28,7 @@
2828

2929

3030
staticList*switch_outer(List*clauses);
31-
staticList*set_tlist_sort_info(List*tlist,List*pathkeys);
31+
staticintset_tlist_sort_info(List*tlist,List*pathkeys);
3232
staticScan*create_scan_node(Path*best_path,List*tlist);
3333
staticJoin*create_join_node(JoinPath*best_path,List*tlist);
3434
staticSeqScan*create_seqscan_node(Path*best_path,List*tlist,
@@ -804,40 +804,65 @@ switch_outer(List *clauses)
804804
* Sets the reskey and reskeyop fields of resdom nodes in a target list
805805
* for a sort node.
806806
*
807-
* 'tlist' is the target list
807+
* 'tlist' is the target list (which is modified in-place).
808+
*tlist's reskey fields must be clear to start with.
808809
* 'pathkeys' is the desired pathkeys for the sort. NIL means no sort.
809810
*
810-
* Returns the modified-in-place target list.
811+
* Returns the number of sort keys assigned (which might be less than
812+
* length(pathkeys)!)
811813
*/
812-
staticList*
814+
staticint
813815
set_tlist_sort_info(List*tlist,List*pathkeys)
814816
{
815-
intkeyno=1;
817+
intkeysassigned=0;
816818
List*i;
817819

818820
foreach(i,pathkeys)
819821
{
820822
List*keysublist= (List*)lfirst(i);
821-
PathKeyItem*pathkey;
822-
Resdom*resdom;
823+
PathKeyItem*pathkey=NULL;
824+
Resdom*resdom=NULL;
825+
List*j;
823826

824827
/*
825828
* We can sort by any one of the sort key items listed in this
826-
* sublist. For now, we always take the first one --- is there
827-
* any way of figuring out which might be cheapest to execute?
828-
* (For example, int4lt is likely much cheaper to execute than
829-
* numericlt, but both might appear in the same pathkey sublist...)
829+
* sublist. For now, we take the first one that corresponds to
830+
* an available Var in the tlist.
831+
*
832+
* XXX if we have a choice, is there any way of figuring out which
833+
* might be cheapest to execute? (For example, int4lt is likely
834+
* much cheaper to execute than numericlt, but both might appear in
835+
* the same pathkey sublist...) Not clear that we ever will have
836+
* a choice in practice, so it may not matter.
830837
*/
831-
pathkey=lfirst(keysublist);
832-
Assert(IsA(pathkey,PathKeyItem));
833-
resdom=tlist_member((Var*)pathkey->key,tlist);
838+
foreach(j,keysublist)
839+
{
840+
pathkey=lfirst(j);
841+
Assert(IsA(pathkey,PathKeyItem));
842+
resdom=tlist_member((Var*)pathkey->key,tlist);
843+
if (resdom)
844+
break;
845+
}
834846
if (!resdom)
835847
elog(ERROR,"set_tlist_sort_info: cannot find tlist item to sort");
836-
resdom->reskey=keyno;
837-
resdom->reskeyop=get_opcode(pathkey->sortop);
838-
keyno++;
848+
849+
/*
850+
* The resdom might be already marked as a sort key, if the pathkeys
851+
* contain duplicate entries. (This can happen in scenarios where
852+
* multiple mergejoinable clauses mention the same var, for example.)
853+
* In that case the current pathkey is essentially a no-op, because
854+
* only one value can be seen within any subgroup where it would be
855+
* consulted. We can ignore it.
856+
*/
857+
if (resdom->reskey==0)
858+
{
859+
/* OK, mark it as a sort key and set the sort operator regproc */
860+
resdom->reskey=++keysassigned;
861+
resdom->reskeyop=get_opcode(pathkey->sortop);
862+
}
839863
}
840-
returntlist;
864+
865+
returnkeysassigned;
841866
}
842867

843868
/*
@@ -885,34 +910,37 @@ make_noname(List *tlist,
885910
Plan*plan_node)
886911
{
887912
List*noname_tlist;
913+
intnumsortkeys;
914+
Plan*tmpplan;
888915
Noname*retval;
889916

890917
/* Create a new target list for the noname, with sort keys set. */
891-
noname_tlist=set_tlist_sort_info(new_unsorted_tlist(tlist),
892-
pathkeys);
918+
noname_tlist=new_unsorted_tlist(tlist);
919+
numsortkeys=set_tlist_sort_info(noname_tlist,pathkeys);
893920

894-
if (pathkeys!=NIL)
921+
if (numsortkeys>0)
895922
{
896923
/* need to sort */
897-
retval= (Noname*)make_seqscan(tlist,
898-
NIL,
899-
_NONAME_RELATION_ID_,
900-
(Plan*)make_sort(noname_tlist,
901-
_NONAME_RELATION_ID_,
902-
plan_node,
903-
length(pathkeys)));
924+
tmpplan= (Plan*)make_sort(noname_tlist,
925+
_NONAME_RELATION_ID_,
926+
plan_node,
927+
numsortkeys);
904928
}
905929
else
906930
{
907931
/* no sort */
908-
retval= (Noname*)make_seqscan(tlist,
909-
NIL,
932+
tmpplan= (Plan*)make_material(noname_tlist,
910933
_NONAME_RELATION_ID_,
911-
(Plan*)make_material(noname_tlist,
912-
_NONAME_RELATION_ID_,
913-
plan_node,
914-
0));
934+
plan_node,
935+
0);
915936
}
937+
938+
/* Return a seqscan using the original tlist */
939+
retval= (Noname*)make_seqscan(tlist,
940+
NIL,
941+
_NONAME_RELATION_ID_,
942+
tmpplan);
943+
916944
returnretval;
917945
}
918946

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp