From: drh Date: Fri, 1 Nov 2013 22:02:56 +0000 (+0000) Subject: Size KeyInfo objects so that IdxInserts always compare the correct number of X-Git-Tag: version-3.8.2~137^2~32 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1153c7b25d6e22cb9801687d7d0f185cb0ec0a18;p=thirdparty%2Fsqlite.git Size KeyInfo objects so that IdxInserts always compare the correct number of fields. FossilOrigin-Name: 302a81390f039fc23eeb8510e95b9d9fa0b41edd --- diff --git a/manifest b/manifest index d07b47f907..5cb7b13613 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index 6ad82b209f..2aaa821acc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f9769d701c65770f4b8488f541c59e508393e6c2 \ No newline at end of file +302a81390f039fc23eeb8510e95b9d9fa0b41edd \ No newline at end of file diff --git a/src/build.c b/src/build.c index 352adc4933..16b0f4840c 100644 --- a/src/build.c +++ b/src/build.c @@ -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; iazColl[i]; diff --git a/src/vdbe.c b/src/vdbe.c index b72ef40cae..68cb0ac956 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -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; } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index fe32800a56..b7f5ab1a31 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -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*); diff --git a/src/vdbemem.c b/src/vdbemem.c index cdaacac83f..8548738a4d 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -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; inField = pKeyInfo->nField; + if( nIgnore ){ + r2->nField = pKeyInfo->nField - nIgnore; assert( r2->nField>0 ); for(i=0; inField; 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; }