1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Merge all of the latest trunk changes into the sessions branch.

FossilOrigin-Name: a9bcb432f58b96f079a73c456efd4851c582221e
This commit is contained in:
drh
2012-01-05 13:02:36 +00:00
116 changed files with 6362 additions and 1967 deletions

View File

@@ -52,7 +52,7 @@
** not misused.
*/
#ifdef SQLITE_DEBUG
# define memAboutToChange(P,M) sqlite3VdbeMemPrepareToChange(P,M)
# define memAboutToChange(P,M) sqlite3VdbeMemAboutToChange(P,M)
#else
# define memAboutToChange(P,M)
#endif
@@ -70,8 +70,8 @@ int sqlite3_search_count = 0;
/*
** When this global variable is positive, it gets decremented once before
** each instruction in the VDBE. When reaches zero, the u1.isInterrupted
** field of the sqlite3 structure is set in order to simulate and interrupt.
** each instruction in the VDBE. When it reaches zero, the u1.isInterrupted
** field of the sqlite3 structure is set in order to simulate an interrupt.
**
** This facility is used for testing purposes only. It does not function
** in an ordinary build.
@@ -206,7 +206,7 @@ static VdbeCursor *allocateCursor(
Vdbe *p, /* The virtual machine */
int iCur, /* Index of the new VdbeCursor */
int nField, /* Number of fields in the table or index */
int iDb, /* When database the cursor belongs to, or -1 */
int iDb, /* Database the cursor belongs to, or -1 */
int isBtreeCursor /* True for B-Tree. False for pseudo-table or vtab */
){
/* Find the memory cell that will be used to store the blob of memory
@@ -488,7 +488,7 @@ static void registerTrace(FILE *out, int iReg, Mem *p){
**
** This macro added to every instruction that does a jump in order to
** implement a loop. This test used to be on every single instruction,
** but that meant we more testing that we needed. By only testing the
** but that meant we more testing than we needed. By only testing the
** flag on jump instructions, we get a (small) speed improvement.
*/
#define CHECK_FOR_INTERRUPT \
@@ -683,7 +683,7 @@ int sqlite3VdbeExec(
assert( pOp->p2<=p->nMem );
pOut = &aMem[pOp->p2];
memAboutToChange(p, pOut);
MemReleaseExt(pOut);
VdbeMemRelease(pOut);
pOut->flags = MEM_Int;
}
@@ -774,7 +774,8 @@ case OP_Goto: { /* jump */
** Write the current address onto register P1
** and then jump to address P2.
*/
case OP_Gosub: { /* jump, in1 */
case OP_Gosub: { /* jump */
assert( pOp->p1>0 && pOp->p1<=p->nMem );
pIn1 = &aMem[pOp->p1];
assert( (pIn1->flags & MEM_Dyn)==0 );
memAboutToChange(p, pIn1);
@@ -971,12 +972,25 @@ case OP_String: { /* out2-prerelease */
break;
}
/* Opcode: Null * P2 * * *
/* Opcode: Null * P2 P3 * *
**
** Write a NULL into register P2.
** Write a NULL into registers P2. If P3 greater than P2, then also write
** NULL into register P3 and ever register in between P2 and P3. If P3
** is less than P2 (typically P3 is zero) then only register P2 is
** set to NULL
*/
case OP_Null: { /* out2-prerelease */
int cnt;
cnt = pOp->p3-pOp->p2;
assert( pOp->p3<=p->nMem );
pOut->flags = MEM_Null;
while( cnt>0 ){
pOut++;
memAboutToChange(p, pOut);
VdbeMemRelease(pOut);
pOut->flags = MEM_Null;
cnt--;
}
break;
}
@@ -1148,7 +1162,7 @@ case OP_ResultRow: {
/* Make sure the results of the current row are \000 terminated
** and have an assigned type. The results are de-ephemeralized as
** as side effect.
** a side effect.
*/
pMem = p->pResultSet = &aMem[pOp->p1];
for(i=0; i<pOp->p2; i++){
@@ -2033,27 +2047,33 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */
/* Opcode: Once P1 P2 * * *
**
** Jump to P2 if the value in register P1 is a not null or zero. If
** the value is NULL or zero, fall through and change the P1 register
** to an integer 1.
** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise,
** set the flag and fall through to the next instruction.
**
** When P1 is not used otherwise in a program, this opcode falls through
** once and jumps on all subsequent invocations. It is the equivalent
** of "OP_If P1 P2", followed by "OP_Integer 1 P1".
** See also: JumpOnce
*/
case OP_Once: { /* jump */
assert( pOp->p1<p->nOnceFlag );
if( p->aOnceFlag[pOp->p1] ){
pc = pOp->p2-1;
}else{
p->aOnceFlag[pOp->p1] = 1;
}
break;
}
/* Opcode: If P1 P2 P3 * *
**
** Jump to P2 if the value in register P1 is true. The value
** is considered true if it is numeric and non-zero. If the value
** in P1 is NULL then take the jump if P3 is true.
** in P1 is NULL then take the jump if P3 is non-zero.
*/
/* Opcode: IfNot P1 P2 P3 * *
**
** Jump to P2 if the value in register P1 is False. The value
** is considered true if it has a numeric value of zero. If the value
** in P1 is NULL then take the jump if P3 is true.
** is considered false if it has a numeric value of zero. If the value
** in P1 is NULL then take the jump if P3 is zero.
*/
case OP_Once: /* jump, in1 */
case OP_If: /* jump, in1 */
case OP_IfNot: { /* jump, in1 */
int c;
@@ -2070,12 +2090,6 @@ case OP_IfNot: { /* jump, in1 */
}
if( c ){
pc = pOp->p2-1;
}else if( pOp->opcode==OP_Once ){
assert( (pIn1->flags & (MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))==0 );
memAboutToChange(p, pIn1);
pIn1->flags = MEM_Int;
pIn1->u.i = 1;
REGISTER_TRACE(pOp->p1, pIn1);
}
break;
}
@@ -2371,7 +2385,7 @@ case OP_Column: {
if( aOffset[p2] ){
assert( rc==SQLITE_OK );
if( zRec ){
MemReleaseExt(pDest);
VdbeMemRelease(pDest);
sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], pDest);
}else{
len = sqlite3VdbeSerialTypeLen(aType[p2]);
@@ -4668,9 +4682,9 @@ case OP_IdxGE: { /* jump */
r.pKeyInfo = pC->pKeyInfo;
r.nField = (u16)pOp->p4.i;
if( pOp->p5 ){
r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID;
r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH;
}else{
r.flags = UNPACKED_IGNORE_ROWID;
r.flags = UNPACKED_PREFIX_MATCH;
}
r.aMem = &aMem[pOp->p3];
#ifdef SQLITE_DEBUG
@@ -5123,7 +5137,6 @@ case OP_Program: { /* jump */
pProgram = pOp->p4.pProgram;
pRt = &aMem[pOp->p3];
assert( memIsValid(pRt) );
assert( pProgram->nOp>0 );
/* If the p5 flag is clear, then recursive invocation of triggers is
@@ -5162,7 +5175,8 @@ case OP_Program: { /* jump */
nMem = pProgram->nMem + pProgram->nCsr;
nByte = ROUND8(sizeof(VdbeFrame))
+ nMem * sizeof(Mem)
+ pProgram->nCsr * sizeof(VdbeCursor *);
+ pProgram->nCsr * sizeof(VdbeCursor *)
+ pProgram->nOnce * sizeof(u8);
pFrame = sqlite3DbMallocZero(db, nByte);
if( !pFrame ){
goto no_mem;
@@ -5182,10 +5196,12 @@ case OP_Program: { /* jump */
pFrame->aOp = p->aOp;
pFrame->nOp = p->nOp;
pFrame->token = pProgram->token;
pFrame->aOnceFlag = p->aOnceFlag;
pFrame->nOnceFlag = p->nOnceFlag;
pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem];
for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){
pMem->flags = MEM_Null;
pMem->flags = MEM_Invalid;
pMem->db = db;
}
}else{
@@ -5207,7 +5223,11 @@ case OP_Program: { /* jump */
p->apCsr = (VdbeCursor **)&aMem[p->nMem+1];
p->aOp = aOp = pProgram->aOp;
p->nOp = pProgram->nOp;
p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
p->nOnceFlag = pProgram->nOnce;
p->nOp = pProgram->nOp;
pc = -1;
memset(p->aOnceFlag, 0, p->nOnceFlag);
break;
}