| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent ff1fcab commit 6a3c614
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,6 +1,6 @@ | |||
| 1 | 1 | /****************************************************************************** | |
| 2 | 2 | ** 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 | ||
| 4 | 4 | ** single large file, the entire code can be compiled as a single translation | |
| 5 | 5 | ** unit. This allows many compilers to do optimizations that would not be | |
| 6 | 6 | ** possible if the files were compiled separately. Performance improvements | |
@@ -18,7 +18,7 @@ | |||
| 18 | 18 | ** separate file. This file contains only code for the core SQLite library. | |
| 19 | 19 | ** | |
| 20 | 20 | ** The content in this amalgamation comes from Fossil check-in | |
| 21 | - ** 281fc0e9afc38674b9b0991943b9e9d1e64c with changes in files: | ||
| 21 | + ** b270f8339eb13b504d0b2ba154ebca966b7d with changes in files: | ||
| 22 | 22 | ** | |
| 23 | 23 | ** | |
| 24 | 24 | */ | |
@@ -467,12 +467,12 @@ extern "C" { | |||
| 467 | 467 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], | |
| 468 | 468 | ** [sqlite_version()] and [sqlite_source_id()]. | |
| 469 | 469 | */ | |
| 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" | ||
| 473 | 473 | #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" | ||
| 476 | 476 | ||
| 477 | 477 | /* | |
| 478 | 478 | ** CAPI3REF: Run-Time Library Version Numbers | |
@@ -41228,12 +41228,18 @@ static int unixLock(sqlite3_file *id, int eFileLock){ | |||
| 41228 | 41228 | pInode->nLock++; | |
| 41229 | 41229 | pInode->nShared = 1; | |
| 41230 | 41230 | } | |
| 41231 | - }else if( (eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1) | ||
| 41232 | - || unixIsSharingShmNode(pFile) | ||
| 41233 | - ){ | ||
| 41231 | + }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){ | ||
| 41234 | 41232 | /* We are trying for an exclusive lock but another thread in this | |
| 41235 | 41233 | ** same process is still holding a shared lock. */ | |
| 41236 | 41234 | 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; | ||
| 41237 | 41243 | }else{ | |
| 41238 | 41244 | /* The request was for a RESERVED or EXCLUSIVE lock. It is | |
| 41239 | 41245 | ** assumed that there is a SHARED or greater lock on the file | |
@@ -43872,26 +43878,21 @@ static int unixFcntlExternalReader(unixFile *pFile, int *piOut){ | |||
| 43872 | 43878 | ** still not a disaster. | |
| 43873 | 43879 | */ | |
| 43874 | 43880 | static int unixIsSharingShmNode(unixFile *pFile){ | |
| 43875 | - int rc; | ||
| 43876 | 43881 | unixShmNode *pShmNode; | |
| 43882 | + struct flock lock; | ||
| 43877 | 43883 | if( pFile->pShm==0 ) return 0; | |
| 43878 | 43884 | if( pFile->ctrlFlags & UNIXFILE_EXCL ) return 0; | |
| 43879 | 43885 | 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); | ||
| 43895 | 43896 | } | |
| 43896 | 43897 | ||
| 43897 | 43898 | /* | |
@@ -115316,9 +115317,22 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ | |||
| 115316 | 115317 | pParse->nMem += nReg; | |
| 115317 | 115318 | if( pExpr->op==TK_SELECT ){ | |
| 115318 | 115319 | 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 | + } | ||
| 115320 | 115334 | 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); | ||
| 115322 | 115336 | VdbeComment((v, "Init subquery result")); | |
| 115323 | 115337 | }else{ | |
| 115324 | 115338 | dest.eDest = SRT_Exists; | |
@@ -148186,9 +148200,14 @@ static void selectInnerLoop( | |||
| 148186 | 148200 | assert( nResultCol<=pDest->nSdst ); | |
| 148187 | 148201 | pushOntoSorter( | |
| 148188 | 148202 | pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg); | |
| 148203 | + pDest->iSDParm = regResult; | ||
| 148189 | 148204 | }else{ | |
| 148190 | 148205 | 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 | + } | ||
| 148192 | 148211 | /* The LIMIT clause will jump out of the loop for us */ | |
| 148193 | 148212 | } | |
| 148194 | 148213 | break; | |
@@ -154203,12 +154222,24 @@ static SQLITE_NOINLINE void existsToJoin( | |||
| 154203 | 154222 | && (pSub->selFlags & SF_Aggregate)==0 | |
| 154204 | 154223 | && !pSub->pSrc->a[0].fg.isSubquery | |
| 154205 | 154224 | && pSub->pLimit==0 | |
| 154225 | + && pSub->pPrior==0 | ||
| 154206 | 154226 | ){ | |
| 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 | + | ||
| 154207 | 154239 | memset(pWhere, 0, sizeof(*pWhere)); | |
| 154208 | 154240 | pWhere->op = TK_INTEGER; | |
| 154209 | 154241 | pWhere->u.iValue = 1; | |
| 154210 | 154242 | ExprSetProperty(pWhere, EP_IntValue); | |
| 154211 | - | ||
| 154212 | 154243 | assert( p->pWhere!=0 ); | |
| 154213 | 154244 | pSub->pSrc->a[0].fg.fromExists = 1; | |
| 154214 | 154245 | pSub->pSrc->a[0].fg.jointype |= JT_CROSS; | |
@@ -174001,6 +174032,9 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ | |||
| 174001 | 174032 | sqlite3 *db = pParse->db; | |
| 174002 | 174033 | int iEnd = sqlite3VdbeCurrentAddr(v); | |
| 174003 | 174034 | int nRJ = 0; | |
| 174035 | + #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT | ||
| 174036 | + int addrSeek = 0; | ||
| 174037 | + #endif | ||
| 174004 | 174038 | ||
| 174005 | 174039 | /* Generate loop termination code. | |
| 174006 | 174040 | */ | |
@@ -174013,7 +174047,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ | |||
| 174013 | 174047 | ** the RIGHT JOIN table */ | |
| 174014 | 174048 | WhereRightJoin *pRJ = pLevel->pRJ; | |
| 174015 | 174049 | 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); | ||
| 174017 | 174054 | pRJ->endSubrtn = sqlite3VdbeCurrentAddr(v); | |
| 174018 | 174055 | sqlite3VdbeAddOp3(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn, 1); | |
| 174019 | 174056 | VdbeCoverage(v); | |
@@ -174022,7 +174059,6 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ | |||
| 174022 | 174059 | pLoop = pLevel->pWLoop; | |
| 174023 | 174060 | if( pLevel->op!=OP_Noop ){ | |
| 174024 | 174061 | #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT | |
| 174025 | - int addrSeek = 0; | ||
| 174026 | 174062 | Index *pIdx; | |
| 174027 | 174063 | int n; | |
| 174028 | 174064 | if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED | |
@@ -174045,25 +174081,26 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ | |||
| 174045 | 174081 | sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2); | |
| 174046 | 174082 | } | |
| 174047 | 174083 | #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 ){ | ||
| 174067 | 174104 | sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3); | |
| 174068 | 174105 | sqlite3VdbeChangeP5(v, pLevel->p5); | |
| 174069 | 174106 | VdbeCoverage(v); | |
@@ -174076,10 +174113,11 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ | |||
| 174076 | 174113 | VdbeCoverage(v); | |
| 174077 | 174114 | } | |
| 174078 | 174115 | #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT | |
| 174079 | - if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek); | ||
| 174116 | + if( addrSeek ){ | ||
| 174117 | + sqlite3VdbeJumpHere(v, addrSeek); | ||
| 174118 | + addrSeek = 0; | ||
| 174119 | + } | ||
| 174080 | 174120 | #endif | |
| 174081 | - }else if( pLevel->addrCont ){ | ||
| 174082 | - sqlite3VdbeResolveLabel(v, pLevel->addrCont); | ||
| 174083 | 174121 | } | |
| 174084 | 174122 | if( (pLoop->wsFlags & WHERE_IN_ABLE)!=0 && pLevel->u.in.nIn>0 ){ | |
| 174085 | 174123 | struct InLoop *pIn; | |
@@ -219453,7 +219491,7 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ | |||
| 219453 | 219491 | if( node.zData==0 ) return; | |
| 219454 | 219492 | nData = sqlite3_value_bytes(apArg[1]); | |
| 219455 | 219493 | if( nData<4 ) return; | |
| 219456 | - if( nData<NCELL(&node)*tree.nBytesPerCell ) return; | ||
| 219494 | + if( nData<4+NCELL(&node)*tree.nBytesPerCell ) return; | ||
| 219457 | 219495 | ||
| 219458 | 219496 | pOut = sqlite3_str_new(0); | |
| 219459 | 219497 | for(ii=0; ii<NCELL(&node); ii++){ | |
@@ -238534,7 +238572,13 @@ typedef sqlite3_uint64 u64; | |||
| 238534 | 238572 | # define FLEXARRAY 1 | |
| 238535 | 238573 | #endif | |
| 238536 | 238574 | ||
| 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)) | ||
| 238538 | 238582 | ||
| 238539 | 238583 | /* Truncate very long tokens to this many bytes. Hard limit is | |
| 238540 | 238584 | ** (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){ | |||
| 253097 | 253141 | fts5StructureRelease(pStruct); | |
| 253098 | 253142 | pStruct = pNew; | |
| 253099 | 253143 | nMin = 1; | |
| 253100 | - nMerge = nMerge*-1; | ||
| 253144 | + nMerge = (nMerge==SMALLEST_INT32 ? LARGEST_INT32 : (nMerge*-1)); | ||
| 253101 | 253145 | } | |
| 253102 | 253146 | if( pStruct && pStruct->nLevel ){ | |
| 253103 | 253147 | if( fts5IndexMerge(p, &pStruct, nMerge, nMin) ){ | |
@@ -260304,7 +260348,7 @@ static void fts5SourceIdFunc( | |||
| 260304 | 260348 | ){ | |
| 260305 | 260349 | assert( nArg==0 ); | |
| 260306 | 260350 | 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); | ||
| 260308 | 260352 | } | |
| 260309 | 260353 | ||
| 260310 | 260354 | /* | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -146,12 +146,12 @@ extern "C" { | |||
| 146 | 146 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], | |
| 147 | 147 | ** [sqlite_version()] and [sqlite_source_id()]. | |
| 148 | 148 | */ | |
| 149 | - #define SQLITE_VERSION "3.51.1" | ||
| 150 | - #define SQLITE_VERSION_NUMBER 3051001 | ||
| 151 | - #define SQLITE_SOURCE_ID "2025-11-28 17:28:25 281fc0e9afc38674b9b0991943b9e9d1e64c6cbdb133d35f6f5c87ff6af38a88" | ||
| 149 | + #define SQLITE_VERSION "3.51.2" | ||
| 150 | + #define SQLITE_VERSION_NUMBER 3051002 | ||
| 151 | + #define SQLITE_SOURCE_ID "2026-01-09 17:27:48 b270f8339eb13b504d0b2ba154ebca966b7dde08e40c3ed7d559749818cb2075" | ||
| 152 | 152 | #define SQLITE_SCM_BRANCH "branch-3.51" | |
| 153 | - #define SQLITE_SCM_TAGS "release version-3.51.1" | ||
| 154 | - #define SQLITE_SCM_DATETIME "2025-11-28T17:28:25.933Z" | ||
| 153 | + #define SQLITE_SCM_TAGS "release version-3.51.2" | ||
| 154 | + #define SQLITE_SCM_DATETIME "2026-01-09T17:27:48.405Z" | ||
| 155 | 155 | ||
| 156 | 156 | /* | |
| 157 | 157 | ** CAPI3REF: Run-Time Library Version Numbers | |
| Back | FazBrowse Home | New Git URL |
0 commit comments