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

Merge all recent enhancements from trunk.

FossilOrigin-Name: f3f9200115caf4b356f90ec97c351d1afbcb9bf6
This commit is contained in:
drh
2016-02-02 02:22:30 +00:00
79 changed files with 3330 additions and 1132 deletions

View File

@@ -481,6 +481,7 @@ static void memTracePrint(Mem *p){
sqlite3VdbeMemPrettyPrint(p, zBuf);
printf(" %s", zBuf);
}
if( p->flags & MEM_Subtype ) printf(" subtype=0x%02x", p->eSubtype);
}
static void registerTrace(int iReg, Mem *p){
printf("REG[%d] = ", iReg);
@@ -561,6 +562,9 @@ int sqlite3VdbeExec(
Op *pOp = aOp; /* Current operation */
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
Op *pOrigOp; /* Value of pOp at the top of the loop */
#endif
#ifdef SQLITE_DEBUG
int nExtraDelete = 0; /* Verifies FORDELETE and AUXDELETE flags */
#endif
int rc = SQLITE_OK; /* Value to return */
sqlite3 *db = p->db; /* The database */
@@ -2077,11 +2081,14 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
** The permutation is only valid until the next OP_Compare that has
** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should
** occur immediately prior to the OP_Compare.
**
** The first integer in the P4 integer array is the length of the array
** and does not become part of the permutation.
*/
case OP_Permutation: {
assert( pOp->p4type==P4_INTARRAY );
assert( pOp->p4.ai );
aPermute = pOp->p4.ai;
aPermute = pOp->p4.ai + 1;
break;
}
@@ -2386,12 +2393,16 @@ case OP_Column: {
u32 t; /* A type code from the record header */
Mem *pReg; /* PseudoTable input register */
pC = p->apCsr[pOp->p1];
p2 = pOp->p2;
/* If the cursor cache is stale, bring it up-to-date */
rc = sqlite3VdbeCursorMoveto(&pC, &p2);
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
pDest = &aMem[pOp->p3];
memAboutToChange(p, pDest);
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( p2<pC->nField );
aOffset = pC->aOffset;
@@ -2400,8 +2411,6 @@ case OP_Column: {
assert( pC->eCurType!=CURTYPE_SORTER );
pCrsr = pC->uc.pCursor;
/* If the cursor cache is stale, bring it up-to-date */
rc = sqlite3VdbeCursorMoveto(pC);
if( rc ) goto abort_due_to_error;
if( pC->cacheStatus!=p->cacheCtr ){
if( pC->nullRow ){
@@ -3009,28 +3018,27 @@ case OP_Savepoint: {
case OP_AutoCommit: {
int desiredAutoCommit;
int iRollback;
int turnOnAC;
desiredAutoCommit = pOp->p1;
iRollback = pOp->p2;
turnOnAC = desiredAutoCommit && !db->autoCommit;
assert( desiredAutoCommit==1 || desiredAutoCommit==0 );
assert( desiredAutoCommit==1 || iRollback==0 );
assert( db->nVdbeActive>0 ); /* At least this one VM is active */
assert( p->bIsReader );
if( turnOnAC && !iRollback && db->nVdbeWrite>0 ){
/* If this instruction implements a COMMIT and other VMs are writing
** return an error indicating that the other VMs must complete first.
*/
sqlite3VdbeError(p, "cannot commit transaction - "
"SQL statements in progress");
rc = SQLITE_BUSY;
}else if( desiredAutoCommit!=db->autoCommit ){
if( desiredAutoCommit!=db->autoCommit ){
if( iRollback ){
assert( desiredAutoCommit==1 );
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
db->autoCommit = 1;
}else if( desiredAutoCommit && db->nVdbeWrite>0 ){
/* If this instruction implements a COMMIT and other VMs are writing
** return an error indicating that the other VMs must complete first.
*/
sqlite3VdbeError(p, "cannot commit transaction - "
"SQL statements in progress");
rc = SQLITE_BUSY;
break;
}else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
goto vdbe_return;
}else{
@@ -3215,15 +3223,15 @@ case OP_ReadCookie: { /* out2 */
/* Opcode: SetCookie P1 P2 P3 * *
**
** Write the content of register P3 (interpreted as an integer)
** into cookie number P2 of database P1. P2==1 is the schema version.
** P2==2 is the database format. P2==3 is the recommended pager cache
** Write the integer value P3 into cookie number P2 of database P1.
** P2==1 is the schema version. P2==2 is the database format.
** P2==3 is the recommended pager cache
** size, and so forth. P1==0 is the main database file and P1==1 is the
** database file used to store temporary tables.
**
** A transaction must be started before executing this opcode.
*/
case OP_SetCookie: { /* in3 */
case OP_SetCookie: {
Db *pDb;
assert( pOp->p2<SQLITE_N_BTREE_META );
assert( pOp->p1>=0 && pOp->p1<db->nDb );
@@ -3232,17 +3240,15 @@ case OP_SetCookie: { /* in3 */
pDb = &db->aDb[pOp->p1];
assert( pDb->pBt!=0 );
assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
pIn3 = &aMem[pOp->p3];
sqlite3VdbeMemIntegerify(pIn3);
/* See note about index shifting on OP_ReadCookie */
rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, (int)pIn3->u.i);
rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, pOp->p3);
if( pOp->p2==BTREE_SCHEMA_VERSION ){
/* When the schema cookie changes, record the new cookie internally */
pDb->pSchema->schema_cookie = (int)pIn3->u.i;
pDb->pSchema->schema_cookie = pOp->p3;
db->flags |= SQLITE_InternChanges;
}else if( pOp->p2==BTREE_FILE_FORMAT ){
/* Record changes in the file format */
pDb->pSchema->file_format = (u8)pIn3->u.i;
pDb->pSchema->file_format = pOp->p3;
}
if( pOp->p1==1 ){
/* Invalidate all prepared statements whenever the TEMP database
@@ -3402,6 +3408,9 @@ case OP_OpenWrite:
pCur->nullRow = 1;
pCur->isOrdered = 1;
pCur->pgnoRoot = p2;
#ifdef SQLITE_DEBUG
pCur->wrFlag = wrFlag;
#endif
rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->uc.pCursor);
pCur->pKeyInfo = pKeyInfo;
/* Set the VdbeCursor.isTable variable. Previous versions of
@@ -3855,32 +3864,6 @@ seek_not_found:
}
break;
}
/* Opcode: Seek P1 P2 * * *
** Synopsis: intkey=r[P2]
**
** P1 is an open table cursor and P2 is a rowid integer. Arrange
** for P1 to move so that it points to the rowid given by P2.
**
** This is actually a deferred seek. Nothing actually happens until
** the cursor is used to read a record. That way, if no reads
** occur, no unnecessary I/O happens.
*/
case OP_Seek: { /* in2 */
VdbeCursor *pC;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( pC->eCurType==CURTYPE_BTREE );
assert( pC->uc.pCursor!=0 );
assert( pC->isTable );
pC->nullRow = 0;
pIn2 = &aMem[pOp->p2];
pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
pC->deferredMoveto = 1;
break;
}
/* Opcode: Found P1 P2 P3 P4 *
@@ -4366,14 +4349,22 @@ case OP_InsertInt: {
**
** Delete the record at which the P1 cursor is currently pointing.
**
** If the P5 parameter is non-zero, the cursor will be left pointing at
** either the next or the previous record in the table. If it is left
** pointing at the next record, then the next Next instruction will be a
** no-op. As a result, in this case it is OK to delete a record from within a
** Next loop. If P5 is zero, then the cursor is left in an undefined state.
** If the OPFLAG_SAVEPOSITION bit of the P5 parameter is set, then
** the cursor will be left pointing at either the next or the previous
** record in the table. If it is left pointing at the next record, then
** the next Next instruction will be a no-op. As a result, in this case
** it is ok to delete a record from within a Next loop. If
** OPFLAG_SAVEPOSITION bit of P5 is clear, then the cursor will be
** left in an undefined state.
**
** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
** incremented (otherwise not).
** If the OPFLAG_AUXDELETE bit is set on P5, that indicates that this
** delete one of several associated with deleting a table row and all its
** associated index entries. Exactly one of those deletes is the "primary"
** delete. The others are all on OPFLAG_FORDELETE cursors or else are
** marked with the AUXDELETE flag.
**
** If the OPFLAG_NCHANGE flag of P2 (NB: P2 not P5) is set, then the row
** change count is incremented (otherwise not).
**
** P1 must not be pseudo-table. It has to be a real table with
** multiple rows.
@@ -4442,6 +4433,25 @@ case OP_Delete: {
if( opflags & OPFLAG_ISNOOP ) break;
/* Only flags that can be set are SAVEPOISTION and AUXDELETE */
assert( (pOp->p5 & ~(OPFLAG_SAVEPOSITION|OPFLAG_AUXDELETE))==0 );
assert( OPFLAG_SAVEPOSITION==BTREE_SAVEPOSITION );
assert( OPFLAG_AUXDELETE==BTREE_AUXDELETE );
#ifdef SQLITE_DEBUG
if( p->pFrame==0 ){
if( pC->isEphemeral==0
&& (pOp->p5 & OPFLAG_AUXDELETE)==0
&& (pC->wrFlag & OPFLAG_FORDELETE)==0
){
nExtraDelete++;
}
if( pOp->p2 & OPFLAG_NCHANGE ){
nExtraDelete--;
}
}
#endif
rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5);
pC->cacheStatus = CACHE_STALE;
@@ -4989,18 +4999,34 @@ case OP_IdxDelete: {
r.nField = (u16)pOp->p3;
r.default_rc = 0;
r.aMem = &aMem[pOp->p2];
#ifdef SQLITE_DEBUG
{ int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
#endif
rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res);
if( rc==SQLITE_OK && res==0 ){
rc = sqlite3BtreeDelete(pCrsr, 0);
rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE);
}
assert( pC->deferredMoveto==0 );
pC->cacheStatus = CACHE_STALE;
break;
}
/* Opcode: Seek P1 * P3 P4 *
** Synopsis: Move P3 to P1.rowid
**
** P1 is an open index cursor and P3 is a cursor on the corresponding
** table. This opcode does a deferred seek of the P3 table cursor
** to the row that corresponds to the current row of P1.
**
** This is a deferred seek. Nothing actually happens until
** the cursor is used to read a record. That way, if no reads
** occur, no unnecessary I/O happens.
**
** P4 may be an array of integers (type P4_INTARRAY) containing
** one entry for each column in the P3 table. If array entry a[i]
** is non-zero, then reading column (a[i]-1) from cursor P3 is
** equivalent to performing the deferred seek and then reading column i
** from P1. This information is stored in P3 and used to redirect
** reads against P3 over to P1, thus possibly avoiding the need to
** seek and read cursor P3.
*/
/* Opcode: IdxRowid P1 P2 * * *
** Synopsis: r[P2]=rowid
**
@@ -5010,37 +5036,57 @@ case OP_IdxDelete: {
**
** See also: Rowid, MakeRecord.
*/
case OP_Seek:
case OP_IdxRowid: { /* out2 */
BtCursor *pCrsr;
VdbeCursor *pC;
i64 rowid;
VdbeCursor *pC; /* The P1 index cursor */
VdbeCursor *pTabCur; /* The P2 table cursor (OP_Seek only) */
i64 rowid; /* Rowid that P1 current points to */
pOut = out2Prerelease(p, pOp);
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( pC->eCurType==CURTYPE_BTREE );
pCrsr = pC->uc.pCursor;
assert( pCrsr!=0 );
pOut->flags = MEM_Null;
assert( pC->uc.pCursor!=0 );
assert( pC->isTable==0 );
assert( pC->deferredMoveto==0 );
assert( !pC->nullRow || pOp->opcode==OP_IdxRowid );
/* The IdxRowid and Seek opcodes are combined because of the commonality
** of sqlite3VdbeCursorRestore() and sqlite3VdbeIdxRowid(). */
rc = sqlite3VdbeCursorRestore(pC);
/* sqlite3VbeCursorRestore() can only fail if the record has been deleted
** out from under the cursor. That will never happend for an IdxRowid
** opcode, hence the NEVER() arround the check of the return value.
*/
rc = sqlite3VdbeCursorRestore(pC);
** out from under the cursor. That will never happens for an IdxRowid
** or Seek opcode */
if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
if( !pC->nullRow ){
rowid = 0; /* Not needed. Only used to silence a warning. */
rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid);
rc = sqlite3VdbeIdxRowid(db, pC->uc.pCursor, &rowid);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
pOut->u.i = rowid;
pOut->flags = MEM_Int;
if( pOp->opcode==OP_Seek ){
assert( pOp->p3>=0 && pOp->p3<p->nCursor );
pTabCur = p->apCsr[pOp->p3];
assert( pTabCur!=0 );
assert( pTabCur->eCurType==CURTYPE_BTREE );
assert( pTabCur->uc.pCursor!=0 );
assert( pTabCur->isTable );
pTabCur->nullRow = 0;
pTabCur->movetoTarget = rowid;
pTabCur->deferredMoveto = 1;
assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 );
pTabCur->aAltMap = pOp->p4.ai;
pTabCur->pAltCursor = pC;
}else{
pOut = out2Prerelease(p, pOp);
pOut->u.i = rowid;
pOut->flags = MEM_Int;
}
}else{
assert( pOp->opcode==OP_IdxRowid );
sqlite3VdbeMemSetNull(&aMem[pOp->p2]);
}
break;
}
@@ -5817,20 +5863,31 @@ case OP_IfPos: { /* jump, in1 */
break;
}
/* Opcode: SetIfNotPos P1 P2 P3 * *
** Synopsis: if r[P1]<=0 then r[P2]=P3
/* Opcode: OffsetLimit P1 P2 P3 * *
** Synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)
**
** Register P1 must contain an integer.
** If the value of register P1 is not positive (if it is less than 1) then
** set the value of register P2 to be the integer P3.
** This opcode performs a commonly used computation associated with
** LIMIT and OFFSET process. r[P1] holds the limit counter. r[P3]
** holds the offset counter. The opcode computes the combined value
** of the LIMIT and OFFSET and stores that value in r[P2]. The r[P2]
** value computed is the total number of rows that will need to be
** visited in order to complete the query.
**
** If r[P3] is zero or negative, that means there is no OFFSET
** and r[P2] is set to be the value of the LIMIT, r[P1].
**
** if r[P1] is zero or negative, that means there is no LIMIT
** and r[P2] is set to -1.
**
** Otherwise, r[P2] is set to the sum of r[P1] and r[P3].
*/
case OP_SetIfNotPos: { /* in1, in2 */
case OP_OffsetLimit: { /* in1, out2, in3 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
if( pIn1->u.i<=0 ){
pOut = out2Prerelease(p, pOp);
pOut->u.i = pOp->p3;
}
pIn3 = &aMem[pOp->p3];
pOut = out2Prerelease(p, pOp);
assert( pIn1->flags & MEM_Int );
assert( pIn3->flags & MEM_Int );
pOut->u.i = pIn1->u.i<=0 ? -1 : pIn1->u.i+(pIn3->u.i>0?pIn3->u.i:0);
break;
}
@@ -6802,6 +6859,9 @@ vdbe_return:
testcase( nVmStep>0 );
p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep;
sqlite3VdbeLeave(p);
assert( rc!=SQLITE_OK || nExtraDelete==0
|| sqlite3_strlike("DELETE%",p->zSql,0)!=0
);
return rc;
/* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH