From: drh Date: Fri, 28 May 2004 08:21:02 +0000 (+0000) Subject: Tables and indices use the same record format. (CVS 1481) X-Git-Tag: version-3.6.10~4593 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f3218fea00cdf51172466010002ed637a45a5d1a;p=thirdparty%2Fsqlite.git Tables and indices use the same record format. (CVS 1481) FossilOrigin-Name: ebd564d10b0ecd7ff15cbd6cd2b979c9f767476c --- diff --git a/VERSION b/VERSION index 01b0f095f3..5e03dc0a91 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.8.13 +3.0.0alpha diff --git a/manifest b/manifest index 4b3bcf03be..88f873d24b 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Remove\sthe\sencoding\sargument\sfrom\ssqlite3VdbeSerialGet.\s\sUse\sthe\s32-bit\nversion\sof\ssqlite3GetVarint\sfor\sschema-level\sparameters.\s(CVS\s1480) -D 2004-05-28T01:39:01 +C Tables\sand\sindices\suse\sthe\ssame\srecord\sformat.\s(CVS\s1481) +D 2004-05-28T08:21:02 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd -F VERSION 4328de2a5fb5000699b907ca405cb9d84ba4e097 +F VERSION 4490ff094970c0e36eff0cbe2adcdb3a701f6ad6 F aclocal.m4 7daea4c35e88de30d5a3f6f7a2ab99720e803bbd F art/SQLite.eps 9b43cc99cfd2be687d386faea6862ea68d6a72b2 F art/SQLite.gif 1bbb94484963f1382e27e1c5e86dd0c1061eba2b @@ -30,7 +30,7 @@ F src/build.c 35cbeb439b49cca5eb5e8a1de010a5194f4523e8 F src/date.c 0eb922af5c5f5e2455f8dc2f98023ed3e04a857e F src/delete.c 66c5ab98cbad7e6b315fc997bfe6c8080784a701 F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37 -F src/expr.c 3f43cae2c8cf51ea8ee2abbf4dcc900b1326c5d6 +F src/expr.c 1f7b853b097806ff6b0a3edd884c9b6675698745 F src/func.c 1fe0763675eb38b6e3992d3edfbec2271798b658 F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb @@ -69,7 +69,7 @@ F src/update.c 96461bcf4e946697e83c09c77c7e61b545a2f66e F src/utf.c 59b5c8f06a4384a9f64933d6c57a2de02ce3673b F src/util.c d299404febd509556e720fbecadd880756b0f899 F src/vacuum.c 8734f89742f246abd91dbd3e087fc153bddbfbad -F src/vdbe.c ea44f5bef30c7fd8eeb28fb4aa5f05875566b369 +F src/vdbe.c c661752ea19a8b5a041d8c4f234e1524f6b3250e F src/vdbe.h e73f890e0f2a6c42b183d7d6937947930fe4fdeb F src/vdbeInt.h 57b649105aeab1e39e77bdb3de3c1560deddc69e F src/vdbeapi.c b0bb1f98c899ba00c8a5cbca612c2a28a1bb79de @@ -203,7 +203,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P 203af2b2e3a25f4fe0e128e350c21834cad0bd7f -R 2b74d4b0c22d8325d92f20886c62da43 +P 321f8c463520e99681de878b743027c570b73e35 +R b41c78025f27adccaab04283941e1081 U drh -Z e19993d4f4e147db54eb88d1ba253c94 +Z 03b836ac44307f3719b7ddd6c55ebe4b diff --git a/manifest.uuid b/manifest.uuid index c4b14adb2c..8acdec43de 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -321f8c463520e99681de878b743027c570b73e35 \ No newline at end of file +ebd564d10b0ecd7ff15cbd6cd2b979c9f767476c \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 20cd58f49d..02f254bd85 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.130 2004/05/27 09:28:42 danielk1977 Exp $ +** $Id: expr.c,v 1.131 2004/05/28 08:21:06 drh Exp $ */ #include "sqliteInt.h" #include @@ -824,6 +824,7 @@ int sqlite3ExprResolveIds( keyInfo.aColl[0] = pParse->db->pDfltColl; sqlite3VdbeOp3(v, OP_OpenTemp, pExpr->iTable, 0, \ (char*)&keyInfo, P3_KEYINFO); + sqlite3VdbeAddOp(v, OP_SetNumColumns, pExpr->iTable, 1); if( pExpr->pSelect ){ /* Case 1: expr IN (SELECT ...) diff --git a/src/vdbe.c b/src/vdbe.c index c407405899..4d7ea7cfe4 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.342 2004/05/28 01:39:01 drh Exp $ +** $Id: vdbe.c,v 1.343 2004/05/28 08:21:09 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -404,66 +404,6 @@ void prettyPrintMem(Mem *pMem, char *zBuf, int nBuf){ char zGdbBuf[100]; #endif -/* -** Move data out of a btree key or data field and into a Mem structure. -** The data or key is taken from the entry that pCur is currently pointing -** to. offset and amt determine what portion of the data or key to retrieve. -** key is true to get the key or false to get data. The result is written -** into the pMem element. -*/ -static int getBtreeMem( - BtCursor *pCur, /* Cursor pointing at record to retrieve. */ - int offset, /* Offset from the start of data to return bytes from. */ - int amt, /* Number of bytes to return. */ - int key, /* If true, retrieve from the btree key, not data. */ - Mem *pMem /* OUT: Return data in this Mem structure. */ -){ - char *zData; - - if( key ){ - zData = (char *)sqlite3BtreeKeyFetch(pCur, offset+amt); - }else{ - zData = (char *)sqlite3BtreeDataFetch(pCur, offset+amt); - } - - if( zData ){ - pMem->z = &zData[offset]; - pMem->n = amt; - pMem->flags = MEM_Blob|MEM_Ephem; - }else{ - int rc; - if( amt>NBFS-2 ){ - zData = (char *)sqliteMallocRaw(amt+2); - if( !zData ){ - return SQLITE_NOMEM; - } - pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term; - }else{ - zData = &(pMem->zShort[0]); - pMem->flags = MEM_Blob|MEM_Short|MEM_Term; - } - pMem->z = zData; - pMem->enc = 0; - pMem->type = SQLITE3_BLOB; - - if( key ){ - rc = sqlite3BtreeKey(pCur, offset, amt, zData); - }else{ - rc = sqlite3BtreeData(pCur, offset, amt, zData); - } - zData[amt] = 0; - zData[amt+1] = 0; - if( rc!=SQLITE_OK ){ - if( amt>NBFS ){ - sqliteFree(zData); - } - return rc; - } - } - - return SQLITE_OK; -} - #ifdef VDBE_PROFILE /* @@ -1801,6 +1741,11 @@ case OP_SetNumColumns: { break; } +/* Opcode: IdxColumn P1 * * +** +** P1 is a cursor opened on an index. Push the first field from the +** current index key onto the stack. +*/ /* Opcode: Column P1 P2 * ** ** Interpret the data that cursor P1 points to as a structure built using @@ -1818,6 +1763,7 @@ case OP_SetNumColumns: { ** stack. The column value is not copied. The number of columns in the ** record is stored on the stack just above the record itself. */ +case OP_IdxColumn: case OP_Column: { int payloadSize; /* Number of bytes in the record */ int p1 = pOp->p1; /* P1 value of the opcode */ @@ -1921,7 +1867,7 @@ case OP_Column: { /* Get the complete header text */ if( !zRec ){ - rc = getBtreeMem(pCrsr, 0, szHdr, pC->keyAsData, &sMem); + rc = sqlite3VdbeMemFromBtree(pCrsr, 0, szHdr, pC->keyAsData, &sMem); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } @@ -1971,7 +1917,7 @@ case OP_Column: { zData = &zRec[aOffset[p2]]; }else{ len = sqlite3VdbeSerialTypeLen(aType[p2]); - getBtreeMem(pCrsr, aOffset[p2], len, pC->keyAsData, &sMem); + sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->keyAsData, &sMem); zData = sMem.z; } sqlite3VdbeSerialGet(zData, aType[p2], pTos); @@ -1988,6 +1934,44 @@ case OP_Column: { break; } +/* Opcode: MakeKey P1 P2 P3 +** +** Convert the top P1 entries of the stack into a single entry suitable +** for use as the key in an index. If P2 is zero, then the original +** entries are popped off the stack. If P2 is not zero, the original +** entries remain on the stack. +** +** P3 is interpreted in the same way as for MakeIdxKey. +*/ +/* Opcode: MakeIdxKey P1 P2 P3 +** +** Convert the top P1 entries of the stack into a single entry suitable +** for use as the key in an index. In addition, take one additional integer +** off of the stack, treat that integer as an eight-byte record number, and +** append the integer to the key as a varint. Thus a total of P1+1 entries +** are popped from the stack for this instruction and a single entry is +** pushed back. +** +** If P2 is not zero and one or more of the P1 entries that go into the +** generated key is NULL, then jump to P2 after the new key has been +** pushed on the stack. In other words, jump to P2 if the key is +** guaranteed to be unique. This jump can be used to skip a subsequent +** uniqueness test. +** +** P3 may be a string that is P1 characters long. The nth character of the +** string indicates the column affinity that should be used for the nth +** field of the index key (i.e. the first character of P3 corresponds to the +** lowest element on the stack). +** +** Character Column affinity +** ------------------------------ +** 'n' NUMERIC +** 'i' INTEGER +** 't' TEXT +** 'o' NONE +** +** If P3 is NULL then datatype coercion occurs. +*/ /* Opcode MakeRecord P1 * P3 ** ** Convert the top P1 entries of the stack into a single entry @@ -2010,6 +1994,8 @@ case OP_Column: { ** ** If P3 is NULL then all index fields have the affinity NONE. */ +case OP_MakeKey: +case OP_MakeIdxKey: case OP_MakeRecord: { /* Assuming the record contains N fields, the record format looks ** like this: @@ -2033,26 +2019,49 @@ case OP_MakeRecord: { unsigned char *zCsr; char *zAffinity; Mem *pRec; + Mem *pRowid; int nData = 0; /* Number of bytes of data space */ int nHdr = 0; /* Number of bytes of header space */ int nByte = 0; /* Space required for this record */ + int addRowid; /* True to append a rowid column at the end */ + u32 serial_type; /* Type field */ + int containsNull; /* True if any of the data fields are NULL */ Mem *pData0 = &pTos[1-nField]; assert( pData0>=p->aStack ); zAffinity = pOp->p3; + addRowid = pOp->opcode==OP_MakeIdxKey; + containsNull = 0; /* Loop through the elements that will make up the record to figure ** out how much space is required for the new record. */ for(pRec=pData0; pRec<=pTos; pRec++){ - u32 serial_type; if( zAffinity ){ applyAffinity(pRec, zAffinity[pRec-pData0], db->enc); } + if( pRec->flags&MEM_Null ){ + containsNull = 1; + } serial_type = sqlite3VdbeSerialType(pRec); nData += sqlite3VdbeSerialTypeLen(serial_type); nHdr += sqlite3VarintLen(serial_type); } + + /* If we have to append a varint rowid to this record, set 'rowid' + ** to the value of the rowid and increase nByte by the amount of space + ** required to store it and the 0x00 seperator byte. + */ + if( addRowid ){ + pRowid = &pTos[0-nField]; + assert( pRowid>=p->aStack ); + Integerify(pRowid, db->enc); + serial_type = sqlite3VdbeSerialType(pRowid); + nData += sqlite3VdbeSerialTypeLen(serial_type); + nHdr += sqlite3VarintLen(serial_type); + } + + /* Add the initial header varint and total the size */ nHdr += sqlite3VarintLen(nHdr); nByte = nHdr+nData; @@ -2071,12 +2080,18 @@ case OP_MakeRecord: { zCsr = zNewRecord; zCsr += sqlite3PutVarint(zCsr, nHdr); for(pRec=pData0; pRec<=pTos; pRec++){ - u32 serial_type = sqlite3VdbeSerialType(pRec); + serial_type = sqlite3VdbeSerialType(pRec); zCsr += sqlite3PutVarint(zCsr, serial_type); /* serial type */ } + if( addRowid ){ + zCsr += sqlite3PutVarint(zCsr, sqlite3VdbeSerialType(pRowid)); + } for(pRec=pData0; pRec<=pTos; pRec++){ zCsr += sqlite3VdbeSerialPut(zCsr, pRec); /* serial data */ } + if( addRowid ){ + zCsr += sqlite3VdbeSerialPut(zCsr, pRowid); + } /* If zCsr has not been advanced exactly nByte bytes, then one ** of the sqlite3PutVarint() or sqlite3VdbeSerialPut() calls above @@ -2088,142 +2103,13 @@ case OP_MakeRecord: { } /* Pop nField entries from the stack and push the new entry on */ - popStack(&pTos, nField); - pTos++; - pTos->n = nByte; - pTos->z = zNewRecord; - pTos->flags = MEM_Blob | MEM_Dyn; - - break; -} - -/* Opcode: MakeKey P1 P2 P3 -** -** Convert the top P1 entries of the stack into a single entry suitable -** for use as the key in an index. If P2 is zero, then the original -** entries are popped off the stack. If P2 is not zero, the original -** entries remain on the stack. -** -** P3 is interpreted in the same way as for MakeIdxKey. -*/ -/* Opcode: MakeIdxKey P1 P2 P3 -** -** Convert the top P1 entries of the stack into a single entry suitable -** for use as the key in an index. In addition, take one additional integer -** off of the stack, treat that integer as an eight-byte record number, and -** append the integer to the key as a varint. Thus a total of P1+1 entries -** are popped from the stack for this instruction and a single entry is -** pushed back. -** -** If P2 is not zero and one or more of the P1 entries that go into the -** generated key is NULL, then jump to P2 after the new key has been -** pushed on the stack. In other words, jump to P2 if the key is -** guaranteed to be unique. This jump can be used to skip a subsequent -** uniqueness test. -** -** P3 may be a string that is P1 characters long. The nth character of the -** string indicates the column affinity that should be used for the nth -** field of the index key (i.e. the first character of P3 corresponds to the -** lowest element on the stack). -** -** Character Column affinity -** ------------------------------ -** 'n' NUMERIC -** 'i' INTEGER -** 't' TEXT -** 'o' NONE -** -** If P3 is NULL then datatype coercion occurs. -*/ -case OP_MakeKey: -case OP_MakeIdxKey: { - Mem *pRec; - Mem *pData0; - int nField; - u64 rowid; - int nByte = 0; - int addRowid; - int containsNull = 0; - char *zKey; /* The new key */ - int offset = 0; - char *zAffinity = pOp->p3; - - nField = pOp->p1; - assert( zAffinity==0 || strlen(zAffinity)>=nField ); - pData0 = &pTos[1-nField]; - assert( pData0>=p->aStack ); - - addRowid = ((pOp->opcode==OP_MakeIdxKey)?1:0); - - /* Loop through the P1 elements that will make up the new index - ** key. Call applyAffinity() to perform any conversion required - ** the column affinity string P3 to modify stack elements in place. - ** Set containsNull to 1 if a NULL value is encountered. - ** - ** Once the value has been coerced, figure out how much space is required - ** to store the coerced values serial-type and blob, and add this - ** quantity to nByte. - ** - ** TODO: Figure out if the in-place coercion causes a problem for - ** OP_MakeKey when P2 is 0 (used by DISTINCT). - */ - for(pRec=pData0; pRec<=pTos; pRec++){ - u32 serial_type; - if( zAffinity ){ - applyAffinity(pRec, zAffinity[pRec-pData0], db->enc); - } - if( pRec->flags&MEM_Null ){ - containsNull = 1; - } - serial_type = sqlite3VdbeSerialType(pRec); - nByte += sqlite3VarintLen(serial_type); - nByte += sqlite3VdbeSerialTypeLen(serial_type); - } - - /* If we have to append a varint rowid to this record, set 'rowid' - ** to the value of the rowid and increase nByte by the amount of space - ** required to store it and the 0x00 seperator byte. - */ - if( addRowid ){ - pRec = &pTos[0-nField]; - assert( pRec>=p->aStack ); - Integerify(pRec, db->enc); - rowid = pRec->i; - nByte += sqlite3VarintLen(rowid); - nByte++; - } - - if( nByte>MAX_BYTES_PER_ROW ){ - rc = SQLITE_TOOBIG; - goto abort_due_to_error; - } - - /* Allocate space for the new key */ - zKey = (char *)sqliteMallocRaw(nByte); - if( !zKey ){ - goto no_mem; - } - - /* Build the key in the buffer pointed to by zKey. */ - for(pRec=pData0; pRec<=pTos; pRec++){ - u32 serial_type = sqlite3VdbeSerialType(pRec); - offset += sqlite3PutVarint(&zKey[offset], serial_type); - offset += sqlite3VdbeSerialPut(&zKey[offset], pRec); - } - if( addRowid ){ - zKey[offset++] = '\0'; - offset += sqlite3PutVarint(&zKey[offset], rowid); - } - assert( offset==nByte ); - - /* Pop the consumed values off the stack and push on the new key. */ - if( addRowid||(pOp->p2==0) ){ + if( addRowid || pOp->p2==0 ){ popStack(&pTos, nField+addRowid); } pTos++; - pTos->flags = MEM_Blob|MEM_Dyn; - pTos->z = zKey; pTos->n = nByte; + pTos->z = zNewRecord; + pTos->flags = MEM_Blob | MEM_Dyn; /* If P2 is non-zero, and if the key contains a NULL value, and if this ** was an OP_MakeIdxKey instruction, not OP_MakeKey, jump to P2. @@ -2842,8 +2728,8 @@ case OP_Found: { ** ** P1 is an index. So it has no data and its key consists of a ** record generated by OP_MakeIdxKey. This key contains one or more -** fields followed by a varint ROWID. -** +** fields followed by a ROWID field. +** ** This instruction asks if there is an entry in P1 where the ** fields matches K but the rowid is different from R. ** If there is no such entry, then there is an immediate @@ -2876,6 +2762,7 @@ case OP_IsUnique: { char *zKey; /* The value of K */ int nKey; /* Number of bytes in K */ int len; /* Number of bytes in K without the rowid at the end */ + int szRowid; /* Size of the rowid column at the end of zKey */ /* Make sure K is a string and make zKey point to K */ @@ -2883,9 +2770,8 @@ case OP_IsUnique: { zKey = pNos->z; nKey = pNos->n; - assert( nKey >= 2 ); - len = nKey-2; - while( zKey[len] && --len ); + szRowid = sqlite3VdbeIdxRowidLen(nKey, zKey); + len = nKey-szRowid; /* Search for an entry in P1 where all but the last four bytes match K. ** If there is no such entry, jump immediately to P2. @@ -2909,8 +2795,8 @@ case OP_IsUnique: { } /* At this point, pCrsr is pointing to an entry in P1 where all but - ** the final varint (the rowid) matches K. Check to see if the - ** final varint is different from R. If it equals R then jump + ** the final entry (the rowid) matches K. Check to see if the + ** final rowid column is different from R. If it equals R then jump ** immediately to P2. */ rc = sqlite3VdbeIdxRowid(pCrsr, &v); @@ -3347,57 +3233,6 @@ case OP_Recno: { break; } -/* Opcode: IdxColumn P1 * * -** -** P1 is a cursor opened on an index. Push the first field from the -** current index key onto the stack. -*/ -case OP_IdxColumn: { - char *zData; - i64 n; - u32 serial_type; - int len; - int freeZData = 0; - BtCursor *pCsr; - - assert( 0==p->apCsr[pOp->p1]->intKey ); - pCsr = p->apCsr[pOp->p1]->pCursor; - rc = sqlite3BtreeKeySize(pCsr, &n); - if( rc!=SQLITE_OK ){ - goto abort_due_to_error; - } - if( n>10 ) n = 10; - - zData = (char *)sqlite3BtreeKeyFetch(pCsr, n); - assert( zData ); - - len = sqlite3GetVarint32(zData, &serial_type); - n = sqlite3VdbeSerialTypeLen(serial_type); - - zData = (char *)sqlite3BtreeKeyFetch(pCsr, len+n); - if( !zData ){ - zData = (char *)sqliteMalloc(n); - if( !zData ){ - goto no_mem; - } - rc = sqlite3BtreeKey(pCsr, len, n, zData); - if( rc!=SQLITE_OK ){ - sqliteFree(zData); - goto abort_due_to_error; - } - freeZData = 1; - len = 0; - } - - pTos++; - sqlite3VdbeSerialGet(&zData[len], serial_type, pTos); - pTos->enc = db->enc; - if( freeZData ){ - sqliteFree(zData); - } - break; -} - /* Opcode: FullKey P1 * * ** ** Extract the complete key from the record that cursor P1 is currently @@ -3592,21 +3427,15 @@ case OP_IdxPut: { if( pOp->p2 ){ int res; int len; - u64 n; /* 'len' is the length of the key minus the rowid at the end */ - len = nKey-2; - while( zKey[len] && --len ); + len = nKey - sqlite3VdbeIdxRowidLen(nKey, zKey); rc = sqlite3BtreeMoveto(pCrsr, zKey, len, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; - while( res!=0 ){ + while( res!=0 && !sqlite3BtreeEof(pCrsr) ){ int c; - sqlite3BtreeKeySize(pCrsr, &n); - if( n==nKey && - sqlite3VdbeIdxKeyCompare(pC, len, zKey, &c)==SQLITE_OK - && c==0 - ){ + if( sqlite3VdbeIdxKeyCompare(pC, len, zKey, &c)==SQLITE_OK && c==0 ){ rc = SQLITE_CONSTRAINT; if( pOp->p3 && pOp->p3[0] ){ sqlite3SetString(&p->zErrMsg, pOp->p3, (char*)0); @@ -3723,18 +3552,23 @@ case OP_IdxRecno: { /* Opcode: IdxGT P1 P2 * ** -** Compare the top of the stack against the key on the index entry that -** cursor P1 is currently pointing to. Ignore the ROWID of the -** index entry. If the index entry is greater than the top of the stack +** The top of the stack is an index entry that omits the ROWID. Compare +** the top of stack against the index that P1 is currently pointing to. +** Ignore the ROWID on the P1 index. +** +** The top of the stack might have fewer columns that P1. +** +** If the P1 index entry is greater than the top of the stack ** then jump to P2. Otherwise fall through to the next instruction. ** In either case, the stack is popped once. */ /* Opcode: IdxGE P1 P2 P3 ** -** Compare the top of the stack against the key on the index entry that -** cursor P1 is currently pointing to. Ignore the ROWID of the -** index entry. If the index in the cursor is greater than or equal to -** the top of the stack +** The top of the stack is an index entry that omits the ROWID. Compare +** the top of stack against the index that P1 is currently pointing to. +** Ignore the ROWID on the P1 index. +** +** If the P1 index entry is greater than or equal to the top of the stack ** then jump to P2. Otherwise fall through to the next instruction. ** In either case, the stack is popped once. ** @@ -3747,9 +3581,11 @@ case OP_IdxRecno: { */ /* Opcode: IdxLT P1 P2 P3 ** -** Compare the top of the stack against the key on the index entry that -** cursor P1 is currently pointing to. Ignore the ROWID of the -** index entry. If the index entry is less than the top of the stack +** The top of the stack is an index entry that omits the ROWID. Compare +** the top of stack against the index that P1 is currently pointing to. +** Ignore the ROWID on the P1 index. +** +** If the P1 index entry is less than the top of the stack ** then jump to P2. Otherwise fall through to the next instruction. ** In either case, the stack is popped once. ** @@ -3770,6 +3606,7 @@ case OP_IdxGE: { if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ int res, rc; + assert( pTos->flags & MEM_Blob ); /* Created using OP_Make*Key */ Stringify(pTos, db->enc); assert( pC->deferredMoveto==0 ); *pC->pIncrKey = pOp->p3!=0; @@ -3806,19 +3643,19 @@ case OP_IdxIsNull: { int i = pOp->p1; int k, n; const char *z; + u32 serial_type; assert( pTos>=p->aStack ); assert( pTos->flags & MEM_Blob ); z = pTos->z; n = pTos->n; - for(k=0; k0; i--){ - u32 serial_type; + k = sqlite3GetVarint32(z, &serial_type); + for(; k0; i--){ k += sqlite3GetVarint32(&z[k], &serial_type); if( serial_type==6 ){ /* Serial type 6 is a NULL */ pc = pOp->p2-1; break; } - k += sqlite3VdbeSerialTypeLen(serial_type); } Release(pTos); pTos--;