|
7 | 7 | *
|
8 | 8 | *
|
9 | 9 | * 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 $ |
11 | 11 | *
|
12 | 12 | * NOTES
|
13 | 13 | *Sorts the first relation into the second relation.
|
@@ -80,7 +80,12 @@ static int _psort_cmp (HeapTuple *ltup, HeapTuple *rtup);
|
80 | 80 |
|
81 | 81 | #defineTEMPDIR "./"
|
82 | 82 |
|
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; |
84 | 89 |
|
85 | 90 | staticTupleDescPsortTupDesc;
|
86 | 91 | staticScanKeyPsortKeys;/* used by _psort_cmp */
|
@@ -150,6 +155,7 @@ psort_begin(Sort * node, int nkeys, ScanKey key)
|
150 | 155 | PS(node)->tupcount=0;
|
151 | 156 |
|
152 | 157 | PS(node)->using_tape_files= false;
|
| 158 | +PS(node)->all_fetched= false; |
153 | 159 | PS(node)->psort_grab_file=NULL;
|
154 | 160 | PS(node)->memtuples=NULL;
|
155 | 161 |
|
@@ -219,21 +225,24 @@ inittapes(Sort * node)
|
219 | 225 | *GETTUP- reads the tuple
|
220 | 226 | *
|
221 | 227 | *Note:
|
222 |
| - *LEN field must bea short; FP is a stream |
| 228 | + *LEN field must beas HeapTuple->t_len; FP is a stream |
223 | 229 | */
|
224 | 230 |
|
225 | 231 |
|
226 | 232 | #definePUTTUP(NODE,TUP,FP) do {\
|
227 | 233 | ((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) |
231 | 239 | #defineALLOCTUP(LEN)((HeapTuple)palloc((unsigned)LEN))
|
232 | 240 | #defineGETTUP(NODE,TUP,LEN,FP) do {\
|
233 | 241 | 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) |
237 | 246 | #defineSETTUPLEN(TUP,LEN)(TUP)->t_len = LEN
|
238 | 247 |
|
239 | 248 | /*
|
@@ -629,11 +638,11 @@ merge(Sort * node, struct tape * dest)
|
629 | 638 | registerstructtape*lasttp;/* (TAPE[P]) */
|
630 | 639 | registerstructtape*tp;
|
631 | 640 | 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; |
637 | 646 |
|
638 | 647 | Assert(node!= (Sort*)NULL);
|
639 | 648 | Assert(PS(node)!= (Psortstate*)NULL);
|
@@ -767,42 +776,120 @@ dumptuples(FILE * file, Sort * node)
|
767 | 776 | HeapTuple
|
768 | 777 | psort_grabtuple(Sort*node,bool*should_free)
|
769 | 778 | {
|
770 |
| -registerHeapTupletup; |
771 |
| -longtuplen; |
| 779 | +registerHeapTupletup; |
772 | 780 |
|
773 | 781 | Assert(node!= (Sort*)NULL);
|
774 | 782 | Assert(PS(node)!= (Psortstate*)NULL);
|
775 | 783 |
|
776 | 784 | if (PS(node)->using_tape_files== true)
|
777 | 785 | {
|
778 |
| -if (!feof(PS(node)->psort_grab_file)) |
| 786 | +unsignedinttuplen; |
| 787 | + |
| 788 | +*should_free= true; |
| 789 | +if (ScanDirectionIsForward (node->plan.state->es_direction)) |
779 | 790 | {
|
| 791 | +if (PS(node)->all_fetched) |
| 792 | +returnNULL; |
780 | 793 | if (GETLEN(tuplen,PS(node)->psort_grab_file)&&tuplen!=0)
|
781 | 794 | {
|
782 | 795 | tup= (HeapTuple)palloc((unsigned)tuplen);
|
783 | 796 | SETTUPLEN(tup,tuplen);
|
784 | 797 | GETTUP(node,tup,tuplen,PS(node)->psort_grab_file);
|
785 | 798 |
|
786 | 799 | /* Update current merged sort file position */
|
787 |
| -PS(node)->psort_current+=tuplen; |
788 |
| -*should_free= true; |
| 800 | +PS(node)->psort_current+=tuplen+sizeof (tlendummy); |
789 | 801 | returntup;
|
790 | 802 | }
|
791 | 803 | else
|
| 804 | +{ |
| 805 | +PS(node)->all_fetched= true; |
792 | 806 | returnNULL;
|
| 807 | +} |
793 | 808 | }
|
794 |
| -else |
| 809 | +/* Backward */ |
| 810 | +if (PS(node)->psort_current <=sizeof (tlendummy)) |
795 | 811 | 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 */ |
796 | 863 | }
|
797 | 864 | else
|
798 | 865 | {
|
799 |
| -if (PS(node)->psort_current<PS(node)->tupcount) |
| 866 | +*should_free= false; |
| 867 | +if (ScanDirectionIsForward (node->plan.state->es_direction)) |
800 | 868 | {
|
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 | +} |
803 | 876 | }
|
804 |
| -else |
| 877 | +/* Backward */ |
| 878 | +if (PS(node)->psort_current <=0) |
805 | 879 | 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]); |
806 | 893 | }
|
807 | 894 | }
|
808 | 895 |
|
|