-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
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
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
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
-f9769d701c65770f4b8488f541c59e508393e6c2
\ No newline at end of file
+302a81390f039fc23eeb8510e95b9d9fa0b41edd
\ No newline at end of file
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
);
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];
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
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;
}
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*);
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];
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++){
*/
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 */
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 ){
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;
}