Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Replace OP_Begin, OP_Commit and OP_Rollback with OP_AutoCommit. (CVS 1500) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
b8ed812c92f2dbb4431d45aeb41646ce |
User & Date: | danielk1977 2004-05-31 08:26:49.000 |
Context
2004-05-31
| ||
08:55 | Remove the <ON CONFLICT> clause from BEGIN (CVS 1501) (check-in: 9029274b61 user: danielk1977 tags: trunk) | |
08:26 | Replace OP_Begin, OP_Commit and OP_Rollback with OP_AutoCommit. (CVS 1500) (check-in: b8ed812c92 user: danielk1977 tags: trunk) | |
2004-05-30
| ||
21:14 | Add 3-byte and 6-byte integer serial types. This makes databases smaller and faster. Should we go ahead and add 5- and 7-byte integer types too? (CVS 1499) (check-in: e6685af815 user: drh tags: trunk) | |
Changes
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.153 2004/05/31 08:26:49 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to ** ** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: ** "Sorting And Searching", pages 473-480. Addison-Wesley ** Publishing Company, Reading, Massachusetts. |
︙ | ︙ | |||
4179 4180 4181 4182 4183 4184 4185 | rc = sqlite3pager_truncate(pBtTo->pPager, nPage); } if( rc ){ sqlite3BtreeRollback(pBtTo); } return rc; } | > > > > > > > > > > > > > > | 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 | rc = sqlite3pager_truncate(pBtTo->pPager, nPage); } if( rc ){ sqlite3BtreeRollback(pBtTo); } return rc; } /* ** Return non-zero if a transaction is active. */ int sqlite3BtreeIsInTrans(Btree *pBt){ return (pBt && pBt->inTrans); } /* ** Return non-zero if a statement transaction is active. */ int sqlite3BtreeIsInStmt(Btree *pBt){ return (pBt && pBt->inStmt); } |
Changes to src/btree.h.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite B-Tree file ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite B-Tree file ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** ** @(#) $Id: btree.h,v 1.50 2004/05/31 08:26:49 danielk1977 Exp $ */ #ifndef _BTREE_H_ #define _BTREE_H_ /* TODO: This definition is just included so other modules compile. It ** needs to be revisited. */ |
︙ | ︙ | |||
44 45 46 47 48 49 50 51 52 53 54 55 56 57 | int sqlite3BtreeBeginTrans(Btree*); int sqlite3BtreeCommit(Btree*); int sqlite3BtreeRollback(Btree*); int sqlite3BtreeBeginStmt(Btree*); int sqlite3BtreeCommitStmt(Btree*); int sqlite3BtreeRollbackStmt(Btree*); int sqlite3BtreeCreateTable(Btree*, int*, int flags); const char *sqlite3BtreeGetFilename(Btree *); int sqlite3BtreeCopyFile(Btree *, Btree *); /* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR ** of the following flags: */ | > > | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | int sqlite3BtreeBeginTrans(Btree*); int sqlite3BtreeCommit(Btree*); int sqlite3BtreeRollback(Btree*); int sqlite3BtreeBeginStmt(Btree*); int sqlite3BtreeCommitStmt(Btree*); int sqlite3BtreeRollbackStmt(Btree*); int sqlite3BtreeCreateTable(Btree*, int*, int flags); int sqlite3BtreeIsInTrans(Btree*); int sqlite3BtreeIsInStmt(Btree*); const char *sqlite3BtreeGetFilename(Btree *); int sqlite3BtreeCopyFile(Btree *, Btree *); /* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR ** of the following flags: */ |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
19 20 21 22 23 24 25 | ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** ** $Id: build.c,v 1.201 2004/05/31 08:26:49 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Check to see if the schema for the database needs |
︙ | ︙ | |||
916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 | ** This plan is not completely bullet-proof. It is possible for ** the schema to change multiple times and for the cookie to be ** set back to prior value. But schema changes are infrequent ** and the probability of hitting the same cookie value is only ** 1 chance in 2^32. So we're safe enough. */ void sqlite3ChangeCookie(sqlite *db, Vdbe *v, int iDb){ if( db->next_cookie==db->aDb[0].schema_cookie ){ unsigned char r; sqlite3Randomness(1, &r); db->next_cookie = db->aDb[0].schema_cookie + r + 1; db->flags |= SQLITE_InternChanges; sqlite3VdbeAddOp(v, OP_Integer, db->next_cookie, 0); sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 0); } } /* ** Measure the number of characters needed to output the given ** identifier. The number returned includes any quotes used ** but does not include the null terminator. */ | > > > > > > > > > > | 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 | ** This plan is not completely bullet-proof. It is possible for ** the schema to change multiple times and for the cookie to be ** set back to prior value. But schema changes are infrequent ** and the probability of hitting the same cookie value is only ** 1 chance in 2^32. So we're safe enough. */ void sqlite3ChangeCookie(sqlite *db, Vdbe *v, int iDb){ unsigned char r; int *pSchemaCookie = &(db->aDb[iDb].schema_cookie); sqlite3Randomness(1, &r); *pSchemaCookie = *pSchemaCookie + r + 1; db->flags |= SQLITE_InternChanges; sqlite3VdbeAddOp(v, OP_Integer, *pSchemaCookie, 0); sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 0); /* if( db->next_cookie==db->aDb[0].schema_cookie ){ unsigned char r; sqlite3Randomness(1, &r); db->next_cookie = db->aDb[0].schema_cookie + r + 1; db->flags |= SQLITE_InternChanges; sqlite3VdbeAddOp(v, OP_Integer, db->next_cookie, 0); sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 0); } */ } /* ** Measure the number of characters needed to output the given ** identifier. The number returned includes any quotes used ** but does not include the null terminator. */ |
︙ | ︙ | |||
1100 1101 1102 1103 1104 1105 1106 | n = Addr(pEnd->z) - Addr(pParse->sNameToken.z) + 1; sqlite3VdbeAddOp(v, OP_String8, 0, 0); sqlite3VdbeChangeP3(v, -1, pParse->sNameToken.z, n); sqlite3VdbeAddOp(v, OP_Concat, 2, 0); } sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC); sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); | | | 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 | n = Addr(pEnd->z) - Addr(pParse->sNameToken.z) + 1; sqlite3VdbeAddOp(v, OP_String8, 0, 0); sqlite3VdbeChangeP3(v, -1, pParse->sNameToken.z, n); sqlite3VdbeAddOp(v, OP_Concat, 2, 0); } sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC); sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); if( p->iDb!=1 ){ sqlite3ChangeCookie(db, v, p->iDb); } sqlite3VdbeAddOp(v, OP_Close, 0, 0); if( pSelect ){ sqlite3VdbeAddOp(v, OP_Integer, p->iDb, 0); sqlite3VdbeAddOp(v, OP_OpenWrite, 1, 0); pParse->nTab = 2; |
︙ | ︙ | |||
1826 1827 1828 1829 1830 1831 1832 | ** has just been created, it contains no data and the index initialization ** step can be skipped. */ else if( db->init.busy==0 ){ int n; Vdbe *v; int lbl1, lbl2; | < | 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 | ** has just been created, it contains no data and the index initialization ** step can be skipped. */ else if( db->init.busy==0 ){ int n; Vdbe *v; int lbl1, lbl2; v = sqlite3GetVdbe(pParse); if( v==0 ) goto exit_create_index; if( pTblName!=0 ){ sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3OpenMasterTable(v, iDb); } |
︙ | ︙ | |||
2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 | } /* ** Begin a transaction */ void sqlite3BeginTransaction(Parse *pParse, int onError){ sqlite *db; if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return; if( pParse->nErr || sqlite3_malloc_failed ) return; if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ) return; | > < < < | | | < < > | > > < < < | < < < | | < > < < < | | < < < < | | | 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 | } /* ** Begin a transaction */ void sqlite3BeginTransaction(Parse *pParse, int onError){ sqlite *db; Vdbe *v; if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return; if( pParse->nErr || sqlite3_malloc_failed ) return; if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ) return; v = sqlite3GetVdbe(pParse); if( !v ) return; sqlite3VdbeAddOp(v, OP_AutoCommit, 0, 0); /* FIX ME: Need to deal with onError */ } /* ** Commit a transaction */ void sqlite3CommitTransaction(Parse *pParse){ sqlite *db; Vdbe *v; if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return; if( pParse->nErr || sqlite3_malloc_failed ) return; if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ) return; v = sqlite3GetVdbe(pParse); if( v ){ sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 0); } } /* ** Rollback a transaction */ void sqlite3RollbackTransaction(Parse *pParse){ sqlite *db; Vdbe *v; if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return; if( pParse->nErr || sqlite3_malloc_failed ) return; if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ) return; v = sqlite3GetVdbe(pParse); if( v ){ sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 1); } } /* ** Generate VDBE code that will verify the schema cookie for all ** named database files. */ void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ sqlite *db = pParse->db; Vdbe *v = sqlite3GetVdbe(pParse); assert( iDb>=0 && iDb<db->nDb ); assert( db->aDb[iDb].pBt!=0 ); if( iDb!=1 && (iDb>63 || !(pParse->cookieMask & ((u64)1<<iDb))) ){ sqlite3VdbeAddOp(v, OP_VerifyCookie, iDb, db->aDb[iDb].schema_cookie); pParse->cookieMask |= ((u64)1<<iDb); } } /* ** Generate VDBE code that prepares for doing an operation that ** might change the database. ** |
︙ | ︙ | |||
2256 2257 2258 2259 2260 2261 2262 | ** ** Only database iDb and the temp database are made writable by this call. ** If iDb==0, then the main and temp databases are made writable. If ** iDb==1 then only the temp database is made writable. If iDb>1 then the ** specified auxiliary database and the temp database are made writable. */ void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ | < < < | < | < | < < < | > | > | < < < | < < < < < | < | 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 | ** ** Only database iDb and the temp database are made writable by this call. ** If iDb==0, then the main and temp databases are made writable. If ** iDb==1 then only the temp database is made writable. If iDb>1 then the ** specified auxiliary database and the temp database are made writable. */ void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ Vdbe *v = sqlite3GetVdbe(pParse); if( v==0 ) return; sqlite3VdbeAddOp(v, OP_Transaction, iDb, 0); sqlite3CodeVerifySchema(pParse, iDb); if( setStatement ){ sqlite3VdbeAddOp(v, OP_Statement, iDb, 0); } if( iDb!=1 ){ sqlite3BeginWriteOperation(pParse, setStatement, 1); } } /* ** Generate code that concludes an operation that may have changed ** the database. If a statement transaction was started, then emit ** an OP_Commit that will cause the changes to be committed to disk. ** ** Note that checkpoints are automatically committed at the end of ** a statement. Note also that there can be multiple calls to ** sqlite3BeginWriteOperation() but there should only be a single ** call to sqlite3EndWriteOperation() at the conclusion of the statement. */ void sqlite3EndWriteOperation(Parse *pParse){ /* Delete me! */ return; } |
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: main.c,v 1.197 2004/05/31 08:26:49 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** A pointer to this structure is used to communicate information |
︙ | ︙ | |||
1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 | if( db==0 ) goto opendb_out; db->onError = OE_Default; db->priorNewRowid = 0; db->magic = SQLITE_MAGIC_BUSY; db->nDb = 2; db->aDb = db->aDbStatic; db->enc = def_enc; /* db->flags |= SQLITE_ShortColNames; */ sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 0); sqlite3HashInit(&db->aCollSeq, SQLITE_HASH_STRING, 0); for(i=0; i<db->nDb; i++){ sqlite3HashInit(&db->aDb[i].tblHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&db->aDb[i].idxHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&db->aDb[i].trigHash, SQLITE_HASH_STRING, 0); | > | 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 | if( db==0 ) goto opendb_out; db->onError = OE_Default; db->priorNewRowid = 0; db->magic = SQLITE_MAGIC_BUSY; db->nDb = 2; db->aDb = db->aDbStatic; db->enc = def_enc; db->autoCommit = 1; /* db->flags |= SQLITE_ShortColNames; */ sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 0); sqlite3HashInit(&db->aCollSeq, SQLITE_HASH_STRING, 0); for(i=0; i<db->nDb; i++){ sqlite3HashInit(&db->aDb[i].tblHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&db->aDb[i].idxHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&db->aDb[i].trigHash, SQLITE_HASH_STRING, 0); |
︙ | ︙ |
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.109 2004/05/31 08:26:49 danielk1977 Exp $ */ #include "os.h" /* Must be first to enable large file support */ #include "sqliteInt.h" #include "pager.h" #include <assert.h> #include <string.h> |
︙ | ︙ | |||
861 862 863 864 865 866 867 | ** but if the operating system crashes or there is an abrupt power ** failure, the database file might be left in an inconsistent and ** unrepairable state. */ void sqlite3pager_set_cachesize(Pager *pPager, int mxPage){ if( mxPage>=0 ){ pPager->noSync = pPager->tempFile; | | | 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 | ** but if the operating system crashes or there is an abrupt power ** failure, the database file might be left in an inconsistent and ** unrepairable state. */ void sqlite3pager_set_cachesize(Pager *pPager, int mxPage){ if( mxPage>=0 ){ pPager->noSync = pPager->tempFile; if( pPager->noSync ) pPager->needSync = 0; }else{ pPager->noSync = 1; mxPage = -mxPage; } if( mxPage>10 ){ pPager->mxPage = mxPage; } |
︙ | ︙ | |||
900 901 902 903 904 905 906 | ** ** Numeric values associated with these states are OFF==1, NORMAL=2, ** and FULL=3. */ void sqlite3pager_set_safety_level(Pager *pPager, int level){ pPager->noSync = level==1 || pPager->tempFile; pPager->fullSync = level==3 && !pPager->tempFile; | | | 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 | ** ** Numeric values associated with these states are OFF==1, NORMAL=2, ** and FULL=3. */ void sqlite3pager_set_safety_level(Pager *pPager, int level){ pPager->noSync = level==1 || pPager->tempFile; pPager->fullSync = level==3 && !pPager->tempFile; if( pPager->noSync ) pPager->needSync = 0; } /* ** Open a temporary file. Write the name of the file into zName ** (zName must be at least SQLITE_TEMPNAME_SIZE bytes long.) Write ** the file descriptor into *fd. Return SQLITE_OK on success or some ** other error code if we fail. |
︙ | ︙ |
Changes to src/pragma.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2003 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. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2003 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. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** ** $Id: pragma.c,v 1.35 2004/05/31 08:26:49 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Interpret the given string as a boolean value. */ |
︙ | ︙ | |||
89 90 91 92 93 94 95 | ** or DEFAULT_TEMP_STORE pragmas. */ static int changeTempStorage(Parse *pParse, const char *zStorageType){ int ts = getTempStore(zStorageType); sqlite *db = pParse->db; if( db->temp_store==ts ) return SQLITE_OK; if( db->aDb[1].pBt!=0 ){ | | | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | ** or DEFAULT_TEMP_STORE pragmas. */ static int changeTempStorage(Parse *pParse, const char *zStorageType){ int ts = getTempStore(zStorageType); sqlite *db = pParse->db; if( db->temp_store==ts ) return SQLITE_OK; if( db->aDb[1].pBt!=0 ){ if( !db->autoCommit ){ sqlite3ErrorMsg(pParse, "temporary storage cannot be changed " "from within a transaction"); return SQLITE_ERROR; } sqlite3BtreeClose(db->aDb[1].pBt); db->aDb[1].pBt = 0; sqlite3ResetInternalSchema(db, 0); |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.262 2004/05/31 08:26:49 danielk1977 Exp $ */ #include "config.h" #include "sqlite.h" #include "hash.h" #include "parse.h" #include <stdio.h> #include <stdlib.h> |
︙ | ︙ | |||
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 | int csChange; /* Current statement change count (see above) */ struct sqlite3InitInfo { /* Information used during initialization */ int iDb; /* When back is being initialized */ int newTnum; /* Rootpage of table being initialized */ u8 busy; /* TRUE if currently initializing */ } init; struct Vdbe *pVdbe; /* List of active virtual machines */ void (*xTrace)(void*,const char*); /* Trace function */ void *pTraceArg; /* Argument to the trace function */ #ifndef SQLITE_OMIT_AUTHORIZATION int (*xAuth)(void*,int,const char*,const char*,const char*,const char*); /* Access authorization function */ void *pAuthArg; /* 1st argument to the access auth function */ #endif #ifndef SQLITE_OMIT_PROGRESS_CALLBACK int (*xProgress)(void *); /* The progress callback */ void *pProgressArg; /* Argument to the progress callback */ int nProgressOps; /* Number of opcodes for progress callback */ #endif int errCode; /* Most recent error code (SQLITE_*) */ char *zErrMsg; /* Most recent error message (UTF-8 encoded) */ void *zErrMsg16; /* Most recent error message (UTF-16 encoded) */ u8 enc; /* Text encoding for this database. */ }; /* ** Possible values for the sqlite.flags and or Db.flags fields. ** ** On sqlite.flags, the SQLITE_InTrans value means that we have ** executed a BEGIN. On Db.flags, SQLITE_InTrans means a statement | > > | 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 | int csChange; /* Current statement change count (see above) */ struct sqlite3InitInfo { /* Information used during initialization */ int iDb; /* When back is being initialized */ int newTnum; /* Rootpage of table being initialized */ u8 busy; /* TRUE if currently initializing */ } init; struct Vdbe *pVdbe; /* List of active virtual machines */ int activeVdbeCnt; /* Number of vdbes currently executing */ void (*xTrace)(void*,const char*); /* Trace function */ void *pTraceArg; /* Argument to the trace function */ #ifndef SQLITE_OMIT_AUTHORIZATION int (*xAuth)(void*,int,const char*,const char*,const char*,const char*); /* Access authorization function */ void *pAuthArg; /* 1st argument to the access auth function */ #endif #ifndef SQLITE_OMIT_PROGRESS_CALLBACK int (*xProgress)(void *); /* The progress callback */ void *pProgressArg; /* Argument to the progress callback */ int nProgressOps; /* Number of opcodes for progress callback */ #endif int errCode; /* Most recent error code (SQLITE_*) */ char *zErrMsg; /* Most recent error message (UTF-8 encoded) */ void *zErrMsg16; /* Most recent error message (UTF-16 encoded) */ u8 enc; /* Text encoding for this database. */ u8 autoCommit; /* The auto-commit flag. */ }; /* ** Possible values for the sqlite.flags and or Db.flags fields. ** ** On sqlite.flags, the SQLITE_InTrans value means that we have ** executed a BEGIN. On Db.flags, SQLITE_InTrans means a statement |
︙ | ︙ | |||
985 986 987 988 989 990 991 992 993 994 995 996 997 998 | int nSet; /* Number of sets used so far */ int nAgg; /* Number of aggregate expressions */ int nVar; /* Number of '?' variables seen in the SQL so far */ AggExpr *aAgg; /* An array of aggregate expressions */ const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */ Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */ TriggerStack *trigStack; /* Trigger actions being coded */ }; /* ** An instance of the following structure can be declared on a stack and used ** to save the Parse.zAuthContext value so that it can be restored later. */ struct AuthContext { | > | 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 | int nSet; /* Number of sets used so far */ int nAgg; /* Number of aggregate expressions */ int nVar; /* Number of '?' variables seen in the SQL so far */ AggExpr *aAgg; /* An array of aggregate expressions */ const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */ Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */ TriggerStack *trigStack; /* Trigger actions being coded */ u64 cookieMask; /* Bitmask of schema verified databases */ }; /* ** An instance of the following structure can be declared on a stack and used ** to save the Parse.zAuthContext value so that it can be restored later. */ struct AuthContext { |
︙ | ︙ |
Changes to src/test3.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the btree.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the btree.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test3.c,v 1.40 2004/05/31 08:26:49 danielk1977 Exp $ */ #include "sqliteInt.h" #include "pager.h" #include "btree.h" #include "tcl.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
180 181 182 183 184 185 186 187 188 189 190 191 192 193 | if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; rc = sqlite3BtreeCommit(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return TCL_OK; } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; rc = sqlite3BtreeCommit(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return TCL_OK; } /* ** Usage: btree_begin_statement ID ** ** Start a new statement transaction */ static int btree_begin_statement( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */ ){ Btree *pBt; int rc; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; rc = sqlite3BtreeBeginStmt(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return TCL_OK; } /* ** Usage: btree_rollback_statement ID ** ** Rollback changes */ static int btree_rollback_statement( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */ ){ Btree *pBt; int rc; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; rc = sqlite3BtreeRollbackStmt(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return TCL_OK; } /* ** Usage: btree_commit_statement ID ** ** Commit all changes */ static int btree_commit_statement( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */ ){ Btree *pBt; int rc; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; rc = sqlite3BtreeCommitStmt(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return TCL_OK; } |
︙ | ︙ | |||
1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 | { "btree_first", (Tcl_CmdProc*)btree_first }, { "btree_last", (Tcl_CmdProc*)btree_last }, { "btree_cursor_info", (Tcl_CmdProc*)btree_cursor_info }, { "btree_cursor_list", (Tcl_CmdProc*)btree_cursor_list }, { "btree_integrity_check", (Tcl_CmdProc*)btree_integrity_check }, { "btree_breakpoint", (Tcl_CmdProc*)btree_breakpoint }, { "btree_varint_test", (Tcl_CmdProc*)btree_varint_test }, }; int i; for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); } Tcl_LinkVar(interp, "pager_refinfo_enable", (char*)&pager3_refinfo_enable, TCL_LINK_INT); Tcl_LinkVar(interp, "btree_trace", (char*)&sqlite3_btree_trace, TCL_LINK_INT); return TCL_OK; } | > > > | 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 | { "btree_first", (Tcl_CmdProc*)btree_first }, { "btree_last", (Tcl_CmdProc*)btree_last }, { "btree_cursor_info", (Tcl_CmdProc*)btree_cursor_info }, { "btree_cursor_list", (Tcl_CmdProc*)btree_cursor_list }, { "btree_integrity_check", (Tcl_CmdProc*)btree_integrity_check }, { "btree_breakpoint", (Tcl_CmdProc*)btree_breakpoint }, { "btree_varint_test", (Tcl_CmdProc*)btree_varint_test }, { "btree_begin_statement", (Tcl_CmdProc*)btree_begin_statement }, { "btree_commit_statement", (Tcl_CmdProc*)btree_commit_statement }, { "btree_rollback_statement", (Tcl_CmdProc*)btree_rollback_statement }, }; int i; for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); } Tcl_LinkVar(interp, "pager_refinfo_enable", (char*)&pager3_refinfo_enable, TCL_LINK_INT); Tcl_LinkVar(interp, "btree_trace", (char*)&sqlite3_btree_trace, TCL_LINK_INT); return TCL_OK; } |
Changes to src/trigger.c.
︙ | ︙ | |||
227 228 229 230 231 232 233 | if( v==0 ) goto triggerfinish_cleanup; sqlite3BeginWriteOperation(pParse, 0, nt->iDb); sqlite3OpenMasterTable(v, nt->iDb); addr = sqlite3VdbeAddOpList(v, ArraySize(insertTrig), insertTrig); sqlite3VdbeChangeP3(v, addr+2, nt->name, 0); sqlite3VdbeChangeP3(v, addr+3, nt->table, 0); sqlite3VdbeChangeP3(v, addr+6, pAll->z, pAll->n); | | | | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | if( v==0 ) goto triggerfinish_cleanup; sqlite3BeginWriteOperation(pParse, 0, nt->iDb); sqlite3OpenMasterTable(v, nt->iDb); addr = sqlite3VdbeAddOpList(v, ArraySize(insertTrig), insertTrig); sqlite3VdbeChangeP3(v, addr+2, nt->name, 0); sqlite3VdbeChangeP3(v, addr+3, nt->table, 0); sqlite3VdbeChangeP3(v, addr+6, pAll->z, pAll->n); if( nt->iDb!=0 ){ sqlite3ChangeCookie(db, v, nt->iDb); } sqlite3VdbeAddOp(v, OP_Close, 0, 0); sqlite3EndWriteOperation(pParse); } if( !pParse->explain ){ Table *pTab; |
︙ | ︙ | |||
484 485 486 487 488 489 490 | { OP_Next, 0, ADDR(1), 0}, /* 8 */ }; sqlite3BeginWriteOperation(pParse, 0, pTrigger->iDb); sqlite3OpenMasterTable(v, pTrigger->iDb); base = sqlite3VdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger); sqlite3VdbeChangeP3(v, base+1, pTrigger->name, 0); | | | | 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 | { OP_Next, 0, ADDR(1), 0}, /* 8 */ }; sqlite3BeginWriteOperation(pParse, 0, pTrigger->iDb); sqlite3OpenMasterTable(v, pTrigger->iDb); base = sqlite3VdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger); sqlite3VdbeChangeP3(v, base+1, pTrigger->name, 0); if( pTrigger->iDb!=1 ){ sqlite3ChangeCookie(db, v, pTrigger->iDb); } sqlite3VdbeAddOp(v, OP_Close, 0, 0); sqlite3EndWriteOperation(pParse); } /* * If this is not an "explain", then delete the trigger structure. |
︙ | ︙ | |||
707 708 709 710 711 712 713 714 715 716 717 718 719 720 | int newIdx, /* The indice of the "new" row to access */ int oldIdx, /* The indice of the "old" row to access */ int orconf, /* ON CONFLICT policy */ int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */ ){ Trigger * pTrigger; TriggerStack * pTriggerStack; assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE); assert(tr_tm == TK_BEFORE || tr_tm == TK_AFTER ); assert(newIdx != -1 || oldIdx != -1); pTrigger = pTab->pTrigger; | > | 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 | int newIdx, /* The indice of the "new" row to access */ int oldIdx, /* The indice of the "old" row to access */ int orconf, /* ON CONFLICT policy */ int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */ ){ Trigger * pTrigger; TriggerStack * pTriggerStack; u64 cookieMask = pParse->cookieMask; assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE); assert(tr_tm == TK_BEFORE || tr_tm == TK_AFTER ); assert(newIdx != -1 || oldIdx != -1); pTrigger = pTab->pTrigger; |
︙ | ︙ | |||
778 779 780 781 782 783 784 785 786 787 788 789 | sqliteFree(pTriggerStack); sqlite3VdbeResolveLabel(pParse->pVdbe, endTrigger); } pTrigger = pTrigger->pNext; } return 0; } | > | 779 780 781 782 783 784 785 786 787 788 789 790 791 | sqliteFree(pTriggerStack); sqlite3VdbeResolveLabel(pParse->pVdbe, endTrigger); } pTrigger = pTrigger->pNext; } pParse->cookieMask = cookieMask; return 0; } |
Changes to src/vacuum.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This file contains code used to implement the VACUUM command. ** ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** This file contains code used to implement the VACUUM command. ** ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. ** ** $Id: vacuum.c,v 1.19 2004/05/31 08:26:49 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #if !defined(SQLITE_OMIT_VACUUM) || SQLITE_OMIT_VACUUM /* ** Generate a random name of 20 character in length. |
︙ | ︙ | |||
92 93 94 95 96 97 98 99 100 101 102 | int sqlite3RunVacuum(char **pzErrMsg, sqlite *db){ int rc = SQLITE_OK; /* Return code from service routines */ #if !defined(SQLITE_OMIT_VACUUM) || SQLITE_OMIT_VACUUM const char *zFilename; /* full pathname of the database file */ int nFilename; /* number of characters in zFilename[] */ char *zTemp = 0; /* a temporary file in same directory as zFilename */ int i; /* Loop counter */ char *zSql = 0; sqlite3_stmt *pStmt = 0; | > | | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | int sqlite3RunVacuum(char **pzErrMsg, sqlite *db){ int rc = SQLITE_OK; /* Return code from service routines */ #if !defined(SQLITE_OMIT_VACUUM) || SQLITE_OMIT_VACUUM const char *zFilename; /* full pathname of the database file */ int nFilename; /* number of characters in zFilename[] */ char *zTemp = 0; /* a temporary file in same directory as zFilename */ int i; /* Loop counter */ Btree *pTemp; char *zSql = 0; sqlite3_stmt *pStmt = 0; if( !db->autoCommit ){ sqlite3SetString(pzErrMsg, "cannot VACUUM from within a transaction", (char*)0); rc = SQLITE_ERROR; goto end_of_vacuum; } /* Get the full pathname of the database file and create a |
︙ | ︙ | |||
185 186 187 188 189 190 191 192 | ** transaction open on the vacuum database, but not on the main database. ** Open a btree level transaction on the main database. This allows a ** call to sqlite3BtreeCopyFile(). The main database btree level ** transaction is then committed, so the SQL level never knows it was ** opened for writing. This way, the SQL transaction used to create the ** temporary database never needs to be committed. */ | > > > > < < < < > | | < < < < < < < < < < < < | 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 | ** transaction open on the vacuum database, but not on the main database. ** Open a btree level transaction on the main database. This allows a ** call to sqlite3BtreeCopyFile(). The main database btree level ** transaction is then committed, so the SQL level never knows it was ** opened for writing. This way, the SQL transaction used to create the ** temporary database never needs to be committed. */ pTemp = db->aDb[db->nDb-1].pBt; if( sqlite3BtreeIsInTrans(pTemp) ){ Btree *pMain = db->aDb[0].pBt; u32 meta; assert( 0==sqlite3BtreeIsInTrans(pMain) ); rc = sqlite3BtreeBeginTrans(db->aDb[0].pBt); if( rc!=SQLITE_OK ) goto end_of_vacuum; /* Copy Btree meta values 3 and 4. These correspond to SQL layer meta ** values 2 and 3, the default values of a couple of pragmas. */ rc = sqlite3BtreeGetMeta(pMain, 3, &meta); if( rc!=SQLITE_OK ) goto end_of_vacuum; rc = sqlite3BtreeUpdateMeta(pTemp, 3, meta); if( rc!=SQLITE_OK ) goto end_of_vacuum; rc = sqlite3BtreeGetMeta(pMain, 4, &meta); if( rc!=SQLITE_OK ) goto end_of_vacuum; rc = sqlite3BtreeUpdateMeta(pTemp, 4, meta); if( rc!=SQLITE_OK ) goto end_of_vacuum; rc = sqlite3BtreeCopyFile(pMain, pTemp); rc = sqlite3BtreeCommit(pMain); } end_of_vacuum: execSql(db, "DETACH vacuum_db;"); execSql(db, "ROLLBACK;"); if( zTemp ){ sqlite3OsDelete(zTemp); |
︙ | ︙ |
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.351 2004/05/31 08:26:49 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
2192 2193 2194 2195 2196 2197 2198 | ** ** The statement is begun on the database file with index P1. The main ** database file has an index of 0 and the file used for temporary tables ** has an index of 1. */ case OP_Statement: { int i = pOp->p1; | > | > > | > > > > | > > > > > > > > > > > > > > > > > > > > > > > > | 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 | ** ** The statement is begun on the database file with index P1. The main ** database file has an index of 0 and the file used for temporary tables ** has an index of 1. */ case OP_Statement: { int i = pOp->p1; Btree *pBt; if( i>=0 && i<db->nDb && (pBt = db->aDb[i].pBt) && !(db->autoCommit) ){ assert( sqlite3BtreeIsInTrans(pBt) ); if( !sqlite3BtreeIsInStmt(pBt) ){ rc = sqlite3BtreeBeginStmt(pBt); } } break; } /* Opcode: AutoCommit P1 P2 * ** ** Set the database auto-commit flag to P1 (1 or 0). If P2 is true, roll ** back any currently active btree transactions. */ case OP_AutoCommit: { u8 i = pOp->p1; u8 rollback = pOp->p2; assert( i==1 || i==0 ); assert( i==1 || rollback==0 ); if( i!=db->autoCommit ){ db->autoCommit = i; if( pOp->p2 ){ sqlite3RollbackAll(db); } }else{ sqlite3SetString(&p->zErrMsg, (!i)?"cannot start a transaction within a transaction":( (rollback)?"cannot rollback - no transaction is active": "cannot commit - no transaction is active"), 0); rc = SQLITE_ERROR; } break; } /* Opcode: Transaction P1 * * ** ** Begin a transaction. The transaction ends when a Commit or Rollback |
︙ | ︙ | |||
2218 2219 2220 2221 2222 2223 2224 2225 | ** transaction is underway. Starting a transaction also creates a ** rollback journal. A transaction must be started before any changes ** can be made to the database. */ case OP_Transaction: { int busy = 1; int i = pOp->p1; assert( i>=0 && i<db->nDb ); | > > | | > > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 | ** transaction is underway. Starting a transaction also creates a ** rollback journal. A transaction must be started before any changes ** can be made to the database. */ case OP_Transaction: { int busy = 1; int i = pOp->p1; Btree *pBt; assert( i>=0 && i<db->nDb ); pBt = db->aDb[i].pBt; if( sqlite3BtreeIsInTrans(pBt) ) break; while( pBt && busy /* && !sqlite3BtreeIsInTrans(pBt) */ ){ rc = sqlite3BtreeBeginTrans(db->aDb[i].pBt); switch( rc ){ case SQLITE_BUSY: { if( db->xBusyCallback==0 ){ p->pc = pc; p->rc = SQLITE_BUSY; p->pTos = pTos; return SQLITE_BUSY; }else if( (*db->xBusyCallback)(db->pBusyArg, "", busy++)==0 ){ sqlite3SetString(&p->zErrMsg, sqlite3_error_string(rc), (char*)0); busy = 0; } break; } case SQLITE_READONLY: { rc = SQLITE_OK; /* Fall thru into the next case */ } case SQLITE_OK: { busy = 0; break; } default: { goto abort_due_to_error; } } } break; } /* Opcode: ReadCookie P1 P2 * ** ** Read cookie number P2 from database P1 and push it onto the stack. ** P2==0 is the schema version. P2==1 is the database format. |
︙ | ︙ | |||
3564 3565 3566 3567 3568 3569 3570 | assert( i>=0 && i<p->nCursor ); pTos++; if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ i64 rowid; assert( pC->deferredMoveto==0 ); assert( pC->intKey==0 ); | > > > | | | | | | > | 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 | assert( i>=0 && i<p->nCursor ); pTos++; if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ i64 rowid; assert( pC->deferredMoveto==0 ); assert( pC->intKey==0 ); if( pC->nullRow ){ pTos->flags = MEM_Null; }else{ rc = sqlite3VdbeIdxRowid(pCrsr, &rowid); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } pTos->flags = MEM_Int; pTos->i = rowid; } #if 0 /* Read the final 9 bytes of the key into buf[]. If the whole key is ** less than 9 bytes then just load the whole thing. Set len to the ** number of bytes read. */ sqlite3BtreeKeySize(pCrsr, &sz); |
︙ | ︙ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
303 304 305 306 307 308 309 | Keylist **keylistStack; /* The stack used by opcodes ListPush & ListPop */ 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 */ int errorAction; /* Recovery action to do in case of an error */ | < | 303 304 305 306 307 308 309 310 311 312 313 314 315 316 | Keylist **keylistStack; /* The stack used by opcodes ListPush & ListPop */ 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 */ int errorAction; /* Recovery action to do in case of an error */ int inTempTrans; /* True if temp database is transactioned */ int returnStack[100]; /* Return address stack for OP_Gosub & OP_Return */ int returnDepth; /* Next unused element in returnStack[] */ int nResColumn; /* Number of columns in one row of the result set */ char **azResColumn; /* Values for one row of result */ u8 resOnStack; /* True if there are result values on the stack */ int popStack; /* Pop the stack this much on entry to VdbeExec() */ |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
163 164 165 166 167 168 169 170 171 172 173 174 175 176 | if( p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_MISUSE; } db = p->db; if( sqlite3SafetyOn(db) ){ p->rc = SQLITE_MISUSE; return SQLITE_MISUSE; } if( p->explain ){ rc = sqlite3VdbeList(p); }else{ rc = sqlite3VdbeExec(p); } | > > > > | 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | if( p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_MISUSE; } db = p->db; if( sqlite3SafetyOn(db) ){ p->rc = SQLITE_MISUSE; return SQLITE_MISUSE; } if( p->pc<0 ){ db->activeVdbeCnt++; p->pc = 0; } if( p->explain ){ rc = sqlite3VdbeList(p); }else{ rc = sqlite3VdbeExec(p); } |
︙ | ︙ | |||
374 375 376 377 378 379 380 | ** out of range, then SQLITE_RANGE is returned. Othewise SQLITE_OK. ** ** The error code stored in database p->db is overwritten with the return ** value in any case. */ static int vdbeUnbind(Vdbe *p, int i){ Mem *pVar; | | | 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 | ** out of range, then SQLITE_RANGE is returned. Othewise SQLITE_OK. ** ** The error code stored in database p->db is overwritten with the return ** value in any case. */ static int vdbeUnbind(Vdbe *p, int i){ Mem *pVar; if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){ sqlite3Error(p->db, SQLITE_MISUSE, 0); return SQLITE_MISUSE; } if( i<1 || i>p->nVar ){ sqlite3Error(p->db, SQLITE_RANGE, 0); return SQLITE_RANGE; } |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
655 656 657 658 659 660 661 | p->agg.pSearch = 0; #ifdef MEMORY_DEBUG if( sqlite3OsFileExists("vdbe_trace") ){ p->trace = stdout; } #endif p->pTos = &p->aStack[-1]; | | < | 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 | p->agg.pSearch = 0; #ifdef MEMORY_DEBUG if( sqlite3OsFileExists("vdbe_trace") ){ p->trace = stdout; } #endif p->pTos = &p->aStack[-1]; p->pc = -1; p->rc = SQLITE_OK; p->uniqueCnt = 0; p->returnDepth = 0; p->errorAction = OE_Abort; p->popStack = 0; p->explain |= isExplain; p->magic = VDBE_MAGIC_RUN; #ifdef VDBE_PROFILE { int i; for(i=0; i<p->nOp; i++){ |
︙ | ︙ | |||
892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 | } if( rc==SQLITE_OK && N==P3_DYNAMIC ){ pColName->flags = (pColName->flags&(~MEM_Static))|MEM_Dyn; } return rc; } /* ** Clean up a VDBE after execution but do not delete the VDBE just yet. ** Write any error messages into *pzErrMsg. Return the result code. ** ** After this routine is run, the VDBE should be ready to be executed ** again. */ int sqlite3VdbeReset(Vdbe *p, char **pzErrMsg){ sqlite *db = p->db; int i; if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){ sqlite3SetString(pzErrMsg, sqlite3_error_string(SQLITE_MISUSE), (char*)0); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | | | < | > | | > > > > | | > > > > > > > > | < | < | > > > > | | | | | | < < | > > | < | < | | > > | | < | | | | | 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 | } if( rc==SQLITE_OK && N==P3_DYNAMIC ){ pColName->flags = (pColName->flags&(~MEM_Static))|MEM_Dyn; } return rc; } /* ** This routine checks that the sqlite3.activeVdbeCnt count variable ** matches the number of vdbe's in the list sqlite3.pVdbe that are ** currently active. An assertion fails if the two counts do not match. ** ** This is a no-op if NDEBUG is defined. */ #ifndef NDEBUG static void checkActiveVdbeCnt(sqlite *db){ Vdbe *p; int cnt = 0; p = db->pVdbe; while( p ){ if( (p->magic==VDBE_MAGIC_RUN && p->pc>=0) || p->magic==VDBE_MAGIC_HALT ){ cnt++; } p = p->pNext; } assert( cnt==db->activeVdbeCnt ); } #else #define checkActiveVdbeCnt(x) #endif /* ** Clean up a VDBE after execution but do not delete the VDBE just yet. ** Write any error messages into *pzErrMsg. Return the result code. ** ** After this routine is run, the VDBE should be ready to be executed ** again. */ int sqlite3VdbeReset(Vdbe *p, char **pzErrMsg){ sqlite *db = p->db; int i; int (*xFunc)(Btree *pBt) = 0; /* Function to call on each btree backend */ int needXcommit = 0; if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){ sqlite3SetString(pzErrMsg, sqlite3_error_string(SQLITE_MISUSE), (char*)0); sqlite3Error(p->db, SQLITE_MISUSE, 0 ,0); db->activeVdbeCnt--; return SQLITE_MISUSE; } if( p->zErrMsg ){ sqlite3Error(p->db, p->rc, "%s", p->zErrMsg, 0); if( pzErrMsg && *pzErrMsg==0 ){ *pzErrMsg = p->zErrMsg; }else{ sqliteFree(p->zErrMsg); } p->zErrMsg = 0; }else if( p->rc ){ sqlite3SetString(pzErrMsg, sqlite3_error_string(p->rc), (char*)0); sqlite3Error(p->db, p->rc, 0); }else{ sqlite3Error(p->db, SQLITE_OK, 0); } Cleanup(p); /* Figure out which function to call on the btree backends that ** have active transactions. */ checkActiveVdbeCnt(db); if( db->autoCommit && db->activeVdbeCnt==1 ){ if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){ xFunc = sqlite3BtreeCommit; needXcommit = 1; }else{ xFunc = sqlite3BtreeRollback; } }else{ if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){ xFunc = sqlite3BtreeCommitStmt; }else if( p->errorAction==OE_Abort ){ xFunc = sqlite3BtreeRollbackStmt; }else{ xFunc = sqlite3BtreeRollback; db->autoCommit = 1; } } for(i=0; xFunc && i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( sqlite3BtreeIsInTrans(pBt) ){ int rc; if( db->xCommitCallback && needXcommit ){ if( db->xCommitCallback(db->pCommitArg)!=0 ){ p->rc = SQLITE_CONSTRAINT; sqlite3Error(db, SQLITE_CONSTRAINT, 0); xFunc = sqlite3BtreeRollback; } needXcommit = 0; } rc = xFunc(pBt); if( p->rc==SQLITE_OK ) p->rc = rc; } } if( p->rc!=SQLITE_OK ){ sqlite3RollbackInternalChanges(db); } if( (p->magic==VDBE_MAGIC_RUN && p->pc>=0) || p->magic==VDBE_MAGIC_HALT ){ db->activeVdbeCnt--; } assert( p->pTos<&p->aStack[p->pc<0?0:p->pc] || sqlite3_malloc_failed==1 ); #ifdef VDBE_PROFILE { FILE *out = fopen("vdbe_profile.out", "a"); if( out ){ int i; fprintf(out, "---- "); for(i=0; i<p->nOp; i++){ |
︙ | ︙ |
Changes to test/attach.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is testing the ATTACH and DETACH commands # and related functionality. # | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is testing the ATTACH and DETACH commands # and related functionality. # # $Id: attach.test,v 1.19 2004/05/31 08:26:49 danielk1977 Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl for {set i 2} {$i<=15} {incr i} { file delete -force test$i.db |
︙ | ︙ | |||
343 344 345 346 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 | do_test attach-3.7 { execsql ROLLBACK execsql {SELECT * FROM t2} db2 } {21 x 22 y} do_test attach-3.8 { execsql BEGIN execsql BEGIN db2 catchsql {SELECT * FROM t2} } {1 {database is locked}} do_test attach-3.9 { catchsql {SELECT * FROM t2} db2 } {0 {21 x 22 y}} do_test attach-3.10 { execsql {SELECT * FROM t1} } {1 2 3 4} do_test attach-3.11 { catchsql {UPDATE t1 SET a=a+1} } {0 {}} do_test attach-3.12 { execsql {SELECT * FROM t1} } {2 2 4 4} do_test attach-3.13 { catchsql {UPDATE t2 SET x=x+1 WHERE x=50} } {1 {database is locked}} do_test attach-3.14 { # Unable to reinitialize the schema tables because the aux database # is still locked. catchsql {SELECT * FROM t1} } {1 {database is locked}} do_test attach-3.15 { execsql COMMIT db2 | > > > > > > | 343 344 345 346 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 375 376 377 378 379 | do_test attach-3.7 { execsql ROLLBACK execsql {SELECT * FROM t2} db2 } {21 x 22 y} do_test attach-3.8 { execsql BEGIN execsql BEGIN db2 execsql {UPDATE t2 SET x=0 WHERE 0} db2 catchsql {SELECT * FROM t2} } {1 {database is locked}} do_test attach-3.9 { catchsql {SELECT * FROM t2} db2 } {0 {21 x 22 y}} do_test attach-3.10 { execsql {SELECT * FROM t1} } {1 2 3 4} do_test attach-3.11 { catchsql {UPDATE t1 SET a=a+1} } {0 {}} do_test attach-3.12 { execsql {SELECT * FROM t1} } {2 2 4 4} do_test attach-3.13 { catchsql {UPDATE t2 SET x=x+1 WHERE x=50} } {1 {database is locked}} # Change for version 3. Transaction is no longer rolled back # for a locked database. execsql {ROLLBACK} do_test attach-3.14 { # Unable to reinitialize the schema tables because the aux database # is still locked. catchsql {SELECT * FROM t1} } {1 {database is locked}} do_test attach-3.15 { execsql COMMIT db2 |
︙ | ︙ | |||
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 | SELECT * FROM main.t4; } } {main.11} do_test attach-4.8 { execsql { ATTACH DATABASE 'test2.db' AS db2; INSERT INTO db2.t3 VALUES(13,14); SELECT * FROM db2.t4 UNION ALL SELECT * FROM main.t4; } } {db2.6 db2.13 main.11} do_test attach-4.9 { execsql { INSERT INTO main.t3 VALUES(15,16); SELECT * FROM db2.t4 UNION ALL SELECT * FROM main.t4; } } {db2.6 db2.13 main.11 main.15} do_test attach-4.10 { execsql { DETACH DATABASE db2; | > > | 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 | SELECT * FROM main.t4; } } {main.11} do_test attach-4.8 { execsql { ATTACH DATABASE 'test2.db' AS db2; INSERT INTO db2.t3 VALUES(13,14); pragma vdbe_trace = on; SELECT * FROM db2.t4 UNION ALL SELECT * FROM main.t4; } } {db2.6 db2.13 main.11} do_test attach-4.9 { execsql { pragma vdbe_trace = off; INSERT INTO main.t3 VALUES(15,16); SELECT * FROM db2.t4 UNION ALL SELECT * FROM main.t4; } } {db2.6 db2.13 main.11 main.15} do_test attach-4.10 { execsql { DETACH DATABASE db2; |
︙ | ︙ |
Changes to test/attach2.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is testing the ATTACH and DETACH commands # and related functionality. # | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is testing the ATTACH and DETACH commands # and related functionality. # # $Id: attach2.test,v 1.10 2004/05/31 08:26:49 danielk1977 Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl # Ticket #354 |
︙ | ︙ | |||
47 48 49 50 51 52 53 54 55 56 57 58 59 60 | } return $list } db eval {DETACH t2} do_test attach2-2.1 { # lock test2.db then try to attach it. Should get an error. db2 eval {BEGIN} catchsql { ATTACH 'test2.db' AS t2; } } {1 {database is locked}} do_test attach2-2.2 { # make sure test2.db did not get attached. db_list db | > | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | } return $list } db eval {DETACH t2} do_test attach2-2.1 { # lock test2.db then try to attach it. Should get an error. db2 eval {BEGIN} db2 eval {UPDATE t1 SET a = 0 WHERE 0} catchsql { ATTACH 'test2.db' AS t2; } } {1 {database is locked}} do_test attach2-2.2 { # make sure test2.db did not get attached. db_list db |
︙ | ︙ | |||
73 74 75 76 77 78 79 80 81 82 83 84 85 86 | catchsql { SELECT name FROM t2.sqlite_master; } } {0 {t1 x1}} do_test attach2-2.6 { # lock test2.db and try to read from it. should get an error. db2 eval BEGIN catchsql { SELECT name FROM t2.sqlite_master; } } {1 {database is locked}} do_test attach2-2.7 { # but we can still read from test1.db even though test2.db is locked. catchsql { | > | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | catchsql { SELECT name FROM t2.sqlite_master; } } {0 {t1 x1}} do_test attach2-2.6 { # lock test2.db and try to read from it. should get an error. db2 eval BEGIN db2 eval {UPDATE t1 SET a = 0 WHERE 0} catchsql { SELECT name FROM t2.sqlite_master; } } {1 {database is locked}} do_test attach2-2.7 { # but we can still read from test1.db even though test2.db is locked. catchsql { |
︙ | ︙ | |||
104 105 106 107 108 109 110 111 112 113 114 115 116 117 | catchsql { INSERT INTO t2.t1 VALUES(1,2); } } {1 {database is locked}} do_test attach2-2.11 { # when the write failed in the previous test, the transaction should # have rolled back. db2 eval ROLLBACK execsql { SELECT * FROM t1 } } {} do_test attach2-2.12 { catchsql { | > > > > | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | catchsql { INSERT INTO t2.t1 VALUES(1,2); } } {1 {database is locked}} do_test attach2-2.11 { # when the write failed in the previous test, the transaction should # have rolled back. # # Update for version 3: A transaction is no longer rolled back if a # database is found to be busy. execsql {rollback} db2 eval ROLLBACK execsql { SELECT * FROM t1 } } {} do_test attach2-2.12 { catchsql { |
︙ | ︙ |
Changes to test/conflict.test.
︙ | ︙ | |||
9 10 11 12 13 14 15 | # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests for the conflict resolution extension # to SQLite. # | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests for the conflict resolution extension # to SQLite. # # $Id: conflict.test,v 1.20 2004/05/31 08:26:49 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Create tables for the first group of tests. # do_test conflict-1.0 { |
︙ | ︙ | |||
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | 13 IGNORE {INSERT OR ABORT} 1 {} 1 14 IGNORE {INSERT OR ROLLBACK} 1 {} {} 15 REPLACE INSERT 0 4 1 16 FAIL INSERT 1 {} 1 17 ABORT INSERT 1 {} 1 18 ROLLBACK INSERT 1 {} {} } { do_test conflict-1.$i { if {$conf!=""} {set conf "ON CONFLICT $conf"} set r0 [catch {execsql [subst { DELETE FROM t1; DELETE FROM t2; INSERT INTO t1 VALUES(1,2,3); BEGIN $conf; INSERT INTO t2 VALUES(1); $cmd INTO t1 VALUES(1,2,4); }]} r1] catch {execsql {COMMIT}} if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]} set r2 [execsql {SELECT x FROM t2}] list $r0 $r1 $r2 } [list $t0 $t1 $t2] } # Create tables for the first group of tests. # do_test conflict-2.0 { execsql { DROP TABLE t1; | > > > > | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | 13 IGNORE {INSERT OR ABORT} 1 {} 1 14 IGNORE {INSERT OR ROLLBACK} 1 {} {} 15 REPLACE INSERT 0 4 1 16 FAIL INSERT 1 {} 1 17 ABORT INSERT 1 {} 1 18 ROLLBACK INSERT 1 {} {} } { if { $conf=={} } { do_test conflict-1.$i { if {$conf!=""} {set conf "ON CONFLICT $conf"} set r0 [catch {execsql [subst { DELETE FROM t1; DELETE FROM t2; INSERT INTO t1 VALUES(1,2,3); BEGIN $conf; INSERT INTO t2 VALUES(1); $cmd INTO t1 VALUES(1,2,4); }]} r1] catch {execsql {COMMIT}} if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]} set r2 [execsql {SELECT x FROM t2}] list $r0 $r1 $r2 } [list $t0 $t1 $t2] } } # Create tables for the first group of tests. # do_test conflict-2.0 { execsql { DROP TABLE t1; |
︙ | ︙ |
Changes to test/hook.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 | # This file implements regression tests for TCL interface to the # SQLite library. # # The focus of the tests in this file is the following interface: # # sqlite_commit_hook # | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # This file implements regression tests for TCL interface to the # SQLite library. # # The focus of the tests in this file is the following interface: # # sqlite_commit_hook # # $Id: hook.test,v 1.4 2004/05/31 08:26:49 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl do_test hook-1.2 { db commit_hook } {} |
︙ | ︙ | |||
61 62 63 64 65 66 67 | INSERT INTO t2 VALUES(5,6); } set commit_cnt } {1 2 2 3 3 4 4 5 5 6} do_test hook-3.6 { set commit_cnt {} proc commit_hook {} { | | | | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | INSERT INTO t2 VALUES(5,6); } set commit_cnt } {1 2 2 3 3 4 4 5 5 6} do_test hook-3.6 { set commit_cnt {} proc commit_hook {} { set ::commit_cnt [execsql {SELECT * FROM t2}] return 1 } catchsql { INSERT INTO t2 VALUES(6,7); } } {1 {constraint failed}} do_test hook-3.7 { set ::commit_cnt } {1 2 2 3 3 4 4 5 5 6 6 7} do_test hook-3.8 { execsql {SELECT * FROM t2} } {1 2 2 3 3 4 4 5 5 6} finish_test |
Changes to test/lock.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2001 September 15 # # 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 implements regression tests for SQLite library. The # focus of this script is database locks. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2001 September 15 # # 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 implements regression tests for SQLite library. The # focus of this script is database locks. # # $Id: lock.test,v 1.21 2004/05/31 08:26:49 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Create an alternative connection to the database # |
︙ | ︙ | |||
56 57 58 59 60 61 62 63 64 65 66 67 68 69 | execsql {SELECT * FROM t1} db2 } {2 1} do_test lock-1.9 { execsql {SELECT * FROM t1} } {2 1} do_test lock-1.10 { execsql {BEGIN TRANSACTION} execsql {SELECT * FROM t1} } {2 1} do_test lock-1.11 { catchsql {SELECT * FROM t1} db2 } {1 {database is locked}} do_test lock-1.12 { execsql {ROLLBACK} | > | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | execsql {SELECT * FROM t1} db2 } {2 1} do_test lock-1.9 { execsql {SELECT * FROM t1} } {2 1} do_test lock-1.10 { execsql {BEGIN TRANSACTION} execsql {UPDATE t1 SET a = 0 WHERE 0} execsql {SELECT * FROM t1} } {2 1} do_test lock-1.11 { catchsql {SELECT * FROM t1} db2 } {1 {database is locked}} do_test lock-1.12 { execsql {ROLLBACK} |
︙ | ︙ | |||
151 152 153 154 155 156 157 | integrity_check lock-1.23 # If one thread has a transaction another thread cannot start # a transaction. # do_test lock-2.1 { execsql {BEGIN TRANSACTION} | > | > > | 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | integrity_check lock-1.23 # If one thread has a transaction another thread cannot start # a transaction. # do_test lock-2.1 { execsql {BEGIN TRANSACTION} execsql {UPDATE t1 SET a = 0 WHERE 0} execsql {BEGIN TRANSACTION} db2 set r [catch {execsql {UPDATE t1 SET a = 0 WHERE 0} db2} msg] execsql {ROLLBACK} db2 lappend r $msg } {1 {database is locked}} # Nor can the other thread do a query. # do_test lock-2.2 { set r [catch {execsql {SELECT * FROM t2} db2} msg] |
︙ | ︙ | |||
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | db2 busy callback set r [catch {execsql {SELECT * FROM t2} db2} msg] lappend r $msg lappend r $::callback_value } {0 {9 8} {1 2 3}} do_test lock-2.7 { execsql {BEGIN TRANSACTION} proc callback {file count} { lappend ::callback_value $count if {$count>2} { execsql {ROLLBACK} } } set ::callback_value {} db2 busy callback | > | > > > | 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 254 255 256 257 258 259 | db2 busy callback set r [catch {execsql {SELECT * FROM t2} db2} msg] lappend r $msg lappend r $::callback_value } {0 {9 8} {1 2 3}} do_test lock-2.7 { execsql {BEGIN TRANSACTION} execsql {UPDATE t1 SET a = 0 WHERE 0} proc callback {file count} { lappend ::callback_value $count if {$count>2} { execsql {ROLLBACK} } } set ::callback_value {} db2 busy callback execsql {BEGIN TRANSACTION} db2 set r [catch {execsql {UPDATE t1 SET a = 0 WHERE 0} db2} msg] execsql {ROLLBACK} db2 lappend r $msg lappend r $::callback_value } {0 {} {1 2 3}} # Test the built-in busy timeout handler # do_test lock-2.8 { db2 timeout 400 execsql BEGIN execsql {UPDATE t1 SET a = 0 WHERE 0} catchsql BEGIN db2 catchsql {UPDATE t1 SET a = 0 WHERE 0} db2 } {1 {database is locked}} do_test lock-2.9 { db2 timeout 0 execsql COMMIT } {} integrity_check lock-2.10 |
︙ | ︙ | |||
263 264 265 266 267 268 269 270 271 272 273 274 275 276 | # opening a new pointer to the database while another pointer # has the database locked. # do_test lock-4.1 { db2 close catch {db eval ROLLBACK} db eval BEGIN sqlite db2 ./test.db set rc [catch {db2 eval {SELECT * FROM t1}} msg] lappend rc $msg } {1 {database is locked}} do_test lock-4.2 { set ::callback_value {} set rc [catch {db2 eval {SELECT * FROM t1}} msg] | > | 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | # opening a new pointer to the database while another pointer # has the database locked. # do_test lock-4.1 { db2 close catch {db eval ROLLBACK} db eval BEGIN db eval {UPDATE t1 SET a=0 WHERE 0} sqlite db2 ./test.db set rc [catch {db2 eval {SELECT * FROM t1}} msg] lappend rc $msg } {1 {database is locked}} do_test lock-4.2 { set ::callback_value {} set rc [catch {db2 eval {SELECT * FROM t1}} msg] |
︙ | ︙ |
Changes to test/misc1.test.
︙ | ︙ | |||
9 10 11 12 13 14 15 | # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests for miscellanous features that were # left out of other test files. # | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests for miscellanous features that were # left out of other test files. # # $Id: misc1.test,v 1.25 2004/05/31 08:26:49 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Test the creation and use of tables that have a large number # of columns. # |
︙ | ︙ | |||
308 309 310 311 312 313 314 315 316 317 318 319 320 321 | } {102} # Make sure the initialization works even if a database is opened while # another process has the database locked. # do_test misc1-11.1 { execsql {BEGIN} sqlite db2 test.db set rc [catch {db2 eval {SELECT count(*) FROM t1}} msg] lappend rc $msg } {1 {database is locked}} do_test misc1-11.2 { execsql {COMMIT} set rc [catch {db2 eval {SELECT count(*) FROM t1}} msg] | > | 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 | } {102} # Make sure the initialization works even if a database is opened while # another process has the database locked. # do_test misc1-11.1 { execsql {BEGIN} execsql {UPDATE t1 SET a=0 WHERE 0} sqlite db2 test.db set rc [catch {db2 eval {SELECT count(*) FROM t1}} msg] lappend rc $msg } {1 {database is locked}} do_test misc1-11.2 { execsql {COMMIT} set rc [catch {db2 eval {SELECT count(*) FROM t1}} msg] |
︙ | ︙ | |||
450 451 452 453 454 455 456 457 458 459 460 461 462 463 | do_test misc1-14.1 { file mkdir tempdir cd tempdir execsql {BEGIN} file exists ./test.db-journal } {0} do_test misc1-14.2 { file exists ../test.db-journal } {1} do_test misc1-14.3 { cd .. file delete tempdir execsql {COMMIT} file exists ./test.db-journal | > | 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 | do_test misc1-14.1 { file mkdir tempdir cd tempdir execsql {BEGIN} file exists ./test.db-journal } {0} do_test misc1-14.2 { execsql {UPDATE t1 SET a=0 WHERE 0} file exists ../test.db-journal } {1} do_test misc1-14.3 { cd .. file delete tempdir execsql {COMMIT} file exists ./test.db-journal |
︙ | ︙ |
Changes to test/progress.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2001 September 15 # # 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 implements regression tests for SQLite library. The # focus of this file is testing the 'progress callback'. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2001 September 15 # # 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 implements regression tests for SQLite library. The # focus of this file is testing the 'progress callback'. # # $Id: progress.test,v 1.2 2004/05/31 08:26:50 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Build some test data # execsql { |
︙ | ︙ | |||
45 46 47 48 49 50 51 | expr $counter > 1 } 1 # Test that the query is abandoned when the progress callback returns non-zero do_test progress1.1 { set counter 0 db progress 1 "[namespace code {incr counter}] ; expr 1" | | | | | | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | expr $counter > 1 } 1 # Test that the query is abandoned when the progress callback returns non-zero do_test progress1.1 { set counter 0 db progress 1 "[namespace code {incr counter}] ; expr 1" set rc [catch {execsql { SELECT * FROM t1 }}] list $counter $rc } {1 1} # Test that the query is rolled back when the progress callback returns # non-zero. do_test progress1.2 { # This figures out how many opcodes it takes to copy 5 extra rows into t1. db progress 1 "[namespace code {incr five_rows}] ; expr 0" |
︙ | ︙ | |||
71 72 73 74 75 76 77 | } # Now set up the progress callback to abandon the query after the number of # opcodes to copy 5 rows. That way, when we try to copy 6 rows, we know # some data will have been inserted into the table by the time the progress # callback abandons the query. db progress $five_rows "expr 1" | | | | | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | } # Now set up the progress callback to abandon the query after the number of # opcodes to copy 5 rows. That way, when we try to copy 6 rows, we know # some data will have been inserted into the table by the time the progress # callback abandons the query. db progress $five_rows "expr 1" catchsql { INSERT INTO t1 SELECT a+10 FROM t1 WHERE a < 9 } execsql { SELECT count(*) FROM t1 } } 10 # Test that an active transaction remains active and not rolled back after the # progress query abandons a query. do_test progress1.3 { db progress 0 "" execsql BEGIN execsql { INSERT INTO t1 VALUES(11) } db progress 1 "expr 1" catchsql { INSERT INTO t1 VALUES(12) } db progress 0 "" execsql COMMIT execsql { SELECT count(*) FROM t1 } |
︙ | ︙ |
Changes to test/trans.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2001 September 15 # # 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 implements regression tests for SQLite library. The # focus of this script is database locks. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2001 September 15 # # 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 implements regression tests for SQLite library. The # focus of this script is database locks. # # $Id: trans.test,v 1.20 2004/05/31 08:26:50 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Create several tables to work with. |
︙ | ︙ | |||
84 85 86 87 88 89 90 91 92 93 94 95 96 97 | integrity_check trans-2.11 # Check the locking behavior # do_test trans-3.1 { execsql { BEGIN; SELECT a FROM one ORDER BY a; } } {1 2 3} do_test trans-3.2 { set v [catch {execsql { SELECT a FROM two ORDER BY a; } altdb} msg] | > | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | integrity_check trans-2.11 # Check the locking behavior # do_test trans-3.1 { execsql { BEGIN; UPDATE one SET a = 0 WHERE 0; SELECT a FROM one ORDER BY a; } } {1 2 3} do_test trans-3.2 { set v [catch {execsql { SELECT a FROM two ORDER BY a; } altdb} msg] |
︙ | ︙ | |||
179 180 181 182 183 184 185 186 187 188 189 190 191 192 | ROLLBACK; } db} msg] lappend v $msg } {1 {cannot rollback - no transaction is active}} do_test trans-4.3 { set v [catch {execsql { BEGIN TRANSACTION; SELECT a FROM two ORDER BY a; } db} msg] lappend v $msg } {0 {1 4 5 10}} do_test trans-4.4 { set v [catch {execsql { SELECT a FROM two ORDER BY a; | > | 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | ROLLBACK; } db} msg] lappend v $msg } {1 {cannot rollback - no transaction is active}} do_test trans-4.3 { set v [catch {execsql { BEGIN TRANSACTION; UPDATE two SET a = 0 WHERE 0; SELECT a FROM two ORDER BY a; } db} msg] lappend v $msg } {0 {1 4 5 10}} do_test trans-4.4 { set v [catch {execsql { SELECT a FROM two ORDER BY a; |
︙ | ︙ |