diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/analyze.c | 2 | ||||
-rw-r--r-- | src/btree.c | 55 | ||||
-rw-r--r-- | src/build.c | 19 | ||||
-rw-r--r-- | src/expr.c | 9 | ||||
-rw-r--r-- | src/func.c | 8 | ||||
-rw-r--r-- | src/main.c | 21 | ||||
-rw-r--r-- | src/os_unix.c | 19 | ||||
-rw-r--r-- | src/os_win.c | 22 | ||||
-rw-r--r-- | src/pager.c | 42 | ||||
-rw-r--r-- | src/parse.y | 2 | ||||
-rw-r--r-- | src/pcache1.c | 2 | ||||
-rw-r--r-- | src/pragma.c | 18 | ||||
-rw-r--r-- | src/printf.c | 6 | ||||
-rw-r--r-- | src/resolve.c | 2 | ||||
-rw-r--r-- | src/select.c | 6 | ||||
-rw-r--r-- | src/shell.c | 92 | ||||
-rw-r--r-- | src/sqlite.h.in | 10 | ||||
-rw-r--r-- | src/sqliteInt.h | 21 | ||||
-rw-r--r-- | src/tclsqlite.c | 23 | ||||
-rw-r--r-- | src/test1.c | 31 | ||||
-rw-r--r-- | src/test_syscall.c | 2 | ||||
-rw-r--r-- | src/trigger.c | 2 | ||||
-rw-r--r-- | src/vdbe.c | 4 | ||||
-rw-r--r-- | src/vdbeapi.c | 7 | ||||
-rw-r--r-- | src/vdbeaux.c | 2 | ||||
-rw-r--r-- | src/vdbesort.c | 2 | ||||
-rw-r--r-- | src/vdbetrace.c | 8 |
27 files changed, 257 insertions, 180 deletions
diff --git a/src/analyze.c b/src/analyze.c index 9a3e9597d..78bbf28b4 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -25,7 +25,7 @@ ** The sqlite_stat2 table is not created or used unless the SQLite version ** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled ** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated. -** The sqlite_stat2 table is superceded by sqlite_stat3, which is only +** The sqlite_stat2 table is superseded by sqlite_stat3, which is only ** created and used by SQLite versions 3.7.9 and later and with ** SQLITE_ENABLE_STAT3 defined. The fucntionality of sqlite_stat3 ** is a superset of sqlite_stat2. diff --git a/src/btree.c b/src/btree.c index 616d40368..f6e564628 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1215,7 +1215,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ }else if( gap+2<=top ){ /* Search the freelist looking for a free slot big enough to satisfy ** the request. The allocation is made from the first free slot in - ** the list that is large enough to accomadate it. + ** the list that is large enough to accommodate it. */ int pc, addr; for(addr=hdr+1; (pc = get2byte(&data[addr]))>0; addr=pc){ @@ -2517,6 +2517,29 @@ page1_init_failed: return rc; } +#ifndef NDEBUG +/* +** Return the number of cursors open on pBt. This is for use +** in assert() expressions, so it is only compiled if NDEBUG is not +** defined. +** +** Only write cursors are counted if wrOnly is true. If wrOnly is +** false then all cursors are counted. +** +** For the purposes of this routine, a cursor is any cursor that +** is capable of reading or writing to the databse. Cursors that +** have been tripped into the CURSOR_FAULT state are not counted. +*/ +static int countValidCursors(BtShared *pBt, int wrOnly){ + BtCursor *pCur; + int r = 0; + for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ + if( (wrOnly==0 || pCur->wrFlag) && pCur->eState!=CURSOR_FAULT ) r++; + } + return r; +} +#endif + /* ** If there are no outstanding cursors and we are not in the middle ** of a transaction but there is a read lock on the database, then @@ -2527,7 +2550,7 @@ page1_init_failed: */ static void unlockBtreeIfUnused(BtShared *pBt){ assert( sqlite3_mutex_held(pBt->mutex) ); - assert( pBt->pCursor==0 || pBt->inTransaction>TRANS_NONE ); + assert( countValidCursors(pBt,0)==0 || pBt->inTransaction>TRANS_NONE ); if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){ assert( pBt->pPage1->aData ); assert( sqlite3PagerRefcount(pBt->pPager)==1 ); @@ -3135,7 +3158,7 @@ int sqlite3BtreeIncrVacuum(Btree *p){ /* ** This routine is called prior to sqlite3PagerCommit when a transaction -** is commited for an auto-vacuum database. +** is committed for an auto-vacuum database. ** ** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages ** the database file should be truncated to during the commit process. @@ -3255,7 +3278,6 @@ static void btreeEndTransaction(Btree *p){ #ifndef SQLITE_OMIT_AUTOVACUUM pBt->bDoTruncate = 0; #endif - btreeClearHasContent(pBt); if( p->inTrans>TRANS_NONE && p->db->activeVdbeCnt>1 ){ /* If there are other active statements that belong to this database ** handle, downgrade to a read-only transaction. The other statements @@ -3330,6 +3352,7 @@ int sqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup){ return rc; } pBt->inTransaction = TRANS_READ; + btreeClearHasContent(pBt); } btreeEndTransaction(p); @@ -3351,27 +3374,6 @@ int sqlite3BtreeCommit(Btree *p){ return rc; } -#ifndef NDEBUG -/* -** Return the number of write-cursors open on this handle. This is for use -** in assert() expressions, so it is only compiled if NDEBUG is not -** defined. -** -** For the purposes of this routine, a write-cursor is any cursor that -** is capable of writing to the databse. That means the cursor was -** originally opened for writing and the cursor has not be disabled -** by having its state changed to CURSOR_FAULT. -*/ -static int countWriteCursors(BtShared *pBt){ - BtCursor *pCur; - int r = 0; - for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ - if( pCur->wrFlag && pCur->eState!=CURSOR_FAULT ) r++; - } - return r; -} -#endif - /* ** This routine sets the state to CURSOR_FAULT and the error ** code to errCode for every cursor on BtShared that pBtree @@ -3451,8 +3453,9 @@ int sqlite3BtreeRollback(Btree *p, int tripCode){ pBt->nPage = nPage; releasePage(pPage1); } - assert( countWriteCursors(pBt)==0 ); + assert( countValidCursors(pBt, 1)==0 ); pBt->inTransaction = TRANS_READ; + btreeClearHasContent(pBt); } btreeEndTransaction(p); diff --git a/src/build.c b/src/build.c index 5920ade05..067b72f7d 100644 --- a/src/build.c +++ b/src/build.c @@ -1276,6 +1276,7 @@ void sqlite3AddCollateType(Parse *pParse, Token *pToken){ if( sqlite3LocateCollSeq(pParse, zColl) ){ Index *pIdx; + sqlite3DbFree(db, p->aCol[i].zColl); p->aCol[i].zColl = zColl; /* If the column is declared as "<name> PRIMARY KEY COLLATE <type>", @@ -2659,10 +2660,8 @@ Index *sqlite3CreateIndex( for(i=0; i<pList->nExpr; i++){ Expr *pExpr = pList->a[i].pExpr; if( pExpr ){ - CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr); - if( pColl ){ - nExtra += (1 + sqlite3Strlen30(pColl->zName)); - } + assert( pExpr->op==TK_COLLATE ); + nExtra += (1 + sqlite3Strlen30(pExpr->u.zToken)); } } @@ -2723,7 +2722,6 @@ Index *sqlite3CreateIndex( const char *zColName = pListItem->zName; Column *pTabCol; int requestedSortOrder; - CollSeq *pColl; /* Collating sequence */ char *zColl; /* Collation sequence name */ for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){ @@ -2736,11 +2734,10 @@ Index *sqlite3CreateIndex( goto exit_create_index; } pIndex->aiColumn[i] = j; - if( pListItem->pExpr - && (pColl = sqlite3ExprCollSeq(pParse, pListItem->pExpr))!=0 - ){ + if( pListItem->pExpr ){ int nColl; - zColl = pColl->zName; + assert( pListItem->pExpr->op==TK_COLLATE ); + zColl = pListItem->pExpr->u.zToken; nColl = sqlite3Strlen30(zColl) + 1; assert( nExtra>=nColl ); memcpy(zExtra, zColl, nColl); @@ -2749,9 +2746,7 @@ Index *sqlite3CreateIndex( nExtra -= nColl; }else{ zColl = pTab->aCol[j].zColl; - if( !zColl ){ - zColl = "BINARY"; - } + if( !zColl ) zColl = "BINARY"; } if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){ goto exit_create_index; diff --git a/src/expr.c b/src/expr.c index a974c5a61..c1a27ebf8 100644 --- a/src/expr.c +++ b/src/expr.c @@ -116,12 +116,7 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ } assert( op!=TK_REGISTER || p->op2!=TK_COLLATE ); if( op==TK_COLLATE ){ - if( db->init.busy ){ - /* Do not report errors when parsing while the schema */ - pColl = sqlite3FindCollSeq(db, ENC(db), p->u.zToken, 0); - }else{ - pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); - } + pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); break; } if( p->pTab!=0 @@ -1651,7 +1646,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ ** ** If rMayHaveNull is zero, that means that the subquery is being used ** for membership testing only. There is no need to initialize any -** registers to indicate the presense or absence of NULLs on the RHS. +** registers to indicate the presence or absence of NULLs on the RHS. ** ** For a SELECT or EXISTS operator, return the register that holds the ** result. For IN operators or if an error occurs, the return value is 0. diff --git a/src/func.c b/src/func.c index 6db155dd2..9bee8576b 100644 --- a/src/func.c +++ b/src/func.c @@ -231,7 +231,7 @@ static void instrFunc( ** ** If p1 is negative, then we begin abs(p1) from the end of x[]. ** -** If p2 is negative, return the p2 characters preceeding p1. +** If p2 is negative, return the p2 characters preceding p1. */ static void substrFunc( sqlite3_context *context, @@ -890,10 +890,6 @@ static const char hexdigits[] = { }; /* -** EXPERIMENTAL - This is not an official function. The interface may -** change. This function may disappear. Do not write code that depends -** on this function. -** ** Implementation of the QUOTE() function. This function takes a single ** argument. If the argument is numeric, the return value is the same as ** the argument. If the argument is NULL, the return value is the string @@ -1210,7 +1206,7 @@ static void zeroblobFunc( /* ** The replace() function. Three arguments are all strings: call ** them A, B, and C. The result is also a string which is derived -** from A by replacing every occurance of B with C. The match +** from A by replacing every occurrence of B with C. The match ** must be exact. Collating sequences are not used. */ static void replaceFunc( diff --git a/src/main.c b/src/main.c index 3b6cd9e82..aa2604362 100644 --- a/src/main.c +++ b/src/main.c @@ -701,7 +701,7 @@ static int binCollFunc( /* ** Another built-in collating sequence: NOCASE. ** -** This collating sequence is intended to be used for "case independant +** This collating sequence is intended to be used for "case independent ** comparison". SQLite's knowledge of upper and lower case equivalents ** extends only to the 26 characters used in the English language. ** @@ -902,6 +902,12 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ ** go ahead and free all resources. */ + /* If a transaction is open, roll it back. This also ensures that if + ** any database schemas have been modified by an uncommitted transaction + ** they are reset. And that the required b-tree mutex is held to make + ** the pager rollback and schema reset an atomic operation. */ + sqlite3RollbackAll(db, SQLITE_OK); + /* Free any outstanding Savepoint structures. */ sqlite3CloseSavepoints(db); @@ -1002,6 +1008,15 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){ int inTrans = 0; assert( sqlite3_mutex_held(db->mutex) ); sqlite3BeginBenignMalloc(); + + /* Obtain all b-tree mutexes before making any calls to BtreeRollback(). + ** This is important in case the transaction being rolled back has + ** modified the database schema. If the b-tree mutexes are not taken + ** here, then another shared-cache connection might sneak in between + ** the database rollback and schema reset, which can cause false + ** corruption reports in some cases. */ + sqlite3BtreeEnterAll(db); + for(i=0; i<db->nDb; i++){ Btree *p = db->aDb[i].pBt; if( p ){ @@ -1009,7 +1024,6 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){ inTrans = 1; } sqlite3BtreeRollback(p, tripCode); - db->aDb[i].inTrans = 0; } } sqlite3VtabRollback(db); @@ -1019,6 +1033,7 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){ sqlite3ExpirePreparedStatements(db); sqlite3ResetAllSchemasOfConnection(db); } + sqlite3BtreeLeaveAll(db); /* Any deferred constraint violations have now been resolved. */ db->nDeferredCons = 0; @@ -2775,8 +2790,6 @@ int sqlite3_global_recover(void){ ** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on ** by default. Autocommit is disabled by a BEGIN statement and reenabled ** by the next COMMIT or ROLLBACK. -** -******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** */ int sqlite3_get_autocommit(sqlite3 *db){ return db->autoCommit; diff --git a/src/os_unix.c b/src/os_unix.c index 30d79f0c5..152bf9a11 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -46,13 +46,6 @@ #include "sqliteInt.h" #if SQLITE_OS_UNIX /* This file is used on unix only */ -/* Use posix_fallocate() if it is available -*/ -#if !defined(HAVE_POSIX_FALLOCATE) \ - && (_XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L) -# define HAVE_POSIX_FALLOCATE 1 -#endif - /* ** There are various methods for file locking used for concurrency ** control: @@ -3775,15 +3768,19 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ } case SQLITE_FCNTL_MMAP_SIZE: { i64 newLimit = *(i64*)pArg; + int rc = SQLITE_OK; if( newLimit>sqlite3GlobalConfig.mxMmap ){ newLimit = sqlite3GlobalConfig.mxMmap; } *(i64*)pArg = pFile->mmapSizeMax; - if( newLimit>=0 ){ + if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){ pFile->mmapSizeMax = newLimit; - if( newLimit<pFile->mmapSize ) pFile->mmapSize = newLimit; + if( pFile->mmapSize>0 ){ + unixUnmapfile(pFile); + rc = unixMapfile(pFile, -1); + } } - return SQLITE_OK; + return rc; } #ifdef SQLITE_DEBUG /* The pager calls this method to signal that it has done @@ -5153,7 +5150,7 @@ static int fillInUnixFile( pNew->pVfs = pVfs; pNew->zPath = zFilename; pNew->ctrlFlags = (u8)ctrlFlags; - pNew->mmapSizeMax = sqlite3GlobalConfig.mxMmap; + pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap; if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0), "psow", SQLITE_POWERSAFE_OVERWRITE) ){ pNew->ctrlFlags |= UNIXFILE_PSOW; diff --git a/src/os_win.c b/src/os_win.c index 66f070387..07b74cbe2 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -2816,6 +2816,9 @@ static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){ /* Forward declaration */ static int getTempname(int nBuf, char *zBuf); +#if SQLITE_MAX_MMAP_SIZE>0 +static int winMapfile(winFile*, sqlite3_int64); +#endif /* ** Control and query of the open file handle. @@ -2899,13 +2902,20 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ #if SQLITE_MAX_MMAP_SIZE>0 case SQLITE_FCNTL_MMAP_SIZE: { i64 newLimit = *(i64*)pArg; + int rc = SQLITE_OK; if( newLimit>sqlite3GlobalConfig.mxMmap ){ newLimit = sqlite3GlobalConfig.mxMmap; } *(i64*)pArg = pFile->mmapSizeMax; - if( newLimit>=0 ) pFile->mmapSizeMax = newLimit; - OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); - return SQLITE_OK; + if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){ + pFile->mmapSizeMax = newLimit; + if( pFile->mmapSize>0 ){ + (void)winUnmapfile(pFile); + rc = winMapfile(pFile, -1); + } + } + OSTRACE(("FCNTL file=%p, rc=%d\n", pFile->h, rc)); + return rc; } #endif } @@ -2937,8 +2947,6 @@ static int winDeviceCharacteristics(sqlite3_file *id){ ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); } -#ifndef SQLITE_OMIT_WAL - /* ** Windows will only let you create file view mappings ** on allocation size granularity boundaries. @@ -2947,6 +2955,8 @@ static int winDeviceCharacteristics(sqlite3_file *id){ */ SYSTEM_INFO winSysInfo; +#ifndef SQLITE_OMIT_WAL + /* ** Helper functions to obtain and relinquish the global mutex. The ** global mutex is used to protect the winLockInfo objects used by @@ -4246,7 +4256,7 @@ static int winOpen( pFile->pMapRegion = 0; pFile->mmapSize = 0; pFile->mmapSizeActual = 0; - pFile->mmapSizeMax = sqlite3GlobalConfig.mxMmap; + pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap; #endif OpenCounter(+1); diff --git a/src/pager.c b/src/pager.c index 1c6a84fea..645cc3d9a 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4214,7 +4214,8 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){ */ assert( rc!=SQLITE_OK || isOpen(pPager->fd) ); if( rc==SQLITE_OK - && (pList->pDirty ? pPager->dbSize : pList->pgno+1)>pPager->dbHintSize + && pPager->dbHintSize<pPager->dbSize + && (pList->pDirty || pList->pgno>pPager->dbHintSize) ){ sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize; sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile); @@ -5179,7 +5180,7 @@ static void pagerUnlockIfUnused(Pager *pPager){ ** page is initialized to all zeros. ** ** If noContent is true, it means that we do not care about the contents -** of the page. This occurs in two seperate scenarios: +** of the page. This occurs in two scenarios: ** ** a) When reading a free-list leaf page from the database, and ** @@ -6589,7 +6590,27 @@ void sqlite3PagerSetCodec( void *sqlite3PagerGetCodec(Pager *pPager){ return pPager->pCodec; } -#endif + +/* +** This function is called by the wal module when writing page content +** into the log file. +** +** This function returns a pointer to a buffer containing the encrypted +** page content. If a malloc fails, this function may return NULL. +*/ +void *sqlite3PagerCodec(PgHdr *pPg){ + void *aData = 0; + CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData); + return aData; +} + +/* +** Return the current pager state +*/ +int sqlite3PagerState(Pager *pPager){ + return pPager->eState; +} +#endif /* SQLITE_HAS_CODEC */ #ifndef SQLITE_OMIT_AUTOVACUUM /* @@ -7144,19 +7165,4 @@ int sqlite3PagerWalFramesize(Pager *pPager){ } #endif -#ifdef SQLITE_HAS_CODEC -/* -** This function is called by the wal module when writing page content -** into the log file. -** -** This function returns a pointer to a buffer containing the encrypted -** page content. If a malloc fails, this function may return NULL. -*/ -void *sqlite3PagerCodec(PgHdr *pPg){ - void *aData = 0; - CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData); - return aData; -} -#endif /* SQLITE_HAS_CODEC */ - #endif /* SQLITE_OMIT_DISKIO */ diff --git a/src/parse.y b/src/parse.y index 8310b2698..d707ee0a8 100644 --- a/src/parse.y +++ b/src/parse.y @@ -213,7 +213,7 @@ id(A) ::= INDEXED(X). {A = X;} . %wildcard ANY. -// Define operator precedence early so that this is the first occurance +// Define operator precedence early so that this is the first occurrence // of the operator tokens in the grammer. Keeping the operators together // causes them to be assigned integer values that are close together, // which keeps parser tables smaller. diff --git a/src/pcache1.c b/src/pcache1.c index 4147d2eff..e06f5dae6 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -562,7 +562,7 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){ int sz; /* Bytes of memory required to allocate the new cache */ /* - ** The seperateCache variable is true if each PCache has its own private + ** The separateCache variable is true if each PCache has its own private ** PGroup. In other words, separateCache is true for mode (1) where no ** mutexing is required. ** diff --git a/src/pragma.c b/src/pragma.c index 3056a7d8e..5803f6c4a 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -774,11 +774,15 @@ void sqlite3Pragma( } } sz = -1; - if( sqlite3_file_control(db,zDb,SQLITE_FCNTL_MMAP_SIZE,&sz)==SQLITE_OK ){ + rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_MMAP_SIZE, &sz); #if SQLITE_MAX_MMAP_SIZE==0 - sz = 0; + sz = 0; #endif + if( rc==SQLITE_OK ){ returnSingleInt(pParse, "mmap_size", sz); + }else if( rc!=SQLITE_NOTFOUND ){ + pParse->nErr++; + pParse->rc = rc; } }else @@ -1309,7 +1313,7 @@ void sqlite3Pragma( #endif #ifndef SQLITE_OMIT_INTEGRITY_CHECK - /* Pragma "quick_check" is an experimental reduced version of + /* Pragma "quick_check" is reduced version of ** integrity_check designed to detect most database corruption ** without most of the overhead of a full integrity-check. */ @@ -1767,10 +1771,10 @@ void sqlite3Pragma( #ifdef SQLITE_HAS_CODEC if( sqlite3StrICmp(zLeft, "key")==0 && zRight ){ - sqlite3_key(db, zRight, sqlite3Strlen30(zRight)); + sqlite3_key_v2(db, zDb, zRight, sqlite3Strlen30(zRight)); }else if( sqlite3StrICmp(zLeft, "rekey")==0 && zRight ){ - sqlite3_rekey(db, zRight, sqlite3Strlen30(zRight)); + sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight)); }else if( zRight && (sqlite3StrICmp(zLeft, "hexkey")==0 || sqlite3StrICmp(zLeft, "hexrekey")==0) ){ @@ -1782,9 +1786,9 @@ void sqlite3Pragma( zKey[i/2] = (h2 & 0x0f) | ((h1 & 0xf)<<4); } if( (zLeft[3] & 0xf)==0xb ){ - sqlite3_key(db, zKey, i/2); + sqlite3_key_v2(db, zDb, zKey, i/2); }else{ - sqlite3_rekey(db, zKey, i/2); + sqlite3_rekey_v2(db, zDb, zKey, i/2); } }else #endif diff --git a/src/printf.c b/src/printf.c index 9f68d204f..8d37d633b 100644 --- a/src/printf.c +++ b/src/printf.c @@ -413,13 +413,7 @@ void sqlite3VXPrintf( else prefix = 0; } if( xtype==etGENERIC && precision>0 ) precision--; -#if 0 - /* Rounding works like BSD when the constant 0.4999 is used. Wierd! */ - for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1); -#else - /* It makes more sense to use 0.5 */ for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){} -#endif if( xtype==etFLOAT ) realvalue += rounder; /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ exp = 0; diff --git a/src/resolve.c b/src/resolve.c index a8e196926..91efcaa1a 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1159,8 +1159,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ ** re-evaluated for each reference to it. */ sNC.pEList = p->pEList; - if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; sNC.ncFlags |= NC_AsMaybe; + if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; sNC.ncFlags &= ~NC_AsMaybe; diff --git a/src/select.c b/src/select.c index f3f149096..9705c1905 100644 --- a/src/select.c +++ b/src/select.c @@ -109,7 +109,7 @@ void sqlite3SelectDelete(sqlite3 *db, Select *p){ } /* -** Given 1 to 3 identifiers preceeding the JOIN keyword, determine the +** Given 1 to 3 identifiers preceding the JOIN keyword, determine the ** type of join. Return an integer constant that expresses that type ** in terms of the following bit values: ** @@ -1523,7 +1523,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ /* ** "LIMIT -1" always shows all rows. There is some - ** contraversy about what the correct behavior should be. + ** controversy about what the correct behavior should be. ** The current implementation interprets "LIMIT 0" to mean ** no rows. */ @@ -4046,7 +4046,7 @@ int sqlite3Select( } /* Increment Parse.nHeight by the height of the largest expression - ** tree refered to by this, the parent select. The child select + ** tree referred to by this, the parent select. The child select ** may contain expression trees of at most ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit ** more conservative than necessary, but much easier than enforcing diff --git a/src/shell.c b/src/shell.c index 1be2871fe..9f2f46bd1 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1523,21 +1523,14 @@ static void resolve_backslashes(char *z){ } /* -** Interpret zArg as a boolean value. Return either 0 or 1. -*/ -static int booleanValue(char *zArg){ - int i; - for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){} - if( i>0 && zArg[i]==0 ) return atoi(zArg); - if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){ - return 1; - } - if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){ - return 0; - } - fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", - zArg); - return 0; +** Return the value of a hexadecimal digit. Return -1 if the input +** is not a hex digit. +*/ +static int hexDigitValue(char c){ + if( c>='0' && c<='9' ) return c - '0'; + if( c>='a' && c<='f' ) return c - 'a' + 10; + if( c>='A' && c<='F' ) return c - 'A' + 10; + return -1; } /* @@ -1564,11 +1557,20 @@ static sqlite3_int64 integerValue(const char *zArg){ }else if( zArg[0]=='+' ){ zArg++; } - while( isdigit(zArg[0]) ){ - v = v*10 + zArg[0] - '0'; - zArg++; + if( zArg[0]=='0' && zArg[1]=='x' ){ + int x; + zArg += 2; + while( (x = hexDigitValue(zArg[0]))>=0 ){ + v = (v<<4) + x; + zArg++; + } + }else{ + while( IsDigit(zArg[0]) ){ + v = v*10 + zArg[0] - '0'; + zArg++; + } } - for(i=0; i<sizeof(aMult)/sizeof(aMult[0]); i++){ + for(i=0; i<ArraySize(aMult); i++){ if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){ v *= aMult[i].iMult; break; @@ -1578,6 +1580,29 @@ static sqlite3_int64 integerValue(const char *zArg){ } /* +** Interpret zArg as either an integer or a boolean value. Return 1 or 0 +** for TRUE and FALSE. Return the integer value if appropriate. +*/ +static int booleanValue(char *zArg){ + int i; + if( zArg[0]=='0' && zArg[1]=='x' ){ + for(i=2; hexDigitValue(zArg[i])>=0; i++){} + }else{ + for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){} + } + if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff); + if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){ + return 1; + } + if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){ + return 0; + } + fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", + zArg); + return 0; +} + +/* ** Close an output file, assuming it is not stderr or stdout */ static void output_file_close(FILE *f){ @@ -1808,7 +1833,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ }else if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){ - if( nArg>1 && (rc = atoi(azArg[1]))!=0 ) exit(rc); + if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc); rc = 2; }else @@ -2305,6 +2330,25 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }else + /* Undocumented commands for internal testing. Subject to change + ** without notice. */ + if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){ + if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){ + int i, v; + for(i=1; i<nArg; i++){ + v = booleanValue(azArg[i]); + fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v); + } + } + if( strncmp(azArg[0]+9, "integer", n-9)==0 ){ + int i; sqlite3_int64 v; + for(i=1; i<nArg; i++){ + v = integerValue(azArg[i]); + fprintf(p->out, "%s: %lld 0x%llx\n", azArg[i], v, v); + } + } + }else + if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){ sqlite3_snprintf(sizeof(p->separator), p->separator, "%.*s", (int)sizeof(p->separator)-1, azArg[1]); @@ -2458,7 +2502,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } } } - if( testctrl<0 ) testctrl = atoi(azArg[1]); + if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]); if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){ fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]); }else{ @@ -2505,7 +2549,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ case SQLITE_TESTCTRL_ASSERT: case SQLITE_TESTCTRL_ALWAYS: if( nArg==3 ){ - int opt = atoi(azArg[2]); + int opt = booleanValue(azArg[2]); rc = sqlite3_test_control(testctrl, opt); fprintf(p->out, "%d (0x%08x)\n", rc, rc); } else { @@ -2542,7 +2586,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){ open_db(p); - sqlite3_busy_timeout(p->db, atoi(azArg[1])); + sqlite3_busy_timeout(p->db, (int)integerValue(azArg[1])); }else if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 @@ -2592,7 +2636,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ int j; assert( nArg<=ArraySize(azArg) ); for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){ - p->colWidth[j-1] = atoi(azArg[j]); + p->colWidth[j-1] = (int)integerValue(azArg[j]); } }else diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 660882317..0d23f3894 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4513,6 +4513,11 @@ int sqlite3_key( sqlite3 *db, /* Database to be rekeyed */ const void *pKey, int nKey /* The key */ ); +int sqlite3_key_v2( + sqlite3 *db, /* Database to be rekeyed */ + const char *zDbName, /* Name of the database */ + const void *pKey, int nKey /* The key */ +); /* ** Change the key on an open database. If the current database is not @@ -4526,6 +4531,11 @@ int sqlite3_rekey( sqlite3 *db, /* Database to be rekeyed */ const void *pKey, int nKey /* The new key */ ); +int sqlite3_rekey_v2( + sqlite3 *db, /* Database to be rekeyed */ + const char *zDbName, /* Name of the database */ + const void *pKey, int nKey /* The new key */ +); /* ** Specify the activation key for a SEE database. Unless diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6b64a58a3..17d26f4b0 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -114,7 +114,7 @@ ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. ** 0 means mutexes are permanently disable and the library is never ** threadsafe. 1 means the library is serialized which is the highest -** level of threadsafety. 2 means the libary is multithreaded - multiple +** level of threadsafety. 2 means the library is multithreaded - multiple ** threads can use SQLite as long as no two threads try to use the same ** database connection at the same time. ** @@ -193,20 +193,12 @@ /* ** We need to define _XOPEN_SOURCE as follows in order to enable -** recursive mutexes on most Unix systems. But Mac OS X is different. -** The _XOPEN_SOURCE define causes problems for Mac OS X we are told, -** so it is omitted there. See ticket #2673. -** -** Later we learn that _XOPEN_SOURCE is poorly or incorrectly -** implemented on some systems. So we avoid defining it at all -** if it is already defined or if it is unneeded because we are -** not doing a threadsafe build. Ticket #2681. -** -** See also ticket #2741. +** recursive mutexes on most Unix systems and fchmod() on OpenBSD. +** But _XOPEN_SOURCE define causes problems for Mac OS X, so omit +** it. */ -#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) \ - && !defined(__APPLE__) && SQLITE_THREADSAFE -# define _XOPEN_SOURCE 500 /* Needed to enable pthread recursive mutexes */ +#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__) +# define _XOPEN_SOURCE 600 #endif /* @@ -758,7 +750,6 @@ typedef struct WhereLevel WhereLevel; struct Db { char *zName; /* Name of this database */ Btree *pBt; /* The B*Tree structure for this database file */ - u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */ u8 safety_level; /* How aggressive at syncing data to disk */ Schema *pSchema; /* Pointer to database schema (possibly shared) */ }; diff --git a/src/tclsqlite.c b/src/tclsqlite.c index f1bb2921d..6d2a51e5a 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -3050,7 +3050,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ */ #ifndef USE_TCL_STUBS # undef Tcl_InitStubs -# define Tcl_InitStubs(a,b,c) +# define Tcl_InitStubs(a,b,c) TCL_VERSION #endif /* @@ -3074,19 +3074,18 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ ** The EXTERN macros are required by TCL in order to work on windows. */ EXTERN int Sqlite3_Init(Tcl_Interp *interp){ - Tcl_InitStubs(interp, "8.4", 0); - Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0); - Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION); - + int rc = Tcl_InitStubs(interp, "8.4", 0)==0 ? TCL_ERROR : TCL_OK; + if( rc==TCL_OK ){ + Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0); #ifndef SQLITE_3_SUFFIX_ONLY - /* The "sqlite" alias is undocumented. It is here only to support - ** legacy scripts. All new scripts should use only the "sqlite3" - ** command. - */ - Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0); + /* The "sqlite" alias is undocumented. It is here only to support + ** legacy scripts. All new scripts should use only the "sqlite3" + ** command. */ + Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0); #endif - - return TCL_OK; + rc = Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION); + } + return rc; } EXTERN int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } EXTERN int Sqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } diff --git a/src/test1.c b/src/test1.c index 59de1db8e..bd6d4a4cf 100644 --- a/src/test1.c +++ b/src/test1.c @@ -682,6 +682,30 @@ static int sqlite_test_close( } /* +** Usage: sqlite3_close_v2 DB +** +** Closes the database opened by sqlite3_open. +*/ +static int sqlite_test_close_v2( + void *NotUsed, + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int argc, /* Number of arguments */ + char **argv /* Text of each argument */ +){ + sqlite3 *db; + int rc; + if( argc!=2 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " FILENAME\"", 0); + return TCL_ERROR; + } + if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; + rc = sqlite3_close_v2(db); + Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC); + return TCL_OK; +} + +/* ** Implementation of the x_coalesce() function. ** Return the first argument non-NULL argument. */ @@ -2445,7 +2469,7 @@ static int sqlite_static_bind_nbyte = 0; /* ** Usage: sqlite3_bind VM IDX VALUE FLAGS ** -** Sets the value of the IDX-th occurance of "?" in the original SQL +** Sets the value of the IDX-th occurrence of "?" in the original SQL ** string. VALUE is the new value. If FLAGS=="null" then VALUE is ** ignored and the value is set to NULL. If FLAGS=="static" then ** the value is set to the value of a static variable named @@ -5539,7 +5563,7 @@ static int test_wal_checkpoint( ** ** Otherwise, this command returns a list of three integers. The first integer ** is 1 if SQLITE_BUSY was returned, or 0 otherwise. The following two integers -** are the values returned via the output paramaters by wal_checkpoint_v2() - +** are the values returned via the output parameters by wal_checkpoint_v2() - ** the number of frames in the log and the number of frames in the log ** that have been checkpointed. */ @@ -5988,6 +6012,7 @@ static int tclLoadStaticExtensionCmd( extern int sqlite3_fuzzer_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_ieee_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_nextchar_init(sqlite3*,char**,const sqlite3_api_routines*); + extern int sqlite3_percentile_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_regexp_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_spellfix_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_wholenumber_init(sqlite3*,char**,const sqlite3_api_routines*); @@ -6000,6 +6025,7 @@ static int tclLoadStaticExtensionCmd( { "fuzzer", sqlite3_fuzzer_init }, { "ieee754", sqlite3_ieee_init }, { "nextchar", sqlite3_nextchar_init }, + { "percentile", sqlite3_percentile_init }, { "regexp", sqlite3_regexp_init }, { "spellfix", sqlite3_spellfix_init }, { "wholenumber", sqlite3_wholenumber_init }, @@ -6077,6 +6103,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_get_table_printf", (Tcl_CmdProc*)test_get_table_printf }, #endif { "sqlite3_close", (Tcl_CmdProc*)sqlite_test_close }, + { "sqlite3_close_v2", (Tcl_CmdProc*)sqlite_test_close_v2 }, { "sqlite3_create_function", (Tcl_CmdProc*)test_create_function }, { "sqlite3_create_aggregate", (Tcl_CmdProc*)test_create_aggregate }, { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func }, diff --git a/src/test_syscall.c b/src/test_syscall.c index 4d62c737a..7c0873c16 100644 --- a/src/test_syscall.c +++ b/src/test_syscall.c @@ -69,13 +69,13 @@ ** the xNextSystemCall() VFS method. */ +#include "sqliteInt.h" #include "sqlite3.h" #include "tcl.h" #include <stdlib.h> #include <string.h> #include <assert.h> -#include "sqliteInt.h" #if SQLITE_OS_UNIX /* From main.c */ diff --git a/src/trigger.c b/src/trigger.c index f1ff766e2..b901d0767 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -1002,7 +1002,7 @@ void sqlite3CodeRowTriggerDirect( /* ** This is called to code the required FOR EACH ROW triggers for an operation ** on table pTab. The operation to code triggers for (INSERT, UPDATE or DELETE) -** is given by the op paramater. The tr_tm parameter determines whether the +** is given by the op parameter. The tr_tm parameter determines whether the ** BEFORE or AFTER triggers are coded. If the operation is an UPDATE, then ** parameter pChanges is passed the list of columns being modified. ** diff --git a/src/vdbe.c b/src/vdbe.c index f343e13d4..7abc2889d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2914,8 +2914,8 @@ case OP_AutoCommit: { ** other process can start another write transaction while this transaction is ** underway. Starting a write transaction also creates a rollback journal. A ** write transaction must be started before any changes can be made to the -** database. If P2 is 2 or greater then an EXCLUSIVE lock is also obtained -** on the file. +** database. If P2 is greater than or equal to 2 then an EXCLUSIVE lock is +** also obtained on the file. ** ** If a write-transaction is started and the Vdbe.usesStmtJournal flag is ** true (this flag is set if the Vdbe may modify more than one row and may diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 7c861e2d4..426b72c5c 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -813,13 +813,6 @@ int sqlite3_column_type(sqlite3_stmt *pStmt, int i){ return iType; } -/* The following function is experimental and subject to change or -** removal */ -/*int sqlite3_column_numeric_type(sqlite3_stmt *pStmt, int i){ -** return sqlite3_value_numeric_type( columnMem(pStmt,i) ); -**} -*/ - /* ** Convert the N-th element of pStmt->pColName[] into a string using ** xFunc() then return that string. If N is out of range, return 0. diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 2c4269a59..e32f2db06 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1996,7 +1996,7 @@ static void checkActiveVdbeCnt(sqlite3 *db){ ** close it now. Argument eOp must be either SAVEPOINT_ROLLBACK or ** SAVEPOINT_RELEASE. If it is SAVEPOINT_ROLLBACK, then the statement ** transaction is rolled back. If eOp is SAVEPOINT_RELEASE, then the -** statement transaction is commtted. +** statement transaction is committed. ** ** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned. ** Otherwise SQLITE_OK. diff --git a/src/vdbesort.c b/src/vdbesort.c index fdfc4a79d..c8709bdaf 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -54,7 +54,7 @@ typedef struct FileWriter FileWriter; ** other key value. If the keys are equal (only possible with two EOF ** values), it doesn't matter which index is stored. ** -** The (N/4) elements of aTree[] that preceed the final (N/2) described +** The (N/4) elements of aTree[] that precede the final (N/2) described ** above contains the index of the smallest of each block of 4 iterators. ** And so on. So that aTree[1] contains the index of the iterator that ** currently points to the smallest key value. aTree[0] is unused. diff --git a/src/vdbetrace.c b/src/vdbetrace.c index 88935beea..356277e8d 100644 --- a/src/vdbetrace.c +++ b/src/vdbetrace.c @@ -142,14 +142,14 @@ char *sqlite3VdbeExpandSql( #endif nOut = pVar->n; #ifdef SQLITE_TRACE_SIZE_LIMIT - if( n>SQLITE_TRACE_SIZE_LIMIT ){ + if( nOut>SQLITE_TRACE_SIZE_LIMIT ){ nOut = SQLITE_TRACE_SIZE_LIMIT; - while( nOut<pVar->n && (pVar->z[n]&0xc0)==0x80 ){ n++; } + while( nOut<pVar->n && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; } } #endif sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z); #ifdef SQLITE_TRACE_SIZE_LIMIT - if( nOut<pVar->n ) sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-n); + if( nOut<pVar->n ) sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut); #endif #ifndef SQLITE_OMIT_UTF16 if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8); @@ -169,7 +169,7 @@ char *sqlite3VdbeExpandSql( } sqlite3StrAccumAppend(&out, "'", 1); #ifdef SQLITE_TRACE_SIZE_LIMIT - if( nOut<pVar->n ) sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-n); + if( nOut<pVar->n ) sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut); #endif } } |