Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Change the name of the Cursor object to VdbeCursor. (CVS 5857) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
fdb98fd8c1706085ebeef8e48ac67378 |
User & Date: | drh 2008-11-03 20:55:07.000 |
Context
2008-11-03
| ||
21:40 | Test cases to verify that COMMIT and ROLLBACK return SQLITE_BUSY when there are active statements. (CVS 5858) (check-in: cedfa214e4 user: drh tags: trunk) | |
20:55 | Change the name of the Cursor object to VdbeCursor. (CVS 5857) (check-in: fdb98fd8c1 user: drh tags: trunk) | |
09:39 | Modify an assert() statement to fix #3473. No other code changes. (CVS 5856) (check-in: aca6b260c0 user: danielk1977 tags: trunk) | |
Changes
Changes to src/analyze.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2005 July 8 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code associated with the ANALYZE command. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2005 July 8 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code associated with the ANALYZE command. ** ** @(#) $Id: analyze.c,v 1.44 2008/11/03 20:55:07 drh Exp $ */ #ifndef SQLITE_OMIT_ANALYZE #include "sqliteInt.h" /* ** This routine generates code that opens the sqlite_stat1 table on cursor ** iStatCur. |
︙ | ︙ | |||
82 83 84 85 86 87 88 | /* ** Generate code to do an analysis of all indices associated with ** a single table. */ static void analyzeOneTable( Parse *pParse, /* Parser context */ Table *pTab, /* Table whose indices are to be analyzed */ | | | | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | /* ** Generate code to do an analysis of all indices associated with ** a single table. */ static void analyzeOneTable( Parse *pParse, /* Parser context */ Table *pTab, /* Table whose indices are to be analyzed */ int iStatCur, /* Index of VdbeCursor that writes the sqlite_stat1 table */ int iMem /* Available memory locations begin here */ ){ Index *pIdx; /* An index to being analyzed */ int iIdxCur; /* Index of VdbeCursor for index being analyzed */ int nCol; /* Number of columns in the index */ Vdbe *v; /* The virtual machine being built up */ int i; /* Loop counter */ int topOfLoop; /* The top of the loop */ int endOfLoop; /* The end of the loop */ int addr; /* The address of an instruction */ int iDb; /* Index of database containing pTab */ |
︙ | ︙ |
Changes to src/bitvec.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file implements an object that represents a fixed-length ** bitmap. Bits are numbered starting with 1. ** | | | > | | > | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file implements an object that represents a fixed-length ** bitmap. Bits are numbered starting with 1. ** ** A bitmap is used to record which pages of a database file have been ** journalled during a transaction, or which pages have the "dont-write" ** property. Usually only a few pages are meet either condition. ** So the bitmap is usually sparse and has low cardinality. ** But sometimes (for example when during a DROP of a large table) most ** or all of the pages in a database can get journalled. In those cases, ** the bitmap becomes dense with high cardinality. The algorithm needs ** to handle both cases well. ** ** The size of the bitmap is fixed when the object is created. ** ** All bits are clear when the bitmap is created. Individual bits ** may be set or cleared one at a time. ** ** Test operations are about 100 times more common that set operations. ** Clear operations are exceedingly rare. There are usually between ** 5 and 500 set operations per Bitvec object, though the number of sets can ** sometimes grow into tens of thousands or larger. The size of the ** Bitvec object is the number of pages in the database file at the ** start of a transaction, and is thus usually less than a few thousand, ** but can be as large as 2 billion for a really big database. ** ** @(#) $Id: bitvec.c,v 1.7 2008/11/03 20:55:07 drh Exp $ */ #include "sqliteInt.h" #define BITVEC_SZ 512 /* Round the union size down to the nearest pointer boundary, since that's how ** it will be aligned within the Bitvec struct. */ #define BITVEC_USIZE (((BITVEC_SZ-12)/sizeof(Bitvec*))*sizeof(Bitvec*)) |
︙ | ︙ | |||
121 122 123 124 125 126 127 128 129 130 131 132 133 134 | return 0; } } /* ** Set the i-th bit. Return 0 on success and an error code if ** anything goes wrong. */ int sqlite3BitvecSet(Bitvec *p, u32 i){ u32 h; assert( p!=0 ); assert( i>0 ); assert( i<=p->iSize ); if( p->iSize<=BITVEC_NBIT ){ | > > > > > > > > | 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | return 0; } } /* ** Set the i-th bit. Return 0 on success and an error code if ** anything goes wrong. ** ** This routine might cause sub-bitmaps to be allocated. Failing ** to get the memory needed to hold the sub-bitmap is the only ** that can go wrong with an insert, assuming p and i are valid. ** ** The calling function must ensure that p is a valid Bitvec object ** and that the value for "i" is within range of the Bitvec object. ** Otherwise the behavior is undefined. */ int sqlite3BitvecSet(Bitvec *p, u32 i){ u32 h; assert( p!=0 ); assert( i>0 ); assert( i<=p->iSize ); if( p->iSize<=BITVEC_NBIT ){ |
︙ | ︙ |
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2004 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* ** 2004 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** $Id: btree.c,v 1.527 2008/11/03 20:55:07 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. ** Including a description of file format and an overview of operation. */ #include "btreeInt.h" |
︙ | ︙ | |||
402 403 404 405 406 407 408 | #define restoreCursorPosition(p) \ (p->eState>=CURSOR_REQUIRESEEK ? \ sqlite3BtreeRestoreCursorPosition(p) : \ SQLITE_OK) /* ** Determine whether or not a cursor has moved from the position it | | | 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 | #define restoreCursorPosition(p) \ (p->eState>=CURSOR_REQUIRESEEK ? \ sqlite3BtreeRestoreCursorPosition(p) : \ SQLITE_OK) /* ** Determine whether or not a cursor has moved from the position it ** was last placed at. Cursors can move when the row they are pointing ** at is deleted out from under them. ** ** This routine returns an error code if something goes wrong. The ** integer *pHasMoved is set to one if the cursor has moved and 0 if not. */ int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){ int rc; |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
18 19 20 21 22 23 24 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** ** $Id: build.c,v 1.500 2008/11/03 20:55:07 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Initialize the pParse structure as needed. |
︙ | ︙ | |||
3053 3054 3055 3056 3057 3058 3059 | pItem->zDatabase = sqlite3NameFromToken(db, pDatabase); pItem->iCursor = -1; pList->nSrc++; return pList; } /* | | | 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 | pItem->zDatabase = sqlite3NameFromToken(db, pDatabase); pItem->iCursor = -1; pList->nSrc++; return pList; } /* ** Assign VdbeCursor index numbers to all tables in a SrcList */ void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ int i; struct SrcList_item *pItem; assert(pList || pParse->db->mallocFailed ); if( pList ){ for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ |
︙ | ︙ |
Changes to src/insert.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** ** $Id: insert.c,v 1.251 2008/11/03 20:55:07 drh Exp $ */ #include "sqliteInt.h" /* ** Set P4 of the most recently inserted opcode to a column affinity ** string for index pIdx. A column affinity string has one character ** for each column in the table, according to the affinity of the column: |
︙ | ︙ | |||
1381 1382 1383 1384 1385 1386 1387 | ** for the table. Indices are opened on subsequent cursors. ** ** Return the number of indices on the table. */ int sqlite3OpenTableAndIndices( Parse *pParse, /* Parsing context */ Table *pTab, /* Table to be opened */ | | | 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 | ** for the table. Indices are opened on subsequent cursors. ** ** Return the number of indices on the table. */ int sqlite3OpenTableAndIndices( Parse *pParse, /* Parsing context */ Table *pTab, /* Table to be opened */ int baseCur, /* Cursor number assigned to the table */ int op /* OP_OpenRead or OP_OpenWrite */ ){ int i; int iDb; Index *pIdx; Vdbe *v; |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.501 2008/11/03 20:55:07 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" /* ** Macros for troubleshooting. Normally turned off */ |
︙ | ︙ | |||
3397 3398 3399 3400 3401 3402 3403 | return pPg->flags&PGHDR_DIRTY; } #endif /* ** A call to this routine tells the pager that it is not necessary to ** write the information on page pPg back to the disk, even though | | > > | 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 | return pPg->flags&PGHDR_DIRTY; } #endif /* ** A call to this routine tells the pager that it is not necessary to ** write the information on page pPg back to the disk, even though ** that page might be marked as dirty. This happens, for example, when ** the page has been added as a leaf of the freelist and so its ** content no longer matters. ** ** The overlying software layer calls this routine when all of the data ** on the given page is unused. The pager marks the page as clean so ** that it does not get written to disk. ** ** Tests show that this optimization, together with the ** sqlite3PagerDontRollback() below, more than double the speed |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.785 2008/11/03 20:55:07 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor |
︙ | ︙ | |||
178 179 180 181 182 183 184 | */ int sqlite3VdbeOpcodeHasProperty(int opcode, int mask){ assert( opcode>0 && opcode<sizeof(opcodeProperty) ); return (opcodeProperty[opcode]&mask)!=0; } /* | | | | | | | | | | | | | | | | > | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | */ int sqlite3VdbeOpcodeHasProperty(int opcode, int mask){ assert( opcode>0 && opcode<sizeof(opcodeProperty) ); return (opcodeProperty[opcode]&mask)!=0; } /* ** Allocate VdbeCursor number iCur. Return a pointer to it. Return NULL ** if we run out of memory. */ static VdbeCursor *allocateCursor( Vdbe *p, /* The virtual machine */ int iCur, /* Index of the new VdbeCursor */ Op *pOp, /* */ int iDb, /* */ int isBtreeCursor /* */ ){ /* Find the memory cell that will be used to store the blob of memory ** required for this VdbeCursor structure. It is convenient to use a ** vdbe memory cell to manage the memory allocation required for a ** VdbeCursor structure for the following reasons: ** ** * Sometimes cursor numbers are used for a couple of different ** purposes in a vdbe program. The different uses might require ** different sized allocations. Memory cells provide growable ** allocations. ** ** * When using ENABLE_MEMORY_MANAGEMENT, memory cell buffers can ** be freed lazily via the sqlite3_release_memory() API. This ** minimizes the number of malloc calls made by the system. ** ** Memory cells for cursors are allocated at the top of the address ** space. Memory cell (p->nMem) corresponds to cursor 0. Space for ** cursor 1 is managed by memory cell (p->nMem-1), etc. */ Mem *pMem = &p->aMem[p->nMem-iCur]; int nByte; VdbeCursor *pCx = 0; /* If the opcode of pOp is OP_SetNumColumns, then pOp->p2 contains ** the number of fields in the records contained in the table or ** index being opened. Use this to reserve space for the ** VdbeCursor.aType[] array. */ int nField = 0; if( pOp->opcode==OP_SetNumColumns || pOp->opcode==OP_OpenEphemeral ){ nField = pOp->p2; } nByte = sizeof(VdbeCursor) + (isBtreeCursor?sqlite3BtreeCursorSize():0) + 2*nField*sizeof(u32); assert( iCur<p->nCursor ); if( p->apCsr[iCur] ){ sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); p->apCsr[iCur] = 0; } if( SQLITE_OK==sqlite3VdbeMemGrow(pMem, nByte, 0) ){ p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z; memset(pMem->z, 0, nByte); pCx->iDb = iDb; pCx->nField = nField; if( nField ){ pCx->aType = (u32 *)&pMem->z[sizeof(VdbeCursor)]; } if( isBtreeCursor ){ pCx->pCursor = (BtCursor*) &pMem->z[sizeof(VdbeCursor)+2*nField*sizeof(u32)]; } } return pCx; } /* ** Try to convert a value into a numeric representation if we can |
︙ | ︙ | |||
1954 1955 1956 1957 1958 1959 1960 | ** the MakeRecord instruction. (See the MakeRecord opcode for additional ** information about the format of the data.) Extract the P2-th column ** from this record. If there are less that (P2+1) ** values in the record, extract a NULL. ** ** The value extracted is stored in register P3. ** | < < < | | 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 | ** the MakeRecord instruction. (See the MakeRecord opcode for additional ** information about the format of the data.) Extract the P2-th column ** from this record. If there are less that (P2+1) ** values in the record, extract a NULL. ** ** The value extracted is stored in register P3. ** ** If the column contains fewer than P2 fields, then extract a NULL. Or, ** if the P4 argument is a P4_MEM use the value of the P4 argument as ** the result. */ case OP_Column: { u32 payloadSize; /* Number of bytes in the record */ int p1 = pOp->p1; /* P1 value of the opcode */ int p2 = pOp->p2; /* column number to retrieve */ VdbeCursor *pC = 0;/* The VDBE cursor */ char *zRec; /* Pointer to complete record-data */ BtCursor *pCrsr; /* The BTree cursor */ u32 *aType; /* aType[i] holds the numeric type of the i-th column */ u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */ u32 nField; /* number of fields in the record */ int len; /* The length of the serialized data for the column */ int i; /* Loop counter */ |
︙ | ︙ | |||
1995 1996 1997 1998 1999 2000 2001 | ** zRec is set to be the complete text of the record if it is available. ** The complete record text is always available for pseudo-tables ** If the record is stored in a cursor, the complete record text ** might be available in the pC->aRow cache. Or it might not be. ** If the data is unavailable, zRec is set to NULL. ** ** We also compute the number of columns in the record. For cursors, | | | 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 | ** zRec is set to be the complete text of the record if it is available. ** The complete record text is always available for pseudo-tables ** If the record is stored in a cursor, the complete record text ** might be available in the pC->aRow cache. Or it might not be. ** If the data is unavailable, zRec is set to NULL. ** ** We also compute the number of columns in the record. For cursors, ** the number of columns is stored in the VdbeCursor.nField element. */ pC = p->apCsr[p1]; assert( pC!=0 ); #ifndef SQLITE_OMIT_VIRTUALTABLE assert( pC->pVtabCursor==0 ); #endif if( pC->pCursor!=0 ){ |
︙ | ︙ | |||
2667 2668 2669 2670 2671 2672 2673 | case OP_OpenRead: case OP_OpenWrite: { int i = pOp->p1; int p2 = pOp->p2; int iDb = pOp->p3; int wrFlag; Btree *pX; | | | 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 | case OP_OpenRead: case OP_OpenWrite: { int i = pOp->p1; int p2 = pOp->p2; int iDb = pOp->p3; int wrFlag; Btree *pX; VdbeCursor *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 ); |
︙ | ︙ | |||
2767 2768 2769 2770 2771 2772 2773 | ** 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; | | | 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 | ** 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; VdbeCursor *pCx; static const int openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_TRANSIENT_DB; |
︙ | ︙ | |||
2833 2834 2835 2836 2837 2838 2839 | ** 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; | | | 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 | ** 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; VdbeCursor *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->isTable = 1; |
︙ | ︙ | |||
2922 2923 2924 2925 2926 2927 2928 | ** 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; | | | 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 | ** 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; VdbeCursor *pC; assert( i>=0 && i<p->nCursor ); pC = p->apCsr[i]; assert( pC!=0 ); if( pC->pCursor!=0 ){ int res, oc; oc = pOp->opcode; |
︙ | ︙ | |||
3039 3040 3041 3042 3043 3044 3045 | ** ** See also: Found, NotExists, IsUnique */ case OP_NotFound: /* jump, in3 */ case OP_Found: { /* jump, in3 */ int i = pOp->p1; int alreadyExists = 0; | | | 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 | ** ** See also: Found, NotExists, IsUnique */ case OP_NotFound: /* jump, in3 */ case OP_Found: { /* jump, in3 */ int i = pOp->p1; int alreadyExists = 0; VdbeCursor *pC; assert( i>=0 && i<p->nCursor ); assert( p->apCsr[i]!=0 ); if( (pC = p->apCsr[i])->pCursor!=0 ){ int res; UnpackedRecord *pIdxKey; assert( pC->isTable==0 ); |
︙ | ︙ | |||
3095 3096 3097 3098 3099 3100 3101 | ** 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; | | | 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 | ** 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; VdbeCursor *pCx; BtCursor *pCrsr; Mem *pK; i64 R; /* Pop the value R off the top of the stack */ assert( pOp->p4type==P4_INT32 ); |
︙ | ︙ | |||
3192 3193 3194 3195 3196 3197 3198 | ** NotFound assumes key is a blob constructed from MakeRecord and ** P1 is an index. ** ** See also: Found, NotFound, IsUnique */ case OP_NotExists: { /* jump, in3 */ int i = pOp->p1; | | | 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 | ** NotFound assumes key is a blob constructed from MakeRecord and ** P1 is an index. ** ** See also: Found, NotFound, IsUnique */ case OP_NotExists: { /* jump, in3 */ int i = pOp->p1; VdbeCursor *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 ); |
︙ | ︙ | |||
3261 3262 3263 3264 3265 3266 3267 | ** 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; | | | 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 | ** 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; VdbeCursor *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. |
︙ | ︙ | |||
3429 3430 3431 3432 3433 3434 3435 | */ 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; | | | 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 | */ 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; VdbeCursor *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); |
︙ | ︙ | |||
3523 3524 3525 3526 3527 3528 3529 | ** 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; | | | 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 | ** 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; VdbeCursor *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 |
︙ | ︙ | |||
3594 3595 3596 3597 3598 3599 3600 | ** ** 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; | | | 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 | ** ** 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; VdbeCursor *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 ); |
︙ | ︙ | |||
3648 3649 3650 3651 3652 3653 3654 | /* Opcode: Rowid P1 P2 * * * ** ** Store in register P2 an integer which is the key of the table entry that ** P1 is currently point to. */ case OP_Rowid: { /* out2-prerelease */ int i = pOp->p1; | | | 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 | /* Opcode: Rowid P1 P2 * * * ** ** Store in register P2 an integer which is the key of the table entry that ** P1 is currently point to. */ case OP_Rowid: { /* out2-prerelease */ int i = pOp->p1; VdbeCursor *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; |
︙ | ︙ | |||
3681 3682 3683 3684 3685 3686 3687 | ** ** 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; | | | 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 | ** ** 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; VdbeCursor *pC; assert( i>=0 && i<p->nCursor ); pC = p->apCsr[i]; assert( pC!=0 ); pC->nullRow = 1; pC->rowidIsValid = 0; if( pC->pCursor ){ |
︙ | ︙ | |||
3704 3705 3706 3707 3708 3709 3710 | ** 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; | | | 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 | ** 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; VdbeCursor *pC; BtCursor *pCrsr; int res; assert( i>=0 && i<p->nCursor ); pC = p->apCsr[i]; assert( pC!=0 ); pCrsr = pC->pCursor; |
︙ | ︙ | |||
3754 3755 3756 3757 3758 3759 3760 | ** 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; | | | 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 | ** 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; VdbeCursor *pC; BtCursor *pCrsr; int res; assert( i>=0 && i<p->nCursor ); pC = p->apCsr[i]; assert( pC!=0 ); if( (pCrsr = pC->pCursor)!=0 ){ |
︙ | ︙ | |||
3799 3800 3801 3802 3803 3804 3805 | ** 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 */ | | | 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 | ** 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 */ VdbeCursor *pC; BtCursor *pCrsr; int res; CHECK_FOR_INTERRUPT; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; if( pC==0 ){ |
︙ | ︙ | |||
3842 3843 3844 3845 3846 3847 3848 | ** 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; | | | 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 | ** 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; VdbeCursor *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); |
︙ | ︙ | |||
3869 3870 3871 3872 3873 3874 3875 | ** ** 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; | | | 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 | ** ** 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; VdbeCursor *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; |
︙ | ︙ | |||
3903 3904 3905 3906 3907 3908 3909 | ** 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; | | | 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 | ** 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; VdbeCursor *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 ); |
︙ | ︙ | |||
3953 3954 3955 3956 3957 3958 3959 | ** ** If P5 is non-zero then the key value is 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; | | | 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 | ** ** If P5 is non-zero then the key value is 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; VdbeCursor *pC; assert( i>=0 && i<p->nCursor ); assert( p->apCsr[i]!=0 ); if( (pC = p->apCsr[i])->pCursor!=0 ){ int res; UnpackedRecord r; assert( pC->deferredMoveto==0 ); |
︙ | ︙ | |||
4636 4637 4638 4639 4640 4641 4642 | /* 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: { | | | 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 | /* 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: { VdbeCursor *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; |
︙ | ︙ | |||
4695 4696 4697 4698 4699 4700 4701 | int iQuery; const sqlite3_module *pModule; Mem *pQuery = &p->aMem[pOp->p3]; Mem *pArgc = &pQuery[1]; sqlite3_vtab_cursor *pVtabCursor; sqlite3_vtab *pVtab; | | | 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 | int iQuery; const sqlite3_module *pModule; Mem *pQuery = &p->aMem[pOp->p3]; Mem *pArgc = &pQuery[1]; sqlite3_vtab_cursor *pVtabCursor; sqlite3_vtab *pVtab; VdbeCursor *pCur = p->apCsr[pOp->p1]; REGISTER_TRACE(pOp->p3, pQuery); assert( pCur->pVtabCursor ); pVtabCursor = pCur->pVtabCursor; pVtab = pVtabCursor->pVtab; pModule = pVtab->pModule; |
︙ | ︙ | |||
4752 4753 4754 4755 4756 4757 4758 | ** Store into register P2 the rowid of ** the virtual-table that the P1 cursor is pointing to. */ case OP_VRowid: { /* out2-prerelease */ sqlite3_vtab *pVtab; const sqlite3_module *pModule; sqlite_int64 iRow; | | | 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 | ** Store into register P2 the rowid of ** the virtual-table that the P1 cursor is pointing to. */ case OP_VRowid: { /* out2-prerelease */ sqlite3_vtab *pVtab; const sqlite3_module *pModule; sqlite_int64 iRow; VdbeCursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); if( pCur->nullRow ){ break; } pVtab = pCur->pVtabCursor->pVtab; pModule = pVtab->pModule; |
︙ | ︙ | |||
4786 4787 4788 4789 4790 4791 4792 | */ case OP_VColumn: { sqlite3_vtab *pVtab; const sqlite3_module *pModule; Mem *pDest; sqlite3_context sContext; | | | 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 | */ case OP_VColumn: { sqlite3_vtab *pVtab; const sqlite3_module *pModule; Mem *pDest; sqlite3_context sContext; VdbeCursor *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; } |
︙ | ︙ | |||
4844 4845 4846 4847 4848 4849 4850 | ** the end of its result set, then fall through to the next instruction. */ case OP_VNext: { /* jump */ sqlite3_vtab *pVtab; const sqlite3_module *pModule; int res = 0; | | | 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 | ** the end of its result set, then fall through to the next instruction. */ case OP_VNext: { /* jump */ sqlite3_vtab *pVtab; const sqlite3_module *pModule; int res = 0; VdbeCursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); if( pCur->nullRow ){ break; } pVtab = pCur->pVtabCursor->pVtab; pModule = pVtab->pModule; assert( pModule->xNext ); |
︙ | ︙ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** This is the header file for information that is private to the ** VDBE. This information used to all be at the top of the single ** source code file "vdbe.c". When that file became too big (over ** 6000 lines long) it was split up into several smaller files and ** this header information was factored out. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** This is the header file for information that is private to the ** VDBE. This information used to all be at the top of the single ** source code file "vdbe.c". When that file became too big (over ** 6000 lines long) it was split up into several smaller files and ** this header information was factored out. ** ** $Id: vdbeInt.h,v 1.156 2008/11/03 20:55:07 drh Exp $ */ #ifndef _VDBEINT_H_ #define _VDBEINT_H_ /* ** intToKey() and keyToInt() used to transform the rowid. But with ** the latest versions of the design they are no-ops. |
︙ | ︙ | |||
46 47 48 49 50 51 52 | ** loop over all entries of the Btree. You can also insert new BTree ** entries or retrieve the key or data from the entry that the cursor ** is currently pointing to. ** ** Every cursor that the virtual machine has open is represented by an ** instance of the following structure. ** | | | | | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | ** loop over all entries of the Btree. You can also insert new BTree ** entries or retrieve the key or data from the entry that the cursor ** is currently pointing to. ** ** Every cursor that the virtual machine has open is represented by an ** instance of the following structure. ** ** If the VdbeCursor.isTriggerRow flag is set it means that this cursor is ** really a single row that represents the NEW or OLD pseudo-table of ** a row trigger. The data for the row is stored in VdbeCursor.pData and ** the rowid is in VdbeCursor.iKey. */ struct VdbeCursor { BtCursor *pCursor; /* The cursor structure of the backend */ int iDb; /* Index of cursor database in db->aDb[] (or -1) */ i64 lastRowid; /* Last rowid from a Next or NextIdx operation */ i64 nextRowid; /* Next rowid returned by OP_NewRowid */ Bool zeroed; /* True if zeroed out and ready for reuse */ Bool rowidIsValid; /* True if lastRowid is valid */ Bool atFirst; /* True if pointing to first entry */ |
︙ | ︙ | |||
89 90 91 92 93 94 95 | */ int cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ int payloadSize; /* Total number of bytes in the record */ u32 *aType; /* Type values for all entries in the record */ u32 *aOffset; /* Cached offsets to the start of each columns data */ u8 *aRow; /* Data for the current row, if all on one page */ }; | | | | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | */ int cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ int payloadSize; /* Total number of bytes in the record */ u32 *aType; /* Type values for all entries in the record */ u32 *aOffset; /* Cached offsets to the start of each columns data */ u8 *aRow; /* Data for the current row, if all on one page */ }; typedef struct VdbeCursor VdbeCursor; /* ** A value for VdbeCursor.cacheValid that means the cache is always invalid. */ #define CACHE_STALE 0 /* ** Internally, the vdbe manipulates nearly all SQL values as Mem ** structures. Each Mem struct may cache multiple representations (string, ** integer etc.) of the same value. A value (and therefore Mem structure) |
︙ | ︙ | |||
287 288 289 290 291 292 293 | Op *aOp; /* Space to hold the virtual machine's program */ int nLabel; /* Number of labels used */ int nLabelAlloc; /* Number of slots allocated in aLabel[] */ int *aLabel; /* Space to hold the labels */ Mem **apArg; /* Arguments to currently executing user function */ Mem *aColName; /* Column names to return */ int nCursor; /* Number of slots in apCsr[] */ | | | | 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | Op *aOp; /* Space to hold the virtual machine's program */ int nLabel; /* Number of labels used */ int nLabelAlloc; /* Number of slots allocated in aLabel[] */ int *aLabel; /* Space to hold the labels */ Mem **apArg; /* Arguments to currently executing user function */ Mem *aColName; /* Column names to return */ int nCursor; /* Number of slots in apCsr[] */ VdbeCursor **apCsr; /* One element of this array for each open cursor */ int nVar; /* Number of entries in aVar[] */ Mem *aVar; /* Values for the OP_Variable opcode. */ char **azVar; /* Name of variables */ int okVar; /* True if azVar[] has been initialized */ int magic; /* Magic number for sanity checking */ int nMem; /* Number of memory locations currently allocated */ Mem *aMem; /* The memory locations */ int nCallback; /* Number of callbacks invoked so far */ int cacheCtr; /* VdbeCursor row cache generation counter */ Fifo sFifo; /* A list of ROWIDs */ int contextStackTop; /* Index of top element in the context stack */ int contextStackDepth; /* The size of the "context" stack */ Context *contextStack; /* Stack used by opcodes ContextPush & ContextPop*/ int pc; /* The program counter */ int rc; /* Value to return */ unsigned uniqueCnt; /* Used by OP_MakeRecord when P2!=0 */ |
︙ | ︙ | |||
347 348 349 350 351 352 353 | #define VDBE_MAGIC_RUN 0xbdf20da3 /* VDBE is ready to execute */ #define VDBE_MAGIC_HALT 0x519c2973 /* VDBE has completed execution */ #define VDBE_MAGIC_DEAD 0xb606c3c8 /* The VDBE has been deallocated */ /* ** Function prototypes */ | | | | | 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 | #define VDBE_MAGIC_RUN 0xbdf20da3 /* VDBE is ready to execute */ #define VDBE_MAGIC_HALT 0x519c2973 /* VDBE has completed execution */ #define VDBE_MAGIC_DEAD 0xb606c3c8 /* The VDBE has been deallocated */ /* ** Function prototypes */ void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); void sqliteVdbePopStack(Vdbe*,int); int sqlite3VdbeCursorMoveto(VdbeCursor*); #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) void sqlite3VdbePrintOp(FILE*, int, Op*); #endif int sqlite3VdbeSerialTypeLen(u32); u32 sqlite3VdbeSerialType(Mem*, int); int sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int); int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); void sqlite3VdbeDeleteAuxData(VdbeFunc*, int); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*); int sqlite3VdbeIdxRowid(BtCursor *, i64 *); int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); int sqlite3VdbeExec(Vdbe*); int sqlite3VdbeList(Vdbe*); int sqlite3VdbeHalt(Vdbe*); int sqlite3VdbeChangeEncoding(Mem *, int); int sqlite3VdbeMemTooBig(Mem*); |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This file contains code used for creating, destroying, and populating ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) Prior ** to version 2.8.7, all this code was combined into the vdbe.c source file. ** But that file was getting too big so this subroutines were split out. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** This file contains code used for creating, destroying, and populating ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) Prior ** to version 2.8.7, all this code was combined into the vdbe.c source file. ** But that file was getting too big so this subroutines were split out. ** ** $Id: vdbeaux.c,v 1.415 2008/11/03 20:55:07 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" |
︙ | ︙ | |||
1017 1018 1019 1020 1021 1022 1023 | * state. */ p->magic = VDBE_MAGIC_RUN; /* For each cursor required, also allocate a memory cell. Memory ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by ** the vdbe program. Instead they are used to allocate space for | | | 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 | * state. */ p->magic = VDBE_MAGIC_RUN; /* For each cursor required, also allocate a memory cell. Memory ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by ** the vdbe program. Instead they are used to allocate space for ** VdbeCursor/BtCursor structures. The blob of memory associated with ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1) ** stores the blob of memory associated with cursor 1, etc. ** ** See also: allocateCursor(). */ nMem += nCursor; |
︙ | ︙ | |||
1041 1042 1043 1044 1045 1046 1047 | p->nMem = nMem = 10; } p->aMem = sqlite3DbMallocZero(db, nMem*sizeof(Mem) /* aMem */ + nVar*sizeof(Mem) /* aVar */ + nArg*sizeof(Mem*) /* apArg */ + nVar*sizeof(char*) /* azVar */ | | | | 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 | p->nMem = nMem = 10; } p->aMem = sqlite3DbMallocZero(db, nMem*sizeof(Mem) /* aMem */ + nVar*sizeof(Mem) /* aVar */ + nArg*sizeof(Mem*) /* apArg */ + nVar*sizeof(char*) /* azVar */ + nCursor*sizeof(VdbeCursor*)+1 /* apCsr */ ); if( !db->mallocFailed ){ p->aMem--; /* aMem[] goes from 1..nMem */ p->nMem = nMem; /* not from 0..nMem-1 */ p->aVar = &p->aMem[nMem+1]; p->nVar = nVar; p->okVar = 0; p->apArg = (Mem**)&p->aVar[nVar]; p->azVar = (char**)&p->apArg[nArg]; p->apCsr = (VdbeCursor**)&p->azVar[nVar]; p->nCursor = nCursor; for(n=0; n<nVar; n++){ p->aVar[n].flags = MEM_Null; p->aVar[n].db = db; } for(n=1; n<=nMem; n++){ p->aMem[n].flags = MEM_Null; |
︙ | ︙ | |||
1094 1095 1096 1097 1098 1099 1100 | #endif } /* ** Close a VDBE cursor and release all the resources that cursor ** happens to hold. */ | | | 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 | #endif } /* ** Close a VDBE cursor and release all the resources that cursor ** happens to hold. */ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ if( pCx==0 ){ return; } if( pCx->pBt ){ sqlite3BtreeClose(pCx->pBt); /* The pCx->pCursor will be close automatically, if it exists, by ** the call above. */ |
︙ | ︙ | |||
1129 1130 1131 1132 1133 1134 1135 | ** Close all cursors except for VTab cursors that are currently ** in use. */ static void closeAllCursorsExceptActiveVtabs(Vdbe *p){ int i; if( p->apCsr==0 ) return; for(i=0; i<p->nCursor; i++){ | | | 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 | ** Close all cursors except for VTab cursors that are currently ** in use. */ static void closeAllCursorsExceptActiveVtabs(Vdbe *p){ int i; if( p->apCsr==0 ) return; for(i=0; i<p->nCursor; i++){ VdbeCursor *pC = p->apCsr[i]; if( pC && (!p->inVtabMethod || !pC->pVtabCursor) ){ sqlite3VdbeFreeCursor(p, pC); p->apCsr[i] = 0; } } } |
︙ | ︙ | |||
1862 1863 1864 1865 1866 1867 1868 | } /* ** If a MoveTo operation is pending on the given cursor, then do that ** MoveTo now. Return an error code. If no MoveTo is pending, this ** routine does nothing and returns SQLITE_OK. */ | | | 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 | } /* ** If a MoveTo operation is pending on the given cursor, then do that ** MoveTo now. Return an error code. If no MoveTo is pending, this ** routine does nothing and returns SQLITE_OK. */ int sqlite3VdbeCursorMoveto(VdbeCursor *p){ if( p->deferredMoveto ){ int res, rc; #ifdef SQLITE_TEST extern int sqlite3_search_count; #endif assert( p->isTable ); rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res); |
︙ | ︙ | |||
2429 2430 2431 2432 2433 2434 2435 | ** is ignored as well. Hence, this routine only compares the prefixes ** of the keys prior to the final rowid, not the entire key. ** ** pUnpacked may be an unpacked version of pKey,nKey. If pUnpacked is ** supplied it is used in place of pKey,nKey. */ int sqlite3VdbeIdxKeyCompare( | | | 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 | ** is ignored as well. Hence, this routine only compares the prefixes ** of the keys prior to the final rowid, not the entire key. ** ** pUnpacked may be an unpacked version of pKey,nKey. If pUnpacked is ** supplied it is used in place of pKey,nKey. */ int sqlite3VdbeIdxKeyCompare( VdbeCursor *pC, /* The cursor to compare against */ UnpackedRecord *pUnpacked, /* Unpacked version of pKey and nKey */ int *res /* Write the comparison result here */ ){ i64 nCellKey = 0; int rc; BtCursor *pCur = pC->pCursor; Mem m; |
︙ | ︙ |