Fossil SCM

Merge from trunk.

brickviking 2025-10-29 11:10 bv-infotool merge
Commit 50b56eec70a93150649ef763b10858f87bb4be289b2b466711ce70e549e1cc9f
+126 -67
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -7182,10 +7182,19 @@
71827182
sqlite3_free(pRe->aOp);
71837183
sqlite3_free(pRe->aArg);
71847184
sqlite3_free(pRe);
71857185
}
71867186
}
7187
+
7188
+/*
7189
+** Version of re_free() that accepts a pointer of type (void*). Required
7190
+** to satisfy sanitizers when the re_free() function is called via a
7191
+** function pointer.
7192
+*/
7193
+static void re_free_voidptr(void *p){
7194
+ re_free((ReCompiled*)p);
7195
+}
71877196
71887197
/*
71897198
** Compile a textual regular expression in zIn[] into a compiled regular
71907199
** expression suitable for us by re_match() and return a pointer to the
71917200
** compiled regular expression in *ppRe. Return NULL on success or an
@@ -7314,11 +7323,11 @@
73147323
zStr = (const unsigned char*)sqlite3_value_text(argv[1]);
73157324
if( zStr!=0 ){
73167325
sqlite3_result_int(context, re_match(pRe, zStr, -1));
73177326
}
73187327
if( setAux ){
7319
- sqlite3_set_auxdata(context, 0, pRe, (void(*)(void*))re_free);
7328
+ sqlite3_set_auxdata(context, 0, pRe, re_free_voidptr);
73207329
}
73217330
}
73227331
73237332
#if defined(SQLITE_DEBUG)
73247333
/*
@@ -8202,11 +8211,11 @@
82028211
82038212
pLvl->zDir = pCur->zPath;
82048213
pCur->zPath = 0;
82058214
pLvl->pDir = opendir(pLvl->zDir);
82068215
if( pLvl->pDir==0 ){
8207
- fsdirSetErrmsg(pCur, "cannot read directory: %s", pCur->zPath);
8216
+ fsdirSetErrmsg(pCur, "cannot read directory: %s", pLvl->zDir);
82088217
return SQLITE_ERROR;
82098218
}
82108219
}
82118220
82128221
while( pCur->iLvl>=0 ){
@@ -12531,15 +12540,15 @@
1253112540
1253212541
/*
1253312542
** Allocate and return nByte bytes of zeroed memory using sqlite3_malloc().
1253412543
** If the allocation fails, set *pRc to SQLITE_NOMEM and return NULL.
1253512544
*/
12536
-static void *idxMalloc(int *pRc, int nByte){
12545
+static void *idxMalloc(int *pRc, i64 nByte){
1253712546
void *pRet;
1253812547
assert( *pRc==SQLITE_OK );
1253912548
assert( nByte>0 );
12540
- pRet = sqlite3_malloc(nByte);
12549
+ pRet = sqlite3_malloc64(nByte);
1254112550
if( pRet ){
1254212551
memset(pRet, 0, nByte);
1254312552
}else{
1254412553
*pRc = SQLITE_NOMEM;
1254512554
}
@@ -12602,11 +12611,11 @@
1260212611
for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){
1260312612
if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){
1260412613
return 1;
1260512614
}
1260612615
}
12607
- pEntry = idxMalloc(pRc, sizeof(IdxHashEntry) + nKey+1 + nVal+1);
12616
+ pEntry = idxMalloc(pRc, sizeof(IdxHashEntry) + (i64)nKey+1 + (i64)nVal+1);
1260812617
if( pEntry ){
1260912618
pEntry->zKey = (char*)&pEntry[1];
1261012619
memcpy(pEntry->zKey, zKey, nKey);
1261112620
if( zVal ){
1261212621
pEntry->zVal = &pEntry->zKey[nKey+1];
@@ -12737,19 +12746,19 @@
1273712746
sqlite3_vtab_cursor base;
1273812747
sqlite3_stmt *pData;
1273912748
};
1274012749
1274112750
static char *expertDequote(const char *zIn){
12742
- int n = STRLEN(zIn);
12743
- char *zRet = sqlite3_malloc(n);
12751
+ i64 n = STRLEN(zIn);
12752
+ char *zRet = sqlite3_malloc64(n);
1274412753
1274512754
assert( zIn[0]=='\'' );
1274612755
assert( zIn[n-1]=='\'' );
1274712756
1274812757
if( zRet ){
12749
- int iOut = 0;
12750
- int iIn = 0;
12758
+ i64 iOut = 0;
12759
+ i64 iIn = 0;
1275112760
for(iIn=1; iIn<(n-1); iIn++){
1275212761
if( zIn[iIn]=='\'' ){
1275312762
assert( zIn[iIn+1]=='\'' );
1275412763
iIn++;
1275512764
}
@@ -13058,11 +13067,11 @@
1305813067
char **pzErrmsg /* OUT: Error message (if not) */
1305913068
){
1306013069
sqlite3_stmt *p1 = 0;
1306113070
int nCol = 0;
1306213071
int nTab;
13063
- int nByte;
13072
+ i64 nByte;
1306413073
IdxTable *pNew = 0;
1306513074
int rc, rc2;
1306613075
char *pCsr = 0;
1306713076
int nPk = 0;
1306813077
@@ -13150,18 +13159,18 @@
1315013159
*/
1315113160
static char *idxAppendText(int *pRc, char *zIn, const char *zFmt, ...){
1315213161
va_list ap;
1315313162
char *zAppend = 0;
1315413163
char *zRet = 0;
13155
- int nIn = zIn ? STRLEN(zIn) : 0;
13156
- int nAppend = 0;
13164
+ i64 nIn = zIn ? STRLEN(zIn) : 0;
13165
+ i64 nAppend = 0;
1315713166
va_start(ap, zFmt);
1315813167
if( *pRc==SQLITE_OK ){
1315913168
zAppend = sqlite3_vmprintf(zFmt, ap);
1316013169
if( zAppend ){
1316113170
nAppend = STRLEN(zAppend);
13162
- zRet = (char*)sqlite3_malloc(nIn + nAppend + 1);
13171
+ zRet = (char*)sqlite3_malloc64(nIn + nAppend + 1);
1316313172
}
1316413173
if( zAppend && zRet ){
1316513174
if( nIn ) memcpy(zRet, zIn, nIn);
1316613175
memcpy(&zRet[nIn], zAppend, nAppend+1);
1316713176
}else{
@@ -13921,12 +13930,12 @@
1392113930
int nSlot;
1392213931
struct IdxRemSlot {
1392313932
int eType; /* SQLITE_NULL, INTEGER, REAL, TEXT, BLOB */
1392413933
i64 iVal; /* SQLITE_INTEGER value */
1392513934
double rVal; /* SQLITE_FLOAT value */
13926
- int nByte; /* Bytes of space allocated at z */
13927
- int n; /* Size of buffer z */
13935
+ i64 nByte; /* Bytes of space allocated at z */
13936
+ i64 n; /* Size of buffer z */
1392813937
char *z; /* SQLITE_TEXT/BLOB value */
1392913938
} aSlot[1];
1393013939
};
1393113940
1393213941
/*
@@ -13958,15 +13967,17 @@
1395813967
case SQLITE_FLOAT:
1395913968
sqlite3_result_double(pCtx, pSlot->rVal);
1396013969
break;
1396113970
1396213971
case SQLITE_BLOB:
13963
- sqlite3_result_blob(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT);
13972
+ assert( pSlot->n <= 0x7fffffff );
13973
+ sqlite3_result_blob(pCtx, pSlot->z, (int)pSlot->n, SQLITE_TRANSIENT);
1396413974
break;
1396513975
1396613976
case SQLITE_TEXT:
13967
- sqlite3_result_text(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT);
13977
+ assert( pSlot->n <= 0x7fffffff );
13978
+ sqlite3_result_text(pCtx, pSlot->z, (int)pSlot->n, SQLITE_TRANSIENT);
1396813979
break;
1396913980
}
1397013981
1397113982
pSlot->eType = sqlite3_value_type(argv[1]);
1397213983
switch( pSlot->eType ){
@@ -13982,14 +13993,14 @@
1398213993
pSlot->rVal = sqlite3_value_double(argv[1]);
1398313994
break;
1398413995
1398513996
case SQLITE_BLOB:
1398613997
case SQLITE_TEXT: {
13987
- int nByte = sqlite3_value_bytes(argv[1]);
13998
+ i64 nByte = sqlite3_value_bytes(argv[1]);
1398813999
const void *pData = 0;
1398914000
if( nByte>pSlot->nByte ){
13990
- char *zNew = (char*)sqlite3_realloc(pSlot->z, nByte*2);
14001
+ char *zNew = (char*)sqlite3_realloc64(pSlot->z, nByte*2);
1399114002
if( zNew==0 ){
1399214003
sqlite3_result_error_nomem(pCtx);
1399314004
return;
1399414005
}
1399514006
pSlot->nByte = nByte*2;
@@ -14040,11 +14051,11 @@
1404014051
char *zOrder = 0;
1404114052
char *zQuery = 0;
1404214053
int nCol = 0;
1404314054
int i;
1404414055
sqlite3_stmt *pQuery = 0;
14045
- int *aStat = 0;
14056
+ i64 *aStat = 0;
1404614057
int rc = SQLITE_OK;
1404714058
1404814059
assert( p->iSample>0 );
1404914060
1405014061
/* Formulate the query text */
@@ -14086,11 +14097,11 @@
1408614097
rc = idxPrepareStmt(dbrem, &pQuery, pzErr, zQuery);
1408714098
}
1408814099
sqlite3_free(zQuery);
1408914100
1409014101
if( rc==SQLITE_OK ){
14091
- aStat = (int*)idxMalloc(&rc, sizeof(int)*(nCol+1));
14102
+ aStat = (i64*)idxMalloc(&rc, sizeof(i64)*(nCol+1));
1409214103
}
1409314104
if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){
1409414105
IdxHashEntry *pEntry;
1409514106
char *zStat = 0;
1409614107
for(i=0; i<=nCol; i++) aStat[i] = 1;
@@ -14103,15 +14114,15 @@
1410314114
aStat[i+1]++;
1410414115
}
1410514116
}
1410614117
1410714118
if( rc==SQLITE_OK ){
14108
- int s0 = aStat[0];
14109
- zStat = sqlite3_mprintf("%d", s0);
14119
+ i64 s0 = aStat[0];
14120
+ zStat = sqlite3_mprintf("%lld", s0);
1411014121
if( zStat==0 ) rc = SQLITE_NOMEM;
1411114122
for(i=1; rc==SQLITE_OK && i<=nCol; i++){
14112
- zStat = idxAppendText(&rc, zStat, " %d", (s0+aStat[i]/2) / aStat[i]);
14123
+ zStat = idxAppendText(&rc, zStat, " %lld", (s0+aStat[i]/2) / aStat[i]);
1411314124
}
1411414125
}
1411514126
1411614127
if( rc==SQLITE_OK ){
1411714128
sqlite3_bind_text(pWriteStat, 1, zTab, -1, SQLITE_STATIC);
@@ -14186,11 +14197,11 @@
1418614197
if( nMax<=0 || rc!=SQLITE_OK ) return rc;
1418714198
1418814199
rc = sqlite3_exec(p->dbm, "ANALYZE; PRAGMA writable_schema=1", 0, 0, 0);
1418914200
1419014201
if( rc==SQLITE_OK ){
14191
- int nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax);
14202
+ i64 nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax);
1419214203
pCtx = (struct IdxRemCtx*)idxMalloc(&rc, nByte);
1419314204
}
1419414205
1419514206
if( rc==SQLITE_OK ){
1419614207
sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv);
@@ -14203,11 +14214,11 @@
1420314214
0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0
1420414215
);
1420514216
}
1420614217
1420714218
if( rc==SQLITE_OK ){
14208
- pCtx->nSlot = nMax+1;
14219
+ pCtx->nSlot = (i64)nMax+1;
1420914220
rc = idxPrepareStmt(p->dbm, &pAllIndex, pzErr, zAllIndex);
1421014221
}
1421114222
if( rc==SQLITE_OK ){
1421214223
rc = idxPrepareStmt(p->dbm, &pIndexXInfo, pzErr, zIndexXInfo);
1421314224
}
@@ -14470,11 +14481,11 @@
1447014481
rc = sqlite3_prepare_v2(p->dbv, zStmt, -1, &pStmt, &zStmt);
1447114482
if( rc==SQLITE_OK ){
1447214483
if( pStmt ){
1447314484
IdxStatement *pNew;
1447414485
const char *z = sqlite3_sql(pStmt);
14475
- int n = STRLEN(z);
14486
+ i64 n = STRLEN(z);
1447614487
pNew = (IdxStatement*)idxMalloc(&rc, sizeof(IdxStatement) + n+1);
1447714488
if( rc==SQLITE_OK ){
1447814489
pNew->zSql = (char*)&pNew[1];
1447914490
memcpy(pNew->zSql, z, n+1);
1448014491
pNew->pNext = p->pStatement;
@@ -21295,11 +21306,11 @@
2129521306
unsigned statsOn; /* True to display memory stats before each finalize */
2129621307
unsigned mEqpLines; /* Mask of vertical lines in the EQP output graph */
2129721308
int inputNesting; /* Track nesting level of .read and other redirects */
2129821309
int outCount; /* Revert to stdout when reaching zero */
2129921310
int cnt; /* Number of records displayed so far */
21300
- int lineno; /* Line number of last line read from in */
21311
+ i64 lineno; /* Line number of last line read from in */
2130121312
int openFlags; /* Additional flags to open. (SQLITE_OPEN_NOFOLLOW) */
2130221313
FILE *in; /* Read commands from this stream */
2130321314
FILE *out; /* Write results here */
2130421315
FILE *traceOut; /* Output for sqlite3_trace() */
2130521316
int nErr; /* Number of errors seen */
@@ -21531,11 +21542,11 @@
2153121542
va_list ap;
2153221543
char *zMsg;
2153321544
va_start(ap, zErrMsg);
2153421545
zMsg = sqlite3_vmprintf(zErrMsg, ap);
2153521546
va_end(ap);
21536
- sqlite3_fprintf(stderr, "line %d: %s\n", p->lineno, zMsg);
21547
+ sqlite3_fprintf(stderr, "line %lld: %s\n", p->lineno, zMsg);
2153721548
exit(1);
2153821549
}
2153921550
}
2154021551
2154121552
/*
@@ -25087,10 +25098,11 @@
2508725098
" --ifexist Only open if FILE already exists",
2508825099
#ifndef SQLITE_OMIT_DESERIALIZE
2508925100
" --maxsize N Maximum size for --hexdb or --deserialized database",
2509025101
#endif
2509125102
" --new Initialize FILE to an empty database",
25103
+ " --normal FILE is an ordinary SQLite database",
2509225104
" --nofollow Do not follow symbolic links",
2509325105
" --readonly Open FILE readonly",
2509425106
" --zip FILE is a ZIP archive",
2509525107
#ifndef SQLITE_SHELL_FIDDLE
2509625108
".output ?FILE? Send output to FILE or stdout if FILE is omitted",
@@ -25321,11 +25333,11 @@
2532125333
sqlite3_free(zPat);
2532225334
return n;
2532325335
}
2532425336
2532525337
/* Forward reference */
25326
-static int process_input(ShellState *p);
25338
+static int process_input(ShellState *p, const char*);
2532725339
2532825340
/*
2532925341
** Read the content of file zName into memory obtained from sqlite3_malloc64()
2533025342
** and return a pointer to the buffer. The caller is responsible for freeing
2533125343
** the memory.
@@ -25428,22 +25440,30 @@
2542825440
** If the file does not exist or is empty but its name looks like a ZIP
2542925441
** archive and the dfltZip flag is true, then assume it is a ZIP archive.
2543025442
** Otherwise, assume an ordinary database regardless of the filename if
2543125443
** the type cannot be determined from content.
2543225444
*/
25433
-int deduceDatabaseType(const char *zName, int dfltZip){
25434
- FILE *f = sqlite3_fopen(zName, "rb");
25445
+int deduceDatabaseType(const char *zName, int dfltZip, int openFlags){
25446
+ FILE *f;
2543525447
size_t n;
25448
+ sqlite3 *db = 0;
25449
+ sqlite3_stmt *pStmt = 0;
2543625450
int rc = SHELL_OPEN_UNSPEC;
2543725451
char zBuf[100];
25438
- if( f==0 ){
25439
- if( dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){
25440
- return SHELL_OPEN_ZIPFILE;
25441
- }else{
25442
- return SHELL_OPEN_NORMAL;
25443
- }
25452
+ if( access(zName,0)!=0 ) goto database_type_by_name;
25453
+ if( sqlite3_open_v2(zName, &db, openFlags, 0)==SQLITE_OK
25454
+ && sqlite3_prepare_v2(db,"SELECT count(*) FROM sqlite_schema",-1,&pStmt,0)
25455
+ ==SQLITE_OK
25456
+ && sqlite3_step(pStmt)==SQLITE_ROW
25457
+ ){
25458
+ rc = SHELL_OPEN_NORMAL;
2544425459
}
25460
+ sqlite3_finalize(pStmt);
25461
+ sqlite3_close(db);
25462
+ if( rc==SHELL_OPEN_NORMAL ) return SHELL_OPEN_NORMAL;
25463
+ f = sqlite3_fopen(zName, "rb");
25464
+ if( f==0 ) goto database_type_by_name;
2544525465
n = fread(zBuf, 16, 1, f);
2544625466
if( n==1 && memcmp(zBuf, "SQLite format 3", 16)==0 ){
2544725467
fclose(f);
2544825468
return SHELL_OPEN_NORMAL;
2544925469
}
@@ -25461,10 +25481,18 @@
2546125481
rc = SHELL_OPEN_ZIPFILE;
2546225482
}
2546325483
}
2546425484
fclose(f);
2546525485
return rc;
25486
+
25487
+database_type_by_name:
25488
+ if( dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){
25489
+ rc = SHELL_OPEN_ZIPFILE;
25490
+ }else{
25491
+ rc = SHELL_OPEN_NORMAL;
25492
+ }
25493
+ return rc;
2546625494
}
2546725495
2546825496
#ifndef SQLITE_OMIT_DESERIALIZE
2546925497
/*
2547025498
** Reconstruct an in-memory database using the output from the "dbtotxt"
@@ -25471,11 +25499,11 @@
2547125499
** program. Read content from the file in p->aAuxDb[].zDbFilename.
2547225500
** If p->aAuxDb[].zDbFilename is 0, then read from standard input.
2547325501
*/
2547425502
static unsigned char *readHexDb(ShellState *p, int *pnData){
2547525503
unsigned char *a = 0;
25476
- int nLine;
25504
+ i64 nLine;
2547725505
int n = 0; /* Size of db per first line of hex dump */
2547825506
i64 sz = 0; /* n rounded up to nearest page boundary */
2547925507
int pgsz = 0;
2548025508
i64 iOffset = 0;
2548125509
int rc;
@@ -25510,10 +25538,14 @@
2551025538
shell_check_oom(a);
2551125539
memset(a, 0, sz);
2551225540
for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){
2551325541
int j = 0; /* Page number from "| page" line */
2551425542
int k = 0; /* Offset from "| page" line */
25543
+ if( nLine>=2000000000 ){
25544
+ sqlite3_fprintf(stderr, "input too big\n");
25545
+ goto readHexDb_error;
25546
+ }
2551525547
rc = sscanf(zLine, "| page %d offset %d", &j, &k);
2551625548
if( rc==2 ){
2551725549
iOffset = k;
2551825550
continue;
2551925551
}
@@ -25548,11 +25580,11 @@
2554825580
if(cli_strncmp(zLine, "| end ", 6)==0 ) break;
2554925581
}
2555025582
p->lineno = nLine;
2555125583
}
2555225584
sqlite3_free(a);
25553
- sqlite3_fprintf(stderr,"Error on line %d of --hexdb input\n", nLine);
25585
+ sqlite3_fprintf(stderr,"Error on line %lld of --hexdb input\n", nLine);
2555425586
return 0;
2555525587
}
2555625588
#endif /* SQLITE_OMIT_DESERIALIZE */
2555725589
2555825590
/*
@@ -25625,11 +25657,11 @@
2562525657
if( p->openMode==SHELL_OPEN_UNSPEC ){
2562625658
if( zDbFilename==0 || zDbFilename[0]==0 ){
2562725659
p->openMode = SHELL_OPEN_NORMAL;
2562825660
}else{
2562925661
p->openMode = (u8)deduceDatabaseType(zDbFilename,
25630
- (openFlags & OPEN_DB_ZIPFILE)!=0);
25662
+ (openFlags & OPEN_DB_ZIPFILE)!=0, p->openFlags);
2563125663
}
2563225664
}
2563325665
if( (p->openFlags & (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE))==0 ){
2563425666
if( p->openFlags==0 ) p->openFlags = SQLITE_OPEN_CREATE;
2563525667
p->openFlags |= SQLITE_OPEN_READWRITE;
@@ -27652,29 +27684,45 @@
2765227684
int *pRc,
2765327685
ArCommand *pAr,
2765427686
char **pzWhere /* OUT: New WHERE clause */
2765527687
){
2765627688
char *zWhere = 0;
27657
- const char *zSameOp = (pAr->bGlob)? "GLOB" : "=";
2765827689
if( *pRc==SQLITE_OK ){
2765927690
if( pAr->nArg==0 ){
2766027691
zWhere = sqlite3_mprintf("1");
2766127692
}else{
27693
+ char *z1 = sqlite3_mprintf(pAr->bGlob ? "" : "name IN(");
27694
+ char *z2 = sqlite3_mprintf("");
27695
+ const char *zSep1 = "";
27696
+ const char *zSep2 = "";
27697
+
2766227698
int i;
27663
- const char *zSep = "";
27664
- for(i=0; i<pAr->nArg; i++){
27699
+ for(i=0; i<pAr->nArg && z1 && z2; i++){
2766527700
const char *z = pAr->azArg[i];
27666
- zWhere = sqlite3_mprintf(
27667
- "%z%s name %s '%q' OR substr(name,1,%d) %s '%q/'",
27668
- zWhere, zSep, zSameOp, z, strlen30(z)+1, zSameOp, z
27701
+ int n = strlen30(z);
27702
+
27703
+ if( pAr->bGlob ){
27704
+ z1 = sqlite3_mprintf("%z%sname GLOB '%q'", z1, zSep2, z);
27705
+ z2 = sqlite3_mprintf(
27706
+ "%z%ssubstr(name,1,%d) GLOB '%q/'", z2, zSep2, n+1,z
27707
+ );
27708
+ }else{
27709
+ z1 = sqlite3_mprintf("%z%s'%q'", z1, zSep1, z);
27710
+ z2 = sqlite3_mprintf("%z%ssubstr(name,1,%d) = '%q/'",z2,zSep2,n+1,z);
27711
+ }
27712
+ zSep1 = ", ";
27713
+ zSep2 = " OR ";
27714
+ }
27715
+ if( z1==0 || z2==0 ){
27716
+ *pRc = SQLITE_NOMEM;
27717
+ }else{
27718
+ zWhere = sqlite3_mprintf("(%s%s OR (name GLOB '*/*' AND (%s))) ",
27719
+ z1, pAr->bGlob==0 ? ")" : "", z2
2766927720
);
27670
- if( zWhere==0 ){
27671
- *pRc = SQLITE_NOMEM;
27672
- break;
27673
- }
27674
- zSep = " OR ";
2767527721
}
27722
+ sqlite3_free(z1);
27723
+ sqlite3_free(z2);
2767627724
}
2767727725
}
2767827726
*pzWhere = zWhere;
2767927727
}
2768027728
@@ -27990,11 +28038,11 @@
2799028038
int eDbType = SHELL_OPEN_UNSPEC;
2799128039
cmd.p = pState;
2799228040
cmd.out = pState->out;
2799328041
cmd.db = pState->db;
2799428042
if( cmd.zFile ){
27995
- eDbType = deduceDatabaseType(cmd.zFile, 1);
28043
+ eDbType = deduceDatabaseType(cmd.zFile, 1, 0);
2799628044
}else{
2799728045
eDbType = pState->openMode;
2799828046
}
2799928047
if( eDbType==SHELL_OPEN_ZIPFILE ){
2800028048
if( cmd.eCmd==AR_CMD_EXTRACT || cmd.eCmd==AR_CMD_LIST ){
@@ -29312,11 +29360,11 @@
2931229360
int nSep; /* Number of bytes in p->colSeparator[] */
2931329361
char *zSql = 0; /* An SQL statement */
2931429362
ImportCtx sCtx; /* Reader context */
2931529363
char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
2931629364
int eVerbose = 0; /* Larger for more console output */
29317
- int nSkip = 0; /* Initial lines to skip */
29365
+ i64 nSkip = 0; /* Initial lines to skip */
2931829366
int useOutputMode = 1; /* Use output mode to determine separators */
2931929367
char *zCreate = 0; /* CREATE TABLE statement text */
2932029368
2932129369
failIfSafeMode(p, "cannot run .import in safe mode");
2932229370
memset(&sCtx, 0, sizeof(sCtx));
@@ -30037,11 +30085,11 @@
3003730085
if( c=='n' && cli_strcmp(azArg[0], "nonce")==0 ){
3003830086
if( nArg!=2 ){
3003930087
eputz("Usage: .nonce NONCE\n");
3004030088
rc = 1;
3004130089
}else if( p->zNonce==0 || cli_strcmp(azArg[1],p->zNonce)!=0 ){
30042
- sqlite3_fprintf(stderr,"line %d: incorrect nonce: \"%s\"\n",
30090
+ sqlite3_fprintf(stderr,"line %lld: incorrect nonce: \"%s\"\n",
3004330091
p->lineno, azArg[1]);
3004430092
exit(1);
3004530093
}else{
3004630094
p->bSafeMode = 0;
3004730095
return 0; /* Return immediately to bypass the safe mode reset
@@ -30092,10 +30140,12 @@
3009230140
#ifndef SQLITE_OMIT_DESERIALIZE
3009330141
}else if( optionMatch(z, "deserialize") ){
3009430142
openMode = SHELL_OPEN_DESERIALIZE;
3009530143
}else if( optionMatch(z, "hexdb") ){
3009630144
openMode = SHELL_OPEN_HEXDB;
30145
+ }else if( optionMatch(z, "normal") ){
30146
+ openMode = SHELL_OPEN_NORMAL;
3009730147
}else if( optionMatch(z, "maxsize") && iName+1<nArg ){
3009830148
p->szMax = integerValue(azArg[++iName]);
3009930149
#endif /* SQLITE_OMIT_DESERIALIZE */
3010030150
}else
3010130151
#endif /* !SQLITE_SHELL_FIDDLE */
@@ -30210,10 +30260,11 @@
3021030260
}else{
3021130261
sqlite3_fprintf(p->out,
3021230262
"ERROR: unknown option: \"%s\". Usage:\n", azArg[i]);
3021330263
showHelp(p->out, azArg[0]);
3021430264
rc = 1;
30265
+ sqlite3_free(zFile);
3021530266
goto meta_command_exit;
3021630267
}
3021730268
}else if( zFile==0 && eMode==0 ){
3021830269
if( cli_strcmp(z, "off")==0 ){
3021930270
#ifdef _WIN32
@@ -30493,11 +30544,11 @@
3049330544
#endif
3049430545
3049530546
#ifndef SQLITE_SHELL_FIDDLE
3049630547
if( c=='r' && n>=3 && cli_strncmp(azArg[0], "read", n)==0 ){
3049730548
FILE *inSaved = p->in;
30498
- int savedLineno = p->lineno;
30549
+ i64 savedLineno = p->lineno;
3049930550
failIfSafeMode(p, "cannot run .read in safe mode");
3050030551
if( nArg!=2 ){
3050130552
eputz("Usage: .read FILE\n");
3050230553
rc = 1;
3050330554
goto meta_command_exit;
@@ -30510,19 +30561,19 @@
3051030561
p->in = sqlite3_popen(azArg[1]+1, "r");
3051130562
if( p->in==0 ){
3051230563
sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
3051330564
rc = 1;
3051430565
}else{
30515
- rc = process_input(p);
30566
+ rc = process_input(p, "<pipe>");
3051630567
pclose(p->in);
3051730568
}
3051830569
#endif
3051930570
}else if( (p->in = openChrSource(azArg[1]))==0 ){
3052030571
sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
3052130572
rc = 1;
3052230573
}else{
30523
- rc = process_input(p);
30574
+ rc = process_input(p, azArg[1]);
3052430575
fclose(p->in);
3052530576
}
3052630577
p->in = inSaved;
3052730578
p->lineno = savedLineno;
3052830579
}else
@@ -32509,11 +32560,11 @@
3250932560
** is saved only if input is interactive. An interrupt signal will
3251032561
** cause this routine to exit immediately, unless input is interactive.
3251132562
**
3251232563
** Return the number of errors.
3251332564
*/
32514
-static int process_input(ShellState *p){
32565
+static int process_input(ShellState *p, const char *zSrc){
3251532566
char *zLine = 0; /* A single input line */
3251632567
char *zSql = 0; /* Accumulated SQL text */
3251732568
i64 nLine; /* Length of current line */
3251832569
i64 nSql = 0; /* Bytes of zSql[] used */
3251932570
i64 nAlloc = 0; /* Allocated zSql[] space */
@@ -32522,12 +32573,12 @@
3252232573
i64 startline = 0; /* Line number for start of current input */
3252332574
QuickScanState qss = QSS_Start; /* Accumulated line status (so far) */
3252432575
3252532576
if( p->inputNesting==MAX_INPUT_NESTING ){
3252632577
/* This will be more informative in a later version. */
32527
- sqlite3_fprintf(stderr,"Input nesting limit (%d) reached at line %d."
32528
- " Check recursion.\n", MAX_INPUT_NESTING, p->lineno);
32578
+ sqlite3_fprintf(stderr,"%s: Input nesting limit (%d) reached at line %lld."
32579
+ " Check recursion.\n", zSrc, MAX_INPUT_NESTING, p->lineno);
3252932580
return 1;
3253032581
}
3253132582
++p->inputNesting;
3253232583
p->lineno = 0;
3253332584
CONTINUE_PROMPT_RESET;
@@ -32588,11 +32639,19 @@
3258832639
}else{
3258932640
zSql[nSql++] = '\n';
3259032641
memcpy(zSql+nSql, zLine, nLine+1);
3259132642
nSql += nLine;
3259232643
}
32593
- if( nSql && QSS_SEMITERM(qss) && sqlite3_complete(zSql) ){
32644
+ if( nSql>0x7fff0000 ){
32645
+ char zSize[100];
32646
+ sqlite3_snprintf(sizeof(zSize),zSize,"%,lld",nSql);
32647
+ sqlite3_fprintf(stderr, "%s:%lld: Input SQL is too big: %s bytes\n",
32648
+ zSrc, startline, zSize);
32649
+ nSql = 0;
32650
+ errCnt++;
32651
+ break;
32652
+ }else if( nSql && QSS_SEMITERM(qss) && sqlite3_complete(zSql) ){
3259432653
echo_group_input(p, zSql);
3259532654
errCnt += runOneSqlLine(p, zSql, p->in, startline);
3259632655
CONTINUE_PROMPT_RESET;
3259732656
nSql = 0;
3259832657
if( p->outCount ){
@@ -32756,11 +32815,11 @@
3275632815
const char *sqliterc_override /* Name of config file. NULL to use default */
3275732816
){
3275832817
char *home_dir = NULL;
3275932818
char *sqliterc = (char*)sqliterc_override;
3276032819
FILE *inSaved = p->in;
32761
- int savedLineno = p->lineno;
32820
+ i64 savedLineno = p->lineno;
3276232821
3276332822
if( sqliterc == NULL ){
3276432823
sqliterc = find_xdg_file("XDG_CONFIG_HOME",
3276532824
".config",
3276632825
"sqlite3/sqliterc");
@@ -32778,11 +32837,11 @@
3277832837
p->in = sqliterc ? sqlite3_fopen(sqliterc,"rb") : 0;
3277932838
if( p->in ){
3278032839
if( stdin_is_interactive ){
3278132840
sqlite3_fprintf(stderr,"-- Loading resources from %s\n", sqliterc);
3278232841
}
32783
- if( process_input(p) && bail_on_error ) exit(1);
32842
+ if( process_input(p, sqliterc) && bail_on_error ) exit(1);
3278432843
fclose(p->in);
3278532844
}else if( sqliterc_override!=0 ){
3278632845
sqlite3_fprintf(stderr,"cannot open: \"%s\"\n", sqliterc);
3278732846
if( bail_on_error ) exit(1);
3278832847
}
@@ -33609,19 +33668,19 @@
3360933668
linenoiseSetCompletionCallback(linenoise_completion);
3361033669
#elif HAVE_LINENOISE==2
3361133670
linenoiseSetCompletionCallback(linenoise_completion, NULL);
3361233671
#endif
3361333672
data.in = 0;
33614
- rc = process_input(&data);
33673
+ rc = process_input(&data, "<stdin>");
3361533674
if( zHistory ){
3361633675
shell_stifle_history(2000);
3361733676
shell_write_history(zHistory);
3361833677
sqlite3_free(zHistory);
3361933678
}
3362033679
}else{
3362133680
data.in = stdin;
33622
- rc = process_input(&data);
33681
+ rc = process_input(&data, "<stdin>");
3362333682
}
3362433683
}
3362533684
#ifndef SQLITE_SHELL_FIDDLE
3362633685
/* In WASM mode we have to leave the db state in place so that
3362733686
** client code can "push" SQL into it after this call returns. */
@@ -33799,10 +33858,10 @@
3379933858
void fiddle_exec(const char * zSql){
3380033859
if(zSql && *zSql){
3380133860
if('.'==*zSql) puts(zSql);
3380233861
shellState.wasm.zInput = zSql;
3380333862
shellState.wasm.zPos = zSql;
33804
- process_input(&shellState);
33863
+ process_input(&shellState, "<stdin>");
3380533864
shellState.wasm.zInput = shellState.wasm.zPos = 0;
3380633865
}
3380733866
}
3380833867
#endif /* SQLITE_SHELL_FIDDLE */
3380933868
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -7182,10 +7182,19 @@
7182 sqlite3_free(pRe->aOp);
7183 sqlite3_free(pRe->aArg);
7184 sqlite3_free(pRe);
7185 }
7186 }
 
 
 
 
 
 
 
 
 
7187
7188 /*
7189 ** Compile a textual regular expression in zIn[] into a compiled regular
7190 ** expression suitable for us by re_match() and return a pointer to the
7191 ** compiled regular expression in *ppRe. Return NULL on success or an
@@ -7314,11 +7323,11 @@
7314 zStr = (const unsigned char*)sqlite3_value_text(argv[1]);
7315 if( zStr!=0 ){
7316 sqlite3_result_int(context, re_match(pRe, zStr, -1));
7317 }
7318 if( setAux ){
7319 sqlite3_set_auxdata(context, 0, pRe, (void(*)(void*))re_free);
7320 }
7321 }
7322
7323 #if defined(SQLITE_DEBUG)
7324 /*
@@ -8202,11 +8211,11 @@
8202
8203 pLvl->zDir = pCur->zPath;
8204 pCur->zPath = 0;
8205 pLvl->pDir = opendir(pLvl->zDir);
8206 if( pLvl->pDir==0 ){
8207 fsdirSetErrmsg(pCur, "cannot read directory: %s", pCur->zPath);
8208 return SQLITE_ERROR;
8209 }
8210 }
8211
8212 while( pCur->iLvl>=0 ){
@@ -12531,15 +12540,15 @@
12531
12532 /*
12533 ** Allocate and return nByte bytes of zeroed memory using sqlite3_malloc().
12534 ** If the allocation fails, set *pRc to SQLITE_NOMEM and return NULL.
12535 */
12536 static void *idxMalloc(int *pRc, int nByte){
12537 void *pRet;
12538 assert( *pRc==SQLITE_OK );
12539 assert( nByte>0 );
12540 pRet = sqlite3_malloc(nByte);
12541 if( pRet ){
12542 memset(pRet, 0, nByte);
12543 }else{
12544 *pRc = SQLITE_NOMEM;
12545 }
@@ -12602,11 +12611,11 @@
12602 for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){
12603 if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){
12604 return 1;
12605 }
12606 }
12607 pEntry = idxMalloc(pRc, sizeof(IdxHashEntry) + nKey+1 + nVal+1);
12608 if( pEntry ){
12609 pEntry->zKey = (char*)&pEntry[1];
12610 memcpy(pEntry->zKey, zKey, nKey);
12611 if( zVal ){
12612 pEntry->zVal = &pEntry->zKey[nKey+1];
@@ -12737,19 +12746,19 @@
12737 sqlite3_vtab_cursor base;
12738 sqlite3_stmt *pData;
12739 };
12740
12741 static char *expertDequote(const char *zIn){
12742 int n = STRLEN(zIn);
12743 char *zRet = sqlite3_malloc(n);
12744
12745 assert( zIn[0]=='\'' );
12746 assert( zIn[n-1]=='\'' );
12747
12748 if( zRet ){
12749 int iOut = 0;
12750 int iIn = 0;
12751 for(iIn=1; iIn<(n-1); iIn++){
12752 if( zIn[iIn]=='\'' ){
12753 assert( zIn[iIn+1]=='\'' );
12754 iIn++;
12755 }
@@ -13058,11 +13067,11 @@
13058 char **pzErrmsg /* OUT: Error message (if not) */
13059 ){
13060 sqlite3_stmt *p1 = 0;
13061 int nCol = 0;
13062 int nTab;
13063 int nByte;
13064 IdxTable *pNew = 0;
13065 int rc, rc2;
13066 char *pCsr = 0;
13067 int nPk = 0;
13068
@@ -13150,18 +13159,18 @@
13150 */
13151 static char *idxAppendText(int *pRc, char *zIn, const char *zFmt, ...){
13152 va_list ap;
13153 char *zAppend = 0;
13154 char *zRet = 0;
13155 int nIn = zIn ? STRLEN(zIn) : 0;
13156 int nAppend = 0;
13157 va_start(ap, zFmt);
13158 if( *pRc==SQLITE_OK ){
13159 zAppend = sqlite3_vmprintf(zFmt, ap);
13160 if( zAppend ){
13161 nAppend = STRLEN(zAppend);
13162 zRet = (char*)sqlite3_malloc(nIn + nAppend + 1);
13163 }
13164 if( zAppend && zRet ){
13165 if( nIn ) memcpy(zRet, zIn, nIn);
13166 memcpy(&zRet[nIn], zAppend, nAppend+1);
13167 }else{
@@ -13921,12 +13930,12 @@
13921 int nSlot;
13922 struct IdxRemSlot {
13923 int eType; /* SQLITE_NULL, INTEGER, REAL, TEXT, BLOB */
13924 i64 iVal; /* SQLITE_INTEGER value */
13925 double rVal; /* SQLITE_FLOAT value */
13926 int nByte; /* Bytes of space allocated at z */
13927 int n; /* Size of buffer z */
13928 char *z; /* SQLITE_TEXT/BLOB value */
13929 } aSlot[1];
13930 };
13931
13932 /*
@@ -13958,15 +13967,17 @@
13958 case SQLITE_FLOAT:
13959 sqlite3_result_double(pCtx, pSlot->rVal);
13960 break;
13961
13962 case SQLITE_BLOB:
13963 sqlite3_result_blob(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT);
 
13964 break;
13965
13966 case SQLITE_TEXT:
13967 sqlite3_result_text(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT);
 
13968 break;
13969 }
13970
13971 pSlot->eType = sqlite3_value_type(argv[1]);
13972 switch( pSlot->eType ){
@@ -13982,14 +13993,14 @@
13982 pSlot->rVal = sqlite3_value_double(argv[1]);
13983 break;
13984
13985 case SQLITE_BLOB:
13986 case SQLITE_TEXT: {
13987 int nByte = sqlite3_value_bytes(argv[1]);
13988 const void *pData = 0;
13989 if( nByte>pSlot->nByte ){
13990 char *zNew = (char*)sqlite3_realloc(pSlot->z, nByte*2);
13991 if( zNew==0 ){
13992 sqlite3_result_error_nomem(pCtx);
13993 return;
13994 }
13995 pSlot->nByte = nByte*2;
@@ -14040,11 +14051,11 @@
14040 char *zOrder = 0;
14041 char *zQuery = 0;
14042 int nCol = 0;
14043 int i;
14044 sqlite3_stmt *pQuery = 0;
14045 int *aStat = 0;
14046 int rc = SQLITE_OK;
14047
14048 assert( p->iSample>0 );
14049
14050 /* Formulate the query text */
@@ -14086,11 +14097,11 @@
14086 rc = idxPrepareStmt(dbrem, &pQuery, pzErr, zQuery);
14087 }
14088 sqlite3_free(zQuery);
14089
14090 if( rc==SQLITE_OK ){
14091 aStat = (int*)idxMalloc(&rc, sizeof(int)*(nCol+1));
14092 }
14093 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){
14094 IdxHashEntry *pEntry;
14095 char *zStat = 0;
14096 for(i=0; i<=nCol; i++) aStat[i] = 1;
@@ -14103,15 +14114,15 @@
14103 aStat[i+1]++;
14104 }
14105 }
14106
14107 if( rc==SQLITE_OK ){
14108 int s0 = aStat[0];
14109 zStat = sqlite3_mprintf("%d", s0);
14110 if( zStat==0 ) rc = SQLITE_NOMEM;
14111 for(i=1; rc==SQLITE_OK && i<=nCol; i++){
14112 zStat = idxAppendText(&rc, zStat, " %d", (s0+aStat[i]/2) / aStat[i]);
14113 }
14114 }
14115
14116 if( rc==SQLITE_OK ){
14117 sqlite3_bind_text(pWriteStat, 1, zTab, -1, SQLITE_STATIC);
@@ -14186,11 +14197,11 @@
14186 if( nMax<=0 || rc!=SQLITE_OK ) return rc;
14187
14188 rc = sqlite3_exec(p->dbm, "ANALYZE; PRAGMA writable_schema=1", 0, 0, 0);
14189
14190 if( rc==SQLITE_OK ){
14191 int nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax);
14192 pCtx = (struct IdxRemCtx*)idxMalloc(&rc, nByte);
14193 }
14194
14195 if( rc==SQLITE_OK ){
14196 sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv);
@@ -14203,11 +14214,11 @@
14203 0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0
14204 );
14205 }
14206
14207 if( rc==SQLITE_OK ){
14208 pCtx->nSlot = nMax+1;
14209 rc = idxPrepareStmt(p->dbm, &pAllIndex, pzErr, zAllIndex);
14210 }
14211 if( rc==SQLITE_OK ){
14212 rc = idxPrepareStmt(p->dbm, &pIndexXInfo, pzErr, zIndexXInfo);
14213 }
@@ -14470,11 +14481,11 @@
14470 rc = sqlite3_prepare_v2(p->dbv, zStmt, -1, &pStmt, &zStmt);
14471 if( rc==SQLITE_OK ){
14472 if( pStmt ){
14473 IdxStatement *pNew;
14474 const char *z = sqlite3_sql(pStmt);
14475 int n = STRLEN(z);
14476 pNew = (IdxStatement*)idxMalloc(&rc, sizeof(IdxStatement) + n+1);
14477 if( rc==SQLITE_OK ){
14478 pNew->zSql = (char*)&pNew[1];
14479 memcpy(pNew->zSql, z, n+1);
14480 pNew->pNext = p->pStatement;
@@ -21295,11 +21306,11 @@
21295 unsigned statsOn; /* True to display memory stats before each finalize */
21296 unsigned mEqpLines; /* Mask of vertical lines in the EQP output graph */
21297 int inputNesting; /* Track nesting level of .read and other redirects */
21298 int outCount; /* Revert to stdout when reaching zero */
21299 int cnt; /* Number of records displayed so far */
21300 int lineno; /* Line number of last line read from in */
21301 int openFlags; /* Additional flags to open. (SQLITE_OPEN_NOFOLLOW) */
21302 FILE *in; /* Read commands from this stream */
21303 FILE *out; /* Write results here */
21304 FILE *traceOut; /* Output for sqlite3_trace() */
21305 int nErr; /* Number of errors seen */
@@ -21531,11 +21542,11 @@
21531 va_list ap;
21532 char *zMsg;
21533 va_start(ap, zErrMsg);
21534 zMsg = sqlite3_vmprintf(zErrMsg, ap);
21535 va_end(ap);
21536 sqlite3_fprintf(stderr, "line %d: %s\n", p->lineno, zMsg);
21537 exit(1);
21538 }
21539 }
21540
21541 /*
@@ -25087,10 +25098,11 @@
25087 " --ifexist Only open if FILE already exists",
25088 #ifndef SQLITE_OMIT_DESERIALIZE
25089 " --maxsize N Maximum size for --hexdb or --deserialized database",
25090 #endif
25091 " --new Initialize FILE to an empty database",
 
25092 " --nofollow Do not follow symbolic links",
25093 " --readonly Open FILE readonly",
25094 " --zip FILE is a ZIP archive",
25095 #ifndef SQLITE_SHELL_FIDDLE
25096 ".output ?FILE? Send output to FILE or stdout if FILE is omitted",
@@ -25321,11 +25333,11 @@
25321 sqlite3_free(zPat);
25322 return n;
25323 }
25324
25325 /* Forward reference */
25326 static int process_input(ShellState *p);
25327
25328 /*
25329 ** Read the content of file zName into memory obtained from sqlite3_malloc64()
25330 ** and return a pointer to the buffer. The caller is responsible for freeing
25331 ** the memory.
@@ -25428,22 +25440,30 @@
25428 ** If the file does not exist or is empty but its name looks like a ZIP
25429 ** archive and the dfltZip flag is true, then assume it is a ZIP archive.
25430 ** Otherwise, assume an ordinary database regardless of the filename if
25431 ** the type cannot be determined from content.
25432 */
25433 int deduceDatabaseType(const char *zName, int dfltZip){
25434 FILE *f = sqlite3_fopen(zName, "rb");
25435 size_t n;
 
 
25436 int rc = SHELL_OPEN_UNSPEC;
25437 char zBuf[100];
25438 if( f==0 ){
25439 if( dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){
25440 return SHELL_OPEN_ZIPFILE;
25441 }else{
25442 return SHELL_OPEN_NORMAL;
25443 }
 
25444 }
 
 
 
 
 
25445 n = fread(zBuf, 16, 1, f);
25446 if( n==1 && memcmp(zBuf, "SQLite format 3", 16)==0 ){
25447 fclose(f);
25448 return SHELL_OPEN_NORMAL;
25449 }
@@ -25461,10 +25481,18 @@
25461 rc = SHELL_OPEN_ZIPFILE;
25462 }
25463 }
25464 fclose(f);
25465 return rc;
 
 
 
 
 
 
 
 
25466 }
25467
25468 #ifndef SQLITE_OMIT_DESERIALIZE
25469 /*
25470 ** Reconstruct an in-memory database using the output from the "dbtotxt"
@@ -25471,11 +25499,11 @@
25471 ** program. Read content from the file in p->aAuxDb[].zDbFilename.
25472 ** If p->aAuxDb[].zDbFilename is 0, then read from standard input.
25473 */
25474 static unsigned char *readHexDb(ShellState *p, int *pnData){
25475 unsigned char *a = 0;
25476 int nLine;
25477 int n = 0; /* Size of db per first line of hex dump */
25478 i64 sz = 0; /* n rounded up to nearest page boundary */
25479 int pgsz = 0;
25480 i64 iOffset = 0;
25481 int rc;
@@ -25510,10 +25538,14 @@
25510 shell_check_oom(a);
25511 memset(a, 0, sz);
25512 for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){
25513 int j = 0; /* Page number from "| page" line */
25514 int k = 0; /* Offset from "| page" line */
 
 
 
 
25515 rc = sscanf(zLine, "| page %d offset %d", &j, &k);
25516 if( rc==2 ){
25517 iOffset = k;
25518 continue;
25519 }
@@ -25548,11 +25580,11 @@
25548 if(cli_strncmp(zLine, "| end ", 6)==0 ) break;
25549 }
25550 p->lineno = nLine;
25551 }
25552 sqlite3_free(a);
25553 sqlite3_fprintf(stderr,"Error on line %d of --hexdb input\n", nLine);
25554 return 0;
25555 }
25556 #endif /* SQLITE_OMIT_DESERIALIZE */
25557
25558 /*
@@ -25625,11 +25657,11 @@
25625 if( p->openMode==SHELL_OPEN_UNSPEC ){
25626 if( zDbFilename==0 || zDbFilename[0]==0 ){
25627 p->openMode = SHELL_OPEN_NORMAL;
25628 }else{
25629 p->openMode = (u8)deduceDatabaseType(zDbFilename,
25630 (openFlags & OPEN_DB_ZIPFILE)!=0);
25631 }
25632 }
25633 if( (p->openFlags & (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE))==0 ){
25634 if( p->openFlags==0 ) p->openFlags = SQLITE_OPEN_CREATE;
25635 p->openFlags |= SQLITE_OPEN_READWRITE;
@@ -27652,29 +27684,45 @@
27652 int *pRc,
27653 ArCommand *pAr,
27654 char **pzWhere /* OUT: New WHERE clause */
27655 ){
27656 char *zWhere = 0;
27657 const char *zSameOp = (pAr->bGlob)? "GLOB" : "=";
27658 if( *pRc==SQLITE_OK ){
27659 if( pAr->nArg==0 ){
27660 zWhere = sqlite3_mprintf("1");
27661 }else{
 
 
 
 
 
27662 int i;
27663 const char *zSep = "";
27664 for(i=0; i<pAr->nArg; i++){
27665 const char *z = pAr->azArg[i];
27666 zWhere = sqlite3_mprintf(
27667 "%z%s name %s '%q' OR substr(name,1,%d) %s '%q/'",
27668 zWhere, zSep, zSameOp, z, strlen30(z)+1, zSameOp, z
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27669 );
27670 if( zWhere==0 ){
27671 *pRc = SQLITE_NOMEM;
27672 break;
27673 }
27674 zSep = " OR ";
27675 }
 
 
27676 }
27677 }
27678 *pzWhere = zWhere;
27679 }
27680
@@ -27990,11 +28038,11 @@
27990 int eDbType = SHELL_OPEN_UNSPEC;
27991 cmd.p = pState;
27992 cmd.out = pState->out;
27993 cmd.db = pState->db;
27994 if( cmd.zFile ){
27995 eDbType = deduceDatabaseType(cmd.zFile, 1);
27996 }else{
27997 eDbType = pState->openMode;
27998 }
27999 if( eDbType==SHELL_OPEN_ZIPFILE ){
28000 if( cmd.eCmd==AR_CMD_EXTRACT || cmd.eCmd==AR_CMD_LIST ){
@@ -29312,11 +29360,11 @@
29312 int nSep; /* Number of bytes in p->colSeparator[] */
29313 char *zSql = 0; /* An SQL statement */
29314 ImportCtx sCtx; /* Reader context */
29315 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
29316 int eVerbose = 0; /* Larger for more console output */
29317 int nSkip = 0; /* Initial lines to skip */
29318 int useOutputMode = 1; /* Use output mode to determine separators */
29319 char *zCreate = 0; /* CREATE TABLE statement text */
29320
29321 failIfSafeMode(p, "cannot run .import in safe mode");
29322 memset(&sCtx, 0, sizeof(sCtx));
@@ -30037,11 +30085,11 @@
30037 if( c=='n' && cli_strcmp(azArg[0], "nonce")==0 ){
30038 if( nArg!=2 ){
30039 eputz("Usage: .nonce NONCE\n");
30040 rc = 1;
30041 }else if( p->zNonce==0 || cli_strcmp(azArg[1],p->zNonce)!=0 ){
30042 sqlite3_fprintf(stderr,"line %d: incorrect nonce: \"%s\"\n",
30043 p->lineno, azArg[1]);
30044 exit(1);
30045 }else{
30046 p->bSafeMode = 0;
30047 return 0; /* Return immediately to bypass the safe mode reset
@@ -30092,10 +30140,12 @@
30092 #ifndef SQLITE_OMIT_DESERIALIZE
30093 }else if( optionMatch(z, "deserialize") ){
30094 openMode = SHELL_OPEN_DESERIALIZE;
30095 }else if( optionMatch(z, "hexdb") ){
30096 openMode = SHELL_OPEN_HEXDB;
 
 
30097 }else if( optionMatch(z, "maxsize") && iName+1<nArg ){
30098 p->szMax = integerValue(azArg[++iName]);
30099 #endif /* SQLITE_OMIT_DESERIALIZE */
30100 }else
30101 #endif /* !SQLITE_SHELL_FIDDLE */
@@ -30210,10 +30260,11 @@
30210 }else{
30211 sqlite3_fprintf(p->out,
30212 "ERROR: unknown option: \"%s\". Usage:\n", azArg[i]);
30213 showHelp(p->out, azArg[0]);
30214 rc = 1;
 
30215 goto meta_command_exit;
30216 }
30217 }else if( zFile==0 && eMode==0 ){
30218 if( cli_strcmp(z, "off")==0 ){
30219 #ifdef _WIN32
@@ -30493,11 +30544,11 @@
30493 #endif
30494
30495 #ifndef SQLITE_SHELL_FIDDLE
30496 if( c=='r' && n>=3 && cli_strncmp(azArg[0], "read", n)==0 ){
30497 FILE *inSaved = p->in;
30498 int savedLineno = p->lineno;
30499 failIfSafeMode(p, "cannot run .read in safe mode");
30500 if( nArg!=2 ){
30501 eputz("Usage: .read FILE\n");
30502 rc = 1;
30503 goto meta_command_exit;
@@ -30510,19 +30561,19 @@
30510 p->in = sqlite3_popen(azArg[1]+1, "r");
30511 if( p->in==0 ){
30512 sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
30513 rc = 1;
30514 }else{
30515 rc = process_input(p);
30516 pclose(p->in);
30517 }
30518 #endif
30519 }else if( (p->in = openChrSource(azArg[1]))==0 ){
30520 sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
30521 rc = 1;
30522 }else{
30523 rc = process_input(p);
30524 fclose(p->in);
30525 }
30526 p->in = inSaved;
30527 p->lineno = savedLineno;
30528 }else
@@ -32509,11 +32560,11 @@
32509 ** is saved only if input is interactive. An interrupt signal will
32510 ** cause this routine to exit immediately, unless input is interactive.
32511 **
32512 ** Return the number of errors.
32513 */
32514 static int process_input(ShellState *p){
32515 char *zLine = 0; /* A single input line */
32516 char *zSql = 0; /* Accumulated SQL text */
32517 i64 nLine; /* Length of current line */
32518 i64 nSql = 0; /* Bytes of zSql[] used */
32519 i64 nAlloc = 0; /* Allocated zSql[] space */
@@ -32522,12 +32573,12 @@
32522 i64 startline = 0; /* Line number for start of current input */
32523 QuickScanState qss = QSS_Start; /* Accumulated line status (so far) */
32524
32525 if( p->inputNesting==MAX_INPUT_NESTING ){
32526 /* This will be more informative in a later version. */
32527 sqlite3_fprintf(stderr,"Input nesting limit (%d) reached at line %d."
32528 " Check recursion.\n", MAX_INPUT_NESTING, p->lineno);
32529 return 1;
32530 }
32531 ++p->inputNesting;
32532 p->lineno = 0;
32533 CONTINUE_PROMPT_RESET;
@@ -32588,11 +32639,19 @@
32588 }else{
32589 zSql[nSql++] = '\n';
32590 memcpy(zSql+nSql, zLine, nLine+1);
32591 nSql += nLine;
32592 }
32593 if( nSql && QSS_SEMITERM(qss) && sqlite3_complete(zSql) ){
 
 
 
 
 
 
 
 
32594 echo_group_input(p, zSql);
32595 errCnt += runOneSqlLine(p, zSql, p->in, startline);
32596 CONTINUE_PROMPT_RESET;
32597 nSql = 0;
32598 if( p->outCount ){
@@ -32756,11 +32815,11 @@
32756 const char *sqliterc_override /* Name of config file. NULL to use default */
32757 ){
32758 char *home_dir = NULL;
32759 char *sqliterc = (char*)sqliterc_override;
32760 FILE *inSaved = p->in;
32761 int savedLineno = p->lineno;
32762
32763 if( sqliterc == NULL ){
32764 sqliterc = find_xdg_file("XDG_CONFIG_HOME",
32765 ".config",
32766 "sqlite3/sqliterc");
@@ -32778,11 +32837,11 @@
32778 p->in = sqliterc ? sqlite3_fopen(sqliterc,"rb") : 0;
32779 if( p->in ){
32780 if( stdin_is_interactive ){
32781 sqlite3_fprintf(stderr,"-- Loading resources from %s\n", sqliterc);
32782 }
32783 if( process_input(p) && bail_on_error ) exit(1);
32784 fclose(p->in);
32785 }else if( sqliterc_override!=0 ){
32786 sqlite3_fprintf(stderr,"cannot open: \"%s\"\n", sqliterc);
32787 if( bail_on_error ) exit(1);
32788 }
@@ -33609,19 +33668,19 @@
33609 linenoiseSetCompletionCallback(linenoise_completion);
33610 #elif HAVE_LINENOISE==2
33611 linenoiseSetCompletionCallback(linenoise_completion, NULL);
33612 #endif
33613 data.in = 0;
33614 rc = process_input(&data);
33615 if( zHistory ){
33616 shell_stifle_history(2000);
33617 shell_write_history(zHistory);
33618 sqlite3_free(zHistory);
33619 }
33620 }else{
33621 data.in = stdin;
33622 rc = process_input(&data);
33623 }
33624 }
33625 #ifndef SQLITE_SHELL_FIDDLE
33626 /* In WASM mode we have to leave the db state in place so that
33627 ** client code can "push" SQL into it after this call returns. */
@@ -33799,10 +33858,10 @@
33799 void fiddle_exec(const char * zSql){
33800 if(zSql && *zSql){
33801 if('.'==*zSql) puts(zSql);
33802 shellState.wasm.zInput = zSql;
33803 shellState.wasm.zPos = zSql;
33804 process_input(&shellState);
33805 shellState.wasm.zInput = shellState.wasm.zPos = 0;
33806 }
33807 }
33808 #endif /* SQLITE_SHELL_FIDDLE */
33809
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -7182,10 +7182,19 @@
7182 sqlite3_free(pRe->aOp);
7183 sqlite3_free(pRe->aArg);
7184 sqlite3_free(pRe);
7185 }
7186 }
7187
7188 /*
7189 ** Version of re_free() that accepts a pointer of type (void*). Required
7190 ** to satisfy sanitizers when the re_free() function is called via a
7191 ** function pointer.
7192 */
7193 static void re_free_voidptr(void *p){
7194 re_free((ReCompiled*)p);
7195 }
7196
7197 /*
7198 ** Compile a textual regular expression in zIn[] into a compiled regular
7199 ** expression suitable for us by re_match() and return a pointer to the
7200 ** compiled regular expression in *ppRe. Return NULL on success or an
@@ -7314,11 +7323,11 @@
7323 zStr = (const unsigned char*)sqlite3_value_text(argv[1]);
7324 if( zStr!=0 ){
7325 sqlite3_result_int(context, re_match(pRe, zStr, -1));
7326 }
7327 if( setAux ){
7328 sqlite3_set_auxdata(context, 0, pRe, re_free_voidptr);
7329 }
7330 }
7331
7332 #if defined(SQLITE_DEBUG)
7333 /*
@@ -8202,11 +8211,11 @@
8211
8212 pLvl->zDir = pCur->zPath;
8213 pCur->zPath = 0;
8214 pLvl->pDir = opendir(pLvl->zDir);
8215 if( pLvl->pDir==0 ){
8216 fsdirSetErrmsg(pCur, "cannot read directory: %s", pLvl->zDir);
8217 return SQLITE_ERROR;
8218 }
8219 }
8220
8221 while( pCur->iLvl>=0 ){
@@ -12531,15 +12540,15 @@
12540
12541 /*
12542 ** Allocate and return nByte bytes of zeroed memory using sqlite3_malloc().
12543 ** If the allocation fails, set *pRc to SQLITE_NOMEM and return NULL.
12544 */
12545 static void *idxMalloc(int *pRc, i64 nByte){
12546 void *pRet;
12547 assert( *pRc==SQLITE_OK );
12548 assert( nByte>0 );
12549 pRet = sqlite3_malloc64(nByte);
12550 if( pRet ){
12551 memset(pRet, 0, nByte);
12552 }else{
12553 *pRc = SQLITE_NOMEM;
12554 }
@@ -12602,11 +12611,11 @@
12611 for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){
12612 if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){
12613 return 1;
12614 }
12615 }
12616 pEntry = idxMalloc(pRc, sizeof(IdxHashEntry) + (i64)nKey+1 + (i64)nVal+1);
12617 if( pEntry ){
12618 pEntry->zKey = (char*)&pEntry[1];
12619 memcpy(pEntry->zKey, zKey, nKey);
12620 if( zVal ){
12621 pEntry->zVal = &pEntry->zKey[nKey+1];
@@ -12737,19 +12746,19 @@
12746 sqlite3_vtab_cursor base;
12747 sqlite3_stmt *pData;
12748 };
12749
12750 static char *expertDequote(const char *zIn){
12751 i64 n = STRLEN(zIn);
12752 char *zRet = sqlite3_malloc64(n);
12753
12754 assert( zIn[0]=='\'' );
12755 assert( zIn[n-1]=='\'' );
12756
12757 if( zRet ){
12758 i64 iOut = 0;
12759 i64 iIn = 0;
12760 for(iIn=1; iIn<(n-1); iIn++){
12761 if( zIn[iIn]=='\'' ){
12762 assert( zIn[iIn+1]=='\'' );
12763 iIn++;
12764 }
@@ -13058,11 +13067,11 @@
13067 char **pzErrmsg /* OUT: Error message (if not) */
13068 ){
13069 sqlite3_stmt *p1 = 0;
13070 int nCol = 0;
13071 int nTab;
13072 i64 nByte;
13073 IdxTable *pNew = 0;
13074 int rc, rc2;
13075 char *pCsr = 0;
13076 int nPk = 0;
13077
@@ -13150,18 +13159,18 @@
13159 */
13160 static char *idxAppendText(int *pRc, char *zIn, const char *zFmt, ...){
13161 va_list ap;
13162 char *zAppend = 0;
13163 char *zRet = 0;
13164 i64 nIn = zIn ? STRLEN(zIn) : 0;
13165 i64 nAppend = 0;
13166 va_start(ap, zFmt);
13167 if( *pRc==SQLITE_OK ){
13168 zAppend = sqlite3_vmprintf(zFmt, ap);
13169 if( zAppend ){
13170 nAppend = STRLEN(zAppend);
13171 zRet = (char*)sqlite3_malloc64(nIn + nAppend + 1);
13172 }
13173 if( zAppend && zRet ){
13174 if( nIn ) memcpy(zRet, zIn, nIn);
13175 memcpy(&zRet[nIn], zAppend, nAppend+1);
13176 }else{
@@ -13921,12 +13930,12 @@
13930 int nSlot;
13931 struct IdxRemSlot {
13932 int eType; /* SQLITE_NULL, INTEGER, REAL, TEXT, BLOB */
13933 i64 iVal; /* SQLITE_INTEGER value */
13934 double rVal; /* SQLITE_FLOAT value */
13935 i64 nByte; /* Bytes of space allocated at z */
13936 i64 n; /* Size of buffer z */
13937 char *z; /* SQLITE_TEXT/BLOB value */
13938 } aSlot[1];
13939 };
13940
13941 /*
@@ -13958,15 +13967,17 @@
13967 case SQLITE_FLOAT:
13968 sqlite3_result_double(pCtx, pSlot->rVal);
13969 break;
13970
13971 case SQLITE_BLOB:
13972 assert( pSlot->n <= 0x7fffffff );
13973 sqlite3_result_blob(pCtx, pSlot->z, (int)pSlot->n, SQLITE_TRANSIENT);
13974 break;
13975
13976 case SQLITE_TEXT:
13977 assert( pSlot->n <= 0x7fffffff );
13978 sqlite3_result_text(pCtx, pSlot->z, (int)pSlot->n, SQLITE_TRANSIENT);
13979 break;
13980 }
13981
13982 pSlot->eType = sqlite3_value_type(argv[1]);
13983 switch( pSlot->eType ){
@@ -13982,14 +13993,14 @@
13993 pSlot->rVal = sqlite3_value_double(argv[1]);
13994 break;
13995
13996 case SQLITE_BLOB:
13997 case SQLITE_TEXT: {
13998 i64 nByte = sqlite3_value_bytes(argv[1]);
13999 const void *pData = 0;
14000 if( nByte>pSlot->nByte ){
14001 char *zNew = (char*)sqlite3_realloc64(pSlot->z, nByte*2);
14002 if( zNew==0 ){
14003 sqlite3_result_error_nomem(pCtx);
14004 return;
14005 }
14006 pSlot->nByte = nByte*2;
@@ -14040,11 +14051,11 @@
14051 char *zOrder = 0;
14052 char *zQuery = 0;
14053 int nCol = 0;
14054 int i;
14055 sqlite3_stmt *pQuery = 0;
14056 i64 *aStat = 0;
14057 int rc = SQLITE_OK;
14058
14059 assert( p->iSample>0 );
14060
14061 /* Formulate the query text */
@@ -14086,11 +14097,11 @@
14097 rc = idxPrepareStmt(dbrem, &pQuery, pzErr, zQuery);
14098 }
14099 sqlite3_free(zQuery);
14100
14101 if( rc==SQLITE_OK ){
14102 aStat = (i64*)idxMalloc(&rc, sizeof(i64)*(nCol+1));
14103 }
14104 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){
14105 IdxHashEntry *pEntry;
14106 char *zStat = 0;
14107 for(i=0; i<=nCol; i++) aStat[i] = 1;
@@ -14103,15 +14114,15 @@
14114 aStat[i+1]++;
14115 }
14116 }
14117
14118 if( rc==SQLITE_OK ){
14119 i64 s0 = aStat[0];
14120 zStat = sqlite3_mprintf("%lld", s0);
14121 if( zStat==0 ) rc = SQLITE_NOMEM;
14122 for(i=1; rc==SQLITE_OK && i<=nCol; i++){
14123 zStat = idxAppendText(&rc, zStat, " %lld", (s0+aStat[i]/2) / aStat[i]);
14124 }
14125 }
14126
14127 if( rc==SQLITE_OK ){
14128 sqlite3_bind_text(pWriteStat, 1, zTab, -1, SQLITE_STATIC);
@@ -14186,11 +14197,11 @@
14197 if( nMax<=0 || rc!=SQLITE_OK ) return rc;
14198
14199 rc = sqlite3_exec(p->dbm, "ANALYZE; PRAGMA writable_schema=1", 0, 0, 0);
14200
14201 if( rc==SQLITE_OK ){
14202 i64 nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax);
14203 pCtx = (struct IdxRemCtx*)idxMalloc(&rc, nByte);
14204 }
14205
14206 if( rc==SQLITE_OK ){
14207 sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv);
@@ -14203,11 +14214,11 @@
14214 0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0
14215 );
14216 }
14217
14218 if( rc==SQLITE_OK ){
14219 pCtx->nSlot = (i64)nMax+1;
14220 rc = idxPrepareStmt(p->dbm, &pAllIndex, pzErr, zAllIndex);
14221 }
14222 if( rc==SQLITE_OK ){
14223 rc = idxPrepareStmt(p->dbm, &pIndexXInfo, pzErr, zIndexXInfo);
14224 }
@@ -14470,11 +14481,11 @@
14481 rc = sqlite3_prepare_v2(p->dbv, zStmt, -1, &pStmt, &zStmt);
14482 if( rc==SQLITE_OK ){
14483 if( pStmt ){
14484 IdxStatement *pNew;
14485 const char *z = sqlite3_sql(pStmt);
14486 i64 n = STRLEN(z);
14487 pNew = (IdxStatement*)idxMalloc(&rc, sizeof(IdxStatement) + n+1);
14488 if( rc==SQLITE_OK ){
14489 pNew->zSql = (char*)&pNew[1];
14490 memcpy(pNew->zSql, z, n+1);
14491 pNew->pNext = p->pStatement;
@@ -21295,11 +21306,11 @@
21306 unsigned statsOn; /* True to display memory stats before each finalize */
21307 unsigned mEqpLines; /* Mask of vertical lines in the EQP output graph */
21308 int inputNesting; /* Track nesting level of .read and other redirects */
21309 int outCount; /* Revert to stdout when reaching zero */
21310 int cnt; /* Number of records displayed so far */
21311 i64 lineno; /* Line number of last line read from in */
21312 int openFlags; /* Additional flags to open. (SQLITE_OPEN_NOFOLLOW) */
21313 FILE *in; /* Read commands from this stream */
21314 FILE *out; /* Write results here */
21315 FILE *traceOut; /* Output for sqlite3_trace() */
21316 int nErr; /* Number of errors seen */
@@ -21531,11 +21542,11 @@
21542 va_list ap;
21543 char *zMsg;
21544 va_start(ap, zErrMsg);
21545 zMsg = sqlite3_vmprintf(zErrMsg, ap);
21546 va_end(ap);
21547 sqlite3_fprintf(stderr, "line %lld: %s\n", p->lineno, zMsg);
21548 exit(1);
21549 }
21550 }
21551
21552 /*
@@ -25087,10 +25098,11 @@
25098 " --ifexist Only open if FILE already exists",
25099 #ifndef SQLITE_OMIT_DESERIALIZE
25100 " --maxsize N Maximum size for --hexdb or --deserialized database",
25101 #endif
25102 " --new Initialize FILE to an empty database",
25103 " --normal FILE is an ordinary SQLite database",
25104 " --nofollow Do not follow symbolic links",
25105 " --readonly Open FILE readonly",
25106 " --zip FILE is a ZIP archive",
25107 #ifndef SQLITE_SHELL_FIDDLE
25108 ".output ?FILE? Send output to FILE or stdout if FILE is omitted",
@@ -25321,11 +25333,11 @@
25333 sqlite3_free(zPat);
25334 return n;
25335 }
25336
25337 /* Forward reference */
25338 static int process_input(ShellState *p, const char*);
25339
25340 /*
25341 ** Read the content of file zName into memory obtained from sqlite3_malloc64()
25342 ** and return a pointer to the buffer. The caller is responsible for freeing
25343 ** the memory.
@@ -25428,22 +25440,30 @@
25440 ** If the file does not exist or is empty but its name looks like a ZIP
25441 ** archive and the dfltZip flag is true, then assume it is a ZIP archive.
25442 ** Otherwise, assume an ordinary database regardless of the filename if
25443 ** the type cannot be determined from content.
25444 */
25445 int deduceDatabaseType(const char *zName, int dfltZip, int openFlags){
25446 FILE *f;
25447 size_t n;
25448 sqlite3 *db = 0;
25449 sqlite3_stmt *pStmt = 0;
25450 int rc = SHELL_OPEN_UNSPEC;
25451 char zBuf[100];
25452 if( access(zName,0)!=0 ) goto database_type_by_name;
25453 if( sqlite3_open_v2(zName, &db, openFlags, 0)==SQLITE_OK
25454 && sqlite3_prepare_v2(db,"SELECT count(*) FROM sqlite_schema",-1,&pStmt,0)
25455 ==SQLITE_OK
25456 && sqlite3_step(pStmt)==SQLITE_ROW
25457 ){
25458 rc = SHELL_OPEN_NORMAL;
25459 }
25460 sqlite3_finalize(pStmt);
25461 sqlite3_close(db);
25462 if( rc==SHELL_OPEN_NORMAL ) return SHELL_OPEN_NORMAL;
25463 f = sqlite3_fopen(zName, "rb");
25464 if( f==0 ) goto database_type_by_name;
25465 n = fread(zBuf, 16, 1, f);
25466 if( n==1 && memcmp(zBuf, "SQLite format 3", 16)==0 ){
25467 fclose(f);
25468 return SHELL_OPEN_NORMAL;
25469 }
@@ -25461,10 +25481,18 @@
25481 rc = SHELL_OPEN_ZIPFILE;
25482 }
25483 }
25484 fclose(f);
25485 return rc;
25486
25487 database_type_by_name:
25488 if( dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){
25489 rc = SHELL_OPEN_ZIPFILE;
25490 }else{
25491 rc = SHELL_OPEN_NORMAL;
25492 }
25493 return rc;
25494 }
25495
25496 #ifndef SQLITE_OMIT_DESERIALIZE
25497 /*
25498 ** Reconstruct an in-memory database using the output from the "dbtotxt"
@@ -25471,11 +25499,11 @@
25499 ** program. Read content from the file in p->aAuxDb[].zDbFilename.
25500 ** If p->aAuxDb[].zDbFilename is 0, then read from standard input.
25501 */
25502 static unsigned char *readHexDb(ShellState *p, int *pnData){
25503 unsigned char *a = 0;
25504 i64 nLine;
25505 int n = 0; /* Size of db per first line of hex dump */
25506 i64 sz = 0; /* n rounded up to nearest page boundary */
25507 int pgsz = 0;
25508 i64 iOffset = 0;
25509 int rc;
@@ -25510,10 +25538,14 @@
25538 shell_check_oom(a);
25539 memset(a, 0, sz);
25540 for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){
25541 int j = 0; /* Page number from "| page" line */
25542 int k = 0; /* Offset from "| page" line */
25543 if( nLine>=2000000000 ){
25544 sqlite3_fprintf(stderr, "input too big\n");
25545 goto readHexDb_error;
25546 }
25547 rc = sscanf(zLine, "| page %d offset %d", &j, &k);
25548 if( rc==2 ){
25549 iOffset = k;
25550 continue;
25551 }
@@ -25548,11 +25580,11 @@
25580 if(cli_strncmp(zLine, "| end ", 6)==0 ) break;
25581 }
25582 p->lineno = nLine;
25583 }
25584 sqlite3_free(a);
25585 sqlite3_fprintf(stderr,"Error on line %lld of --hexdb input\n", nLine);
25586 return 0;
25587 }
25588 #endif /* SQLITE_OMIT_DESERIALIZE */
25589
25590 /*
@@ -25625,11 +25657,11 @@
25657 if( p->openMode==SHELL_OPEN_UNSPEC ){
25658 if( zDbFilename==0 || zDbFilename[0]==0 ){
25659 p->openMode = SHELL_OPEN_NORMAL;
25660 }else{
25661 p->openMode = (u8)deduceDatabaseType(zDbFilename,
25662 (openFlags & OPEN_DB_ZIPFILE)!=0, p->openFlags);
25663 }
25664 }
25665 if( (p->openFlags & (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE))==0 ){
25666 if( p->openFlags==0 ) p->openFlags = SQLITE_OPEN_CREATE;
25667 p->openFlags |= SQLITE_OPEN_READWRITE;
@@ -27652,29 +27684,45 @@
27684 int *pRc,
27685 ArCommand *pAr,
27686 char **pzWhere /* OUT: New WHERE clause */
27687 ){
27688 char *zWhere = 0;
 
27689 if( *pRc==SQLITE_OK ){
27690 if( pAr->nArg==0 ){
27691 zWhere = sqlite3_mprintf("1");
27692 }else{
27693 char *z1 = sqlite3_mprintf(pAr->bGlob ? "" : "name IN(");
27694 char *z2 = sqlite3_mprintf("");
27695 const char *zSep1 = "";
27696 const char *zSep2 = "";
27697
27698 int i;
27699 for(i=0; i<pAr->nArg && z1 && z2; i++){
 
27700 const char *z = pAr->azArg[i];
27701 int n = strlen30(z);
27702
27703 if( pAr->bGlob ){
27704 z1 = sqlite3_mprintf("%z%sname GLOB '%q'", z1, zSep2, z);
27705 z2 = sqlite3_mprintf(
27706 "%z%ssubstr(name,1,%d) GLOB '%q/'", z2, zSep2, n+1,z
27707 );
27708 }else{
27709 z1 = sqlite3_mprintf("%z%s'%q'", z1, zSep1, z);
27710 z2 = sqlite3_mprintf("%z%ssubstr(name,1,%d) = '%q/'",z2,zSep2,n+1,z);
27711 }
27712 zSep1 = ", ";
27713 zSep2 = " OR ";
27714 }
27715 if( z1==0 || z2==0 ){
27716 *pRc = SQLITE_NOMEM;
27717 }else{
27718 zWhere = sqlite3_mprintf("(%s%s OR (name GLOB '*/*' AND (%s))) ",
27719 z1, pAr->bGlob==0 ? ")" : "", z2
27720 );
 
 
 
 
 
27721 }
27722 sqlite3_free(z1);
27723 sqlite3_free(z2);
27724 }
27725 }
27726 *pzWhere = zWhere;
27727 }
27728
@@ -27990,11 +28038,11 @@
28038 int eDbType = SHELL_OPEN_UNSPEC;
28039 cmd.p = pState;
28040 cmd.out = pState->out;
28041 cmd.db = pState->db;
28042 if( cmd.zFile ){
28043 eDbType = deduceDatabaseType(cmd.zFile, 1, 0);
28044 }else{
28045 eDbType = pState->openMode;
28046 }
28047 if( eDbType==SHELL_OPEN_ZIPFILE ){
28048 if( cmd.eCmd==AR_CMD_EXTRACT || cmd.eCmd==AR_CMD_LIST ){
@@ -29312,11 +29360,11 @@
29360 int nSep; /* Number of bytes in p->colSeparator[] */
29361 char *zSql = 0; /* An SQL statement */
29362 ImportCtx sCtx; /* Reader context */
29363 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
29364 int eVerbose = 0; /* Larger for more console output */
29365 i64 nSkip = 0; /* Initial lines to skip */
29366 int useOutputMode = 1; /* Use output mode to determine separators */
29367 char *zCreate = 0; /* CREATE TABLE statement text */
29368
29369 failIfSafeMode(p, "cannot run .import in safe mode");
29370 memset(&sCtx, 0, sizeof(sCtx));
@@ -30037,11 +30085,11 @@
30085 if( c=='n' && cli_strcmp(azArg[0], "nonce")==0 ){
30086 if( nArg!=2 ){
30087 eputz("Usage: .nonce NONCE\n");
30088 rc = 1;
30089 }else if( p->zNonce==0 || cli_strcmp(azArg[1],p->zNonce)!=0 ){
30090 sqlite3_fprintf(stderr,"line %lld: incorrect nonce: \"%s\"\n",
30091 p->lineno, azArg[1]);
30092 exit(1);
30093 }else{
30094 p->bSafeMode = 0;
30095 return 0; /* Return immediately to bypass the safe mode reset
@@ -30092,10 +30140,12 @@
30140 #ifndef SQLITE_OMIT_DESERIALIZE
30141 }else if( optionMatch(z, "deserialize") ){
30142 openMode = SHELL_OPEN_DESERIALIZE;
30143 }else if( optionMatch(z, "hexdb") ){
30144 openMode = SHELL_OPEN_HEXDB;
30145 }else if( optionMatch(z, "normal") ){
30146 openMode = SHELL_OPEN_NORMAL;
30147 }else if( optionMatch(z, "maxsize") && iName+1<nArg ){
30148 p->szMax = integerValue(azArg[++iName]);
30149 #endif /* SQLITE_OMIT_DESERIALIZE */
30150 }else
30151 #endif /* !SQLITE_SHELL_FIDDLE */
@@ -30210,10 +30260,11 @@
30260 }else{
30261 sqlite3_fprintf(p->out,
30262 "ERROR: unknown option: \"%s\". Usage:\n", azArg[i]);
30263 showHelp(p->out, azArg[0]);
30264 rc = 1;
30265 sqlite3_free(zFile);
30266 goto meta_command_exit;
30267 }
30268 }else if( zFile==0 && eMode==0 ){
30269 if( cli_strcmp(z, "off")==0 ){
30270 #ifdef _WIN32
@@ -30493,11 +30544,11 @@
30544 #endif
30545
30546 #ifndef SQLITE_SHELL_FIDDLE
30547 if( c=='r' && n>=3 && cli_strncmp(azArg[0], "read", n)==0 ){
30548 FILE *inSaved = p->in;
30549 i64 savedLineno = p->lineno;
30550 failIfSafeMode(p, "cannot run .read in safe mode");
30551 if( nArg!=2 ){
30552 eputz("Usage: .read FILE\n");
30553 rc = 1;
30554 goto meta_command_exit;
@@ -30510,19 +30561,19 @@
30561 p->in = sqlite3_popen(azArg[1]+1, "r");
30562 if( p->in==0 ){
30563 sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
30564 rc = 1;
30565 }else{
30566 rc = process_input(p, "<pipe>");
30567 pclose(p->in);
30568 }
30569 #endif
30570 }else if( (p->in = openChrSource(azArg[1]))==0 ){
30571 sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
30572 rc = 1;
30573 }else{
30574 rc = process_input(p, azArg[1]);
30575 fclose(p->in);
30576 }
30577 p->in = inSaved;
30578 p->lineno = savedLineno;
30579 }else
@@ -32509,11 +32560,11 @@
32560 ** is saved only if input is interactive. An interrupt signal will
32561 ** cause this routine to exit immediately, unless input is interactive.
32562 **
32563 ** Return the number of errors.
32564 */
32565 static int process_input(ShellState *p, const char *zSrc){
32566 char *zLine = 0; /* A single input line */
32567 char *zSql = 0; /* Accumulated SQL text */
32568 i64 nLine; /* Length of current line */
32569 i64 nSql = 0; /* Bytes of zSql[] used */
32570 i64 nAlloc = 0; /* Allocated zSql[] space */
@@ -32522,12 +32573,12 @@
32573 i64 startline = 0; /* Line number for start of current input */
32574 QuickScanState qss = QSS_Start; /* Accumulated line status (so far) */
32575
32576 if( p->inputNesting==MAX_INPUT_NESTING ){
32577 /* This will be more informative in a later version. */
32578 sqlite3_fprintf(stderr,"%s: Input nesting limit (%d) reached at line %lld."
32579 " Check recursion.\n", zSrc, MAX_INPUT_NESTING, p->lineno);
32580 return 1;
32581 }
32582 ++p->inputNesting;
32583 p->lineno = 0;
32584 CONTINUE_PROMPT_RESET;
@@ -32588,11 +32639,19 @@
32639 }else{
32640 zSql[nSql++] = '\n';
32641 memcpy(zSql+nSql, zLine, nLine+1);
32642 nSql += nLine;
32643 }
32644 if( nSql>0x7fff0000 ){
32645 char zSize[100];
32646 sqlite3_snprintf(sizeof(zSize),zSize,"%,lld",nSql);
32647 sqlite3_fprintf(stderr, "%s:%lld: Input SQL is too big: %s bytes\n",
32648 zSrc, startline, zSize);
32649 nSql = 0;
32650 errCnt++;
32651 break;
32652 }else if( nSql && QSS_SEMITERM(qss) && sqlite3_complete(zSql) ){
32653 echo_group_input(p, zSql);
32654 errCnt += runOneSqlLine(p, zSql, p->in, startline);
32655 CONTINUE_PROMPT_RESET;
32656 nSql = 0;
32657 if( p->outCount ){
@@ -32756,11 +32815,11 @@
32815 const char *sqliterc_override /* Name of config file. NULL to use default */
32816 ){
32817 char *home_dir = NULL;
32818 char *sqliterc = (char*)sqliterc_override;
32819 FILE *inSaved = p->in;
32820 i64 savedLineno = p->lineno;
32821
32822 if( sqliterc == NULL ){
32823 sqliterc = find_xdg_file("XDG_CONFIG_HOME",
32824 ".config",
32825 "sqlite3/sqliterc");
@@ -32778,11 +32837,11 @@
32837 p->in = sqliterc ? sqlite3_fopen(sqliterc,"rb") : 0;
32838 if( p->in ){
32839 if( stdin_is_interactive ){
32840 sqlite3_fprintf(stderr,"-- Loading resources from %s\n", sqliterc);
32841 }
32842 if( process_input(p, sqliterc) && bail_on_error ) exit(1);
32843 fclose(p->in);
32844 }else if( sqliterc_override!=0 ){
32845 sqlite3_fprintf(stderr,"cannot open: \"%s\"\n", sqliterc);
32846 if( bail_on_error ) exit(1);
32847 }
@@ -33609,19 +33668,19 @@
33668 linenoiseSetCompletionCallback(linenoise_completion);
33669 #elif HAVE_LINENOISE==2
33670 linenoiseSetCompletionCallback(linenoise_completion, NULL);
33671 #endif
33672 data.in = 0;
33673 rc = process_input(&data, "<stdin>");
33674 if( zHistory ){
33675 shell_stifle_history(2000);
33676 shell_write_history(zHistory);
33677 sqlite3_free(zHistory);
33678 }
33679 }else{
33680 data.in = stdin;
33681 rc = process_input(&data, "<stdin>");
33682 }
33683 }
33684 #ifndef SQLITE_SHELL_FIDDLE
33685 /* In WASM mode we have to leave the db state in place so that
33686 ** client code can "push" SQL into it after this call returns. */
@@ -33799,10 +33858,10 @@
33858 void fiddle_exec(const char * zSql){
33859 if(zSql && *zSql){
33860 if('.'==*zSql) puts(zSql);
33861 shellState.wasm.zInput = zSql;
33862 shellState.wasm.zPos = zSql;
33863 process_input(&shellState, "<stdin>");
33864 shellState.wasm.zInput = shellState.wasm.zPos = 0;
33865 }
33866 }
33867 #endif /* SQLITE_SHELL_FIDDLE */
33868
+378 -38
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -16,11 +16,11 @@
1616
** if you want a wrapper to interface SQLite with your choice of programming
1717
** language. The code for the "sqlite3" command-line shell is also in a
1818
** separate file. This file contains only code for the core SQLite library.
1919
**
2020
** The content in this amalgamation comes from Fossil check-in
21
-** 5cbccab499bc3983aac1f57355552db607de with changes in files:
21
+** 724f2299f206cc9e7f830f984c50a8fc4ac1 with changes in files:
2222
**
2323
**
2424
*/
2525
#ifndef SQLITE_AMALGAMATION
2626
#define SQLITE_CORE 1
@@ -467,14 +467,14 @@
467467
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
468468
** [sqlite_version()] and [sqlite_source_id()].
469469
*/
470470
#define SQLITE_VERSION "3.51.0"
471471
#define SQLITE_VERSION_NUMBER 3051000
472
-#define SQLITE_SOURCE_ID "2025-10-15 10:52:45 5cbccab499bc3983aac1f57355552db607dee6c7ef4eb00d794dbee89c18db70"
472
+#define SQLITE_SOURCE_ID "2025-10-28 13:24:50 724f2299f206cc9e7f830f984c50a8fc4ac1c17210d71d9affe657b45252b060"
473473
#define SQLITE_SCM_BRANCH "trunk"
474474
#define SQLITE_SCM_TAGS ""
475
-#define SQLITE_SCM_DATETIME "2025-10-15T10:52:45.276Z"
475
+#define SQLITE_SCM_DATETIME "2025-10-28T13:24:50.858Z"
476476
477477
/*
478478
** CAPI3REF: Run-Time Library Version Numbers
479479
** KEYWORDS: sqlite3_version sqlite3_sourceid
480480
**
@@ -1251,11 +1251,11 @@
12511251
** to the [sqlite3_file] object associated with the journal file (either
12521252
** the [rollback journal] or the [write-ahead log]) for a particular database
12531253
** connection. See also [SQLITE_FCNTL_FILE_POINTER].
12541254
**
12551255
** <li>[[SQLITE_FCNTL_SYNC_OMITTED]]
1256
-** No longer in use.
1256
+** The SQLITE_FCNTL_SYNC_OMITTED file-control is no longer used.
12571257
**
12581258
** <li>[[SQLITE_FCNTL_SYNC]]
12591259
** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and
12601260
** sent to the VFS immediately before the xSync method is invoked on a
12611261
** database file descriptor. Or, if the xSync method is not invoked
@@ -1548,10 +1548,19 @@
15481548
** <li>[[SQLITE_FCNTL_RESET_CACHE]]
15491549
** If there is currently no transaction open on the database, and the
15501550
** database is not a temp db, then the [SQLITE_FCNTL_RESET_CACHE] file-control
15511551
** purges the contents of the in-memory page cache. If there is an open
15521552
** transaction, or if the db is a temp-db, this opcode is a no-op, not an error.
1553
+**
1554
+** <li>[[SQLITE_FCNTL_FILESTAT]]
1555
+** The [SQLITE_FCNTL_FILESTAT] opcode returns low-level diagnostic information
1556
+** about the [sqlite3_file] objects used access the database and journal files
1557
+** for the given schema. The fourth parameter to [sqlite3_file_control()]
1558
+** should be an initialized [sqlite3_str] pointer. JSON text describing
1559
+** various aspects of the sqlite3_file object is appended to the sqlite3_str.
1560
+** The SQLITE_FCNTL_FILESTAT opcode is usually a no-op, unless compile-time
1561
+** options are used to enable it.
15531562
** </ul>
15541563
*/
15551564
#define SQLITE_FCNTL_LOCKSTATE 1
15561565
#define SQLITE_FCNTL_GET_LOCKPROXYFILE 2
15571566
#define SQLITE_FCNTL_SET_LOCKPROXYFILE 3
@@ -1593,10 +1602,11 @@
15931602
#define SQLITE_FCNTL_EXTERNAL_READER 40
15941603
#define SQLITE_FCNTL_CKSM_FILE 41
15951604
#define SQLITE_FCNTL_RESET_CACHE 42
15961605
#define SQLITE_FCNTL_NULL_IO 43
15971606
#define SQLITE_FCNTL_BLOCK_ON_CONNECT 44
1607
+#define SQLITE_FCNTL_FILESTAT 45
15981608
15991609
/* deprecated names */
16001610
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
16011611
#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
16021612
#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -5226,13 +5236,15 @@
52265236
** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in
52275237
** [prepared statement] S to have an SQL value of NULL, but to also be
52285238
** associated with the pointer P of type T. ^D is either a NULL pointer or
52295239
** a pointer to a destructor function for P. ^SQLite will invoke the
52305240
** destructor D with a single argument of P when it is finished using
5231
-** P. The T parameter should be a static string, preferably a string
5232
-** literal. The sqlite3_bind_pointer() routine is part of the
5233
-** [pointer passing interface] added for SQLite 3.20.0.
5241
+** P, even if the call to sqlite3_bind_pointer() fails. Due to a
5242
+** historical design quirk, results are undefined if D is
5243
+** SQLITE_TRANSIENT. The T parameter should be a static string,
5244
+** preferably a string literal. The sqlite3_bind_pointer() routine is
5245
+** part of the [pointer passing interface] added for SQLite 3.20.0.
52345246
**
52355247
** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer
52365248
** for the [prepared statement] or with a prepared statement for which
52375249
** [sqlite3_step()] has been called more recently than [sqlite3_reset()],
52385250
** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_()
@@ -11472,23 +11484,25 @@
1147211484
** array to be bound, and N is the number of eements in the array. The
1147311485
** F argument is one of constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64],
1147411486
** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], or [SQLITE_CARRAY_BLOB] to
1147511487
** indicate the datatype of the array being bound. The X argument is not a
1147611488
** NULL pointer, then SQLite will invoke the function X on the P parameter
11477
-** after it has finished using P.
11489
+** after it has finished using P, even if the call to
11490
+** sqlite3_carray_bind() fails. The special-case finalizer
11491
+** SQLITE_TRANSIENT has no effect here.
1147811492
*/
11479
-SQLITE_API SQLITE_API int sqlite3_carray_bind(
11493
+SQLITE_API int sqlite3_carray_bind(
1148011494
sqlite3_stmt *pStmt, /* Statement to be bound */
1148111495
int i, /* Parameter index */
1148211496
void *aData, /* Pointer to array data */
1148311497
int nData, /* Number of data elements */
1148411498
int mFlags, /* CARRAY flags */
1148511499
void (*xDel)(void*) /* Destructor for aData */
1148611500
);
1148711501
1148811502
/*
11489
-** CAPI3REF: Datatypes for the CARRAY table-valued funtion
11503
+** CAPI3REF: Datatypes for the CARRAY table-valued function
1149011504
**
1149111505
** The fifth argument to the [sqlite3_carray_bind()] interface musts be
1149211506
** one of the following constants, to specify the datatype of the array
1149311507
** that is being bound into the [carray table-valued function].
1149411508
*/
@@ -22014,11 +22028,11 @@
2201422028
SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3*, int, Pgno, Pgno);
2201522029
SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*);
2201622030
SQLITE_PRIVATE void sqlite3AlterFunctions(void);
2201722031
SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
2201822032
SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
22019
-SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
22033
+SQLITE_PRIVATE i64 sqlite3GetToken(const unsigned char *, int *);
2202022034
SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
2202122035
SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int);
2202222036
SQLITE_PRIVATE void sqlite3CodeRhsOfIN(Parse*, Expr*, int);
2202322037
SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr*);
2202422038
SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
@@ -39781,10 +39795,123 @@
3978139795
#endif
3978239796
3978339797
}; /* End of the overrideable system calls */
3978439798
3978539799
39800
+#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
39801
+/*
39802
+** Extract Posix Advisory Locking information about file description fd
39803
+** from the /proc/PID/fdinfo/FD pseudo-file. Fill the string buffer a[16]
39804
+** with characters to indicate which SQLite-relevant locks are held.
39805
+** a[16] will be a 15-character zero-terminated string with the following
39806
+** schema:
39807
+**
39808
+** AAA/B.DDD.DDDDD
39809
+**
39810
+** Each of character A-D will be "w" or "r" or "-" to indicate either a
39811
+** write-lock, a read-lock, or no-lock, respectively. The "." and "/"
39812
+** characters are delimiters intended to make the string more easily
39813
+** readable by humans. Here are the meaning of the specific letters:
39814
+**
39815
+** AAA -> The main database locks. PENDING_BYTE, RESERVED_BYTE,
39816
+** and SHARED_FIRST, respectively.
39817
+**
39818
+** B -> The deadman switch lock. Offset 128 of the -shm file.
39819
+**
39820
+** CCC -> WAL locks: WRITE, CKPT, RECOVER
39821
+**
39822
+** DDDDD -> WAL read-locks 0 through 5
39823
+**
39824
+** Note that elements before the "/" apply to the main database file and
39825
+** elements after the "/" apply to the -shm file in WAL mode.
39826
+**
39827
+** Here is another way of thinking about the meaning of the result string:
39828
+**
39829
+** AAA/B.CCC.DDDDD
39830
+** ||| | ||| \___/
39831
+** PENDING--'|| | ||| `----- READ 0-5
39832
+** RESERVED--'| | ||`---- RECOVER
39833
+** SHARED ----' | |`----- CKPT
39834
+** DMS ------' `------ WRITE
39835
+**
39836
+** Return SQLITE_OK on success and SQLITE_ERROR_UNABLE if the /proc
39837
+** pseudo-filesystem is unavailable.
39838
+*/
39839
+static int unixPosixAdvisoryLocks(
39840
+ int fd, /* The file descriptor to analyze */
39841
+ char a[16] /* Write a text description of PALs here */
39842
+){
39843
+ int in;
39844
+ ssize_t n;
39845
+ char *p, *pNext, *x;
39846
+ char z[2000];
39847
+
39848
+ /* 1 */
39849
+ /* 012 4 678 01234 */
39850
+ memcpy(a, "---/-.---.-----", 16);
39851
+ sqlite3_snprintf(sizeof(z), z, "/proc/%d/fdinfo/%d", getpid(), fd);
39852
+ in = osOpen(z, O_RDONLY, 0);
39853
+ if( in<0 ){
39854
+ return SQLITE_ERROR_UNABLE;
39855
+ }
39856
+ n = osRead(in, z, sizeof(z)-1);
39857
+ osClose(in);
39858
+ if( n<=0 ) return SQLITE_ERROR_UNABLE;
39859
+ z[n] = 0;
39860
+
39861
+ /* We are looking for lines that begin with "lock:\t". Examples:
39862
+ **
39863
+ ** lock: 1: POSIX ADVISORY READ 494716 08:02:5277597 1073741826 1073742335
39864
+ ** lock: 1: POSIX ADVISORY WRITE 494716 08:02:5282282 120 120
39865
+ ** lock: 2: POSIX ADVISORY READ 494716 08:02:5282282 123 123
39866
+ ** lock: 3: POSIX ADVISORY READ 494716 08:02:5282282 128 128
39867
+ */
39868
+ pNext = strstr(z, "lock:\t");
39869
+ while( pNext ){
39870
+ char cType = 0;
39871
+ sqlite3_int64 iFirst, iLast;
39872
+ p = pNext+6;
39873
+ pNext = strstr(p, "lock:\t");
39874
+ if( pNext ) pNext[-1] = 0;
39875
+ if( (x = strstr(p, " READ "))!=0 ){
39876
+ cType = 'r';
39877
+ x += 6;
39878
+ }else if( (x = strstr(p, " WRITE "))!=0 ){
39879
+ cType = 'w';
39880
+ x += 7;
39881
+ }else{
39882
+ continue;
39883
+ }
39884
+ x = strrchr(x, ' ');
39885
+ if( x==0 ) continue;
39886
+ iLast = strtoll(x+1, 0, 10);
39887
+ *x = 0;
39888
+ x = strrchr(p, ' ');
39889
+ if( x==0 ) continue;
39890
+ iFirst = strtoll(x+1, 0, 10);
39891
+ if( iLast>=PENDING_BYTE ){
39892
+ if( iFirst<=PENDING_BYTE && iLast>=PENDING_BYTE ) a[0] = cType;
39893
+ if( iFirst<=PENDING_BYTE+1 && iLast>=PENDING_BYTE+1 ) a[1] = cType;
39894
+ if( iFirst<=PENDING_BYTE+2 && iLast>=PENDING_BYTE+510 ) a[2] = cType;
39895
+ }else if( iLast<=128 ){
39896
+ if( iFirst<=128 && iLast>=128 ) a[4] = cType;
39897
+ if( iFirst<=120 && iLast>=120 ) a[6] = cType;
39898
+ if( iFirst<=121 && iLast>=121 ) a[7] = cType;
39899
+ if( iFirst<=122 && iLast>=122 ) a[8] = cType;
39900
+ if( iFirst<=123 && iLast>=123 ) a[10] = cType;
39901
+ if( iFirst<=124 && iLast>=124 ) a[11] = cType;
39902
+ if( iFirst<=125 && iLast>=125 ) a[12] = cType;
39903
+ if( iFirst<=126 && iLast>=126 ) a[13] = cType;
39904
+ if( iFirst<=127 && iLast>=127 ) a[14] = cType;
39905
+ }
39906
+ }
39907
+ return SQLITE_OK;
39908
+}
39909
+#else
39910
+# define unixPosixAdvisoryLocks(A,B) SQLITE_ERROR_UNABLE
39911
+#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */
39912
+
3978639913
/*
3978739914
** On some systems, calls to fchown() will trigger a message in a security
3978839915
** log if they come from non-root processes. So avoid calling fchown() if
3978939916
** we are not running as root.
3979039917
*/
@@ -40904,10 +41031,13 @@
4090441031
rc = osSetPosixAdvisoryLock(pFile->h, pLock, pFile);
4090541032
}
4090641033
return rc;
4090741034
}
4090841035
41036
+/* Forward reference */
41037
+static int unixIsSharingShmNode(unixFile*);
41038
+
4090941039
/*
4091041040
** Lock the file with the lock specified by parameter eFileLock - one
4091141041
** of the following:
4091241042
**
4091341043
** (1) SHARED_LOCK
@@ -41092,11 +41222,13 @@
4109241222
}else{
4109341223
pFile->eFileLock = SHARED_LOCK;
4109441224
pInode->nLock++;
4109541225
pInode->nShared = 1;
4109641226
}
41097
- }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){
41227
+ }else if( (eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1)
41228
+ || unixIsSharingShmNode(pFile)
41229
+ ){
4109841230
/* We are trying for an exclusive lock but another thread in this
4109941231
** same process is still holding a shared lock. */
4110041232
rc = SQLITE_BUSY;
4110141233
}else{
4110241234
/* The request was for a RESERVED or EXCLUSIVE lock. It is
@@ -43187,10 +43319,14 @@
4318743319
/* Forward declaration */
4318843320
static int unixGetTempname(int nBuf, char *zBuf);
4318943321
#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL)
4319043322
static int unixFcntlExternalReader(unixFile*, int*);
4319143323
#endif
43324
+#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
43325
+ static void unixDescribeShm(sqlite3_str*,unixShm*);
43326
+#endif
43327
+
4319243328
4319343329
/*
4319443330
** Information and control of an open file handle.
4319543331
*/
4319643332
static int unixFileControl(sqlite3_file *id, int op, void *pArg){
@@ -43329,10 +43465,70 @@
4332943465
#else
4333043466
*(int*)pArg = 0;
4333143467
return SQLITE_OK;
4333243468
#endif
4333343469
}
43470
+
43471
+#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
43472
+ case SQLITE_FCNTL_FILESTAT: {
43473
+ sqlite3_str *pStr = (sqlite3_str*)pArg;
43474
+ char aLck[16];
43475
+ unixInodeInfo *pInode;
43476
+ static const char *azLock[] = { "SHARED", "RESERVED",
43477
+ "PENDING", "EXCLUSIVE" };
43478
+ sqlite3_str_appendf(pStr, "{\"h\":%d", pFile->h);
43479
+ sqlite3_str_appendf(pStr, ",\"vfs\":\"%s\"", pFile->pVfs->zName);
43480
+ if( pFile->eFileLock ){
43481
+ sqlite3_str_appendf(pStr, ",\"eFileLock\":\"%s\"",
43482
+ azLock[pFile->eFileLock-1]);
43483
+ if( unixPosixAdvisoryLocks(pFile->h, aLck)==SQLITE_OK ){
43484
+ sqlite3_str_appendf(pStr, ",\"pal\":\"%s\"", aLck);
43485
+ }
43486
+ }
43487
+ unixEnterMutex();
43488
+ if( pFile->pShm ){
43489
+ sqlite3_str_appendall(pStr, ",\"shm\":");
43490
+ unixDescribeShm(pStr, pFile->pShm);
43491
+ }
43492
+#if SQLITE_MAX_MMAP_SIZE>0
43493
+ if( pFile->mmapSize ){
43494
+ sqlite3_str_appendf(pStr, ",\"mmapSize\":%lld", pFile->mmapSize);
43495
+ sqlite3_str_appendf(pStr, ",\"nFetchOut\":%d", pFile->nFetchOut);
43496
+ }
43497
+#endif
43498
+ if( (pInode = pFile->pInode)!=0 ){
43499
+ sqlite3_str_appendf(pStr, ",\"inode\":{\"nRef\":%d",pInode->nRef);
43500
+ sqlite3_mutex_enter(pInode->pLockMutex);
43501
+ sqlite3_str_appendf(pStr, ",\"nShared\":%d", pInode->nShared);
43502
+ if( pInode->eFileLock ){
43503
+ sqlite3_str_appendf(pStr, ",\"eFileLock\":\"%s\"",
43504
+ azLock[pInode->eFileLock-1]);
43505
+ }
43506
+ if( pInode->pUnused ){
43507
+ char cSep = '[';
43508
+ UnixUnusedFd *pUFd = pFile->pInode->pUnused;
43509
+ sqlite3_str_appendall(pStr, ",\"unusedFd\":");
43510
+ while( pUFd ){
43511
+ sqlite3_str_appendf(pStr, "%c{\"fd\":%d,\"flags\":%d",
43512
+ cSep, pUFd->fd, pUFd->flags);
43513
+ cSep = ',';
43514
+ if( unixPosixAdvisoryLocks(pUFd->fd, aLck)==SQLITE_OK ){
43515
+ sqlite3_str_appendf(pStr, ",\"pal\":\"%s\"", aLck);
43516
+ }
43517
+ sqlite3_str_append(pStr, "}", 1);
43518
+ pUFd = pUFd->pNext;
43519
+ }
43520
+ sqlite3_str_append(pStr, "]", 1);
43521
+ }
43522
+ sqlite3_mutex_leave(pInode->pLockMutex);
43523
+ sqlite3_str_append(pStr, "}", 1);
43524
+ }
43525
+ unixLeaveMutex();
43526
+ sqlite3_str_append(pStr, "}", 1);
43527
+ return SQLITE_OK;
43528
+ }
43529
+#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */
4333443530
}
4333543531
return SQLITE_NOTFOUND;
4333643532
}
4333743533
4333843534
/*
@@ -43595,10 +43791,30 @@
4359543791
** Constants used for locking
4359643792
*/
4359743793
#define UNIX_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */
4359843794
#define UNIX_SHM_DMS (UNIX_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */
4359943795
43796
+#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
43797
+/*
43798
+** Describe the pShm object using JSON. Used for diagnostics only.
43799
+*/
43800
+static void unixDescribeShm(sqlite3_str *pStr, unixShm *pShm){
43801
+ unixShmNode *pNode = pShm->pShmNode;
43802
+ char aLck[16];
43803
+ sqlite3_str_appendf(pStr, "{\"h\":%d", pNode->hShm);
43804
+ assert( unixMutexHeld() );
43805
+ sqlite3_str_appendf(pStr, ",\"nRef\":%d", pNode->nRef);
43806
+ sqlite3_str_appendf(pStr, ",\"id\":%d", pShm->id);
43807
+ sqlite3_str_appendf(pStr, ",\"sharedMask\":%d", pShm->sharedMask);
43808
+ sqlite3_str_appendf(pStr, ",\"exclMask\":%d", pShm->exclMask);
43809
+ if( unixPosixAdvisoryLocks(pNode->hShm, aLck)==SQLITE_OK ){
43810
+ sqlite3_str_appendf(pStr, ",\"pal\":\"%s\"", aLck);
43811
+ }
43812
+ sqlite3_str_append(pStr, "}", 1);
43813
+}
43814
+#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */
43815
+
4360043816
/*
4360143817
** Use F_GETLK to check whether or not there are any readers with open
4360243818
** wal-mode transactions in other processes on database file pFile. If
4360343819
** no error occurs, return SQLITE_OK and set (*piOut) to 1 if there are
4360443820
** such transactions, or 0 otherwise. If an error occurs, return an
@@ -43628,10 +43844,53 @@
4362843844
}
4362943845
4363043846
return rc;
4363143847
}
4363243848
43849
+/*
43850
+** If pFile has a -shm file open and it is sharing that file with some
43851
+** other connection, either in the same process or in a separate process,
43852
+** then return true. Return false if either pFile does not have a -shm
43853
+** file open or if it is the only connection to that -shm file across the
43854
+** entire system.
43855
+**
43856
+** This routine is not required for correct operation. It can always return
43857
+** false and SQLite will continue to operate according to spec. However,
43858
+** when this routine does its job, it adds extra robustness in cases
43859
+** where database file locks have been erroneously deleted in a WAL-mode
43860
+** database by doing close(open(DATABASE_PATHNAME)) or similar.
43861
+**
43862
+** With false negatives, SQLite still operates to spec, though with less
43863
+** robustness. With false positives, the last database connection on a
43864
+** WAL-mode database will fail to unlink the -wal and -shm files, which
43865
+** is annoying but harmless. False positives will also prevent a database
43866
+** connection from running "PRAGMA journal_mode=DELETE" in order to take
43867
+** the database out of WAL mode, which is perhaps more serious, but is
43868
+** still not a disaster.
43869
+*/
43870
+static int unixIsSharingShmNode(unixFile *pFile){
43871
+ int rc;
43872
+ unixShmNode *pShmNode;
43873
+ if( pFile->pShm==0 ) return 0;
43874
+ if( pFile->ctrlFlags & UNIXFILE_EXCL ) return 0;
43875
+ pShmNode = pFile->pShm->pShmNode;
43876
+ rc = 1;
43877
+ unixEnterMutex();
43878
+ if( ALWAYS(pShmNode->nRef==1) ){
43879
+ struct flock lock;
43880
+ lock.l_whence = SEEK_SET;
43881
+ lock.l_start = UNIX_SHM_DMS;
43882
+ lock.l_len = 1;
43883
+ lock.l_type = F_WRLCK;
43884
+ osFcntl(pShmNode->hShm, F_GETLK, &lock);
43885
+ if( lock.l_type==F_UNLCK ){
43886
+ rc = 0;
43887
+ }
43888
+ }
43889
+ unixLeaveMutex();
43890
+ return rc;
43891
+}
4363343892
4363443893
/*
4363543894
** Apply posix advisory locks for all bytes from ofst through ofst+n-1.
4363643895
**
4363743896
** Locks block if the mask is exactly UNIX_SHM_C and are non-blocking
@@ -43673,11 +43932,12 @@
4367343932
/* Shared locks never span more than one byte */
4367443933
assert( n==1 || lockType!=F_RDLCK );
4367543934
4367643935
/* Locks are within range */
4367743936
assert( n>=1 && n<=SQLITE_SHM_NLOCK );
43678
- assert( ofst>=UNIX_SHM_BASE && ofst<=(UNIX_SHM_DMS+SQLITE_SHM_NLOCK) );
43937
+ assert( ofst>=UNIX_SHM_BASE && ofst<=UNIX_SHM_DMS );
43938
+ assert( ofst+n-1<=UNIX_SHM_DMS );
4367943939
4368043940
if( pShmNode->hShm>=0 ){
4368143941
int res;
4368243942
/* Initialize the locking parameters */
4368343943
f.l_type = lockType;
@@ -51478,10 +51738,32 @@
5147851738
int iNew = *(int*)pArg;
5147951739
pFile->bBlockOnConnect = iNew;
5148051740
return SQLITE_OK;
5148151741
}
5148251742
#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */
51743
+
51744
+#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
51745
+ case SQLITE_FCNTL_FILESTAT: {
51746
+ sqlite3_str *pStr = (sqlite3_str*)pArg;
51747
+ sqlite3_str_appendf(pStr, "{\"h\":%llu", (sqlite3_uint64)pFile->h);
51748
+ sqlite3_str_appendf(pStr, ",\"vfs\":\"%s\"", pFile->pVfs->zName);
51749
+ if( pFile->locktype ){
51750
+ static const char *azLock[] = { "SHARED", "RESERVED",
51751
+ "PENDING", "EXCLUSIVE" };
51752
+ sqlite3_str_appendf(pStr, ",\"locktype\":\"%s\"",
51753
+ azLock[pFile->locktype-1]);
51754
+ }
51755
+#if SQLITE_MAX_MMAP_SIZE>0
51756
+ if( pFile->mmapSize ){
51757
+ sqlite3_str_appendf(pStr, ",\"mmapSize\":%lld", pFile->mmapSize);
51758
+ sqlite3_str_appendf(pStr, ",\"nFetchOut\":%d", pFile->nFetchOut);
51759
+ }
51760
+#endif
51761
+ sqlite3_str_append(pStr, "}", 1);
51762
+ return SQLITE_OK;
51763
+ }
51764
+#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */
5148351765
5148451766
}
5148551767
OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
5148651768
return SQLITE_NOTFOUND;
5148751769
}
@@ -67063,11 +67345,11 @@
6706367345
} aSegment[FLEXARRAY]; /* One for every 32KB page in the wal-index */
6706467346
};
6706567347
6706667348
/* Size (in bytes) of a WalIterator object suitable for N or fewer segments */
6706767349
#define SZ_WALITERATOR(N) \
67068
- (offsetof(WalIterator,aSegment)*(N)*sizeof(struct WalSegment))
67350
+ (offsetof(WalIterator,aSegment)+(N)*sizeof(struct WalSegment))
6706967351
6707067352
/*
6707167353
** Define the parameters of the hash tables in the wal-index file. There
6707267354
** is a hash-table following every HASHTABLE_NPAGE page numbers in the
6707367355
** wal-index.
@@ -94735,14 +95017,14 @@
9473595017
** zSql is a zero-terminated string of UTF-8 SQL text. Return the number of
9473695018
** bytes in this text up to but excluding the first character in
9473795019
** a host parameter. If the text contains no host parameters, return
9473895020
** the total number of bytes in the text.
9473995021
*/
94740
-static int findNextHostParameter(const char *zSql, int *pnToken){
95022
+static i64 findNextHostParameter(const char *zSql, i64 *pnToken){
9474195023
int tokenType;
94742
- int nTotal = 0;
94743
- int n;
95024
+ i64 nTotal = 0;
95025
+ i64 n;
9474495026
9474595027
*pnToken = 0;
9474695028
while( zSql[0] ){
9474795029
n = sqlite3GetToken((u8*)zSql, &tokenType);
9474895030
assert( n>0 && tokenType!=TK_ILLEGAL );
@@ -94785,12 +95067,12 @@
9478595067
const char *zRawSql /* Raw text of the SQL statement */
9478695068
){
9478795069
sqlite3 *db; /* The database connection */
9478895070
int idx = 0; /* Index of a host parameter */
9478995071
int nextIndex = 1; /* Index of next ? host parameter */
94790
- int n; /* Length of a token prefix */
94791
- int nToken; /* Length of the parameter token */
95072
+ i64 n; /* Length of a token prefix */
95073
+ i64 nToken; /* Length of the parameter token */
9479295074
int i; /* Loop counter */
9479395075
Mem *pVar; /* Value of a host parameter */
9479495076
StrAccum out; /* Accumulate the output here */
9479595077
#ifndef SQLITE_OMIT_UTF16
9479695078
Mem utf8; /* Used to convert UTF16 into UTF8 for display */
@@ -96816,10 +97098,13 @@
9681697098
nByte = pIn1->n;
9681797099
nByte += pIn2->n;
9681897100
if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
9681997101
goto too_big;
9682097102
}
97103
+#if SQLITE_MAX_LENGTH>2147483645
97104
+ if( nByte>2147483645 ){ goto too_big; }
97105
+#endif
9682197106
if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
9682297107
goto no_mem;
9682397108
}
9682497109
MemSetTypeFlag(pOut, MEM_Str);
9682597110
if( pOut!=pIn2 ){
@@ -131915,11 +132200,11 @@
131915132200
static void *contextMalloc(sqlite3_context *context, i64 nByte){
131916132201
char *z;
131917132202
sqlite3 *db = sqlite3_context_db_handle(context);
131918132203
assert( nByte>0 );
131919132204
testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH] );
131920
- testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
132205
+ testcase( nByte==(i64)db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
131921132206
if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
131922132207
sqlite3_result_error_toobig(context);
131923132208
z = 0;
131924132209
}else{
131925132210
z = sqlite3Malloc(nByte);
@@ -134180,12 +134465,12 @@
134180134465
** aggregate. Remember all input Y values until the very end.
134181134466
** Those values are accumulated in the Percentile.a[] array.
134182134467
*/
134183134468
typedef struct Percentile Percentile;
134184134469
struct Percentile {
134185
- unsigned nAlloc; /* Number of slots allocated for a[] */
134186
- unsigned nUsed; /* Number of slots actually used in a[] */
134470
+ u64 nAlloc; /* Number of slots allocated for a[] */
134471
+ u64 nUsed; /* Number of slots actually used in a[] */
134187134472
char bSorted; /* True if a[] is already in sorted order */
134188134473
char bKeepSorted; /* True if advantageous to keep a[] sorted */
134189134474
char bPctValid; /* True if rPct is valid */
134190134475
double rPct; /* Fraction. 0.0 to 1.0 */
134191134476
double *a; /* Array of Y values */
@@ -134218,15 +134503,15 @@
134218134503
** If bExact is false, return the index at which a new entry with
134219134504
** value y should be insert in order to keep the values in sorted
134220134505
** order. The smallest return value in this case will be 0, and
134221134506
** the largest return value will be p->nUsed.
134222134507
*/
134223
-static int percentBinarySearch(Percentile *p, double y, int bExact){
134224
- int iFirst = 0; /* First element of search range */
134225
- int iLast = p->nUsed - 1; /* Last element of search range */
134508
+static i64 percentBinarySearch(Percentile *p, double y, int bExact){
134509
+ i64 iFirst = 0; /* First element of search range */
134510
+ i64 iLast = (i64)p->nUsed - 1; /* Last element of search range */
134226134511
while( iLast>=iFirst ){
134227
- int iMid = (iFirst+iLast)/2;
134512
+ i64 iMid = (iFirst+iLast)/2;
134228134513
double x = p->a[iMid];
134229134514
if( x<y ){
134230134515
iFirst = iMid + 1;
134231134516
}else if( x>y ){
134232134517
iLast = iMid - 1;
@@ -134325,11 +134610,11 @@
134325134610
return;
134326134611
}
134327134612
134328134613
/* Allocate and store the Y */
134329134614
if( p->nUsed>=p->nAlloc ){
134330
- unsigned n = p->nAlloc*2 + 250;
134615
+ u64 n = p->nAlloc*2 + 250;
134331134616
double *a = sqlite3_realloc64(p->a, sizeof(double)*n);
134332134617
if( a==0 ){
134333134618
sqlite3_free(p->a);
134334134619
memset(p, 0, sizeof(*p));
134335134620
sqlite3_result_error_nomem(pCtx);
@@ -134342,11 +134627,11 @@
134342134627
p->a[p->nUsed++] = y;
134343134628
p->bSorted = 1;
134344134629
}else if( !p->bSorted || y>=p->a[p->nUsed-1] ){
134345134630
p->a[p->nUsed++] = y;
134346134631
}else if( p->bKeepSorted ){
134347
- int i;
134632
+ i64 i;
134348134633
i = percentBinarySearch(p, y, 0);
134349134634
if( i<(int)p->nUsed ){
134350134635
memmove(&p->a[i+1], &p->a[i], (p->nUsed-i)*sizeof(p->a[0]));
134351134636
}
134352134637
p->a[i] = y;
@@ -134427,11 +134712,11 @@
134427134712
*/
134428134713
static void percentInverse(sqlite3_context *pCtx,int argc,sqlite3_value **argv){
134429134714
Percentile *p;
134430134715
int eType;
134431134716
double y;
134432
- int i;
134717
+ i64 i;
134433134718
assert( argc==2 || argc==1 );
134434134719
134435134720
/* Allocate the session context. */
134436134721
p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p));
134437134722
assert( p!=0 );
@@ -134513,10 +134798,60 @@
134513134798
percentCompute(pCtx, 0);
134514134799
}
134515134800
/****** End of percentile family of functions ******/
134516134801
#endif /* SQLITE_ENABLE_PERCENTILE */
134517134802
134803
+#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
134804
+/*
134805
+** Implementation of sqlite_filestat(SCHEMA).
134806
+**
134807
+** Return JSON text that describes low-level debug/diagnostic information
134808
+** about the sqlite3_file object associated with SCHEMA.
134809
+*/
134810
+static void filestatFunc(
134811
+ sqlite3_context *context,
134812
+ int argc,
134813
+ sqlite3_value **argv
134814
+){
134815
+ sqlite3 *db = sqlite3_context_db_handle(context);
134816
+ const char *zDbName;
134817
+ sqlite3_str *pStr;
134818
+ Btree *pBtree;
134819
+
134820
+ zDbName = (const char*)sqlite3_value_text(argv[0]);
134821
+ pBtree = sqlite3DbNameToBtree(db, zDbName);
134822
+ if( pBtree ){
134823
+ Pager *pPager;
134824
+ sqlite3_file *fd;
134825
+ int rc;
134826
+ sqlite3BtreeEnter(pBtree);
134827
+ pPager = sqlite3BtreePager(pBtree);
134828
+ assert( pPager!=0 );
134829
+ fd = sqlite3PagerFile(pPager);
134830
+ pStr = sqlite3_str_new(db);
134831
+ if( pStr==0 ){
134832
+ sqlite3_result_error_nomem(context);
134833
+ }else{
134834
+ sqlite3_str_append(pStr, "{\"db\":", 6);
134835
+ rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_FILESTAT, pStr);
134836
+ if( rc ) sqlite3_str_append(pStr, "null", 4);
134837
+ fd = sqlite3PagerJrnlFile(pPager);
134838
+ if( fd && fd->pMethods!=0 ){
134839
+ sqlite3_str_appendall(pStr, ",\"journal\":");
134840
+ rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_FILESTAT, pStr);
134841
+ if( rc ) sqlite3_str_append(pStr, "null", 4);
134842
+ }
134843
+ sqlite3_str_append(pStr, "}", 1);
134844
+ sqlite3_result_text(context, sqlite3_str_finish(pStr), -1,
134845
+ sqlite3_free);
134846
+ }
134847
+ sqlite3BtreeLeave(pBtree);
134848
+ }else{
134849
+ sqlite3_result_text(context, "{}", 2, SQLITE_STATIC);
134850
+ }
134851
+}
134852
+#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */
134518134853
134519134854
#ifdef SQLITE_DEBUG
134520134855
/*
134521134856
** Implementation of fpdecode(x,y,z) function.
134522134857
**
@@ -134672,10 +135007,13 @@
134672135007
INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
134673135008
INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
134674135009
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
134675135010
INLINE_FUNC(sqlite_offset, 1, INLINEFUNC_sqlite_offset, 0 ),
134676135011
#endif
135012
+#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
135013
+ FUNCTION(sqlite_filestat, 1, 0, 0, filestatFunc ),
135014
+#endif
134677135015
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
134678135016
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
134679135017
FUNCTION(rtrim, 1, 2, 0, trimFunc ),
134680135018
FUNCTION(rtrim, 2, 2, 0, trimFunc ),
134681135019
FUNCTION(trim, 1, 3, 0, trimFunc ),
@@ -183458,12 +183796,13 @@
183458183796
183459183797
/*
183460183798
** Return the length (in bytes) of the token that begins at z[0].
183461183799
** Store the token type in *tokenType before returning.
183462183800
*/
183463
-SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
183464
- int i, c;
183801
+SQLITE_PRIVATE i64 sqlite3GetToken(const unsigned char *z, int *tokenType){
183802
+ i64 i;
183803
+ int c;
183465183804
switch( aiClass[*z] ){ /* Switch on the character-class of the first byte
183466183805
** of the token. See the comment on the CC_ defines
183467183806
** above. */
183468183807
case CC_SPACE: {
183469183808
testcase( z[0]==' ' );
@@ -183787,11 +184126,11 @@
183787184126
** Run the parser on the given SQL string.
183788184127
*/
183789184128
SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){
183790184129
int nErr = 0; /* Number of errors encountered */
183791184130
void *pEngine; /* The LEMON-generated LALR(1) parser */
183792
- int n = 0; /* Length of the next token token */
184131
+ i64 n = 0; /* Length of the next token token */
183793184132
int tokenType; /* type of the next token */
183794184133
int lastTokenParsed = -1; /* type of the previous token */
183795184134
sqlite3 *db = pParse->db; /* The database connection */
183796184135
int mxSqlLen; /* Max length of an SQL string */
183797184136
Parse *pParentParse = 0; /* Outer parse context, if any */
@@ -183890,17 +184229,17 @@
183890184229
zSql += n;
183891184230
continue;
183892184231
}else if( tokenType!=TK_QNUMBER ){
183893184232
Token x;
183894184233
x.z = zSql;
183895
- x.n = n;
184234
+ x.n = (u32)n;
183896184235
sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", &x);
183897184236
break;
183898184237
}
183899184238
}
183900184239
pParse->sLastToken.z = zSql;
183901
- pParse->sLastToken.n = n;
184240
+ pParse->sLastToken.n = (u32)n;
183902184241
sqlite3Parser(pEngine, tokenType, pParse->sLastToken);
183903184242
lastTokenParsed = tokenType;
183904184243
zSql += n;
183905184244
assert( db->mallocFailed==0 || pParse->rc!=SQLITE_OK || startedWithOom );
183906184245
if( pParse->rc!=SQLITE_OK ) break;
@@ -183972,11 +184311,11 @@
183972184311
Vdbe *pVdbe, /* VM being reprepared */
183973184312
const char *zSql /* The original SQL string */
183974184313
){
183975184314
sqlite3 *db; /* The database connection */
183976184315
int i; /* Next unread byte of zSql[] */
183977
- int n; /* length of current token */
184316
+ i64 n; /* length of current token */
183978184317
int tokenType; /* type of current token */
183979184318
int prevType = 0; /* Previous non-whitespace token */
183980184319
int nParen; /* Number of nested levels of parentheses */
183981184320
int iStartIN; /* Start of RHS of IN operator in z[] */
183982184321
int nParenAtIN; /* Value of nParent at start of RHS of IN operator */
@@ -215365,11 +215704,11 @@
215365215704
/* #include "sqlite3ext.h" */
215366215705
SQLITE_EXTENSION_INIT1
215367215706
#else
215368215707
/* #include "sqlite3.h" */
215369215708
#endif
215370
-SQLITE_PRIVATE int sqlite3GetToken(const unsigned char*,int*); /* In the SQLite core */
215709
+SQLITE_PRIVATE sqlite3_int64 sqlite3GetToken(const unsigned char*,int*); /* In SQLite core */
215371215710
215372215711
/* #include <stddef.h> */
215373215712
215374215713
/*
215375215714
** If building separately, we will need some setup that is normally
@@ -229904,11 +230243,12 @@
229904230243
if( (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK && pData ){
229905230244
unsigned char *aPage = sqlite3PagerGetData(pDbPage);
229906230245
memcpy(aPage, pData, szPage);
229907230246
pTab->pgnoTrunc = 0;
229908230247
}
229909
- }else{
230248
+ }
230249
+ if( rc!=SQLITE_OK ){
229910230250
pTab->pgnoTrunc = 0;
229911230251
}
229912230252
sqlite3PagerUnref(pDbPage);
229913230253
return rc;
229914230254
@@ -259926,11 +260266,11 @@
259926260266
int nArg, /* Number of args */
259927260267
sqlite3_value **apUnused /* Function arguments */
259928260268
){
259929260269
assert( nArg==0 );
259930260270
UNUSED_PARAM2(nArg, apUnused);
259931
- sqlite3_result_text(pCtx, "fts5: 2025-10-15 10:52:45 5cbccab499bc3983aac1f57355552db607dee6c7ef4eb00d794dbee89c18db70", -1, SQLITE_TRANSIENT);
260271
+ sqlite3_result_text(pCtx, "fts5: 2025-10-28 13:24:50 724f2299f206cc9e7f830f984c50a8fc4ac1c17210d71d9affe657b45252b060", -1, SQLITE_TRANSIENT);
259932260272
}
259933260273
259934260274
/*
259935260275
** Implementation of fts5_locale(LOCALE, TEXT) function.
259936260276
**
259937260277
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -16,11 +16,11 @@
16 ** if you want a wrapper to interface SQLite with your choice of programming
17 ** language. The code for the "sqlite3" command-line shell is also in a
18 ** separate file. This file contains only code for the core SQLite library.
19 **
20 ** The content in this amalgamation comes from Fossil check-in
21 ** 5cbccab499bc3983aac1f57355552db607de with changes in files:
22 **
23 **
24 */
25 #ifndef SQLITE_AMALGAMATION
26 #define SQLITE_CORE 1
@@ -467,14 +467,14 @@
467 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
468 ** [sqlite_version()] and [sqlite_source_id()].
469 */
470 #define SQLITE_VERSION "3.51.0"
471 #define SQLITE_VERSION_NUMBER 3051000
472 #define SQLITE_SOURCE_ID "2025-10-15 10:52:45 5cbccab499bc3983aac1f57355552db607dee6c7ef4eb00d794dbee89c18db70"
473 #define SQLITE_SCM_BRANCH "trunk"
474 #define SQLITE_SCM_TAGS ""
475 #define SQLITE_SCM_DATETIME "2025-10-15T10:52:45.276Z"
476
477 /*
478 ** CAPI3REF: Run-Time Library Version Numbers
479 ** KEYWORDS: sqlite3_version sqlite3_sourceid
480 **
@@ -1251,11 +1251,11 @@
1251 ** to the [sqlite3_file] object associated with the journal file (either
1252 ** the [rollback journal] or the [write-ahead log]) for a particular database
1253 ** connection. See also [SQLITE_FCNTL_FILE_POINTER].
1254 **
1255 ** <li>[[SQLITE_FCNTL_SYNC_OMITTED]]
1256 ** No longer in use.
1257 **
1258 ** <li>[[SQLITE_FCNTL_SYNC]]
1259 ** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and
1260 ** sent to the VFS immediately before the xSync method is invoked on a
1261 ** database file descriptor. Or, if the xSync method is not invoked
@@ -1548,10 +1548,19 @@
1548 ** <li>[[SQLITE_FCNTL_RESET_CACHE]]
1549 ** If there is currently no transaction open on the database, and the
1550 ** database is not a temp db, then the [SQLITE_FCNTL_RESET_CACHE] file-control
1551 ** purges the contents of the in-memory page cache. If there is an open
1552 ** transaction, or if the db is a temp-db, this opcode is a no-op, not an error.
 
 
 
 
 
 
 
 
 
1553 ** </ul>
1554 */
1555 #define SQLITE_FCNTL_LOCKSTATE 1
1556 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2
1557 #define SQLITE_FCNTL_SET_LOCKPROXYFILE 3
@@ -1593,10 +1602,11 @@
1593 #define SQLITE_FCNTL_EXTERNAL_READER 40
1594 #define SQLITE_FCNTL_CKSM_FILE 41
1595 #define SQLITE_FCNTL_RESET_CACHE 42
1596 #define SQLITE_FCNTL_NULL_IO 43
1597 #define SQLITE_FCNTL_BLOCK_ON_CONNECT 44
 
1598
1599 /* deprecated names */
1600 #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
1601 #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
1602 #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -5226,13 +5236,15 @@
5226 ** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in
5227 ** [prepared statement] S to have an SQL value of NULL, but to also be
5228 ** associated with the pointer P of type T. ^D is either a NULL pointer or
5229 ** a pointer to a destructor function for P. ^SQLite will invoke the
5230 ** destructor D with a single argument of P when it is finished using
5231 ** P. The T parameter should be a static string, preferably a string
5232 ** literal. The sqlite3_bind_pointer() routine is part of the
5233 ** [pointer passing interface] added for SQLite 3.20.0.
 
 
5234 **
5235 ** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer
5236 ** for the [prepared statement] or with a prepared statement for which
5237 ** [sqlite3_step()] has been called more recently than [sqlite3_reset()],
5238 ** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_()
@@ -11472,23 +11484,25 @@
11472 ** array to be bound, and N is the number of eements in the array. The
11473 ** F argument is one of constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64],
11474 ** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], or [SQLITE_CARRAY_BLOB] to
11475 ** indicate the datatype of the array being bound. The X argument is not a
11476 ** NULL pointer, then SQLite will invoke the function X on the P parameter
11477 ** after it has finished using P.
 
 
11478 */
11479 SQLITE_API SQLITE_API int sqlite3_carray_bind(
11480 sqlite3_stmt *pStmt, /* Statement to be bound */
11481 int i, /* Parameter index */
11482 void *aData, /* Pointer to array data */
11483 int nData, /* Number of data elements */
11484 int mFlags, /* CARRAY flags */
11485 void (*xDel)(void*) /* Destructor for aData */
11486 );
11487
11488 /*
11489 ** CAPI3REF: Datatypes for the CARRAY table-valued funtion
11490 **
11491 ** The fifth argument to the [sqlite3_carray_bind()] interface musts be
11492 ** one of the following constants, to specify the datatype of the array
11493 ** that is being bound into the [carray table-valued function].
11494 */
@@ -22014,11 +22028,11 @@
22014 SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3*, int, Pgno, Pgno);
22015 SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*);
22016 SQLITE_PRIVATE void sqlite3AlterFunctions(void);
22017 SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
22018 SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
22019 SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
22020 SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
22021 SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int);
22022 SQLITE_PRIVATE void sqlite3CodeRhsOfIN(Parse*, Expr*, int);
22023 SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr*);
22024 SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
@@ -39781,10 +39795,123 @@
39781 #endif
39782
39783 }; /* End of the overrideable system calls */
39784
39785
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39786 /*
39787 ** On some systems, calls to fchown() will trigger a message in a security
39788 ** log if they come from non-root processes. So avoid calling fchown() if
39789 ** we are not running as root.
39790 */
@@ -40904,10 +41031,13 @@
40904 rc = osSetPosixAdvisoryLock(pFile->h, pLock, pFile);
40905 }
40906 return rc;
40907 }
40908
 
 
 
40909 /*
40910 ** Lock the file with the lock specified by parameter eFileLock - one
40911 ** of the following:
40912 **
40913 ** (1) SHARED_LOCK
@@ -41092,11 +41222,13 @@
41092 }else{
41093 pFile->eFileLock = SHARED_LOCK;
41094 pInode->nLock++;
41095 pInode->nShared = 1;
41096 }
41097 }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){
 
 
41098 /* We are trying for an exclusive lock but another thread in this
41099 ** same process is still holding a shared lock. */
41100 rc = SQLITE_BUSY;
41101 }else{
41102 /* The request was for a RESERVED or EXCLUSIVE lock. It is
@@ -43187,10 +43319,14 @@
43187 /* Forward declaration */
43188 static int unixGetTempname(int nBuf, char *zBuf);
43189 #if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL)
43190 static int unixFcntlExternalReader(unixFile*, int*);
43191 #endif
 
 
 
 
43192
43193 /*
43194 ** Information and control of an open file handle.
43195 */
43196 static int unixFileControl(sqlite3_file *id, int op, void *pArg){
@@ -43329,10 +43465,70 @@
43329 #else
43330 *(int*)pArg = 0;
43331 return SQLITE_OK;
43332 #endif
43333 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43334 }
43335 return SQLITE_NOTFOUND;
43336 }
43337
43338 /*
@@ -43595,10 +43791,30 @@
43595 ** Constants used for locking
43596 */
43597 #define UNIX_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */
43598 #define UNIX_SHM_DMS (UNIX_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */
43599
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43600 /*
43601 ** Use F_GETLK to check whether or not there are any readers with open
43602 ** wal-mode transactions in other processes on database file pFile. If
43603 ** no error occurs, return SQLITE_OK and set (*piOut) to 1 if there are
43604 ** such transactions, or 0 otherwise. If an error occurs, return an
@@ -43628,10 +43844,53 @@
43628 }
43629
43630 return rc;
43631 }
43632
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43633
43634 /*
43635 ** Apply posix advisory locks for all bytes from ofst through ofst+n-1.
43636 **
43637 ** Locks block if the mask is exactly UNIX_SHM_C and are non-blocking
@@ -43673,11 +43932,12 @@
43673 /* Shared locks never span more than one byte */
43674 assert( n==1 || lockType!=F_RDLCK );
43675
43676 /* Locks are within range */
43677 assert( n>=1 && n<=SQLITE_SHM_NLOCK );
43678 assert( ofst>=UNIX_SHM_BASE && ofst<=(UNIX_SHM_DMS+SQLITE_SHM_NLOCK) );
 
43679
43680 if( pShmNode->hShm>=0 ){
43681 int res;
43682 /* Initialize the locking parameters */
43683 f.l_type = lockType;
@@ -51478,10 +51738,32 @@
51478 int iNew = *(int*)pArg;
51479 pFile->bBlockOnConnect = iNew;
51480 return SQLITE_OK;
51481 }
51482 #endif /* SQLITE_ENABLE_SETLK_TIMEOUT */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51483
51484 }
51485 OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
51486 return SQLITE_NOTFOUND;
51487 }
@@ -67063,11 +67345,11 @@
67063 } aSegment[FLEXARRAY]; /* One for every 32KB page in the wal-index */
67064 };
67065
67066 /* Size (in bytes) of a WalIterator object suitable for N or fewer segments */
67067 #define SZ_WALITERATOR(N) \
67068 (offsetof(WalIterator,aSegment)*(N)*sizeof(struct WalSegment))
67069
67070 /*
67071 ** Define the parameters of the hash tables in the wal-index file. There
67072 ** is a hash-table following every HASHTABLE_NPAGE page numbers in the
67073 ** wal-index.
@@ -94735,14 +95017,14 @@
94735 ** zSql is a zero-terminated string of UTF-8 SQL text. Return the number of
94736 ** bytes in this text up to but excluding the first character in
94737 ** a host parameter. If the text contains no host parameters, return
94738 ** the total number of bytes in the text.
94739 */
94740 static int findNextHostParameter(const char *zSql, int *pnToken){
94741 int tokenType;
94742 int nTotal = 0;
94743 int n;
94744
94745 *pnToken = 0;
94746 while( zSql[0] ){
94747 n = sqlite3GetToken((u8*)zSql, &tokenType);
94748 assert( n>0 && tokenType!=TK_ILLEGAL );
@@ -94785,12 +95067,12 @@
94785 const char *zRawSql /* Raw text of the SQL statement */
94786 ){
94787 sqlite3 *db; /* The database connection */
94788 int idx = 0; /* Index of a host parameter */
94789 int nextIndex = 1; /* Index of next ? host parameter */
94790 int n; /* Length of a token prefix */
94791 int nToken; /* Length of the parameter token */
94792 int i; /* Loop counter */
94793 Mem *pVar; /* Value of a host parameter */
94794 StrAccum out; /* Accumulate the output here */
94795 #ifndef SQLITE_OMIT_UTF16
94796 Mem utf8; /* Used to convert UTF16 into UTF8 for display */
@@ -96816,10 +97098,13 @@
96816 nByte = pIn1->n;
96817 nByte += pIn2->n;
96818 if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
96819 goto too_big;
96820 }
 
 
 
96821 if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
96822 goto no_mem;
96823 }
96824 MemSetTypeFlag(pOut, MEM_Str);
96825 if( pOut!=pIn2 ){
@@ -131915,11 +132200,11 @@
131915 static void *contextMalloc(sqlite3_context *context, i64 nByte){
131916 char *z;
131917 sqlite3 *db = sqlite3_context_db_handle(context);
131918 assert( nByte>0 );
131919 testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH] );
131920 testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
131921 if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
131922 sqlite3_result_error_toobig(context);
131923 z = 0;
131924 }else{
131925 z = sqlite3Malloc(nByte);
@@ -134180,12 +134465,12 @@
134180 ** aggregate. Remember all input Y values until the very end.
134181 ** Those values are accumulated in the Percentile.a[] array.
134182 */
134183 typedef struct Percentile Percentile;
134184 struct Percentile {
134185 unsigned nAlloc; /* Number of slots allocated for a[] */
134186 unsigned nUsed; /* Number of slots actually used in a[] */
134187 char bSorted; /* True if a[] is already in sorted order */
134188 char bKeepSorted; /* True if advantageous to keep a[] sorted */
134189 char bPctValid; /* True if rPct is valid */
134190 double rPct; /* Fraction. 0.0 to 1.0 */
134191 double *a; /* Array of Y values */
@@ -134218,15 +134503,15 @@
134218 ** If bExact is false, return the index at which a new entry with
134219 ** value y should be insert in order to keep the values in sorted
134220 ** order. The smallest return value in this case will be 0, and
134221 ** the largest return value will be p->nUsed.
134222 */
134223 static int percentBinarySearch(Percentile *p, double y, int bExact){
134224 int iFirst = 0; /* First element of search range */
134225 int iLast = p->nUsed - 1; /* Last element of search range */
134226 while( iLast>=iFirst ){
134227 int iMid = (iFirst+iLast)/2;
134228 double x = p->a[iMid];
134229 if( x<y ){
134230 iFirst = iMid + 1;
134231 }else if( x>y ){
134232 iLast = iMid - 1;
@@ -134325,11 +134610,11 @@
134325 return;
134326 }
134327
134328 /* Allocate and store the Y */
134329 if( p->nUsed>=p->nAlloc ){
134330 unsigned n = p->nAlloc*2 + 250;
134331 double *a = sqlite3_realloc64(p->a, sizeof(double)*n);
134332 if( a==0 ){
134333 sqlite3_free(p->a);
134334 memset(p, 0, sizeof(*p));
134335 sqlite3_result_error_nomem(pCtx);
@@ -134342,11 +134627,11 @@
134342 p->a[p->nUsed++] = y;
134343 p->bSorted = 1;
134344 }else if( !p->bSorted || y>=p->a[p->nUsed-1] ){
134345 p->a[p->nUsed++] = y;
134346 }else if( p->bKeepSorted ){
134347 int i;
134348 i = percentBinarySearch(p, y, 0);
134349 if( i<(int)p->nUsed ){
134350 memmove(&p->a[i+1], &p->a[i], (p->nUsed-i)*sizeof(p->a[0]));
134351 }
134352 p->a[i] = y;
@@ -134427,11 +134712,11 @@
134427 */
134428 static void percentInverse(sqlite3_context *pCtx,int argc,sqlite3_value **argv){
134429 Percentile *p;
134430 int eType;
134431 double y;
134432 int i;
134433 assert( argc==2 || argc==1 );
134434
134435 /* Allocate the session context. */
134436 p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p));
134437 assert( p!=0 );
@@ -134513,10 +134798,60 @@
134513 percentCompute(pCtx, 0);
134514 }
134515 /****** End of percentile family of functions ******/
134516 #endif /* SQLITE_ENABLE_PERCENTILE */
134517
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134518
134519 #ifdef SQLITE_DEBUG
134520 /*
134521 ** Implementation of fpdecode(x,y,z) function.
134522 **
@@ -134672,10 +135007,13 @@
134672 INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
134673 INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
134674 #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
134675 INLINE_FUNC(sqlite_offset, 1, INLINEFUNC_sqlite_offset, 0 ),
134676 #endif
 
 
 
134677 FUNCTION(ltrim, 1, 1, 0, trimFunc ),
134678 FUNCTION(ltrim, 2, 1, 0, trimFunc ),
134679 FUNCTION(rtrim, 1, 2, 0, trimFunc ),
134680 FUNCTION(rtrim, 2, 2, 0, trimFunc ),
134681 FUNCTION(trim, 1, 3, 0, trimFunc ),
@@ -183458,12 +183796,13 @@
183458
183459 /*
183460 ** Return the length (in bytes) of the token that begins at z[0].
183461 ** Store the token type in *tokenType before returning.
183462 */
183463 SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
183464 int i, c;
 
183465 switch( aiClass[*z] ){ /* Switch on the character-class of the first byte
183466 ** of the token. See the comment on the CC_ defines
183467 ** above. */
183468 case CC_SPACE: {
183469 testcase( z[0]==' ' );
@@ -183787,11 +184126,11 @@
183787 ** Run the parser on the given SQL string.
183788 */
183789 SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){
183790 int nErr = 0; /* Number of errors encountered */
183791 void *pEngine; /* The LEMON-generated LALR(1) parser */
183792 int n = 0; /* Length of the next token token */
183793 int tokenType; /* type of the next token */
183794 int lastTokenParsed = -1; /* type of the previous token */
183795 sqlite3 *db = pParse->db; /* The database connection */
183796 int mxSqlLen; /* Max length of an SQL string */
183797 Parse *pParentParse = 0; /* Outer parse context, if any */
@@ -183890,17 +184229,17 @@
183890 zSql += n;
183891 continue;
183892 }else if( tokenType!=TK_QNUMBER ){
183893 Token x;
183894 x.z = zSql;
183895 x.n = n;
183896 sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", &x);
183897 break;
183898 }
183899 }
183900 pParse->sLastToken.z = zSql;
183901 pParse->sLastToken.n = n;
183902 sqlite3Parser(pEngine, tokenType, pParse->sLastToken);
183903 lastTokenParsed = tokenType;
183904 zSql += n;
183905 assert( db->mallocFailed==0 || pParse->rc!=SQLITE_OK || startedWithOom );
183906 if( pParse->rc!=SQLITE_OK ) break;
@@ -183972,11 +184311,11 @@
183972 Vdbe *pVdbe, /* VM being reprepared */
183973 const char *zSql /* The original SQL string */
183974 ){
183975 sqlite3 *db; /* The database connection */
183976 int i; /* Next unread byte of zSql[] */
183977 int n; /* length of current token */
183978 int tokenType; /* type of current token */
183979 int prevType = 0; /* Previous non-whitespace token */
183980 int nParen; /* Number of nested levels of parentheses */
183981 int iStartIN; /* Start of RHS of IN operator in z[] */
183982 int nParenAtIN; /* Value of nParent at start of RHS of IN operator */
@@ -215365,11 +215704,11 @@
215365 /* #include "sqlite3ext.h" */
215366 SQLITE_EXTENSION_INIT1
215367 #else
215368 /* #include "sqlite3.h" */
215369 #endif
215370 SQLITE_PRIVATE int sqlite3GetToken(const unsigned char*,int*); /* In the SQLite core */
215371
215372 /* #include <stddef.h> */
215373
215374 /*
215375 ** If building separately, we will need some setup that is normally
@@ -229904,11 +230243,12 @@
229904 if( (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK && pData ){
229905 unsigned char *aPage = sqlite3PagerGetData(pDbPage);
229906 memcpy(aPage, pData, szPage);
229907 pTab->pgnoTrunc = 0;
229908 }
229909 }else{
 
229910 pTab->pgnoTrunc = 0;
229911 }
229912 sqlite3PagerUnref(pDbPage);
229913 return rc;
229914
@@ -259926,11 +260266,11 @@
259926 int nArg, /* Number of args */
259927 sqlite3_value **apUnused /* Function arguments */
259928 ){
259929 assert( nArg==0 );
259930 UNUSED_PARAM2(nArg, apUnused);
259931 sqlite3_result_text(pCtx, "fts5: 2025-10-15 10:52:45 5cbccab499bc3983aac1f57355552db607dee6c7ef4eb00d794dbee89c18db70", -1, SQLITE_TRANSIENT);
259932 }
259933
259934 /*
259935 ** Implementation of fts5_locale(LOCALE, TEXT) function.
259936 **
259937
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -16,11 +16,11 @@
16 ** if you want a wrapper to interface SQLite with your choice of programming
17 ** language. The code for the "sqlite3" command-line shell is also in a
18 ** separate file. This file contains only code for the core SQLite library.
19 **
20 ** The content in this amalgamation comes from Fossil check-in
21 ** 724f2299f206cc9e7f830f984c50a8fc4ac1 with changes in files:
22 **
23 **
24 */
25 #ifndef SQLITE_AMALGAMATION
26 #define SQLITE_CORE 1
@@ -467,14 +467,14 @@
467 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
468 ** [sqlite_version()] and [sqlite_source_id()].
469 */
470 #define SQLITE_VERSION "3.51.0"
471 #define SQLITE_VERSION_NUMBER 3051000
472 #define SQLITE_SOURCE_ID "2025-10-28 13:24:50 724f2299f206cc9e7f830f984c50a8fc4ac1c17210d71d9affe657b45252b060"
473 #define SQLITE_SCM_BRANCH "trunk"
474 #define SQLITE_SCM_TAGS ""
475 #define SQLITE_SCM_DATETIME "2025-10-28T13:24:50.858Z"
476
477 /*
478 ** CAPI3REF: Run-Time Library Version Numbers
479 ** KEYWORDS: sqlite3_version sqlite3_sourceid
480 **
@@ -1251,11 +1251,11 @@
1251 ** to the [sqlite3_file] object associated with the journal file (either
1252 ** the [rollback journal] or the [write-ahead log]) for a particular database
1253 ** connection. See also [SQLITE_FCNTL_FILE_POINTER].
1254 **
1255 ** <li>[[SQLITE_FCNTL_SYNC_OMITTED]]
1256 ** The SQLITE_FCNTL_SYNC_OMITTED file-control is no longer used.
1257 **
1258 ** <li>[[SQLITE_FCNTL_SYNC]]
1259 ** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and
1260 ** sent to the VFS immediately before the xSync method is invoked on a
1261 ** database file descriptor. Or, if the xSync method is not invoked
@@ -1548,10 +1548,19 @@
1548 ** <li>[[SQLITE_FCNTL_RESET_CACHE]]
1549 ** If there is currently no transaction open on the database, and the
1550 ** database is not a temp db, then the [SQLITE_FCNTL_RESET_CACHE] file-control
1551 ** purges the contents of the in-memory page cache. If there is an open
1552 ** transaction, or if the db is a temp-db, this opcode is a no-op, not an error.
1553 **
1554 ** <li>[[SQLITE_FCNTL_FILESTAT]]
1555 ** The [SQLITE_FCNTL_FILESTAT] opcode returns low-level diagnostic information
1556 ** about the [sqlite3_file] objects used access the database and journal files
1557 ** for the given schema. The fourth parameter to [sqlite3_file_control()]
1558 ** should be an initialized [sqlite3_str] pointer. JSON text describing
1559 ** various aspects of the sqlite3_file object is appended to the sqlite3_str.
1560 ** The SQLITE_FCNTL_FILESTAT opcode is usually a no-op, unless compile-time
1561 ** options are used to enable it.
1562 ** </ul>
1563 */
1564 #define SQLITE_FCNTL_LOCKSTATE 1
1565 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2
1566 #define SQLITE_FCNTL_SET_LOCKPROXYFILE 3
@@ -1593,10 +1602,11 @@
1602 #define SQLITE_FCNTL_EXTERNAL_READER 40
1603 #define SQLITE_FCNTL_CKSM_FILE 41
1604 #define SQLITE_FCNTL_RESET_CACHE 42
1605 #define SQLITE_FCNTL_NULL_IO 43
1606 #define SQLITE_FCNTL_BLOCK_ON_CONNECT 44
1607 #define SQLITE_FCNTL_FILESTAT 45
1608
1609 /* deprecated names */
1610 #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
1611 #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
1612 #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -5226,13 +5236,15 @@
5236 ** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in
5237 ** [prepared statement] S to have an SQL value of NULL, but to also be
5238 ** associated with the pointer P of type T. ^D is either a NULL pointer or
5239 ** a pointer to a destructor function for P. ^SQLite will invoke the
5240 ** destructor D with a single argument of P when it is finished using
5241 ** P, even if the call to sqlite3_bind_pointer() fails. Due to a
5242 ** historical design quirk, results are undefined if D is
5243 ** SQLITE_TRANSIENT. The T parameter should be a static string,
5244 ** preferably a string literal. The sqlite3_bind_pointer() routine is
5245 ** part of the [pointer passing interface] added for SQLite 3.20.0.
5246 **
5247 ** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer
5248 ** for the [prepared statement] or with a prepared statement for which
5249 ** [sqlite3_step()] has been called more recently than [sqlite3_reset()],
5250 ** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_()
@@ -11472,23 +11484,25 @@
11484 ** array to be bound, and N is the number of eements in the array. The
11485 ** F argument is one of constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64],
11486 ** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], or [SQLITE_CARRAY_BLOB] to
11487 ** indicate the datatype of the array being bound. The X argument is not a
11488 ** NULL pointer, then SQLite will invoke the function X on the P parameter
11489 ** after it has finished using P, even if the call to
11490 ** sqlite3_carray_bind() fails. The special-case finalizer
11491 ** SQLITE_TRANSIENT has no effect here.
11492 */
11493 SQLITE_API int sqlite3_carray_bind(
11494 sqlite3_stmt *pStmt, /* Statement to be bound */
11495 int i, /* Parameter index */
11496 void *aData, /* Pointer to array data */
11497 int nData, /* Number of data elements */
11498 int mFlags, /* CARRAY flags */
11499 void (*xDel)(void*) /* Destructor for aData */
11500 );
11501
11502 /*
11503 ** CAPI3REF: Datatypes for the CARRAY table-valued function
11504 **
11505 ** The fifth argument to the [sqlite3_carray_bind()] interface musts be
11506 ** one of the following constants, to specify the datatype of the array
11507 ** that is being bound into the [carray table-valued function].
11508 */
@@ -22014,11 +22028,11 @@
22028 SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3*, int, Pgno, Pgno);
22029 SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*);
22030 SQLITE_PRIVATE void sqlite3AlterFunctions(void);
22031 SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
22032 SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
22033 SQLITE_PRIVATE i64 sqlite3GetToken(const unsigned char *, int *);
22034 SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
22035 SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int);
22036 SQLITE_PRIVATE void sqlite3CodeRhsOfIN(Parse*, Expr*, int);
22037 SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr*);
22038 SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
@@ -39781,10 +39795,123 @@
39795 #endif
39796
39797 }; /* End of the overrideable system calls */
39798
39799
39800 #if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
39801 /*
39802 ** Extract Posix Advisory Locking information about file description fd
39803 ** from the /proc/PID/fdinfo/FD pseudo-file. Fill the string buffer a[16]
39804 ** with characters to indicate which SQLite-relevant locks are held.
39805 ** a[16] will be a 15-character zero-terminated string with the following
39806 ** schema:
39807 **
39808 ** AAA/B.DDD.DDDDD
39809 **
39810 ** Each of character A-D will be "w" or "r" or "-" to indicate either a
39811 ** write-lock, a read-lock, or no-lock, respectively. The "." and "/"
39812 ** characters are delimiters intended to make the string more easily
39813 ** readable by humans. Here are the meaning of the specific letters:
39814 **
39815 ** AAA -> The main database locks. PENDING_BYTE, RESERVED_BYTE,
39816 ** and SHARED_FIRST, respectively.
39817 **
39818 ** B -> The deadman switch lock. Offset 128 of the -shm file.
39819 **
39820 ** CCC -> WAL locks: WRITE, CKPT, RECOVER
39821 **
39822 ** DDDDD -> WAL read-locks 0 through 5
39823 **
39824 ** Note that elements before the "/" apply to the main database file and
39825 ** elements after the "/" apply to the -shm file in WAL mode.
39826 **
39827 ** Here is another way of thinking about the meaning of the result string:
39828 **
39829 ** AAA/B.CCC.DDDDD
39830 ** ||| | ||| \___/
39831 ** PENDING--'|| | ||| `----- READ 0-5
39832 ** RESERVED--'| | ||`---- RECOVER
39833 ** SHARED ----' | |`----- CKPT
39834 ** DMS ------' `------ WRITE
39835 **
39836 ** Return SQLITE_OK on success and SQLITE_ERROR_UNABLE if the /proc
39837 ** pseudo-filesystem is unavailable.
39838 */
39839 static int unixPosixAdvisoryLocks(
39840 int fd, /* The file descriptor to analyze */
39841 char a[16] /* Write a text description of PALs here */
39842 ){
39843 int in;
39844 ssize_t n;
39845 char *p, *pNext, *x;
39846 char z[2000];
39847
39848 /* 1 */
39849 /* 012 4 678 01234 */
39850 memcpy(a, "---/-.---.-----", 16);
39851 sqlite3_snprintf(sizeof(z), z, "/proc/%d/fdinfo/%d", getpid(), fd);
39852 in = osOpen(z, O_RDONLY, 0);
39853 if( in<0 ){
39854 return SQLITE_ERROR_UNABLE;
39855 }
39856 n = osRead(in, z, sizeof(z)-1);
39857 osClose(in);
39858 if( n<=0 ) return SQLITE_ERROR_UNABLE;
39859 z[n] = 0;
39860
39861 /* We are looking for lines that begin with "lock:\t". Examples:
39862 **
39863 ** lock: 1: POSIX ADVISORY READ 494716 08:02:5277597 1073741826 1073742335
39864 ** lock: 1: POSIX ADVISORY WRITE 494716 08:02:5282282 120 120
39865 ** lock: 2: POSIX ADVISORY READ 494716 08:02:5282282 123 123
39866 ** lock: 3: POSIX ADVISORY READ 494716 08:02:5282282 128 128
39867 */
39868 pNext = strstr(z, "lock:\t");
39869 while( pNext ){
39870 char cType = 0;
39871 sqlite3_int64 iFirst, iLast;
39872 p = pNext+6;
39873 pNext = strstr(p, "lock:\t");
39874 if( pNext ) pNext[-1] = 0;
39875 if( (x = strstr(p, " READ "))!=0 ){
39876 cType = 'r';
39877 x += 6;
39878 }else if( (x = strstr(p, " WRITE "))!=0 ){
39879 cType = 'w';
39880 x += 7;
39881 }else{
39882 continue;
39883 }
39884 x = strrchr(x, ' ');
39885 if( x==0 ) continue;
39886 iLast = strtoll(x+1, 0, 10);
39887 *x = 0;
39888 x = strrchr(p, ' ');
39889 if( x==0 ) continue;
39890 iFirst = strtoll(x+1, 0, 10);
39891 if( iLast>=PENDING_BYTE ){
39892 if( iFirst<=PENDING_BYTE && iLast>=PENDING_BYTE ) a[0] = cType;
39893 if( iFirst<=PENDING_BYTE+1 && iLast>=PENDING_BYTE+1 ) a[1] = cType;
39894 if( iFirst<=PENDING_BYTE+2 && iLast>=PENDING_BYTE+510 ) a[2] = cType;
39895 }else if( iLast<=128 ){
39896 if( iFirst<=128 && iLast>=128 ) a[4] = cType;
39897 if( iFirst<=120 && iLast>=120 ) a[6] = cType;
39898 if( iFirst<=121 && iLast>=121 ) a[7] = cType;
39899 if( iFirst<=122 && iLast>=122 ) a[8] = cType;
39900 if( iFirst<=123 && iLast>=123 ) a[10] = cType;
39901 if( iFirst<=124 && iLast>=124 ) a[11] = cType;
39902 if( iFirst<=125 && iLast>=125 ) a[12] = cType;
39903 if( iFirst<=126 && iLast>=126 ) a[13] = cType;
39904 if( iFirst<=127 && iLast>=127 ) a[14] = cType;
39905 }
39906 }
39907 return SQLITE_OK;
39908 }
39909 #else
39910 # define unixPosixAdvisoryLocks(A,B) SQLITE_ERROR_UNABLE
39911 #endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */
39912
39913 /*
39914 ** On some systems, calls to fchown() will trigger a message in a security
39915 ** log if they come from non-root processes. So avoid calling fchown() if
39916 ** we are not running as root.
39917 */
@@ -40904,10 +41031,13 @@
41031 rc = osSetPosixAdvisoryLock(pFile->h, pLock, pFile);
41032 }
41033 return rc;
41034 }
41035
41036 /* Forward reference */
41037 static int unixIsSharingShmNode(unixFile*);
41038
41039 /*
41040 ** Lock the file with the lock specified by parameter eFileLock - one
41041 ** of the following:
41042 **
41043 ** (1) SHARED_LOCK
@@ -41092,11 +41222,13 @@
41222 }else{
41223 pFile->eFileLock = SHARED_LOCK;
41224 pInode->nLock++;
41225 pInode->nShared = 1;
41226 }
41227 }else if( (eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1)
41228 || unixIsSharingShmNode(pFile)
41229 ){
41230 /* We are trying for an exclusive lock but another thread in this
41231 ** same process is still holding a shared lock. */
41232 rc = SQLITE_BUSY;
41233 }else{
41234 /* The request was for a RESERVED or EXCLUSIVE lock. It is
@@ -43187,10 +43319,14 @@
43319 /* Forward declaration */
43320 static int unixGetTempname(int nBuf, char *zBuf);
43321 #if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL)
43322 static int unixFcntlExternalReader(unixFile*, int*);
43323 #endif
43324 #if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
43325 static void unixDescribeShm(sqlite3_str*,unixShm*);
43326 #endif
43327
43328
43329 /*
43330 ** Information and control of an open file handle.
43331 */
43332 static int unixFileControl(sqlite3_file *id, int op, void *pArg){
@@ -43329,10 +43465,70 @@
43465 #else
43466 *(int*)pArg = 0;
43467 return SQLITE_OK;
43468 #endif
43469 }
43470
43471 #if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
43472 case SQLITE_FCNTL_FILESTAT: {
43473 sqlite3_str *pStr = (sqlite3_str*)pArg;
43474 char aLck[16];
43475 unixInodeInfo *pInode;
43476 static const char *azLock[] = { "SHARED", "RESERVED",
43477 "PENDING", "EXCLUSIVE" };
43478 sqlite3_str_appendf(pStr, "{\"h\":%d", pFile->h);
43479 sqlite3_str_appendf(pStr, ",\"vfs\":\"%s\"", pFile->pVfs->zName);
43480 if( pFile->eFileLock ){
43481 sqlite3_str_appendf(pStr, ",\"eFileLock\":\"%s\"",
43482 azLock[pFile->eFileLock-1]);
43483 if( unixPosixAdvisoryLocks(pFile->h, aLck)==SQLITE_OK ){
43484 sqlite3_str_appendf(pStr, ",\"pal\":\"%s\"", aLck);
43485 }
43486 }
43487 unixEnterMutex();
43488 if( pFile->pShm ){
43489 sqlite3_str_appendall(pStr, ",\"shm\":");
43490 unixDescribeShm(pStr, pFile->pShm);
43491 }
43492 #if SQLITE_MAX_MMAP_SIZE>0
43493 if( pFile->mmapSize ){
43494 sqlite3_str_appendf(pStr, ",\"mmapSize\":%lld", pFile->mmapSize);
43495 sqlite3_str_appendf(pStr, ",\"nFetchOut\":%d", pFile->nFetchOut);
43496 }
43497 #endif
43498 if( (pInode = pFile->pInode)!=0 ){
43499 sqlite3_str_appendf(pStr, ",\"inode\":{\"nRef\":%d",pInode->nRef);
43500 sqlite3_mutex_enter(pInode->pLockMutex);
43501 sqlite3_str_appendf(pStr, ",\"nShared\":%d", pInode->nShared);
43502 if( pInode->eFileLock ){
43503 sqlite3_str_appendf(pStr, ",\"eFileLock\":\"%s\"",
43504 azLock[pInode->eFileLock-1]);
43505 }
43506 if( pInode->pUnused ){
43507 char cSep = '[';
43508 UnixUnusedFd *pUFd = pFile->pInode->pUnused;
43509 sqlite3_str_appendall(pStr, ",\"unusedFd\":");
43510 while( pUFd ){
43511 sqlite3_str_appendf(pStr, "%c{\"fd\":%d,\"flags\":%d",
43512 cSep, pUFd->fd, pUFd->flags);
43513 cSep = ',';
43514 if( unixPosixAdvisoryLocks(pUFd->fd, aLck)==SQLITE_OK ){
43515 sqlite3_str_appendf(pStr, ",\"pal\":\"%s\"", aLck);
43516 }
43517 sqlite3_str_append(pStr, "}", 1);
43518 pUFd = pUFd->pNext;
43519 }
43520 sqlite3_str_append(pStr, "]", 1);
43521 }
43522 sqlite3_mutex_leave(pInode->pLockMutex);
43523 sqlite3_str_append(pStr, "}", 1);
43524 }
43525 unixLeaveMutex();
43526 sqlite3_str_append(pStr, "}", 1);
43527 return SQLITE_OK;
43528 }
43529 #endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */
43530 }
43531 return SQLITE_NOTFOUND;
43532 }
43533
43534 /*
@@ -43595,10 +43791,30 @@
43791 ** Constants used for locking
43792 */
43793 #define UNIX_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */
43794 #define UNIX_SHM_DMS (UNIX_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */
43795
43796 #if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
43797 /*
43798 ** Describe the pShm object using JSON. Used for diagnostics only.
43799 */
43800 static void unixDescribeShm(sqlite3_str *pStr, unixShm *pShm){
43801 unixShmNode *pNode = pShm->pShmNode;
43802 char aLck[16];
43803 sqlite3_str_appendf(pStr, "{\"h\":%d", pNode->hShm);
43804 assert( unixMutexHeld() );
43805 sqlite3_str_appendf(pStr, ",\"nRef\":%d", pNode->nRef);
43806 sqlite3_str_appendf(pStr, ",\"id\":%d", pShm->id);
43807 sqlite3_str_appendf(pStr, ",\"sharedMask\":%d", pShm->sharedMask);
43808 sqlite3_str_appendf(pStr, ",\"exclMask\":%d", pShm->exclMask);
43809 if( unixPosixAdvisoryLocks(pNode->hShm, aLck)==SQLITE_OK ){
43810 sqlite3_str_appendf(pStr, ",\"pal\":\"%s\"", aLck);
43811 }
43812 sqlite3_str_append(pStr, "}", 1);
43813 }
43814 #endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */
43815
43816 /*
43817 ** Use F_GETLK to check whether or not there are any readers with open
43818 ** wal-mode transactions in other processes on database file pFile. If
43819 ** no error occurs, return SQLITE_OK and set (*piOut) to 1 if there are
43820 ** such transactions, or 0 otherwise. If an error occurs, return an
@@ -43628,10 +43844,53 @@
43844 }
43845
43846 return rc;
43847 }
43848
43849 /*
43850 ** If pFile has a -shm file open and it is sharing that file with some
43851 ** other connection, either in the same process or in a separate process,
43852 ** then return true. Return false if either pFile does not have a -shm
43853 ** file open or if it is the only connection to that -shm file across the
43854 ** entire system.
43855 **
43856 ** This routine is not required for correct operation. It can always return
43857 ** false and SQLite will continue to operate according to spec. However,
43858 ** when this routine does its job, it adds extra robustness in cases
43859 ** where database file locks have been erroneously deleted in a WAL-mode
43860 ** database by doing close(open(DATABASE_PATHNAME)) or similar.
43861 **
43862 ** With false negatives, SQLite still operates to spec, though with less
43863 ** robustness. With false positives, the last database connection on a
43864 ** WAL-mode database will fail to unlink the -wal and -shm files, which
43865 ** is annoying but harmless. False positives will also prevent a database
43866 ** connection from running "PRAGMA journal_mode=DELETE" in order to take
43867 ** the database out of WAL mode, which is perhaps more serious, but is
43868 ** still not a disaster.
43869 */
43870 static int unixIsSharingShmNode(unixFile *pFile){
43871 int rc;
43872 unixShmNode *pShmNode;
43873 if( pFile->pShm==0 ) return 0;
43874 if( pFile->ctrlFlags & UNIXFILE_EXCL ) return 0;
43875 pShmNode = pFile->pShm->pShmNode;
43876 rc = 1;
43877 unixEnterMutex();
43878 if( ALWAYS(pShmNode->nRef==1) ){
43879 struct flock lock;
43880 lock.l_whence = SEEK_SET;
43881 lock.l_start = UNIX_SHM_DMS;
43882 lock.l_len = 1;
43883 lock.l_type = F_WRLCK;
43884 osFcntl(pShmNode->hShm, F_GETLK, &lock);
43885 if( lock.l_type==F_UNLCK ){
43886 rc = 0;
43887 }
43888 }
43889 unixLeaveMutex();
43890 return rc;
43891 }
43892
43893 /*
43894 ** Apply posix advisory locks for all bytes from ofst through ofst+n-1.
43895 **
43896 ** Locks block if the mask is exactly UNIX_SHM_C and are non-blocking
@@ -43673,11 +43932,12 @@
43932 /* Shared locks never span more than one byte */
43933 assert( n==1 || lockType!=F_RDLCK );
43934
43935 /* Locks are within range */
43936 assert( n>=1 && n<=SQLITE_SHM_NLOCK );
43937 assert( ofst>=UNIX_SHM_BASE && ofst<=UNIX_SHM_DMS );
43938 assert( ofst+n-1<=UNIX_SHM_DMS );
43939
43940 if( pShmNode->hShm>=0 ){
43941 int res;
43942 /* Initialize the locking parameters */
43943 f.l_type = lockType;
@@ -51478,10 +51738,32 @@
51738 int iNew = *(int*)pArg;
51739 pFile->bBlockOnConnect = iNew;
51740 return SQLITE_OK;
51741 }
51742 #endif /* SQLITE_ENABLE_SETLK_TIMEOUT */
51743
51744 #if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
51745 case SQLITE_FCNTL_FILESTAT: {
51746 sqlite3_str *pStr = (sqlite3_str*)pArg;
51747 sqlite3_str_appendf(pStr, "{\"h\":%llu", (sqlite3_uint64)pFile->h);
51748 sqlite3_str_appendf(pStr, ",\"vfs\":\"%s\"", pFile->pVfs->zName);
51749 if( pFile->locktype ){
51750 static const char *azLock[] = { "SHARED", "RESERVED",
51751 "PENDING", "EXCLUSIVE" };
51752 sqlite3_str_appendf(pStr, ",\"locktype\":\"%s\"",
51753 azLock[pFile->locktype-1]);
51754 }
51755 #if SQLITE_MAX_MMAP_SIZE>0
51756 if( pFile->mmapSize ){
51757 sqlite3_str_appendf(pStr, ",\"mmapSize\":%lld", pFile->mmapSize);
51758 sqlite3_str_appendf(pStr, ",\"nFetchOut\":%d", pFile->nFetchOut);
51759 }
51760 #endif
51761 sqlite3_str_append(pStr, "}", 1);
51762 return SQLITE_OK;
51763 }
51764 #endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */
51765
51766 }
51767 OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
51768 return SQLITE_NOTFOUND;
51769 }
@@ -67063,11 +67345,11 @@
67345 } aSegment[FLEXARRAY]; /* One for every 32KB page in the wal-index */
67346 };
67347
67348 /* Size (in bytes) of a WalIterator object suitable for N or fewer segments */
67349 #define SZ_WALITERATOR(N) \
67350 (offsetof(WalIterator,aSegment)+(N)*sizeof(struct WalSegment))
67351
67352 /*
67353 ** Define the parameters of the hash tables in the wal-index file. There
67354 ** is a hash-table following every HASHTABLE_NPAGE page numbers in the
67355 ** wal-index.
@@ -94735,14 +95017,14 @@
95017 ** zSql is a zero-terminated string of UTF-8 SQL text. Return the number of
95018 ** bytes in this text up to but excluding the first character in
95019 ** a host parameter. If the text contains no host parameters, return
95020 ** the total number of bytes in the text.
95021 */
95022 static i64 findNextHostParameter(const char *zSql, i64 *pnToken){
95023 int tokenType;
95024 i64 nTotal = 0;
95025 i64 n;
95026
95027 *pnToken = 0;
95028 while( zSql[0] ){
95029 n = sqlite3GetToken((u8*)zSql, &tokenType);
95030 assert( n>0 && tokenType!=TK_ILLEGAL );
@@ -94785,12 +95067,12 @@
95067 const char *zRawSql /* Raw text of the SQL statement */
95068 ){
95069 sqlite3 *db; /* The database connection */
95070 int idx = 0; /* Index of a host parameter */
95071 int nextIndex = 1; /* Index of next ? host parameter */
95072 i64 n; /* Length of a token prefix */
95073 i64 nToken; /* Length of the parameter token */
95074 int i; /* Loop counter */
95075 Mem *pVar; /* Value of a host parameter */
95076 StrAccum out; /* Accumulate the output here */
95077 #ifndef SQLITE_OMIT_UTF16
95078 Mem utf8; /* Used to convert UTF16 into UTF8 for display */
@@ -96816,10 +97098,13 @@
97098 nByte = pIn1->n;
97099 nByte += pIn2->n;
97100 if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
97101 goto too_big;
97102 }
97103 #if SQLITE_MAX_LENGTH>2147483645
97104 if( nByte>2147483645 ){ goto too_big; }
97105 #endif
97106 if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
97107 goto no_mem;
97108 }
97109 MemSetTypeFlag(pOut, MEM_Str);
97110 if( pOut!=pIn2 ){
@@ -131915,11 +132200,11 @@
132200 static void *contextMalloc(sqlite3_context *context, i64 nByte){
132201 char *z;
132202 sqlite3 *db = sqlite3_context_db_handle(context);
132203 assert( nByte>0 );
132204 testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH] );
132205 testcase( nByte==(i64)db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
132206 if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
132207 sqlite3_result_error_toobig(context);
132208 z = 0;
132209 }else{
132210 z = sqlite3Malloc(nByte);
@@ -134180,12 +134465,12 @@
134465 ** aggregate. Remember all input Y values until the very end.
134466 ** Those values are accumulated in the Percentile.a[] array.
134467 */
134468 typedef struct Percentile Percentile;
134469 struct Percentile {
134470 u64 nAlloc; /* Number of slots allocated for a[] */
134471 u64 nUsed; /* Number of slots actually used in a[] */
134472 char bSorted; /* True if a[] is already in sorted order */
134473 char bKeepSorted; /* True if advantageous to keep a[] sorted */
134474 char bPctValid; /* True if rPct is valid */
134475 double rPct; /* Fraction. 0.0 to 1.0 */
134476 double *a; /* Array of Y values */
@@ -134218,15 +134503,15 @@
134503 ** If bExact is false, return the index at which a new entry with
134504 ** value y should be insert in order to keep the values in sorted
134505 ** order. The smallest return value in this case will be 0, and
134506 ** the largest return value will be p->nUsed.
134507 */
134508 static i64 percentBinarySearch(Percentile *p, double y, int bExact){
134509 i64 iFirst = 0; /* First element of search range */
134510 i64 iLast = (i64)p->nUsed - 1; /* Last element of search range */
134511 while( iLast>=iFirst ){
134512 i64 iMid = (iFirst+iLast)/2;
134513 double x = p->a[iMid];
134514 if( x<y ){
134515 iFirst = iMid + 1;
134516 }else if( x>y ){
134517 iLast = iMid - 1;
@@ -134325,11 +134610,11 @@
134610 return;
134611 }
134612
134613 /* Allocate and store the Y */
134614 if( p->nUsed>=p->nAlloc ){
134615 u64 n = p->nAlloc*2 + 250;
134616 double *a = sqlite3_realloc64(p->a, sizeof(double)*n);
134617 if( a==0 ){
134618 sqlite3_free(p->a);
134619 memset(p, 0, sizeof(*p));
134620 sqlite3_result_error_nomem(pCtx);
@@ -134342,11 +134627,11 @@
134627 p->a[p->nUsed++] = y;
134628 p->bSorted = 1;
134629 }else if( !p->bSorted || y>=p->a[p->nUsed-1] ){
134630 p->a[p->nUsed++] = y;
134631 }else if( p->bKeepSorted ){
134632 i64 i;
134633 i = percentBinarySearch(p, y, 0);
134634 if( i<(int)p->nUsed ){
134635 memmove(&p->a[i+1], &p->a[i], (p->nUsed-i)*sizeof(p->a[0]));
134636 }
134637 p->a[i] = y;
@@ -134427,11 +134712,11 @@
134712 */
134713 static void percentInverse(sqlite3_context *pCtx,int argc,sqlite3_value **argv){
134714 Percentile *p;
134715 int eType;
134716 double y;
134717 i64 i;
134718 assert( argc==2 || argc==1 );
134719
134720 /* Allocate the session context. */
134721 p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p));
134722 assert( p!=0 );
@@ -134513,10 +134798,60 @@
134798 percentCompute(pCtx, 0);
134799 }
134800 /****** End of percentile family of functions ******/
134801 #endif /* SQLITE_ENABLE_PERCENTILE */
134802
134803 #if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
134804 /*
134805 ** Implementation of sqlite_filestat(SCHEMA).
134806 **
134807 ** Return JSON text that describes low-level debug/diagnostic information
134808 ** about the sqlite3_file object associated with SCHEMA.
134809 */
134810 static void filestatFunc(
134811 sqlite3_context *context,
134812 int argc,
134813 sqlite3_value **argv
134814 ){
134815 sqlite3 *db = sqlite3_context_db_handle(context);
134816 const char *zDbName;
134817 sqlite3_str *pStr;
134818 Btree *pBtree;
134819
134820 zDbName = (const char*)sqlite3_value_text(argv[0]);
134821 pBtree = sqlite3DbNameToBtree(db, zDbName);
134822 if( pBtree ){
134823 Pager *pPager;
134824 sqlite3_file *fd;
134825 int rc;
134826 sqlite3BtreeEnter(pBtree);
134827 pPager = sqlite3BtreePager(pBtree);
134828 assert( pPager!=0 );
134829 fd = sqlite3PagerFile(pPager);
134830 pStr = sqlite3_str_new(db);
134831 if( pStr==0 ){
134832 sqlite3_result_error_nomem(context);
134833 }else{
134834 sqlite3_str_append(pStr, "{\"db\":", 6);
134835 rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_FILESTAT, pStr);
134836 if( rc ) sqlite3_str_append(pStr, "null", 4);
134837 fd = sqlite3PagerJrnlFile(pPager);
134838 if( fd && fd->pMethods!=0 ){
134839 sqlite3_str_appendall(pStr, ",\"journal\":");
134840 rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_FILESTAT, pStr);
134841 if( rc ) sqlite3_str_append(pStr, "null", 4);
134842 }
134843 sqlite3_str_append(pStr, "}", 1);
134844 sqlite3_result_text(context, sqlite3_str_finish(pStr), -1,
134845 sqlite3_free);
134846 }
134847 sqlite3BtreeLeave(pBtree);
134848 }else{
134849 sqlite3_result_text(context, "{}", 2, SQLITE_STATIC);
134850 }
134851 }
134852 #endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */
134853
134854 #ifdef SQLITE_DEBUG
134855 /*
134856 ** Implementation of fpdecode(x,y,z) function.
134857 **
@@ -134672,10 +135007,13 @@
135007 INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
135008 INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
135009 #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
135010 INLINE_FUNC(sqlite_offset, 1, INLINEFUNC_sqlite_offset, 0 ),
135011 #endif
135012 #if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
135013 FUNCTION(sqlite_filestat, 1, 0, 0, filestatFunc ),
135014 #endif
135015 FUNCTION(ltrim, 1, 1, 0, trimFunc ),
135016 FUNCTION(ltrim, 2, 1, 0, trimFunc ),
135017 FUNCTION(rtrim, 1, 2, 0, trimFunc ),
135018 FUNCTION(rtrim, 2, 2, 0, trimFunc ),
135019 FUNCTION(trim, 1, 3, 0, trimFunc ),
@@ -183458,12 +183796,13 @@
183796
183797 /*
183798 ** Return the length (in bytes) of the token that begins at z[0].
183799 ** Store the token type in *tokenType before returning.
183800 */
183801 SQLITE_PRIVATE i64 sqlite3GetToken(const unsigned char *z, int *tokenType){
183802 i64 i;
183803 int c;
183804 switch( aiClass[*z] ){ /* Switch on the character-class of the first byte
183805 ** of the token. See the comment on the CC_ defines
183806 ** above. */
183807 case CC_SPACE: {
183808 testcase( z[0]==' ' );
@@ -183787,11 +184126,11 @@
184126 ** Run the parser on the given SQL string.
184127 */
184128 SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){
184129 int nErr = 0; /* Number of errors encountered */
184130 void *pEngine; /* The LEMON-generated LALR(1) parser */
184131 i64 n = 0; /* Length of the next token token */
184132 int tokenType; /* type of the next token */
184133 int lastTokenParsed = -1; /* type of the previous token */
184134 sqlite3 *db = pParse->db; /* The database connection */
184135 int mxSqlLen; /* Max length of an SQL string */
184136 Parse *pParentParse = 0; /* Outer parse context, if any */
@@ -183890,17 +184229,17 @@
184229 zSql += n;
184230 continue;
184231 }else if( tokenType!=TK_QNUMBER ){
184232 Token x;
184233 x.z = zSql;
184234 x.n = (u32)n;
184235 sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", &x);
184236 break;
184237 }
184238 }
184239 pParse->sLastToken.z = zSql;
184240 pParse->sLastToken.n = (u32)n;
184241 sqlite3Parser(pEngine, tokenType, pParse->sLastToken);
184242 lastTokenParsed = tokenType;
184243 zSql += n;
184244 assert( db->mallocFailed==0 || pParse->rc!=SQLITE_OK || startedWithOom );
184245 if( pParse->rc!=SQLITE_OK ) break;
@@ -183972,11 +184311,11 @@
184311 Vdbe *pVdbe, /* VM being reprepared */
184312 const char *zSql /* The original SQL string */
184313 ){
184314 sqlite3 *db; /* The database connection */
184315 int i; /* Next unread byte of zSql[] */
184316 i64 n; /* length of current token */
184317 int tokenType; /* type of current token */
184318 int prevType = 0; /* Previous non-whitespace token */
184319 int nParen; /* Number of nested levels of parentheses */
184320 int iStartIN; /* Start of RHS of IN operator in z[] */
184321 int nParenAtIN; /* Value of nParent at start of RHS of IN operator */
@@ -215365,11 +215704,11 @@
215704 /* #include "sqlite3ext.h" */
215705 SQLITE_EXTENSION_INIT1
215706 #else
215707 /* #include "sqlite3.h" */
215708 #endif
215709 SQLITE_PRIVATE sqlite3_int64 sqlite3GetToken(const unsigned char*,int*); /* In SQLite core */
215710
215711 /* #include <stddef.h> */
215712
215713 /*
215714 ** If building separately, we will need some setup that is normally
@@ -229904,11 +230243,12 @@
230243 if( (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK && pData ){
230244 unsigned char *aPage = sqlite3PagerGetData(pDbPage);
230245 memcpy(aPage, pData, szPage);
230246 pTab->pgnoTrunc = 0;
230247 }
230248 }
230249 if( rc!=SQLITE_OK ){
230250 pTab->pgnoTrunc = 0;
230251 }
230252 sqlite3PagerUnref(pDbPage);
230253 return rc;
230254
@@ -259926,11 +260266,11 @@
260266 int nArg, /* Number of args */
260267 sqlite3_value **apUnused /* Function arguments */
260268 ){
260269 assert( nArg==0 );
260270 UNUSED_PARAM2(nArg, apUnused);
260271 sqlite3_result_text(pCtx, "fts5: 2025-10-28 13:24:50 724f2299f206cc9e7f830f984c50a8fc4ac1c17210d71d9affe657b45252b060", -1, SQLITE_TRANSIENT);
260272 }
260273
260274 /*
260275 ** Implementation of fts5_locale(LOCALE, TEXT) function.
260276 **
260277
+23 -9
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,14 +146,14 @@
146146
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147147
** [sqlite_version()] and [sqlite_source_id()].
148148
*/
149149
#define SQLITE_VERSION "3.51.0"
150150
#define SQLITE_VERSION_NUMBER 3051000
151
-#define SQLITE_SOURCE_ID "2025-10-15 10:52:45 5cbccab499bc3983aac1f57355552db607dee6c7ef4eb00d794dbee89c18db70"
151
+#define SQLITE_SOURCE_ID "2025-10-28 13:24:50 724f2299f206cc9e7f830f984c50a8fc4ac1c17210d71d9affe657b45252b060"
152152
#define SQLITE_SCM_BRANCH "trunk"
153153
#define SQLITE_SCM_TAGS ""
154
-#define SQLITE_SCM_DATETIME "2025-10-15T10:52:45.276Z"
154
+#define SQLITE_SCM_DATETIME "2025-10-28T13:24:50.858Z"
155155
156156
/*
157157
** CAPI3REF: Run-Time Library Version Numbers
158158
** KEYWORDS: sqlite3_version sqlite3_sourceid
159159
**
@@ -930,11 +930,11 @@
930930
** to the [sqlite3_file] object associated with the journal file (either
931931
** the [rollback journal] or the [write-ahead log]) for a particular database
932932
** connection. See also [SQLITE_FCNTL_FILE_POINTER].
933933
**
934934
** <li>[[SQLITE_FCNTL_SYNC_OMITTED]]
935
-** No longer in use.
935
+** The SQLITE_FCNTL_SYNC_OMITTED file-control is no longer used.
936936
**
937937
** <li>[[SQLITE_FCNTL_SYNC]]
938938
** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and
939939
** sent to the VFS immediately before the xSync method is invoked on a
940940
** database file descriptor. Or, if the xSync method is not invoked
@@ -1227,10 +1227,19 @@
12271227
** <li>[[SQLITE_FCNTL_RESET_CACHE]]
12281228
** If there is currently no transaction open on the database, and the
12291229
** database is not a temp db, then the [SQLITE_FCNTL_RESET_CACHE] file-control
12301230
** purges the contents of the in-memory page cache. If there is an open
12311231
** transaction, or if the db is a temp-db, this opcode is a no-op, not an error.
1232
+**
1233
+** <li>[[SQLITE_FCNTL_FILESTAT]]
1234
+** The [SQLITE_FCNTL_FILESTAT] opcode returns low-level diagnostic information
1235
+** about the [sqlite3_file] objects used access the database and journal files
1236
+** for the given schema. The fourth parameter to [sqlite3_file_control()]
1237
+** should be an initialized [sqlite3_str] pointer. JSON text describing
1238
+** various aspects of the sqlite3_file object is appended to the sqlite3_str.
1239
+** The SQLITE_FCNTL_FILESTAT opcode is usually a no-op, unless compile-time
1240
+** options are used to enable it.
12321241
** </ul>
12331242
*/
12341243
#define SQLITE_FCNTL_LOCKSTATE 1
12351244
#define SQLITE_FCNTL_GET_LOCKPROXYFILE 2
12361245
#define SQLITE_FCNTL_SET_LOCKPROXYFILE 3
@@ -1272,10 +1281,11 @@
12721281
#define SQLITE_FCNTL_EXTERNAL_READER 40
12731282
#define SQLITE_FCNTL_CKSM_FILE 41
12741283
#define SQLITE_FCNTL_RESET_CACHE 42
12751284
#define SQLITE_FCNTL_NULL_IO 43
12761285
#define SQLITE_FCNTL_BLOCK_ON_CONNECT 44
1286
+#define SQLITE_FCNTL_FILESTAT 45
12771287
12781288
/* deprecated names */
12791289
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
12801290
#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
12811291
#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -4905,13 +4915,15 @@
49054915
** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in
49064916
** [prepared statement] S to have an SQL value of NULL, but to also be
49074917
** associated with the pointer P of type T. ^D is either a NULL pointer or
49084918
** a pointer to a destructor function for P. ^SQLite will invoke the
49094919
** destructor D with a single argument of P when it is finished using
4910
-** P. The T parameter should be a static string, preferably a string
4911
-** literal. The sqlite3_bind_pointer() routine is part of the
4912
-** [pointer passing interface] added for SQLite 3.20.0.
4920
+** P, even if the call to sqlite3_bind_pointer() fails. Due to a
4921
+** historical design quirk, results are undefined if D is
4922
+** SQLITE_TRANSIENT. The T parameter should be a static string,
4923
+** preferably a string literal. The sqlite3_bind_pointer() routine is
4924
+** part of the [pointer passing interface] added for SQLite 3.20.0.
49134925
**
49144926
** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer
49154927
** for the [prepared statement] or with a prepared statement for which
49164928
** [sqlite3_step()] has been called more recently than [sqlite3_reset()],
49174929
** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_()
@@ -11151,23 +11163,25 @@
1115111163
** array to be bound, and N is the number of eements in the array. The
1115211164
** F argument is one of constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64],
1115311165
** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], or [SQLITE_CARRAY_BLOB] to
1115411166
** indicate the datatype of the array being bound. The X argument is not a
1115511167
** NULL pointer, then SQLite will invoke the function X on the P parameter
11156
-** after it has finished using P.
11168
+** after it has finished using P, even if the call to
11169
+** sqlite3_carray_bind() fails. The special-case finalizer
11170
+** SQLITE_TRANSIENT has no effect here.
1115711171
*/
11158
-SQLITE_API SQLITE_API int sqlite3_carray_bind(
11172
+SQLITE_API int sqlite3_carray_bind(
1115911173
sqlite3_stmt *pStmt, /* Statement to be bound */
1116011174
int i, /* Parameter index */
1116111175
void *aData, /* Pointer to array data */
1116211176
int nData, /* Number of data elements */
1116311177
int mFlags, /* CARRAY flags */
1116411178
void (*xDel)(void*) /* Destructor for aData */
1116511179
);
1116611180
1116711181
/*
11168
-** CAPI3REF: Datatypes for the CARRAY table-valued funtion
11182
+** CAPI3REF: Datatypes for the CARRAY table-valued function
1116911183
**
1117011184
** The fifth argument to the [sqlite3_carray_bind()] interface musts be
1117111185
** one of the following constants, to specify the datatype of the array
1117211186
** that is being bound into the [carray table-valued function].
1117311187
*/
1117411188
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,14 +146,14 @@
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.51.0"
150 #define SQLITE_VERSION_NUMBER 3051000
151 #define SQLITE_SOURCE_ID "2025-10-15 10:52:45 5cbccab499bc3983aac1f57355552db607dee6c7ef4eb00d794dbee89c18db70"
152 #define SQLITE_SCM_BRANCH "trunk"
153 #define SQLITE_SCM_TAGS ""
154 #define SQLITE_SCM_DATETIME "2025-10-15T10:52:45.276Z"
155
156 /*
157 ** CAPI3REF: Run-Time Library Version Numbers
158 ** KEYWORDS: sqlite3_version sqlite3_sourceid
159 **
@@ -930,11 +930,11 @@
930 ** to the [sqlite3_file] object associated with the journal file (either
931 ** the [rollback journal] or the [write-ahead log]) for a particular database
932 ** connection. See also [SQLITE_FCNTL_FILE_POINTER].
933 **
934 ** <li>[[SQLITE_FCNTL_SYNC_OMITTED]]
935 ** No longer in use.
936 **
937 ** <li>[[SQLITE_FCNTL_SYNC]]
938 ** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and
939 ** sent to the VFS immediately before the xSync method is invoked on a
940 ** database file descriptor. Or, if the xSync method is not invoked
@@ -1227,10 +1227,19 @@
1227 ** <li>[[SQLITE_FCNTL_RESET_CACHE]]
1228 ** If there is currently no transaction open on the database, and the
1229 ** database is not a temp db, then the [SQLITE_FCNTL_RESET_CACHE] file-control
1230 ** purges the contents of the in-memory page cache. If there is an open
1231 ** transaction, or if the db is a temp-db, this opcode is a no-op, not an error.
 
 
 
 
 
 
 
 
 
1232 ** </ul>
1233 */
1234 #define SQLITE_FCNTL_LOCKSTATE 1
1235 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2
1236 #define SQLITE_FCNTL_SET_LOCKPROXYFILE 3
@@ -1272,10 +1281,11 @@
1272 #define SQLITE_FCNTL_EXTERNAL_READER 40
1273 #define SQLITE_FCNTL_CKSM_FILE 41
1274 #define SQLITE_FCNTL_RESET_CACHE 42
1275 #define SQLITE_FCNTL_NULL_IO 43
1276 #define SQLITE_FCNTL_BLOCK_ON_CONNECT 44
 
1277
1278 /* deprecated names */
1279 #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
1280 #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
1281 #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -4905,13 +4915,15 @@
4905 ** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in
4906 ** [prepared statement] S to have an SQL value of NULL, but to also be
4907 ** associated with the pointer P of type T. ^D is either a NULL pointer or
4908 ** a pointer to a destructor function for P. ^SQLite will invoke the
4909 ** destructor D with a single argument of P when it is finished using
4910 ** P. The T parameter should be a static string, preferably a string
4911 ** literal. The sqlite3_bind_pointer() routine is part of the
4912 ** [pointer passing interface] added for SQLite 3.20.0.
 
 
4913 **
4914 ** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer
4915 ** for the [prepared statement] or with a prepared statement for which
4916 ** [sqlite3_step()] has been called more recently than [sqlite3_reset()],
4917 ** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_()
@@ -11151,23 +11163,25 @@
11151 ** array to be bound, and N is the number of eements in the array. The
11152 ** F argument is one of constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64],
11153 ** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], or [SQLITE_CARRAY_BLOB] to
11154 ** indicate the datatype of the array being bound. The X argument is not a
11155 ** NULL pointer, then SQLite will invoke the function X on the P parameter
11156 ** after it has finished using P.
 
 
11157 */
11158 SQLITE_API SQLITE_API int sqlite3_carray_bind(
11159 sqlite3_stmt *pStmt, /* Statement to be bound */
11160 int i, /* Parameter index */
11161 void *aData, /* Pointer to array data */
11162 int nData, /* Number of data elements */
11163 int mFlags, /* CARRAY flags */
11164 void (*xDel)(void*) /* Destructor for aData */
11165 );
11166
11167 /*
11168 ** CAPI3REF: Datatypes for the CARRAY table-valued funtion
11169 **
11170 ** The fifth argument to the [sqlite3_carray_bind()] interface musts be
11171 ** one of the following constants, to specify the datatype of the array
11172 ** that is being bound into the [carray table-valued function].
11173 */
11174
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,14 +146,14 @@
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.51.0"
150 #define SQLITE_VERSION_NUMBER 3051000
151 #define SQLITE_SOURCE_ID "2025-10-28 13:24:50 724f2299f206cc9e7f830f984c50a8fc4ac1c17210d71d9affe657b45252b060"
152 #define SQLITE_SCM_BRANCH "trunk"
153 #define SQLITE_SCM_TAGS ""
154 #define SQLITE_SCM_DATETIME "2025-10-28T13:24:50.858Z"
155
156 /*
157 ** CAPI3REF: Run-Time Library Version Numbers
158 ** KEYWORDS: sqlite3_version sqlite3_sourceid
159 **
@@ -930,11 +930,11 @@
930 ** to the [sqlite3_file] object associated with the journal file (either
931 ** the [rollback journal] or the [write-ahead log]) for a particular database
932 ** connection. See also [SQLITE_FCNTL_FILE_POINTER].
933 **
934 ** <li>[[SQLITE_FCNTL_SYNC_OMITTED]]
935 ** The SQLITE_FCNTL_SYNC_OMITTED file-control is no longer used.
936 **
937 ** <li>[[SQLITE_FCNTL_SYNC]]
938 ** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and
939 ** sent to the VFS immediately before the xSync method is invoked on a
940 ** database file descriptor. Or, if the xSync method is not invoked
@@ -1227,10 +1227,19 @@
1227 ** <li>[[SQLITE_FCNTL_RESET_CACHE]]
1228 ** If there is currently no transaction open on the database, and the
1229 ** database is not a temp db, then the [SQLITE_FCNTL_RESET_CACHE] file-control
1230 ** purges the contents of the in-memory page cache. If there is an open
1231 ** transaction, or if the db is a temp-db, this opcode is a no-op, not an error.
1232 **
1233 ** <li>[[SQLITE_FCNTL_FILESTAT]]
1234 ** The [SQLITE_FCNTL_FILESTAT] opcode returns low-level diagnostic information
1235 ** about the [sqlite3_file] objects used access the database and journal files
1236 ** for the given schema. The fourth parameter to [sqlite3_file_control()]
1237 ** should be an initialized [sqlite3_str] pointer. JSON text describing
1238 ** various aspects of the sqlite3_file object is appended to the sqlite3_str.
1239 ** The SQLITE_FCNTL_FILESTAT opcode is usually a no-op, unless compile-time
1240 ** options are used to enable it.
1241 ** </ul>
1242 */
1243 #define SQLITE_FCNTL_LOCKSTATE 1
1244 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2
1245 #define SQLITE_FCNTL_SET_LOCKPROXYFILE 3
@@ -1272,10 +1281,11 @@
1281 #define SQLITE_FCNTL_EXTERNAL_READER 40
1282 #define SQLITE_FCNTL_CKSM_FILE 41
1283 #define SQLITE_FCNTL_RESET_CACHE 42
1284 #define SQLITE_FCNTL_NULL_IO 43
1285 #define SQLITE_FCNTL_BLOCK_ON_CONNECT 44
1286 #define SQLITE_FCNTL_FILESTAT 45
1287
1288 /* deprecated names */
1289 #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
1290 #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
1291 #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -4905,13 +4915,15 @@
4915 ** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in
4916 ** [prepared statement] S to have an SQL value of NULL, but to also be
4917 ** associated with the pointer P of type T. ^D is either a NULL pointer or
4918 ** a pointer to a destructor function for P. ^SQLite will invoke the
4919 ** destructor D with a single argument of P when it is finished using
4920 ** P, even if the call to sqlite3_bind_pointer() fails. Due to a
4921 ** historical design quirk, results are undefined if D is
4922 ** SQLITE_TRANSIENT. The T parameter should be a static string,
4923 ** preferably a string literal. The sqlite3_bind_pointer() routine is
4924 ** part of the [pointer passing interface] added for SQLite 3.20.0.
4925 **
4926 ** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer
4927 ** for the [prepared statement] or with a prepared statement for which
4928 ** [sqlite3_step()] has been called more recently than [sqlite3_reset()],
4929 ** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_()
@@ -11151,23 +11163,25 @@
11163 ** array to be bound, and N is the number of eements in the array. The
11164 ** F argument is one of constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64],
11165 ** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], or [SQLITE_CARRAY_BLOB] to
11166 ** indicate the datatype of the array being bound. The X argument is not a
11167 ** NULL pointer, then SQLite will invoke the function X on the P parameter
11168 ** after it has finished using P, even if the call to
11169 ** sqlite3_carray_bind() fails. The special-case finalizer
11170 ** SQLITE_TRANSIENT has no effect here.
11171 */
11172 SQLITE_API int sqlite3_carray_bind(
11173 sqlite3_stmt *pStmt, /* Statement to be bound */
11174 int i, /* Parameter index */
11175 void *aData, /* Pointer to array data */
11176 int nData, /* Number of data elements */
11177 int mFlags, /* CARRAY flags */
11178 void (*xDel)(void*) /* Destructor for aData */
11179 );
11180
11181 /*
11182 ** CAPI3REF: Datatypes for the CARRAY table-valued function
11183 **
11184 ** The fifth argument to the [sqlite3_carray_bind()] interface musts be
11185 ** one of the following constants, to specify the datatype of the array
11186 ** that is being bound into the [carray table-valued function].
11187 */
11188
+16 -4
--- src/branch.c
+++ src/branch.c
@@ -18,10 +18,22 @@
1818
** This file contains code used to create new branches within a repository.
1919
*/
2020
#include "config.h"
2121
#include "branch.h"
2222
#include <assert.h>
23
+
24
+/*
25
+** Return the name of the main branch. Cache the result.
26
+**
27
+** This is the current value of the "main-branch" setting, or its default
28
+** value (historically, and as of 2025-10-28: "trunk") if not set.
29
+*/
30
+const char *db_main_branch(void){
31
+ static char *zMainBranch = 0;
32
+ if( zMainBranch==0 ) zMainBranch = db_get("main-branch", 0);
33
+ return zMainBranch;
34
+}
2335
2436
/*
2537
** Return true if zBr is the branch name associated with check-in with
2638
** blob.uuid value of zUuid
2739
*/
@@ -53,13 +65,11 @@
5365
if( db_step(&q)==SQLITE_ROW ){
5466
zBr = fossil_strdup(db_column_text(&q,0));
5567
}
5668
db_reset(&q);
5769
if( zBr==0 ){
58
- static char *zMain = 0;
59
- if( zMain==0 ) zMain = db_get("main-branch",0);
60
- zBr = fossil_strdup(zMain);
70
+ zBr = fossil_strdup(db_main_branch());
6171
}
6272
return zBr;
6373
}
6474
6575
/*
@@ -837,18 +847,20 @@
837847
*/
838848
static void new_brlist_page(void){
839849
Stmt q;
840850
double rNow;
841851
int show_colors = PB("colors");
852
+ const char *zMainBranch;
842853
login_check_credentials();
843854
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
844855
style_set_current_feature("branch");
845856
style_header("Branches");
846857
style_adunit_config(ADUNIT_RIGHT_OK);
847858
style_submenu_checkbox("colors", "Use Branch Colors", 0, 0);
848859
849860
login_anonymous_available();
861
+ zMainBranch = db_main_branch();
850862
851863
brlist_create_temp_table();
852864
db_prepare(&q, "SELECT * FROM tmp_brlist ORDER BY mtime DESC");
853865
rNow = db_double(0.0, "SELECT julianday('now')");
854866
@ <script id="brlist-data" type="application/json">\
@@ -873,11 +885,11 @@
873885
char *zAge = human_readable_age(rNow - rMtime);
874886
sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0);
875887
if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0;
876888
if( zBgClr ) zBgClr = reasonable_bg_color(zBgClr, 0);
877889
if( zBgClr==0 ){
878
- if( zBranch==0 || strcmp(zBranch,"trunk")==0 ){
890
+ if( zBranch==0 || strcmp(zBranch, zMainBranch)==0 ){
879891
zBgClr = 0;
880892
}else{
881893
zBgClr = hash_color(zBranch);
882894
}
883895
}
884896
--- src/branch.c
+++ src/branch.c
@@ -18,10 +18,22 @@
18 ** This file contains code used to create new branches within a repository.
19 */
20 #include "config.h"
21 #include "branch.h"
22 #include <assert.h>
 
 
 
 
 
 
 
 
 
 
 
 
23
24 /*
25 ** Return true if zBr is the branch name associated with check-in with
26 ** blob.uuid value of zUuid
27 */
@@ -53,13 +65,11 @@
53 if( db_step(&q)==SQLITE_ROW ){
54 zBr = fossil_strdup(db_column_text(&q,0));
55 }
56 db_reset(&q);
57 if( zBr==0 ){
58 static char *zMain = 0;
59 if( zMain==0 ) zMain = db_get("main-branch",0);
60 zBr = fossil_strdup(zMain);
61 }
62 return zBr;
63 }
64
65 /*
@@ -837,18 +847,20 @@
837 */
838 static void new_brlist_page(void){
839 Stmt q;
840 double rNow;
841 int show_colors = PB("colors");
 
842 login_check_credentials();
843 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
844 style_set_current_feature("branch");
845 style_header("Branches");
846 style_adunit_config(ADUNIT_RIGHT_OK);
847 style_submenu_checkbox("colors", "Use Branch Colors", 0, 0);
848
849 login_anonymous_available();
 
850
851 brlist_create_temp_table();
852 db_prepare(&q, "SELECT * FROM tmp_brlist ORDER BY mtime DESC");
853 rNow = db_double(0.0, "SELECT julianday('now')");
854 @ <script id="brlist-data" type="application/json">\
@@ -873,11 +885,11 @@
873 char *zAge = human_readable_age(rNow - rMtime);
874 sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0);
875 if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0;
876 if( zBgClr ) zBgClr = reasonable_bg_color(zBgClr, 0);
877 if( zBgClr==0 ){
878 if( zBranch==0 || strcmp(zBranch,"trunk")==0 ){
879 zBgClr = 0;
880 }else{
881 zBgClr = hash_color(zBranch);
882 }
883 }
884
--- src/branch.c
+++ src/branch.c
@@ -18,10 +18,22 @@
18 ** This file contains code used to create new branches within a repository.
19 */
20 #include "config.h"
21 #include "branch.h"
22 #include <assert.h>
23
24 /*
25 ** Return the name of the main branch. Cache the result.
26 **
27 ** This is the current value of the "main-branch" setting, or its default
28 ** value (historically, and as of 2025-10-28: "trunk") if not set.
29 */
30 const char *db_main_branch(void){
31 static char *zMainBranch = 0;
32 if( zMainBranch==0 ) zMainBranch = db_get("main-branch", 0);
33 return zMainBranch;
34 }
35
36 /*
37 ** Return true if zBr is the branch name associated with check-in with
38 ** blob.uuid value of zUuid
39 */
@@ -53,13 +65,11 @@
65 if( db_step(&q)==SQLITE_ROW ){
66 zBr = fossil_strdup(db_column_text(&q,0));
67 }
68 db_reset(&q);
69 if( zBr==0 ){
70 zBr = fossil_strdup(db_main_branch());
 
 
71 }
72 return zBr;
73 }
74
75 /*
@@ -837,18 +847,20 @@
847 */
848 static void new_brlist_page(void){
849 Stmt q;
850 double rNow;
851 int show_colors = PB("colors");
852 const char *zMainBranch;
853 login_check_credentials();
854 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
855 style_set_current_feature("branch");
856 style_header("Branches");
857 style_adunit_config(ADUNIT_RIGHT_OK);
858 style_submenu_checkbox("colors", "Use Branch Colors", 0, 0);
859
860 login_anonymous_available();
861 zMainBranch = db_main_branch();
862
863 brlist_create_temp_table();
864 db_prepare(&q, "SELECT * FROM tmp_brlist ORDER BY mtime DESC");
865 rNow = db_double(0.0, "SELECT julianday('now')");
866 @ <script id="brlist-data" type="application/json">\
@@ -873,11 +885,11 @@
885 char *zAge = human_readable_age(rNow - rMtime);
886 sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0);
887 if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0;
888 if( zBgClr ) zBgClr = reasonable_bg_color(zBgClr, 0);
889 if( zBgClr==0 ){
890 if( zBranch==0 || strcmp(zBranch, zMainBranch)==0 ){
891 zBgClr = 0;
892 }else{
893 zBgClr = hash_color(zBranch);
894 }
895 }
896
+2 -2
--- src/browse.c
+++ src/browse.c
@@ -127,11 +127,11 @@
127127
**
128128
** * Links to files go to /doc (showing the file content directly,
129129
** depending on mimetype) rather than to /file (which always shows
130130
** the file embedded in a standard Fossil page frame).
131131
**
132
-** * The submenu and the page title is now show. The page is plain.
132
+** * The submenu and the page title is not shown. The page is plain.
133133
**
134134
** The /docdir page is a shorthand for /dir with the "dx" query parameter.
135135
**
136136
** Query parameters:
137137
**
@@ -192,11 +192,11 @@
192192
193193
/* If a specific check-in is requested, fetch and parse it. If the
194194
** specific check-in does not exist, clear zCI. zCI==0 will cause all
195195
** files from all check-ins to be displayed.
196196
*/
197
- if( bDocDir && zCI==0 ) zCI = "trunk";
197
+ if( bDocDir && zCI==0 ) zCI = db_main_branch();
198198
if( zCI ){
199199
pM = manifest_get_by_name(zCI, &rid);
200200
if( pM ){
201201
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
202202
isSymbolicCI = (sqlite3_strnicmp(zUuid, zCI, strlen(zCI))!=0);
203203
--- src/browse.c
+++ src/browse.c
@@ -127,11 +127,11 @@
127 **
128 ** * Links to files go to /doc (showing the file content directly,
129 ** depending on mimetype) rather than to /file (which always shows
130 ** the file embedded in a standard Fossil page frame).
131 **
132 ** * The submenu and the page title is now show. The page is plain.
133 **
134 ** The /docdir page is a shorthand for /dir with the "dx" query parameter.
135 **
136 ** Query parameters:
137 **
@@ -192,11 +192,11 @@
192
193 /* If a specific check-in is requested, fetch and parse it. If the
194 ** specific check-in does not exist, clear zCI. zCI==0 will cause all
195 ** files from all check-ins to be displayed.
196 */
197 if( bDocDir && zCI==0 ) zCI = "trunk";
198 if( zCI ){
199 pM = manifest_get_by_name(zCI, &rid);
200 if( pM ){
201 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
202 isSymbolicCI = (sqlite3_strnicmp(zUuid, zCI, strlen(zCI))!=0);
203
--- src/browse.c
+++ src/browse.c
@@ -127,11 +127,11 @@
127 **
128 ** * Links to files go to /doc (showing the file content directly,
129 ** depending on mimetype) rather than to /file (which always shows
130 ** the file embedded in a standard Fossil page frame).
131 **
132 ** * The submenu and the page title is not shown. The page is plain.
133 **
134 ** The /docdir page is a shorthand for /dir with the "dx" query parameter.
135 **
136 ** Query parameters:
137 **
@@ -192,11 +192,11 @@
192
193 /* If a specific check-in is requested, fetch and parse it. If the
194 ** specific check-in does not exist, clear zCI. zCI==0 will cause all
195 ** files from all check-ins to be displayed.
196 */
197 if( bDocDir && zCI==0 ) zCI = db_main_branch();
198 if( zCI ){
199 pM = manifest_get_by_name(zCI, &rid);
200 if( pM ){
201 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
202 isSymbolicCI = (sqlite3_strnicmp(zUuid, zCI, strlen(zCI))!=0);
203
+3 -2
--- src/checkin.c
+++ src/checkin.c
@@ -1627,19 +1627,20 @@
16271627
int dryRunFlag /* True for a dry-run only */
16281628
){
16291629
Blob *pDesc;
16301630
char *zTags;
16311631
char *zFilename;
1632
+ const char *zMainBranch = db_main_branch();
16321633
Blob desc;
16331634
blob_init(&desc, 0, 0);
16341635
pDesc = &desc;
16351636
blob_appendf(pDesc, "checkout %s\n", g.zLocalRoot);
16361637
blob_appendf(pDesc, "repository %s\n", g.zRepositoryName);
16371638
blob_appendf(pDesc, "user %s\n",
16381639
p->zUserOvrd ? p->zUserOvrd : login_name());
16391640
blob_appendf(pDesc, "branch %s\n",
1640
- (p->zBranch && p->zBranch[0]) ? p->zBranch : "trunk");
1641
+ (p->zBranch && p->zBranch[0]) ? p->zBranch : zMainBranch);
16411642
zTags = info_tags_of_checkin(parent_rid, 1);
16421643
if( zTags || p->azTag ){
16431644
blob_append(pDesc, "tags ", -1);
16441645
if(zTags){
16451646
blob_appendf(pDesc, "%z%s", zTags, p->azTag ? ", " : "");
@@ -2624,11 +2625,11 @@
26242625
/* Get the ID of the parent manifest artifact */
26252626
vid = db_lget_int("checkout", 0);
26262627
if( vid==0 ){
26272628
useCksum = 1;
26282629
if( privateFlag==0 && sCiInfo.zBranch==0 ) {
2629
- sCiInfo.zBranch=db_get("main-branch", 0);
2630
+ sCiInfo.zBranch = db_main_branch();
26302631
}
26312632
}else{
26322633
privateParent = content_is_private(vid);
26332634
}
26342635
26352636
--- src/checkin.c
+++ src/checkin.c
@@ -1627,19 +1627,20 @@
1627 int dryRunFlag /* True for a dry-run only */
1628 ){
1629 Blob *pDesc;
1630 char *zTags;
1631 char *zFilename;
 
1632 Blob desc;
1633 blob_init(&desc, 0, 0);
1634 pDesc = &desc;
1635 blob_appendf(pDesc, "checkout %s\n", g.zLocalRoot);
1636 blob_appendf(pDesc, "repository %s\n", g.zRepositoryName);
1637 blob_appendf(pDesc, "user %s\n",
1638 p->zUserOvrd ? p->zUserOvrd : login_name());
1639 blob_appendf(pDesc, "branch %s\n",
1640 (p->zBranch && p->zBranch[0]) ? p->zBranch : "trunk");
1641 zTags = info_tags_of_checkin(parent_rid, 1);
1642 if( zTags || p->azTag ){
1643 blob_append(pDesc, "tags ", -1);
1644 if(zTags){
1645 blob_appendf(pDesc, "%z%s", zTags, p->azTag ? ", " : "");
@@ -2624,11 +2625,11 @@
2624 /* Get the ID of the parent manifest artifact */
2625 vid = db_lget_int("checkout", 0);
2626 if( vid==0 ){
2627 useCksum = 1;
2628 if( privateFlag==0 && sCiInfo.zBranch==0 ) {
2629 sCiInfo.zBranch=db_get("main-branch", 0);
2630 }
2631 }else{
2632 privateParent = content_is_private(vid);
2633 }
2634
2635
--- src/checkin.c
+++ src/checkin.c
@@ -1627,19 +1627,20 @@
1627 int dryRunFlag /* True for a dry-run only */
1628 ){
1629 Blob *pDesc;
1630 char *zTags;
1631 char *zFilename;
1632 const char *zMainBranch = db_main_branch();
1633 Blob desc;
1634 blob_init(&desc, 0, 0);
1635 pDesc = &desc;
1636 blob_appendf(pDesc, "checkout %s\n", g.zLocalRoot);
1637 blob_appendf(pDesc, "repository %s\n", g.zRepositoryName);
1638 blob_appendf(pDesc, "user %s\n",
1639 p->zUserOvrd ? p->zUserOvrd : login_name());
1640 blob_appendf(pDesc, "branch %s\n",
1641 (p->zBranch && p->zBranch[0]) ? p->zBranch : zMainBranch);
1642 zTags = info_tags_of_checkin(parent_rid, 1);
1643 if( zTags || p->azTag ){
1644 blob_append(pDesc, "tags ", -1);
1645 if(zTags){
1646 blob_appendf(pDesc, "%z%s", zTags, p->azTag ? ", " : "");
@@ -2624,11 +2625,11 @@
2625 /* Get the ID of the parent manifest artifact */
2626 vid = db_lget_int("checkout", 0);
2627 if( vid==0 ){
2628 useCksum = 1;
2629 if( privateFlag==0 && sCiInfo.zBranch==0 ) {
2630 sCiInfo.zBranch = db_main_branch();
2631 }
2632 }else{
2633 privateParent = content_is_private(vid);
2634 }
2635
2636
+1 -1
--- src/checkout.c
+++ src/checkout.c
@@ -496,11 +496,11 @@
496496
verify_all_options();
497497
if( g.argc<3 || g.argc>4 ){
498498
usage("URL ?VERSION? ?OPTIONS?");
499499
}
500500
zUrl = g.argv[2];
501
- zVers = g.argc==4 ? g.argv[3] : "trunk";
501
+ zVers = g.argc==4 ? g.argv[3] : db_main_branch();
502502
503503
/* Parse the URL of the repository */
504504
url_parse(zUrl, 0);
505505
506506
/* Construct an appropriate name for the destination directory */
507507
--- src/checkout.c
+++ src/checkout.c
@@ -496,11 +496,11 @@
496 verify_all_options();
497 if( g.argc<3 || g.argc>4 ){
498 usage("URL ?VERSION? ?OPTIONS?");
499 }
500 zUrl = g.argv[2];
501 zVers = g.argc==4 ? g.argv[3] : "trunk";
502
503 /* Parse the URL of the repository */
504 url_parse(zUrl, 0);
505
506 /* Construct an appropriate name for the destination directory */
507
--- src/checkout.c
+++ src/checkout.c
@@ -496,11 +496,11 @@
496 verify_all_options();
497 if( g.argc<3 || g.argc>4 ){
498 usage("URL ?VERSION? ?OPTIONS?");
499 }
500 zUrl = g.argv[2];
501 zVers = g.argc==4 ? g.argv[3] : db_main_branch();
502
503 /* Parse the URL of the repository */
504 url_parse(zUrl, 0);
505
506 /* Construct an appropriate name for the destination directory */
507
+1 -1
--- src/db.c
+++ src/db.c
@@ -4403,11 +4403,11 @@
44034403
/* Figure out which revision to open. */
44044404
if( !emptyFlag ){
44054405
if( g.argc==4 ){
44064406
g.zOpenRevision = g.argv[3];
44074407
}else if( db_exists("SELECT 1 FROM event WHERE type='ci'") ){
4408
- g.zOpenRevision = db_get("main-branch", 0);
4408
+ g.zOpenRevision = fossil_strdup(db_main_branch());
44094409
}
44104410
if( autosync_loop(SYNC_PULL, !bForce, "open") && !bForce ){
44114411
fossil_fatal("unable to auto-sync the repository");
44124412
}
44134413
}
44144414
--- src/db.c
+++ src/db.c
@@ -4403,11 +4403,11 @@
4403 /* Figure out which revision to open. */
4404 if( !emptyFlag ){
4405 if( g.argc==4 ){
4406 g.zOpenRevision = g.argv[3];
4407 }else if( db_exists("SELECT 1 FROM event WHERE type='ci'") ){
4408 g.zOpenRevision = db_get("main-branch", 0);
4409 }
4410 if( autosync_loop(SYNC_PULL, !bForce, "open") && !bForce ){
4411 fossil_fatal("unable to auto-sync the repository");
4412 }
4413 }
4414
--- src/db.c
+++ src/db.c
@@ -4403,11 +4403,11 @@
4403 /* Figure out which revision to open. */
4404 if( !emptyFlag ){
4405 if( g.argc==4 ){
4406 g.zOpenRevision = g.argv[3];
4407 }else if( db_exists("SELECT 1 FROM event WHERE type='ci'") ){
4408 g.zOpenRevision = fossil_strdup(db_main_branch());
4409 }
4410 if( autosync_loop(SYNC_PULL, !bForce, "open") && !bForce ){
4411 fossil_fatal("unable to auto-sync the repository");
4412 }
4413 }
4414
--- src/descendants.c
+++ src/descendants.c
@@ -437,11 +437,11 @@
437437
int multipleFlag = find_option("multiple","m",0)!=0;
438438
const char *zWidth = find_option("width","W",1);
439439
char *zLastBr = 0;
440440
int n, width;
441441
char zLineNo[10];
442
- char * const zMainBranch = db_get("main-branch","trunk");
442
+ const char *zMainBranch = db_main_branch();
443443
444444
if( multipleFlag ) byBranch = 1;
445445
if( zWidth ){
446446
width = atoi(zWidth);
447447
if( (width!=0) && (width<=39) ){
@@ -535,11 +535,10 @@
535535
zBranchPoint ? zBranchPoint : "");
536536
comment_print(z, zCom, 7, width, get_comment_format());
537537
fossil_free(z);
538538
fossil_free(zBranchPoint);
539539
}
540
- fossil_free(zMainBranch);
541540
fossil_free(zLastBr);
542541
db_finalize(&q);
543542
}
544543
545544
/*
546545
--- src/descendants.c
+++ src/descendants.c
@@ -437,11 +437,11 @@
437 int multipleFlag = find_option("multiple","m",0)!=0;
438 const char *zWidth = find_option("width","W",1);
439 char *zLastBr = 0;
440 int n, width;
441 char zLineNo[10];
442 char * const zMainBranch = db_get("main-branch","trunk");
443
444 if( multipleFlag ) byBranch = 1;
445 if( zWidth ){
446 width = atoi(zWidth);
447 if( (width!=0) && (width<=39) ){
@@ -535,11 +535,10 @@
535 zBranchPoint ? zBranchPoint : "");
536 comment_print(z, zCom, 7, width, get_comment_format());
537 fossil_free(z);
538 fossil_free(zBranchPoint);
539 }
540 fossil_free(zMainBranch);
541 fossil_free(zLastBr);
542 db_finalize(&q);
543 }
544
545 /*
546
--- src/descendants.c
+++ src/descendants.c
@@ -437,11 +437,11 @@
437 int multipleFlag = find_option("multiple","m",0)!=0;
438 const char *zWidth = find_option("width","W",1);
439 char *zLastBr = 0;
440 int n, width;
441 char zLineNo[10];
442 const char *zMainBranch = db_main_branch();
443
444 if( multipleFlag ) byBranch = 1;
445 if( zWidth ){
446 width = atoi(zWidth);
447 if( (width!=0) && (width<=39) ){
@@ -535,11 +535,10 @@
535 zBranchPoint ? zBranchPoint : "");
536 comment_print(z, zCom, 7, width, get_comment_format());
537 fossil_free(z);
538 fossil_free(zBranchPoint);
539 }
 
540 fossil_free(zLastBr);
541 db_finalize(&q);
542 }
543
544 /*
545
+2 -1
--- src/diff.c
+++ src/diff.c
@@ -3949,11 +3949,12 @@
39493949
** -n|--limit LIMIT LIMIT can be one of:
39503950
** N Up to N versions
39513951
** Xs As much as possible in X seconds
39523952
** none No limit
39533953
** -o|--origin VERSION The origin check-in. By default this is the
3954
-** root of the repository. Set to "trunk" or
3954
+** root of the repository. Set to the name of
3955
+** the main branch (usually "trunk") or
39553956
** similar for a reverse annotation.
39563957
** -w|--ignore-all-space Ignore white space when comparing lines
39573958
** -Z|--ignore-trailing-space Ignore whitespace at line end
39583959
**
39593960
** See also: [[info]], [[finfo]], [[timeline]]
39603961
--- src/diff.c
+++ src/diff.c
@@ -3949,11 +3949,12 @@
3949 ** -n|--limit LIMIT LIMIT can be one of:
3950 ** N Up to N versions
3951 ** Xs As much as possible in X seconds
3952 ** none No limit
3953 ** -o|--origin VERSION The origin check-in. By default this is the
3954 ** root of the repository. Set to "trunk" or
 
3955 ** similar for a reverse annotation.
3956 ** -w|--ignore-all-space Ignore white space when comparing lines
3957 ** -Z|--ignore-trailing-space Ignore whitespace at line end
3958 **
3959 ** See also: [[info]], [[finfo]], [[timeline]]
3960
--- src/diff.c
+++ src/diff.c
@@ -3949,11 +3949,12 @@
3949 ** -n|--limit LIMIT LIMIT can be one of:
3950 ** N Up to N versions
3951 ** Xs As much as possible in X seconds
3952 ** none No limit
3953 ** -o|--origin VERSION The origin check-in. By default this is the
3954 ** root of the repository. Set to the name of
3955 ** the main branch (usually "trunk") or
3956 ** similar for a reverse annotation.
3957 ** -w|--ignore-all-space Ignore white space when comparing lines
3958 ** -Z|--ignore-trailing-space Ignore whitespace at line end
3959 **
3960 ** See also: [[info]], [[finfo]], [[timeline]]
3961
+8 -5
--- src/export.c
+++ src/export.c
@@ -491,20 +491,21 @@
491491
Stmt q, q2, q3;
492492
Bag blobs, vers;
493493
unsigned int unused_mark = 1;
494494
const char *markfile_in;
495495
const char *markfile_out;
496
+ const char *zMainBranch = db_main_branch();
496497
497498
bag_init(&blobs);
498499
bag_init(&vers);
499500
500501
find_option("git", 0, 0); /* Ignore the --git option for now */
501502
markfile_in = find_option("import-marks", 0, 1);
502503
markfile_out = find_option("export-marks", 0, 1);
503504
504505
if( !(gexport.zTrunkName = find_option("rename-trunk", 0, 1)) ){
505
- gexport.zTrunkName = "trunk";
506
+ gexport.zTrunkName = fossil_strdup(zMainBranch);
506507
}
507508
508509
db_find_and_open_repository(0, 2);
509510
verify_all_options();
510511
if( g.argc!=2 && g.argc!=3 ){ usage("--git ?REPOSITORY?"); }
@@ -629,11 +630,11 @@
629630
630631
bag_insert(&vers, ckinId);
631632
db_bind_int(&q2, ":rid", ckinId);
632633
db_step(&q2);
633634
db_reset(&q2);
634
- if( zBranch==0 || fossil_strcmp(zBranch, "trunk")==0 ){
635
+ if( zBranch==0 || fossil_strcmp(zBranch, zMainBranch)==0 ){
635636
zBranch = gexport.zTrunkName;
636637
}
637638
zMark = mark_name_from_rid(ckinId, &unused_mark);
638639
printf("commit refs/heads/");
639640
print_ref(zBranch);
@@ -857,12 +858,12 @@
857858
#define VERB_ERROR 1
858859
#define VERB_NORMAL 2
859860
#define VERB_EXTRA 3
860861
static int gitmirror_verbosity = VERB_NORMAL;
861862
862
-/* The main branch in the Git repository. The "trunk" branch of
863
-** Fossil is renamed to be this branch name.
863
+/* The main branch in the Git repository. The main branch of the
864
+** Fossil repository (usually "trunk") is renamed to be this branch name.
864865
*/
865866
static const char *gitmirror_mainbranch = 0;
866867
867868
/*
868869
** Output routine that depends on verbosity
@@ -1090,10 +1091,11 @@
10901091
int bPhantomOk; /* True if phantom files should be ignored */
10911092
char buf[24];
10921093
char *zEmail; /* Contact info for Git committer field */
10931094
int fManifest; /* Should the manifest files be included? */
10941095
int fPManifest = 0; /* OR of the manifest files for all parents */
1096
+ const char *zMainBranch;
10951097
10961098
pMan = manifest_get(rid, CFTYPE_MANIFEST, 0);
10971099
if( pMan==0 ){
10981100
/* Must be a phantom. Return without doing anything, and in particular
10991101
** without creating a mark for this check-in. */
@@ -1149,11 +1151,12 @@
11491151
/* Figure out which branch this check-in is a member of */
11501152
zBranch = db_text(0,
11511153
"SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0 AND rid=%d",
11521154
TAG_BRANCH, rid
11531155
);
1154
- if( fossil_strcmp(zBranch,"trunk")==0 ){
1156
+ zMainBranch = db_main_branch();
1157
+ if( fossil_strcmp(zBranch, zMainBranch)==0 ){
11551158
assert( gitmirror_mainbranch!=0 );
11561159
fossil_free(zBranch);
11571160
zBranch = fossil_strdup(gitmirror_mainbranch);
11581161
}else if( zBranch==0 ){
11591162
zBranch = mprintf("unknown");
11601163
--- src/export.c
+++ src/export.c
@@ -491,20 +491,21 @@
491 Stmt q, q2, q3;
492 Bag blobs, vers;
493 unsigned int unused_mark = 1;
494 const char *markfile_in;
495 const char *markfile_out;
 
496
497 bag_init(&blobs);
498 bag_init(&vers);
499
500 find_option("git", 0, 0); /* Ignore the --git option for now */
501 markfile_in = find_option("import-marks", 0, 1);
502 markfile_out = find_option("export-marks", 0, 1);
503
504 if( !(gexport.zTrunkName = find_option("rename-trunk", 0, 1)) ){
505 gexport.zTrunkName = "trunk";
506 }
507
508 db_find_and_open_repository(0, 2);
509 verify_all_options();
510 if( g.argc!=2 && g.argc!=3 ){ usage("--git ?REPOSITORY?"); }
@@ -629,11 +630,11 @@
629
630 bag_insert(&vers, ckinId);
631 db_bind_int(&q2, ":rid", ckinId);
632 db_step(&q2);
633 db_reset(&q2);
634 if( zBranch==0 || fossil_strcmp(zBranch, "trunk")==0 ){
635 zBranch = gexport.zTrunkName;
636 }
637 zMark = mark_name_from_rid(ckinId, &unused_mark);
638 printf("commit refs/heads/");
639 print_ref(zBranch);
@@ -857,12 +858,12 @@
857 #define VERB_ERROR 1
858 #define VERB_NORMAL 2
859 #define VERB_EXTRA 3
860 static int gitmirror_verbosity = VERB_NORMAL;
861
862 /* The main branch in the Git repository. The "trunk" branch of
863 ** Fossil is renamed to be this branch name.
864 */
865 static const char *gitmirror_mainbranch = 0;
866
867 /*
868 ** Output routine that depends on verbosity
@@ -1090,10 +1091,11 @@
1090 int bPhantomOk; /* True if phantom files should be ignored */
1091 char buf[24];
1092 char *zEmail; /* Contact info for Git committer field */
1093 int fManifest; /* Should the manifest files be included? */
1094 int fPManifest = 0; /* OR of the manifest files for all parents */
 
1095
1096 pMan = manifest_get(rid, CFTYPE_MANIFEST, 0);
1097 if( pMan==0 ){
1098 /* Must be a phantom. Return without doing anything, and in particular
1099 ** without creating a mark for this check-in. */
@@ -1149,11 +1151,12 @@
1149 /* Figure out which branch this check-in is a member of */
1150 zBranch = db_text(0,
1151 "SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0 AND rid=%d",
1152 TAG_BRANCH, rid
1153 );
1154 if( fossil_strcmp(zBranch,"trunk")==0 ){
 
1155 assert( gitmirror_mainbranch!=0 );
1156 fossil_free(zBranch);
1157 zBranch = fossil_strdup(gitmirror_mainbranch);
1158 }else if( zBranch==0 ){
1159 zBranch = mprintf("unknown");
1160
--- src/export.c
+++ src/export.c
@@ -491,20 +491,21 @@
491 Stmt q, q2, q3;
492 Bag blobs, vers;
493 unsigned int unused_mark = 1;
494 const char *markfile_in;
495 const char *markfile_out;
496 const char *zMainBranch = db_main_branch();
497
498 bag_init(&blobs);
499 bag_init(&vers);
500
501 find_option("git", 0, 0); /* Ignore the --git option for now */
502 markfile_in = find_option("import-marks", 0, 1);
503 markfile_out = find_option("export-marks", 0, 1);
504
505 if( !(gexport.zTrunkName = find_option("rename-trunk", 0, 1)) ){
506 gexport.zTrunkName = fossil_strdup(zMainBranch);
507 }
508
509 db_find_and_open_repository(0, 2);
510 verify_all_options();
511 if( g.argc!=2 && g.argc!=3 ){ usage("--git ?REPOSITORY?"); }
@@ -629,11 +630,11 @@
630
631 bag_insert(&vers, ckinId);
632 db_bind_int(&q2, ":rid", ckinId);
633 db_step(&q2);
634 db_reset(&q2);
635 if( zBranch==0 || fossil_strcmp(zBranch, zMainBranch)==0 ){
636 zBranch = gexport.zTrunkName;
637 }
638 zMark = mark_name_from_rid(ckinId, &unused_mark);
639 printf("commit refs/heads/");
640 print_ref(zBranch);
@@ -857,12 +858,12 @@
858 #define VERB_ERROR 1
859 #define VERB_NORMAL 2
860 #define VERB_EXTRA 3
861 static int gitmirror_verbosity = VERB_NORMAL;
862
863 /* The main branch in the Git repository. The main branch of the
864 ** Fossil repository (usually "trunk") is renamed to be this branch name.
865 */
866 static const char *gitmirror_mainbranch = 0;
867
868 /*
869 ** Output routine that depends on verbosity
@@ -1090,10 +1091,11 @@
1091 int bPhantomOk; /* True if phantom files should be ignored */
1092 char buf[24];
1093 char *zEmail; /* Contact info for Git committer field */
1094 int fManifest; /* Should the manifest files be included? */
1095 int fPManifest = 0; /* OR of the manifest files for all parents */
1096 const char *zMainBranch;
1097
1098 pMan = manifest_get(rid, CFTYPE_MANIFEST, 0);
1099 if( pMan==0 ){
1100 /* Must be a phantom. Return without doing anything, and in particular
1101 ** without creating a mark for this check-in. */
@@ -1149,11 +1151,12 @@
1151 /* Figure out which branch this check-in is a member of */
1152 zBranch = db_text(0,
1153 "SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0 AND rid=%d",
1154 TAG_BRANCH, rid
1155 );
1156 zMainBranch = db_main_branch();
1157 if( fossil_strcmp(zBranch, zMainBranch)==0 ){
1158 assert( gitmirror_mainbranch!=0 );
1159 fossil_free(zBranch);
1160 zBranch = fossil_strdup(gitmirror_mainbranch);
1161 }else if( zBranch==0 ){
1162 zBranch = mprintf("unknown");
1163
+1 -1
--- src/fileedit.c
+++ src/fileedit.c
@@ -833,11 +833,11 @@
833833
}
834834
if(zRevision==0 || zRevision[0]==0){
835835
if(g.localOpen/*check-out*/){
836836
zRevision = db_lget("checkout-hash", 0)/*leak*/;
837837
}else{
838
- zRevision = "trunk";
838
+ zRevision = db_main_branch();
839839
}
840840
}
841841
name_to_uuid2(zRevision, "ci", &cimi.zParentUuid);
842842
if(cimi.zParentUuid==0){
843843
fossil_fatal("Cannot determine version to commit to.");
844844
--- src/fileedit.c
+++ src/fileedit.c
@@ -833,11 +833,11 @@
833 }
834 if(zRevision==0 || zRevision[0]==0){
835 if(g.localOpen/*check-out*/){
836 zRevision = db_lget("checkout-hash", 0)/*leak*/;
837 }else{
838 zRevision = "trunk";
839 }
840 }
841 name_to_uuid2(zRevision, "ci", &cimi.zParentUuid);
842 if(cimi.zParentUuid==0){
843 fossil_fatal("Cannot determine version to commit to.");
844
--- src/fileedit.c
+++ src/fileedit.c
@@ -833,11 +833,11 @@
833 }
834 if(zRevision==0 || zRevision[0]==0){
835 if(g.localOpen/*check-out*/){
836 zRevision = db_lget("checkout-hash", 0)/*leak*/;
837 }else{
838 zRevision = db_main_branch();
839 }
840 }
841 name_to_uuid2(zRevision, "ci", &cimi.zParentUuid);
842 if(cimi.zParentUuid==0){
843 fossil_fatal("Cannot determine version to commit to.");
844
+7 -3
--- src/finfo.c
+++ src/finfo.c
@@ -176,10 +176,11 @@
176176
const char *zFilename;
177177
const char *zLimit;
178178
const char *zWidth;
179179
const char *zOffset;
180180
int iLimit, iOffset, iBrief, iWidth;
181
+ const char *zMainBranch;
181182
182183
if( find_option("log","l",0) ){
183184
/* this is the default, no-op */
184185
}
185186
zLimit = find_option("limit","n",1);
@@ -231,19 +232,20 @@
231232
);
232233
blob_zero(&line);
233234
if( iBrief == 0 ){
234235
fossil_print("History for %s\n", blob_str(&fname));
235236
}
237
+ zMainBranch = db_main_branch();
236238
while( db_step(&q)==SQLITE_ROW ){
237239
const char *zFileUuid = db_column_text(&q, 0);
238240
const char *zCiUuid = db_column_text(&q,1);
239241
const char *zDate = db_column_text(&q, 2);
240242
const char *zCom = db_column_text(&q, 3);
241243
const char *zUser = db_column_text(&q, 4);
242244
const char *zBr = db_column_text(&q, 5);
243245
char *zOut;
244
- if( zBr==0 ) zBr = "trunk";
246
+ if( zBr==0 ) zBr = fossil_strdup(zMainBranch);
245247
if( iBrief == 0 ){
246248
fossil_print("%s ", zDate);
247249
zOut = mprintf(
248250
"[%S] %s (user: %s, artifact: [%S], branch: %s)",
249251
zCiUuid, zCom, zUser, zFileUuid, zBr);
@@ -376,10 +378,11 @@
376378
int tmFlags = 0; /* Viewing mode */
377379
const char *zStyle; /* Viewing mode name */
378380
const char *zMark; /* Mark this version of the file */
379381
int selRid = 0; /* RID of the marked file version */
380382
int mxfnid; /* Maximum filename.fnid value */
383
+ const char *zMainBranch;
381384
382385
login_check_credentials();
383386
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
384387
fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
385388
ridCi = zCI ? name_to_rid_www("ci") : 0;
@@ -633,15 +636,16 @@
633636
while( db_step(&qparent)==SQLITE_ROW && nParent<count(aParent) ){
634637
aParent[nParent] = db_column_int64(&qparent, 0);
635638
nParent++;
636639
}
637640
db_reset(&qparent);
638
- if( zBr==0 ) zBr = "trunk";
641
+ zMainBranch = db_main_branch();
642
+ if( zBr==0 ) zBr = fossil_strdup(zMainBranch);
639643
if( uBg ){
640644
zBgClr = user_color(zUser);
641645
}else if( brBg || zBgClr==0 || zBgClr[0]==0 ){
642
- zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr);
646
+ zBgClr = strcmp(zBr, zMainBranch)==0 ? "" : hash_color(zBr);
643647
}else if( zBgClr ){
644648
zBgClr = reasonable_bg_color(zBgClr,0);
645649
}
646650
gidx = graph_add_row(pGraph,
647651
frid>0 ? (GraphRowId)frid*(mxfnid+1)+fnid : fpid+1000000000,
648652
--- src/finfo.c
+++ src/finfo.c
@@ -176,10 +176,11 @@
176 const char *zFilename;
177 const char *zLimit;
178 const char *zWidth;
179 const char *zOffset;
180 int iLimit, iOffset, iBrief, iWidth;
 
181
182 if( find_option("log","l",0) ){
183 /* this is the default, no-op */
184 }
185 zLimit = find_option("limit","n",1);
@@ -231,19 +232,20 @@
231 );
232 blob_zero(&line);
233 if( iBrief == 0 ){
234 fossil_print("History for %s\n", blob_str(&fname));
235 }
 
236 while( db_step(&q)==SQLITE_ROW ){
237 const char *zFileUuid = db_column_text(&q, 0);
238 const char *zCiUuid = db_column_text(&q,1);
239 const char *zDate = db_column_text(&q, 2);
240 const char *zCom = db_column_text(&q, 3);
241 const char *zUser = db_column_text(&q, 4);
242 const char *zBr = db_column_text(&q, 5);
243 char *zOut;
244 if( zBr==0 ) zBr = "trunk";
245 if( iBrief == 0 ){
246 fossil_print("%s ", zDate);
247 zOut = mprintf(
248 "[%S] %s (user: %s, artifact: [%S], branch: %s)",
249 zCiUuid, zCom, zUser, zFileUuid, zBr);
@@ -376,10 +378,11 @@
376 int tmFlags = 0; /* Viewing mode */
377 const char *zStyle; /* Viewing mode name */
378 const char *zMark; /* Mark this version of the file */
379 int selRid = 0; /* RID of the marked file version */
380 int mxfnid; /* Maximum filename.fnid value */
 
381
382 login_check_credentials();
383 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
384 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
385 ridCi = zCI ? name_to_rid_www("ci") : 0;
@@ -633,15 +636,16 @@
633 while( db_step(&qparent)==SQLITE_ROW && nParent<count(aParent) ){
634 aParent[nParent] = db_column_int64(&qparent, 0);
635 nParent++;
636 }
637 db_reset(&qparent);
638 if( zBr==0 ) zBr = "trunk";
 
639 if( uBg ){
640 zBgClr = user_color(zUser);
641 }else if( brBg || zBgClr==0 || zBgClr[0]==0 ){
642 zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr);
643 }else if( zBgClr ){
644 zBgClr = reasonable_bg_color(zBgClr,0);
645 }
646 gidx = graph_add_row(pGraph,
647 frid>0 ? (GraphRowId)frid*(mxfnid+1)+fnid : fpid+1000000000,
648
--- src/finfo.c
+++ src/finfo.c
@@ -176,10 +176,11 @@
176 const char *zFilename;
177 const char *zLimit;
178 const char *zWidth;
179 const char *zOffset;
180 int iLimit, iOffset, iBrief, iWidth;
181 const char *zMainBranch;
182
183 if( find_option("log","l",0) ){
184 /* this is the default, no-op */
185 }
186 zLimit = find_option("limit","n",1);
@@ -231,19 +232,20 @@
232 );
233 blob_zero(&line);
234 if( iBrief == 0 ){
235 fossil_print("History for %s\n", blob_str(&fname));
236 }
237 zMainBranch = db_main_branch();
238 while( db_step(&q)==SQLITE_ROW ){
239 const char *zFileUuid = db_column_text(&q, 0);
240 const char *zCiUuid = db_column_text(&q,1);
241 const char *zDate = db_column_text(&q, 2);
242 const char *zCom = db_column_text(&q, 3);
243 const char *zUser = db_column_text(&q, 4);
244 const char *zBr = db_column_text(&q, 5);
245 char *zOut;
246 if( zBr==0 ) zBr = fossil_strdup(zMainBranch);
247 if( iBrief == 0 ){
248 fossil_print("%s ", zDate);
249 zOut = mprintf(
250 "[%S] %s (user: %s, artifact: [%S], branch: %s)",
251 zCiUuid, zCom, zUser, zFileUuid, zBr);
@@ -376,10 +378,11 @@
378 int tmFlags = 0; /* Viewing mode */
379 const char *zStyle; /* Viewing mode name */
380 const char *zMark; /* Mark this version of the file */
381 int selRid = 0; /* RID of the marked file version */
382 int mxfnid; /* Maximum filename.fnid value */
383 const char *zMainBranch;
384
385 login_check_credentials();
386 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
387 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
388 ridCi = zCI ? name_to_rid_www("ci") : 0;
@@ -633,15 +636,16 @@
636 while( db_step(&qparent)==SQLITE_ROW && nParent<count(aParent) ){
637 aParent[nParent] = db_column_int64(&qparent, 0);
638 nParent++;
639 }
640 db_reset(&qparent);
641 zMainBranch = db_main_branch();
642 if( zBr==0 ) zBr = fossil_strdup(zMainBranch);
643 if( uBg ){
644 zBgClr = user_color(zUser);
645 }else if( brBg || zBgClr==0 || zBgClr[0]==0 ){
646 zBgClr = strcmp(zBr, zMainBranch)==0 ? "" : hash_color(zBr);
647 }else if( zBgClr ){
648 zBgClr = reasonable_bg_color(zBgClr,0);
649 }
650 gidx = graph_add_row(pGraph,
651 frid>0 ? (GraphRowId)frid*(mxfnid+1)+fnid : fpid+1000000000,
652
+4 -2
--- src/graph.c
+++ src/graph.c
@@ -513,10 +513,11 @@
513513
GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
514514
int i, j;
515515
u64 mask;
516516
int hasDup = 0; /* True if one or more isDup entries */
517517
const char *zTrunk;
518
+ const char *zMainBranch;
518519
u8 *aMap; /* Copy of p->aiRailMap */
519520
int omitDescenders = (tmFlags & TIMELINE_DISJOINT)!=0;
520521
int nTimewarp = 0;
521522
int riserMargin = (tmFlags & TIMELINE_DISJOINT) ? 0 : RISER_MARGIN;
522523
@@ -706,13 +707,14 @@
706707
}
707708
708709
/* Identify rows where the primary parent is off screen. Assign
709710
** each to a rail and draw descenders downward.
710711
**
711
- ** Strive to put the "trunk" branch on far left.
712
+ ** Strive to put the main branch (usually "trunk") on far left.
712713
*/
713
- zTrunk = persistBranchName(p, "trunk");
714
+ zMainBranch = db_main_branch();
715
+ zTrunk = persistBranchName(p, zMainBranch);
714716
for(i=0; i<2; i++){
715717
for(pRow=p->pLast; pRow; pRow=pRow->pPrev){
716718
if( i==0 && pRow->zBranch!=zTrunk ) continue;
717719
if( pRow->iRail>=0 ) continue;
718720
if( pRow->isDup ) continue;
719721
--- src/graph.c
+++ src/graph.c
@@ -513,10 +513,11 @@
513 GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
514 int i, j;
515 u64 mask;
516 int hasDup = 0; /* True if one or more isDup entries */
517 const char *zTrunk;
 
518 u8 *aMap; /* Copy of p->aiRailMap */
519 int omitDescenders = (tmFlags & TIMELINE_DISJOINT)!=0;
520 int nTimewarp = 0;
521 int riserMargin = (tmFlags & TIMELINE_DISJOINT) ? 0 : RISER_MARGIN;
522
@@ -706,13 +707,14 @@
706 }
707
708 /* Identify rows where the primary parent is off screen. Assign
709 ** each to a rail and draw descenders downward.
710 **
711 ** Strive to put the "trunk" branch on far left.
712 */
713 zTrunk = persistBranchName(p, "trunk");
 
714 for(i=0; i<2; i++){
715 for(pRow=p->pLast; pRow; pRow=pRow->pPrev){
716 if( i==0 && pRow->zBranch!=zTrunk ) continue;
717 if( pRow->iRail>=0 ) continue;
718 if( pRow->isDup ) continue;
719
--- src/graph.c
+++ src/graph.c
@@ -513,10 +513,11 @@
513 GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
514 int i, j;
515 u64 mask;
516 int hasDup = 0; /* True if one or more isDup entries */
517 const char *zTrunk;
518 const char *zMainBranch;
519 u8 *aMap; /* Copy of p->aiRailMap */
520 int omitDescenders = (tmFlags & TIMELINE_DISJOINT)!=0;
521 int nTimewarp = 0;
522 int riserMargin = (tmFlags & TIMELINE_DISJOINT) ? 0 : RISER_MARGIN;
523
@@ -706,13 +707,14 @@
707 }
708
709 /* Identify rows where the primary parent is off screen. Assign
710 ** each to a rail and draw descenders downward.
711 **
712 ** Strive to put the main branch (usually "trunk") on far left.
713 */
714 zMainBranch = db_main_branch();
715 zTrunk = persistBranchName(p, zMainBranch);
716 for(i=0; i<2; i++){
717 for(pRow=p->pLast; pRow; pRow=pRow->pPrev){
718 if( i==0 && pRow->zBranch!=zTrunk ) continue;
719 if( pRow->iRail>=0 ) continue;
720 if( pRow->isDup ) continue;
721
+7 -5
--- src/import.c
+++ src/import.c
@@ -568,12 +568,12 @@
568568
**
569569
** (A) refs/heads/BRANCHNAME
570570
** (B) refs/tags/TAGNAME
571571
**
572572
** If pattern A is used, then the branchname used is as shown.
573
- ** Except, the "master" branch which is the default branch name in
574
- ** Git is changed to "trunk" which is the default name in Fossil.
573
+ ** Except, the "master" branch which is the default branch name in Git
574
+ ** is changed to the default main branch name in Fossil (usually "trunk")
575575
** If the pattern is B, then the new commit should be on the same
576576
** branch as its parent. And, we might need to add the TAGNAME
577577
** tag to the new commit. However, if there are multiple instances
578578
** of pattern B with the same TAGNAME, then only put the tag on the
579579
** last commit that holds that tag.
@@ -1263,10 +1263,11 @@
12631263
** Return 0 if not a branch, tag, or trunk, or if ignored by --ignore-tree.
12641264
*/
12651265
static int svn_parse_path(char *zPath, char **zFile, int *type){
12661266
char *zBranch = 0;
12671267
int branchId = 0;
1268
+ const char *zMainBranch;
12681269
if( gsvn.azIgnTree ){
12691270
const char **pzIgnTree;
12701271
unsigned nPath = strlen(zPath);
12711272
for( pzIgnTree = gsvn.azIgnTree; *pzIgnTree; ++pzIgnTree ){
12721273
const char *zIgn = *pzIgnTree;
@@ -1277,18 +1278,19 @@
12771278
}
12781279
}
12791280
}
12801281
*type = SVN_UNKNOWN;
12811282
*zFile = 0;
1283
+ zMainBranch = db_main_branch();
12821284
if( gsvn.lenTrunk==0 ){
1283
- zBranch = "trunk";
1285
+ zBranch = fossil_strdup(zMainBranch);
12841286
*zFile = zPath;
12851287
*type = SVN_TRUNK;
12861288
}else
12871289
if( strncmp(zPath, gsvn.zTrunk, gsvn.lenTrunk-1)==0 ){
12881290
if( zPath[gsvn.lenTrunk-1]=='/' || zPath[gsvn.lenTrunk-1]==0 ){
1289
- zBranch = "trunk";
1291
+ zBranch = fossil_strdup(zMainBranch);
12901292
*zFile = zPath+gsvn.lenTrunk;
12911293
*type = SVN_TRUNK;
12921294
}else{
12931295
zBranch = 0;
12941296
*type = SVN_UNKNOWN;
@@ -1770,11 +1772,11 @@
17701772
*renOpt->varSuf = renOpt->zDefaultSuf;
17711773
}
17721774
}
17731775
}
17741776
if( !(gimport.zTrunkName = find_option("rename-trunk", 0, 1)) ){
1775
- gimport.zTrunkName = "trunk";
1777
+ gimport.zTrunkName = fossil_strdup(db_main_branch());
17761778
}
17771779
17781780
if( svnFlag ){
17791781
/* Get --svn related options here, so verify_all_options() fails when
17801782
* svn-only options are specified with --git
17811783
--- src/import.c
+++ src/import.c
@@ -568,12 +568,12 @@
568 **
569 ** (A) refs/heads/BRANCHNAME
570 ** (B) refs/tags/TAGNAME
571 **
572 ** If pattern A is used, then the branchname used is as shown.
573 ** Except, the "master" branch which is the default branch name in
574 ** Git is changed to "trunk" which is the default name in Fossil.
575 ** If the pattern is B, then the new commit should be on the same
576 ** branch as its parent. And, we might need to add the TAGNAME
577 ** tag to the new commit. However, if there are multiple instances
578 ** of pattern B with the same TAGNAME, then only put the tag on the
579 ** last commit that holds that tag.
@@ -1263,10 +1263,11 @@
1263 ** Return 0 if not a branch, tag, or trunk, or if ignored by --ignore-tree.
1264 */
1265 static int svn_parse_path(char *zPath, char **zFile, int *type){
1266 char *zBranch = 0;
1267 int branchId = 0;
 
1268 if( gsvn.azIgnTree ){
1269 const char **pzIgnTree;
1270 unsigned nPath = strlen(zPath);
1271 for( pzIgnTree = gsvn.azIgnTree; *pzIgnTree; ++pzIgnTree ){
1272 const char *zIgn = *pzIgnTree;
@@ -1277,18 +1278,19 @@
1277 }
1278 }
1279 }
1280 *type = SVN_UNKNOWN;
1281 *zFile = 0;
 
1282 if( gsvn.lenTrunk==0 ){
1283 zBranch = "trunk";
1284 *zFile = zPath;
1285 *type = SVN_TRUNK;
1286 }else
1287 if( strncmp(zPath, gsvn.zTrunk, gsvn.lenTrunk-1)==0 ){
1288 if( zPath[gsvn.lenTrunk-1]=='/' || zPath[gsvn.lenTrunk-1]==0 ){
1289 zBranch = "trunk";
1290 *zFile = zPath+gsvn.lenTrunk;
1291 *type = SVN_TRUNK;
1292 }else{
1293 zBranch = 0;
1294 *type = SVN_UNKNOWN;
@@ -1770,11 +1772,11 @@
1770 *renOpt->varSuf = renOpt->zDefaultSuf;
1771 }
1772 }
1773 }
1774 if( !(gimport.zTrunkName = find_option("rename-trunk", 0, 1)) ){
1775 gimport.zTrunkName = "trunk";
1776 }
1777
1778 if( svnFlag ){
1779 /* Get --svn related options here, so verify_all_options() fails when
1780 * svn-only options are specified with --git
1781
--- src/import.c
+++ src/import.c
@@ -568,12 +568,12 @@
568 **
569 ** (A) refs/heads/BRANCHNAME
570 ** (B) refs/tags/TAGNAME
571 **
572 ** If pattern A is used, then the branchname used is as shown.
573 ** Except, the "master" branch which is the default branch name in Git
574 ** is changed to the default main branch name in Fossil (usually "trunk")
575 ** If the pattern is B, then the new commit should be on the same
576 ** branch as its parent. And, we might need to add the TAGNAME
577 ** tag to the new commit. However, if there are multiple instances
578 ** of pattern B with the same TAGNAME, then only put the tag on the
579 ** last commit that holds that tag.
@@ -1263,10 +1263,11 @@
1263 ** Return 0 if not a branch, tag, or trunk, or if ignored by --ignore-tree.
1264 */
1265 static int svn_parse_path(char *zPath, char **zFile, int *type){
1266 char *zBranch = 0;
1267 int branchId = 0;
1268 const char *zMainBranch;
1269 if( gsvn.azIgnTree ){
1270 const char **pzIgnTree;
1271 unsigned nPath = strlen(zPath);
1272 for( pzIgnTree = gsvn.azIgnTree; *pzIgnTree; ++pzIgnTree ){
1273 const char *zIgn = *pzIgnTree;
@@ -1277,18 +1278,19 @@
1278 }
1279 }
1280 }
1281 *type = SVN_UNKNOWN;
1282 *zFile = 0;
1283 zMainBranch = db_main_branch();
1284 if( gsvn.lenTrunk==0 ){
1285 zBranch = fossil_strdup(zMainBranch);
1286 *zFile = zPath;
1287 *type = SVN_TRUNK;
1288 }else
1289 if( strncmp(zPath, gsvn.zTrunk, gsvn.lenTrunk-1)==0 ){
1290 if( zPath[gsvn.lenTrunk-1]=='/' || zPath[gsvn.lenTrunk-1]==0 ){
1291 zBranch = fossil_strdup(zMainBranch);
1292 *zFile = zPath+gsvn.lenTrunk;
1293 *type = SVN_TRUNK;
1294 }else{
1295 zBranch = 0;
1296 *type = SVN_UNKNOWN;
@@ -1770,11 +1772,11 @@
1772 *renOpt->varSuf = renOpt->zDefaultSuf;
1773 }
1774 }
1775 }
1776 if( !(gimport.zTrunkName = find_option("rename-trunk", 0, 1)) ){
1777 gimport.zTrunkName = fossil_strdup(db_main_branch());
1778 }
1779
1780 if( svnFlag ){
1781 /* Get --svn related options here, so verify_all_options() fails when
1782 * svn-only options are specified with --git
1783
+5 -3
--- src/info.c
+++ src/info.c
@@ -1141,13 +1141,14 @@
11411141
}
11421142
@ %s(zLinks)</td></tr>
11431143
}
11441144
11451145
if( g.perm.Hyperlink ){
1146
+ const char *zMainBranch = db_main_branch();
11461147
@ <tr><th>Other&nbsp;Links:</th>
11471148
@ <td>
1148
- if( fossil_strcmp(zBrName, db_get("main-branch",0))!=0 ){
1149
+ if( fossil_strcmp(zBrName, zMainBranch)!=0 ){
11491150
@ %z(href("%R/vdiff?branch=%!S", zUuid))branch diff</a> |
11501151
}
11511152
@ %z(href("%R/artifact/%!S",zUuid))manifest</a>
11521153
@ | %z(href("%R/ci_tags/%!S",zUuid))tags</a>
11531154
if( g.perm.Admin ){
@@ -3717,10 +3718,11 @@
37173718
style_header("Edit Check-in [%s]", zUuid);
37183719
if( P("preview") ){
37193720
Blob suffix;
37203721
int nTag = 0;
37213722
const char *zDplyBr; /* Branch name used to determine BG color */
3723
+ const char *zMainBranch = db_main_branch();
37223724
if( zNewBrFlag[0] && zNewBranch[0] ){
37233725
zDplyBr = zNewBranch;
37243726
}else{
37253727
zDplyBr = zBranchName;
37263728
}
@@ -3729,11 +3731,11 @@
37293731
@ <table border=0>
37303732
if( zNewColorFlag[0] && zNewColor && zNewColor[0] ){
37313733
@ <tr><td style="background-color:%h(reasonable_bg_color(zNewColor,0));">
37323734
}else if( zColor[0] ){
37333735
@ <tr><td style="background-color:%h(reasonable_bg_color(zColor,0));">
3734
- }else if( zDplyBr && fossil_strcmp(zDplyBr,"trunk")!=0 ){
3736
+ }else if( zDplyBr && fossil_strcmp(zDplyBr, zMainBranch)!=0 ){
37353737
@ <tr><td style="background-color:%h(hash_color(zDplyBr));">
37363738
}else{
37373739
@ <tr><td>
37383740
}
37393741
@ %!W(blob_str(&comment))
@@ -3855,11 +3857,11 @@
38553857
}
38563858
db_finalize(&q);
38573859
@ </td></tr>
38583860
38593861
if( !zBranchName ){
3860
- zBranchName = db_get("main-branch", 0);
3862
+ zBranchName = fossil_strdup(db_main_branch());
38613863
}
38623864
if( !zNewBranch || !zNewBranch[0]){
38633865
zNewBranch = zBranchName;
38643866
}
38653867
@ <tr><th align="right" valign="top">Branching:</th>
38663868
--- src/info.c
+++ src/info.c
@@ -1141,13 +1141,14 @@
1141 }
1142 @ %s(zLinks)</td></tr>
1143 }
1144
1145 if( g.perm.Hyperlink ){
 
1146 @ <tr><th>Other&nbsp;Links:</th>
1147 @ <td>
1148 if( fossil_strcmp(zBrName, db_get("main-branch",0))!=0 ){
1149 @ %z(href("%R/vdiff?branch=%!S", zUuid))branch diff</a> |
1150 }
1151 @ %z(href("%R/artifact/%!S",zUuid))manifest</a>
1152 @ | %z(href("%R/ci_tags/%!S",zUuid))tags</a>
1153 if( g.perm.Admin ){
@@ -3717,10 +3718,11 @@
3717 style_header("Edit Check-in [%s]", zUuid);
3718 if( P("preview") ){
3719 Blob suffix;
3720 int nTag = 0;
3721 const char *zDplyBr; /* Branch name used to determine BG color */
 
3722 if( zNewBrFlag[0] && zNewBranch[0] ){
3723 zDplyBr = zNewBranch;
3724 }else{
3725 zDplyBr = zBranchName;
3726 }
@@ -3729,11 +3731,11 @@
3729 @ <table border=0>
3730 if( zNewColorFlag[0] && zNewColor && zNewColor[0] ){
3731 @ <tr><td style="background-color:%h(reasonable_bg_color(zNewColor,0));">
3732 }else if( zColor[0] ){
3733 @ <tr><td style="background-color:%h(reasonable_bg_color(zColor,0));">
3734 }else if( zDplyBr && fossil_strcmp(zDplyBr,"trunk")!=0 ){
3735 @ <tr><td style="background-color:%h(hash_color(zDplyBr));">
3736 }else{
3737 @ <tr><td>
3738 }
3739 @ %!W(blob_str(&comment))
@@ -3855,11 +3857,11 @@
3855 }
3856 db_finalize(&q);
3857 @ </td></tr>
3858
3859 if( !zBranchName ){
3860 zBranchName = db_get("main-branch", 0);
3861 }
3862 if( !zNewBranch || !zNewBranch[0]){
3863 zNewBranch = zBranchName;
3864 }
3865 @ <tr><th align="right" valign="top">Branching:</th>
3866
--- src/info.c
+++ src/info.c
@@ -1141,13 +1141,14 @@
1141 }
1142 @ %s(zLinks)</td></tr>
1143 }
1144
1145 if( g.perm.Hyperlink ){
1146 const char *zMainBranch = db_main_branch();
1147 @ <tr><th>Other&nbsp;Links:</th>
1148 @ <td>
1149 if( fossil_strcmp(zBrName, zMainBranch)!=0 ){
1150 @ %z(href("%R/vdiff?branch=%!S", zUuid))branch diff</a> |
1151 }
1152 @ %z(href("%R/artifact/%!S",zUuid))manifest</a>
1153 @ | %z(href("%R/ci_tags/%!S",zUuid))tags</a>
1154 if( g.perm.Admin ){
@@ -3717,10 +3718,11 @@
3718 style_header("Edit Check-in [%s]", zUuid);
3719 if( P("preview") ){
3720 Blob suffix;
3721 int nTag = 0;
3722 const char *zDplyBr; /* Branch name used to determine BG color */
3723 const char *zMainBranch = db_main_branch();
3724 if( zNewBrFlag[0] && zNewBranch[0] ){
3725 zDplyBr = zNewBranch;
3726 }else{
3727 zDplyBr = zBranchName;
3728 }
@@ -3729,11 +3731,11 @@
3731 @ <table border=0>
3732 if( zNewColorFlag[0] && zNewColor && zNewColor[0] ){
3733 @ <tr><td style="background-color:%h(reasonable_bg_color(zNewColor,0));">
3734 }else if( zColor[0] ){
3735 @ <tr><td style="background-color:%h(reasonable_bg_color(zColor,0));">
3736 }else if( zDplyBr && fossil_strcmp(zDplyBr, zMainBranch)!=0 ){
3737 @ <tr><td style="background-color:%h(hash_color(zDplyBr));">
3738 }else{
3739 @ <tr><td>
3740 }
3741 @ %!W(blob_str(&comment))
@@ -3855,11 +3857,11 @@
3857 }
3858 db_finalize(&q);
3859 @ </td></tr>
3860
3861 if( !zBranchName ){
3862 zBranchName = fossil_strdup(db_main_branch());
3863 }
3864 if( !zNewBranch || !zNewBranch[0]){
3865 zNewBranch = zBranchName;
3866 }
3867 @ <tr><th align="right" valign="top">Branching:</th>
3868
--- src/json_branch.c
+++ src/json_branch.c
@@ -313,10 +313,11 @@
313313
cson_value * payV = NULL;
314314
cson_object * pay = NULL;
315315
int rc = 0;
316316
BranchCreateOptions opt;
317317
char * zUuid = NULL;
318
+ const char *zMainBranch = db_main_branch();
318319
int rid = 0;
319320
if( !g.perm.Write ){
320321
json_set_err(FSL_JSON_E_DENIED,
321322
"Requires 'i' permissions.");
322323
return NULL;
@@ -340,11 +341,11 @@
340341
opt.zBasis = json_find_option_cstr("basis",NULL,NULL);
341342
if(!opt.zBasis && !g.isHTTP){
342343
opt.zBasis = json_command_arg(g.json.dispatchDepth+2);
343344
}
344345
if(!opt.zBasis){
345
- opt.zBasis = "trunk";
346
+ opt.zBasis = fossil_strdup(zMainBranch);
346347
}
347348
opt.isPrivate = json_find_option_bool("private",NULL,NULL,-1);
348349
if(-1==opt.isPrivate){
349350
if(!g.isHTTP){
350351
opt.isPrivate = (NULL != find_option("private","",0));
351352
--- src/json_branch.c
+++ src/json_branch.c
@@ -313,10 +313,11 @@
313 cson_value * payV = NULL;
314 cson_object * pay = NULL;
315 int rc = 0;
316 BranchCreateOptions opt;
317 char * zUuid = NULL;
 
318 int rid = 0;
319 if( !g.perm.Write ){
320 json_set_err(FSL_JSON_E_DENIED,
321 "Requires 'i' permissions.");
322 return NULL;
@@ -340,11 +341,11 @@
340 opt.zBasis = json_find_option_cstr("basis",NULL,NULL);
341 if(!opt.zBasis && !g.isHTTP){
342 opt.zBasis = json_command_arg(g.json.dispatchDepth+2);
343 }
344 if(!opt.zBasis){
345 opt.zBasis = "trunk";
346 }
347 opt.isPrivate = json_find_option_bool("private",NULL,NULL,-1);
348 if(-1==opt.isPrivate){
349 if(!g.isHTTP){
350 opt.isPrivate = (NULL != find_option("private","",0));
351
--- src/json_branch.c
+++ src/json_branch.c
@@ -313,10 +313,11 @@
313 cson_value * payV = NULL;
314 cson_object * pay = NULL;
315 int rc = 0;
316 BranchCreateOptions opt;
317 char * zUuid = NULL;
318 const char *zMainBranch = db_main_branch();
319 int rid = 0;
320 if( !g.perm.Write ){
321 json_set_err(FSL_JSON_E_DENIED,
322 "Requires 'i' permissions.");
323 return NULL;
@@ -340,11 +341,11 @@
341 opt.zBasis = json_find_option_cstr("basis",NULL,NULL);
342 if(!opt.zBasis && !g.isHTTP){
343 opt.zBasis = json_command_arg(g.json.dispatchDepth+2);
344 }
345 if(!opt.zBasis){
346 opt.zBasis = fossil_strdup(zMainBranch);
347 }
348 opt.isPrivate = json_find_option_bool("private",NULL,NULL,-1);
349 if(-1==opt.isPrivate){
350 if(!g.isHTTP){
351 opt.isPrivate = (NULL != find_option("private","",0));
352
+3 -1
--- src/leaf.c
+++ src/leaf.c
@@ -226,14 +226,16 @@
226226
int leaf_ambiguity_warning(int rid, int currentCkout){
227227
char *zBr;
228228
Stmt q;
229229
int n = 0;
230230
Blob msg;
231
+ const char *zMainBranch;
231232
if( leaf_ambiguity(rid)==0 ) return 0;
233
+ zMainBranch = db_main_branch();
232234
zBr = db_text(0, "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
233235
TAG_BRANCH, rid);
234
- if( zBr==0 ) zBr = fossil_strdup("trunk");
236
+ if( zBr==0 ) zBr = fossil_strdup(zMainBranch);
235237
blob_init(&msg, 0, 0);
236238
blob_appendf(&msg, "WARNING: multiple open leaf check-ins on %s:", zBr);
237239
db_prepare(&q,
238240
"SELECT"
239241
" (SELECT uuid FROM blob WHERE rid=leaf.rid),"
240242
--- src/leaf.c
+++ src/leaf.c
@@ -226,14 +226,16 @@
226 int leaf_ambiguity_warning(int rid, int currentCkout){
227 char *zBr;
228 Stmt q;
229 int n = 0;
230 Blob msg;
 
231 if( leaf_ambiguity(rid)==0 ) return 0;
 
232 zBr = db_text(0, "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
233 TAG_BRANCH, rid);
234 if( zBr==0 ) zBr = fossil_strdup("trunk");
235 blob_init(&msg, 0, 0);
236 blob_appendf(&msg, "WARNING: multiple open leaf check-ins on %s:", zBr);
237 db_prepare(&q,
238 "SELECT"
239 " (SELECT uuid FROM blob WHERE rid=leaf.rid),"
240
--- src/leaf.c
+++ src/leaf.c
@@ -226,14 +226,16 @@
226 int leaf_ambiguity_warning(int rid, int currentCkout){
227 char *zBr;
228 Stmt q;
229 int n = 0;
230 Blob msg;
231 const char *zMainBranch;
232 if( leaf_ambiguity(rid)==0 ) return 0;
233 zMainBranch = db_main_branch();
234 zBr = db_text(0, "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
235 TAG_BRANCH, rid);
236 if( zBr==0 ) zBr = fossil_strdup(zMainBranch);
237 blob_init(&msg, 0, 0);
238 blob_appendf(&msg, "WARNING: multiple open leaf check-ins on %s:", zBr);
239 db_prepare(&q,
240 "SELECT"
241 " (SELECT uuid FROM blob WHERE rid=leaf.rid),"
242
+1
--- src/path.c
+++ src/path.c
@@ -192,10 +192,11 @@
192192
path_reset();
193193
path.brCost = branchCost;
194194
path.pStart = path_new_node(iFrom, 0, 0);
195195
if( iTo==iFrom ){
196196
path.pEnd = path.pStart;
197
+ path.pEnd->u.pTo = 0;
197198
return path.pStart;
198199
}
199200
if( oneWayOnly && directOnly ){
200201
db_prepare(&s,
201202
"SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim"
202203
--- src/path.c
+++ src/path.c
@@ -192,10 +192,11 @@
192 path_reset();
193 path.brCost = branchCost;
194 path.pStart = path_new_node(iFrom, 0, 0);
195 if( iTo==iFrom ){
196 path.pEnd = path.pStart;
 
197 return path.pStart;
198 }
199 if( oneWayOnly && directOnly ){
200 db_prepare(&s,
201 "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim"
202
--- src/path.c
+++ src/path.c
@@ -192,10 +192,11 @@
192 path_reset();
193 path.brCost = branchCost;
194 path.pStart = path_new_node(iFrom, 0, 0);
195 if( iTo==iFrom ){
196 path.pEnd = path.pStart;
197 path.pEnd->u.pTo = 0;
198 return path.pStart;
199 }
200 if( oneWayOnly && directOnly ){
201 db_prepare(&s,
202 "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim"
203
+4 -3
--- src/rebuild.c
+++ src/rebuild.c
@@ -351,11 +351,12 @@
351351
/*
352352
** Check to see if the "sym-trunk" tag exists. If not, create it
353353
** and attach it to the very first check-in.
354354
*/
355355
static void rebuild_tag_trunk(void){
356
- int tagid = db_int(0, "SELECT 1 FROM tag WHERE tagname='sym-trunk'");
356
+ const char *zMainBranch = db_main_branch();
357
+ int tagid = db_int(0, "SELECT 1 FROM tag WHERE tagname='sym-%q'",zMainBranch);
357358
int rid;
358359
char *zUuid;
359360
360361
if( tagid>0 ) return;
361362
rid = db_int(0, "SELECT pid FROM plink AS x WHERE NOT EXISTS("
@@ -363,12 +364,12 @@
363364
if( rid==0 ) return;
364365
365366
/* Add the trunk tag to the root of the whole tree */
366367
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
367368
if( zUuid==0 ) return;
368
- tag_add_artifact("sym-", "trunk", zUuid, 0, 2, 0, 0);
369
- tag_add_artifact("", "branch", zUuid, "trunk", 2, 0, 0);
369
+ tag_add_artifact("sym-", zMainBranch, zUuid, 0, 2, 0, 0);
370
+ tag_add_artifact("", "branch", zUuid, zMainBranch, 2, 0, 0);
370371
}
371372
372373
/*
373374
** Core function to rebuild the information in the derived tables of a
374375
** fossil repository from the blobs. This function is shared between
375376
--- src/rebuild.c
+++ src/rebuild.c
@@ -351,11 +351,12 @@
351 /*
352 ** Check to see if the "sym-trunk" tag exists. If not, create it
353 ** and attach it to the very first check-in.
354 */
355 static void rebuild_tag_trunk(void){
356 int tagid = db_int(0, "SELECT 1 FROM tag WHERE tagname='sym-trunk'");
 
357 int rid;
358 char *zUuid;
359
360 if( tagid>0 ) return;
361 rid = db_int(0, "SELECT pid FROM plink AS x WHERE NOT EXISTS("
@@ -363,12 +364,12 @@
363 if( rid==0 ) return;
364
365 /* Add the trunk tag to the root of the whole tree */
366 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
367 if( zUuid==0 ) return;
368 tag_add_artifact("sym-", "trunk", zUuid, 0, 2, 0, 0);
369 tag_add_artifact("", "branch", zUuid, "trunk", 2, 0, 0);
370 }
371
372 /*
373 ** Core function to rebuild the information in the derived tables of a
374 ** fossil repository from the blobs. This function is shared between
375
--- src/rebuild.c
+++ src/rebuild.c
@@ -351,11 +351,12 @@
351 /*
352 ** Check to see if the "sym-trunk" tag exists. If not, create it
353 ** and attach it to the very first check-in.
354 */
355 static void rebuild_tag_trunk(void){
356 const char *zMainBranch = db_main_branch();
357 int tagid = db_int(0, "SELECT 1 FROM tag WHERE tagname='sym-%q'",zMainBranch);
358 int rid;
359 char *zUuid;
360
361 if( tagid>0 ) return;
362 rid = db_int(0, "SELECT pid FROM plink AS x WHERE NOT EXISTS("
@@ -363,12 +364,12 @@
364 if( rid==0 ) return;
365
366 /* Add the trunk tag to the root of the whole tree */
367 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
368 if( zUuid==0 ) return;
369 tag_add_artifact("sym-", zMainBranch, zUuid, 0, 2, 0, 0);
370 tag_add_artifact("", "branch", zUuid, zMainBranch, 2, 0, 0);
371 }
372
373 /*
374 ** Core function to rebuild the information in the derived tables of a
375 ** fossil repository from the blobs. This function is shared between
376
+4 -2
--- src/search.c
+++ src/search.c
@@ -852,11 +852,12 @@
852852
){
853853
search_init(zPattern, "<mark>", "</mark>", " ... ",
854854
SRCHFLG_STATIC|SRCHFLG_HTML);
855855
if( (srchFlags & SRCH_DOC)!=0 ){
856856
char *zDocGlob = db_get("doc-glob","");
857
- char *zDocBr = db_get("doc-branch","trunk");
857
+ const char *zMainBranch = db_main_branch();
858
+ char *zDocBr = db_get("doc-branch", zMainBranch);
858859
if( zDocGlob && zDocGlob[0] && zDocBr && zDocBr[0] ){
859860
Glob * pGlob = glob_create(zDocBr)
860861
/* We're misusing a Glob as a list of comma-/space-delimited
861862
** tokens. We're not actually doing glob matches here. */;
862863
int i;
@@ -1986,11 +1987,12 @@
19861987
** and if the latest check-in on doc-br is in the unindexed set of
19871988
** check-ins, then update all 'd' entries in FTSDOCS that have
19881989
** changed.
19891990
*/
19901991
static void search_update_doc_index(void){
1991
- const char *zDocBranches = db_get("doc-branch","trunk");
1992
+ const char *zMainBranch = db_main_branch();
1993
+ const char *zDocBranches = db_get("doc-branch", zMainBranch);
19921994
int i;
19931995
Glob * pGlob = glob_create(zDocBranches)
19941996
/* We're misusing a Glob as a list of comma-/space-delimited
19951997
** tokens. We're not actually doing glob matches here. */;
19961998
if( !pGlob ) return;
19971999
--- src/search.c
+++ src/search.c
@@ -852,11 +852,12 @@
852 ){
853 search_init(zPattern, "<mark>", "</mark>", " ... ",
854 SRCHFLG_STATIC|SRCHFLG_HTML);
855 if( (srchFlags & SRCH_DOC)!=0 ){
856 char *zDocGlob = db_get("doc-glob","");
857 char *zDocBr = db_get("doc-branch","trunk");
 
858 if( zDocGlob && zDocGlob[0] && zDocBr && zDocBr[0] ){
859 Glob * pGlob = glob_create(zDocBr)
860 /* We're misusing a Glob as a list of comma-/space-delimited
861 ** tokens. We're not actually doing glob matches here. */;
862 int i;
@@ -1986,11 +1987,12 @@
1986 ** and if the latest check-in on doc-br is in the unindexed set of
1987 ** check-ins, then update all 'd' entries in FTSDOCS that have
1988 ** changed.
1989 */
1990 static void search_update_doc_index(void){
1991 const char *zDocBranches = db_get("doc-branch","trunk");
 
1992 int i;
1993 Glob * pGlob = glob_create(zDocBranches)
1994 /* We're misusing a Glob as a list of comma-/space-delimited
1995 ** tokens. We're not actually doing glob matches here. */;
1996 if( !pGlob ) return;
1997
--- src/search.c
+++ src/search.c
@@ -852,11 +852,12 @@
852 ){
853 search_init(zPattern, "<mark>", "</mark>", " ... ",
854 SRCHFLG_STATIC|SRCHFLG_HTML);
855 if( (srchFlags & SRCH_DOC)!=0 ){
856 char *zDocGlob = db_get("doc-glob","");
857 const char *zMainBranch = db_main_branch();
858 char *zDocBr = db_get("doc-branch", zMainBranch);
859 if( zDocGlob && zDocGlob[0] && zDocBr && zDocBr[0] ){
860 Glob * pGlob = glob_create(zDocBr)
861 /* We're misusing a Glob as a list of comma-/space-delimited
862 ** tokens. We're not actually doing glob matches here. */;
863 int i;
@@ -1986,11 +1987,12 @@
1987 ** and if the latest check-in on doc-br is in the unindexed set of
1988 ** check-ins, then update all 'd' entries in FTSDOCS that have
1989 ** changed.
1990 */
1991 static void search_update_doc_index(void){
1992 const char *zMainBranch = db_main_branch();
1993 const char *zDocBranches = db_get("doc-branch", zMainBranch);
1994 int i;
1995 Glob * pGlob = glob_create(zDocBranches)
1996 /* We're misusing a Glob as a list of comma-/space-delimited
1997 ** tokens. We're not actually doing glob matches here. */;
1998 if( !pGlob ) return;
1999
+5 -2
--- src/setup.c
+++ src/setup.c
@@ -2282,10 +2282,11 @@
22822282
** WEBPAGE: srchsetup
22832283
**
22842284
** Configure the search engine. Requires Admin privilege.
22852285
*/
22862286
void page_srchsetup(){
2287
+ const char *zMainBranch;
22872288
login_check_credentials();
22882289
if( !g.perm.Admin ){
22892290
login_needed(0);
22902291
return;
22912292
}
@@ -2312,13 +2313,15 @@
23122313
@ <tr><td>*<td><td>Search all checked-in files</tr>
23132314
@ <tr><td><i>(blank)</i><td>
23142315
@ <td>Search nothing. (Disables document search).</tr>
23152316
@ </table>
23162317
@ <hr>
2317
- entry_attribute("Document Branches", 20, "doc-branch", "db", "trunk", 0);
2318
+ zMainBranch = db_main_branch();
2319
+ entry_attribute("Document Branches", 20, "doc-branch", "db", zMainBranch, 0);
23182320
@ <p>When searching documents, use the versions of the files found at the
2319
- @ type of the "Document Branches" branch. Recommended value: "trunk".
2321
+ @ type of the "Document Branches" branch. Recommended value: the name of
2322
+ @ the main branch (usually "trunk").
23202323
@ Document search is disabled if blank. It may be a list of branch names
23212324
@ separated by spaces and/or commas.
23222325
@ <hr>
23232326
onoff_attribute("Search Check-in Comments", "search-ci", "sc", 0, 0);
23242327
@ <br>
23252328
--- src/setup.c
+++ src/setup.c
@@ -2282,10 +2282,11 @@
2282 ** WEBPAGE: srchsetup
2283 **
2284 ** Configure the search engine. Requires Admin privilege.
2285 */
2286 void page_srchsetup(){
 
2287 login_check_credentials();
2288 if( !g.perm.Admin ){
2289 login_needed(0);
2290 return;
2291 }
@@ -2312,13 +2313,15 @@
2312 @ <tr><td>*<td><td>Search all checked-in files</tr>
2313 @ <tr><td><i>(blank)</i><td>
2314 @ <td>Search nothing. (Disables document search).</tr>
2315 @ </table>
2316 @ <hr>
2317 entry_attribute("Document Branches", 20, "doc-branch", "db", "trunk", 0);
 
2318 @ <p>When searching documents, use the versions of the files found at the
2319 @ type of the "Document Branches" branch. Recommended value: "trunk".
 
2320 @ Document search is disabled if blank. It may be a list of branch names
2321 @ separated by spaces and/or commas.
2322 @ <hr>
2323 onoff_attribute("Search Check-in Comments", "search-ci", "sc", 0, 0);
2324 @ <br>
2325
--- src/setup.c
+++ src/setup.c
@@ -2282,10 +2282,11 @@
2282 ** WEBPAGE: srchsetup
2283 **
2284 ** Configure the search engine. Requires Admin privilege.
2285 */
2286 void page_srchsetup(){
2287 const char *zMainBranch;
2288 login_check_credentials();
2289 if( !g.perm.Admin ){
2290 login_needed(0);
2291 return;
2292 }
@@ -2312,13 +2313,15 @@
2313 @ <tr><td>*<td><td>Search all checked-in files</tr>
2314 @ <tr><td><i>(blank)</i><td>
2315 @ <td>Search nothing. (Disables document search).</tr>
2316 @ </table>
2317 @ <hr>
2318 zMainBranch = db_main_branch();
2319 entry_attribute("Document Branches", 20, "doc-branch", "db", zMainBranch, 0);
2320 @ <p>When searching documents, use the versions of the files found at the
2321 @ type of the "Document Branches" branch. Recommended value: the name of
2322 @ the main branch (usually "trunk").
2323 @ Document search is disabled if blank. It may be a list of branch names
2324 @ separated by spaces and/or commas.
2325 @ <hr>
2326 onoff_attribute("Search Check-in Comments", "search-ci", "sc", 0, 0);
2327 @ <br>
2328
+12 -8
--- src/tar.c
+++ src/tar.c
@@ -38,10 +38,11 @@
3838
** "_" and "-". Changes are made in-place.
3939
*/
4040
static void sanitize_name(char *zName){
4141
int i;
4242
char c;
43
+ if( zName==0 ) return;
4344
for(i=0; (c = zName[i])!=0; i++){
4445
if( fossil_isupper(c) ){
4546
zName[i] = fossil_tolower(c);
4647
}else if( !fossil_isalnum(c) && c!='_' && c!='-' ){
4748
if( c<=0x7f ){
@@ -77,14 +78,13 @@
7778
}
7879
zName = db_text(0,
7980
"SELECT %Q||"
8081
" strftime('-%%Y%%m%%d%%H%%M%%S-',event.mtime)||"
8182
" substr(blob.uuid,1,10)"
82
- " FROM blob, event LEFT JOIN config"
83
+ " FROM blob, event"
8384
" WHERE blob.rid=%d"
84
- " AND event.objid=%d"
85
- " AND config.name='project-name'",
85
+ " AND event.objid=%d",
8686
zPrefix, rid, rid);
8787
fossil_free(zPrefix);
8888
sanitize_name(zName);
8989
return zName;
9090
}
@@ -884,11 +884,12 @@
884884
** Generate a compressed tarball for the check-in specified by VERSION.
885885
** The tarball is called NAME.tar.gz and has a top-level directory called
886886
** NAME. If TAG is provided, then VERSION must hold TAG or else an error
887887
** is returned.
888888
**
889
-** The optional VERSION element defaults to "trunk" per the r= rules below.
889
+** The optional VERSION element defaults to the name of the main branch
890
+** (usually "trunk") per the r= rules below.
890891
** All of the following URLs are equivalent:
891892
**
892893
** /tarball/release/xyz.tar.gz
893894
** /tarball?r=release&name=xyz.tar.gz
894895
** /tarball/xyz.tar.gz?r=release
@@ -897,23 +898,26 @@
897898
** Query parameters:
898899
**
899900
** name=[CKIN/]NAME The optional CKIN component of the name= parameter
900901
** identifies the check-in from which the tarball is
901902
** constructed. If CKIN is omitted and there is no
902
-** r= query parameter, then use "trunk". NAME is the
903
+** r= query parameter, then use the name of the main
904
+** branch (usually "trunk"). NAME is the
903905
** name of the download file. The top-level directory
904906
** in the generated tarball is called by NAME with the
905907
** file extension removed.
906908
**
907909
** r=TAG TAG identifies the check-in that is turned into a
908
-** compressed tarball. The default value is "trunk".
910
+** compressed tarball. The default value is the name of
911
+** the main branch (usually "trunk").
909912
** If r= is omitted and if the name= query parameter
910913
** contains one "/" character then the of part the
911914
** name= value before the / becomes the TAG and the
912915
** part of the name= value after the / is the download
913916
** filename. If no check-in is specified by either
914
-** name= or r=, then "trunk" is used.
917
+** name= or r=, then the name of the main branch
918
+** (usually "trunk") is used.
915919
**
916920
** in=PATTERN Only include files that match the comma-separate
917921
** list of GLOB patterns in PATTERN, as with ex=
918922
**
919923
** ex=PATTERN Omit any file that match PATTERN. PATTERN is a
@@ -954,11 +958,11 @@
954958
fossil_nice_default();
955959
zName = fossil_strdup(PD("name",""));
956960
z = P("r");
957961
if( z==0 ) z = P("uuid");
958962
if( z==0 ) z = tar_uuid_from_name(&zName);
959
- if( z==0 ) z = "trunk";
963
+ if( z==0 ) z = fossil_strdup(db_main_branch());
960964
g.zOpenRevision = zRid = fossil_strdup(z);
961965
nRid = strlen(zRid);
962966
zInclude = P("in");
963967
if( zInclude ) pInclude = glob_create(zInclude);
964968
zExclude = P("ex");
965969
--- src/tar.c
+++ src/tar.c
@@ -38,10 +38,11 @@
38 ** "_" and "-". Changes are made in-place.
39 */
40 static void sanitize_name(char *zName){
41 int i;
42 char c;
 
43 for(i=0; (c = zName[i])!=0; i++){
44 if( fossil_isupper(c) ){
45 zName[i] = fossil_tolower(c);
46 }else if( !fossil_isalnum(c) && c!='_' && c!='-' ){
47 if( c<=0x7f ){
@@ -77,14 +78,13 @@
77 }
78 zName = db_text(0,
79 "SELECT %Q||"
80 " strftime('-%%Y%%m%%d%%H%%M%%S-',event.mtime)||"
81 " substr(blob.uuid,1,10)"
82 " FROM blob, event LEFT JOIN config"
83 " WHERE blob.rid=%d"
84 " AND event.objid=%d"
85 " AND config.name='project-name'",
86 zPrefix, rid, rid);
87 fossil_free(zPrefix);
88 sanitize_name(zName);
89 return zName;
90 }
@@ -884,11 +884,12 @@
884 ** Generate a compressed tarball for the check-in specified by VERSION.
885 ** The tarball is called NAME.tar.gz and has a top-level directory called
886 ** NAME. If TAG is provided, then VERSION must hold TAG or else an error
887 ** is returned.
888 **
889 ** The optional VERSION element defaults to "trunk" per the r= rules below.
 
890 ** All of the following URLs are equivalent:
891 **
892 ** /tarball/release/xyz.tar.gz
893 ** /tarball?r=release&name=xyz.tar.gz
894 ** /tarball/xyz.tar.gz?r=release
@@ -897,23 +898,26 @@
897 ** Query parameters:
898 **
899 ** name=[CKIN/]NAME The optional CKIN component of the name= parameter
900 ** identifies the check-in from which the tarball is
901 ** constructed. If CKIN is omitted and there is no
902 ** r= query parameter, then use "trunk". NAME is the
 
903 ** name of the download file. The top-level directory
904 ** in the generated tarball is called by NAME with the
905 ** file extension removed.
906 **
907 ** r=TAG TAG identifies the check-in that is turned into a
908 ** compressed tarball. The default value is "trunk".
 
909 ** If r= is omitted and if the name= query parameter
910 ** contains one "/" character then the of part the
911 ** name= value before the / becomes the TAG and the
912 ** part of the name= value after the / is the download
913 ** filename. If no check-in is specified by either
914 ** name= or r=, then "trunk" is used.
 
915 **
916 ** in=PATTERN Only include files that match the comma-separate
917 ** list of GLOB patterns in PATTERN, as with ex=
918 **
919 ** ex=PATTERN Omit any file that match PATTERN. PATTERN is a
@@ -954,11 +958,11 @@
954 fossil_nice_default();
955 zName = fossil_strdup(PD("name",""));
956 z = P("r");
957 if( z==0 ) z = P("uuid");
958 if( z==0 ) z = tar_uuid_from_name(&zName);
959 if( z==0 ) z = "trunk";
960 g.zOpenRevision = zRid = fossil_strdup(z);
961 nRid = strlen(zRid);
962 zInclude = P("in");
963 if( zInclude ) pInclude = glob_create(zInclude);
964 zExclude = P("ex");
965
--- src/tar.c
+++ src/tar.c
@@ -38,10 +38,11 @@
38 ** "_" and "-". Changes are made in-place.
39 */
40 static void sanitize_name(char *zName){
41 int i;
42 char c;
43 if( zName==0 ) return;
44 for(i=0; (c = zName[i])!=0; i++){
45 if( fossil_isupper(c) ){
46 zName[i] = fossil_tolower(c);
47 }else if( !fossil_isalnum(c) && c!='_' && c!='-' ){
48 if( c<=0x7f ){
@@ -77,14 +78,13 @@
78 }
79 zName = db_text(0,
80 "SELECT %Q||"
81 " strftime('-%%Y%%m%%d%%H%%M%%S-',event.mtime)||"
82 " substr(blob.uuid,1,10)"
83 " FROM blob, event"
84 " WHERE blob.rid=%d"
85 " AND event.objid=%d",
 
86 zPrefix, rid, rid);
87 fossil_free(zPrefix);
88 sanitize_name(zName);
89 return zName;
90 }
@@ -884,11 +884,12 @@
884 ** Generate a compressed tarball for the check-in specified by VERSION.
885 ** The tarball is called NAME.tar.gz and has a top-level directory called
886 ** NAME. If TAG is provided, then VERSION must hold TAG or else an error
887 ** is returned.
888 **
889 ** The optional VERSION element defaults to the name of the main branch
890 ** (usually "trunk") per the r= rules below.
891 ** All of the following URLs are equivalent:
892 **
893 ** /tarball/release/xyz.tar.gz
894 ** /tarball?r=release&name=xyz.tar.gz
895 ** /tarball/xyz.tar.gz?r=release
@@ -897,23 +898,26 @@
898 ** Query parameters:
899 **
900 ** name=[CKIN/]NAME The optional CKIN component of the name= parameter
901 ** identifies the check-in from which the tarball is
902 ** constructed. If CKIN is omitted and there is no
903 ** r= query parameter, then use the name of the main
904 ** branch (usually "trunk"). NAME is the
905 ** name of the download file. The top-level directory
906 ** in the generated tarball is called by NAME with the
907 ** file extension removed.
908 **
909 ** r=TAG TAG identifies the check-in that is turned into a
910 ** compressed tarball. The default value is the name of
911 ** the main branch (usually "trunk").
912 ** If r= is omitted and if the name= query parameter
913 ** contains one "/" character then the of part the
914 ** name= value before the / becomes the TAG and the
915 ** part of the name= value after the / is the download
916 ** filename. If no check-in is specified by either
917 ** name= or r=, then the name of the main branch
918 ** (usually "trunk") is used.
919 **
920 ** in=PATTERN Only include files that match the comma-separate
921 ** list of GLOB patterns in PATTERN, as with ex=
922 **
923 ** ex=PATTERN Omit any file that match PATTERN. PATTERN is a
@@ -954,11 +958,11 @@
958 fossil_nice_default();
959 zName = fossil_strdup(PD("name",""));
960 z = P("r");
961 if( z==0 ) z = P("uuid");
962 if( z==0 ) z = tar_uuid_from_name(&zName);
963 if( z==0 ) z = fossil_strdup(db_main_branch());
964 g.zOpenRevision = zRid = fossil_strdup(z);
965 nRid = strlen(zRid);
966 zInclude = P("in");
967 if( zInclude ) pInclude = glob_create(zInclude);
968 zExclude = P("ex");
969
+2 -2
--- src/timeline.c
+++ src/timeline.c
@@ -388,11 +388,11 @@
388388
const char *zStyle; /* Sub-name for classes for the style */
389389
const char *zDateFmt;
390390
int iTableId = timeline_tableid();
391391
int bTimestampLinksToInfo; /* True if timestamp hyperlinks go to the /info
392392
** page rather than the /timeline page */
393
- char *zMainBranch = db_get("main-branch","trunk");
393
+ const char *zMainBranch = db_main_branch();
394394
395395
396396
if( cgi_is_loopback(g.zIpAddr) && db_open_local(0) ){
397397
vid = db_lget_int("checkout", 0);
398398
}
@@ -592,11 +592,11 @@
592592
zBr = branch_of_rid(rid);
593593
if( zBgClr==0 || (tmFlags & TIMELINE_BRCOLOR)!=0 ){
594594
/* If no background color is specified, use a color based on the
595595
** branch name */
596596
if( tmFlags & (TIMELINE_DELTA|TIMELINE_NOCOLOR) ){
597
- }else if( zBr==0 || strcmp(zBr,zMainBranch)==0 ){
597
+ }else if( zBr==0 || strcmp(zBr, zMainBranch)==0 ){
598598
zBgClr = 0;
599599
}else{
600600
zBgClr = hash_color(zBr);
601601
}
602602
}
603603
--- src/timeline.c
+++ src/timeline.c
@@ -388,11 +388,11 @@
388 const char *zStyle; /* Sub-name for classes for the style */
389 const char *zDateFmt;
390 int iTableId = timeline_tableid();
391 int bTimestampLinksToInfo; /* True if timestamp hyperlinks go to the /info
392 ** page rather than the /timeline page */
393 char *zMainBranch = db_get("main-branch","trunk");
394
395
396 if( cgi_is_loopback(g.zIpAddr) && db_open_local(0) ){
397 vid = db_lget_int("checkout", 0);
398 }
@@ -592,11 +592,11 @@
592 zBr = branch_of_rid(rid);
593 if( zBgClr==0 || (tmFlags & TIMELINE_BRCOLOR)!=0 ){
594 /* If no background color is specified, use a color based on the
595 ** branch name */
596 if( tmFlags & (TIMELINE_DELTA|TIMELINE_NOCOLOR) ){
597 }else if( zBr==0 || strcmp(zBr,zMainBranch)==0 ){
598 zBgClr = 0;
599 }else{
600 zBgClr = hash_color(zBr);
601 }
602 }
603
--- src/timeline.c
+++ src/timeline.c
@@ -388,11 +388,11 @@
388 const char *zStyle; /* Sub-name for classes for the style */
389 const char *zDateFmt;
390 int iTableId = timeline_tableid();
391 int bTimestampLinksToInfo; /* True if timestamp hyperlinks go to the /info
392 ** page rather than the /timeline page */
393 const char *zMainBranch = db_main_branch();
394
395
396 if( cgi_is_loopback(g.zIpAddr) && db_open_local(0) ){
397 vid = db_lget_int("checkout", 0);
398 }
@@ -592,11 +592,11 @@
592 zBr = branch_of_rid(rid);
593 if( zBgClr==0 || (tmFlags & TIMELINE_BRCOLOR)!=0 ){
594 /* If no background color is specified, use a color based on the
595 ** branch name */
596 if( tmFlags & (TIMELINE_DELTA|TIMELINE_NOCOLOR) ){
597 }else if( zBr==0 || strcmp(zBr, zMainBranch)==0 ){
598 zBgClr = 0;
599 }else{
600 zBgClr = hash_color(zBr);
601 }
602 }
603
+1 -1
--- src/update.c
+++ src/update.c
@@ -756,11 +756,11 @@
756756
757757
/* Determine the check-in manifest artifact ID. Panic on failure. */
758758
if( zRevision ){
759759
vid = name_to_typed_rid(zRevision, "ci");
760760
}else if( !g.localOpen ){
761
- vid = name_to_typed_rid(db_get("main-branch", 0), "ci");
761
+ vid = name_to_typed_rid(db_main_branch(), "ci");
762762
}else{
763763
vid = db_lget_int("checkout", 0);
764764
if( !is_a_version(vid) ){
765765
if( vid==0 ) return 0;
766766
zRevision = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
767767
--- src/update.c
+++ src/update.c
@@ -756,11 +756,11 @@
756
757 /* Determine the check-in manifest artifact ID. Panic on failure. */
758 if( zRevision ){
759 vid = name_to_typed_rid(zRevision, "ci");
760 }else if( !g.localOpen ){
761 vid = name_to_typed_rid(db_get("main-branch", 0), "ci");
762 }else{
763 vid = db_lget_int("checkout", 0);
764 if( !is_a_version(vid) ){
765 if( vid==0 ) return 0;
766 zRevision = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
767
--- src/update.c
+++ src/update.c
@@ -756,11 +756,11 @@
756
757 /* Determine the check-in manifest artifact ID. Panic on failure. */
758 if( zRevision ){
759 vid = name_to_typed_rid(zRevision, "ci");
760 }else if( !g.localOpen ){
761 vid = name_to_typed_rid(db_main_branch(), "ci");
762 }else{
763 vid = db_lget_int("checkout", 0);
764 if( !is_a_version(vid) ){
765 if( vid==0 ) return 0;
766 zRevision = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
767
+9 -5
--- src/zip.c
+++ src/zip.c
@@ -953,11 +953,12 @@
953953
**
954954
** Generate a ZIP Archive or an SQL Archive for the check-in specified by
955955
** VERSION. The archive is called NAME.zip or NAME.sqlar and has a top-level
956956
** directory called NAME.
957957
**
958
-** The optional VERSION element defaults to "trunk" per the r= rules below.
958
+** The optional VERSION element defaults to the name of the main branch
959
+** (usually "trunk") per the r= rules below.
959960
** All of the following URLs are equivalent:
960961
**
961962
** /zip/release/xyz.zip
962963
** /zip?r=release&name=xyz.zip
963964
** /zip/xyz.zip?r=release
@@ -966,23 +967,26 @@
966967
** Query parameters:
967968
**
968969
** name=[CKIN/]NAME The optional CKIN component of the name= parameter
969970
** identifies the check-in from which the archive is
970971
** constructed. If CKIN is omitted and there is no
971
-** r= query parameter, then use "trunk". NAME is the
972
+** r= query parameter, then use the name of the main
973
+** branch (usually "trunk"). NAME is the
972974
** name of the download file. The top-level directory
973975
** in the generated archive is called by NAME with the
974976
** file extension removed.
975977
**
976978
** r=TAG TAG identifies the check-in that is turned into an
977
-** SQL or ZIP archive. The default value is "trunk".
979
+** SQL or ZIP archive. The default value is the name
980
+** of the main branch (usually "trunk").
978981
** If r= is omitted and if the name= query parameter
979982
** contains one "/" character then the of part the
980983
** name= value before the / becomes the TAG and the
981984
** part of the name= value after the / is the download
982985
** filename. If no check-in is specified by either
983
-** name= or r=, then "trunk" is used.
986
+** name= or r=, then the name of the main branch
987
+** (usually "trunk") is used.
984988
**
985989
** in=PATTERN Only include files that match the comma-separate
986990
** list of GLOB patterns in PATTERN, as with ex=
987991
**
988992
** ex=PATTERN Omit any file that match PATTERN. PATTERN is a
@@ -1032,11 +1036,11 @@
10321036
fossil_nice_default();
10331037
zName = fossil_strdup(PD("name",""));
10341038
z = P("r");
10351039
if( z==0 ) z = P("uuid");
10361040
if( z==0 ) z = tar_uuid_from_name(&zName);
1037
- if( z==0 ) z = "trunk";
1041
+ if( z==0 ) z = fossil_strdup(db_main_branch());
10381042
nName = strlen(zName);
10391043
g.zOpenRevision = zRid = fossil_strdup(z);
10401044
nRid = strlen(zRid);
10411045
zInclude = P("in");
10421046
if( zInclude ) pInclude = glob_create(zInclude);
10431047
--- src/zip.c
+++ src/zip.c
@@ -953,11 +953,12 @@
953 **
954 ** Generate a ZIP Archive or an SQL Archive for the check-in specified by
955 ** VERSION. The archive is called NAME.zip or NAME.sqlar and has a top-level
956 ** directory called NAME.
957 **
958 ** The optional VERSION element defaults to "trunk" per the r= rules below.
 
959 ** All of the following URLs are equivalent:
960 **
961 ** /zip/release/xyz.zip
962 ** /zip?r=release&name=xyz.zip
963 ** /zip/xyz.zip?r=release
@@ -966,23 +967,26 @@
966 ** Query parameters:
967 **
968 ** name=[CKIN/]NAME The optional CKIN component of the name= parameter
969 ** identifies the check-in from which the archive is
970 ** constructed. If CKIN is omitted and there is no
971 ** r= query parameter, then use "trunk". NAME is the
 
972 ** name of the download file. The top-level directory
973 ** in the generated archive is called by NAME with the
974 ** file extension removed.
975 **
976 ** r=TAG TAG identifies the check-in that is turned into an
977 ** SQL or ZIP archive. The default value is "trunk".
 
978 ** If r= is omitted and if the name= query parameter
979 ** contains one "/" character then the of part the
980 ** name= value before the / becomes the TAG and the
981 ** part of the name= value after the / is the download
982 ** filename. If no check-in is specified by either
983 ** name= or r=, then "trunk" is used.
 
984 **
985 ** in=PATTERN Only include files that match the comma-separate
986 ** list of GLOB patterns in PATTERN, as with ex=
987 **
988 ** ex=PATTERN Omit any file that match PATTERN. PATTERN is a
@@ -1032,11 +1036,11 @@
1032 fossil_nice_default();
1033 zName = fossil_strdup(PD("name",""));
1034 z = P("r");
1035 if( z==0 ) z = P("uuid");
1036 if( z==0 ) z = tar_uuid_from_name(&zName);
1037 if( z==0 ) z = "trunk";
1038 nName = strlen(zName);
1039 g.zOpenRevision = zRid = fossil_strdup(z);
1040 nRid = strlen(zRid);
1041 zInclude = P("in");
1042 if( zInclude ) pInclude = glob_create(zInclude);
1043
--- src/zip.c
+++ src/zip.c
@@ -953,11 +953,12 @@
953 **
954 ** Generate a ZIP Archive or an SQL Archive for the check-in specified by
955 ** VERSION. The archive is called NAME.zip or NAME.sqlar and has a top-level
956 ** directory called NAME.
957 **
958 ** The optional VERSION element defaults to the name of the main branch
959 ** (usually "trunk") per the r= rules below.
960 ** All of the following URLs are equivalent:
961 **
962 ** /zip/release/xyz.zip
963 ** /zip?r=release&name=xyz.zip
964 ** /zip/xyz.zip?r=release
@@ -966,23 +967,26 @@
967 ** Query parameters:
968 **
969 ** name=[CKIN/]NAME The optional CKIN component of the name= parameter
970 ** identifies the check-in from which the archive is
971 ** constructed. If CKIN is omitted and there is no
972 ** r= query parameter, then use the name of the main
973 ** branch (usually "trunk"). NAME is the
974 ** name of the download file. The top-level directory
975 ** in the generated archive is called by NAME with the
976 ** file extension removed.
977 **
978 ** r=TAG TAG identifies the check-in that is turned into an
979 ** SQL or ZIP archive. The default value is the name
980 ** of the main branch (usually "trunk").
981 ** If r= is omitted and if the name= query parameter
982 ** contains one "/" character then the of part the
983 ** name= value before the / becomes the TAG and the
984 ** part of the name= value after the / is the download
985 ** filename. If no check-in is specified by either
986 ** name= or r=, then the name of the main branch
987 ** (usually "trunk") is used.
988 **
989 ** in=PATTERN Only include files that match the comma-separate
990 ** list of GLOB patterns in PATTERN, as with ex=
991 **
992 ** ex=PATTERN Omit any file that match PATTERN. PATTERN is a
@@ -1032,11 +1036,11 @@
1036 fossil_nice_default();
1037 zName = fossil_strdup(PD("name",""));
1038 z = P("r");
1039 if( z==0 ) z = P("uuid");
1040 if( z==0 ) z = tar_uuid_from_name(&zName);
1041 if( z==0 ) z = fossil_strdup(db_main_branch());
1042 nName = strlen(zName);
1043 g.zOpenRevision = zRid = fossil_strdup(z);
1044 nRid = strlen(zRid);
1045 zInclude = P("in");
1046 if( zInclude ) pInclude = glob_create(zInclude);
1047
--- tools/email-sender.tcl
+++ tools/email-sender.tcl
@@ -3,11 +3,11 @@
33
# Monitor the database file named by the DBFILE variable
44
# looking for email messages sent by Fossil. Forward each
55
# to /usr/sbin/sendmail.
66
#
77
set POLLING_INTERVAL 10000 ;# milliseconds
8
-set DBFILE /home/www/fossil/emailqueue.db
8
+set DBFILE /home/www/data/emailqueue.db
99
set PIPE "/usr/sbin/sendmail -ti"
1010
1111
package require sqlite3
1212
# puts "SQLite version [sqlite3 -version]"
1313
sqlite3 db $DBFILE
@@ -16,26 +16,50 @@
1616
db eval {
1717
CREATE TABLE IF NOT EXISTS email(
1818
emailid INTEGER PRIMARY KEY,
1919
msg TXT
2020
);
21
+ CREATE TABLE IF NOT EXISTS sentlog(
22
+ mtime INT,
23
+ xto TEXT,
24
+ xfrom TEXT,
25
+ xsubject TEXT,
26
+ xsize INT
27
+ );
2128
}
29
+set ctr 0
2230
while {1} {
31
+ set n 0
2332
db transaction immediate {
24
- set n 0
25
- db eval {SELECT msg FROM email} {
33
+ set emailid 0
34
+ db eval {SELECT emailid, msg FROM email LIMIT 1} {
2635
set pipe $PIPE
27
- if {[regexp {\nFrom:[^\n]*<([^>]+)>} $msg all addr]} {
28
- append pipe " -f $addr"
36
+ set to unk
37
+ set subject none
38
+ set size [string length $msg]
39
+ regexp {To:[^\n]*<([^>]+)>} $msg all to
40
+ regexp {\nSubject:[ ]*([^\r\n]+)} $msg all subject
41
+ set subject [string trim $subject]
42
+ if {[regexp {\nFrom:[^\n]*<([^>]+)>} $msg all from]} {
43
+ append pipe " -f $from"
2944
}
3045
set out [open |$pipe w]
3146
puts -nonewline $out $msg
3247
flush $out
3348
close $out
3449
incr n
50
+ incr ctr
3551
}
3652
if {$n>0} {
37
- db eval {DELETE FROM email}
53
+ db eval {DELETE FROM email WHERE emailid=$emailid}
54
+ db eval {INSERT INTO sentlog(mtime,xto,xfrom,xsubject,xsize)
55
+ VALUES(unixepoch(),$to,$from,$subject,$size)}
3856
}
3957
}
40
- after $POLLING_INTERVAL
58
+ if {$n==0} {
59
+ if {$ctr>100} {
60
+ db eval {DELETE FROM sentlog WHERE mtime<unixepoch('now','-30 days')}
61
+ set ctr 0
62
+ }
63
+ after $POLLING_INTERVAL
64
+ }
4165
}
4266
--- tools/email-sender.tcl
+++ tools/email-sender.tcl
@@ -3,11 +3,11 @@
3 # Monitor the database file named by the DBFILE variable
4 # looking for email messages sent by Fossil. Forward each
5 # to /usr/sbin/sendmail.
6 #
7 set POLLING_INTERVAL 10000 ;# milliseconds
8 set DBFILE /home/www/fossil/emailqueue.db
9 set PIPE "/usr/sbin/sendmail -ti"
10
11 package require sqlite3
12 # puts "SQLite version [sqlite3 -version]"
13 sqlite3 db $DBFILE
@@ -16,26 +16,50 @@
16 db eval {
17 CREATE TABLE IF NOT EXISTS email(
18 emailid INTEGER PRIMARY KEY,
19 msg TXT
20 );
 
 
 
 
 
 
 
21 }
 
22 while {1} {
 
23 db transaction immediate {
24 set n 0
25 db eval {SELECT msg FROM email} {
26 set pipe $PIPE
27 if {[regexp {\nFrom:[^\n]*<([^>]+)>} $msg all addr]} {
28 append pipe " -f $addr"
 
 
 
 
 
 
29 }
30 set out [open |$pipe w]
31 puts -nonewline $out $msg
32 flush $out
33 close $out
34 incr n
 
35 }
36 if {$n>0} {
37 db eval {DELETE FROM email}
 
 
38 }
39 }
40 after $POLLING_INTERVAL
 
 
 
 
 
 
41 }
42
--- tools/email-sender.tcl
+++ tools/email-sender.tcl
@@ -3,11 +3,11 @@
3 # Monitor the database file named by the DBFILE variable
4 # looking for email messages sent by Fossil. Forward each
5 # to /usr/sbin/sendmail.
6 #
7 set POLLING_INTERVAL 10000 ;# milliseconds
8 set DBFILE /home/www/data/emailqueue.db
9 set PIPE "/usr/sbin/sendmail -ti"
10
11 package require sqlite3
12 # puts "SQLite version [sqlite3 -version]"
13 sqlite3 db $DBFILE
@@ -16,26 +16,50 @@
16 db eval {
17 CREATE TABLE IF NOT EXISTS email(
18 emailid INTEGER PRIMARY KEY,
19 msg TXT
20 );
21 CREATE TABLE IF NOT EXISTS sentlog(
22 mtime INT,
23 xto TEXT,
24 xfrom TEXT,
25 xsubject TEXT,
26 xsize INT
27 );
28 }
29 set ctr 0
30 while {1} {
31 set n 0
32 db transaction immediate {
33 set emailid 0
34 db eval {SELECT emailid, msg FROM email LIMIT 1} {
35 set pipe $PIPE
36 set to unk
37 set subject none
38 set size [string length $msg]
39 regexp {To:[^\n]*<([^>]+)>} $msg all to
40 regexp {\nSubject:[ ]*([^\r\n]+)} $msg all subject
41 set subject [string trim $subject]
42 if {[regexp {\nFrom:[^\n]*<([^>]+)>} $msg all from]} {
43 append pipe " -f $from"
44 }
45 set out [open |$pipe w]
46 puts -nonewline $out $msg
47 flush $out
48 close $out
49 incr n
50 incr ctr
51 }
52 if {$n>0} {
53 db eval {DELETE FROM email WHERE emailid=$emailid}
54 db eval {INSERT INTO sentlog(mtime,xto,xfrom,xsubject,xsize)
55 VALUES(unixepoch(),$to,$from,$subject,$size)}
56 }
57 }
58 if {$n==0} {
59 if {$ctr>100} {
60 db eval {DELETE FROM sentlog WHERE mtime<unixepoch('now','-30 days')}
61 set ctr 0
62 }
63 after $POLLING_INTERVAL
64 }
65 }
66
+2 -3
--- www/alerts.md
+++ www/alerts.md
@@ -390,13 +390,12 @@
390390
391391
When you configure a Fossil server this way, it adds outgoing email
392392
messages to an SQLite database file. A separate daemon process can then
393393
extract those messages for further disposition.
394394
395
-Fossil includes a copy of [the daemon](/file/tools/email-sender.tcl)
396
-used on `fossil-scm.org`: it is just a short Tcl script that
397
-continuously monitors this database for new messages and hands any that
395
+Fossil uses a short TCL script (seen at [](/file/tools/email-sender.tcl))
396
+that continuously monitors this database for new messages and hands any that
398397
it finds off to a local MTA using the same [pipe to MTA protocol](#pipe)
399398
as above.
400399
401400
In this way, outbound email alerts escape the chroot jail without
402401
requiring that we insert a separate MTA configuration inside that jail.
403402
--- www/alerts.md
+++ www/alerts.md
@@ -390,13 +390,12 @@
390
391 When you configure a Fossil server this way, it adds outgoing email
392 messages to an SQLite database file. A separate daemon process can then
393 extract those messages for further disposition.
394
395 Fossil includes a copy of [the daemon](/file/tools/email-sender.tcl)
396 used on `fossil-scm.org`: it is just a short Tcl script that
397 continuously monitors this database for new messages and hands any that
398 it finds off to a local MTA using the same [pipe to MTA protocol](#pipe)
399 as above.
400
401 In this way, outbound email alerts escape the chroot jail without
402 requiring that we insert a separate MTA configuration inside that jail.
403
--- www/alerts.md
+++ www/alerts.md
@@ -390,13 +390,12 @@
390
391 When you configure a Fossil server this way, it adds outgoing email
392 messages to an SQLite database file. A separate daemon process can then
393 extract those messages for further disposition.
394
395 Fossil uses a short TCL script (seen at [](/file/tools/email-sender.tcl))
396 that continuously monitors this database for new messages and hands any that
 
397 it finds off to a local MTA using the same [pipe to MTA protocol](#pipe)
398 as above.
399
400 In this way, outbound email alerts escape the chroot jail without
401 requiring that we insert a separate MTA configuration inside that jail.
402

Keyboard Shortcuts

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