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

Commit78351f4

Browse files
committed
Fix for backward cursors with ORDER BY.
1 parent9acf938 commit78351f4

File tree

2 files changed

+113
-25
lines changed

2 files changed

+113
-25
lines changed

‎src/backend/utils/sort/psort.c

Lines changed: 111 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/utils/sort/Attic/psort.c,v 1.25 1997/09/26 20:05:47 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/utils/sort/Attic/psort.c,v 1.26 1997/10/15 06:36:08 vadim Exp $
1111
*
1212
* NOTES
1313
*Sorts the first relation into the second relation.
@@ -80,7 +80,12 @@ static int _psort_cmp (HeapTuple *ltup, HeapTuple *rtup);
8080

8181
#defineTEMPDIR "./"
8282

83-
staticlongshortzero=0;/* used to delimit runs */
83+
/*
84+
* tlenzero used to delimit runs; both vars below must have
85+
* the same size as HeapTuple->t_len
86+
*/
87+
staticunsignedinttlenzero=0;
88+
staticunsignedinttlendummy;
8489

8590
staticTupleDescPsortTupDesc;
8691
staticScanKeyPsortKeys;/* used by _psort_cmp */
@@ -150,6 +155,7 @@ psort_begin(Sort * node, int nkeys, ScanKey key)
150155
PS(node)->tupcount=0;
151156

152157
PS(node)->using_tape_files= false;
158+
PS(node)->all_fetched= false;
153159
PS(node)->psort_grab_file=NULL;
154160
PS(node)->memtuples=NULL;
155161

@@ -219,21 +225,24 @@ inittapes(Sort * node)
219225
*GETTUP- reads the tuple
220226
*
221227
*Note:
222-
*LEN field must bea short; FP is a stream
228+
*LEN field must beas HeapTuple->t_len; FP is a stream
223229
*/
224230

225231

226232
#definePUTTUP(NODE,TUP,FP) do {\
227233
((Psortstate *)NODE->psortstate)->BytesWritten += (TUP)->t_len; \
228-
fwrite((char *)TUP, (TUP)->t_len, 1, FP);} while (0)
229-
#defineENDRUN(FP)fwrite((char *)&shortzero, sizeof (shortzero), 1, FP)
230-
#defineGETLEN(LEN,FP) fread((char *)&(LEN), sizeof (shortzero), 1, FP)
234+
fwrite((char *)TUP, (TUP)->t_len, 1, FP); \
235+
fwrite((char *)&((TUP)->t_len), sizeof (tlendummy), 1, FP); \
236+
} while (0)
237+
#defineENDRUN(FP)fwrite((char *)&tlenzero, sizeof (tlenzero), 1, FP)
238+
#defineGETLEN(LEN,FP) fread((char *)&(LEN), sizeof (tlenzero), 1, FP)
231239
#defineALLOCTUP(LEN)((HeapTuple)palloc((unsigned)LEN))
232240
#defineGETTUP(NODE,TUP,LEN,FP) do {\
233241
IncrProcessed(); \
234-
((Psortstate *)NODE->psortstate)->BytesRead += (LEN) - sizeof (shortzero); \
235-
fread((char *)(TUP) + sizeof (shortzero), (LEN) - sizeof (shortzero), 1, FP);} \
236-
while (0)
242+
((Psortstate *)NODE->psortstate)->BytesRead += (LEN) - sizeof (tlenzero); \
243+
fread((char *)(TUP) + sizeof (tlenzero), (LEN) - sizeof (tlenzero), 1, FP); \
244+
fread((char *)&tlendummy, sizeof (tlendummy), 1, FP); \
245+
} while (0)
237246
#defineSETTUPLEN(TUP,LEN)(TUP)->t_len = LEN
238247

239248
/*
@@ -629,11 +638,11 @@ merge(Sort * node, struct tape * dest)
629638
registerstructtape*lasttp;/* (TAPE[P]) */
630639
registerstructtape*tp;
631640
structleftist*tuples;
632-
FILE*destfile;
633-
inttimes;/* runs left to merge */
634-
intoutdummy;/* complete dummy runs */
635-
shortfromtape;
636-
longtuplen;
641+
FILE*destfile;
642+
inttimes;/* runs left to merge */
643+
intoutdummy;/* complete dummy runs */
644+
shortfromtape;
645+
unsignedinttuplen;
637646

638647
Assert(node!= (Sort*)NULL);
639648
Assert(PS(node)!= (Psortstate*)NULL);
@@ -767,42 +776,120 @@ dumptuples(FILE * file, Sort * node)
767776
HeapTuple
768777
psort_grabtuple(Sort*node,bool*should_free)
769778
{
770-
registerHeapTupletup;
771-
longtuplen;
779+
registerHeapTupletup;
772780

773781
Assert(node!= (Sort*)NULL);
774782
Assert(PS(node)!= (Psortstate*)NULL);
775783

776784
if (PS(node)->using_tape_files== true)
777785
{
778-
if (!feof(PS(node)->psort_grab_file))
786+
unsignedinttuplen;
787+
788+
*should_free= true;
789+
if (ScanDirectionIsForward (node->plan.state->es_direction))
779790
{
791+
if (PS(node)->all_fetched)
792+
returnNULL;
780793
if (GETLEN(tuplen,PS(node)->psort_grab_file)&&tuplen!=0)
781794
{
782795
tup= (HeapTuple)palloc((unsigned)tuplen);
783796
SETTUPLEN(tup,tuplen);
784797
GETTUP(node,tup,tuplen,PS(node)->psort_grab_file);
785798

786799
/* Update current merged sort file position */
787-
PS(node)->psort_current+=tuplen;
788-
*should_free= true;
800+
PS(node)->psort_current+=tuplen+sizeof (tlendummy);
789801
returntup;
790802
}
791803
else
804+
{
805+
PS(node)->all_fetched= true;
792806
returnNULL;
807+
}
793808
}
794-
else
809+
/* Backward */
810+
if (PS(node)->psort_current <=sizeof (tlendummy))
795811
returnNULL;
812+
/*
813+
* if all tuples are fetched already then we return last tuple,
814+
* else - tuple before last returned.
815+
*/
816+
if (PS(node)->all_fetched)
817+
{
818+
/* psort_current is pointing to the zero tuplen at the end of file */
819+
fseek(PS(node)->psort_grab_file,
820+
PS(node)->psort_current-sizeof (tlendummy),SEEK_SET);
821+
GETLEN(tuplen,PS(node)->psort_grab_file);
822+
if (PS(node)->psort_current<tuplen)
823+
elog (FATAL,"psort_grabtuple: too big last tuple len in backward scan");
824+
PS(node)->all_fetched= false;
825+
}
826+
else
827+
{
828+
/* move to position of end tlen of prev tuple */
829+
PS(node)->psort_current-=sizeof (tlendummy);
830+
fseek(PS(node)->psort_grab_file,PS(node)->psort_current,SEEK_SET);
831+
GETLEN(tuplen,PS(node)->psort_grab_file);/* get tlen of prev tuple */
832+
if (tuplen==0)
833+
elog (FATAL,"psort_grabtuple: tuplen is 0 in backward scan");
834+
if (PS(node)->psort_current <=tuplen+sizeof (tlendummy))
835+
{/* prev tuple should be first one */
836+
if (PS(node)->psort_current!=tuplen)
837+
elog (FATAL,"psort_grabtuple: first tuple expected in backward scan");
838+
PS(node)->psort_current=0;
839+
fseek(PS(node)->psort_grab_file,PS(node)->psort_current,SEEK_SET);
840+
returnNULL;
841+
}
842+
/*
843+
* Get position of prev tuple. This tuple becomes current tuple
844+
* now and we have to return previous one.
845+
*/
846+
PS(node)->psort_current-=tuplen;
847+
/* move to position of end tlen of prev tuple */
848+
fseek(PS(node)->psort_grab_file,
849+
PS(node)->psort_current-sizeof (tlendummy),SEEK_SET);
850+
GETLEN(tuplen,PS(node)->psort_grab_file);
851+
if (PS(node)->psort_current<tuplen+sizeof (tlendummy))
852+
elog (FATAL,"psort_grabtuple: too big tuple len in backward scan");
853+
}
854+
/*
855+
* move to prev (or last) tuple start position + sizeof(t_len)
856+
*/
857+
fseek(PS(node)->psort_grab_file,
858+
PS(node)->psort_current-tuplen,SEEK_SET);
859+
tup= (HeapTuple)palloc((unsigned)tuplen);
860+
SETTUPLEN(tup,tuplen);
861+
GETTUP(node,tup,tuplen,PS(node)->psort_grab_file);
862+
returntup;/* file position is equal to psort_current */
796863
}
797864
else
798865
{
799-
if (PS(node)->psort_current<PS(node)->tupcount)
866+
*should_free= false;
867+
if (ScanDirectionIsForward (node->plan.state->es_direction))
800868
{
801-
*should_free= false;
802-
return (PS(node)->memtuples[PS(node)->psort_current++]);
869+
if (PS(node)->psort_current<PS(node)->tupcount)
870+
return (PS(node)->memtuples[PS(node)->psort_current++]);
871+
else
872+
{
873+
PS(node)->all_fetched= true;
874+
returnNULL;
875+
}
803876
}
804-
else
877+
/* Backward */
878+
if (PS(node)->psort_current <=0)
805879
returnNULL;
880+
/*
881+
* if all tuples are fetched already then we return last tuple,
882+
* else - tuple before last returned.
883+
*/
884+
if (PS(node)->all_fetched)
885+
PS(node)->all_fetched= false;
886+
else
887+
{
888+
PS(node)->psort_current--;/* last returned tuple */
889+
if (PS(node)->psort_current <=0)
890+
returnNULL;
891+
}
892+
return (PS(node)->memtuples[PS(node)->psort_current-1]);
806893
}
807894
}
808895

‎src/include/utils/psort.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: psort.h,v 1.13 1997/09/18 14:42:35 vadim Exp $
9+
* $Id: psort.h,v 1.14 1997/10/15 06:36:36 vadim Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -62,6 +62,7 @@ typedef struct Psortstate
6262
longpsort_current;/* could be file offset, or array index */
6363
longpsort_saved;/* could be file offset, or array index */
6464
boolusing_tape_files;
65+
boolall_fetched;/* this is for cursors */
6566

6667
HeapTuple*memtuples;
6768
}Psortstate;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp