vdbe.c.svn-base
上传用户:sunhongbo
上传日期:2022-01-25
资源大小:3010k
文件大小:151k
- pDb->pSchema->schema_cookie = pIn3->u.i;
- db->flags |= SQLITE_InternChanges;
- }else if( pOp->p2==1 ){
- /* Record changes in the file format */
- pDb->pSchema->file_format = pIn3->u.i;
- }
- if( pOp->p1==1 ){
- /* Invalidate all prepared statements whenever the TEMP database
- ** schema is changed. Ticket #1644 */
- sqlite3ExpirePreparedStatements(db);
- }
- break;
- }
- /* Opcode: VerifyCookie P1 P2 *
- **
- ** Check the value of global database parameter number 0 (the
- ** schema version) and make sure it is equal to P2.
- ** P1 is the database number which is 0 for the main database file
- ** and 1 for the file holding temporary tables and some higher number
- ** for auxiliary databases.
- **
- ** The cookie changes its value whenever the database schema changes.
- ** This operation is used to detect when that the cookie has changed
- ** and that the current process needs to reread the schema.
- **
- ** Either a transaction needs to have been started or an OP_Open needs
- ** to be executed (to establish a read lock) before this opcode is
- ** invoked.
- */
- case OP_VerifyCookie: {
- int iMeta;
- Btree *pBt;
- assert( pOp->p1>=0 && pOp->p1<db->nDb );
- assert( (p->btreeMask & (1<<pOp->p1))!=0 );
- pBt = db->aDb[pOp->p1].pBt;
- if( pBt ){
- rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&iMeta);
- }else{
- rc = SQLITE_OK;
- iMeta = 0;
- }
- if( rc==SQLITE_OK && iMeta!=pOp->p2 ){
- sqlite3_free(p->zErrMsg);
- p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
- /* If the schema-cookie from the database file matches the cookie
- ** stored with the in-memory representation of the schema, do
- ** not reload the schema from the database file.
- **
- ** If virtual-tables are in use, this is not just an optimisation.
- ** Often, v-tables store their data in other SQLite tables, which
- ** are queried from within xNext() and other v-table methods using
- ** prepared queries. If such a query is out-of-date, we do not want to
- ** discard the database schema, as the user code implementing the
- ** v-table would have to be ready for the sqlite3_vtab structure itself
- ** to be invalidated whenever sqlite3_step() is called from within
- ** a v-table method.
- */
- if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){
- sqlite3ResetInternalSchema(db, pOp->p1);
- }
- sqlite3ExpirePreparedStatements(db);
- rc = SQLITE_SCHEMA;
- }
- break;
- }
- /* Opcode: OpenRead P1 P2 P3 P4 P5
- **
- ** Open a read-only cursor for the database table whose root page is
- ** P2 in a database file. The database file is determined by P3.
- ** P3==0 means the main database, P3==1 means the database used for
- ** temporary tables, and P3>1 means used the corresponding attached
- ** database. Give the new cursor an identifier of P1. The P1
- ** values need not be contiguous but all P1 values should be small integers.
- ** It is an error for P1 to be negative.
- **
- ** If P5!=0 then use the content of register P2 as the root page, not
- ** the value of P2 itself.
- **
- ** There will be a read lock on the database whenever there is an
- ** open cursor. If the database was unlocked prior to this instruction
- ** then a read lock is acquired as part of this instruction. A read
- ** lock allows other processes to read the database but prohibits
- ** any other process from modifying the database. The read lock is
- ** released when all cursors are closed. If this instruction attempts
- ** to get a read lock but fails, the script terminates with an
- ** SQLITE_BUSY error code.
- **
- ** The P4 value is a pointer to a KeyInfo structure that defines the
- ** content and collating sequence of indices. P4 is NULL for cursors
- ** that are not pointing to indices.
- **
- ** See also OpenWrite.
- */
- /* Opcode: OpenWrite P1 P2 P3 P4 P5
- **
- ** Open a read/write cursor named P1 on the table or index whose root
- ** page is P2. Or if P5!=0 use the content of register P2 to find the
- ** root page.
- **
- ** The P4 value is a pointer to a KeyInfo structure that defines the
- ** content and collating sequence of indices. P4 is NULL for cursors
- ** that are not pointing to indices.
- **
- ** This instruction works just like OpenRead except that it opens the cursor
- ** in read/write mode. For a given table, there can be one or more read-only
- ** cursors or a single read/write cursor but not both.
- **
- ** See also OpenRead.
- */
- case OP_OpenRead:
- case OP_OpenWrite: {
- int i = pOp->p1;
- int p2 = pOp->p2;
- int iDb = pOp->p3;
- int wrFlag;
- Btree *pX;
- Cursor *pCur;
- Db *pDb;
-
- assert( iDb>=0 && iDb<db->nDb );
- assert( (p->btreeMask & (1<<iDb))!=0 );
- pDb = &db->aDb[iDb];
- pX = pDb->pBt;
- assert( pX!=0 );
- if( pOp->opcode==OP_OpenWrite ){
- wrFlag = 1;
- if( pDb->pSchema->file_format < p->minWriteFileFormat ){
- p->minWriteFileFormat = pDb->pSchema->file_format;
- }
- }else{
- wrFlag = 0;
- }
- if( pOp->p5 ){
- assert( p2>0 );
- assert( p2<=p->nMem );
- pIn2 = &p->aMem[p2];
- sqlite3VdbeMemIntegerify(pIn2);
- p2 = pIn2->u.i;
- assert( p2>=2 );
- }
- assert( i>=0 );
- pCur = allocateCursor(p, i, &pOp[-1], iDb, 1);
- if( pCur==0 ) goto no_mem;
- pCur->nullRow = 1;
- rc = sqlite3BtreeCursor(pX, p2, wrFlag, pOp->p4.p, pCur->pCursor);
- if( pOp->p4type==P4_KEYINFO ){
- pCur->pKeyInfo = pOp->p4.pKeyInfo;
- pCur->pIncrKey = &pCur->pKeyInfo->incrKey;
- pCur->pKeyInfo->enc = ENC(p->db);
- }else{
- pCur->pKeyInfo = 0;
- pCur->pIncrKey = &pCur->bogusIncrKey;
- }
- switch( rc ){
- case SQLITE_BUSY: {
- p->pc = pc;
- p->rc = rc = SQLITE_BUSY;
- goto vdbe_return;
- }
- case SQLITE_OK: {
- int flags = sqlite3BtreeFlags(pCur->pCursor);
- /* Sanity checking. Only the lower four bits of the flags byte should
- ** be used. Bit 3 (mask 0x08) is unpreditable. The lower 3 bits
- ** (mask 0x07) should be either 5 (intkey+leafdata for tables) or
- ** 2 (zerodata for indices). If these conditions are not met it can
- ** only mean that we are dealing with a corrupt database file
- */
- if( (flags & 0xf0)!=0 || ((flags & 0x07)!=5 && (flags & 0x07)!=2) ){
- rc = SQLITE_CORRUPT_BKPT;
- goto abort_due_to_error;
- }
- pCur->isTable = (flags & BTREE_INTKEY)!=0;
- pCur->isIndex = (flags & BTREE_ZERODATA)!=0;
- /* If P4==0 it means we are expected to open a table. If P4!=0 then
- ** we expect to be opening an index. If this is not what happened,
- ** then the database is corrupt
- */
- if( (pCur->isTable && pOp->p4type==P4_KEYINFO)
- || (pCur->isIndex && pOp->p4type!=P4_KEYINFO) ){
- rc = SQLITE_CORRUPT_BKPT;
- goto abort_due_to_error;
- }
- break;
- }
- case SQLITE_EMPTY: {
- pCur->isTable = pOp->p4type!=P4_KEYINFO;
- pCur->isIndex = !pCur->isTable;
- pCur->pCursor = 0;
- rc = SQLITE_OK;
- break;
- }
- default: {
- goto abort_due_to_error;
- }
- }
- break;
- }
- /* Opcode: OpenEphemeral P1 P2 * P4 *
- **
- ** Open a new cursor P1 to a transient table.
- ** The cursor is always opened read/write even if
- ** the main database is read-only. The transient or virtual
- ** table is deleted automatically when the cursor is closed.
- **
- ** P2 is the number of columns in the virtual table.
- ** The cursor points to a BTree table if P4==0 and to a BTree index
- ** if P4 is not 0. If P4 is not NULL, it points to a KeyInfo structure
- ** that defines the format of keys in the index.
- **
- ** This opcode was once called OpenTemp. But that created
- ** confusion because the term "temp table", might refer either
- ** to a TEMP table at the SQL level, or to a table opened by
- ** this opcode. Then this opcode was call OpenVirtual. But
- ** that created confusion with the whole virtual-table idea.
- */
- case OP_OpenEphemeral: {
- int i = pOp->p1;
- Cursor *pCx;
- static const int openFlags =
- SQLITE_OPEN_READWRITE |
- SQLITE_OPEN_CREATE |
- SQLITE_OPEN_EXCLUSIVE |
- SQLITE_OPEN_DELETEONCLOSE |
- SQLITE_OPEN_TRANSIENT_DB;
- assert( i>=0 );
- pCx = allocateCursor(p, i, pOp, -1, 1);
- if( pCx==0 ) goto no_mem;
- pCx->nullRow = 1;
- rc = sqlite3BtreeFactory(db, 0, 1, SQLITE_DEFAULT_TEMP_CACHE_SIZE, openFlags,
- &pCx->pBt);
- if( rc==SQLITE_OK ){
- rc = sqlite3BtreeBeginTrans(pCx->pBt, 1);
- }
- if( rc==SQLITE_OK ){
- /* If a transient index is required, create it by calling
- ** sqlite3BtreeCreateTable() with the BTREE_ZERODATA flag before
- ** opening it. If a transient table is required, just use the
- ** automatically created table with root-page 1 (an INTKEY table).
- */
- if( pOp->p4.pKeyInfo ){
- int pgno;
- assert( pOp->p4type==P4_KEYINFO );
- rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_ZERODATA);
- if( rc==SQLITE_OK ){
- assert( pgno==MASTER_ROOT+1 );
- rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1,
- (KeyInfo*)pOp->p4.z, pCx->pCursor);
- pCx->pKeyInfo = pOp->p4.pKeyInfo;
- pCx->pKeyInfo->enc = ENC(p->db);
- pCx->pIncrKey = &pCx->pKeyInfo->incrKey;
- }
- pCx->isTable = 0;
- }else{
- rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, pCx->pCursor);
- pCx->isTable = 1;
- pCx->pIncrKey = &pCx->bogusIncrKey;
- }
- }
- pCx->isIndex = !pCx->isTable;
- break;
- }
- /* Opcode: OpenPseudo P1 P2 * * *
- **
- ** Open a new cursor that points to a fake table that contains a single
- ** row of data. Any attempt to write a second row of data causes the
- ** first row to be deleted. All data is deleted when the cursor is
- ** closed.
- **
- ** A pseudo-table created by this opcode is useful for holding the
- ** NEW or OLD tables in a trigger. Also used to hold the a single
- ** row output from the sorter so that the row can be decomposed into
- ** individual columns using the OP_Column opcode.
- **
- ** When OP_Insert is executed to insert a row in to the pseudo table,
- ** the pseudo-table cursor may or may not make it's own copy of the
- ** original row data. If P2 is 0, then the pseudo-table will copy the
- ** original row data. Otherwise, a pointer to the original memory cell
- ** is stored. In this case, the vdbe program must ensure that the
- ** memory cell containing the row data is not overwritten until the
- ** pseudo table is closed (or a new row is inserted into it).
- */
- case OP_OpenPseudo: {
- int i = pOp->p1;
- Cursor *pCx;
- assert( i>=0 );
- pCx = allocateCursor(p, i, &pOp[-1], -1, 0);
- if( pCx==0 ) goto no_mem;
- pCx->nullRow = 1;
- pCx->pseudoTable = 1;
- pCx->ephemPseudoTable = pOp->p2;
- pCx->pIncrKey = &pCx->bogusIncrKey;
- pCx->isTable = 1;
- pCx->isIndex = 0;
- break;
- }
- /* Opcode: Close P1 * * * *
- **
- ** Close a cursor previously opened as P1. If P1 is not
- ** currently open, this instruction is a no-op.
- */
- case OP_Close: {
- int i = pOp->p1;
- assert( i>=0 && i<p->nCursor );
- sqlite3VdbeFreeCursor(p, p->apCsr[i]);
- p->apCsr[i] = 0;
- break;
- }
- /* Opcode: MoveGe P1 P2 P3 * *
- **
- ** Use the value in register P3 as a key. Reposition
- ** cursor P1 so that it points to the smallest entry that is greater
- ** than or equal to the key in register P3.
- ** If there are no records greater than or equal to the key and P2
- ** is not zero, then jump to P2.
- **
- ** A special feature of this opcode (and different from the
- ** related OP_MoveGt, OP_MoveLt, and OP_MoveLe) is that if P2 is
- ** zero and P1 is an SQL table (a b-tree with integer keys) then
- ** the seek is deferred until it is actually needed. It might be
- ** the case that the cursor is never accessed. By deferring the
- ** seek, we avoid unnecessary seeks.
- **
- ** See also: Found, NotFound, Distinct, MoveLt, MoveGt, MoveLe
- */
- /* Opcode: MoveGt P1 P2 P3 * *
- **
- ** Use the value in register P3 as a key. Reposition
- ** cursor P1 so that it points to the smallest entry that is greater
- ** than the key in register P3.
- ** If there are no records greater than the key
- ** then jump to P2.
- **
- ** See also: Found, NotFound, Distinct, MoveLt, MoveGe, MoveLe
- */
- /* Opcode: MoveLt P1 P2 P3 * *
- **
- ** Use the value in register P3 as a key. Reposition
- ** cursor P1 so that it points to the largest entry that is less
- ** than the key in register P3.
- ** If there are no records less than the key
- ** then jump to P2.
- **
- ** See also: Found, NotFound, Distinct, MoveGt, MoveGe, MoveLe
- */
- /* Opcode: MoveLe P1 P2 P3 * *
- **
- ** Use the value in register P3 as a key. Reposition
- ** cursor P1 so that it points to the largest entry that is less than
- ** or equal to the key.
- ** If there are no records less than or eqal to the key
- ** then jump to P2.
- **
- ** See also: Found, NotFound, Distinct, MoveGt, MoveGe, MoveLt
- */
- case OP_MoveLt: /* jump, in3 */
- case OP_MoveLe: /* jump, in3 */
- case OP_MoveGe: /* jump, in3 */
- case OP_MoveGt: { /* jump, in3 */
- int i = pOp->p1;
- Cursor *pC;
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC!=0 );
- if( pC->pCursor!=0 ){
- int res, oc;
- oc = pOp->opcode;
- pC->nullRow = 0;
- *pC->pIncrKey = oc==OP_MoveGt || oc==OP_MoveLe;
- if( pC->isTable ){
- i64 iKey = sqlite3VdbeIntValue(pIn3);
- if( pOp->p2==0 ){
- assert( pOp->opcode==OP_MoveGe );
- pC->movetoTarget = iKey;
- pC->rowidIsValid = 0;
- pC->deferredMoveto = 1;
- break;
- }
- rc = sqlite3BtreeMoveto(pC->pCursor, 0, 0, (u64)iKey, 0, &res);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- pC->lastRowid = iKey;
- pC->rowidIsValid = res==0;
- }else{
- assert( pIn3->flags & MEM_Blob );
- ExpandBlob(pIn3);
- rc = sqlite3BtreeMoveto(pC->pCursor, pIn3->z, 0, pIn3->n, 0, &res);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- pC->rowidIsValid = 0;
- }
- pC->deferredMoveto = 0;
- pC->cacheStatus = CACHE_STALE;
- *pC->pIncrKey = 0;
- #ifdef SQLITE_TEST
- sqlite3_search_count++;
- #endif
- if( oc==OP_MoveGe || oc==OP_MoveGt ){
- if( res<0 ){
- rc = sqlite3BtreeNext(pC->pCursor, &res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- pC->rowidIsValid = 0;
- }else{
- res = 0;
- }
- }else{
- assert( oc==OP_MoveLt || oc==OP_MoveLe );
- if( res>=0 ){
- rc = sqlite3BtreePrevious(pC->pCursor, &res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- pC->rowidIsValid = 0;
- }else{
- /* res might be negative because the table is empty. Check to
- ** see if this is the case.
- */
- res = sqlite3BtreeEof(pC->pCursor);
- }
- }
- assert( pOp->p2>0 );
- if( res ){
- pc = pOp->p2 - 1;
- }
- }
- break;
- }
- /* Opcode: Found P1 P2 P3 * *
- **
- ** Register P3 holds a blob constructed by MakeRecord. P1 is an index.
- ** If an entry that matches the value in register p3 exists in P1 then
- ** jump to P2. If the P3 value does not match any entry in P1
- ** then fall thru. The P1 cursor is left pointing at the matching entry
- ** if it exists.
- **
- ** This instruction is used to implement the IN operator where the
- ** left-hand side is a SELECT statement. P1 may be a true index, or it
- ** may be a temporary index that holds the results of the SELECT
- ** statement. This instruction is also used to implement the
- ** DISTINCT keyword in SELECT statements.
- **
- ** This instruction checks if index P1 contains a record for which
- ** the first N serialised values exactly match the N serialised values
- ** in the record in register P3, where N is the total number of values in
- ** the P3 record (the P3 record is a prefix of the P1 record).
- **
- ** See also: NotFound, MoveTo, IsUnique, NotExists
- */
- /* Opcode: NotFound P1 P2 P3 * *
- **
- ** Register P3 holds a blob constructed by MakeRecord. P1 is
- ** an index. If no entry exists in P1 that matches the blob then jump
- ** to P2. If an entry does existing, fall through. The cursor is left
- ** pointing to the entry that matches.
- **
- ** See also: Found, MoveTo, NotExists, IsUnique
- */
- case OP_NotFound: /* jump, in3 */
- case OP_Found: { /* jump, in3 */
- int i = pOp->p1;
- int alreadyExists = 0;
- Cursor *pC;
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
- if( (pC = p->apCsr[i])->pCursor!=0 ){
- int res;
- assert( pC->isTable==0 );
- assert( pIn3->flags & MEM_Blob );
- if( pOp->opcode==OP_Found ){
- pC->pKeyInfo->prefixIsEqual = 1;
- }
- rc = sqlite3BtreeMoveto(pC->pCursor, pIn3->z, 0, pIn3->n, 0, &res);
- pC->pKeyInfo->prefixIsEqual = 0;
- if( rc!=SQLITE_OK ){
- break;
- }
- alreadyExists = (res==0);
- pC->deferredMoveto = 0;
- pC->cacheStatus = CACHE_STALE;
- }
- if( pOp->opcode==OP_Found ){
- if( alreadyExists ) pc = pOp->p2 - 1;
- }else{
- if( !alreadyExists ) pc = pOp->p2 - 1;
- }
- break;
- }
- /* Opcode: IsUnique P1 P2 P3 P4 *
- **
- ** The P3 register contains an integer record number. Call this
- ** record number R. The P4 register contains an index key created
- ** using MakeIdxRec. Call it K.
- **
- ** P1 is an index. So it has no data and its key consists of a
- ** record generated by OP_MakeRecord where the last field is the
- ** rowid of the entry that the index refers to.
- **
- ** 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
- ** jump to P2. If any entry does exist where the index string
- ** matches K but the record number is not R, then the record
- ** number for that entry is written into P3 and control
- ** falls through to the next instruction.
- **
- ** See also: NotFound, NotExists, Found
- */
- case OP_IsUnique: { /* jump, in3 */
- int i = pOp->p1;
- Cursor *pCx;
- BtCursor *pCrsr;
- Mem *pK;
- i64 R;
- /* Pop the value R off the top of the stack
- */
- assert( pOp->p4type==P4_INT32 );
- assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem );
- pK = &p->aMem[pOp->p4.i];
- sqlite3VdbeMemIntegerify(pIn3);
- R = pIn3->u.i;
- assert( i>=0 && i<p->nCursor );
- pCx = p->apCsr[i];
- assert( pCx!=0 );
- pCrsr = pCx->pCursor;
- if( pCrsr!=0 ){
- int res;
- i64 v; /* The record number on the P1 entry that matches K */
- 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
- */
- assert( pK->flags & MEM_Blob );
- zKey = pK->z;
- nKey = pK->n;
- szRowid = sqlite3VdbeIdxRowidLen((u8*)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.
- */
- assert( pCx->deferredMoveto==0 );
- pCx->cacheStatus = CACHE_STALE;
- rc = sqlite3BtreeMoveto(pCrsr, zKey, 0, len, 0, &res);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- if( res<0 ){
- rc = sqlite3BtreeNext(pCrsr, &res);
- if( res ){
- pc = pOp->p2 - 1;
- break;
- }
- }
- rc = sqlite3VdbeIdxKeyCompare(pCx, len, (u8*)zKey, &res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- if( res>0 ){
- pc = pOp->p2 - 1;
- break;
- }
- /* At this point, pCrsr is pointing to an entry in P1 where all but
- ** 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);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- if( v==R ){
- pc = pOp->p2 - 1;
- break;
- }
- /* The final varint of the key is different from R. Store it back
- ** into register R3. (The record number of an entry that violates
- ** a UNIQUE constraint.)
- */
- pIn3->u.i = v;
- assert( pIn3->flags&MEM_Int );
- }
- break;
- }
- /* Opcode: NotExists P1 P2 P3 * *
- **
- ** Use the content of register P3 as a integer key. If a record
- ** with that key does not exist in table of P1, then jump to P2.
- ** If the record does exist, then fall thru. The cursor is left
- ** pointing to the record if it exists.
- **
- ** The difference between this operation and NotFound is that this
- ** operation assumes the key is an integer and that P1 is a table whereas
- ** NotFound assumes key is a blob constructed from MakeRecord and
- ** P1 is an index.
- **
- ** See also: Found, MoveTo, NotFound, IsUnique
- */
- case OP_NotExists: { /* jump, in3 */
- int i = pOp->p1;
- Cursor *pC;
- BtCursor *pCrsr;
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
- if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
- int res;
- u64 iKey;
- assert( pIn3->flags & MEM_Int );
- assert( p->apCsr[i]->isTable );
- iKey = intToKey(pIn3->u.i);
- rc = sqlite3BtreeMoveto(pCrsr, 0, 0, iKey, 0,&res);
- pC->lastRowid = pIn3->u.i;
- pC->rowidIsValid = res==0;
- pC->nullRow = 0;
- pC->cacheStatus = CACHE_STALE;
- /* res might be uninitialized if rc!=SQLITE_OK. But if rc!=SQLITE_OK
- ** processing is about to abort so we really do not care whether or not
- ** the following jump is taken. (In other words, do not stress over
- ** the error that valgrind sometimes shows on the next statement when
- ** running ioerr.test and similar failure-recovery test scripts.) */
- if( res!=0 ){
- pc = pOp->p2 - 1;
- assert( pC->rowidIsValid==0 );
- }
- }
- break;
- }
- /* Opcode: Sequence P1 P2 * * *
- **
- ** Find the next available sequence number for cursor P1.
- ** Write the sequence number into register P2.
- ** The sequence number on the cursor is incremented after this
- ** instruction.
- */
- case OP_Sequence: { /* out2-prerelease */
- int i = pOp->p1;
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
- pOut->u.i = p->apCsr[i]->seqCount++;
- MemSetTypeFlag(pOut, MEM_Int);
- break;
- }
- /* Opcode: NewRowid P1 P2 P3 * *
- **
- ** Get a new integer record number (a.k.a "rowid") used as the key to a table.
- ** The record number is not previously used as a key in the database
- ** table that cursor P1 points to. The new record number is written
- ** written to register P2.
- **
- ** If P3>0 then P3 is a register that holds the largest previously
- ** generated record number. No new record numbers are allowed to be less
- ** than this value. When this value reaches its maximum, a SQLITE_FULL
- ** error is generated. The P3 register is updated with the generated
- ** record number. This P3 mechanism is used to help implement the
- ** AUTOINCREMENT feature.
- */
- case OP_NewRowid: { /* out2-prerelease */
- int i = pOp->p1;
- i64 v = 0;
- Cursor *pC;
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
- if( (pC = p->apCsr[i])->pCursor==0 ){
- /* The zero initialization above is all that is needed */
- }else{
- /* The next rowid or record number (different terms for the same
- ** thing) is obtained in a two-step algorithm.
- **
- ** First we attempt to find the largest existing rowid and add one
- ** to that. But if the largest existing rowid is already the maximum
- ** positive integer, we have to fall through to the second
- ** probabilistic algorithm
- **
- ** The second algorithm is to select a rowid at random and see if
- ** it already exists in the table. If it does not exist, we have
- ** succeeded. If the random rowid does exist, we select a new one
- ** and try again, up to 1000 times.
- **
- ** For a table with less than 2 billion entries, the probability
- ** of not finding a unused rowid is about 1.0e-300. This is a
- ** non-zero probability, but it is still vanishingly small and should
- ** never cause a problem. You are much, much more likely to have a
- ** hardware failure than for this algorithm to fail.
- **
- ** The analysis in the previous paragraph assumes that you have a good
- ** source of random numbers. Is a library function like lrand48()
- ** good enough? Maybe. Maybe not. It's hard to know whether there
- ** might be subtle bugs is some implementations of lrand48() that
- ** could cause problems. To avoid uncertainty, SQLite uses its own
- ** random number generator based on the RC4 algorithm.
- **
- ** To promote locality of reference for repetitive inserts, the
- ** first few attempts at chosing a random rowid pick values just a little
- ** larger than the previous rowid. This has been shown experimentally
- ** to double the speed of the COPY operation.
- */
- int res, rx=SQLITE_OK, cnt;
- i64 x;
- cnt = 0;
- if( (sqlite3BtreeFlags(pC->pCursor)&(BTREE_INTKEY|BTREE_ZERODATA)) !=
- BTREE_INTKEY ){
- rc = SQLITE_CORRUPT_BKPT;
- goto abort_due_to_error;
- }
- assert( (sqlite3BtreeFlags(pC->pCursor) & BTREE_INTKEY)!=0 );
- assert( (sqlite3BtreeFlags(pC->pCursor) & BTREE_ZERODATA)==0 );
- #ifdef SQLITE_32BIT_ROWID
- # define MAX_ROWID 0x7fffffff
- #else
- /* Some compilers complain about constants of the form 0x7fffffffffffffff.
- ** Others complain about 0x7ffffffffffffffffLL. The following macro seems
- ** to provide the constant while making all compilers happy.
- */
- # define MAX_ROWID ( (((u64)0x7fffffff)<<32) | (u64)0xffffffff )
- #endif
- if( !pC->useRandomRowid ){
- if( pC->nextRowidValid ){
- v = pC->nextRowid;
- }else{
- rc = sqlite3BtreeLast(pC->pCursor, &res);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- if( res ){
- v = 1;
- }else{
- sqlite3BtreeKeySize(pC->pCursor, &v);
- v = keyToInt(v);
- if( v==MAX_ROWID ){
- pC->useRandomRowid = 1;
- }else{
- v++;
- }
- }
- }
- #ifndef SQLITE_OMIT_AUTOINCREMENT
- if( pOp->p3 ){
- Mem *pMem;
- assert( pOp->p3>0 && pOp->p3<=p->nMem ); /* P3 is a valid memory cell */
- pMem = &p->aMem[pOp->p3];
- REGISTER_TRACE(pOp->p3, pMem);
- sqlite3VdbeMemIntegerify(pMem);
- assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */
- if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){
- rc = SQLITE_FULL;
- goto abort_due_to_error;
- }
- if( v<pMem->u.i+1 ){
- v = pMem->u.i + 1;
- }
- pMem->u.i = v;
- }
- #endif
- if( v<MAX_ROWID ){
- pC->nextRowidValid = 1;
- pC->nextRowid = v+1;
- }else{
- pC->nextRowidValid = 0;
- }
- }
- if( pC->useRandomRowid ){
- assert( pOp->p3==0 ); /* SQLITE_FULL must have occurred prior to this */
- v = db->priorNewRowid;
- cnt = 0;
- do{
- if( cnt==0 && (v&0xffffff)==v ){
- v++;
- }else{
- sqlite3_randomness(sizeof(v), &v);
- if( cnt<5 ) v &= 0xffffff;
- }
- if( v==0 ) continue;
- x = intToKey(v);
- rx = sqlite3BtreeMoveto(pC->pCursor, 0, 0, (u64)x, 0, &res);
- cnt++;
- }while( cnt<100 && rx==SQLITE_OK && res==0 );
- db->priorNewRowid = v;
- if( rx==SQLITE_OK && res==0 ){
- rc = SQLITE_FULL;
- goto abort_due_to_error;
- }
- }
- pC->rowidIsValid = 0;
- pC->deferredMoveto = 0;
- pC->cacheStatus = CACHE_STALE;
- }
- MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = v;
- break;
- }
- /* Opcode: Insert P1 P2 P3 P4 P5
- **
- ** Write an entry into the table of cursor P1. A new entry is
- ** created if it doesn't already exist or the data for an existing
- ** entry is overwritten. The data is the value stored register
- ** number P2. The key is stored in register P3. The key must
- ** be an integer.
- **
- ** If the OPFLAG_NCHANGE flag of P5 is set, then the row change count is
- ** incremented (otherwise not). If the OPFLAG_LASTROWID flag of P5 is set,
- ** then rowid is stored for subsequent return by the
- ** sqlite3_last_insert_rowid() function (otherwise it is unmodified).
- **
- ** Parameter P4 may point to a string containing the table-name, or
- ** may be NULL. If it is not NULL, then the update-hook
- ** (sqlite3.xUpdateCallback) is invoked following a successful insert.
- **
- ** (WARNING/TODO: If P1 is a pseudo-cursor and P2 is dynamically
- ** allocated, then ownership of P2 is transferred to the pseudo-cursor
- ** and register P2 becomes ephemeral. If the cursor is changed, the
- ** value of register P2 will then change. Make sure this does not
- ** cause any problems.)
- **
- ** This instruction only works on tables. The equivalent instruction
- ** for indices is OP_IdxInsert.
- */
- case OP_Insert: {
- Mem *pData = &p->aMem[pOp->p2];
- Mem *pKey = &p->aMem[pOp->p3];
- i64 iKey; /* The integer ROWID or key for the record to be inserted */
- int i = pOp->p1;
- Cursor *pC;
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC!=0 );
- assert( pC->pCursor!=0 || pC->pseudoTable );
- assert( pKey->flags & MEM_Int );
- assert( pC->isTable );
- REGISTER_TRACE(pOp->p2, pData);
- REGISTER_TRACE(pOp->p3, pKey);
- iKey = intToKey(pKey->u.i);
- if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
- if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = pKey->u.i;
- if( pC->nextRowidValid && pKey->u.i>=pC->nextRowid ){
- pC->nextRowidValid = 0;
- }
- if( pData->flags & MEM_Null ){
- pData->z = 0;
- pData->n = 0;
- }else{
- assert( pData->flags & (MEM_Blob|MEM_Str) );
- }
- if( pC->pseudoTable ){
- if( !pC->ephemPseudoTable ){
- sqlite3_free(pC->pData);
- }
- pC->iKey = iKey;
- pC->nData = pData->n;
- if( pData->z==pData->zMalloc || pC->ephemPseudoTable ){
- pC->pData = pData->z;
- if( !pC->ephemPseudoTable ){
- pData->flags &= ~MEM_Dyn;
- pData->flags |= MEM_Ephem;
- pData->zMalloc = 0;
- }
- }else{
- pC->pData = sqlite3_malloc( pC->nData+2 );
- if( !pC->pData ) goto no_mem;
- memcpy(pC->pData, pData->z, pC->nData);
- pC->pData[pC->nData] = 0;
- pC->pData[pC->nData+1] = 0;
- }
- pC->nullRow = 0;
- }else{
- int nZero;
- if( pData->flags & MEM_Zero ){
- nZero = pData->u.i;
- }else{
- nZero = 0;
- }
- rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
- pData->z, pData->n, nZero,
- pOp->p5 & OPFLAG_APPEND);
- }
-
- pC->rowidIsValid = 0;
- pC->deferredMoveto = 0;
- pC->cacheStatus = CACHE_STALE;
- /* Invoke the update-hook if required. */
- if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
- const char *zDb = db->aDb[pC->iDb].zName;
- const char *zTbl = pOp->p4.z;
- int op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
- assert( pC->isTable );
- db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey);
- assert( pC->iDb>=0 );
- }
- break;
- }
- /* Opcode: Delete P1 P2 * P4 *
- **
- ** Delete the record at which the P1 cursor is currently pointing.
- **
- ** 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. Hence it is OK to delete
- ** a record from within an Next loop.
- **
- ** If the OPFLAG_NCHANGE flag of P2 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.
- **
- ** If P4 is not NULL, then it is the name of the table that P1 is
- ** pointing to. The update hook will be invoked, if it exists.
- ** If P4 is not NULL then the P1 cursor must have been positioned
- ** using OP_NotFound prior to invoking this opcode.
- */
- case OP_Delete: {
- int i = pOp->p1;
- i64 iKey;
- Cursor *pC;
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC!=0 );
- assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */
- /* If the update-hook will be invoked, set iKey to the rowid of the
- ** row being deleted.
- */
- if( db->xUpdateCallback && pOp->p4.z ){
- assert( pC->isTable );
- assert( pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */
- iKey = pC->lastRowid;
- }
- rc = sqlite3VdbeCursorMoveto(pC);
- if( rc ) goto abort_due_to_error;
- rc = sqlite3BtreeDelete(pC->pCursor);
- pC->nextRowidValid = 0;
- pC->cacheStatus = CACHE_STALE;
- /* Invoke the update-hook if required. */
- if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
- const char *zDb = db->aDb[pC->iDb].zName;
- const char *zTbl = pOp->p4.z;
- db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, iKey);
- assert( pC->iDb>=0 );
- }
- if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
- break;
- }
- /* Opcode: ResetCount P1 * *
- **
- ** This opcode resets the VMs internal change counter to 0. If P1 is true,
- ** then the value of the change counter is copied to the database handle
- ** change counter (returned by subsequent calls to sqlite3_changes())
- ** before it is reset. This is used by trigger programs.
- */
- case OP_ResetCount: {
- if( pOp->p1 ){
- sqlite3VdbeSetChanges(db, p->nChange);
- }
- p->nChange = 0;
- break;
- }
- /* Opcode: RowData P1 P2 * * *
- **
- ** Write into register P2 the complete row data for cursor P1.
- ** There is no interpretation of the data.
- ** It is just copied onto the P2 register exactly as
- ** it is found in the database file.
- **
- ** If the P1 cursor must be pointing to a valid row (not a NULL row)
- ** of a real table, not a pseudo-table.
- */
- /* Opcode: RowKey P1 P2 * * *
- **
- ** Write into register P2 the complete row key for cursor P1.
- ** There is no interpretation of the data.
- ** The key is copied onto the P3 register exactly as
- ** it is found in the database file.
- **
- ** If the P1 cursor must be pointing to a valid row (not a NULL row)
- ** of a real table, not a pseudo-table.
- */
- case OP_RowKey:
- case OP_RowData: {
- int i = pOp->p1;
- Cursor *pC;
- BtCursor *pCrsr;
- u32 n;
- pOut = &p->aMem[pOp->p2];
- /* Note that RowKey and RowData are really exactly the same instruction */
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC->isTable || pOp->opcode==OP_RowKey );
- assert( pC->isIndex || pOp->opcode==OP_RowData );
- assert( pC!=0 );
- assert( pC->nullRow==0 );
- assert( pC->pseudoTable==0 );
- assert( pC->pCursor!=0 );
- pCrsr = pC->pCursor;
- rc = sqlite3VdbeCursorMoveto(pC);
- if( rc ) goto abort_due_to_error;
- if( pC->isIndex ){
- i64 n64;
- assert( !pC->isTable );
- sqlite3BtreeKeySize(pCrsr, &n64);
- if( n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
- goto too_big;
- }
- n = n64;
- }else{
- sqlite3BtreeDataSize(pCrsr, &n);
- if( n>db->aLimit[SQLITE_LIMIT_LENGTH] ){
- goto too_big;
- }
- }
- if( sqlite3VdbeMemGrow(pOut, n, 0) ){
- goto no_mem;
- }
- pOut->n = n;
- MemSetTypeFlag(pOut, MEM_Blob);
- if( pC->isIndex ){
- rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z);
- }else{
- rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z);
- }
- pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */
- UPDATE_MAX_BLOBSIZE(pOut);
- break;
- }
- /* Opcode: Rowid P1 P2 * * *
- **
- ** Store in register P2 an integer which is the key of the table entry that
- ** P1 is currently point to. If p2==0 then push the integer.
- */
- case OP_Rowid: { /* out2-prerelease */
- int i = pOp->p1;
- Cursor *pC;
- i64 v;
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC!=0 );
- rc = sqlite3VdbeCursorMoveto(pC);
- if( rc ) goto abort_due_to_error;
- if( pC->rowidIsValid ){
- v = pC->lastRowid;
- }else if( pC->pseudoTable ){
- v = keyToInt(pC->iKey);
- }else if( pC->nullRow ){
- /* Leave the rowid set to a NULL */
- break;
- }else{
- assert( pC->pCursor!=0 );
- sqlite3BtreeKeySize(pC->pCursor, &v);
- v = keyToInt(v);
- }
- pOut->u.i = v;
- MemSetTypeFlag(pOut, MEM_Int);
- break;
- }
- /* Opcode: NullRow P1 * * * *
- **
- ** Move the cursor P1 to a null row. Any OP_Column operations
- ** that occur while the cursor is on the null row will always
- ** write a NULL.
- */
- case OP_NullRow: {
- int i = pOp->p1;
- Cursor *pC;
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC!=0 );
- pC->nullRow = 1;
- pC->rowidIsValid = 0;
- break;
- }
- /* Opcode: Last P1 P2 * * *
- **
- ** The next use of the Rowid or Column or Next instruction for P1
- ** will refer to the last entry in the database table or index.
- ** If the table or index is empty and P2>0, then jump immediately to P2.
- ** If P2 is 0 or if the table or index is not empty, fall through
- ** to the following instruction.
- */
- case OP_Last: { /* jump */
- int i = pOp->p1;
- Cursor *pC;
- BtCursor *pCrsr;
- int res;
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC!=0 );
- pCrsr = pC->pCursor;
- assert( pCrsr!=0 );
- rc = sqlite3BtreeLast(pCrsr, &res);
- pC->nullRow = res;
- pC->deferredMoveto = 0;
- pC->cacheStatus = CACHE_STALE;
- if( res && pOp->p2>0 ){
- pc = pOp->p2 - 1;
- }
- break;
- }
- /* Opcode: Sort P1 P2 * * *
- **
- ** This opcode does exactly the same thing as OP_Rewind except that
- ** it increments an undocumented global variable used for testing.
- **
- ** Sorting is accomplished by writing records into a sorting index,
- ** then rewinding that index and playing it back from beginning to
- ** end. We use the OP_Sort opcode instead of OP_Rewind to do the
- ** rewinding so that the global variable will be incremented and
- ** regression tests can determine whether or not the optimizer is
- ** correctly optimizing out sorts.
- */
- case OP_Sort: { /* jump */
- #ifdef SQLITE_TEST
- sqlite3_sort_count++;
- sqlite3_search_count--;
- #endif
- /* Fall through into OP_Rewind */
- }
- /* Opcode: Rewind P1 P2 * * *
- **
- ** The next use of the Rowid or Column or Next instruction for P1
- ** will refer to the first entry in the database table or index.
- ** If the table or index is empty and P2>0, then jump immediately to P2.
- ** If P2 is 0 or if the table or index is not empty, fall through
- ** to the following instruction.
- */
- case OP_Rewind: { /* jump */
- int i = pOp->p1;
- Cursor *pC;
- BtCursor *pCrsr;
- int res;
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC!=0 );
- if( (pCrsr = pC->pCursor)!=0 ){
- rc = sqlite3BtreeFirst(pCrsr, &res);
- pC->atFirst = res==0;
- pC->deferredMoveto = 0;
- pC->cacheStatus = CACHE_STALE;
- }else{
- res = 1;
- }
- pC->nullRow = res;
- assert( pOp->p2>0 && pOp->p2<p->nOp );
- if( res ){
- pc = pOp->p2 - 1;
- }
- break;
- }
- /* Opcode: Next P1 P2 * * *
- **
- ** Advance cursor P1 so that it points to the next key/data pair in its
- ** table or index. If there are no more key/value pairs then fall through
- ** to the following instruction. But if the cursor advance was successful,
- ** jump immediately to P2.
- **
- ** The P1 cursor must be for a real table, not a pseudo-table.
- **
- ** See also: Prev
- */
- /* Opcode: Prev P1 P2 * * *
- **
- ** Back up cursor P1 so that it points to the previous key/data pair in its
- ** table or index. If there is no previous key/value pairs then fall through
- ** to the following instruction. But if the cursor backup was successful,
- ** jump immediately to P2.
- **
- ** The P1 cursor must be for a real table, not a pseudo-table.
- */
- case OP_Prev: /* jump */
- case OP_Next: { /* jump */
- Cursor *pC;
- BtCursor *pCrsr;
- CHECK_FOR_INTERRUPT;
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- pC = p->apCsr[pOp->p1];
- if( pC==0 ){
- break; /* See ticket #2273 */
- }
- pCrsr = pC->pCursor;
- assert( pCrsr );
- if( pC->nullRow==0 ){
- int res = 1;
- assert( pC->deferredMoveto==0 );
- rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(pCrsr, &res) :
- sqlite3BtreePrevious(pCrsr, &res);
- pC->nullRow = res;
- pC->cacheStatus = CACHE_STALE;
- if( res==0 ){
- pc = pOp->p2 - 1;
- #ifdef SQLITE_TEST
- sqlite3_search_count++;
- #endif
- }
- }
- pC->rowidIsValid = 0;
- break;
- }
- /* Opcode: IdxInsert P1 P2 P3 * *
- **
- ** Register P2 holds a SQL index key made using the
- ** MakeIdxRec instructions. This opcode writes that key
- ** into the index P1. Data for the entry is nil.
- **
- ** P3 is a flag that provides a hint to the b-tree layer that this
- ** insert is likely to be an append.
- **
- ** This instruction only works for indices. The equivalent instruction
- ** for tables is OP_Insert.
- */
- case OP_IdxInsert: { /* in2 */
- int i = pOp->p1;
- Cursor *pC;
- BtCursor *pCrsr;
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
- assert( pIn2->flags & MEM_Blob );
- if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
- assert( pC->isTable==0 );
- rc = ExpandBlob(pIn2);
- if( rc==SQLITE_OK ){
- int nKey = pIn2->n;
- const char *zKey = pIn2->z;
- rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0, 0, pOp->p3);
- assert( pC->deferredMoveto==0 );
- pC->cacheStatus = CACHE_STALE;
- }
- }
- break;
- }
- /* Opcode: IdxDeleteM P1 P2 P3 * *
- **
- ** The content of P3 registers starting at register P2 form
- ** an unpacked index key. This opcode removes that entry from the
- ** index opened by cursor P1.
- */
- case OP_IdxDelete: {
- int i = pOp->p1;
- Cursor *pC;
- BtCursor *pCrsr;
- assert( pOp->p3>0 );
- assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem );
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
- if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
- int res;
- UnpackedRecord r;
- r.pKeyInfo = pC->pKeyInfo;
- r.nField = pOp->p3;
- r.needFree = 0;
- r.needDestroy = 0;
- r.aMem = &p->aMem[pOp->p2];
- rc = sqlite3BtreeMoveto(pCrsr, 0, &r, 0, 0, &res);
- if( rc==SQLITE_OK && res==0 ){
- rc = sqlite3BtreeDelete(pCrsr);
- }
- assert( pC->deferredMoveto==0 );
- pC->cacheStatus = CACHE_STALE;
- }
- break;
- }
- /* Opcode: IdxRowid P1 P2 * * *
- **
- ** Write into register P2 an integer which is the last entry in the record at
- ** the end of the index key pointed to by cursor P1. This integer should be
- ** the rowid of the table entry to which this index entry points.
- **
- ** See also: Rowid, MakeIdxRec.
- */
- case OP_IdxRowid: { /* out2-prerelease */
- int i = pOp->p1;
- BtCursor *pCrsr;
- Cursor *pC;
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
- if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
- i64 rowid;
- assert( pC->deferredMoveto==0 );
- assert( pC->isTable==0 );
- if( !pC->nullRow ){
- rc = sqlite3VdbeIdxRowid(pCrsr, &rowid);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = rowid;
- }
- }
- break;
- }
- /* Opcode: IdxGE P1 P2 P3 * P5
- **
- ** The value in register P3 is an index entry that omits the ROWID. Compare
- ** this value 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 value in
- ** register P3 then jump to P2. Otherwise fall through to the next
- ** instruction.
- **
- ** If P5 is non-zero then the value in register P3 is temporarily
- ** increased by an epsilon prior to the comparison. This make the opcode work
- ** like IdxGT except that if the key from register P3 is a prefix of
- ** the key in the cursor, the result is false whereas it would be
- ** true with IdxGT.
- */
- /* Opcode: IdxLT P1 P2 P3 * P5
- **
- ** The value in register P3 is an index entry that omits the ROWID. Compare
- ** the this value 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 register P3 value
- ** then jump to P2. Otherwise fall through to the next instruction.
- **
- ** If P5 is non-zero then the
- ** index taken from register P3 is temporarily increased by
- ** an epsilon prior to the comparison. This makes the opcode work
- ** like IdxLE.
- */
- case OP_IdxLT: /* jump, in3 */
- case OP_IdxGE: { /* jump, in3 */
- int i= pOp->p1;
- Cursor *pC;
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
- if( (pC = p->apCsr[i])->pCursor!=0 ){
- int res;
-
- assert( pIn3->flags & MEM_Blob ); /* Created using OP_MakeRecord */
- assert( pC->deferredMoveto==0 );
- ExpandBlob(pIn3);
- assert( pOp->p5==0 || pOp->p5==1 );
- *pC->pIncrKey = pOp->p5;
- rc = sqlite3VdbeIdxKeyCompare(pC, pIn3->n, (u8*)pIn3->z, &res);
- *pC->pIncrKey = 0;
- if( rc!=SQLITE_OK ){
- break;
- }
- if( pOp->opcode==OP_IdxLT ){
- res = -res;
- }else{
- assert( pOp->opcode==OP_IdxGE );
- res++;
- }
- if( res>0 ){
- pc = pOp->p2 - 1 ;
- }
- }
- break;
- }
- /* Opcode: Destroy P1 P2 P3 * *
- **
- ** Delete an entire database table or index whose root page in the database
- ** file is given by P1.
- **
- ** The table being destroyed is in the main database file if P3==0. If
- ** P3==1 then the table to be clear is in the auxiliary database file
- ** that is used to store tables create using CREATE TEMPORARY TABLE.
- **
- ** If AUTOVACUUM is enabled then it is possible that another root page
- ** might be moved into the newly deleted root page in order to keep all
- ** root pages contiguous at the beginning of the database. The former
- ** value of the root page that moved - its value before the move occurred -
- ** is stored in register P2. If no page
- ** movement was required (because the table being dropped was already
- ** the last one in the database) then a zero is stored in register P2.
- ** If AUTOVACUUM is disabled then a zero is stored in register P2.
- **
- ** See also: Clear
- */
- case OP_Destroy: { /* out2-prerelease */
- int iMoved;
- int iCnt;
- #ifndef SQLITE_OMIT_VIRTUALTABLE
- Vdbe *pVdbe;
- iCnt = 0;
- for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
- if( pVdbe->magic==VDBE_MAGIC_RUN && pVdbe->inVtabMethod<2 && pVdbe->pc>=0 ){
- iCnt++;
- }
- }
- #else
- iCnt = db->activeVdbeCnt;
- #endif
- if( iCnt>1 ){
- rc = SQLITE_LOCKED;
- p->errorAction = OE_Abort;
- }else{
- int iDb = pOp->p3;
- assert( iCnt==1 );
- assert( (p->btreeMask & (1<<iDb))!=0 );
- rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved);
- MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = iMoved;
- #ifndef SQLITE_OMIT_AUTOVACUUM
- if( rc==SQLITE_OK && iMoved!=0 ){
- sqlite3RootPageMoved(&db->aDb[iDb], iMoved, pOp->p1);
- }
- #endif
- }
- break;
- }
- /* Opcode: Clear P1 P2 *
- **
- ** Delete all contents of the database table or index whose root page
- ** in the database file is given by P1. But, unlike Destroy, do not
- ** remove the table or index from the database file.
- **
- ** The table being clear is in the main database file if P2==0. If
- ** P2==1 then the table to be clear is in the auxiliary database file
- ** that is used to store tables create using CREATE TEMPORARY TABLE.
- **
- ** See also: Destroy
- */
- case OP_Clear: {
- assert( (p->btreeMask & (1<<pOp->p2))!=0 );
- rc = sqlite3BtreeClearTable(db->aDb[pOp->p2].pBt, pOp->p1);
- break;
- }
- /* Opcode: CreateTable P1 P2 * * *
- **
- ** Allocate a new table in the main database file if P1==0 or in the
- ** auxiliary database file if P1==1 or in an attached database if
- ** P1>1. Write the root page number of the new table into
- ** register P2
- **
- ** The difference between a table and an index is this: A table must
- ** have a 4-byte integer key and can have arbitrary data. An index
- ** has an arbitrary key but no data.
- **
- ** See also: CreateIndex
- */
- /* Opcode: CreateIndex P1 P2 * * *
- **
- ** Allocate a new index in the main database file if P1==0 or in the
- ** auxiliary database file if P1==1 or in an attached database if
- ** P1>1. Write the root page number of the new table into
- ** register P2.
- **
- ** See documentation on OP_CreateTable for additional information.
- */
- case OP_CreateIndex: /* out2-prerelease */
- case OP_CreateTable: { /* out2-prerelease */
- int pgno;
- int flags;
- Db *pDb;
- assert( pOp->p1>=0 && pOp->p1<db->nDb );
- assert( (p->btreeMask & (1<<pOp->p1))!=0 );
- pDb = &db->aDb[pOp->p1];
- assert( pDb->pBt!=0 );
- if( pOp->opcode==OP_CreateTable ){
- /* flags = BTREE_INTKEY; */
- flags = BTREE_LEAFDATA|BTREE_INTKEY;
- }else{
- flags = BTREE_ZERODATA;
- }
- rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
- if( rc==SQLITE_OK ){
- pOut->u.i = pgno;
- MemSetTypeFlag(pOut, MEM_Int);
- }
- break;
- }
- /* Opcode: ParseSchema P1 P2 * P4 *
- **
- ** Read and parse all entries from the SQLITE_MASTER table of database P1
- ** that match the WHERE clause P4. P2 is the "force" flag. Always do
- ** the parsing if P2 is true. If P2 is false, then this routine is a
- ** no-op if the schema is not currently loaded. In other words, if P2
- ** is false, the SQLITE_MASTER table is only parsed if the rest of the
- ** schema is already loaded into the symbol table.
- **
- ** This opcode invokes the parser to create a new virtual machine,
- ** then runs the new virtual machine. It is thus a reentrant opcode.
- */
- case OP_ParseSchema: {
- char *zSql;
- int iDb = pOp->p1;
- const char *zMaster;
- InitData initData;
- assert( iDb>=0 && iDb<db->nDb );
- if( !pOp->p2 && !DbHasProperty(db, iDb, DB_SchemaLoaded) ){
- break;
- }
- zMaster = SCHEMA_TABLE(iDb);
- initData.db = db;
- initData.iDb = pOp->p1;
- initData.pzErrMsg = &p->zErrMsg;
- zSql = sqlite3MPrintf(db,
- "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s",
- db->aDb[iDb].zName, zMaster, pOp->p4.z);
- if( zSql==0 ) goto no_mem;
- (void)sqlite3SafetyOff(db);
- assert( db->init.busy==0 );
- db->init.busy = 1;
- assert( !db->mallocFailed );
- rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
- if( rc==SQLITE_ABORT ) rc = initData.rc;
- sqlite3_free(zSql);
- db->init.busy = 0;
- (void)sqlite3SafetyOn(db);
- if( rc==SQLITE_NOMEM ){
- goto no_mem;
- }
- break;
- }
- #if !defined(SQLITE_OMIT_ANALYZE) && !defined(SQLITE_OMIT_PARSER)
- /* Opcode: LoadAnalysis P1 * * * *
- **
- ** Read the sqlite_stat1 table for database P1 and load the content
- ** of that table into the internal index hash table. This will cause
- ** the analysis to be used when preparing all subsequent queries.
- */
- case OP_LoadAnalysis: {
- int iDb = pOp->p1;
- assert( iDb>=0 && iDb<db->nDb );
- rc = sqlite3AnalysisLoad(db, iDb);
- break;
- }
- #endif /* !defined(SQLITE_OMIT_ANALYZE) && !defined(SQLITE_OMIT_PARSER) */
- /* Opcode: DropTable P1 * * P4 *
- **
- ** Remove the internal (in-memory) data structures that describe
- ** the table named P4 in database P1. This is called after a table
- ** is dropped in order to keep the internal representation of the
- ** schema consistent with what is on disk.
- */
- case OP_DropTable: {
- sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z);
- break;
- }
- /* Opcode: DropIndex P1 * * P4 *
- **
- ** Remove the internal (in-memory) data structures that describe
- ** the index named P4 in database P1. This is called after an index
- ** is dropped in order to keep the internal representation of the
- ** schema consistent with what is on disk.
- */
- case OP_DropIndex: {
- sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z);
- break;
- }
- /* Opcode: DropTrigger P1 * * P4 *
- **
- ** Remove the internal (in-memory) data structures that describe
- ** the trigger named P4 in database P1. This is called after a trigger
- ** is dropped in order to keep the internal representation of the
- ** schema consistent with what is on disk.
- */
- case OP_DropTrigger: {
- sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z);
- break;
- }
- #ifndef SQLITE_OMIT_INTEGRITY_CHECK
- /* Opcode: IntegrityCk P1 P2 P3 * P5
- **
- ** Do an analysis of the currently open database. Store in
- ** register P1 the text of an error message describing any problems.
- ** If no problems are found, store a NULL in register P1.
- **
- ** The register P3 contains the maximum number of allowed errors.
- ** At most reg(P3) errors will be reported.
- ** In other words, the analysis stops as soon as reg(P1) errors are
- ** seen. Reg(P1) is updated with the number of errors remaining.
- **
- ** The root page numbers of all tables in the database are integer
- ** stored in reg(P1), reg(P1+1), reg(P1+2), .... There are P2 tables
- ** total.
- **
- ** If P5 is not zero, the check is done on the auxiliary database
- ** file, not the main database file.
- **
- ** This opcode is used to implement the integrity_check pragma.
- */
- case OP_IntegrityCk: {
- int nRoot; /* Number of tables to check. (Number of root pages.) */
- int *aRoot; /* Array of rootpage numbers for tables to be checked */
- int j; /* Loop counter */
- int nErr; /* Number of errors reported */
- char *z; /* Text of the error report */
- Mem *pnErr; /* Register keeping track of errors remaining */
-
- nRoot = pOp->p2;
- assert( nRoot>0 );
- aRoot = sqlite3_malloc( sizeof(int)*(nRoot+1) );
- if( aRoot==0 ) goto no_mem;
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
- pnErr = &p->aMem[pOp->p3];
- assert( (pnErr->flags & MEM_Int)!=0 );
- assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 );
- pIn1 = &p->aMem[pOp->p1];
- for(j=0; j<nRoot; j++){
- aRoot[j] = sqlite3VdbeIntValue(&pIn1[j]);
- }
- aRoot[j] = 0;
- assert( pOp->p5<db->nDb );
- assert( (p->btreeMask & (1<<pOp->p5))!=0 );
- z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot,
- pnErr->u.i, &nErr);
- pnErr->u.i -= nErr;
- sqlite3VdbeMemSetNull(pIn1);
- if( nErr==0 ){
- assert( z==0 );
- }else{
- sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free);
- }
- UPDATE_MAX_BLOBSIZE(pIn1);
- sqlite3VdbeChangeEncoding(pIn1, encoding);
- sqlite3_free(aRoot);
- break;
- }
- #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
- /* Opcode: FifoWrite P1 * * * *
- **
- ** Write the integer from register P1 into the Fifo.
- */
- case OP_FifoWrite: { /* in1 */
- if( sqlite3VdbeFifoPush(&p->sFifo, sqlite3VdbeIntValue(pIn1))==SQLITE_NOMEM ){
- goto no_mem;
- }
- break;
- }
- /* Opcode: FifoRead P1 P2 * * *
- **
- ** Attempt to read a single integer from the Fifo. Store that
- ** integer in register P1.
- **
- ** If the Fifo is empty jump to P2.
- */
- case OP_FifoRead: { /* jump */
- CHECK_FOR_INTERRUPT;
- assert( pOp->p1>0 && pOp->p1<=p->nMem );
- pOut = &p->aMem[pOp->p1];
- MemSetTypeFlag(pOut, MEM_Int);
- if( sqlite3VdbeFifoPop(&p->sFifo, &pOut->u.i)==SQLITE_DONE ){
- pc = pOp->p2 - 1;
- }
- break;
- }
- #ifndef SQLITE_OMIT_TRIGGER
- /* Opcode: ContextPush * * *
- **
- ** Save the current Vdbe context such that it can be restored by a ContextPop
- ** opcode. The context stores the last insert row id, the last statement change
- ** count, and the current statement change count.
- */
- case OP_ContextPush: {
- int i = p->contextStackTop++;
- Context *pContext;
- assert( i>=0 );
- /* FIX ME: This should be allocated as part of the vdbe at compile-time */
- if( i>=p->contextStackDepth ){
- p->contextStackDepth = i+1;
- p->contextStack = sqlite3DbReallocOrFree(db, p->contextStack,
- sizeof(Context)*(i+1));
- if( p->contextStack==0 ) goto no_mem;
- }
- pContext = &p->contextStack[i];
- pContext->lastRowid = db->lastRowid;
- pContext->nChange = p->nChange;
- pContext->sFifo = p->sFifo;
- sqlite3VdbeFifoInit(&p->sFifo);
- break;
- }
- /* Opcode: ContextPop * * *
- **
- ** Restore the Vdbe context to the state it was in when contextPush was last
- ** executed. The context stores the last insert row id, the last statement
- ** change count, and the current statement change count.
- */
- case OP_ContextPop: {
- Context *pContext = &p->contextStack[--p->contextStackTop];
- assert( p->contextStackTop>=0 );
- db->lastRowid = pContext->lastRowid;
- p->nChange = pContext->nChange;
- sqlite3VdbeFifoClear(&p->sFifo);
- p->sFifo = pContext->sFifo;
- break;
- }
- #endif /* #ifndef SQLITE_OMIT_TRIGGER */
- #ifndef SQLITE_OMIT_AUTOINCREMENT
- /* Opcode: MemMax P1 P2 * * *
- **
- ** Set the value of register P1 to the maximum of its current value
- ** and the value in register P2.
- **
- ** This instruction throws an error if the memory cell is not initially
- ** an integer.
- */
- case OP_MemMax: { /* in1, in2 */
- sqlite3VdbeMemIntegerify(pIn1);
- sqlite3VdbeMemIntegerify(pIn2);
- if( pIn1->u.i<pIn2->u.i){
- pIn1->u.i = pIn2->u.i;
- }
- break;
- }
- #endif /* SQLITE_OMIT_AUTOINCREMENT */
- /* Opcode: IfPos P1 P2 * * *
- **
- ** If the value of register P1 is 1 or greater, jump to P2.
- **
- ** It is illegal to use this instruction on a register that does
- ** not contain an integer. An assertion fault will result if you try.
- */
- case OP_IfPos: { /* jump, in1 */
- assert( pIn1->flags&MEM_Int );
- if( pIn1->u.i>0 ){
- pc = pOp->p2 - 1;
- }
- break;
- }
- /* Opcode: IfNeg P1 P2 * * *
- **
- ** If the value of register P1 is less than zero, jump to P2.
- **
- ** It is illegal to use this instruction on a register that does
- ** not contain an integer. An assertion fault will result if you try.
- */
- case OP_IfNeg: { /* jump, in1 */
- assert( pIn1->flags&MEM_Int );
- if( pIn1->u.i<0 ){
- pc = pOp->p2 - 1;
- }
- break;
- }
- /* Opcode: IfZero P1 P2 * * *
- **
- ** If the value of register P1 is exactly 0, jump to P2.
- **
- ** It is illegal to use this instruction on a register that does
- ** not contain an integer. An assertion fault will result if you try.
- */
- case OP_IfZero: { /* jump, in1 */
- assert( pIn1->flags&MEM_Int );
- if( pIn1->u.i==0 ){
- pc = pOp->p2 - 1;
- }
- break;
- }
- /* Opcode: AggStep * P2 P3 P4 P5
- **
- ** Execute the step function for an aggregate. The
- ** function has P5 arguments. P4 is a pointer to the FuncDef
- ** structure that specifies the function. Use register
- ** P3 as the accumulator.
- **
- ** The P5 arguments are taken from register P2 and its
- ** successors.
- */
- case OP_AggStep: {
- int n = pOp->p5;
- int i;
- Mem *pMem, *pRec;
- sqlite3_context ctx;
- sqlite3_value **apVal;
- assert( n>=0 );
- pRec = &p->aMem[pOp->p2];
- apVal = p->apArg;
- assert( apVal || n==0 );
- for(i=0; i<n; i++, pRec++){
- apVal[i] = pRec;
- storeTypeInfo(pRec, encoding);
- }
- ctx.pFunc = pOp->p4.pFunc;
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
- ctx.pMem = pMem = &p->aMem[pOp->p3];
- pMem->n++;
- ctx.s.flags = MEM_Null;
- ctx.s.z = 0;
- ctx.s.zMalloc = 0;
- ctx.s.xDel = 0;
- ctx.s.db = db;
- ctx.isError = 0;
- ctx.pColl = 0;
- if( ctx.pFunc->needCollSeq ){
- assert( pOp>p->aOp );
- assert( pOp[-1].p4type==P4_COLLSEQ );
- assert( pOp[-1].opcode==OP_CollSeq );
- ctx.pColl = pOp[-1].p4.pColl;
- }
- (ctx.pFunc->xStep)(&ctx, n, apVal);
- if( ctx.isError ){
- sqlite3SetString(&p->zErrMsg, sqlite3_value_text(&ctx.s), (char*)0);
- rc = ctx.isError;
- }
- sqlite3VdbeMemRelease(&ctx.s);
- break;
- }
- /* Opcode: AggFinal P1 P2 * P4 *
- **
- ** Execute the finalizer function for an aggregate. P1 is
- ** the memory location that is the accumulator for the aggregate.
- **
- ** P2 is the number of arguments that the step function takes and
- ** P4 is a pointer to the FuncDef for this function. The P2
- ** argument is not used by this opcode. It is only there to disambiguate
- ** functions that can take varying numbers of arguments. The
- ** P4 argument is only needed for the degenerate case where
- ** the step function was not previously called.
- */
- case OP_AggFinal: {
- Mem *pMem;
- assert( pOp->p1>0 && pOp->p1<=p->nMem );
- pMem = &p->aMem[pOp->p1];
- assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
- rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
- if( rc==SQLITE_ERROR ){
- sqlite3SetString(&p->zErrMsg, sqlite3_value_text(pMem), (char*)0);
- }
- sqlite3VdbeChangeEncoding(pMem, encoding);
- UPDATE_MAX_BLOBSIZE(pMem);
- if( sqlite3VdbeMemTooBig(pMem) ){
- goto too_big;
- }
- break;
- }
- #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
- /* Opcode: Vacuum * * * * *
- **
- ** Vacuum the entire database. This opcode will cause other virtual
- ** machines to be created and run. It may not be called from within
- ** a transaction.
- */
- case OP_Vacuum: {
- if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- rc = sqlite3RunVacuum(&p->zErrMsg, db);
- if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
- break;
- }
- #endif
- #if !defined(SQLITE_OMIT_AUTOVACUUM)
- /* Opcode: IncrVacuum P1 P2 * * *
- **
- ** Perform a single step of the incremental vacuum procedure on
- ** the P1 database. If the vacuum has finished, jump to instruction
- ** P2. Otherwise, fall through to the next instruction.
- */
- case OP_IncrVacuum: { /* jump */
- Btree *pBt;
- assert( pOp->p1>=0 && pOp->p1<db->nDb );
- assert( (p->btreeMask & (1<<pOp->p1))!=0 );
- pBt = db->aDb[pOp->p1].pBt;
- rc = sqlite3BtreeIncrVacuum(pBt);
- if( rc==SQLITE_DONE ){
- pc = pOp->p2 - 1;
- rc = SQLITE_OK;
- }
- break;
- }
- #endif
- /* Opcode: Expire P1 * * * *
- **
- ** Cause precompiled statements to become expired. An expired statement
- ** fails with an error code of SQLITE_SCHEMA if it is ever executed
- ** (via sqlite3_step()).
- **
- ** If P1 is 0, then all SQL statements become expired. If P1 is non-zero,
- ** then only the currently executing statement is affected.
- */
- case OP_Expire: {
- if( !pOp->p1 ){
- sqlite3ExpirePreparedStatements(db);
- }else{
- p->expired = 1;
- }
- break;
- }
- #ifndef SQLITE_OMIT_SHARED_CACHE
- /* Opcode: TableLock P1 P2 P3 P4 *
- **
- ** Obtain a lock on a particular table. This instruction is only used when
- ** the shared-cache feature is enabled.
- **
- ** If P1 is the index of the database in sqlite3.aDb[] of the database
- ** on which the lock is acquired. A readlock is obtained if P3==0 or
- ** a write lock if P3==1.
- **
- ** P2 contains the root-page of the table to lock.
- **
- ** P4 contains a pointer to the name of the table being locked. This is only
- ** used to generate an error message if the lock cannot be obtained.
- */
- case OP_TableLock: {
- int p1 = pOp->p1;
- u8 isWriteLock = pOp->p3;
- assert( p1>=0 && p1<db->nDb );
- assert( (p->btreeMask & (1<<p1))!=0 );
- assert( isWriteLock==0 || isWriteLock==1 );
- rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
- if( rc==SQLITE_LOCKED ){
- const char *z = pOp->p4.z;
- sqlite3SetString(&p->zErrMsg, "database table is locked: ", z, (char*)0);
- }
- break;
- }
- #endif /* SQLITE_OMIT_SHARED_CACHE */
- #ifndef SQLITE_OMIT_VIRTUALTABLE
- /* Opcode: VBegin * * * P4 *
- **
- ** P4 a pointer to an sqlite3_vtab structure. Call the xBegin method
- ** for that table.
- */
- case OP_VBegin: {
- rc = sqlite3VtabBegin(db, pOp->p4.pVtab);
- break;
- }
- #endif /* SQLITE_OMIT_VIRTUALTABLE */
- #ifndef SQLITE_OMIT_VIRTUALTABLE
- /* Opcode: VCreate P1 * * P4 *
- **
- ** P4 is the name of a virtual table in database P1. Call the xCreate method
- ** for that table.
- */
- case OP_VCreate: {
- rc = sqlite3VtabCallCreate(db, pOp->p1, pOp->p4.z, &p->zErrMsg);
- break;
- }
- #endif /* SQLITE_OMIT_VIRTUALTABLE */
- #ifndef SQLITE_OMIT_VIRTUALTABLE
- /* Opcode: VDestroy P1 * * P4 *
- **
- ** P4 is the name of a virtual table in database P1. Call the xDestroy method
- ** of that table.
- */
- case OP_VDestroy: {
- p->inVtabMethod = 2;
- rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z);
- p->inVtabMethod = 0;
- break;
- }
- #endif /* SQLITE_OMIT_VIRTUALTABLE */
- #ifndef SQLITE_OMIT_VIRTUALTABLE
- /* Opcode: VOpen P1 * * P4 *
- **
- ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure.
- ** P1 is a cursor number. This opcode opens a cursor to the virtual
- ** table and stores that cursor in P1.
- */
- case OP_VOpen: {
- Cursor *pCur = 0;
- sqlite3_vtab_cursor *pVtabCursor = 0;
- sqlite3_vtab *pVtab = pOp->p4.pVtab;
- sqlite3_module *pModule = (sqlite3_module *)pVtab->pModule;
- assert(pVtab && pModule);
- if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- rc = pModule->xOpen(pVtab, &pVtabCursor);
- if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
- if( SQLITE_OK==rc ){
- /* Initialise sqlite3_vtab_cursor base class */
- pVtabCursor->pVtab = pVtab;
- /* Initialise vdbe cursor object */
- pCur = allocateCursor(p, pOp->p1, &pOp[-1], -1, 0);
- if( pCur ){
- pCur->pVtabCursor = pVtabCursor;
- pCur->pModule = pVtabCursor->pVtab->pModule;
- }else{
- db->mallocFailed = 1;
- pModule->xClose(pVtabCursor);
- }
- }
- break;
- }
- #endif /* SQLITE_OMIT_VIRTUALTABLE */
- #ifndef SQLITE_OMIT_VIRTUALTABLE
- /* Opcode: VFilter P1 P2 P3 P4 *
- **
- ** P1 is a cursor opened using VOpen. P2 is an address to jump to if
- ** the filtered result set is empty.
- **
- ** P4 is either NULL or a string that was generated by the xBestIndex
- ** method of the module. The interpretation of the P4 string is left
- ** to the module implementation.
- **
- ** This opcode invokes the xFilter method on the virtual table specified
- ** by P1. The integer query plan parameter to xFilter is stored in register
- ** P3. Register P3+1 stores the argc parameter to be passed to the
- ** xFilter method. Registers P3+2..P3+1+argc are the argc additional
- ** parametersneath additional parameters which are passed to
- ** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter.
- **
- ** A jump is made to P2 if the result set after filtering would be empty.
- */
- case OP_VFilter: { /* jump */
- int nArg;
- int iQuery;
- const sqlite3_module *pModule;
- Mem *pQuery = &p->aMem[pOp->p3];
- Mem *pArgc = &pQuery[1];
- Cursor *pCur = p->apCsr[pOp->p1];
- REGISTER_TRACE(pOp->p3, pQuery);
- assert( pCur->pVtabCursor );
- pModule = pCur->pVtabCursor->pVtab->pModule;
- /* Grab the index number and argc parameters */
- assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int );
- nArg = pArgc->u.i;
- iQuery = pQuery->u.i;
- /* Invoke the xFilter method */
- {
- int res = 0;
- int i;
- Mem **apArg = p->apArg;
- for(i = 0; i<nArg; i++){
- apArg[i] = &pArgc[i+1];
- storeTypeInfo(apArg[i], 0);
- }
- if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- p->inVtabMethod = 1;
- rc = pModule->xFilter(pCur->pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
- p->inVtabMethod = 0;
- if( rc==SQLITE_OK ){
- res = pModule->xEof(pCur->pVtabCursor);
- }
- if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
- if( res ){
- pc = pOp->p2 - 1;
- }
- }
- pCur->nullRow = 0;
- break;
- }
- #endif /* SQLITE_OMIT_VIRTUALTABLE */
- #ifndef SQLITE_OMIT_VIRTUALTABLE
- /* Opcode: VRowid P1 P2 * * *
- **
- ** Store into register P2 the rowid of
- ** the virtual-table that the P1 cursor is pointing to.
- */
- case OP_VRowid: { /* out2-prerelease */
- const sqlite3_module *pModule;
- sqlite_int64 iRow;
- Cursor *pCur = p->apCsr[pOp->p1];
- assert( pCur->pVtabCursor );
- if( pCur->nullRow ){
- break;
- }
- pModule = pCur->pVtabCursor->pVtab->pModule;
- assert( pModule->xRowid );
- if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- rc = pModule->xRowid(pCur->pVtabCursor, &iRow);
- if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
- MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = iRow;
- break;
- }
- #endif /* SQLITE_OMIT_VIRTUALTABLE */
- #ifndef SQLITE_OMIT_VIRTUALTABLE
- /* Opcode: VColumn P1 P2 P3 * *
- **
- ** Store the value of the P2-th column of
- ** the row of the virtual-table that the
- ** P1 cursor is pointing to into register P3.
- */
- case OP_VColumn: {
- const sqlite3_module *pModule;
- Mem *pDest;
- sqlite3_context sContext;
- Cursor *pCur = p->apCsr[pOp->p1];
- assert( pCur->pVtabCursor );
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
- pDest = &p->aMem[pOp->p3];
- if( pCur->nullRow ){
- sqlite3VdbeMemSetNull(pDest);
- break;
- }
- pModule = pCur->pVtabCursor->pVtab->pModule;
- assert( pModule->xColumn );
- memset(&sContext, 0, sizeof(sContext));
- /* The output cell may already have a buffer allocated. Move
- ** the current contents to sContext.s so in case the user-function
- ** can use the already allocated buffer instead of allocating a
- ** new one.
- */
- sqlite3VdbeMemMove(&sContext.s, pDest);
- MemSetTypeFlag(&sContext.s, MEM_Null);
- if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);
- /* Copy the result of the function to the P3 register. We
- ** do this regardless of whether or not an error occured to ensure any
- ** dynamic allocation in sContext.s (a Mem struct) is released.
- */
- sqlite3VdbeChangeEncoding(&sContext.s, encoding);
- REGISTER_TRACE(pOp->p3, pDest);
- sqlite3VdbeMemMove(pDest, &sContext.s);
- UPDATE_MAX_BLOBSIZE(pDest);
- if( sqlite3SafetyOn(db) ){
- goto abort_due_to_misuse;
- }
- if( sqlite3VdbeMemTooBig(pDest) ){
- goto too_big;
- }
- break;
- }
- #endif /* SQLITE_OMIT_VIRTUALTABLE */
- #ifndef SQLITE_OMIT_VIRTUALTABLE
- /* Opcode: VNext P1 P2 * * *
- **
- ** Advance virtual table P1 to the next row in its result set and
- ** jump to instruction P2. Or, if the virtual table has reached
- ** the end of its result set, then fall through to the next instruction.
- */
- case OP_VNext: { /* jump */
- const sqlite3_module *pModule;
- int res = 0;
- Cursor *pCur = p->apCsr[pOp->p1];
- assert( pCur->pVtabCursor );
- if( pCur->nullRow ){
- break;
- }
- pModule = pCur->pVtabCursor->pVtab->pModule;
- assert( pModule->xNext );
- /* Invoke the xNext() method of the module. There is no way for the
- ** underlying implementation to return an error if one occurs during
- ** xNext(). Instead, if an error occurs, true is returned (indicating that
- ** data is available) and the error code returned when xColumn or
- ** some other method is next invoked on the save virtual table cursor.
- */
- if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- p->inVtabMethod = 1;
- rc = pModule->xNext(pCur->pVtabCursor);
- p->inVtabMethod = 0;
- if( rc==SQLITE_OK ){
- res = pModule->xEof(pCur->pVtabCursor);
- }
- if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
- if( !res ){
- /* If there is data, jump to P2 */
- pc = pOp->p2 - 1;
- }
- break;
- }
- #endif /* SQLITE_OMIT_VIRTUALTABLE */
- #ifndef SQLITE_OMIT_VIRTUALTABLE
- /* Opcode: VRename P1 * * P4 *
- **
- ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure.
- ** This opcode invokes the corresponding xRename method. The value
- ** in register P1 is passed as the zName argument to the xRename method.
- */
- case OP_VRename: {
- sqlite3_vtab *pVtab = pOp->p4.pVtab;
- Mem *pName = &p->aMem[pOp->p1];
- assert( pVtab->pModule->xRename );
- REGISTER_TRACE(pOp->p1, pName);
- Stringify(pName, encoding);
- if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- sqlite3VtabLock(pVtab);
- rc = pVtab->pModule->xRename(pVtab, pName->z);
- sqlite3VtabUnlock(db, pVtab);
- if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
- break;
- }
- #endif
- #ifndef SQLITE_OMIT_VIRTUALTABLE
- /* Opcode: VUpdate P1 P2 P3 P4 *
- **
- ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure.
- ** This opcode invokes the corresponding xUpdate method. P2 values
- ** are contiguous memory cells starting at P3 to pass to the xUpdate
- ** invocation. The value in register (P3+P2-1) corresponds to the
- ** p2th element of the argv array passed to xUpdate.
- **
- ** The xUpdate method will do a DELETE or an INSERT or both.
- ** The argv[0] element (which corresponds to memory cell P3)
- ** is the rowid of a row to delete. If argv[0] is NULL then no
- ** deletion occurs. The argv[1] element is the rowid of the new
- ** row. This can be NULL to have the virtual table select the new
- ** rowid for itself. The subsequent elements in the array are
- ** the values of columns in the new row.
- **
- ** If P2==1 then no insert is performed. argv[0] is the rowid of
- ** a row to delete.
- **
- ** P1 is a boolean flag. If it is set to true and the xUpdate call
- ** is successful, then the value returned by sqlite3_last_insert_rowid()
- ** is set to the value of the rowid for the row just inserted.
- */
- case OP_VUpdate: {
- sqlite3_vtab *pVtab = pOp->p4.pVtab;
- sqlite3_module *pModule = (sqlite3_module *)pVtab->pModule;
- int nArg = pOp->p2;
- assert( pOp->p4type==P4_VTAB );
- if( pModule->xUpdate==0 ){
- sqlite3SetString(&p->zErrMsg, "read-only table", 0);
- rc = SQLITE_ERROR;
- }else{
- int i;
- sqlite_int64 rowid;
- Mem **apArg = p->apArg;
- Mem *pX = &p->aMem[pOp->p3];
- for(i=0; i<nArg; i++){
- storeTypeInfo(pX, 0);
- apArg[i] = pX;
- pX++;
- }
- if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- sqlite3VtabLock(pVtab);
- rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);
- sqlite3VtabUnlock(db, pVtab);
- if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
- if( pOp->p1 && rc==SQLITE_OK ){
- assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
- db->lastRowid = rowid;
- }
- p->nChange++;
- }
- break;
- }
- #endif /* SQLITE_OMIT_VIRTUALTABLE */
- #ifndef SQLITE_OMIT_TRACE
- /* Opcode: Trace * * * P4 *
- **
- ** If tracing is enabled (by the sqlite3_trace()) interface, then
- ** the UTF-8 string contained in P4 is emitted on the trace callback.
- */
- case OP_Trace: {
- if( pOp->p4.z ){
- if( db->xTrace ){
- db->xTrace(db->pTraceArg, pOp->p4.z);
- }
- #ifdef SQLITE_DEBUG
- if( (db->flags & SQLITE_SqlTrace)!=0 ){
- sqlite3DebugPrintf("SQL-trace: %sn", pOp->p4.z);
- }
- #endif /* SQLITE_DEBUG */
- }
- break;
- }
- #endif
- /* Opcode: Noop * * * * *
- **
- ** Do nothing. This instruction is often useful as a jump
- ** destination.
- */
- /*
- ** The magic Explain opcode are only inserted when explain==2 (which
- ** is to say when the EXPLAIN QUERY PLAN syntax is used.)
- ** This opcode records information from the optimizer. It is the
- ** the same as a no-op. This opcodesnever appears in a real VM program.
- */
- default: { /* This is really OP_Noop and OP_Explain */
- break;
- }
- /*****************************************************************************
- ** The cases of the switch statement above this line should all be indented
- ** by 6 spaces. But the left-most 6 spaces have been removed to improve the
- ** readability. From this point on down, the normal indentation rules are
- ** restored.
- *****************************************************************************/
- }
- #ifdef VDBE_PROFILE
- {
- long long elapse = hwtime() - start;
- pOp->cycles += elapse;
- pOp->cnt++;
- #if 0
- fprintf(stdout, "%10lld ", elapse);
- sqlite3VdbePrintOp(stdout, origPc, &p->aOp[origPc]);
- #endif
- }
- #endif
- /* The following code adds nothing to the actual functionality
- ** of the program. It is only here for testing and debugging.
- ** On the other hand, it does burn CPU cycles every time through
- ** the evaluator loop. So we can leave it out when NDEBUG is defined.
- */
- #ifndef NDEBUG
- assert( pc>=-1 && pc<p->nOp );
- #ifdef SQLITE_DEBUG
- if( p->trace ){
- if( rc!=0 ) fprintf(p->trace,"rc=%dn",rc);
- if( opProperty & OPFLG_OUT2_PRERELEASE ){
- registerTrace(p->trace, pOp->p2, pOut);
- }
- if( opProperty & OPFLG_OUT3 ){
- registerTrace(p->trace, pOp->p3, pOut);
- }
- }
- #endif /* SQLITE_DEBUG */
- #endif /* NDEBUG */
- } /* The end of the for(;;) loop the loops through opcodes */
- /* If we reach this point, it means that execution is finished with
- ** an error of some kind.
- */
- vdbe_error_halt:
- assert( rc );
- p->rc = rc;
- rc = SQLITE_ERROR;
- sqlite3VdbeHalt(p);
- /* This is the only way out of this procedure. We have to
- ** release the mutexes on btrees that were acquired at the
- ** top. */
- vdbe_return:
- sqlite3BtreeMutexArrayLeave(&p->aMutex);
- return rc;
- /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH
- ** is encountered.
- */
- too_big:
- sqlite3SetString(&p->zErrMsg, "string or blob too big", (char*)0);
- rc = SQLITE_TOOBIG;
- goto vdbe_error_halt;
- /* Jump to here if a malloc() fails.
- */
- no_mem:
- db->mallocFailed = 1;
- sqlite3SetString(&p->zErrMsg, "out of memory", (char*)0);
- rc = SQLITE_NOMEM;
- goto vdbe_error_halt;
- /* Jump to here for an SQLITE_MISUSE error.
- */
- abort_due_to_misuse:
- rc = SQLITE_MISUSE;
- /* Fall thru into abort_due_to_error */
- /* Jump to here for any other kind of fatal error. The "rc" variable
- ** should hold the error number.
- */
- abort_due_to_error:
- assert( p->zErrMsg==0 );
- if( db->mallocFailed ) rc = SQLITE_NOMEM;
- sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
- goto vdbe_error_halt;
- /* Jump to here if the sqlite3_interrupt() API sets the interrupt
- ** flag.
- */
- abort_due_to_interrupt:
- assert( db->u1.isInterrupted );
- rc = SQLITE_INTERRUPT;
- p->rc = rc;
- sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
- goto vdbe_error_halt;
- }