Tables and indices use the same record format. (CVS 1481)
FossilOrigin-Name: ebd564d10b0ecd7ff15cbd6cd2b979c9f767476c
This commit is contained in:
parent
25aa1b4580
commit
f3218fea00
16
manifest
16
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
|
||||
|
@ -1 +1 @@
|
||||
321f8c463520e99681de878b743027c570b73e35
|
||||
ebd564d10b0ecd7ff15cbd6cd2b979c9f767476c
|
@ -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 <ctype.h>
|
||||
@ -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 ...)
|
||||
|
445
src/vdbe.c
445
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,115 +1934,6 @@ case OP_Column: {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode MakeRecord P1 * P3
|
||||
**
|
||||
** Convert the top P1 entries of the stack into a single entry
|
||||
** suitable for use as a data record in a database table. The
|
||||
** details of the format are irrelavant as long as the OP_Column
|
||||
** opcode can decode the record later. Refer to source code
|
||||
** comments for the details of the record format.
|
||||
**
|
||||
** 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 all index fields have the affinity NONE.
|
||||
*/
|
||||
case OP_MakeRecord: {
|
||||
/* Assuming the record contains N fields, the record format looks
|
||||
** like this:
|
||||
**
|
||||
** --------------------------------------------------------------------------
|
||||
** | header-siz | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 |
|
||||
** --------------------------------------------------------------------------
|
||||
**
|
||||
** Data(0) is taken from the lowest element of the stack and data(N-1) is
|
||||
** the top of the stack.
|
||||
**
|
||||
** Each type field is a varint representing the serial type of the
|
||||
** corresponding data element (see sqlite3VdbeSerialType()). The
|
||||
** num-fields field is also a varint storing N.
|
||||
**
|
||||
** TODO: Even when the record is short enough for Mem::zShort, this opcode
|
||||
** allocates it dynamically.
|
||||
*/
|
||||
int nField = pOp->p1;
|
||||
unsigned char *zNewRecord;
|
||||
unsigned char *zCsr;
|
||||
char *zAffinity;
|
||||
Mem *pRec;
|
||||
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 */
|
||||
|
||||
Mem *pData0 = &pTos[1-nField];
|
||||
assert( pData0>=p->aStack );
|
||||
zAffinity = pOp->p3;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
serial_type = sqlite3VdbeSerialType(pRec);
|
||||
nData += sqlite3VdbeSerialTypeLen(serial_type);
|
||||
nHdr += sqlite3VarintLen(serial_type);
|
||||
}
|
||||
nHdr += sqlite3VarintLen(nHdr);
|
||||
nByte = nHdr+nData;
|
||||
|
||||
if( nByte>MAX_BYTES_PER_ROW ){
|
||||
rc = SQLITE_TOOBIG;
|
||||
goto abort_due_to_error;
|
||||
}
|
||||
|
||||
/* Allocate space for the new record. */
|
||||
zNewRecord = sqliteMallocRaw(nByte);
|
||||
if( !zNewRecord ){
|
||||
goto no_mem;
|
||||
}
|
||||
|
||||
/* Write the record */
|
||||
zCsr = zNewRecord;
|
||||
zCsr += sqlite3PutVarint(zCsr, nHdr);
|
||||
for(pRec=pData0; pRec<=pTos; pRec++){
|
||||
u32 serial_type = sqlite3VdbeSerialType(pRec);
|
||||
zCsr += sqlite3PutVarint(zCsr, serial_type); /* serial type */
|
||||
}
|
||||
for(pRec=pData0; pRec<=pTos; pRec++){
|
||||
zCsr += sqlite3VdbeSerialPut(zCsr, pRec); /* serial data */
|
||||
}
|
||||
|
||||
/* If zCsr has not been advanced exactly nByte bytes, then one
|
||||
** of the sqlite3PutVarint() or sqlite3VdbeSerialPut() calls above
|
||||
** failed. This indicates a corrupted memory cell or code bug.
|
||||
*/
|
||||
if( zCsr!=(zNewRecord+nByte) ){
|
||||
rc = SQLITE_INTERNAL;
|
||||
goto abort_due_to_error;
|
||||
}
|
||||
|
||||
/* 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
|
||||
@ -2135,40 +1972,71 @@ case OP_MakeRecord: {
|
||||
**
|
||||
** If P3 is NULL then datatype coercion occurs.
|
||||
*/
|
||||
/* Opcode MakeRecord P1 * P3
|
||||
**
|
||||
** Convert the top P1 entries of the stack into a single entry
|
||||
** suitable for use as a data record in a database table. The
|
||||
** details of the format are irrelavant as long as the OP_Column
|
||||
** opcode can decode the record later. Refer to source code
|
||||
** comments for the details of the record format.
|
||||
**
|
||||
** 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 all index fields have the affinity NONE.
|
||||
*/
|
||||
case OP_MakeKey:
|
||||
case OP_MakeIdxKey: {
|
||||
case OP_MakeIdxKey:
|
||||
case OP_MakeRecord: {
|
||||
/* Assuming the record contains N fields, the record format looks
|
||||
** like this:
|
||||
**
|
||||
** --------------------------------------------------------------------------
|
||||
** | header-siz | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 |
|
||||
** --------------------------------------------------------------------------
|
||||
**
|
||||
** Data(0) is taken from the lowest element of the stack and data(N-1) is
|
||||
** the top of the stack.
|
||||
**
|
||||
** Each type field is a varint representing the serial type of the
|
||||
** corresponding data element (see sqlite3VdbeSerialType()). The
|
||||
** num-fields field is also a varint storing N.
|
||||
**
|
||||
** TODO: Even when the record is short enough for Mem::zShort, this opcode
|
||||
** allocates it dynamically.
|
||||
*/
|
||||
int nField = pOp->p1;
|
||||
unsigned char *zNewRecord;
|
||||
unsigned char *zCsr;
|
||||
char *zAffinity;
|
||||
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];
|
||||
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;
|
||||
|
||||
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).
|
||||
/* 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);
|
||||
}
|
||||
@ -2176,8 +2044,8 @@ case OP_MakeIdxKey: {
|
||||
containsNull = 1;
|
||||
}
|
||||
serial_type = sqlite3VdbeSerialType(pRec);
|
||||
nByte += sqlite3VarintLen(serial_type);
|
||||
nByte += sqlite3VdbeSerialTypeLen(serial_type);
|
||||
nData += sqlite3VdbeSerialTypeLen(serial_type);
|
||||
nHdr += sqlite3VarintLen(serial_type);
|
||||
}
|
||||
|
||||
/* If we have to append a varint rowid to this record, set 'rowid'
|
||||
@ -2185,45 +2053,63 @@ case OP_MakeIdxKey: {
|
||||
** 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++;
|
||||
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;
|
||||
|
||||
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 ){
|
||||
/* Allocate space for the new record. */
|
||||
zNewRecord = sqliteMallocRaw(nByte);
|
||||
if( !zNewRecord ){
|
||||
goto no_mem;
|
||||
}
|
||||
|
||||
/* Build the key in the buffer pointed to by zKey. */
|
||||
|
||||
/* Write the record */
|
||||
zCsr = zNewRecord;
|
||||
zCsr += sqlite3PutVarint(zCsr, nHdr);
|
||||
for(pRec=pData0; pRec<=pTos; pRec++){
|
||||
u32 serial_type = sqlite3VdbeSerialType(pRec);
|
||||
offset += sqlite3PutVarint(&zKey[offset], serial_type);
|
||||
offset += sqlite3VdbeSerialPut(&zKey[offset], pRec);
|
||||
serial_type = sqlite3VdbeSerialType(pRec);
|
||||
zCsr += sqlite3PutVarint(zCsr, serial_type); /* serial type */
|
||||
}
|
||||
if( addRowid ){
|
||||
zKey[offset++] = '\0';
|
||||
offset += sqlite3PutVarint(&zKey[offset], rowid);
|
||||
zCsr += sqlite3PutVarint(zCsr, sqlite3VdbeSerialType(pRowid));
|
||||
}
|
||||
for(pRec=pData0; pRec<=pTos; pRec++){
|
||||
zCsr += sqlite3VdbeSerialPut(zCsr, pRec); /* serial data */
|
||||
}
|
||||
if( addRowid ){
|
||||
zCsr += sqlite3VdbeSerialPut(zCsr, pRowid);
|
||||
}
|
||||
assert( offset==nByte );
|
||||
|
||||
/* Pop the consumed values off the stack and push on the new key. */
|
||||
if( addRowid||(pOp->p2==0) ){
|
||||
/* If zCsr has not been advanced exactly nByte bytes, then one
|
||||
** of the sqlite3PutVarint() or sqlite3VdbeSerialPut() calls above
|
||||
** failed. This indicates a corrupted memory cell or code bug.
|
||||
*/
|
||||
if( zCsr!=(zNewRecord+nByte) ){
|
||||
rc = SQLITE_INTERNAL;
|
||||
goto abort_due_to_error;
|
||||
}
|
||||
|
||||
/* Pop nField entries from the stack and push the new entry on */
|
||||
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; k<n && i>0; i--){
|
||||
u32 serial_type;
|
||||
k = sqlite3GetVarint32(z, &serial_type);
|
||||
for(; k<n && i>0; 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--;
|
||||
|
Loading…
x
Reference in New Issue
Block a user