diff options
Diffstat (limited to 'src/backend/utils/sort/psort.c')
-rw-r--r-- | src/backend/utils/sort/psort.c | 112 |
1 files changed, 57 insertions, 55 deletions
diff --git a/src/backend/utils/sort/psort.c b/src/backend/utils/sort/psort.c index b1ac2528075..14db10c1198 100644 --- a/src/backend/utils/sort/psort.c +++ b/src/backend/utils/sort/psort.c @@ -4,7 +4,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: psort.c,v 1.56 1999/07/17 20:18:16 momjian Exp $ + * $Id: psort.c,v 1.57 1999/10/13 15:02:31 tgl Exp $ * * NOTES * Sorts the first relation into the second relation. @@ -142,7 +142,8 @@ psort_begin(Sort *node, int nkeys, ScanKey key) PS(node)->psort_grab_file = mergeruns(node); PS(node)->psort_current = 0; - PS(node)->psort_saved = 0; + PS(node)->psort_saved_fileno = 0; + PS(node)->psort_saved = 0L; return true; } @@ -227,7 +228,7 @@ inittapes(Sort *node) #define SETTUPLEN(TUP, LEN) ((TUP)->t_len = (LEN) - HEAPTUPLESIZE) -#define rewind(FP) BufFileSeek(FP, 0L, SEEK_SET) +#define rewind(FP) BufFileSeek(FP, 0, 0L, SEEK_SET) /* * USEMEM - record use of memory FREEMEM - record @@ -764,9 +765,6 @@ psort_grabtuple(Sort *node, bool *should_free) tup = ALLOCTUP(tuplen); SETTUPLEN(tup, tuplen); GETTUP(node, tup, tuplen, PS(node)->psort_grab_file); - - /* Update current merged sort file position */ - PS(node)->psort_current += tuplen + sizeof(tlendummy); return tup; } else @@ -775,70 +773,67 @@ psort_grabtuple(Sort *node, bool *should_free) return NULL; } } - /* Backward */ - if (PS(node)->psort_current <= sizeof(tlendummy)) - return NULL; - - /* + /* Backward. + * * if all tuples are fetched already then we return last tuple, * else - tuple before last returned. */ if (PS(node)->all_fetched) { - /* - * psort_current is pointing to the zero tuplen at the end of - * file + * Assume seek position is pointing just past the zero tuplen + * at the end of file; back up and fetch last tuple's ending + * length word. If seek fails we must have a completely empty + * file. */ - BufFileSeek(PS(node)->psort_grab_file, - PS(node)->psort_current - sizeof(tlendummy), SEEK_SET); + if (BufFileSeek(PS(node)->psort_grab_file, 0, + - (long) (2 * sizeof(tlendummy)), SEEK_CUR)) + return NULL; GETLEN(tuplen, PS(node)->psort_grab_file); - if (PS(node)->psort_current < tuplen) - elog(ERROR, "psort_grabtuple: too big last tuple len in backward scan"); PS(node)->all_fetched = false; } else { - /* move to position of end tlen of prev tuple */ - PS(node)->psort_current -= sizeof(tlendummy); - BufFileSeek(PS(node)->psort_grab_file, - PS(node)->psort_current, SEEK_SET); - GETLEN(tuplen, PS(node)->psort_grab_file); /* get tlen of prev - * tuple */ + /* + * Back up and fetch prev tuple's ending length word. + * If seek fails, assume we are at start of file. + */ + if (BufFileSeek(PS(node)->psort_grab_file, 0, + - (long) sizeof(tlendummy), SEEK_CUR)) + return NULL; + GETLEN(tuplen, PS(node)->psort_grab_file); if (tuplen == 0) elog(ERROR, "psort_grabtuple: tuplen is 0 in backward scan"); - if (PS(node)->psort_current <= tuplen + sizeof(tlendummy)) - { /* prev tuple should be first one */ - if (PS(node)->psort_current != tuplen) - elog(ERROR, "psort_grabtuple: first tuple expected in backward scan"); - PS(node)->psort_current = 0; - BufFileSeek(PS(node)->psort_grab_file, - PS(node)->psort_current, SEEK_SET); - return NULL; - } - /* - * Get position of prev tuple. This tuple becomes current - * tuple now and we have to return previous one. + * Back up to get ending length word of tuple before it. */ - PS(node)->psort_current -= tuplen; - /* move to position of end tlen of prev tuple */ - BufFileSeek(PS(node)->psort_grab_file, - PS(node)->psort_current - sizeof(tlendummy), SEEK_SET); + if (BufFileSeek(PS(node)->psort_grab_file, 0, + - (long) (tuplen + 2*sizeof(tlendummy)), SEEK_CUR)) + { + /* If fail, presumably the prev tuple is the first in the file. + * Back up so that it becomes next to read in forward direction + * (not obviously right, but that is what in-memory case does) + */ + if (BufFileSeek(PS(node)->psort_grab_file, 0, + - (long) (tuplen + sizeof(tlendummy)), SEEK_CUR)) + elog(ERROR, "psort_grabtuple: too big last tuple len in backward scan"); + return NULL; + } GETLEN(tuplen, PS(node)->psort_grab_file); - if (PS(node)->psort_current < tuplen + sizeof(tlendummy)) - elog(ERROR, "psort_grabtuple: too big tuple len in backward scan"); } /* - * move to prev (or last) tuple start position + sizeof(t_len) + * Now we have the length of the prior tuple, back up and read it. + * Note: GETTUP expects we are positioned after the initial length + * word of the tuple, so back up to that point. */ - BufFileSeek(PS(node)->psort_grab_file, - PS(node)->psort_current - tuplen, SEEK_SET); + if (BufFileSeek(PS(node)->psort_grab_file, 0, + - (long) tuplen, SEEK_CUR)) + elog(ERROR, "psort_grabtuple: too big tuple len in backward scan"); tup = ALLOCTUP(tuplen); SETTUPLEN(tup, tuplen); GETTUP(node, tup, tuplen, PS(node)->psort_grab_file); - return tup; /* file position is equal to psort_current */ + return tup; } else { @@ -875,6 +870,8 @@ psort_grabtuple(Sort *node, bool *should_free) /* * psort_markpos - saves current position in the merged sort file + * + * XXX I suspect these need to save & restore the all_fetched flag as well! */ void psort_markpos(Sort *node) @@ -882,7 +879,12 @@ psort_markpos(Sort *node) Assert(node != (Sort *) NULL); Assert(PS(node) != (Psortstate *) NULL); - PS(node)->psort_saved = PS(node)->psort_current; + if (PS(node)->using_tape_files == true) + BufFileTell(PS(node)->psort_grab_file, + & PS(node)->psort_saved_fileno, + & PS(node)->psort_saved); + else + PS(node)->psort_saved = PS(node)->psort_current; } /* @@ -897,8 +899,11 @@ psort_restorepos(Sort *node) if (PS(node)->using_tape_files == true) BufFileSeek(PS(node)->psort_grab_file, - PS(node)->psort_saved, SEEK_SET); - PS(node)->psort_current = PS(node)->psort_saved; + PS(node)->psort_saved_fileno, + PS(node)->psort_saved, + SEEK_SET); + else + PS(node)->psort_current = PS(node)->psort_saved; } /* @@ -952,7 +957,8 @@ psort_rescan(Sort *node) { PS(node)->all_fetched = false; PS(node)->psort_current = 0; - PS(node)->psort_saved = 0; + PS(node)->psort_saved_fileno = 0; + PS(node)->psort_saved = 0L; if (PS(node)->using_tape_files == true) rewind(PS(node)->psort_grab_file); } @@ -973,11 +979,7 @@ psort_rescan(Sort *node) static BufFile * gettape() { - File tfile; - - tfile = OpenTemporaryFile(); - Assert(tfile >= 0); - return BufFileCreate(tfile); + return BufFileCreateTemp(); } /* |