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**
2424*/
@@ -468,12 +468,12 @@ extern "C" {
468468** [sqlite3_libversion_number()], [sqlite3_sourceid()],
469469** [sqlite_version()] and [sqlite_source_id()].
470470*/
471- #define SQLITE_VERSION "3.51.1 "
472- #define SQLITE_VERSION_NUMBER 3051001
473- #define SQLITE_SOURCE_ID "2025-11-28 17:28:25 281fc0e9afc38674b9b0991943b9e9d1e64c6cbdb133d35f6f5c87ff6af38a88 "
471+ #define SQLITE_VERSION "3.51.2 "
472+ #define SQLITE_VERSION_NUMBER 3051002
473+ #define SQLITE_SOURCE_ID "2026-01-09 17:27:48 b270f8339eb13b504d0b2ba154ebca966b7dde08e40c3ed7d559749818cb2075 "
474474#define SQLITE_SCM_BRANCH "branch-3.51"
475- #define SQLITE_SCM_TAGS "release version-3.51.1 "
476- #define SQLITE_SCM_DATETIME "2025-11-28T17:28:25.933Z "
475+ #define SQLITE_SCM_TAGS "release version-3.51.2 "
476+ #define SQLITE_SCM_DATETIME "2026-01-09T17:27:48.405Z "
477477
478478/*
479479** CAPI3REF: Run-Time Library Version Numbers
@@ -41229,12 +41229,18 @@ static int unixLock(sqlite3_file *id, int eFileLock){
4122941229 pInode->nLock++;
4123041230 pInode->nShared = 1;
4123141231 }
41232- }else if( (eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1)
41233- || unixIsSharingShmNode(pFile)
41234- ){
41232+ }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){
4123541233 /* We are trying for an exclusive lock but another thread in this
4123641234 ** same process is still holding a shared lock. */
4123741235 rc = SQLITE_BUSY;
41236+ }else if( unixIsSharingShmNode(pFile) ){
41237+ /* We are in WAL mode and attempting to delete the SHM and WAL
41238+ ** files due to closing the connection or changing out of WAL mode,
41239+ ** but another process still holds locks on the SHM file, thus
41240+ ** indicating that database locks have been broken, perhaps due
41241+ ** to a rogue close(open(dbFile)) or similar.
41242+ */
41243+ rc = SQLITE_BUSY;
4123841244 }else{
4123941245 /* The request was for a RESERVED or EXCLUSIVE lock. It is
4124041246 ** assumed that there is a SHARED or greater lock on the file
@@ -43873,26 +43879,21 @@ static int unixFcntlExternalReader(unixFile *pFile, int *piOut){
4387343879** still not a disaster.
4387443880*/
4387543881static int unixIsSharingShmNode(unixFile *pFile){
43876- int rc;
4387743882 unixShmNode *pShmNode;
43883+ struct flock lock;
4387843884 if( pFile->pShm==0 ) return 0;
4387943885 if( pFile->ctrlFlags & UNIXFILE_EXCL ) return 0;
4388043886 pShmNode = pFile->pShm->pShmNode;
43881- rc = 1;
43882- unixEnterMutex();
43883- if( ALWAYS(pShmNode->nRef==1) ){
43884- struct flock lock;
43885- lock.l_whence = SEEK_SET;
43886- lock.l_start = UNIX_SHM_DMS;
43887- lock.l_len = 1;
43888- lock.l_type = F_WRLCK;
43889- osFcntl(pShmNode->hShm, F_GETLK, &lock);
43890- if( lock.l_type==F_UNLCK ){
43891- rc = 0;
43892- }
43893- }
43894- unixLeaveMutex();
43895- return rc;
43887+ #if SQLITE_ATOMIC_INTRINSICS
43888+ assert( AtomicLoad(&pShmNode->nRef)==1 );
43889+ #endif
43890+ memset(&lock, 0, sizeof(lock));
43891+ lock.l_whence = SEEK_SET;
43892+ lock.l_start = UNIX_SHM_DMS;
43893+ lock.l_len = 1;
43894+ lock.l_type = F_WRLCK;
43895+ osFcntl(pShmNode->hShm, F_GETLK, &lock);
43896+ return (lock.l_type!=F_UNLCK);
4389643897}
4389743898
4389843899/*
@@ -115317,9 +115318,22 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
115317115318 pParse->nMem += nReg;
115318115319 if( pExpr->op==TK_SELECT ){
115319115320 dest.eDest = SRT_Mem;
115320- dest.iSdst = dest.iSDParm;
115321+ if( (pSel->selFlags&SF_Distinct) && pSel->pLimit && pSel->pLimit->pRight ){
115322+ /* If there is both a DISTINCT and an OFFSET clause, then allocate
115323+ ** a separate dest.iSdst array for sqlite3Select() and other
115324+ ** routines to populate. In this case results will be copied over
115325+ ** into the dest.iSDParm array only after OFFSET processing. This
115326+ ** ensures that in the case where OFFSET excludes all rows, the
115327+ ** dest.iSDParm array is not left populated with the contents of the
115328+ ** last row visited - it should be all NULLs if all rows were
115329+ ** excluded by OFFSET. */
115330+ dest.iSdst = pParse->nMem+1;
115331+ pParse->nMem += nReg;
115332+ }else{
115333+ dest.iSdst = dest.iSDParm;
115334+ }
115321115335 dest.nSdst = nReg;
115322- sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1 );
115336+ sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, pParse->nMem );
115323115337 VdbeComment((v, "Init subquery result"));
115324115338 }else{
115325115339 dest.eDest = SRT_Exists;
@@ -148187,9 +148201,14 @@ static void selectInnerLoop(
148187148201 assert( nResultCol<=pDest->nSdst );
148188148202 pushOntoSorter(
148189148203 pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg);
148204+ pDest->iSDParm = regResult;
148190148205 }else{
148191148206 assert( nResultCol==pDest->nSdst );
148192- assert( regResult==iParm );
148207+ if( regResult!=iParm ){
148208+ /* This occurs in cases where the SELECT had both a DISTINCT and
148209+ ** an OFFSET clause. */
148210+ sqlite3VdbeAddOp3(v, OP_Copy, regResult, iParm, nResultCol-1);
148211+ }
148193148212 /* The LIMIT clause will jump out of the loop for us */
148194148213 }
148195148214 break;
@@ -154204,12 +154223,24 @@ static SQLITE_NOINLINE void existsToJoin(
154204154223 && (pSub->selFlags & SF_Aggregate)==0
154205154224 && !pSub->pSrc->a[0].fg.isSubquery
154206154225 && pSub->pLimit==0
154226+ && pSub->pPrior==0
154207154227 ){
154228+ /* Before combining the sub-select with the parent, renumber the
154229+ ** cursor used by the subselect. This is because the EXISTS expression
154230+ ** might be a copy of another EXISTS expression from somewhere
154231+ ** else in the tree, and in this case it is important that it use
154232+ ** a unique cursor number. */
154233+ sqlite3 *db = pParse->db;
154234+ int *aCsrMap = sqlite3DbMallocZero(db, (pParse->nTab+2)*sizeof(int));
154235+ if( aCsrMap==0 ) return;
154236+ aCsrMap[0] = (pParse->nTab+1);
154237+ renumberCursors(pParse, pSub, -1, aCsrMap);
154238+ sqlite3DbFree(db, aCsrMap);
154239+
154208154240 memset(pWhere, 0, sizeof(*pWhere));
154209154241 pWhere->op = TK_INTEGER;
154210154242 pWhere->u.iValue = 1;
154211154243 ExprSetProperty(pWhere, EP_IntValue);
154212-
154213154244 assert( p->pWhere!=0 );
154214154245 pSub->pSrc->a[0].fg.fromExists = 1;
154215154246 pSub->pSrc->a[0].fg.jointype |= JT_CROSS;
@@ -174002,6 +174033,9 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
174002174033 sqlite3 *db = pParse->db;
174003174034 int iEnd = sqlite3VdbeCurrentAddr(v);
174004174035 int nRJ = 0;
174036+ #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
174037+ int addrSeek = 0;
174038+ #endif
174005174039
174006174040 /* Generate loop termination code.
174007174041 */
@@ -174014,7 +174048,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
174014174048 ** the RIGHT JOIN table */
174015174049 WhereRightJoin *pRJ = pLevel->pRJ;
174016174050 sqlite3VdbeResolveLabel(v, pLevel->addrCont);
174017- pLevel->addrCont = 0;
174051+ /* Replace addrCont with a new label that will never be used, just so
174052+ ** the subsequent call to resolve pLevel->addrCont will have something
174053+ ** to resolve. */
174054+ pLevel->addrCont = sqlite3VdbeMakeLabel(pParse);
174018174055 pRJ->endSubrtn = sqlite3VdbeCurrentAddr(v);
174019174056 sqlite3VdbeAddOp3(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn, 1);
174020174057 VdbeCoverage(v);
@@ -174023,7 +174060,6 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
174023174060 pLoop = pLevel->pWLoop;
174024174061 if( pLevel->op!=OP_Noop ){
174025174062#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
174026- int addrSeek = 0;
174027174063 Index *pIdx;
174028174064 int n;
174029174065 if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED
@@ -174046,25 +174082,26 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
174046174082 sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
174047174083 }
174048174084#endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
174049- if( pTabList->a[pLevel->iFrom].fg.fromExists && i==pWInfo->nLevel-1 ){
174050- /* If the EXISTS-to-JOIN optimization was applied, then the EXISTS
174051- ** loop(s) will be the inner-most loops of the join. There might be
174052- ** multiple EXISTS loops, but they will all be nested, and the join
174053- ** order will not have been changed by the query planner. If the
174054- ** inner-most EXISTS loop sees a single successful row, it should
174055- ** break out of *all* EXISTS loops. But only the inner-most of the
174056- ** nested EXISTS loops should do this breakout. */
174057- int nOuter = 0; /* Nr of outer EXISTS that this one is nested within */
174058- while( nOuter<i ){
174059- if( !pTabList->a[pLevel[-nOuter-1].iFrom].fg.fromExists ) break;
174060- nOuter++;
174061- }
174062- testcase( nOuter>0 );
174063- sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel[-nOuter].addrBrk);
174064- VdbeComment((v, "EXISTS break"));
174065- }
174066- /* The common case: Advance to the next row */
174067- if( pLevel->addrCont ) sqlite3VdbeResolveLabel(v, pLevel->addrCont);
174085+ }
174086+ if( pTabList->a[pLevel->iFrom].fg.fromExists && i==pWInfo->nLevel-1 ){
174087+ /* If the EXISTS-to-JOIN optimization was applied, then the EXISTS
174088+ ** loop(s) will be the inner-most loops of the join. There might be
174089+ ** multiple EXISTS loops, but they will all be nested, and the join
174090+ ** order will not have been changed by the query planner. If the
174091+ ** inner-most EXISTS loop sees a single successful row, it should
174092+ ** break out of *all* EXISTS loops. But only the inner-most of the
174093+ ** nested EXISTS loops should do this breakout. */
174094+ int nOuter = 0; /* Nr of outer EXISTS that this one is nested within */
174095+ while( nOuter<i ){
174096+ if( !pTabList->a[pLevel[-nOuter-1].iFrom].fg.fromExists ) break;
174097+ nOuter++;
174098+ }
174099+ testcase( nOuter>0 );
174100+ sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel[-nOuter].addrBrk);
174101+ VdbeComment((v, "EXISTS break"));
174102+ }
174103+ sqlite3VdbeResolveLabel(v, pLevel->addrCont);
174104+ if( pLevel->op!=OP_Noop ){
174068174105 sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
174069174106 sqlite3VdbeChangeP5(v, pLevel->p5);
174070174107 VdbeCoverage(v);
@@ -174077,10 +174114,11 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
174077174114 VdbeCoverage(v);
174078174115 }
174079174116#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
174080- if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek);
174117+ if( addrSeek ){
174118+ sqlite3VdbeJumpHere(v, addrSeek);
174119+ addrSeek = 0;
174120+ }
174081174121#endif
174082- }else if( pLevel->addrCont ){
174083- sqlite3VdbeResolveLabel(v, pLevel->addrCont);
174084174122 }
174085174123 if( (pLoop->wsFlags & WHERE_IN_ABLE)!=0 && pLevel->u.in.nIn>0 ){
174086174124 struct InLoop *pIn;
@@ -219470,7 +219508,7 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
219470219508 if( node.zData==0 ) return;
219471219509 nData = sqlite3_value_bytes(apArg[1]);
219472219510 if( nData<4 ) return;
219473- if( nData<NCELL(&node)*tree.nBytesPerCell ) return;
219511+ if( nData<4+ NCELL(&node)*tree.nBytesPerCell ) return;
219474219512
219475219513 pOut = sqlite3_str_new(0);
219476219514 for(ii=0; ii<NCELL(&node); ii++){
@@ -238551,7 +238589,13 @@ typedef sqlite3_uint64 u64;
238551238589# define FLEXARRAY 1
238552238590#endif
238553238591
238554- #endif
238592+ #endif /* SQLITE_AMALGAMATION */
238593+
238594+ /*
238595+ ** Constants for the largest and smallest possible 32-bit signed integers.
238596+ */
238597+ # define LARGEST_INT32 ((int)(0x7fffffff))
238598+ # define SMALLEST_INT32 ((int)((-1) - LARGEST_INT32))
238555238599
238556238600/* Truncate very long tokens to this many bytes. Hard limit is
238557238601** (65536-1-1-4-9)==65521 bytes. The limiting factor is the 16-bit offset
@@ -253114,7 +253158,7 @@ static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){
253114253158 fts5StructureRelease(pStruct);
253115253159 pStruct = pNew;
253116253160 nMin = 1;
253117- nMerge = nMerge*-1;
253161+ nMerge = ( nMerge==SMALLEST_INT32 ? LARGEST_INT32 : (nMerge *-1)) ;
253118253162 }
253119253163 if( pStruct && pStruct->nLevel ){
253120253164 if( fts5IndexMerge(p, &pStruct, nMerge, nMin) ){
@@ -260321,7 +260365,7 @@ static void fts5SourceIdFunc(
260321260365){
260322260366 assert( nArg==0 );
260323260367 UNUSED_PARAM2(nArg, apUnused);
260324- sqlite3_result_text(pCtx, "fts5: 2025-11-28 17:28:25 281fc0e9afc38674b9b0991943b9e9d1e64c6cbdb133d35f6f5c87ff6af38a88 ", -1, SQLITE_TRANSIENT);
260368+ sqlite3_result_text(pCtx, "fts5: 2026-01-09 17:27:48 b270f8339eb13b504d0b2ba154ebca966b7dde08e40c3ed7d559749818cb2075 ", -1, SQLITE_TRANSIENT);
260325260369}
260326260370
260327260371/*
0 commit comments