11/******************************************************************************
22** This file is an amalgamation of many separate C source files from SQLite
3- ** version 3.51.1 . By combining all the individual C code files into this
3+ ** version 3.51.2 . By combining all the individual C code files into this
44** single large file, the entire code can be compiled as a single translation
55** unit. This allows many compilers to do optimizations that would not be
66** possible if the files were compiled separately. Performance improvements
1818** separate file. This file contains only code for the core SQLite library.
1919**
2020** The content in this amalgamation comes from Fossil check-in
21- ** 281fc0e9afc38674b9b0991943b9e9d1e64c with changes in files:
21+ ** b270f8339eb13b504d0b2ba154ebca966b7d with changes in files:
2222**
2323** .fossil-settings/binary-glob
2424** .fossil-settings/empty-dirs
@@ -496,12 +496,12 @@ extern "C" {
496496** [sqlite3_libversion_number()], [sqlite3_sourceid()],
497497** [sqlite_version()] and [sqlite_source_id()].
498498*/
499- #define SQLITE_VERSION "3.51.1 "
500- #define SQLITE_VERSION_NUMBER 3051001
501- #define SQLITE_SOURCE_ID "2025-11-28 17:28:25 281fc0e9afc38674b9b0991943b9e9d1e64c6cbdb133d35f6f5c87ff6af3alt1 "
499+ #define SQLITE_VERSION "3.51.2 "
500+ #define SQLITE_VERSION_NUMBER 3051002
501+ #define SQLITE_SOURCE_ID "2026-01-09 17:27:48 b270f8339eb13b504d0b2ba154ebca966b7dde08e40c3ed7d559749818cbalt1 "
502502#define SQLITE_SCM_BRANCH "branch-3.51"
503- #define SQLITE_SCM_TAGS "release version-3.51.1 "
504- #define SQLITE_SCM_DATETIME "2025-11-28T17:28:25.933Z "
503+ #define SQLITE_SCM_TAGS "release version-3.51.2 "
504+ #define SQLITE_SCM_DATETIME "2026-01-09T17:27:48.405Z "
505505
506506/*
507507** CAPI3REF: Run-Time Library Version Numbers
@@ -41359,12 +41359,18 @@ static int unixLock(sqlite3_file *id, int eFileLock){
4135941359 pInode->nLock++;
4136041360 pInode->nShared = 1;
4136141361 }
41362- }else if( (eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1)
41363- || unixIsSharingShmNode(pFile)
41364- ){
41362+ }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){
4136541363 /* We are trying for an exclusive lock but another thread in this
4136641364 ** same process is still holding a shared lock. */
4136741365 rc = SQLITE_BUSY;
41366+ }else if( unixIsSharingShmNode(pFile) ){
41367+ /* We are in WAL mode and attempting to delete the SHM and WAL
41368+ ** files due to closing the connection or changing out of WAL mode,
41369+ ** but another process still holds locks on the SHM file, thus
41370+ ** indicating that database locks have been broken, perhaps due
41371+ ** to a rogue close(open(dbFile)) or similar.
41372+ */
41373+ rc = SQLITE_BUSY;
4136841374 }else{
4136941375 /* The request was for a RESERVED or EXCLUSIVE lock. It is
4137041376 ** assumed that there is a SHARED or greater lock on the file
@@ -44003,26 +44009,21 @@ static int unixFcntlExternalReader(unixFile *pFile, int *piOut){
4400344009** still not a disaster.
4400444010*/
4400544011static int unixIsSharingShmNode(unixFile *pFile){
44006- int rc;
4400744012 unixShmNode *pShmNode;
44013+ struct flock lock;
4400844014 if( pFile->pShm==0 ) return 0;
4400944015 if( pFile->ctrlFlags & UNIXFILE_EXCL ) return 0;
4401044016 pShmNode = pFile->pShm->pShmNode;
44011- rc = 1;
44012- unixEnterMutex();
44013- if( ALWAYS(pShmNode->nRef==1) ){
44014- struct flock lock;
44015- lock.l_whence = SEEK_SET;
44016- lock.l_start = UNIX_SHM_DMS;
44017- lock.l_len = 1;
44018- lock.l_type = F_WRLCK;
44019- osFcntl(pShmNode->hShm, F_GETLK, &lock);
44020- if( lock.l_type==F_UNLCK ){
44021- rc = 0;
44022- }
44023- }
44024- unixLeaveMutex();
44025- return rc;
44017+ #if SQLITE_ATOMIC_INTRINSICS
44018+ assert( AtomicLoad(&pShmNode->nRef)==1 );
44019+ #endif
44020+ memset(&lock, 0, sizeof(lock));
44021+ lock.l_whence = SEEK_SET;
44022+ lock.l_start = UNIX_SHM_DMS;
44023+ lock.l_len = 1;
44024+ lock.l_type = F_WRLCK;
44025+ osFcntl(pShmNode->hShm, F_GETLK, &lock);
44026+ return (lock.l_type!=F_UNLCK);
4402644027}
4402744028
4402844029/*
@@ -109494,7 +109495,7 @@ SQLITE_API void sqlite3pager_reset(Pager *pPager);
109494109495#define CIPHER_STR(s) #s
109495109496
109496109497#ifndef CIPHER_VERSION_NUMBER
109497- #define CIPHER_VERSION_NUMBER 4.12 .0
109498+ #define CIPHER_VERSION_NUMBER 4.13 .0
109498109499#endif
109499109500
109500109501#ifndef CIPHER_VERSION_BUILD
@@ -109811,7 +109812,7 @@ static void (*const sqlcipher_fini_func)(void) __attribute__((used, section(".fi
109811109812static void sqlcipher_exportFunc(sqlite3_context*, int, sqlite3_value**);
109812109813
109813109814static int sqlcipher_export_init(sqlite3* db, const char** errmsg, const struct sqlite3_api_routines* api) {
109814- sqlite3_create_function_v2(db, "sqlcipher_export", -1, SQLITE_TEXT , 0, sqlcipher_exportFunc, 0, 0, 0);
109815+ sqlite3_create_function_v2(db, "sqlcipher_export", -1, SQLITE_UTF8 , 0, sqlcipher_exportFunc, 0, 0, 0);
109815109816 return SQLITE_OK;
109816109817}
109817109818
@@ -120412,9 +120413,22 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
120412120413 pParse->nMem += nReg;
120413120414 if( pExpr->op==TK_SELECT ){
120414120415 dest.eDest = SRT_Mem;
120415- dest.iSdst = dest.iSDParm;
120416+ if( (pSel->selFlags&SF_Distinct) && pSel->pLimit && pSel->pLimit->pRight ){
120417+ /* If there is both a DISTINCT and an OFFSET clause, then allocate
120418+ ** a separate dest.iSdst array for sqlite3Select() and other
120419+ ** routines to populate. In this case results will be copied over
120420+ ** into the dest.iSDParm array only after OFFSET processing. This
120421+ ** ensures that in the case where OFFSET excludes all rows, the
120422+ ** dest.iSDParm array is not left populated with the contents of the
120423+ ** last row visited - it should be all NULLs if all rows were
120424+ ** excluded by OFFSET. */
120425+ dest.iSdst = pParse->nMem+1;
120426+ pParse->nMem += nReg;
120427+ }else{
120428+ dest.iSdst = dest.iSDParm;
120429+ }
120416120430 dest.nSdst = nReg;
120417- sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1 );
120431+ sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, pParse->nMem );
120418120432 VdbeComment((v, "Init subquery result"));
120419120433 }else{
120420120434 dest.eDest = SRT_Exists;
@@ -153433,9 +153447,14 @@ static void selectInnerLoop(
153433153447 assert( nResultCol<=pDest->nSdst );
153434153448 pushOntoSorter(
153435153449 pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg);
153450+ pDest->iSDParm = regResult;
153436153451 }else{
153437153452 assert( nResultCol==pDest->nSdst );
153438- assert( regResult==iParm );
153453+ if( regResult!=iParm ){
153454+ /* This occurs in cases where the SELECT had both a DISTINCT and
153455+ ** an OFFSET clause. */
153456+ sqlite3VdbeAddOp3(v, OP_Copy, regResult, iParm, nResultCol-1);
153457+ }
153439153458 /* The LIMIT clause will jump out of the loop for us */
153440153459 }
153441153460 break;
@@ -159450,12 +159469,24 @@ static SQLITE_NOINLINE void existsToJoin(
159450159469 && (pSub->selFlags & SF_Aggregate)==0
159451159470 && !pSub->pSrc->a[0].fg.isSubquery
159452159471 && pSub->pLimit==0
159472+ && pSub->pPrior==0
159453159473 ){
159474+ /* Before combining the sub-select with the parent, renumber the
159475+ ** cursor used by the subselect. This is because the EXISTS expression
159476+ ** might be a copy of another EXISTS expression from somewhere
159477+ ** else in the tree, and in this case it is important that it use
159478+ ** a unique cursor number. */
159479+ sqlite3 *db = pParse->db;
159480+ int *aCsrMap = sqlite3DbMallocZero(db, (pParse->nTab+2)*sizeof(int));
159481+ if( aCsrMap==0 ) return;
159482+ aCsrMap[0] = (pParse->nTab+1);
159483+ renumberCursors(pParse, pSub, -1, aCsrMap);
159484+ sqlite3DbFree(db, aCsrMap);
159485+
159454159486 memset(pWhere, 0, sizeof(*pWhere));
159455159487 pWhere->op = TK_INTEGER;
159456159488 pWhere->u.iValue = 1;
159457159489 ExprSetProperty(pWhere, EP_IntValue);
159458-
159459159490 assert( p->pWhere!=0 );
159460159491 pSub->pSrc->a[0].fg.fromExists = 1;
159461159492 pSub->pSrc->a[0].fg.jointype |= JT_CROSS;
@@ -179263,6 +179294,9 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
179263179294 sqlite3 *db = pParse->db;
179264179295 int iEnd = sqlite3VdbeCurrentAddr(v);
179265179296 int nRJ = 0;
179297+ #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
179298+ int addrSeek = 0;
179299+ #endif
179266179300
179267179301 /* Generate loop termination code.
179268179302 */
@@ -179275,7 +179309,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
179275179309 ** the RIGHT JOIN table */
179276179310 WhereRightJoin *pRJ = pLevel->pRJ;
179277179311 sqlite3VdbeResolveLabel(v, pLevel->addrCont);
179278- pLevel->addrCont = 0;
179312+ /* Replace addrCont with a new label that will never be used, just so
179313+ ** the subsequent call to resolve pLevel->addrCont will have something
179314+ ** to resolve. */
179315+ pLevel->addrCont = sqlite3VdbeMakeLabel(pParse);
179279179316 pRJ->endSubrtn = sqlite3VdbeCurrentAddr(v);
179280179317 sqlite3VdbeAddOp3(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn, 1);
179281179318 VdbeCoverage(v);
@@ -179284,7 +179321,6 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
179284179321 pLoop = pLevel->pWLoop;
179285179322 if( pLevel->op!=OP_Noop ){
179286179323#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
179287- int addrSeek = 0;
179288179324 Index *pIdx;
179289179325 int n;
179290179326 if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED
@@ -179307,25 +179343,26 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
179307179343 sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
179308179344 }
179309179345#endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
179310- if( pTabList->a[pLevel->iFrom].fg.fromExists && i==pWInfo->nLevel-1 ){
179311- /* If the EXISTS-to-JOIN optimization was applied, then the EXISTS
179312- ** loop(s) will be the inner-most loops of the join. There might be
179313- ** multiple EXISTS loops, but they will all be nested, and the join
179314- ** order will not have been changed by the query planner. If the
179315- ** inner-most EXISTS loop sees a single successful row, it should
179316- ** break out of *all* EXISTS loops. But only the inner-most of the
179317- ** nested EXISTS loops should do this breakout. */
179318- int nOuter = 0; /* Nr of outer EXISTS that this one is nested within */
179319- while( nOuter<i ){
179320- if( !pTabList->a[pLevel[-nOuter-1].iFrom].fg.fromExists ) break;
179321- nOuter++;
179322- }
179323- testcase( nOuter>0 );
179324- sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel[-nOuter].addrBrk);
179325- VdbeComment((v, "EXISTS break"));
179326- }
179327- /* The common case: Advance to the next row */
179328- if( pLevel->addrCont ) sqlite3VdbeResolveLabel(v, pLevel->addrCont);
179346+ }
179347+ if( pTabList->a[pLevel->iFrom].fg.fromExists && i==pWInfo->nLevel-1 ){
179348+ /* If the EXISTS-to-JOIN optimization was applied, then the EXISTS
179349+ ** loop(s) will be the inner-most loops of the join. There might be
179350+ ** multiple EXISTS loops, but they will all be nested, and the join
179351+ ** order will not have been changed by the query planner. If the
179352+ ** inner-most EXISTS loop sees a single successful row, it should
179353+ ** break out of *all* EXISTS loops. But only the inner-most of the
179354+ ** nested EXISTS loops should do this breakout. */
179355+ int nOuter = 0; /* Nr of outer EXISTS that this one is nested within */
179356+ while( nOuter<i ){
179357+ if( !pTabList->a[pLevel[-nOuter-1].iFrom].fg.fromExists ) break;
179358+ nOuter++;
179359+ }
179360+ testcase( nOuter>0 );
179361+ sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel[-nOuter].addrBrk);
179362+ VdbeComment((v, "EXISTS break"));
179363+ }
179364+ sqlite3VdbeResolveLabel(v, pLevel->addrCont);
179365+ if( pLevel->op!=OP_Noop ){
179329179366 sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
179330179367 sqlite3VdbeChangeP5(v, pLevel->p5);
179331179368 VdbeCoverage(v);
@@ -179338,10 +179375,11 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
179338179375 VdbeCoverage(v);
179339179376 }
179340179377#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
179341- if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek);
179378+ if( addrSeek ){
179379+ sqlite3VdbeJumpHere(v, addrSeek);
179380+ addrSeek = 0;
179381+ }
179342179382#endif
179343- }else if( pLevel->addrCont ){
179344- sqlite3VdbeResolveLabel(v, pLevel->addrCont);
179345179383 }
179346179384 if( (pLoop->wsFlags & WHERE_IN_ABLE)!=0 && pLevel->u.in.nIn>0 ){
179347179385 struct InLoop *pIn;
@@ -224757,7 +224795,7 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
224757224795 if( node.zData==0 ) return;
224758224796 nData = sqlite3_value_bytes(apArg[1]);
224759224797 if( nData<4 ) return;
224760- if( nData<NCELL(&node)*tree.nBytesPerCell ) return;
224798+ if( nData<4+ NCELL(&node)*tree.nBytesPerCell ) return;
224761224799
224762224800 pOut = sqlite3_str_new(0);
224763224801 for(ii=0; ii<NCELL(&node); ii++){
@@ -243838,7 +243876,13 @@ typedef sqlite3_uint64 u64;
243838243876# define FLEXARRAY 1
243839243877#endif
243840243878
243841- #endif
243879+ #endif /* SQLITE_AMALGAMATION */
243880+
243881+ /*
243882+ ** Constants for the largest and smallest possible 32-bit signed integers.
243883+ */
243884+ # define LARGEST_INT32 ((int)(0x7fffffff))
243885+ # define SMALLEST_INT32 ((int)((-1) - LARGEST_INT32))
243842243886
243843243887/* Truncate very long tokens to this many bytes. Hard limit is
243844243888** (65536-1-1-4-9)==65521 bytes. The limiting factor is the 16-bit offset
@@ -258401,7 +258445,7 @@ static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){
258401258445 fts5StructureRelease(pStruct);
258402258446 pStruct = pNew;
258403258447 nMin = 1;
258404- nMerge = nMerge*-1;
258448+ nMerge = ( nMerge==SMALLEST_INT32 ? LARGEST_INT32 : (nMerge *-1)) ;
258405258449 }
258406258450 if( pStruct && pStruct->nLevel ){
258407258451 if( fts5IndexMerge(p, &pStruct, nMerge, nMin) ){
@@ -265608,7 +265652,7 @@ static void fts5SourceIdFunc(
265608265652){
265609265653 assert( nArg==0 );
265610265654 UNUSED_PARAM2(nArg, apUnused);
265611- sqlite3_result_text(pCtx, "fts5: 2025-11-28 17:28:25 281fc0e9afc38674b9b0991943b9e9d1e64c6cbdb133d35f6f5c87ff6af38a88 ", -1, SQLITE_TRANSIENT);
265655+ sqlite3_result_text(pCtx, "fts5: 2026-01-09 17:27:48 b270f8339eb13b504d0b2ba154ebca966b7dde08e40c3ed7d559749818cb2075 ", -1, SQLITE_TRANSIENT);
265612265656}
265613265657
265614265658/*
0 commit comments