]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Size KeyInfo objects so that IdxInserts always compare the correct number of
authordrh <drh@noemail.net>
Fri, 1 Nov 2013 22:02:56 +0000 (22:02 +0000)
committerdrh <drh@noemail.net>
Fri, 1 Nov 2013 22:02:56 +0000 (22:02 +0000)
fields.

FossilOrigin-Name: 302a81390f039fc23eeb8510e95b9d9fa0b41edd

manifest
manifest.uuid
src/build.c
src/vdbe.c
src/vdbeInt.h
src/vdbemem.c
src/vdbesort.c

index d07b47f907efbc28b5d2d84b7154e854ca85a08e..5cb7b13613fc9395724992afe9290186126bb456 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\ssqlite3_analyzer\sso\sthat\sit\sworks\swith\sWITHOUT\sROWID\stables.\nFix\sindex\sgeneration\sfor\ssecondary\sindices\sthat\sinclude\sfields\sfrom\nthe\sPRIMARY\sKEY.
-D 2013-11-01T20:30:36.718
+C Size\sKeyInfo\sobjects\sso\sthat\sIdxInserts\salways\scompare\sthe\scorrect\snumber\sof\nfields.
+D 2013-11-01T22:02:56.824
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 0522b53cdc1fcfc18f3a98e0246add129136c654
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -168,7 +168,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
 F src/btree.c 509722ce305471b626d3401c0631a808fd33237b
 F src/btree.h bfe0e8c5759b4ec77b0d18390064a6ef3cdffaaf
 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0
-F src/build.c 7a940e5e3ee55b3036be294571770c144751ee82
+F src/build.c bc63356abffdde0271f8d7667bad32e0566debe1
 F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2
 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
 F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c
@@ -279,14 +279,14 @@ F src/update.c 94d63d3e06b09df3618655a841dc95d5b9466dc6
 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918
 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
-F src/vdbe.c 613af4c9ac24b1bf70fe35484502e74183492802
+F src/vdbe.c 9f3dc84302556f7731e53d64b5e6723b1e568b8d
 F src/vdbe.h c18a2dd91c838601b867a214e43c5f66d5d001ba
-F src/vdbeInt.h 42dcff74dbeb2b071e569b53f885fc9c2e4b4cb0
+F src/vdbeInt.h f2fa3ceccceeb757773921fb08af7c6e9f3caa1c
 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed
 F src/vdbeaux.c cf6d0bc68fd1783747909cd14387bc06ac10a4e2
 F src/vdbeblob.c ef973d8d9f8170015343dd8824f795da675caa87
-F src/vdbemem.c 6087553f2c61c06c8e1ab3959a60e174d6240c98
-F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017
+F src/vdbemem.c e62206af9efa102c5bae58269955cae1965ad728
+F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147
 F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc
 F src/vtab.c 5a423b042eb1402ef77697d03d6a67378d97bc8d
 F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
@@ -1128,7 +1128,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 65384ae0f027d05cf9208faed56575870d63c486
-R b82044a07d71eebf83fb22f28eefd449
+P f9769d701c65770f4b8488f541c59e508393e6c2
+R 71880bd74bc5edec870109286fe9bf00
 U drh
-Z 66f9c600d762e843b5b86dd8d9c3ba4d
+Z 951dd2ac14cd893ffdc1dceac85de36b
index 6ad82b209f3d170ff9ba21c8163558bffdd44bc9..2aaa821acc221b96264a2c82c84c2449f3654e29 100644 (file)
@@ -1 +1 @@
-f9769d701c65770f4b8488f541c59e508393e6c2
\ No newline at end of file
+302a81390f039fc23eeb8510e95b9d9fa0b41edd
\ No newline at end of file
index 352adc493324787895b4b81fdb20212a98b9866a..16b0f4840cec3569e14c693e3789cc0b96c57f8a 100644 (file)
@@ -2644,11 +2644,13 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
   sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
 
   addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
-  if( pIndex->onError!=OE_None ){
+  assert( pKey!=0 || db->mallocFailed || pParse->nErr );
+  if( pIndex->onError!=OE_None && pKey!=0 ){
     int j2 = sqlite3VdbeCurrentAddr(v) + 3;
     sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
     addr2 = sqlite3VdbeCurrentAddr(v);
-    sqlite3VdbeAddOp3(v, OP_SorterCompare, iSorter, j2, regRecord);
+    sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
+                         pKey->nField - pIndex->nKeyCol);
     sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_UNIQUE,
         OE_Abort, "indexed columns are not unique", P4_STATIC
     );
@@ -4072,7 +4074,11 @@ KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
   int nKey = pIdx->nKeyCol;
   KeyInfo *pKey;
 
-  pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey);
+  if( pIdx->uniqNotNull ){
+    pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey);
+  }else{
+    pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0);
+  }
   if( pKey ){
     for(i=0; i<nCol; i++){
       char *zColl = pIdx->azColl[i];
index b72ef40cae41381bf3a325945a414bda7e23fe15..68cb0ac9563654b6dbc6338b5d1ee3b95656cbe4 100644 (file)
@@ -3358,8 +3358,7 @@ case OP_OpenEphemeral: {
   break;
 }
 
-/* Opcode: SorterOpen P1 P2 * P4 *
-** Synopsis: nColumn=P2
+/* Opcode: SorterOpen P1 * * P4 *
 **
 ** This opcode works like OP_OpenEphemeral except that it opens
 ** a transient index that is specifically designed to sort large
@@ -4194,22 +4193,32 @@ case OP_ResetCount: {
   break;
 }
 
-/* Opcode: SorterCompare P1 P2 P3
-** Synopsis:  if key(P1)!=r[P3] goto P2
+/* Opcode: SorterCompare P1 P2 P3 P4
+** Synopsis:  if key(P1)!=rtrim(r[P3],P4) goto P2
+**
+** P1 is a sorter cursor. This instruction compares a prefix of the
+** the record blob in register P3 against a prefix of the entry that 
+** the sorter cursor currently points to.  The final P4 fields of both
+** the P3 and sorter record are ignored.
 **
-** P1 is a sorter cursor. This instruction compares the record blob in 
-** register P3 with the entry that the sorter cursor currently points to.
-** If, excluding the rowid fields at the end, the two records are a match,
-** fall through to the next instruction. Otherwise, jump to instruction P2.
+** If either P3 or the sorter contains a NULL in one of their significant
+** fields (not counting the P4 fields at the end which are ignored) then
+** the comparison is assumed to be equal.
+**
+** Fall through to next instruction if the two records compare equal to
+** each other.  Jump to P2 if they are different.
 */
 case OP_SorterCompare: {
   VdbeCursor *pC;
   int res;
+  int nIgnore;
 
   pC = p->apCsr[pOp->p1];
   assert( isSorter(pC) );
+  assert( pOp->p4type==P4_INT32 );
   pIn3 = &aMem[pOp->p3];
-  rc = sqlite3VdbeSorterCompare(pC, pIn3, &res);
+  nIgnore = pOp->p4.i;
+  rc = sqlite3VdbeSorterCompare(pC, pIn3, nIgnore, &res);
   if( res ){
     pc = pOp->p2-1;
   }
index fe32800a565b883e2b13a0c29ae49f1cd0569f0b..b7f5ab1a3134bb0718635770be97bf6038936e5c 100644 (file)
@@ -447,7 +447,7 @@ int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *);
 int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *);
 int sqlite3VdbeSorterRewind(sqlite3 *, const VdbeCursor *, int *);
 int sqlite3VdbeSorterWrite(sqlite3 *, const VdbeCursor *, Mem *);
-int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int *);
+int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
 
 #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
   void sqlite3VdbeEnter(Vdbe*);
index cdaacac83f3904ea79377bd9cd7b60b408c76072..8548738a4d4c49ee7dd0b4e116997a73b6eebd9a 100644 (file)
@@ -1038,7 +1038,7 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
       if( pRec ){
         pRec->pKeyInfo = sqlite3IndexKeyinfo(p->pParse, pIdx);
         if( pRec->pKeyInfo ){
-          assert( pRec->pKeyInfo->nField+1==nCol );
+          assert( pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField==nCol );
           pRec->pKeyInfo->enc = ENC(db);
           pRec->flags = UNPACKED_PREFIX_MATCH;
           pRec->aMem = (Mem *)&pRec[1];
@@ -1362,7 +1362,7 @@ int sqlite3Stat4ProbeSetValue(
 void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){
   if( pRec ){
     int i;
-    int nCol = pRec->pKeyInfo->nField+1;
+    int nCol = pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField;
     Mem *aMem = pRec->aMem;
     sqlite3 *db = aMem[0].db;
     for(i=0; i<nCol; i++){
index c8709bdafd8e4e18e4e2658661b100b81a2105ab..3e4cad5b4a4efb189afbaf8e1b148a38597df8ce 100644 (file)
@@ -386,7 +386,7 @@ static int vdbeSorterIterInit(
 */
 static void vdbeSorterCompare(
   const VdbeCursor *pCsr,         /* Cursor object (for pKeyInfo) */
-  int bOmitRowid,                 /* Ignore rowid field at end of keys */
+  int nIgnore,                    /* Ignore the last nIgnore fields */
   const void *pKey1, int nKey1,   /* Left side of comparison */
   const void *pKey2, int nKey2,   /* Right side of comparison */
   int *pRes                       /* OUT: Result of comparison */
@@ -400,8 +400,8 @@ static void vdbeSorterCompare(
     sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, r2);
   }
 
-  if( bOmitRowid ){
-    r2->nField = pKeyInfo->nField;
+  if( nIgnore ){
+    r2->nField = pKeyInfo->nField - nIgnore;
     assert( r2->nField>0 );
     for(i=0; i<r2->nField; i++){
       if( r2->aMem[i].flags & MEM_Null ){
@@ -1027,12 +1027,13 @@ int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){
 int sqlite3VdbeSorterCompare(
   const VdbeCursor *pCsr,         /* Sorter cursor */
   Mem *pVal,                      /* Value to compare to current sorter key */
+  int nIgnore,                    /* Ignore this many fields at the end */
   int *pRes                       /* OUT: Result of comparison */
 ){
   VdbeSorter *pSorter = pCsr->pSorter;
   void *pKey; int nKey;           /* Sorter key to compare pVal with */
 
   pKey = vdbeSorterRowkey(pSorter, &nKey);
-  vdbeSorterCompare(pCsr, 1, pVal->z, pVal->n, pKey, nKey, pRes);
+  vdbeSorterCompare(pCsr, nIgnore, pVal->z, pVal->n, pKey, nKey, pRes);
   return SQLITE_OK;
 }