mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-18 10:21:03 +03:00
Merge all the latest trunk enhancements into the sessions branch.
FossilOrigin-Name: c91065f8edb1e54076791716fc20d3fcfe3070dc
This commit is contained in:
@@ -769,6 +769,10 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
|
||||
b.pDest = pTo;
|
||||
b.iNext = 1;
|
||||
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
sqlite3PagerAlignReserve(sqlite3BtreePager(pTo), sqlite3BtreePager(pFrom));
|
||||
#endif
|
||||
|
||||
/* 0x7FFFFFFF is the hard limit for the number of pages in a database
|
||||
** file. By passing this as the number of pages to copy to
|
||||
** sqlite3_backup_step(), we can guarantee that the copy finishes
|
||||
|
||||
@@ -8186,7 +8186,8 @@ int sqlite3BtreeDelete(BtCursor *pCur, int bPreserve){
|
||||
if( rc==SQLITE_OK ){
|
||||
if( bSkipnext ){
|
||||
assert( bPreserve && pCur->iPage==iCellDepth );
|
||||
assert( pPage->nCell>0 && iCellIdx<=pPage->nCell );
|
||||
assert( pPage==pCur->apPage[pCur->iPage] );
|
||||
assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell );
|
||||
pCur->eState = CURSOR_SKIPNEXT;
|
||||
if( iCellIdx>=pPage->nCell ){
|
||||
pCur->skipNext = -1;
|
||||
@@ -8921,6 +8922,10 @@ static void checkList(
|
||||
#endif
|
||||
iPage = get4byte(pOvflData);
|
||||
sqlite3PagerUnref(pOvflPage);
|
||||
|
||||
if( isFreeList && N<(iPage!=0) ){
|
||||
checkAppendMsg(pCheck, "free-page count in header is too small");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
|
||||
|
||||
@@ -415,6 +415,7 @@ void sqlite3DeleteFrom(
|
||||
if( pWInfo==0 ) goto delete_from_cleanup;
|
||||
eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
|
||||
assert( IsVirtual(pTab)==0 || eOnePass==ONEPASS_OFF );
|
||||
assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
|
||||
|
||||
/* Keep track of the number of rows to be deleted */
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
|
||||
@@ -4660,7 +4660,8 @@ static void unixShmBarrier(
|
||||
sqlite3_file *fd /* Database file holding the shared memory */
|
||||
){
|
||||
UNUSED_PARAMETER(fd);
|
||||
unixEnterMutex();
|
||||
sqlite3MemoryBarrier(); /* compiler-defined memory barrier */
|
||||
unixEnterMutex(); /* Also mutex, for redundancy */
|
||||
unixLeaveMutex();
|
||||
}
|
||||
|
||||
|
||||
@@ -3850,8 +3850,8 @@ static void winShmBarrier(
|
||||
sqlite3_file *fd /* Database holding the shared memory */
|
||||
){
|
||||
UNUSED_PARAMETER(fd);
|
||||
/* MemoryBarrier(); // does not work -- do not know why not */
|
||||
winShmEnterMutex();
|
||||
sqlite3MemoryBarrier(); /* compiler-defined memory barrier */
|
||||
winShmEnterMutex(); /* Also mutex, for redundancy */
|
||||
winShmLeaveMutex();
|
||||
}
|
||||
|
||||
|
||||
14
src/pager.c
14
src/pager.c
@@ -2116,6 +2116,20 @@ static void pagerReportSize(Pager *pPager){
|
||||
# define pagerReportSize(X) /* No-op if we do not support a codec */
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
/*
|
||||
** Make sure the number of reserved bits is the same in the destination
|
||||
** pager as it is in the source. This comes up when a VACUUM changes the
|
||||
** number of reserved bits to the "optimal" amount.
|
||||
*/
|
||||
void sqlite3PagerAlignReserve(Pager *pDest, Pager *pSrc){
|
||||
if( pDest->nReserve!=pSrc->nReserve ){
|
||||
pDest->nReserve = pSrc->nReserve;
|
||||
pagerReportSize(pDest);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Read a single page from either the journal file (if isMainJrnl==1) or
|
||||
** from the sub-journal (if isMainJrnl==0) and playback that page.
|
||||
|
||||
@@ -118,6 +118,9 @@ int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
|
||||
/* Functions used to configure a Pager object. */
|
||||
void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
|
||||
int sqlite3PagerSetPagesize(Pager*, u32*, int);
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
void sqlite3PagerAlignReserve(Pager*,Pager*);
|
||||
#endif
|
||||
int sqlite3PagerMaxPageCount(Pager*, int);
|
||||
void sqlite3PagerSetCachesize(Pager*, int);
|
||||
void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64);
|
||||
|
||||
@@ -413,7 +413,7 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){
|
||||
assert( pCache->pGroup==&pcache1.grp );
|
||||
pcache1LeaveMutex(pCache->pGroup);
|
||||
#endif
|
||||
if( benignMalloc ) sqlite3BeginBenignMalloc();
|
||||
if( benignMalloc ){ sqlite3BeginBenignMalloc(); }
|
||||
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
|
||||
pPg = pcache1Alloc(pCache->szPage);
|
||||
p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra);
|
||||
@@ -426,7 +426,7 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){
|
||||
pPg = pcache1Alloc(pCache->szAlloc);
|
||||
p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
|
||||
#endif
|
||||
if( benignMalloc ) sqlite3EndBenignMalloc();
|
||||
if( benignMalloc ){ sqlite3EndBenignMalloc(); }
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
pcache1EnterMutex(pCache->pGroup);
|
||||
#endif
|
||||
|
||||
@@ -355,8 +355,13 @@ static int lookupName(
|
||||
/*
|
||||
** Perhaps the name is a reference to the ROWID
|
||||
*/
|
||||
if( cnt==0 && cntTab==1 && pMatch && sqlite3IsRowid(zCol)
|
||||
&& VisibleRowid(pMatch->pTab) ){
|
||||
if( cnt==0
|
||||
&& cntTab==1
|
||||
&& pMatch
|
||||
&& (pNC->ncFlags & NC_IdxExpr)==0
|
||||
&& sqlite3IsRowid(zCol)
|
||||
&& VisibleRowid(pMatch->pTab)
|
||||
){
|
||||
cnt = 1;
|
||||
pExpr->iColumn = -1; /* IMP: R-44911-55124 */
|
||||
pExpr->affinity = SQLITE_AFF_INTEGER;
|
||||
|
||||
@@ -4267,9 +4267,12 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
pTab->nRef++;
|
||||
#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
|
||||
if( pTab->pSelect || IsVirtual(pTab) ){
|
||||
/* We reach here if the named table is a really a view */
|
||||
if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
|
||||
assert( pFrom->pSelect==0 );
|
||||
if( pFrom->fg.isTabFunc && !IsVirtual(pTab) ){
|
||||
sqlite3ErrorMsg(pParse, "'%s' is not a function", pTab->zName);
|
||||
return WRC_Abort;
|
||||
}
|
||||
pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
|
||||
sqlite3SelectSetName(pFrom->pSelect, pTab->zName);
|
||||
sqlite3WalkSelect(pWalker, pFrom->pSelect);
|
||||
|
||||
@@ -3630,7 +3630,7 @@ const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
|
||||
**
|
||||
** See also: [sqlite3_bind_blob|sqlite3_bind()],
|
||||
** [sqlite3_bind_parameter_count()], and
|
||||
** [sqlite3_bind_parameter_index()].
|
||||
** [sqlite3_bind_parameter_name()].
|
||||
*/
|
||||
int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
|
||||
|
||||
|
||||
@@ -912,18 +912,19 @@ static const Mem *columnNullValue(void){
|
||||
#endif
|
||||
= {
|
||||
/* .u = */ {0},
|
||||
/* .flags = */ MEM_Null,
|
||||
/* .enc = */ 0,
|
||||
/* .n = */ 0,
|
||||
/* .z = */ 0,
|
||||
/* .zMalloc = */ 0,
|
||||
/* .szMalloc = */ 0,
|
||||
/* .iPadding1 = */ 0,
|
||||
/* .db = */ 0,
|
||||
/* .xDel = */ 0,
|
||||
/* .flags = */ (u16)MEM_Null,
|
||||
/* .enc = */ (u8)0,
|
||||
/* .eSubtype = */ (u8)0,
|
||||
/* .n = */ (int)0,
|
||||
/* .z = */ (char*)0,
|
||||
/* .zMalloc = */ (char*)0,
|
||||
/* .szMalloc = */ (int)0,
|
||||
/* .uTemp = */ (u32)0,
|
||||
/* .db = */ (sqlite3*)0,
|
||||
/* .xDel = */ (void(*)(void*))0,
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* .pScopyFrom = */ 0,
|
||||
/* .pFiller = */ 0,
|
||||
/* .pScopyFrom = */ (Mem*)0,
|
||||
/* .pFiller = */ (void*)0,
|
||||
#endif
|
||||
};
|
||||
return &nullMem;
|
||||
|
||||
@@ -182,7 +182,7 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
|
||||
while( pScan->iEquiv<=pScan->nEquiv ){
|
||||
iCur = pScan->aiCur[pScan->iEquiv-1];
|
||||
iColumn = pScan->aiColumn[pScan->iEquiv-1];
|
||||
assert( iColumn!=(-2) || pScan->pIdxExpr!=0 );
|
||||
if( iColumn==(-2) && pScan->pIdxExpr==0 ) return 0;
|
||||
while( (pWC = pScan->pWC)!=0 ){
|
||||
for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){
|
||||
if( pTerm->leftCursor==iCur
|
||||
@@ -193,10 +193,9 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
|
||||
){
|
||||
if( (pTerm->eOperator & WO_EQUIV)!=0
|
||||
&& pScan->nEquiv<ArraySize(pScan->aiCur)
|
||||
&& (pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight))->op==TK_COLUMN
|
||||
){
|
||||
int j;
|
||||
pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight);
|
||||
assert( pX->op==TK_COLUMN );
|
||||
for(j=0; j<pScan->nEquiv; j++){
|
||||
if( pScan->aiCur[j]==pX->iTable
|
||||
&& pScan->aiColumn[j]==pX->iColumn ){
|
||||
|
||||
@@ -65,7 +65,7 @@ static const char *explainIndexColumnName(Index *pIdx, int i){
|
||||
**
|
||||
** "a=? AND b>?"
|
||||
*/
|
||||
static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop, Table *pTab){
|
||||
static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){
|
||||
Index *pIndex = pLoop->u.btree.pIndex;
|
||||
u16 nEq = pLoop->u.btree.nEq;
|
||||
u16 nSkip = pLoop->nSkip;
|
||||
@@ -166,7 +166,7 @@ int sqlite3WhereExplainOneScan(
|
||||
if( zFmt ){
|
||||
sqlite3StrAccumAppend(&str, " USING ", 7);
|
||||
sqlite3XPrintf(&str, 0, zFmt, pIdx->zName);
|
||||
explainIndexRange(&str, pLoop, pItem->pTab);
|
||||
explainIndexRange(&str, pLoop);
|
||||
}
|
||||
}else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
|
||||
const char *zRangeOp;
|
||||
@@ -514,8 +514,8 @@ static int codeAllEqualityTerms(
|
||||
sqlite3VdbeJumpHere(v, j);
|
||||
for(j=0; j<nSkip; j++){
|
||||
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, j, regBase+j);
|
||||
assert( pIdx->aiColumn[j]>=0 );
|
||||
VdbeComment((v, "%s", pIdx->pTable->aCol[pIdx->aiColumn[j]].zName));
|
||||
testcase( pIdx->aiColumn[j]==(-2) );
|
||||
VdbeComment((v, "%s", explainIndexColumnName(pIdx, j)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user