diff --git a/manifest b/manifest index 8a852eeac5..54e5fbb108 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Version\s2.7.0\s(CVS\s729) -D 2002-08-25T20:58:12 +C Fix\sfor\sticket\s#142:\sMake\ssure\swe\sget\sthe\scorrect\ssort\sorder\seven\swhen\sthe\ncolumns\sbeing\ssorted\scontain\sNULLs.\s(CVS\s730) +D 2002-08-26T19:55:08 F Makefile.in bcb81f40d9a17bd94f59e67157b1e1c54c046c2b F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -51,8 +51,8 @@ F src/threadtest.c 72bce0a284647314847bbea44616ceb056bfb77f F src/tokenize.c 8bd6251e5237c9a16d0bbfb9894925eb129985fa F src/trigger.c c90a292a4bef25e478fd5deda6d300319be6a023 F src/update.c f07e6ed2c517c92871e54d3f5886d1cf56121b11 -F src/util.c 60bc91db77cf488618ec4720cb06eedb7f959268 -F src/vdbe.c 99b5714751b541a1c64c2c4dede83a474ca6b7e2 +F src/util.c c70d5da5357e01b58392faebae3c3620c1d71f14 +F src/vdbe.c ea41a3ac96511399e95ae18d16d32ec41ca91ec0 F src/vdbe.h 52ec880c63c6ca74bb6377432149260b1b237873 F src/where.c ce42cce65d7bf42341627f3fb0a17f69fea6a4f4 F test/all.test efd958d048c70a3247997c482f0b33561f7759f0 @@ -93,7 +93,7 @@ F test/select3.test 3e98cec10e755226cbabdd7073ec37baab9ab148 F test/select4.test 10ba54f24ef6ca7958a7045b001079378db2370c F test/select5.test c2a6c4a003316ee42cbbd689eebef8fdce0db2ac F test/select6.test efb8d0c07a440441db87db2c4ade6904e1407e85 -F test/sort.test f9744a81a488d6b448aeeb98d0546b5c802248ae +F test/sort.test 876b76c5a837af5bead713146c7c65f85e84fbf5 F test/subselect.test f0fea8cf9f386d416d64d152e3c65f9116d0f50f F test/table.test dedb4d3a73340d811e309672ca14537daa542fb1 F test/tableapi.test 3c80421a889e1d106df16e5800fa787f0d2914a6 @@ -147,7 +147,7 @@ F www/speed.tcl a20a792738475b68756ea7a19321600f23d1d803 F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 -P e2d95f85a3c4beeb5f8e78498f52fc00475f38ed -R 1887224d7be529eb62028d618058de77 +P 9e341d9c934c2111be6834743f1ce30463b095b6 +R c3833aec2102312b5a02d97350523f61 U drh -Z 2d9f1fc80b5f3e7813cac3b3ac44d578 +Z 83157ab4770270ac20f0733ba099c807 diff --git a/manifest.uuid b/manifest.uuid index 3752548f31..07ec281392 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9e341d9c934c2111be6834743f1ce30463b095b6 \ No newline at end of file +45847390d007718a4b7a4e9fa445136d013113f8 \ No newline at end of file diff --git a/src/util.c b/src/util.c index 200a14c376..b4dca2af0d 100644 --- a/src/util.c +++ b/src/util.c @@ -14,7 +14,7 @@ ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** -** $Id: util.c,v 1.49 2002/08/25 18:29:12 drh Exp $ +** $Id: util.c,v 1.50 2002/08/26 19:55:08 drh Exp $ */ #include "sqliteInt.h" #include @@ -710,6 +710,10 @@ int sqliteCompare(const char *atext, const char *btext){ ** ** Aone\000Dtwo\000Athree\000\000 ** +** All elements begin with one of the characters "+-AD" and end with "\000" +** with zero or more text elements in between. Except, NULL elements +** consist of the special two-character sequence "N\000". +** ** Both arguments will have the same number of elements. This routine ** returns negative, zero, or positive if the first argument is less ** than, equal to, or greater than the first. (Result is a-b). @@ -744,17 +748,26 @@ int sqliteSortCompare(const char *a, const char *b){ int len; int res = 0; int isNumA, isNumB; + int dir; while( res==0 && *a && *b ){ - assert( a[0]==b[0] ); - if( a[1]==0 ){ - res = -1; - break; - }else if( b[1]==0 ){ - res = +1; + if( a[0]=='N' || b[0]=='N' ){ + if( a[0]==b[0] ){ + a += 2; + b += 2; + continue; + } + if( a[0]=='N' ){ + dir = b[0]; + res = -1; + }else{ + dir = a[0]; + res = +1; + } break; } - if( a[0]=='A' || a[0]=='D' ){ + assert( a[0]==b[0] ); + if( (dir=a[0])=='A' || a[0]=='D' ){ res = strcmp(&a[1],&b[1]); if( res ) break; }else{ @@ -788,7 +801,7 @@ int sqliteSortCompare(const char *a, const char *b){ a += len; b += len; } - if( *a=='-' || *a=='D' ) res = -res; + if( dir=='-' || dir=='D' ) res = -res; return res; } diff --git a/src/vdbe.c b/src/vdbe.c index cfd0810bb0..dd6c973046 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -30,7 +30,7 @@ ** But other routines are also provided to help in building up ** a program instruction by instruction. ** -** $Id: vdbe.c,v 1.171 2002/08/25 19:20:40 drh Exp $ +** $Id: vdbe.c,v 1.172 2002/08/26 19:55:08 drh Exp $ */ #include "sqliteInt.h" #include @@ -4393,11 +4393,13 @@ case OP_SortMakeRec: { ** number of stack entries consumed is the number of characters in ** the string P3. One character from P3 is prepended to each entry. ** The first character of P3 is prepended to the element lowest in -** the stack and the last character of P3 is appended to the top of +** the stack and the last character of P3 is prepended to the top of ** the stack. All stack entries are separated by a \000 character ** in the result. The whole key is terminated by two \000 characters ** in a row. ** +** "N" is substituted in place of the P3 character for NULL values. +** ** See also the MakeKey and MakeIdxKey opcodes. */ case OP_SortMakeKey: { @@ -4410,18 +4412,28 @@ case OP_SortMakeKey: { VERIFY( if( p->tos+1tos-nField+1; i<=p->tos; i++){ - if( Stringify(p, i) ) goto no_mem; - nByte += aStack[i].n+2; + if( (aStack[i].flags & STK_Null)!=0 ){ + nByte += 2; + }else{ + if( Stringify(p, i) ) goto no_mem; + nByte += aStack[i].n+2; + } } zNewKey = sqliteMalloc( nByte ); if( zNewKey==0 ) goto no_mem; j = 0; k = 0; for(i=p->tos-nField+1; i<=p->tos; i++){ - zNewKey[j++] = pOp->p3[k++]; - memcpy(&zNewKey[j], zStack[i], aStack[i].n-1); - j += aStack[i].n-1; - zNewKey[j++] = 0; + if( (aStack[i].flags & STK_Null)!=0 ){ + zNewKey[j++] = 'N'; + zNewKey[j++] = 0; + k++; + }else{ + zNewKey[j++] = pOp->p3[k++]; + memcpy(&zNewKey[j], zStack[i], aStack[i].n-1); + j += aStack[i].n-1; + zNewKey[j++] = 0; + } } zNewKey[j] = 0; assert( j