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*/
@@ -467,12 +467,12 @@ extern "C" {
467467** [sqlite3_libversion_number()], [sqlite3_sourceid()],
468468** [sqlite_version()] and [sqlite_source_id()].
469469*/
470- #define SQLITE_VERSION "3.51.1 "
471- #define SQLITE_VERSION_NUMBER 3051001
472- #define SQLITE_SOURCE_ID "2025-11-28 17:28:25 281fc0e9afc38674b9b0991943b9e9d1e64c6cbdb133d35f6f5c87ff6af38a88 "
470+ #define SQLITE_VERSION "3.51.2 "
471+ #define SQLITE_VERSION_NUMBER 3051002
472+ #define SQLITE_SOURCE_ID "2026-01-09 17:27:48 b270f8339eb13b504d0b2ba154ebca966b7dde08e40c3ed7d559749818cb2075 "
473473#define SQLITE_SCM_BRANCH "branch-3.51"
474- #define SQLITE_SCM_TAGS "release version-3.51.1 "
475- #define SQLITE_SCM_DATETIME "2025-11-28T17:28:25.933Z "
474+ #define SQLITE_SCM_TAGS "release version-3.51.2 "
475+ #define SQLITE_SCM_DATETIME "2026-01-09T17:27:48.405Z "
476476
477477/*
478478** CAPI3REF: Run-Time Library Version Numbers
@@ -41228,12 +41228,18 @@ static int unixLock(sqlite3_file *id, int eFileLock){
4122841228 pInode->nLock++;
4122941229 pInode->nShared = 1;
4123041230 }
41231- }else if( (eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1)
41232- || unixIsSharingShmNode(pFile)
41233- ){
41231+ }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){
4123441232 /* We are trying for an exclusive lock but another thread in this
4123541233 ** same process is still holding a shared lock. */
4123641234 rc = SQLITE_BUSY;
41235+ }else if( unixIsSharingShmNode(pFile) ){
41236+ /* We are in WAL mode and attempting to delete the SHM and WAL
41237+ ** files due to closing the connection or changing out of WAL mode,
41238+ ** but another process still holds locks on the SHM file, thus
41239+ ** indicating that database locks have been broken, perhaps due
41240+ ** to a rogue close(open(dbFile)) or similar.
41241+ */
41242+ rc = SQLITE_BUSY;
4123741243 }else{
4123841244 /* The request was for a RESERVED or EXCLUSIVE lock. It is
4123941245 ** assumed that there is a SHARED or greater lock on the file
@@ -43872,26 +43878,21 @@ static int unixFcntlExternalReader(unixFile *pFile, int *piOut){
4387243878** still not a disaster.
4387343879*/
4387443880static int unixIsSharingShmNode(unixFile *pFile){
43875- int rc;
4387643881 unixShmNode *pShmNode;
43882+ struct flock lock;
4387743883 if( pFile->pShm==0 ) return 0;
4387843884 if( pFile->ctrlFlags & UNIXFILE_EXCL ) return 0;
4387943885 pShmNode = pFile->pShm->pShmNode;
43880- rc = 1;
43881- unixEnterMutex();
43882- if( ALWAYS(pShmNode->nRef==1) ){
43883- struct flock lock;
43884- lock.l_whence = SEEK_SET;
43885- lock.l_start = UNIX_SHM_DMS;
43886- lock.l_len = 1;
43887- lock.l_type = F_WRLCK;
43888- osFcntl(pShmNode->hShm, F_GETLK, &lock);
43889- if( lock.l_type==F_UNLCK ){
43890- rc = 0;
43891- }
43892- }
43893- unixLeaveMutex();
43894- return rc;
43886+ #if SQLITE_ATOMIC_INTRINSICS
43887+ assert( AtomicLoad(&pShmNode->nRef)==1 );
43888+ #endif
43889+ memset(&lock, 0, sizeof(lock));
43890+ lock.l_whence = SEEK_SET;
43891+ lock.l_start = UNIX_SHM_DMS;
43892+ lock.l_len = 1;
43893+ lock.l_type = F_WRLCK;
43894+ osFcntl(pShmNode->hShm, F_GETLK, &lock);
43895+ return (lock.l_type!=F_UNLCK);
4389543896}
4389643897
4389743898/*
@@ -115316,9 +115317,22 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
115316115317 pParse->nMem += nReg;
115317115318 if( pExpr->op==TK_SELECT ){
115318115319 dest.eDest = SRT_Mem;
115319- dest.iSdst = dest.iSDParm;
115320+ if( (pSel->selFlags&SF_Distinct) && pSel->pLimit && pSel->pLimit->pRight ){
115321+ /* If there is both a DISTINCT and an OFFSET clause, then allocate
115322+ ** a separate dest.iSdst array for sqlite3Select() and other
115323+ ** routines to populate. In this case results will be copied over
115324+ ** into the dest.iSDParm array only after OFFSET processing. This
115325+ ** ensures that in the case where OFFSET excludes all rows, the
115326+ ** dest.iSDParm array is not left populated with the contents of the
115327+ ** last row visited - it should be all NULLs if all rows were
115328+ ** excluded by OFFSET. */
115329+ dest.iSdst = pParse->nMem+1;
115330+ pParse->nMem += nReg;
115331+ }else{
115332+ dest.iSdst = dest.iSDParm;
115333+ }
115320115334 dest.nSdst = nReg;
115321- sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1 );
115335+ sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, pParse->nMem );
115322115336 VdbeComment((v, "Init subquery result"));
115323115337 }else{
115324115338 dest.eDest = SRT_Exists;
@@ -148186,9 +148200,14 @@ static void selectInnerLoop(
148186148200 assert( nResultCol<=pDest->nSdst );
148187148201 pushOntoSorter(
148188148202 pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg);
148203+ pDest->iSDParm = regResult;
148189148204 }else{
148190148205 assert( nResultCol==pDest->nSdst );
148191- assert( regResult==iParm );
148206+ if( regResult!=iParm ){
148207+ /* This occurs in cases where the SELECT had both a DISTINCT and
148208+ ** an OFFSET clause. */
148209+ sqlite3VdbeAddOp3(v, OP_Copy, regResult, iParm, nResultCol-1);
148210+ }
148192148211 /* The LIMIT clause will jump out of the loop for us */
148193148212 }
148194148213 break;
@@ -154203,12 +154222,24 @@ static SQLITE_NOINLINE void existsToJoin(
154203154222 && (pSub->selFlags & SF_Aggregate)==0
154204154223 && !pSub->pSrc->a[0].fg.isSubquery
154205154224 && pSub->pLimit==0
154225+ && pSub->pPrior==0
154206154226 ){
154227+ /* Before combining the sub-select with the parent, renumber the
154228+ ** cursor used by the subselect. This is because the EXISTS expression
154229+ ** might be a copy of another EXISTS expression from somewhere
154230+ ** else in the tree, and in this case it is important that it use
154231+ ** a unique cursor number. */
154232+ sqlite3 *db = pParse->db;
154233+ int *aCsrMap = sqlite3DbMallocZero(db, (pParse->nTab+2)*sizeof(int));
154234+ if( aCsrMap==0 ) return;
154235+ aCsrMap[0] = (pParse->nTab+1);
154236+ renumberCursors(pParse, pSub, -1, aCsrMap);
154237+ sqlite3DbFree(db, aCsrMap);
154238+
154207154239 memset(pWhere, 0, sizeof(*pWhere));
154208154240 pWhere->op = TK_INTEGER;
154209154241 pWhere->u.iValue = 1;
154210154242 ExprSetProperty(pWhere, EP_IntValue);
154211-
154212154243 assert( p->pWhere!=0 );
154213154244 pSub->pSrc->a[0].fg.fromExists = 1;
154214154245 pSub->pSrc->a[0].fg.jointype |= JT_CROSS;
@@ -174001,6 +174032,9 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
174001174032 sqlite3 *db = pParse->db;
174002174033 int iEnd = sqlite3VdbeCurrentAddr(v);
174003174034 int nRJ = 0;
174035+ #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
174036+ int addrSeek = 0;
174037+ #endif
174004174038
174005174039 /* Generate loop termination code.
174006174040 */
@@ -174013,7 +174047,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
174013174047 ** the RIGHT JOIN table */
174014174048 WhereRightJoin *pRJ = pLevel->pRJ;
174015174049 sqlite3VdbeResolveLabel(v, pLevel->addrCont);
174016- pLevel->addrCont = 0;
174050+ /* Replace addrCont with a new label that will never be used, just so
174051+ ** the subsequent call to resolve pLevel->addrCont will have something
174052+ ** to resolve. */
174053+ pLevel->addrCont = sqlite3VdbeMakeLabel(pParse);
174017174054 pRJ->endSubrtn = sqlite3VdbeCurrentAddr(v);
174018174055 sqlite3VdbeAddOp3(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn, 1);
174019174056 VdbeCoverage(v);
@@ -174022,7 +174059,6 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
174022174059 pLoop = pLevel->pWLoop;
174023174060 if( pLevel->op!=OP_Noop ){
174024174061#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
174025- int addrSeek = 0;
174026174062 Index *pIdx;
174027174063 int n;
174028174064 if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED
@@ -174045,25 +174081,26 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
174045174081 sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
174046174082 }
174047174083#endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
174048- if( pTabList->a[pLevel->iFrom].fg.fromExists && i==pWInfo->nLevel-1 ){
174049- /* If the EXISTS-to-JOIN optimization was applied, then the EXISTS
174050- ** loop(s) will be the inner-most loops of the join. There might be
174051- ** multiple EXISTS loops, but they will all be nested, and the join
174052- ** order will not have been changed by the query planner. If the
174053- ** inner-most EXISTS loop sees a single successful row, it should
174054- ** break out of *all* EXISTS loops. But only the inner-most of the
174055- ** nested EXISTS loops should do this breakout. */
174056- int nOuter = 0; /* Nr of outer EXISTS that this one is nested within */
174057- while( nOuter<i ){
174058- if( !pTabList->a[pLevel[-nOuter-1].iFrom].fg.fromExists ) break;
174059- nOuter++;
174060- }
174061- testcase( nOuter>0 );
174062- sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel[-nOuter].addrBrk);
174063- VdbeComment((v, "EXISTS break"));
174064- }
174065- /* The common case: Advance to the next row */
174066- if( pLevel->addrCont ) sqlite3VdbeResolveLabel(v, pLevel->addrCont);
174084+ }
174085+ if( pTabList->a[pLevel->iFrom].fg.fromExists && i==pWInfo->nLevel-1 ){
174086+ /* If the EXISTS-to-JOIN optimization was applied, then the EXISTS
174087+ ** loop(s) will be the inner-most loops of the join. There might be
174088+ ** multiple EXISTS loops, but they will all be nested, and the join
174089+ ** order will not have been changed by the query planner. If the
174090+ ** inner-most EXISTS loop sees a single successful row, it should
174091+ ** break out of *all* EXISTS loops. But only the inner-most of the
174092+ ** nested EXISTS loops should do this breakout. */
174093+ int nOuter = 0; /* Nr of outer EXISTS that this one is nested within */
174094+ while( nOuter<i ){
174095+ if( !pTabList->a[pLevel[-nOuter-1].iFrom].fg.fromExists ) break;
174096+ nOuter++;
174097+ }
174098+ testcase( nOuter>0 );
174099+ sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel[-nOuter].addrBrk);
174100+ VdbeComment((v, "EXISTS break"));
174101+ }
174102+ sqlite3VdbeResolveLabel(v, pLevel->addrCont);
174103+ if( pLevel->op!=OP_Noop ){
174067174104 sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
174068174105 sqlite3VdbeChangeP5(v, pLevel->p5);
174069174106 VdbeCoverage(v);
@@ -174076,10 +174113,11 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
174076174113 VdbeCoverage(v);
174077174114 }
174078174115#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
174079- if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek);
174116+ if( addrSeek ){
174117+ sqlite3VdbeJumpHere(v, addrSeek);
174118+ addrSeek = 0;
174119+ }
174080174120#endif
174081- }else if( pLevel->addrCont ){
174082- sqlite3VdbeResolveLabel(v, pLevel->addrCont);
174083174121 }
174084174122 if( (pLoop->wsFlags & WHERE_IN_ABLE)!=0 && pLevel->u.in.nIn>0 ){
174085174123 struct InLoop *pIn;
@@ -219453,7 +219491,7 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
219453219491 if( node.zData==0 ) return;
219454219492 nData = sqlite3_value_bytes(apArg[1]);
219455219493 if( nData<4 ) return;
219456- if( nData<NCELL(&node)*tree.nBytesPerCell ) return;
219494+ if( nData<4+ NCELL(&node)*tree.nBytesPerCell ) return;
219457219495
219458219496 pOut = sqlite3_str_new(0);
219459219497 for(ii=0; ii<NCELL(&node); ii++){
@@ -238534,7 +238572,13 @@ typedef sqlite3_uint64 u64;
238534238572# define FLEXARRAY 1
238535238573#endif
238536238574
238537- #endif
238575+ #endif /* SQLITE_AMALGAMATION */
238576+
238577+ /*
238578+ ** Constants for the largest and smallest possible 32-bit signed integers.
238579+ */
238580+ # define LARGEST_INT32 ((int)(0x7fffffff))
238581+ # define SMALLEST_INT32 ((int)((-1) - LARGEST_INT32))
238538238582
238539238583/* Truncate very long tokens to this many bytes. Hard limit is
238540238584** (65536-1-1-4-9)==65521 bytes. The limiting factor is the 16-bit offset
@@ -253097,7 +253141,7 @@ static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){
253097253141 fts5StructureRelease(pStruct);
253098253142 pStruct = pNew;
253099253143 nMin = 1;
253100- nMerge = nMerge*-1;
253144+ nMerge = ( nMerge==SMALLEST_INT32 ? LARGEST_INT32 : (nMerge *-1)) ;
253101253145 }
253102253146 if( pStruct && pStruct->nLevel ){
253103253147 if( fts5IndexMerge(p, &pStruct, nMerge, nMin) ){
@@ -260304,7 +260348,7 @@ static void fts5SourceIdFunc(
260304260348){
260305260349 assert( nArg==0 );
260306260350 UNUSED_PARAM2(nArg, apUnused);
260307- sqlite3_result_text(pCtx, "fts5: 2025-11-28 17:28:25 281fc0e9afc38674b9b0991943b9e9d1e64c6cbdb133d35f6f5c87ff6af38a88 ", -1, SQLITE_TRANSIENT);
260351+ sqlite3_result_text(pCtx, "fts5: 2026-01-09 17:27:48 b270f8339eb13b504d0b2ba154ebca966b7dde08e40c3ed7d559749818cb2075 ", -1, SQLITE_TRANSIENT);
260308260352}
260309260353
260310260354/*
0 commit comments