Compare commits

..

31 Commits

Author SHA1 Message Date
drh 988e6236d9 Prototype implementation of "PRAGMA reset_database". This pragma differs from
SQLITE_DBCONFIG_RESET_DATABASE in that the pragma only works if the database
is reasonably well-formed, whereas the dbconfig works regardless.

FossilOrigin-Name: cf0999d4f8fd120c4796240600cd42fcc8baa056efad432d0dae7da372023787
2022-09-28 17:10:23 +00:00
drh 5d48e0cdc5 Provide the SQLITE_MAX_ALLOCATION_SIZE compile-time option for limiting the
maximum memory allocation size.

FossilOrigin-Name: 584de6a996c78b8e41bdfcd05a8e2a3844664c6b4efedb5883c8b8af388462b5
2022-09-27 16:35:06 +00:00
drh 6319a8003c Make the legacy FTS3 code more robust against integer overflow during
memory allocation.

FossilOrigin-Name: 5517bc50988b5339c2fd071b29de1b5ca03037b0b635c3b112cf7108fab54d5f
2022-09-27 01:53:05 +00:00
drh 80cf891792 Enhance defensive mode so that it disallows CREATE TRIGGER statements if the
statements within the trigger attempt to write on a shadow table.

FossilOrigin-Name: 3283bbd12a60f472ed03cb7c6209a605a3bf9f3d9083371e17840b56e8b3f559
2022-09-27 00:56:45 +00:00
drh f333370e1f Reduced and improved comments on the constraintCompatibleWithOuterJoin()
function.

FossilOrigin-Name: 38aaf26e082bd95df6b64df43e1772fe6e20c4eb71307dcd97559cac7f11f8f1
2022-09-21 18:21:31 +00:00
drh 2897b88f9e The RIGHT JOIN logic added to version 3.39.0 added a new restriction on the
query flattener which resulted in a performance regression for some queries,
as documented by [forum:/forumpost/96b9e5709cf47cda|forum post 96b9e5709cf47cda].
This change removes that restriction (thus restoring performance) and fixes the
problem that RIGHT JOIN was having in a different way.

FossilOrigin-Name: 501609eddf2a46d51e8cd56477a22d4df142a166e78fe4322c0db11d1eed6687
2022-09-21 09:54:41 +00:00
drh faaacd3fbb Break out the decision of whether or not a constraint term is usable by
an outer join into a subroutine: constraintCompatibleWithOuterJoin().

FossilOrigin-Name: c7fbc9b0453050e2746af27e3a11e0c3701bef8c56da8e19173242c6ea3aff8b
2022-09-21 00:16:59 +00:00
drh 0f51aa3972 Do not allow EP_InnerON terms to be used on a outer join.
FossilOrigin-Name: f47aa745690c018800243bf76930b2499ff4537411c4e27b4b16ba3854cc2bf8
2022-09-20 22:19:13 +00:00
drh 0cc6f78bcf Add new test cases that (current) get an incorrect answer.
FossilOrigin-Name: fe5c37736444e397ace387b761ec2491229785d7a437f3f60232aedf9d1f00ec
2022-09-20 21:07:52 +00:00
drh 4c5c941b6e New test cases for query flattening when there are ON clauses and outer joins.
FossilOrigin-Name: db55387b1972bc7bc6855bd3497af744a111e7d28d09893cd985fbb01be41bcc
2022-09-20 19:45:04 +00:00
drh 8b9a3d1fc8 Modify the OP_IfNotOpen opcode so that the jump is taken if the cursor is open
but was previously set to a NULL row using OP_NullRow.

FossilOrigin-Name: 1292d68caa7086610ddda343f3852e63de8da1eb66536ee4716b6529f5a31bc6
2022-09-20 19:22:17 +00:00
drh 5a0771a1f4 Remove code that has been previously commented out.
FossilOrigin-Name: 852b385a5de622aa32026824210d4bd23db52a4a8a697b83d22d6000edeba487
2022-09-20 18:18:00 +00:00
drh a5f8c42c98 Merge the fuzzcheck fix from trunk into the flattener improvement branch.
FossilOrigin-Name: 930a8c1561d0d5dc70dc5378edac77f79ac59ab6569b561de3dfb02f160c38c5
2022-09-20 17:43:40 +00:00
drh 703c208d30 Update the fuzz invariant checker to conform to the latest changes in
dbsqlfuzz.

FossilOrigin-Name: 8d8c124349d2a25200ace9a60d76751594b722468ad0c39d927a5d2c6e2464e0
2022-09-20 17:21:54 +00:00
drh 40c9becc81 Is the query flattener restriction 29 (do not allow both EP_InnerON and
EP_OuterON constraints on the same FROM clause term) really necessary?   This
branch explores what happens if we omit that restriction.  This is an effort
to address the performance regression reported by
[forum:/forumpost/96b9e5709cf47cda|forum post 96b9e5709cf47cda] that is caused
by flattener restriction 29.

FossilOrigin-Name: 19270577ad1d08c9e6e5f0600396b8a1ccda9df1e67a0df845aee6b60437f379
2022-09-20 16:57:49 +00:00
drh b22b493338 Clarify comments that describe query flattener restrictions associated with
outer joins.  No code changes.

FossilOrigin-Name: 2647d73bb1876d01851f52cb3fd6af08a962ab336b6d51c160d27b1baf94f75f
2022-09-19 19:25:15 +00:00
drh 316cd40122 Fix a minor comment typo. No changes to code or documentation.
FossilOrigin-Name: 8032db4ade66f70a102abb9d3a49e20620e204c45ad7a954a49d20403985bf07
2022-09-19 17:41:59 +00:00
drh bcdb4cc71b Remove a NEVER macro in defragmentPage() that dbsqlfuzz discovered can be
true.  crash-32d9312f145cdce41613573f6431d9a3e439e3d7

FossilOrigin-Name: 90403759e1cf30f7c11fa8170d6df59a0dd138e1de59d2b60bec7ba15d74f67c
2022-09-18 17:59:28 +00:00
drh 3e4e697d1c New run-time options to the speed-check.sh script.
FossilOrigin-Name: ff46bc9d2a844dde9dafa157114f4d9ee157205ca5c08ed9ee32f018de310e62
2022-09-12 16:07:24 +00:00
mistachkin bdb6368d72 Fix harmless compiler warning seen with MSVC.
FossilOrigin-Name: 73c4c68d3b4c16caf8281dabddd7365d24691e5ee2da89b1783eca66bfbd9280
2022-09-09 17:50:29 +00:00
drh b53e0992b2 Enhance an assert() to impose for tighter constraints on the operation of pcache.
FossilOrigin-Name: 42105eb43a916a7cd839fa6c582eaffaef17f50b23c3e05142400c379feb73c7
2022-09-07 20:11:22 +00:00
drh 8c983ddb67 An improved technique for ensuring that the Rekey() operation does not
overwrite an existing page number.  This approach does not change the
semantics of the underlying pluggable pcache and it is easier to prove
correct.  This replaces the changes at
[aadd38f99a3e5abc] and [81cff9f1955874aa].

FossilOrigin-Name: 7dbddde79e3ca1b81e00288616fc27434698ce6dcb47714728fce8602ae91f45
2022-09-07 19:28:18 +00:00
drh 2e440a0801 Add the tool/omittest-msvc.tcl script that will try to build using MSVC
using various compile-time options, to ensure that the compile-time options
all build without errors.

FossilOrigin-Name: 6b00ecb59fd303f7985902c35a46db9e729201d4beaedea46596b728d9e4b1c8
2022-09-05 22:54:36 +00:00
drh 0c4517a61a Get the tool/omittest-msvc.tcl script working.
FossilOrigin-Name: 82b89f8a074858a81d841dfc26436e8d39ce4907b8f989eba4d848db16758303
2022-09-05 22:53:24 +00:00
drh 4c8404e555 Add a prototype for a script, similar to tool/omittest.tcl, that is designed
to test builds using MSVC to ensure they work with various OMIT options.

FossilOrigin-Name: b1e37a0bd31fa9f8e58c2859a80c23a682b4702eefab2c55b243f1e21d475d6c
2022-09-05 20:42:01 +00:00
drh 6e440ab3de Fix the windows build so that it works with -DSQLITE_OMIT_AUTOINIT.
FossilOrigin-Name: f74a5ea8c986dc33d3afcda169c38abbe55728c56716cf9991a5e2ef7fc4917a
2022-09-05 18:17:03 +00:00
dan ad617b4d6d Ensure the Pager.journalOff variable is zeroed if an error occurs while writing the initial header to the journal file.
FossilOrigin-Name: da7af290960ab8a04a1f55cdc5eeac36b47fa194edf67f0a05daa4b7f2a4071c
2022-09-02 21:19:24 +00:00
drh 173b418e60 Fix an assert() associated with the dbsqlfuzz error at [8372468bb5d8922c].
FossilOrigin-Name: 54251f81ebc43839cc97f91d2df4c320c1b96b5690cc11ce45b60c087c9becd6
2022-09-02 17:25:25 +00:00
drh 5fc3a8a32f If sqlite3PcacheMove() really performs a swap, then be sure to renumber the
second page.

FossilOrigin-Name: 81cff9f1955874aade55daa94263f58f06d966bd51ad558755f92777069a7347
2022-09-02 15:09:55 +00:00
drh 4e9bf5ace3 Enhance the pcache1 implementation so that during an xRekey operation if
another page already exists at the destination, that other page gets moved
to the source key.

FossilOrigin-Name: aadd38f99a3e5abcf9bef49f4367752f163cc79500a28f812bb71969d7de419c
2022-09-02 14:29:54 +00:00
drh e04c9f4b33 Mutex protect access to the sqlite3_test_directory and sqlite3_data_directory
global variables.  See
[forum:/forumpost/719a11e1314d1c70|forum thread 719a11e1314d1c70].

FossilOrigin-Name: 8e6ad3a3e942a326cf16432e16d6596c7206c05b6f45cd0ff3a9b836bcfc9deb
2022-09-02 11:45:26 +00:00
29 changed files with 502 additions and 262 deletions
+2 -2
View File
@@ -2888,7 +2888,7 @@ static int fts3TermSelectMerge(
**
** Similar padding is added in the fts3DoclistOrMerge() function.
*/
pTS->aaOutput[0] = sqlite3_malloc(nDoclist + FTS3_VARINT_MAX + 1);
pTS->aaOutput[0] = sqlite3_malloc64((i64)nDoclist + FTS3_VARINT_MAX + 1);
pTS->anOutput[0] = nDoclist;
if( pTS->aaOutput[0] ){
memcpy(pTS->aaOutput[0], aDoclist, nDoclist);
@@ -4745,7 +4745,7 @@ static int fts3EvalIncrPhraseNext(
if( bEof==0 ){
int nList = 0;
int nByte = a[p->nToken-1].nList;
char *aDoclist = sqlite3_malloc(nByte+FTS3_BUFFER_PADDING);
char *aDoclist = sqlite3_malloc64((i64)nByte+FTS3_BUFFER_PADDING);
if( !aDoclist ) return SQLITE_NOMEM;
memcpy(aDoclist, a[p->nToken-1].pList, nByte+1);
memset(&aDoclist[nByte], 0, FTS3_BUFFER_PADDING);
+1 -1
View File
@@ -558,7 +558,7 @@ struct Fts3MultiSegReader {
int nAdvance; /* How many seg-readers to advance */
Fts3SegFilter *pFilter; /* Pointer to filter object */
char *aBuffer; /* Buffer to merge doclists in */
int nBuffer; /* Allocated size of aBuffer[] in bytes */
i64 nBuffer; /* Allocated size of aBuffer[] in bytes */
int iColFilter; /* If >=0, filter for this column */
int bRestart;
+1 -1
View File
@@ -621,7 +621,7 @@ static int porterNext(
if( n>c->nAllocated ){
char *pNew;
c->nAllocated = n+20;
pNew = sqlite3_realloc(c->zToken, c->nAllocated);
pNew = sqlite3_realloc64(c->zToken, c->nAllocated);
if( !pNew ) return SQLITE_NOMEM;
c->zToken = pNew;
}
+1 -1
View File
@@ -185,7 +185,7 @@ static int simpleNext(
if( n>c->nTokenAllocated ){
char *pNew;
c->nTokenAllocated = n+20;
pNew = sqlite3_realloc(c->pToken, c->nTokenAllocated);
pNew = sqlite3_realloc64(c->pToken, c->nTokenAllocated);
if( !pNew ) return SQLITE_NOMEM;
c->pToken = pNew;
}
+32 -30
View File
@@ -649,7 +649,7 @@ static int fts3PendingListAppendVarint(
/* Allocate or grow the PendingList as required. */
if( !p ){
p = sqlite3_malloc(sizeof(*p) + 100);
p = sqlite3_malloc64(sizeof(*p) + 100);
if( !p ){
return SQLITE_NOMEM;
}
@@ -658,14 +658,14 @@ static int fts3PendingListAppendVarint(
p->nData = 0;
}
else if( p->nData+FTS3_VARINT_MAX+1>p->nSpace ){
int nNew = p->nSpace * 2;
p = sqlite3_realloc(p, sizeof(*p) + nNew);
i64 nNew = p->nSpace * 2;
p = sqlite3_realloc64(p, sizeof(*p) + nNew);
if( !p ){
sqlite3_free(*pp);
*pp = 0;
return SQLITE_NOMEM;
}
p->nSpace = nNew;
p->nSpace = (int)nNew;
p->aData = (char *)&p[1];
}
@@ -1222,7 +1222,7 @@ int sqlite3Fts3ReadBlock(
int nByte = sqlite3_blob_bytes(p->pSegments);
*pnBlob = nByte;
if( paBlob ){
char *aByte = sqlite3_malloc(nByte + FTS3_NODE_PADDING);
char *aByte = sqlite3_malloc64((i64)nByte + FTS3_NODE_PADDING);
if( !aByte ){
rc = SQLITE_NOMEM;
}else{
@@ -1339,7 +1339,7 @@ static int fts3SegReaderNext(
int nTerm = fts3HashKeysize(pElem);
if( (nTerm+1)>pReader->nTermAlloc ){
sqlite3_free(pReader->zTerm);
pReader->zTerm = (char*)sqlite3_malloc((nTerm+1)*2);
pReader->zTerm = (char*)sqlite3_malloc64(((i64)nTerm+1)*2);
if( !pReader->zTerm ) return SQLITE_NOMEM;
pReader->nTermAlloc = (nTerm+1)*2;
}
@@ -1347,7 +1347,7 @@ static int fts3SegReaderNext(
pReader->zTerm[nTerm] = '\0';
pReader->nTerm = nTerm;
aCopy = (char*)sqlite3_malloc(nCopy);
aCopy = (char*)sqlite3_malloc64(nCopy);
if( !aCopy ) return SQLITE_NOMEM;
memcpy(aCopy, pList->aData, nCopy);
pReader->nNode = pReader->nDoclist = nCopy;
@@ -1634,7 +1634,7 @@ int sqlite3Fts3SegReaderNew(
nExtra = nRoot + FTS3_NODE_PADDING;
}
pReader = (Fts3SegReader *)sqlite3_malloc(sizeof(Fts3SegReader) + nExtra);
pReader = (Fts3SegReader *)sqlite3_malloc64(sizeof(Fts3SegReader) + nExtra);
if( !pReader ){
return SQLITE_NOMEM;
}
@@ -1726,7 +1726,7 @@ int sqlite3Fts3SegReaderPending(
if( nElem==nAlloc ){
Fts3HashElem **aElem2;
nAlloc += 16;
aElem2 = (Fts3HashElem **)sqlite3_realloc(
aElem2 = (Fts3HashElem **)sqlite3_realloc64(
aElem, nAlloc*sizeof(Fts3HashElem *)
);
if( !aElem2 ){
@@ -2060,7 +2060,7 @@ static int fts3NodeAddTerm(
** this is not expected to be a serious problem.
*/
assert( pTree->aData==(char *)&pTree[1] );
pTree->aData = (char *)sqlite3_malloc(nReq);
pTree->aData = (char *)sqlite3_malloc64(nReq);
if( !pTree->aData ){
return SQLITE_NOMEM;
}
@@ -2078,7 +2078,7 @@ static int fts3NodeAddTerm(
if( isCopyTerm ){
if( pTree->nMalloc<nTerm ){
char *zNew = sqlite3_realloc(pTree->zMalloc, nTerm*2);
char *zNew = sqlite3_realloc64(pTree->zMalloc, (i64)nTerm*2);
if( !zNew ){
return SQLITE_NOMEM;
}
@@ -2104,7 +2104,7 @@ static int fts3NodeAddTerm(
** now. Instead, the term is inserted into the parent of pTree. If pTree
** has no parent, one is created here.
*/
pNew = (SegmentNode *)sqlite3_malloc(sizeof(SegmentNode) + p->nNodeSize);
pNew = (SegmentNode *)sqlite3_malloc64(sizeof(SegmentNode) + p->nNodeSize);
if( !pNew ){
return SQLITE_NOMEM;
}
@@ -2242,7 +2242,7 @@ static int fts3SegWriterAdd(
){
int nPrefix; /* Size of term prefix in bytes */
int nSuffix; /* Size of term suffix in bytes */
int nReq; /* Number of bytes required on leaf page */
i64 nReq; /* Number of bytes required on leaf page */
int nData;
SegmentWriter *pWriter = *ppWriter;
@@ -2251,13 +2251,13 @@ static int fts3SegWriterAdd(
sqlite3_stmt *pStmt;
/* Allocate the SegmentWriter structure */
pWriter = (SegmentWriter *)sqlite3_malloc(sizeof(SegmentWriter));
pWriter = (SegmentWriter *)sqlite3_malloc64(sizeof(SegmentWriter));
if( !pWriter ) return SQLITE_NOMEM;
memset(pWriter, 0, sizeof(SegmentWriter));
*ppWriter = pWriter;
/* Allocate a buffer in which to accumulate data */
pWriter->aData = (char *)sqlite3_malloc(p->nNodeSize);
pWriter->aData = (char *)sqlite3_malloc64(p->nNodeSize);
if( !pWriter->aData ) return SQLITE_NOMEM;
pWriter->nSize = p->nNodeSize;
@@ -2332,7 +2332,7 @@ static int fts3SegWriterAdd(
** the buffer to make it large enough.
*/
if( nReq>pWriter->nSize ){
char *aNew = sqlite3_realloc(pWriter->aData, nReq);
char *aNew = sqlite3_realloc64(pWriter->aData, nReq);
if( !aNew ) return SQLITE_NOMEM;
pWriter->aData = aNew;
pWriter->nSize = nReq;
@@ -2357,7 +2357,7 @@ static int fts3SegWriterAdd(
*/
if( isCopyTerm ){
if( nTerm>pWriter->nMalloc ){
char *zNew = sqlite3_realloc(pWriter->zMalloc, nTerm*2);
char *zNew = sqlite3_realloc64(pWriter->zMalloc, (i64)nTerm*2);
if( !zNew ){
return SQLITE_NOMEM;
}
@@ -2665,12 +2665,12 @@ static void fts3ColumnFilter(
static int fts3MsrBufferData(
Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */
char *pList,
int nList
i64 nList
){
if( nList>pMsr->nBuffer ){
char *pNew;
pMsr->nBuffer = nList*2;
pNew = (char *)sqlite3_realloc(pMsr->aBuffer, pMsr->nBuffer);
pNew = (char *)sqlite3_realloc64(pMsr->aBuffer, pMsr->nBuffer);
if( !pNew ) return SQLITE_NOMEM;
pMsr->aBuffer = pNew;
}
@@ -2726,7 +2726,7 @@ int sqlite3Fts3MsrIncrNext(
fts3SegReaderSort(pMsr->apSegment, nMerge, j, xCmp);
if( nList>0 && fts3SegReaderIsPending(apSegment[0]) ){
rc = fts3MsrBufferData(pMsr, pList, nList+1);
rc = fts3MsrBufferData(pMsr, pList, (i64)nList+1);
if( rc!=SQLITE_OK ) return rc;
assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 );
pList = pMsr->aBuffer;
@@ -2863,11 +2863,11 @@ int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr){
return SQLITE_OK;
}
static int fts3GrowSegReaderBuffer(Fts3MultiSegReader *pCsr, int nReq){
static int fts3GrowSegReaderBuffer(Fts3MultiSegReader *pCsr, i64 nReq){
if( nReq>pCsr->nBuffer ){
char *aNew;
pCsr->nBuffer = nReq*2;
aNew = sqlite3_realloc(pCsr->aBuffer, pCsr->nBuffer);
aNew = sqlite3_realloc64(pCsr->aBuffer, pCsr->nBuffer);
if( !aNew ){
return SQLITE_NOMEM;
}
@@ -2958,7 +2958,8 @@ int sqlite3Fts3SegReaderStep(
){
pCsr->nDoclist = apSegment[0]->nDoclist;
if( fts3SegReaderIsPending(apSegment[0]) ){
rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, pCsr->nDoclist);
rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist,
(i64)pCsr->nDoclist);
pCsr->aDoclist = pCsr->aBuffer;
}else{
pCsr->aDoclist = apSegment[0]->aDoclist;
@@ -3011,7 +3012,8 @@ int sqlite3Fts3SegReaderStep(
nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0);
rc = fts3GrowSegReaderBuffer(pCsr, nByte+nDoclist+FTS3_NODE_PADDING);
rc = fts3GrowSegReaderBuffer(pCsr,
(i64)nByte+nDoclist+FTS3_NODE_PADDING);
if( rc ) return rc;
if( isFirst ){
@@ -3037,7 +3039,7 @@ int sqlite3Fts3SegReaderStep(
fts3SegReaderSort(apSegment, nMerge, j, xCmp);
}
if( nDoclist>0 ){
rc = fts3GrowSegReaderBuffer(pCsr, nDoclist+FTS3_NODE_PADDING);
rc = fts3GrowSegReaderBuffer(pCsr, (i64)nDoclist+FTS3_NODE_PADDING);
if( rc ) return rc;
memset(&pCsr->aBuffer[nDoclist], 0, FTS3_NODE_PADDING);
pCsr->aDoclist = pCsr->aBuffer;
@@ -3750,7 +3752,7 @@ struct NodeReader {
static void blobGrowBuffer(Blob *pBlob, int nMin, int *pRc){
if( *pRc==SQLITE_OK && nMin>pBlob->nAlloc ){
int nAlloc = nMin;
char *a = (char *)sqlite3_realloc(pBlob->a, nAlloc);
char *a = (char *)sqlite3_realloc64(pBlob->a, nAlloc);
if( a ){
pBlob->nAlloc = nAlloc;
pBlob->a = a;
@@ -4547,7 +4549,7 @@ static int fts3RepackSegdirLevel(
if( nIdx>=nAlloc ){
int *aNew;
nAlloc += 16;
aNew = sqlite3_realloc(aIdx, nAlloc*sizeof(int));
aNew = sqlite3_realloc64(aIdx, nAlloc*sizeof(int));
if( !aNew ){
rc = SQLITE_NOMEM;
break;
@@ -4921,7 +4923,7 @@ int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){
/* Allocate space for the cursor, filter and writer objects */
const int nAlloc = sizeof(*pCsr) + sizeof(*pFilter) + sizeof(*pWriter);
pWriter = (IncrmergeWriter *)sqlite3_malloc(nAlloc);
pWriter = (IncrmergeWriter *)sqlite3_malloc64(nAlloc);
if( !pWriter ) return SQLITE_NOMEM;
pFilter = (Fts3SegFilter *)&pWriter[1];
pCsr = (Fts3MultiSegReader *)&pFilter[1];
@@ -5557,7 +5559,7 @@ int sqlite3Fts3DeferredTokenList(
return SQLITE_OK;
}
pRet = (char *)sqlite3_malloc(p->pList->nData);
pRet = (char *)sqlite3_malloc64(p->pList->nData);
if( !pRet ) return SQLITE_NOMEM;
nSkip = sqlite3Fts3GetVarint(p->pList->aData, &dummy);
@@ -5577,7 +5579,7 @@ int sqlite3Fts3DeferToken(
int iCol /* Column that token must appear in (or -1) */
){
Fts3DeferredToken *pDeferred;
pDeferred = sqlite3_malloc(sizeof(*pDeferred));
pDeferred = sqlite3_malloc64(sizeof(*pDeferred));
if( !pDeferred ){
return SQLITE_NOMEM;
}
+35 -31
View File
@@ -1,5 +1,5 @@
C Improved\smutex\sprotection\sof\sthe\ssqlite3_temp_directory\sand\nsqlite3_data_directory\sglobal\svariables.
D 2022-09-02T11:12:16.831
C Prototype\simplementation\sof\s"PRAGMA\sreset_database".\s\sThis\spragma\sdiffers\sfrom\nSQLITE_DBCONFIG_RESET_DATABASE\sin\sthat\sthe\spragma\sonly\sworks\sif\sthe\sdatabase\nis\sreasonably\swell-formed,\swhereas\sthe\sdbconfig\sworks\sregardless.
D 2022-09-28T17:10:23.906
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -85,25 +85,25 @@ F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
F ext/fts3/fts3.c b20bd583991e740c1e14371896f3ab61d7b6c033740646366bbf6667191bc4e2
F ext/fts3/fts3.c 46c116ee0868fc09520d61a1b747c62343c71c399ba67a3d0395b0be29b1a19f
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h dafdc371f9fbab175744b06cfe019d5f040cdfdbd11fea752f5dc28d45b04c05
F ext/fts3/fts3Int.h ae2a44b04cddb5fb35cac4ea5f7f819b2894fd258186465777a19f7acfdf84ed
F ext/fts3/fts3_aux.c f0dc9bd98582615b7750218899bd0c729879b6bbf94d1be57ca1833ff49afc6f
F ext/fts3/fts3_expr.c 903bfb9433109fffb10e910d7066c49cbf8eeae316adc93f0499c4da7dfc932a
F ext/fts3/fts3_hash.c 8b6e31bfb0844c27dc6092c2620bdb1fca17ed613072db057d96952c6bdb48b7
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
F ext/fts3/fts3_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116
F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009
F ext/fts3/fts3_porter.c e19807ce0ae31c1c6e9898e89ecc93183d7ec224ea101af039722a4f49e5f2b8
F ext/fts3/fts3_snippet.c f9a8149173553113f3c495a503843e30028b5dc3723d0ca798c5ad6142e130e6
F ext/fts3/fts3_term.c f45a1e7c6ef464abb1231245d123dae12266b69e05cc56e14045b76591ae92d1
F ext/fts3/fts3_test.c d8d7b2734f894e8a489987447658e374cdd3a3bc8575c401decf1911cb7c6454
F ext/fts3/fts3_tokenize_vtab.c a95feda3590f3c3e17672fe35b67ea6112471aeea4c07ef7744a6606b66549aa
F ext/fts3/fts3_tokenizer.c 6d8fc150c48238955d5182bf661498db0dd473c8a2a80e00c16994a646fa96e7
F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
F ext/fts3/fts3_tokenizer1.c c1de4ae28356ad98ccb8b2e3388a7fdcce7607b5523738c9afb6275dab765154
F ext/fts3/fts3_unicode.c de426ff05c1c2e7bce161cf6b706638419c3a1d9c2667de9cb9dc0458c18e226
F ext/fts3/fts3_unicode2.c 416eb7e1e81142703520d284b768ca2751d40e31fa912cae24ba74860532bf0f
F ext/fts3/fts3_write.c 85279b980f99253c296006503a13f92957ec49b716123083f021acc74545ecfc
F ext/fts3/fts3_write.c 4fb644df0ff840267e47a724286c7a1fa5540273a7ce15756dd5913a101ec302
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73
F ext/fts3/tool/fts3view.c 413c346399159df81f86c4928b7c4a455caab73bfbc8cd68f950f632e5751674
@@ -528,7 +528,7 @@ F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf
F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7
F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d
F src/btmutex.c 6ffb0a22c19e2f9110be0964d0731d2ef1c67b5f7fabfbaeb7b9dabc4b7740ca
F src/btree.c 138804ba7c054533573e87facdfcf9f8aa003c7123152dda8d9281f837ab2622
F src/btree.c 55688477058bb5733128e5d2ff385c58ea82d198ba8a90aeef087946343d9445
F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22
F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e
F src/build.c 898884afd67d953808cb687babc15b66a10213f99fe2ce7db98960e959881f98
@@ -539,7 +539,7 @@ F src/date.c 94ce83b4cd848a387680a5f920c9018c16655db778c4d36525af0a0f34679ac5
F src/dbpage.c 5808e91bc27fa3981b028000f8fadfdc10ce9e59a34ce7dc4e035a69be3906ec
F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d
F src/delete.c 86573edae75e3d3e9a8b590d87db8e47222103029df4f3e11fa56044459b514e
F src/expr.c 24e828db6b2fab8aabfb5d2c0d83dbdfc5a1972b1147fa893350e317ab7e282f
F src/expr.c 1cbdd76eeedb729ea9060df03e3e6b74a302784a13bfa38794a8194f894641ea
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 722f20779f5342a787922deded3628d8c74b5249cab04098cf17ee2f2aaff002
F src/func.c 8f72e88cccdee22185133c10f96ccd61dc34c5ea4b1fa9a73c237ef59b2e64f1
@@ -553,7 +553,7 @@ F src/json.c 7749b98c62f691697c7ee536b570c744c0583cab4a89200fdd0fc2aa8cc8cbd6
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 853385cc7a604157e137585097949252d5d0c731768e16b044608e5c95c3614b
F src/main.c 8983b4a316d7e09946dd731913aa41712f02e2b55cb5c6c92126ccfe2473244a
F src/malloc.c b7a3430cbe91d3e8e04fc10c2041b3a19794e63556ad2441a13d8dadd9b2bafc
F src/malloc.c dfddca1e163496c0a10250cedeafaf56dff47673e0f15888fb0925340a8e3f90
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
F src/mem2.c c8bfc9446fd0798bddd495eb5d9dbafa7d4b7287d8c22d50a83ac9daa26d8a75
@@ -573,27 +573,27 @@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
F src/os_unix.c 102f7e5c5b59c18ea3dbc929dc3be8acb3afc0e0b6ad572e032335c9c27f44f1
F src/os_win.c d55025aeb5b36b5d92d7c09fe709edaf2be901420782540ba4adad86729636a0
F src/os_win.c 8d129ae3e59e0fa900e20d0ad789e96f2e08177f0b00b53cdda65c40331e0902
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c c60031c483960660853dfecf14c8e830503baab1f638ac997f0144f1bd3e1781
F src/pager.c 6176d9752eb580419e8fef4592dc417a6b00ddfd43ee22f818819bf8840ceee8
F src/pager.h f82e9844166e1585f5786837ddc7709966138ced17f568c16af7ccf946c2baa3
F src/parse.y 8e67d820030d2655b9942ffe61c1e7e6b96cea2f2f72183533299393907d0564
F src/pcache.c 5a64e084260560910d9a61bc0e760394fa88aaa22201477ab3e49e278db92edb
F src/pcache.c f4268f7f73c6a3db12ce22fd25bc68dc42315d19599414ab1207d7cf32f79197
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
F src/pcache1.c 5cde56d6bb057b0d7420f89bebd3bb9103f4ed9acfc17cef765dca8c33cd3a1f
F src/pragma.c 9bf7d8a2a9ad3bc36df3ec0d61817a44c38a1da527d59c26c203047f906e334a
F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
F src/prepare.c 971d5819a4bda88038c2283d71fc0a2974ffc3dd480f9bd941341017abacfd1b
F src/pcache1.c dee95e3cd2b61e6512dc814c5ab76d5eb36f0bfc9441dbb4260fccc0d12bbddc
F src/pragma.c 7a66d429ac95147809b496b0129636a4ed2913355da5868be990090861c97f27
F src/pragma.h 05e527d0aef2e9fcf4854cd7af1a852c3d3f316936000e4968298ac1dd570a34
F src/prepare.c 1730581972370ba6f7ce3ce713492d6bb21ae801cb566817540db1b3b46e8b82
F src/printf.c e99ee9741e79ae3873458146f59644276657340385ade4e76a5f5d1c25793764
F src/random.c 546d6feb15ec69c1aafe9bb351a277cbb498fd5410e646add673acb805714960
F src/resolve.c efea4e5fbecfd6d0a9071b0be0d952620991673391b6ffaaf4c277b0bb674633
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
F src/select.c d69dfb5b082f9a25e6700e152ddb3d942359b847b1df504eb09f9b4531844f8d
F src/select.c bb18acf4eded647fef88d4d543c673874dbebff516fbeba90a85e6c13f2a58cd
F src/shell.c.in e7e7c2c69ae86c5ee9e8ad66227203d46ff6dce8700a1b1dababff01c71d33df
F src/sqlite.h.in b9b7fd73239d94db20332bb6e504688001e5564b655e1318a4427a1caef4b99e
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h a988810c9b21c0dc36dc7a62735012339dc76fc7ab448fb0792721d30eacb69d
F src/sqliteInt.h a46ea998c6fdc3390a414db276c7410d9322ce40a2562775ddf5d1082f820763
F src/sqliteInt.h 7bba148584fdbc11f32dbdffaeb97f7957646aedec9ae27b3d9e6d03d9facd58
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -654,13 +654,13 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c 1305797eab3542a0896b552c6e7669c972c1468e11e92b370533c1f37a37082b
F src/treeview.c 07787f67cd297a6d09d04b8d70c06769c60c9c1d9080378f93929c16f8fd3298
F src/trigger.c 61bea163b1fa3039bc572ed8312461b978e5c527e5301f302b078f4c1ccdec6a
F src/trigger.c bc70c58e713dcfb6cabe5cc0bed71aedb02c3e9e128c6089a78aca945ba4d720
F src/update.c c52a7991bece0453d22c77c08469512ee2f1391c12503fd347d1c939220c5877
F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23
F src/vacuum.c bb346170b0b54c6683bba4a5983aea40485597fdf605c87ec8bc2e199fe88cd8
F src/vdbe.c d27ec9a57f752fc2acf6a64d43bbf6072d2415efc976184f6d8a146e65819d3b
F src/util.c 0be191521ff6d2805995f4910f0b6231b42843678b2efdc1abecaf39929a673f
F src/vacuum.c 7d641f22e047bc033d577cef75146f445a88ac23785e5131e74f053c6215f69a
F src/vdbe.c 57004f80fc2a7d45473a6c83cc18dc9a362f5d218f10dff740f1f6e3246b2b50
F src/vdbe.h 64619af62603dc3c4f5ff6ff6d2c8f389abd667a29ce6007ed44bd22b3211cd0
F src/vdbeInt.h 17b7461ffcf9ee760d1341731715a419f6b8c763089a7ece25c2e8098d702b3f
F src/vdbeapi.c fc3183daf72808b4311b228989120fdbc2dc44972fb0d77d5c453460cc0e5b2c
@@ -675,7 +675,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d
F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b
F src/where.c 424c42590b71968a9b81cd890df2671902028613fee38a50ed4c2f7ca65315d3
F src/where.c 63e712bcad47f70e94c2150976cd7da5040933699e3938d4189d064acbe40891
F src/whereInt.h 70cd30de9ed784aa33fa6bd1245f060617de7a00d992469b6d8e419eed915743
F src/wherecode.c 6bb1cf9d0a4e3e04dab0bf0ea4a8d936a0dcc05a7e2207beeda6c61aea6dd341
F src/whereexpr.c 55a39f42aaf982574fbf52906371a84cceed98a994422198dfd03db4fce4cc46
@@ -1116,7 +1116,7 @@ F test/fuzzdata8.db ca9a97f401b06b0d5376139ec7e1f9e773e13345a9a2d9ccc0032cdbfede
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc
F test/fuzzinvariants.c c1c7ae6be4c5fe4e5b845ce2b166c17a3d0f8ef545ab0248c9990505010070da
F test/fuzzinvariants.c d7bb4a0fcc0ac344bcb72f1b86e4ae0acba5ea26dddde8160ee3db6520f10c64
F test/gcfault.test dd28c228a38976d6336a3fc42d7e5f1ad060cb8c
F test/gencol1.test cc0dbb0ee116e5602e18ea7d47f2a0f76b26e09a823b7c36ef254370c2b0f3c1
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
@@ -1180,7 +1180,7 @@ F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c
F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4
F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b
F test/istrue.test e7f285bb70282625c258e866ce6337d4c762922f5a300e1b50f958aef6e7d9c9
F test/join.test 21dbc65ab2476b10ae3ed1dcf64a99fb9a40473caa22f4cec2d6a829933c1442
F test/join.test e32cb9b1491eed682489e2cde33a22a4eb7611fe5aa3b0aa4b275fe27ab3f3ac
F test/join2.test 466b07233820f5deee66a6c3bf6e4500c8bbf7b83649e67606f5f649c07928c0
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
@@ -1932,7 +1932,7 @@ F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a89
F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef
F tool/mkopcodeh.tcl bcb2bd5affb545fd219ef0304c7978e2a356407ab723f45ec8569235892c1c3f
F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
F tool/mkpragmatab.tcl bd07bd59d45d0f3448e123d6937e9811195f9908a51e09d774609883055bfd3d
F tool/mkpragmatab.tcl cb827237c3184697c8335ff427085a31c1ac1ce18f5cdf893c9dfad78c98f3b1
F tool/mkshellc.tcl df5d249617f9cc94d5c48eb0401673eb3f31f383ecbc54e8a13ca3dd97e89450
F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
@@ -1942,6 +1942,7 @@ F tool/mksqlite3h.tcl 1f5e4a1dbbbc43c83cc6e74fe32c6c620502240b66c7c0f33a51378e78
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5
F tool/offsets.c 8ed2b344d33f06e71366a9b93ccedaa38c096cc1dbd4c3c26ad08c6115285845
F tool/omittest-msvc.tcl d6b8f501ac1d7798c4126065030f89812379012cad98a1735d6d7221492abc08
F tool/omittest.tcl 3bc9609aceea871e1ca6ed6749df9ce79b89369d22b492f6ce6078f40647cc3f
F tool/opcodesum.tcl 740ed206ba8c5040018988129abbf3089a0ccf4a
F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b
@@ -1957,7 +1958,7 @@ F tool/showstat4.c 0682ebea7abf4d3657f53c4a243f2e7eab48eab344ed36a94bb75dcd19a5c
F tool/showwal.c 0253c187ae16fdae9cde89e63e1dfcd3bb35e5416d066415f99e2f8cac6ab03d
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
F tool/spaceanal.tcl 1b5be34c6223cb1af06da2a10fb77863eb869b1962d055820b0a11cf2336ab45
F tool/speed-check.sh ff74a68bb95a0341275f4d3c9a7d8a3800bd278aceecf1913295a1f0175bc3e6
F tool/speed-check.sh 13f8e07dbfe25f3aecda33fb6068894665af61ca1360a7b654be0ad0c3f3ae0b
F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355
F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
@@ -1999,8 +2000,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 5ee3515fbb88bf1ae5f8b507844f82dcc429380b6ebeab9b09b52b25ee60a60d
R c72d5281577d5a05e206ee4555729db3
P 584de6a996c78b8e41bdfcd05a8e2a3844664c6b4efedb5883c8b8af388462b5
R df3dd3e3ab8a07ab9eb6697e699f0af2
T *branch * reset-database
T *sym-reset-database *
T -sym-trunk *
U drh
Z 7b1cb313ea01e869890e1646257d0d7e
Z 8ce23413b5db3390219d6d34f63e62a0
# Remove this line to create a well-formed Fossil manifest.
+1 -1
View File
@@ -1 +1 @@
ebbe9634d6dde9e097f61fb98a79111e46de422b7bbbd9ed3af7b6f22aacf5ec
cf0999d4f8fd120c4796240600cd42fcc8baa056efad432d0dae7da372023787
+9 -9
View File
@@ -1547,7 +1547,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
sz += sz2;
}else if( NEVER(iFree+sz>usableSize) ){
}else if( iFree+sz>usableSize ){
return SQLITE_CORRUPT_PAGE(pPage);
}
@@ -3502,16 +3502,16 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){
}
assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 );
if( (p->db->flags & SQLITE_ResetDatabase)
&& sqlite3PagerIsreadonly(pPager)==0
){
pBt->btsFlags &= ~BTS_READ_ONLY;
}
/* Write transactions are not possible on a read-only database */
if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){
rc = SQLITE_READONLY;
goto trans_begun;
if( (p->db->flags & SQLITE_ResetDatabase)
&& sqlite3PagerIsreadonly(pPager)==0
){
pBt->btsFlags &= ~BTS_READ_ONLY;
}else{
rc = SQLITE_READONLY;
goto trans_begun;
}
}
#ifndef SQLITE_OMIT_SHARED_CACHE
+1
View File
@@ -3223,6 +3223,7 @@ void sqlite3CodeRhsOfIN(
sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
}
if( addrOnce ){
sqlite3VdbeAddOp1(v, OP_NullRow, iTab);
sqlite3VdbeJumpHere(v, addrOnce);
/* Subroutine return */
assert( ExprUseYSub(pExpr) );
+22 -6
View File
@@ -270,18 +270,34 @@ static void mallocWithAlarm(int n, void **pp){
*pp = p;
}
/*
** Maximum size of any single memory allocation.
**
** This is not a limit on the total amount of memory used. This is
** a limit on the size parameter to sqlite3_malloc() and sqlite3_realloc().
**
** The upper bound is slightly less than 2GiB: 0x7ffffeff == 2,147,483,391
** This provides a 256-byte safety margin for defense against 32-bit
** signed integer overflow bugs when computing memory allocation sizes.
** Parnoid applications might want to reduce the maximum allocation size
** further for an even larger safety margin. 0x3fffffff or 0x0fffffff
** or even smaller would be reasonable upper bounds on the size of a memory
** allocations for most applications.
*/
#ifndef SQLITE_MAX_ALLOCATION_SIZE
# define SQLITE_MAX_ALLOCATION_SIZE 2147483391
#endif
#if SQLITE_MAX_ALLOCATION_SIZE>2147483391
# error Maximum size for SQLITE_MAX_ALLOCATION_SIZE is 2147483391
#endif
/*
** Allocate memory. This routine is like sqlite3_malloc() except that it
** assumes the memory subsystem has already been initialized.
*/
void *sqlite3Malloc(u64 n){
void *p;
if( n==0 || n>=0x7fffff00 ){
/* A memory allocation of a number of bytes which is near the maximum
** signed integer value might cause an integer overflow inside of the
** xMalloc(). Hence we limit the maximum size to 0x7fffff00, giving
** 255 bytes of overhead. SQLite itself will never use anything near
** this amount. The only way to reach the limit is with sqlite3_malloc() */
if( n==0 || n>SQLITE_MAX_ALLOCATION_SIZE ){
p = 0;
}else if( sqlite3GlobalConfig.bMemstat ){
sqlite3_mutex_enter(mem0.mutex);
+4 -2
View File
@@ -1918,8 +1918,9 @@ int sqlite3_win32_set_directory8(
const char *zValue /* New value for directory being set or reset */
){
char **ppDirectory = 0;
int rc;
#ifndef SQLITE_OMIT_AUTOINIT
int rc = sqlite3_initialize();
rc = sqlite3_initialize();
if( rc ) return rc;
#endif
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
@@ -5762,7 +5763,8 @@ static int winFullPathname(
char *zFull /* Output buffer */
){
int rc;
sqlite3_mutex *pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR);
MUTEX_LOGIC( sqlite3_mutex *pMutex; )
MUTEX_LOGIC( pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR); )
sqlite3_mutex_enter(pMutex);
rc = winFullPathnameNoMutex(pVfs, zRelative, nFull, zFull);
sqlite3_mutex_leave(pMutex);
+1
View File
@@ -5822,6 +5822,7 @@ static int pager_open_journal(Pager *pPager){
if( rc!=SQLITE_OK ){
sqlite3BitvecDestroy(pPager->pInJournal);
pPager->pInJournal = 0;
pPager->journalOff = 0;
}else{
assert( pPager->eState==PAGER_WRITER_LOCKED );
pPager->eState = PAGER_WRITER_CACHEMOD;
+9
View File
@@ -649,10 +649,19 @@ void sqlite3PcacheClearSyncFlags(PCache *pCache){
*/
void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
PCache *pCache = p->pCache;
sqlite3_pcache_page *pOther;
assert( p->nRef>0 );
assert( newPgno>0 );
assert( sqlite3PcachePageSanity(p) );
pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno));
pOther = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, newPgno, 0);
if( pOther ){
PgHdr *pXPage = (PgHdr*)pOther->pExtra;
assert( pXPage->nRef==0 );
pXPage->nRef++;
pCache->nRefSum++;
sqlite3PcacheDrop(pXPage);
}
sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
p->pgno = newPgno;
if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
+8 -8
View File
@@ -1119,26 +1119,26 @@ static void pcache1Rekey(
PCache1 *pCache = (PCache1 *)p;
PgHdr1 *pPage = (PgHdr1 *)pPg;
PgHdr1 **pp;
unsigned int h;
unsigned int hOld, hNew;
assert( pPage->iKey==iOld );
assert( pPage->pCache==pCache );
assert( iOld!=iNew ); /* The page number really is changing */
pcache1EnterMutex(pCache->pGroup);
assert( pcache1FetchNoMutex(p, iOld, 0)==pPage ); /* pPg really is iOld */
h = iOld%pCache->nHash;
pp = &pCache->apHash[h];
hOld = iOld%pCache->nHash;
pp = &pCache->apHash[hOld];
while( (*pp)!=pPage ){
pp = &(*pp)->pNext;
}
*pp = pPage->pNext;
assert( pcache1FetchNoMutex(p, iNew, 0)==0 ); /* iNew not previously used */
h = iNew%pCache->nHash;
assert( pcache1FetchNoMutex(p, iNew, 0)==0 ); /* iNew not in cache */
hNew = iNew%pCache->nHash;
pPage->iKey = iNew;
pPage->pNext = pCache->apHash[h];
pCache->apHash[h] = pPage;
pPage->pNext = pCache->apHash[hNew];
pCache->apHash[hNew] = pPage;
if( iNew>pCache->iMaxKey ){
pCache->iMaxKey = iNew;
}
+14
View File
@@ -2385,6 +2385,20 @@ void sqlite3Pragma(
break;
}
#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
/*
** PRAGMA schema.reset_database
** PRAGMA reset_database
**
** Remove all content from a database file. Bring the size of the
** file back to zero.
*/
case PragTyp_RESET_DATABASE: {
sqlite3VdbeAddOp3(v, OP_Vacuum, iDb, 0, 1);
break;
}
#endif
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
/*
** Report the current state of file logs for all databases
+24 -14
View File
@@ -38,19 +38,20 @@
#define PragTyp_OPTIMIZE 30
#define PragTyp_PAGE_SIZE 31
#define PragTyp_PRAGMA_LIST 32
#define PragTyp_SECURE_DELETE 33
#define PragTyp_SHRINK_MEMORY 34
#define PragTyp_SOFT_HEAP_LIMIT 35
#define PragTyp_SYNCHRONOUS 36
#define PragTyp_TABLE_INFO 37
#define PragTyp_TABLE_LIST 38
#define PragTyp_TEMP_STORE 39
#define PragTyp_TEMP_STORE_DIRECTORY 40
#define PragTyp_THREADS 41
#define PragTyp_WAL_AUTOCHECKPOINT 42
#define PragTyp_WAL_CHECKPOINT 43
#define PragTyp_LOCK_STATUS 44
#define PragTyp_STATS 45
#define PragTyp_RESET_DATABASE 33
#define PragTyp_SECURE_DELETE 34
#define PragTyp_SHRINK_MEMORY 35
#define PragTyp_SOFT_HEAP_LIMIT 36
#define PragTyp_SYNCHRONOUS 37
#define PragTyp_TABLE_INFO 38
#define PragTyp_TABLE_LIST 39
#define PragTyp_TEMP_STORE 40
#define PragTyp_TEMP_STORE_DIRECTORY 41
#define PragTyp_THREADS 42
#define PragTyp_WAL_AUTOCHECKPOINT 43
#define PragTyp_WAL_CHECKPOINT 44
#define PragTyp_LOCK_STATUS 45
#define PragTyp_STATS 46
/* Property flags associated with various pragma. */
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
@@ -500,6 +501,15 @@ static const PragmaName aPragmaName[] = {
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
/* iArg: */ SQLITE_RecTriggers },
#endif
#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
{/* zName: */ "reset_database",
/* ePragTyp: */ PragTyp_RESET_DATABASE,
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{/* zName: */ "reverse_unordered_selects",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
@@ -657,4 +667,4 @@ static const PragmaName aPragmaName[] = {
/* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
#endif
};
/* Number of pragmas: 68 on by default, 78 total. */
/* Number of pragmas: 69 on by default, 79 total. */
-3
View File
@@ -286,9 +286,6 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
for(i=0; i<ArraySize(meta); i++){
sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
}
if( (db->flags & SQLITE_ResetDatabase)!=0 ){
memset(meta, 0, sizeof(meta));
}
pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1];
/* If opening a non-empty database, check the text encoding. For the
+3 -47
View File
@@ -3724,7 +3724,7 @@ static int multiSelectOrderBy(
** the left operands of a RIGHT JOIN. In either case, we need to potentially
** bypass the substituted expression with OP_IfNullRow.
**
** Suppose the original expression integer constant. Even though the table
** Suppose the original expression is an integer constant. Even though the table
** has the nullRow flag set, because the expression is an integer constant,
** it will not be NULLed out. So instead, we insert an OP_IfNullRow opcode
** that checks to see if the nullRow flag is set on the table. If the nullRow
@@ -4181,19 +4181,13 @@ static void renumberCursors(
** See also (3) for restrictions on LEFT JOIN.
**
** (27) The subquery may not contain a FULL or RIGHT JOIN unless it
** is the first element of the parent query. This must be the
** the case if:
** (27a) the subquery is not compound query, and
** is the first element of the parent query. Two subcases:
** (27a) the subquery is not a compound query.
** (27b) the subquery is a compound query and the RIGHT JOIN occurs
** in any arm of the compound query. (See also (17g).)
**
** (28) The subquery is not a MATERIALIZED CTE.
**
** (29) Either the subquery is not the right-hand operand of a join with an
** ON or USING clause nor the right-hand operand of a NATURAL JOIN, or
** the right-most table within the FROM clause of the subquery
** is not part of an outer join.
**
**
** In this routine, the "p" parameter is a pointer to the outer query.
** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
@@ -4297,15 +4291,6 @@ static int flattenSubquery(
}
isOuterJoin = 1;
}
#ifdef SQLITE_EXTRA_IFNULLROW
else if( iFrom>0 && !isAgg ){
/* Setting isOuterJoin to -1 causes OP_IfNullRow opcodes to be generated for
** every reference to any result column from subquery in a join, even
** though they are not necessary. This will stress-test the OP_IfNullRow
** opcode. */
isOuterJoin = -1;
}
#endif
assert( pSubSrc->nSrc>0 ); /* True by restriction (7) */
if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
@@ -4315,35 +4300,6 @@ static int flattenSubquery(
return 0; /* (28) */
}
/* Restriction (29):
**
** We do not want two constraints on the same term of the flattened
** query where one constraint has EP_InnerON and the other is EP_OuterON.
** To prevent this, one or the other of the following conditions must be
** false:
**
** (29a) The right-most entry in the FROM clause of the subquery
** must not be part of an outer join.
**
** (29b) The subquery itself must not be the right operand of a
** NATURAL join or a join that as an ON or USING clause.
**
** These conditions are sufficient to keep an EP_OuterON from being
** flattened into an EP_InnerON. Restrictions (3a) and (27a) prevent
** an EP_InnerON from being flattened into an EP_OuterON.
*/
if( pSubSrc->nSrc>=2
&& (pSubSrc->a[pSubSrc->nSrc-1].fg.jointype & JT_OUTER)!=0
){
if( (pSubitem->fg.jointype & JT_NATURAL)!=0
|| pSubitem->fg.isUsing
|| NEVER(pSubitem->u3.pOn!=0) /* ON clause already shifted into WHERE */
|| pSubitem->fg.isOn
){
return 0;
}
}
/* Restriction (17): If the sub-query is a compound SELECT, then it must
** use only the UNION ALL operator. And none of the simple select queries
** that make up the compound SELECT are allowed to be aggregate or distinct
+1 -2
View File
@@ -4561,7 +4561,6 @@ int sqlite3IndexHasDuplicateRootPage(Index*);
int sqlite3Init(sqlite3*, char**);
int sqlite3InitCallback(void*, int, char**, char**);
int sqlite3InitOne(sqlite3*, int, char**, u32);
char *sqlite3TempDirectory(void);
void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
#ifndef SQLITE_OMIT_VIRTUALTABLE
Module *sqlite3PragmaVtabRegister(sqlite3*,const char *zName);
@@ -4740,7 +4739,7 @@ Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
void sqlite3Vacuum(Parse*,Token*,Expr*);
int sqlite3RunVacuum(char**, sqlite3*, int, sqlite3_value*);
int sqlite3RunVacuum(char**, sqlite3*, int, sqlite3_value*, int);
char *sqlite3NameFromToken(sqlite3*, const Token*);
int sqlite3ExprCompare(const Parse*,const Expr*,const Expr*, int);
int sqlite3ExprCompareSkip(Expr*,Expr*,int);
+17
View File
@@ -351,6 +351,23 @@ void sqlite3FinishTrigger(
Vdbe *v;
char *z;
/* If this is a new CREATE TABLE statement, and if shadow tables
** are read-only, and the trigger makes a change to a shadow table,
** then raise an error - do not allow the trigger to be created. */
if( sqlite3ReadOnlyShadowTables(db) ){
TriggerStep *pStep;
for(pStep=pTrig->step_list; pStep; pStep=pStep->pNext){
if( pStep->zTarget!=0
&& sqlite3ShadowTableName(db, pStep->zTarget)
){
sqlite3ErrorMsg(pParse,
"trigger \"%s\" may not write to shadow table \"%s\"",
pTrig->zName, pStep->zTarget);
goto triggerfinish_cleanup;
}
}
}
/* Make an entry in the sqlite_schema table */
v = sqlite3GetVdbe(pParse);
if( v==0 ) goto triggerfinish_cleanup;
+1 -1
View File
@@ -190,7 +190,7 @@ void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
va_list ap;
sqlite3 *db = pParse->db;
assert( db!=0 );
assert( db->pParse==pParse );
assert( db->pParse==pParse || db->pParse->pToplevel==pParse );
db->errByteOffset = -2;
va_start(ap, zFormat);
zMsg = sqlite3VMPrintf(db, zFormat, ap);
+55 -47
View File
@@ -144,7 +144,8 @@ SQLITE_NOINLINE int sqlite3RunVacuum(
char **pzErrMsg, /* Write error message here */
sqlite3 *db, /* Database connection */
int iDb, /* Which attached DB to vacuum */
sqlite3_value *pOut /* Write results here, if not NULL. VACUUM INTO */
sqlite3_value *pOut, /* Write results here, if not NULL. VACUUM INTO */
int bReset /* Reset the database if true */
){
int rc = SQLITE_OK; /* Return code from service routines */
Btree *pMain; /* The database being vacuumed */
@@ -162,6 +163,8 @@ SQLITE_NOINLINE int sqlite3RunVacuum(
const char *zDbMain; /* Schema name of database to vacuum */
const char *zOut; /* Name of output file */
assert( bReset==0 || pOut==0 );
if( (db->flags & SQLITE_ResetDatabase)!=0 && pOut==0 ) bReset = 1;
if( !db->autoCommit ){
sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
return SQLITE_ERROR; /* IMP: R-12218-18073 */
@@ -269,54 +272,59 @@ SQLITE_NOINLINE int sqlite3RunVacuum(
sqlite3BtreeGetAutoVacuum(pMain));
#endif
/* Query the schema of the main database. Create a mirror schema
** in the temporary database.
*/
db->init.iDb = nDb; /* force new CREATE statements into vacuum_db */
rc = execSqlF(db, pzErrMsg,
"SELECT sql FROM \"%w\".sqlite_schema"
" WHERE type='table'AND name<>'sqlite_sequence'"
" AND coalesce(rootpage,1)>0",
zDbMain
);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
rc = execSqlF(db, pzErrMsg,
"SELECT sql FROM \"%w\".sqlite_schema"
" WHERE type='index'",
zDbMain
);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
db->init.iDb = 0;
/* Loop through the tables in the main database. For each, do
** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
** the contents to the temporary database.
*/
rc = execSqlF(db, pzErrMsg,
"SELECT'INSERT INTO vacuum_db.'||quote(name)"
"||' SELECT*FROM\"%w\".'||quote(name)"
"FROM vacuum_db.sqlite_schema "
"WHERE type='table'AND coalesce(rootpage,1)>0",
zDbMain
);
assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 );
db->mDbFlags &= ~DBFLAG_Vacuum;
if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Copy the triggers, views, and virtual tables from the main database
** over to the temporary database. None of these objects has any
** associated storage, so all we have to do is copy their entries
** from the schema table.
*/
rc = execSqlF(db, pzErrMsg,
"INSERT INTO vacuum_db.sqlite_schema"
" SELECT*FROM \"%w\".sqlite_schema"
" WHERE type IN('view','trigger')"
" OR(type='table'AND rootpage=0)",
zDbMain
);
if( !bReset ){
/* Query the schema of the main database. Create a mirror schema
** in the temporary database.
*/
db->init.iDb = nDb; /* force new CREATE statements into vacuum_db */
rc = execSqlF(db, pzErrMsg,
"SELECT sql FROM \"%w\".sqlite_schema"
" WHERE type='table'AND name<>'sqlite_sequence'"
" AND coalesce(rootpage,1)>0",
zDbMain
);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
rc = execSqlF(db, pzErrMsg,
"SELECT sql FROM \"%w\".sqlite_schema"
" WHERE type='index'",
zDbMain
);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
db->init.iDb = 0;
/* Loop through the tables in the main database. For each, do
** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
** the contents to the temporary database.
*/
rc = execSqlF(db, pzErrMsg,
"SELECT'INSERT INTO vacuum_db.'||quote(name)"
"||' SELECT*FROM\"%w\".'||quote(name)"
"FROM vacuum_db.sqlite_schema "
"WHERE type='table'AND coalesce(rootpage,1)>0",
zDbMain
);
assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 );
db->mDbFlags &= ~DBFLAG_Vacuum;
if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Copy the triggers, views, and virtual tables from the main database
** over to the temporary database. None of these objects has any
** associated storage, so all we have to do is copy their entries
** from the schema table.
*/
rc = execSqlF(db, pzErrMsg,
"INSERT INTO vacuum_db.sqlite_schema"
" SELECT*FROM \"%w\".sqlite_schema"
" WHERE type IN('view','trigger')"
" OR(type='table'AND rootpage=0)",
zDbMain
);
}else{
rc = sqlite3BtreeBeginTrans(pTemp, 2, 0);
}
if( rc ) goto end_of_vacuum;
/* At this point, there is a write transaction open on both the
** vacuum database and the main database. Assuming no error occurs,
** both transactions are closed by this block - the main database
+13 -5
View File
@@ -4897,12 +4897,16 @@ case OP_SeekHit: {
/* Opcode: IfNotOpen P1 P2 * * *
** Synopsis: if( !csr[P1] ) goto P2
**
** If cursor P1 is not open, jump to instruction P2. Otherwise, fall through.
** If cursor P1 is not open or if P1 is set to a NULL row using the
** OP_NullRow opcode, then jump to instruction P2. Otherwise, fall through.
*/
case OP_IfNotOpen: { /* jump */
VdbeCursor *pCur;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
VdbeBranchTaken(p->apCsr[pOp->p1]==0, 2);
if( !p->apCsr[pOp->p1] ){
pCur = p->apCsr[pOp->p1];
VdbeBranchTaken(pCur==0 || pCur->nullRow, 2);
if( pCur==0 || pCur->nullRow ){
goto jump_to_p2_and_check_for_interrupt;
}
break;
@@ -7632,7 +7636,7 @@ case OP_JournalMode: { /* out2 */
#endif /* SQLITE_OMIT_PRAGMA */
#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
/* Opcode: Vacuum P1 P2 * * *
/* Opcode: Vacuum P1 P2 P3 * *
**
** Vacuum the entire database P1. P1 is 0 for "main", and 2 or more
** for an attached database. The "temp" database may not be vacuumed.
@@ -7640,11 +7644,15 @@ case OP_JournalMode: { /* out2 */
** If P2 is not zero, then it is a register holding a string which is
** the file into which the result of vacuum should be written. When
** P2 is zero, the vacuum overwrites the original database.
**
** If P3 is not zero, then delete all database content as part of the
** vacuum. It is not allowed for both P2 and P3 to be non-zero at the
** same time.
*/
case OP_Vacuum: {
assert( p->readOnly==0 );
rc = sqlite3RunVacuum(&p->zErrMsg, db, pOp->p1,
pOp->p2 ? &aMem[pOp->p2] : 0);
pOp->p2 ? &aMem[pOp->p2] : 0, pOp->p3);
if( rc ) goto abort_due_to_error;
break;
}
+49 -51
View File
@@ -743,6 +743,43 @@ static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){
#define whereTraceIndexInfoOutputs(A)
#endif
/*
** We know that pSrc is an operand of an outer join. Return true if
** pTerm is a constraint that is compatible with that join.
**
** pTerm must be EP_OuterON if pSrc is the right operand of an
** outer join. pTerm can be either EP_OuterON or EP_InnerON if pSrc
** is the left operand of a RIGHT join.
**
** See https://sqlite.org/forum/forumpost/206d99a16dd9212f
** for an example of a WHERE clause constraints that may not be used on
** the right table of a RIGHT JOIN because the constraint implies a
** not-NULL condition on the left table of the RIGHT JOIN.
*/
static int constraintCompatibleWithOuterJoin(
const WhereTerm *pTerm, /* WHERE clause term to check */
const SrcItem *pSrc /* Table we are trying to access */
){
assert( (pSrc->fg.jointype&(JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ); /* By caller */
testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT );
testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ );
testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) )
testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) );
if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON)
|| pTerm->pExpr->w.iJoin != pSrc->iCursor
){
return 0;
}
if( (pSrc->fg.jointype & (JT_LEFT|JT_RIGHT))!=0
&& ExprHasProperty(pTerm->pExpr, EP_InnerON)
){
return 0;
}
return 1;
}
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
/*
** Return TRUE if the WHERE clause term pTerm is of a form where it
@@ -758,16 +795,10 @@ static int termCanDriveIndex(
if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
assert( (pSrc->fg.jointype & JT_RIGHT)==0 );
if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){
testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT );
testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ );
testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) )
testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) );
if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON)
|| pTerm->pExpr->w.iJoin != pSrc->iCursor
){
return 0; /* See tag-20191211-001 */
}
if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0
&& !constraintCompatibleWithOuterJoin(pTerm,pSrc)
){
return 0; /* See https://sqlite.org/forum/forumpost/51e6959f61 */
}
if( (pTerm->prereqRight & notReady)!=0 ) return 0;
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
@@ -1179,22 +1210,10 @@ static sqlite3_index_info *allocateIndexInfo(
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
assert( pTerm->u.x.leftColumn>=XN_ROWID );
assert( pTerm->u.x.leftColumn<pTab->nCol );
/* tag-20191211-002: WHERE-clause constraints are not useful to the
** right-hand table of a LEFT JOIN nor to the either table of a
** RIGHT JOIN. See tag-20191211-001 for the
** equivalent restriction for ordinary tables. */
if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){
testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT );
testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_RIGHT );
testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ );
testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) );
testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) );
if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON)
|| pTerm->pExpr->w.iJoin != pSrc->iCursor
){
continue;
}
if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0
&& !constraintCompatibleWithOuterJoin(pTerm,pSrc)
){
continue;
}
nTerm++;
pTerm->wtFlags |= TERM_OK;
@@ -2852,32 +2871,11 @@ static int whereLoopAddBtreeIndex(
** to mix with a lower range bound from some other source */
if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;
/* tag-20191211-001: Do not allow constraints from the WHERE clause to
** be used by the right table of a LEFT JOIN nor by the left table of a
** RIGHT JOIN. Only constraints in the ON clause are allowed.
** See tag-20191211-002 for the vtab equivalent.
**
** 2022-06-06: See https://sqlite.org/forum/forumpost/206d99a16dd9212f
** for an example of a WHERE clause constraints that may not be used on
** the right table of a RIGHT JOIN because the constraint implies a
** not-NULL condition on the left table of the RIGHT JOIN.
**
** 2022-06-10: The same condition applies to termCanDriveIndex() above.
** https://sqlite.org/forum/forumpost/51e6959f61
*/
if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){
testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT );
testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_RIGHT );
testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ );
testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) )
testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) );
if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON)
|| pTerm->pExpr->w.iJoin != pSrc->iCursor
){
continue;
}
if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0
&& !constraintCompatibleWithOuterJoin(pTerm,pSrc)
){
continue;
}
if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){
pBuilder->bldFlags1 |= SQLITE_BLDF1_UNIQUE;
}else{
+14
View File
@@ -129,6 +129,19 @@ int fuzz_invariant(
return SQLITE_CORRUPT;
}
sqlite3_finalize(pCk);
if( sqlite3_strlike("%group%by%order%by%desc%",sqlite3_sql(pStmt),0)==0 ){
/* dbsqlfuzz crash-647c162051c9b23ce091b7bbbe5125ce5f00e922
** Original statement is:
**
** SELECT a,c,d,b,'' FROM t1 GROUP BY 1 HAVING d<>345 ORDER BY a DESC;
**
** The values of c, d, and b are indeterminate and change when the
** enclosed in the test query because the DESC is dropped.
**
** SELECT * FROM (...) WHERE "a"==0
*/
goto not_a_fault;
}
rc = sqlite3_prepare_v2(db,
"SELECT 1 FROM bytecode(?1) WHERE opcode='VOpen'", -1, &pCk, 0);
if( rc==SQLITE_OK ){
@@ -143,6 +156,7 @@ int fuzz_invariant(
printf("invariant-error ignored due to the use of virtual tables\n");
}
}
not_a_fault:
sqlite3_finalize(pTestStmt);
return SQLITE_OK;
}
+76
View File
@@ -1130,5 +1130,81 @@ do_execsql_test join-27.5 {
) AS t99 ON b IN (1,2,3);
} {}
db null NULL
do_execsql_test join-27.6 {
INSERT INTO t1 VALUES(3,4,NULL);
INSERT INTO t2 VALUES(1,2);
WITH t99(b) AS (
SELECT coalesce(b,3) FROM t2 AS x LEFT JOIN t1 ON c IN (SELECT x FROM t3)
)
SELECT d, e, b FROM t2 JOIN t99 ON b IN (1,2,3) ORDER BY +d;
} {NULL NULL 3 NULL NULL 3 1 2 3 1 2 3}
do_execsql_test join-27.7 {
SELECT d, e, b2
FROM t2
JOIN (SELECT coalesce(b,3) AS b2 FROM t2 AS x LEFT JOIN t1
ON c IN (SELECT x FROM t3)) AS t99
ON b2 IN (1,2,3) ORDER BY +d;
} {NULL NULL 3 NULL NULL 3 1 2 3 1 2 3}
do_execsql_test join-27.8 {
DELETE FROM t1;
DELETE FROM t2 WHERE d IS NOT NULL;
DELETE FROM t3;
SELECT * FROM t2 JOIN (SELECT b FROM t2 LEFT JOIN t1
ON c IN (SELECT x FROM t3)) AS t99 ON b IN (1,2,3);
} {}
do_execsql_test join-27.9 {
DELETE FROM t1;
DELETE FROM t2;
DELETE FROM t3;
INSERT INTO t1 VALUES(4,3,5);
INSERT INTO t2 VALUES(1,2);
INSERT INTO t3 VALUES(5);
SELECT * FROM t2 JOIN (SELECT b FROM t2 LEFT JOIN t1
ON c IN (SELECT x FROM t3)) AS t99 ON b IS NULL;
} {}
do_execsql_test join-27.10 {
WITH t99(b) AS (
SELECT b FROM t2 AS x LEFT JOIN t1 ON c IN (SELECT x FROM t3)
)
SELECT d, e, b FROM t2 JOIN t99 ON b IS NULL;
} {}
# 2022-09-19 https://sqlite.org/forum/forumpost/96b9e5709cf47cda
# Performance regression relative to version 3.38.0 that resulted from
# a new query flattener restriction that was added to fixes the join-27.*
# tests above. The restriction needed to be removed and the join-27.*
# problem fixed another way.
#
reset_db
do_execsql_test join-28.1 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT, c INT);
CREATE TABLE t2(d INTEGER PRIMARY KEY, e INT);
CREATE VIEW t3(a,b,c,d,e) AS SELECT * FROM t1 LEFT JOIN t2 ON d=c;
CREATE TABLE t4(x INT, y INT);
INSERT INTO t1 VALUES(1,2,3);
INSERT INTO t2 VALUES(1,5);
INSERT INTO t4 VALUES(1,4);
SELECT a, b, y FROM t4 JOIN t3 ON a=x;
} {1 2 4}
do_eqp_test join-28.2 {
SELECT a, b, y FROM t4 JOIN t3 ON a=x;
} {
QUERY PLAN
|--SCAN t4
`--SEARCH t1 USING INTEGER PRIMARY KEY (rowid=?)
}
# ^^^^^^^ Without the fix (if the query flattening optimization does not
# run) the query plan above would look like this:
#
# QUERY PLAN
# |--MATERIALIZE t3
# | |--SCAN t1
# | `--SEARCH t2 USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN
# |--SCAN t4
# `--SEARCH t3 USING AUTOMATIC COVERING INDEX (a=?)
finish_test
+3
View File
@@ -398,6 +398,9 @@ set pragma_def {
TYPE: FLAG
ARG: SQLITE_LegacyAlter
IF: !defined(SQLITE_OMIT_FLAG_PRAGMAS)
NAME: reset_database
IF: !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
}
# Open the output file
+99
View File
@@ -0,0 +1,99 @@
# Run this TCL script in order to build using MSVC multiple times
# with various compile-time options. Use this to verify that the various
# compile-time options all work with MSVC.
#
set OPTIONS [list \
SQLITE_ALLOW_ROWID_IN_VIEW \
SQLITE_ENABLE_COLUMN_METADATA \
SQLITE_ENABLE_EXPENSIVE_ASSERT \
SQLITE_ENABLE_IOTRACE \
SQLITE_ENABLE_MEMORY_MANAGEMENT \
SQLITE_ENABLE_MEMSYS3 \
SQLITE_ENABLE_MEMSYS5 \
SQLITE_ENABLE_OVERSIZE_CELL_CHECK \
SQLITE_ENABLE_UNLOCK_NOTIFY \
SQLITE_ENABLE_UPDATE_DELETE_LIMIT \
SQLITE_OMIT_ALTERTABLE-x \
SQLITE_OMIT_ATTACH-x \
SQLITE_OMIT_AUTHORIZATION \
SQLITE_OMIT_AUTOINCREMENT \
SQLITE_OMIT_AUTOINIT \
SQLITE_OMIT_AUTOMATIC_INDEX \
SQLITE_OMIT_AUTORESET \
SQLITE_OMIT_AUTOVACUUM \
SQLITE_OMIT_BETWEEN_OPTIMIZATION \
SQLITE_OMIT_BLOB_LITERAL \
SQLITE_OMIT_BTREECOUNT \
SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA \
SQLITE_OMIT_CAST \
SQLITE_OMIT_CHECK \
SQLITE_OMIT_COMPILEOPTION_DIAGS \
SQLITE_OMIT_COMPLETE \
SQLITE_OMIT_COMPOUND_SELECT \
SQLITE_OMIT_CONFLICT_CLAUSE \
SQLITE_OMIT_CTE \
SQLITE_OMIT_DATETIME_FUNCS \
SQLITE_OMIT_DECLTYPE \
SQLITE_OMIT_DEPRECATED \
SQLITE_OMIT_DESERIALIZE \
SQLITE_OMIT_DISKIO-x \
SQLITE_OMIT_EXPLAIN-x \
SQLITE_OMIT_FLAG_PRAGMAS \
SQLITE_OMIT_FLOATING_POINT \
SQLITE_OMIT_FOREIGN_KEY \
SQLITE_OMIT_GENERATED_COLUMNS \
SQLITE_OMIT_GET_TABLE \
SQLITE_OMIT_HEX_INTEGER \
SQLITE_OMIT_INCRBLOB-x \
SQLITE_OMIT_INTEGRITY_CHECK \
SQLITE_OMIT_INTROSPECTION_PRAGMAS \
SQLITE_OMIT_JSON \
SQLITE_OMIT_LIKE_OPTIMIZATION \
SQLITE_OMIT_LOAD_EXTENSION \
SQLITE_OMIT_LOCALTIME \
SQLITE_OMIT_LOOKASIDE \
SQLITE_OMIT_MEMORYDB \
SQLITE_OMIT_OR_OPTIMIZATION \
SQLITE_OMIT_PAGER_PRAGMAS-x \
SQLITE_OMIT_PARSER_TRACE \
SQLITE_OMIT_POPEN \
SQLITE_OMIT_PRAGMA-x \
SQLITE_OMIT_PROGRESS_CALLBACK \
SQLITE_OMIT_QUICKBALANCE \
SQLITE_OMIT_RANDOMNESS \
SQLITE_OMIT_REINDEX-x \
SQLITE_OMIT_SCHEMA_PRAGMAS \
SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS \
SQLITE_OMIT_SHARED_CACHE \
SQLITE_OMIT_SHUTDOWN_DIRECTORIES \
SQLITE_OMIT_SUBQUERY-x \
SQLITE_OMIT_TCL_VARIABLE \
SQLITE_OMIT_TEMPDB \
SQLITE_OMIT_TEST_CONTROL \
SQLITE_OMIT_TRACE \
SQLITE_OMIT_TRIGGER \
SQLITE_OMIT_TRUNCATE_OPTIMIZATION \
SQLITE_OMIT_UPSERT \
SQLITE_OMIT_UTF16 \
SQLITE_OMIT_VACUUM-x \
SQLITE_OMIT_VIEW-x \
SQLITE_OMIT_VIRTUALTABLE-x \
SQLITE_OMIT_WAL \
SQLITE_OMIT_WINDOWFUNC-x \
SQLITE_OMIT_WSD \
SQLITE_OMIT_XFER_OPT \
]
set start [lindex $argv 0]
foreach opt $OPTIONS {
if {[regexp x $opt]} continue
if {[string compare $opt $start]<0} continue
exec fossil clean -x
set cmd "nmake /f Makefile.msc USE_FULLWARN=0 OPTIMIZATIONS=0"
append cmd " CCOPTS=-D$opt"
puts $cmd
set res [catch {eval exec $cmd} outtxt]
if {[regexp {sqlite3.c.\d+.: error} $outtxt]} {
puts "FAILED:\n$outtxt"
exit
}
}
+6
View File
@@ -96,6 +96,9 @@ while test "$1" != ""; do
--cachesize)
shift; SPEEDTEST_OPTS="$SPEEDTEST_OPTS --cachesize $1"
;;
--stmtcache)
shift; SPEEDTEST_OPTS="$SPEEDTEST_OPTS --stmtcache $1"
;;
--checkpoint)
SPEEDTEST_OPTS="$SPEEDTEST_OPTS --checkpoint"
;;
@@ -143,6 +146,9 @@ while test "$1" != ""; do
SPEEDTEST_OPTS="$SPEEDTEST_OPTS --testset rtree"
CC_OPTS="$CC_OPTS -DSQLITE_ENABLE_RTREE"
;;
--persist)
SPEEDTEST_OPTS="$SPEEDTEST_OPTS --persist"
;;
--orm)
SPEEDTEST_OPTS="$SPEEDTEST_OPTS --testset orm"
;;