Fossil SCM

Sync with trunk.

florian 2022-10-01 06:48 timeline-keyboard-navigation merge
Commit e5c5e6f0e9da7a09a40709850a503627d37d111ec15011bc7b95f688d66b4cb0
+154 -172
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -452,11 +452,11 @@
452452
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
453453
** [sqlite_version()] and [sqlite_source_id()].
454454
*/
455455
#define SQLITE_VERSION "3.40.0"
456456
#define SQLITE_VERSION_NUMBER 3040000
457
-#define SQLITE_SOURCE_ID "2022-09-02 21:19:24 da7af290960ab8a04a1f55cdc5eeac36b47fa194edf67f0a05daa4b7f2a4071c"
457
+#define SQLITE_SOURCE_ID "2022-09-28 19:14:01 f25cf63471cbed1edb27591e57fead62550d4046dbdcb61312288f0f6f24c646"
458458
459459
/*
460460
** CAPI3REF: Run-Time Library Version Numbers
461461
** KEYWORDS: sqlite3_version sqlite3_sourceid
462462
**
@@ -29076,22 +29076,38 @@
2907629076
sqlite3StatusUp(SQLITE_STATUS_MALLOC_COUNT, 1);
2907729077
}
2907829078
*pp = p;
2907929079
}
2908029080
29081
+/*
29082
+** Maximum size of any single memory allocation.
29083
+**
29084
+** This is not a limit on the total amount of memory used. This is
29085
+** a limit on the size parameter to sqlite3_malloc() and sqlite3_realloc().
29086
+**
29087
+** The upper bound is slightly less than 2GiB: 0x7ffffeff == 2,147,483,391
29088
+** This provides a 256-byte safety margin for defense against 32-bit
29089
+** signed integer overflow bugs when computing memory allocation sizes.
29090
+** Parnoid applications might want to reduce the maximum allocation size
29091
+** further for an even larger safety margin. 0x3fffffff or 0x0fffffff
29092
+** or even smaller would be reasonable upper bounds on the size of a memory
29093
+** allocations for most applications.
29094
+*/
29095
+#ifndef SQLITE_MAX_ALLOCATION_SIZE
29096
+# define SQLITE_MAX_ALLOCATION_SIZE 2147483391
29097
+#endif
29098
+#if SQLITE_MAX_ALLOCATION_SIZE>2147483391
29099
+# error Maximum size for SQLITE_MAX_ALLOCATION_SIZE is 2147483391
29100
+#endif
29101
+
2908129102
/*
2908229103
** Allocate memory. This routine is like sqlite3_malloc() except that it
2908329104
** assumes the memory subsystem has already been initialized.
2908429105
*/
2908529106
SQLITE_PRIVATE void *sqlite3Malloc(u64 n){
2908629107
void *p;
29087
- if( n==0 || n>=0x7fffff00 ){
29088
- /* A memory allocation of a number of bytes which is near the maximum
29089
- ** signed integer value might cause an integer overflow inside of the
29090
- ** xMalloc(). Hence we limit the maximum size to 0x7fffff00, giving
29091
- ** 255 bytes of overhead. SQLite itself will never use anything near
29092
- ** this amount. The only way to reach the limit is with sqlite3_malloc() */
29108
+ if( n==0 || n>SQLITE_MAX_ALLOCATION_SIZE ){
2909329109
p = 0;
2909429110
}else if( sqlite3GlobalConfig.bMemstat ){
2909529111
sqlite3_mutex_enter(mem0.mutex);
2909629112
mallocWithAlarm((int)n, &p);
2909729113
sqlite3_mutex_leave(mem0.mutex);
@@ -45571,12 +45587,13 @@
4557145587
SQLITE_API int sqlite3_win32_set_directory8(
4557245588
unsigned long type, /* Identifier for directory being set or reset */
4557345589
const char *zValue /* New value for directory being set or reset */
4557445590
){
4557545591
char **ppDirectory = 0;
45592
+ int rc;
4557645593
#ifndef SQLITE_OMIT_AUTOINIT
45577
- int rc = sqlite3_initialize();
45594
+ rc = sqlite3_initialize();
4557845595
if( rc ) return rc;
4557945596
#endif
4558045597
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
4558145598
if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){
4558245599
ppDirectory = &sqlite3_data_directory;
@@ -49415,11 +49432,12 @@
4941549432
const char *zRelative, /* Possibly relative input path */
4941649433
int nFull, /* Size of output buffer in bytes */
4941749434
char *zFull /* Output buffer */
4941849435
){
4941949436
int rc;
49420
- sqlite3_mutex *pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR);
49437
+ MUTEX_LOGIC( sqlite3_mutex *pMutex; )
49438
+ MUTEX_LOGIC( pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR); )
4942149439
sqlite3_mutex_enter(pMutex);
4942249440
rc = winFullPathnameNoMutex(pVfs, zRelative, nFull, zFull);
4942349441
sqlite3_mutex_leave(pMutex);
4942449442
return rc;
4942549443
}
@@ -51798,18 +51816,18 @@
5179851816
assert( p->nRef>0 );
5179951817
assert( newPgno>0 );
5180051818
assert( sqlite3PcachePageSanity(p) );
5180151819
pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno));
5180251820
pOther = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, newPgno, 0);
51803
- sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
5180451821
if( pOther ){
51805
- PgHdr *pPg = (PgHdr*)pOther->pExtra;
51806
- pPg->pgno = p->pgno;
51807
- if( pPg->pPage==0 ){
51808
- sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pOther, 0);
51809
- }
51822
+ PgHdr *pXPage = (PgHdr*)pOther->pExtra;
51823
+ assert( pXPage->nRef==0 );
51824
+ pXPage->nRef++;
51825
+ pCache->nRefSum++;
51826
+ sqlite3PcacheDrop(pXPage);
5181051827
}
51828
+ sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
5181151829
p->pgno = newPgno;
5181251830
if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
5181351831
pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
5181451832
assert( sqlite3PcachePageSanity(p) );
5181551833
}
@@ -53202,27 +53220,12 @@
5320253220
while( (*pp)!=pPage ){
5320353221
pp = &(*pp)->pNext;
5320453222
}
5320553223
*pp = pPage->pNext;
5320653224
53225
+ assert( pcache1FetchNoMutex(p, iNew, 0)==0 ); /* iNew not in cache */
5320753226
hNew = iNew%pCache->nHash;
53208
- pp = &pCache->apHash[hNew];
53209
- while( *pp ){
53210
- if( (*pp)->iKey==iNew ){
53211
- /* If there is already another pcache entry at iNew, change it to iOld,
53212
- ** thus swapping the positions of iNew and iOld */
53213
- PgHdr1 *pOld = *pp;
53214
- *pp = pOld->pNext;
53215
- pOld->pNext = pCache->apHash[hOld];
53216
- pCache->apHash[hOld] = pOld;
53217
- pOld->iKey = iOld;
53218
- break;
53219
- }else{
53220
- pp = &(*pp)->pNext;
53221
- }
53222
- }
53223
-
5322453227
pPage->iKey = iNew;
5322553228
pPage->pNext = pCache->apHash[hNew];
5322653229
pCache->apHash[hNew] = pPage;
5322753230
if( iNew>pCache->iMaxKey ){
5322853231
pCache->iMaxKey = iNew;
@@ -68523,11 +68526,11 @@
6852368526
if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage);
6852468527
sz2 = get2byte(&data[iFree2+2]);
6852568528
if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
6852668529
memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
6852768530
sz += sz2;
68528
- }else if( NEVER(iFree+sz>usableSize) ){
68531
+ }else if( iFree+sz>usableSize ){
6852968532
return SQLITE_CORRUPT_PAGE(pPage);
6853068533
}
6853168534
6853268535
cbrk = top+sz;
6853368536
assert( cbrk+(iFree-top) <= usableSize );
@@ -93400,16 +93403,20 @@
9340093403
}
9340193404
9340293405
/* Opcode: IfNotOpen P1 P2 * * *
9340393406
** Synopsis: if( !csr[P1] ) goto P2
9340493407
**
93405
-** If cursor P1 is not open, jump to instruction P2. Otherwise, fall through.
93408
+** If cursor P1 is not open or if P1 is set to a NULL row using the
93409
+** OP_NullRow opcode, then jump to instruction P2. Otherwise, fall through.
9340693410
*/
9340793411
case OP_IfNotOpen: { /* jump */
93412
+ VdbeCursor *pCur;
93413
+
9340893414
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
93409
- VdbeBranchTaken(p->apCsr[pOp->p1]==0, 2);
93410
- if( !p->apCsr[pOp->p1] ){
93415
+ pCur = p->apCsr[pOp->p1];
93416
+ VdbeBranchTaken(pCur==0 || pCur->nullRow, 2);
93417
+ if( pCur==0 || pCur->nullRow ){
9341193418
goto jump_to_p2_and_check_for_interrupt;
9341293419
}
9341393420
break;
9341493421
}
9341593422
@@ -107028,10 +107035,11 @@
107028107035
}
107029107036
if( pKeyInfo ){
107030107037
sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
107031107038
}
107032107039
if( addrOnce ){
107040
+ sqlite3VdbeAddOp1(v, OP_NullRow, iTab);
107033107041
sqlite3VdbeJumpHere(v, addrOnce);
107034107042
/* Subroutine return */
107035107043
assert( ExprUseYSub(pExpr) );
107036107044
assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
107037107045
|| pParse->nErr );
@@ -139569,11 +139577,11 @@
139569139577
** position in the parent that NULL-able due to an OUTER JOIN. Either the
139570139578
** target slot in the parent is the right operand of a LEFT JOIN, or one of
139571139579
** the left operands of a RIGHT JOIN. In either case, we need to potentially
139572139580
** bypass the substituted expression with OP_IfNullRow.
139573139581
**
139574
-** Suppose the original expression integer constant. Even though the table
139582
+** Suppose the original expression is an integer constant. Even though the table
139575139583
** has the nullRow flag set, because the expression is an integer constant,
139576139584
** it will not be NULLed out. So instead, we insert an OP_IfNullRow opcode
139577139585
** that checks to see if the nullRow flag is set on the table. If the nullRow
139578139586
** flag is set, then the value in the register is set to NULL and the original
139579139587
** expression is bypassed. If the nullRow flag is not set, then the original
@@ -140026,23 +140034,17 @@
140026140034
**
140027140035
** (26) The subquery may not be the right operand of a RIGHT JOIN.
140028140036
** See also (3) for restrictions on LEFT JOIN.
140029140037
**
140030140038
** (27) The subquery may not contain a FULL or RIGHT JOIN unless it
140031
-** is the first element of the parent query. This must be the
140032
-** the case if:
140033
-** (27a) the subquery is not compound query, and
140039
+** is the first element of the parent query. Two subcases:
140040
+** (27a) the subquery is not a compound query.
140034140041
** (27b) the subquery is a compound query and the RIGHT JOIN occurs
140035140042
** in any arm of the compound query. (See also (17g).)
140036140043
**
140037140044
** (28) The subquery is not a MATERIALIZED CTE.
140038140045
**
140039
-** (29) Either the subquery is not the right-hand operand of a join with an
140040
-** ON or USING clause nor the right-hand operand of a NATURAL JOIN, or
140041
-** the right-most table within the FROM clause of the subquery
140042
-** is not part of an outer join.
140043
-**
140044140046
**
140045140047
** In this routine, the "p" parameter is a pointer to the outer query.
140046140048
** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
140047140049
** uses aggregates.
140048140050
**
@@ -140142,57 +140144,19 @@
140142140144
){
140143140145
return 0;
140144140146
}
140145140147
isOuterJoin = 1;
140146140148
}
140147
-#ifdef SQLITE_EXTRA_IFNULLROW
140148
- else if( iFrom>0 && !isAgg ){
140149
- /* Setting isOuterJoin to -1 causes OP_IfNullRow opcodes to be generated for
140150
- ** every reference to any result column from subquery in a join, even
140151
- ** though they are not necessary. This will stress-test the OP_IfNullRow
140152
- ** opcode. */
140153
- isOuterJoin = -1;
140154
- }
140155
-#endif
140156140149
140157140150
assert( pSubSrc->nSrc>0 ); /* True by restriction (7) */
140158140151
if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
140159140152
return 0; /* Restriction (27a) */
140160140153
}
140161140154
if( pSubitem->fg.isCte && pSubitem->u2.pCteUse->eM10d==M10d_Yes ){
140162140155
return 0; /* (28) */
140163140156
}
140164140157
140165
- /* Restriction (29):
140166
- **
140167
- ** We do not want two constraints on the same term of the flattened
140168
- ** query where one constraint has EP_InnerON and the other is EP_OuterON.
140169
- ** To prevent this, one or the other of the following conditions must be
140170
- ** false:
140171
- **
140172
- ** (29a) The right-most entry in the FROM clause of the subquery
140173
- ** must not be part of an outer join.
140174
- **
140175
- ** (29b) The subquery itself must not be the right operand of a
140176
- ** NATURAL join or a join that as an ON or USING clause.
140177
- **
140178
- ** These conditions are sufficient to keep an EP_OuterON from being
140179
- ** flattened into an EP_InnerON. Restrictions (3a) and (27a) prevent
140180
- ** an EP_InnerON from being flattened into an EP_OuterON.
140181
- */
140182
- if( pSubSrc->nSrc>=2
140183
- && (pSubSrc->a[pSubSrc->nSrc-1].fg.jointype & JT_OUTER)!=0
140184
- ){
140185
- if( (pSubitem->fg.jointype & JT_NATURAL)!=0
140186
- || pSubitem->fg.isUsing
140187
- || NEVER(pSubitem->u3.pOn!=0) /* ON clause already shifted into WHERE */
140188
- || pSubitem->fg.isOn
140189
- ){
140190
- return 0;
140191
- }
140192
- }
140193
-
140194140158
/* Restriction (17): If the sub-query is a compound SELECT, then it must
140195140159
** use only the UNION ALL operator. And none of the simple select queries
140196140160
** that make up the compound SELECT are allowed to be aggregate or distinct
140197140161
** queries.
140198140162
*/
@@ -144296,10 +144260,27 @@
144296144260
** build the sqlite_schema entry
144297144261
*/
144298144262
if( !db->init.busy ){
144299144263
Vdbe *v;
144300144264
char *z;
144265
+
144266
+ /* If this is a new CREATE TABLE statement, and if shadow tables
144267
+ ** are read-only, and the trigger makes a change to a shadow table,
144268
+ ** then raise an error - do not allow the trigger to be created. */
144269
+ if( sqlite3ReadOnlyShadowTables(db) ){
144270
+ TriggerStep *pStep;
144271
+ for(pStep=pTrig->step_list; pStep; pStep=pStep->pNext){
144272
+ if( pStep->zTarget!=0
144273
+ && sqlite3ShadowTableName(db, pStep->zTarget)
144274
+ ){
144275
+ sqlite3ErrorMsg(pParse,
144276
+ "trigger \"%s\" may not write to shadow table \"%s\"",
144277
+ pTrig->zName, pStep->zTarget);
144278
+ goto triggerfinish_cleanup;
144279
+ }
144280
+ }
144281
+ }
144301144282
144302144283
/* Make an entry in the sqlite_schema table */
144303144284
v = sqlite3GetVdbe(pParse);
144304144285
if( v==0 ) goto triggerfinish_cleanup;
144305144286
sqlite3BeginWriteOperation(pParse, 0, iDb);
@@ -155004,10 +154985,47 @@
155004154985
}
155005154986
#else
155006154987
#define whereTraceIndexInfoInputs(A)
155007154988
#define whereTraceIndexInfoOutputs(A)
155008154989
#endif
154990
+
154991
+/*
154992
+** We know that pSrc is an operand of an outer join. Return true if
154993
+** pTerm is a constraint that is compatible with that join.
154994
+**
154995
+** pTerm must be EP_OuterON if pSrc is the right operand of an
154996
+** outer join. pTerm can be either EP_OuterON or EP_InnerON if pSrc
154997
+** is the left operand of a RIGHT join.
154998
+**
154999
+** See https://sqlite.org/forum/forumpost/206d99a16dd9212f
155000
+** for an example of a WHERE clause constraints that may not be used on
155001
+** the right table of a RIGHT JOIN because the constraint implies a
155002
+** not-NULL condition on the left table of the RIGHT JOIN.
155003
+*/
155004
+static int constraintCompatibleWithOuterJoin(
155005
+ const WhereTerm *pTerm, /* WHERE clause term to check */
155006
+ const SrcItem *pSrc /* Table we are trying to access */
155007
+){
155008
+ assert( (pSrc->fg.jointype&(JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ); /* By caller */
155009
+ testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT );
155010
+ testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ );
155011
+ testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) )
155012
+ testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) );
155013
+ if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON)
155014
+ || pTerm->pExpr->w.iJoin != pSrc->iCursor
155015
+ ){
155016
+ return 0;
155017
+ }
155018
+ if( (pSrc->fg.jointype & (JT_LEFT|JT_RIGHT))!=0
155019
+ && ExprHasProperty(pTerm->pExpr, EP_InnerON)
155020
+ ){
155021
+ return 0;
155022
+ }
155023
+ return 1;
155024
+}
155025
+
155026
+
155009155027
155010155028
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
155011155029
/*
155012155030
** Return TRUE if the WHERE clause term pTerm is of a form where it
155013155031
** could be used with an index to access pSrc, assuming an appropriate
@@ -155020,20 +155038,14 @@
155020155038
){
155021155039
char aff;
155022155040
if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
155023155041
if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
155024155042
assert( (pSrc->fg.jointype & JT_RIGHT)==0 );
155025
- if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){
155026
- testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT );
155027
- testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ );
155028
- testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) )
155029
- testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) );
155030
- if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON)
155031
- || pTerm->pExpr->w.iJoin != pSrc->iCursor
155032
- ){
155033
- return 0; /* See tag-20191211-001 */
155034
- }
155043
+ if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0
155044
+ && !constraintCompatibleWithOuterJoin(pTerm,pSrc)
155045
+ ){
155046
+ return 0; /* See https://sqlite.org/forum/forumpost/51e6959f61 */
155035155047
}
155036155048
if( (pTerm->prereqRight & notReady)!=0 ) return 0;
155037155049
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
155038155050
if( pTerm->u.x.leftColumn<0 ) return 0;
155039155051
aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity;
@@ -155441,26 +155453,14 @@
155441155453
if( pTerm->wtFlags & TERM_VNULL ) continue;
155442155454
155443155455
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
155444155456
assert( pTerm->u.x.leftColumn>=XN_ROWID );
155445155457
assert( pTerm->u.x.leftColumn<pTab->nCol );
155446
-
155447
- /* tag-20191211-002: WHERE-clause constraints are not useful to the
155448
- ** right-hand table of a LEFT JOIN nor to the either table of a
155449
- ** RIGHT JOIN. See tag-20191211-001 for the
155450
- ** equivalent restriction for ordinary tables. */
155451
- if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){
155452
- testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT );
155453
- testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_RIGHT );
155454
- testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ );
155455
- testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) );
155456
- testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) );
155457
- if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON)
155458
- || pTerm->pExpr->w.iJoin != pSrc->iCursor
155459
- ){
155460
- continue;
155461
- }
155458
+ if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0
155459
+ && !constraintCompatibleWithOuterJoin(pTerm,pSrc)
155460
+ ){
155461
+ continue;
155462155462
}
155463155463
nTerm++;
155464155464
pTerm->wtFlags |= TERM_OK;
155465155465
}
155466155466
@@ -157114,36 +157114,15 @@
157114157114
157115157115
/* Do not allow the upper bound of a LIKE optimization range constraint
157116157116
** to mix with a lower range bound from some other source */
157117157117
if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;
157118157118
157119
- /* tag-20191211-001: Do not allow constraints from the WHERE clause to
157120
- ** be used by the right table of a LEFT JOIN nor by the left table of a
157121
- ** RIGHT JOIN. Only constraints in the ON clause are allowed.
157122
- ** See tag-20191211-002 for the vtab equivalent.
157123
- **
157124
- ** 2022-06-06: See https://sqlite.org/forum/forumpost/206d99a16dd9212f
157125
- ** for an example of a WHERE clause constraints that may not be used on
157126
- ** the right table of a RIGHT JOIN because the constraint implies a
157127
- ** not-NULL condition on the left table of the RIGHT JOIN.
157128
- **
157129
- ** 2022-06-10: The same condition applies to termCanDriveIndex() above.
157130
- ** https://sqlite.org/forum/forumpost/51e6959f61
157131
- */
157132
- if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){
157133
- testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT );
157134
- testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_RIGHT );
157135
- testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ );
157136
- testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) )
157137
- testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) );
157138
- if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON)
157139
- || pTerm->pExpr->w.iJoin != pSrc->iCursor
157140
- ){
157141
- continue;
157142
- }
157143
- }
157144
-
157119
+ if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0
157120
+ && !constraintCompatibleWithOuterJoin(pTerm,pSrc)
157121
+ ){
157122
+ continue;
157123
+ }
157145157124
if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){
157146157125
pBuilder->bldFlags1 |= SQLITE_BLDF1_UNIQUE;
157147157126
}else{
157148157127
pBuilder->bldFlags1 |= SQLITE_BLDF1_INDEXED;
157149157128
}
@@ -177299,11 +177278,11 @@
177299177278
Fts3SegReader **apSegment; /* Array of Fts3SegReader objects */
177300177279
int nSegment; /* Size of apSegment array */
177301177280
int nAdvance; /* How many seg-readers to advance */
177302177281
Fts3SegFilter *pFilter; /* Pointer to filter object */
177303177282
char *aBuffer; /* Buffer to merge doclists in */
177304
- int nBuffer; /* Allocated size of aBuffer[] in bytes */
177283
+ i64 nBuffer; /* Allocated size of aBuffer[] in bytes */
177305177284
177306177285
int iColFilter; /* If >=0, filter for this column */
177307177286
int bRestart;
177308177287
177309177288
/* Used by fts3.c only. */
@@ -179995,11 +179974,11 @@
179995179974
** as a single-byte delta, whereas in the second it must be stored as a
179996179975
** FTS3_VARINT_MAX byte varint.
179997179976
**
179998179977
** Similar padding is added in the fts3DoclistOrMerge() function.
179999179978
*/
180000
- pTS->aaOutput[0] = sqlite3_malloc(nDoclist + FTS3_VARINT_MAX + 1);
179979
+ pTS->aaOutput[0] = sqlite3_malloc64((i64)nDoclist + FTS3_VARINT_MAX + 1);
180001179980
pTS->anOutput[0] = nDoclist;
180002179981
if( pTS->aaOutput[0] ){
180003179982
memcpy(pTS->aaOutput[0], aDoclist, nDoclist);
180004179983
memset(&pTS->aaOutput[0][nDoclist], 0, FTS3_VARINT_MAX);
180005179984
}else{
@@ -181852,11 +181831,11 @@
181852181831
181853181832
/* Check if the current entries really are a phrase match */
181854181833
if( bEof==0 ){
181855181834
int nList = 0;
181856181835
int nByte = a[p->nToken-1].nList;
181857
- char *aDoclist = sqlite3_malloc(nByte+FTS3_BUFFER_PADDING);
181836
+ char *aDoclist = sqlite3_malloc64((i64)nByte+FTS3_BUFFER_PADDING);
181858181837
if( !aDoclist ) return SQLITE_NOMEM;
181859181838
memcpy(aDoclist, a[p->nToken-1].pList, nByte+1);
181860181839
memset(&aDoclist[nByte], 0, FTS3_BUFFER_PADDING);
181861181840
181862181841
for(i=0; i<(p->nToken-1); i++){
@@ -186088,11 +186067,11 @@
186088186067
if( c->iOffset>iStartOffset ){
186089186068
int n = c->iOffset-iStartOffset;
186090186069
if( n>c->nAllocated ){
186091186070
char *pNew;
186092186071
c->nAllocated = n+20;
186093
- pNew = sqlite3_realloc(c->zToken, c->nAllocated);
186072
+ pNew = sqlite3_realloc64(c->zToken, c->nAllocated);
186094186073
if( !pNew ) return SQLITE_NOMEM;
186095186074
c->zToken = pNew;
186096186075
}
186097186076
porter_stemmer(&z[iStartOffset], n, c->zToken, pnBytes);
186098186077
*pzToken = c->zToken;
@@ -186840,11 +186819,11 @@
186840186819
if( c->iOffset>iStartOffset ){
186841186820
int i, n = c->iOffset-iStartOffset;
186842186821
if( n>c->nTokenAllocated ){
186843186822
char *pNew;
186844186823
c->nTokenAllocated = n+20;
186845
- pNew = sqlite3_realloc(c->pToken, c->nTokenAllocated);
186824
+ pNew = sqlite3_realloc64(c->pToken, c->nTokenAllocated);
186846186825
if( !pNew ) return SQLITE_NOMEM;
186847186826
c->pToken = pNew;
186848186827
}
186849186828
for(i=0; i<n; i++){
186850186829
/* TODO(shess) This needs expansion to handle UTF-8
@@ -188002,27 +187981,27 @@
188002187981
){
188003187982
PendingList *p = *pp;
188004187983
188005187984
/* Allocate or grow the PendingList as required. */
188006187985
if( !p ){
188007
- p = sqlite3_malloc(sizeof(*p) + 100);
187986
+ p = sqlite3_malloc64(sizeof(*p) + 100);
188008187987
if( !p ){
188009187988
return SQLITE_NOMEM;
188010187989
}
188011187990
p->nSpace = 100;
188012187991
p->aData = (char *)&p[1];
188013187992
p->nData = 0;
188014187993
}
188015187994
else if( p->nData+FTS3_VARINT_MAX+1>p->nSpace ){
188016
- int nNew = p->nSpace * 2;
188017
- p = sqlite3_realloc(p, sizeof(*p) + nNew);
187995
+ i64 nNew = p->nSpace * 2;
187996
+ p = sqlite3_realloc64(p, sizeof(*p) + nNew);
188018187997
if( !p ){
188019187998
sqlite3_free(*pp);
188020187999
*pp = 0;
188021188000
return SQLITE_NOMEM;
188022188001
}
188023
- p->nSpace = nNew;
188002
+ p->nSpace = (int)nNew;
188024188003
p->aData = (char *)&p[1];
188025188004
}
188026188005
188027188006
/* Append the new serialized varint to the end of the list. */
188028188007
p->nData += sqlite3Fts3PutVarint(&p->aData[p->nData], i);
@@ -188575,11 +188554,11 @@
188575188554
188576188555
if( rc==SQLITE_OK ){
188577188556
int nByte = sqlite3_blob_bytes(p->pSegments);
188578188557
*pnBlob = nByte;
188579188558
if( paBlob ){
188580
- char *aByte = sqlite3_malloc(nByte + FTS3_NODE_PADDING);
188559
+ char *aByte = sqlite3_malloc64((i64)nByte + FTS3_NODE_PADDING);
188581188560
if( !aByte ){
188582188561
rc = SQLITE_NOMEM;
188583188562
}else{
188584188563
if( pnLoad && nByte>(FTS3_NODE_CHUNK_THRESHOLD) ){
188585188564
nByte = FTS3_NODE_CHUNKSIZE;
@@ -188692,19 +188671,19 @@
188692188671
int nCopy = pList->nData+1;
188693188672
188694188673
int nTerm = fts3HashKeysize(pElem);
188695188674
if( (nTerm+1)>pReader->nTermAlloc ){
188696188675
sqlite3_free(pReader->zTerm);
188697
- pReader->zTerm = (char*)sqlite3_malloc((nTerm+1)*2);
188676
+ pReader->zTerm = (char*)sqlite3_malloc64(((i64)nTerm+1)*2);
188698188677
if( !pReader->zTerm ) return SQLITE_NOMEM;
188699188678
pReader->nTermAlloc = (nTerm+1)*2;
188700188679
}
188701188680
memcpy(pReader->zTerm, fts3HashKey(pElem), nTerm);
188702188681
pReader->zTerm[nTerm] = '\0';
188703188682
pReader->nTerm = nTerm;
188704188683
188705
- aCopy = (char*)sqlite3_malloc(nCopy);
188684
+ aCopy = (char*)sqlite3_malloc64(nCopy);
188706188685
if( !aCopy ) return SQLITE_NOMEM;
188707188686
memcpy(aCopy, pList->aData, nCopy);
188708188687
pReader->nNode = pReader->nDoclist = nCopy;
188709188688
pReader->aNode = pReader->aDoclist = aCopy;
188710188689
pReader->ppNextElem++;
@@ -188987,11 +188966,11 @@
188987188966
if( iStartLeaf==0 ){
188988188967
if( iEndLeaf!=0 ) return FTS_CORRUPT_VTAB;
188989188968
nExtra = nRoot + FTS3_NODE_PADDING;
188990188969
}
188991188970
188992
- pReader = (Fts3SegReader *)sqlite3_malloc(sizeof(Fts3SegReader) + nExtra);
188971
+ pReader = (Fts3SegReader *)sqlite3_malloc64(sizeof(Fts3SegReader) + nExtra);
188993188972
if( !pReader ){
188994188973
return SQLITE_NOMEM;
188995188974
}
188996188975
memset(pReader, 0, sizeof(Fts3SegReader));
188997188976
pReader->iIdx = iAge;
@@ -189079,11 +189058,11 @@
189079189058
int nKey = fts3HashKeysize(pE);
189080189059
if( nTerm==0 || (nKey>=nTerm && 0==memcmp(zKey, zTerm, nTerm)) ){
189081189060
if( nElem==nAlloc ){
189082189061
Fts3HashElem **aElem2;
189083189062
nAlloc += 16;
189084
- aElem2 = (Fts3HashElem **)sqlite3_realloc(
189063
+ aElem2 = (Fts3HashElem **)sqlite3_realloc64(
189085189064
aElem, nAlloc*sizeof(Fts3HashElem *)
189086189065
);
189087189066
if( !aElem2 ){
189088189067
rc = SQLITE_NOMEM;
189089189068
nElem = 0;
@@ -189413,11 +189392,11 @@
189413189392
** p->nNodeSize bytes, but since this scenario only comes about when
189414189393
** the database contain two terms that share a prefix of almost 2KB,
189415189394
** this is not expected to be a serious problem.
189416189395
*/
189417189396
assert( pTree->aData==(char *)&pTree[1] );
189418
- pTree->aData = (char *)sqlite3_malloc(nReq);
189397
+ pTree->aData = (char *)sqlite3_malloc64(nReq);
189419189398
if( !pTree->aData ){
189420189399
return SQLITE_NOMEM;
189421189400
}
189422189401
}
189423189402
@@ -189431,11 +189410,11 @@
189431189410
pTree->nData = nData + nSuffix;
189432189411
pTree->nEntry++;
189433189412
189434189413
if( isCopyTerm ){
189435189414
if( pTree->nMalloc<nTerm ){
189436
- char *zNew = sqlite3_realloc(pTree->zMalloc, nTerm*2);
189415
+ char *zNew = sqlite3_realloc64(pTree->zMalloc, (i64)nTerm*2);
189437189416
if( !zNew ){
189438189417
return SQLITE_NOMEM;
189439189418
}
189440189419
pTree->nMalloc = nTerm*2;
189441189420
pTree->zMalloc = zNew;
@@ -189457,11 +189436,11 @@
189457189436
**
189458189437
** Otherwise, the term is not added to the new node, it is left empty for
189459189438
** now. Instead, the term is inserted into the parent of pTree. If pTree
189460189439
** has no parent, one is created here.
189461189440
*/
189462
- pNew = (SegmentNode *)sqlite3_malloc(sizeof(SegmentNode) + p->nNodeSize);
189441
+ pNew = (SegmentNode *)sqlite3_malloc64(sizeof(SegmentNode) + p->nNodeSize);
189463189442
if( !pNew ){
189464189443
return SQLITE_NOMEM;
189465189444
}
189466189445
memset(pNew, 0, sizeof(SegmentNode));
189467189446
pNew->nData = 1 + FTS3_VARINT_MAX;
@@ -189595,26 +189574,26 @@
189595189574
const char *aDoclist, /* Pointer to buffer containing doclist */
189596189575
int nDoclist /* Size of doclist in bytes */
189597189576
){
189598189577
int nPrefix; /* Size of term prefix in bytes */
189599189578
int nSuffix; /* Size of term suffix in bytes */
189600
- int nReq; /* Number of bytes required on leaf page */
189579
+ i64 nReq; /* Number of bytes required on leaf page */
189601189580
int nData;
189602189581
SegmentWriter *pWriter = *ppWriter;
189603189582
189604189583
if( !pWriter ){
189605189584
int rc;
189606189585
sqlite3_stmt *pStmt;
189607189586
189608189587
/* Allocate the SegmentWriter structure */
189609
- pWriter = (SegmentWriter *)sqlite3_malloc(sizeof(SegmentWriter));
189588
+ pWriter = (SegmentWriter *)sqlite3_malloc64(sizeof(SegmentWriter));
189610189589
if( !pWriter ) return SQLITE_NOMEM;
189611189590
memset(pWriter, 0, sizeof(SegmentWriter));
189612189591
*ppWriter = pWriter;
189613189592
189614189593
/* Allocate a buffer in which to accumulate data */
189615
- pWriter->aData = (char *)sqlite3_malloc(p->nNodeSize);
189594
+ pWriter->aData = (char *)sqlite3_malloc64(p->nNodeSize);
189616189595
if( !pWriter->aData ) return SQLITE_NOMEM;
189617189596
pWriter->nSize = p->nNodeSize;
189618189597
189619189598
/* Find the next free blockid in the %_segments table */
189620189599
rc = fts3SqlStmt(p, SQL_NEXT_SEGMENTS_ID, &pStmt, 0);
@@ -189685,11 +189664,11 @@
189685189664
189686189665
/* If the buffer currently allocated is too small for this entry, realloc
189687189666
** the buffer to make it large enough.
189688189667
*/
189689189668
if( nReq>pWriter->nSize ){
189690
- char *aNew = sqlite3_realloc(pWriter->aData, nReq);
189669
+ char *aNew = sqlite3_realloc64(pWriter->aData, nReq);
189691189670
if( !aNew ) return SQLITE_NOMEM;
189692189671
pWriter->aData = aNew;
189693189672
pWriter->nSize = nReq;
189694189673
}
189695189674
assert( nData+nReq<=pWriter->nSize );
@@ -189710,11 +189689,11 @@
189710189689
** zTerm is transient, so take a copy of the term data. Otherwise, just
189711189690
** store a copy of the pointer.
189712189691
*/
189713189692
if( isCopyTerm ){
189714189693
if( nTerm>pWriter->nMalloc ){
189715
- char *zNew = sqlite3_realloc(pWriter->zMalloc, nTerm*2);
189694
+ char *zNew = sqlite3_realloc64(pWriter->zMalloc, (i64)nTerm*2);
189716189695
if( !zNew ){
189717189696
return SQLITE_NOMEM;
189718189697
}
189719189698
pWriter->nMalloc = nTerm*2;
189720189699
pWriter->zMalloc = zNew;
@@ -190018,16 +189997,16 @@
190018189997
** trying to resize the buffer, return SQLITE_NOMEM.
190019189998
*/
190020189999
static int fts3MsrBufferData(
190021190000
Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */
190022190001
char *pList,
190023
- int nList
190002
+ i64 nList
190024190003
){
190025190004
if( nList>pMsr->nBuffer ){
190026190005
char *pNew;
190027190006
pMsr->nBuffer = nList*2;
190028
- pNew = (char *)sqlite3_realloc(pMsr->aBuffer, pMsr->nBuffer);
190007
+ pNew = (char *)sqlite3_realloc64(pMsr->aBuffer, pMsr->nBuffer);
190029190008
if( !pNew ) return SQLITE_NOMEM;
190030190009
pMsr->aBuffer = pNew;
190031190010
}
190032190011
190033190012
assert( nList>0 );
@@ -190079,11 +190058,11 @@
190079190058
}
190080190059
if( rc!=SQLITE_OK ) return rc;
190081190060
fts3SegReaderSort(pMsr->apSegment, nMerge, j, xCmp);
190082190061
190083190062
if( nList>0 && fts3SegReaderIsPending(apSegment[0]) ){
190084
- rc = fts3MsrBufferData(pMsr, pList, nList+1);
190063
+ rc = fts3MsrBufferData(pMsr, pList, (i64)nList+1);
190085190064
if( rc!=SQLITE_OK ) return rc;
190086190065
assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 );
190087190066
pList = pMsr->aBuffer;
190088190067
}
190089190068
@@ -190216,15 +190195,15 @@
190216190195
}
190217190196
190218190197
return SQLITE_OK;
190219190198
}
190220190199
190221
-static int fts3GrowSegReaderBuffer(Fts3MultiSegReader *pCsr, int nReq){
190200
+static int fts3GrowSegReaderBuffer(Fts3MultiSegReader *pCsr, i64 nReq){
190222190201
if( nReq>pCsr->nBuffer ){
190223190202
char *aNew;
190224190203
pCsr->nBuffer = nReq*2;
190225
- aNew = sqlite3_realloc(pCsr->aBuffer, pCsr->nBuffer);
190204
+ aNew = sqlite3_realloc64(pCsr->aBuffer, pCsr->nBuffer);
190226190205
if( !aNew ){
190227190206
return SQLITE_NOMEM;
190228190207
}
190229190208
pCsr->aBuffer = aNew;
190230190209
}
@@ -190311,11 +190290,12 @@
190311190290
&& !isFirst
190312190291
&& (p->bDescIdx==0 || fts3SegReaderIsPending(apSegment[0])==0)
190313190292
){
190314190293
pCsr->nDoclist = apSegment[0]->nDoclist;
190315190294
if( fts3SegReaderIsPending(apSegment[0]) ){
190316
- rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, pCsr->nDoclist);
190295
+ rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist,
190296
+ (i64)pCsr->nDoclist);
190317190297
pCsr->aDoclist = pCsr->aBuffer;
190318190298
}else{
190319190299
pCsr->aDoclist = apSegment[0]->aDoclist;
190320190300
}
190321190301
if( rc==SQLITE_OK ) rc = SQLITE_ROW;
@@ -190364,11 +190344,12 @@
190364190344
iDelta = (i64)((u64)iDocid - (u64)iPrev);
190365190345
}
190366190346
190367190347
nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0);
190368190348
190369
- rc = fts3GrowSegReaderBuffer(pCsr, nByte+nDoclist+FTS3_NODE_PADDING);
190349
+ rc = fts3GrowSegReaderBuffer(pCsr,
190350
+ (i64)nByte+nDoclist+FTS3_NODE_PADDING);
190370190351
if( rc ) return rc;
190371190352
190372190353
if( isFirst ){
190373190354
char *a = &pCsr->aBuffer[nDoclist];
190374190355
int nWrite;
@@ -190390,11 +190371,11 @@
190390190371
}
190391190372
190392190373
fts3SegReaderSort(apSegment, nMerge, j, xCmp);
190393190374
}
190394190375
if( nDoclist>0 ){
190395
- rc = fts3GrowSegReaderBuffer(pCsr, nDoclist+FTS3_NODE_PADDING);
190376
+ rc = fts3GrowSegReaderBuffer(pCsr, (i64)nDoclist+FTS3_NODE_PADDING);
190396190377
if( rc ) return rc;
190397190378
memset(&pCsr->aBuffer[nDoclist], 0, FTS3_NODE_PADDING);
190398190379
pCsr->aDoclist = pCsr->aBuffer;
190399190380
pCsr->nDoclist = nDoclist;
190400190381
rc = SQLITE_ROW;
@@ -191103,11 +191084,11 @@
191103191084
** to reflect the new size of the pBlob->a[] buffer.
191104191085
*/
191105191086
static void blobGrowBuffer(Blob *pBlob, int nMin, int *pRc){
191106191087
if( *pRc==SQLITE_OK && nMin>pBlob->nAlloc ){
191107191088
int nAlloc = nMin;
191108
- char *a = (char *)sqlite3_realloc(pBlob->a, nAlloc);
191089
+ char *a = (char *)sqlite3_realloc64(pBlob->a, nAlloc);
191109191090
if( a ){
191110191091
pBlob->nAlloc = nAlloc;
191111191092
pBlob->a = a;
191112191093
}else{
191113191094
*pRc = SQLITE_NOMEM;
@@ -191900,11 +191881,11 @@
191900191881
sqlite3_bind_int64(pSelect, 1, iAbsLevel);
191901191882
while( SQLITE_ROW==sqlite3_step(pSelect) ){
191902191883
if( nIdx>=nAlloc ){
191903191884
int *aNew;
191904191885
nAlloc += 16;
191905
- aNew = sqlite3_realloc(aIdx, nAlloc*sizeof(int));
191886
+ aNew = sqlite3_realloc64(aIdx, nAlloc*sizeof(int));
191906191887
if( !aNew ){
191907191888
rc = SQLITE_NOMEM;
191908191889
break;
191909191890
}
191910191891
aIdx = aNew;
@@ -192274,11 +192255,11 @@
192274192255
Blob hint = {0, 0, 0}; /* Hint read from %_stat table */
192275192256
int bDirtyHint = 0; /* True if blob 'hint' has been modified */
192276192257
192277192258
/* Allocate space for the cursor, filter and writer objects */
192278192259
const int nAlloc = sizeof(*pCsr) + sizeof(*pFilter) + sizeof(*pWriter);
192279
- pWriter = (IncrmergeWriter *)sqlite3_malloc(nAlloc);
192260
+ pWriter = (IncrmergeWriter *)sqlite3_malloc64(nAlloc);
192280192261
if( !pWriter ) return SQLITE_NOMEM;
192281192262
pFilter = (Fts3SegFilter *)&pWriter[1];
192282192263
pCsr = (Fts3MultiSegReader *)&pFilter[1];
192283192264
192284192265
rc = fts3IncrmergeHintLoad(p, &hint);
@@ -192910,11 +192891,11 @@
192910192891
192911192892
if( p->pList==0 ){
192912192893
return SQLITE_OK;
192913192894
}
192914192895
192915
- pRet = (char *)sqlite3_malloc(p->pList->nData);
192896
+ pRet = (char *)sqlite3_malloc64(p->pList->nData);
192916192897
if( !pRet ) return SQLITE_NOMEM;
192917192898
192918192899
nSkip = sqlite3Fts3GetVarint(p->pList->aData, &dummy);
192919192900
*pnData = p->pList->nData - nSkip;
192920192901
*ppData = pRet;
@@ -192930,11 +192911,11 @@
192930192911
Fts3Cursor *pCsr, /* Fts3 table cursor */
192931192912
Fts3PhraseToken *pToken, /* Token to defer */
192932192913
int iCol /* Column that token must appear in (or -1) */
192933192914
){
192934192915
Fts3DeferredToken *pDeferred;
192935
- pDeferred = sqlite3_malloc(sizeof(*pDeferred));
192916
+ pDeferred = sqlite3_malloc64(sizeof(*pDeferred));
192936192917
if( !pDeferred ){
192937192918
return SQLITE_NOMEM;
192938192919
}
192939192920
memset(pDeferred, 0, sizeof(*pDeferred));
192940192921
pDeferred->pToken = pToken;
@@ -205112,12 +205093,13 @@
205112205093
}
205113205094
pExpr = uregex_open(zPattern, -1, 0, 0, &status);
205114205095
205115205096
if( U_SUCCESS(status) ){
205116205097
sqlite3_set_auxdata(p, 0, pExpr, icuRegexpDelete);
205117
- }else{
205118
- assert(!pExpr);
205098
+ pExpr = sqlite3_get_auxdata(p, 0);
205099
+ }
205100
+ if( !pExpr ){
205119205101
icuFunctionError(p, "uregex_open", status);
205120205102
return;
205121205103
}
205122205104
}
205123205105
@@ -237002,11 +236984,11 @@
237002236984
int nArg, /* Number of args */
237003236985
sqlite3_value **apUnused /* Function arguments */
237004236986
){
237005236987
assert( nArg==0 );
237006236988
UNUSED_PARAM2(nArg, apUnused);
237007
- sqlite3_result_text(pCtx, "fts5: 2022-09-02 21:19:24 da7af290960ab8a04a1f55cdc5eeac36b47fa194edf67f0a05daa4b7f2a4071c", -1, SQLITE_TRANSIENT);
236989
+ sqlite3_result_text(pCtx, "fts5: 2022-09-28 19:14:01 f25cf63471cbed1edb27591e57fead62550d4046dbdcb61312288f0f6f24c646", -1, SQLITE_TRANSIENT);
237008236990
}
237009236991
237010236992
/*
237011236993
** Return true if zName is the extension on one of the shadow tables used
237012236994
** by this module.
237013236995
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -452,11 +452,11 @@
452 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
453 ** [sqlite_version()] and [sqlite_source_id()].
454 */
455 #define SQLITE_VERSION "3.40.0"
456 #define SQLITE_VERSION_NUMBER 3040000
457 #define SQLITE_SOURCE_ID "2022-09-02 21:19:24 da7af290960ab8a04a1f55cdc5eeac36b47fa194edf67f0a05daa4b7f2a4071c"
458
459 /*
460 ** CAPI3REF: Run-Time Library Version Numbers
461 ** KEYWORDS: sqlite3_version sqlite3_sourceid
462 **
@@ -29076,22 +29076,38 @@
29076 sqlite3StatusUp(SQLITE_STATUS_MALLOC_COUNT, 1);
29077 }
29078 *pp = p;
29079 }
29080
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29081 /*
29082 ** Allocate memory. This routine is like sqlite3_malloc() except that it
29083 ** assumes the memory subsystem has already been initialized.
29084 */
29085 SQLITE_PRIVATE void *sqlite3Malloc(u64 n){
29086 void *p;
29087 if( n==0 || n>=0x7fffff00 ){
29088 /* A memory allocation of a number of bytes which is near the maximum
29089 ** signed integer value might cause an integer overflow inside of the
29090 ** xMalloc(). Hence we limit the maximum size to 0x7fffff00, giving
29091 ** 255 bytes of overhead. SQLite itself will never use anything near
29092 ** this amount. The only way to reach the limit is with sqlite3_malloc() */
29093 p = 0;
29094 }else if( sqlite3GlobalConfig.bMemstat ){
29095 sqlite3_mutex_enter(mem0.mutex);
29096 mallocWithAlarm((int)n, &p);
29097 sqlite3_mutex_leave(mem0.mutex);
@@ -45571,12 +45587,13 @@
45571 SQLITE_API int sqlite3_win32_set_directory8(
45572 unsigned long type, /* Identifier for directory being set or reset */
45573 const char *zValue /* New value for directory being set or reset */
45574 ){
45575 char **ppDirectory = 0;
 
45576 #ifndef SQLITE_OMIT_AUTOINIT
45577 int rc = sqlite3_initialize();
45578 if( rc ) return rc;
45579 #endif
45580 sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
45581 if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){
45582 ppDirectory = &sqlite3_data_directory;
@@ -49415,11 +49432,12 @@
49415 const char *zRelative, /* Possibly relative input path */
49416 int nFull, /* Size of output buffer in bytes */
49417 char *zFull /* Output buffer */
49418 ){
49419 int rc;
49420 sqlite3_mutex *pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR);
 
49421 sqlite3_mutex_enter(pMutex);
49422 rc = winFullPathnameNoMutex(pVfs, zRelative, nFull, zFull);
49423 sqlite3_mutex_leave(pMutex);
49424 return rc;
49425 }
@@ -51798,18 +51816,18 @@
51798 assert( p->nRef>0 );
51799 assert( newPgno>0 );
51800 assert( sqlite3PcachePageSanity(p) );
51801 pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno));
51802 pOther = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, newPgno, 0);
51803 sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
51804 if( pOther ){
51805 PgHdr *pPg = (PgHdr*)pOther->pExtra;
51806 pPg->pgno = p->pgno;
51807 if( pPg->pPage==0 ){
51808 sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pOther, 0);
51809 }
51810 }
 
51811 p->pgno = newPgno;
51812 if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
51813 pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
51814 assert( sqlite3PcachePageSanity(p) );
51815 }
@@ -53202,27 +53220,12 @@
53202 while( (*pp)!=pPage ){
53203 pp = &(*pp)->pNext;
53204 }
53205 *pp = pPage->pNext;
53206
 
53207 hNew = iNew%pCache->nHash;
53208 pp = &pCache->apHash[hNew];
53209 while( *pp ){
53210 if( (*pp)->iKey==iNew ){
53211 /* If there is already another pcache entry at iNew, change it to iOld,
53212 ** thus swapping the positions of iNew and iOld */
53213 PgHdr1 *pOld = *pp;
53214 *pp = pOld->pNext;
53215 pOld->pNext = pCache->apHash[hOld];
53216 pCache->apHash[hOld] = pOld;
53217 pOld->iKey = iOld;
53218 break;
53219 }else{
53220 pp = &(*pp)->pNext;
53221 }
53222 }
53223
53224 pPage->iKey = iNew;
53225 pPage->pNext = pCache->apHash[hNew];
53226 pCache->apHash[hNew] = pPage;
53227 if( iNew>pCache->iMaxKey ){
53228 pCache->iMaxKey = iNew;
@@ -68523,11 +68526,11 @@
68523 if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage);
68524 sz2 = get2byte(&data[iFree2+2]);
68525 if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
68526 memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
68527 sz += sz2;
68528 }else if( NEVER(iFree+sz>usableSize) ){
68529 return SQLITE_CORRUPT_PAGE(pPage);
68530 }
68531
68532 cbrk = top+sz;
68533 assert( cbrk+(iFree-top) <= usableSize );
@@ -93400,16 +93403,20 @@
93400 }
93401
93402 /* Opcode: IfNotOpen P1 P2 * * *
93403 ** Synopsis: if( !csr[P1] ) goto P2
93404 **
93405 ** If cursor P1 is not open, jump to instruction P2. Otherwise, fall through.
 
93406 */
93407 case OP_IfNotOpen: { /* jump */
 
 
93408 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
93409 VdbeBranchTaken(p->apCsr[pOp->p1]==0, 2);
93410 if( !p->apCsr[pOp->p1] ){
 
93411 goto jump_to_p2_and_check_for_interrupt;
93412 }
93413 break;
93414 }
93415
@@ -107028,10 +107035,11 @@
107028 }
107029 if( pKeyInfo ){
107030 sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
107031 }
107032 if( addrOnce ){
 
107033 sqlite3VdbeJumpHere(v, addrOnce);
107034 /* Subroutine return */
107035 assert( ExprUseYSub(pExpr) );
107036 assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
107037 || pParse->nErr );
@@ -139569,11 +139577,11 @@
139569 ** position in the parent that NULL-able due to an OUTER JOIN. Either the
139570 ** target slot in the parent is the right operand of a LEFT JOIN, or one of
139571 ** the left operands of a RIGHT JOIN. In either case, we need to potentially
139572 ** bypass the substituted expression with OP_IfNullRow.
139573 **
139574 ** Suppose the original expression integer constant. Even though the table
139575 ** has the nullRow flag set, because the expression is an integer constant,
139576 ** it will not be NULLed out. So instead, we insert an OP_IfNullRow opcode
139577 ** that checks to see if the nullRow flag is set on the table. If the nullRow
139578 ** flag is set, then the value in the register is set to NULL and the original
139579 ** expression is bypassed. If the nullRow flag is not set, then the original
@@ -140026,23 +140034,17 @@
140026 **
140027 ** (26) The subquery may not be the right operand of a RIGHT JOIN.
140028 ** See also (3) for restrictions on LEFT JOIN.
140029 **
140030 ** (27) The subquery may not contain a FULL or RIGHT JOIN unless it
140031 ** is the first element of the parent query. This must be the
140032 ** the case if:
140033 ** (27a) the subquery is not compound query, and
140034 ** (27b) the subquery is a compound query and the RIGHT JOIN occurs
140035 ** in any arm of the compound query. (See also (17g).)
140036 **
140037 ** (28) The subquery is not a MATERIALIZED CTE.
140038 **
140039 ** (29) Either the subquery is not the right-hand operand of a join with an
140040 ** ON or USING clause nor the right-hand operand of a NATURAL JOIN, or
140041 ** the right-most table within the FROM clause of the subquery
140042 ** is not part of an outer join.
140043 **
140044 **
140045 ** In this routine, the "p" parameter is a pointer to the outer query.
140046 ** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
140047 ** uses aggregates.
140048 **
@@ -140142,57 +140144,19 @@
140142 ){
140143 return 0;
140144 }
140145 isOuterJoin = 1;
140146 }
140147 #ifdef SQLITE_EXTRA_IFNULLROW
140148 else if( iFrom>0 && !isAgg ){
140149 /* Setting isOuterJoin to -1 causes OP_IfNullRow opcodes to be generated for
140150 ** every reference to any result column from subquery in a join, even
140151 ** though they are not necessary. This will stress-test the OP_IfNullRow
140152 ** opcode. */
140153 isOuterJoin = -1;
140154 }
140155 #endif
140156
140157 assert( pSubSrc->nSrc>0 ); /* True by restriction (7) */
140158 if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
140159 return 0; /* Restriction (27a) */
140160 }
140161 if( pSubitem->fg.isCte && pSubitem->u2.pCteUse->eM10d==M10d_Yes ){
140162 return 0; /* (28) */
140163 }
140164
140165 /* Restriction (29):
140166 **
140167 ** We do not want two constraints on the same term of the flattened
140168 ** query where one constraint has EP_InnerON and the other is EP_OuterON.
140169 ** To prevent this, one or the other of the following conditions must be
140170 ** false:
140171 **
140172 ** (29a) The right-most entry in the FROM clause of the subquery
140173 ** must not be part of an outer join.
140174 **
140175 ** (29b) The subquery itself must not be the right operand of a
140176 ** NATURAL join or a join that as an ON or USING clause.
140177 **
140178 ** These conditions are sufficient to keep an EP_OuterON from being
140179 ** flattened into an EP_InnerON. Restrictions (3a) and (27a) prevent
140180 ** an EP_InnerON from being flattened into an EP_OuterON.
140181 */
140182 if( pSubSrc->nSrc>=2
140183 && (pSubSrc->a[pSubSrc->nSrc-1].fg.jointype & JT_OUTER)!=0
140184 ){
140185 if( (pSubitem->fg.jointype & JT_NATURAL)!=0
140186 || pSubitem->fg.isUsing
140187 || NEVER(pSubitem->u3.pOn!=0) /* ON clause already shifted into WHERE */
140188 || pSubitem->fg.isOn
140189 ){
140190 return 0;
140191 }
140192 }
140193
140194 /* Restriction (17): If the sub-query is a compound SELECT, then it must
140195 ** use only the UNION ALL operator. And none of the simple select queries
140196 ** that make up the compound SELECT are allowed to be aggregate or distinct
140197 ** queries.
140198 */
@@ -144296,10 +144260,27 @@
144296 ** build the sqlite_schema entry
144297 */
144298 if( !db->init.busy ){
144299 Vdbe *v;
144300 char *z;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144301
144302 /* Make an entry in the sqlite_schema table */
144303 v = sqlite3GetVdbe(pParse);
144304 if( v==0 ) goto triggerfinish_cleanup;
144305 sqlite3BeginWriteOperation(pParse, 0, iDb);
@@ -155004,10 +154985,47 @@
155004 }
155005 #else
155006 #define whereTraceIndexInfoInputs(A)
155007 #define whereTraceIndexInfoOutputs(A)
155008 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155009
155010 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
155011 /*
155012 ** Return TRUE if the WHERE clause term pTerm is of a form where it
155013 ** could be used with an index to access pSrc, assuming an appropriate
@@ -155020,20 +155038,14 @@
155020 ){
155021 char aff;
155022 if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
155023 if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
155024 assert( (pSrc->fg.jointype & JT_RIGHT)==0 );
155025 if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){
155026 testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT );
155027 testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ );
155028 testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) )
155029 testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) );
155030 if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON)
155031 || pTerm->pExpr->w.iJoin != pSrc->iCursor
155032 ){
155033 return 0; /* See tag-20191211-001 */
155034 }
155035 }
155036 if( (pTerm->prereqRight & notReady)!=0 ) return 0;
155037 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
155038 if( pTerm->u.x.leftColumn<0 ) return 0;
155039 aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity;
@@ -155441,26 +155453,14 @@
155441 if( pTerm->wtFlags & TERM_VNULL ) continue;
155442
155443 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
155444 assert( pTerm->u.x.leftColumn>=XN_ROWID );
155445 assert( pTerm->u.x.leftColumn<pTab->nCol );
155446
155447 /* tag-20191211-002: WHERE-clause constraints are not useful to the
155448 ** right-hand table of a LEFT JOIN nor to the either table of a
155449 ** RIGHT JOIN. See tag-20191211-001 for the
155450 ** equivalent restriction for ordinary tables. */
155451 if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){
155452 testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT );
155453 testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_RIGHT );
155454 testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ );
155455 testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) );
155456 testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) );
155457 if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON)
155458 || pTerm->pExpr->w.iJoin != pSrc->iCursor
155459 ){
155460 continue;
155461 }
155462 }
155463 nTerm++;
155464 pTerm->wtFlags |= TERM_OK;
155465 }
155466
@@ -157114,36 +157114,15 @@
157114
157115 /* Do not allow the upper bound of a LIKE optimization range constraint
157116 ** to mix with a lower range bound from some other source */
157117 if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;
157118
157119 /* tag-20191211-001: Do not allow constraints from the WHERE clause to
157120 ** be used by the right table of a LEFT JOIN nor by the left table of a
157121 ** RIGHT JOIN. Only constraints in the ON clause are allowed.
157122 ** See tag-20191211-002 for the vtab equivalent.
157123 **
157124 ** 2022-06-06: See https://sqlite.org/forum/forumpost/206d99a16dd9212f
157125 ** for an example of a WHERE clause constraints that may not be used on
157126 ** the right table of a RIGHT JOIN because the constraint implies a
157127 ** not-NULL condition on the left table of the RIGHT JOIN.
157128 **
157129 ** 2022-06-10: The same condition applies to termCanDriveIndex() above.
157130 ** https://sqlite.org/forum/forumpost/51e6959f61
157131 */
157132 if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){
157133 testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT );
157134 testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_RIGHT );
157135 testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ );
157136 testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) )
157137 testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) );
157138 if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON)
157139 || pTerm->pExpr->w.iJoin != pSrc->iCursor
157140 ){
157141 continue;
157142 }
157143 }
157144
157145 if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){
157146 pBuilder->bldFlags1 |= SQLITE_BLDF1_UNIQUE;
157147 }else{
157148 pBuilder->bldFlags1 |= SQLITE_BLDF1_INDEXED;
157149 }
@@ -177299,11 +177278,11 @@
177299 Fts3SegReader **apSegment; /* Array of Fts3SegReader objects */
177300 int nSegment; /* Size of apSegment array */
177301 int nAdvance; /* How many seg-readers to advance */
177302 Fts3SegFilter *pFilter; /* Pointer to filter object */
177303 char *aBuffer; /* Buffer to merge doclists in */
177304 int nBuffer; /* Allocated size of aBuffer[] in bytes */
177305
177306 int iColFilter; /* If >=0, filter for this column */
177307 int bRestart;
177308
177309 /* Used by fts3.c only. */
@@ -179995,11 +179974,11 @@
179995 ** as a single-byte delta, whereas in the second it must be stored as a
179996 ** FTS3_VARINT_MAX byte varint.
179997 **
179998 ** Similar padding is added in the fts3DoclistOrMerge() function.
179999 */
180000 pTS->aaOutput[0] = sqlite3_malloc(nDoclist + FTS3_VARINT_MAX + 1);
180001 pTS->anOutput[0] = nDoclist;
180002 if( pTS->aaOutput[0] ){
180003 memcpy(pTS->aaOutput[0], aDoclist, nDoclist);
180004 memset(&pTS->aaOutput[0][nDoclist], 0, FTS3_VARINT_MAX);
180005 }else{
@@ -181852,11 +181831,11 @@
181852
181853 /* Check if the current entries really are a phrase match */
181854 if( bEof==0 ){
181855 int nList = 0;
181856 int nByte = a[p->nToken-1].nList;
181857 char *aDoclist = sqlite3_malloc(nByte+FTS3_BUFFER_PADDING);
181858 if( !aDoclist ) return SQLITE_NOMEM;
181859 memcpy(aDoclist, a[p->nToken-1].pList, nByte+1);
181860 memset(&aDoclist[nByte], 0, FTS3_BUFFER_PADDING);
181861
181862 for(i=0; i<(p->nToken-1); i++){
@@ -186088,11 +186067,11 @@
186088 if( c->iOffset>iStartOffset ){
186089 int n = c->iOffset-iStartOffset;
186090 if( n>c->nAllocated ){
186091 char *pNew;
186092 c->nAllocated = n+20;
186093 pNew = sqlite3_realloc(c->zToken, c->nAllocated);
186094 if( !pNew ) return SQLITE_NOMEM;
186095 c->zToken = pNew;
186096 }
186097 porter_stemmer(&z[iStartOffset], n, c->zToken, pnBytes);
186098 *pzToken = c->zToken;
@@ -186840,11 +186819,11 @@
186840 if( c->iOffset>iStartOffset ){
186841 int i, n = c->iOffset-iStartOffset;
186842 if( n>c->nTokenAllocated ){
186843 char *pNew;
186844 c->nTokenAllocated = n+20;
186845 pNew = sqlite3_realloc(c->pToken, c->nTokenAllocated);
186846 if( !pNew ) return SQLITE_NOMEM;
186847 c->pToken = pNew;
186848 }
186849 for(i=0; i<n; i++){
186850 /* TODO(shess) This needs expansion to handle UTF-8
@@ -188002,27 +187981,27 @@
188002 ){
188003 PendingList *p = *pp;
188004
188005 /* Allocate or grow the PendingList as required. */
188006 if( !p ){
188007 p = sqlite3_malloc(sizeof(*p) + 100);
188008 if( !p ){
188009 return SQLITE_NOMEM;
188010 }
188011 p->nSpace = 100;
188012 p->aData = (char *)&p[1];
188013 p->nData = 0;
188014 }
188015 else if( p->nData+FTS3_VARINT_MAX+1>p->nSpace ){
188016 int nNew = p->nSpace * 2;
188017 p = sqlite3_realloc(p, sizeof(*p) + nNew);
188018 if( !p ){
188019 sqlite3_free(*pp);
188020 *pp = 0;
188021 return SQLITE_NOMEM;
188022 }
188023 p->nSpace = nNew;
188024 p->aData = (char *)&p[1];
188025 }
188026
188027 /* Append the new serialized varint to the end of the list. */
188028 p->nData += sqlite3Fts3PutVarint(&p->aData[p->nData], i);
@@ -188575,11 +188554,11 @@
188575
188576 if( rc==SQLITE_OK ){
188577 int nByte = sqlite3_blob_bytes(p->pSegments);
188578 *pnBlob = nByte;
188579 if( paBlob ){
188580 char *aByte = sqlite3_malloc(nByte + FTS3_NODE_PADDING);
188581 if( !aByte ){
188582 rc = SQLITE_NOMEM;
188583 }else{
188584 if( pnLoad && nByte>(FTS3_NODE_CHUNK_THRESHOLD) ){
188585 nByte = FTS3_NODE_CHUNKSIZE;
@@ -188692,19 +188671,19 @@
188692 int nCopy = pList->nData+1;
188693
188694 int nTerm = fts3HashKeysize(pElem);
188695 if( (nTerm+1)>pReader->nTermAlloc ){
188696 sqlite3_free(pReader->zTerm);
188697 pReader->zTerm = (char*)sqlite3_malloc((nTerm+1)*2);
188698 if( !pReader->zTerm ) return SQLITE_NOMEM;
188699 pReader->nTermAlloc = (nTerm+1)*2;
188700 }
188701 memcpy(pReader->zTerm, fts3HashKey(pElem), nTerm);
188702 pReader->zTerm[nTerm] = '\0';
188703 pReader->nTerm = nTerm;
188704
188705 aCopy = (char*)sqlite3_malloc(nCopy);
188706 if( !aCopy ) return SQLITE_NOMEM;
188707 memcpy(aCopy, pList->aData, nCopy);
188708 pReader->nNode = pReader->nDoclist = nCopy;
188709 pReader->aNode = pReader->aDoclist = aCopy;
188710 pReader->ppNextElem++;
@@ -188987,11 +188966,11 @@
188987 if( iStartLeaf==0 ){
188988 if( iEndLeaf!=0 ) return FTS_CORRUPT_VTAB;
188989 nExtra = nRoot + FTS3_NODE_PADDING;
188990 }
188991
188992 pReader = (Fts3SegReader *)sqlite3_malloc(sizeof(Fts3SegReader) + nExtra);
188993 if( !pReader ){
188994 return SQLITE_NOMEM;
188995 }
188996 memset(pReader, 0, sizeof(Fts3SegReader));
188997 pReader->iIdx = iAge;
@@ -189079,11 +189058,11 @@
189079 int nKey = fts3HashKeysize(pE);
189080 if( nTerm==0 || (nKey>=nTerm && 0==memcmp(zKey, zTerm, nTerm)) ){
189081 if( nElem==nAlloc ){
189082 Fts3HashElem **aElem2;
189083 nAlloc += 16;
189084 aElem2 = (Fts3HashElem **)sqlite3_realloc(
189085 aElem, nAlloc*sizeof(Fts3HashElem *)
189086 );
189087 if( !aElem2 ){
189088 rc = SQLITE_NOMEM;
189089 nElem = 0;
@@ -189413,11 +189392,11 @@
189413 ** p->nNodeSize bytes, but since this scenario only comes about when
189414 ** the database contain two terms that share a prefix of almost 2KB,
189415 ** this is not expected to be a serious problem.
189416 */
189417 assert( pTree->aData==(char *)&pTree[1] );
189418 pTree->aData = (char *)sqlite3_malloc(nReq);
189419 if( !pTree->aData ){
189420 return SQLITE_NOMEM;
189421 }
189422 }
189423
@@ -189431,11 +189410,11 @@
189431 pTree->nData = nData + nSuffix;
189432 pTree->nEntry++;
189433
189434 if( isCopyTerm ){
189435 if( pTree->nMalloc<nTerm ){
189436 char *zNew = sqlite3_realloc(pTree->zMalloc, nTerm*2);
189437 if( !zNew ){
189438 return SQLITE_NOMEM;
189439 }
189440 pTree->nMalloc = nTerm*2;
189441 pTree->zMalloc = zNew;
@@ -189457,11 +189436,11 @@
189457 **
189458 ** Otherwise, the term is not added to the new node, it is left empty for
189459 ** now. Instead, the term is inserted into the parent of pTree. If pTree
189460 ** has no parent, one is created here.
189461 */
189462 pNew = (SegmentNode *)sqlite3_malloc(sizeof(SegmentNode) + p->nNodeSize);
189463 if( !pNew ){
189464 return SQLITE_NOMEM;
189465 }
189466 memset(pNew, 0, sizeof(SegmentNode));
189467 pNew->nData = 1 + FTS3_VARINT_MAX;
@@ -189595,26 +189574,26 @@
189595 const char *aDoclist, /* Pointer to buffer containing doclist */
189596 int nDoclist /* Size of doclist in bytes */
189597 ){
189598 int nPrefix; /* Size of term prefix in bytes */
189599 int nSuffix; /* Size of term suffix in bytes */
189600 int nReq; /* Number of bytes required on leaf page */
189601 int nData;
189602 SegmentWriter *pWriter = *ppWriter;
189603
189604 if( !pWriter ){
189605 int rc;
189606 sqlite3_stmt *pStmt;
189607
189608 /* Allocate the SegmentWriter structure */
189609 pWriter = (SegmentWriter *)sqlite3_malloc(sizeof(SegmentWriter));
189610 if( !pWriter ) return SQLITE_NOMEM;
189611 memset(pWriter, 0, sizeof(SegmentWriter));
189612 *ppWriter = pWriter;
189613
189614 /* Allocate a buffer in which to accumulate data */
189615 pWriter->aData = (char *)sqlite3_malloc(p->nNodeSize);
189616 if( !pWriter->aData ) return SQLITE_NOMEM;
189617 pWriter->nSize = p->nNodeSize;
189618
189619 /* Find the next free blockid in the %_segments table */
189620 rc = fts3SqlStmt(p, SQL_NEXT_SEGMENTS_ID, &pStmt, 0);
@@ -189685,11 +189664,11 @@
189685
189686 /* If the buffer currently allocated is too small for this entry, realloc
189687 ** the buffer to make it large enough.
189688 */
189689 if( nReq>pWriter->nSize ){
189690 char *aNew = sqlite3_realloc(pWriter->aData, nReq);
189691 if( !aNew ) return SQLITE_NOMEM;
189692 pWriter->aData = aNew;
189693 pWriter->nSize = nReq;
189694 }
189695 assert( nData+nReq<=pWriter->nSize );
@@ -189710,11 +189689,11 @@
189710 ** zTerm is transient, so take a copy of the term data. Otherwise, just
189711 ** store a copy of the pointer.
189712 */
189713 if( isCopyTerm ){
189714 if( nTerm>pWriter->nMalloc ){
189715 char *zNew = sqlite3_realloc(pWriter->zMalloc, nTerm*2);
189716 if( !zNew ){
189717 return SQLITE_NOMEM;
189718 }
189719 pWriter->nMalloc = nTerm*2;
189720 pWriter->zMalloc = zNew;
@@ -190018,16 +189997,16 @@
190018 ** trying to resize the buffer, return SQLITE_NOMEM.
190019 */
190020 static int fts3MsrBufferData(
190021 Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */
190022 char *pList,
190023 int nList
190024 ){
190025 if( nList>pMsr->nBuffer ){
190026 char *pNew;
190027 pMsr->nBuffer = nList*2;
190028 pNew = (char *)sqlite3_realloc(pMsr->aBuffer, pMsr->nBuffer);
190029 if( !pNew ) return SQLITE_NOMEM;
190030 pMsr->aBuffer = pNew;
190031 }
190032
190033 assert( nList>0 );
@@ -190079,11 +190058,11 @@
190079 }
190080 if( rc!=SQLITE_OK ) return rc;
190081 fts3SegReaderSort(pMsr->apSegment, nMerge, j, xCmp);
190082
190083 if( nList>0 && fts3SegReaderIsPending(apSegment[0]) ){
190084 rc = fts3MsrBufferData(pMsr, pList, nList+1);
190085 if( rc!=SQLITE_OK ) return rc;
190086 assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 );
190087 pList = pMsr->aBuffer;
190088 }
190089
@@ -190216,15 +190195,15 @@
190216 }
190217
190218 return SQLITE_OK;
190219 }
190220
190221 static int fts3GrowSegReaderBuffer(Fts3MultiSegReader *pCsr, int nReq){
190222 if( nReq>pCsr->nBuffer ){
190223 char *aNew;
190224 pCsr->nBuffer = nReq*2;
190225 aNew = sqlite3_realloc(pCsr->aBuffer, pCsr->nBuffer);
190226 if( !aNew ){
190227 return SQLITE_NOMEM;
190228 }
190229 pCsr->aBuffer = aNew;
190230 }
@@ -190311,11 +190290,12 @@
190311 && !isFirst
190312 && (p->bDescIdx==0 || fts3SegReaderIsPending(apSegment[0])==0)
190313 ){
190314 pCsr->nDoclist = apSegment[0]->nDoclist;
190315 if( fts3SegReaderIsPending(apSegment[0]) ){
190316 rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, pCsr->nDoclist);
 
190317 pCsr->aDoclist = pCsr->aBuffer;
190318 }else{
190319 pCsr->aDoclist = apSegment[0]->aDoclist;
190320 }
190321 if( rc==SQLITE_OK ) rc = SQLITE_ROW;
@@ -190364,11 +190344,12 @@
190364 iDelta = (i64)((u64)iDocid - (u64)iPrev);
190365 }
190366
190367 nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0);
190368
190369 rc = fts3GrowSegReaderBuffer(pCsr, nByte+nDoclist+FTS3_NODE_PADDING);
 
190370 if( rc ) return rc;
190371
190372 if( isFirst ){
190373 char *a = &pCsr->aBuffer[nDoclist];
190374 int nWrite;
@@ -190390,11 +190371,11 @@
190390 }
190391
190392 fts3SegReaderSort(apSegment, nMerge, j, xCmp);
190393 }
190394 if( nDoclist>0 ){
190395 rc = fts3GrowSegReaderBuffer(pCsr, nDoclist+FTS3_NODE_PADDING);
190396 if( rc ) return rc;
190397 memset(&pCsr->aBuffer[nDoclist], 0, FTS3_NODE_PADDING);
190398 pCsr->aDoclist = pCsr->aBuffer;
190399 pCsr->nDoclist = nDoclist;
190400 rc = SQLITE_ROW;
@@ -191103,11 +191084,11 @@
191103 ** to reflect the new size of the pBlob->a[] buffer.
191104 */
191105 static void blobGrowBuffer(Blob *pBlob, int nMin, int *pRc){
191106 if( *pRc==SQLITE_OK && nMin>pBlob->nAlloc ){
191107 int nAlloc = nMin;
191108 char *a = (char *)sqlite3_realloc(pBlob->a, nAlloc);
191109 if( a ){
191110 pBlob->nAlloc = nAlloc;
191111 pBlob->a = a;
191112 }else{
191113 *pRc = SQLITE_NOMEM;
@@ -191900,11 +191881,11 @@
191900 sqlite3_bind_int64(pSelect, 1, iAbsLevel);
191901 while( SQLITE_ROW==sqlite3_step(pSelect) ){
191902 if( nIdx>=nAlloc ){
191903 int *aNew;
191904 nAlloc += 16;
191905 aNew = sqlite3_realloc(aIdx, nAlloc*sizeof(int));
191906 if( !aNew ){
191907 rc = SQLITE_NOMEM;
191908 break;
191909 }
191910 aIdx = aNew;
@@ -192274,11 +192255,11 @@
192274 Blob hint = {0, 0, 0}; /* Hint read from %_stat table */
192275 int bDirtyHint = 0; /* True if blob 'hint' has been modified */
192276
192277 /* Allocate space for the cursor, filter and writer objects */
192278 const int nAlloc = sizeof(*pCsr) + sizeof(*pFilter) + sizeof(*pWriter);
192279 pWriter = (IncrmergeWriter *)sqlite3_malloc(nAlloc);
192280 if( !pWriter ) return SQLITE_NOMEM;
192281 pFilter = (Fts3SegFilter *)&pWriter[1];
192282 pCsr = (Fts3MultiSegReader *)&pFilter[1];
192283
192284 rc = fts3IncrmergeHintLoad(p, &hint);
@@ -192910,11 +192891,11 @@
192910
192911 if( p->pList==0 ){
192912 return SQLITE_OK;
192913 }
192914
192915 pRet = (char *)sqlite3_malloc(p->pList->nData);
192916 if( !pRet ) return SQLITE_NOMEM;
192917
192918 nSkip = sqlite3Fts3GetVarint(p->pList->aData, &dummy);
192919 *pnData = p->pList->nData - nSkip;
192920 *ppData = pRet;
@@ -192930,11 +192911,11 @@
192930 Fts3Cursor *pCsr, /* Fts3 table cursor */
192931 Fts3PhraseToken *pToken, /* Token to defer */
192932 int iCol /* Column that token must appear in (or -1) */
192933 ){
192934 Fts3DeferredToken *pDeferred;
192935 pDeferred = sqlite3_malloc(sizeof(*pDeferred));
192936 if( !pDeferred ){
192937 return SQLITE_NOMEM;
192938 }
192939 memset(pDeferred, 0, sizeof(*pDeferred));
192940 pDeferred->pToken = pToken;
@@ -205112,12 +205093,13 @@
205112 }
205113 pExpr = uregex_open(zPattern, -1, 0, 0, &status);
205114
205115 if( U_SUCCESS(status) ){
205116 sqlite3_set_auxdata(p, 0, pExpr, icuRegexpDelete);
205117 }else{
205118 assert(!pExpr);
 
205119 icuFunctionError(p, "uregex_open", status);
205120 return;
205121 }
205122 }
205123
@@ -237002,11 +236984,11 @@
237002 int nArg, /* Number of args */
237003 sqlite3_value **apUnused /* Function arguments */
237004 ){
237005 assert( nArg==0 );
237006 UNUSED_PARAM2(nArg, apUnused);
237007 sqlite3_result_text(pCtx, "fts5: 2022-09-02 21:19:24 da7af290960ab8a04a1f55cdc5eeac36b47fa194edf67f0a05daa4b7f2a4071c", -1, SQLITE_TRANSIENT);
237008 }
237009
237010 /*
237011 ** Return true if zName is the extension on one of the shadow tables used
237012 ** by this module.
237013
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -452,11 +452,11 @@
452 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
453 ** [sqlite_version()] and [sqlite_source_id()].
454 */
455 #define SQLITE_VERSION "3.40.0"
456 #define SQLITE_VERSION_NUMBER 3040000
457 #define SQLITE_SOURCE_ID "2022-09-28 19:14:01 f25cf63471cbed1edb27591e57fead62550d4046dbdcb61312288f0f6f24c646"
458
459 /*
460 ** CAPI3REF: Run-Time Library Version Numbers
461 ** KEYWORDS: sqlite3_version sqlite3_sourceid
462 **
@@ -29076,22 +29076,38 @@
29076 sqlite3StatusUp(SQLITE_STATUS_MALLOC_COUNT, 1);
29077 }
29078 *pp = p;
29079 }
29080
29081 /*
29082 ** Maximum size of any single memory allocation.
29083 **
29084 ** This is not a limit on the total amount of memory used. This is
29085 ** a limit on the size parameter to sqlite3_malloc() and sqlite3_realloc().
29086 **
29087 ** The upper bound is slightly less than 2GiB: 0x7ffffeff == 2,147,483,391
29088 ** This provides a 256-byte safety margin for defense against 32-bit
29089 ** signed integer overflow bugs when computing memory allocation sizes.
29090 ** Parnoid applications might want to reduce the maximum allocation size
29091 ** further for an even larger safety margin. 0x3fffffff or 0x0fffffff
29092 ** or even smaller would be reasonable upper bounds on the size of a memory
29093 ** allocations for most applications.
29094 */
29095 #ifndef SQLITE_MAX_ALLOCATION_SIZE
29096 # define SQLITE_MAX_ALLOCATION_SIZE 2147483391
29097 #endif
29098 #if SQLITE_MAX_ALLOCATION_SIZE>2147483391
29099 # error Maximum size for SQLITE_MAX_ALLOCATION_SIZE is 2147483391
29100 #endif
29101
29102 /*
29103 ** Allocate memory. This routine is like sqlite3_malloc() except that it
29104 ** assumes the memory subsystem has already been initialized.
29105 */
29106 SQLITE_PRIVATE void *sqlite3Malloc(u64 n){
29107 void *p;
29108 if( n==0 || n>SQLITE_MAX_ALLOCATION_SIZE ){
 
 
 
 
 
29109 p = 0;
29110 }else if( sqlite3GlobalConfig.bMemstat ){
29111 sqlite3_mutex_enter(mem0.mutex);
29112 mallocWithAlarm((int)n, &p);
29113 sqlite3_mutex_leave(mem0.mutex);
@@ -45571,12 +45587,13 @@
45587 SQLITE_API int sqlite3_win32_set_directory8(
45588 unsigned long type, /* Identifier for directory being set or reset */
45589 const char *zValue /* New value for directory being set or reset */
45590 ){
45591 char **ppDirectory = 0;
45592 int rc;
45593 #ifndef SQLITE_OMIT_AUTOINIT
45594 rc = sqlite3_initialize();
45595 if( rc ) return rc;
45596 #endif
45597 sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
45598 if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){
45599 ppDirectory = &sqlite3_data_directory;
@@ -49415,11 +49432,12 @@
49432 const char *zRelative, /* Possibly relative input path */
49433 int nFull, /* Size of output buffer in bytes */
49434 char *zFull /* Output buffer */
49435 ){
49436 int rc;
49437 MUTEX_LOGIC( sqlite3_mutex *pMutex; )
49438 MUTEX_LOGIC( pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR); )
49439 sqlite3_mutex_enter(pMutex);
49440 rc = winFullPathnameNoMutex(pVfs, zRelative, nFull, zFull);
49441 sqlite3_mutex_leave(pMutex);
49442 return rc;
49443 }
@@ -51798,18 +51816,18 @@
51816 assert( p->nRef>0 );
51817 assert( newPgno>0 );
51818 assert( sqlite3PcachePageSanity(p) );
51819 pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno));
51820 pOther = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, newPgno, 0);
 
51821 if( pOther ){
51822 PgHdr *pXPage = (PgHdr*)pOther->pExtra;
51823 assert( pXPage->nRef==0 );
51824 pXPage->nRef++;
51825 pCache->nRefSum++;
51826 sqlite3PcacheDrop(pXPage);
51827 }
51828 sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
51829 p->pgno = newPgno;
51830 if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
51831 pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
51832 assert( sqlite3PcachePageSanity(p) );
51833 }
@@ -53202,27 +53220,12 @@
53220 while( (*pp)!=pPage ){
53221 pp = &(*pp)->pNext;
53222 }
53223 *pp = pPage->pNext;
53224
53225 assert( pcache1FetchNoMutex(p, iNew, 0)==0 ); /* iNew not in cache */
53226 hNew = iNew%pCache->nHash;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53227 pPage->iKey = iNew;
53228 pPage->pNext = pCache->apHash[hNew];
53229 pCache->apHash[hNew] = pPage;
53230 if( iNew>pCache->iMaxKey ){
53231 pCache->iMaxKey = iNew;
@@ -68523,11 +68526,11 @@
68526 if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage);
68527 sz2 = get2byte(&data[iFree2+2]);
68528 if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
68529 memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
68530 sz += sz2;
68531 }else if( iFree+sz>usableSize ){
68532 return SQLITE_CORRUPT_PAGE(pPage);
68533 }
68534
68535 cbrk = top+sz;
68536 assert( cbrk+(iFree-top) <= usableSize );
@@ -93400,16 +93403,20 @@
93403 }
93404
93405 /* Opcode: IfNotOpen P1 P2 * * *
93406 ** Synopsis: if( !csr[P1] ) goto P2
93407 **
93408 ** If cursor P1 is not open or if P1 is set to a NULL row using the
93409 ** OP_NullRow opcode, then jump to instruction P2. Otherwise, fall through.
93410 */
93411 case OP_IfNotOpen: { /* jump */
93412 VdbeCursor *pCur;
93413
93414 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
93415 pCur = p->apCsr[pOp->p1];
93416 VdbeBranchTaken(pCur==0 || pCur->nullRow, 2);
93417 if( pCur==0 || pCur->nullRow ){
93418 goto jump_to_p2_and_check_for_interrupt;
93419 }
93420 break;
93421 }
93422
@@ -107028,10 +107035,11 @@
107035 }
107036 if( pKeyInfo ){
107037 sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
107038 }
107039 if( addrOnce ){
107040 sqlite3VdbeAddOp1(v, OP_NullRow, iTab);
107041 sqlite3VdbeJumpHere(v, addrOnce);
107042 /* Subroutine return */
107043 assert( ExprUseYSub(pExpr) );
107044 assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
107045 || pParse->nErr );
@@ -139569,11 +139577,11 @@
139577 ** position in the parent that NULL-able due to an OUTER JOIN. Either the
139578 ** target slot in the parent is the right operand of a LEFT JOIN, or one of
139579 ** the left operands of a RIGHT JOIN. In either case, we need to potentially
139580 ** bypass the substituted expression with OP_IfNullRow.
139581 **
139582 ** Suppose the original expression is an integer constant. Even though the table
139583 ** has the nullRow flag set, because the expression is an integer constant,
139584 ** it will not be NULLed out. So instead, we insert an OP_IfNullRow opcode
139585 ** that checks to see if the nullRow flag is set on the table. If the nullRow
139586 ** flag is set, then the value in the register is set to NULL and the original
139587 ** expression is bypassed. If the nullRow flag is not set, then the original
@@ -140026,23 +140034,17 @@
140034 **
140035 ** (26) The subquery may not be the right operand of a RIGHT JOIN.
140036 ** See also (3) for restrictions on LEFT JOIN.
140037 **
140038 ** (27) The subquery may not contain a FULL or RIGHT JOIN unless it
140039 ** is the first element of the parent query. Two subcases:
140040 ** (27a) the subquery is not a compound query.
 
140041 ** (27b) the subquery is a compound query and the RIGHT JOIN occurs
140042 ** in any arm of the compound query. (See also (17g).)
140043 **
140044 ** (28) The subquery is not a MATERIALIZED CTE.
140045 **
 
 
 
 
 
140046 **
140047 ** In this routine, the "p" parameter is a pointer to the outer query.
140048 ** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
140049 ** uses aggregates.
140050 **
@@ -140142,57 +140144,19 @@
140144 ){
140145 return 0;
140146 }
140147 isOuterJoin = 1;
140148 }
 
 
 
 
 
 
 
 
 
140149
140150 assert( pSubSrc->nSrc>0 ); /* True by restriction (7) */
140151 if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
140152 return 0; /* Restriction (27a) */
140153 }
140154 if( pSubitem->fg.isCte && pSubitem->u2.pCteUse->eM10d==M10d_Yes ){
140155 return 0; /* (28) */
140156 }
140157
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140158 /* Restriction (17): If the sub-query is a compound SELECT, then it must
140159 ** use only the UNION ALL operator. And none of the simple select queries
140160 ** that make up the compound SELECT are allowed to be aggregate or distinct
140161 ** queries.
140162 */
@@ -144296,10 +144260,27 @@
144260 ** build the sqlite_schema entry
144261 */
144262 if( !db->init.busy ){
144263 Vdbe *v;
144264 char *z;
144265
144266 /* If this is a new CREATE TABLE statement, and if shadow tables
144267 ** are read-only, and the trigger makes a change to a shadow table,
144268 ** then raise an error - do not allow the trigger to be created. */
144269 if( sqlite3ReadOnlyShadowTables(db) ){
144270 TriggerStep *pStep;
144271 for(pStep=pTrig->step_list; pStep; pStep=pStep->pNext){
144272 if( pStep->zTarget!=0
144273 && sqlite3ShadowTableName(db, pStep->zTarget)
144274 ){
144275 sqlite3ErrorMsg(pParse,
144276 "trigger \"%s\" may not write to shadow table \"%s\"",
144277 pTrig->zName, pStep->zTarget);
144278 goto triggerfinish_cleanup;
144279 }
144280 }
144281 }
144282
144283 /* Make an entry in the sqlite_schema table */
144284 v = sqlite3GetVdbe(pParse);
144285 if( v==0 ) goto triggerfinish_cleanup;
144286 sqlite3BeginWriteOperation(pParse, 0, iDb);
@@ -155004,10 +154985,47 @@
154985 }
154986 #else
154987 #define whereTraceIndexInfoInputs(A)
154988 #define whereTraceIndexInfoOutputs(A)
154989 #endif
154990
154991 /*
154992 ** We know that pSrc is an operand of an outer join. Return true if
154993 ** pTerm is a constraint that is compatible with that join.
154994 **
154995 ** pTerm must be EP_OuterON if pSrc is the right operand of an
154996 ** outer join. pTerm can be either EP_OuterON or EP_InnerON if pSrc
154997 ** is the left operand of a RIGHT join.
154998 **
154999 ** See https://sqlite.org/forum/forumpost/206d99a16dd9212f
155000 ** for an example of a WHERE clause constraints that may not be used on
155001 ** the right table of a RIGHT JOIN because the constraint implies a
155002 ** not-NULL condition on the left table of the RIGHT JOIN.
155003 */
155004 static int constraintCompatibleWithOuterJoin(
155005 const WhereTerm *pTerm, /* WHERE clause term to check */
155006 const SrcItem *pSrc /* Table we are trying to access */
155007 ){
155008 assert( (pSrc->fg.jointype&(JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ); /* By caller */
155009 testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT );
155010 testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ );
155011 testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) )
155012 testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) );
155013 if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON)
155014 || pTerm->pExpr->w.iJoin != pSrc->iCursor
155015 ){
155016 return 0;
155017 }
155018 if( (pSrc->fg.jointype & (JT_LEFT|JT_RIGHT))!=0
155019 && ExprHasProperty(pTerm->pExpr, EP_InnerON)
155020 ){
155021 return 0;
155022 }
155023 return 1;
155024 }
155025
155026
155027
155028 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
155029 /*
155030 ** Return TRUE if the WHERE clause term pTerm is of a form where it
155031 ** could be used with an index to access pSrc, assuming an appropriate
@@ -155020,20 +155038,14 @@
155038 ){
155039 char aff;
155040 if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
155041 if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
155042 assert( (pSrc->fg.jointype & JT_RIGHT)==0 );
155043 if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0
155044 && !constraintCompatibleWithOuterJoin(pTerm,pSrc)
155045 ){
155046 return 0; /* See https://sqlite.org/forum/forumpost/51e6959f61 */
 
 
 
 
 
 
155047 }
155048 if( (pTerm->prereqRight & notReady)!=0 ) return 0;
155049 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
155050 if( pTerm->u.x.leftColumn<0 ) return 0;
155051 aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity;
@@ -155441,26 +155453,14 @@
155453 if( pTerm->wtFlags & TERM_VNULL ) continue;
155454
155455 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
155456 assert( pTerm->u.x.leftColumn>=XN_ROWID );
155457 assert( pTerm->u.x.leftColumn<pTab->nCol );
155458 if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0
155459 && !constraintCompatibleWithOuterJoin(pTerm,pSrc)
155460 ){
155461 continue;
 
 
 
 
 
 
 
 
 
 
 
 
155462 }
155463 nTerm++;
155464 pTerm->wtFlags |= TERM_OK;
155465 }
155466
@@ -157114,36 +157114,15 @@
157114
157115 /* Do not allow the upper bound of a LIKE optimization range constraint
157116 ** to mix with a lower range bound from some other source */
157117 if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;
157118
157119 if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0
157120 && !constraintCompatibleWithOuterJoin(pTerm,pSrc)
157121 ){
157122 continue;
157123 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157124 if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){
157125 pBuilder->bldFlags1 |= SQLITE_BLDF1_UNIQUE;
157126 }else{
157127 pBuilder->bldFlags1 |= SQLITE_BLDF1_INDEXED;
157128 }
@@ -177299,11 +177278,11 @@
177278 Fts3SegReader **apSegment; /* Array of Fts3SegReader objects */
177279 int nSegment; /* Size of apSegment array */
177280 int nAdvance; /* How many seg-readers to advance */
177281 Fts3SegFilter *pFilter; /* Pointer to filter object */
177282 char *aBuffer; /* Buffer to merge doclists in */
177283 i64 nBuffer; /* Allocated size of aBuffer[] in bytes */
177284
177285 int iColFilter; /* If >=0, filter for this column */
177286 int bRestart;
177287
177288 /* Used by fts3.c only. */
@@ -179995,11 +179974,11 @@
179974 ** as a single-byte delta, whereas in the second it must be stored as a
179975 ** FTS3_VARINT_MAX byte varint.
179976 **
179977 ** Similar padding is added in the fts3DoclistOrMerge() function.
179978 */
179979 pTS->aaOutput[0] = sqlite3_malloc64((i64)nDoclist + FTS3_VARINT_MAX + 1);
179980 pTS->anOutput[0] = nDoclist;
179981 if( pTS->aaOutput[0] ){
179982 memcpy(pTS->aaOutput[0], aDoclist, nDoclist);
179983 memset(&pTS->aaOutput[0][nDoclist], 0, FTS3_VARINT_MAX);
179984 }else{
@@ -181852,11 +181831,11 @@
181831
181832 /* Check if the current entries really are a phrase match */
181833 if( bEof==0 ){
181834 int nList = 0;
181835 int nByte = a[p->nToken-1].nList;
181836 char *aDoclist = sqlite3_malloc64((i64)nByte+FTS3_BUFFER_PADDING);
181837 if( !aDoclist ) return SQLITE_NOMEM;
181838 memcpy(aDoclist, a[p->nToken-1].pList, nByte+1);
181839 memset(&aDoclist[nByte], 0, FTS3_BUFFER_PADDING);
181840
181841 for(i=0; i<(p->nToken-1); i++){
@@ -186088,11 +186067,11 @@
186067 if( c->iOffset>iStartOffset ){
186068 int n = c->iOffset-iStartOffset;
186069 if( n>c->nAllocated ){
186070 char *pNew;
186071 c->nAllocated = n+20;
186072 pNew = sqlite3_realloc64(c->zToken, c->nAllocated);
186073 if( !pNew ) return SQLITE_NOMEM;
186074 c->zToken = pNew;
186075 }
186076 porter_stemmer(&z[iStartOffset], n, c->zToken, pnBytes);
186077 *pzToken = c->zToken;
@@ -186840,11 +186819,11 @@
186819 if( c->iOffset>iStartOffset ){
186820 int i, n = c->iOffset-iStartOffset;
186821 if( n>c->nTokenAllocated ){
186822 char *pNew;
186823 c->nTokenAllocated = n+20;
186824 pNew = sqlite3_realloc64(c->pToken, c->nTokenAllocated);
186825 if( !pNew ) return SQLITE_NOMEM;
186826 c->pToken = pNew;
186827 }
186828 for(i=0; i<n; i++){
186829 /* TODO(shess) This needs expansion to handle UTF-8
@@ -188002,27 +187981,27 @@
187981 ){
187982 PendingList *p = *pp;
187983
187984 /* Allocate or grow the PendingList as required. */
187985 if( !p ){
187986 p = sqlite3_malloc64(sizeof(*p) + 100);
187987 if( !p ){
187988 return SQLITE_NOMEM;
187989 }
187990 p->nSpace = 100;
187991 p->aData = (char *)&p[1];
187992 p->nData = 0;
187993 }
187994 else if( p->nData+FTS3_VARINT_MAX+1>p->nSpace ){
187995 i64 nNew = p->nSpace * 2;
187996 p = sqlite3_realloc64(p, sizeof(*p) + nNew);
187997 if( !p ){
187998 sqlite3_free(*pp);
187999 *pp = 0;
188000 return SQLITE_NOMEM;
188001 }
188002 p->nSpace = (int)nNew;
188003 p->aData = (char *)&p[1];
188004 }
188005
188006 /* Append the new serialized varint to the end of the list. */
188007 p->nData += sqlite3Fts3PutVarint(&p->aData[p->nData], i);
@@ -188575,11 +188554,11 @@
188554
188555 if( rc==SQLITE_OK ){
188556 int nByte = sqlite3_blob_bytes(p->pSegments);
188557 *pnBlob = nByte;
188558 if( paBlob ){
188559 char *aByte = sqlite3_malloc64((i64)nByte + FTS3_NODE_PADDING);
188560 if( !aByte ){
188561 rc = SQLITE_NOMEM;
188562 }else{
188563 if( pnLoad && nByte>(FTS3_NODE_CHUNK_THRESHOLD) ){
188564 nByte = FTS3_NODE_CHUNKSIZE;
@@ -188692,19 +188671,19 @@
188671 int nCopy = pList->nData+1;
188672
188673 int nTerm = fts3HashKeysize(pElem);
188674 if( (nTerm+1)>pReader->nTermAlloc ){
188675 sqlite3_free(pReader->zTerm);
188676 pReader->zTerm = (char*)sqlite3_malloc64(((i64)nTerm+1)*2);
188677 if( !pReader->zTerm ) return SQLITE_NOMEM;
188678 pReader->nTermAlloc = (nTerm+1)*2;
188679 }
188680 memcpy(pReader->zTerm, fts3HashKey(pElem), nTerm);
188681 pReader->zTerm[nTerm] = '\0';
188682 pReader->nTerm = nTerm;
188683
188684 aCopy = (char*)sqlite3_malloc64(nCopy);
188685 if( !aCopy ) return SQLITE_NOMEM;
188686 memcpy(aCopy, pList->aData, nCopy);
188687 pReader->nNode = pReader->nDoclist = nCopy;
188688 pReader->aNode = pReader->aDoclist = aCopy;
188689 pReader->ppNextElem++;
@@ -188987,11 +188966,11 @@
188966 if( iStartLeaf==0 ){
188967 if( iEndLeaf!=0 ) return FTS_CORRUPT_VTAB;
188968 nExtra = nRoot + FTS3_NODE_PADDING;
188969 }
188970
188971 pReader = (Fts3SegReader *)sqlite3_malloc64(sizeof(Fts3SegReader) + nExtra);
188972 if( !pReader ){
188973 return SQLITE_NOMEM;
188974 }
188975 memset(pReader, 0, sizeof(Fts3SegReader));
188976 pReader->iIdx = iAge;
@@ -189079,11 +189058,11 @@
189058 int nKey = fts3HashKeysize(pE);
189059 if( nTerm==0 || (nKey>=nTerm && 0==memcmp(zKey, zTerm, nTerm)) ){
189060 if( nElem==nAlloc ){
189061 Fts3HashElem **aElem2;
189062 nAlloc += 16;
189063 aElem2 = (Fts3HashElem **)sqlite3_realloc64(
189064 aElem, nAlloc*sizeof(Fts3HashElem *)
189065 );
189066 if( !aElem2 ){
189067 rc = SQLITE_NOMEM;
189068 nElem = 0;
@@ -189413,11 +189392,11 @@
189392 ** p->nNodeSize bytes, but since this scenario only comes about when
189393 ** the database contain two terms that share a prefix of almost 2KB,
189394 ** this is not expected to be a serious problem.
189395 */
189396 assert( pTree->aData==(char *)&pTree[1] );
189397 pTree->aData = (char *)sqlite3_malloc64(nReq);
189398 if( !pTree->aData ){
189399 return SQLITE_NOMEM;
189400 }
189401 }
189402
@@ -189431,11 +189410,11 @@
189410 pTree->nData = nData + nSuffix;
189411 pTree->nEntry++;
189412
189413 if( isCopyTerm ){
189414 if( pTree->nMalloc<nTerm ){
189415 char *zNew = sqlite3_realloc64(pTree->zMalloc, (i64)nTerm*2);
189416 if( !zNew ){
189417 return SQLITE_NOMEM;
189418 }
189419 pTree->nMalloc = nTerm*2;
189420 pTree->zMalloc = zNew;
@@ -189457,11 +189436,11 @@
189436 **
189437 ** Otherwise, the term is not added to the new node, it is left empty for
189438 ** now. Instead, the term is inserted into the parent of pTree. If pTree
189439 ** has no parent, one is created here.
189440 */
189441 pNew = (SegmentNode *)sqlite3_malloc64(sizeof(SegmentNode) + p->nNodeSize);
189442 if( !pNew ){
189443 return SQLITE_NOMEM;
189444 }
189445 memset(pNew, 0, sizeof(SegmentNode));
189446 pNew->nData = 1 + FTS3_VARINT_MAX;
@@ -189595,26 +189574,26 @@
189574 const char *aDoclist, /* Pointer to buffer containing doclist */
189575 int nDoclist /* Size of doclist in bytes */
189576 ){
189577 int nPrefix; /* Size of term prefix in bytes */
189578 int nSuffix; /* Size of term suffix in bytes */
189579 i64 nReq; /* Number of bytes required on leaf page */
189580 int nData;
189581 SegmentWriter *pWriter = *ppWriter;
189582
189583 if( !pWriter ){
189584 int rc;
189585 sqlite3_stmt *pStmt;
189586
189587 /* Allocate the SegmentWriter structure */
189588 pWriter = (SegmentWriter *)sqlite3_malloc64(sizeof(SegmentWriter));
189589 if( !pWriter ) return SQLITE_NOMEM;
189590 memset(pWriter, 0, sizeof(SegmentWriter));
189591 *ppWriter = pWriter;
189592
189593 /* Allocate a buffer in which to accumulate data */
189594 pWriter->aData = (char *)sqlite3_malloc64(p->nNodeSize);
189595 if( !pWriter->aData ) return SQLITE_NOMEM;
189596 pWriter->nSize = p->nNodeSize;
189597
189598 /* Find the next free blockid in the %_segments table */
189599 rc = fts3SqlStmt(p, SQL_NEXT_SEGMENTS_ID, &pStmt, 0);
@@ -189685,11 +189664,11 @@
189664
189665 /* If the buffer currently allocated is too small for this entry, realloc
189666 ** the buffer to make it large enough.
189667 */
189668 if( nReq>pWriter->nSize ){
189669 char *aNew = sqlite3_realloc64(pWriter->aData, nReq);
189670 if( !aNew ) return SQLITE_NOMEM;
189671 pWriter->aData = aNew;
189672 pWriter->nSize = nReq;
189673 }
189674 assert( nData+nReq<=pWriter->nSize );
@@ -189710,11 +189689,11 @@
189689 ** zTerm is transient, so take a copy of the term data. Otherwise, just
189690 ** store a copy of the pointer.
189691 */
189692 if( isCopyTerm ){
189693 if( nTerm>pWriter->nMalloc ){
189694 char *zNew = sqlite3_realloc64(pWriter->zMalloc, (i64)nTerm*2);
189695 if( !zNew ){
189696 return SQLITE_NOMEM;
189697 }
189698 pWriter->nMalloc = nTerm*2;
189699 pWriter->zMalloc = zNew;
@@ -190018,16 +189997,16 @@
189997 ** trying to resize the buffer, return SQLITE_NOMEM.
189998 */
189999 static int fts3MsrBufferData(
190000 Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */
190001 char *pList,
190002 i64 nList
190003 ){
190004 if( nList>pMsr->nBuffer ){
190005 char *pNew;
190006 pMsr->nBuffer = nList*2;
190007 pNew = (char *)sqlite3_realloc64(pMsr->aBuffer, pMsr->nBuffer);
190008 if( !pNew ) return SQLITE_NOMEM;
190009 pMsr->aBuffer = pNew;
190010 }
190011
190012 assert( nList>0 );
@@ -190079,11 +190058,11 @@
190058 }
190059 if( rc!=SQLITE_OK ) return rc;
190060 fts3SegReaderSort(pMsr->apSegment, nMerge, j, xCmp);
190061
190062 if( nList>0 && fts3SegReaderIsPending(apSegment[0]) ){
190063 rc = fts3MsrBufferData(pMsr, pList, (i64)nList+1);
190064 if( rc!=SQLITE_OK ) return rc;
190065 assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 );
190066 pList = pMsr->aBuffer;
190067 }
190068
@@ -190216,15 +190195,15 @@
190195 }
190196
190197 return SQLITE_OK;
190198 }
190199
190200 static int fts3GrowSegReaderBuffer(Fts3MultiSegReader *pCsr, i64 nReq){
190201 if( nReq>pCsr->nBuffer ){
190202 char *aNew;
190203 pCsr->nBuffer = nReq*2;
190204 aNew = sqlite3_realloc64(pCsr->aBuffer, pCsr->nBuffer);
190205 if( !aNew ){
190206 return SQLITE_NOMEM;
190207 }
190208 pCsr->aBuffer = aNew;
190209 }
@@ -190311,11 +190290,12 @@
190290 && !isFirst
190291 && (p->bDescIdx==0 || fts3SegReaderIsPending(apSegment[0])==0)
190292 ){
190293 pCsr->nDoclist = apSegment[0]->nDoclist;
190294 if( fts3SegReaderIsPending(apSegment[0]) ){
190295 rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist,
190296 (i64)pCsr->nDoclist);
190297 pCsr->aDoclist = pCsr->aBuffer;
190298 }else{
190299 pCsr->aDoclist = apSegment[0]->aDoclist;
190300 }
190301 if( rc==SQLITE_OK ) rc = SQLITE_ROW;
@@ -190364,11 +190344,12 @@
190344 iDelta = (i64)((u64)iDocid - (u64)iPrev);
190345 }
190346
190347 nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0);
190348
190349 rc = fts3GrowSegReaderBuffer(pCsr,
190350 (i64)nByte+nDoclist+FTS3_NODE_PADDING);
190351 if( rc ) return rc;
190352
190353 if( isFirst ){
190354 char *a = &pCsr->aBuffer[nDoclist];
190355 int nWrite;
@@ -190390,11 +190371,11 @@
190371 }
190372
190373 fts3SegReaderSort(apSegment, nMerge, j, xCmp);
190374 }
190375 if( nDoclist>0 ){
190376 rc = fts3GrowSegReaderBuffer(pCsr, (i64)nDoclist+FTS3_NODE_PADDING);
190377 if( rc ) return rc;
190378 memset(&pCsr->aBuffer[nDoclist], 0, FTS3_NODE_PADDING);
190379 pCsr->aDoclist = pCsr->aBuffer;
190380 pCsr->nDoclist = nDoclist;
190381 rc = SQLITE_ROW;
@@ -191103,11 +191084,11 @@
191084 ** to reflect the new size of the pBlob->a[] buffer.
191085 */
191086 static void blobGrowBuffer(Blob *pBlob, int nMin, int *pRc){
191087 if( *pRc==SQLITE_OK && nMin>pBlob->nAlloc ){
191088 int nAlloc = nMin;
191089 char *a = (char *)sqlite3_realloc64(pBlob->a, nAlloc);
191090 if( a ){
191091 pBlob->nAlloc = nAlloc;
191092 pBlob->a = a;
191093 }else{
191094 *pRc = SQLITE_NOMEM;
@@ -191900,11 +191881,11 @@
191881 sqlite3_bind_int64(pSelect, 1, iAbsLevel);
191882 while( SQLITE_ROW==sqlite3_step(pSelect) ){
191883 if( nIdx>=nAlloc ){
191884 int *aNew;
191885 nAlloc += 16;
191886 aNew = sqlite3_realloc64(aIdx, nAlloc*sizeof(int));
191887 if( !aNew ){
191888 rc = SQLITE_NOMEM;
191889 break;
191890 }
191891 aIdx = aNew;
@@ -192274,11 +192255,11 @@
192255 Blob hint = {0, 0, 0}; /* Hint read from %_stat table */
192256 int bDirtyHint = 0; /* True if blob 'hint' has been modified */
192257
192258 /* Allocate space for the cursor, filter and writer objects */
192259 const int nAlloc = sizeof(*pCsr) + sizeof(*pFilter) + sizeof(*pWriter);
192260 pWriter = (IncrmergeWriter *)sqlite3_malloc64(nAlloc);
192261 if( !pWriter ) return SQLITE_NOMEM;
192262 pFilter = (Fts3SegFilter *)&pWriter[1];
192263 pCsr = (Fts3MultiSegReader *)&pFilter[1];
192264
192265 rc = fts3IncrmergeHintLoad(p, &hint);
@@ -192910,11 +192891,11 @@
192891
192892 if( p->pList==0 ){
192893 return SQLITE_OK;
192894 }
192895
192896 pRet = (char *)sqlite3_malloc64(p->pList->nData);
192897 if( !pRet ) return SQLITE_NOMEM;
192898
192899 nSkip = sqlite3Fts3GetVarint(p->pList->aData, &dummy);
192900 *pnData = p->pList->nData - nSkip;
192901 *ppData = pRet;
@@ -192930,11 +192911,11 @@
192911 Fts3Cursor *pCsr, /* Fts3 table cursor */
192912 Fts3PhraseToken *pToken, /* Token to defer */
192913 int iCol /* Column that token must appear in (or -1) */
192914 ){
192915 Fts3DeferredToken *pDeferred;
192916 pDeferred = sqlite3_malloc64(sizeof(*pDeferred));
192917 if( !pDeferred ){
192918 return SQLITE_NOMEM;
192919 }
192920 memset(pDeferred, 0, sizeof(*pDeferred));
192921 pDeferred->pToken = pToken;
@@ -205112,12 +205093,13 @@
205093 }
205094 pExpr = uregex_open(zPattern, -1, 0, 0, &status);
205095
205096 if( U_SUCCESS(status) ){
205097 sqlite3_set_auxdata(p, 0, pExpr, icuRegexpDelete);
205098 pExpr = sqlite3_get_auxdata(p, 0);
205099 }
205100 if( !pExpr ){
205101 icuFunctionError(p, "uregex_open", status);
205102 return;
205103 }
205104 }
205105
@@ -237002,11 +236984,11 @@
236984 int nArg, /* Number of args */
236985 sqlite3_value **apUnused /* Function arguments */
236986 ){
236987 assert( nArg==0 );
236988 UNUSED_PARAM2(nArg, apUnused);
236989 sqlite3_result_text(pCtx, "fts5: 2022-09-28 19:14:01 f25cf63471cbed1edb27591e57fead62550d4046dbdcb61312288f0f6f24c646", -1, SQLITE_TRANSIENT);
236990 }
236991
236992 /*
236993 ** Return true if zName is the extension on one of the shadow tables used
236994 ** by this module.
236995
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,11 @@
146146
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147147
** [sqlite_version()] and [sqlite_source_id()].
148148
*/
149149
#define SQLITE_VERSION "3.40.0"
150150
#define SQLITE_VERSION_NUMBER 3040000
151
-#define SQLITE_SOURCE_ID "2022-09-02 21:19:24 da7af290960ab8a04a1f55cdc5eeac36b47fa194edf67f0a05daa4b7f2a4071c"
151
+#define SQLITE_SOURCE_ID "2022-09-28 19:14:01 f25cf63471cbed1edb27591e57fead62550d4046dbdcb61312288f0f6f24c646"
152152
153153
/*
154154
** CAPI3REF: Run-Time Library Version Numbers
155155
** KEYWORDS: sqlite3_version sqlite3_sourceid
156156
**
157157
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,11 @@
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.40.0"
150 #define SQLITE_VERSION_NUMBER 3040000
151 #define SQLITE_SOURCE_ID "2022-09-02 21:19:24 da7af290960ab8a04a1f55cdc5eeac36b47fa194edf67f0a05daa4b7f2a4071c"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
157
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,11 @@
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.40.0"
150 #define SQLITE_VERSION_NUMBER 3040000
151 #define SQLITE_SOURCE_ID "2022-09-28 19:14:01 f25cf63471cbed1edb27591e57fead62550d4046dbdcb61312288f0f6f24c646"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
157
+3 -3
--- src/chat.c
+++ src/chat.c
@@ -650,11 +650,11 @@
650650
/* see https://fossil-scm.org/forum/forumpost/e0be0eeb4c */
651651
blob_appendf(&json, "null,");
652652
isWiki = 0;
653653
}
654654
blob_appendf(&json, "\"uclr\":%!j,",
655
- user_color(zFrom ? zFrom : "nobody"));
655
+ isWiki ? "transparent" : user_color(zFrom ? zFrom : "nobody"));
656656
657657
if(bRaw){
658658
blob_appendf(&json, "\"xmsg\":%!j,", zRawMsg);
659659
}else{
660660
zMsg = chat_format_to_html(zRawMsg ? zRawMsg : "", isWiki);
@@ -745,18 +745,18 @@
745745
blob_appendf(&json, "\"lmtime\":%!j,", zLMtime);
746746
}
747747
blob_append(&json, "\"xfrom\":", -1);
748748
if(zFrom){
749749
blob_appendf(&json, "%!j,", zFrom);
750
- isWiki = fossil_strcmp(zFrom, zChatUser);
750
+ isWiki = fossil_strcmp(zFrom, zChatUser)==0;
751751
}else{
752752
/* see https://fossil-scm.org/forum/forumpost/e0be0eeb4c */
753753
blob_appendf(&json, "null,");
754754
isWiki = 0;
755755
}
756756
blob_appendf(&json, "\"uclr\":%!j,",
757
- user_color(zFrom ? zFrom : "nobody"));
757
+ isWiki ? "transparent" : user_color(zFrom ? zFrom : "nobody"));
758758
blob_append(&json,"\"xmsg\":", 7);
759759
if(fRaw){
760760
blob_appendf(&json, "%!j,", zRawMsg);
761761
}else{
762762
char * zMsg = chat_format_to_html(zRawMsg ? zRawMsg : "", isWiki);
763763
--- src/chat.c
+++ src/chat.c
@@ -650,11 +650,11 @@
650 /* see https://fossil-scm.org/forum/forumpost/e0be0eeb4c */
651 blob_appendf(&json, "null,");
652 isWiki = 0;
653 }
654 blob_appendf(&json, "\"uclr\":%!j,",
655 user_color(zFrom ? zFrom : "nobody"));
656
657 if(bRaw){
658 blob_appendf(&json, "\"xmsg\":%!j,", zRawMsg);
659 }else{
660 zMsg = chat_format_to_html(zRawMsg ? zRawMsg : "", isWiki);
@@ -745,18 +745,18 @@
745 blob_appendf(&json, "\"lmtime\":%!j,", zLMtime);
746 }
747 blob_append(&json, "\"xfrom\":", -1);
748 if(zFrom){
749 blob_appendf(&json, "%!j,", zFrom);
750 isWiki = fossil_strcmp(zFrom, zChatUser);
751 }else{
752 /* see https://fossil-scm.org/forum/forumpost/e0be0eeb4c */
753 blob_appendf(&json, "null,");
754 isWiki = 0;
755 }
756 blob_appendf(&json, "\"uclr\":%!j,",
757 user_color(zFrom ? zFrom : "nobody"));
758 blob_append(&json,"\"xmsg\":", 7);
759 if(fRaw){
760 blob_appendf(&json, "%!j,", zRawMsg);
761 }else{
762 char * zMsg = chat_format_to_html(zRawMsg ? zRawMsg : "", isWiki);
763
--- src/chat.c
+++ src/chat.c
@@ -650,11 +650,11 @@
650 /* see https://fossil-scm.org/forum/forumpost/e0be0eeb4c */
651 blob_appendf(&json, "null,");
652 isWiki = 0;
653 }
654 blob_appendf(&json, "\"uclr\":%!j,",
655 isWiki ? "transparent" : user_color(zFrom ? zFrom : "nobody"));
656
657 if(bRaw){
658 blob_appendf(&json, "\"xmsg\":%!j,", zRawMsg);
659 }else{
660 zMsg = chat_format_to_html(zRawMsg ? zRawMsg : "", isWiki);
@@ -745,18 +745,18 @@
745 blob_appendf(&json, "\"lmtime\":%!j,", zLMtime);
746 }
747 blob_append(&json, "\"xfrom\":", -1);
748 if(zFrom){
749 blob_appendf(&json, "%!j,", zFrom);
750 isWiki = fossil_strcmp(zFrom, zChatUser)==0;
751 }else{
752 /* see https://fossil-scm.org/forum/forumpost/e0be0eeb4c */
753 blob_appendf(&json, "null,");
754 isWiki = 0;
755 }
756 blob_appendf(&json, "\"uclr\":%!j,",
757 isWiki ? "transparent" : user_color(zFrom ? zFrom : "nobody"));
758 blob_append(&json,"\"xmsg\":", 7);
759 if(fRaw){
760 blob_appendf(&json, "%!j,", zRawMsg);
761 }else{
762 char * zMsg = chat_format_to_html(zRawMsg ? zRawMsg : "", isWiki);
763
+5 -2
--- src/checkin.c
+++ src/checkin.c
@@ -97,13 +97,16 @@
9797
}else if( isDir==0 ){
9898
fossil_warning("not found: %s", &zName[nRoot]);
9999
}else if( file_access(zName, R_OK) ){
100100
fossil_fatal("cannot open %s", &zName[nRoot]);
101101
}else{
102
+ /* Only add unmanaged file paths specified on the command line. */
102103
db_multi_exec(
103
- "INSERT OR IGNORE INTO sfile(pathname) VALUES(%Q)",
104
- &zName[nRoot]
104
+ "INSERT OR IGNORE INTO sfile(pathname)"
105
+ " SELECT %Q WHERE NOT EXISTS"
106
+ " (SELECT 1 FROM vfile WHERE pathname=%Q)",
107
+ &zName[nRoot], &zName[nRoot]
105108
);
106109
}
107110
blob_reset(&name);
108111
}
109112
}
110113
--- src/checkin.c
+++ src/checkin.c
@@ -97,13 +97,16 @@
97 }else if( isDir==0 ){
98 fossil_warning("not found: %s", &zName[nRoot]);
99 }else if( file_access(zName, R_OK) ){
100 fossil_fatal("cannot open %s", &zName[nRoot]);
101 }else{
 
102 db_multi_exec(
103 "INSERT OR IGNORE INTO sfile(pathname) VALUES(%Q)",
104 &zName[nRoot]
 
 
105 );
106 }
107 blob_reset(&name);
108 }
109 }
110
--- src/checkin.c
+++ src/checkin.c
@@ -97,13 +97,16 @@
97 }else if( isDir==0 ){
98 fossil_warning("not found: %s", &zName[nRoot]);
99 }else if( file_access(zName, R_OK) ){
100 fossil_fatal("cannot open %s", &zName[nRoot]);
101 }else{
102 /* Only add unmanaged file paths specified on the command line. */
103 db_multi_exec(
104 "INSERT OR IGNORE INTO sfile(pathname)"
105 " SELECT %Q WHERE NOT EXISTS"
106 " (SELECT 1 FROM vfile WHERE pathname=%Q)",
107 &zName[nRoot], &zName[nRoot]
108 );
109 }
110 blob_reset(&name);
111 }
112 }
113
+1
--- src/file.c
+++ src/file.c
@@ -493,10 +493,11 @@
493493
#else
494494
rc = chdir(zPath);
495495
if( !rc && bChroot ){
496496
rc = chroot(zPath);
497497
if( !rc ) rc = chdir("/");
498
+ g.fJail = 1;
498499
}
499500
#endif
500501
fossil_path_free(zPath);
501502
return rc;
502503
}
503504
--- src/file.c
+++ src/file.c
@@ -493,10 +493,11 @@
493 #else
494 rc = chdir(zPath);
495 if( !rc && bChroot ){
496 rc = chroot(zPath);
497 if( !rc ) rc = chdir("/");
 
498 }
499 #endif
500 fossil_path_free(zPath);
501 return rc;
502 }
503
--- src/file.c
+++ src/file.c
@@ -493,10 +493,11 @@
493 #else
494 rc = chdir(zPath);
495 if( !rc && bChroot ){
496 rc = chroot(zPath);
497 if( !rc ) rc = chdir("/");
498 g.fJail = 1;
499 }
500 #endif
501 fossil_path_free(zPath);
502 return rc;
503 }
504
+4 -5
--- src/href.js
+++ src/href.js
@@ -16,11 +16,10 @@
1616
** milliseconds delay prior to populating href= and action=. If the
1717
** mouseover boolean is true, then the href= rewrite is further delayed
1818
** until the first mousedown event that occurs after the timer expires.
1919
*/
2020
var antiRobot = 0;
21
-var antiRobotBody = document.getElementsByTagName("body")[0];
2221
function antiRobotGo(){
2322
if( antiRobot!=3 ) return;
2423
antiRobot = 7;
2524
var anchors = document.getElementsByTagName("a");
2625
for(var i=0; i<anchors.length; i++){
@@ -36,19 +35,19 @@
3635
function antiRobotDefense(){
3736
var x = document.getElementById("href-data");
3837
var jx = x.textContent || x.innerText;
3938
var g = JSON.parse(jx);
4039
if( g.mouseover ){
41
- antiRobotBody.onmousedown=function(){
40
+ document.body.onmousedown=function(){
4241
antiRobot |= 2;
4342
antiRobotGo();
44
- antiRobotBody.onmousedown=null;
43
+ document.body.onmousedown=null;
4544
}
46
- antiRobotBody.onmousemove=function(){
45
+ document.body.onmousemove=function(){
4746
antiRobot |= 2;
4847
antiRobotGo();
49
- antiRobotBody.onmousemove=null;
48
+ document.body.onmousemove=null;
5049
}
5150
}else{
5251
antiRobot |= 2;
5352
}
5453
if( g.delay>0 ){
5554
--- src/href.js
+++ src/href.js
@@ -16,11 +16,10 @@
16 ** milliseconds delay prior to populating href= and action=. If the
17 ** mouseover boolean is true, then the href= rewrite is further delayed
18 ** until the first mousedown event that occurs after the timer expires.
19 */
20 var antiRobot = 0;
21 var antiRobotBody = document.getElementsByTagName("body")[0];
22 function antiRobotGo(){
23 if( antiRobot!=3 ) return;
24 antiRobot = 7;
25 var anchors = document.getElementsByTagName("a");
26 for(var i=0; i<anchors.length; i++){
@@ -36,19 +35,19 @@
36 function antiRobotDefense(){
37 var x = document.getElementById("href-data");
38 var jx = x.textContent || x.innerText;
39 var g = JSON.parse(jx);
40 if( g.mouseover ){
41 antiRobotBody.onmousedown=function(){
42 antiRobot |= 2;
43 antiRobotGo();
44 antiRobotBody.onmousedown=null;
45 }
46 antiRobotBody.onmousemove=function(){
47 antiRobot |= 2;
48 antiRobotGo();
49 antiRobotBody.onmousemove=null;
50 }
51 }else{
52 antiRobot |= 2;
53 }
54 if( g.delay>0 ){
55
--- src/href.js
+++ src/href.js
@@ -16,11 +16,10 @@
16 ** milliseconds delay prior to populating href= and action=. If the
17 ** mouseover boolean is true, then the href= rewrite is further delayed
18 ** until the first mousedown event that occurs after the timer expires.
19 */
20 var antiRobot = 0;
 
21 function antiRobotGo(){
22 if( antiRobot!=3 ) return;
23 antiRobot = 7;
24 var anchors = document.getElementsByTagName("a");
25 for(var i=0; i<anchors.length; i++){
@@ -36,19 +35,19 @@
35 function antiRobotDefense(){
36 var x = document.getElementById("href-data");
37 var jx = x.textContent || x.innerText;
38 var g = JSON.parse(jx);
39 if( g.mouseover ){
40 document.body.onmousedown=function(){
41 antiRobot |= 2;
42 antiRobotGo();
43 document.body.onmousedown=null;
44 }
45 document.body.onmousemove=function(){
46 antiRobot |= 2;
47 antiRobotGo();
48 document.body.onmousemove=null;
49 }
50 }else{
51 antiRobot |= 2;
52 }
53 if( g.delay>0 ){
54
+22 -23
--- src/login.c
+++ src/login.c
@@ -2123,34 +2123,33 @@
21232123
** Usage: %fossil login-group ?SUBCOMMAND? ?OPTIONS?
21242124
**
21252125
** Run various subcommands to manage login-group related settings of the open
21262126
** repository or of the repository identified by the -R or --repository option.
21272127
**
2128
-** > fossil login-group
2129
-**
2130
-** Show the login-group to which the repository belongs.
2131
-**
2132
-** > fossil login-group join REPO ?--name NAME?
2133
-**
2134
-** Add this repository to login group to which REPO belongs, or creates a
2135
-** new login group between itself and REPO if REPO does not already belong
2136
-** to a login-group. When creating a new login-group, the name of the new
2137
-** group is determined by the "--name" option. REPO may optionally be
2138
-** specified using the -R REPO flag.
2139
-**
2140
-** > fossil login-group leave
2141
-**
2142
-** Takes the repository out of whatever login group it is currently
2143
-** a part of.
2144
-**
2145
-** Options valid for all subcommands:
2146
-**
2147
-** -R|--repository REPO Run commands on repository REPO
2128
+** > fossil login-group ?-R REPO?
2129
+**
2130
+** Show the login-group to which REPO, or if invoked from within a checkout
2131
+** the repository on which the current checkout is based, belongs.
2132
+**
2133
+** > fossil login-group join ?-R? REPO ?--name NAME?
2134
+**
2135
+** This subcommand must be invoked from within a checkout to either: add
2136
+** the open repository to the login group that REPO is a member, in which
2137
+** case the optional "--name" argument is not required; or create a new
2138
+** login group between the open repository and REPO, in which case the new
2139
+** group NAME is determined by the mandatory "--name" option. REPO may be
2140
+** specified with or without the -R flag.
2141
+**
2142
+** > fossil login-group leave ?-R REPO?
2143
+**
2144
+** Take the repository REPO, or if invoked from within a checkout the
2145
+** repository on which the current checkout is based, out of whatever
2146
+** login group it is a member.
21482147
**
21492148
** About Login Groups:
2150
-**
2151
-** A login-group is a set of repositories that share user credentials.
2149
+**
2150
+** A login-group is a set of repositories that share user credentials.
21522151
** If a user is logged into one member of the group, then that user can
21532152
** access any other group member as long as they have an entry in the USER
21542153
** table of that member. If a user changes their password using web
21552154
** interface, their password is also automatically changed in every other
21562155
** member of the login group.
@@ -2203,12 +2202,12 @@
22032202
if( zLGName==0 ){
22042203
fossil_print("Not currently a part of any login-group\n");
22052204
return;
22062205
}
22072206
fossil_print("Now part of login-group \"%s\" with:\n", zLGName);
2208
- db_prepare(&q, "SELECT value FROM config WHERE name LIKE 'peer-name-%%'");
2207
+ db_prepare(&q, "SELECT value FROM config WHERE name LIKE 'peer-repo-%%'");
22092208
while( db_step(&q)==SQLITE_ROW ){
22102209
fossil_print(" %s\n", db_column_text(&q,0));
22112210
}
22122211
db_finalize(&q);
22132212
22142213
}
22152214
--- src/login.c
+++ src/login.c
@@ -2123,34 +2123,33 @@
2123 ** Usage: %fossil login-group ?SUBCOMMAND? ?OPTIONS?
2124 **
2125 ** Run various subcommands to manage login-group related settings of the open
2126 ** repository or of the repository identified by the -R or --repository option.
2127 **
2128 ** > fossil login-group
2129 **
2130 ** Show the login-group to which the repository belongs.
2131 **
2132 ** > fossil login-group join REPO ?--name NAME?
2133 **
2134 ** Add this repository to login group to which REPO belongs, or creates a
2135 ** new login group between itself and REPO if REPO does not already belong
2136 ** to a login-group. When creating a new login-group, the name of the new
2137 ** group is determined by the "--name" option. REPO may optionally be
2138 ** specified using the -R REPO flag.
2139 **
2140 ** > fossil login-group leave
2141 **
2142 ** Takes the repository out of whatever login group it is currently
2143 ** a part of.
2144 **
2145 ** Options valid for all subcommands:
2146 **
2147 ** -R|--repository REPO Run commands on repository REPO
2148 **
2149 ** About Login Groups:
2150 **
2151 ** A login-group is a set of repositories that share user credentials.
2152 ** If a user is logged into one member of the group, then that user can
2153 ** access any other group member as long as they have an entry in the USER
2154 ** table of that member. If a user changes their password using web
2155 ** interface, their password is also automatically changed in every other
2156 ** member of the login group.
@@ -2203,12 +2202,12 @@
2203 if( zLGName==0 ){
2204 fossil_print("Not currently a part of any login-group\n");
2205 return;
2206 }
2207 fossil_print("Now part of login-group \"%s\" with:\n", zLGName);
2208 db_prepare(&q, "SELECT value FROM config WHERE name LIKE 'peer-name-%%'");
2209 while( db_step(&q)==SQLITE_ROW ){
2210 fossil_print(" %s\n", db_column_text(&q,0));
2211 }
2212 db_finalize(&q);
2213
2214 }
2215
--- src/login.c
+++ src/login.c
@@ -2123,34 +2123,33 @@
2123 ** Usage: %fossil login-group ?SUBCOMMAND? ?OPTIONS?
2124 **
2125 ** Run various subcommands to manage login-group related settings of the open
2126 ** repository or of the repository identified by the -R or --repository option.
2127 **
2128 ** > fossil login-group ?-R REPO?
2129 **
2130 ** Show the login-group to which REPO, or if invoked from within a checkout
2131 ** the repository on which the current checkout is based, belongs.
2132 **
2133 ** > fossil login-group join ?-R? REPO ?--name NAME?
2134 **
2135 ** This subcommand must be invoked from within a checkout to either: add
2136 ** the open repository to the login group that REPO is a member, in which
2137 ** case the optional "--name" argument is not required; or create a new
2138 ** login group between the open repository and REPO, in which case the new
2139 ** group NAME is determined by the mandatory "--name" option. REPO may be
2140 ** specified with or without the -R flag.
2141 **
2142 ** > fossil login-group leave ?-R REPO?
2143 **
2144 ** Take the repository REPO, or if invoked from within a checkout the
2145 ** repository on which the current checkout is based, out of whatever
2146 ** login group it is a member.
 
2147 **
2148 ** About Login Groups:
2149 **
2150 ** A login-group is a set of repositories that share user credentials.
2151 ** If a user is logged into one member of the group, then that user can
2152 ** access any other group member as long as they have an entry in the USER
2153 ** table of that member. If a user changes their password using web
2154 ** interface, their password is also automatically changed in every other
2155 ** member of the login group.
@@ -2203,12 +2202,12 @@
2202 if( zLGName==0 ){
2203 fossil_print("Not currently a part of any login-group\n");
2204 return;
2205 }
2206 fossil_print("Now part of login-group \"%s\" with:\n", zLGName);
2207 db_prepare(&q, "SELECT value FROM config WHERE name LIKE 'peer-repo-%%'");
2208 while( db_step(&q)==SQLITE_ROW ){
2209 fossil_print(" %s\n", db_column_text(&q,0));
2210 }
2211 db_finalize(&q);
2212
2213 }
2214
+8 -4
--- src/main.c
+++ src/main.c
@@ -1511,11 +1511,10 @@
15111511
}
15121512
zRepo += n;
15131513
if( *zRepo == '\0' ) zRepo = "/";
15141514
}else {
15151515
zRepo = "/";
1516
- g.fJail = 1;
15171516
}
15181517
if( file_chdir(zDir, 1) ){
15191518
fossil_panic("unable to chroot into %s", zDir);
15201519
}
15211520
}else{
@@ -2451,18 +2450,22 @@
24512450
*/
24522451
cgi_setenv("HOME", blob_str(&value));
24532452
blob_reset(&value);
24542453
continue;
24552454
}
2456
- if( blob_eq(&key, "skin:") && blob_token(&line, &value) ){
2455
+ if( blob_eq(&key, "skin:") ){
24572456
/* skin: LABEL
24582457
**
24592458
** Use one of the built-in skins defined by LABEL. LABEL is the
24602459
** name of the subdirectory under the skins/ directory that holds
24612460
** the elements of the built-in skin. If LABEL does not match,
2462
- ** this directive is a silent no-op.
2461
+ ** this directive is a silent no-op. It may alternately be
2462
+ ** an absolute path to a directory which holds skin definition
2463
+ ** files (header.txt, footer.txt, etc.). If LABEL is empty,
2464
+ ** the skin stored in the CONFIG db table is used.
24632465
*/
2466
+ blob_token(&line, &value);
24642467
fossil_free(skin_use_alternative(blob_str(&value), 1));
24652468
blob_reset(&value);
24662469
continue;
24672470
}
24682471
if( blob_eq(&key, "jsmode:") && blob_token(&line, &value) ){
@@ -2720,11 +2723,12 @@
27202723
** --out FILE Write the HTTP reply to FILE instead of to
27212724
** standard output
27222725
** --pkey FILE Read the private key used for TLS from FILE.
27232726
** --repolist If REPOSITORY is directory, URL "/" lists all repos
27242727
** --scgi Interpret input as SCGI rather than HTTP
2725
-** --skin LABEL Use override skin LABEL
2728
+** --skin LABEL Use override skin LABEL. Use an empty string ("")
2729
+** to force use of the current local skin config.
27262730
** --th-trace Trace TH1 execution (for debugging purposes)
27272731
** --usepidkey Use saved encryption key from parent process. This is
27282732
** only necessary when using SEE on Windows.
27292733
**
27302734
** See also: [[cgi]], [[server]], [[winsrv]]
27312735
--- src/main.c
+++ src/main.c
@@ -1511,11 +1511,10 @@
1511 }
1512 zRepo += n;
1513 if( *zRepo == '\0' ) zRepo = "/";
1514 }else {
1515 zRepo = "/";
1516 g.fJail = 1;
1517 }
1518 if( file_chdir(zDir, 1) ){
1519 fossil_panic("unable to chroot into %s", zDir);
1520 }
1521 }else{
@@ -2451,18 +2450,22 @@
2451 */
2452 cgi_setenv("HOME", blob_str(&value));
2453 blob_reset(&value);
2454 continue;
2455 }
2456 if( blob_eq(&key, "skin:") && blob_token(&line, &value) ){
2457 /* skin: LABEL
2458 **
2459 ** Use one of the built-in skins defined by LABEL. LABEL is the
2460 ** name of the subdirectory under the skins/ directory that holds
2461 ** the elements of the built-in skin. If LABEL does not match,
2462 ** this directive is a silent no-op.
 
 
 
2463 */
 
2464 fossil_free(skin_use_alternative(blob_str(&value), 1));
2465 blob_reset(&value);
2466 continue;
2467 }
2468 if( blob_eq(&key, "jsmode:") && blob_token(&line, &value) ){
@@ -2720,11 +2723,12 @@
2720 ** --out FILE Write the HTTP reply to FILE instead of to
2721 ** standard output
2722 ** --pkey FILE Read the private key used for TLS from FILE.
2723 ** --repolist If REPOSITORY is directory, URL "/" lists all repos
2724 ** --scgi Interpret input as SCGI rather than HTTP
2725 ** --skin LABEL Use override skin LABEL
 
2726 ** --th-trace Trace TH1 execution (for debugging purposes)
2727 ** --usepidkey Use saved encryption key from parent process. This is
2728 ** only necessary when using SEE on Windows.
2729 **
2730 ** See also: [[cgi]], [[server]], [[winsrv]]
2731
--- src/main.c
+++ src/main.c
@@ -1511,11 +1511,10 @@
1511 }
1512 zRepo += n;
1513 if( *zRepo == '\0' ) zRepo = "/";
1514 }else {
1515 zRepo = "/";
 
1516 }
1517 if( file_chdir(zDir, 1) ){
1518 fossil_panic("unable to chroot into %s", zDir);
1519 }
1520 }else{
@@ -2451,18 +2450,22 @@
2450 */
2451 cgi_setenv("HOME", blob_str(&value));
2452 blob_reset(&value);
2453 continue;
2454 }
2455 if( blob_eq(&key, "skin:") ){
2456 /* skin: LABEL
2457 **
2458 ** Use one of the built-in skins defined by LABEL. LABEL is the
2459 ** name of the subdirectory under the skins/ directory that holds
2460 ** the elements of the built-in skin. If LABEL does not match,
2461 ** this directive is a silent no-op. It may alternately be
2462 ** an absolute path to a directory which holds skin definition
2463 ** files (header.txt, footer.txt, etc.). If LABEL is empty,
2464 ** the skin stored in the CONFIG db table is used.
2465 */
2466 blob_token(&line, &value);
2467 fossil_free(skin_use_alternative(blob_str(&value), 1));
2468 blob_reset(&value);
2469 continue;
2470 }
2471 if( blob_eq(&key, "jsmode:") && blob_token(&line, &value) ){
@@ -2720,11 +2723,12 @@
2723 ** --out FILE Write the HTTP reply to FILE instead of to
2724 ** standard output
2725 ** --pkey FILE Read the private key used for TLS from FILE.
2726 ** --repolist If REPOSITORY is directory, URL "/" lists all repos
2727 ** --scgi Interpret input as SCGI rather than HTTP
2728 ** --skin LABEL Use override skin LABEL. Use an empty string ("")
2729 ** to force use of the current local skin config.
2730 ** --th-trace Trace TH1 execution (for debugging purposes)
2731 ** --usepidkey Use saved encryption key from parent process. This is
2732 ** only necessary when using SEE on Windows.
2733 **
2734 ** See also: [[cgi]], [[server]], [[winsrv]]
2735
+20 -9
--- src/skins.c
+++ src/skins.c
@@ -71,10 +71,16 @@
7171
** or NULL if the skin should be as configured.
7272
*/
7373
static struct BuiltinSkin *pAltSkin = 0;
7474
static char *zAltSkinDir = 0;
7575
static int iDraftSkin = 0;
76
+/*
77
+** Used by skin_use_alternative() to store the current skin rank skin
78
+** so that the /skins page can, if warranted, warn the user that skin
79
+** changes won't have any effect.
80
+*/
81
+static int nSkinRank = 5;
7682
7783
/*
7884
** Skin details are a set of key/value pairs that define display
7985
** attributes of the skin that cannot be easily specified using CSS
8086
** or that need to be known on the server-side.
@@ -139,15 +145,14 @@
139145
** As a special case, a NULL or empty name resets zAltSkinDir and
140146
** pAltSkin to 0 to indicate that the current config-side skin should
141147
** be used (rank 3, above), then returns 0.
142148
*/
143149
char *skin_use_alternative(const char *zName, int rank){
144
- static int currentRank = 5;
145150
int i;
146151
Blob err = BLOB_INITIALIZER;
147
- if(rank > currentRank) return 0;
148
- currentRank = rank;
152
+ if(rank > nSkinRank) return 0;
153
+ nSkinRank = rank;
149154
if( zName && 1==rank && strchr(zName, '/')!=0 ){
150155
zAltSkinDir = fossil_strdup(zName);
151156
return 0;
152157
}
153158
if( zName && sqlite3_strglob("draft[1-9]", zName)==0 ){
@@ -1198,16 +1203,22 @@
11981203
}
11991204
fossil_free(zPattern);
12001205
}
12011206
login_check_credentials();
12021207
style_header("Skins");
1203
- if(zAltSkinDir && zAltSkinDir[0]){
1204
- @ <p class="warning">Warning: this fossil instance was started with
1205
- @ a hard-coded skin value which trumps any option selected below.
1206
- @ A skins selected below will be recorded in your prefere cookie
1207
- @ but will not be used until/unless the site administrator
1208
- @ configures the site to run without a forced hard-coded skin.
1208
+ if( iDraftSkin || nSkinRank<=1 ){
1209
+ @ <p class="warning">Warning:
1210
+ if( iDraftSkin>0 ){
1211
+ @ you are using a draft skin,
1212
+ }else{
1213
+ @ this fossil instance was started with a hard-coded skin
1214
+ @ value,
1215
+ }
1216
+ @ which trumps any option selected below. A skin selected
1217
+ @ below will be recorded in your preference cookie
1218
+ @ but will not be used so long as the site has a
1219
+ @ higher-priority skin in place.
12091220
@ </p>
12101221
}
12111222
@ <p>The following skins are available for this repository:</p>
12121223
@ <ul>
12131224
if( pAltSkin==0 && zAltSkinDir==0 && iDraftSkin==0 ){
12141225
--- src/skins.c
+++ src/skins.c
@@ -71,10 +71,16 @@
71 ** or NULL if the skin should be as configured.
72 */
73 static struct BuiltinSkin *pAltSkin = 0;
74 static char *zAltSkinDir = 0;
75 static int iDraftSkin = 0;
 
 
 
 
 
 
76
77 /*
78 ** Skin details are a set of key/value pairs that define display
79 ** attributes of the skin that cannot be easily specified using CSS
80 ** or that need to be known on the server-side.
@@ -139,15 +145,14 @@
139 ** As a special case, a NULL or empty name resets zAltSkinDir and
140 ** pAltSkin to 0 to indicate that the current config-side skin should
141 ** be used (rank 3, above), then returns 0.
142 */
143 char *skin_use_alternative(const char *zName, int rank){
144 static int currentRank = 5;
145 int i;
146 Blob err = BLOB_INITIALIZER;
147 if(rank > currentRank) return 0;
148 currentRank = rank;
149 if( zName && 1==rank && strchr(zName, '/')!=0 ){
150 zAltSkinDir = fossil_strdup(zName);
151 return 0;
152 }
153 if( zName && sqlite3_strglob("draft[1-9]", zName)==0 ){
@@ -1198,16 +1203,22 @@
1198 }
1199 fossil_free(zPattern);
1200 }
1201 login_check_credentials();
1202 style_header("Skins");
1203 if(zAltSkinDir && zAltSkinDir[0]){
1204 @ <p class="warning">Warning: this fossil instance was started with
1205 @ a hard-coded skin value which trumps any option selected below.
1206 @ A skins selected below will be recorded in your prefere cookie
1207 @ but will not be used until/unless the site administrator
1208 @ configures the site to run without a forced hard-coded skin.
 
 
 
 
 
 
1209 @ </p>
1210 }
1211 @ <p>The following skins are available for this repository:</p>
1212 @ <ul>
1213 if( pAltSkin==0 && zAltSkinDir==0 && iDraftSkin==0 ){
1214
--- src/skins.c
+++ src/skins.c
@@ -71,10 +71,16 @@
71 ** or NULL if the skin should be as configured.
72 */
73 static struct BuiltinSkin *pAltSkin = 0;
74 static char *zAltSkinDir = 0;
75 static int iDraftSkin = 0;
76 /*
77 ** Used by skin_use_alternative() to store the current skin rank skin
78 ** so that the /skins page can, if warranted, warn the user that skin
79 ** changes won't have any effect.
80 */
81 static int nSkinRank = 5;
82
83 /*
84 ** Skin details are a set of key/value pairs that define display
85 ** attributes of the skin that cannot be easily specified using CSS
86 ** or that need to be known on the server-side.
@@ -139,15 +145,14 @@
145 ** As a special case, a NULL or empty name resets zAltSkinDir and
146 ** pAltSkin to 0 to indicate that the current config-side skin should
147 ** be used (rank 3, above), then returns 0.
148 */
149 char *skin_use_alternative(const char *zName, int rank){
 
150 int i;
151 Blob err = BLOB_INITIALIZER;
152 if(rank > nSkinRank) return 0;
153 nSkinRank = rank;
154 if( zName && 1==rank && strchr(zName, '/')!=0 ){
155 zAltSkinDir = fossil_strdup(zName);
156 return 0;
157 }
158 if( zName && sqlite3_strglob("draft[1-9]", zName)==0 ){
@@ -1198,16 +1203,22 @@
1203 }
1204 fossil_free(zPattern);
1205 }
1206 login_check_credentials();
1207 style_header("Skins");
1208 if( iDraftSkin || nSkinRank<=1 ){
1209 @ <p class="warning">Warning:
1210 if( iDraftSkin>0 ){
1211 @ you are using a draft skin,
1212 }else{
1213 @ this fossil instance was started with a hard-coded skin
1214 @ value,
1215 }
1216 @ which trumps any option selected below. A skin selected
1217 @ below will be recorded in your preference cookie
1218 @ but will not be used so long as the site has a
1219 @ higher-priority skin in place.
1220 @ </p>
1221 }
1222 @ <p>The following skins are available for this repository:</p>
1223 @ <ul>
1224 if( pAltSkin==0 && zAltSkinDir==0 && iDraftSkin==0 ){
1225
+28 -15
--- src/stash.c
+++ src/stash.c
@@ -693,25 +693,38 @@
693693
undo_save_stash(0);
694694
stash_drop(stashid);
695695
undo_finish();
696696
}
697697
}else
698
- if( memcmp(zCmd, "pop", nCmd)==0 ){
699
- if( g.argc>3 ) usage("pop");
700
- stashid = stash_get_id(0);
701
- undo_begin();
702
- stash_apply(stashid, 0);
703
- undo_save_stash(stashid);
704
- undo_finish();
705
- stash_drop(stashid);
706
- }else
707
- if( memcmp(zCmd, "apply", nCmd)==0 ){
708
- if( g.argc>4 ) usage("apply STASHID");
709
- stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
710
- undo_begin();
711
- stash_apply(stashid, 0);
712
- undo_finish();
698
+ if( memcmp(zCmd, "pop", nCmd)==0 || memcmp(zCmd, "apply", nCmd)==0 ){
699
+ char *zCom = 0, *zDate = 0, *zHash = 0;
700
+ int popped = *zCmd=='p';
701
+ if( popped ){
702
+ if( g.argc>3 ) usage("pop");
703
+ stashid = stash_get_id(0);
704
+ }else{
705
+ if( g.argc>4 ) usage("apply STASHID");
706
+ stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
707
+ }
708
+ zCom = db_text(0, "SELECT comment FROM stash WHERE stashid=%d", stashid);
709
+ zDate = db_text(0, "SELECT datetime(ctime) FROM stash WHERE stashid=%d",
710
+ stashid);
711
+ zHash = db_text(0, "SELECT hash FROM stash WHERE stashid=%d", stashid);
712
+ undo_begin();
713
+ stash_apply(stashid, 0);
714
+ if( popped ) undo_save_stash(stashid);
715
+ fossil_print("%s stash:\n%5d: [%.14s] from %s\n",
716
+ popped ? "Popped" : "Applied", stashid, zHash, zDate);
717
+ if( zCom && *zCom ){
718
+ fossil_print(" ");
719
+ comment_print(zCom, 0, 7, -1, get_comment_format());
720
+ }
721
+ fossil_free(zCom);
722
+ fossil_free(zDate);
723
+ fossil_free(zHash);
724
+ undo_finish();
725
+ if( popped ) stash_drop(stashid);
713726
}else
714727
if( memcmp(zCmd, "goto", nCmd)==0 ){
715728
int nConflict;
716729
int vid;
717730
if( g.argc>4 ) usage("apply STASHID");
718731
--- src/stash.c
+++ src/stash.c
@@ -693,25 +693,38 @@
693 undo_save_stash(0);
694 stash_drop(stashid);
695 undo_finish();
696 }
697 }else
698 if( memcmp(zCmd, "pop", nCmd)==0 ){
699 if( g.argc>3 ) usage("pop");
700 stashid = stash_get_id(0);
701 undo_begin();
702 stash_apply(stashid, 0);
703 undo_save_stash(stashid);
704 undo_finish();
705 stash_drop(stashid);
706 }else
707 if( memcmp(zCmd, "apply", nCmd)==0 ){
708 if( g.argc>4 ) usage("apply STASHID");
709 stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
710 undo_begin();
711 stash_apply(stashid, 0);
712 undo_finish();
 
 
 
 
 
 
 
 
 
 
 
 
 
713 }else
714 if( memcmp(zCmd, "goto", nCmd)==0 ){
715 int nConflict;
716 int vid;
717 if( g.argc>4 ) usage("apply STASHID");
718
--- src/stash.c
+++ src/stash.c
@@ -693,25 +693,38 @@
693 undo_save_stash(0);
694 stash_drop(stashid);
695 undo_finish();
696 }
697 }else
698 if( memcmp(zCmd, "pop", nCmd)==0 || memcmp(zCmd, "apply", nCmd)==0 ){
699 char *zCom = 0, *zDate = 0, *zHash = 0;
700 int popped = *zCmd=='p';
701 if( popped ){
702 if( g.argc>3 ) usage("pop");
703 stashid = stash_get_id(0);
704 }else{
705 if( g.argc>4 ) usage("apply STASHID");
706 stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
707 }
708 zCom = db_text(0, "SELECT comment FROM stash WHERE stashid=%d", stashid);
709 zDate = db_text(0, "SELECT datetime(ctime) FROM stash WHERE stashid=%d",
710 stashid);
711 zHash = db_text(0, "SELECT hash FROM stash WHERE stashid=%d", stashid);
712 undo_begin();
713 stash_apply(stashid, 0);
714 if( popped ) undo_save_stash(stashid);
715 fossil_print("%s stash:\n%5d: [%.14s] from %s\n",
716 popped ? "Popped" : "Applied", stashid, zHash, zDate);
717 if( zCom && *zCom ){
718 fossil_print(" ");
719 comment_print(zCom, 0, 7, -1, get_comment_format());
720 }
721 fossil_free(zCom);
722 fossil_free(zDate);
723 fossil_free(zHash);
724 undo_finish();
725 if( popped ) stash_drop(stashid);
726 }else
727 if( memcmp(zCmd, "goto", nCmd)==0 ){
728 int nConflict;
729 int vid;
730 if( g.argc>4 ) usage("apply STASHID");
731
+12 -7
--- src/sync.c
+++ src/sync.c
@@ -481,13 +481,14 @@
481481
** COMMAND: remote-url*
482482
**
483483
** Usage: %fossil remote ?SUBCOMMAND ...?
484484
**
485485
** View or modify the URLs of remote repositories used for syncing.
486
-** The "default" remote is the URL used in the most recent "sync",
487
-** "push", "pull", "clone", or similar command. The default remote can
488
-** change with each sync command. Other named remotes are persistent.
486
+** The "default" remote is specially named by Fossil and corresponds to
487
+** the URL used in the most recent "sync", "push", "pull", "clone", or
488
+** similar command. As such, the default remote can be updated by
489
+** Fossil with each sync command. Other named remotes are persistent.
489490
**
490491
** > fossil remote
491492
**
492493
** With no arguments, this command shows the current default remote
493494
** URL. If there is no default, it shows "off".
@@ -494,12 +495,14 @@
494495
**
495496
** > fossil remote add NAME URL
496497
**
497498
** Add a new named URL. Afterwards, NAME can be used as a short
498499
** symbolic name for URL in contexts where a URL is required. The
499
-** URL argument can be "default" or a prior symbolic name, to make
500
-** a copy of an existing URL under a new name.
500
+** URL argument can be "default" or a prior symbolic name to make
501
+** a copy of an existing URL under the new NAME. The "default"
502
+** remote cannot be defined with this subcommand; instead,
503
+** use 'fossil remote REF' as documented below.
501504
**
502505
** > fossil remote config-data
503506
**
504507
** DEBUG USE ONLY - Show the name and value of every CONFIG table
505508
** entry in the repository that is associated with the remote URL store.
@@ -633,11 +636,14 @@
633636
UrlData x;
634637
if( g.argc!=5 ) usage("add NAME URL");
635638
memset(&x, 0, sizeof(x));
636639
zName = g.argv[3];
637640
zUrl = g.argv[4];
638
- if( strcmp(zName,"default")==0 ) goto remote_add_default;
641
+ if( strcmp(zName,"default")==0 ){
642
+ fossil_fatal("update the \"default\" remote-url with 'fossil remote REF'"
643
+ "\nsee 'fossil help remote' for complete usage information");
644
+ }
639645
db_begin_write();
640646
if( fossil_strcmp(zUrl,"default")==0 ){
641647
x.canonical = db_get("last-sync-url",0);
642648
x.passwd = unobscure(db_get("last-sync-pw",0));
643649
}else{
@@ -788,11 +794,10 @@
788794
|| sqlite3_strlike("https://%",zArg,0)==0
789795
|| sqlite3_strlike("ssh:%",zArg,0)==0
790796
|| sqlite3_strlike("file:%",zArg,0)==0
791797
|| db_exists("SELECT 1 FROM config WHERE name='sync-url:%q'",zArg)
792798
){
793
-remote_add_default:
794799
db_unset("last-sync-url", 0);
795800
db_unset("last-sync-pw", 0);
796801
url_parse(g.argv[2], URL_REMEMBER|URL_PROMPT_PW|
797802
URL_USE_CONFIG|URL_ASK_REMEMBER_PW);
798803
url_remember();
799804
--- src/sync.c
+++ src/sync.c
@@ -481,13 +481,14 @@
481 ** COMMAND: remote-url*
482 **
483 ** Usage: %fossil remote ?SUBCOMMAND ...?
484 **
485 ** View or modify the URLs of remote repositories used for syncing.
486 ** The "default" remote is the URL used in the most recent "sync",
487 ** "push", "pull", "clone", or similar command. The default remote can
488 ** change with each sync command. Other named remotes are persistent.
 
489 **
490 ** > fossil remote
491 **
492 ** With no arguments, this command shows the current default remote
493 ** URL. If there is no default, it shows "off".
@@ -494,12 +495,14 @@
494 **
495 ** > fossil remote add NAME URL
496 **
497 ** Add a new named URL. Afterwards, NAME can be used as a short
498 ** symbolic name for URL in contexts where a URL is required. The
499 ** URL argument can be "default" or a prior symbolic name, to make
500 ** a copy of an existing URL under a new name.
 
 
501 **
502 ** > fossil remote config-data
503 **
504 ** DEBUG USE ONLY - Show the name and value of every CONFIG table
505 ** entry in the repository that is associated with the remote URL store.
@@ -633,11 +636,14 @@
633 UrlData x;
634 if( g.argc!=5 ) usage("add NAME URL");
635 memset(&x, 0, sizeof(x));
636 zName = g.argv[3];
637 zUrl = g.argv[4];
638 if( strcmp(zName,"default")==0 ) goto remote_add_default;
 
 
 
639 db_begin_write();
640 if( fossil_strcmp(zUrl,"default")==0 ){
641 x.canonical = db_get("last-sync-url",0);
642 x.passwd = unobscure(db_get("last-sync-pw",0));
643 }else{
@@ -788,11 +794,10 @@
788 || sqlite3_strlike("https://%",zArg,0)==0
789 || sqlite3_strlike("ssh:%",zArg,0)==0
790 || sqlite3_strlike("file:%",zArg,0)==0
791 || db_exists("SELECT 1 FROM config WHERE name='sync-url:%q'",zArg)
792 ){
793 remote_add_default:
794 db_unset("last-sync-url", 0);
795 db_unset("last-sync-pw", 0);
796 url_parse(g.argv[2], URL_REMEMBER|URL_PROMPT_PW|
797 URL_USE_CONFIG|URL_ASK_REMEMBER_PW);
798 url_remember();
799
--- src/sync.c
+++ src/sync.c
@@ -481,13 +481,14 @@
481 ** COMMAND: remote-url*
482 **
483 ** Usage: %fossil remote ?SUBCOMMAND ...?
484 **
485 ** View or modify the URLs of remote repositories used for syncing.
486 ** The "default" remote is specially named by Fossil and corresponds to
487 ** the URL used in the most recent "sync", "push", "pull", "clone", or
488 ** similar command. As such, the default remote can be updated by
489 ** Fossil with each sync command. Other named remotes are persistent.
490 **
491 ** > fossil remote
492 **
493 ** With no arguments, this command shows the current default remote
494 ** URL. If there is no default, it shows "off".
@@ -494,12 +495,14 @@
495 **
496 ** > fossil remote add NAME URL
497 **
498 ** Add a new named URL. Afterwards, NAME can be used as a short
499 ** symbolic name for URL in contexts where a URL is required. The
500 ** URL argument can be "default" or a prior symbolic name to make
501 ** a copy of an existing URL under the new NAME. The "default"
502 ** remote cannot be defined with this subcommand; instead,
503 ** use 'fossil remote REF' as documented below.
504 **
505 ** > fossil remote config-data
506 **
507 ** DEBUG USE ONLY - Show the name and value of every CONFIG table
508 ** entry in the repository that is associated with the remote URL store.
@@ -633,11 +636,14 @@
636 UrlData x;
637 if( g.argc!=5 ) usage("add NAME URL");
638 memset(&x, 0, sizeof(x));
639 zName = g.argv[3];
640 zUrl = g.argv[4];
641 if( strcmp(zName,"default")==0 ){
642 fossil_fatal("update the \"default\" remote-url with 'fossil remote REF'"
643 "\nsee 'fossil help remote' for complete usage information");
644 }
645 db_begin_write();
646 if( fossil_strcmp(zUrl,"default")==0 ){
647 x.canonical = db_get("last-sync-url",0);
648 x.passwd = unobscure(db_get("last-sync-pw",0));
649 }else{
@@ -788,11 +794,10 @@
794 || sqlite3_strlike("https://%",zArg,0)==0
795 || sqlite3_strlike("ssh:%",zArg,0)==0
796 || sqlite3_strlike("file:%",zArg,0)==0
797 || db_exists("SELECT 1 FROM config WHERE name='sync-url:%q'",zArg)
798 ){
 
799 db_unset("last-sync-url", 0);
800 db_unset("last-sync-pw", 0);
801 url_parse(g.argv[2], URL_REMEMBER|URL_PROMPT_PW|
802 URL_USE_CONFIG|URL_ASK_REMEMBER_PW);
803 url_remember();
804
--- tools/skintxt2config.c
+++ tools/skintxt2config.c
@@ -90,11 +90,11 @@
9090
err("Malloc failed.");
9191
rc = ENOMEM;
9292
goto end;
9393
}
9494
zMem[fpos] = 0;
95
- if((size_t)1 != fread(zMem, (size_t)fpos, 1, f)){
95
+ if(fpos && (size_t)1 != fread(zMem, (size_t)fpos, 1, f)){
9696
rc = EIO;
9797
err("Error #%d reading file %s", rc, zFilename);
9898
goto end;
9999
}
100100
end:
101101
--- tools/skintxt2config.c
+++ tools/skintxt2config.c
@@ -90,11 +90,11 @@
90 err("Malloc failed.");
91 rc = ENOMEM;
92 goto end;
93 }
94 zMem[fpos] = 0;
95 if((size_t)1 != fread(zMem, (size_t)fpos, 1, f)){
96 rc = EIO;
97 err("Error #%d reading file %s", rc, zFilename);
98 goto end;
99 }
100 end:
101
--- tools/skintxt2config.c
+++ tools/skintxt2config.c
@@ -90,11 +90,11 @@
90 err("Malloc failed.");
91 rc = ENOMEM;
92 goto end;
93 }
94 zMem[fpos] = 0;
95 if(fpos && (size_t)1 != fread(zMem, (size_t)fpos, 1, f)){
96 rc = EIO;
97 err("Error #%d reading file %s", rc, zFilename);
98 goto end;
99 }
100 end:
101
--- www/containers.md
+++ www/containers.md
@@ -155,12 +155,12 @@
155155
--volume ~/museum/my-project.fossil:/jail/museum/repo.fossil
156156
```
157157
158158
That lets us have a convenient file name for the project outside the
159159
container while letting the configuration inside the container refer to
160
-the generic “`/museum/repo.fossil`” name. Why should we have to rename
161
-the container generically on the outside just to placate the container?
160
+the generic “`/museum/repo.fossil`” name. Why should we have to name
161
+the repo generically on the outside merely to placate the container?
162162
163163
The reason is, you might be serving that repo with [WAL mode][wal]
164164
enabled. If you map the repo DB alone into the container, the Fossil
165165
instance inside the container will write the `-journal` and `-wal` files
166166
alongside the mapped-in repository inside the container. That’s fine as
@@ -174,28 +174,16 @@
174174
so there is at least a *hope* that WAL will work properly across that
175175
boundary. The success of the scheme depends on the `mmap()` and shared
176176
memory system calls being coordinated properly by the OS kernel the two
177177
worlds share.
178178
179
-At some point, someone should perform tests in the hopes of *failing* to
180
-create database corruption in this scenario.
181
-
182
-Why the tortured grammar? Because you cannot prove a negative, being in
183
-this case “SQLite will not corrupt the database in WAL mode if there’s a
184
-container barrier in the way.” All you can prove is that a given test
185
-didn’t cause corruption. With enough tests of sufficient power, you can
186
-begin to make definitive statements, but even then, science is always
187
-provisional, awaiting a single disproving experiment. Atop that, OCI
188
-container runtimes give the sysadmin freedom to impose barriers between
189
-the two worlds, so even if you convince yourself that WAL mode is safe
190
-in a given setup, it’s possible to configure it to fail. As if that
191
-weren’t enough, different container runtimes have different defaults,
192
-including details like whether shared memory is truly shared between
193
-the host and its containers.
194
-
195
-Until someone gets around to establishing this ground truth and scoping
196
-its applicable range, my advice to those who want to use WAL mode on
179
+There is [a plan](https://tangentsoft.com/sqlite/dir/walbanger?ci=trunk)
180
+for proving to a reasonable level of confidence that using WAL across a
181
+container boundary is safe, but this effort is still in the early stages
182
+as of this writing.
183
+
184
+Until that’s settled, my advice to those who want to use WAL mode on
197185
containerized servers is to map the whole directory as shown in these
198186
examples, but then isolate the two sides with a secondary clone. On the
199187
outside, you say something like this:
200188
201189
```
202190
--- www/containers.md
+++ www/containers.md
@@ -155,12 +155,12 @@
155 --volume ~/museum/my-project.fossil:/jail/museum/repo.fossil
156 ```
157
158 That lets us have a convenient file name for the project outside the
159 container while letting the configuration inside the container refer to
160 the generic “`/museum/repo.fossil`” name. Why should we have to rename
161 the container generically on the outside just to placate the container?
162
163 The reason is, you might be serving that repo with [WAL mode][wal]
164 enabled. If you map the repo DB alone into the container, the Fossil
165 instance inside the container will write the `-journal` and `-wal` files
166 alongside the mapped-in repository inside the container. That’s fine as
@@ -174,28 +174,16 @@
174 so there is at least a *hope* that WAL will work properly across that
175 boundary. The success of the scheme depends on the `mmap()` and shared
176 memory system calls being coordinated properly by the OS kernel the two
177 worlds share.
178
179 At some point, someone should perform tests in the hopes of *failing* to
180 create database corruption in this scenario.
181
182 Why the tortured grammar? Because you cannot prove a negative, being in
183 this case “SQLite will not corrupt the database in WAL mode if there’s a
184 container barrier in the way.” All you can prove is that a given test
185 didn’t cause corruption. With enough tests of sufficient power, you can
186 begin to make definitive statements, but even then, science is always
187 provisional, awaiting a single disproving experiment. Atop that, OCI
188 container runtimes give the sysadmin freedom to impose barriers between
189 the two worlds, so even if you convince yourself that WAL mode is safe
190 in a given setup, it’s possible to configure it to fail. As if that
191 weren’t enough, different container runtimes have different defaults,
192 including details like whether shared memory is truly shared between
193 the host and its containers.
194
195 Until someone gets around to establishing this ground truth and scoping
196 its applicable range, my advice to those who want to use WAL mode on
197 containerized servers is to map the whole directory as shown in these
198 examples, but then isolate the two sides with a secondary clone. On the
199 outside, you say something like this:
200
201 ```
202
--- www/containers.md
+++ www/containers.md
@@ -155,12 +155,12 @@
155 --volume ~/museum/my-project.fossil:/jail/museum/repo.fossil
156 ```
157
158 That lets us have a convenient file name for the project outside the
159 container while letting the configuration inside the container refer to
160 the generic “`/museum/repo.fossil`” name. Why should we have to name
161 the repo generically on the outside merely to placate the container?
162
163 The reason is, you might be serving that repo with [WAL mode][wal]
164 enabled. If you map the repo DB alone into the container, the Fossil
165 instance inside the container will write the `-journal` and `-wal` files
166 alongside the mapped-in repository inside the container. That’s fine as
@@ -174,28 +174,16 @@
174 so there is at least a *hope* that WAL will work properly across that
175 boundary. The success of the scheme depends on the `mmap()` and shared
176 memory system calls being coordinated properly by the OS kernel the two
177 worlds share.
178
179 There is [a plan](https://tangentsoft.com/sqlite/dir/walbanger?ci=trunk)
180 for proving to a reasonable level of confidence that using WAL across a
181 container boundary is safe, but this effort is still in the early stages
182 as of this writing.
183
184 Until that’s settled, my advice to those who want to use WAL mode on
 
 
 
 
 
 
 
 
 
 
 
 
185 containerized servers is to map the whole directory as shown in these
186 examples, but then isolate the two sides with a secondary clone. On the
187 outside, you say something like this:
188
189 ```
190
--- www/encryptedrepos.wiki
+++ www/encryptedrepos.wiki
@@ -4,18 +4,18 @@
44
the [https://www.sqlite.org/see/doc/trunk/www/readme.wiki|SQLite Encryption Extension].
55
This technical note explains the process.
66
</blockquote>
77
<h2>Building An Encryption-Enabled Fossil</h2><blockquote>
88
The SQLite Encryption Extension (SEE) is proprietary software and requires
9
-[http://www.hwaci.com/cgi-bin/see-step1|purchasing a license].
9
+[https://sqlite.org/purchase/see|purchasing a license].
1010
<p>
1111
Assuming you have an SEE license, the first step of compiling Fossil to
1212
use SEE is to create an SEE-enabled version of the SQLite database source code.
1313
This alternative SQLite database source file should be called "sqlite3-see.c"
14
-and should be placed in the src/ subfolder of the Fossil sources, right beside
14
+and should be placed in the extsrc/ subfolder of the Fossil sources, right beside
1515
the public-domain "sqlite3.c" source file. Also make a copy of the SEE-enabled
16
-"shell.c" file, renamed as "shell-see.c", and place it in the src/ subfolder
16
+"shell.c" file, renamed as "shell-see.c", and place it in the extsrc/ subfolder
1717
beside the original "shell.c".
1818
<p>
1919
Add the --with-see command-line option to the configuration script to enable
2020
the use of SEE on unix-like systems.
2121
<blockquote><pre>
2222
--- www/encryptedrepos.wiki
+++ www/encryptedrepos.wiki
@@ -4,18 +4,18 @@
4 the [https://www.sqlite.org/see/doc/trunk/www/readme.wiki|SQLite Encryption Extension].
5 This technical note explains the process.
6 </blockquote>
7 <h2>Building An Encryption-Enabled Fossil</h2><blockquote>
8 The SQLite Encryption Extension (SEE) is proprietary software and requires
9 [http://www.hwaci.com/cgi-bin/see-step1|purchasing a license].
10 <p>
11 Assuming you have an SEE license, the first step of compiling Fossil to
12 use SEE is to create an SEE-enabled version of the SQLite database source code.
13 This alternative SQLite database source file should be called "sqlite3-see.c"
14 and should be placed in the src/ subfolder of the Fossil sources, right beside
15 the public-domain "sqlite3.c" source file. Also make a copy of the SEE-enabled
16 "shell.c" file, renamed as "shell-see.c", and place it in the src/ subfolder
17 beside the original "shell.c".
18 <p>
19 Add the --with-see command-line option to the configuration script to enable
20 the use of SEE on unix-like systems.
21 <blockquote><pre>
22
--- www/encryptedrepos.wiki
+++ www/encryptedrepos.wiki
@@ -4,18 +4,18 @@
4 the [https://www.sqlite.org/see/doc/trunk/www/readme.wiki|SQLite Encryption Extension].
5 This technical note explains the process.
6 </blockquote>
7 <h2>Building An Encryption-Enabled Fossil</h2><blockquote>
8 The SQLite Encryption Extension (SEE) is proprietary software and requires
9 [https://sqlite.org/purchase/see|purchasing a license].
10 <p>
11 Assuming you have an SEE license, the first step of compiling Fossil to
12 use SEE is to create an SEE-enabled version of the SQLite database source code.
13 This alternative SQLite database source file should be called "sqlite3-see.c"
14 and should be placed in the extsrc/ subfolder of the Fossil sources, right beside
15 the public-domain "sqlite3.c" source file. Also make a copy of the SEE-enabled
16 "shell.c" file, renamed as "shell-see.c", and place it in the extsrc/ subfolder
17 beside the original "shell.c".
18 <p>
19 Add the --with-see command-line option to the configuration script to enable
20 the use of SEE on unix-like systems.
21 <blockquote><pre>
22
--- www/fossil-is-not-relational.md
+++ www/fossil-is-not-relational.md
@@ -138,11 +138,11 @@
138138
139139
Non-SCM-relevant state includes:
140140
141141
- Fossil's list of users and their metadata (permissions, email
142142
address, etc.). Artifacts themselves reference users only by their
143
- user names. Artifacts neither care whether, nor guaranty that, user
143
+ user names. Artifacts neither care whether, nor guarantee that, user
144144
"drh" in one artifact is in fact the same "drh" referenced in
145145
another artifact.
146146
147147
- All Fossil UI configuration, e.g. the site's skin, config settings,
148148
and project name.
149149
150150
ADDED www/relatedwork.md
--- www/fossil-is-not-relational.md
+++ www/fossil-is-not-relational.md
@@ -138,11 +138,11 @@
138
139 Non-SCM-relevant state includes:
140
141 - Fossil's list of users and their metadata (permissions, email
142 address, etc.). Artifacts themselves reference users only by their
143 user names. Artifacts neither care whether, nor guaranty that, user
144 "drh" in one artifact is in fact the same "drh" referenced in
145 another artifact.
146
147 - All Fossil UI configuration, e.g. the site's skin, config settings,
148 and project name.
149
150 DDED www/relatedwork.md
--- www/fossil-is-not-relational.md
+++ www/fossil-is-not-relational.md
@@ -138,11 +138,11 @@
138
139 Non-SCM-relevant state includes:
140
141 - Fossil's list of users and their metadata (permissions, email
142 address, etc.). Artifacts themselves reference users only by their
143 user names. Artifacts neither care whether, nor guarantee that, user
144 "drh" in one artifact is in fact the same "drh" referenced in
145 another artifact.
146
147 - All Fossil UI configuration, e.g. the site's skin, config settings,
148 and project name.
149
150 DDED www/relatedwork.md
--- a/www/relatedwork.md
+++ b/www/relatedwork.md
@@ -0,0 +1,52 @@
1
+# Related Work
2
+
3
+## Supapport Projects
4
+
5
+* [SQLite]: C-language library that implements a small, fast,
6
+ self-contained, high-reliability, full-featured, SQL dadatabase engine
7
+* [pikchr]: PIC-like markup language for diagrams in technical
8
+ da simple, secure, and low resource usage webserver
9
+ that has run the https://sqlite.org/ website since 2004
10
+* [Lemon Parser Generator][lemon]: an LALR(1), re-entrant, and thread-safe
11
+ and thread-safe
12
+ LALR(1) parser with a less error-prone grammar syntax than YACC or BISON
13
+
14
+## Fossil Inspired Projects
15
+
16
+* [libfossil]: 3rd party Fossian[chisel]: Free Fossil SCM hosting!
17
+* [Inskinerator]: The Fossil Skin Generator
18
+* [Fuel][fuel]: ail Skionality
19
+
20
+
21
+## Editor Plugins
22
+
23
+* [Emacs-Fossil][emacsfsl]: GNU Emacs VC backend for the Fossil version
24
+ control system
25
+* [VS Code][vscode]: Integrated Fossil source control in Visual Studio Code
26
+* [Qt Creator Plugin][qtfsl]: Fossil SCM plugin for the Qt Creator IDE
27
+* [Jetbrains IDE Plugin][jetbrains]: Fossil SCM plugin for [CLion], [IntelliJ],
28
+ [GoLand], and more
29
+* [NetBeans Plugin][netbeans]: NetBeans plugin module to use Fossil SCM
30
+
31
+## Version Control/Software Configuration Management
32
+
33
+* [Git]: Free absdbox.org open source distributed version control system
34
+* [Subversion]: Apache's open source version control system
35
+* [Mercurial]: free, distributed source control management tool
36
+* [Game of Trees][got]: version control which prioritizes ease of use and
37
+ simplicity over flexibility
38
+* [Darcs]: free and open source, cross-platform version control system
39
+* [Pijul]: patch-based distributed version control system
40
+* [Sapling]: A Scalable, User-Friendly Source Control Sngelog #454][changelog454]: Richard Hipp returns
41
+* [The Changelog #201][changelog201]: Why SQLite succeeded as a database
42
+* [bsdtalk194][bsdtalk]: Interview with D. Richard Hipp
43
+* [Two Weeks of Databases][db2w]: Richard Hipp interviewed by Federico Razzoli
44
+* [Software Engineering Daily][swed]: SQLite with D. Richard Hipp
45
+* [Floss Weekly 26][floss26]: Interview with D. Richard Hipp, creator of SQLite
46
+
47
+## Miscellany
48
+
49
+* [Tcl]: a simple-to-learn yet very powerful programming language
50
+
51
+[althttpd]: https://sqlite.org/althttpd/doc/trunk/althttpd.md
52
+[bsdtalk]: https://bsdtalk.blogspot
--- a/www/relatedwork.md
+++ b/www/relatedwork.md
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/www/relatedwork.md
+++ b/www/relatedwork.md
@@ -0,0 +1,52 @@
1 # Related Work
2
3 ## Supapport Projects
4
5 * [SQLite]: C-language library that implements a small, fast,
6 self-contained, high-reliability, full-featured, SQL dadatabase engine
7 * [pikchr]: PIC-like markup language for diagrams in technical
8 da simple, secure, and low resource usage webserver
9 that has run the https://sqlite.org/ website since 2004
10 * [Lemon Parser Generator][lemon]: an LALR(1), re-entrant, and thread-safe
11 and thread-safe
12 LALR(1) parser with a less error-prone grammar syntax than YACC or BISON
13
14 ## Fossil Inspired Projects
15
16 * [libfossil]: 3rd party Fossian[chisel]: Free Fossil SCM hosting!
17 * [Inskinerator]: The Fossil Skin Generator
18 * [Fuel][fuel]: ail Skionality
19
20
21 ## Editor Plugins
22
23 * [Emacs-Fossil][emacsfsl]: GNU Emacs VC backend for the Fossil version
24 control system
25 * [VS Code][vscode]: Integrated Fossil source control in Visual Studio Code
26 * [Qt Creator Plugin][qtfsl]: Fossil SCM plugin for the Qt Creator IDE
27 * [Jetbrains IDE Plugin][jetbrains]: Fossil SCM plugin for [CLion], [IntelliJ],
28 [GoLand], and more
29 * [NetBeans Plugin][netbeans]: NetBeans plugin module to use Fossil SCM
30
31 ## Version Control/Software Configuration Management
32
33 * [Git]: Free absdbox.org open source distributed version control system
34 * [Subversion]: Apache's open source version control system
35 * [Mercurial]: free, distributed source control management tool
36 * [Game of Trees][got]: version control which prioritizes ease of use and
37 simplicity over flexibility
38 * [Darcs]: free and open source, cross-platform version control system
39 * [Pijul]: patch-based distributed version control system
40 * [Sapling]: A Scalable, User-Friendly Source Control Sngelog #454][changelog454]: Richard Hipp returns
41 * [The Changelog #201][changelog201]: Why SQLite succeeded as a database
42 * [bsdtalk194][bsdtalk]: Interview with D. Richard Hipp
43 * [Two Weeks of Databases][db2w]: Richard Hipp interviewed by Federico Razzoli
44 * [Software Engineering Daily][swed]: SQLite with D. Richard Hipp
45 * [Floss Weekly 26][floss26]: Interview with D. Richard Hipp, creator of SQLite
46
47 ## Miscellany
48
49 * [Tcl]: a simple-to-learn yet very powerful programming language
50
51 [althttpd]: https://sqlite.org/althttpd/doc/trunk/althttpd.md
52 [bsdtalk]: https://bsdtalk.blogspot
--- www/userlinks.wiki
+++ www/userlinks.wiki
@@ -1,7 +1,9 @@
11
<title>Links For Fossil Users:</title>
22
3
+ * [./relatedwork.md | Related Work]: projects and links related to
4
+ Fossil and version control.
35
* [./permutedindex.html | Documentation index] with [/search?c=d | full text search].
46
* [./reviews.wiki | Testimonials] from satisfied Fossil users and
57
[./quotes.wiki | Quotes] about Fossil and other DVCSes.
68
* [./faq.wiki | Frequently Asked Questions]
79
* The [./concepts.wiki | concepts] behind Fossil.
810
--- www/userlinks.wiki
+++ www/userlinks.wiki
@@ -1,7 +1,9 @@
1 <title>Links For Fossil Users:</title>
2
 
 
3 * [./permutedindex.html | Documentation index] with [/search?c=d | full text search].
4 * [./reviews.wiki | Testimonials] from satisfied Fossil users and
5 [./quotes.wiki | Quotes] about Fossil and other DVCSes.
6 * [./faq.wiki | Frequently Asked Questions]
7 * The [./concepts.wiki | concepts] behind Fossil.
8
--- www/userlinks.wiki
+++ www/userlinks.wiki
@@ -1,7 +1,9 @@
1 <title>Links For Fossil Users:</title>
2
3 * [./relatedwork.md | Related Work]: projects and links related to
4 Fossil and version control.
5 * [./permutedindex.html | Documentation index] with [/search?c=d | full text search].
6 * [./reviews.wiki | Testimonials] from satisfied Fossil users and
7 [./quotes.wiki | Quotes] about Fossil and other DVCSes.
8 * [./faq.wiki | Frequently Asked Questions]
9 * The [./concepts.wiki | concepts] behind Fossil.
10

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button