|
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 |
|
|