Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | More work toward getting sqlite3_interrupt() to work from separate threads. Ticket #1897. (CVS 3336) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
e431131d47481f9fc64c498e8934b10a |
User & Date: | drh 2006-07-26 13:43:31.000 |
Context
2006-07-26
| ||
14:49 | Add a test case to trigger an assertion fault when running sqlite3_prepare16() with a predefined string size. (CVS 3337) (check-in: 93878e6ebf user: drh tags: trunk) | |
13:43 | More work toward getting sqlite3_interrupt() to work from separate threads. Ticket #1897. (CVS 3336) (check-in: e431131d47 user: drh tags: trunk) | |
01:39 | Initial attempt at making sqlite3_interrupt() work even when called from a separate thread. (CVS 3335) (check-in: 35fd67d7a0 user: drh tags: trunk) | |
Changes
Changes to src/prepare.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. ** | | > | 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 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. ** ** $Id: prepare.c,v 1.37 2006/07/26 13:43:31 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** Fill the InitData structure with an error message that indicates ** that the database is corrupt. */ static void corruptSchema(InitData *pData, const char *zExtra){ if( !sqlite3MallocFailed() ){ sqlite3SetString(pData->pzErrMsg, "malformed database schema", zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0); } pData->rc = SQLITE_CORRUPT; } /* ** This is the callback routine for the code that initializes the ** database. See sqlite3Init() below for additional information. ** This routine is also called from the OP_ParseSchema opcode of the VDBE. ** |
︙ | ︙ | |||
45 46 47 48 49 50 51 52 53 54 55 56 57 58 | ** */ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){ InitData *pData = (InitData*)pInit; sqlite3 *db = pData->db; int iDb; if( sqlite3MallocFailed() ){ return SQLITE_NOMEM; } assert( argc==4 ); if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ if( argv[1]==0 || argv[3]==0 ){ | > | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | ** */ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){ InitData *pData = (InitData*)pInit; sqlite3 *db = pData->db; int iDb; pData->rc = SQLITE_OK; if( sqlite3MallocFailed() ){ return SQLITE_NOMEM; } assert( argc==4 ); if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ if( argv[1]==0 || argv[3]==0 ){ |
︙ | ︙ | |||
72 73 74 75 76 77 78 79 80 | assert( db->init.busy ); db->init.iDb = iDb; db->init.newTnum = atoi(argv[1]); rc = sqlite3_exec(db, argv[2], 0, 0, &zErr); db->init.iDb = 0; assert( rc!=SQLITE_OK || zErr==0 ); if( SQLITE_OK!=rc ){ if( rc==SQLITE_NOMEM ){ sqlite3FailedMalloc(); | > | | | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | assert( db->init.busy ); db->init.iDb = iDb; db->init.newTnum = atoi(argv[1]); rc = sqlite3_exec(db, argv[2], 0, 0, &zErr); db->init.iDb = 0; assert( rc!=SQLITE_OK || zErr==0 ); if( SQLITE_OK!=rc ){ pData->rc = rc; if( rc==SQLITE_NOMEM ){ sqlite3FailedMalloc(); }else if( rc!=SQLITE_INTERRUPT ){ corruptSchema(pData, zErr); } sqlite3_free(zErr); return 1; } }else{ /* If the SQL column is blank it means this is an index that ** was created to be the PRIMARY KEY or to fulfill a UNIQUE ** constraint for a CREATE TABLE. The index should have already ** been created when we processed the CREATE TABLE. All we have ** to do here is record the root page number for that index. |
︙ | ︙ | |||
175 176 177 178 179 180 181 | azArg[2] = zMasterSchema; sprintf(zDbNum, "%d", iDb); azArg[3] = zDbNum; azArg[4] = 0; initData.db = db; initData.pzErrMsg = pzErrMsg; rc = sqlite3InitCallback(&initData, 4, (char **)azArg, 0); | | | | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | azArg[2] = zMasterSchema; sprintf(zDbNum, "%d", iDb); azArg[3] = zDbNum; azArg[4] = 0; initData.db = db; initData.pzErrMsg = pzErrMsg; rc = sqlite3InitCallback(&initData, 4, (char **)azArg, 0); if( rc ){ sqlite3SafetyOn(db); return initData.rc; } pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName); if( pTab ){ pTab->readOnly = 1; } sqlite3SafetyOn(db); |
︙ | ︙ | |||
291 292 293 294 295 296 297 298 299 300 301 302 303 304 | }else{ char *zSql; zSql = sqlite3MPrintf( "SELECT name, rootpage, sql, '%s' FROM '%q'.%s", zDbNum, db->aDb[iDb].zName, zMasterName); sqlite3SafetyOff(db); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); sqlite3SafetyOn(db); sqliteFree(zSql); #ifndef SQLITE_OMIT_ANALYZE if( rc==SQLITE_OK ){ sqlite3AnalysisLoad(db, iDb); } #endif | > | 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | }else{ char *zSql; zSql = sqlite3MPrintf( "SELECT name, rootpage, sql, '%s' FROM '%q'.%s", zDbNum, db->aDb[iDb].zName, zMasterName); sqlite3SafetyOff(db); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); if( rc==SQLITE_ABORT ) rc = initData.rc; sqlite3SafetyOn(db); sqliteFree(zSql); #ifndef SQLITE_OMIT_ANALYZE if( rc==SQLITE_OK ){ sqlite3AnalysisLoad(db, iDb); } #endif |
︙ | ︙ |
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.523 2006/07/26 13:43:31 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** Extra interface definitions for those who need them */ |
︙ | ︙ | |||
1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 | /* ** A pointer to this structure is used to communicate information ** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback. */ typedef struct { sqlite3 *db; /* The database being initialized */ char **pzErrMsg; /* Error message stored here */ } InitData; /* * This global flag is set for performance testing of triggers. When it is set * SQLite will perform the overhead of building new and old trigger references * even when no triggers exist */ | > | 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 | /* ** A pointer to this structure is used to communicate information ** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback. */ typedef struct { sqlite3 *db; /* The database being initialized */ char **pzErrMsg; /* Error message stored here */ int rc; /* Result code stored here */ } InitData; /* * This global flag is set for performance testing of triggers. When it is set * SQLite will perform the overhead of building new and old trigger references * even when no triggers exist */ |
︙ | ︙ |
Changes to src/tokenize.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** An tokenizer for SQL ** ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** An tokenizer for SQL ** ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** ** $Id: tokenize.c,v 1.123 2006/07/26 13:43:31 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include <stdlib.h> /* |
︙ | ︙ | |||
390 391 392 393 394 395 396 | int tokenType; int lastTokenParsed = -1; sqlite3 *db = pParse->db; extern void *sqlite3ParserAlloc(void*(*)(int)); extern void sqlite3ParserFree(void*, void(*)(void*)); extern int sqlite3Parser(void*, int, Token, Parse*); | > | > | 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 | int tokenType; int lastTokenParsed = -1; sqlite3 *db = pParse->db; extern void *sqlite3ParserAlloc(void*(*)(int)); extern void sqlite3ParserFree(void*, void(*)(void*)); extern int sqlite3Parser(void*, int, Token, Parse*); if( db->activeVdbeCnt==0 ){ db->u1.isInterrupted = 0; } pParse->rc = SQLITE_OK; i = 0; pEngine = sqlite3ParserAlloc((void*(*)(int))sqlite3MallocX); if( pEngine==0 ){ return SQLITE_NOMEM; } assert( pParse->sLastToken.dyn==0 ); |
︙ | ︙ |
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.572 2006/07/26 13:43:31 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 | pOp->p1, db->aDb[iDb].zName, zMaster, pOp->p3); if( zSql==0 ) goto no_mem; sqlite3SafetyOff(db); assert( db->init.busy==0 ); db->init.busy = 1; assert( !sqlite3MallocFailed() ); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); sqliteFree(zSql); db->init.busy = 0; sqlite3SafetyOn(db); if( rc==SQLITE_NOMEM ){ sqlite3FailedMalloc(); goto no_mem; } | > | 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 | pOp->p1, db->aDb[iDb].zName, zMaster, pOp->p3); if( zSql==0 ) goto no_mem; sqlite3SafetyOff(db); assert( db->init.busy==0 ); db->init.busy = 1; assert( !sqlite3MallocFailed() ); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); if( rc==SQLITE_ABORT ) rc = initData.rc; sqliteFree(zSql); db->init.busy = 0; sqlite3SafetyOn(db); if( rc==SQLITE_NOMEM ){ sqlite3FailedMalloc(); goto no_mem; } |
︙ | ︙ | |||
4967 4968 4969 4970 4971 4972 4973 | goto vdbe_halt; /* Jump to here if the sqlite3_interrupt() API sets the interrupt ** flag. */ abort_due_to_interrupt: assert( db->u1.isInterrupted ); | < | 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 | goto vdbe_halt; /* Jump to here if the sqlite3_interrupt() API sets the interrupt ** flag. */ abort_due_to_interrupt: assert( db->u1.isInterrupted ); if( db->magic!=SQLITE_MAGIC_BUSY ){ rc = SQLITE_MISUSE; }else{ rc = SQLITE_INTERRUPT; } p->rc = rc; sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0); goto vdbe_halt; } |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
176 177 178 179 180 181 182 183 184 185 186 187 188 189 | } db = p->db; if( sqlite3SafetyOn(db) ){ p->rc = SQLITE_MISUSE; return SQLITE_MISUSE; } if( p->pc<0 ){ #ifndef SQLITE_OMIT_TRACE /* Invoke the trace callback if there is one */ if( db->xTrace && !db->init.busy ){ assert( p->nOp>0 ); assert( p->aOp[p->nOp-1].opcode==OP_Noop ); assert( p->aOp[p->nOp-1].p3!=0 ); | > > > > > > > > | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | } db = p->db; if( sqlite3SafetyOn(db) ){ p->rc = SQLITE_MISUSE; return SQLITE_MISUSE; } if( p->pc<0 ){ /* If there are no other statements currently running, then ** reset the interrupt flag. This prevents a call to sqlite3_interrupt ** from interrupting a statement that has not yet started. */ if( db->activeVdbeCnt==0 ){ db->u1.isInterrupted = 0; } #ifndef SQLITE_OMIT_TRACE /* Invoke the trace callback if there is one */ if( db->xTrace && !db->init.busy ){ assert( p->nOp>0 ); assert( p->aOp[p->nOp-1].opcode==OP_Noop ); assert( p->aOp[p->nOp-1].p3!=0 ); |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
667 668 669 670 671 672 673 | do{ i = p->pc++; }while( i<p->nOp && p->explain==2 && p->aOp[i].opcode!=OP_Explain ); if( i>=p->nOp ){ p->rc = SQLITE_OK; rc = SQLITE_DONE; }else if( db->u1.isInterrupted ){ | < | 667 668 669 670 671 672 673 674 675 676 677 678 679 680 | do{ i = p->pc++; }while( i<p->nOp && p->explain==2 && p->aOp[i].opcode!=OP_Explain ); if( i>=p->nOp ){ p->rc = SQLITE_OK; rc = SQLITE_DONE; }else if( db->u1.isInterrupted ){ p->rc = SQLITE_INTERRUPT; rc = SQLITE_ERROR; sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(p->rc), (char*)0); }else{ Op *pOp = &p->aOp[i]; Mem *pMem = p->aStack; pMem->flags = MEM_Int; |
︙ | ︙ |