aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/alter.c10
-rw-r--r--src/analyze.c19
-rw-r--r--src/attach.c10
-rw-r--r--src/backup.c6
-rw-r--r--src/bitvec.c4
-rw-r--r--src/btree.c41
-rw-r--r--src/btree.h1
-rw-r--r--src/build.c26
-rw-r--r--src/callback.c70
-rw-r--r--src/complete.c2
-rw-r--r--src/date.c10
-rw-r--r--src/dbstat.c20
-rw-r--r--src/expr.c8
-rw-r--r--src/func.c86
-rw-r--r--src/global.c2
-rw-r--r--src/journal.c2
-rw-r--r--src/legacy.c2
-rw-r--r--src/loadext.c8
-rw-r--r--src/main.c108
-rw-r--r--src/malloc.c2
-rw-r--r--src/memjournal.c2
-rw-r--r--src/os.c8
-rw-r--r--src/os_unix.c38
-rw-r--r--src/os_win.c136
-rw-r--r--src/pager.c48
-rw-r--r--src/pager.h1
-rw-r--r--src/parse.y403
-rw-r--r--src/pcache.c4
-rw-r--r--src/prepare.c8
-rw-r--r--src/resolve.c4
-rw-r--r--src/select.c43
-rw-r--r--src/shell.c2
-rw-r--r--src/sqlite.h.in2
-rw-r--r--src/sqliteInt.h291
-rw-r--r--src/table.c6
-rw-r--r--src/test1.c2
-rw-r--r--src/test_blob.c2
-rw-r--r--src/test_fs.c4
-rw-r--r--src/threads.c14
-rw-r--r--src/tokenize.c13
-rw-r--r--src/treeview.c5
-rw-r--r--src/utf.c4
-rw-r--r--src/util.c21
-rw-r--r--src/vacuum.c4
-rw-r--r--src/vdbe.c235
-rw-r--r--src/vdbeInt.h3
-rw-r--r--src/vdbeapi.c11
-rw-r--r--src/vdbeaux.c60
-rw-r--r--src/vdbemem.c35
-rw-r--r--src/vdbesort.c38
-rw-r--r--src/vtab.c12
-rw-r--r--src/wal.c18
-rw-r--r--src/where.c64
-rw-r--r--src/whereInt.h1
-rw-r--r--src/wherecode.c26
-rw-r--r--src/whereexpr.c2
56 files changed, 1069 insertions, 938 deletions
diff --git a/src/alter.c b/src/alter.c
index 34221777a..f10a85022 100644
--- a/src/alter.c
+++ b/src/alter.c
@@ -229,7 +229,7 @@ static void renameTriggerFunc(
** Register built-in functions used to help implement ALTER TABLE
*/
void sqlite3AlterFunctions(void){
- static SQLITE_WSD FuncDef aAlterTableFuncs[] = {
+ static FuncDef aAlterTableFuncs[] = {
FUNCTION(sqlite_rename_table, 2, 0, 0, renameTableFunc),
#ifndef SQLITE_OMIT_TRIGGER
FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc),
@@ -238,13 +238,7 @@ void sqlite3AlterFunctions(void){
FUNCTION(sqlite_rename_parent, 3, 0, 0, renameParentFunc),
#endif
};
- int i;
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
- FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAlterTableFuncs);
-
- for(i=0; i<ArraySize(aAlterTableFuncs); i++){
- sqlite3FuncDefInsert(pHash, &aFunc[i]);
- }
+ sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
}
/*
diff --git a/src/analyze.c b/src/analyze.c
index 1e026a753..cd59ae681 100644
--- a/src/analyze.c
+++ b/src/analyze.c
@@ -481,8 +481,7 @@ static const FuncDef statInitFuncdef = {
statInit, /* xSFunc */
0, /* xFinalize */
"stat_init", /* zName */
- 0, /* pHash */
- 0 /* pDestructor */
+ {0}
};
#ifdef SQLITE_ENABLE_STAT4
@@ -781,8 +780,7 @@ static const FuncDef statPushFuncdef = {
statPush, /* xSFunc */
0, /* xFinalize */
"stat_push", /* zName */
- 0, /* pHash */
- 0 /* pDestructor */
+ {0}
};
#define STAT_GET_STAT1 0 /* "stat" column of stat1 table */
@@ -927,8 +925,7 @@ static const FuncDef statGetFuncdef = {
statGet, /* xSFunc */
0, /* xFinalize */
"stat_get", /* zName */
- 0, /* pHash */
- 0 /* pDestructor */
+ {0}
};
static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){
@@ -1673,7 +1670,7 @@ static int loadStatTbl(
assert( db->lookaside.bDisable );
zSql = sqlite3MPrintf(db, zSql1, zDb);
if( !zSql ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
sqlite3DbFree(db, zSql);
@@ -1713,7 +1710,7 @@ static int loadStatTbl(
pIdx->aSample = sqlite3DbMallocZero(db, nByte);
if( pIdx->aSample==0 ){
sqlite3_finalize(pStmt);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pSpace = (tRowcnt*)&pIdx->aSample[nSample];
pIdx->aAvgEq = pSpace; pSpace += nIdxCol;
@@ -1729,7 +1726,7 @@ static int loadStatTbl(
zSql = sqlite3MPrintf(db, zSql2, zDb);
if( !zSql ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
sqlite3DbFree(db, zSql);
@@ -1767,7 +1764,7 @@ static int loadStatTbl(
pSample->p = sqlite3DbMallocZero(db, pSample->n + 2);
if( pSample->p==0 ){
sqlite3_finalize(pStmt);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n);
pIdx->nSample++;
@@ -1856,7 +1853,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
zSql = sqlite3MPrintf(db,
"SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
if( zSql==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
sqlite3DbFree(db, zSql);
diff --git a/src/attach.c b/src/attach.c
index 2288ac9b6..484a5a110 100644
--- a/src/attach.c
+++ b/src/attach.c
@@ -144,7 +144,7 @@ static void attachFunc(
Pager *pPager;
aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt);
if( !aNew->pSchema ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
zErrDyn = sqlite3MPrintf(db,
"attached databases must use the same text encoding as main database");
@@ -164,7 +164,7 @@ static void attachFunc(
aNew->safety_level = 3;
aNew->zName = sqlite3DbStrDup(db, zName);
if( rc==SQLITE_OK && aNew->zName==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
@@ -392,8 +392,7 @@ void sqlite3Detach(Parse *pParse, Expr *pDbname){
detachFunc, /* xSFunc */
0, /* xFinalize */
"sqlite_detach", /* zName */
- 0, /* pHash */
- 0 /* pDestructor */
+ {0}
};
codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname);
}
@@ -412,8 +411,7 @@ void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){
attachFunc, /* xSFunc */
0, /* xFinalize */
"sqlite_attach", /* zName */
- 0, /* pHash */
- 0 /* pDestructor */
+ {0}
};
codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey);
}
diff --git a/src/backup.c b/src/backup.c
index 1c282242d..455671a1a 100644
--- a/src/backup.c
+++ b/src/backup.c
@@ -88,7 +88,7 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse));
if( pParse==0 ){
sqlite3ErrorWithMsg(pErrorDb, SQLITE_NOMEM, "out of memory");
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
pParse->db = pDb;
if( sqlite3OpenTempDatabase(pParse) ){
@@ -182,7 +182,7 @@ sqlite3_backup *sqlite3_backup_init(
** sqlite3_backup_finish(). */
p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup));
if( !p ){
- sqlite3Error(pDestDb, SQLITE_NOMEM);
+ sqlite3Error(pDestDb, SQLITE_NOMEM_BKPT);
}
}
@@ -581,7 +581,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
}
if( rc==SQLITE_IOERR_NOMEM ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
p->rc = rc;
}
diff --git a/src/bitvec.c b/src/bitvec.c
index f7f544cff..9d13ba918 100644
--- a/src/bitvec.c
+++ b/src/bitvec.c
@@ -177,7 +177,7 @@ int sqlite3BitvecSet(Bitvec *p, u32 i){
i = i%p->iDivisor;
if( p->u.apSub[bin]==0 ){
p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor );
- if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM;
+ if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM_BKPT;
}
p = p->u.apSub[bin];
}
@@ -212,7 +212,7 @@ bitvec_set_rehash:
int rc;
u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash));
if( aiValues==0 ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}else{
memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
memset(p->u.apSub, 0, sizeof(p->u.apSub));
diff --git a/src/btree.c b/src/btree.c
index c6f9c34f7..036e63a01 100644
--- a/src/btree.c
+++ b/src/btree.c
@@ -350,7 +350,7 @@ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){
if( !pLock ){
pLock = (BtLock *)sqlite3MallocZero(sizeof(BtLock));
if( !pLock ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pLock->iTable = iTable;
pLock->pBtree = p;
@@ -553,7 +553,7 @@ static int btreeSetHasContent(BtShared *pBt, Pgno pgno){
assert( pgno<=pBt->nPage );
pBt->pHasContent = sqlite3BitvecCreate(pBt->nPage);
if( !pBt->pHasContent ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
}
if( rc==SQLITE_OK && pgno<=sqlite3BitvecSize(pBt->pHasContent) ){
@@ -632,7 +632,7 @@ static int saveCursorKey(BtCursor *pCur){
sqlite3_free(pKey);
}
}else{
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
}
assert( !pCur->curIntKey || !pCur->pKey );
@@ -764,7 +764,7 @@ static int btreeMoveto(
pIdxKey = sqlite3VdbeAllocUnpackedRecord(
pCur->pKeyInfo, aSpace, sizeof(aSpace), &pFree
);
- if( pIdxKey==0 ) return SQLITE_NOMEM;
+ if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT;
sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey);
if( pIdxKey->nField==0 ){
sqlite3DbFree(pCur->pKeyInfo->db, pFree);
@@ -2176,7 +2176,7 @@ int sqlite3BtreeOpen(
}
p = sqlite3MallocZero(sizeof(Btree));
if( !p ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
p->inTrans = TRANS_NONE;
p->db = db;
@@ -2200,7 +2200,7 @@ int sqlite3BtreeOpen(
p->sharable = 1;
if( !zFullPathname ){
sqlite3_free(p);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
if( isMemdb ){
memcpy(zFullPathname, zFilename, nFilename);
@@ -2268,7 +2268,7 @@ int sqlite3BtreeOpen(
pBt = sqlite3MallocZero( sizeof(*pBt) );
if( pBt==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto btree_open_out;
}
rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename,
@@ -2337,7 +2337,7 @@ int sqlite3BtreeOpen(
if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){
pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST);
if( pBt->mutex==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto btree_open_out;
}
}
@@ -2620,21 +2620,6 @@ int sqlite3BtreeSetPagerFlags(
#endif
/*
-** Return TRUE if the given btree is set to safety level 1. In other
-** words, return TRUE if no sync() occurs on the disk files.
-*/
-int sqlite3BtreeSyncDisabled(Btree *p){
- BtShared *pBt = p->pBt;
- int rc;
- assert( sqlite3_mutex_held(p->db->mutex) );
- sqlite3BtreeEnter(p);
- assert( pBt && pBt->pPager );
- rc = sqlite3PagerNosync(pBt->pPager);
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-/*
** Change the default pages size and the number of reserved bytes per page.
** Or, if the page size has already been fixed, return SQLITE_READONLY
** without changing anything.
@@ -4114,7 +4099,7 @@ static int btreeCursor(
if( wrFlag ){
allocateTempSpace(pBt);
- if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM;
+ if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM_BKPT;
}
if( iTable==1 && btreePagecount(pBt)==0 ){
assert( wrFlag==0 );
@@ -4512,7 +4497,7 @@ static int accessPayload(
pCur->aOverflow, nOvfl*2*sizeof(Pgno)
);
if( aNew==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
pCur->nOvflAlloc = nOvfl*2;
pCur->aOverflow = aNew;
@@ -5217,7 +5202,7 @@ int sqlite3BtreeMovetoUnpacked(
}
pCellKey = sqlite3Malloc( nCell+18 );
if( pCellKey==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto moveto_finish;
}
pCur->aiIdx[pCur->iPage] = (u16)idx;
@@ -7036,7 +7021,7 @@ static int balance_nonroot(
assert( pParent->nOverflow==0 || pParent->aiOvfl[0]==iParentIdx );
if( !aOvflSpace ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
/* Find the sibling pages to balance. Also locate the cells in pParent
@@ -7136,7 +7121,7 @@ static int balance_nonroot(
assert( szScratch<=6*(int)pBt->pageSize );
b.apCell = sqlite3ScratchMalloc( szScratch );
if( b.apCell==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto balance_cleanup;
}
b.szCell = (u16*)&b.apCell[nMaxCells];
diff --git a/src/btree.h b/src/btree.h
index 30522e99e..9ba233ac3 100644
--- a/src/btree.h
+++ b/src/btree.h
@@ -68,7 +68,6 @@ int sqlite3BtreeSetSpillSize(Btree*,int);
int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
#endif
int sqlite3BtreeSetPagerFlags(Btree*,unsigned);
-int sqlite3BtreeSyncDisabled(Btree*);
int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
int sqlite3BtreeGetPageSize(Btree*);
int sqlite3BtreeMaxPageCount(Btree*,int);
diff --git a/src/build.c b/src/build.c
index 250dc20d2..b14d45f6d 100644
--- a/src/build.c
+++ b/src/build.c
@@ -710,12 +710,8 @@ int sqlite3FindDbName(sqlite3 *db, const char *zName){
int i = -1; /* Database number */
if( zName ){
Db *pDb;
- int n = sqlite3Strlen30(zName);
for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){
- if( (!OMIT_TEMPDB || i!=1 ) && n==sqlite3Strlen30(pDb->zName) &&
- 0==sqlite3StrICmp(pDb->zName, zName) ){
- break;
- }
+ if( 0==sqlite3StrICmp(pDb->zName, zName) ) break;
}
}
return i;
@@ -927,7 +923,7 @@ void sqlite3StartTable(
pTable = sqlite3DbMallocZero(db, sizeof(Table));
if( pTable==0 ){
assert( db->mallocFailed );
- pParse->rc = SQLITE_NOMEM;
+ pParse->rc = SQLITE_NOMEM_BKPT;
pParse->nErr++;
goto begin_table_error;
}
@@ -1608,7 +1604,7 @@ static int resizeIndexObject(sqlite3 *db, Index *pIdx, int N){
assert( pIdx->isResized==0 );
nByte = (sizeof(char*) + sizeof(i16) + 1)*N;
zExtra = sqlite3DbMallocZero(db, nByte);
- if( zExtra==0 ) return SQLITE_NOMEM;
+ if( zExtra==0 ) return SQLITE_NOMEM_BKPT;
memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn);
pIdx->azColl = (const char**)zExtra;
zExtra += sizeof(char*)*N;
@@ -3200,6 +3196,20 @@ Index *sqlite3CreateIndex(
sqlite3DefaultRowEst(pIndex);
if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex);
+ /* If this index contains every column of its table, then mark
+ ** it as a covering index */
+ assert( HasRowid(pTab)
+ || pTab->iPKey<0 || sqlite3ColumnOfIndex(pIndex, pTab->iPKey)>=0 );
+ if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){
+ pIndex->isCovering = 1;
+ for(j=0; j<pTab->nCol; j++){
+ if( j==pTab->iPKey ) continue;
+ if( sqlite3ColumnOfIndex(pIndex,j)>=0 ) continue;
+ pIndex->isCovering = 0;
+ break;
+ }
+ }
+
if( pTab==pParse->pNewTable ){
/* This routine has been called to create an automatic index as a
** result of a PRIMARY KEY or UNIQUE clause on a column definition, or
@@ -3237,7 +3247,7 @@ Index *sqlite3CreateIndex(
if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
z1 = pIdx->azColl[k];
z2 = pIndex->azColl[k];
- if( z1!=z2 && sqlite3StrICmp(z1, z2) ) break;
+ if( sqlite3StrICmp(z1, z2) ) break;
}
if( k==pIdx->nKeyCol ){
if( pIdx->onError!=pIndex->onError ){
diff --git a/src/callback.c b/src/callback.c
index 2b955fdcd..235117886 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -284,14 +284,12 @@ static int matchQuality(
** a pointer to the matching FuncDef if found, or 0 if there is no match.
*/
static FuncDef *functionSearch(
- FuncDefHash *pHash, /* Hash table to search */
int h, /* Hash of the name */
- const char *zFunc, /* Name of function */
- int nFunc /* Number of bytes in zFunc */
+ const char *zFunc /* Name of function */
){
FuncDef *p;
- for(p=pHash->a[h]; p; p=p->pHash){
- if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 && p->zName[nFunc]==0 ){
+ for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){
+ if( sqlite3StrICmp(p->zName, zFunc)==0 ){
return p;
}
}
@@ -301,23 +299,26 @@ static FuncDef *functionSearch(
/*
** Insert a new FuncDef into a FuncDefHash hash table.
*/
-void sqlite3FuncDefInsert(
- FuncDefHash *pHash, /* The hash table into which to insert */
- FuncDef *pDef /* The function definition to insert */
+void sqlite3InsertBuiltinFuncs(
+ FuncDef *aDef, /* List of global functions to be inserted */
+ int nDef /* Length of the apDef[] list */
){
- FuncDef *pOther;
- int nName = sqlite3Strlen30(pDef->zName);
- u8 c1 = (u8)pDef->zName[0];
- int h = (sqlite3UpperToLower[c1] + nName) % ArraySize(pHash->a);
- pOther = functionSearch(pHash, h, pDef->zName, nName);
- if( pOther ){
- assert( pOther!=pDef && pOther->pNext!=pDef );
- pDef->pNext = pOther->pNext;
- pOther->pNext = pDef;
- }else{
- pDef->pNext = 0;
- pDef->pHash = pHash->a[h];
- pHash->a[h] = pDef;
+ int i;
+ for(i=0; i<nDef; i++){
+ FuncDef *pOther;
+ const char *zName = aDef[i].zName;
+ int nName = sqlite3Strlen30(zName);
+ int h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ;
+ pOther = functionSearch(h, zName);
+ if( pOther ){
+ assert( pOther!=&aDef[i] && pOther->pNext!=&aDef[i] );
+ aDef[i].pNext = pOther->pNext;
+ pOther->pNext = &aDef[i];
+ }else{
+ aDef[i].pNext = 0;
+ aDef[i].u.pHash = sqlite3BuiltinFunctions.a[h];
+ sqlite3BuiltinFunctions.a[h] = &aDef[i];
+ }
}
}
@@ -344,8 +345,7 @@ void sqlite3FuncDefInsert(
*/
FuncDef *sqlite3FindFunction(
sqlite3 *db, /* An open database */
- const char *zName, /* Name of the function. Not null-terminated */
- int nName, /* Number of characters in the name */
+ const char *zName, /* Name of the function. zero-terminated */
int nArg, /* Number of arguments. -1 means any number */
u8 enc, /* Preferred text encoding */
u8 createFlag /* Create new entry if true and does not otherwise exist */
@@ -354,14 +354,15 @@ FuncDef *sqlite3FindFunction(
FuncDef *pBest = 0; /* Best match found so far */
int bestScore = 0; /* Score of best match */
int h; /* Hash value */
+ int nName; /* Length of the name */
assert( nArg>=(-2) );
assert( nArg>=(-1) || createFlag==0 );
- h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a);
+ nName = sqlite3Strlen30(zName);
/* First search for a match amongst the application-defined functions.
*/
- p = functionSearch(&db->aFunc, h, zName, nName);
+ p = (FuncDef*)sqlite3HashFind(&db->aFunc, zName);
while( p ){
int score = matchQuality(p, nArg, enc);
if( score>bestScore ){
@@ -384,9 +385,9 @@ FuncDef *sqlite3FindFunction(
** So we must not search for built-ins when creating a new function.
*/
if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
bestScore = 0;
- p = functionSearch(pHash, h, zName, nName);
+ h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ;
+ p = functionSearch(h, zName);
while( p ){
int score = matchQuality(p, nArg, enc);
if( score>bestScore ){
@@ -403,12 +404,19 @@ FuncDef *sqlite3FindFunction(
*/
if( createFlag && bestScore<FUNC_PERFECT_MATCH &&
(pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
- pBest->zName = (char *)&pBest[1];
+ FuncDef *pOther;
+ pBest->zName = (const char*)&pBest[1];
pBest->nArg = (u16)nArg;
pBest->funcFlags = enc;
- memcpy(pBest->zName, zName, nName);
- pBest->zName[nName] = 0;
- sqlite3FuncDefInsert(&db->aFunc, pBest);
+ memcpy((char*)&pBest[1], zName, nName+1);
+ pOther = (FuncDef*)sqlite3HashInsert(&db->aFunc, pBest->zName, pBest);
+ if( pOther==pBest ){
+ sqlite3DbFree(db, pBest);
+ sqlite3OomFault(db);
+ return 0;
+ }else{
+ pBest->pNext = pOther;
+ }
}
if( pBest && (pBest->xSFunc || createFlag) ){
diff --git a/src/complete.c b/src/complete.c
index b120b7e81..bb2c03098 100644
--- a/src/complete.c
+++ b/src/complete.c
@@ -281,7 +281,7 @@ int sqlite3_complete16(const void *zSql){
if( zSql8 ){
rc = sqlite3_complete(zSql8);
}else{
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
sqlite3ValueFree(pVal);
return rc & 0xff;
diff --git a/src/date.c b/src/date.c
index 0a1d0e079..ef05d4408 100644
--- a/src/date.c
+++ b/src/date.c
@@ -1136,7 +1136,7 @@ static void currentTimeFunc(
** external linkage.
*/
void sqlite3RegisterDateTimeFunctions(void){
- static SQLITE_WSD FuncDef aDateTimeFuncs[] = {
+ static FuncDef aDateTimeFuncs[] = {
#ifndef SQLITE_OMIT_DATETIME_FUNCS
DFUNCTION(julianday, -1, 0, 0, juliandayFunc ),
DFUNCTION(date, -1, 0, 0, dateFunc ),
@@ -1152,11 +1152,5 @@ void sqlite3RegisterDateTimeFunctions(void){
STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc),
#endif
};
- int i;
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
- FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aDateTimeFuncs);
-
- for(i=0; i<ArraySize(aDateTimeFuncs); i++){
- sqlite3FuncDefInsert(pHash, &aFunc[i]);
- }
+ sqlite3InsertBuiltinFuncs(aDateTimeFuncs, ArraySize(aDateTimeFuncs));
}
diff --git a/src/dbstat.c b/src/dbstat.c
index 5e42cdfe3..b8e79b086 100644
--- a/src/dbstat.c
+++ b/src/dbstat.c
@@ -162,7 +162,7 @@ static int statConnect(
rc = sqlite3_declare_vtab(db, VTAB_SCHEMA);
if( rc==SQLITE_OK ){
pTab = (StatTable *)sqlite3_malloc64(sizeof(StatTable));
- if( pTab==0 ) rc = SQLITE_NOMEM;
+ if( pTab==0 ) rc = SQLITE_NOMEM_BKPT;
}
assert( rc==SQLITE_OK || pTab==0 );
@@ -243,7 +243,7 @@ static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
pCsr = (StatCursor *)sqlite3_malloc64(sizeof(StatCursor));
if( pCsr==0 ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}else{
memset(pCsr, 0, sizeof(StatCursor));
pCsr->base.pVtab = pVTab;
@@ -349,7 +349,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){
nUsable = szPage - sqlite3BtreeGetReserveNoMutex(pBt);
sqlite3BtreeLeave(pBt);
p->aCell = sqlite3_malloc64((p->nCell+1) * sizeof(StatCell));
- if( p->aCell==0 ) return SQLITE_NOMEM;
+ if( p->aCell==0 ) return SQLITE_NOMEM_BKPT;
memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell));
for(i=0; i<p->nCell; i++){
@@ -382,7 +382,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){
pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
pCell->nOvfl = nOvfl;
pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
- if( pCell->aOvfl==0 ) return SQLITE_NOMEM;
+ if( pCell->aOvfl==0 ) return SQLITE_NOMEM_BKPT;
pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
for(j=1; j<nOvfl; j++){
int rc;
@@ -461,7 +461,7 @@ statNextRestart:
pCsr->aPage[0].iCell = 0;
pCsr->aPage[0].zPath = z = sqlite3_mprintf("/");
pCsr->iPage = 0;
- if( z==0 ) rc = SQLITE_NOMEM;
+ if( z==0 ) rc = SQLITE_NOMEM_BKPT;
}else{
pCsr->isEof = 1;
return sqlite3_reset(pCsr->pStmt);
@@ -496,7 +496,7 @@ statNextRestart:
}
pCell->iOvfl++;
statSizeAndOffset(pCsr);
- return z==0 ? SQLITE_NOMEM : SQLITE_OK;
+ return z==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK;
}
if( p->iRightChildPg ) break;
p->iCell++;
@@ -520,7 +520,7 @@ statNextRestart:
p[1].iCell = 0;
p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
p->iCell++;
- if( z==0 ) rc = SQLITE_NOMEM;
+ if( z==0 ) rc = SQLITE_NOMEM_BKPT;
}
@@ -554,7 +554,7 @@ statNextRestart:
pCsr->nUnused = p->nUnused;
pCsr->nMxPayload = p->nMxPayload;
pCsr->zPath = z = sqlite3_mprintf("%s", p->zPath);
- if( z==0 ) rc = SQLITE_NOMEM;
+ if( z==0 ) rc = SQLITE_NOMEM_BKPT;
nPayload = 0;
for(i=0; i<p->nCell; i++){
nPayload += p->aCell[i].nLocal;
@@ -588,7 +588,7 @@ static int statFilter(
if( pCsr->iDb<0 ){
sqlite3_free(pCursor->pVtab->zErrMsg);
pCursor->pVtab->zErrMsg = sqlite3_mprintf("no such schema: %s", zDbase);
- return pCursor->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
+ return pCursor->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM_BKPT;
}
}else{
pCsr->iDb = pTab->iDb;
@@ -604,7 +604,7 @@ static int statFilter(
" FROM \"%w\".%s WHERE rootpage!=0"
" ORDER BY name", pTab->db->aDb[pCsr->iDb].zName, zMaster);
if( zSql==0 ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}else{
rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
sqlite3_free(zSql);
diff --git a/src/expr.c b/src/expr.c
index 8d96ba10c..3070de96f 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -2888,7 +2888,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
ExprList *pFarg; /* List of function arguments */
int nFarg; /* Number of function arguments */
FuncDef *pDef; /* The function definition object */
- int nId; /* Length of the function name in bytes */
const char *zId; /* The function name */
u32 constMask = 0; /* Mask of function arguments that are constant */
int i; /* Loop counter */
@@ -2904,10 +2903,9 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
nFarg = pFarg ? pFarg->nExpr : 0;
assert( !ExprHasProperty(pExpr, EP_IntValue) );
zId = pExpr->u.zToken;
- nId = sqlite3Strlen30(zId);
- pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0);
+ pDef = sqlite3FindFunction(db, zId, nFarg, enc, 0);
if( pDef==0 || pDef->xFinalize!=0 ){
- sqlite3ErrorMsg(pParse, "unknown function: %.*s()", nId, zId);
+ sqlite3ErrorMsg(pParse, "unknown function: %s()", zId);
break;
}
@@ -4132,7 +4130,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
pItem->iMem = ++pParse->nMem;
assert( !ExprHasProperty(pExpr, EP_IntValue) );
pItem->pFunc = sqlite3FindFunction(pParse->db,
- pExpr->u.zToken, sqlite3Strlen30(pExpr->u.zToken),
+ pExpr->u.zToken,
pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0);
if( pExpr->flags & EP_Distinct ){
pItem->iDistinct = pParse->nTab++;
diff --git a/src/func.c b/src/func.c
index d615cf90b..662a08f50 100644
--- a/src/func.c
+++ b/src/func.c
@@ -1611,7 +1611,7 @@ static void groupConcatFinalize(sqlite3_context *context){
** of the built-in functions above are part of the global function set.
** This routine only deals with those that are not global.
*/
-void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
+void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){
int rc = sqlite3_overload_function(db, "MATCH", 2);
assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
if( rc==SQLITE_NOMEM ){
@@ -1624,8 +1624,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
*/
static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){
FuncDef *pDef;
- pDef = sqlite3FindFunction(db, zName, sqlite3Strlen30(zName),
- 2, SQLITE_UTF8, 0);
+ pDef = sqlite3FindFunction(db, zName, 2, SQLITE_UTF8, 0);
if( ALWAYS(pDef) ){
pDef->funcFlags |= flagVal;
}
@@ -1673,9 +1672,7 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
return 0;
}
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- pDef = sqlite3FindFunction(db, pExpr->u.zToken,
- sqlite3Strlen30(pExpr->u.zToken),
- 2, SQLITE_UTF8, 0);
+ pDef = sqlite3FindFunction(db, pExpr->u.zToken, 2, SQLITE_UTF8, 0);
if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){
return 0;
}
@@ -1699,7 +1696,7 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
**
** After this routine runs
*/
-void sqlite3RegisterGlobalFunctions(void){
+void sqlite3RegisterBuiltinFunctions(void){
/*
** The following array holds FuncDef structures for all of the functions
** defined in this file.
@@ -1707,8 +1704,27 @@ void sqlite3RegisterGlobalFunctions(void){
** The array cannot be constant since changes are made to the
** FuncDef.pHash elements at start-time. The elements of this array
** are read-only after initialization is complete.
+ **
+ ** For peak efficiency, put the most frequently used function last.
*/
- static SQLITE_WSD FuncDef aBuiltinFunc[] = {
+ static FuncDef aBuiltinFunc[] = {
+#ifdef SQLITE_SOUNDEX
+ FUNCTION(soundex, 1, 0, 0, soundexFunc ),
+#endif
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
+ VFUNCTION(load_extension, 1, 0, 0, loadExt ),
+ VFUNCTION(load_extension, 2, 0, 0, loadExt ),
+#endif
+#if SQLITE_USER_AUTHENTICATION
+ FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ),
+#endif
+#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+ DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ),
+ DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ),
+#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
+ FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
+ FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
+ FUNCTION2(likely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
FUNCTION(rtrim, 1, 2, 0, trimFunc ),
@@ -1726,8 +1742,6 @@ void sqlite3RegisterGlobalFunctions(void){
FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF),
FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH),
FUNCTION(instr, 2, 0, 0, instrFunc ),
- FUNCTION(substr, 2, 0, 0, substrFunc ),
- FUNCTION(substr, 3, 0, 0, substrFunc ),
FUNCTION(printf, -1, 0, 0, printfFunc ),
FUNCTION(unicode, 1, 0, 0, unicodeFunc ),
FUNCTION(char, -1, 0, 0, charFunc ),
@@ -1738,40 +1752,22 @@ void sqlite3RegisterGlobalFunctions(void){
#endif
FUNCTION(upper, 1, 0, 0, upperFunc ),
FUNCTION(lower, 1, 0, 0, lowerFunc ),
- FUNCTION(coalesce, 1, 0, 0, 0 ),
- FUNCTION(coalesce, 0, 0, 0, 0 ),
- FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
FUNCTION(hex, 1, 0, 0, hexFunc ),
FUNCTION2(ifnull, 2, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
- FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
- FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
- FUNCTION2(likely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
VFUNCTION(random, 0, 0, 0, randomFunc ),
VFUNCTION(randomblob, 1, 0, 0, randomBlob ),
FUNCTION(nullif, 2, 0, 1, nullifFunc ),
DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ),
-#if SQLITE_USER_AUTHENTICATION
- FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ),
-#endif
-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
- DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ),
- DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ),
-#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
FUNCTION(quote, 1, 0, 0, quoteFunc ),
VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
VFUNCTION(changes, 0, 0, 0, changes ),
VFUNCTION(total_changes, 0, 0, 0, total_changes ),
FUNCTION(replace, 3, 0, 0, replaceFunc ),
FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ),
- #ifdef SQLITE_SOUNDEX
- FUNCTION(soundex, 1, 0, 0, soundexFunc ),
- #endif
- #ifndef SQLITE_OMIT_LOAD_EXTENSION
- VFUNCTION(load_extension, 1, 0, 0, loadExt ),
- VFUNCTION(load_extension, 2, 0, 0, loadExt ),
- #endif
+ FUNCTION(substr, 2, 0, 0, substrFunc ),
+ FUNCTION(substr, 3, 0, 0, substrFunc ),
AGGREGATE(sum, 1, 0, 0, sumStep, sumFinalize ),
AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ),
AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ),
@@ -1789,20 +1785,32 @@ void sqlite3RegisterGlobalFunctions(void){
LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
#endif
+ FUNCTION(coalesce, 1, 0, 0, 0 ),
+ FUNCTION(coalesce, 0, 0, 0, 0 ),
+ FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
};
-
- int i;
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
- FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aBuiltinFunc);
-
- for(i=0; i<ArraySize(aBuiltinFunc); i++){
- sqlite3FuncDefInsert(pHash, &aFunc[i]);
- }
- sqlite3RegisterDateTimeFunctions();
#ifndef SQLITE_OMIT_ALTERTABLE
sqlite3AlterFunctions();
#endif
#if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4)
sqlite3AnalyzeFunctions();
#endif
+ sqlite3RegisterDateTimeFunctions();
+ sqlite3InsertBuiltinFuncs(aBuiltinFunc, ArraySize(aBuiltinFunc));
+
+#if 0 /* Enable to print out how the built-in functions are hashed */
+ {
+ int i;
+ FuncDef *p;
+ for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
+ printf("FUNC-HASH %02d:", i);
+ for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash){
+ int n = sqlite3Strlen30(p->zName);
+ int h = p->zName[0] + n;
+ printf(" %s(%d)", p->zName, h);
+ }
+ printf("\n");
+ }
+ }
+#endif
}
diff --git a/src/global.c b/src/global.c
index 64966b35d..294d62fea 100644
--- a/src/global.c
+++ b/src/global.c
@@ -219,7 +219,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
** database connections. After initialization, this table is
** read-only.
*/
-SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
+FuncDefHash sqlite3BuiltinFunctions;
/*
** Constant tokens for values 0 and 1.
diff --git a/src/journal.c b/src/journal.c
index fed27be3e..a5cf8c8e2 100644
--- a/src/journal.c
+++ b/src/journal.c
@@ -212,7 +212,7 @@ int sqlite3JournalOpen(
if( nBuf>0 ){
p->zBuf = sqlite3MallocZero(nBuf);
if( !p->zBuf ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
}else{
return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0);
diff --git a/src/legacy.c b/src/legacy.c
index 1b5e518d4..bd34512d3 100644
--- a/src/legacy.c
+++ b/src/legacy.c
@@ -131,7 +131,7 @@ exec_out:
if( *pzErrMsg ){
memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg);
}else{
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
sqlite3Error(db, SQLITE_NOMEM);
}
}else if( pzErrMsg ){
diff --git a/src/loadext.c b/src/loadext.c
index 94298c476..3469fbb73 100644
--- a/src/loadext.c
+++ b/src/loadext.c
@@ -478,7 +478,7 @@ static int sqlite3LoadExtension(
#if SQLITE_OS_UNIX || SQLITE_OS_WIN
for(ii=0; ii<ArraySize(azEndings) && handle==0; ii++){
char *zAltFile = sqlite3_mprintf("%s.%s", zFile, azEndings[ii]);
- if( zAltFile==0 ) return SQLITE_NOMEM;
+ if( zAltFile==0 ) return SQLITE_NOMEM_BKPT;
handle = sqlite3OsDlOpen(pVfs, zAltFile);
sqlite3_free(zAltFile);
}
@@ -514,7 +514,7 @@ static int sqlite3LoadExtension(
zAltEntry = sqlite3_malloc64(ncFile+30);
if( zAltEntry==0 ){
sqlite3OsDlClose(pVfs, handle);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memcpy(zAltEntry, "sqlite3_", 8);
for(iFile=ncFile-1; iFile>=0 && zFile[iFile]!='/'; iFile--){}
@@ -557,7 +557,7 @@ static int sqlite3LoadExtension(
/* Append the new shared library handle to the db->aExtension array. */
aHandle = sqlite3DbMallocZero(db, sizeof(handle)*(db->nExtension+1));
if( aHandle==0 ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
if( db->nExtension>0 ){
memcpy(aHandle, db->aExtension, sizeof(handle)*db->nExtension);
@@ -679,7 +679,7 @@ int sqlite3_auto_extension(void (*xInit)(void)){
void (**aNew)(void);
aNew = sqlite3_realloc64(wsdAutoext.aExt, nByte);
if( aNew==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
wsdAutoext.aExt = aNew;
wsdAutoext.aExt[wsdAutoext.nExt] = xInit;
diff --git a/src/main.c b/src/main.c
index 5def95d32..9a8c156c6 100644
--- a/src/main.c
+++ b/src/main.c
@@ -187,7 +187,7 @@ int sqlite3_initialize(void){
sqlite3GlobalConfig.pInitMutex =
sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
if( sqlite3GlobalConfig.bCoreMutex && !sqlite3GlobalConfig.pInitMutex ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
}
}
@@ -218,7 +218,6 @@ int sqlite3_initialize(void){
*/
sqlite3_mutex_enter(sqlite3GlobalConfig.pInitMutex);
if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
sqlite3GlobalConfig.inProgress = 1;
#ifdef SQLITE_ENABLE_SQLLOG
{
@@ -226,8 +225,8 @@ int sqlite3_initialize(void){
sqlite3_init_sqllog();
}
#endif
- memset(pHash, 0, sizeof(sqlite3GlobalFunctions));
- sqlite3RegisterGlobalFunctions();
+ memset(&sqlite3BuiltinFunctions, 0, sizeof(sqlite3BuiltinFunctions));
+ sqlite3RegisterBuiltinFunctions();
if( sqlite3GlobalConfig.isPCacheInit==0 ){
rc = sqlite3PcacheInitialize();
}
@@ -958,7 +957,7 @@ void sqlite3CloseSavepoints(sqlite3 *db){
** with SQLITE_ANY as the encoding.
*/
static void functionDestroy(sqlite3 *db, FuncDef *p){
- FuncDestructor *pDestructor = p->pDestructor;
+ FuncDestructor *pDestructor = p->u.pDestructor;
if( pDestructor ){
pDestructor->nRef--;
if( pDestructor->nRef==0 ){
@@ -1140,18 +1139,17 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
*/
sqlite3ConnectionClosed(db);
- for(j=0; j<ArraySize(db->aFunc.a); j++){
- FuncDef *pNext, *pHash, *p;
- for(p=db->aFunc.a[j]; p; p=pHash){
- pHash = p->pHash;
- while( p ){
- functionDestroy(db, p);
- pNext = p->pNext;
- sqlite3DbFree(db, p);
- p = pNext;
- }
- }
- }
+ for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
+ FuncDef *pNext, *p;
+ p = sqliteHashData(i);
+ do{
+ functionDestroy(db, p);
+ pNext = p->pNext;
+ sqlite3DbFree(db, p);
+ p = pNext;
+ }while( p );
+ }
+ sqlite3HashClear(&db->aFunc);
for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){
CollSeq *pColl = (CollSeq *)sqliteHashData(i);
/* Invoke any destructors registered for collation sequence user data. */
@@ -1630,7 +1628,7 @@ int sqlite3CreateFunc(
** is being overridden/deleted but there are no active VMs, allow the
** operation to continue but invalidate all precompiled statements.
*/
- p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0);
+ p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 0);
if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){
if( db->nVdbeActive ){
sqlite3ErrorWithMsg(db, SQLITE_BUSY,
@@ -1642,10 +1640,10 @@ int sqlite3CreateFunc(
}
}
- p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 1);
+ p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 1);
assert(p || db->mallocFailed);
if( !p ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
/* If an older version of the function with a configured destructor is
@@ -1655,7 +1653,7 @@ int sqlite3CreateFunc(
if( pDestructor ){
pDestructor->nRef++;
}
- p->pDestructor = pDestructor;
+ p->u.pDestructor = pDestructor;
p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags;
testcase( p->funcFlags & SQLITE_DETERMINISTIC );
p->xSFunc = xSFunc ? xSFunc : xStep;
@@ -1770,7 +1768,6 @@ int sqlite3_overload_function(
const char *zName,
int nArg
){
- int nName = sqlite3Strlen30(zName);
int rc = SQLITE_OK;
#ifdef SQLITE_ENABLE_API_ARMOR
@@ -1779,7 +1776,7 @@ int sqlite3_overload_function(
}
#endif
sqlite3_mutex_enter(db->mutex);
- if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
+ if( sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)==0 ){
rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
0, sqlite3InvalidFunction, 0, 0, 0);
}
@@ -2170,14 +2167,14 @@ int sqlite3TempInMemory(const sqlite3 *db){
const char *sqlite3_errmsg(sqlite3 *db){
const char *z;
if( !db ){
- return sqlite3ErrStr(SQLITE_NOMEM);
+ return sqlite3ErrStr(SQLITE_NOMEM_BKPT);
}
if( !sqlite3SafetyCheckSickOrOk(db) ){
return sqlite3ErrStr(SQLITE_MISUSE_BKPT);
}
sqlite3_mutex_enter(db->mutex);
if( db->mallocFailed ){
- z = sqlite3ErrStr(SQLITE_NOMEM);
+ z = sqlite3ErrStr(SQLITE_NOMEM_BKPT);
}else{
testcase( db->pErr==0 );
z = (char*)sqlite3_value_text(db->pErr);
@@ -2245,7 +2242,7 @@ int sqlite3_errcode(sqlite3 *db){
return SQLITE_MISUSE_BKPT;
}
if( !db || db->mallocFailed ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
return db->errCode & db->errMask;
}
@@ -2254,7 +2251,7 @@ int sqlite3_extended_errcode(sqlite3 *db){
return SQLITE_MISUSE_BKPT;
}
if( !db || db->mallocFailed ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
return db->errCode;
}
@@ -2334,7 +2331,7 @@ static int createCollation(
}
pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 1);
- if( pColl==0 ) return SQLITE_NOMEM;
+ if( pColl==0 ) return SQLITE_NOMEM_BKPT;
pColl->xCmp = xCompare;
pColl->pUser = pCtx;
pColl->xDel = xDel;
@@ -2382,8 +2379,8 @@ static const int aHardLimit[] = {
#if SQLITE_MAX_VDBE_OP<40
# error SQLITE_MAX_VDBE_OP must be at least 40
#endif
-#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000
-# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000
+#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>127
+# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 127
#endif
#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125
# error SQLITE_MAX_ATTACHED must be between 0 and 125
@@ -2513,7 +2510,7 @@ int sqlite3ParseUri(
for(iIn=0; iIn<nUri; iIn++) nByte += (zUri[iIn]=='&');
zFile = sqlite3_malloc64(nByte);
- if( !zFile ) return SQLITE_NOMEM;
+ if( !zFile ) return SQLITE_NOMEM_BKPT;
iIn = 5;
#ifdef SQLITE_ALLOW_URI_AUTHORITY
@@ -2679,7 +2676,7 @@ int sqlite3ParseUri(
}else{
zFile = sqlite3_malloc64(nUri+2);
- if( !zFile ) return SQLITE_NOMEM;
+ if( !zFile ) return SQLITE_NOMEM_BKPT;
memcpy(zFile, zUri, nUri);
zFile[nUri] = '\0';
zFile[nUri+1] = '\0';
@@ -2878,7 +2875,7 @@ static int openDatabase(
flags | SQLITE_OPEN_MAIN_DB);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_IOERR_NOMEM ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
sqlite3Error(db, rc);
goto opendb_out;
@@ -2889,13 +2886,13 @@ static int openDatabase(
sqlite3BtreeLeave(db->aDb[0].pBt);
db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);
- /* The default safety_level for the main database is 'full'; for the temp
- ** database it is 'NONE'. This matches the pager layer defaults.
+ /* The default safety_level for the main database is FULL; for the temp
+ ** database it is OFF. This matches the pager layer defaults.
*/
db->aDb[0].zName = "main";
- db->aDb[0].safety_level = 3;
+ db->aDb[0].safety_level = PAGER_SYNCHRONOUS_FULL;
db->aDb[1].zName = "temp";
- db->aDb[1].safety_level = 1;
+ db->aDb[1].safety_level = PAGER_SYNCHRONOUS_OFF;
db->magic = SQLITE_MAGIC_OPEN;
if( db->mallocFailed ){
@@ -2907,7 +2904,7 @@ static int openDatabase(
** is accessed.
*/
sqlite3Error(db, SQLITE_OK);
- sqlite3RegisterBuiltinFunctions(db);
+ sqlite3RegisterPerConnectionBuiltinFunctions(db);
/* Load automatic extensions - extensions that have been registered
** using the sqlite3_automatic_extension() API.
@@ -3081,7 +3078,7 @@ int sqlite3_open16(
SCHEMA_ENC(*ppDb) = ENC(*ppDb) = SQLITE_UTF16NATIVE;
}
}else{
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
sqlite3ValueFree(pVal);
@@ -3226,7 +3223,7 @@ int sqlite3_get_autocommit(sqlite3 *db){
/*
** The following routines are substitutes for constants SQLITE_CORRUPT,
-** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_IOERR and possibly other error
+** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_NOMEM and possibly other error
** constants. They serve two purposes:
**
** 1. Serve as a convenient place to set a breakpoint in a debugger
@@ -3235,28 +3232,33 @@ int sqlite3_get_autocommit(sqlite3 *db){
** 2. Invoke sqlite3_log() to provide the source code location where
** a low-level error is first detected.
*/
+static int reportError(int iErr, int lineno, const char *zType){
+ sqlite3_log(iErr, "%s at line %d of [%.10s]",
+ zType, lineno, 20+sqlite3_sourceid());
+ return iErr;
+}
int sqlite3CorruptError(int lineno){
testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(SQLITE_CORRUPT,
- "database corruption at line %d of [%.10s]",
- lineno, 20+sqlite3_sourceid());
- return SQLITE_CORRUPT;
+ return reportError(SQLITE_CORRUPT, lineno, "database corruption");
}
int sqlite3MisuseError(int lineno){
testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(SQLITE_MISUSE,
- "misuse at line %d of [%.10s]",
- lineno, 20+sqlite3_sourceid());
- return SQLITE_MISUSE;
+ return reportError(SQLITE_MISUSE, lineno, "misuse");
}
int sqlite3CantopenError(int lineno){
testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(SQLITE_CANTOPEN,
- "cannot open file at line %d of [%.10s]",
- lineno, 20+sqlite3_sourceid());
- return SQLITE_CANTOPEN;
+ return reportError(SQLITE_CANTOPEN, lineno, "cannot open file");
}
-
+#ifdef SQLITE_DEBUG
+int sqlite3NomemError(int lineno){
+ testcase( sqlite3GlobalConfig.xLog!=0 );
+ return reportError(SQLITE_NOMEM, lineno, "OOM");
+}
+int sqlite3IoerrnomemError(int lineno){
+ testcase( sqlite3GlobalConfig.xLog!=0 );
+ return reportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error");
+}
+#endif
#ifndef SQLITE_OMIT_DEPRECATED
/*
diff --git a/src/malloc.c b/src/malloc.c
index ebe044035..462d78e68 100644
--- a/src/malloc.c
+++ b/src/malloc.c
@@ -795,7 +795,7 @@ void sqlite3OomClear(sqlite3 *db){
static SQLITE_NOINLINE int apiOomError(sqlite3 *db){
sqlite3OomClear(db);
sqlite3Error(db, SQLITE_NOMEM);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
/*
diff --git a/src/memjournal.c b/src/memjournal.c
index 6452cecc3..62594530e 100644
--- a/src/memjournal.c
+++ b/src/memjournal.c
@@ -133,7 +133,7 @@ static int memjrnlWrite(
/* New chunk is required to extend the file. */
FileChunk *pNew = sqlite3_malloc(sizeof(FileChunk));
if( !pNew ){
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
pNew->pNext = 0;
if( pChunk ){
diff --git a/src/os.c b/src/os.c
index 90130d0eb..2fd44abf8 100644
--- a/src/os.c
+++ b/src/os.c
@@ -68,7 +68,7 @@ int sqlite3_memdebug_vfs_oom_test = 1;
#define DO_OS_MALLOC_TEST(x) \
if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) { \
void *pTstAlloc = sqlite3Malloc(10); \
- if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \
+ if (!pTstAlloc) return SQLITE_IOERR_NOMEM_BKPT; \
sqlite3_free(pTstAlloc); \
}
#else
@@ -287,7 +287,7 @@ int sqlite3OsOpenMalloc(
int flags,
int *pOutFlags
){
- int rc = SQLITE_NOMEM;
+ int rc;
sqlite3_file *pFile;
pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
if( pFile ){
@@ -297,6 +297,8 @@ int sqlite3OsOpenMalloc(
}else{
*ppFile = pFile;
}
+ }else{
+ rc = SQLITE_NOMEM_BKPT;
}
return rc;
}
@@ -316,7 +318,7 @@ int sqlite3OsCloseFree(sqlite3_file *pFile){
*/
int sqlite3OsInit(void){
void *p = sqlite3_malloc(10);
- if( p==0 ) return SQLITE_NOMEM;
+ if( p==0 ) return SQLITE_NOMEM_BKPT;
sqlite3_free(p);
return sqlite3_os_init();
}
diff --git a/src/os_unix.c b/src/os_unix.c
index fe1fc6af1..ea07bd99f 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -1302,7 +1302,7 @@ static int findInodeInfo(
if( pInode==0 ){
pInode = sqlite3_malloc64( sizeof(*pInode) );
if( pInode==0 ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memset(pInode, 0, sizeof(*pInode));
memcpy(&pInode->fileId, &fileId, sizeof(fileId));
@@ -4222,7 +4222,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
/* Allocate space for the new unixShm object. */
p = sqlite3_malloc64( sizeof(*p) );
- if( p==0 ) return SQLITE_NOMEM;
+ if( p==0 ) return SQLITE_NOMEM_BKPT;
memset(p, 0, sizeof(*p));
assert( pDbFd->pShm==0 );
@@ -4254,7 +4254,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
#endif
pShmNode = sqlite3_malloc64( sizeof(*pShmNode) + nShmFilename );
if( pShmNode==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto shm_open_err;
}
memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename);
@@ -4272,7 +4272,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
pShmNode->pInode = pDbFd->pInode;
pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
if( pShmNode->mutex==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto shm_open_err;
}
@@ -4445,7 +4445,7 @@ static int unixShmMap(
pShmNode->apRegion, nReqRegion*sizeof(char *)
);
if( !apNew ){
- rc = SQLITE_IOERR_NOMEM;
+ rc = SQLITE_IOERR_NOMEM_BKPT;
goto shmpage_out;
}
pShmNode->apRegion = apNew;
@@ -4465,7 +4465,7 @@ static int unixShmMap(
}else{
pMem = sqlite3_malloc64(szRegion);
if( pMem==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto shmpage_out;
}
memset(pMem, 0, szRegion);
@@ -5243,7 +5243,7 @@ static int fillInUnixFile(
pNew->pId = vxworksFindFileId(zFilename);
if( pNew->pId==0 ){
ctrlFlags |= UNIXFILE_NOLOCK;
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
#endif
@@ -5299,7 +5299,7 @@ static int fillInUnixFile(
afpLockingContext *pCtx;
pNew->lockingContext = pCtx = sqlite3_malloc64( sizeof(*pCtx) );
if( pCtx==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
/* NB: zFilename exists and remains valid until the file is closed
** according to requirement F11141. So we do not need to make a
@@ -5329,7 +5329,7 @@ static int fillInUnixFile(
nFilename = (int)strlen(zFilename) + 6;
zLockFile = (char *)sqlite3_malloc64(nFilename);
if( zLockFile==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename);
}
@@ -5352,7 +5352,7 @@ static int fillInUnixFile(
if( zSemName[n]=='/' ) zSemName[n] = '_';
pNew->pInode->pSem = sem_open(zSemName, O_CREAT, 0666, 1);
if( pNew->pInode->pSem == SEM_FAILED ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
pNew->pInode->aSemName[0] = '\0';
}
}
@@ -5693,7 +5693,7 @@ static int unixOpen(
}else{
pUnused = sqlite3_malloc64(sizeof(*pUnused));
if( !pUnused ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
}
p->pUnused = pUnused;
@@ -5779,7 +5779,7 @@ static int unixOpen(
zPath = sqlite3_mprintf("%s", zName);
if( zPath==0 ){
robust_close(p, fd, __LINE__);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
#else
osUnlink(zName);
@@ -6011,7 +6011,7 @@ static int unixFullPathname(
if( bLink ){
if( zDel==0 ){
zDel = sqlite3_malloc(nOut);
- if( zDel==0 ) rc = SQLITE_NOMEM;
+ if( zDel==0 ) rc = SQLITE_NOMEM_BKPT;
}else if( ++nLink>SQLITE_MAX_SYMLINKS ){
rc = SQLITE_CANTOPEN_BKPT;
}
@@ -6555,7 +6555,7 @@ static int proxyCreateUnixFile(
}else{
pUnused = sqlite3_malloc64(sizeof(*pUnused));
if( !pUnused ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
}
if( fd<0 ){
@@ -6588,7 +6588,7 @@ static int proxyCreateUnixFile(
pNew = (unixFile *)sqlite3_malloc64(sizeof(*pNew));
if( pNew==NULL ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto end_create_proxy;
}
memset(pNew, 0, sizeof(unixFile));
@@ -7001,7 +7001,7 @@ static int proxyTakeConch(unixFile *pFile){
if( tempLockPath ){
pCtx->lockProxyPath = sqlite3DbStrDup(0, tempLockPath);
if( !pCtx->lockProxyPath ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
}
}
@@ -7066,7 +7066,7 @@ static int proxyCreateConchPathname(char *dbPath, char **pConchPath){
** the name of the original database file. */
*pConchPath = conchPath = (char *)sqlite3_malloc64(len + 8);
if( conchPath==0 ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memcpy(conchPath, dbPath, len+1);
@@ -7182,7 +7182,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
pCtx = sqlite3_malloc64( sizeof(*pCtx) );
if( pCtx==0 ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memset(pCtx, 0, sizeof(*pCtx));
@@ -7218,7 +7218,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
if( rc==SQLITE_OK ){
pCtx->dbPath = sqlite3DbStrDup(0, dbPath);
if( pCtx->dbPath==NULL ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
}
if( rc==SQLITE_OK ){
diff --git a/src/os_win.c b/src/os_win.c
index eda6cf59f..af6b1c814 100644
--- a/src/os_win.c
+++ b/src/os_win.c
@@ -1222,7 +1222,7 @@ int sqlite3_win32_compact_heap(LPUINT pnLargest){
if( lastErrno==NO_ERROR ){
sqlite3_log(SQLITE_NOMEM, "failed to HeapCompact (no space), heap=%p",
(void*)hHeap);
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
sqlite3_log(SQLITE_ERROR, "failed to HeapCompact (%lu), heap=%p",
osGetLastError(), (void*)hHeap);
@@ -1542,7 +1542,7 @@ static int winMemInit(void *pAppData){
"failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu",
osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize,
dwMaximumSize);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pWinMemData->bOwned = TRUE;
assert( pWinMemData->bOwned );
@@ -1552,7 +1552,7 @@ static int winMemInit(void *pAppData){
if( !pWinMemData->hHeap ){
sqlite3_log(SQLITE_NOMEM,
"failed to GetProcessHeap (%lu)", osGetLastError());
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pWinMemData->bOwned = FALSE;
assert( !pWinMemData->bOwned );
@@ -1789,7 +1789,7 @@ int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
if( zValue && zValue[0] ){
zValueUtf8 = winUnicodeToUtf8(zValue);
if ( zValueUtf8==0 ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
}
sqlite3_free(*ppDirectory);
@@ -2066,7 +2066,7 @@ static int winceCreateLock(const char *zFilename, winFile *pFile){
zName = winUtf8ToUnicode(zFilename);
if( zName==0 ){
/* out of memory */
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
/* Initialize the local lockdata */
@@ -3615,12 +3615,12 @@ static int winOpenSharedMemory(winFile *pDbFd){
** allocate space for a new winShmNode and filename.
*/
p = sqlite3MallocZero( sizeof(*p) );
- if( p==0 ) return SQLITE_IOERR_NOMEM;
+ if( p==0 ) return SQLITE_IOERR_NOMEM_BKPT;
nName = sqlite3Strlen30(pDbFd->zPath);
pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 );
if( pNew==0 ){
sqlite3_free(p);
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
pNew->zFilename = (char*)&pNew[1];
sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
@@ -3647,7 +3647,7 @@ static int winOpenSharedMemory(winFile *pDbFd){
pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
if( pShmNode->mutex==0 ){
- rc = SQLITE_IOERR_NOMEM;
+ rc = SQLITE_IOERR_NOMEM_BKPT;
goto shm_open_err;
}
@@ -3952,7 +3952,7 @@ static int winShmMap(
pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
);
if( !apNew ){
- rc = SQLITE_IOERR_NOMEM;
+ rc = SQLITE_IOERR_NOMEM_BKPT;
goto shmpage_out;
}
pShmNode->aRegion = apNew;
@@ -4382,7 +4382,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
zBuf = sqlite3MallocZero( nBuf );
if( !zBuf ){
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
/* Figure out the effective temporary directory. First, check if one
@@ -4440,7 +4440,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
if( !zConverted ){
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( winIsDir(zConverted) ){
sqlite3_snprintf(nMax, zBuf, "%s", zDir);
@@ -4453,7 +4453,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
if( !zConverted ){
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( cygwin_conv_path(
osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir,
@@ -4474,7 +4474,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
sqlite3_free(zConverted);
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
sqlite3_free(zUtf8);
@@ -4492,7 +4492,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
if( !zWidePath ){
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( osGetTempPathW(nMax, zWidePath)==0 ){
sqlite3_free(zWidePath);
@@ -4510,7 +4510,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
sqlite3_free(zWidePath);
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
}
#ifdef SQLITE_WIN32_HAS_ANSI
@@ -4520,7 +4520,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
if( !zMbcsPath ){
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( osGetTempPathA(nMax, zMbcsPath)==0 ){
sqlite3_free(zBuf);
@@ -4535,7 +4535,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
}else{
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
}
#endif /* SQLITE_WIN32_HAS_ANSI */
@@ -4727,7 +4727,7 @@ static int winOpen(
if( zConverted==0 ){
sqlite3_free(zTmpname);
OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( winIsDir(zConverted) ){
@@ -4927,7 +4927,7 @@ static int winDelete(
zConverted = winConvertFromUtf8Filename(zFilename);
if( zConverted==0 ){
OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( osIsNT() ){
do {
@@ -5035,7 +5035,7 @@ static int winAccess(
zConverted = winConvertFromUtf8Filename(zFilename);
if( zConverted==0 ){
OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( osIsNT() ){
int cnt = 0;
@@ -5162,7 +5162,7 @@ static int winFullPathname(
*/
char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
if( !zOut ){
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( cygwin_conv_path(
(osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) |
@@ -5174,7 +5174,7 @@ static int winFullPathname(
char *zUtf8 = winConvertToUtf8Filename(zOut);
if( !zUtf8 ){
sqlite3_free(zOut);
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
sqlite3_data_directory, winGetDirSep(), zUtf8);
@@ -5184,7 +5184,7 @@ static int winFullPathname(
}else{
char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
if( !zOut ){
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( cygwin_conv_path(
(osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A),
@@ -5196,7 +5196,7 @@ static int winFullPathname(
char *zUtf8 = winConvertToUtf8Filename(zOut);
if( !zUtf8 ){
sqlite3_free(zOut);
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8);
sqlite3_free(zUtf8);
@@ -5256,7 +5256,7 @@ static int winFullPathname(
}
zConverted = winConvertFromUtf8Filename(zRelative);
if( zConverted==0 ){
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( osIsNT() ){
LPWSTR zTemp;
@@ -5270,7 +5270,7 @@ static int winFullPathname(
zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
if( zTemp==0 ){
sqlite3_free(zConverted);
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
if( nByte==0 ){
@@ -5296,7 +5296,7 @@ static int winFullPathname(
zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
if( zTemp==0 ){
sqlite3_free(zConverted);
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
if( nByte==0 ){
@@ -5315,7 +5315,7 @@ static int winFullPathname(
sqlite3_free(zOut);
return SQLITE_OK;
}else{
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
#endif
}
@@ -5390,65 +5390,85 @@ static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
#define winDlClose 0
#endif
+/* State information for the randomness gatherer. */
+typedef struct EntropyGatherer EntropyGatherer;
+struct EntropyGatherer {
+ unsigned char *a; /* Gather entropy into this buffer */
+ int na; /* Size of a[] in bytes */
+ int i; /* XOR next input into a[i] */
+ int nXor; /* Number of XOR operations done */
+};
+
+#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS)
+/* Mix sz bytes of entropy into p. */
+static void xorMemory(EntropyGatherer *p, unsigned char *x, int sz){
+ int j, k;
+ for(j=0, k=p->i; j<sz; j++){
+ p->a[k++] ^= x[j];
+ if( k>=p->na ) k = 0;
+ }
+ p->i = k;
+ p->nXor += sz;
+}
+#endif /* !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) */
/*
** Write up to nBuf bytes of randomness into zBuf.
*/
static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
- int n = 0;
- UNUSED_PARAMETER(pVfs);
#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS)
- n = nBuf;
+ UNUSED_PARAMETER(pVfs);
memset(zBuf, 0, nBuf);
+ return nBuf;
#else
- if( sizeof(SYSTEMTIME)<=nBuf-n ){
+ EntropyGatherer e;
+ UNUSED_PARAMETER(pVfs);
+ memset(zBuf, 0, nBuf);
+#if defined(_MSC_VER) && _MSC_VER>=1400
+ rand_s((int*)zBuf); /* rand_s() is not available with MinGW */
+#endif /* defined(_MSC_VER) && _MSC_VER>=1400 */
+ e.a = (unsigned char*)zBuf;
+ e.na = nBuf;
+ e.nXor = 0;
+ e.i = 0;
+ {
SYSTEMTIME x;
osGetSystemTime(&x);
- memcpy(&zBuf[n], &x, sizeof(x));
- n += sizeof(x);
+ xorMemory(&e, (unsigned char*)&x, sizeof(SYSTEMTIME));
}
- if( sizeof(DWORD)<=nBuf-n ){
+ {
DWORD pid = osGetCurrentProcessId();
- memcpy(&zBuf[n], &pid, sizeof(pid));
- n += sizeof(pid);
+ xorMemory(&e, (unsigned char*)&pid, sizeof(DWORD));
}
#if SQLITE_OS_WINRT
- if( sizeof(ULONGLONG)<=nBuf-n ){
+ {
ULONGLONG cnt = osGetTickCount64();
- memcpy(&zBuf[n], &cnt, sizeof(cnt));
- n += sizeof(cnt);
+ xorMemory(&e, (unsigned char*)&cnt, sizeof(ULONGLONG));
}
#else
- if( sizeof(DWORD)<=nBuf-n ){
+ {
DWORD cnt = osGetTickCount();
- memcpy(&zBuf[n], &cnt, sizeof(cnt));
- n += sizeof(cnt);
+ xorMemory(&e, (unsigned char*)&cnt, sizeof(DWORD));
}
-#endif
- if( sizeof(LARGE_INTEGER)<=nBuf-n ){
+#endif /* SQLITE_OS_WINRT */
+ {
LARGE_INTEGER i;
osQueryPerformanceCounter(&i);
- memcpy(&zBuf[n], &i, sizeof(i));
- n += sizeof(i);
+ xorMemory(&e, (unsigned char*)&i, sizeof(LARGE_INTEGER));
}
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
- if( sizeof(UUID)<=nBuf-n ){
+ {
UUID id;
memset(&id, 0, sizeof(UUID));
osUuidCreate(&id);
- memcpy(&zBuf[n], &id, sizeof(UUID));
- n += sizeof(UUID);
- }
- if( sizeof(UUID)<=nBuf-n ){
- UUID id;
+ xorMemory(&e, (unsigned char*)&id, sizeof(UUID));
memset(&id, 0, sizeof(UUID));
osUuidCreateSequential(&id);
- memcpy(&zBuf[n], &id, sizeof(UUID));
- n += sizeof(UUID);
+ xorMemory(&e, (unsigned char*)&id, sizeof(UUID));
}
-#endif
-#endif /* defined(SQLITE_TEST) || defined(SQLITE_ZERO_PRNG_SEED) */
- return n;
+#endif /* !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID */
+ return e.nXor>nBuf ? nBuf : e.nXor;
+#endif /* defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) */
}
diff --git a/src/pager.c b/src/pager.c
index 5c61968e3..51bd45e48 100644
--- a/src/pager.c
+++ b/src/pager.c
@@ -2324,9 +2324,9 @@ static int pager_playback_one_page(
pPager->dbFileSize = pgno;
}
if( pPager->pBackup ){
- CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM);
+ CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
- CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM, aData);
+ CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData);
}
}else if( !isMainJrnl && pPg==0 ){
/* If this is a rollback of a savepoint and data was not written to
@@ -2398,7 +2398,7 @@ static int pager_playback_one_page(
}
/* Decode the page just read from disk */
- CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM);
+ CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT);
sqlite3PcacheRelease(pPg);
}
return rc;
@@ -2464,7 +2464,7 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){
pMaster = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2);
pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile);
if( !pMaster ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0);
@@ -2481,7 +2481,7 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){
nMasterPtr = pVfs->mxPathname+1;
zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 1);
if( !zMasterJournal ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto delmaster_out;
}
zMasterPtr = &zMasterJournal[nMasterJournal+1];
@@ -2951,7 +2951,7 @@ static int readDbPage(PgHdr *pPg, u32 iFrame){
memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers));
}
}
- CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM);
+ CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM_BKPT);
PAGER_INCR(sqlite3_pager_readdb_count);
PAGER_INCR(pPager->nRead);
@@ -3311,7 +3311,7 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){
if( pSavepoint ){
pDone = sqlite3BitvecCreate(pSavepoint->nOrig);
if( !pDone ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
}
@@ -3674,7 +3674,7 @@ int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){
}
if( rc==SQLITE_OK ){
pNew = (char *)sqlite3PageMalloc(pageSize);
- if( !pNew ) rc = SQLITE_NOMEM;
+ if( !pNew ) rc = SQLITE_NOMEM_BKPT;
}
if( rc==SQLITE_OK ){
@@ -3950,7 +3950,7 @@ static int pagerAcquireMapPage(
*ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra);
if( p==0 ){
sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
p->pExtra = (void *)&p[1];
p->flags = PGHDR_MMAP;
@@ -4308,7 +4308,7 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
if( pList->pgno==1 ) pager_write_changecounter(pList);
/* Encode the database */
- CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData);
+ CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM_BKPT, pData);
/* Write out the page data. */
rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
@@ -4395,7 +4395,7 @@ static int subjournalPage(PgHdr *pPg){
i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize);
char *pData2;
- CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
+ CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
rc = write32bits(pPager->sjfd, offset, pPg->pgno);
if( rc==SQLITE_OK ){
@@ -4599,7 +4599,7 @@ int sqlite3PagerOpen(
memDb = 1;
if( zFilename && zFilename[0] ){
zPathname = sqlite3DbStrDup(0, zFilename);
- if( zPathname==0 ) return SQLITE_NOMEM;
+ if( zPathname==0 ) return SQLITE_NOMEM_BKPT;
nPathname = sqlite3Strlen30(zPathname);
zFilename = 0;
}
@@ -4615,7 +4615,7 @@ int sqlite3PagerOpen(
nPathname = pVfs->mxPathname+1;
zPathname = sqlite3DbMallocRaw(0, nPathname*2);
if( zPathname==0 ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */
rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
@@ -4668,7 +4668,7 @@ int sqlite3PagerOpen(
assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
if( !pPtr ){
sqlite3DbFree(0, zPathname);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pPager = (Pager*)(pPtr);
pPager->pPCache = (PCache*)(pPtr += ROUND8(sizeof(*pPager)));
@@ -5388,7 +5388,7 @@ int sqlite3PagerGet(
if( rc!=SQLITE_OK ) goto pager_acquire_err;
if( pBase==0 ){
pPg = *ppPage = 0;
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto pager_acquire_err;
}
}
@@ -5562,7 +5562,7 @@ static int pager_open_journal(Pager *pPager){
if( !pagerUseWal(pPager) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize);
if( pPager->pInJournal==0 ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
/* Open the journal file if it is not already open. */
@@ -5717,7 +5717,7 @@ static SQLITE_NOINLINE int pagerAddPageToRollbackJournal(PgHdr *pPg){
assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
assert( pPager->journalHdr<=pPager->journalOff );
- CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
+ CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
cksum = pager_cksum(pPager, (u8*)pData2);
/* Even if an IO or diskfull error occurs while journalling the
@@ -6074,7 +6074,7 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
if( DIRECT_MODE ){
const void *zBuf;
assert( pPager->dbFileSize>0 );
- CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM, zBuf);
+ CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM_BKPT, zBuf);
if( rc==SQLITE_OK ){
rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0);
pPager->aStat[PAGER_STAT_WRITE]++;
@@ -6573,7 +6573,7 @@ static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){
pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint
);
if( !aNew ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint));
pPager->aSavepoint = aNew;
@@ -6589,7 +6589,7 @@ static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){
aNew[ii].iSubRec = pPager->nSubRec;
aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize);
if( !aNew[ii].pInSavepoint ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
if( pagerUseWal(pPager) ){
sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData);
@@ -6738,14 +6738,6 @@ const char *sqlite3PagerJournalname(Pager *pPager){
return pPager->zJournal;
}
-/*
-** Return true if fsync() calls are disabled for this pager. Return FALSE
-** if fsync()s are executed normally.
-*/
-int sqlite3PagerNosync(Pager *pPager){
- return pPager->noSync;
-}
-
#ifdef SQLITE_HAS_CODEC
/*
** Set or retrieve the codec for this pager
diff --git a/src/pager.h b/src/pager.h
index 8d9f08108..38a498215 100644
--- a/src/pager.h
+++ b/src/pager.h
@@ -191,7 +191,6 @@ sqlite3_vfs *sqlite3PagerVfs(Pager*);
sqlite3_file *sqlite3PagerFile(Pager*);
sqlite3_file *sqlite3PagerJrnlFile(Pager*);
const char *sqlite3PagerJournalname(Pager*);
-int sqlite3PagerNosync(Pager*);
void *sqlite3PagerTempSpace(Pager*);
int sqlite3PagerIsMemdb(Pager*);
void sqlite3PagerCacheStat(Pager *, int, int, int *);
diff --git a/src/parse.y b/src/parse.y
index 0bfe4e473..e7e0d1d95 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -35,7 +35,6 @@
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
}
%stack_overflow {
- UNUSED_PARAMETER(yypMinor); /* Silence some compiler warnings */
sqlite3ErrorMsg(pParse, "parser stack overflow");
}
@@ -139,9 +138,9 @@ trans_opt ::= TRANSACTION.
trans_opt ::= TRANSACTION nm.
%type transtype {int}
transtype(A) ::= . {A = TK_DEFERRED;}
-transtype(A) ::= DEFERRED(X). {A = @X;}
-transtype(A) ::= IMMEDIATE(X). {A = @X;}
-transtype(A) ::= EXCLUSIVE(X). {A = @X;}
+transtype(A) ::= DEFERRED(X). {A = @X; /*A-overwrites-X*/}
+transtype(A) ::= IMMEDIATE(X). {A = @X; /*A-overwrites-X*/}
+transtype(A) ::= EXCLUSIVE(X). {A = @X; /*A-overwrites-X*/}
cmd ::= COMMIT trans_opt. {sqlite3CommitTransaction(pParse);}
cmd ::= END trans_opt. {sqlite3CommitTransaction(pParse);}
cmd ::= ROLLBACK trans_opt. {sqlite3RollbackTransaction(pParse);}
@@ -164,10 +163,8 @@ cmd ::= create_table create_table_args.
create_table ::= createkw temp(T) TABLE ifnotexists(E) nm(Y) dbnm(Z). {
sqlite3StartTable(pParse,&Y,&Z,T,0,0,E);
}
-createkw(A) ::= CREATE(X). {
- disableLookaside(pParse);
- A = X;
-}
+createkw(A) ::= CREATE(A). {disableLookaside(pParse);}
+
%type ifnotexists {int}
ifnotexists(A) ::= . {A = 0;}
ifnotexists(A) ::= IF NOT EXISTS. {A = 1;}
@@ -201,13 +198,11 @@ columnlist ::= column.
// datatype, and other keywords such as PRIMARY KEY, UNIQUE, REFERENCES,
// NOT NULL and so forth.
//
-column(A) ::= columnid(X) type carglist. {
- A.z = X.z;
- A.n = (int)(pParse->sLastToken.z-X.z) + pParse->sLastToken.n;
+column(A) ::= columnid(A) type carglist. {
+ A.n = (int)(pParse->sLastToken.z-A.z) + pParse->sLastToken.n;
}
-columnid(A) ::= nm(X). {
- sqlite3AddColumn(pParse,&X);
- A = X;
+columnid(A) ::= nm(A). {
+ sqlite3AddColumn(pParse,&A);
pParse->constraintName.n = 0;
}
@@ -265,9 +260,9 @@ columnid(A) ::= nm(X). {
// The name of a column or table can be any of the following:
//
%type nm {Token}
-nm(A) ::= id(X). {A = X;}
-nm(A) ::= STRING(X). {A = X;}
-nm(A) ::= JOIN_KW(X). {A = X;}
+nm(A) ::= id(A).
+nm(A) ::= STRING(A).
+nm(A) ::= JOIN_KW(A).
// A typetoken is really one or more tokens that form a type name such
// as can be found after the column name in a CREATE TABLE statement.
@@ -276,18 +271,16 @@ nm(A) ::= JOIN_KW(X). {A = X;}
%type typetoken {Token}
type ::= .
type ::= typetoken(X). {sqlite3AddColumnType(pParse,&X);}
-typetoken(A) ::= typename(X). {A = X;}
-typetoken(A) ::= typename(X) LP signed RP(Y). {
- A.z = X.z;
- A.n = (int)(&Y.z[Y.n] - X.z);
+typetoken(A) ::= typename(A).
+typetoken(A) ::= typename(A) LP signed RP(Y). {
+ A.n = (int)(&Y.z[Y.n] - A.z);
}
-typetoken(A) ::= typename(X) LP signed COMMA signed RP(Y). {
- A.z = X.z;
- A.n = (int)(&Y.z[Y.n] - X.z);
+typetoken(A) ::= typename(A) LP signed COMMA signed RP(Y). {
+ A.n = (int)(&Y.z[Y.n] - A.z);
}
%type typename {Token}
-typename(A) ::= ids(X). {A = X;}
-typename(A) ::= typename(X) ids(Y). {A.z=X.z; A.n=Y.n+(int)(Y.z-X.z);}
+typename(A) ::= ids(A).
+typename(A) ::= typename(A) ids(Y). {A.n=Y.n+(int)(Y.z-A.z);}
signed ::= plus_num.
signed ::= minus_num.
@@ -309,7 +302,7 @@ ccons ::= DEFAULT MINUS(A) term(X). {
}
ccons ::= DEFAULT id(X). {
ExprSpan v;
- spanExpr(&v, pParse, TK_STRING, &X);
+ spanExpr(&v, pParse, TK_STRING, X);
sqlite3AddDefaultValue(pParse,&v);
}
@@ -339,7 +332,7 @@ autoinc(X) ::= AUTOINCR. {X = 1;}
//
%type refargs {int}
refargs(A) ::= . { A = OE_None*0x0101; /* EV: R-19803-45884 */}
-refargs(A) ::= refargs(X) refarg(Y). { A = (X & ~Y.mask) | Y.value; }
+refargs(A) ::= refargs(A) refarg(Y). { A = (A & ~Y.mask) | Y.value; }
%type refarg {struct {int value; int mask;}}
refarg(A) ::= MATCH nm. { A.value = 0; A.mask = 0x000000; }
refarg(A) ::= ON INSERT refact. { A.value = 0; A.mask = 0x000000; }
@@ -360,7 +353,7 @@ init_deferred_pred_opt(A) ::= INITIALLY DEFERRED. {A = 1;}
init_deferred_pred_opt(A) ::= INITIALLY IMMEDIATE. {A = 0;}
conslist_opt(A) ::= . {A.n = 0; A.z = 0;}
-conslist_opt(A) ::= COMMA(X) conslist. {A = X;}
+conslist_opt(A) ::= COMMA(A) conslist.
conslist ::= conslist tconscomma tcons.
conslist ::= tcons.
tconscomma ::= COMMA. {pParse->constraintName.n = 0;}
@@ -379,7 +372,7 @@ tcons ::= FOREIGN KEY LP eidlist(FA) RP
}
%type defer_subclause_opt {int}
defer_subclause_opt(A) ::= . {A = 0;}
-defer_subclause_opt(A) ::= defer_subclause(X). {A = X;}
+defer_subclause_opt(A) ::= defer_subclause(A).
// The following is a non-standard extension that allows us to declare the
// default behavior when there is a constraint conflict.
@@ -391,7 +384,7 @@ onconf(A) ::= . {A = OE_Default;}
onconf(A) ::= ON CONFLICT resolvetype(X). {A = X;}
orconf(A) ::= . {A = OE_Default;}
orconf(A) ::= OR resolvetype(X). {A = X;}
-resolvetype(A) ::= raisetype(X). {A = X;}
+resolvetype(A) ::= raisetype(A).
resolvetype(A) ::= IGNORE. {A = OE_Ignore;}
resolvetype(A) ::= REPLACE. {A = OE_Replace;}
@@ -463,14 +456,14 @@ select(A) ::= with(W) selectnowith(X). {
}else{
sqlite3WithDelete(pParse->db, W);
}
- A = p;
+ A = p; /*A-overwrites-W*/
}
-selectnowith(A) ::= oneselect(X). {A = X;}
+selectnowith(A) ::= oneselect(A).
%ifndef SQLITE_OMIT_COMPOUND_SELECT
-selectnowith(A) ::= selectnowith(X) multiselect_op(Y) oneselect(Z). {
+selectnowith(A) ::= selectnowith(A) multiselect_op(Y) oneselect(Z). {
Select *pRhs = Z;
- Select *pLhs = X;
+ Select *pLhs = A;
if( pRhs && pRhs->pPrior ){
SrcList *pFrom;
Token x;
@@ -491,12 +484,15 @@ selectnowith(A) ::= selectnowith(X) multiselect_op(Y) oneselect(Z). {
A = pRhs;
}
%type multiselect_op {int}
-multiselect_op(A) ::= UNION(OP). {A = @OP;}
+multiselect_op(A) ::= UNION(OP). {A = @OP; /*A-overwrites-OP*/}
multiselect_op(A) ::= UNION ALL. {A = TK_ALL;}
-multiselect_op(A) ::= EXCEPT|INTERSECT(OP). {A = @OP;}
+multiselect_op(A) ::= EXCEPT|INTERSECT(OP). {A = @OP; /*A-overwrites-OP*/}
%endif SQLITE_OMIT_COMPOUND_SELECT
oneselect(A) ::= SELECT(S) distinct(D) selcollist(W) from(X) where_opt(Y)
groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). {
+#if SELECTTRACE_ENABLED
+ Token s = S; /*A-overwrites-S*/
+#endif
A = sqlite3SelectNew(pParse,W,X,Y,P,Q,Z,D,L.pLimit,L.pOffset);
#if SELECTTRACE_ENABLED
/* Populate the Select.zSelName[] string that is used to help with
@@ -509,7 +505,7 @@ oneselect(A) ::= SELECT(S) distinct(D) selcollist(W) from(X) where_opt(Y)
** is an integer that is incremented with each SELECT statement seen.
*/
if( A!=0 ){
- const char *z = S.z+6;
+ const char *z = s.z+6;
int i;
sqlite3_snprintf(sizeof(A->zSelName), A->zSelName, "#%d",
++pParse->nSelect);
@@ -523,20 +519,19 @@ oneselect(A) ::= SELECT(S) distinct(D) selcollist(W) from(X) where_opt(Y)
}
#endif /* SELECTRACE_ENABLED */
}
-oneselect(A) ::= values(X). {A = X;}
+oneselect(A) ::= values(A).
%type values {Select*}
%destructor values {sqlite3SelectDelete(pParse->db, $$);}
values(A) ::= VALUES LP nexprlist(X) RP. {
A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0,0);
}
-values(A) ::= values(X) COMMA LP exprlist(Y) RP. {
- Select *pRight, *pLeft = X;
+values(A) ::= values(A) COMMA LP exprlist(Y) RP. {
+ Select *pRight, *pLeft = A;
pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values|SF_MultiValue,0,0);
if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
if( pRight ){
pRight->op = TK_ALL;
- pLeft = X;
pRight->pPrior = pLeft;
A = pRight;
}else{
@@ -561,22 +556,22 @@ distinct(A) ::= . {A = 0;}
%destructor selcollist {sqlite3ExprListDelete(pParse->db, $$);}
%type sclp {ExprList*}
%destructor sclp {sqlite3ExprListDelete(pParse->db, $$);}
-sclp(A) ::= selcollist(X) COMMA. {A = X;}
+sclp(A) ::= selcollist(A) COMMA.
sclp(A) ::= . {A = 0;}
-selcollist(A) ::= sclp(P) expr(X) as(Y). {
- A = sqlite3ExprListAppend(pParse, P, X.pExpr);
+selcollist(A) ::= sclp(A) expr(X) as(Y). {
+ A = sqlite3ExprListAppend(pParse, A, X.pExpr);
if( Y.n>0 ) sqlite3ExprListSetName(pParse, A, &Y, 1);
sqlite3ExprListSetSpan(pParse,A,&X);
}
-selcollist(A) ::= sclp(P) STAR. {
+selcollist(A) ::= sclp(A) STAR. {
Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
- A = sqlite3ExprListAppend(pParse, P, p);
+ A = sqlite3ExprListAppend(pParse, A, p);
}
-selcollist(A) ::= sclp(P) nm(X) DOT STAR(Y). {
+selcollist(A) ::= sclp(A) nm(X) DOT STAR(Y). {
Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0, &Y);
Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &X);
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
- A = sqlite3ExprListAppend(pParse,P, pDot);
+ A = sqlite3ExprListAppend(pParse,A, pDot);
}
// An option "AS <id>" phrase that can follow one of the expressions that
@@ -584,7 +579,7 @@ selcollist(A) ::= sclp(P) nm(X) DOT STAR(Y). {
//
%type as {Token}
as(X) ::= AS nm(Y). {X = Y;}
-as(X) ::= ids(Y). {X = Y;}
+as(X) ::= ids(X).
as(X) ::= . {X.n = 0;}
@@ -606,32 +601,31 @@ from(A) ::= FROM seltablist(X). {
// "seltablist" is a "Select Table List" - the content of the FROM clause
// in a SELECT statement. "stl_prefix" is a prefix of this list.
//
-stl_prefix(A) ::= seltablist(X) joinop(Y). {
- A = X;
+stl_prefix(A) ::= seltablist(A) joinop(Y). {
if( ALWAYS(A && A->nSrc>0) ) A->a[A->nSrc-1].fg.jointype = (u8)Y;
}
stl_prefix(A) ::= . {A = 0;}
-seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) indexed_opt(I)
+seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) as(Z) indexed_opt(I)
on_opt(N) using_opt(U). {
- A = sqlite3SrcListAppendFromTerm(pParse,X,&Y,&D,&Z,0,N,U);
+ A = sqlite3SrcListAppendFromTerm(pParse,A,&Y,&D,&Z,0,N,U);
sqlite3SrcListIndexedBy(pParse, A, &I);
}
-seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) LP exprlist(E) RP as(Z)
+seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) LP exprlist(E) RP as(Z)
on_opt(N) using_opt(U). {
- A = sqlite3SrcListAppendFromTerm(pParse,X,&Y,&D,&Z,0,N,U);
+ A = sqlite3SrcListAppendFromTerm(pParse,A,&Y,&D,&Z,0,N,U);
sqlite3SrcListFuncArgs(pParse, A, E);
}
%ifndef SQLITE_OMIT_SUBQUERY
- seltablist(A) ::= stl_prefix(X) LP select(S) RP
+ seltablist(A) ::= stl_prefix(A) LP select(S) RP
as(Z) on_opt(N) using_opt(U). {
- A = sqlite3SrcListAppendFromTerm(pParse,X,0,0,&Z,S,N,U);
+ A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,S,N,U);
}
- seltablist(A) ::= stl_prefix(X) LP seltablist(F) RP
+ seltablist(A) ::= stl_prefix(A) LP seltablist(F) RP
as(Z) on_opt(N) using_opt(U). {
- if( X==0 && Z.n==0 && N==0 && U==0 ){
+ if( A==0 && Z.n==0 && N==0 && U==0 ){
A = F;
}else if( F->nSrc==1 ){
- A = sqlite3SrcListAppendFromTerm(pParse,X,0,0,&Z,0,N,U);
+ A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,0,N,U);
if( A ){
struct SrcList_item *pNew = &A->a[A->nSrc-1];
struct SrcList_item *pOld = F->a;
@@ -646,7 +640,7 @@ seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) LP exprlist(E) RP as(Z)
Select *pSubquery;
sqlite3SrcListShiftJoinType(F);
pSubquery = sqlite3SelectNew(pParse,0,F,0,0,0,0,SF_NestedFrom,0,0);
- A = sqlite3SrcListAppendFromTerm(pParse,X,0,0,&Z,pSubquery,N,U);
+ A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,pSubquery,N,U);
}
}
%endif SQLITE_OMIT_SUBQUERY
@@ -657,14 +651,17 @@ dbnm(A) ::= DOT nm(X). {A = X;}
%type fullname {SrcList*}
%destructor fullname {sqlite3SrcListDelete(pParse->db, $$);}
-fullname(A) ::= nm(X) dbnm(Y). {A = sqlite3SrcListAppend(pParse->db,0,&X,&Y);}
+fullname(A) ::= nm(X) dbnm(Y).
+ {A = sqlite3SrcListAppend(pParse->db,0,&X,&Y); /*A-overwrites-X*/}
%type joinop {int}
joinop(X) ::= COMMA|JOIN. { X = JT_INNER; }
-joinop(X) ::= JOIN_KW(A) JOIN. { X = sqlite3JoinType(pParse,&A,0,0); }
-joinop(X) ::= JOIN_KW(A) nm(B) JOIN. { X = sqlite3JoinType(pParse,&A,&B,0); }
+joinop(X) ::= JOIN_KW(A) JOIN.
+ {X = sqlite3JoinType(pParse,&A,0,0); /*X-overwrites-A*/}
+joinop(X) ::= JOIN_KW(A) nm(B) JOIN.
+ {X = sqlite3JoinType(pParse,&A,&B,0); /*X-overwrites-A*/}
joinop(X) ::= JOIN_KW(A) nm(B) nm(C) JOIN.
- { X = sqlite3JoinType(pParse,&A,&B,&C); }
+ {X = sqlite3JoinType(pParse,&A,&B,&C);/*X-overwrites-A*/}
%type on_opt {Expr*}
%destructor on_opt {sqlite3ExprDelete(pParse->db, $$);}
@@ -704,12 +701,12 @@ using_opt(U) ::= . {U = 0;}
orderby_opt(A) ::= . {A = 0;}
orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;}
-sortlist(A) ::= sortlist(X) COMMA expr(Y) sortorder(Z). {
- A = sqlite3ExprListAppend(pParse,X,Y.pExpr);
+sortlist(A) ::= sortlist(A) COMMA expr(Y) sortorder(Z). {
+ A = sqlite3ExprListAppend(pParse,A,Y.pExpr);
sqlite3ExprListSetSortOrder(A,Z);
}
sortlist(A) ::= expr(Y) sortorder(Z). {
- A = sqlite3ExprListAppend(pParse,0,Y.pExpr);
+ A = sqlite3ExprListAppend(pParse,0,Y.pExpr); /*A-overwrites-Y*/
sqlite3ExprListSetSortOrder(A,Z);
}
@@ -799,8 +796,8 @@ cmd ::= with(C) UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y)
%type setlist {ExprList*}
%destructor setlist {sqlite3ExprListDelete(pParse->db, $$);}
-setlist(A) ::= setlist(Z) COMMA nm(X) EQ expr(Y). {
- A = sqlite3ExprListAppend(pParse, Z, Y.pExpr);
+setlist(A) ::= setlist(A) COMMA nm(X) EQ expr(Y). {
+ A = sqlite3ExprListAppend(pParse, A, Y.pExpr);
sqlite3ExprListSetName(pParse, A, &X, 1);
}
setlist(A) ::= nm(X) EQ expr(Y). {
@@ -831,10 +828,10 @@ insert_cmd(A) ::= REPLACE. {A = OE_Replace;}
idlist_opt(A) ::= . {A = 0;}
idlist_opt(A) ::= LP idlist(X) RP. {A = X;}
-idlist(A) ::= idlist(X) COMMA nm(Y).
- {A = sqlite3IdListAppend(pParse->db,X,&Y);}
+idlist(A) ::= idlist(A) COMMA nm(Y).
+ {A = sqlite3IdListAppend(pParse->db,A,&Y);}
idlist(A) ::= nm(Y).
- {A = sqlite3IdListAppend(pParse->db,0,&Y);}
+ {A = sqlite3IdListAppend(pParse->db,0,&Y); /*A-overwrites-Y*/}
/////////////////////////// Expression Processing /////////////////////////////
//
@@ -858,61 +855,62 @@ idlist(A) ::= nm(Y).
** new Expr to populate pOut. Set the span of pOut to be the identifier
** that created the expression.
*/
- static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token *pValue){
- pOut->pExpr = sqlite3PExpr(pParse, op, 0, 0, pValue);
- pOut->zStart = pValue->z;
- pOut->zEnd = &pValue->z[pValue->n];
+ static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token t){
+ pOut->pExpr = sqlite3PExpr(pParse, op, 0, 0, &t);
+ pOut->zStart = t.z;
+ pOut->zEnd = &t.z[t.n];
}
}
-expr(A) ::= term(X). {A = X;}
-expr(A) ::= LP(B) expr(X) RP(E). {A.pExpr = X.pExpr; spanSet(&A,&B,&E);}
-term(A) ::= NULL(X). {spanExpr(&A, pParse, @X, &X);}
-expr(A) ::= id(X). {spanExpr(&A, pParse, TK_ID, &X);}
-expr(A) ::= JOIN_KW(X). {spanExpr(&A, pParse, TK_ID, &X);}
+expr(A) ::= term(A).
+expr(A) ::= LP(B) expr(X) RP(E).
+ {spanSet(&A,&B,&E); /*A-overwrites-B*/ A.pExpr = X.pExpr;}
+term(A) ::= NULL(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/}
+expr(A) ::= id(X). {spanExpr(&A,pParse,TK_ID,X); /*A-overwrites-X*/}
+expr(A) ::= JOIN_KW(X). {spanExpr(&A,pParse,TK_ID,X); /*A-overwrites-X*/}
expr(A) ::= nm(X) DOT nm(Y). {
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &X);
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &Y);
+ spanSet(&A,&X,&Y); /*A-overwrites-X*/
A.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
- spanSet(&A,&X,&Y);
}
expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). {
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &X);
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &Y);
Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &Z);
Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0);
+ spanSet(&A,&X,&Z); /*A-overwrites-X*/
A.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
- spanSet(&A,&X,&Z);
}
-term(A) ::= INTEGER|FLOAT|BLOB(X). {spanExpr(&A, pParse, @X, &X);}
-term(A) ::= STRING(X). {spanExpr(&A, pParse, @X, &X);}
+term(A) ::= INTEGER|FLOAT|BLOB(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/}
+term(A) ::= STRING(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/}
expr(A) ::= VARIABLE(X). {
- if( X.n>=2 && X.z[0]=='#' && sqlite3Isdigit(X.z[1]) ){
+ Token t = X; /*A-overwrites-X*/
+ if( t.n>=2 && t.z[0]=='#' && sqlite3Isdigit(t.z[1]) ){
/* When doing a nested parse, one can include terms in an expression
** that look like this: #1 #2 ... These terms refer to registers
** in the virtual machine. #N is the N-th register. */
+ spanSet(&A, &t, &t);
if( pParse->nested==0 ){
- sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &X);
+ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
A.pExpr = 0;
}else{
- A.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &X);
- if( A.pExpr ) sqlite3GetInt32(&X.z[1], &A.pExpr->iTable);
+ A.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &t);
+ if( A.pExpr ) sqlite3GetInt32(&t.z[1], &A.pExpr->iTable);
}
}else{
- spanExpr(&A, pParse, TK_VARIABLE, &X);
+ spanExpr(&A, pParse, TK_VARIABLE, t);
sqlite3ExprAssignVarNumber(pParse, A.pExpr);
}
- spanSet(&A, &X, &X);
}
-expr(A) ::= expr(E) COLLATE ids(C). {
- A.pExpr = sqlite3ExprAddCollateToken(pParse, E.pExpr, &C, 1);
- A.zStart = E.zStart;
+expr(A) ::= expr(A) COLLATE ids(C). {
+ A.pExpr = sqlite3ExprAddCollateToken(pParse, A.pExpr, &C, 1);
A.zEnd = &C.z[C.n];
}
%ifndef SQLITE_OMIT_CAST
expr(A) ::= CAST(X) LP expr(E) AS typetoken(T) RP(Y). {
+ spanSet(&A,&X,&Y); /*A-overwrites-X*/
A.pExpr = sqlite3PExpr(pParse, TK_CAST, E.pExpr, 0, &T);
- spanSet(&A,&X,&Y);
}
%endif SQLITE_OMIT_CAST
expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP(E). {
@@ -939,58 +937,56 @@ term(A) ::= CTIME_KW(OP). {
** objects and uses the result to populate a new ExprSpan object.
*/
static void spanBinaryExpr(
- ExprSpan *pOut, /* Write the result here */
Parse *pParse, /* The parsing context. Errors accumulate here */
int op, /* The binary operation */
- ExprSpan *pLeft, /* The left operand */
+ ExprSpan *pLeft, /* The left operand, and output */
ExprSpan *pRight /* The right operand */
){
- pOut->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr, 0);
- pOut->zStart = pLeft->zStart;
- pOut->zEnd = pRight->zEnd;
+ pLeft->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr, 0);
+ pLeft->zEnd = pRight->zEnd;
}
/* If doNot is true, then add a TK_NOT Expr-node wrapper around the
** outside of *ppExpr.
*/
- static void exprNot(Parse *pParse, int doNot, Expr **ppExpr){
- if( doNot ) *ppExpr = sqlite3PExpr(pParse, TK_NOT, *ppExpr, 0, 0);
+ static void exprNot(Parse *pParse, int doNot, ExprSpan *pSpan){
+ if( doNot ){
+ pSpan->pExpr = sqlite3PExpr(pParse, TK_NOT, pSpan->pExpr, 0, 0);
+ }
}
}
-expr(A) ::= expr(X) AND(OP) expr(Y). {spanBinaryExpr(&A,pParse,@OP,&X,&Y);}
-expr(A) ::= expr(X) OR(OP) expr(Y). {spanBinaryExpr(&A,pParse,@OP,&X,&Y);}
-expr(A) ::= expr(X) LT|GT|GE|LE(OP) expr(Y).
- {spanBinaryExpr(&A,pParse,@OP,&X,&Y);}
-expr(A) ::= expr(X) EQ|NE(OP) expr(Y). {spanBinaryExpr(&A,pParse,@OP,&X,&Y);}
-expr(A) ::= expr(X) BITAND|BITOR|LSHIFT|RSHIFT(OP) expr(Y).
- {spanBinaryExpr(&A,pParse,@OP,&X,&Y);}
-expr(A) ::= expr(X) PLUS|MINUS(OP) expr(Y).
- {spanBinaryExpr(&A,pParse,@OP,&X,&Y);}
-expr(A) ::= expr(X) STAR|SLASH|REM(OP) expr(Y).
- {spanBinaryExpr(&A,pParse,@OP,&X,&Y);}
-expr(A) ::= expr(X) CONCAT(OP) expr(Y). {spanBinaryExpr(&A,pParse,@OP,&X,&Y);}
+expr(A) ::= expr(A) AND(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);}
+expr(A) ::= expr(A) OR(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);}
+expr(A) ::= expr(A) LT|GT|GE|LE(OP) expr(Y).
+ {spanBinaryExpr(pParse,@OP,&A,&Y);}
+expr(A) ::= expr(A) EQ|NE(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);}
+expr(A) ::= expr(A) BITAND|BITOR|LSHIFT|RSHIFT(OP) expr(Y).
+ {spanBinaryExpr(pParse,@OP,&A,&Y);}
+expr(A) ::= expr(A) PLUS|MINUS(OP) expr(Y).
+ {spanBinaryExpr(pParse,@OP,&A,&Y);}
+expr(A) ::= expr(A) STAR|SLASH|REM(OP) expr(Y).
+ {spanBinaryExpr(pParse,@OP,&A,&Y);}
+expr(A) ::= expr(A) CONCAT(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);}
%type likeop {struct LikeOp}
-likeop(A) ::= LIKE_KW|MATCH(X). {A.eOperator = X; A.bNot = 0;}
+likeop(A) ::= LIKE_KW|MATCH(X). {A.eOperator = X; A.bNot = 0;/*A-overwrites-X*/}
likeop(A) ::= NOT LIKE_KW|MATCH(X). {A.eOperator = X; A.bNot = 1;}
-expr(A) ::= expr(X) likeop(OP) expr(Y). [LIKE_KW] {
+expr(A) ::= expr(A) likeop(OP) expr(Y). [LIKE_KW] {
ExprList *pList;
pList = sqlite3ExprListAppend(pParse,0, Y.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, X.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, A.pExpr);
A.pExpr = sqlite3ExprFunction(pParse, pList, &OP.eOperator);
- exprNot(pParse, OP.bNot, &A.pExpr);
- A.zStart = X.zStart;
+ exprNot(pParse, OP.bNot, &A);
A.zEnd = Y.zEnd;
if( A.pExpr ) A.pExpr->flags |= EP_InfixFunc;
}
-expr(A) ::= expr(X) likeop(OP) expr(Y) ESCAPE expr(E). [LIKE_KW] {
+expr(A) ::= expr(A) likeop(OP) expr(Y) ESCAPE expr(E). [LIKE_KW] {
ExprList *pList;
pList = sqlite3ExprListAppend(pParse,0, Y.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, X.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, A.pExpr);
pList = sqlite3ExprListAppend(pParse,pList, E.pExpr);
A.pExpr = sqlite3ExprFunction(pParse, pList, &OP.eOperator);
- exprNot(pParse, OP.bNot, &A.pExpr);
- A.zStart = X.zStart;
+ exprNot(pParse, OP.bNot, &A);
A.zEnd = E.zEnd;
if( A.pExpr ) A.pExpr->flags |= EP_InfixFunc;
}
@@ -999,20 +995,18 @@ expr(A) ::= expr(X) likeop(OP) expr(Y) ESCAPE expr(E). [LIKE_KW] {
/* Construct an expression node for a unary postfix operator
*/
static void spanUnaryPostfix(
- ExprSpan *pOut, /* Write the new expression node here */
Parse *pParse, /* Parsing context to record errors */
int op, /* The operator */
- ExprSpan *pOperand, /* The operand */
+ ExprSpan *pOperand, /* The operand, and output */
Token *pPostOp /* The operand token for setting the span */
){
- pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
- pOut->zStart = pOperand->zStart;
- pOut->zEnd = &pPostOp->z[pPostOp->n];
+ pOperand->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
+ pOperand->zEnd = &pPostOp->z[pPostOp->n];
}
}
-expr(A) ::= expr(X) ISNULL|NOTNULL(E). {spanUnaryPostfix(&A,pParse,@E,&X,&E);}
-expr(A) ::= expr(X) NOT NULL(E). {spanUnaryPostfix(&A,pParse,TK_NOTNULL,&X,&E);}
+expr(A) ::= expr(A) ISNULL|NOTNULL(E). {spanUnaryPostfix(pParse,@E,&A,&E);}
+expr(A) ::= expr(A) NOT NULL(E). {spanUnaryPostfix(pParse,TK_NOTNULL,&A,&E);}
%include {
/* A routine to convert a binary TK_IS or TK_ISNOT expression into a
@@ -1033,12 +1027,12 @@ expr(A) ::= expr(X) NOT NULL(E). {spanUnaryPostfix(&A,pParse,TK_NOTNULL,&X,&E);}
// If expr2 is NULL then code as TK_ISNULL or TK_NOTNULL. If expr2
// is any other expression, code as TK_IS or TK_ISNOT.
//
-expr(A) ::= expr(X) IS expr(Y). {
- spanBinaryExpr(&A,pParse,TK_IS,&X,&Y);
+expr(A) ::= expr(A) IS expr(Y). {
+ spanBinaryExpr(pParse,TK_IS,&A,&Y);
binaryToUnaryIfNull(pParse, Y.pExpr, A.pExpr, TK_ISNULL);
}
-expr(A) ::= expr(X) IS NOT expr(Y). {
- spanBinaryExpr(&A,pParse,TK_ISNOT,&X,&Y);
+expr(A) ::= expr(A) IS NOT expr(Y). {
+ spanBinaryExpr(pParse,TK_ISNOT,&A,&Y);
binaryToUnaryIfNull(pParse, Y.pExpr, A.pExpr, TK_NOTNULL);
}
@@ -1052,42 +1046,43 @@ expr(A) ::= expr(X) IS NOT expr(Y). {
ExprSpan *pOperand, /* The operand */
Token *pPreOp /* The operand token for setting the span */
){
- pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
pOut->zStart = pPreOp->z;
+ pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
pOut->zEnd = pOperand->zEnd;
}
}
-expr(A) ::= NOT(B) expr(X). {spanUnaryPrefix(&A,pParse,@B,&X,&B);}
-expr(A) ::= BITNOT(B) expr(X). {spanUnaryPrefix(&A,pParse,@B,&X,&B);}
+expr(A) ::= NOT(B) expr(X).
+ {spanUnaryPrefix(&A,pParse,@B,&X,&B);/*A-overwrites-B*/}
+expr(A) ::= BITNOT(B) expr(X).
+ {spanUnaryPrefix(&A,pParse,@B,&X,&B);/*A-overwrites-B*/}
expr(A) ::= MINUS(B) expr(X). [BITNOT]
- {spanUnaryPrefix(&A,pParse,TK_UMINUS,&X,&B);}
+ {spanUnaryPrefix(&A,pParse,TK_UMINUS,&X,&B);/*A-overwrites-B*/}
expr(A) ::= PLUS(B) expr(X). [BITNOT]
- {spanUnaryPrefix(&A,pParse,TK_UPLUS,&X,&B);}
+ {spanUnaryPrefix(&A,pParse,TK_UPLUS,&X,&B);/*A-overwrites-B*/}
%type between_op {int}
between_op(A) ::= BETWEEN. {A = 0;}
between_op(A) ::= NOT BETWEEN. {A = 1;}
-expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
+expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
ExprList *pList = sqlite3ExprListAppend(pParse,0, X.pExpr);
pList = sqlite3ExprListAppend(pParse,pList, Y.pExpr);
- A.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, W.pExpr, 0, 0);
+ A.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, A.pExpr, 0, 0);
if( A.pExpr ){
A.pExpr->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
- exprNot(pParse, N, &A.pExpr);
- A.zStart = W.zStart;
+ exprNot(pParse, N, &A);
A.zEnd = Y.zEnd;
}
%ifndef SQLITE_OMIT_SUBQUERY
%type in_op {int}
in_op(A) ::= IN. {A = 0;}
in_op(A) ::= NOT IN. {A = 1;}
- expr(A) ::= expr(X) in_op(N) LP exprlist(Y) RP(E). [IN] {
+ expr(A) ::= expr(A) in_op(N) LP exprlist(Y) RP(E). [IN] {
if( Y==0 ){
/* Expressions of the form
**
@@ -1097,8 +1092,8 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
** simplify to constants 0 (false) and 1 (true), respectively,
** regardless of the value of expr1.
*/
+ sqlite3ExprDelete(pParse->db, A.pExpr);
A.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[N]);
- sqlite3ExprDelete(pParse->db, X.pExpr);
}else if( Y->nExpr==1 ){
/* Expressions of the form:
**
@@ -1125,21 +1120,21 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
pRHS->flags &= ~EP_Collate;
pRHS->flags |= EP_Generic;
}
- A.pExpr = sqlite3PExpr(pParse, N ? TK_NE : TK_EQ, X.pExpr, pRHS, 0);
+ A.pExpr = sqlite3PExpr(pParse, N ? TK_NE : TK_EQ, A.pExpr, pRHS, 0);
}else{
- A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
+ A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0);
if( A.pExpr ){
A.pExpr->x.pList = Y;
sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
}else{
sqlite3ExprListDelete(pParse->db, Y);
}
- exprNot(pParse, N, &A.pExpr);
+ exprNot(pParse, N, &A);
}
- A.zStart = X.zStart;
A.zEnd = &E.z[E.n];
}
expr(A) ::= LP(B) select(X) RP(E). {
+ spanSet(&A,&B,&E); /*A-overwrites-B*/
A.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
if( A.pExpr ){
A.pExpr->x.pSelect = X;
@@ -1148,11 +1143,9 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
}else{
sqlite3SelectDelete(pParse->db, X);
}
- A.zStart = B.z;
- A.zEnd = &E.z[E.n];
}
- expr(A) ::= expr(X) in_op(N) LP select(Y) RP(E). [IN] {
- A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
+ expr(A) ::= expr(A) in_op(N) LP select(Y) RP(E). [IN] {
+ A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0);
if( A.pExpr ){
A.pExpr->x.pSelect = Y;
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
@@ -1160,13 +1153,12 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
}else{
sqlite3SelectDelete(pParse->db, Y);
}
- exprNot(pParse, N, &A.pExpr);
- A.zStart = X.zStart;
+ exprNot(pParse, N, &A);
A.zEnd = &E.z[E.n];
}
- expr(A) ::= expr(X) in_op(N) nm(Y) dbnm(Z). [IN] {
+ expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z). [IN] {
SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&Y,&Z);
- A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
+ A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0);
if( A.pExpr ){
A.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
@@ -1174,12 +1166,13 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
}else{
sqlite3SrcListDelete(pParse->db, pSrc);
}
- exprNot(pParse, N, &A.pExpr);
- A.zStart = X.zStart;
+ exprNot(pParse, N, &A);
A.zEnd = Z.z ? &Z.z[Z.n] : &Y.z[Y.n];
}
expr(A) ::= EXISTS(B) LP select(Y) RP(E). {
- Expr *p = A.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
+ Expr *p;
+ spanSet(&A,&B,&E); /*A-overwrites-B*/
+ p = A.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
if( p ){
p->x.pSelect = Y;
ExprSetProperty(p, EP_xIsSelect|EP_Subquery);
@@ -1187,13 +1180,12 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
}else{
sqlite3SelectDelete(pParse->db, Y);
}
- A.zStart = B.z;
- A.zEnd = &E.z[E.n];
}
%endif SQLITE_OMIT_SUBQUERY
/* CASE expressions */
expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
+ spanSet(&A,&C,&E); /*A-overwrites-C*/
A.pExpr = sqlite3PExpr(pParse, TK_CASE, X, 0, 0);
if( A.pExpr ){
A.pExpr->x.pList = Z ? sqlite3ExprListAppend(pParse,Y,Z) : Y;
@@ -1202,13 +1194,11 @@ expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
sqlite3ExprListDelete(pParse->db, Y);
sqlite3ExprDelete(pParse->db, Z);
}
- A.zStart = C.z;
- A.zEnd = &E.z[E.n];
}
%type case_exprlist {ExprList*}
%destructor case_exprlist {sqlite3ExprListDelete(pParse->db, $$);}
-case_exprlist(A) ::= case_exprlist(X) WHEN expr(Y) THEN expr(Z). {
- A = sqlite3ExprListAppend(pParse,X, Y.pExpr);
+case_exprlist(A) ::= case_exprlist(A) WHEN expr(Y) THEN expr(Z). {
+ A = sqlite3ExprListAppend(pParse,A, Y.pExpr);
A = sqlite3ExprListAppend(pParse,A, Z.pExpr);
}
case_exprlist(A) ::= WHEN expr(Y) THEN expr(Z). {
@@ -1221,7 +1211,7 @@ case_else(A) ::= ELSE expr(X). {A = X.pExpr;}
case_else(A) ::= . {A = 0;}
%type case_operand {Expr*}
%destructor case_operand {sqlite3ExprDelete(pParse->db, $$);}
-case_operand(A) ::= expr(X). {A = X.pExpr;}
+case_operand(A) ::= expr(X). {A = X.pExpr; /*A-overwrites-X*/}
case_operand(A) ::= . {A = 0;}
%type exprlist {ExprList*}
@@ -1229,12 +1219,12 @@ case_operand(A) ::= . {A = 0;}
%type nexprlist {ExprList*}
%destructor nexprlist {sqlite3ExprListDelete(pParse->db, $$);}
-exprlist(A) ::= nexprlist(X). {A = X;}
+exprlist(A) ::= nexprlist(A).
exprlist(A) ::= . {A = 0;}
-nexprlist(A) ::= nexprlist(X) COMMA expr(Y).
- {A = sqlite3ExprListAppend(pParse,X,Y.pExpr);}
+nexprlist(A) ::= nexprlist(A) COMMA expr(Y).
+ {A = sqlite3ExprListAppend(pParse,A,Y.pExpr);}
nexprlist(A) ::= expr(Y).
- {A = sqlite3ExprListAppend(pParse,0,Y.pExpr);}
+ {A = sqlite3ExprListAppend(pParse,0,Y.pExpr); /*A-overwrites-Y*/}
///////////////////////////// The CREATE INDEX command ///////////////////////
@@ -1298,11 +1288,11 @@ uniqueflag(A) ::= . {A = OE_None;}
eidlist_opt(A) ::= . {A = 0;}
eidlist_opt(A) ::= LP eidlist(X) RP. {A = X;}
-eidlist(A) ::= eidlist(X) COMMA nm(Y) collate(C) sortorder(Z). {
- A = parserAddExprIdListTerm(pParse, X, &Y, C, Z);
+eidlist(A) ::= eidlist(A) COMMA nm(Y) collate(C) sortorder(Z). {
+ A = parserAddExprIdListTerm(pParse, A, &Y, C, Z);
}
eidlist(A) ::= nm(Y) collate(C) sortorder(Z). {
- A = parserAddExprIdListTerm(pParse, 0, &Y, C, Z);
+ A = parserAddExprIdListTerm(pParse, 0, &Y, C, Z); /*A-overwrites-Y*/
}
%type collate {int}
@@ -1334,15 +1324,15 @@ cmd ::= PRAGMA nm(X) dbnm(Z) EQ minus_num(Y).
cmd ::= PRAGMA nm(X) dbnm(Z) LP minus_num(Y) RP.
{sqlite3Pragma(pParse,&X,&Z,&Y,1);}
-nmnum(A) ::= plus_num(X). {A = X;}
-nmnum(A) ::= nm(X). {A = X;}
-nmnum(A) ::= ON(X). {A = X;}
-nmnum(A) ::= DELETE(X). {A = X;}
-nmnum(A) ::= DEFAULT(X). {A = X;}
+nmnum(A) ::= plus_num(A).
+nmnum(A) ::= nm(A).
+nmnum(A) ::= ON(A).
+nmnum(A) ::= DELETE(A).
+nmnum(A) ::= DEFAULT(A).
%endif SQLITE_OMIT_PRAGMA
%token_class number INTEGER|FLOAT.
plus_num(A) ::= PLUS number(X). {A = X;}
-plus_num(A) ::= number(X). {A = X;}
+plus_num(A) ::= number(A).
minus_num(A) ::= MINUS number(X). {A = X;}
//////////////////////////// The CREATE TRIGGER command /////////////////////
@@ -1359,7 +1349,7 @@ trigger_decl(A) ::= temp(T) TRIGGER ifnotexists(NOERR) nm(B) dbnm(Z)
trigger_time(C) trigger_event(D)
ON fullname(E) foreach_clause when_clause(G). {
sqlite3BeginTrigger(pParse, &B, &Z, C, D.a, D.b, E, G, T, NOERR);
- A = (Z.n==0?B:Z);
+ A = (Z.n==0?B:Z); /*A-overwrites-T*/
}
%type trigger_time {int}
@@ -1370,9 +1360,9 @@ trigger_time(A) ::= . { A = TK_BEFORE; }
%type trigger_event {struct TrigEvent}
%destructor trigger_event {sqlite3IdListDelete(pParse->db, $$.b);}
-trigger_event(A) ::= DELETE|INSERT(OP). {A.a = @OP; A.b = 0;}
-trigger_event(A) ::= UPDATE(OP). {A.a = @OP; A.b = 0;}
-trigger_event(A) ::= UPDATE OF idlist(X). {A.a = TK_UPDATE; A.b = X;}
+trigger_event(A) ::= DELETE|INSERT(X). {A.a = @X; /*A-overwrites-X*/ A.b = 0;}
+trigger_event(A) ::= UPDATE(X). {A.a = @X; /*A-overwrites-X*/ A.b = 0;}
+trigger_event(A) ::= UPDATE OF idlist(X).{A.a = TK_UPDATE; A.b = X;}
foreach_clause ::= .
foreach_clause ::= FOR EACH ROW.
@@ -1384,16 +1374,14 @@ when_clause(A) ::= WHEN expr(X). { A = X.pExpr; }
%type trigger_cmd_list {TriggerStep*}
%destructor trigger_cmd_list {sqlite3DeleteTriggerStep(pParse->db, $$);}
-trigger_cmd_list(A) ::= trigger_cmd_list(Y) trigger_cmd(X) SEMI. {
- assert( Y!=0 );
- Y->pLast->pNext = X;
- Y->pLast = X;
- A = Y;
-}
-trigger_cmd_list(A) ::= trigger_cmd(X) SEMI. {
- assert( X!=0 );
- X->pLast = X;
- A = X;
+trigger_cmd_list(A) ::= trigger_cmd_list(A) trigger_cmd(X) SEMI. {
+ assert( A!=0 );
+ A->pLast->pNext = X;
+ A->pLast = X;
+}
+trigger_cmd_list(A) ::= trigger_cmd(A) SEMI. {
+ assert( A!=0 );
+ A->pLast = A;
}
// Disallow qualified table names on INSERT, UPDATE, and DELETE statements
@@ -1401,7 +1389,7 @@ trigger_cmd_list(A) ::= trigger_cmd(X) SEMI. {
// the same database as the table that the trigger fires on.
//
%type trnm {Token}
-trnm(A) ::= nm(X). {A = X;}
+trnm(A) ::= nm(A).
trnm(A) ::= nm DOT nm(X). {
A = X;
sqlite3ErrorMsg(pParse,
@@ -1432,35 +1420,34 @@ tridxby ::= NOT INDEXED. {
// UPDATE
trigger_cmd(A) ::=
UPDATE orconf(R) trnm(X) tridxby SET setlist(Y) where_opt(Z).
- { A = sqlite3TriggerUpdateStep(pParse->db, &X, Y, Z, R); }
+ {A = sqlite3TriggerUpdateStep(pParse->db, &X, Y, Z, R);}
// INSERT
trigger_cmd(A) ::= insert_cmd(R) INTO trnm(X) idlist_opt(F) select(S).
- {A = sqlite3TriggerInsertStep(pParse->db, &X, F, S, R);}
+ {A = sqlite3TriggerInsertStep(pParse->db, &X, F, S, R);/*A-overwrites-R*/}
// DELETE
trigger_cmd(A) ::= DELETE FROM trnm(X) tridxby where_opt(Y).
- {A = sqlite3TriggerDeleteStep(pParse->db, &X, Y);}
+ {A = sqlite3TriggerDeleteStep(pParse->db, &X, Y);}
// SELECT
-trigger_cmd(A) ::= select(X). {A = sqlite3TriggerSelectStep(pParse->db, X); }
+trigger_cmd(A) ::= select(X).
+ {A = sqlite3TriggerSelectStep(pParse->db, X); /*A-overwrites-X*/}
// The special RAISE expression that may occur in trigger programs
expr(A) ::= RAISE(X) LP IGNORE RP(Y). {
+ spanSet(&A,&X,&Y); /*A-overwrites-X*/
A.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
if( A.pExpr ){
A.pExpr->affinity = OE_Ignore;
}
- A.zStart = X.z;
- A.zEnd = &Y.z[Y.n];
}
expr(A) ::= RAISE(X) LP raisetype(T) COMMA nm(Z) RP(Y). {
+ spanSet(&A,&X,&Y); /*A-overwrites-X*/
A.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &Z);
if( A.pExpr ) {
A.pExpr->affinity = (char)T;
}
- A.zStart = X.z;
- A.zEnd = &Y.z[Y.n];
}
%endif !SQLITE_OMIT_TRIGGER
@@ -1556,9 +1543,9 @@ with(A) ::= WITH wqlist(W). { A = W; }
with(A) ::= WITH RECURSIVE wqlist(W). { A = W; }
wqlist(A) ::= nm(X) eidlist_opt(Y) AS LP select(Z) RP. {
- A = sqlite3WithAdd(pParse, 0, &X, Y, Z);
+ A = sqlite3WithAdd(pParse, 0, &X, Y, Z); /*A-overwrites-X*/
}
-wqlist(A) ::= wqlist(W) COMMA nm(X) eidlist_opt(Y) AS LP select(Z) RP. {
- A = sqlite3WithAdd(pParse, W, &X, Y, Z);
+wqlist(A) ::= wqlist(A) COMMA nm(X) eidlist_opt(Y) AS LP select(Z) RP. {
+ A = sqlite3WithAdd(pParse, A, &X, Y, Z);
}
%endif SQLITE_OMIT_CTE
diff --git a/src/pcache.c b/src/pcache.c
index 5ac9d34a1..61e758742 100644
--- a/src/pcache.c
+++ b/src/pcache.c
@@ -191,7 +191,7 @@ int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)),
pCache->bPurgeable
);
- if( pNew==0 ) return SQLITE_NOMEM;
+ if( pNew==0 ) return SQLITE_NOMEM_BKPT;
sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache));
if( pCache->pCache ){
sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
@@ -301,7 +301,7 @@ int sqlite3PcacheFetchStress(
}
}
*ppPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2);
- return *ppPage==0 ? SQLITE_NOMEM : SQLITE_OK;
+ return *ppPage==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK;
}
/*
diff --git a/src/prepare.c b/src/prepare.c
index f74aa52e0..6685dfeaf 100644
--- a/src/prepare.c
+++ b/src/prepare.c
@@ -33,7 +33,7 @@ static void corruptSchema(
sqlite3DbFree(db, *pData->pzErrMsg);
*pData->pzErrMsg = z;
}
- pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT;
+ pData->rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_CORRUPT_BKPT;
}
/*
@@ -307,7 +307,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
#endif
}
if( db->mallocFailed ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
sqlite3ResetAllSchemasOfConnection(db);
}
if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){
@@ -524,7 +524,7 @@ static int sqlite3Prepare(
/* Allocate the parsing context */
pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
if( pParse==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto end_prepare;
}
pParse->pReprepare = pReprepare;
@@ -601,7 +601,7 @@ static int sqlite3Prepare(
schemaIsValid(pParse);
}
if( db->mallocFailed ){
- pParse->rc = SQLITE_NOMEM;
+ pParse->rc = SQLITE_NOMEM_BKPT;
}
if( pzTail ){
*pzTail = pParse->zTail;
diff --git a/src/resolve.c b/src/resolve.c
index 81bb712a2..8e290af12 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -656,9 +656,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
notValid(pParse, pNC, "functions", NC_PartIdx);
zId = pExpr->u.zToken;
nId = sqlite3Strlen30(zId);
- pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
+ pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
if( pDef==0 ){
- pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
+ pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
if( pDef==0 ){
no_such_func = 1;
}else{
diff --git a/src/select.c b/src/select.c
index c3132c232..bde278b43 100644
--- a/src/select.c
+++ b/src/select.c
@@ -105,7 +105,7 @@ Select *sqlite3SelectNew(
ExprList *pGroupBy, /* the GROUP BY clause */
Expr *pHaving, /* the HAVING clause */
ExprList *pOrderBy, /* the ORDER BY clause */
- u16 selFlags, /* Flag parameters, such as SF_Distinct */
+ u32 selFlags, /* Flag parameters, such as SF_Distinct */
Expr *pLimit, /* LIMIT value. NULL means not used */
Expr *pOffset /* OFFSET value. NULL means no offset */
){
@@ -1688,7 +1688,7 @@ int sqlite3ColumnsFromExprList(
sqlite3DbFree(db, aCol);
*paCol = 0;
*pnCol = 0;
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
return SQLITE_OK;
}
@@ -1845,8 +1845,9 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
VdbeComment((v, "LIMIT counter"));
if( n==0 ){
sqlite3VdbeGoto(v, iBreak);
- }else if( n>=0 && p->nSelectRow>(u64)n ){
- p->nSelectRow = n;
+ }else if( n>=0 && p->nSelectRow>sqlite3LogEst((u64)n) ){
+ p->nSelectRow = sqlite3LogEst((u64)n);
+ p->selFlags |= SF_FixedLimit;
}
}else{
sqlite3ExprCode(pParse, p->pLimit, iLimit);
@@ -2287,12 +2288,12 @@ static int multiSelect(
testcase( rc!=SQLITE_OK );
pDelete = p->pPrior;
p->pPrior = pPrior;
- p->nSelectRow += pPrior->nSelectRow;
+ p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
if( pPrior->pLimit
&& sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
- && nLimit>0 && p->nSelectRow > (u64)nLimit
+ && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit)
){
- p->nSelectRow = nLimit;
+ p->nSelectRow = sqlite3LogEst((u64)nLimit);
}
if( addr ){
sqlite3VdbeJumpHere(v, addr);
@@ -2364,7 +2365,9 @@ static int multiSelect(
pDelete = p->pPrior;
p->pPrior = pPrior;
p->pOrderBy = 0;
- if( p->op==TK_UNION ) p->nSelectRow += pPrior->nSelectRow;
+ if( p->op==TK_UNION ){
+ p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
+ }
sqlite3ExprDelete(db, p->pLimit);
p->pLimit = pLimit;
p->pOffset = pOffset;
@@ -2499,7 +2502,7 @@ static int multiSelect(
nCol = p->pEList->nExpr;
pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1);
if( !pKeyInfo ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto multi_select_end;
}
for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
@@ -2854,7 +2857,7 @@ static int multiSelectOrderBy(
}
if( j==nOrderBy ){
Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
- if( pNew==0 ) return SQLITE_NOMEM;
+ if( pNew==0 ) return SQLITE_NOMEM_BKPT;
pNew->flags |= EP_IntValue;
pNew->u.iValue = i;
pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
@@ -3001,7 +3004,7 @@ static int multiSelectOrderBy(
addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd);
VdbeCoverage(v);
sqlite3VdbeGoto(v, addrEofA);
- p->nSelectRow += pPrior->nSelectRow;
+ p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
}
/* Generate a subroutine to run when the results from select B
@@ -4091,7 +4094,7 @@ static int withExpand(
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
- if( db->mallocFailed ) return SQLITE_NOMEM;
+ if( db->mallocFailed ) return SQLITE_NOMEM_BKPT;
assert( pFrom->pSelect );
/* Check if this is a recursive CTE. */
@@ -4987,7 +4990,7 @@ int sqlite3Select(
sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
sqlite3Select(pParse, pSub, &dest);
- pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow);
+ pItem->pTab->nRowLogEst = pSub->nSelectRow;
pItem->fg.viaCoroutine = 1;
pItem->regResult = dest.iSdst;
sqlite3VdbeEndCoroutine(v, pItem->regReturn);
@@ -5018,7 +5021,7 @@ int sqlite3Select(
sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
sqlite3Select(pParse, pSub, &dest);
- pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow);
+ pItem->pTab->nRowLogEst = pSub->nSelectRow;
if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
VdbeComment((v, "end %s", pItem->pTab->zName));
@@ -5101,7 +5104,7 @@ int sqlite3Select(
/* Set the limiter.
*/
iEnd = sqlite3VdbeMakeLabel(v);
- p->nSelectRow = LARGEST_INT64;
+ p->nSelectRow = 320; /* 4 billion rows */
computeLimitRegisters(pParse, p, iEnd);
if( p->iLimit==0 && sSort.addrSortIndex>=0 ){
sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen);
@@ -5125,10 +5128,12 @@ int sqlite3Select(
if( !isAgg && pGroupBy==0 ){
/* No aggregate functions and no GROUP BY clause */
u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0);
+ assert( WHERE_USE_LIMIT==SF_FixedLimit );
+ wctrlFlags |= p->selFlags & SF_FixedLimit;
/* Begin the database scan. */
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
- p->pEList, wctrlFlags, 0);
+ p->pEList, wctrlFlags, p->nSelectRow);
if( pWInfo==0 ) goto select_end;
if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){
p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo);
@@ -5188,9 +5193,11 @@ int sqlite3Select(
for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){
pItem->u.x.iAlias = 0;
}
- if( p->nSelectRow>100 ) p->nSelectRow = 100;
+ assert( 66==sqlite3LogEst(100) );
+ if( p->nSelectRow>66 ) p->nSelectRow = 66;
}else{
- p->nSelectRow = 1;
+ assert( 0==sqlite3LogEst(1) );
+ p->nSelectRow = 0;
}
/* If there is both a GROUP BY and an ORDER BY clause and they are
diff --git a/src/shell.c b/src/shell.c
index 2988f48d0..1cf9eb447 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -3260,7 +3260,7 @@ static int do_meta_command(char *zLine, ShellState *p){
char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
char cSep = '(';
while( xRead(&sCtx) ){
- zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z);
+ zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
cSep = ',';
if( sCtx.cTerm!=sCtx.cColSep ) break;
}
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index bf0dad4cb..a790d7797 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -7489,7 +7489,7 @@ void sqlite3_log(int iErrCode, const char *zFormat, ...);
** previously registered write-ahead log callback. ^Note that the
** [sqlite3_wal_autocheckpoint()] interface and the
** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
-** those overwrite any prior [sqlite3_wal_hook()] settings.
+** overwrite any prior [sqlite3_wal_hook()] settings.
*/
void *sqlite3_wal_hook(
sqlite3*,
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index e15c681a0..5ac33b4de 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -16,6 +16,14 @@
#define _SQLITEINT_H_
/*
+** Make sure that rand_s() is available on Windows systems with MSVC 2005
+** or higher.
+*/
+#if defined(_MSC_VER) && _MSC_VER>=1400
+# define _CRT_RAND_S
+#endif
+
+/*
** Include the header file used to customize the compiler options for MSVC.
** This should be done first so that it can successfully prevent spurious
** compiler warnings due to subsequent content in this file and other files
@@ -149,7 +157,7 @@
** to the next, so we have developed the following set of #if statements
** to generate appropriate macros for a wide range of compilers.
**
-** The correct "ANSI" way to do this is to use the intptr_t type.
+** The correct "ANSI" way to do this is to use the intptr_t type.
** Unfortunately, that typedef is not available on all compilers, or
** if it is available, it requires an #include of specific headers
** that vary from one machine to the next.
@@ -316,7 +324,7 @@
** is set. Thus NDEBUG becomes an opt-in rather than an opt-out
** feature.
*/
-#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
+#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
# define NDEBUG 1
#endif
#if defined(NDEBUG) && defined(SQLITE_DEBUG)
@@ -331,7 +339,7 @@
#endif
/*
-** The testcase() macro is used to aid in coverage testing. When
+** The testcase() macro is used to aid in coverage testing. When
** doing coverage testing, the condition inside the argument to
** testcase() must be evaluated both true and false in order to
** get full branch coverage. The testcase() macro is inserted
@@ -377,7 +385,7 @@
#endif
/*
-** The ALWAYS and NEVER macros surround boolean expressions which
+** The ALWAYS and NEVER macros surround boolean expressions which
** are intended to always be true or false, respectively. Such
** expressions could be omitted from the code completely. But they
** are included in a few cases in order to enhance the resilience
@@ -490,7 +498,7 @@
/*
** OMIT_TEMPDB is set to 1 if SQLITE_OMIT_TEMPDB is defined, or 0
-** afterward. Having this macro allows us to cause the C compiler
+** afterward. Having this macro allows us to cause the C compiler
** to omit code used by TEMP tables without messy #ifndef statements.
*/
#ifdef SQLITE_OMIT_TEMPDB
@@ -529,7 +537,7 @@
/*
** If no value has been provided for SQLITE_MAX_WORKER_THREADS, or if
-** SQLITE_TEMP_STORE is set to 3 (never use temporary files), set it
+** SQLITE_TEMP_STORE is set to 3 (never use temporary files), set it
** to zero.
*/
#if SQLITE_TEMP_STORE==3 || SQLITE_THREADSAFE==0
@@ -677,7 +685,7 @@ typedef INT8_TYPE i8; /* 1-byte signed integer */
** 4 -> 20 1000 -> 99 1048576 -> 200
** 10 -> 33 1024 -> 100 4294967296 -> 320
**
-** The LogEst can be negative to indicate fractional values.
+** The LogEst can be negative to indicate fractional values.
** Examples:
**
** 0.5 -> -10 0.1 -> -33 0.0625 -> -40
@@ -743,7 +751,7 @@ typedef INT16_TYPE LogEst;
#define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32))
#define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
-/*
+/*
** Round up a number to the next larger multiple of 8. This is used
** to force 8-byte alignment on 64-bit architectures.
*/
@@ -837,7 +845,7 @@ typedef INT16_TYPE LogEst;
/*
** An instance of the following structure is used to store the busy-handler
-** callback for a given sqlite handle.
+** callback for a given sqlite handle.
**
** The sqlite.busyHandler member of the sqlite struct contains the busy
** callback for the database handle. Each pager opened via the sqlite
@@ -882,9 +890,9 @@ struct BusyHandler {
/*
** The following value as a destructor means to use sqlite3DbFree().
-** The sqlite3DbFree() routine requires two parameters instead of the
-** one parameter that destructors normally want. So we have to introduce
-** this magic value that the code knows to handle differently. Any
+** The sqlite3DbFree() routine requires two parameters instead of the
+** one parameter that destructors normally want. So we have to introduce
+** this magic value that the code knows to handle differently. Any
** pointer will work here as long as it is distinct from SQLITE_STATIC
** and SQLITE_TRANSIENT.
*/
@@ -911,16 +919,16 @@ struct BusyHandler {
int sqlite3_wsd_init(int N, int J);
void *sqlite3_wsd_find(void *K, int L);
#else
- #define SQLITE_WSD
+ #define SQLITE_WSD
#define GLOBAL(t,v) v
#define sqlite3GlobalConfig sqlite3Config
#endif
/*
** The following macros are used to suppress compiler warnings and to
-** make it clear to human readers when a function parameter is deliberately
+** make it clear to human readers when a function parameter is deliberately
** left unused within the body of a function. This usually happens when
-** a function is called via a function pointer. For example the
+** a function is called via a function pointer. For example the
** implementation of an SQL aggregate step callback may not use the
** parameter indicating the number of arguments passed to the aggregate,
** if it knows that this is enforced elsewhere.
@@ -987,7 +995,7 @@ typedef struct WhereInfo WhereInfo;
typedef struct With With;
/*
-** Defer sourcing vdbe.h and btree.h until after the "u8" and
+** Defer sourcing vdbe.h and btree.h until after the "u8" and
** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque
** pointer types (i.e. FuncDef) defined above.
*/
@@ -1021,7 +1029,7 @@ struct Db {
** the Schema for the TEMP databaes (sqlite3.aDb[1]) which is free-standing.
** In shared cache mode, a single Schema object can be shared by multiple
** Btrees that refer to the same underlying BtShared object.
-**
+**
** Schema objects are automatically deallocated when the last Btree that
** references them is destroyed. The TEMP Schema is manually freed by
** sqlite3_close().
@@ -1046,7 +1054,7 @@ struct Schema {
};
/*
-** These macros can be used to test, set, or clear bits in the
+** These macros can be used to test, set, or clear bits in the
** Db.pSchema->flags field.
*/
#define DbHasProperty(D,I,P) (((D)->aDb[I].pSchema->schemaFlags&(P))==(P))
@@ -1110,13 +1118,15 @@ struct LookasideSlot {
};
/*
-** A hash table for function definitions.
+** A hash table for built-in function definitions. (Application-defined
+** functions use a regular table table from hash.h.)
**
** Hash each FuncDef structure into one of the FuncDefHash.a[] slots.
-** Collisions are on the FuncDef.pHash chain.
+** Collisions are on the FuncDef.u.pHash chain.
*/
+#define SQLITE_FUNC_HASH_SZ 23
struct FuncDefHash {
- FuncDef *a[23]; /* Hash table for functions */
+ FuncDef *a[SQLITE_FUNC_HASH_SZ]; /* Hash table for functions */
};
#ifdef SQLITE_USER_AUTHENTICATION
@@ -1209,9 +1219,9 @@ struct sqlite3 {
void *pTraceArg; /* Argument to the trace function */
void (*xProfile)(void*,const char*,u64); /* Profiling function */
void *pProfileArg; /* Argument to profile function */
- void *pCommitArg; /* Argument to xCommitCallback() */
+ void *pCommitArg; /* Argument to xCommitCallback() */
int (*xCommitCallback)(void*); /* Invoked at every commit. */
- void *pRollbackArg; /* Argument to xRollbackCallback() */
+ void *pRollbackArg; /* Argument to xRollbackCallback() */
void (*xRollbackCallback)(void*); /* Invoked at every commit. */
void *pUpdateArg;
void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
@@ -1251,7 +1261,7 @@ struct sqlite3 {
VTable **aVTrans; /* Virtual tables with open transactions */
VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */
#endif
- FuncDefHash aFunc; /* Hash table of connection functions */
+ Hash aFunc; /* Hash table of connection functions */
Hash aCollSeq; /* All collating sequences */
BusyHandler busyHandler; /* Busy callback */
Db aDbStatic[2]; /* Static space for the 2 default backends */
@@ -1263,8 +1273,8 @@ struct sqlite3 {
i64 nDeferredImmCons; /* Net deferred immediate constraints */
int *pnBytesFreed; /* If not NULL, increment this in DbFree() */
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
- /* The following variables are all protected by the STATIC_MASTER
- ** mutex, not by sqlite3.mutex. They are used by code in notify.c.
+ /* The following variables are all protected by the STATIC_MASTER
+ ** mutex, not by sqlite3.mutex. They are used by code in notify.c.
**
** When X.pUnlockConnection==Y, that means that X is waiting for Y to
** unlock so that it can proceed.
@@ -1378,27 +1388,33 @@ struct sqlite3 {
/*
** Each SQL function is defined by an instance of the following
-** structure. A pointer to this structure is stored in the sqlite.aFunc
-** hash table. When multiple functions have the same name, the hash table
-** points to a linked list of these structures.
+** structure. For global built-in functions (ex: substr(), max(), count())
+** a pointer to this structure is held in the sqlite3BuiltinFunctions object.
+** For per-connection application-defined functions, a pointer to this
+** structure is held in the db->aHash hash table.
+**
+** The u.pHash field is used by the global built-ins. The u.pDestructor
+** field is used by per-connection app-def functions.
*/
struct FuncDef {
- i16 nArg; /* Number of arguments. -1 means unlimited */
+ i8 nArg; /* Number of arguments. -1 means unlimited */
u16 funcFlags; /* Some combination of SQLITE_FUNC_* */
void *pUserData; /* User data parameter */
FuncDef *pNext; /* Next function with same name */
void (*xSFunc)(sqlite3_context*,int,sqlite3_value**); /* func or agg-step */
void (*xFinalize)(sqlite3_context*); /* Agg finalizer */
- char *zName; /* SQL name of the function. */
- FuncDef *pHash; /* Next with a different name but the same hash */
- FuncDestructor *pDestructor; /* Reference counted destructor function */
+ const char *zName; /* SQL name of the function. */
+ union {
+ FuncDef *pHash; /* Next with a different name but the same hash */
+ FuncDestructor *pDestructor; /* Reference counted destructor function */
+ } u;
};
/*
** This structure encapsulates a user-function destructor callback (as
** configured using create_function_v2()) and a reference counter. When
** create_function_v2() is called to create a function with a destructor,
-** a single object of this type is allocated. FuncDestructor.nRef is set to
+** a single object of this type is allocated. FuncDestructor.nRef is set to
** the number of FuncDef objects created (either 1 or 3, depending on whether
** or not the specified encoding is SQLITE_ANY). The FuncDef.pDestructor
** member of each of the new FuncDef objects is set to point to the allocated
@@ -1440,10 +1456,10 @@ struct FuncDestructor {
** used to create the initializers for the FuncDef structures.
**
** FUNCTION(zName, nArg, iArg, bNC, xFunc)
-** Used to create a scalar function definition of a function zName
+** Used to create a scalar function definition of a function zName
** implemented by C function xFunc that accepts nArg arguments. The
** value passed as iArg is cast to a (void*) and made available
-** as the user-data (sqlite3_user_data()) for the function. If
+** as the user-data (sqlite3_user_data()) for the function. If
** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set.
**
** VFUNCTION(zName, nArg, iArg, bNC, xFunc)
@@ -1462,8 +1478,8 @@ struct FuncDestructor {
** FUNCTION().
**
** LIKEFUNC(zName, nArg, pArg, flags)
-** Used to create a scalar function definition of a function zName
-** that accepts nArg arguments and is implemented by a call to C
+** Used to create a scalar function definition of a function zName
+** that accepts nArg arguments and is implemented by a call to C
** function likeFunc. Argument pArg is cast to a (void *) and made
** available as the function user-data (sqlite3_user_data()). The
** FuncDef.flags variable is set to the value passed as the flags
@@ -1471,28 +1487,28 @@ struct FuncDestructor {
*/
#define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
{nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
- SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, 0, 0}
+ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
#define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \
{nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
- SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, 0, 0}
+ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
#define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \
{nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
- SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, 0, 0}
+ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
#define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \
{nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\
- SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, 0, 0}
+ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
#define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
{nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
- pArg, 0, xFunc, 0, #zName, 0, 0}
+ pArg, 0, xFunc, 0, #zName, }
#define LIKEFUNC(zName, nArg, arg, flags) \
{nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \
- (void *)arg, 0, likeFunc, 0, #zName, 0, 0}
+ (void *)arg, 0, likeFunc, 0, #zName, {0} }
#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
- SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName,0,0}
+ SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}}
#define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \
- SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName,0,0}
+ SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}}
/*
** All current savepoints are stored in a linked list starting at
@@ -1579,7 +1595,7 @@ struct CollSeq {
**
** These used to have mnemonic name like 'i' for SQLITE_AFF_INTEGER and
** 't' for SQLITE_AFF_TEXT. But we can save a little space and improve
-** the speed a little by numbering the values consecutively.
+** the speed a little by numbering the values consecutively.
**
** But rather than start with 0 or 1, we begin with 'A'. That way,
** when multiple affinity types are concatenated into a string and
@@ -1598,7 +1614,7 @@ struct CollSeq {
/*
** The SQLITE_AFF_MASK values masks off the significant bits of an
-** affinity value.
+** affinity value.
*/
#define SQLITE_AFF_MASK 0x47
@@ -1618,20 +1634,20 @@ struct CollSeq {
/*
** An object of this type is created for each virtual table present in
-** the database schema.
+** the database schema.
**
** If the database schema is shared, then there is one instance of this
** structure for each database connection (sqlite3*) that uses the shared
** schema. This is because each database connection requires its own unique
-** instance of the sqlite3_vtab* handle used to access the virtual table
-** implementation. sqlite3_vtab* handles can not be shared between
-** database connections, even when the rest of the in-memory database
+** instance of the sqlite3_vtab* handle used to access the virtual table
+** implementation. sqlite3_vtab* handles can not be shared between
+** database connections, even when the rest of the in-memory database
** schema is shared, as the implementation often stores the database
** connection handle passed to it via the xConnect() or xCreate() method
** during initialization internally. This database connection handle may
-** then be used by the virtual table implementation to access real tables
-** within the database. So that they appear as part of the callers
-** transaction, these accesses need to be made via the same database
+** then be used by the virtual table implementation to access real tables
+** within the database. So that they appear as part of the callers
+** transaction, these accesses need to be made via the same database
** connection as that used to execute SQL operations on the virtual table.
**
** All VTable objects that correspond to a single table in a shared
@@ -1643,19 +1659,19 @@ struct CollSeq {
** sqlite3_vtab* handle in the compiled query.
**
** When an in-memory Table object is deleted (for example when the
-** schema is being reloaded for some reason), the VTable objects are not
-** deleted and the sqlite3_vtab* handles are not xDisconnect()ed
+** schema is being reloaded for some reason), the VTable objects are not
+** deleted and the sqlite3_vtab* handles are not xDisconnect()ed
** immediately. Instead, they are moved from the Table.pVTable list to
** another linked list headed by the sqlite3.pDisconnect member of the
-** corresponding sqlite3 structure. They are then deleted/xDisconnected
+** corresponding sqlite3 structure. They are then deleted/xDisconnected
** next time a statement is prepared using said sqlite3*. This is done
** to avoid deadlock issues involving multiple sqlite3.mutex mutexes.
** Refer to comments above function sqlite3VtabUnlockList() for an
** explanation as to why it is safe to add an entry to an sqlite3.pDisconnect
** list without holding the corresponding sqlite3.mutex mutex.
**
-** The memory for objects of this type is always allocated by
-** sqlite3DbMalloc(), using the connection handle stored in VTable.db as
+** The memory for objects of this type is always allocated by
+** sqlite3DbMalloc(), using the connection handle stored in VTable.db as
** the first argument.
*/
struct VTable {
@@ -1823,7 +1839,7 @@ struct FKey {
** key is set to NULL. CASCADE means that a DELETE or UPDATE of the
** referenced table row is propagated into the row that holds the
** foreign key.
-**
+**
** The following symbolic values are used to record which type
** of action to take.
*/
@@ -1844,7 +1860,7 @@ struct FKey {
/*
** An instance of the following structure is passed as the first
-** argument to sqlite3VdbeKeyCompare and is used to control the
+** argument to sqlite3VdbeKeyCompare and is used to control the
** comparison of the two index keys.
**
** Note that aSortOrder[] and aColl[] have nField+1 slots. There
@@ -1885,7 +1901,7 @@ struct KeyInfo {
** The key comparison functions actually return default_rc when they find
** an equals comparison. default_rc can be -1, 0, or +1. If there are
** multiple entries in the b-tree with the same key (when only looking
-** at the first pKeyInfo->nFields,) then default_rc can be set to -1 to
+** at the first pKeyInfo->nFields,) then default_rc can be set to -1 to
** cause the search to find the last match, or +1 to cause the search to
** find the first match.
**
@@ -1922,7 +1938,7 @@ struct UnpackedRecord {
** In the Table structure describing Ex1, nCol==3 because there are
** three columns in the table. In the Index structure describing
** Ex2, nColumn==2 since 2 of the 3 columns of Ex1 are indexed.
-** The value of aiColumn is {2, 0}. aiColumn[0]==2 because the
+** The value of aiColumn is {2, 0}. aiColumn[0]==2 because the
** first column to be indexed (c3) has an index of 2 in Ex1.aCol[].
** The second column to be indexed (c1) has an index of 0 in
** Ex1.aCol[], hence Ex2.aiColumn[1]==0.
@@ -1930,7 +1946,7 @@ struct UnpackedRecord {
** The Index.onError field determines whether or not the indexed columns
** must be unique and what to do if they are not. When Index.onError=OE_None,
** it means this is not a unique index. Otherwise it is a unique index
-** and the value of Index.onError indicate the which conflict resolution
+** and the value of Index.onError indicate the which conflict resolution
** algorithm to employ whenever an attempt is made to insert a non-unique
** element.
**
@@ -1995,7 +2011,7 @@ struct Index {
#define XN_EXPR (-2) /* Indexed column is an expression */
/*
-** Each sample stored in the sqlite_stat3 table is represented in memory
+** Each sample stored in the sqlite_stat3 table is represented in memory
** using a structure of this type. See documentation at the top of the
** analyze.c source file for additional information.
*/
@@ -2090,9 +2106,9 @@ typedef int ynVar;
** to represent the greater-than-or-equal-to operator in the expression
** tree.
**
-** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB,
+** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB,
** or TK_STRING), then Expr.token contains the text of the SQL literal. If
-** the expression is a variable (TK_VARIABLE), then Expr.token contains the
+** the expression is a variable (TK_VARIABLE), then Expr.token contains the
** variable name. Finally, if the expression is an SQL function (TK_FUNCTION),
** then Expr.token contains the name of the function.
**
@@ -2103,7 +2119,7 @@ typedef int ynVar;
** a CASE expression or an IN expression of the form "<lhs> IN (<y>, <z>...)".
** Expr.x.pSelect is used if the expression is a sub-select or an expression of
** the form "<lhs> IN (SELECT ...)". If the EP_xIsSelect bit is set in the
-** Expr.flags mask, then Expr.x.pSelect is valid. Otherwise, Expr.x.pList is
+** Expr.flags mask, then Expr.x.pSelect is valid. Otherwise, Expr.x.pList is
** valid.
**
** An expression of the form ID or ID.ID refers to a column in a table.
@@ -2114,8 +2130,8 @@ typedef int ynVar;
** value is also stored in the Expr.iAgg column in the aggregate so that
** it can be accessed after all aggregates are computed.
**
-** If the expression is an unbound variable marker (a question mark
-** character '?' in the original SQL) then the Expr.iTable holds the index
+** If the expression is an unbound variable marker (a question mark
+** character '?' in the original SQL) then the Expr.iTable holds the index
** number for that variable.
**
** If the expression is a subquery then Expr.iColumn holds an integer
@@ -2154,7 +2170,7 @@ struct Expr {
/* If the EP_TokenOnly flag is set in the Expr.flags mask, then no
** space is allocated for the fields below this point. An attempt to
- ** access them will result in a segfault or malfunction.
+ ** access them will result in a segfault or malfunction.
*********************************************************************/
Expr *pLeft; /* Left subnode */
@@ -2220,7 +2236,7 @@ struct Expr {
#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */
/*
-** These macros can be used to test, set, or clear bits in the
+** These macros can be used to test, set, or clear bits in the
** Expr.flags field.
*/
#define ExprHasProperty(E,P) (((E)->flags&(P))!=0)
@@ -2239,8 +2255,8 @@ struct Expr {
#endif
/*
-** Macros to determine the number of bytes required by a normal Expr
-** struct, an Expr struct with the EP_Reduced flag set in Expr.flags
+** Macros to determine the number of bytes required by a normal Expr
+** struct, an Expr struct with the EP_Reduced flag set in Expr.flags
** and an Expr struct with the EP_TokenOnly flag set.
*/
#define EXPR_FULLSIZE sizeof(Expr) /* Full size */
@@ -2248,7 +2264,7 @@ struct Expr {
#define EXPR_TOKENONLYSIZE offsetof(Expr,pLeft) /* Fewer features */
/*
-** Flags passed to the sqlite3ExprDup() function. See the header comment
+** Flags passed to the sqlite3ExprDup() function. See the header comment
** above sqlite3ExprDup() for details.
*/
#define EXPRDUP_REDUCE 0x0001 /* Used reduced-size Expr nodes */
@@ -2330,7 +2346,11 @@ struct IdList {
** tables in a join to 32 instead of 64. But it also reduces the size
** of the library by 738 bytes on ix86.
*/
-typedef u64 Bitmask;
+#ifdef SQLITE_BITMASK_TYPE
+ typedef SQLITE_BITMASK_TYPE Bitmask;
+#else
+ typedef u64 Bitmask;
+#endif
/*
** The number of bits in a Bitmask. "BMS" means "BitMask Size".
@@ -2430,6 +2450,7 @@ struct SrcList {
#define WHERE_SORTBYGROUP 0x0800 /* Support sqlite3WhereIsSorted() */
#define WHERE_REOPEN_IDX 0x1000 /* Try to use OP_ReopenIdx */
#define WHERE_ONEPASS_MULTIROW 0x2000 /* ONEPASS is ok with multiple rows */
+#define WHERE_USE_LIMIT 0x4000 /* There is a constant LIMIT clause */
/* Allowed return values from sqlite3WhereIsDistinct()
*/
@@ -2447,12 +2468,12 @@ struct SrcList {
** pEList corresponds to the result set of a SELECT and is NULL for
** other statements.
**
-** NameContexts can be nested. When resolving names, the inner-most
+** NameContexts can be nested. When resolving names, the inner-most
** context is searched first. If no match is found, the next outer
** context is checked. If there is still no match, the next context
** is checked. This process continues until either a match is found
** or all contexts are check. When a match is found, the nRef member of
-** the context containing the match is incremented.
+** the context containing the match is incremented.
**
** Each subquery gets a new NameContext. The pNext field points to the
** NameContext in the parent query. Thus the process of scanning the
@@ -2475,7 +2496,7 @@ struct NameContext {
**
** Note: NC_MinMaxAgg must have the same value as SF_MinMaxAgg and
** SQLITE_FUNC_MINMAX.
-**
+**
*/
#define NC_AllowAgg 0x0001 /* Aggregate functions are allowed here */
#define NC_HasAgg 0x0002 /* One or more aggregate functions seen */
@@ -2508,13 +2529,13 @@ struct NameContext {
struct Select {
ExprList *pEList; /* The fields of the result */
u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
- u16 selFlags; /* Various SF_* values */
+ LogEst nSelectRow; /* Estimated number of result rows */
+ u32 selFlags; /* Various SF_* values */
int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
#if SELECTTRACE_ENABLED
char zSelName[12]; /* Symbolic name of this SELECT use for debugging */
#endif
int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */
- u64 nSelectRow; /* Estimated number of result rows */
SrcList *pSrc; /* The FROM clause */
Expr *pWhere; /* The WHERE clause */
ExprList *pGroupBy; /* The GROUP BY clause */
@@ -2531,22 +2552,23 @@ struct Select {
** Allowed values for Select.selFlags. The "SF" prefix stands for
** "Select Flag".
*/
-#define SF_Distinct 0x0001 /* Output should be DISTINCT */
-#define SF_All 0x0002 /* Includes the ALL keyword */
-#define SF_Resolved 0x0004 /* Identifiers have been resolved */
-#define SF_Aggregate 0x0008 /* Contains aggregate functions */
-#define SF_UsesEphemeral 0x0010 /* Uses the OpenEphemeral opcode */
-#define SF_Expanded 0x0020 /* sqlite3SelectExpand() called on this */
-#define SF_HasTypeInfo 0x0040 /* FROM subqueries have Table metadata */
-#define SF_Compound 0x0080 /* Part of a compound query */
-#define SF_Values 0x0100 /* Synthesized from VALUES clause */
-#define SF_MultiValue 0x0200 /* Single VALUES term with multiple rows */
-#define SF_NestedFrom 0x0400 /* Part of a parenthesized FROM clause */
-#define SF_MaybeConvert 0x0800 /* Need convertCompoundSelectToSubquery() */
-#define SF_MinMaxAgg 0x1000 /* Aggregate containing min() or max() */
-#define SF_Recursive 0x2000 /* The recursive part of a recursive CTE */
-#define SF_Converted 0x4000 /* By convertCompoundSelectToSubquery() */
-#define SF_IncludeHidden 0x8000 /* Include hidden columns in output */
+#define SF_Distinct 0x00001 /* Output should be DISTINCT */
+#define SF_All 0x00002 /* Includes the ALL keyword */
+#define SF_Resolved 0x00004 /* Identifiers have been resolved */
+#define SF_Aggregate 0x00008 /* Contains aggregate functions */
+#define SF_UsesEphemeral 0x00010 /* Uses the OpenEphemeral opcode */
+#define SF_Expanded 0x00020 /* sqlite3SelectExpand() called on this */
+#define SF_HasTypeInfo 0x00040 /* FROM subqueries have Table metadata */
+#define SF_Compound 0x00080 /* Part of a compound query */
+#define SF_Values 0x00100 /* Synthesized from VALUES clause */
+#define SF_MultiValue 0x00200 /* Single VALUES term with multiple rows */
+#define SF_NestedFrom 0x00400 /* Part of a parenthesized FROM clause */
+#define SF_MaybeConvert 0x00800 /* Need convertCompoundSelectToSubquery() */
+#define SF_MinMaxAgg 0x01000 /* Aggregate containing min() or max() */
+#define SF_Recursive 0x02000 /* The recursive part of a recursive CTE */
+#define SF_FixedLimit 0x04000 /* nSelectRow set by a constant LIMIT */
+#define SF_Converted 0x08000 /* By convertCompoundSelectToSubquery() */
+#define SF_IncludeHidden 0x10000 /* Include hidden columns in output */
/*
@@ -2554,7 +2576,7 @@ struct Select {
** by one of the following macros. The "SRT" prefix means "SELECT Result
** Type".
**
-** SRT_Union Store results as a key in a temporary index
+** SRT_Union Store results as a key in a temporary index
** identified by pDest->iSDParm.
**
** SRT_Except Remove results from the temporary index pDest->iSDParm.
@@ -2578,7 +2600,7 @@ struct Select {
** of the query. This destination implies "LIMIT 1".
**
** SRT_Set The result must be a single column. Store each
-** row of result as the key in table pDest->iSDParm.
+** row of result as the key in table pDest->iSDParm.
** Apply the affinity pDest->affSdst before storing
** results. Used to implement "IN (SELECT ...)".
**
@@ -2646,7 +2668,7 @@ struct SelectDest {
};
/*
-** During code generation of statements that do inserts into AUTOINCREMENT
+** During code generation of statements that do inserts into AUTOINCREMENT
** tables, the following information is attached to the Table.u.autoInc.p
** pointer of each autoincrement table to record some side information that
** the code generator needs. We have to keep per-table autoincrement
@@ -2669,7 +2691,7 @@ struct AutoincInfo {
#endif
/*
-** At least one instance of the following structure is created for each
+** At least one instance of the following structure is created for each
** trigger that may be fired while parsing an INSERT, UPDATE or DELETE
** statement. All such objects are stored in the linked list headed at
** Parse.pTriggerPrg and deleted once statement compilation has been
@@ -2682,7 +2704,7 @@ struct AutoincInfo {
** values for both pTrigger and orconf.
**
** The TriggerPrg.aColmask[0] variable is set to a mask of old.* columns
-** accessed (or set to 0 for triggers fired as a result of INSERT
+** accessed (or set to 0 for triggers fired as a result of INSERT
** statements). Similarly, the TriggerPrg.aColmask[1] variable is set to
** a mask of new.* columns used by the program.
*/
@@ -2723,7 +2745,7 @@ struct TriggerPrg {
** is constant but the second part is reset at the beginning and end of
** each recursion.
**
-** The nTableLock and aTableLock variables are only used if the shared-cache
+** The nTableLock and aTableLock variables are only used if the shared-cache
** feature is enabled (if sqlite3Tsd()->useSharedData is true). They are
** used to store the set of table-locks required by the statement being
** compiled. Function sqlite3TableLock() is used to add entries to the
@@ -2880,10 +2902,10 @@ struct AuthContext {
/*
* Each trigger present in the database schema is stored as an instance of
- * struct Trigger.
+ * struct Trigger.
*
* Pointers to instances of struct Trigger are stored in two ways.
- * 1. In the "trigHash" hash table (part of the sqlite3* that represents the
+ * 1. In the "trigHash" hash table (part of the sqlite3* that represents the
* database). This allows Trigger structures to be retrieved by name.
* 2. All triggers associated with a single table form a linked list, using the
* pNext member of struct Trigger. A pointer to the first element of the
@@ -2909,7 +2931,7 @@ struct Trigger {
/*
** A trigger is either a BEFORE or an AFTER trigger. The following constants
-** determine which.
+** determine which.
**
** If there are multiple triggers, you might of some BEFORE and some AFTER.
** In that cases, the constants below can be ORed together.
@@ -2919,15 +2941,15 @@ struct Trigger {
/*
* An instance of struct TriggerStep is used to store a single SQL statement
- * that is a part of a trigger-program.
+ * that is a part of a trigger-program.
*
* Instances of struct TriggerStep are stored in a singly linked list (linked
- * using the "pNext" member) referenced by the "step_list" member of the
+ * using the "pNext" member) referenced by the "step_list" member of the
* associated struct Trigger instance. The first element of the linked list is
* the first step of the trigger-program.
- *
+ *
* The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or
- * "SELECT" statement. The meanings of the other members is determined by the
+ * "SELECT" statement. The meanings of the other members is determined by the
* value of "op" as follows:
*
* (op == TK_INSERT)
@@ -2937,7 +2959,7 @@ struct Trigger {
* zTarget -> Dequoted name of the table to insert into.
* pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
* this stores values to be inserted. Otherwise NULL.
- * pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ...
+ * pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ...
* statement, then this stores the column-names to be
* inserted into.
*
@@ -2945,7 +2967,7 @@ struct Trigger {
* zTarget -> Dequoted name of the table to delete from.
* pWhere -> The WHERE clause of the DELETE statement if one is specified.
* Otherwise NULL.
- *
+ *
* (op == TK_UPDATE)
* zTarget -> Dequoted name of the table to update.
* pWhere -> The WHERE clause of the UPDATE statement if one is specified.
@@ -2953,7 +2975,7 @@ struct Trigger {
* pExprList -> A list of the columns to update and the expressions to update
* them to. See sqlite3Update() documentation of "pChanges"
* argument.
- *
+ *
*/
struct TriggerStep {
u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
@@ -2971,7 +2993,7 @@ struct TriggerStep {
/*
** The following structure contains information used by the sqliteFix...
** routines as they walk the parse tree to make database references
-** explicit.
+** explicit.
*/
typedef struct DbFixer DbFixer;
struct DbFixer {
@@ -3181,6 +3203,15 @@ int sqlite3CantopenError(int);
#define SQLITE_CORRUPT_BKPT sqlite3CorruptError(__LINE__)
#define SQLITE_MISUSE_BKPT sqlite3MisuseError(__LINE__)
#define SQLITE_CANTOPEN_BKPT sqlite3CantopenError(__LINE__)
+#ifdef SQLITE_DEBUG
+ int sqlite3NomemError(int);
+ int sqlite3IoerrnomemError(int);
+# define SQLITE_NOMEM_BKPT sqlite3NomemError(__LINE__)
+# define SQLITE_IOERR_NOMEM_BKPT sqlite3IoerrnomemError(__LINE__)
+#else
+# define SQLITE_NOMEM_BKPT SQLITE_NOMEM
+# define SQLITE_IOERR_NOMEM_BKPT SQLITE_IOERR_NOMEM
+#endif
/*
** FTS3 and FTS4 both require virtual table support
@@ -3237,7 +3268,7 @@ int sqlite3IsIdChar(u8);
/*
** Internal function prototypes
*/
-#define sqlite3StrICmp sqlite3_stricmp
+int sqlite3StrICmp(const char*,const char*);
int sqlite3Strlen30(const char*);
#define sqlite3StrNICmp sqlite3_strnicmp
@@ -3277,7 +3308,7 @@ int sqlite3HeapNearlyFull(void);
#ifdef SQLITE_USE_ALLOCA
# define sqlite3StackAllocRaw(D,N) alloca(N)
# define sqlite3StackAllocZero(D,N) memset(alloca(N), 0, N)
-# define sqlite3StackFree(D,P)
+# define sqlite3StackFree(D,P)
#else
# define sqlite3StackAllocRaw(D,N) sqlite3DbMallocRaw(D,N)
# define sqlite3StackAllocZero(D,N) sqlite3DbMallocZero(D,N)
@@ -3472,7 +3503,7 @@ Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
void sqlite3DropIndex(Parse*, SrcList*, int);
int sqlite3Select(Parse*, Select*, SelectDest*);
Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
- Expr*,ExprList*,u16,Expr*,Expr*);
+ Expr*,ExprList*,u32,Expr*,Expr*);
void sqlite3SelectDelete(sqlite3*, Select*);
Table *sqlite3SrcListLookup(Parse*, SrcList*);
int sqlite3IsReadOnly(Parse*, Table*, int);
@@ -3484,7 +3515,7 @@ void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
void sqlite3WhereEnd(WhereInfo*);
-u64 sqlite3WhereOutputRowCount(WhereInfo*);
+LogEst sqlite3WhereOutputRowCount(WhereInfo*);
int sqlite3WhereIsDistinct(WhereInfo*);
int sqlite3WhereIsOrdered(WhereInfo*);
int sqlite3WhereIsSorted(WhereInfo*);
@@ -3584,11 +3615,11 @@ void sqlite3SelectSetName(Select*,const char*);
#else
# define sqlite3SelectSetName(A,B)
#endif
-void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
-FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8);
-void sqlite3RegisterBuiltinFunctions(sqlite3*);
+void sqlite3InsertBuiltinFuncs(FuncDef*,int);
+FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
+void sqlite3RegisterBuiltinFunctions(void);
void sqlite3RegisterDateTimeFunctions(void);
-void sqlite3RegisterGlobalFunctions(void);
+void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*);
int sqlite3SafetyCheckOk(sqlite3*);
int sqlite3SafetyCheckSickOrOk(sqlite3*);
void sqlite3ChangeCookie(Parse*, int);
@@ -3734,7 +3765,7 @@ u8 sqlite3GetBoolean(const char *z,u8);
const void *sqlite3ValueText(sqlite3_value*, u8);
int sqlite3ValueBytes(sqlite3_value*, u8);
-void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
+void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
void(*)(void*));
void sqlite3ValueSetNull(sqlite3_value*);
void sqlite3ValueFree(sqlite3_value*);
@@ -3749,7 +3780,7 @@ extern const unsigned char sqlite3UpperToLower[];
extern const unsigned char sqlite3CtypeMap[];
extern const Token sqlite3IntTokens[];
extern SQLITE_WSD struct Sqlite3Config sqlite3Config;
-extern SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
+extern FuncDefHash sqlite3BuiltinFunctions;
#ifndef SQLITE_OMIT_WSD
extern int sqlite3PendingByte;
#endif
@@ -3794,7 +3825,7 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*);
#ifdef SQLITE_DEBUG
int sqlite3KeyInfoIsWriteable(KeyInfo*);
#endif
-int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
+int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
void (*)(sqlite3_context*,int,sqlite3_value **),
void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
FuncDestructor *pDestructor
@@ -3857,7 +3888,7 @@ void sqlite3AutoLoadExtensions(sqlite3*);
# define sqlite3VtabRollback(X)
# define sqlite3VtabCommit(X)
# define sqlite3VtabInSync(db) 0
-# define sqlite3VtabLock(X)
+# define sqlite3VtabLock(X)
# define sqlite3VtabUnlock(X)
# define sqlite3VtabUnlockList(X)
# define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK
@@ -3915,7 +3946,7 @@ const char *sqlite3JournalModename(int);
** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign
** key functionality is available. If OMIT_TRIGGER is defined but
** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In
-** this case foreign keys are parsed, but no other functionality is
+** this case foreign keys are parsed, but no other functionality is
** provided (enforcement of FK constraints requires the triggers sub-system).
*/
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
@@ -4019,7 +4050,7 @@ void sqlite3Put4byte(u8*, u32);
/*
** If the SQLITE_ENABLE IOTRACE exists then the global variable
** sqlite3IoTrace is a pointer to a printf-like routine used to
-** print I/O tracing messages.
+** print I/O tracing messages.
*/
#ifdef SQLITE_ENABLE_IOTRACE
# define IOTRACE(A) if( sqlite3IoTrace ){ sqlite3IoTrace A; }
@@ -4053,7 +4084,7 @@ SQLITE_API SQLITE_EXTERN void (SQLITE_CDECL *sqlite3IoTrace)(const char*,...);
** that allocations that might have been satisfied by lookaside are not
** passed back to non-lookaside free() routines. Asserts such as the
** example above are placed on the non-lookaside free() routines to verify
-** this constraint.
+** this constraint.
**
** All of this is no-op for a production build. It only comes into
** play when the SQLITE_MEMDEBUG compile-time option is used.
diff --git a/src/table.c b/src/table.c
index 153bfb319..a50d83ce6 100644
--- a/src/table.c
+++ b/src/table.c
@@ -101,7 +101,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
return 0;
malloc_failed:
- p->rc = SQLITE_NOMEM;
+ p->rc = SQLITE_NOMEM_BKPT;
return 1;
}
@@ -142,7 +142,7 @@ int sqlite3_get_table(
res.azResult = sqlite3_malloc64(sizeof(char*)*res.nAlloc );
if( res.azResult==0 ){
db->errCode = SQLITE_NOMEM;
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
res.azResult[0] = 0;
rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
@@ -171,7 +171,7 @@ int sqlite3_get_table(
if( azNew==0 ){
sqlite3_free_table(&res.azResult[1]);
db->errCode = SQLITE_NOMEM;
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
res.azResult = azNew;
}
diff --git a/src/test1.c b/src/test1.c
index c5e71582b..713152b82 100644
--- a/src/test1.c
+++ b/src/test1.c
@@ -3154,7 +3154,7 @@ static int test_bind_zeroblob64(
){
sqlite3_stmt *pStmt;
int idx;
- i64 n;
+ Tcl_WideInt n;
int rc;
if( objc!=4 ){
diff --git a/src/test_blob.c b/src/test_blob.c
index 4a7075a28..ec2227bb3 100644
--- a/src/test_blob.c
+++ b/src/test_blob.c
@@ -105,7 +105,7 @@ static int test_blob_open(
const char *zDb;
const char *zTable;
const char *zColumn;
- sqlite_int64 iRowid;
+ Tcl_WideInt iRowid;
int flags;
const char *zVarname;
int nVarname;
diff --git a/src/test_fs.c b/src/test_fs.c
index 45db0b53b..32026d0f3 100644
--- a/src/test_fs.c
+++ b/src/test_fs.c
@@ -496,9 +496,9 @@ static int fstreeFilter(
#if SQLITE_OS_WIN
zRoot = sqlite3_mprintf("%s%c", getenv("SystemDrive"), '/');
- nRoot = strlen(zRoot);
+ nRoot = sqlite3Strlen30(zRoot);
zPrefix = sqlite3_mprintf("%s", getenv("SystemDrive"));
- nPrefix = strlen(zPrefix);
+ nPrefix = sqlite3Strlen30(zPrefix);
#else
zRoot = "/";
nRoot = 1;
diff --git a/src/threads.c b/src/threads.c
index 251b9b763..f128d69fc 100644
--- a/src/threads.c
+++ b/src/threads.c
@@ -63,7 +63,7 @@ int sqlite3ThreadCreate(
*ppThread = 0;
p = sqlite3Malloc(sizeof(*p));
- if( p==0 ) return SQLITE_NOMEM;
+ if( p==0 ) return SQLITE_NOMEM_BKPT;
memset(p, 0, sizeof(*p));
p->xTask = xTask;
p->pIn = pIn;
@@ -89,7 +89,7 @@ int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
int rc;
assert( ppOut!=0 );
- if( NEVER(p==0) ) return SQLITE_NOMEM;
+ if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT;
if( p->done ){
*ppOut = p->pOut;
rc = SQLITE_OK;
@@ -154,7 +154,7 @@ int sqlite3ThreadCreate(
assert( xTask!=0 );
*ppThread = 0;
p = sqlite3Malloc(sizeof(*p));
- if( p==0 ) return SQLITE_NOMEM;
+ if( p==0 ) return SQLITE_NOMEM_BKPT;
/* If the SQLITE_TESTCTRL_FAULT_INSTALL callback is registered to a
** function that returns SQLITE_ERROR when passed the argument 200, that
** forces worker threads to run sequentially and deterministically
@@ -186,7 +186,7 @@ int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
BOOL bRc;
assert( ppOut!=0 );
- if( NEVER(p==0) ) return SQLITE_NOMEM;
+ if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT;
if( p->xTask==0 ){
/* assert( p->id==GetCurrentThreadId() ); */
rc = WAIT_OBJECT_0;
@@ -234,7 +234,7 @@ int sqlite3ThreadCreate(
assert( xTask!=0 );
*ppThread = 0;
p = sqlite3Malloc(sizeof(*p));
- if( p==0 ) return SQLITE_NOMEM;
+ if( p==0 ) return SQLITE_NOMEM_BKPT;
if( (SQLITE_PTR_TO_INT(p)/17)&1 ){
p->xTask = xTask;
p->pIn = pIn;
@@ -250,7 +250,7 @@ int sqlite3ThreadCreate(
int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
assert( ppOut!=0 );
- if( NEVER(p==0) ) return SQLITE_NOMEM;
+ if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT;
if( p->xTask ){
*ppOut = p->xTask(p->pIn);
}else{
@@ -261,7 +261,7 @@ int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
#if defined(SQLITE_TEST)
{
void *pTstAlloc = sqlite3Malloc(10);
- if (!pTstAlloc) return SQLITE_NOMEM;
+ if (!pTstAlloc) return SQLITE_NOMEM_BKPT;
sqlite3_free(pTstAlloc);
}
#endif
diff --git a/src/tokenize.c b/src/tokenize.c
index 9b3444ac8..19a5ddf04 100644
--- a/src/tokenize.c
+++ b/src/tokenize.c
@@ -285,7 +285,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
case CC_BANG: {
if( z[1]!='=' ){
*tokenType = TK_ILLEGAL;
- return 2;
+ return 1;
}else{
*tokenType = TK_NE;
return 2;
@@ -435,8 +435,8 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
*tokenType = TK_ID;
return keywordCode((char*)z, i, tokenType);
}
-#ifndef SQLITE_OMIT_BLOB_LITERAL
case CC_X: {
+#ifndef SQLITE_OMIT_BLOB_LITERAL
testcase( z[0]=='x' ); testcase( z[0]=='X' );
if( z[1]=='\'' ){
*tokenType = TK_BLOB;
@@ -448,10 +448,10 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
if( z[i] ) i++;
return i;
}
+#endif
/* If it is not a BLOB literal, then it must be an ID, since no
** SQL keywords start with the letter 'x'. Fall through */
}
-#endif
case CC_ID: {
i = 1;
break;
@@ -495,7 +495,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
pEngine = sqlite3ParserAlloc(sqlite3Malloc);
if( pEngine==0 ){
sqlite3OomFault(db);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
assert( pParse->pNewTable==0 );
assert( pParse->pNewTrigger==0 );
@@ -523,18 +523,17 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
break;
}
}else{
- if( tokenType==TK_SEMI ) pParse->zTail = &zSql[i];
sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse);
lastTokenParsed = tokenType;
if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break;
}
}
assert( nErr==0 );
+ pParse->zTail = &zSql[i];
if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
assert( zSql[i]==0 );
if( lastTokenParsed!=TK_SEMI ){
sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
- pParse->zTail = &zSql[i];
}
if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
@@ -549,7 +548,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
#endif /* YYDEBUG */
sqlite3ParserFree(pEngine, sqlite3_free);
if( db->mallocFailed ){
- pParse->rc = SQLITE_NOMEM;
+ pParse->rc = SQLITE_NOMEM_BKPT;
}
if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc));
diff --git a/src/treeview.c b/src/treeview.c
index 298580431..ff3b4be5a 100644
--- a/src/treeview.c
+++ b/src/treeview.c
@@ -132,9 +132,10 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
sqlite3TreeViewPush(pView, 1);
}
do{
- sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x",
+ sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x nSelectRow=%d",
((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
- ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags
+ ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags,
+ (int)p->nSelectRow
);
if( cnt++ ) sqlite3TreeViewPop(pView);
if( p->pPrior ){
diff --git a/src/utf.c b/src/utf.c
index e42ab418a..7801306cb 100644
--- a/src/utf.c
+++ b/src/utf.c
@@ -231,7 +231,7 @@ SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
rc = sqlite3VdbeMemMakeWriteable(pMem);
if( rc!=SQLITE_OK ){
assert( rc==SQLITE_NOMEM );
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
zIn = (u8*)pMem->z;
zTerm = &zIn[pMem->n&~1];
@@ -273,7 +273,7 @@ SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
zTerm = &zIn[pMem->n];
zOut = sqlite3DbMallocRaw(pMem->db, len);
if( !zOut ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
z = zOut;
diff --git a/src/util.c b/src/util.c
index 37b585b2e..e325a7311 100644
--- a/src/util.c
+++ b/src/util.c
@@ -256,16 +256,25 @@ void sqlite3TokenInit(Token *p, char *z){
** independence" that SQLite uses internally when comparing identifiers.
*/
int sqlite3_stricmp(const char *zLeft, const char *zRight){
- register unsigned char *a, *b;
if( zLeft==0 ){
return zRight ? -1 : 0;
}else if( zRight==0 ){
return 1;
}
+ return sqlite3StrICmp(zLeft, zRight);
+}
+int sqlite3StrICmp(const char *zLeft, const char *zRight){
+ unsigned char *a, *b;
+ int c;
a = (unsigned char *)zLeft;
b = (unsigned char *)zRight;
- while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
- return UpperToLower[*a] - UpperToLower[*b];
+ for(;;){
+ c = (int)UpperToLower[*a] - (int)UpperToLower[*b];
+ if( c || *a==0 ) break;
+ a++;
+ b++;
+ }
+ return c;
}
int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
register unsigned char *a, *b;
@@ -1107,10 +1116,12 @@ u32 sqlite3Get4byte(const u8 *p){
void sqlite3Put4byte(unsigned char *p, u32 v){
#if SQLITE_BYTEORDER==4321
memcpy(p,&v,4);
-#elif SQLITE_BYTEORDER==1234 && defined(__GNUC__) && GCC_VERSION>=4003000
+#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
+ && defined(__GNUC__) && GCC_VERSION>=4003000
u32 x = __builtin_bswap32(v);
memcpy(p,&x,4);
-#elif SQLITE_BYTEORDER==1234 && defined(_MSC_VER) && _MSC_VER>=1300
+#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
+ && defined(_MSC_VER) && _MSC_VER>=1300
u32 x = _byteswap_ulong(v);
memcpy(p,&x,4);
#else
diff --git a/src/vacuum.c b/src/vacuum.c
index adc802e60..bc7b5831b 100644
--- a/src/vacuum.c
+++ b/src/vacuum.c
@@ -38,7 +38,7 @@ static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
sqlite3_stmt *pStmt;
VVA_ONLY( int rc; )
if( !zSql ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
@@ -219,7 +219,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
|| (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0))
|| NEVER(db->mallocFailed)
){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto end_of_vacuum;
}
diff --git a/src/vdbe.c b/src/vdbe.c
index cab029834..7a47ef8b8 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -637,7 +637,11 @@ int sqlite3VdbeExec(
}
sqlite3EndBenignMalloc();
#endif
- for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){
+ for(pOp=&aOp[p->pc]; 1; pOp++){
+ /* Errors are detected by individual opcodes, with an immediate
+ ** jumps to abort_due_to_error. */
+ assert( rc==SQLITE_OK );
+
assert( pOp>=aOp && pOp<&aOp[p->nOp]);
#ifdef VDBE_PROFILE
start = sqlite3Hwtime();
@@ -784,7 +788,7 @@ check_for_interrupt:
nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps);
if( db->xProgress(db->pProgressArg) ){
rc = SQLITE_INTERRUPT;
- goto vdbe_error_halt;
+ goto abort_due_to_error;
}
}
#endif
@@ -1063,7 +1067,10 @@ case OP_String8: { /* same as TK_STRING, out2 */
#ifndef SQLITE_OMIT_UTF16
if( encoding!=SQLITE_UTF8 ){
rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
- if( rc==SQLITE_TOOBIG ) goto too_big;
+ if( rc ){
+ assert( rc==SQLITE_TOOBIG ); /* This is the only possible error here */
+ goto too_big;
+ }
if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
assert( pOut->szMalloc>0 && pOut->zMalloc==pOut->z );
assert( VdbeMemDynamic(pOut)==0 );
@@ -1329,7 +1336,7 @@ case OP_ResultRow: {
&& db->xProgress(db->pProgressArg)!=0
){
rc = SQLITE_INTERRUPT;
- goto vdbe_error_halt;
+ goto abort_due_to_error;
}
#endif
@@ -1339,7 +1346,7 @@ case OP_ResultRow: {
if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){
assert( db->flags&SQLITE_CountRows );
assert( p->usesStmtJournal );
- break;
+ goto abort_due_to_error;
}
/* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then
@@ -1359,9 +1366,7 @@ case OP_ResultRow: {
*/
assert( p->iStatement==0 || db->flags&SQLITE_CountRows );
rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE);
- if( NEVER(rc!=SQLITE_OK) ){
- break;
- }
+ assert( rc==SQLITE_OK );
/* Invalidate all ephemeral cursor row caches */
p->cacheCtr = (p->cacheCtr + 2)|1;
@@ -1684,7 +1689,8 @@ case OP_Function: {
sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut));
rc = pCtx->isError;
}
- sqlite3VdbeDeleteAuxData(p, pCtx->iOp, pOp->p1);
+ sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
+ if( rc ) goto abort_due_to_error;
}
/* Copy the result of the function into register P3 */
@@ -1868,6 +1874,7 @@ case OP_Cast: { /* in1 */
rc = ExpandBlob(pIn1);
sqlite3VdbeMemCast(pIn1, pOp->p2, encoding);
UPDATE_MAX_BLOBSIZE(pIn1);
+ if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_CAST */
@@ -2477,7 +2484,7 @@ case OP_Column: {
*/
if( offset > 98307 || offset > pC->payloadSize ){
rc = SQLITE_CORRUPT_BKPT;
- goto op_column_error;
+ goto abort_due_to_error;
}
}
@@ -2502,7 +2509,7 @@ case OP_Column: {
if( pC->aRow==0 ){
memset(&sMem, 0, sizeof(sMem));
rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0], !pC->isTable, &sMem);
- if( rc!=SQLITE_OK ) goto op_column_error;
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
zData = (u8*)sMem.z;
}else{
zData = pC->aRow;
@@ -2538,7 +2545,7 @@ case OP_Column: {
|| (offset64 > pC->payloadSize)
){
rc = SQLITE_CORRUPT_BKPT;
- goto op_column_error;
+ goto abort_due_to_error;
}
}else{
t = 0;
@@ -2611,15 +2618,13 @@ case OP_Column: {
}else{
rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, !pC->isTable,
pDest);
- if( rc==SQLITE_OK ){
- sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
- pDest->flags &= ~MEM_Ephem;
- }
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
+ pDest->flags &= ~MEM_Ephem;
}
}
op_column_out:
-op_column_error:
UPDATE_MAX_BLOBSIZE(pDest);
REGISTER_TRACE(pOp->p3, pDest);
break;
@@ -2824,6 +2829,7 @@ case OP_Count: { /* out2 */
assert( pCrsr );
nEntry = 0; /* Not needed. Only used to silence a warning. */
rc = sqlite3BtreeCount(pCrsr, &nEntry);
+ if( rc ) goto abort_due_to_error;
pOut = out2Prerelease(p, pOp);
pOut->u.i = nEntry;
break;
@@ -3001,6 +3007,7 @@ case OP_Savepoint: {
}
}
}
+ if( rc ) goto abort_due_to_error;
break;
}
@@ -3037,7 +3044,7 @@ case OP_AutoCommit: {
sqlite3VdbeError(p, "cannot commit transaction - "
"SQL statements in progress");
rc = SQLITE_BUSY;
- break;
+ goto abort_due_to_error;
}else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
goto vdbe_return;
}else{
@@ -3064,6 +3071,7 @@ case OP_AutoCommit: {
"cannot commit - no transaction is active"));
rc = SQLITE_ERROR;
+ goto abort_due_to_error;
}
break;
}
@@ -3186,6 +3194,7 @@ case OP_Transaction: {
p->expired = 1;
rc = SQLITE_SCHEMA;
}
+ if( rc ) goto abort_due_to_error;
break;
}
@@ -3255,6 +3264,7 @@ case OP_SetCookie: {
sqlite3ExpirePreparedStatements(db);
p->expired = 0;
}
+ if( rc ) goto abort_due_to_error;
break;
}
@@ -3352,7 +3362,7 @@ case OP_OpenWrite:
if( p->expired ){
rc = SQLITE_ABORT_ROLLBACK;
- break;
+ goto abort_due_to_error;
}
nField = 0;
@@ -3386,10 +3396,7 @@ case OP_OpenWrite:
** that opcode will always set the p2 value to 2 or more or else fail.
** If there were a failure, the prepared statement would have halted
** before reaching this instruction. */
- if( NEVER(p2<2) ) {
- rc = SQLITE_CORRUPT_BKPT;
- goto abort_due_to_error;
- }
+ assert( p2>=2 );
}
if( pOp->p4type==P4_KEYINFO ){
pKeyInfo = pOp->p4.pKeyInfo;
@@ -3427,6 +3434,7 @@ open_cursor_set_hints:
#endif
sqlite3BtreeCursorHintFlags(pCur->uc.pCursor,
(pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ)));
+ if( rc ) goto abort_due_to_error;
break;
}
@@ -3503,6 +3511,7 @@ case OP_OpenEphemeral: {
pCx->isTable = 1;
}
}
+ if( rc ) goto abort_due_to_error;
pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
break;
}
@@ -3528,6 +3537,7 @@ case OP_SorterOpen: {
assert( pCx->pKeyInfo->db==db );
assert( pCx->pKeyInfo->enc==ENC(db) );
rc = sqlite3VdbeSorterInit(db, pOp->p3, pCx);
+ if( rc ) goto abort_due_to_error;
break;
}
@@ -3990,7 +4000,7 @@ case OP_Found: { /* jump, in3 */
rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, pIdxKey, 0, 0, &res);
sqlite3DbFree(db, pFree);
if( rc!=SQLITE_OK ){
- break;
+ goto abort_due_to_error;
}
pC->seekResult = res;
alreadyExists = (res==0);
@@ -4062,6 +4072,7 @@ case OP_NotExists: { /* jump, in3 */
goto jump_to_p2;
}
}
+ if( rc ) goto abort_due_to_error;
break;
}
@@ -4204,7 +4215,8 @@ case OP_NewRowid: { /* out2 */
0, &res))==SQLITE_OK)
&& (res==0)
&& (++cnt<100));
- if( rc==SQLITE_OK && res==0 ){
+ if( rc ) goto abort_due_to_error;
+ if( res==0 ){
rc = SQLITE_FULL; /* IMP: R-38219-53002 */
goto abort_due_to_error;
}
@@ -4338,7 +4350,8 @@ case OP_InsertInt: {
pC->cacheStatus = CACHE_STALE;
/* Invoke the update-hook if required. */
- if( rc==SQLITE_OK && db->xUpdateCallback && op && HasRowid(pTab) ){
+ if( rc ) goto abort_due_to_error;
+ if( db->xUpdateCallback && op && HasRowid(pTab) ){
db->xUpdateCallback(db->pUpdateArg, op, zDb, pTab->zName, iKey);
}
break;
@@ -4453,6 +4466,7 @@ case OP_Delete: {
rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5);
pC->cacheStatus = CACHE_STALE;
+ if( rc ) goto abort_due_to_error;
/* Invoke the update-hook if required. */
if( opflags & OPFLAG_NCHANGE ){
@@ -4507,6 +4521,7 @@ case OP_SorterCompare: {
res = 0;
rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res);
VdbeBranchTaken(res!=0,2);
+ if( rc ) goto abort_due_to_error;
if( res ) goto jump_to_p2;
break;
};
@@ -4532,6 +4547,7 @@ case OP_SorterData: {
rc = sqlite3VdbeSorterRowkey(pC, pOut);
assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) );
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ if( rc ) goto abort_due_to_error;
p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE;
break;
}
@@ -4620,6 +4636,7 @@ case OP_RowData: {
}else{
rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z);
}
+ if( rc ) goto abort_due_to_error;
pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */
UPDATE_MAX_BLOBSIZE(pOut);
REGISTER_TRACE(pOp->p2, pOut);
@@ -4660,6 +4677,7 @@ case OP_Rowid: { /* out2 */
assert( pModule->xRowid );
rc = pModule->xRowid(pC->uc.pVCur, &v);
sqlite3VtabImportErrmsg(p, pVtab);
+ if( rc ) goto abort_due_to_error;
#endif /* SQLITE_OMIT_VIRTUALTABLE */
}else{
assert( pC->eCurType==CURTYPE_BTREE );
@@ -4730,6 +4748,7 @@ case OP_Last: { /* jump */
#ifdef SQLITE_DEBUG
pC->seekOp = OP_Last;
#endif
+ if( rc ) goto abort_due_to_error;
if( pOp->p2>0 ){
VdbeBranchTaken(res!=0,2);
if( res ) goto jump_to_p2;
@@ -4794,6 +4813,7 @@ case OP_Rewind: { /* jump */
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
}
+ if( rc ) goto abort_due_to_error;
pC->nullRow = (u8)res;
assert( pOp->p2>0 && pOp->p2<p->nOp );
VdbeBranchTaken(res!=0,2);
@@ -4906,6 +4926,7 @@ case OP_Next: /* jump */
next_tail:
pC->cacheStatus = CACHE_STALE;
VdbeBranchTaken(res==0,2);
+ if( rc ) goto abort_due_to_error;
if( res==0 ){
pC->nullRow = 0;
p->aCounter[pOp->p5]++;
@@ -4956,19 +4977,19 @@ case OP_IdxInsert: { /* in2 */
assert( pC->eCurType==CURTYPE_BTREE || pOp->opcode==OP_SorterInsert );
assert( pC->isTable==0 );
rc = ExpandBlob(pIn2);
- if( rc==SQLITE_OK ){
- if( pOp->opcode==OP_SorterInsert ){
- rc = sqlite3VdbeSorterWrite(pC, pIn2);
- }else{
- nKey = pIn2->n;
- zKey = pIn2->z;
- rc = sqlite3BtreeInsert(pC->uc.pCursor, zKey, nKey, "", 0, 0, pOp->p3,
- ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
- );
- assert( pC->deferredMoveto==0 );
- pC->cacheStatus = CACHE_STALE;
- }
+ if( rc ) goto abort_due_to_error;
+ if( pOp->opcode==OP_SorterInsert ){
+ rc = sqlite3VdbeSorterWrite(pC, pIn2);
+ }else{
+ nKey = pIn2->n;
+ zKey = pIn2->z;
+ rc = sqlite3BtreeInsert(pC->uc.pCursor, zKey, nKey, "", 0, 0, pOp->p3,
+ ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
+ );
+ assert( pC->deferredMoveto==0 );
+ pC->cacheStatus = CACHE_STALE;
}
+ if( rc) goto abort_due_to_error;
break;
}
@@ -4999,8 +5020,10 @@ case OP_IdxDelete: {
r.default_rc = 0;
r.aMem = &aMem[pOp->p2];
rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res);
- if( rc==SQLITE_OK && res==0 ){
+ if( rc ) goto abort_due_to_error;
+ if( res==0 ){
rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE);
+ if( rc ) goto abort_due_to_error;
}
assert( pC->deferredMoveto==0 );
pC->cacheStatus = CACHE_STALE;
@@ -5175,6 +5198,7 @@ case OP_IdxGE: { /* jump */
res++;
}
VdbeBranchTaken(res>0,2);
+ if( rc ) goto abort_due_to_error;
if( res>0 ) goto jump_to_p2;
break;
}
@@ -5210,6 +5234,7 @@ case OP_Destroy: { /* out2 */
if( db->nVdbeRead > db->nVDestroy+1 ){
rc = SQLITE_LOCKED;
p->errorAction = OE_Abort;
+ goto abort_due_to_error;
}else{
iDb = pOp->p3;
assert( DbMaskTest(p->btreeMask, iDb) );
@@ -5217,8 +5242,9 @@ case OP_Destroy: { /* out2 */
rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved);
pOut->flags = MEM_Int;
pOut->u.i = iMoved;
+ if( rc ) goto abort_due_to_error;
#ifndef SQLITE_OMIT_AUTOVACUUM
- if( rc==SQLITE_OK && iMoved!=0 ){
+ if( iMoved!=0 ){
sqlite3RootPageMoved(db, iDb, iMoved, pOp->p1);
/* All OP_Destroy operations occur on the same btree */
assert( resetSchemaOnFault==0 || resetSchemaOnFault==iDb+1 );
@@ -5264,6 +5290,7 @@ case OP_Clear: {
aMem[pOp->p3].u.i += nChange;
}
}
+ if( rc ) goto abort_due_to_error;
break;
}
@@ -5287,6 +5314,7 @@ case OP_ResetSorter: {
assert( pC->eCurType==CURTYPE_BTREE );
assert( pC->isEphemeral );
rc = sqlite3BtreeClearTableOfCursor(pC->uc.pCursor);
+ if( rc ) goto abort_due_to_error;
}
break;
}
@@ -5335,6 +5363,7 @@ case OP_CreateTable: { /* out2 */
flags = BTREE_BLOBKEY;
}
rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
+ if( rc ) goto abort_due_to_error;
pOut->u.i = pgno;
break;
}
@@ -5375,7 +5404,7 @@ case OP_ParseSchema: {
"SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
db->aDb[iDb].zName, zMaster, pOp->p4.z);
if( zSql==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
assert( db->init.busy==0 );
db->init.busy = 1;
@@ -5387,9 +5416,12 @@ case OP_ParseSchema: {
db->init.busy = 0;
}
}
- if( rc ) sqlite3ResetAllSchemasOfConnection(db);
- if( rc==SQLITE_NOMEM ){
- goto no_mem;
+ if( rc ){
+ sqlite3ResetAllSchemasOfConnection(db);
+ if( rc==SQLITE_NOMEM ){
+ goto no_mem;
+ }
+ goto abort_due_to_error;
}
break;
}
@@ -5404,6 +5436,7 @@ case OP_ParseSchema: {
case OP_LoadAnalysis: {
assert( pOp->p1>=0 && pOp->p1<db->nDb );
rc = sqlite3AnalysisLoad(db, pOp->p1);
+ if( rc ) goto abort_due_to_error;
break;
}
#endif /* !defined(SQLITE_OMIT_ANALYZE) */
@@ -5663,7 +5696,7 @@ case OP_Program: { /* jump */
if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){
rc = SQLITE_ERROR;
sqlite3VdbeError(p, "too many levels of trigger recursion");
- break;
+ goto abort_due_to_error;
}
/* Register pRt is used to store the memory required to save the state
@@ -5723,6 +5756,9 @@ case OP_Program: { /* jump */
pFrame->lastRowid = lastRowid;
pFrame->nChange = p->nChange;
pFrame->nDbChange = p->db->nChange;
+ assert( pFrame->pAuxData==0 );
+ pFrame->pAuxData = p->pAuxData;
+ p->pAuxData = 0;
p->nChange = 0;
p->pFrame = pFrame;
p->aMem = aMem = &VdbeFrameMem(pFrame)[-1];
@@ -6027,6 +6063,7 @@ case OP_AggStep: {
rc = pCtx->isError;
}
sqlite3VdbeMemRelease(&t);
+ if( rc ) goto abort_due_to_error;
}else{
assert( t.flags==MEM_Null );
}
@@ -6059,6 +6096,7 @@ case OP_AggFinal: {
rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
if( rc ){
sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem));
+ goto abort_due_to_error;
}
sqlite3VdbeChangeEncoding(pMem, encoding);
UPDATE_MAX_BLOBSIZE(pMem);
@@ -6094,7 +6132,8 @@ case OP_Checkpoint: {
|| pOp->p2==SQLITE_CHECKPOINT_TRUNCATE
);
rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]);
- if( rc==SQLITE_BUSY ){
+ if( rc ){
+ if( rc!=SQLITE_BUSY ) goto abort_due_to_error;
rc = SQLITE_OK;
aRes[0] = 1;
}
@@ -6167,7 +6206,7 @@ case OP_JournalMode: { /* out2 */
"cannot change %s wal mode from within a transaction",
(eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
);
- break;
+ goto abort_due_to_error;
}else{
if( eOld==PAGER_JOURNALMODE_WAL ){
@@ -6197,9 +6236,7 @@ case OP_JournalMode: { /* out2 */
}
#endif /* ifndef SQLITE_OMIT_WAL */
- if( rc ){
- eNew = eOld;
- }
+ if( rc ) eNew = eOld;
eNew = sqlite3PagerSetJournalMode(pPager, eNew);
pOut->flags = MEM_Str|MEM_Static|MEM_Term;
@@ -6207,6 +6244,7 @@ case OP_JournalMode: { /* out2 */
pOut->n = sqlite3Strlen30(pOut->z);
pOut->enc = SQLITE_UTF8;
sqlite3VdbeChangeEncoding(pOut, encoding);
+ if( rc ) goto abort_due_to_error;
break;
};
#endif /* SQLITE_OMIT_PRAGMA */
@@ -6221,6 +6259,7 @@ case OP_JournalMode: { /* out2 */
case OP_Vacuum: {
assert( p->readOnly==0 );
rc = sqlite3RunVacuum(&p->zErrMsg, db);
+ if( rc ) goto abort_due_to_error;
break;
}
#endif
@@ -6241,7 +6280,8 @@ case OP_IncrVacuum: { /* jump */
pBt = db->aDb[pOp->p1].pBt;
rc = sqlite3BtreeIncrVacuum(pBt);
VdbeBranchTaken(rc==SQLITE_DONE,2);
- if( rc==SQLITE_DONE ){
+ if( rc ){
+ if( rc!=SQLITE_DONE ) goto abort_due_to_error;
rc = SQLITE_OK;
goto jump_to_p2;
}
@@ -6292,9 +6332,12 @@ case OP_TableLock: {
assert( DbMaskTest(p->btreeMask, p1) );
assert( isWriteLock==0 || isWriteLock==1 );
rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
- if( (rc&0xFF)==SQLITE_LOCKED ){
- const char *z = pOp->p4.z;
- sqlite3VdbeError(p, "database table is locked: %s", z);
+ if( rc ){
+ if( (rc&0xFF)==SQLITE_LOCKED ){
+ const char *z = pOp->p4.z;
+ sqlite3VdbeError(p, "database table is locked: %s", z);
+ }
+ goto abort_due_to_error;
}
}
break;
@@ -6316,6 +6359,7 @@ case OP_VBegin: {
pVTab = pOp->p4.pVtab;
rc = sqlite3VtabBegin(db, pVTab);
if( pVTab ) sqlite3VtabImportErrmsg(p, pVTab->pVtab);
+ if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -6344,6 +6388,7 @@ case OP_VCreate: {
rc = sqlite3VtabCallCreate(db, pOp->p1, zTab, &p->zErrMsg);
}
sqlite3VdbeMemRelease(&sMem);
+ if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -6358,6 +6403,7 @@ case OP_VDestroy: {
db->nVDestroy++;
rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z);
db->nVDestroy--;
+ if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -6381,25 +6427,25 @@ case OP_VOpen: {
pVtab = pOp->p4.pVtab->pVtab;
if( pVtab==0 || NEVER(pVtab->pModule==0) ){
rc = SQLITE_LOCKED;
- break;
+ goto abort_due_to_error;
}
pModule = pVtab->pModule;
rc = pModule->xOpen(pVtab, &pVCur);
sqlite3VtabImportErrmsg(p, pVtab);
- if( SQLITE_OK==rc ){
- /* Initialize sqlite3_vtab_cursor base class */
- pVCur->pVtab = pVtab;
-
- /* Initialize vdbe cursor object */
- pCur = allocateCursor(p, pOp->p1, 0, -1, CURTYPE_VTAB);
- if( pCur ){
- pCur->uc.pVCur = pVCur;
- pVtab->nRef++;
- }else{
- assert( db->mallocFailed );
- pModule->xClose(pVCur);
- goto no_mem;
- }
+ if( rc ) goto abort_due_to_error;
+
+ /* Initialize sqlite3_vtab_cursor base class */
+ pVCur->pVtab = pVtab;
+
+ /* Initialize vdbe cursor object */
+ pCur = allocateCursor(p, pOp->p1, 0, -1, CURTYPE_VTAB);
+ if( pCur ){
+ pCur->uc.pVCur = pVCur;
+ pVtab->nRef++;
+ }else{
+ assert( db->mallocFailed );
+ pModule->xClose(pVCur);
+ goto no_mem;
}
break;
}
@@ -6461,9 +6507,8 @@ case OP_VFilter: { /* jump */
}
rc = pModule->xFilter(pVCur, iQuery, pOp->p4.z, nArg, apArg);
sqlite3VtabImportErrmsg(p, pVtab);
- if( rc==SQLITE_OK ){
- res = pModule->xEof(pVCur);
- }
+ if( rc ) goto abort_due_to_error;
+ res = pModule->xEof(pVCur);
pCur->nullRow = 0;
VdbeBranchTaken(res!=0,2);
if( res ) goto jump_to_p2;
@@ -6512,6 +6557,7 @@ case OP_VColumn: {
if( sqlite3VdbeMemTooBig(pDest) ){
goto too_big;
}
+ if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -6547,9 +6593,8 @@ case OP_VNext: { /* jump */
*/
rc = pModule->xNext(pCur->uc.pVCur);
sqlite3VtabImportErrmsg(p, pVtab);
- if( rc==SQLITE_OK ){
- res = pModule->xEof(pCur->uc.pVCur);
- }
+ if( rc ) goto abort_due_to_error;
+ res = pModule->xEof(pCur->uc.pVCur);
VdbeBranchTaken(!res,2);
if( !res ){
/* If there is data, jump to P2 */
@@ -6581,11 +6626,11 @@ case OP_VRename: {
testcase( pName->enc==SQLITE_UTF16BE );
testcase( pName->enc==SQLITE_UTF16LE );
rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8);
- if( rc==SQLITE_OK ){
- rc = pVtab->pModule->xRename(pVtab, pName->z);
- sqlite3VtabImportErrmsg(p, pVtab);
- p->expired = 0;
- }
+ if( rc ) goto abort_due_to_error;
+ rc = pVtab->pModule->xRename(pVtab, pName->z);
+ sqlite3VtabImportErrmsg(p, pVtab);
+ p->expired = 0;
+ if( rc ) goto abort_due_to_error;
break;
}
#endif
@@ -6634,7 +6679,7 @@ case OP_VUpdate: {
pVtab = pOp->p4.pVtab->pVtab;
if( pVtab==0 || NEVER(pVtab->pModule==0) ){
rc = SQLITE_LOCKED;
- break;
+ goto abort_due_to_error;
}
pModule = pVtab->pModule;
nArg = pOp->p2;
@@ -6666,6 +6711,7 @@ case OP_VUpdate: {
}else{
p->nChange++;
}
+ if( rc ) goto abort_due_to_error;
}
break;
}
@@ -6837,8 +6883,12 @@ default: { /* This is really OP_Noop and OP_Explain */
/* If we reach this point, it means that execution is finished with
** an error of some kind.
*/
-vdbe_error_halt:
+abort_due_to_error:
+ if( db->mallocFailed ) rc = SQLITE_NOMEM_BKPT;
assert( rc );
+ if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){
+ sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
+ }
p->rc = rc;
testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3_log(rc, "statement aborts at %d: [%s] %s",
@@ -6869,34 +6919,23 @@ vdbe_return:
too_big:
sqlite3VdbeError(p, "string or blob too big");
rc = SQLITE_TOOBIG;
- goto vdbe_error_halt;
+ goto abort_due_to_error;
/* Jump to here if a malloc() fails.
*/
no_mem:
sqlite3OomFault(db);
sqlite3VdbeError(p, "out of memory");
- rc = SQLITE_NOMEM;
- goto vdbe_error_halt;
-
- /* Jump to here for any other kind of fatal error. The "rc" variable
- ** should hold the error number.
- */
-abort_due_to_error:
- assert( p->zErrMsg==0 );
- if( db->mallocFailed ) rc = SQLITE_NOMEM;
- if( rc!=SQLITE_IOERR_NOMEM ){
- sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
- }
- goto vdbe_error_halt;
+ rc = SQLITE_NOMEM_BKPT;
+ goto abort_due_to_error;
/* Jump to here if the sqlite3_interrupt() API sets the interrupt
** flag.
*/
abort_due_to_interrupt:
assert( db->u1.isInterrupted );
- rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_INTERRUPT;
+ rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
p->rc = rc;
sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
- goto vdbe_error_halt;
+ goto abort_due_to_error;
}
diff --git a/src/vdbeInt.h b/src/vdbeInt.h
index fada20370..4dab3ba49 100644
--- a/src/vdbeInt.h
+++ b/src/vdbeInt.h
@@ -161,6 +161,7 @@ struct VdbeFrame {
VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */
void *token; /* Copy of SubProgram.token */
i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */
+ AuxData *pAuxData; /* Linked list of auxdata allocations */
int nCursor; /* Number of entries in apCsr */
int pc; /* Program Counter in parent (calling) frame */
int nOp; /* Size of aOp array */
@@ -462,7 +463,7 @@ u8 sqlite3VdbeOneByteSerialTypeLen(u8);
u32 sqlite3VdbeSerialType(Mem*, int, u32*);
u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
-void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
+void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int);
int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
diff --git a/src/vdbeapi.c b/src/vdbeapi.c
index be70c6719..1feecb3e1 100644
--- a/src/vdbeapi.c
+++ b/src/vdbeapi.c
@@ -471,7 +471,7 @@ void sqlite3_result_error_toobig(sqlite3_context *pCtx){
void sqlite3_result_error_nomem(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetNull(pCtx->pOut);
- pCtx->isError = SQLITE_NOMEM;
+ pCtx->isError = SQLITE_NOMEM_BKPT;
pCtx->fErrorOrAux = 1;
sqlite3OomFault(pCtx->pOut->db);
}
@@ -547,7 +547,7 @@ static int sqlite3Step(Vdbe *p){
db = p->db;
if( db->mallocFailed ){
p->rc = SQLITE_NOMEM;
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
if( p->pc<=0 && p->expired ){
@@ -610,7 +610,7 @@ static int sqlite3Step(Vdbe *p){
db->errCode = rc;
if( SQLITE_NOMEM==sqlite3ApiExit(p->db, p->rc) ){
- p->rc = SQLITE_NOMEM;
+ p->rc = SQLITE_NOMEM_BKPT;
}
end_of_step:
/* At this point local variable rc holds the value that should be
@@ -677,7 +677,7 @@ int sqlite3_step(sqlite3_stmt *pStmt){
v->rc = rc2;
} else {
v->zErrMsg = 0;
- v->rc = rc = SQLITE_NOMEM;
+ v->rc = rc = SQLITE_NOMEM_BKPT;
}
}
rc = sqlite3ApiExit(db, rc);
@@ -1301,6 +1301,9 @@ int sqlite3_bind_blob(
int nData,
void (*xDel)(void*)
){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( nData<0 ) return SQLITE_MISUSE_BKPT;
+#endif
return bindText(pStmt, i, zData, nData, xDel, 0);
}
int sqlite3_bind_blob64(
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index 5545e8785..50f5e99c5 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -130,7 +130,7 @@ static int growOpArray(Vdbe *v, int nOp){
p->nOpAlloc = p->szOpAlloc/sizeof(Op);
v->aOp = pNew;
}
- return (pNew ? SQLITE_OK : SQLITE_NOMEM);
+ return (pNew ? SQLITE_OK : SQLITE_NOMEM_BKPT);
}
#ifdef SQLITE_DEBUG
@@ -1489,6 +1489,7 @@ void sqlite3VdbeFrameDelete(VdbeFrame *p){
sqlite3VdbeFreeCursor(p->v, apCsr[i]);
}
releaseMemArray(aMem, p->nChildMem);
+ sqlite3VdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0);
sqlite3DbFree(p->v->db, p);
}
@@ -1531,7 +1532,7 @@ int sqlite3VdbeList(
releaseMemArray(pMem, 8);
p->pResultSet = 0;
- if( p->rc==SQLITE_NOMEM ){
+ if( p->rc==SQLITE_NOMEM_BKPT ){
/* This happens if a malloc() inside a call to sqlite3_column_text() or
** sqlite3_column_text16() failed. */
sqlite3OomFault(db);
@@ -2017,6 +2018,9 @@ int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
v->db->lastRowid = pFrame->lastRowid;
v->nChange = pFrame->nChange;
v->db->nChange = pFrame->nDbChange;
+ sqlite3VdbeDeleteAuxData(v->db, &v->pAuxData, -1, 0);
+ v->pAuxData = pFrame->pAuxData;
+ pFrame->pAuxData = 0;
return pFrame->pc;
}
@@ -2048,7 +2052,7 @@ static void closeAllCursors(Vdbe *p){
}
/* Delete any auxdata allocations made by the VM */
- if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p, -1, 0);
+ if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p->db, &p->pAuxData, -1, 0);
assert( p->pAuxData==0 );
}
@@ -2120,7 +2124,7 @@ int sqlite3VdbeSetColName(
assert( var<COLNAME_N );
if( p->db->mallocFailed ){
assert( !zName || xDel!=SQLITE_DYNAMIC );
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
assert( p->aColName!=0 );
pColName = &(p->aColName[idx+var*p->nResColumn]);
@@ -2137,7 +2141,9 @@ int sqlite3VdbeSetColName(
*/
static int vdbeCommit(sqlite3 *db, Vdbe *p){
int i;
- int nTrans = 0; /* Number of databases with an active write-transaction */
+ int nTrans = 0; /* Number of databases with an active write-transaction
+ ** that are candidates for a two-phase commit using a
+ ** master-journal */
int rc = SQLITE_OK;
int needXcommit = 0;
@@ -2165,10 +2171,28 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
Btree *pBt = db->aDb[i].pBt;
if( sqlite3BtreeIsInTrans(pBt) ){
+ /* Whether or not a database might need a master journal depends upon
+ ** its journal mode (among other things). This matrix determines which
+ ** journal modes use a master journal and which do not */
+ static const u8 aMJNeeded[] = {
+ /* DELETE */ 1,
+ /* PERSIST */ 1,
+ /* OFF */ 0,
+ /* TRUNCATE */ 1,
+ /* MEMORY */ 0,
+ /* WAL */ 0
+ };
+ Pager *pPager; /* Pager associated with pBt */
needXcommit = 1;
- if( i!=1 ) nTrans++;
sqlite3BtreeEnter(pBt);
- rc = sqlite3PagerExclusiveLock(sqlite3BtreePager(pBt));
+ pPager = sqlite3BtreePager(pBt);
+ if( db->aDb[i].safety_level!=PAGER_SYNCHRONOUS_OFF
+ && aMJNeeded[sqlite3PagerGetJournalMode(pPager)]
+ ){
+ assert( i!=1 );
+ nTrans++;
+ }
+ rc = sqlite3PagerExclusiveLock(pPager);
sqlite3BtreeLeave(pBt);
}
}
@@ -2226,7 +2250,6 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
#ifndef SQLITE_OMIT_DISKIO
else{
sqlite3_vfs *pVfs = db->pVfs;
- int needSync = 0;
char *zMaster = 0; /* File-name for the master journal */
char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
sqlite3_file *pMaster = 0;
@@ -2238,7 +2261,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
/* Select a master journal file name */
nMainFile = sqlite3Strlen30(zMainFile);
zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XXz", zMainFile);
- if( zMaster==0 ) return SQLITE_NOMEM;
+ if( zMaster==0 ) return SQLITE_NOMEM_BKPT;
do {
u32 iRandom;
if( retryCount ){
@@ -2286,9 +2309,6 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
continue; /* Ignore TEMP and :memory: databases */
}
assert( zFile[0]!=0 );
- if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){
- needSync = 1;
- }
rc = sqlite3OsWrite(pMaster, zFile, sqlite3Strlen30(zFile)+1, offset);
offset += sqlite3Strlen30(zFile)+1;
if( rc!=SQLITE_OK ){
@@ -2303,8 +2323,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
/* Sync the master journal file. If the IOCAP_SEQUENTIAL device
** flag is set this is not required.
*/
- if( needSync
- && 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL)
+ if( 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL)
&& SQLITE_OK!=(rc = sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL))
){
sqlite3OsCloseFree(pMaster);
@@ -2340,7 +2359,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
** doing this the directory is synced again before any individual
** transaction files are deleted.
*/
- rc = sqlite3OsDelete(pVfs, zMaster, needSync);
+ rc = sqlite3OsDelete(pVfs, zMaster, 1);
sqlite3DbFree(db, zMaster);
zMaster = 0;
if( rc ){
@@ -2528,7 +2547,7 @@ int sqlite3VdbeHalt(Vdbe *p){
*/
if( db->mallocFailed ){
- p->rc = SQLITE_NOMEM;
+ p->rc = SQLITE_NOMEM_BKPT;
}
if( p->aOnceFlag ) memset(p->aOnceFlag, 0, p->nOnceFlag);
closeAllCursors(p);
@@ -2689,7 +2708,7 @@ int sqlite3VdbeHalt(Vdbe *p){
p->magic = VDBE_MAGIC_HALT;
checkActiveVdbeCnt(db);
if( db->mallocFailed ){
- p->rc = SQLITE_NOMEM;
+ p->rc = SQLITE_NOMEM_BKPT;
}
/* If the auto-commit flag is set to true, then any locks that were held
@@ -2876,8 +2895,7 @@ int sqlite3VdbeFinalize(Vdbe *p){
** * the corresponding bit in argument mask is clear (where the first
** function parameter corresponds to bit 0 etc.).
*/
-void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){
- AuxData **pp = &pVdbe->pAuxData;
+void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, int mask){
while( *pp ){
AuxData *pAux = *pp;
if( (iOp<0)
@@ -2888,7 +2906,7 @@ void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){
pAux->xDelete(pAux->pAux);
}
*pp = pAux->pNext;
- sqlite3DbFree(pVdbe->db, pAux);
+ sqlite3DbFree(db, pAux);
}else{
pp= &pAux->pNext;
}
@@ -3668,7 +3686,7 @@ static int vdbeCompareMemString(
v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc);
n2 = v2==0 ? 0 : c2.n;
rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
- if( (v1==0 || v2==0) && prcErr ) *prcErr = SQLITE_NOMEM;
+ if( (v1==0 || v2==0) && prcErr ) *prcErr = SQLITE_NOMEM_BKPT;
sqlite3VdbeMemRelease(&c1);
sqlite3VdbeMemRelease(&c2);
return rc;
diff --git a/src/vdbemem.c b/src/vdbemem.c
index 83b8feb34..8930c76d4 100644
--- a/src/vdbemem.c
+++ b/src/vdbemem.c
@@ -138,7 +138,7 @@ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
sqlite3VdbeMemSetNull(pMem);
pMem->z = 0;
pMem->szMalloc = 0;
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}else{
pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
}
@@ -196,7 +196,7 @@ int sqlite3VdbeMemMakeWriteable(Mem *pMem){
f = pMem->flags;
if( (f&(MEM_Str|MEM_Blob)) && (pMem->szMalloc==0 || pMem->z!=pMem->zMalloc) ){
if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pMem->z[pMem->n] = 0;
pMem->z[pMem->n+1] = 0;
@@ -228,7 +228,7 @@ int sqlite3VdbeMemExpandBlob(Mem *pMem){
nByte = 1;
}
if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
@@ -245,7 +245,7 @@ int sqlite3VdbeMemExpandBlob(Mem *pMem){
*/
static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pMem->z[pMem->n] = 0;
pMem->z[pMem->n+1] = 0;
@@ -294,7 +294,7 @@ int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
/* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
@@ -901,7 +901,7 @@ int sqlite3VdbeMemSetStr(
testcase( nAlloc==31 );
testcase( nAlloc==32 );
if( sqlite3VdbeMemClearAndResize(pMem, MAX(nAlloc,32)) ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memcpy(pMem->z, z, nAlloc);
}else if( xDel==SQLITE_DYNAMIC ){
@@ -921,7 +921,7 @@ int sqlite3VdbeMemSetStr(
#ifndef SQLITE_OMIT_UTF16
if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
#endif
@@ -1182,7 +1182,6 @@ static int valueFromFunction(
FuncDef *pFunc = 0; /* Function definition */
sqlite3_value *pVal = 0; /* New value */
int rc = SQLITE_OK; /* Return code */
- int nName; /* Size of function name in bytes */
ExprList *pList = 0; /* Function arguments */
int i; /* Iterator variable */
@@ -1190,8 +1189,7 @@ static int valueFromFunction(
assert( (p->flags & EP_TokenOnly)==0 );
pList = p->x.pList;
if( pList ) nVal = pList->nExpr;
- nName = sqlite3Strlen30(p->u.zToken);
- pFunc = sqlite3FindFunction(db, p->u.zToken, nName, nVal, enc, 0);
+ pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0);
assert( pFunc );
if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0
|| (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
@@ -1202,7 +1200,7 @@ static int valueFromFunction(
if( pList ){
apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal);
if( apVal==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto value_from_function_out;
}
for(i=0; i<nVal; i++){
@@ -1213,7 +1211,7 @@ static int valueFromFunction(
pVal = valueNew(db, pCtx);
if( pVal==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto value_from_function_out;
}
@@ -1386,7 +1384,7 @@ no_mem:
#else
assert( pCtx==0 ); sqlite3ValueFree(pVal);
#endif
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
/*
@@ -1453,15 +1451,10 @@ static void recordFunc(
** Register built-in functions used to help read ANALYZE data.
*/
void sqlite3AnalyzeFunctions(void){
- static SQLITE_WSD FuncDef aAnalyzeTableFuncs[] = {
+ static FuncDef aAnalyzeTableFuncs[] = {
FUNCTION(sqlite_record, 1, 0, 0, recordFunc),
};
- int i;
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
- FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAnalyzeTableFuncs);
- for(i=0; i<ArraySize(aAnalyzeTableFuncs); i++){
- sqlite3FuncDefInsert(pHash, &aFunc[i]);
- }
+ sqlite3InsertBuiltinFuncs(aAnalyzeTableFuncs, ArraySize(aAnalyzeTableFuncs));
}
/*
@@ -1640,7 +1633,7 @@ int sqlite3Stat4Column(
if( iField>nRec ) return SQLITE_CORRUPT_BKPT;
if( pMem==0 ){
pMem = *ppVal = sqlite3ValueNew(db);
- if( pMem==0 ) return SQLITE_NOMEM;
+ if( pMem==0 ) return SQLITE_NOMEM_BKPT;
}
sqlite3VdbeSerialGet(&a[iField-szField], t, pMem);
pMem->enc = ENC(db);
diff --git a/src/vdbesort.c b/src/vdbesort.c
index 380772ee1..5913cda6d 100644
--- a/src/vdbesort.c
+++ b/src/vdbesort.c
@@ -540,7 +540,7 @@ static int vdbePmaReadBlob(
int nNew = MAX(128, p->nAlloc*2);
while( nByte>nNew ) nNew = nNew*2;
aNew = sqlite3Realloc(p->aAlloc, nNew);
- if( !aNew ) return SQLITE_NOMEM;
+ if( !aNew ) return SQLITE_NOMEM_BKPT;
p->nAlloc = nNew;
p->aAlloc = aNew;
}
@@ -652,7 +652,7 @@ static int vdbePmaReaderSeek(
int iBuf = pReadr->iReadOff % pgsz;
if( pReadr->aBuffer==0 ){
pReadr->aBuffer = (u8*)sqlite3Malloc(pgsz);
- if( pReadr->aBuffer==0 ) rc = SQLITE_NOMEM;
+ if( pReadr->aBuffer==0 ) rc = SQLITE_NOMEM_BKPT;
pReadr->nBuffer = pgsz;
}
if( rc==SQLITE_OK && iBuf ){
@@ -968,7 +968,7 @@ int sqlite3VdbeSorterInit(
pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo);
pCsr->uc.pSorter = pSorter;
if( pSorter==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz);
memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
@@ -1002,7 +1002,7 @@ int sqlite3VdbeSorterInit(
assert( pSorter->iMemory==0 );
pSorter->nMemory = pgsz;
pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz);
- if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM;
+ if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM_BKPT;
}
}
@@ -1324,7 +1324,7 @@ static int vdbeSortAllocUnpacked(SortSubtask *pTask){
pTask->pSorter->pKeyInfo, 0, 0, &pFree
);
assert( pTask->pUnpacked==(UnpackedRecord*)pFree );
- if( pFree==0 ) return SQLITE_NOMEM;
+ if( pFree==0 ) return SQLITE_NOMEM_BKPT;
pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nField;
pTask->pUnpacked->errCode = 0;
}
@@ -1399,7 +1399,7 @@ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){
aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *));
if( !aSlot ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
while( p ){
@@ -1449,7 +1449,7 @@ static void vdbePmaWriterInit(
memset(p, 0, sizeof(PmaWriter));
p->aBuffer = (u8*)sqlite3Malloc(nBuf);
if( !p->aBuffer ){
- p->eFWErr = SQLITE_NOMEM;
+ p->eFWErr = SQLITE_NOMEM_BKPT;
}else{
p->iBufEnd = p->iBufStart = (iStart % nBuf);
p->iWriteOff = iStart - p->iBufStart;
@@ -1737,7 +1737,7 @@ static int vdbeSorterFlushPMA(VdbeSorter *pSorter){
pSorter->nMemory = sqlite3MallocSize(aMem);
}else if( pSorter->list.aMemory ){
pSorter->list.aMemory = sqlite3Malloc(pSorter->nMemory);
- if( !pSorter->list.aMemory ) return SQLITE_NOMEM;
+ if( !pSorter->list.aMemory ) return SQLITE_NOMEM_BKPT;
}
rc = vdbeSorterCreateThread(pTask, vdbeSorterFlushThread, pCtx);
@@ -1828,7 +1828,7 @@ int sqlite3VdbeSorterWrite(
if( nNew < nMin ) nNew = nMin;
aNew = sqlite3Realloc(pSorter->list.aMemory, nNew);
- if( !aNew ) return SQLITE_NOMEM;
+ if( !aNew ) return SQLITE_NOMEM_BKPT;
pSorter->list.pList = (SorterRecord*)&aNew[iListOff];
pSorter->list.aMemory = aNew;
pSorter->nMemory = nNew;
@@ -1842,7 +1842,7 @@ int sqlite3VdbeSorterWrite(
}else{
pNew = (SorterRecord *)sqlite3Malloc(nReq);
if( pNew==0 ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pNew->u.pNext = pSorter->list.pList;
}
@@ -1989,7 +1989,7 @@ static int vdbeIncrMergerNew(
pTask->file2.iEof += pIncr->mxSz;
}else{
vdbeMergeEngineFree(pMerger);
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
return rc;
}
@@ -2294,10 +2294,10 @@ static int vdbeMergeEngineLevel0(
int rc = SQLITE_OK;
*ppOut = pNew = vdbeMergeEngineNew(nPMA);
- if( pNew==0 ) rc = SQLITE_NOMEM;
+ if( pNew==0 ) rc = SQLITE_NOMEM_BKPT;
for(i=0; i<nPMA && rc==SQLITE_OK; i++){
- i64 nDummy;
+ i64 nDummy = 0;
PmaReader *pReadr = &pNew->aReadr[i];
rc = vdbePmaReaderInit(pTask, &pTask->file, iOff, pReadr, &nDummy);
iOff = pReadr->iEof;
@@ -2365,7 +2365,7 @@ static int vdbeSorterAddToTree(
if( pReadr->pIncr==0 ){
MergeEngine *pNew = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT);
if( pNew==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
rc = vdbeIncrMergerNew(pTask, pNew, &pReadr->pIncr);
}
@@ -2410,7 +2410,7 @@ static int vdbeSorterMergeTreeBuild(
assert( pSorter->bUseThreads || pSorter->nTask==1 );
if( pSorter->nTask>1 ){
pMain = vdbeMergeEngineNew(pSorter->nTask);
- if( pMain==0 ) rc = SQLITE_NOMEM;
+ if( pMain==0 ) rc = SQLITE_NOMEM_BKPT;
}
#endif
@@ -2428,7 +2428,7 @@ static int vdbeSorterMergeTreeBuild(
int i;
int iSeq = 0;
pRoot = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT);
- if( pRoot==0 ) rc = SQLITE_NOMEM;
+ if( pRoot==0 ) rc = SQLITE_NOMEM_BKPT;
for(i=0; i<pTask->nPMA && rc==SQLITE_OK; i += SORTER_MAX_MERGE_COUNT){
MergeEngine *pMerger = 0; /* New level-0 PMA merger */
int nReader; /* Number of level-0 PMAs to merge */
@@ -2499,7 +2499,7 @@ static int vdbeSorterSetupMerge(VdbeSorter *pSorter){
if( rc==SQLITE_OK ){
pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader));
pSorter->pReader = pReadr;
- if( pReadr==0 ) rc = SQLITE_NOMEM;
+ if( pReadr==0 ) rc = SQLITE_NOMEM_BKPT;
}
if( rc==SQLITE_OK ){
rc = vdbeIncrMergerNew(pLast, pMain, &pReadr->pIncr);
@@ -2676,7 +2676,7 @@ int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){
pSorter = pCsr->uc.pSorter;
pKey = vdbeSorterRowkey(pSorter, &nKey);
if( sqlite3VdbeMemClearAndResize(pOut, nKey) ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pOut->n = nKey;
MemSetTypeFlag(pOut, MEM_Blob);
@@ -2721,7 +2721,7 @@ int sqlite3VdbeSorterCompare(
char *p;
r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo,0,0,&p);
assert( pSorter->pUnpacked==(UnpackedRecord*)p );
- if( r2==0 ) return SQLITE_NOMEM;
+ if( r2==0 ) return SQLITE_NOMEM_BKPT;
r2->nField = nKeyCol;
}
assert( r2->nField==nKeyCol );
diff --git a/src/vtab.c b/src/vtab.c
index e8794e687..fa1954819 100644
--- a/src/vtab.c
+++ b/src/vtab.c
@@ -506,13 +506,13 @@ static int vtabCallConstructor(
zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
if( !zModuleName ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pVTable = sqlite3DbMallocZero(db, sizeof(VTable));
if( !pVTable ){
sqlite3DbFree(db, zModuleName);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pVTable->db = db;
pVTable->pMod = pMod;
@@ -655,7 +655,7 @@ static int growVTrans(sqlite3 *db){
int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR);
aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes);
if( !aVTrans ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR);
db->aVTrans = aVTrans;
@@ -747,7 +747,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
if( pParse==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
pParse->declareVtab = 1;
pParse->db = db;
@@ -1059,8 +1059,8 @@ FuncDef *sqlite3VtabOverloadFunction(
return pDef;
}
*pNew = *pDef;
- pNew->zName = (char *)&pNew[1];
- memcpy(pNew->zName, pDef->zName, sqlite3Strlen30(pDef->zName)+1);
+ pNew->zName = (const char*)&pNew[1];
+ memcpy((char*)&pNew[1], pDef->zName, sqlite3Strlen30(pDef->zName)+1);
pNew->xSFunc = xSFunc;
pNew->pUserData = pArg;
pNew->funcFlags |= SQLITE_FUNC_EPHEM;
diff --git a/src/wal.c b/src/wal.c
index d7a6b701e..bbac1bd6d 100644
--- a/src/wal.c
+++ b/src/wal.c
@@ -546,7 +546,7 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
if( !apNew ){
*ppPage = 0;
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memset((void*)&apNew[pWal->nWiData], 0,
sizeof(u32*)*(iPage+1-pWal->nWiData));
@@ -558,7 +558,7 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
if( pWal->apWiData[iPage]==0 ){
if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
- if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM;
+ if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
}else{
rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
@@ -1173,7 +1173,7 @@ static int walIndexRecover(Wal *pWal){
szFrame = szPage + WAL_FRAME_HDRSIZE;
aFrame = (u8 *)sqlite3_malloc64(szFrame);
if( !aFrame ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto recovery_error;
}
aData = &aFrame[WAL_FRAME_HDRSIZE];
@@ -1311,7 +1311,7 @@ int sqlite3WalOpen(
*ppWal = 0;
pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile);
if( !pRet ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pRet->pVfs = pVfs;
@@ -1575,7 +1575,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
+ iLast*sizeof(ht_slot);
p = (WalIterator *)sqlite3_malloc64(nByte);
if( !p ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memset(p, 0, nByte);
p->nSegment = nSegment;
@@ -1587,7 +1587,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
);
if( !aTmp ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
for(i=0; rc==SQLITE_OK && i<nSegment; i++){
@@ -2880,7 +2880,7 @@ static int walWriteOneFrame(
void *pData; /* Data actually written */
u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */
#if defined(SQLITE_HAS_CODEC)
- if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM;
+ if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM_BKPT;
#else
pData = pPage->pData;
#endif
@@ -2909,7 +2909,7 @@ static int walRewriteChecksums(Wal *pWal, u32 iLast){
i64 iCksumOff;
aBuf = sqlite3_malloc(szPage + WAL_FRAME_HDRSIZE);
- if( aBuf==0 ) return SQLITE_NOMEM;
+ if( aBuf==0 ) return SQLITE_NOMEM_BKPT;
/* Find the checksum values to use as input for the recalculating the
** first checksum. If the first frame is frame 1 (implying that the current
@@ -3385,7 +3385,7 @@ int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot){
pRet = (WalIndexHdr*)sqlite3_malloc(sizeof(WalIndexHdr));
if( pRet==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
memcpy(pRet, &pWal->hdr, sizeof(WalIndexHdr));
*ppSnapshot = (sqlite3_snapshot*)pRet;
diff --git a/src/where.c b/src/where.c
index 8ecdd840f..a68dcf5bf 100644
--- a/src/where.c
+++ b/src/where.c
@@ -31,8 +31,8 @@ static int whereLoopResize(sqlite3*, WhereLoop*, int);
/*
** Return the estimated number of output rows from a WHERE clause
*/
-u64 sqlite3WhereOutputRowCount(WhereInfo *pWInfo){
- return sqlite3LogEstToInt(pWInfo->nRowOut);
+LogEst sqlite3WhereOutputRowCount(WhereInfo *pWInfo){
+ return pWInfo->nRowOut;
}
/*
@@ -1736,7 +1736,7 @@ static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){
if( p->nLSlot>=n ) return SQLITE_OK;
n = (n+7)&~7;
paNew = sqlite3DbMallocRawNN(db, sizeof(p->aLTerm[0])*n);
- if( paNew==0 ) return SQLITE_NOMEM;
+ if( paNew==0 ) return SQLITE_NOMEM_BKPT;
memcpy(paNew, p->aLTerm, sizeof(p->aLTerm[0])*p->nLSlot);
if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm);
p->aLTerm = paNew;
@@ -1751,7 +1751,7 @@ static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){
whereLoopClearUnion(db, pTo);
if( whereLoopResize(db, pTo, pFrom->nLTerm) ){
memset(&pTo->u, 0, sizeof(pTo->u));
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ);
memcpy(pTo->aLTerm, pFrom->aLTerm, pTo->nLTerm*sizeof(pTo->aLTerm[0]));
@@ -2033,7 +2033,7 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
if( p==0 ){
/* Allocate a new WhereLoop to add to the end of the list */
*ppPrev = p = sqlite3DbMallocRawNN(db, sizeof(WhereLoop));
- if( p==0 ) return SQLITE_NOMEM;
+ if( p==0 ) return SQLITE_NOMEM_BKPT;
whereLoopInit(p);
p->pNextLoop = 0;
}else{
@@ -2189,7 +2189,7 @@ static int whereLoopAddBtreeIndex(
WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */
pNew = pBuilder->pNew;
- if( db->mallocFailed ) return SQLITE_NOMEM;
+ if( db->mallocFailed ) return SQLITE_NOMEM_BKPT;
assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
@@ -2806,7 +2806,7 @@ static int whereLoopAddVirtual(
pTab = pSrc->pTab;
assert( IsVirtual(pTab) );
pIdxInfo = allocateIndexInfo(pParse, pWC, mUnusable, pSrc,pBuilder->pOrderBy);
- if( pIdxInfo==0 ) return SQLITE_NOMEM;
+ if( pIdxInfo==0 ) return SQLITE_NOMEM_BKPT;
pNew->prereq = 0;
pNew->rSetup = 0;
pNew->wsFlags = WHERE_VIRTUALTABLE;
@@ -2816,7 +2816,7 @@ static int whereLoopAddVirtual(
nConstraint = pIdxInfo->nConstraint;
if( whereLoopResize(db, pNew, nConstraint) ){
sqlite3DbFree(db, pIdxInfo);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
for(iPhase=0; iPhase<=3; iPhase++){
@@ -3438,6 +3438,7 @@ static const char *wherePathName(WherePath *pPath, int nLoop, WhereLoop *pLast){
** order.
*/
static LogEst whereSortingCost(
+ WhereInfo *pWInfo,
LogEst nRow,
int nOrderBy,
int nSorted
@@ -3458,7 +3459,15 @@ static LogEst whereSortingCost(
LogEst rScale, rSortCost;
assert( nOrderBy>0 && 66==sqlite3LogEst(100) );
rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66;
- rSortCost = nRow + estLog(nRow) + rScale + 16;
+ rSortCost = nRow + rScale + 16;
+
+ /* Multiple by log(M) where M is the number of output rows.
+ ** Use the LIMIT for M if it is smaller */
+ if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 ){
+ LogEst m = sqlite3LogEst(pWInfo->iLimit);
+ if( m<nRow ) nRow = m;
+ }
+ rSortCost += estLog(nRow);
return rSortCost;
}
@@ -3521,7 +3530,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
nSpace = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2;
nSpace += sizeof(LogEst) * nOrderBy;
pSpace = sqlite3DbMallocRawNN(db, nSpace);
- if( pSpace==0 ) return SQLITE_NOMEM;
+ if( pSpace==0 ) return SQLITE_NOMEM_BKPT;
aTo = (WherePath*)pSpace;
aFrom = aTo+mxChoice;
memset(aFrom, 0, sizeof(aFrom[0]));
@@ -3576,6 +3585,12 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue;
if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue;
+ if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<10 ){
+ /* Do not use an automatic index if the this loop is expected
+ ** to run less than 2 times. */
+ assert( 10==sqlite3LogEst(2) );
+ continue;
+ }
/* At this point, pWLoop is a candidate to be the next loop.
** Compute its cost */
rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow);
@@ -3592,7 +3607,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
if( isOrdered>=0 && isOrdered<nOrderBy ){
if( aSortCost[isOrdered]==0 ){
aSortCost[isOrdered] = whereSortingCost(
- nRowEst, nOrderBy, isOrdered
+ pWInfo, nRowEst, nOrderBy, isOrdered
);
}
rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]);
@@ -3991,7 +4006,8 @@ WhereInfo *sqlite3WhereBegin(
ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */
ExprList *pResultSet, /* Result set of the query */
u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */
- int iIdxCur /* If WHERE_ONETABLE_ONLY is set, index cursor number */
+ int iAuxArg /* If WHERE_ONETABLE_ONLY is set, index cursor number,
+ ** If WHERE_USE_LIMIT, then the limit amount */
){
int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */
int nTabList; /* Number of elements in pTabList */
@@ -4012,6 +4028,10 @@ WhereInfo *sqlite3WhereBegin(
&& (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0
));
+ /* Only one of WHERE_ONETABLE_ONLY or WHERE_USE_LIMIT */
+ assert( (wctrlFlags & WHERE_ONETABLE_ONLY)==0
+ || (wctrlFlags & WHERE_USE_LIMIT)==0 );
+
/* Variable initialization */
db = pParse->db;
memset(&sWLB, 0, sizeof(sWLB));
@@ -4065,6 +4085,7 @@ WhereInfo *sqlite3WhereBegin(
pWInfo->pResultSet = pResultSet;
pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
pWInfo->wctrlFlags = wctrlFlags;
+ pWInfo->iLimit = iAuxArg;
pWInfo->savedNQueryLoop = pParse->nQueryLoop;
assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */
pMaskSet = &pWInfo->sMaskSet;
@@ -4145,9 +4166,14 @@ WhereInfo *sqlite3WhereBegin(
}
/* Construct the WhereLoop objects */
- WHERETRACE(0xffff,("*** Optimizer Start *** (wctrlFlags: 0x%x)\n",
- wctrlFlags));
#if defined(WHERETRACE_ENABLED)
+ if( sqlite3WhereTrace & 0xffff ){
+ sqlite3DebugPrintf("*** Optimizer Start *** (wctrlFlags: 0x%x",wctrlFlags);
+ if( wctrlFlags & WHERE_USE_LIMIT ){
+ sqlite3DebugPrintf(", limit: %d", iAuxArg);
+ }
+ sqlite3DebugPrintf(")\n");
+ }
if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */
int i;
for(i=0; i<sWLB.pWC->nTerm; i++){
@@ -4330,8 +4356,8 @@ WhereInfo *sqlite3WhereBegin(
Index *pIx = pLoop->u.btree.pIndex;
int iIndexCur;
int op = OP_OpenRead;
- /* iIdxCur is always set if to a positive value if ONEPASS is possible */
- assert( iIdxCur!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 );
+ /* iAuxArg is always set if to a positive value if ONEPASS is possible */
+ assert( iAuxArg!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 );
if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIx)
&& (wctrlFlags & WHERE_ONETABLE_ONLY)!=0
){
@@ -4341,7 +4367,7 @@ WhereInfo *sqlite3WhereBegin(
op = 0;
}else if( pWInfo->eOnePass!=ONEPASS_OFF ){
Index *pJ = pTabItem->pTab->pIndex;
- iIndexCur = iIdxCur;
+ iIndexCur = iAuxArg;
assert( wctrlFlags & WHERE_ONEPASS_DESIRED );
while( ALWAYS(pJ) && pJ!=pIx ){
iIndexCur++;
@@ -4349,8 +4375,8 @@ WhereInfo *sqlite3WhereBegin(
}
op = OP_OpenWrite;
pWInfo->aiCurOnePass[1] = iIndexCur;
- }else if( iIdxCur && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){
- iIndexCur = iIdxCur;
+ }else if( iAuxArg && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){
+ iIndexCur = iAuxArg;
if( wctrlFlags & WHERE_REOPEN_IDX ) op = OP_ReopenIdx;
}else{
iIndexCur = pParse->nTab++;
diff --git a/src/whereInt.h b/src/whereInt.h
index 1a189980e..eb6ca326f 100644
--- a/src/whereInt.h
+++ b/src/whereInt.h
@@ -412,6 +412,7 @@ struct WhereInfo {
WhereLoop *pLoops; /* List of all WhereLoop objects */
Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
LogEst nRowOut; /* Estimated number of output rows */
+ LogEst iLimit; /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */
u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */
u8 sorted; /* True if really sorted (not just grouped) */
diff --git a/src/wherecode.c b/src/wherecode.c
index bb48e5dc7..accc14086 100644
--- a/src/wherecode.c
+++ b/src/wherecode.c
@@ -1212,16 +1212,22 @@ Bitmask sqlite3WhereCodeOneLoopStart(
start_constraints = 1;
}
codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff);
- op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
- assert( op!=0 );
- sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
- VdbeCoverage(v);
- VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind );
- VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last );
- VdbeCoverageIf(v, op==OP_SeekGT); testcase( op==OP_SeekGT );
- VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE );
- VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE );
- VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT );
+ if( pLoop->nSkip>0 && nConstraint==pLoop->nSkip ){
+ /* The skip-scan logic inside the call to codeAllEqualityConstraints()
+ ** above has already left the cursor sitting on the correct row,
+ ** so no further seeking is needed */
+ }else{
+ op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
+ assert( op!=0 );
+ sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
+ VdbeCoverage(v);
+ VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind );
+ VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last );
+ VdbeCoverageIf(v, op==OP_SeekGT); testcase( op==OP_SeekGT );
+ VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE );
+ VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE );
+ VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT );
+ }
/* Load the value for the inequality constraint at the end of the
** range (if any).
diff --git a/src/whereexpr.c b/src/whereexpr.c
index c84d2f230..0ad1f6a0d 100644
--- a/src/whereexpr.c
+++ b/src/whereexpr.c
@@ -533,6 +533,7 @@ static void exprAnalyzeOrTerm(
if( pOrInfo==0 ) return;
pTerm->wtFlags |= TERM_ORINFO;
pOrWc = &pOrInfo->wc;
+ memset(pOrWc->aStatic, 0, sizeof(pOrWc->aStatic));
sqlite3WhereClauseInit(pOrWc, pWInfo);
sqlite3WhereSplit(pOrWc, pExpr, TK_OR);
sqlite3WhereExprAnalyze(pSrc, pOrWc);
@@ -559,6 +560,7 @@ static void exprAnalyzeOrTerm(
pOrTerm->wtFlags |= TERM_ANDINFO;
pOrTerm->eOperator = WO_AND;
pAndWC = &pAndInfo->wc;
+ memset(pAndWC->aStatic, 0, sizeof(pAndWC->aStatic));
sqlite3WhereClauseInit(pAndWC, pWC->pWInfo);
sqlite3WhereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
sqlite3WhereExprAnalyze(pSrc, pAndWC);