Fossil SCM

Merge from trunk

brickviking 2024-12-16 03:20 bv-corrections01 merge
Commit 0fc2f3d95beffbf47df1f905637e87ba03eeebe66aadeb039284b6bcc37c297d
+409 -67
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -457,14 +457,24 @@
457457
** that into UTF-8. Otherwise, non-ASCII characters all get translated
458458
** into '?'.
459459
*/
460460
wchar_t *b1 = sqlite3_malloc( sz*sizeof(wchar_t) );
461461
if( b1==0 ) return 0;
462
- _setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT);
463
- if( fgetws(b1, sz/4, in)==0 ){
464
- sqlite3_free(b1);
465
- return 0;
462
+#ifndef SQLITE_USE_STDIO_FOR_CONSOLE
463
+ DWORD nRead = 0;
464
+ if( IsConsole(in)
465
+ && ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), b1, sz, &nRead, 0)
466
+ ){
467
+ b1[nRead] = 0;
468
+ }else
469
+#endif
470
+ {
471
+ _setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT);
472
+ if( fgetws(b1, sz/4, in)==0 ){
473
+ sqlite3_free(b1);
474
+ return 0;
475
+ }
466476
}
467477
WideCharToMultiByte(CP_UTF8, 0, b1, -1, buf, sz, 0, 0);
468478
sqlite3_free(b1);
469479
return buf;
470480
}else{
@@ -516,24 +526,37 @@
516526
if( !UseWtextForOutput(out) ){
517527
/* Writing to a file or other destination, just write bytes without
518528
** any translation. */
519529
return fputs(z, out);
520530
}else{
521
- /* When writing to the command-prompt in Windows, it is necessary
522
- ** to use O_U8TEXT to render Unicode U+0080 and greater. Go ahead
523
- ** use O_U8TEXT for everything in text mode.
531
+ /* One must use UTF16 in order to get unicode support when writing
532
+ ** to the console on Windows.
524533
*/
525534
int sz = (int)strlen(z);
526535
wchar_t *b1 = sqlite3_malloc( (sz+1)*sizeof(wchar_t) );
527536
if( b1==0 ) return 0;
528537
sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz);
529538
b1[sz] = 0;
530
- _setmode(_fileno(out), _O_U8TEXT);
531
- if( UseBinaryWText(out) ){
532
- piecemealOutput(b1, sz, out);
533
- }else{
534
- fputws(b1, out);
539
+
540
+#ifndef SQLITE_STDIO_FOR_CONSOLE
541
+ DWORD nWr = 0;
542
+ if( IsConsole(out)
543
+ && WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),b1,sz,&nWr,0)
544
+ ){
545
+ /* If writing to the console, then the WriteConsoleW() is all we
546
+ ** need to do. */
547
+ }else
548
+#endif
549
+ {
550
+ /* For non-console I/O, or if SQLITE_USE_STDIO_FOR_CONSOLE is defined
551
+ ** then write using the standard library. */
552
+ _setmode(_fileno(out), _O_U8TEXT);
553
+ if( UseBinaryWText(out) ){
554
+ piecemealOutput(b1, sz, out);
555
+ }else{
556
+ fputws(b1, out);
557
+ }
535558
}
536559
sqlite3_free(b1);
537560
return 0;
538561
}
539562
}
@@ -2344,11 +2367,11 @@
23442367
**
23452368
******************************************************************************
23462369
**
23472370
** This SQLite extension implements functions that compute SHA3 hashes
23482371
** in the way described by the (U.S.) NIST FIPS 202 SHA-3 Standard.
2349
-** Two SQL functions are implemented:
2372
+** Three SQL functions are implemented:
23502373
**
23512374
** sha3(X,SIZE)
23522375
** sha3_agg(Y,SIZE)
23532376
** sha3_query(Z,SIZE)
23542377
**
@@ -14170,11 +14193,11 @@
1417014193
/* A view. Or a trigger on a view. */
1417114194
if( zSql ) rc = expertSchemaSql(p->dbv, zSql, pzErrmsg);
1417214195
}else{
1417314196
IdxTable *pTab;
1417414197
rc = idxGetTableInfo(p->db, zName, &pTab, pzErrmsg);
14175
- if( rc==SQLITE_OK ){
14198
+ if( rc==SQLITE_OK && ALWAYS(pTab!=0) ){
1417614199
int i;
1417714200
char *zInner = 0;
1417814201
char *zOuter = 0;
1417914202
pTab->pNext = p->pTable;
1418014203
p->pTable = pTab;
@@ -16238,11 +16261,31 @@
1623816261
**
1623916262
** Similar compiler commands will work on different systems. The key
1624016263
** invariants are (1) you must have -DSQLITE_ENABLE_VFSTRACE so that
1624116264
** the shell.c source file will know to include the -vfstrace command-line
1624216265
** option and (2) you must compile and link the three source files
16243
-** shell,c, test_vfstrace.c, and sqlite3.c.
16266
+** shell,c, test_vfstrace.c, and sqlite3.c.
16267
+**
16268
+** RUNTIME CONTROL OF VFSTRACE OUTPUT
16269
+**
16270
+** The application can use the "vfstrace" pragma to control which VFS
16271
+** APIs are traced. To disable all output:
16272
+**
16273
+** PRAGMA vfstrace('-all');
16274
+**
16275
+** To enable all output (which is the default setting):
16276
+**
16277
+** PRAGMA vfstrace('+all');
16278
+**
16279
+** Individual APIs can be enabled or disabled by name, with or without
16280
+** the initial "x" character. For example, to set up for tracing lock
16281
+** primatives only:
16282
+**
16283
+** PRAGMA vfstrace('-all, +Lock,Unlock,ShmLock');
16284
+**
16285
+** The argument to the vfstrace pragma ignores capitalization and any
16286
+** characters other than alphabetics, '+', and '-'.
1624416287
*/
1624516288
#include <stdlib.h>
1624616289
#include <string.h>
1624716290
/* #include "sqlite3.h" */
1624816291
@@ -16252,10 +16295,12 @@
1625216295
*/
1625316296
typedef struct vfstrace_info vfstrace_info;
1625416297
struct vfstrace_info {
1625516298
sqlite3_vfs *pRootVfs; /* The underlying real VFS */
1625616299
int (*xOut)(const char*, void*); /* Send output here */
16300
+ unsigned int mTrace; /* Mask of interfaces to trace */
16301
+ u8 bOn; /* Tracing on/off */
1625716302
void *pOutArg; /* First argument to xOut */
1625816303
const char *zVfsName; /* Name of this trace-VFS */
1625916304
sqlite3_vfs *pTraceVfs; /* Pointer back to the trace VFS */
1626016305
};
1626116306
@@ -16268,10 +16313,42 @@
1626816313
vfstrace_info *pInfo; /* The trace-VFS to which this file belongs */
1626916314
const char *zFName; /* Base name of the file */
1627016315
sqlite3_file *pReal; /* The real underlying file */
1627116316
};
1627216317
16318
+/*
16319
+** Bit values for vfstrace_info.mTrace.
16320
+*/
16321
+#define VTR_CLOSE 0x00000001
16322
+#define VTR_READ 0x00000002
16323
+#define VTR_WRITE 0x00000004
16324
+#define VTR_TRUNC 0x00000008
16325
+#define VTR_SYNC 0x00000010
16326
+#define VTR_FSIZE 0x00000020
16327
+#define VTR_LOCK 0x00000040
16328
+#define VTR_UNLOCK 0x00000080
16329
+#define VTR_CRL 0x00000100
16330
+#define VTR_FCTRL 0x00000200
16331
+#define VTR_SECSZ 0x00000400
16332
+#define VTR_DEVCHAR 0x00000800
16333
+#define VTR_SHMLOCK 0x00001000
16334
+#define VTR_SHMMAP 0x00002000
16335
+#define VTR_SHMBAR 0x00004000
16336
+#define VTR_SHMUNMAP 0x00008000
16337
+#define VTR_OPEN 0x00010000
16338
+#define VTR_DELETE 0x00020000
16339
+#define VTR_ACCESS 0x00040000
16340
+#define VTR_FULLPATH 0x00080000
16341
+#define VTR_DLOPEN 0x00100000
16342
+#define VTR_DLERR 0x00200000
16343
+#define VTR_DLSYM 0x00400000
16344
+#define VTR_DLCLOSE 0x00800000
16345
+#define VTR_RAND 0x01000000
16346
+#define VTR_SLEEP 0x02000000
16347
+#define VTR_CURTIME 0x04000000
16348
+#define VTR_LASTERR 0x08000000
16349
+
1627316350
/*
1627416351
** Method declarations for vfstrace_file.
1627516352
*/
1627616353
static int vfstraceClose(sqlite3_file*);
1627716354
static int vfstraceRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
@@ -16332,15 +16409,17 @@
1633216409
const char *zFormat,
1633316410
...
1633416411
){
1633516412
va_list ap;
1633616413
char *zMsg;
16337
- va_start(ap, zFormat);
16338
- zMsg = sqlite3_vmprintf(zFormat, ap);
16339
- va_end(ap);
16340
- pInfo->xOut(zMsg, pInfo->pOutArg);
16341
- sqlite3_free(zMsg);
16414
+ if( pInfo->bOn ){
16415
+ va_start(ap, zFormat);
16416
+ zMsg = sqlite3_vmprintf(zFormat, ap);
16417
+ va_end(ap);
16418
+ pInfo->xOut(zMsg, pInfo->pOutArg);
16419
+ sqlite3_free(zMsg);
16420
+ }
1634216421
}
1634316422
1634416423
/*
1634516424
** Try to convert an error code into a symbolic name for that error code.
1634616425
*/
@@ -16434,18 +16513,26 @@
1643416513
int i = *pI;
1643516514
while( zAppend[0] ){ z[i++] = *(zAppend++); }
1643616515
z[i] = 0;
1643716516
*pI = i;
1643816517
}
16518
+
16519
+/*
16520
+** Turn tracing output on or off according to mMask.
16521
+*/
16522
+static void vfstraceOnOff(vfstrace_info *pInfo, unsigned int mMask){
16523
+ pInfo->bOn = (pInfo->mTrace & mMask)!=0;
16524
+}
1643916525
1644016526
/*
1644116527
** Close an vfstrace-file.
1644216528
*/
1644316529
static int vfstraceClose(sqlite3_file *pFile){
1644416530
vfstrace_file *p = (vfstrace_file *)pFile;
1644516531
vfstrace_info *pInfo = p->pInfo;
1644616532
int rc;
16533
+ vfstraceOnOff(pInfo, VTR_CLOSE);
1644716534
vfstrace_printf(pInfo, "%s.xClose(%s)", pInfo->zVfsName, p->zFName);
1644816535
rc = p->pReal->pMethods->xClose(p->pReal);
1644916536
vfstrace_print_errcode(pInfo, " -> %s\n", rc);
1645016537
if( rc==SQLITE_OK ){
1645116538
sqlite3_free((void*)p->base.pMethods);
@@ -16464,10 +16551,11 @@
1646416551
sqlite_int64 iOfst
1646516552
){
1646616553
vfstrace_file *p = (vfstrace_file *)pFile;
1646716554
vfstrace_info *pInfo = p->pInfo;
1646816555
int rc;
16556
+ vfstraceOnOff(pInfo, VTR_READ);
1646916557
vfstrace_printf(pInfo, "%s.xRead(%s,n=%d,ofst=%lld)",
1647016558
pInfo->zVfsName, p->zFName, iAmt, iOfst);
1647116559
rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
1647216560
vfstrace_print_errcode(pInfo, " -> %s\n", rc);
1647316561
return rc;
@@ -16483,10 +16571,11 @@
1648316571
sqlite_int64 iOfst
1648416572
){
1648516573
vfstrace_file *p = (vfstrace_file *)pFile;
1648616574
vfstrace_info *pInfo = p->pInfo;
1648716575
int rc;
16576
+ vfstraceOnOff(pInfo, VTR_WRITE);
1648816577
vfstrace_printf(pInfo, "%s.xWrite(%s,n=%d,ofst=%lld)",
1648916578
pInfo->zVfsName, p->zFName, iAmt, iOfst);
1649016579
rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
1649116580
vfstrace_print_errcode(pInfo, " -> %s\n", rc);
1649216581
return rc;
@@ -16497,10 +16586,11 @@
1649716586
*/
1649816587
static int vfstraceTruncate(sqlite3_file *pFile, sqlite_int64 size){
1649916588
vfstrace_file *p = (vfstrace_file *)pFile;
1650016589
vfstrace_info *pInfo = p->pInfo;
1650116590
int rc;
16591
+ vfstraceOnOff(pInfo, VTR_TRUNC);
1650216592
vfstrace_printf(pInfo, "%s.xTruncate(%s,%lld)", pInfo->zVfsName, p->zFName,
1650316593
size);
1650416594
rc = p->pReal->pMethods->xTruncate(p->pReal, size);
1650516595
vfstrace_printf(pInfo, " -> %d\n", rc);
1650616596
return rc;
@@ -16521,10 +16611,11 @@
1652116611
else if( flags & SQLITE_SYNC_NORMAL ) strappend(zBuf, &i, "|NORMAL");
1652216612
if( flags & SQLITE_SYNC_DATAONLY ) strappend(zBuf, &i, "|DATAONLY");
1652316613
if( flags & ~(SQLITE_SYNC_FULL|SQLITE_SYNC_DATAONLY) ){
1652416614
sqlite3_snprintf(sizeof(zBuf)-i, &zBuf[i], "|0x%x", flags);
1652516615
}
16616
+ vfstraceOnOff(pInfo, VTR_SYNC);
1652616617
vfstrace_printf(pInfo, "%s.xSync(%s,%s)", pInfo->zVfsName, p->zFName,
1652716618
&zBuf[1]);
1652816619
rc = p->pReal->pMethods->xSync(p->pReal, flags);
1652916620
vfstrace_printf(pInfo, " -> %d\n", rc);
1653016621
return rc;
@@ -16535,10 +16626,11 @@
1653516626
*/
1653616627
static int vfstraceFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
1653716628
vfstrace_file *p = (vfstrace_file *)pFile;
1653816629
vfstrace_info *pInfo = p->pInfo;
1653916630
int rc;
16631
+ vfstraceOnOff(pInfo, VTR_FSIZE);
1654016632
vfstrace_printf(pInfo, "%s.xFileSize(%s)", pInfo->zVfsName, p->zFName);
1654116633
rc = p->pReal->pMethods->xFileSize(p->pReal, pSize);
1654216634
vfstrace_print_errcode(pInfo, " -> %s,", rc);
1654316635
vfstrace_printf(pInfo, " size=%lld\n", *pSize);
1654416636
return rc;
@@ -16563,10 +16655,11 @@
1656316655
*/
1656416656
static int vfstraceLock(sqlite3_file *pFile, int eLock){
1656516657
vfstrace_file *p = (vfstrace_file *)pFile;
1656616658
vfstrace_info *pInfo = p->pInfo;
1656716659
int rc;
16660
+ vfstraceOnOff(pInfo, VTR_LOCK);
1656816661
vfstrace_printf(pInfo, "%s.xLock(%s,%s)", pInfo->zVfsName, p->zFName,
1656916662
lockName(eLock));
1657016663
rc = p->pReal->pMethods->xLock(p->pReal, eLock);
1657116664
vfstrace_print_errcode(pInfo, " -> %s\n", rc);
1657216665
return rc;
@@ -16577,10 +16670,11 @@
1657716670
*/
1657816671
static int vfstraceUnlock(sqlite3_file *pFile, int eLock){
1657916672
vfstrace_file *p = (vfstrace_file *)pFile;
1658016673
vfstrace_info *pInfo = p->pInfo;
1658116674
int rc;
16675
+ vfstraceOnOff(pInfo, VTR_UNLOCK);
1658216676
vfstrace_printf(pInfo, "%s.xUnlock(%s,%s)", pInfo->zVfsName, p->zFName,
1658316677
lockName(eLock));
1658416678
rc = p->pReal->pMethods->xUnlock(p->pReal, eLock);
1658516679
vfstrace_print_errcode(pInfo, " -> %s\n", rc);
1658616680
return rc;
@@ -16591,10 +16685,11 @@
1659116685
*/
1659216686
static int vfstraceCheckReservedLock(sqlite3_file *pFile, int *pResOut){
1659316687
vfstrace_file *p = (vfstrace_file *)pFile;
1659416688
vfstrace_info *pInfo = p->pInfo;
1659516689
int rc;
16690
+ vfstraceOnOff(pInfo, VTR_CRL);
1659616691
vfstrace_printf(pInfo, "%s.xCheckReservedLock(%s,%d)",
1659716692
pInfo->zVfsName, p->zFName);
1659816693
rc = p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut);
1659916694
vfstrace_print_errcode(pInfo, " -> %s", rc);
1660016695
vfstrace_printf(pInfo, ", out=%d\n", *pResOut);
@@ -16610,10 +16705,11 @@
1661016705
int rc;
1661116706
char zBuf[100];
1661216707
char zBuf2[100];
1661316708
char *zOp;
1661416709
char *zRVal = 0;
16710
+ vfstraceOnOff(pInfo, VTR_FCTRL);
1661516711
switch( op ){
1661616712
case SQLITE_FCNTL_LOCKSTATE: zOp = "LOCKSTATE"; break;
1661716713
case SQLITE_GET_LOCKPROXYFILE: zOp = "GET_LOCKPROXYFILE"; break;
1661816714
case SQLITE_SET_LOCKPROXYFILE: zOp = "SET_LOCKPROXYFILE"; break;
1661916715
case SQLITE_LAST_ERRNO: zOp = "LAST_ERRNO"; break;
@@ -16638,10 +16734,83 @@
1663816734
case SQLITE_FCNTL_OVERWRITE: zOp = "OVERWRITE"; break;
1663916735
case SQLITE_FCNTL_VFSNAME: zOp = "VFSNAME"; break;
1664016736
case SQLITE_FCNTL_POWERSAFE_OVERWRITE: zOp = "POWERSAFE_OVERWRITE"; break;
1664116737
case SQLITE_FCNTL_PRAGMA: {
1664216738
const char *const* a = (const char*const*)pArg;
16739
+ if( a[1] && strcmp(a[1],"vfstrace")==0 && a[2] ){
16740
+ const u8 *zArg = (const u8*)a[2];
16741
+ if( zArg[0]>='0' && zArg[0]<=9 ){
16742
+ pInfo->mTrace = (sqlite3_uint64)strtoll(a[2], 0, 0);
16743
+ }else{
16744
+ static const struct {
16745
+ const char *z;
16746
+ unsigned int m;
16747
+ } aKw[] = {
16748
+ { "all", 0xffffffff },
16749
+ { "close", VTR_CLOSE },
16750
+ { "read", VTR_READ },
16751
+ { "write", VTR_WRITE },
16752
+ { "truncate", VTR_TRUNC },
16753
+ { "sync", VTR_SYNC },
16754
+ { "filesize", VTR_FSIZE },
16755
+ { "lock", VTR_LOCK },
16756
+ { "unlock", VTR_UNLOCK },
16757
+ { "checkreservedlock", VTR_CRL },
16758
+ { "filecontrol", VTR_FCTRL },
16759
+ { "sectorsize", VTR_SECSZ },
16760
+ { "devicecharacteristics", VTR_DEVCHAR },
16761
+ { "shmlock", VTR_SHMLOCK },
16762
+ { "shmmap", VTR_SHMMAP },
16763
+ { "shmummap", VTR_SHMUNMAP },
16764
+ { "shmbarrier", VTR_SHMBAR },
16765
+ { "open", VTR_OPEN },
16766
+ { "delete", VTR_DELETE },
16767
+ { "access", VTR_ACCESS },
16768
+ { "fullpathname", VTR_FULLPATH },
16769
+ { "dlopen", VTR_DLOPEN },
16770
+ { "dlerror", VTR_DLERR },
16771
+ { "dlsym", VTR_DLSYM },
16772
+ { "dlclose", VTR_DLCLOSE },
16773
+ { "randomness", VTR_RAND },
16774
+ { "sleep", VTR_SLEEP },
16775
+ { "currenttime", VTR_CURTIME },
16776
+ { "currenttimeint64", VTR_CURTIME },
16777
+ { "getlasterror", VTR_LASTERR },
16778
+ };
16779
+ int onOff = 1;
16780
+ while( zArg[0] ){
16781
+ int jj, n;
16782
+ while( zArg[0]!=0 && zArg[0]!='-' && zArg[0]!='+'
16783
+ && !isalpha(zArg[0]) ) zArg++;
16784
+ if( zArg[0]==0 ) break;
16785
+ if( zArg[0]=='-' ){
16786
+ onOff = 0;
16787
+ zArg++;
16788
+ }else if( zArg[0]=='+' ){
16789
+ onOff = 1;
16790
+ zArg++;
16791
+ }
16792
+ while( !isalpha(zArg[0]) ){
16793
+ if( zArg[0]==0 ) break;
16794
+ zArg++;
16795
+ }
16796
+ if( zArg[0]=='x' && isalpha(zArg[1]) ) zArg++;
16797
+ for(n=0; isalpha(zArg[n]); n++){}
16798
+ for(jj=0; jj<(int)(sizeof(aKw)/sizeof(aKw[0])); jj++){
16799
+ if( sqlite3_strnicmp(aKw[jj].z,(const char*)zArg,n)==0 ){
16800
+ if( onOff ){
16801
+ pInfo->mTrace |= aKw[jj].m;
16802
+ }else{
16803
+ pInfo->mTrace &= ~aKw[jj].m;
16804
+ }
16805
+ break;
16806
+ }
16807
+ }
16808
+ zArg += n;
16809
+ }
16810
+ }
16811
+ }
1664316812
sqlite3_snprintf(sizeof(zBuf), zBuf, "PRAGMA,[%s,%s]",a[1],a[2]);
1664416813
zOp = zBuf;
1664516814
break;
1664616815
}
1664716816
case SQLITE_FCNTL_BUSYHANDLER: zOp = "BUSYHANDLER"; break;
@@ -16733,10 +16902,11 @@
1673316902
*/
1673416903
static int vfstraceSectorSize(sqlite3_file *pFile){
1673516904
vfstrace_file *p = (vfstrace_file *)pFile;
1673616905
vfstrace_info *pInfo = p->pInfo;
1673716906
int rc;
16907
+ vfstraceOnOff(pInfo, VTR_SECSZ);
1673816908
vfstrace_printf(pInfo, "%s.xSectorSize(%s)", pInfo->zVfsName, p->zFName);
1673916909
rc = p->pReal->pMethods->xSectorSize(p->pReal);
1674016910
vfstrace_printf(pInfo, " -> %d\n", rc);
1674116911
return rc;
1674216912
}
@@ -16746,10 +16916,11 @@
1674616916
*/
1674716917
static int vfstraceDeviceCharacteristics(sqlite3_file *pFile){
1674816918
vfstrace_file *p = (vfstrace_file *)pFile;
1674916919
vfstrace_info *pInfo = p->pInfo;
1675016920
int rc;
16921
+ vfstraceOnOff(pInfo, VTR_DEVCHAR);
1675116922
vfstrace_printf(pInfo, "%s.xDeviceCharacteristics(%s)",
1675216923
pInfo->zVfsName, p->zFName);
1675316924
rc = p->pReal->pMethods->xDeviceCharacteristics(p->pReal);
1675416925
vfstrace_printf(pInfo, " -> 0x%08x\n", rc);
1675516926
return rc;
@@ -16757,25 +16928,43 @@
1675716928
1675816929
/*
1675916930
** Shared-memory operations.
1676016931
*/
1676116932
static int vfstraceShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
16933
+ static const char *azLockName[] = {
16934
+ "WRITE",
16935
+ "CKPT",
16936
+ "RECOVER",
16937
+ "READ0",
16938
+ "READ1",
16939
+ "READ2",
16940
+ "READ3",
16941
+ "READ4",
16942
+ };
1676216943
vfstrace_file *p = (vfstrace_file *)pFile;
1676316944
vfstrace_info *pInfo = p->pInfo;
1676416945
int rc;
1676516946
char zLck[100];
1676616947
int i = 0;
16948
+ vfstraceOnOff(pInfo, VTR_SHMLOCK);
1676716949
memcpy(zLck, "|0", 3);
1676816950
if( flags & SQLITE_SHM_UNLOCK ) strappend(zLck, &i, "|UNLOCK");
1676916951
if( flags & SQLITE_SHM_LOCK ) strappend(zLck, &i, "|LOCK");
1677016952
if( flags & SQLITE_SHM_SHARED ) strappend(zLck, &i, "|SHARED");
1677116953
if( flags & SQLITE_SHM_EXCLUSIVE ) strappend(zLck, &i, "|EXCLUSIVE");
1677216954
if( flags & ~(0xf) ){
1677316955
sqlite3_snprintf(sizeof(zLck)-i, &zLck[i], "|0x%x", flags);
1677416956
}
16775
- vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=%d,n=%d,%s)",
16776
- pInfo->zVfsName, p->zFName, ofst, n, &zLck[1]);
16957
+ if( ofst>=0 && ofst<(int)(sizeof(azLockName)/sizeof(azLockName[0])) ){
16958
+ vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=%d(%s),n=%d,%s)",
16959
+ pInfo->zVfsName, p->zFName, ofst, azLockName[ofst],
16960
+ n, &zLck[1]);
16961
+ }else{
16962
+ vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=5d,n=%d,%s)",
16963
+ pInfo->zVfsName, p->zFName, ofst,
16964
+ n, &zLck[1]);
16965
+ }
1677716966
rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
1677816967
vfstrace_print_errcode(pInfo, " -> %s\n", rc);
1677916968
return rc;
1678016969
}
1678116970
static int vfstraceShmMap(
@@ -16786,26 +16975,29 @@
1678616975
void volatile **pp
1678716976
){
1678816977
vfstrace_file *p = (vfstrace_file *)pFile;
1678916978
vfstrace_info *pInfo = p->pInfo;
1679016979
int rc;
16980
+ vfstraceOnOff(pInfo, VTR_SHMMAP);
1679116981
vfstrace_printf(pInfo, "%s.xShmMap(%s,iRegion=%d,szRegion=%d,isWrite=%d,*)",
1679216982
pInfo->zVfsName, p->zFName, iRegion, szRegion, isWrite);
1679316983
rc = p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
1679416984
vfstrace_print_errcode(pInfo, " -> %s\n", rc);
1679516985
return rc;
1679616986
}
1679716987
static void vfstraceShmBarrier(sqlite3_file *pFile){
1679816988
vfstrace_file *p = (vfstrace_file *)pFile;
1679916989
vfstrace_info *pInfo = p->pInfo;
16990
+ vfstraceOnOff(pInfo, VTR_SHMBAR);
1680016991
vfstrace_printf(pInfo, "%s.xShmBarrier(%s)\n", pInfo->zVfsName, p->zFName);
1680116992
p->pReal->pMethods->xShmBarrier(p->pReal);
1680216993
}
1680316994
static int vfstraceShmUnmap(sqlite3_file *pFile, int delFlag){
1680416995
vfstrace_file *p = (vfstrace_file *)pFile;
1680516996
vfstrace_info *pInfo = p->pInfo;
1680616997
int rc;
16998
+ vfstraceOnOff(pInfo, VTR_SHMUNMAP);
1680716999
vfstrace_printf(pInfo, "%s.xShmUnmap(%s,delFlag=%d)",
1680817000
pInfo->zVfsName, p->zFName, delFlag);
1680917001
rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
1681017002
vfstrace_print_errcode(pInfo, " -> %s\n", rc);
1681117003
return rc;
@@ -16829,10 +17021,11 @@
1682917021
sqlite3_vfs *pRoot = pInfo->pRootVfs;
1683017022
p->pInfo = pInfo;
1683117023
p->zFName = zName ? fileTail(zName) : "<temp>";
1683217024
p->pReal = (sqlite3_file *)&p[1];
1683317025
rc = pRoot->xOpen(pRoot, zName, p->pReal, flags, pOutFlags);
17026
+ vfstraceOnOff(pInfo, VTR_OPEN);
1683417027
vfstrace_printf(pInfo, "%s.xOpen(%s,flags=0x%x)",
1683517028
pInfo->zVfsName, p->zFName, flags);
1683617029
if( p->pReal->pMethods ){
1683717030
sqlite3_io_methods *pNew = sqlite3_malloc( sizeof(*pNew) );
1683817031
const sqlite3_io_methods *pSub = p->pReal->pMethods;
@@ -16874,10 +17067,11 @@
1687417067
*/
1687517068
static int vfstraceDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
1687617069
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
1687717070
sqlite3_vfs *pRoot = pInfo->pRootVfs;
1687817071
int rc;
17072
+ vfstraceOnOff(pInfo, VTR_DELETE);
1687917073
vfstrace_printf(pInfo, "%s.xDelete(\"%s\",%d)",
1688017074
pInfo->zVfsName, zPath, dirSync);
1688117075
rc = pRoot->xDelete(pRoot, zPath, dirSync);
1688217076
vfstrace_print_errcode(pInfo, " -> %s\n", rc);
1688317077
return rc;
@@ -16894,10 +17088,11 @@
1689417088
int *pResOut
1689517089
){
1689617090
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
1689717091
sqlite3_vfs *pRoot = pInfo->pRootVfs;
1689817092
int rc;
17093
+ vfstraceOnOff(pInfo, VTR_ACCESS);
1689917094
vfstrace_printf(pInfo, "%s.xAccess(\"%s\",%d)",
1690017095
pInfo->zVfsName, zPath, flags);
1690117096
rc = pRoot->xAccess(pRoot, zPath, flags, pResOut);
1690217097
vfstrace_print_errcode(pInfo, " -> %s", rc);
1690317098
vfstrace_printf(pInfo, ", out=%d\n", *pResOut);
@@ -16916,10 +17111,11 @@
1691617111
char *zOut
1691717112
){
1691817113
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
1691917114
sqlite3_vfs *pRoot = pInfo->pRootVfs;
1692017115
int rc;
17116
+ vfstraceOnOff(pInfo, VTR_FULLPATH);
1692117117
vfstrace_printf(pInfo, "%s.xFullPathname(\"%s\")",
1692217118
pInfo->zVfsName, zPath);
1692317119
rc = pRoot->xFullPathname(pRoot, zPath, nOut, zOut);
1692417120
vfstrace_print_errcode(pInfo, " -> %s", rc);
1692517121
vfstrace_printf(pInfo, ", out=\"%.*s\"\n", nOut, zOut);
@@ -16930,10 +17126,11 @@
1693017126
** Open the dynamic library located at zPath and return a handle.
1693117127
*/
1693217128
static void *vfstraceDlOpen(sqlite3_vfs *pVfs, const char *zPath){
1693317129
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
1693417130
sqlite3_vfs *pRoot = pInfo->pRootVfs;
17131
+ vfstraceOnOff(pInfo, VTR_DLOPEN);
1693517132
vfstrace_printf(pInfo, "%s.xDlOpen(\"%s\")\n", pInfo->zVfsName, zPath);
1693617133
return pRoot->xDlOpen(pRoot, zPath);
1693717134
}
1693817135
1693917136
/*
@@ -16942,10 +17139,11 @@
1694217139
** with dynamic libraries.
1694317140
*/
1694417141
static void vfstraceDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
1694517142
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
1694617143
sqlite3_vfs *pRoot = pInfo->pRootVfs;
17144
+ vfstraceOnOff(pInfo, VTR_DLERR);
1694717145
vfstrace_printf(pInfo, "%s.xDlError(%d)", pInfo->zVfsName, nByte);
1694817146
pRoot->xDlError(pRoot, nByte, zErrMsg);
1694917147
vfstrace_printf(pInfo, " -> \"%s\"", zErrMsg);
1695017148
}
1695117149
@@ -16963,10 +17161,11 @@
1696317161
** Close the dynamic library handle pHandle.
1696417162
*/
1696517163
static void vfstraceDlClose(sqlite3_vfs *pVfs, void *pHandle){
1696617164
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
1696717165
sqlite3_vfs *pRoot = pInfo->pRootVfs;
17166
+ vfstraceOnOff(pInfo, VTR_DLCLOSE);
1696817167
vfstrace_printf(pInfo, "%s.xDlOpen()\n", pInfo->zVfsName);
1696917168
pRoot->xDlClose(pRoot, pHandle);
1697017169
}
1697117170
1697217171
/*
@@ -16974,10 +17173,11 @@
1697417173
** random data.
1697517174
*/
1697617175
static int vfstraceRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
1697717176
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
1697817177
sqlite3_vfs *pRoot = pInfo->pRootVfs;
17178
+ vfstraceOnOff(pInfo, VTR_RAND);
1697917179
vfstrace_printf(pInfo, "%s.xRandomness(%d)\n", pInfo->zVfsName, nByte);
1698017180
return pRoot->xRandomness(pRoot, nByte, zBufOut);
1698117181
}
1698217182
1698317183
/*
@@ -16985,34 +17185,52 @@
1698517185
** actually slept.
1698617186
*/
1698717187
static int vfstraceSleep(sqlite3_vfs *pVfs, int nMicro){
1698817188
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
1698917189
sqlite3_vfs *pRoot = pInfo->pRootVfs;
17190
+ vfstraceOnOff(pInfo, VTR_SLEEP);
17191
+ vfstrace_printf(pInfo, "%s.xSleep(%d)\n", pInfo->zVfsName, nMicro);
1699017192
return pRoot->xSleep(pRoot, nMicro);
1699117193
}
1699217194
1699317195
/*
1699417196
** Return the current time as a Julian Day number in *pTimeOut.
1699517197
*/
1699617198
static int vfstraceCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
1699717199
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
1699817200
sqlite3_vfs *pRoot = pInfo->pRootVfs;
16999
- return pRoot->xCurrentTime(pRoot, pTimeOut);
17201
+ int rc;
17202
+ vfstraceOnOff(pInfo, VTR_CURTIME);
17203
+ vfstrace_printf(pInfo, "%s.xCurrentTime()", pInfo->zVfsName);
17204
+ rc = pRoot->xCurrentTime(pRoot, pTimeOut);
17205
+ vfstrace_printf(pInfo, " -> %.17g\n", *pTimeOut);
17206
+ return rc;
1700017207
}
1700117208
static int vfstraceCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
1700217209
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
1700317210
sqlite3_vfs *pRoot = pInfo->pRootVfs;
17004
- return pRoot->xCurrentTimeInt64(pRoot, pTimeOut);
17211
+ int rc;
17212
+ vfstraceOnOff(pInfo, VTR_CURTIME);
17213
+ vfstrace_printf(pInfo, "%s.xCurrentTimeInt64()", pInfo->zVfsName);
17214
+ rc = pRoot->xCurrentTimeInt64(pRoot, pTimeOut);
17215
+ vfstrace_printf(pInfo, " -> %lld\n", *pTimeOut);
17216
+ return rc;
1700517217
}
1700617218
1700717219
/*
17008
-** Return th3 most recent error code and message
17220
+** Return the most recent error code and message
1700917221
*/
17010
-static int vfstraceGetLastError(sqlite3_vfs *pVfs, int iErr, char *zErr){
17222
+static int vfstraceGetLastError(sqlite3_vfs *pVfs, int nErr, char *zErr){
1701117223
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
1701217224
sqlite3_vfs *pRoot = pInfo->pRootVfs;
17013
- return pRoot->xGetLastError(pRoot, iErr, zErr);
17225
+ int rc;
17226
+ vfstraceOnOff(pInfo, VTR_LASTERR);
17227
+ vfstrace_printf(pInfo, "%s.xGetLastError(%d,zBuf)", pInfo->zVfsName, nErr);
17228
+ if( nErr ) zErr[0] = 0;
17229
+ rc = pRoot->xGetLastError(pRoot, nErr, zErr);
17230
+ vfstrace_printf(pInfo, " -> zBuf[] = \"%s\", rc = %d\n", nErr?zErr:"", rc);
17231
+ return rc;
1701417232
}
1701517233
1701617234
/*
1701717235
** Override system calls.
1701817236
*/
@@ -17102,10 +17320,12 @@
1710217320
pInfo->pRootVfs = pRoot;
1710317321
pInfo->xOut = xOut;
1710417322
pInfo->pOutArg = pOutArg;
1710517323
pInfo->zVfsName = pNew->zName;
1710617324
pInfo->pTraceVfs = pNew;
17325
+ pInfo->mTrace = 0xffffffff;
17326
+ pInfo->bOn = 1;
1710717327
vfstrace_printf(pInfo, "%s.enabled_for(\"%s\")\n",
1710817328
pInfo->zVfsName, pRoot->zName);
1710917329
return sqlite3_vfs_register(pNew, makeDefault);
1711017330
}
1711117331
@@ -20231,10 +20451,12 @@
2023120451
apVal[iField] = sqlite3_value_dup( pVal );
2023220452
if( apVal[iField]==0 ){
2023320453
recoverError(p, SQLITE_NOMEM, 0);
2023420454
}
2023520455
p1->nVal = iField+1;
20456
+ }else if( pTab->nCol==0 ){
20457
+ p1->nVal = pTab->nCol;
2023620458
}
2023720459
p1->iPrevCell = iCell;
2023820460
p1->iPrevPage = iPage;
2023920461
}
2024020462
}else{
@@ -22010,11 +22232,11 @@
2201022232
2201122233
/*
2201222234
** Output the given string as quoted according to JSON quoting rules.
2201322235
*/
2201422236
static void output_json_string(FILE *out, const char *z, i64 n){
22015
- char c;
22237
+ unsigned char c;
2201622238
static const char *zq = "\"";
2201722239
static long ctrlMask = ~0L;
2201822240
static const char *zDQBS = "\"\\";
2201922241
const char *pcLimit;
2202022242
char ace[3] = "\\?";
@@ -22030,11 +22252,11 @@
2203022252
if( pcEnd > z ){
2203122253
sqlite3_fprintf(out, "%.*s", (int)(pcEnd-z), z);
2203222254
z = pcEnd;
2203322255
}
2203422256
if( z >= pcLimit ) break;
22035
- c = *(z++);
22257
+ c = (unsigned char)*(z++);
2203622258
switch( c ){
2203722259
case '"': case '\\':
2203822260
cbsSay = (char)c;
2203922261
break;
2204022262
case '\b': cbsSay = 'b'; break;
@@ -22045,11 +22267,11 @@
2204522267
default: cbsSay = 0; break;
2204622268
}
2204722269
if( cbsSay ){
2204822270
ace[1] = cbsSay;
2204922271
sqlite3_fputs(ace, out);
22050
- }else if( c<=0x1f || c==0x7f ){
22272
+ }else if( c<=0x1f || c>=0x7f ){
2205122273
sqlite3_fprintf(out, "\\u%04x", c);
2205222274
}else{
2205322275
ace[1] = (char)c;
2205422276
sqlite3_fputs(ace+1, out);
2205522277
}
@@ -24787,13 +25009,13 @@
2478725009
if( rc ){
2478825010
sqlite3_fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
2478925011
}else{
2479025012
rc = SQLITE_CORRUPT;
2479125013
}
24792
- sqlite3_free(zErr);
2479325014
free(zQ2);
2479425015
}
25016
+ sqlite3_free(zErr);
2479525017
return rc;
2479625018
}
2479725019
2479825020
/*
2479925021
** Text of help messages.
@@ -24852,10 +25074,11 @@
2485225074
".databases List names and files of attached databases",
2485325075
".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
2485425076
#if SQLITE_SHELL_HAVE_RECOVER
2485525077
".dbinfo ?DB? Show status information about the database",
2485625078
#endif
25079
+ ".dbtotxt Hex dump of the database file",
2485725080
".dump ?OBJECTS? Render database content as SQL",
2485825081
" Options:",
2485925082
" --data-only Output only INSERT statements",
2486025083
" --newlines Allow unescaped newline characters in output",
2486125084
" --nosys Omit system tables (ex: \"sqlite_stat1\")",
@@ -26401,18 +26624,24 @@
2640126624
#endif
2640226625
2640326626
/*
2640426627
** Run an SQL command and return the single integer result.
2640526628
*/
26406
-static int db_int(sqlite3 *db, const char *zSql){
26629
+static int db_int(sqlite3 *db, const char *zSql, ...){
2640726630
sqlite3_stmt *pStmt;
2640826631
int res = 0;
26409
- sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
26632
+ char *z;
26633
+ va_list ap;
26634
+ va_start(ap, zSql);
26635
+ z = sqlite3_vmprintf(zSql, ap);
26636
+ va_end(ap);
26637
+ sqlite3_prepare_v2(db, z, -1, &pStmt, 0);
2641026638
if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2641126639
res = sqlite3_column_int(pStmt,0);
2641226640
}
2641326641
sqlite3_finalize(pStmt);
26642
+ sqlite3_free(z);
2641426643
return res;
2641526644
}
2641626645
2641726646
#if SQLITE_SHELL_HAVE_RECOVER
2641826647
/*
@@ -26511,21 +26740,112 @@
2651126740
zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_schema");
2651226741
}else{
2651326742
zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_schema", zDb);
2651426743
}
2651526744
for(i=0; i<ArraySize(aQuery); i++){
26516
- char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
26517
- int val = db_int(p->db, zSql);
26518
- sqlite3_free(zSql);
26745
+ int val = db_int(p->db, aQuery[i].zSql, zSchemaTab);
2651926746
sqlite3_fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
2652026747
}
2652126748
sqlite3_free(zSchemaTab);
2652226749
sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
2652326750
sqlite3_fprintf(p->out, "%-20s %u\n", "data version", iDataVersion);
2652426751
return 0;
2652526752
}
2652626753
#endif /* SQLITE_SHELL_HAVE_RECOVER */
26754
+
26755
+/*
26756
+** Implementation of the ".dbtotxt" command.
26757
+**
26758
+** Return 1 on error, 2 to exit, and 0 otherwise.
26759
+*/
26760
+static int shell_dbtotxt_command(ShellState *p, int nArg, char **azArg){
26761
+ sqlite3_stmt *pStmt = 0;
26762
+ sqlite3_int64 nPage = 0;
26763
+ int pgSz = 0;
26764
+ const char *zTail;
26765
+ char *zName = 0;
26766
+ int rc, i, j;
26767
+ unsigned char bShow[256]; /* Characters ok to display */
26768
+
26769
+ UNUSED_PARAMETER(nArg);
26770
+ UNUSED_PARAMETER(azArg);
26771
+ memset(bShow, '.', sizeof(bShow));
26772
+ for(i=' '; i<='~'; i++){
26773
+ if( i!='{' && i!='}' && i!='"' && i!='\\' ) bShow[i] = (unsigned char)i;
26774
+ }
26775
+ rc = sqlite3_prepare_v2(p->db, "PRAGMA page_size", -1, &pStmt, 0);
26776
+ if( rc ) goto dbtotxt_error;
26777
+ rc = 0;
26778
+ if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error;
26779
+ pgSz = sqlite3_column_int(pStmt, 0);
26780
+ sqlite3_finalize(pStmt);
26781
+ pStmt = 0;
26782
+ if( pgSz<512 || pgSz>65536 || (pgSz&(pgSz-1))!=0 ) goto dbtotxt_error;
26783
+ rc = sqlite3_prepare_v2(p->db, "PRAGMA page_count", -1, &pStmt, 0);
26784
+ if( rc ) goto dbtotxt_error;
26785
+ rc = 0;
26786
+ if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error;
26787
+ nPage = sqlite3_column_int64(pStmt, 0);
26788
+ sqlite3_finalize(pStmt);
26789
+ pStmt = 0;
26790
+ if( nPage<1 ) goto dbtotxt_error;
26791
+ rc = sqlite3_prepare_v2(p->db, "PRAGMA databases", -1, &pStmt, 0);
26792
+ if( rc ) goto dbtotxt_error;
26793
+ if( sqlite3_step(pStmt)!=SQLITE_ROW ){
26794
+ zTail = "unk.db";
26795
+ }else{
26796
+ const char *zFilename = (const char*)sqlite3_column_text(pStmt, 2);
26797
+ if( zFilename==0 || zFilename[0]==0 ) zFilename = "unk.db";
26798
+ zTail = strrchr(zFilename, '/');
26799
+#if defined(_WIN32)
26800
+ if( zTail==0 ) zTail = strrchr(zFilename, '\\');
26801
+#endif
26802
+ }
26803
+ zName = strdup(zTail);
26804
+ shell_check_oom(zName);
26805
+ sqlite3_fprintf(p->out, "| size %lld pagesize %d filename %s\n",
26806
+ nPage*pgSz, pgSz, zName);
26807
+ sqlite3_finalize(pStmt);
26808
+ pStmt = 0;
26809
+ rc = sqlite3_prepare_v2(p->db,
26810
+ "SELECT pgno, data FROM sqlite_dbpage ORDER BY pgno", -1, &pStmt, 0);
26811
+ if( rc ) goto dbtotxt_error;
26812
+ while( sqlite3_step(pStmt)==SQLITE_ROW ){
26813
+ sqlite3_int64 pgno = sqlite3_column_int64(pStmt, 0);
26814
+ const u8 *aData = sqlite3_column_blob(pStmt, 1);
26815
+ int seenPageLabel = 0;
26816
+ for(i=0; i<pgSz; i+=16){
26817
+ const u8 *aLine = aData+i;
26818
+ for(j=0; j<16 && aLine[j]==0; j++){}
26819
+ if( j==16 ) continue;
26820
+ if( !seenPageLabel ){
26821
+ sqlite3_fprintf(p->out, "| page %lld offset %lld\n", pgno, pgno*pgSz);
26822
+ seenPageLabel = 1;
26823
+ }
26824
+ sqlite3_fprintf(p->out, "| %5d:", i);
26825
+ for(j=0; j<16; j++) sqlite3_fprintf(p->out, " %02x", aLine[j]);
26826
+ sqlite3_fprintf(p->out, " ");
26827
+ for(j=0; j<16; j++){
26828
+ unsigned char c = (unsigned char)aLine[j];
26829
+ sqlite3_fprintf(p->out, "%c", bShow[c]);
26830
+ }
26831
+ sqlite3_fprintf(p->out, "\n");
26832
+ }
26833
+ }
26834
+ sqlite3_finalize(pStmt);
26835
+ sqlite3_fprintf(p->out, "| end %s\n", zName);
26836
+ free(zName);
26837
+ return 0;
26838
+
26839
+dbtotxt_error:
26840
+ if( rc ){
26841
+ sqlite3_fprintf(stderr, "ERROR: %s\n", sqlite3_errmsg(p->db));
26842
+ }
26843
+ sqlite3_finalize(pStmt);
26844
+ free(zName);
26845
+ return 1;
26846
+}
2652726847
2652826848
/*
2652926849
** Print the given string as an error message.
2653026850
*/
2653126851
static void shellEmitError(const char *zErr){
@@ -28078,12 +28398,12 @@
2807828398
}else if( *pDb==0 ){
2807928399
return 0;
2808028400
}else{
2808128401
/* Formulate the columns spec, close the DB, zero *pDb. */
2808228402
char *zColsSpec = 0;
28083
- int hasDupes = db_int(*pDb, zHasDupes);
28084
- int nDigits = (hasDupes)? db_int(*pDb, zColDigits) : 0;
28403
+ int hasDupes = db_int(*pDb, "%s", zHasDupes);
28404
+ int nDigits = (hasDupes)? db_int(*pDb, "%s", zColDigits) : 0;
2808528405
if( hasDupes ){
2808628406
#ifdef SHELL_COLUMN_RENAME_CLEAN
2808728407
rc = sqlite3_exec(*pDb, zDedoctor, 0, 0, 0);
2808828408
rc_err_oom_die(rc);
2808928409
#endif
@@ -28094,11 +28414,11 @@
2809428414
sqlite3_bind_int(pStmt, 1, nDigits);
2809528415
rc = sqlite3_step(pStmt);
2809628416
sqlite3_finalize(pStmt);
2809728417
if( rc!=SQLITE_DONE ) rc_err_oom_die(SQLITE_NOMEM);
2809828418
}
28099
- assert(db_int(*pDb, zHasDupes)==0); /* Consider: remove this */
28419
+ assert(db_int(*pDb, "%s", zHasDupes)==0); /* Consider: remove this */
2810028420
rc = sqlite3_prepare_v2(*pDb, zCollectVar, -1, &pStmt, 0);
2810128421
rc_err_oom_die(rc);
2810228422
rc = sqlite3_step(pStmt);
2810328423
if( rc==SQLITE_ROW ){
2810428424
zColsSpec = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
@@ -28699,10 +29019,14 @@
2869929019
}else{
2870029020
eputz("Usage: .echo on|off\n");
2870129021
rc = 1;
2870229022
}
2870329023
}else
29024
+
29025
+ if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbtotxt", n)==0 ){
29026
+ rc = shell_dbtotxt_command(p, nArg, azArg);
29027
+ }else
2870429028
2870529029
if( c=='e' && cli_strncmp(azArg[0], "eqp", n)==0 ){
2870629030
if( nArg==2 ){
2870729031
p->autoEQPtest = 0;
2870829032
if( p->autoEQPtrace ){
@@ -29140,11 +29464,15 @@
2914029464
/* Below, resources must be freed before exit. */
2914129465
while( (nSkip--)>0 ){
2914229466
while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
2914329467
}
2914429468
import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
29145
- if( sqlite3_table_column_metadata(p->db, zSchema, zTable,0,0,0,0,0,0) ){
29469
+ if( sqlite3_table_column_metadata(p->db, zSchema, zTable,0,0,0,0,0,0)
29470
+ && 0==db_int(p->db, "SELECT count(*) FROM \"%w\".sqlite_schema"
29471
+ " WHERE name=%Q AND type='view'",
29472
+ zSchema ? zSchema : "main", zTable)
29473
+ ){
2914629474
/* Table does not exist. Create it. */
2914729475
sqlite3 *dbCols = 0;
2914829476
char *zRenames = 0;
2914929477
char *zColDefs;
2915029478
zCreate = sqlite3_mprintf("CREATE TABLE \"%w\".\"%w\"",
@@ -30212,11 +30540,14 @@
3021230540
}
3021330541
close_db(pSrc);
3021430542
}else
3021530543
#endif /* !defined(SQLITE_SHELL_FIDDLE) */
3021630544
30217
- if( c=='s' && cli_strncmp(azArg[0], "scanstats", n)==0 ){
30545
+ if( c=='s' &&
30546
+ (cli_strncmp(azArg[0], "scanstats", n)==0 ||
30547
+ cli_strncmp(azArg[0], "scanstatus", n)==0)
30548
+ ){
3021830549
if( nArg==2 ){
3021930550
if( cli_strcmp(azArg[1], "vm")==0 ){
3022030551
p->scanstatsOn = 3;
3022130552
}else
3022230553
if( cli_strcmp(azArg[1], "est")==0 ){
@@ -31267,11 +31598,13 @@
3126731598
{ 0x10000000, 1, "OrderBySubq" },
3126831599
{ 0xffffffff, 0, "All" },
3126931600
};
3127031601
unsigned int curOpt;
3127131602
unsigned int newOpt;
31603
+ unsigned int m;
3127231604
int ii;
31605
+ int nOff;
3127331606
sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, p->db, &curOpt);
3127431607
newOpt = curOpt;
3127531608
for(ii=2; ii<nArg; ii++){
3127631609
const char *z = azArg[ii];
3127731610
int useLabel = 0;
@@ -31308,28 +31641,32 @@
3130831641
}
3130931642
}
3131031643
}
3131131644
if( curOpt!=newOpt ){
3131231645
sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,p->db,newOpt);
31313
- }else if( nArg<3 ){
31314
- curOpt = ~newOpt;
31646
+ }
31647
+ for(ii=nOff=0, m=1; ii<32; ii++, m <<= 1){
31648
+ if( m & newOpt ) nOff++;
3131531649
}
31316
- if( newOpt==0 ){
31317
- sqlite3_fputs("+All\n", p->out);
31318
- }else if( newOpt==0xffffffff ){
31319
- sqlite3_fputs("-All\n", p->out);
31650
+ if( nOff<12 ){
31651
+ sqlite3_fputs("+All", p->out);
31652
+ for(ii=0; ii<ArraySize(aLabel); ii++){
31653
+ if( !aLabel[ii].bDsply ) continue;
31654
+ if( (newOpt & aLabel[ii].mask)!=0 ){
31655
+ sqlite3_fprintf(p->out, " -%s", aLabel[ii].zLabel);
31656
+ }
31657
+ }
3132031658
}else{
31321
- int jj;
31322
- for(jj=0; jj<ArraySize(aLabel); jj++){
31323
- unsigned int m = aLabel[jj].mask;
31324
- if( !aLabel[jj].bDsply ) continue;
31325
- if( (curOpt&m)!=(newOpt&m) ){
31326
- sqlite3_fprintf(p->out, "%c%s\n", (newOpt & m)==0 ? '+' : '-',
31327
- aLabel[jj].zLabel);
31659
+ sqlite3_fputs("-All", p->out);
31660
+ for(ii=0; ii<ArraySize(aLabel); ii++){
31661
+ if( !aLabel[ii].bDsply ) continue;
31662
+ if( (newOpt & aLabel[ii].mask)==0 ){
31663
+ sqlite3_fprintf(p->out, " +%s", aLabel[ii].zLabel);
3132831664
}
3132931665
}
3133031666
}
31667
+ sqlite3_fputs("\n", p->out);
3133131668
rc2 = isOk = 3;
3133231669
break;
3133331670
}
3133431671
3133531672
/* sqlite3_test_control(int, db, int) */
@@ -31786,11 +32123,10 @@
3178632123
SCAN_TRACKER_REFTYPE pst){
3178732124
char cin;
3178832125
char cWait = (char)qss; /* intentional narrowing loss */
3178932126
if( cWait==0 ){
3179032127
PlainScan:
31791
- assert( cWait==0 );
3179232128
while( (cin = *zLine++)!=0 ){
3179332129
if( IsSpace(cin) )
3179432130
continue;
3179532131
switch (cin){
3179632132
case '-':
@@ -31838,11 +32174,10 @@
3183832174
switch( cWait ){
3183932175
case '*':
3184032176
if( *zLine != '/' )
3184132177
continue;
3184232178
++zLine;
31843
- cWait = 0;
3184432179
CONTINUE_PROMPT_AWAITC(pst, 0);
3184532180
qss = QSS_SETV(qss, 0);
3184632181
goto PlainScan;
3184732182
case '`': case '\'': case '"':
3184832183
if(*zLine==cWait){
@@ -31850,11 +32185,10 @@
3185032185
++zLine;
3185132186
continue;
3185232187
}
3185332188
deliberate_fall_through;
3185432189
case ']':
31855
- cWait = 0;
3185632190
CONTINUE_PROMPT_AWAITC(pst, 0);
3185732191
qss = QSS_SETV(qss, 0);
3185832192
goto PlainScan;
3185932193
default: assert(0);
3186032194
}
@@ -32038,11 +32372,14 @@
3203832372
if( doAutoDetectRestore(p, zSql) ) return 1;
3203932373
return 0;
3204032374
}
3204132375
3204232376
static void echo_group_input(ShellState *p, const char *zDo){
32043
- if( ShellHasFlag(p, SHFLG_Echo) ) sqlite3_fprintf(p->out, "%s\n", zDo);
32377
+ if( ShellHasFlag(p, SHFLG_Echo) ){
32378
+ sqlite3_fprintf(p->out, "%s\n", zDo);
32379
+ fflush(p->out);
32380
+ }
3204432381
}
3204532382
3204632383
#ifdef SQLITE_SHELL_FIDDLE
3204732384
/*
3204832385
** Alternate one_input_line() impl for wasm mode. This is not in the primary
@@ -32498,10 +32835,19 @@
3249832835
}
3249932836
3250032837
static void sayAbnormalExit(void){
3250132838
if( seenInterrupt ) eputz("Program interrupted.\n");
3250232839
}
32840
+
32841
+/* Routine to output from vfstrace
32842
+*/
32843
+static int vfstraceOut(const char *z, void *pArg){
32844
+ ShellState *p = (ShellState*)pArg;
32845
+ sqlite3_fputs(z, p->out);
32846
+ fflush(p->out);
32847
+ return 1;
32848
+}
3250332849
3250432850
#ifndef SQLITE_SHELL_IS_UTF8
3250532851
# if (defined(_WIN32) || defined(WIN32)) \
3250632852
&& (defined(_MSC_VER) || (defined(UNICODE) && defined(__GNUC__)))
3250732853
# define SQLITE_SHELL_IS_UTF8 (0)
@@ -32735,12 +33081,10 @@
3273533081
case 0: sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); break;
3273633082
case 2: sqlite3_config(SQLITE_CONFIG_MULTITHREAD); break;
3273733083
default: sqlite3_config(SQLITE_CONFIG_SERIALIZED); break;
3273833084
}
3273933085
}else if( cli_strcmp(z,"-vfstrace")==0 ){
32740
- vfstrace_register("trace",0,(int(*)(const char*,void*))sqlite3_fputs,
32741
- stderr,1);
3274233086
bEnableVfstrace = 1;
3274333087
#ifdef SQLITE_ENABLE_MULTIPLEX
3274433088
}else if( cli_strcmp(z,"-multiplex")==0 ){
3274533089
extern int sqlite3_multiplex_initialize(const char*,int);
3274633090
sqlite3_multiplex_initialize(0, 1);
@@ -32833,10 +33177,13 @@
3283333177
"%s: Error: no database filename specified\n", Argv0);
3283433178
return 1;
3283533179
#endif
3283633180
}
3283733181
data.out = stdout;
33182
+ if( bEnableVfstrace ){
33183
+ vfstrace_register("trace",0,vfstraceOut, &data, 1);
33184
+ }
3283833185
#ifndef SQLITE_SHELL_FIDDLE
3283933186
sqlite3_appendvfs_init(0,0,0);
3284033187
#endif
3284133188
3284233189
/* Go ahead and open the database file if it already exists. If the
@@ -33077,19 +33424,14 @@
3307733424
*/
3307833425
if( stdin_is_interactive ){
3307933426
char *zHome;
3308033427
char *zHistory;
3308133428
int nHistory;
33082
-#if CIO_WIN_WC_XLATE
33083
-# define SHELL_CIO_CHAR_SET (stdout_is_console? " (UTF-16 console I/O)" : "")
33084
-#else
33085
-# define SHELL_CIO_CHAR_SET ""
33086
-#endif
3308733429
sqlite3_fprintf(stdout,
33088
- "SQLite version %s %.19s%s\n" /*extra-version-info*/
33430
+ "SQLite version %s %.19s\n" /*extra-version-info*/
3308933431
"Enter \".help\" for usage hints.\n",
33090
- sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET);
33432
+ sqlite3_libversion(), sqlite3_sourceid());
3309133433
if( warnInmemoryDb ){
3309233434
sputz(stdout, "Connected to a ");
3309333435
printBold("transient in-memory database");
3309433436
sputz(stdout, ".\nUse \".open FILENAME\" to reopen on a"
3309533437
" persistent database.\n");
3309633438
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -457,14 +457,24 @@
457 ** that into UTF-8. Otherwise, non-ASCII characters all get translated
458 ** into '?'.
459 */
460 wchar_t *b1 = sqlite3_malloc( sz*sizeof(wchar_t) );
461 if( b1==0 ) return 0;
462 _setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT);
463 if( fgetws(b1, sz/4, in)==0 ){
464 sqlite3_free(b1);
465 return 0;
 
 
 
 
 
 
 
 
 
 
466 }
467 WideCharToMultiByte(CP_UTF8, 0, b1, -1, buf, sz, 0, 0);
468 sqlite3_free(b1);
469 return buf;
470 }else{
@@ -516,24 +526,37 @@
516 if( !UseWtextForOutput(out) ){
517 /* Writing to a file or other destination, just write bytes without
518 ** any translation. */
519 return fputs(z, out);
520 }else{
521 /* When writing to the command-prompt in Windows, it is necessary
522 ** to use O_U8TEXT to render Unicode U+0080 and greater. Go ahead
523 ** use O_U8TEXT for everything in text mode.
524 */
525 int sz = (int)strlen(z);
526 wchar_t *b1 = sqlite3_malloc( (sz+1)*sizeof(wchar_t) );
527 if( b1==0 ) return 0;
528 sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz);
529 b1[sz] = 0;
530 _setmode(_fileno(out), _O_U8TEXT);
531 if( UseBinaryWText(out) ){
532 piecemealOutput(b1, sz, out);
533 }else{
534 fputws(b1, out);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
535 }
536 sqlite3_free(b1);
537 return 0;
538 }
539 }
@@ -2344,11 +2367,11 @@
2344 **
2345 ******************************************************************************
2346 **
2347 ** This SQLite extension implements functions that compute SHA3 hashes
2348 ** in the way described by the (U.S.) NIST FIPS 202 SHA-3 Standard.
2349 ** Two SQL functions are implemented:
2350 **
2351 ** sha3(X,SIZE)
2352 ** sha3_agg(Y,SIZE)
2353 ** sha3_query(Z,SIZE)
2354 **
@@ -14170,11 +14193,11 @@
14170 /* A view. Or a trigger on a view. */
14171 if( zSql ) rc = expertSchemaSql(p->dbv, zSql, pzErrmsg);
14172 }else{
14173 IdxTable *pTab;
14174 rc = idxGetTableInfo(p->db, zName, &pTab, pzErrmsg);
14175 if( rc==SQLITE_OK ){
14176 int i;
14177 char *zInner = 0;
14178 char *zOuter = 0;
14179 pTab->pNext = p->pTable;
14180 p->pTable = pTab;
@@ -16238,11 +16261,31 @@
16238 **
16239 ** Similar compiler commands will work on different systems. The key
16240 ** invariants are (1) you must have -DSQLITE_ENABLE_VFSTRACE so that
16241 ** the shell.c source file will know to include the -vfstrace command-line
16242 ** option and (2) you must compile and link the three source files
16243 ** shell,c, test_vfstrace.c, and sqlite3.c.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16244 */
16245 #include <stdlib.h>
16246 #include <string.h>
16247 /* #include "sqlite3.h" */
16248
@@ -16252,10 +16295,12 @@
16252 */
16253 typedef struct vfstrace_info vfstrace_info;
16254 struct vfstrace_info {
16255 sqlite3_vfs *pRootVfs; /* The underlying real VFS */
16256 int (*xOut)(const char*, void*); /* Send output here */
 
 
16257 void *pOutArg; /* First argument to xOut */
16258 const char *zVfsName; /* Name of this trace-VFS */
16259 sqlite3_vfs *pTraceVfs; /* Pointer back to the trace VFS */
16260 };
16261
@@ -16268,10 +16313,42 @@
16268 vfstrace_info *pInfo; /* The trace-VFS to which this file belongs */
16269 const char *zFName; /* Base name of the file */
16270 sqlite3_file *pReal; /* The real underlying file */
16271 };
16272
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16273 /*
16274 ** Method declarations for vfstrace_file.
16275 */
16276 static int vfstraceClose(sqlite3_file*);
16277 static int vfstraceRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
@@ -16332,15 +16409,17 @@
16332 const char *zFormat,
16333 ...
16334 ){
16335 va_list ap;
16336 char *zMsg;
16337 va_start(ap, zFormat);
16338 zMsg = sqlite3_vmprintf(zFormat, ap);
16339 va_end(ap);
16340 pInfo->xOut(zMsg, pInfo->pOutArg);
16341 sqlite3_free(zMsg);
 
 
16342 }
16343
16344 /*
16345 ** Try to convert an error code into a symbolic name for that error code.
16346 */
@@ -16434,18 +16513,26 @@
16434 int i = *pI;
16435 while( zAppend[0] ){ z[i++] = *(zAppend++); }
16436 z[i] = 0;
16437 *pI = i;
16438 }
 
 
 
 
 
 
 
16439
16440 /*
16441 ** Close an vfstrace-file.
16442 */
16443 static int vfstraceClose(sqlite3_file *pFile){
16444 vfstrace_file *p = (vfstrace_file *)pFile;
16445 vfstrace_info *pInfo = p->pInfo;
16446 int rc;
 
16447 vfstrace_printf(pInfo, "%s.xClose(%s)", pInfo->zVfsName, p->zFName);
16448 rc = p->pReal->pMethods->xClose(p->pReal);
16449 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16450 if( rc==SQLITE_OK ){
16451 sqlite3_free((void*)p->base.pMethods);
@@ -16464,10 +16551,11 @@
16464 sqlite_int64 iOfst
16465 ){
16466 vfstrace_file *p = (vfstrace_file *)pFile;
16467 vfstrace_info *pInfo = p->pInfo;
16468 int rc;
 
16469 vfstrace_printf(pInfo, "%s.xRead(%s,n=%d,ofst=%lld)",
16470 pInfo->zVfsName, p->zFName, iAmt, iOfst);
16471 rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
16472 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16473 return rc;
@@ -16483,10 +16571,11 @@
16483 sqlite_int64 iOfst
16484 ){
16485 vfstrace_file *p = (vfstrace_file *)pFile;
16486 vfstrace_info *pInfo = p->pInfo;
16487 int rc;
 
16488 vfstrace_printf(pInfo, "%s.xWrite(%s,n=%d,ofst=%lld)",
16489 pInfo->zVfsName, p->zFName, iAmt, iOfst);
16490 rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
16491 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16492 return rc;
@@ -16497,10 +16586,11 @@
16497 */
16498 static int vfstraceTruncate(sqlite3_file *pFile, sqlite_int64 size){
16499 vfstrace_file *p = (vfstrace_file *)pFile;
16500 vfstrace_info *pInfo = p->pInfo;
16501 int rc;
 
16502 vfstrace_printf(pInfo, "%s.xTruncate(%s,%lld)", pInfo->zVfsName, p->zFName,
16503 size);
16504 rc = p->pReal->pMethods->xTruncate(p->pReal, size);
16505 vfstrace_printf(pInfo, " -> %d\n", rc);
16506 return rc;
@@ -16521,10 +16611,11 @@
16521 else if( flags & SQLITE_SYNC_NORMAL ) strappend(zBuf, &i, "|NORMAL");
16522 if( flags & SQLITE_SYNC_DATAONLY ) strappend(zBuf, &i, "|DATAONLY");
16523 if( flags & ~(SQLITE_SYNC_FULL|SQLITE_SYNC_DATAONLY) ){
16524 sqlite3_snprintf(sizeof(zBuf)-i, &zBuf[i], "|0x%x", flags);
16525 }
 
16526 vfstrace_printf(pInfo, "%s.xSync(%s,%s)", pInfo->zVfsName, p->zFName,
16527 &zBuf[1]);
16528 rc = p->pReal->pMethods->xSync(p->pReal, flags);
16529 vfstrace_printf(pInfo, " -> %d\n", rc);
16530 return rc;
@@ -16535,10 +16626,11 @@
16535 */
16536 static int vfstraceFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
16537 vfstrace_file *p = (vfstrace_file *)pFile;
16538 vfstrace_info *pInfo = p->pInfo;
16539 int rc;
 
16540 vfstrace_printf(pInfo, "%s.xFileSize(%s)", pInfo->zVfsName, p->zFName);
16541 rc = p->pReal->pMethods->xFileSize(p->pReal, pSize);
16542 vfstrace_print_errcode(pInfo, " -> %s,", rc);
16543 vfstrace_printf(pInfo, " size=%lld\n", *pSize);
16544 return rc;
@@ -16563,10 +16655,11 @@
16563 */
16564 static int vfstraceLock(sqlite3_file *pFile, int eLock){
16565 vfstrace_file *p = (vfstrace_file *)pFile;
16566 vfstrace_info *pInfo = p->pInfo;
16567 int rc;
 
16568 vfstrace_printf(pInfo, "%s.xLock(%s,%s)", pInfo->zVfsName, p->zFName,
16569 lockName(eLock));
16570 rc = p->pReal->pMethods->xLock(p->pReal, eLock);
16571 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16572 return rc;
@@ -16577,10 +16670,11 @@
16577 */
16578 static int vfstraceUnlock(sqlite3_file *pFile, int eLock){
16579 vfstrace_file *p = (vfstrace_file *)pFile;
16580 vfstrace_info *pInfo = p->pInfo;
16581 int rc;
 
16582 vfstrace_printf(pInfo, "%s.xUnlock(%s,%s)", pInfo->zVfsName, p->zFName,
16583 lockName(eLock));
16584 rc = p->pReal->pMethods->xUnlock(p->pReal, eLock);
16585 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16586 return rc;
@@ -16591,10 +16685,11 @@
16591 */
16592 static int vfstraceCheckReservedLock(sqlite3_file *pFile, int *pResOut){
16593 vfstrace_file *p = (vfstrace_file *)pFile;
16594 vfstrace_info *pInfo = p->pInfo;
16595 int rc;
 
16596 vfstrace_printf(pInfo, "%s.xCheckReservedLock(%s,%d)",
16597 pInfo->zVfsName, p->zFName);
16598 rc = p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut);
16599 vfstrace_print_errcode(pInfo, " -> %s", rc);
16600 vfstrace_printf(pInfo, ", out=%d\n", *pResOut);
@@ -16610,10 +16705,11 @@
16610 int rc;
16611 char zBuf[100];
16612 char zBuf2[100];
16613 char *zOp;
16614 char *zRVal = 0;
 
16615 switch( op ){
16616 case SQLITE_FCNTL_LOCKSTATE: zOp = "LOCKSTATE"; break;
16617 case SQLITE_GET_LOCKPROXYFILE: zOp = "GET_LOCKPROXYFILE"; break;
16618 case SQLITE_SET_LOCKPROXYFILE: zOp = "SET_LOCKPROXYFILE"; break;
16619 case SQLITE_LAST_ERRNO: zOp = "LAST_ERRNO"; break;
@@ -16638,10 +16734,83 @@
16638 case SQLITE_FCNTL_OVERWRITE: zOp = "OVERWRITE"; break;
16639 case SQLITE_FCNTL_VFSNAME: zOp = "VFSNAME"; break;
16640 case SQLITE_FCNTL_POWERSAFE_OVERWRITE: zOp = "POWERSAFE_OVERWRITE"; break;
16641 case SQLITE_FCNTL_PRAGMA: {
16642 const char *const* a = (const char*const*)pArg;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16643 sqlite3_snprintf(sizeof(zBuf), zBuf, "PRAGMA,[%s,%s]",a[1],a[2]);
16644 zOp = zBuf;
16645 break;
16646 }
16647 case SQLITE_FCNTL_BUSYHANDLER: zOp = "BUSYHANDLER"; break;
@@ -16733,10 +16902,11 @@
16733 */
16734 static int vfstraceSectorSize(sqlite3_file *pFile){
16735 vfstrace_file *p = (vfstrace_file *)pFile;
16736 vfstrace_info *pInfo = p->pInfo;
16737 int rc;
 
16738 vfstrace_printf(pInfo, "%s.xSectorSize(%s)", pInfo->zVfsName, p->zFName);
16739 rc = p->pReal->pMethods->xSectorSize(p->pReal);
16740 vfstrace_printf(pInfo, " -> %d\n", rc);
16741 return rc;
16742 }
@@ -16746,10 +16916,11 @@
16746 */
16747 static int vfstraceDeviceCharacteristics(sqlite3_file *pFile){
16748 vfstrace_file *p = (vfstrace_file *)pFile;
16749 vfstrace_info *pInfo = p->pInfo;
16750 int rc;
 
16751 vfstrace_printf(pInfo, "%s.xDeviceCharacteristics(%s)",
16752 pInfo->zVfsName, p->zFName);
16753 rc = p->pReal->pMethods->xDeviceCharacteristics(p->pReal);
16754 vfstrace_printf(pInfo, " -> 0x%08x\n", rc);
16755 return rc;
@@ -16757,25 +16928,43 @@
16757
16758 /*
16759 ** Shared-memory operations.
16760 */
16761 static int vfstraceShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
 
 
 
 
 
 
 
 
 
 
16762 vfstrace_file *p = (vfstrace_file *)pFile;
16763 vfstrace_info *pInfo = p->pInfo;
16764 int rc;
16765 char zLck[100];
16766 int i = 0;
 
16767 memcpy(zLck, "|0", 3);
16768 if( flags & SQLITE_SHM_UNLOCK ) strappend(zLck, &i, "|UNLOCK");
16769 if( flags & SQLITE_SHM_LOCK ) strappend(zLck, &i, "|LOCK");
16770 if( flags & SQLITE_SHM_SHARED ) strappend(zLck, &i, "|SHARED");
16771 if( flags & SQLITE_SHM_EXCLUSIVE ) strappend(zLck, &i, "|EXCLUSIVE");
16772 if( flags & ~(0xf) ){
16773 sqlite3_snprintf(sizeof(zLck)-i, &zLck[i], "|0x%x", flags);
16774 }
16775 vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=%d,n=%d,%s)",
16776 pInfo->zVfsName, p->zFName, ofst, n, &zLck[1]);
 
 
 
 
 
 
 
16777 rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
16778 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16779 return rc;
16780 }
16781 static int vfstraceShmMap(
@@ -16786,26 +16975,29 @@
16786 void volatile **pp
16787 ){
16788 vfstrace_file *p = (vfstrace_file *)pFile;
16789 vfstrace_info *pInfo = p->pInfo;
16790 int rc;
 
16791 vfstrace_printf(pInfo, "%s.xShmMap(%s,iRegion=%d,szRegion=%d,isWrite=%d,*)",
16792 pInfo->zVfsName, p->zFName, iRegion, szRegion, isWrite);
16793 rc = p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
16794 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16795 return rc;
16796 }
16797 static void vfstraceShmBarrier(sqlite3_file *pFile){
16798 vfstrace_file *p = (vfstrace_file *)pFile;
16799 vfstrace_info *pInfo = p->pInfo;
 
16800 vfstrace_printf(pInfo, "%s.xShmBarrier(%s)\n", pInfo->zVfsName, p->zFName);
16801 p->pReal->pMethods->xShmBarrier(p->pReal);
16802 }
16803 static int vfstraceShmUnmap(sqlite3_file *pFile, int delFlag){
16804 vfstrace_file *p = (vfstrace_file *)pFile;
16805 vfstrace_info *pInfo = p->pInfo;
16806 int rc;
 
16807 vfstrace_printf(pInfo, "%s.xShmUnmap(%s,delFlag=%d)",
16808 pInfo->zVfsName, p->zFName, delFlag);
16809 rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
16810 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16811 return rc;
@@ -16829,10 +17021,11 @@
16829 sqlite3_vfs *pRoot = pInfo->pRootVfs;
16830 p->pInfo = pInfo;
16831 p->zFName = zName ? fileTail(zName) : "<temp>";
16832 p->pReal = (sqlite3_file *)&p[1];
16833 rc = pRoot->xOpen(pRoot, zName, p->pReal, flags, pOutFlags);
 
16834 vfstrace_printf(pInfo, "%s.xOpen(%s,flags=0x%x)",
16835 pInfo->zVfsName, p->zFName, flags);
16836 if( p->pReal->pMethods ){
16837 sqlite3_io_methods *pNew = sqlite3_malloc( sizeof(*pNew) );
16838 const sqlite3_io_methods *pSub = p->pReal->pMethods;
@@ -16874,10 +17067,11 @@
16874 */
16875 static int vfstraceDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
16876 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
16877 sqlite3_vfs *pRoot = pInfo->pRootVfs;
16878 int rc;
 
16879 vfstrace_printf(pInfo, "%s.xDelete(\"%s\",%d)",
16880 pInfo->zVfsName, zPath, dirSync);
16881 rc = pRoot->xDelete(pRoot, zPath, dirSync);
16882 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16883 return rc;
@@ -16894,10 +17088,11 @@
16894 int *pResOut
16895 ){
16896 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
16897 sqlite3_vfs *pRoot = pInfo->pRootVfs;
16898 int rc;
 
16899 vfstrace_printf(pInfo, "%s.xAccess(\"%s\",%d)",
16900 pInfo->zVfsName, zPath, flags);
16901 rc = pRoot->xAccess(pRoot, zPath, flags, pResOut);
16902 vfstrace_print_errcode(pInfo, " -> %s", rc);
16903 vfstrace_printf(pInfo, ", out=%d\n", *pResOut);
@@ -16916,10 +17111,11 @@
16916 char *zOut
16917 ){
16918 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
16919 sqlite3_vfs *pRoot = pInfo->pRootVfs;
16920 int rc;
 
16921 vfstrace_printf(pInfo, "%s.xFullPathname(\"%s\")",
16922 pInfo->zVfsName, zPath);
16923 rc = pRoot->xFullPathname(pRoot, zPath, nOut, zOut);
16924 vfstrace_print_errcode(pInfo, " -> %s", rc);
16925 vfstrace_printf(pInfo, ", out=\"%.*s\"\n", nOut, zOut);
@@ -16930,10 +17126,11 @@
16930 ** Open the dynamic library located at zPath and return a handle.
16931 */
16932 static void *vfstraceDlOpen(sqlite3_vfs *pVfs, const char *zPath){
16933 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
16934 sqlite3_vfs *pRoot = pInfo->pRootVfs;
 
16935 vfstrace_printf(pInfo, "%s.xDlOpen(\"%s\")\n", pInfo->zVfsName, zPath);
16936 return pRoot->xDlOpen(pRoot, zPath);
16937 }
16938
16939 /*
@@ -16942,10 +17139,11 @@
16942 ** with dynamic libraries.
16943 */
16944 static void vfstraceDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
16945 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
16946 sqlite3_vfs *pRoot = pInfo->pRootVfs;
 
16947 vfstrace_printf(pInfo, "%s.xDlError(%d)", pInfo->zVfsName, nByte);
16948 pRoot->xDlError(pRoot, nByte, zErrMsg);
16949 vfstrace_printf(pInfo, " -> \"%s\"", zErrMsg);
16950 }
16951
@@ -16963,10 +17161,11 @@
16963 ** Close the dynamic library handle pHandle.
16964 */
16965 static void vfstraceDlClose(sqlite3_vfs *pVfs, void *pHandle){
16966 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
16967 sqlite3_vfs *pRoot = pInfo->pRootVfs;
 
16968 vfstrace_printf(pInfo, "%s.xDlOpen()\n", pInfo->zVfsName);
16969 pRoot->xDlClose(pRoot, pHandle);
16970 }
16971
16972 /*
@@ -16974,10 +17173,11 @@
16974 ** random data.
16975 */
16976 static int vfstraceRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
16977 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
16978 sqlite3_vfs *pRoot = pInfo->pRootVfs;
 
16979 vfstrace_printf(pInfo, "%s.xRandomness(%d)\n", pInfo->zVfsName, nByte);
16980 return pRoot->xRandomness(pRoot, nByte, zBufOut);
16981 }
16982
16983 /*
@@ -16985,34 +17185,52 @@
16985 ** actually slept.
16986 */
16987 static int vfstraceSleep(sqlite3_vfs *pVfs, int nMicro){
16988 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
16989 sqlite3_vfs *pRoot = pInfo->pRootVfs;
 
 
16990 return pRoot->xSleep(pRoot, nMicro);
16991 }
16992
16993 /*
16994 ** Return the current time as a Julian Day number in *pTimeOut.
16995 */
16996 static int vfstraceCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
16997 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
16998 sqlite3_vfs *pRoot = pInfo->pRootVfs;
16999 return pRoot->xCurrentTime(pRoot, pTimeOut);
 
 
 
 
 
17000 }
17001 static int vfstraceCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
17002 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17003 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17004 return pRoot->xCurrentTimeInt64(pRoot, pTimeOut);
 
 
 
 
 
17005 }
17006
17007 /*
17008 ** Return th3 most recent error code and message
17009 */
17010 static int vfstraceGetLastError(sqlite3_vfs *pVfs, int iErr, char *zErr){
17011 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17012 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17013 return pRoot->xGetLastError(pRoot, iErr, zErr);
 
 
 
 
 
 
17014 }
17015
17016 /*
17017 ** Override system calls.
17018 */
@@ -17102,10 +17320,12 @@
17102 pInfo->pRootVfs = pRoot;
17103 pInfo->xOut = xOut;
17104 pInfo->pOutArg = pOutArg;
17105 pInfo->zVfsName = pNew->zName;
17106 pInfo->pTraceVfs = pNew;
 
 
17107 vfstrace_printf(pInfo, "%s.enabled_for(\"%s\")\n",
17108 pInfo->zVfsName, pRoot->zName);
17109 return sqlite3_vfs_register(pNew, makeDefault);
17110 }
17111
@@ -20231,10 +20451,12 @@
20231 apVal[iField] = sqlite3_value_dup( pVal );
20232 if( apVal[iField]==0 ){
20233 recoverError(p, SQLITE_NOMEM, 0);
20234 }
20235 p1->nVal = iField+1;
 
 
20236 }
20237 p1->iPrevCell = iCell;
20238 p1->iPrevPage = iPage;
20239 }
20240 }else{
@@ -22010,11 +22232,11 @@
22010
22011 /*
22012 ** Output the given string as quoted according to JSON quoting rules.
22013 */
22014 static void output_json_string(FILE *out, const char *z, i64 n){
22015 char c;
22016 static const char *zq = "\"";
22017 static long ctrlMask = ~0L;
22018 static const char *zDQBS = "\"\\";
22019 const char *pcLimit;
22020 char ace[3] = "\\?";
@@ -22030,11 +22252,11 @@
22030 if( pcEnd > z ){
22031 sqlite3_fprintf(out, "%.*s", (int)(pcEnd-z), z);
22032 z = pcEnd;
22033 }
22034 if( z >= pcLimit ) break;
22035 c = *(z++);
22036 switch( c ){
22037 case '"': case '\\':
22038 cbsSay = (char)c;
22039 break;
22040 case '\b': cbsSay = 'b'; break;
@@ -22045,11 +22267,11 @@
22045 default: cbsSay = 0; break;
22046 }
22047 if( cbsSay ){
22048 ace[1] = cbsSay;
22049 sqlite3_fputs(ace, out);
22050 }else if( c<=0x1f || c==0x7f ){
22051 sqlite3_fprintf(out, "\\u%04x", c);
22052 }else{
22053 ace[1] = (char)c;
22054 sqlite3_fputs(ace+1, out);
22055 }
@@ -24787,13 +25009,13 @@
24787 if( rc ){
24788 sqlite3_fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
24789 }else{
24790 rc = SQLITE_CORRUPT;
24791 }
24792 sqlite3_free(zErr);
24793 free(zQ2);
24794 }
 
24795 return rc;
24796 }
24797
24798 /*
24799 ** Text of help messages.
@@ -24852,10 +25074,11 @@
24852 ".databases List names and files of attached databases",
24853 ".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
24854 #if SQLITE_SHELL_HAVE_RECOVER
24855 ".dbinfo ?DB? Show status information about the database",
24856 #endif
 
24857 ".dump ?OBJECTS? Render database content as SQL",
24858 " Options:",
24859 " --data-only Output only INSERT statements",
24860 " --newlines Allow unescaped newline characters in output",
24861 " --nosys Omit system tables (ex: \"sqlite_stat1\")",
@@ -26401,18 +26624,24 @@
26401 #endif
26402
26403 /*
26404 ** Run an SQL command and return the single integer result.
26405 */
26406 static int db_int(sqlite3 *db, const char *zSql){
26407 sqlite3_stmt *pStmt;
26408 int res = 0;
26409 sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
 
 
 
 
 
26410 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
26411 res = sqlite3_column_int(pStmt,0);
26412 }
26413 sqlite3_finalize(pStmt);
 
26414 return res;
26415 }
26416
26417 #if SQLITE_SHELL_HAVE_RECOVER
26418 /*
@@ -26511,21 +26740,112 @@
26511 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_schema");
26512 }else{
26513 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_schema", zDb);
26514 }
26515 for(i=0; i<ArraySize(aQuery); i++){
26516 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
26517 int val = db_int(p->db, zSql);
26518 sqlite3_free(zSql);
26519 sqlite3_fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
26520 }
26521 sqlite3_free(zSchemaTab);
26522 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
26523 sqlite3_fprintf(p->out, "%-20s %u\n", "data version", iDataVersion);
26524 return 0;
26525 }
26526 #endif /* SQLITE_SHELL_HAVE_RECOVER */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26527
26528 /*
26529 ** Print the given string as an error message.
26530 */
26531 static void shellEmitError(const char *zErr){
@@ -28078,12 +28398,12 @@
28078 }else if( *pDb==0 ){
28079 return 0;
28080 }else{
28081 /* Formulate the columns spec, close the DB, zero *pDb. */
28082 char *zColsSpec = 0;
28083 int hasDupes = db_int(*pDb, zHasDupes);
28084 int nDigits = (hasDupes)? db_int(*pDb, zColDigits) : 0;
28085 if( hasDupes ){
28086 #ifdef SHELL_COLUMN_RENAME_CLEAN
28087 rc = sqlite3_exec(*pDb, zDedoctor, 0, 0, 0);
28088 rc_err_oom_die(rc);
28089 #endif
@@ -28094,11 +28414,11 @@
28094 sqlite3_bind_int(pStmt, 1, nDigits);
28095 rc = sqlite3_step(pStmt);
28096 sqlite3_finalize(pStmt);
28097 if( rc!=SQLITE_DONE ) rc_err_oom_die(SQLITE_NOMEM);
28098 }
28099 assert(db_int(*pDb, zHasDupes)==0); /* Consider: remove this */
28100 rc = sqlite3_prepare_v2(*pDb, zCollectVar, -1, &pStmt, 0);
28101 rc_err_oom_die(rc);
28102 rc = sqlite3_step(pStmt);
28103 if( rc==SQLITE_ROW ){
28104 zColsSpec = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
@@ -28699,10 +29019,14 @@
28699 }else{
28700 eputz("Usage: .echo on|off\n");
28701 rc = 1;
28702 }
28703 }else
 
 
 
 
28704
28705 if( c=='e' && cli_strncmp(azArg[0], "eqp", n)==0 ){
28706 if( nArg==2 ){
28707 p->autoEQPtest = 0;
28708 if( p->autoEQPtrace ){
@@ -29140,11 +29464,15 @@
29140 /* Below, resources must be freed before exit. */
29141 while( (nSkip--)>0 ){
29142 while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
29143 }
29144 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
29145 if( sqlite3_table_column_metadata(p->db, zSchema, zTable,0,0,0,0,0,0) ){
 
 
 
 
29146 /* Table does not exist. Create it. */
29147 sqlite3 *dbCols = 0;
29148 char *zRenames = 0;
29149 char *zColDefs;
29150 zCreate = sqlite3_mprintf("CREATE TABLE \"%w\".\"%w\"",
@@ -30212,11 +30540,14 @@
30212 }
30213 close_db(pSrc);
30214 }else
30215 #endif /* !defined(SQLITE_SHELL_FIDDLE) */
30216
30217 if( c=='s' && cli_strncmp(azArg[0], "scanstats", n)==0 ){
 
 
 
30218 if( nArg==2 ){
30219 if( cli_strcmp(azArg[1], "vm")==0 ){
30220 p->scanstatsOn = 3;
30221 }else
30222 if( cli_strcmp(azArg[1], "est")==0 ){
@@ -31267,11 +31598,13 @@
31267 { 0x10000000, 1, "OrderBySubq" },
31268 { 0xffffffff, 0, "All" },
31269 };
31270 unsigned int curOpt;
31271 unsigned int newOpt;
 
31272 int ii;
 
31273 sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, p->db, &curOpt);
31274 newOpt = curOpt;
31275 for(ii=2; ii<nArg; ii++){
31276 const char *z = azArg[ii];
31277 int useLabel = 0;
@@ -31308,28 +31641,32 @@
31308 }
31309 }
31310 }
31311 if( curOpt!=newOpt ){
31312 sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,p->db,newOpt);
31313 }else if( nArg<3 ){
31314 curOpt = ~newOpt;
 
31315 }
31316 if( newOpt==0 ){
31317 sqlite3_fputs("+All\n", p->out);
31318 }else if( newOpt==0xffffffff ){
31319 sqlite3_fputs("-All\n", p->out);
 
 
 
 
31320 }else{
31321 int jj;
31322 for(jj=0; jj<ArraySize(aLabel); jj++){
31323 unsigned int m = aLabel[jj].mask;
31324 if( !aLabel[jj].bDsply ) continue;
31325 if( (curOpt&m)!=(newOpt&m) ){
31326 sqlite3_fprintf(p->out, "%c%s\n", (newOpt & m)==0 ? '+' : '-',
31327 aLabel[jj].zLabel);
31328 }
31329 }
31330 }
 
31331 rc2 = isOk = 3;
31332 break;
31333 }
31334
31335 /* sqlite3_test_control(int, db, int) */
@@ -31786,11 +32123,10 @@
31786 SCAN_TRACKER_REFTYPE pst){
31787 char cin;
31788 char cWait = (char)qss; /* intentional narrowing loss */
31789 if( cWait==0 ){
31790 PlainScan:
31791 assert( cWait==0 );
31792 while( (cin = *zLine++)!=0 ){
31793 if( IsSpace(cin) )
31794 continue;
31795 switch (cin){
31796 case '-':
@@ -31838,11 +32174,10 @@
31838 switch( cWait ){
31839 case '*':
31840 if( *zLine != '/' )
31841 continue;
31842 ++zLine;
31843 cWait = 0;
31844 CONTINUE_PROMPT_AWAITC(pst, 0);
31845 qss = QSS_SETV(qss, 0);
31846 goto PlainScan;
31847 case '`': case '\'': case '"':
31848 if(*zLine==cWait){
@@ -31850,11 +32185,10 @@
31850 ++zLine;
31851 continue;
31852 }
31853 deliberate_fall_through;
31854 case ']':
31855 cWait = 0;
31856 CONTINUE_PROMPT_AWAITC(pst, 0);
31857 qss = QSS_SETV(qss, 0);
31858 goto PlainScan;
31859 default: assert(0);
31860 }
@@ -32038,11 +32372,14 @@
32038 if( doAutoDetectRestore(p, zSql) ) return 1;
32039 return 0;
32040 }
32041
32042 static void echo_group_input(ShellState *p, const char *zDo){
32043 if( ShellHasFlag(p, SHFLG_Echo) ) sqlite3_fprintf(p->out, "%s\n", zDo);
 
 
 
32044 }
32045
32046 #ifdef SQLITE_SHELL_FIDDLE
32047 /*
32048 ** Alternate one_input_line() impl for wasm mode. This is not in the primary
@@ -32498,10 +32835,19 @@
32498 }
32499
32500 static void sayAbnormalExit(void){
32501 if( seenInterrupt ) eputz("Program interrupted.\n");
32502 }
 
 
 
 
 
 
 
 
 
32503
32504 #ifndef SQLITE_SHELL_IS_UTF8
32505 # if (defined(_WIN32) || defined(WIN32)) \
32506 && (defined(_MSC_VER) || (defined(UNICODE) && defined(__GNUC__)))
32507 # define SQLITE_SHELL_IS_UTF8 (0)
@@ -32735,12 +33081,10 @@
32735 case 0: sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); break;
32736 case 2: sqlite3_config(SQLITE_CONFIG_MULTITHREAD); break;
32737 default: sqlite3_config(SQLITE_CONFIG_SERIALIZED); break;
32738 }
32739 }else if( cli_strcmp(z,"-vfstrace")==0 ){
32740 vfstrace_register("trace",0,(int(*)(const char*,void*))sqlite3_fputs,
32741 stderr,1);
32742 bEnableVfstrace = 1;
32743 #ifdef SQLITE_ENABLE_MULTIPLEX
32744 }else if( cli_strcmp(z,"-multiplex")==0 ){
32745 extern int sqlite3_multiplex_initialize(const char*,int);
32746 sqlite3_multiplex_initialize(0, 1);
@@ -32833,10 +33177,13 @@
32833 "%s: Error: no database filename specified\n", Argv0);
32834 return 1;
32835 #endif
32836 }
32837 data.out = stdout;
 
 
 
32838 #ifndef SQLITE_SHELL_FIDDLE
32839 sqlite3_appendvfs_init(0,0,0);
32840 #endif
32841
32842 /* Go ahead and open the database file if it already exists. If the
@@ -33077,19 +33424,14 @@
33077 */
33078 if( stdin_is_interactive ){
33079 char *zHome;
33080 char *zHistory;
33081 int nHistory;
33082 #if CIO_WIN_WC_XLATE
33083 # define SHELL_CIO_CHAR_SET (stdout_is_console? " (UTF-16 console I/O)" : "")
33084 #else
33085 # define SHELL_CIO_CHAR_SET ""
33086 #endif
33087 sqlite3_fprintf(stdout,
33088 "SQLite version %s %.19s%s\n" /*extra-version-info*/
33089 "Enter \".help\" for usage hints.\n",
33090 sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET);
33091 if( warnInmemoryDb ){
33092 sputz(stdout, "Connected to a ");
33093 printBold("transient in-memory database");
33094 sputz(stdout, ".\nUse \".open FILENAME\" to reopen on a"
33095 " persistent database.\n");
33096
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -457,14 +457,24 @@
457 ** that into UTF-8. Otherwise, non-ASCII characters all get translated
458 ** into '?'.
459 */
460 wchar_t *b1 = sqlite3_malloc( sz*sizeof(wchar_t) );
461 if( b1==0 ) return 0;
462 #ifndef SQLITE_USE_STDIO_FOR_CONSOLE
463 DWORD nRead = 0;
464 if( IsConsole(in)
465 && ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), b1, sz, &nRead, 0)
466 ){
467 b1[nRead] = 0;
468 }else
469 #endif
470 {
471 _setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT);
472 if( fgetws(b1, sz/4, in)==0 ){
473 sqlite3_free(b1);
474 return 0;
475 }
476 }
477 WideCharToMultiByte(CP_UTF8, 0, b1, -1, buf, sz, 0, 0);
478 sqlite3_free(b1);
479 return buf;
480 }else{
@@ -516,24 +526,37 @@
526 if( !UseWtextForOutput(out) ){
527 /* Writing to a file or other destination, just write bytes without
528 ** any translation. */
529 return fputs(z, out);
530 }else{
531 /* One must use UTF16 in order to get unicode support when writing
532 ** to the console on Windows.
 
533 */
534 int sz = (int)strlen(z);
535 wchar_t *b1 = sqlite3_malloc( (sz+1)*sizeof(wchar_t) );
536 if( b1==0 ) return 0;
537 sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz);
538 b1[sz] = 0;
539
540 #ifndef SQLITE_STDIO_FOR_CONSOLE
541 DWORD nWr = 0;
542 if( IsConsole(out)
543 && WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),b1,sz,&nWr,0)
544 ){
545 /* If writing to the console, then the WriteConsoleW() is all we
546 ** need to do. */
547 }else
548 #endif
549 {
550 /* For non-console I/O, or if SQLITE_USE_STDIO_FOR_CONSOLE is defined
551 ** then write using the standard library. */
552 _setmode(_fileno(out), _O_U8TEXT);
553 if( UseBinaryWText(out) ){
554 piecemealOutput(b1, sz, out);
555 }else{
556 fputws(b1, out);
557 }
558 }
559 sqlite3_free(b1);
560 return 0;
561 }
562 }
@@ -2344,11 +2367,11 @@
2367 **
2368 ******************************************************************************
2369 **
2370 ** This SQLite extension implements functions that compute SHA3 hashes
2371 ** in the way described by the (U.S.) NIST FIPS 202 SHA-3 Standard.
2372 ** Three SQL functions are implemented:
2373 **
2374 ** sha3(X,SIZE)
2375 ** sha3_agg(Y,SIZE)
2376 ** sha3_query(Z,SIZE)
2377 **
@@ -14170,11 +14193,11 @@
14193 /* A view. Or a trigger on a view. */
14194 if( zSql ) rc = expertSchemaSql(p->dbv, zSql, pzErrmsg);
14195 }else{
14196 IdxTable *pTab;
14197 rc = idxGetTableInfo(p->db, zName, &pTab, pzErrmsg);
14198 if( rc==SQLITE_OK && ALWAYS(pTab!=0) ){
14199 int i;
14200 char *zInner = 0;
14201 char *zOuter = 0;
14202 pTab->pNext = p->pTable;
14203 p->pTable = pTab;
@@ -16238,11 +16261,31 @@
16261 **
16262 ** Similar compiler commands will work on different systems. The key
16263 ** invariants are (1) you must have -DSQLITE_ENABLE_VFSTRACE so that
16264 ** the shell.c source file will know to include the -vfstrace command-line
16265 ** option and (2) you must compile and link the three source files
16266 ** shell,c, test_vfstrace.c, and sqlite3.c.
16267 **
16268 ** RUNTIME CONTROL OF VFSTRACE OUTPUT
16269 **
16270 ** The application can use the "vfstrace" pragma to control which VFS
16271 ** APIs are traced. To disable all output:
16272 **
16273 ** PRAGMA vfstrace('-all');
16274 **
16275 ** To enable all output (which is the default setting):
16276 **
16277 ** PRAGMA vfstrace('+all');
16278 **
16279 ** Individual APIs can be enabled or disabled by name, with or without
16280 ** the initial "x" character. For example, to set up for tracing lock
16281 ** primatives only:
16282 **
16283 ** PRAGMA vfstrace('-all, +Lock,Unlock,ShmLock');
16284 **
16285 ** The argument to the vfstrace pragma ignores capitalization and any
16286 ** characters other than alphabetics, '+', and '-'.
16287 */
16288 #include <stdlib.h>
16289 #include <string.h>
16290 /* #include "sqlite3.h" */
16291
@@ -16252,10 +16295,12 @@
16295 */
16296 typedef struct vfstrace_info vfstrace_info;
16297 struct vfstrace_info {
16298 sqlite3_vfs *pRootVfs; /* The underlying real VFS */
16299 int (*xOut)(const char*, void*); /* Send output here */
16300 unsigned int mTrace; /* Mask of interfaces to trace */
16301 u8 bOn; /* Tracing on/off */
16302 void *pOutArg; /* First argument to xOut */
16303 const char *zVfsName; /* Name of this trace-VFS */
16304 sqlite3_vfs *pTraceVfs; /* Pointer back to the trace VFS */
16305 };
16306
@@ -16268,10 +16313,42 @@
16313 vfstrace_info *pInfo; /* The trace-VFS to which this file belongs */
16314 const char *zFName; /* Base name of the file */
16315 sqlite3_file *pReal; /* The real underlying file */
16316 };
16317
16318 /*
16319 ** Bit values for vfstrace_info.mTrace.
16320 */
16321 #define VTR_CLOSE 0x00000001
16322 #define VTR_READ 0x00000002
16323 #define VTR_WRITE 0x00000004
16324 #define VTR_TRUNC 0x00000008
16325 #define VTR_SYNC 0x00000010
16326 #define VTR_FSIZE 0x00000020
16327 #define VTR_LOCK 0x00000040
16328 #define VTR_UNLOCK 0x00000080
16329 #define VTR_CRL 0x00000100
16330 #define VTR_FCTRL 0x00000200
16331 #define VTR_SECSZ 0x00000400
16332 #define VTR_DEVCHAR 0x00000800
16333 #define VTR_SHMLOCK 0x00001000
16334 #define VTR_SHMMAP 0x00002000
16335 #define VTR_SHMBAR 0x00004000
16336 #define VTR_SHMUNMAP 0x00008000
16337 #define VTR_OPEN 0x00010000
16338 #define VTR_DELETE 0x00020000
16339 #define VTR_ACCESS 0x00040000
16340 #define VTR_FULLPATH 0x00080000
16341 #define VTR_DLOPEN 0x00100000
16342 #define VTR_DLERR 0x00200000
16343 #define VTR_DLSYM 0x00400000
16344 #define VTR_DLCLOSE 0x00800000
16345 #define VTR_RAND 0x01000000
16346 #define VTR_SLEEP 0x02000000
16347 #define VTR_CURTIME 0x04000000
16348 #define VTR_LASTERR 0x08000000
16349
16350 /*
16351 ** Method declarations for vfstrace_file.
16352 */
16353 static int vfstraceClose(sqlite3_file*);
16354 static int vfstraceRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
@@ -16332,15 +16409,17 @@
16409 const char *zFormat,
16410 ...
16411 ){
16412 va_list ap;
16413 char *zMsg;
16414 if( pInfo->bOn ){
16415 va_start(ap, zFormat);
16416 zMsg = sqlite3_vmprintf(zFormat, ap);
16417 va_end(ap);
16418 pInfo->xOut(zMsg, pInfo->pOutArg);
16419 sqlite3_free(zMsg);
16420 }
16421 }
16422
16423 /*
16424 ** Try to convert an error code into a symbolic name for that error code.
16425 */
@@ -16434,18 +16513,26 @@
16513 int i = *pI;
16514 while( zAppend[0] ){ z[i++] = *(zAppend++); }
16515 z[i] = 0;
16516 *pI = i;
16517 }
16518
16519 /*
16520 ** Turn tracing output on or off according to mMask.
16521 */
16522 static void vfstraceOnOff(vfstrace_info *pInfo, unsigned int mMask){
16523 pInfo->bOn = (pInfo->mTrace & mMask)!=0;
16524 }
16525
16526 /*
16527 ** Close an vfstrace-file.
16528 */
16529 static int vfstraceClose(sqlite3_file *pFile){
16530 vfstrace_file *p = (vfstrace_file *)pFile;
16531 vfstrace_info *pInfo = p->pInfo;
16532 int rc;
16533 vfstraceOnOff(pInfo, VTR_CLOSE);
16534 vfstrace_printf(pInfo, "%s.xClose(%s)", pInfo->zVfsName, p->zFName);
16535 rc = p->pReal->pMethods->xClose(p->pReal);
16536 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16537 if( rc==SQLITE_OK ){
16538 sqlite3_free((void*)p->base.pMethods);
@@ -16464,10 +16551,11 @@
16551 sqlite_int64 iOfst
16552 ){
16553 vfstrace_file *p = (vfstrace_file *)pFile;
16554 vfstrace_info *pInfo = p->pInfo;
16555 int rc;
16556 vfstraceOnOff(pInfo, VTR_READ);
16557 vfstrace_printf(pInfo, "%s.xRead(%s,n=%d,ofst=%lld)",
16558 pInfo->zVfsName, p->zFName, iAmt, iOfst);
16559 rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
16560 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16561 return rc;
@@ -16483,10 +16571,11 @@
16571 sqlite_int64 iOfst
16572 ){
16573 vfstrace_file *p = (vfstrace_file *)pFile;
16574 vfstrace_info *pInfo = p->pInfo;
16575 int rc;
16576 vfstraceOnOff(pInfo, VTR_WRITE);
16577 vfstrace_printf(pInfo, "%s.xWrite(%s,n=%d,ofst=%lld)",
16578 pInfo->zVfsName, p->zFName, iAmt, iOfst);
16579 rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
16580 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16581 return rc;
@@ -16497,10 +16586,11 @@
16586 */
16587 static int vfstraceTruncate(sqlite3_file *pFile, sqlite_int64 size){
16588 vfstrace_file *p = (vfstrace_file *)pFile;
16589 vfstrace_info *pInfo = p->pInfo;
16590 int rc;
16591 vfstraceOnOff(pInfo, VTR_TRUNC);
16592 vfstrace_printf(pInfo, "%s.xTruncate(%s,%lld)", pInfo->zVfsName, p->zFName,
16593 size);
16594 rc = p->pReal->pMethods->xTruncate(p->pReal, size);
16595 vfstrace_printf(pInfo, " -> %d\n", rc);
16596 return rc;
@@ -16521,10 +16611,11 @@
16611 else if( flags & SQLITE_SYNC_NORMAL ) strappend(zBuf, &i, "|NORMAL");
16612 if( flags & SQLITE_SYNC_DATAONLY ) strappend(zBuf, &i, "|DATAONLY");
16613 if( flags & ~(SQLITE_SYNC_FULL|SQLITE_SYNC_DATAONLY) ){
16614 sqlite3_snprintf(sizeof(zBuf)-i, &zBuf[i], "|0x%x", flags);
16615 }
16616 vfstraceOnOff(pInfo, VTR_SYNC);
16617 vfstrace_printf(pInfo, "%s.xSync(%s,%s)", pInfo->zVfsName, p->zFName,
16618 &zBuf[1]);
16619 rc = p->pReal->pMethods->xSync(p->pReal, flags);
16620 vfstrace_printf(pInfo, " -> %d\n", rc);
16621 return rc;
@@ -16535,10 +16626,11 @@
16626 */
16627 static int vfstraceFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
16628 vfstrace_file *p = (vfstrace_file *)pFile;
16629 vfstrace_info *pInfo = p->pInfo;
16630 int rc;
16631 vfstraceOnOff(pInfo, VTR_FSIZE);
16632 vfstrace_printf(pInfo, "%s.xFileSize(%s)", pInfo->zVfsName, p->zFName);
16633 rc = p->pReal->pMethods->xFileSize(p->pReal, pSize);
16634 vfstrace_print_errcode(pInfo, " -> %s,", rc);
16635 vfstrace_printf(pInfo, " size=%lld\n", *pSize);
16636 return rc;
@@ -16563,10 +16655,11 @@
16655 */
16656 static int vfstraceLock(sqlite3_file *pFile, int eLock){
16657 vfstrace_file *p = (vfstrace_file *)pFile;
16658 vfstrace_info *pInfo = p->pInfo;
16659 int rc;
16660 vfstraceOnOff(pInfo, VTR_LOCK);
16661 vfstrace_printf(pInfo, "%s.xLock(%s,%s)", pInfo->zVfsName, p->zFName,
16662 lockName(eLock));
16663 rc = p->pReal->pMethods->xLock(p->pReal, eLock);
16664 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16665 return rc;
@@ -16577,10 +16670,11 @@
16670 */
16671 static int vfstraceUnlock(sqlite3_file *pFile, int eLock){
16672 vfstrace_file *p = (vfstrace_file *)pFile;
16673 vfstrace_info *pInfo = p->pInfo;
16674 int rc;
16675 vfstraceOnOff(pInfo, VTR_UNLOCK);
16676 vfstrace_printf(pInfo, "%s.xUnlock(%s,%s)", pInfo->zVfsName, p->zFName,
16677 lockName(eLock));
16678 rc = p->pReal->pMethods->xUnlock(p->pReal, eLock);
16679 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16680 return rc;
@@ -16591,10 +16685,11 @@
16685 */
16686 static int vfstraceCheckReservedLock(sqlite3_file *pFile, int *pResOut){
16687 vfstrace_file *p = (vfstrace_file *)pFile;
16688 vfstrace_info *pInfo = p->pInfo;
16689 int rc;
16690 vfstraceOnOff(pInfo, VTR_CRL);
16691 vfstrace_printf(pInfo, "%s.xCheckReservedLock(%s,%d)",
16692 pInfo->zVfsName, p->zFName);
16693 rc = p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut);
16694 vfstrace_print_errcode(pInfo, " -> %s", rc);
16695 vfstrace_printf(pInfo, ", out=%d\n", *pResOut);
@@ -16610,10 +16705,11 @@
16705 int rc;
16706 char zBuf[100];
16707 char zBuf2[100];
16708 char *zOp;
16709 char *zRVal = 0;
16710 vfstraceOnOff(pInfo, VTR_FCTRL);
16711 switch( op ){
16712 case SQLITE_FCNTL_LOCKSTATE: zOp = "LOCKSTATE"; break;
16713 case SQLITE_GET_LOCKPROXYFILE: zOp = "GET_LOCKPROXYFILE"; break;
16714 case SQLITE_SET_LOCKPROXYFILE: zOp = "SET_LOCKPROXYFILE"; break;
16715 case SQLITE_LAST_ERRNO: zOp = "LAST_ERRNO"; break;
@@ -16638,10 +16734,83 @@
16734 case SQLITE_FCNTL_OVERWRITE: zOp = "OVERWRITE"; break;
16735 case SQLITE_FCNTL_VFSNAME: zOp = "VFSNAME"; break;
16736 case SQLITE_FCNTL_POWERSAFE_OVERWRITE: zOp = "POWERSAFE_OVERWRITE"; break;
16737 case SQLITE_FCNTL_PRAGMA: {
16738 const char *const* a = (const char*const*)pArg;
16739 if( a[1] && strcmp(a[1],"vfstrace")==0 && a[2] ){
16740 const u8 *zArg = (const u8*)a[2];
16741 if( zArg[0]>='0' && zArg[0]<=9 ){
16742 pInfo->mTrace = (sqlite3_uint64)strtoll(a[2], 0, 0);
16743 }else{
16744 static const struct {
16745 const char *z;
16746 unsigned int m;
16747 } aKw[] = {
16748 { "all", 0xffffffff },
16749 { "close", VTR_CLOSE },
16750 { "read", VTR_READ },
16751 { "write", VTR_WRITE },
16752 { "truncate", VTR_TRUNC },
16753 { "sync", VTR_SYNC },
16754 { "filesize", VTR_FSIZE },
16755 { "lock", VTR_LOCK },
16756 { "unlock", VTR_UNLOCK },
16757 { "checkreservedlock", VTR_CRL },
16758 { "filecontrol", VTR_FCTRL },
16759 { "sectorsize", VTR_SECSZ },
16760 { "devicecharacteristics", VTR_DEVCHAR },
16761 { "shmlock", VTR_SHMLOCK },
16762 { "shmmap", VTR_SHMMAP },
16763 { "shmummap", VTR_SHMUNMAP },
16764 { "shmbarrier", VTR_SHMBAR },
16765 { "open", VTR_OPEN },
16766 { "delete", VTR_DELETE },
16767 { "access", VTR_ACCESS },
16768 { "fullpathname", VTR_FULLPATH },
16769 { "dlopen", VTR_DLOPEN },
16770 { "dlerror", VTR_DLERR },
16771 { "dlsym", VTR_DLSYM },
16772 { "dlclose", VTR_DLCLOSE },
16773 { "randomness", VTR_RAND },
16774 { "sleep", VTR_SLEEP },
16775 { "currenttime", VTR_CURTIME },
16776 { "currenttimeint64", VTR_CURTIME },
16777 { "getlasterror", VTR_LASTERR },
16778 };
16779 int onOff = 1;
16780 while( zArg[0] ){
16781 int jj, n;
16782 while( zArg[0]!=0 && zArg[0]!='-' && zArg[0]!='+'
16783 && !isalpha(zArg[0]) ) zArg++;
16784 if( zArg[0]==0 ) break;
16785 if( zArg[0]=='-' ){
16786 onOff = 0;
16787 zArg++;
16788 }else if( zArg[0]=='+' ){
16789 onOff = 1;
16790 zArg++;
16791 }
16792 while( !isalpha(zArg[0]) ){
16793 if( zArg[0]==0 ) break;
16794 zArg++;
16795 }
16796 if( zArg[0]=='x' && isalpha(zArg[1]) ) zArg++;
16797 for(n=0; isalpha(zArg[n]); n++){}
16798 for(jj=0; jj<(int)(sizeof(aKw)/sizeof(aKw[0])); jj++){
16799 if( sqlite3_strnicmp(aKw[jj].z,(const char*)zArg,n)==0 ){
16800 if( onOff ){
16801 pInfo->mTrace |= aKw[jj].m;
16802 }else{
16803 pInfo->mTrace &= ~aKw[jj].m;
16804 }
16805 break;
16806 }
16807 }
16808 zArg += n;
16809 }
16810 }
16811 }
16812 sqlite3_snprintf(sizeof(zBuf), zBuf, "PRAGMA,[%s,%s]",a[1],a[2]);
16813 zOp = zBuf;
16814 break;
16815 }
16816 case SQLITE_FCNTL_BUSYHANDLER: zOp = "BUSYHANDLER"; break;
@@ -16733,10 +16902,11 @@
16902 */
16903 static int vfstraceSectorSize(sqlite3_file *pFile){
16904 vfstrace_file *p = (vfstrace_file *)pFile;
16905 vfstrace_info *pInfo = p->pInfo;
16906 int rc;
16907 vfstraceOnOff(pInfo, VTR_SECSZ);
16908 vfstrace_printf(pInfo, "%s.xSectorSize(%s)", pInfo->zVfsName, p->zFName);
16909 rc = p->pReal->pMethods->xSectorSize(p->pReal);
16910 vfstrace_printf(pInfo, " -> %d\n", rc);
16911 return rc;
16912 }
@@ -16746,10 +16916,11 @@
16916 */
16917 static int vfstraceDeviceCharacteristics(sqlite3_file *pFile){
16918 vfstrace_file *p = (vfstrace_file *)pFile;
16919 vfstrace_info *pInfo = p->pInfo;
16920 int rc;
16921 vfstraceOnOff(pInfo, VTR_DEVCHAR);
16922 vfstrace_printf(pInfo, "%s.xDeviceCharacteristics(%s)",
16923 pInfo->zVfsName, p->zFName);
16924 rc = p->pReal->pMethods->xDeviceCharacteristics(p->pReal);
16925 vfstrace_printf(pInfo, " -> 0x%08x\n", rc);
16926 return rc;
@@ -16757,25 +16928,43 @@
16928
16929 /*
16930 ** Shared-memory operations.
16931 */
16932 static int vfstraceShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
16933 static const char *azLockName[] = {
16934 "WRITE",
16935 "CKPT",
16936 "RECOVER",
16937 "READ0",
16938 "READ1",
16939 "READ2",
16940 "READ3",
16941 "READ4",
16942 };
16943 vfstrace_file *p = (vfstrace_file *)pFile;
16944 vfstrace_info *pInfo = p->pInfo;
16945 int rc;
16946 char zLck[100];
16947 int i = 0;
16948 vfstraceOnOff(pInfo, VTR_SHMLOCK);
16949 memcpy(zLck, "|0", 3);
16950 if( flags & SQLITE_SHM_UNLOCK ) strappend(zLck, &i, "|UNLOCK");
16951 if( flags & SQLITE_SHM_LOCK ) strappend(zLck, &i, "|LOCK");
16952 if( flags & SQLITE_SHM_SHARED ) strappend(zLck, &i, "|SHARED");
16953 if( flags & SQLITE_SHM_EXCLUSIVE ) strappend(zLck, &i, "|EXCLUSIVE");
16954 if( flags & ~(0xf) ){
16955 sqlite3_snprintf(sizeof(zLck)-i, &zLck[i], "|0x%x", flags);
16956 }
16957 if( ofst>=0 && ofst<(int)(sizeof(azLockName)/sizeof(azLockName[0])) ){
16958 vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=%d(%s),n=%d,%s)",
16959 pInfo->zVfsName, p->zFName, ofst, azLockName[ofst],
16960 n, &zLck[1]);
16961 }else{
16962 vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=5d,n=%d,%s)",
16963 pInfo->zVfsName, p->zFName, ofst,
16964 n, &zLck[1]);
16965 }
16966 rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
16967 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16968 return rc;
16969 }
16970 static int vfstraceShmMap(
@@ -16786,26 +16975,29 @@
16975 void volatile **pp
16976 ){
16977 vfstrace_file *p = (vfstrace_file *)pFile;
16978 vfstrace_info *pInfo = p->pInfo;
16979 int rc;
16980 vfstraceOnOff(pInfo, VTR_SHMMAP);
16981 vfstrace_printf(pInfo, "%s.xShmMap(%s,iRegion=%d,szRegion=%d,isWrite=%d,*)",
16982 pInfo->zVfsName, p->zFName, iRegion, szRegion, isWrite);
16983 rc = p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
16984 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16985 return rc;
16986 }
16987 static void vfstraceShmBarrier(sqlite3_file *pFile){
16988 vfstrace_file *p = (vfstrace_file *)pFile;
16989 vfstrace_info *pInfo = p->pInfo;
16990 vfstraceOnOff(pInfo, VTR_SHMBAR);
16991 vfstrace_printf(pInfo, "%s.xShmBarrier(%s)\n", pInfo->zVfsName, p->zFName);
16992 p->pReal->pMethods->xShmBarrier(p->pReal);
16993 }
16994 static int vfstraceShmUnmap(sqlite3_file *pFile, int delFlag){
16995 vfstrace_file *p = (vfstrace_file *)pFile;
16996 vfstrace_info *pInfo = p->pInfo;
16997 int rc;
16998 vfstraceOnOff(pInfo, VTR_SHMUNMAP);
16999 vfstrace_printf(pInfo, "%s.xShmUnmap(%s,delFlag=%d)",
17000 pInfo->zVfsName, p->zFName, delFlag);
17001 rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
17002 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
17003 return rc;
@@ -16829,10 +17021,11 @@
17021 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17022 p->pInfo = pInfo;
17023 p->zFName = zName ? fileTail(zName) : "<temp>";
17024 p->pReal = (sqlite3_file *)&p[1];
17025 rc = pRoot->xOpen(pRoot, zName, p->pReal, flags, pOutFlags);
17026 vfstraceOnOff(pInfo, VTR_OPEN);
17027 vfstrace_printf(pInfo, "%s.xOpen(%s,flags=0x%x)",
17028 pInfo->zVfsName, p->zFName, flags);
17029 if( p->pReal->pMethods ){
17030 sqlite3_io_methods *pNew = sqlite3_malloc( sizeof(*pNew) );
17031 const sqlite3_io_methods *pSub = p->pReal->pMethods;
@@ -16874,10 +17067,11 @@
17067 */
17068 static int vfstraceDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
17069 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17070 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17071 int rc;
17072 vfstraceOnOff(pInfo, VTR_DELETE);
17073 vfstrace_printf(pInfo, "%s.xDelete(\"%s\",%d)",
17074 pInfo->zVfsName, zPath, dirSync);
17075 rc = pRoot->xDelete(pRoot, zPath, dirSync);
17076 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
17077 return rc;
@@ -16894,10 +17088,11 @@
17088 int *pResOut
17089 ){
17090 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17091 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17092 int rc;
17093 vfstraceOnOff(pInfo, VTR_ACCESS);
17094 vfstrace_printf(pInfo, "%s.xAccess(\"%s\",%d)",
17095 pInfo->zVfsName, zPath, flags);
17096 rc = pRoot->xAccess(pRoot, zPath, flags, pResOut);
17097 vfstrace_print_errcode(pInfo, " -> %s", rc);
17098 vfstrace_printf(pInfo, ", out=%d\n", *pResOut);
@@ -16916,10 +17111,11 @@
17111 char *zOut
17112 ){
17113 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17114 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17115 int rc;
17116 vfstraceOnOff(pInfo, VTR_FULLPATH);
17117 vfstrace_printf(pInfo, "%s.xFullPathname(\"%s\")",
17118 pInfo->zVfsName, zPath);
17119 rc = pRoot->xFullPathname(pRoot, zPath, nOut, zOut);
17120 vfstrace_print_errcode(pInfo, " -> %s", rc);
17121 vfstrace_printf(pInfo, ", out=\"%.*s\"\n", nOut, zOut);
@@ -16930,10 +17126,11 @@
17126 ** Open the dynamic library located at zPath and return a handle.
17127 */
17128 static void *vfstraceDlOpen(sqlite3_vfs *pVfs, const char *zPath){
17129 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17130 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17131 vfstraceOnOff(pInfo, VTR_DLOPEN);
17132 vfstrace_printf(pInfo, "%s.xDlOpen(\"%s\")\n", pInfo->zVfsName, zPath);
17133 return pRoot->xDlOpen(pRoot, zPath);
17134 }
17135
17136 /*
@@ -16942,10 +17139,11 @@
17139 ** with dynamic libraries.
17140 */
17141 static void vfstraceDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
17142 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17143 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17144 vfstraceOnOff(pInfo, VTR_DLERR);
17145 vfstrace_printf(pInfo, "%s.xDlError(%d)", pInfo->zVfsName, nByte);
17146 pRoot->xDlError(pRoot, nByte, zErrMsg);
17147 vfstrace_printf(pInfo, " -> \"%s\"", zErrMsg);
17148 }
17149
@@ -16963,10 +17161,11 @@
17161 ** Close the dynamic library handle pHandle.
17162 */
17163 static void vfstraceDlClose(sqlite3_vfs *pVfs, void *pHandle){
17164 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17165 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17166 vfstraceOnOff(pInfo, VTR_DLCLOSE);
17167 vfstrace_printf(pInfo, "%s.xDlOpen()\n", pInfo->zVfsName);
17168 pRoot->xDlClose(pRoot, pHandle);
17169 }
17170
17171 /*
@@ -16974,10 +17173,11 @@
17173 ** random data.
17174 */
17175 static int vfstraceRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
17176 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17177 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17178 vfstraceOnOff(pInfo, VTR_RAND);
17179 vfstrace_printf(pInfo, "%s.xRandomness(%d)\n", pInfo->zVfsName, nByte);
17180 return pRoot->xRandomness(pRoot, nByte, zBufOut);
17181 }
17182
17183 /*
@@ -16985,34 +17185,52 @@
17185 ** actually slept.
17186 */
17187 static int vfstraceSleep(sqlite3_vfs *pVfs, int nMicro){
17188 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17189 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17190 vfstraceOnOff(pInfo, VTR_SLEEP);
17191 vfstrace_printf(pInfo, "%s.xSleep(%d)\n", pInfo->zVfsName, nMicro);
17192 return pRoot->xSleep(pRoot, nMicro);
17193 }
17194
17195 /*
17196 ** Return the current time as a Julian Day number in *pTimeOut.
17197 */
17198 static int vfstraceCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
17199 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17200 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17201 int rc;
17202 vfstraceOnOff(pInfo, VTR_CURTIME);
17203 vfstrace_printf(pInfo, "%s.xCurrentTime()", pInfo->zVfsName);
17204 rc = pRoot->xCurrentTime(pRoot, pTimeOut);
17205 vfstrace_printf(pInfo, " -> %.17g\n", *pTimeOut);
17206 return rc;
17207 }
17208 static int vfstraceCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
17209 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17210 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17211 int rc;
17212 vfstraceOnOff(pInfo, VTR_CURTIME);
17213 vfstrace_printf(pInfo, "%s.xCurrentTimeInt64()", pInfo->zVfsName);
17214 rc = pRoot->xCurrentTimeInt64(pRoot, pTimeOut);
17215 vfstrace_printf(pInfo, " -> %lld\n", *pTimeOut);
17216 return rc;
17217 }
17218
17219 /*
17220 ** Return the most recent error code and message
17221 */
17222 static int vfstraceGetLastError(sqlite3_vfs *pVfs, int nErr, char *zErr){
17223 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17224 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17225 int rc;
17226 vfstraceOnOff(pInfo, VTR_LASTERR);
17227 vfstrace_printf(pInfo, "%s.xGetLastError(%d,zBuf)", pInfo->zVfsName, nErr);
17228 if( nErr ) zErr[0] = 0;
17229 rc = pRoot->xGetLastError(pRoot, nErr, zErr);
17230 vfstrace_printf(pInfo, " -> zBuf[] = \"%s\", rc = %d\n", nErr?zErr:"", rc);
17231 return rc;
17232 }
17233
17234 /*
17235 ** Override system calls.
17236 */
@@ -17102,10 +17320,12 @@
17320 pInfo->pRootVfs = pRoot;
17321 pInfo->xOut = xOut;
17322 pInfo->pOutArg = pOutArg;
17323 pInfo->zVfsName = pNew->zName;
17324 pInfo->pTraceVfs = pNew;
17325 pInfo->mTrace = 0xffffffff;
17326 pInfo->bOn = 1;
17327 vfstrace_printf(pInfo, "%s.enabled_for(\"%s\")\n",
17328 pInfo->zVfsName, pRoot->zName);
17329 return sqlite3_vfs_register(pNew, makeDefault);
17330 }
17331
@@ -20231,10 +20451,12 @@
20451 apVal[iField] = sqlite3_value_dup( pVal );
20452 if( apVal[iField]==0 ){
20453 recoverError(p, SQLITE_NOMEM, 0);
20454 }
20455 p1->nVal = iField+1;
20456 }else if( pTab->nCol==0 ){
20457 p1->nVal = pTab->nCol;
20458 }
20459 p1->iPrevCell = iCell;
20460 p1->iPrevPage = iPage;
20461 }
20462 }else{
@@ -22010,11 +22232,11 @@
22232
22233 /*
22234 ** Output the given string as quoted according to JSON quoting rules.
22235 */
22236 static void output_json_string(FILE *out, const char *z, i64 n){
22237 unsigned char c;
22238 static const char *zq = "\"";
22239 static long ctrlMask = ~0L;
22240 static const char *zDQBS = "\"\\";
22241 const char *pcLimit;
22242 char ace[3] = "\\?";
@@ -22030,11 +22252,11 @@
22252 if( pcEnd > z ){
22253 sqlite3_fprintf(out, "%.*s", (int)(pcEnd-z), z);
22254 z = pcEnd;
22255 }
22256 if( z >= pcLimit ) break;
22257 c = (unsigned char)*(z++);
22258 switch( c ){
22259 case '"': case '\\':
22260 cbsSay = (char)c;
22261 break;
22262 case '\b': cbsSay = 'b'; break;
@@ -22045,11 +22267,11 @@
22267 default: cbsSay = 0; break;
22268 }
22269 if( cbsSay ){
22270 ace[1] = cbsSay;
22271 sqlite3_fputs(ace, out);
22272 }else if( c<=0x1f || c>=0x7f ){
22273 sqlite3_fprintf(out, "\\u%04x", c);
22274 }else{
22275 ace[1] = (char)c;
22276 sqlite3_fputs(ace+1, out);
22277 }
@@ -24787,13 +25009,13 @@
25009 if( rc ){
25010 sqlite3_fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
25011 }else{
25012 rc = SQLITE_CORRUPT;
25013 }
 
25014 free(zQ2);
25015 }
25016 sqlite3_free(zErr);
25017 return rc;
25018 }
25019
25020 /*
25021 ** Text of help messages.
@@ -24852,10 +25074,11 @@
25074 ".databases List names and files of attached databases",
25075 ".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
25076 #if SQLITE_SHELL_HAVE_RECOVER
25077 ".dbinfo ?DB? Show status information about the database",
25078 #endif
25079 ".dbtotxt Hex dump of the database file",
25080 ".dump ?OBJECTS? Render database content as SQL",
25081 " Options:",
25082 " --data-only Output only INSERT statements",
25083 " --newlines Allow unescaped newline characters in output",
25084 " --nosys Omit system tables (ex: \"sqlite_stat1\")",
@@ -26401,18 +26624,24 @@
26624 #endif
26625
26626 /*
26627 ** Run an SQL command and return the single integer result.
26628 */
26629 static int db_int(sqlite3 *db, const char *zSql, ...){
26630 sqlite3_stmt *pStmt;
26631 int res = 0;
26632 char *z;
26633 va_list ap;
26634 va_start(ap, zSql);
26635 z = sqlite3_vmprintf(zSql, ap);
26636 va_end(ap);
26637 sqlite3_prepare_v2(db, z, -1, &pStmt, 0);
26638 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
26639 res = sqlite3_column_int(pStmt,0);
26640 }
26641 sqlite3_finalize(pStmt);
26642 sqlite3_free(z);
26643 return res;
26644 }
26645
26646 #if SQLITE_SHELL_HAVE_RECOVER
26647 /*
@@ -26511,21 +26740,112 @@
26740 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_schema");
26741 }else{
26742 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_schema", zDb);
26743 }
26744 for(i=0; i<ArraySize(aQuery); i++){
26745 int val = db_int(p->db, aQuery[i].zSql, zSchemaTab);
 
 
26746 sqlite3_fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
26747 }
26748 sqlite3_free(zSchemaTab);
26749 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
26750 sqlite3_fprintf(p->out, "%-20s %u\n", "data version", iDataVersion);
26751 return 0;
26752 }
26753 #endif /* SQLITE_SHELL_HAVE_RECOVER */
26754
26755 /*
26756 ** Implementation of the ".dbtotxt" command.
26757 **
26758 ** Return 1 on error, 2 to exit, and 0 otherwise.
26759 */
26760 static int shell_dbtotxt_command(ShellState *p, int nArg, char **azArg){
26761 sqlite3_stmt *pStmt = 0;
26762 sqlite3_int64 nPage = 0;
26763 int pgSz = 0;
26764 const char *zTail;
26765 char *zName = 0;
26766 int rc, i, j;
26767 unsigned char bShow[256]; /* Characters ok to display */
26768
26769 UNUSED_PARAMETER(nArg);
26770 UNUSED_PARAMETER(azArg);
26771 memset(bShow, '.', sizeof(bShow));
26772 for(i=' '; i<='~'; i++){
26773 if( i!='{' && i!='}' && i!='"' && i!='\\' ) bShow[i] = (unsigned char)i;
26774 }
26775 rc = sqlite3_prepare_v2(p->db, "PRAGMA page_size", -1, &pStmt, 0);
26776 if( rc ) goto dbtotxt_error;
26777 rc = 0;
26778 if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error;
26779 pgSz = sqlite3_column_int(pStmt, 0);
26780 sqlite3_finalize(pStmt);
26781 pStmt = 0;
26782 if( pgSz<512 || pgSz>65536 || (pgSz&(pgSz-1))!=0 ) goto dbtotxt_error;
26783 rc = sqlite3_prepare_v2(p->db, "PRAGMA page_count", -1, &pStmt, 0);
26784 if( rc ) goto dbtotxt_error;
26785 rc = 0;
26786 if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error;
26787 nPage = sqlite3_column_int64(pStmt, 0);
26788 sqlite3_finalize(pStmt);
26789 pStmt = 0;
26790 if( nPage<1 ) goto dbtotxt_error;
26791 rc = sqlite3_prepare_v2(p->db, "PRAGMA databases", -1, &pStmt, 0);
26792 if( rc ) goto dbtotxt_error;
26793 if( sqlite3_step(pStmt)!=SQLITE_ROW ){
26794 zTail = "unk.db";
26795 }else{
26796 const char *zFilename = (const char*)sqlite3_column_text(pStmt, 2);
26797 if( zFilename==0 || zFilename[0]==0 ) zFilename = "unk.db";
26798 zTail = strrchr(zFilename, '/');
26799 #if defined(_WIN32)
26800 if( zTail==0 ) zTail = strrchr(zFilename, '\\');
26801 #endif
26802 }
26803 zName = strdup(zTail);
26804 shell_check_oom(zName);
26805 sqlite3_fprintf(p->out, "| size %lld pagesize %d filename %s\n",
26806 nPage*pgSz, pgSz, zName);
26807 sqlite3_finalize(pStmt);
26808 pStmt = 0;
26809 rc = sqlite3_prepare_v2(p->db,
26810 "SELECT pgno, data FROM sqlite_dbpage ORDER BY pgno", -1, &pStmt, 0);
26811 if( rc ) goto dbtotxt_error;
26812 while( sqlite3_step(pStmt)==SQLITE_ROW ){
26813 sqlite3_int64 pgno = sqlite3_column_int64(pStmt, 0);
26814 const u8 *aData = sqlite3_column_blob(pStmt, 1);
26815 int seenPageLabel = 0;
26816 for(i=0; i<pgSz; i+=16){
26817 const u8 *aLine = aData+i;
26818 for(j=0; j<16 && aLine[j]==0; j++){}
26819 if( j==16 ) continue;
26820 if( !seenPageLabel ){
26821 sqlite3_fprintf(p->out, "| page %lld offset %lld\n", pgno, pgno*pgSz);
26822 seenPageLabel = 1;
26823 }
26824 sqlite3_fprintf(p->out, "| %5d:", i);
26825 for(j=0; j<16; j++) sqlite3_fprintf(p->out, " %02x", aLine[j]);
26826 sqlite3_fprintf(p->out, " ");
26827 for(j=0; j<16; j++){
26828 unsigned char c = (unsigned char)aLine[j];
26829 sqlite3_fprintf(p->out, "%c", bShow[c]);
26830 }
26831 sqlite3_fprintf(p->out, "\n");
26832 }
26833 }
26834 sqlite3_finalize(pStmt);
26835 sqlite3_fprintf(p->out, "| end %s\n", zName);
26836 free(zName);
26837 return 0;
26838
26839 dbtotxt_error:
26840 if( rc ){
26841 sqlite3_fprintf(stderr, "ERROR: %s\n", sqlite3_errmsg(p->db));
26842 }
26843 sqlite3_finalize(pStmt);
26844 free(zName);
26845 return 1;
26846 }
26847
26848 /*
26849 ** Print the given string as an error message.
26850 */
26851 static void shellEmitError(const char *zErr){
@@ -28078,12 +28398,12 @@
28398 }else if( *pDb==0 ){
28399 return 0;
28400 }else{
28401 /* Formulate the columns spec, close the DB, zero *pDb. */
28402 char *zColsSpec = 0;
28403 int hasDupes = db_int(*pDb, "%s", zHasDupes);
28404 int nDigits = (hasDupes)? db_int(*pDb, "%s", zColDigits) : 0;
28405 if( hasDupes ){
28406 #ifdef SHELL_COLUMN_RENAME_CLEAN
28407 rc = sqlite3_exec(*pDb, zDedoctor, 0, 0, 0);
28408 rc_err_oom_die(rc);
28409 #endif
@@ -28094,11 +28414,11 @@
28414 sqlite3_bind_int(pStmt, 1, nDigits);
28415 rc = sqlite3_step(pStmt);
28416 sqlite3_finalize(pStmt);
28417 if( rc!=SQLITE_DONE ) rc_err_oom_die(SQLITE_NOMEM);
28418 }
28419 assert(db_int(*pDb, "%s", zHasDupes)==0); /* Consider: remove this */
28420 rc = sqlite3_prepare_v2(*pDb, zCollectVar, -1, &pStmt, 0);
28421 rc_err_oom_die(rc);
28422 rc = sqlite3_step(pStmt);
28423 if( rc==SQLITE_ROW ){
28424 zColsSpec = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
@@ -28699,10 +29019,14 @@
29019 }else{
29020 eputz("Usage: .echo on|off\n");
29021 rc = 1;
29022 }
29023 }else
29024
29025 if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbtotxt", n)==0 ){
29026 rc = shell_dbtotxt_command(p, nArg, azArg);
29027 }else
29028
29029 if( c=='e' && cli_strncmp(azArg[0], "eqp", n)==0 ){
29030 if( nArg==2 ){
29031 p->autoEQPtest = 0;
29032 if( p->autoEQPtrace ){
@@ -29140,11 +29464,15 @@
29464 /* Below, resources must be freed before exit. */
29465 while( (nSkip--)>0 ){
29466 while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
29467 }
29468 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
29469 if( sqlite3_table_column_metadata(p->db, zSchema, zTable,0,0,0,0,0,0)
29470 && 0==db_int(p->db, "SELECT count(*) FROM \"%w\".sqlite_schema"
29471 " WHERE name=%Q AND type='view'",
29472 zSchema ? zSchema : "main", zTable)
29473 ){
29474 /* Table does not exist. Create it. */
29475 sqlite3 *dbCols = 0;
29476 char *zRenames = 0;
29477 char *zColDefs;
29478 zCreate = sqlite3_mprintf("CREATE TABLE \"%w\".\"%w\"",
@@ -30212,11 +30540,14 @@
30540 }
30541 close_db(pSrc);
30542 }else
30543 #endif /* !defined(SQLITE_SHELL_FIDDLE) */
30544
30545 if( c=='s' &&
30546 (cli_strncmp(azArg[0], "scanstats", n)==0 ||
30547 cli_strncmp(azArg[0], "scanstatus", n)==0)
30548 ){
30549 if( nArg==2 ){
30550 if( cli_strcmp(azArg[1], "vm")==0 ){
30551 p->scanstatsOn = 3;
30552 }else
30553 if( cli_strcmp(azArg[1], "est")==0 ){
@@ -31267,11 +31598,13 @@
31598 { 0x10000000, 1, "OrderBySubq" },
31599 { 0xffffffff, 0, "All" },
31600 };
31601 unsigned int curOpt;
31602 unsigned int newOpt;
31603 unsigned int m;
31604 int ii;
31605 int nOff;
31606 sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, p->db, &curOpt);
31607 newOpt = curOpt;
31608 for(ii=2; ii<nArg; ii++){
31609 const char *z = azArg[ii];
31610 int useLabel = 0;
@@ -31308,28 +31641,32 @@
31641 }
31642 }
31643 }
31644 if( curOpt!=newOpt ){
31645 sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,p->db,newOpt);
31646 }
31647 for(ii=nOff=0, m=1; ii<32; ii++, m <<= 1){
31648 if( m & newOpt ) nOff++;
31649 }
31650 if( nOff<12 ){
31651 sqlite3_fputs("+All", p->out);
31652 for(ii=0; ii<ArraySize(aLabel); ii++){
31653 if( !aLabel[ii].bDsply ) continue;
31654 if( (newOpt & aLabel[ii].mask)!=0 ){
31655 sqlite3_fprintf(p->out, " -%s", aLabel[ii].zLabel);
31656 }
31657 }
31658 }else{
31659 sqlite3_fputs("-All", p->out);
31660 for(ii=0; ii<ArraySize(aLabel); ii++){
31661 if( !aLabel[ii].bDsply ) continue;
31662 if( (newOpt & aLabel[ii].mask)==0 ){
31663 sqlite3_fprintf(p->out, " +%s", aLabel[ii].zLabel);
 
 
31664 }
31665 }
31666 }
31667 sqlite3_fputs("\n", p->out);
31668 rc2 = isOk = 3;
31669 break;
31670 }
31671
31672 /* sqlite3_test_control(int, db, int) */
@@ -31786,11 +32123,10 @@
32123 SCAN_TRACKER_REFTYPE pst){
32124 char cin;
32125 char cWait = (char)qss; /* intentional narrowing loss */
32126 if( cWait==0 ){
32127 PlainScan:
 
32128 while( (cin = *zLine++)!=0 ){
32129 if( IsSpace(cin) )
32130 continue;
32131 switch (cin){
32132 case '-':
@@ -31838,11 +32174,10 @@
32174 switch( cWait ){
32175 case '*':
32176 if( *zLine != '/' )
32177 continue;
32178 ++zLine;
 
32179 CONTINUE_PROMPT_AWAITC(pst, 0);
32180 qss = QSS_SETV(qss, 0);
32181 goto PlainScan;
32182 case '`': case '\'': case '"':
32183 if(*zLine==cWait){
@@ -31850,11 +32185,10 @@
32185 ++zLine;
32186 continue;
32187 }
32188 deliberate_fall_through;
32189 case ']':
 
32190 CONTINUE_PROMPT_AWAITC(pst, 0);
32191 qss = QSS_SETV(qss, 0);
32192 goto PlainScan;
32193 default: assert(0);
32194 }
@@ -32038,11 +32372,14 @@
32372 if( doAutoDetectRestore(p, zSql) ) return 1;
32373 return 0;
32374 }
32375
32376 static void echo_group_input(ShellState *p, const char *zDo){
32377 if( ShellHasFlag(p, SHFLG_Echo) ){
32378 sqlite3_fprintf(p->out, "%s\n", zDo);
32379 fflush(p->out);
32380 }
32381 }
32382
32383 #ifdef SQLITE_SHELL_FIDDLE
32384 /*
32385 ** Alternate one_input_line() impl for wasm mode. This is not in the primary
@@ -32498,10 +32835,19 @@
32835 }
32836
32837 static void sayAbnormalExit(void){
32838 if( seenInterrupt ) eputz("Program interrupted.\n");
32839 }
32840
32841 /* Routine to output from vfstrace
32842 */
32843 static int vfstraceOut(const char *z, void *pArg){
32844 ShellState *p = (ShellState*)pArg;
32845 sqlite3_fputs(z, p->out);
32846 fflush(p->out);
32847 return 1;
32848 }
32849
32850 #ifndef SQLITE_SHELL_IS_UTF8
32851 # if (defined(_WIN32) || defined(WIN32)) \
32852 && (defined(_MSC_VER) || (defined(UNICODE) && defined(__GNUC__)))
32853 # define SQLITE_SHELL_IS_UTF8 (0)
@@ -32735,12 +33081,10 @@
33081 case 0: sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); break;
33082 case 2: sqlite3_config(SQLITE_CONFIG_MULTITHREAD); break;
33083 default: sqlite3_config(SQLITE_CONFIG_SERIALIZED); break;
33084 }
33085 }else if( cli_strcmp(z,"-vfstrace")==0 ){
 
 
33086 bEnableVfstrace = 1;
33087 #ifdef SQLITE_ENABLE_MULTIPLEX
33088 }else if( cli_strcmp(z,"-multiplex")==0 ){
33089 extern int sqlite3_multiplex_initialize(const char*,int);
33090 sqlite3_multiplex_initialize(0, 1);
@@ -32833,10 +33177,13 @@
33177 "%s: Error: no database filename specified\n", Argv0);
33178 return 1;
33179 #endif
33180 }
33181 data.out = stdout;
33182 if( bEnableVfstrace ){
33183 vfstrace_register("trace",0,vfstraceOut, &data, 1);
33184 }
33185 #ifndef SQLITE_SHELL_FIDDLE
33186 sqlite3_appendvfs_init(0,0,0);
33187 #endif
33188
33189 /* Go ahead and open the database file if it already exists. If the
@@ -33077,19 +33424,14 @@
33424 */
33425 if( stdin_is_interactive ){
33426 char *zHome;
33427 char *zHistory;
33428 int nHistory;
 
 
 
 
 
33429 sqlite3_fprintf(stdout,
33430 "SQLite version %s %.19s\n" /*extra-version-info*/
33431 "Enter \".help\" for usage hints.\n",
33432 sqlite3_libversion(), sqlite3_sourceid());
33433 if( warnInmemoryDb ){
33434 sputz(stdout, "Connected to a ");
33435 printBold("transient in-memory database");
33436 sputz(stdout, ".\nUse \".open FILENAME\" to reopen on a"
33437 " persistent database.\n");
33438
+860 -1153
--- 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
-** 5495b12569c318d5020b4b5a625a392ef8e7 with changes in files:
21
+** e2bae4143afd07de1ae55a6d2606a3b541a5 with changes in files:
2222
**
2323
**
2424
*/
2525
#ifndef SQLITE_AMALGAMATION
2626
#define SQLITE_CORE 1
@@ -27,11 +27,10 @@
2727
#define SQLITE_AMALGAMATION 1
2828
#ifndef SQLITE_PRIVATE
2929
# define SQLITE_PRIVATE static
3030
#endif
3131
/************** Begin file sqliteInt.h ***************************************/
32
-#line 1 "tsrc/sqliteInt.h"
3332
/*
3433
** 2001 September 15
3534
**
3635
** The author disclaims copyright to this source code. In place of
3736
** a legal notice, here is a blessing:
@@ -88,11 +87,10 @@
8887
** compiler warnings due to subsequent content in this file and other files
8988
** that are included by this file.
9089
*/
9190
/************** Include msvc.h in the middle of sqliteInt.h ******************/
9291
/************** Begin file msvc.h ********************************************/
93
-#line 1 "tsrc/msvc.h"
9492
/*
9593
** 2015 January 12
9694
**
9795
** The author disclaims copyright to this source code. In place of
9896
** a legal notice, here is a blessing:
@@ -137,18 +135,16 @@
137135
138136
#endif /* SQLITE_MSVC_H */
139137
140138
/************** End of msvc.h ************************************************/
141139
/************** Continuing where we left off in sqliteInt.h ******************/
142
-#line 60 "tsrc/sqliteInt.h"
143140
144141
/*
145142
** Special setup for VxWorks
146143
*/
147144
/************** Include vxworks.h in the middle of sqliteInt.h ***************/
148145
/************** Begin file vxworks.h *****************************************/
149
-#line 1 "tsrc/vxworks.h"
150146
/*
151147
** 2015-03-02
152148
**
153149
** The author disclaims copyright to this source code. In place of
154150
** a legal notice, here is a blessing:
@@ -180,11 +176,10 @@
180176
#define HAVE_LSTAT 1
181177
#endif /* defined(_WRS_KERNEL) */
182178
183179
/************** End of vxworks.h *********************************************/
184180
/************** Continuing where we left off in sqliteInt.h ******************/
185
-#line 65 "tsrc/sqliteInt.h"
186181
187182
/*
188183
** These #defines should enable >2GB file support on POSIX if the
189184
** underlying operating system supports it. If the OS lacks
190185
** large file support, or if the OS is windows, these should be no-ops.
@@ -320,11 +315,10 @@
320315
** first in QNX. Also, the _USE_32BIT_TIME_T macro must appear first for
321316
** MinGW.
322317
*/
323318
/************** Include sqlite3.h in the middle of sqliteInt.h ***************/
324319
/************** Begin file sqlite3.h *****************************************/
325
-#line 1 "tsrc/sqlite3.h"
326320
/*
327321
** 2001-09-15
328322
**
329323
** The author disclaims copyright to this source code. In place of
330324
** a legal notice, here is a blessing:
@@ -471,11 +465,11 @@
471465
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
472466
** [sqlite_version()] and [sqlite_source_id()].
473467
*/
474468
#define SQLITE_VERSION "3.48.0"
475469
#define SQLITE_VERSION_NUMBER 3048000
476
-#define SQLITE_SOURCE_ID "2024-11-06 12:58:31 5495b12569c318d5020b4b5a625a392ef8e777b81c0200624fbbc2a6b5eddef9"
470
+#define SQLITE_SOURCE_ID "2024-12-09 20:46:36 e2bae4143afd07de1ae55a6d2606a3b541a5b94568aa41f6a96e5d1245471653"
477471
478472
/*
479473
** CAPI3REF: Run-Time Library Version Numbers
480474
** KEYWORDS: sqlite3_version sqlite3_sourceid
481475
**
@@ -1423,10 +1417,15 @@
14231417
** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
14241418
** opcode causes the xFileControl method to swap the file handle with the one
14251419
** pointed to by the pArg argument. This capability is used during testing
14261420
** and only needs to be supported when SQLITE_TEST is defined.
14271421
**
1422
+** <li>[[SQLITE_FCNTL_NULL_IO]]
1423
+** The [SQLITE_FCNTL_NULL_IO] opcode sets the low-level file descriptor
1424
+** or file handle for the [sqlite3_file] object such that it will no longer
1425
+** read or write to the database file.
1426
+**
14281427
** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
14291428
** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
14301429
** be advantageous to block on the next WAL lock if the lock is not immediately
14311430
** available. The WAL subsystem issues this signal during rare
14321431
** circumstances in order to fix a problem with priority inversion.
@@ -1576,10 +1575,11 @@
15761575
#define SQLITE_FCNTL_RESERVE_BYTES 38
15771576
#define SQLITE_FCNTL_CKPT_START 39
15781577
#define SQLITE_FCNTL_EXTERNAL_READER 40
15791578
#define SQLITE_FCNTL_CKSM_FILE 41
15801579
#define SQLITE_FCNTL_RESET_CACHE 42
1580
+#define SQLITE_FCNTL_NULL_IO 43
15811581
15821582
/* deprecated names */
15831583
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
15841584
#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
15851585
#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -2954,14 +2954,18 @@
29542954
**
29552955
** ^These functions return the number of rows modified, inserted or
29562956
** deleted by the most recently completed INSERT, UPDATE or DELETE
29572957
** statement on the database connection specified by the only parameter.
29582958
** The two functions are identical except for the type of the return value
2959
-** and that if the number of rows modified by the most recent INSERT, UPDATE
2959
+** and that if the number of rows modified by the most recent INSERT, UPDATE,
29602960
** or DELETE is greater than the maximum value supported by type "int", then
29612961
** the return value of sqlite3_changes() is undefined. ^Executing any other
29622962
** type of SQL statement does not modify the value returned by these functions.
2963
+** For the purposes of this interface, a CREATE TABLE AS SELECT statement
2964
+** does not count as an INSERT, UPDATE or DELETE statement and hence the rows
2965
+** added to the new table by the CREATE TABLE AS SELECT statement are not
2966
+** counted.
29632967
**
29642968
** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are
29652969
** considered - auxiliary changes caused by [CREATE TRIGGER | triggers],
29662970
** [foreign key actions] or [REPLACE] constraint resolution are not counted.
29672971
**
@@ -4517,15 +4521,26 @@
45174521
**
45184522
** [[SQLITE_PREPARE_NO_VTAB]] <dt>SQLITE_PREPARE_NO_VTAB</dt>
45194523
** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler
45204524
** to return an error (error code SQLITE_ERROR) if the statement uses
45214525
** any virtual tables.
4526
+**
4527
+** [[SQLITE_PREPARE_DONT_LOG]] <dt>SQLITE_PREPARE_DONT_LOG</dt>
4528
+** <dd>The SQLITE_PREPARE_DONT_LOG flag prevents SQL compiler
4529
+** errors from being sent to the error log defined by
4530
+** [SQLITE_CONFIG_LOG]. This can be used, for example, to do test
4531
+** compiles to see if some SQL syntax is well-formed, without generating
4532
+** messages on the global error log when it is not. If the test compile
4533
+** fails, the sqlite3_prepare_v3() call returns the same error indications
4534
+** with or without this flag; it just omits the call to [sqlite3_log()] that
4535
+** logs the error.
45224536
** </dl>
45234537
*/
45244538
#define SQLITE_PREPARE_PERSISTENT 0x01
45254539
#define SQLITE_PREPARE_NORMALIZE 0x02
45264540
#define SQLITE_PREPARE_NO_VTAB 0x04
4541
+#define SQLITE_PREPARE_DONT_LOG 0x10
45274542
45284543
/*
45294544
** CAPI3REF: Compiling An SQL Statement
45304545
** KEYWORDS: {SQL statement compiler}
45314546
** METHOD: sqlite3
@@ -13463,17 +13478,32 @@
1346313478
** This is used to access token iToken of phrase hit iIdx within the
1346413479
** current row. If iIdx is less than zero or greater than or equal to the
1346513480
** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise,
1346613481
** output variable (*ppToken) is set to point to a buffer containing the
1346713482
** matching document token, and (*pnToken) to the size of that buffer in
13468
-** bytes. This API is not available if the specified token matches a
13469
-** prefix query term. In that case both output variables are always set
13470
-** to 0.
13483
+** bytes.
1347113484
**
1347213485
** The output text is not a copy of the document text that was tokenized.
1347313486
** It is the output of the tokenizer module. For tokendata=1 tables, this
1347413487
** includes any embedded 0x00 and trailing data.
13488
+**
13489
+** This API may be slow in some cases if the token identified by parameters
13490
+** iIdx and iToken matched a prefix token in the query. In most cases, the
13491
+** first call to this API for each prefix token in the query is forced
13492
+** to scan the portion of the full-text index that matches the prefix
13493
+** token to collect the extra data required by this API. If the prefix
13494
+** token matches a large number of token instances in the document set,
13495
+** this may be a performance problem.
13496
+**
13497
+** If the user knows in advance that a query may use this API for a
13498
+** prefix token, FTS5 may be configured to collect all required data as part
13499
+** of the initial querying of the full-text index, avoiding the second scan
13500
+** entirely. This also causes prefix queries that do not use this API to
13501
+** run more slowly and use more memory. FTS5 may be configured in this way
13502
+** either on a per-table basis using the [FTS5 insttoken | 'insttoken']
13503
+** option, or on a per-query basis using the
13504
+** [fts5_insttoken | fts5_insttoken()] user function.
1347513505
**
1347613506
** This API can be quite slow if used with an FTS5 table created with the
1347713507
** "detail=none" or "detail=column" option.
1347813508
**
1347913509
** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale)
@@ -13908,11 +13938,10 @@
1390813938
/******** End of fts5.h *********/
1390913939
#endif /* SQLITE3_H */
1391013940
1391113941
/************** End of sqlite3.h *********************************************/
1391213942
/************** Continuing where we left off in sqliteInt.h ******************/
13913
-#line 203 "tsrc/sqliteInt.h"
1391413943
1391513944
/*
1391613945
** Reuse the STATIC_LRU for mutex access to sqlite3_temp_directory.
1391713946
*/
1391813947
#define SQLITE_MUTEX_STATIC_TEMPDIR SQLITE_MUTEX_STATIC_VFS1
@@ -13926,11 +13955,10 @@
1392613955
#define SQLITECONFIG_H 1
1392713956
#endif
1392813957
1392913958
/************** Include sqliteLimit.h in the middle of sqliteInt.h ***********/
1393013959
/************** Begin file sqliteLimit.h *************************************/
13931
-#line 1 "tsrc/sqliteLimit.h"
1393213960
/*
1393313961
** 2007 May 7
1393413962
**
1393513963
** The author disclaims copyright to this source code. In place of
1393613964
** a legal notice, here is a blessing:
@@ -13952,10 +13980,11 @@
1395213980
** to count the size: 2^31-1 or 2147483647.
1395313981
*/
1395413982
#ifndef SQLITE_MAX_LENGTH
1395513983
# define SQLITE_MAX_LENGTH 1000000000
1395613984
#endif
13985
+#define SQLITE_MIN_LENGTH 30 /* Minimum value for the length limit */
1395713986
1395813987
/*
1395913988
** This is the maximum number of
1396013989
**
1396113990
** * Columns in a table
@@ -14140,11 +14169,10 @@
1414014169
# define SQLITE_MAX_TRIGGER_DEPTH 1000
1414114170
#endif
1414214171
1414314172
/************** End of sqliteLimit.h *****************************************/
1414414173
/************** Continuing where we left off in sqliteInt.h ******************/
14145
-#line 219 "tsrc/sqliteInt.h"
1414614174
1414714175
/* Disable nuisance warnings on Borland compilers */
1414814176
#if defined(__BORLANDC__)
1414914177
#pragma warn -rch /* unreachable code */
1415014178
#pragma warn -ccc /* Condition is always true or false */
@@ -14558,11 +14586,10 @@
1455814586
#define likely(X) (X)
1455914587
#define unlikely(X) (X)
1456014588
1456114589
/************** Include hash.h in the middle of sqliteInt.h ******************/
1456214590
/************** Begin file hash.h ********************************************/
14563
-#line 1 "tsrc/hash.h"
1456414591
/*
1456514592
** 2001 September 22
1456614593
**
1456714594
** The author disclaims copyright to this source code. In place of
1456814595
** a legal notice, here is a blessing:
@@ -14658,14 +14685,12 @@
1465814685
1465914686
#endif /* SQLITE_HASH_H */
1466014687
1466114688
/************** End of hash.h ************************************************/
1466214689
/************** Continuing where we left off in sqliteInt.h ******************/
14663
-#line 635 "tsrc/sqliteInt.h"
1466414690
/************** Include parse.h in the middle of sqliteInt.h *****************/
1466514691
/************** Begin file parse.h *******************************************/
14666
-#line 1 "tsrc/parse.h"
1466714692
#define TK_SEMI 1
1466814693
#define TK_EXPLAIN 2
1466914694
#define TK_QUERY 3
1467014695
#define TK_PLAN 4
1467114696
#define TK_BEGIN 5
@@ -14850,11 +14875,10 @@
1485014875
#define TK_SPACE 184
1485114876
#define TK_ILLEGAL 185
1485214877
1485314878
/************** End of parse.h ***********************************************/
1485414879
/************** Continuing where we left off in sqliteInt.h ******************/
14855
-#line 636 "tsrc/sqliteInt.h"
1485614880
#include <stdio.h>
1485714881
#include <stdlib.h>
1485814882
#include <string.h>
1485914883
#include <assert.h>
1486014884
#include <stddef.h>
@@ -15616,11 +15640,10 @@
1561615640
** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque
1561715641
** pointer types (i.e. FuncDef) defined above.
1561815642
*/
1561915643
/************** Include os.h in the middle of sqliteInt.h ********************/
1562015644
/************** Begin file os.h **********************************************/
15621
-#line 1 "tsrc/os.h"
1562215645
/*
1562315646
** 2001 September 16
1562415647
**
1562515648
** The author disclaims copyright to this source code. In place of
1562615649
** a legal notice, here is a blessing:
@@ -15645,11 +15668,10 @@
1564515668
** Attempt to automatically detect the operating system and setup the
1564615669
** necessary pre-processor macros for it.
1564715670
*/
1564815671
/************** Include os_setup.h in the middle of os.h *********************/
1564915672
/************** Begin file os_setup.h ****************************************/
15650
-#line 1 "tsrc/os_setup.h"
1565115673
/*
1565215674
** 2013 November 25
1565315675
**
1565415676
** The author disclaims copyright to this source code. In place of
1565515677
** a legal notice, here is a blessing:
@@ -15740,11 +15762,10 @@
1574015762
1574115763
#endif /* SQLITE_OS_SETUP_H */
1574215764
1574315765
/************** End of os_setup.h ********************************************/
1574415766
/************** Continuing where we left off in os.h *************************/
15745
-#line 28 "tsrc/os.h"
1574615767
1574715768
/* If the SET_FULLSYNC macro is not defined above, then make it
1574815769
** a no-op
1574915770
*/
1575015771
#ifndef SET_FULLSYNC
@@ -15942,14 +15963,12 @@
1594215963
1594315964
#endif /* _SQLITE_OS_H_ */
1594415965
1594515966
/************** End of os.h **************************************************/
1594615967
/************** Continuing where we left off in sqliteInt.h ******************/
15947
-#line 1400 "tsrc/sqliteInt.h"
1594815968
/************** Include pager.h in the middle of sqliteInt.h *****************/
1594915969
/************** Begin file pager.h *******************************************/
15950
-#line 1 "tsrc/pager.h"
1595115970
/*
1595215971
** 2001 September 15
1595315972
**
1595415973
** The author disclaims copyright to this source code. In place of
1595515974
** a legal notice, here is a blessing:
@@ -16196,14 +16215,12 @@
1619616215
1619716216
#endif /* SQLITE_PAGER_H */
1619816217
1619916218
/************** End of pager.h ***********************************************/
1620016219
/************** Continuing where we left off in sqliteInt.h ******************/
16201
-#line 1401 "tsrc/sqliteInt.h"
1620216220
/************** Include btree.h in the middle of sqliteInt.h *****************/
1620316221
/************** Begin file btree.h *******************************************/
16204
-#line 1 "tsrc/btree.h"
1620516222
/*
1620616223
** 2001 September 15
1620716224
**
1620816225
** The author disclaims copyright to this source code. In place of
1620916226
** a legal notice, here is a blessing:
@@ -16627,14 +16644,12 @@
1662716644
1662816645
#endif /* SQLITE_BTREE_H */
1662916646
1663016647
/************** End of btree.h ***********************************************/
1663116648
/************** Continuing where we left off in sqliteInt.h ******************/
16632
-#line 1402 "tsrc/sqliteInt.h"
1663316649
/************** Include vdbe.h in the middle of sqliteInt.h ******************/
1663416650
/************** Begin file vdbe.h ********************************************/
16635
-#line 1 "tsrc/vdbe.h"
1663616651
/*
1663716652
** 2001 September 15
1663816653
**
1663916654
** The author disclaims copyright to this source code. In place of
1664016655
** a legal notice, here is a blessing:
@@ -16814,11 +16829,10 @@
1681416829
** The makefile scans the vdbe.c source file and creates the "opcodes.h"
1681516830
** header file that defines a number for each opcode used by the VDBE.
1681616831
*/
1681716832
/************** Include opcodes.h in the middle of vdbe.h ********************/
1681816833
/************** Begin file opcodes.h *****************************************/
16819
-#line 1 "tsrc/opcodes.h"
1682016834
/* Automatically generated. Do not edit */
1682116835
/* See the tool/mkopcodeh.tcl script for details */
1682216836
#define OP_Savepoint 0
1682316837
#define OP_AutoCommit 1
1682416838
#define OP_Transaction 2
@@ -17056,17 +17070,16 @@
1705617070
*/
1705717071
#define SQLITE_MX_JUMP_OPCODE 64 /* Maximum JUMP opcode */
1705817072
1705917073
/************** End of opcodes.h *********************************************/
1706017074
/************** Continuing where we left off in vdbe.h ***********************/
17061
-#line 183 "tsrc/vdbe.h"
1706217075
1706317076
/*
1706417077
** Additional non-public SQLITE_PREPARE_* flags
1706517078
*/
1706617079
#define SQLITE_PREPARE_SAVESQL 0x80 /* Preserve SQL text */
17067
-#define SQLITE_PREPARE_MASK 0x0f /* Mask of public flags */
17080
+#define SQLITE_PREPARE_MASK 0x1f /* Mask of public flags */
1706817081
1706917082
/*
1707017083
** Prototypes for the VDBE interface. See comments on the implementation
1707117084
** for a description of what each of these routines does.
1707217085
*/
@@ -17306,14 +17319,12 @@
1730617319
1730717320
#endif /* SQLITE_VDBE_H */
1730817321
1730917322
/************** End of vdbe.h ************************************************/
1731017323
/************** Continuing where we left off in sqliteInt.h ******************/
17311
-#line 1403 "tsrc/sqliteInt.h"
1731217324
/************** Include pcache.h in the middle of sqliteInt.h ****************/
1731317325
/************** Begin file pcache.h ******************************************/
17314
-#line 1 "tsrc/pcache.h"
1731517326
/*
1731617327
** 2008 August 05
1731717328
**
1731817329
** The author disclaims copyright to this source code. In place of
1731917330
** a legal notice, here is a blessing:
@@ -17503,14 +17514,12 @@
1750317514
1750417515
#endif /* _PCACHE_H_ */
1750517516
1750617517
/************** End of pcache.h **********************************************/
1750717518
/************** Continuing where we left off in sqliteInt.h ******************/
17508
-#line 1404 "tsrc/sqliteInt.h"
1750917519
/************** Include mutex.h in the middle of sqliteInt.h *****************/
1751017520
/************** Begin file mutex.h *******************************************/
17511
-#line 1 "tsrc/mutex.h"
1751217521
/*
1751317522
** 2007 August 28
1751417523
**
1751517524
** The author disclaims copyright to this source code. In place of
1751617525
** a legal notice, here is a blessing:
@@ -17581,11 +17590,10 @@
1758117590
SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
1758217591
#endif /* defined(SQLITE_MUTEX_OMIT) */
1758317592
1758417593
/************** End of mutex.h ***********************************************/
1758517594
/************** Continuing where we left off in sqliteInt.h ******************/
17586
-#line 1405 "tsrc/sqliteInt.h"
1758717595
1758817596
/* The SQLITE_EXTRA_DURABLE compile-time option used to set the default
1758917597
** synchronous setting to EXTRA. It is no longer supported.
1759017598
*/
1759117599
#ifdef SQLITE_EXTRA_DURABLE
@@ -21982,11 +21990,10 @@
2198221990
2198321991
#endif /* SQLITEINT_H */
2198421992
2198521993
/************** End of sqliteInt.h *******************************************/
2198621994
/************** Begin file os_common.h ***************************************/
21987
-#line 1 "tsrc/os_common.h"
2198821995
/*
2198921996
** 2004 May 22
2199021997
**
2199121998
** The author disclaims copyright to this source code. In place of
2199221999
** a legal notice, here is a blessing:
@@ -22085,11 +22092,10 @@
2208522092
2208622093
#endif /* !defined(_OS_COMMON_H_) */
2208722094
2208822095
/************** End of os_common.h *******************************************/
2208922096
/************** Begin file ctime.c *******************************************/
22090
-#line 1 "tsrc/ctime.c"
2209122097
/* DO NOT EDIT!
2209222098
** This file is automatically generated by the script in the canonical
2209322099
** SQLite source tree at tool/mkctimec.tcl.
2209422100
**
2209522101
** To modify this header, edit any of the various lists in that script
@@ -22885,11 +22891,10 @@
2288522891
2288622892
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
2288722893
2288822894
/************** End of ctime.c ***********************************************/
2288922895
/************** Begin file global.c ******************************************/
22890
-#line 1 "tsrc/global.c"
2289122896
/*
2289222897
** 2008 June 13
2289322898
**
2289422899
** The author disclaims copyright to this source code. In place of
2289522900
** a legal notice, here is a blessing:
@@ -23290,11 +23295,10 @@
2329023295
"TEXT"
2329123296
};
2329223297
2329323298
/************** End of global.c **********************************************/
2329423299
/************** Begin file status.c ******************************************/
23295
-#line 1 "tsrc/status.c"
2329623300
/*
2329723301
** 2008 June 18
2329823302
**
2329923303
** The author disclaims copyright to this source code. In place of
2330023304
** a legal notice, here is a blessing:
@@ -23309,11 +23313,10 @@
2330923313
** functionality.
2331023314
*/
2331123315
/* #include "sqliteInt.h" */
2331223316
/************** Include vdbeInt.h in the middle of status.c ******************/
2331323317
/************** Begin file vdbeInt.h *****************************************/
23314
-#line 1 "tsrc/vdbeInt.h"
2331523318
/*
2331623319
** 2003 September 6
2331723320
**
2331823321
** The author disclaims copyright to this source code. In place of
2331923322
** a legal notice, here is a blessing:
@@ -24046,11 +24049,10 @@
2404624049
2404724050
#endif /* !defined(SQLITE_VDBEINT_H) */
2404824051
2404924052
/************** End of vdbeInt.h *********************************************/
2405024053
/************** Continuing where we left off in status.c *********************/
24051
-#line 18 "tsrc/status.c"
2405224054
2405324055
/*
2405424056
** Variables in which to record status information.
2405524057
*/
2405624058
#if SQLITE_PTRSIZE>4
@@ -24431,11 +24433,10 @@
2443124433
return rc;
2443224434
}
2443324435
2443424436
/************** End of status.c **********************************************/
2443524437
/************** Begin file date.c ********************************************/
24436
-#line 1 "tsrc/date.c"
2443724438
/*
2443824439
** 2003 October 31
2443924440
**
2444024441
** The author disclaims copyright to this source code. In place of
2444124442
** a legal notice, here is a blessing:
@@ -26250,11 +26251,10 @@
2625026251
sqlite3InsertBuiltinFuncs(aDateTimeFuncs, ArraySize(aDateTimeFuncs));
2625126252
}
2625226253
2625326254
/************** End of date.c ************************************************/
2625426255
/************** Begin file os.c **********************************************/
26255
-#line 1 "tsrc/os.c"
2625626256
/*
2625726257
** 2005 November 29
2625826258
**
2625926259
** The author disclaims copyright to this source code. In place of
2626026260
** a legal notice, here is a blessing:
@@ -26701,11 +26701,10 @@
2670126701
return SQLITE_OK;
2670226702
}
2670326703
2670426704
/************** End of os.c **************************************************/
2670526705
/************** Begin file fault.c *******************************************/
26706
-#line 1 "tsrc/fault.c"
2670726706
/*
2670826707
** 2008 Jan 22
2670926708
**
2671026709
** The author disclaims copyright to this source code. In place of
2671126710
** a legal notice, here is a blessing:
@@ -26792,11 +26791,10 @@
2679226791
2679326792
#endif /* #ifndef SQLITE_UNTESTABLE */
2679426793
2679526794
/************** End of fault.c ***********************************************/
2679626795
/************** Begin file mem0.c ********************************************/
26797
-#line 1 "tsrc/mem0.c"
2679826796
/*
2679926797
** 2008 October 28
2680026798
**
2680126799
** The author disclaims copyright to this source code. In place of
2680226800
** a legal notice, here is a blessing:
@@ -26855,11 +26853,10 @@
2685526853
2685626854
#endif /* SQLITE_ZERO_MALLOC */
2685726855
2685826856
/************** End of mem0.c ************************************************/
2685926857
/************** Begin file mem1.c ********************************************/
26860
-#line 1 "tsrc/mem1.c"
2686126858
/*
2686226859
** 2007 August 14
2686326860
**
2686426861
** The author disclaims copyright to this source code. In place of
2686526862
** a legal notice, here is a blessing:
@@ -27150,11 +27147,10 @@
2715027147
2715127148
#endif /* SQLITE_SYSTEM_MALLOC */
2715227149
2715327150
/************** End of mem1.c ************************************************/
2715427151
/************** Begin file mem2.c ********************************************/
27155
-#line 1 "tsrc/mem2.c"
2715627152
/*
2715727153
** 2007 August 15
2715827154
**
2715927155
** The author disclaims copyright to this source code. In place of
2716027156
** a legal notice, here is a blessing:
@@ -27682,11 +27678,10 @@
2768227678
2768327679
#endif /* SQLITE_MEMDEBUG */
2768427680
2768527681
/************** End of mem2.c ************************************************/
2768627682
/************** Begin file mem3.c ********************************************/
27687
-#line 1 "tsrc/mem3.c"
2768827683
/*
2768927684
** 2007 October 14
2769027685
**
2769127686
** The author disclaims copyright to this source code. In place of
2769227687
** a legal notice, here is a blessing:
@@ -28373,11 +28368,10 @@
2837328368
2837428369
#endif /* SQLITE_ENABLE_MEMSYS3 */
2837528370
2837628371
/************** End of mem3.c ************************************************/
2837728372
/************** Begin file mem5.c ********************************************/
28378
-#line 1 "tsrc/mem5.c"
2837928373
/*
2838028374
** 2007 October 14
2838128375
**
2838228376
** The author disclaims copyright to this source code. In place of
2838328377
** a legal notice, here is a blessing:
@@ -28962,11 +28956,10 @@
2896228956
2896328957
#endif /* SQLITE_ENABLE_MEMSYS5 */
2896428958
2896528959
/************** End of mem5.c ************************************************/
2896628960
/************** Begin file mutex.c *******************************************/
28967
-#line 1 "tsrc/mutex.c"
2896828961
/*
2896928962
** 2007 August 14
2897028963
**
2897128964
** The author disclaims copyright to this source code. In place of
2897228965
** a legal notice, here is a blessing:
@@ -29340,11 +29333,10 @@
2934029333
2934129334
#endif /* !defined(SQLITE_MUTEX_OMIT) */
2934229335
2934329336
/************** End of mutex.c ***********************************************/
2934429337
/************** Begin file mutex_noop.c **************************************/
29345
-#line 1 "tsrc/mutex_noop.c"
2934629338
/*
2934729339
** 2008 October 07
2934829340
**
2934929341
** The author disclaims copyright to this source code. In place of
2935029342
** a legal notice, here is a blessing:
@@ -29559,11 +29551,10 @@
2955929551
#endif /* defined(SQLITE_MUTEX_NOOP) */
2956029552
#endif /* !defined(SQLITE_MUTEX_OMIT) */
2956129553
2956229554
/************** End of mutex_noop.c ******************************************/
2956329555
/************** Begin file mutex_unix.c **************************************/
29564
-#line 1 "tsrc/mutex_unix.c"
2956529556
/*
2956629557
** 2007 August 28
2956729558
**
2956829559
** The author disclaims copyright to this source code. In place of
2956929560
** a legal notice, here is a blessing:
@@ -29957,11 +29948,10 @@
2995729948
2995829949
#endif /* SQLITE_MUTEX_PTHREADS */
2995929950
2996029951
/************** End of mutex_unix.c ******************************************/
2996129952
/************** Begin file mutex_w32.c ***************************************/
29962
-#line 1 "tsrc/mutex_w32.c"
2996329953
/*
2996429954
** 2007 August 14
2996529955
**
2996629956
** The author disclaims copyright to this source code. In place of
2996729957
** a legal notice, here is a blessing:
@@ -29984,11 +29974,10 @@
2998429974
/*
2998529975
** Include the header file for the Windows VFS.
2998629976
*/
2998729977
/************** Include os_win.h in the middle of mutex_w32.c ****************/
2998829978
/************** Begin file os_win.h ******************************************/
29989
-#line 1 "tsrc/os_win.h"
2999029979
/*
2999129980
** 2013 November 25
2999229981
**
2999329982
** The author disclaims copyright to this source code. In place of
2999429983
** a legal notice, here is a blessing:
@@ -30076,11 +30065,10 @@
3007630065
3007730066
#endif /* SQLITE_OS_WIN_H */
3007830067
3007930068
/************** End of os_win.h **********************************************/
3008030069
/************** Continuing where we left off in mutex_w32.c ******************/
30081
-#line 26 "tsrc/mutex_w32.c"
3008230070
#endif
3008330071
3008430072
/*
3008530073
** The code in this file is only used if we are compiling multithreaded
3008630074
** on a Win32 system.
@@ -30454,11 +30442,10 @@
3045430442
3045530443
#endif /* SQLITE_MUTEX_W32 */
3045630444
3045730445
/************** End of mutex_w32.c *******************************************/
3045830446
/************** Begin file malloc.c ******************************************/
30459
-#line 1 "tsrc/malloc.c"
3046030447
/*
3046130448
** 2001 September 15
3046230449
**
3046330450
** The author disclaims copyright to this source code. In place of
3046430451
** a legal notice, here is a blessing:
@@ -31378,11 +31365,10 @@
3137831365
return 0;
3137931366
}
3138031367
3138131368
/************** End of malloc.c **********************************************/
3138231369
/************** Begin file printf.c ******************************************/
31383
-#line 1 "tsrc/printf.c"
3138431370
/*
3138531371
** The "printf" code that follows dates from the 1980's. It is in
3138631372
** the public domain.
3138731373
**
3138831374
**************************************************************************
@@ -32319,10 +32305,11 @@
3231932305
&& (ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) || pExpr->w.iOfst<=0)
3232032306
){
3232132307
pExpr = pExpr->pLeft;
3232232308
}
3232332309
if( pExpr==0 ) return;
32310
+ if( ExprHasProperty(pExpr, EP_FromDDL) ) return;
3232432311
db->errByteOffset = pExpr->w.iOfst;
3232532312
}
3232632313
3232732314
/*
3232832315
** Enlarge the memory allocation on a StrAccum object so that it is
@@ -32828,11 +32815,10 @@
3282832815
}
3282932816
}
3283032817
3283132818
/************** End of printf.c **********************************************/
3283232819
/************** Begin file treeview.c ****************************************/
32833
-#line 1 "tsrc/treeview.c"
3283432820
/*
3283532821
** 2015-06-08
3283632822
**
3283732823
** The author disclaims copyright to this source code. In place of
3283832824
** a legal notice, here is a blessing:
@@ -33049,11 +33035,11 @@
3304933035
}
3305033036
if( pItem->fg.isCte ){
3305133037
sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse);
3305233038
}
3305333039
if( pItem->fg.isOn || (pItem->fg.isUsing==0 && pItem->u3.pOn!=0) ){
33054
- sqlite3_str_appendf(&x, " ON");
33040
+ sqlite3_str_appendf(&x, " isOn");
3305533041
}
3305633042
if( pItem->fg.isTabFunc ) sqlite3_str_appendf(&x, " isTabFunc");
3305733043
if( pItem->fg.isCorrelated ) sqlite3_str_appendf(&x, " isCorrelated");
3305833044
if( pItem->fg.isMaterialized ) sqlite3_str_appendf(&x, " isMaterialized");
3305933045
if( pItem->fg.viaCoroutine ) sqlite3_str_appendf(&x, " viaCoroutine");
@@ -34133,10 +34119,14 @@
3413334119
**
3413434120
** This routines are given external linkage so that they will always be
3413534121
** accessible to the debugging, and to avoid warnings about unused
3413634122
** functions. But these routines only exist in debugging builds, so they
3413734123
** do not contaminate the interface.
34124
+**
34125
+** See Also:
34126
+**
34127
+** sqlite3ShowWhereTerm() in where.c
3413834128
*/
3413934129
SQLITE_PRIVATE void sqlite3ShowExpr(const Expr *p){ sqlite3TreeViewExpr(0,p,0); }
3414034130
SQLITE_PRIVATE void sqlite3ShowExprList(const ExprList *p){ sqlite3TreeViewExprList(0,p,0,0);}
3414134131
SQLITE_PRIVATE void sqlite3ShowIdList(const IdList *p){ sqlite3TreeViewIdList(0,p,0,0); }
3414234132
SQLITE_PRIVATE void sqlite3ShowSrcList(const SrcList *p){ sqlite3TreeViewSrcList(0,p); }
@@ -34160,11 +34150,10 @@
3416034150
3416134151
#endif /* SQLITE_DEBUG */
3416234152
3416334153
/************** End of treeview.c ********************************************/
3416434154
/************** Begin file random.c ******************************************/
34165
-#line 1 "tsrc/random.c"
3416634155
/*
3416734156
** 2001 September 15
3416834157
**
3416934158
** The author disclaims copyright to this source code. In place of
3417034159
** a legal notice, here is a blessing:
@@ -34321,11 +34310,10 @@
3432134310
}
3432234311
#endif /* SQLITE_UNTESTABLE */
3432334312
3432434313
/************** End of random.c **********************************************/
3432534314
/************** Begin file threads.c *****************************************/
34326
-#line 1 "tsrc/threads.c"
3432734315
/*
3432834316
** 2012 July 21
3432934317
**
3433034318
** The author disclaims copyright to this source code. In place of
3433134319
** a legal notice, here is a blessing:
@@ -34599,11 +34587,10 @@
3459934587
/****************************** End Single-Threaded *************************/
3460034588
#endif /* SQLITE_MAX_WORKER_THREADS>0 */
3460134589
3460234590
/************** End of threads.c *********************************************/
3460334591
/************** Begin file utf.c *********************************************/
34604
-#line 1 "tsrc/utf.c"
3460534592
/*
3460634593
** 2004 April 13
3460734594
**
3460834595
** The author disclaims copyright to this source code. In place of
3460934596
** a legal notice, here is a blessing:
@@ -35171,11 +35158,10 @@
3517135158
#endif /* SQLITE_TEST */
3517235159
#endif /* SQLITE_OMIT_UTF16 */
3517335160
3517435161
/************** End of utf.c *************************************************/
3517535162
/************** Begin file util.c ********************************************/
35176
-#line 1 "tsrc/util.c"
3517735163
/*
3517835164
** 2001 September 15
3517935165
**
3518035166
** The author disclaims copyright to this source code. In place of
3518135167
** a legal notice, here is a blessing:
@@ -35713,12 +35699,12 @@
3571335699
int esign = 1; /* sign of exponent */
3571435700
int e = 0; /* exponent */
3571535701
int eValid = 1; /* True exponent is either not used or is well-formed */
3571635702
int nDigit = 0; /* Number of digits processed */
3571735703
int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */
35704
+ u64 s2; /* round-tripped significand */
3571835705
double rr[2];
35719
- u64 s2;
3572035706
3572135707
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
3572235708
*pResult = 0.0; /* Default return value, in case of an error */
3572335709
if( length==0 ) return 0;
3572435710
@@ -35817,25 +35803,36 @@
3581735803
3581835804
/* adjust exponent by d, and update sign */
3581935805
e = (e*esign) + d;
3582035806
3582135807
/* Try to adjust the exponent to make it smaller */
35822
- while( e>0 && s<(LARGEST_UINT64/10) ){
35808
+ while( e>0 && s<((LARGEST_UINT64-0x7ff)/10) ){
3582335809
s *= 10;
3582435810
e--;
3582535811
}
3582635812
while( e<0 && (s%10)==0 ){
3582735813
s /= 10;
3582835814
e++;
3582935815
}
3583035816
3583135817
rr[0] = (double)s;
35832
- s2 = (u64)rr[0];
35833
-#if defined(_MSC_VER) && _MSC_VER<1700
35834
- if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); }
35818
+ assert( sizeof(s2)==sizeof(rr[0]) );
35819
+#ifdef SQLITE_DEBUG
35820
+ rr[1] = 18446744073709549568.0;
35821
+ memcpy(&s2, &rr[1], sizeof(s2));
35822
+ assert( s2==0x43efffffffffffffLL );
3583535823
#endif
35836
- rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s);
35824
+ /* Largest double that can be safely converted to u64
35825
+ ** vvvvvvvvvvvvvvvvvvvvvv */
35826
+ if( rr[0]<=18446744073709549568.0 ){
35827
+ s2 = (u64)rr[0];
35828
+ rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s);
35829
+ }else{
35830
+ rr[1] = 0.0;
35831
+ }
35832
+ assert( rr[1]<=1.0e-10*rr[0] ); /* Equal only when rr[0]==0.0 */
35833
+
3583735834
if( e>0 ){
3583835835
while( e>=100 ){
3583935836
e -= 100;
3584035837
dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83);
3584135838
}
@@ -37023,11 +37020,10 @@
3702337020
return 0;
3702437021
}
3702537022
3702637023
/************** End of util.c ************************************************/
3702737024
/************** Begin file hash.c ********************************************/
37028
-#line 1 "tsrc/hash.c"
3702937025
/*
3703037026
** 2001 September 22
3703137027
**
3703237028
** The author disclaims copyright to this source code. In place of
3703337029
** a legal notice, here is a blessing:
@@ -37297,11 +37293,10 @@
3729737293
return 0;
3729837294
}
3729937295
3730037296
/************** End of hash.c ************************************************/
3730137297
/************** Begin file opcodes.c *****************************************/
37302
-#line 1 "tsrc/opcodes.c"
3730337298
/* Automatically generated. Do not edit */
3730437299
/* See the tool/mkopcodec.tcl script for details. */
3730537300
#if !defined(SQLITE_OMIT_EXPLAIN) \
3730637301
|| defined(VDBE_PROFILE) \
3730737302
|| defined(SQLITE_DEBUG)
@@ -37507,11 +37502,10 @@
3750737502
}
3750837503
#endif
3750937504
3751037505
/************** End of opcodes.c *********************************************/
3751137506
/************** Begin file os_kv.c *******************************************/
37512
-#line 1 "tsrc/os_kv.c"
3751337507
/*
3751437508
** 2022-09-06
3751537509
**
3751637510
** The author disclaims copyright to this source code. In place of
3751737511
** a legal notice, here is a blessing:
@@ -38490,11 +38484,10 @@
3849038484
}
3849138485
#endif
3849238486
3849338487
/************** End of os_kv.c ***********************************************/
3849438488
/************** Begin file os_unix.c *****************************************/
38495
-#line 1 "tsrc/os_unix.c"
3849638489
/*
3849738490
** 2004 May 22
3849838491
**
3849938492
** The author disclaims copyright to this source code. In place of
3850038493
** a legal notice, here is a blessing:
@@ -42480,10 +42473,15 @@
4248042473
int rc = osIoctl(pFile->h, F2FS_IOC_ABORT_VOLATILE_WRITE);
4248142474
return rc ? SQLITE_IOERR_ROLLBACK_ATOMIC : SQLITE_OK;
4248242475
}
4248342476
#endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */
4248442477
42478
+ case SQLITE_FCNTL_NULL_IO: {
42479
+ osClose(pFile->h);
42480
+ pFile->h = -1;
42481
+ return SQLITE_OK;
42482
+ }
4248542483
case SQLITE_FCNTL_LOCKSTATE: {
4248642484
*(int*)pArg = pFile->eFileLock;
4248742485
return SQLITE_OK;
4248842486
}
4248942487
case SQLITE_FCNTL_LAST_ERRNO: {
@@ -46760,11 +46758,10 @@
4676046758
4676146759
#endif /* SQLITE_OS_UNIX */
4676246760
4676346761
/************** End of os_unix.c *********************************************/
4676446762
/************** Begin file os_win.c ******************************************/
46765
-#line 1 "tsrc/os_win.c"
4676646763
/*
4676746764
** 2004 May 22
4676846765
**
4676946766
** The author disclaims copyright to this source code. In place of
4677046767
** a legal notice, here is a blessing:
@@ -50362,10 +50359,15 @@
5036250359
OSTRACE(("FCNTL oldFile=%p, newFile=%p, rc=SQLITE_OK\n",
5036350360
hOldFile, pFile->h));
5036450361
return SQLITE_OK;
5036550362
}
5036650363
#endif
50364
+ case SQLITE_FCNTL_NULL_IO: {
50365
+ (void)osCloseHandle(pFile->h);
50366
+ pFile->h = NULL;
50367
+ return SQLITE_OK;
50368
+ }
5036750369
case SQLITE_FCNTL_TEMPFILENAME: {
5036850370
char *zTFile = 0;
5036950371
int rc = winGetTempname(pFile->pVfs, &zTFile);
5037050372
if( rc==SQLITE_OK ){
5037150373
*(char**)pArg = zTFile;
@@ -51811,11 +51813,11 @@
5181151813
*/
5181251814
char *zTmpname = 0; /* For temporary filename, if necessary. */
5181351815
5181451816
int rc = SQLITE_OK; /* Function Return Code */
5181551817
#if !defined(NDEBUG) || SQLITE_OS_WINCE
51816
- int eType = flags&0xFFFFFF00; /* Type of file to open */
51818
+ int eType = flags&0x0FFF00; /* Type of file to open */
5181751819
#endif
5181851820
5181951821
int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE);
5182051822
int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE);
5182151823
int isCreate = (flags & SQLITE_OPEN_CREATE);
@@ -52975,11 +52977,10 @@
5297552977
5297652978
#endif /* SQLITE_OS_WIN */
5297752979
5297852980
/************** End of os_win.c **********************************************/
5297952981
/************** Begin file memdb.c *******************************************/
52980
-#line 1 "tsrc/memdb.c"
5298152982
/*
5298252983
** 2016-09-07
5298352984
**
5298452985
** The author disclaims copyright to this source code. In place of
5298552986
** a legal notice, here is a blessing:
@@ -53915,11 +53916,10 @@
5391553916
}
5391653917
#endif /* SQLITE_OMIT_DESERIALIZE */
5391753918
5391853919
/************** End of memdb.c ***********************************************/
5391953920
/************** Begin file bitvec.c ******************************************/
53920
-#line 1 "tsrc/bitvec.c"
5392153921
/*
5392253922
** 2008 February 16
5392353923
**
5392453924
** The author disclaims copyright to this source code. In place of
5392553925
** a legal notice, here is a blessing:
@@ -54330,11 +54330,10 @@
5433054330
}
5433154331
#endif /* SQLITE_UNTESTABLE */
5433254332
5433354333
/************** End of bitvec.c **********************************************/
5433454334
/************** Begin file pcache.c ******************************************/
54335
-#line 1 "tsrc/pcache.c"
5433654335
/*
5433754336
** 2008 August 05
5433854337
**
5433954338
** The author disclaims copyright to this source code. In place of
5434054339
** a legal notice, here is a blessing:
@@ -55270,11 +55269,10 @@
5527055269
}
5527155270
#endif
5527255271
5527355272
/************** End of pcache.c **********************************************/
5527455273
/************** Begin file pcache1.c *****************************************/
55275
-#line 1 "tsrc/pcache1.c"
5527655274
/*
5527755275
** 2008 November 05
5527855276
**
5527955277
** The author disclaims copyright to this source code. In place of
5528055278
** a legal notice, here is a blessing:
@@ -56556,11 +56554,10 @@
5655656554
}
5655756555
#endif
5655856556
5655956557
/************** End of pcache1.c *********************************************/
5656056558
/************** Begin file rowset.c ******************************************/
56561
-#line 1 "tsrc/rowset.c"
5656256559
/*
5656356560
** 2008 December 3
5656456561
**
5656556562
** The author disclaims copyright to this source code. In place of
5656656563
** a legal notice, here is a blessing:
@@ -57062,11 +57059,10 @@
5706257059
return 0;
5706357060
}
5706457061
5706557062
/************** End of rowset.c **********************************************/
5706657063
/************** Begin file pager.c *******************************************/
57067
-#line 1 "tsrc/pager.c"
5706857064
/*
5706957065
** 2001 September 15
5707057066
**
5707157067
** The author disclaims copyright to this source code. In place of
5707257068
** a legal notice, here is a blessing:
@@ -57087,11 +57083,10 @@
5708757083
*/
5708857084
#ifndef SQLITE_OMIT_DISKIO
5708957085
/* #include "sqliteInt.h" */
5709057086
/************** Include wal.h in the middle of pager.c ***********************/
5709157087
/************** Begin file wal.h *********************************************/
57092
-#line 1 "tsrc/wal.h"
5709357088
/*
5709457089
** 2010 February 1
5709557090
**
5709657091
** The author disclaims copyright to this source code. In place of
5709757092
** a legal notice, here is a blessing:
@@ -57251,11 +57246,10 @@
5725157246
#endif /* ifndef SQLITE_OMIT_WAL */
5725257247
#endif /* SQLITE_WAL_H */
5725357248
5725457249
/************** End of wal.h *************************************************/
5725557250
/************** Continuing where we left off in pager.c **********************/
57256
-#line 24 "tsrc/pager.c"
5725757251
5725857252
5725957253
/******************* NOTES ON THE DESIGN OF THE PAGER ************************
5726057254
**
5726157255
** This comment block describes invariants that hold when using a rollback
@@ -65041,11 +65035,10 @@
6504165035
6504265036
#endif /* SQLITE_OMIT_DISKIO */
6504365037
6504465038
/************** End of pager.c ***********************************************/
6504565039
/************** Begin file wal.c *********************************************/
65046
-#line 1 "tsrc/wal.c"
6504765040
/*
6504865041
** 2010 February 1
6504965042
**
6505065043
** The author disclaims copyright to this source code. In place of
6505165044
** a legal notice, here is a blessing:
@@ -69638,11 +69631,10 @@
6963869631
6963969632
#endif /* #ifndef SQLITE_OMIT_WAL */
6964069633
6964169634
/************** End of wal.c *************************************************/
6964269635
/************** Begin file btmutex.c *****************************************/
69643
-#line 1 "tsrc/btmutex.c"
6964469636
/*
6964569637
** 2007 August 27
6964669638
**
6964769639
** The author disclaims copyright to this source code. In place of
6964869640
** a legal notice, here is a blessing:
@@ -69658,11 +69650,10 @@
6965869650
** big and we want to break it down some. This packaged seemed like
6965969651
** a good breakout.
6966069652
*/
6966169653
/************** Include btreeInt.h in the middle of btmutex.c ****************/
6966269654
/************** Begin file btreeInt.h ****************************************/
69663
-#line 1 "tsrc/btreeInt.h"
6966469655
/*
6966569656
** 2004 April 6
6966669657
**
6966769658
** The author disclaims copyright to this source code. In place of
6966869659
** a legal notice, here is a blessing:
@@ -70396,11 +70387,10 @@
7039670387
# define get2byteAligned(x) ((x)[0]<<8 | (x)[1])
7039770388
#endif
7039870389
7039970390
/************** End of btreeInt.h ********************************************/
7040070391
/************** Continuing where we left off in btmutex.c ********************/
70401
-#line 19 "tsrc/btmutex.c"
7040270392
#ifndef SQLITE_OMIT_SHARED_CACHE
7040370393
#if SQLITE_THREADSAFE
7040470394
7040570395
/*
7040670396
** Obtain the BtShared mutex associated with B-Tree handle p. Also,
@@ -70691,11 +70681,10 @@
7069170681
7069270682
#endif /* ifndef SQLITE_OMIT_SHARED_CACHE */
7069370683
7069470684
/************** End of btmutex.c *********************************************/
7069570685
/************** Begin file btree.c *******************************************/
70696
-#line 1 "tsrc/btree.c"
7069770686
/*
7069870687
** 2004 April 6
7069970688
**
7070070689
** The author disclaims copyright to this source code. In place of
7070170690
** a legal notice, here is a blessing:
@@ -82186,11 +82175,10 @@
8218682175
}
8218782176
#endif
8218882177
8218982178
/************** End of btree.c ***********************************************/
8219082179
/************** Begin file backup.c ******************************************/
82191
-#line 1 "tsrc/backup.c"
8219282180
/*
8219382181
** 2009 January 28
8219482182
**
8219582183
** The author disclaims copyright to this source code. In place of
8219682184
** a legal notice, here is a blessing:
@@ -82957,11 +82945,10 @@
8295782945
}
8295882946
#endif /* SQLITE_OMIT_VACUUM */
8295982947
8296082948
/************** End of backup.c **********************************************/
8296182949
/************** Begin file vdbemem.c *****************************************/
82962
-#line 1 "tsrc/vdbemem.c"
8296382950
/*
8296482951
** 2004 May 26
8296582952
**
8296682953
** The author disclaims copyright to this source code. In place of
8296782954
** a legal notice, here is a blessing:
@@ -85014,11 +85001,10 @@
8501485001
return valueBytes(pVal, enc);
8501585002
}
8501685003
8501785004
/************** End of vdbemem.c *********************************************/
8501885005
/************** Begin file vdbeaux.c *****************************************/
85019
-#line 1 "tsrc/vdbeaux.c"
8502085006
/*
8502185007
** 2003 September 6
8502285008
**
8502385009
** The author disclaims copyright to this source code. In place of
8502485010
** a legal notice, here is a blessing:
@@ -90566,11 +90552,10 @@
9056690552
}
9056790553
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
9056890554
9056990555
/************** End of vdbeaux.c *********************************************/
9057090556
/************** Begin file vdbeapi.c *****************************************/
90571
-#line 1 "tsrc/vdbeapi.c"
9057290557
/*
9057390558
** 2004 May 26
9057490559
**
9057590560
** The author disclaims copyright to this source code. In place of
9057690561
** a legal notice, here is a blessing:
@@ -93153,11 +93138,10 @@
9315393138
}
9315493139
#endif /* SQLITE_ENABLE_STMT_SCANSTATUS */
9315593140
9315693141
/************** End of vdbeapi.c *********************************************/
9315793142
/************** Begin file vdbetrace.c ***************************************/
93158
-#line 1 "tsrc/vdbetrace.c"
9315993143
/*
9316093144
** 2009 November 25
9316193145
**
9316293146
** The author disclaims copyright to this source code. In place of
9316393147
** a legal notice, here is a blessing:
@@ -93349,11 +93333,10 @@
9334993333
9335093334
#endif /* #ifndef SQLITE_OMIT_TRACE */
9335193335
9335293336
/************** End of vdbetrace.c *******************************************/
9335393337
/************** Begin file vdbe.c ********************************************/
93354
-#line 1 "tsrc/vdbe.c"
9335593338
/*
9335693339
** 2001 September 15
9335793340
**
9335893341
** The author disclaims copyright to this source code. In place of
9335993342
** a legal notice, here is a blessing:
@@ -93381,11 +93364,10 @@
9338193364
#if defined(VDBE_PROFILE) \
9338293365
|| defined(SQLITE_PERFORMANCE_TRACE) \
9338393366
|| defined(SQLITE_ENABLE_STMT_SCANSTATUS)
9338493367
/************** Include hwtime.h in the middle of vdbe.c *********************/
9338593368
/************** Begin file hwtime.h ******************************************/
93386
-#line 1 "tsrc/hwtime.h"
9338793369
/*
9338893370
** 2008 May 27
9338993371
**
9339093372
** The author disclaims copyright to this source code. In place of
9339193373
** a legal notice, here is a blessing:
@@ -93470,11 +93452,10 @@
9347093452
9347193453
#endif /* !defined(SQLITE_HWTIME_H) */
9347293454
9347393455
/************** End of hwtime.h **********************************************/
9347493456
/************** Continuing where we left off in vdbe.c ***********************/
93475
-#line 31 "tsrc/vdbe.c"
9347693457
#endif
9347793458
9347893459
/*
9347993460
** Invoke this macro on memory cells just prior to changing the
9348093461
** value of the cell. This macro verifies that shallow copies are
@@ -102664,11 +102645,10 @@
102664102645
}
102665102646
102666102647
102667102648
/************** End of vdbe.c ************************************************/
102668102649
/************** Begin file vdbeblob.c ****************************************/
102669
-#line 1 "tsrc/vdbeblob.c"
102670102650
/*
102671102651
** 2007 May 1
102672102652
**
102673102653
** The author disclaims copyright to this source code. In place of
102674102654
** a legal notice, here is a blessing:
@@ -103188,11 +103168,10 @@
103188103168
103189103169
#endif /* #ifndef SQLITE_OMIT_INCRBLOB */
103190103170
103191103171
/************** End of vdbeblob.c ********************************************/
103192103172
/************** Begin file vdbesort.c ****************************************/
103193
-#line 1 "tsrc/vdbesort.c"
103194103173
/*
103195103174
** 2011-07-09
103196103175
**
103197103176
** The author disclaims copyright to this source code. In place of
103198103177
** a legal notice, here is a blessing:
@@ -105959,11 +105938,10 @@
105959105938
return SQLITE_OK;
105960105939
}
105961105940
105962105941
/************** End of vdbesort.c ********************************************/
105963105942
/************** Begin file vdbevtab.c ****************************************/
105964
-#line 1 "tsrc/vdbevtab.c"
105965105943
/*
105966105944
** 2020-03-23
105967105945
**
105968105946
** The author disclaims copyright to this source code. In place of
105969105947
** a legal notice, here is a blessing:
@@ -106409,11 +106387,10 @@
106409106387
SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){ return SQLITE_OK; }
106410106388
#endif /* SQLITE_ENABLE_BYTECODE_VTAB */
106411106389
106412106390
/************** End of vdbevtab.c ********************************************/
106413106391
/************** Begin file memjournal.c **************************************/
106414
-#line 1 "tsrc/memjournal.c"
106415106392
/*
106416106393
** 2008 October 7
106417106394
**
106418106395
** The author disclaims copyright to this source code. In place of
106419106396
** a legal notice, here is a blessing:
@@ -106853,11 +106830,10 @@
106853106830
return MAX(pVfs->szOsFile, (int)sizeof(MemJournal));
106854106831
}
106855106832
106856106833
/************** End of memjournal.c ******************************************/
106857106834
/************** Begin file walker.c ******************************************/
106858
-#line 1 "tsrc/walker.c"
106859106835
/*
106860106836
** 2008 August 16
106861106837
**
106862106838
** The author disclaims copyright to this source code. In place of
106863106839
** a legal notice, here is a blessing:
@@ -107118,11 +107094,10 @@
107118107094
return WRC_Continue;
107119107095
}
107120107096
107121107097
/************** End of walker.c **********************************************/
107122107098
/************** Begin file resolve.c *****************************************/
107123
-#line 1 "tsrc/resolve.c"
107124107099
/*
107125107100
** 2008 August 18
107126107101
**
107127107102
** The author disclaims copyright to this source code. In place of
107128107103
** a legal notice, here is a blessing:
@@ -109440,11 +109415,10 @@
109440109415
return rc;
109441109416
}
109442109417
109443109418
/************** End of resolve.c *********************************************/
109444109419
/************** Begin file expr.c ********************************************/
109445
-#line 1 "tsrc/expr.c"
109446109420
/*
109447109421
** 2001 September 15
109448109422
**
109449109423
** The author disclaims copyright to this source code. In place of
109450109424
** a legal notice, here is a blessing:
@@ -112089,11 +112063,11 @@
112089112063
**
112090112064
** (4) If pSrc is the right operand of a LEFT JOIN, then...
112091112065
** (4a) pExpr must come from an ON clause..
112092112066
** (4b) and specifically the ON clause associated with the LEFT JOIN.
112093112067
**
112094
-** (5) If pSrc is not the right operand of a LEFT JOIN or the left
112068
+** (5) If pSrc is the right operand of a LEFT JOIN or the left
112095112069
** operand of a RIGHT JOIN, then pExpr must be from the WHERE
112096112070
** clause, not an ON clause.
112097112071
**
112098112072
** (6) Either:
112099112073
**
@@ -115623,35 +115597,41 @@
115623115597
**
115624115598
** Additionally, if pExpr is a simple SQL value and the value is the
115625115599
** same as that currently bound to variable pVar, non-zero is returned.
115626115600
** Otherwise, if the values are not the same or if pExpr is not a simple
115627115601
** SQL value, zero is returned.
115602
+**
115603
+** If the SQLITE_EnableQPSG flag is set on the database connection, then
115604
+** this routine always returns false.
115628115605
*/
115629
-static int exprCompareVariable(
115606
+static SQLITE_NOINLINE int exprCompareVariable(
115630115607
const Parse *pParse,
115631115608
const Expr *pVar,
115632115609
const Expr *pExpr
115633115610
){
115634
- int res = 0;
115611
+ int res = 2;
115635115612
int iVar;
115636115613
sqlite3_value *pL, *pR = 0;
115637115614
115615
+ if( pExpr->op==TK_VARIABLE && pVar->iColumn==pExpr->iColumn ){
115616
+ return 0;
115617
+ }
115618
+ if( (pParse->db->flags & SQLITE_EnableQPSG)!=0 ) return 2;
115638115619
sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR);
115639115620
if( pR ){
115640115621
iVar = pVar->iColumn;
115641115622
sqlite3VdbeSetVarmask(pParse->pVdbe, iVar);
115642115623
pL = sqlite3VdbeGetBoundValue(pParse->pReprepare, iVar, SQLITE_AFF_BLOB);
115643115624
if( pL ){
115644115625
if( sqlite3_value_type(pL)==SQLITE_TEXT ){
115645115626
sqlite3_value_text(pL); /* Make sure the encoding is UTF-8 */
115646115627
}
115647
- res = 0==sqlite3MemCompare(pL, pR, 0);
115628
+ res = sqlite3MemCompare(pL, pR, 0) ? 2 : 0;
115648115629
}
115649115630
sqlite3ValueFree(pR);
115650115631
sqlite3ValueFree(pL);
115651115632
}
115652
-
115653115633
return res;
115654115634
}
115655115635
115656115636
/*
115657115637
** Do a deep comparison of two expression trees. Return 0 if the two
@@ -115673,16 +115653,14 @@
115673115653
** can be sure the expressions are the same. In the places where
115674115654
** this routine is used, it does not hurt to get an extra 2 - that
115675115655
** just might result in some slightly slower code. But returning
115676115656
** an incorrect 0 or 1 could lead to a malfunction.
115677115657
**
115678
-** If pParse is not NULL then TK_VARIABLE terms in pA with bindings in
115679
-** pParse->pReprepare can be matched against literals in pB. The
115680
-** pParse->pVdbe->expmask bitmask is updated for each variable referenced.
115681
-** If pParse is NULL (the normal case) then any TK_VARIABLE term in
115682
-** Argument pParse should normally be NULL. If it is not NULL and pA or
115683
-** pB causes a return value of 2.
115658
+** If pParse is not NULL and SQLITE_EnableQPSG is off then TK_VARIABLE
115659
+** terms in pA with bindings in pParse->pReprepare can be matched against
115660
+** literals in pB. The pParse->pVdbe->expmask bitmask is updated for
115661
+** each variable referenced.
115684115662
*/
115685115663
SQLITE_PRIVATE int sqlite3ExprCompare(
115686115664
const Parse *pParse,
115687115665
const Expr *pA,
115688115666
const Expr *pB,
@@ -115690,12 +115668,12 @@
115690115668
){
115691115669
u32 combinedFlags;
115692115670
if( pA==0 || pB==0 ){
115693115671
return pB==pA ? 0 : 2;
115694115672
}
115695
- if( pParse && pA->op==TK_VARIABLE && exprCompareVariable(pParse, pA, pB) ){
115696
- return 0;
115673
+ if( pParse && pA->op==TK_VARIABLE ){
115674
+ return exprCompareVariable(pParse, pA, pB);
115697115675
}
115698115676
combinedFlags = pA->flags | pB->flags;
115699115677
if( combinedFlags & EP_IntValue ){
115700115678
if( (pA->flags&pB->flags&EP_IntValue)!=0 && pA->u.iValue==pB->u.iValue ){
115701115679
return 0;
@@ -115885,23 +115863,75 @@
115885115863
return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
115886115864
}
115887115865
}
115888115866
return 0;
115889115867
}
115868
+
115869
+/*
115870
+** Return true if the boolean value of the expression is always either
115871
+** FALSE or NULL.
115872
+*/
115873
+static int sqlite3ExprIsNotTrue(Expr *pExpr){
115874
+ int v;
115875
+ if( pExpr->op==TK_NULL ) return 1;
115876
+ if( pExpr->op==TK_TRUEFALSE && sqlite3ExprTruthValue(pExpr)==0 ) return 1;
115877
+ v = 1;
115878
+ if( sqlite3ExprIsInteger(pExpr, &v, 0) && v==0 ) return 1;
115879
+ return 0;
115880
+}
115881
+
115882
+/*
115883
+** Return true if the expression is one of the following:
115884
+**
115885
+** CASE WHEN x THEN y END
115886
+** CASE WHEN x THEN y ELSE NULL END
115887
+** CASE WHEN x THEN y ELSE false END
115888
+** iif(x,y)
115889
+** iif(x,y,NULL)
115890
+** iif(x,y,false)
115891
+*/
115892
+static int sqlite3ExprIsIIF(sqlite3 *db, const Expr *pExpr){
115893
+ ExprList *pList;
115894
+ if( pExpr->op==TK_FUNCTION ){
115895
+ const char *z = pExpr->u.zToken;
115896
+ FuncDef *pDef;
115897
+ if( (z[0]!='i' && z[0]!='I') ) return 0;
115898
+ if( pExpr->x.pList==0 ) return 0;
115899
+ pDef = sqlite3FindFunction(db, z, pExpr->x.pList->nExpr, ENC(db), 0);
115900
+#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
115901
+ if( pDef==0 ) return 0;
115902
+#else
115903
+ if( NEVER(pDef==0) ) return 0;
115904
+#endif
115905
+ if( (pDef->funcFlags & SQLITE_FUNC_INLINE)==0 ) return 0;
115906
+ if( SQLITE_PTR_TO_INT(pDef->pUserData)!=INLINEFUNC_iif ) return 0;
115907
+ }else if( pExpr->op==TK_CASE ){
115908
+ if( pExpr->pLeft!=0 ) return 0;
115909
+ }else{
115910
+ return 0;
115911
+ }
115912
+ pList = pExpr->x.pList;
115913
+ assert( pList!=0 );
115914
+ if( pList->nExpr==2 ) return 1;
115915
+ if( pList->nExpr==3 && sqlite3ExprIsNotTrue(pList->a[2].pExpr) ) return 1;
115916
+ return 0;
115917
+}
115890115918
115891115919
/*
115892115920
** Return true if we can prove the pE2 will always be true if pE1 is
115893115921
** true. Return false if we cannot complete the proof or if pE2 might
115894115922
** be false. Examples:
115895115923
**
115896
-** pE1: x==5 pE2: x==5 Result: true
115897
-** pE1: x>0 pE2: x==5 Result: false
115898
-** pE1: x=21 pE2: x=21 OR y=43 Result: true
115899
-** pE1: x!=123 pE2: x IS NOT NULL Result: true
115900
-** pE1: x!=?1 pE2: x IS NOT NULL Result: true
115901
-** pE1: x IS NULL pE2: x IS NOT NULL Result: false
115902
-** pE1: x IS ?2 pE2: x IS NOT NULL Result: false
115924
+** pE1: x==5 pE2: x==5 Result: true
115925
+** pE1: x>0 pE2: x==5 Result: false
115926
+** pE1: x=21 pE2: x=21 OR y=43 Result: true
115927
+** pE1: x!=123 pE2: x IS NOT NULL Result: true
115928
+** pE1: x!=?1 pE2: x IS NOT NULL Result: true
115929
+** pE1: x IS NULL pE2: x IS NOT NULL Result: false
115930
+** pE1: x IS ?2 pE2: x IS NOT NULL Result: false
115931
+** pE1: iif(x,y) pE2: x Result: true
115932
+** PE1: iif(x,y,0) pE2: x Result: true
115903115933
**
115904115934
** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has
115905115935
** Expr.iTable<0 then assume a table number given by iTab.
115906115936
**
115907115937
** If pParse is not NULL, then the values of bound variables in pE1 are
@@ -115931,10 +115961,13 @@
115931115961
if( pE2->op==TK_NOTNULL
115932115962
&& exprImpliesNotNull(pParse, pE1, pE2->pLeft, iTab, 0)
115933115963
){
115934115964
return 1;
115935115965
}
115966
+ if( sqlite3ExprIsIIF(pParse->db, pE1) ){
115967
+ return sqlite3ExprImpliesExpr(pParse,pE1->x.pList->a[0].pExpr,pE2,iTab);
115968
+ }
115936115969
return 0;
115937115970
}
115938115971
115939115972
/* This is a helper function to impliesNotNullRow(). In this routine,
115940115973
** set pWalker->eCode to one only if *both* of the input expressions
@@ -116770,11 +116803,10 @@
116770116803
}
116771116804
#endif /* SQLITE_DEBUG */
116772116805
116773116806
/************** End of expr.c ************************************************/
116774116807
/************** Begin file alter.c *******************************************/
116775
-#line 1 "tsrc/alter.c"
116776116808
/*
116777116809
** 2005 February 15
116778116810
**
116779116811
** The author disclaims copyright to this source code. In place of
116780116812
** a legal notice, here is a blessing:
@@ -119090,11 +119122,10 @@
119090119122
}
119091119123
#endif /* SQLITE_ALTER_TABLE */
119092119124
119093119125
/************** End of alter.c ***********************************************/
119094119126
/************** Begin file analyze.c *****************************************/
119095
-#line 1 "tsrc/analyze.c"
119096119127
/*
119097119128
** 2005-07-08
119098119129
**
119099119130
** The author disclaims copyright to this source code. In place of
119100119131
** a legal notice, here is a blessing:
@@ -121115,11 +121146,10 @@
121115121146
121116121147
#endif /* SQLITE_OMIT_ANALYZE */
121117121148
121118121149
/************** End of analyze.c *********************************************/
121119121150
/************** Begin file attach.c ******************************************/
121120
-#line 1 "tsrc/attach.c"
121121121151
/*
121122121152
** 2003 April 6
121123121153
**
121124121154
** The author disclaims copyright to this source code. In place of
121125121155
** a legal notice, here is a blessing:
@@ -121728,11 +121758,10 @@
121728121758
}
121729121759
#endif
121730121760
121731121761
/************** End of attach.c **********************************************/
121732121762
/************** Begin file auth.c ********************************************/
121733
-#line 1 "tsrc/auth.c"
121734121763
/*
121735121764
** 2003 January 11
121736121765
**
121737121766
** The author disclaims copyright to this source code. In place of
121738121767
** a legal notice, here is a blessing:
@@ -121992,11 +122021,10 @@
121992122021
121993122022
#endif /* SQLITE_OMIT_AUTHORIZATION */
121994122023
121995122024
/************** End of auth.c ************************************************/
121996122025
/************** Begin file build.c *******************************************/
121997
-#line 1 "tsrc/build.c"
121998122026
/*
121999122027
** 2001 September 15
122000122028
**
122001122029
** The author disclaims copyright to this source code. In place of
122002122030
** a legal notice, here is a blessing:
@@ -127763,11 +127791,10 @@
127763127791
}
127764127792
#endif /* !defined(SQLITE_OMIT_CTE) */
127765127793
127766127794
/************** End of build.c ***********************************************/
127767127795
/************** Begin file callback.c ****************************************/
127768
-#line 1 "tsrc/callback.c"
127769127796
/*
127770127797
** 2005 May 23
127771127798
**
127772127799
** The author disclaims copyright to this source code. In place of
127773127800
** a legal notice, here is a blessing:
@@ -128307,11 +128334,10 @@
128307128334
return p;
128308128335
}
128309128336
128310128337
/************** End of callback.c ********************************************/
128311128338
/************** Begin file delete.c ******************************************/
128312
-#line 1 "tsrc/delete.c"
128313128339
/*
128314128340
** 2001 September 15
128315128341
**
128316128342
** The author disclaims copyright to this source code. In place of
128317128343
** a legal notice, here is a blessing:
@@ -129341,11 +129367,10 @@
129341129367
}
129342129368
}
129343129369
129344129370
/************** End of delete.c **********************************************/
129345129371
/************** Begin file func.c ********************************************/
129346
-#line 1 "tsrc/func.c"
129347129372
/*
129348129373
** 2002 February 23
129349129374
**
129350129375
** The author disclaims copyright to this source code. In place of
129351129376
** a legal notice, here is a blessing:
@@ -132158,11 +132183,14 @@
132158132183
MFUNCTION(degrees, 1, radToDeg, math1Func ),
132159132184
MFUNCTION(pi, 0, 0, piFunc ),
132160132185
#endif /* SQLITE_ENABLE_MATH_FUNCTIONS */
132161132186
FUNCTION(sign, 1, 0, 0, signFunc ),
132162132187
INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, 0 ),
132188
+ INLINE_FUNC(iif, 2, INLINEFUNC_iif, 0 ),
132163132189
INLINE_FUNC(iif, 3, INLINEFUNC_iif, 0 ),
132190
+ INLINE_FUNC(if, 2, INLINEFUNC_iif, 0 ),
132191
+ INLINE_FUNC(if, 3, INLINEFUNC_iif, 0 ),
132164132192
};
132165132193
#ifndef SQLITE_OMIT_ALTERTABLE
132166132194
sqlite3AlterFunctions();
132167132195
#endif
132168132196
sqlite3WindowFunctions();
@@ -132188,11 +132216,10 @@
132188132216
#endif
132189132217
}
132190132218
132191132219
/************** End of func.c ************************************************/
132192132220
/************** Begin file fkey.c ********************************************/
132193
-#line 1 "tsrc/fkey.c"
132194132221
/*
132195132222
**
132196132223
** The author disclaims copyright to this source code. In place of
132197132224
** a legal notice, here is a blessing:
132198132225
**
@@ -133676,11 +133703,10 @@
133676133703
}
133677133704
#endif /* ifndef SQLITE_OMIT_FOREIGN_KEY */
133678133705
133679133706
/************** End of fkey.c ************************************************/
133680133707
/************** Begin file insert.c ******************************************/
133681
-#line 1 "tsrc/insert.c"
133682133708
/*
133683133709
** 2001 September 15
133684133710
**
133685133711
** The author disclaims copyright to this source code. In place of
133686133712
** a legal notice, here is a blessing:
@@ -137072,11 +137098,10 @@
137072137098
}
137073137099
#endif /* SQLITE_OMIT_XFER_OPT */
137074137100
137075137101
/************** End of insert.c **********************************************/
137076137102
/************** Begin file legacy.c ******************************************/
137077
-#line 1 "tsrc/legacy.c"
137078137103
/*
137079137104
** 2001 September 15
137080137105
**
137081137106
** The author disclaims copyright to this source code. In place of
137082137107
** a legal notice, here is a blessing:
@@ -137217,11 +137242,10 @@
137217137242
return rc;
137218137243
}
137219137244
137220137245
/************** End of legacy.c **********************************************/
137221137246
/************** Begin file loadext.c *****************************************/
137222
-#line 1 "tsrc/loadext.c"
137223137247
/*
137224137248
** 2006 June 7
137225137249
**
137226137250
** The author disclaims copyright to this source code. In place of
137227137251
** a legal notice, here is a blessing:
@@ -137238,11 +137262,10 @@
137238137262
#ifndef SQLITE_CORE
137239137263
#define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */
137240137264
#endif
137241137265
/************** Include sqlite3ext.h in the middle of loadext.c **************/
137242137266
/************** Begin file sqlite3ext.h **************************************/
137243
-#line 1 "tsrc/sqlite3ext.h"
137244137267
/*
137245137268
** 2006 June 7
137246137269
**
137247137270
** The author disclaims copyright to this source code. In place of
137248137271
** a legal notice, here is a blessing:
@@ -137961,11 +137984,10 @@
137961137984
137962137985
#endif /* SQLITE3EXT_H */
137963137986
137964137987
/************** End of sqlite3ext.h ******************************************/
137965137988
/************** Continuing where we left off in loadext.c ********************/
137966
-#line 20 "tsrc/loadext.c"
137967137989
/* #include "sqliteInt.h" */
137968137990
137969137991
#ifndef SQLITE_OMIT_LOAD_EXTENSION
137970137992
/*
137971137993
** Some API routines are omitted when various features are
@@ -138867,11 +138889,10 @@
138867138889
}
138868138890
}
138869138891
138870138892
/************** End of loadext.c *********************************************/
138871138893
/************** Begin file pragma.c ******************************************/
138872
-#line 1 "tsrc/pragma.c"
138873138894
/*
138874138895
** 2003 April 6
138875138896
**
138876138897
** The author disclaims copyright to this source code. In place of
138877138898
** a legal notice, here is a blessing:
@@ -138900,11 +138921,10 @@
138900138921
** lexicographical order to facility a binary search of the pragma name.
138901138922
** Do not edit pragma.h directly. Edit and rerun the script in at
138902138923
** ../tool/mkpragmatab.tcl. */
138903138924
/************** Include pragma.h in the middle of pragma.c *******************/
138904138925
/************** Begin file pragma.h ******************************************/
138905
-#line 1 "tsrc/pragma.h"
138906138926
/* DO NOT EDIT!
138907138927
** This file is automatically generated by the script at
138908138928
** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit
138909138929
** that script and rerun it.
138910138930
*/
@@ -139564,11 +139584,10 @@
139564139584
};
139565139585
/* Number of pragmas: 68 on by default, 78 total. */
139566139586
139567139587
/************** End of pragma.h **********************************************/
139568139588
/************** Continuing where we left off in pragma.c *********************/
139569
-#line 32 "tsrc/pragma.c"
139570139589
139571139590
/*
139572139591
** When the 0x10 bit of PRAGMA optimize is set, any ANALYZE commands
139573139592
** will be run with an analysis_limit set to the lessor of the value of
139574139593
** the following macro or to the actual analysis_limit if it is non-zero,
@@ -140815,11 +140834,12 @@
140815140834
pTab = sqliteHashData(k);
140816140835
if( pTab->nCol==0 ){
140817140836
char *zSql = sqlite3MPrintf(db, "SELECT*FROM\"%w\"", pTab->zName);
140818140837
if( zSql ){
140819140838
sqlite3_stmt *pDummy = 0;
140820
- (void)sqlite3_prepare(db, zSql, -1, &pDummy, 0);
140839
+ (void)sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_DONT_LOG,
140840
+ &pDummy, 0);
140821140841
(void)sqlite3_finalize(pDummy);
140822140842
sqlite3DbFree(db, zSql);
140823140843
}
140824140844
if( db->mallocFailed ){
140825140845
sqlite3ErrorMsg(db->pParse, "out of memory");
@@ -142608,11 +142628,10 @@
142608142628
142609142629
#endif /* SQLITE_OMIT_PRAGMA */
142610142630
142611142631
/************** End of pragma.c **********************************************/
142612142632
/************** Begin file prepare.c *****************************************/
142613
-#line 1 "tsrc/prepare.c"
142614142633
/*
142615142634
** 2005 May 25
142616142635
**
142617142636
** The author disclaims copyright to this source code. In place of
142618142637
** a legal notice, here is a blessing:
@@ -143702,11 +143721,10 @@
143702143721
143703143722
#endif /* SQLITE_OMIT_UTF16 */
143704143723
143705143724
/************** End of prepare.c *********************************************/
143706143725
/************** Begin file select.c ******************************************/
143707
-#line 1 "tsrc/select.c"
143708143726
/*
143709143727
** 2001 September 15
143710143728
**
143711143729
** The author disclaims copyright to this source code. In place of
143712143730
** a legal notice, here is a blessing:
@@ -147616,36 +147634,36 @@
147616147634
return pExpr;
147617147635
}
147618147636
if( pSubst->isOuterJoin ){
147619147637
ExprSetProperty(pNew, EP_CanBeNull);
147620147638
}
147639
+ if( pNew->op==TK_TRUEFALSE ){
147640
+ pNew->u.iValue = sqlite3ExprTruthValue(pNew);
147641
+ pNew->op = TK_INTEGER;
147642
+ ExprSetProperty(pNew, EP_IntValue);
147643
+ }
147644
+
147645
+ /* Ensure that the expression now has an implicit collation sequence,
147646
+ ** just as it did when it was a column of a view or sub-query. */
147647
+ {
147648
+ CollSeq *pNat = sqlite3ExprCollSeq(pSubst->pParse, pNew);
147649
+ CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse,
147650
+ pSubst->pCList->a[iColumn].pExpr
147651
+ );
147652
+ if( pNat!=pColl || (pNew->op!=TK_COLUMN && pNew->op!=TK_COLLATE) ){
147653
+ pNew = sqlite3ExprAddCollateString(pSubst->pParse, pNew,
147654
+ (pColl ? pColl->zName : "BINARY")
147655
+ );
147656
+ }
147657
+ }
147658
+ ExprClearProperty(pNew, EP_Collate);
147621147659
if( ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) ){
147622147660
sqlite3SetJoinExpr(pNew, pExpr->w.iJoin,
147623147661
pExpr->flags & (EP_OuterON|EP_InnerON));
147624147662
}
147625147663
sqlite3ExprDelete(db, pExpr);
147626147664
pExpr = pNew;
147627
- if( pExpr->op==TK_TRUEFALSE ){
147628
- pExpr->u.iValue = sqlite3ExprTruthValue(pExpr);
147629
- pExpr->op = TK_INTEGER;
147630
- ExprSetProperty(pExpr, EP_IntValue);
147631
- }
147632
-
147633
- /* Ensure that the expression now has an implicit collation sequence,
147634
- ** just as it did when it was a column of a view or sub-query. */
147635
- {
147636
- CollSeq *pNat = sqlite3ExprCollSeq(pSubst->pParse, pExpr);
147637
- CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse,
147638
- pSubst->pCList->a[iColumn].pExpr
147639
- );
147640
- if( pNat!=pColl || (pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE) ){
147641
- pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr,
147642
- (pColl ? pColl->zName : "BINARY")
147643
- );
147644
- }
147645
- }
147646
- ExprClearProperty(pExpr, EP_Collate);
147647147665
}
147648147666
}
147649147667
}else{
147650147668
if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){
147651147669
pExpr->iTable = pSubst->iNewTable;
@@ -148378,20 +148396,20 @@
148378148396
}
148379148397
148380148398
/* Transfer the FROM clause terms from the subquery into the
148381148399
** outer query.
148382148400
*/
148401
+ iNewParent = pSubSrc->a[0].iCursor;
148383148402
for(i=0; i<nSubSrc; i++){
148384148403
SrcItem *pItem = &pSrc->a[i+iFrom];
148385148404
assert( pItem->fg.isTabFunc==0 );
148386148405
assert( pItem->fg.isSubquery
148387148406
|| pItem->fg.fixedSchema
148388148407
|| pItem->u4.zDatabase==0 );
148389148408
if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing);
148390148409
*pItem = pSubSrc->a[i];
148391148410
pItem->fg.jointype |= ltorj;
148392
- iNewParent = pSubSrc->a[i].iCursor;
148393148411
memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
148394148412
}
148395148413
pSrc->a[iFrom].fg.jointype &= JT_LTORJ;
148396148414
pSrc->a[iFrom].fg.jointype |= jointype | ltorj;
148397148415
@@ -148427,10 +148445,11 @@
148427148445
pSub->pOrderBy = 0;
148428148446
}
148429148447
pWhere = pSub->pWhere;
148430148448
pSub->pWhere = 0;
148431148449
if( isOuterJoin>0 ){
148450
+ assert( pSubSrc->nSrc==1 );
148432148451
sqlite3SetJoinExpr(pWhere, iNewParent, EP_OuterON);
148433148452
}
148434148453
if( pWhere ){
148435148454
if( pParent->pWhere ){
148436148455
pParent->pWhere = sqlite3PExpr(pParse, TK_AND, pWhere, pParent->pWhere);
@@ -151526,11 +151545,11 @@
151526151545
sqlite3TreeViewSelect(0, p, 0);
151527151546
}
151528151547
#endif
151529151548
assert( pSubq->pSelect && (pSub->selFlags & SF_PushDown)!=0 );
151530151549
}else{
151531
- TREETRACE(0x4000,pParse,p,("WHERE-lcause push-down not possible\n"));
151550
+ TREETRACE(0x4000,pParse,p,("WHERE-clause push-down not possible\n"));
151532151551
}
151533151552
151534151553
/* Convert unused result columns of the subquery into simple NULL
151535151554
** expressions, to avoid unneeded searching and computation.
151536151555
** tag-select-0440
@@ -152475,11 +152494,10 @@
152475152494
return rc;
152476152495
}
152477152496
152478152497
/************** End of select.c **********************************************/
152479152498
/************** Begin file table.c *******************************************/
152480
-#line 1 "tsrc/table.c"
152481152499
/*
152482152500
** 2001 September 15
152483152501
**
152484152502
** The author disclaims copyright to this source code. In place of
152485152503
** a legal notice, here is a blessing:
@@ -152677,11 +152695,10 @@
152677152695
152678152696
#endif /* SQLITE_OMIT_GET_TABLE */
152679152697
152680152698
/************** End of table.c ***********************************************/
152681152699
/************** Begin file trigger.c *****************************************/
152682
-#line 1 "tsrc/trigger.c"
152683152700
/*
152684152701
**
152685152702
** The author disclaims copyright to this source code. In place of
152686152703
** a legal notice, here is a blessing:
152687152704
**
@@ -154244,11 +154261,10 @@
154244154261
154245154262
#endif /* !defined(SQLITE_OMIT_TRIGGER) */
154246154263
154247154264
/************** End of trigger.c *********************************************/
154248154265
/************** Begin file update.c ******************************************/
154249
-#line 1 "tsrc/update.c"
154250154266
/*
154251154267
** 2001 September 15
154252154268
**
154253154269
** The author disclaims copyright to this source code. In place of
154254154270
** a legal notice, here is a blessing:
@@ -155616,11 +155632,10 @@
155616155632
}
155617155633
#endif /* SQLITE_OMIT_VIRTUALTABLE */
155618155634
155619155635
/************** End of update.c **********************************************/
155620155636
/************** Begin file upsert.c ******************************************/
155621
-#line 1 "tsrc/upsert.c"
155622155637
/*
155623155638
** 2018-04-12
155624155639
**
155625155640
** The author disclaims copyright to this source code. In place of
155626155641
** a legal notice, here is a blessing:
@@ -155949,11 +155964,10 @@
155949155964
155950155965
#endif /* SQLITE_OMIT_UPSERT */
155951155966
155952155967
/************** End of upsert.c **********************************************/
155953155968
/************** Begin file vacuum.c ******************************************/
155954
-#line 1 "tsrc/vacuum.c"
155955155969
/*
155956155970
** 2003 April 6
155957155971
**
155958155972
** The author disclaims copyright to this source code. In place of
155959155973
** a legal notice, here is a blessing:
@@ -156371,11 +156385,10 @@
156371156385
156372156386
#endif /* SQLITE_OMIT_VACUUM && SQLITE_OMIT_ATTACH */
156373156387
156374156388
/************** End of vacuum.c **********************************************/
156375156389
/************** Begin file vtab.c ********************************************/
156376
-#line 1 "tsrc/vtab.c"
156377156390
/*
156378156391
** 2006 June 10
156379156392
**
156380156393
** The author disclaims copyright to this source code. In place of
156381156394
** a legal notice, here is a blessing:
@@ -157749,11 +157762,10 @@
157749157762
157750157763
#endif /* SQLITE_OMIT_VIRTUALTABLE */
157751157764
157752157765
/************** End of vtab.c ************************************************/
157753157766
/************** Begin file wherecode.c ***************************************/
157754
-#line 1 "tsrc/wherecode.c"
157755157767
/*
157756157768
** 2015-06-06
157757157769
**
157758157770
** The author disclaims copyright to this source code. In place of
157759157771
** a legal notice, here is a blessing:
@@ -157772,11 +157784,10 @@
157772157784
** file retains the code that does query planning and analysis.
157773157785
*/
157774157786
/* #include "sqliteInt.h" */
157775157787
/************** Include whereInt.h in the middle of wherecode.c **************/
157776157788
/************** Begin file whereInt.h ****************************************/
157777
-#line 1 "tsrc/whereInt.h"
157778157789
/*
157779157790
** 2013-11-12
157780157791
**
157781157792
** The author disclaims copyright to this source code. In place of
157782157793
** a legal notice, here is a blessing:
@@ -158429,11 +158440,10 @@
158429158440
158430158441
#endif /* !defined(SQLITE_WHEREINT_H) */
158431158442
158432158443
/************** End of whereInt.h ********************************************/
158433158444
/************** Continuing where we left off in wherecode.c ******************/
158434
-#line 22 "tsrc/wherecode.c"
158435158445
158436158446
#ifndef SQLITE_OMIT_EXPLAIN
158437158447
158438158448
/*
158439158449
** Return the name of the i-th column of the pIdx index.
@@ -159026,10 +159036,11 @@
159026159036
if( pOrigLhs ){
159027159037
sqlite3ExprListDelete(db, pOrigLhs);
159028159038
pNew->pLeft->x.pList = pLhs;
159029159039
}
159030159040
pSelect->pEList = pRhs;
159041
+ pSelect->selId = ++pParse->nSelect; /* Req'd for SubrtnSig validity */
159031159042
if( pLhs && pLhs->nExpr==1 ){
159032159043
/* Take care here not to generate a TK_VECTOR containing only a
159033159044
** single value. Since the parser never creates such a vector, some
159034159045
** of the subroutines do not handle this case. */
159035159046
Expr *p = pLhs->a[0].pExpr;
@@ -161352,11 +161363,10 @@
161352161363
pParse->withinRJSubrtn--;
161353161364
}
161354161365
161355161366
/************** End of wherecode.c *******************************************/
161356161367
/************** Begin file whereexpr.c ***************************************/
161357
-#line 1 "tsrc/whereexpr.c"
161358161368
/*
161359161369
** 2015-06-08
161360161370
**
161361161371
** The author disclaims copyright to this source code. In place of
161362161372
** a legal notice, here is a blessing:
@@ -163258,11 +163268,10 @@
163258163268
}
163259163269
}
163260163270
163261163271
/************** End of whereexpr.c *******************************************/
163262163272
/************** Begin file where.c *******************************************/
163263
-#line 1 "tsrc/where.c"
163264163273
/*
163265163274
** 2001 September 15
163266163275
**
163267163276
** The author disclaims copyright to this source code. In place of
163268163277
** a legal notice, here is a blessing:
@@ -164100,11 +164109,11 @@
164100164109
|| pTerm->pExpr->w.iJoin != pSrc->iCursor
164101164110
){
164102164111
return 0;
164103164112
}
164104164113
if( (pSrc->fg.jointype & (JT_LEFT|JT_RIGHT))!=0
164105
- && ExprHasProperty(pTerm->pExpr, EP_InnerON)
164114
+ && NEVER(ExprHasProperty(pTerm->pExpr, EP_InnerON))
164106164115
){
164107164116
return 0;
164108164117
}
164109164118
return 1;
164110164119
}
@@ -165593,11 +165602,11 @@
165593165602
return rc;
165594165603
}
165595165604
#endif /* SQLITE_ENABLE_STAT4 */
165596165605
165597165606
165598
-#ifdef WHERETRACE_ENABLED
165607
+#if defined(WHERETRACE_ENABLED) || defined(SQLITE_DEBUG)
165599165608
/*
165600165609
** Print the content of a WhereTerm object
165601165610
*/
165602165611
SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){
165603165612
if( pTerm==0 ){
@@ -165636,10 +165645,13 @@
165636165645
sqlite3DebugPrintf(" iParent=%d", pTerm->iParent);
165637165646
}
165638165647
sqlite3DebugPrintf("\n");
165639165648
sqlite3TreeViewExpr(0, pTerm->pExpr, 0);
165640165649
}
165650
+}
165651
+SQLITE_PRIVATE void sqlite3ShowWhereTerm(WhereTerm *pTerm){
165652
+ sqlite3WhereTermPrint(pTerm, 0);
165641165653
}
165642165654
#endif
165643165655
165644165656
#ifdef WHERETRACE_ENABLED
165645165657
/*
@@ -166822,11 +166834,10 @@
166822166834
pParse = pWC->pWInfo->pParse;
166823166835
while( pWhere->op==TK_AND ){
166824166836
if( !whereUsablePartialIndex(iTab,jointype,pWC,pWhere->pLeft) ) return 0;
166825166837
pWhere = pWhere->pRight;
166826166838
}
166827
- if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
166828166839
for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
166829166840
Expr *pExpr;
166830166841
pExpr = pTerm->pExpr;
166831166842
if( (!ExprHasProperty(pExpr, EP_OuterON) || pExpr->w.iJoin==iTab)
166832166843
&& ((jointype & JT_OUTER)==0 || ExprHasProperty(pExpr, EP_OuterON))
@@ -169483,11 +169494,11 @@
169483169494
break;
169484169495
}
169485169496
}
169486169497
if( hasRightJoin
169487169498
&& ExprHasProperty(pTerm->pExpr, EP_InnerON)
169488
- && pTerm->pExpr->w.iJoin==pItem->iCursor
169499
+ && NEVER(pTerm->pExpr->w.iJoin==pItem->iCursor)
169489169500
){
169490169501
break; /* restriction (5) */
169491169502
}
169492169503
}
169493169504
if( pTerm<pEnd ) continue;
@@ -170759,11 +170770,10 @@
170759170770
return;
170760170771
}
170761170772
170762170773
/************** End of where.c ***********************************************/
170763170774
/************** Begin file window.c ******************************************/
170764
-#line 1 "tsrc/window.c"
170765170775
/*
170766170776
** 2018 May 08
170767170777
**
170768170778
** The author disclaims copyright to this source code. In place of
170769170779
** a legal notice, here is a blessing:
@@ -172432,10 +172442,11 @@
172432172442
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
172433172443
FuncDef *pFunc = pWin->pWFunc;
172434172444
int regArg;
172435172445
int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin);
172436172446
int i;
172447
+ int addrIf = 0;
172437172448
172438172449
assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED );
172439172450
172440172451
/* All OVER clauses in the same window function aggregate step must
172441172452
** be the same. */
@@ -172447,10 +172458,22 @@
172447172458
}else{
172448172459
sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+i, reg+i);
172449172460
}
172450172461
}
172451172462
regArg = reg;
172463
+
172464
+ if( pWin->pFilter ){
172465
+ int regTmp;
172466
+ assert( ExprUseXList(pWin->pOwner) );
172467
+ assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr );
172468
+ assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 );
172469
+ regTmp = sqlite3GetTempReg(pParse);
172470
+ sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
172471
+ addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
172472
+ VdbeCoverage(v);
172473
+ sqlite3ReleaseTempReg(pParse, regTmp);
172474
+ }
172452172475
172453172476
if( pMWin->regStartRowid==0
172454172477
&& (pFunc->funcFlags & SQLITE_FUNC_MINMAX)
172455172478
&& (pWin->eStart!=TK_UNBOUNDED)
172456172479
){
@@ -172467,29 +172490,17 @@
172467172490
sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp);
172468172491
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
172469172492
}
172470172493
sqlite3VdbeJumpHere(v, addrIsNull);
172471172494
}else if( pWin->regApp ){
172495
+ assert( pWin->pFilter==0 );
172472172496
assert( pFunc->zName==nth_valueName
172473172497
|| pFunc->zName==first_valueName
172474172498
);
172475172499
assert( bInverse==0 || bInverse==1 );
172476172500
sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
172477172501
}else if( pFunc->xSFunc!=noopStepFunc ){
172478
- int addrIf = 0;
172479
- if( pWin->pFilter ){
172480
- int regTmp;
172481
- assert( ExprUseXList(pWin->pOwner) );
172482
- assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr );
172483
- assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 );
172484
- regTmp = sqlite3GetTempReg(pParse);
172485
- sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
172486
- addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
172487
- VdbeCoverage(v);
172488
- sqlite3ReleaseTempReg(pParse, regTmp);
172489
- }
172490
-
172491172502
if( pWin->bExprArgs ){
172492172503
int iOp = sqlite3VdbeCurrentAddr(v);
172493172504
int iEnd;
172494172505
172495172506
assert( ExprUseXList(pWin->pOwner) );
@@ -172516,12 +172527,13 @@
172516172527
sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF);
172517172528
sqlite3VdbeChangeP5(v, (u8)nArg);
172518172529
if( pWin->bExprArgs ){
172519172530
sqlite3ReleaseTempRange(pParse, regArg, nArg);
172520172531
}
172521
- if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
172522172532
}
172533
+
172534
+ if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
172523172535
}
172524172536
}
172525172537
172526172538
/*
172527172539
** Values that may be passed as the second argument to windowCodeOp().
@@ -173869,11 +173881,10 @@
173869173881
173870173882
#endif /* SQLITE_OMIT_WINDOWFUNC */
173871173883
173872173884
/************** End of window.c **********************************************/
173873173885
/************** Begin file parse.c *******************************************/
173874
-#line 1 "tsrc/parse.c"
173875173886
/* This file is automatically generated by Lemon from input grammar
173876173887
** source file "parse.y".
173877173888
*/
173878173889
/*
173879173890
** 2001-09-15
@@ -173893,11 +173904,10 @@
173893173904
** That input file is processed by Lemon to generate a C-language
173894173905
** implementation of a parser for the given grammar. You might be reading
173895173906
** this comment as part of the translated C-code. Edits should be made
173896173907
** to the original parse.y sources.
173897173908
*/
173898
-#line 62 "parse.y"
173899173909
173900173910
/* #include "sqliteInt.h" */
173901173911
173902173912
/*
173903173913
** Disable all error recovery processing in the parser push-down
@@ -173945,10 +173955,17 @@
173945173955
** Then the "b" IdList records the list "a,b,c".
173946173956
*/
173947173957
struct TrigEvent { int a; IdList * b; };
173948173958
173949173959
struct FrameBound { int eType; Expr *pExpr; };
173960
+
173961
+/*
173962
+** Generate a syntax error
173963
+*/
173964
+static void parserSyntaxError(Parse *pParse, Token *p){
173965
+ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", p);
173966
+}
173950173967
173951173968
/*
173952173969
** Disable lookaside memory allocation for objects that might be
173953173970
** shared across database connections.
173954173971
*/
@@ -173977,11 +173994,10 @@
173977173994
sqlite3ExprListDelete(pParse->db, pOrderBy);
173978173995
sqlite3ExprDelete(pParse->db, pLimit);
173979173996
}
173980173997
#endif /* SQLITE_ENABLE_UPDATE_DELETE_LIMIT */
173981173998
173982
-#line 517 "parse.y"
173983173999
173984174000
/*
173985174001
** For a compound SELECT statement, make sure p->pPrior->pNext==p for
173986174002
** all elements in the list. And make sure list length does not exceed
173987174003
** SQLITE_LIMIT_COMPOUND_SELECT.
@@ -174032,11 +174048,10 @@
174032174048
** testing.
174033174049
*/
174034174050
static void *parserStackRealloc(void *pOld, sqlite3_uint64 newSize){
174035174051
return sqlite3FaultSim(700) ? 0 : sqlite3_realloc(pOld, newSize);
174036174052
}
174037
-#line 1085 "parse.y"
174038174053
174039174054
174040174055
/* Construct a new Expr object from a single token */
174041174056
static Expr *tokenExpr(Parse *pParse, int op, Token t){
174042174057
Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
@@ -174069,11 +174084,10 @@
174069174084
}
174070174085
}
174071174086
return p;
174072174087
}
174073174088
174074
-#line 1329 "parse.y"
174075174089
174076174090
/* A routine to convert a binary TK_IS or TK_ISNOT expression into a
174077174091
** unary TK_ISNULL or TK_NOTNULL expression. */
174078174092
static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){
174079174093
sqlite3 *db = pParse->db;
@@ -174081,11 +174095,10 @@
174081174095
pA->op = (u8)op;
174082174096
sqlite3ExprDelete(db, pA->pRight);
174083174097
pA->pRight = 0;
174084174098
}
174085174099
}
174086
-#line 1564 "parse.y"
174087174100
174088174101
/* Add a single new term to an ExprList that is used to store a
174089174102
** list of identifiers. Report an error if the ID list contains
174090174103
** a COLLATE clause or an ASC or DESC keyword, except ignore the
174091174104
** error while parsing a legacy schema.
@@ -174105,16 +174118,14 @@
174105174118
pIdToken->n, pIdToken->z);
174106174119
}
174107174120
sqlite3ExprListSetName(pParse, p, pIdToken, 1);
174108174121
return p;
174109174122
}
174110
-#line 2048 "parse.y"
174111174123
174112174124
#if TK_SPAN>255
174113174125
# error too many tokens in the grammar
174114174126
#endif
174115
-#line 267 "parse.sql"
174116174127
/**************** End of %include directives **********************************/
174117174128
/* These constants specify the various numeric values for terminal symbols.
174118174129
***************** Begin token definitions *************************************/
174119174130
#ifndef TK_SEMI
174120174131
#define TK_SEMI 1
@@ -176295,13 +176306,11 @@
176295176306
case 240: /* selectnowith */
176296176307
case 241: /* oneselect */
176297176308
case 253: /* values */
176298176309
case 255: /* mvalues */
176299176310
{
176300
-#line 511 "parse.y"
176301176311
sqlite3SelectDelete(pParse->db, (yypminor->yy555));
176302
-#line 2453 "parse.sql"
176303176312
}
176304176313
break;
176305176314
case 217: /* term */
176306176315
case 218: /* expr */
176307176316
case 247: /* where_opt */
@@ -176312,13 +176321,11 @@
176312176321
case 285: /* vinto */
176313176322
case 292: /* when_clause */
176314176323
case 297: /* key_opt */
176315176324
case 314: /* filter_clause */
176316176325
{
176317
-#line 1083 "parse.y"
176318176326
sqlite3ExprDelete(pParse->db, (yypminor->yy454));
176319
-#line 2470 "parse.sql"
176320176327
}
176321176328
break;
176322176329
case 222: /* eidlist_opt */
176323176330
case 232: /* sortlist */
176324176331
case 233: /* eidlist */
@@ -176331,82 +176338,64 @@
176331176338
case 270: /* setlist */
176332176339
case 279: /* paren_exprlist */
176333176340
case 281: /* case_exprlist */
176334176341
case 313: /* part_opt */
176335176342
{
176336
-#line 1562 "parse.y"
176337176343
sqlite3ExprListDelete(pParse->db, (yypminor->yy14));
176338
-#line 2489 "parse.sql"
176339176344
}
176340176345
break;
176341176346
case 239: /* fullname */
176342176347
case 246: /* from */
176343176348
case 258: /* seltablist */
176344176349
case 259: /* stl_prefix */
176345176350
case 264: /* xfullname */
176346176351
{
176347
-#line 789 "parse.y"
176348176352
sqlite3SrcListDelete(pParse->db, (yypminor->yy203));
176349
-#line 2500 "parse.sql"
176350176353
}
176351176354
break;
176352176355
case 242: /* wqlist */
176353176356
{
176354
-#line 1849 "parse.y"
176355176357
sqlite3WithDelete(pParse->db, (yypminor->yy59));
176356
-#line 2507 "parse.sql"
176357176358
}
176358176359
break;
176359176360
case 252: /* window_clause */
176360176361
case 309: /* windowdefn_list */
176361176362
{
176362
-#line 1977 "parse.y"
176363176363
sqlite3WindowListDelete(pParse->db, (yypminor->yy211));
176364
-#line 2515 "parse.sql"
176365176364
}
176366176365
break;
176367176366
case 265: /* idlist */
176368176367
case 272: /* idlist_opt */
176369176368
{
176370
-#line 1068 "parse.y"
176371176369
sqlite3IdListDelete(pParse->db, (yypminor->yy132));
176372
-#line 2523 "parse.sql"
176373176370
}
176374176371
break;
176375176372
case 275: /* filter_over */
176376176373
case 310: /* windowdefn */
176377176374
case 311: /* window */
176378176375
case 312: /* frame_opt */
176379176376
case 315: /* over_clause */
176380176377
{
176381
-#line 1916 "parse.y"
176382176378
sqlite3WindowDelete(pParse->db, (yypminor->yy211));
176383
-#line 2534 "parse.sql"
176384176379
}
176385176380
break;
176386176381
case 288: /* trigger_cmd_list */
176387176382
case 293: /* trigger_cmd */
176388176383
{
176389
-#line 1677 "parse.y"
176390176384
sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy427));
176391
-#line 2542 "parse.sql"
176392176385
}
176393176386
break;
176394176387
case 290: /* trigger_event */
176395176388
{
176396
-#line 1663 "parse.y"
176397176389
sqlite3IdListDelete(pParse->db, (yypminor->yy286).b);
176398
-#line 2549 "parse.sql"
176399176390
}
176400176391
break;
176401176392
case 317: /* frame_bound */
176402176393
case 318: /* frame_bound_s */
176403176394
case 319: /* frame_bound_e */
176404176395
{
176405
-#line 1921 "parse.y"
176406176396
sqlite3ExprDelete(pParse->db, (yypminor->yy509).pExpr);
176407
-#line 2558 "parse.sql"
176408176397
}
176409176398
break;
176410176399
/********* End destructor definitions *****************************************/
176411176400
default: break; /* If no destructor action specified: do nothing */
176412176401
}
@@ -176637,14 +176626,12 @@
176637176626
#endif
176638176627
while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
176639176628
/* Here code is inserted which will execute if the parser
176640176629
** stack every overflows */
176641176630
/******** Begin %stack_overflow code ******************************************/
176642
-#line 51 "parse.y"
176643176631
176644176632
sqlite3OomFault(pParse->db);
176645
-#line 2796 "parse.sql"
176646176633
/******** End %stack_overflow code ********************************************/
176647176634
sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument var */
176648176635
sqlite3ParserCTX_STORE
176649176636
}
176650176637
@@ -177571,481 +177558,330 @@
177571177558
** break;
177572177559
*/
177573177560
/********** Begin reduce actions **********************************************/
177574177561
YYMINORTYPE yylhsminor;
177575177562
case 0: /* explain ::= EXPLAIN */
177576
-#line 155 "parse.y"
177577177563
{ if( pParse->pReprepare==0 ) pParse->explain = 1; }
177578
-#line 3729 "parse.sql"
177579177564
break;
177580177565
case 1: /* explain ::= EXPLAIN QUERY PLAN */
177581
-#line 156 "parse.y"
177582177566
{ if( pParse->pReprepare==0 ) pParse->explain = 2; }
177583
-#line 3734 "parse.sql"
177584177567
break;
177585177568
case 2: /* cmdx ::= cmd */
177586
-#line 158 "parse.y"
177587177569
{ sqlite3FinishCoding(pParse); }
177588
-#line 3739 "parse.sql"
177589177570
break;
177590177571
case 3: /* cmd ::= BEGIN transtype trans_opt */
177591
-#line 163 "parse.y"
177592177572
{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy144);}
177593
-#line 3744 "parse.sql"
177594177573
break;
177595177574
case 4: /* transtype ::= */
177596
-#line 168 "parse.y"
177597177575
{yymsp[1].minor.yy144 = TK_DEFERRED;}
177598
-#line 3749 "parse.sql"
177599177576
break;
177600177577
case 5: /* transtype ::= DEFERRED */
177601177578
case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
177602177579
case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
177603177580
case 324: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==324);
177604
-#line 169 "parse.y"
177605177581
{yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-X*/}
177606
-#line 3757 "parse.sql"
177607177582
break;
177608177583
case 8: /* cmd ::= COMMIT|END trans_opt */
177609177584
case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9);
177610
-#line 172 "parse.y"
177611177585
{sqlite3EndTransaction(pParse,yymsp[-1].major);}
177612
-#line 3763 "parse.sql"
177613177586
break;
177614177587
case 10: /* cmd ::= SAVEPOINT nm */
177615
-#line 177 "parse.y"
177616177588
{
177617177589
sqlite3Savepoint(pParse, SAVEPOINT_BEGIN, &yymsp[0].minor.yy0);
177618177590
}
177619
-#line 3770 "parse.sql"
177620177591
break;
177621177592
case 11: /* cmd ::= RELEASE savepoint_opt nm */
177622
-#line 180 "parse.y"
177623177593
{
177624177594
sqlite3Savepoint(pParse, SAVEPOINT_RELEASE, &yymsp[0].minor.yy0);
177625177595
}
177626
-#line 3777 "parse.sql"
177627177596
break;
177628177597
case 12: /* cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
177629
-#line 183 "parse.y"
177630177598
{
177631177599
sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0);
177632177600
}
177633
-#line 3784 "parse.sql"
177634177601
break;
177635177602
case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
177636
-#line 190 "parse.y"
177637177603
{
177638177604
sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy144,0,0,yymsp[-2].minor.yy144);
177639177605
}
177640
-#line 3791 "parse.sql"
177641177606
break;
177642177607
case 14: /* createkw ::= CREATE */
177643
-#line 193 "parse.y"
177644177608
{disableLookaside(pParse);}
177645
-#line 3796 "parse.sql"
177646177609
break;
177647177610
case 15: /* ifnotexists ::= */
177648177611
case 18: /* temp ::= */ yytestcase(yyruleno==18);
177649177612
case 47: /* autoinc ::= */ yytestcase(yyruleno==47);
177650177613
case 62: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==62);
177651177614
case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72);
177652177615
case 81: /* ifexists ::= */ yytestcase(yyruleno==81);
177653177616
case 100: /* distinct ::= */ yytestcase(yyruleno==100);
177654177617
case 246: /* collate ::= */ yytestcase(yyruleno==246);
177655
-#line 196 "parse.y"
177656177618
{yymsp[1].minor.yy144 = 0;}
177657
-#line 3808 "parse.sql"
177658177619
break;
177659177620
case 16: /* ifnotexists ::= IF NOT EXISTS */
177660
-#line 197 "parse.y"
177661177621
{yymsp[-2].minor.yy144 = 1;}
177662
-#line 3813 "parse.sql"
177663177622
break;
177664177623
case 17: /* temp ::= TEMP */
177665
-#line 200 "parse.y"
177666177624
{yymsp[0].minor.yy144 = pParse->db->init.busy==0;}
177667
-#line 3818 "parse.sql"
177668177625
break;
177669177626
case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_option_set */
177670
-#line 203 "parse.y"
177671177627
{
177672177628
sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy391,0);
177673177629
}
177674
-#line 3825 "parse.sql"
177675177630
break;
177676177631
case 20: /* create_table_args ::= AS select */
177677
-#line 206 "parse.y"
177678177632
{
177679177633
sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy555);
177680177634
sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy555);
177681177635
}
177682
-#line 3833 "parse.sql"
177683177636
break;
177684177637
case 21: /* table_option_set ::= */
177685
-#line 212 "parse.y"
177686177638
{yymsp[1].minor.yy391 = 0;}
177687
-#line 3838 "parse.sql"
177688177639
break;
177689177640
case 22: /* table_option_set ::= table_option_set COMMA table_option */
177690
-#line 214 "parse.y"
177691177641
{yylhsminor.yy391 = yymsp[-2].minor.yy391|yymsp[0].minor.yy391;}
177692
-#line 3843 "parse.sql"
177693177642
yymsp[-2].minor.yy391 = yylhsminor.yy391;
177694177643
break;
177695177644
case 23: /* table_option ::= WITHOUT nm */
177696
-#line 215 "parse.y"
177697177645
{
177698177646
if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
177699177647
yymsp[-1].minor.yy391 = TF_WithoutRowid | TF_NoVisibleRowid;
177700177648
}else{
177701177649
yymsp[-1].minor.yy391 = 0;
177702177650
sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
177703177651
}
177704177652
}
177705
-#line 3856 "parse.sql"
177706177653
break;
177707177654
case 24: /* table_option ::= nm */
177708
-#line 223 "parse.y"
177709177655
{
177710177656
if( yymsp[0].minor.yy0.n==6 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"strict",6)==0 ){
177711177657
yylhsminor.yy391 = TF_Strict;
177712177658
}else{
177713177659
yylhsminor.yy391 = 0;
177714177660
sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
177715177661
}
177716177662
}
177717
-#line 3868 "parse.sql"
177718177663
yymsp[0].minor.yy391 = yylhsminor.yy391;
177719177664
break;
177720177665
case 25: /* columnname ::= nm typetoken */
177721
-#line 233 "parse.y"
177722177666
{sqlite3AddColumn(pParse,yymsp[-1].minor.yy0,yymsp[0].minor.yy0);}
177723
-#line 3874 "parse.sql"
177724177667
break;
177725177668
case 26: /* typetoken ::= */
177726177669
case 65: /* conslist_opt ::= */ yytestcase(yyruleno==65);
177727177670
case 106: /* as ::= */ yytestcase(yyruleno==106);
177728
-#line 327 "parse.y"
177729177671
{yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;}
177730
-#line 3881 "parse.sql"
177731177672
break;
177732177673
case 27: /* typetoken ::= typename LP signed RP */
177733
-#line 329 "parse.y"
177734177674
{
177735177675
yymsp[-3].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z);
177736177676
}
177737
-#line 3888 "parse.sql"
177738177677
break;
177739177678
case 28: /* typetoken ::= typename LP signed COMMA signed RP */
177740
-#line 332 "parse.y"
177741177679
{
177742177680
yymsp[-5].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z);
177743177681
}
177744
-#line 3895 "parse.sql"
177745177682
break;
177746177683
case 29: /* typename ::= typename ID|STRING */
177747
-#line 337 "parse.y"
177748177684
{yymsp[-1].minor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
177749
-#line 3900 "parse.sql"
177750177685
break;
177751177686
case 30: /* scanpt ::= */
177752
-#line 355 "parse.y"
177753177687
{
177754177688
assert( yyLookahead!=YYNOCODE );
177755177689
yymsp[1].minor.yy168 = yyLookaheadToken.z;
177756177690
}
177757
-#line 3908 "parse.sql"
177758177691
break;
177759177692
case 31: /* scantok ::= */
177760
-#line 359 "parse.y"
177761177693
{
177762177694
assert( yyLookahead!=YYNOCODE );
177763177695
yymsp[1].minor.yy0 = yyLookaheadToken;
177764177696
}
177765
-#line 3916 "parse.sql"
177766177697
break;
177767177698
case 32: /* ccons ::= CONSTRAINT nm */
177768177699
case 67: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==67);
177769
-#line 369 "parse.y"
177770177700
{pParse->constraintName = yymsp[0].minor.yy0;}
177771
-#line 3922 "parse.sql"
177772177701
break;
177773177702
case 33: /* ccons ::= DEFAULT scantok term */
177774
-#line 371 "parse.y"
177775177703
{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
177776
-#line 3927 "parse.sql"
177777177704
break;
177778177705
case 34: /* ccons ::= DEFAULT LP expr RP */
177779
-#line 373 "parse.y"
177780177706
{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy454,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
177781
-#line 3932 "parse.sql"
177782177707
break;
177783177708
case 35: /* ccons ::= DEFAULT PLUS scantok term */
177784
-#line 375 "parse.y"
177785177709
{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
177786
-#line 3937 "parse.sql"
177787177710
break;
177788177711
case 36: /* ccons ::= DEFAULT MINUS scantok term */
177789
-#line 376 "parse.y"
177790177712
{
177791177713
Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy454, 0);
177792177714
sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);
177793177715
}
177794
-#line 3945 "parse.sql"
177795177716
break;
177796177717
case 37: /* ccons ::= DEFAULT scantok ID|INDEXED */
177797
-#line 380 "parse.y"
177798177718
{
177799177719
Expr *p = tokenExpr(pParse, TK_STRING, yymsp[0].minor.yy0);
177800177720
if( p ){
177801177721
sqlite3ExprIdToTrueFalse(p);
177802177722
testcase( p->op==TK_TRUEFALSE && sqlite3ExprTruthValue(p) );
177803177723
}
177804177724
sqlite3AddDefaultValue(pParse,p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.z+yymsp[0].minor.yy0.n);
177805177725
}
177806
-#line 3957 "parse.sql"
177807177726
break;
177808177727
case 38: /* ccons ::= NOT NULL onconf */
177809
-#line 393 "parse.y"
177810177728
{sqlite3AddNotNull(pParse, yymsp[0].minor.yy144);}
177811
-#line 3962 "parse.sql"
177812177729
break;
177813177730
case 39: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
177814
-#line 395 "parse.y"
177815177731
{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy144,yymsp[0].minor.yy144,yymsp[-2].minor.yy144);}
177816
-#line 3967 "parse.sql"
177817177732
break;
177818177733
case 40: /* ccons ::= UNIQUE onconf */
177819
-#line 396 "parse.y"
177820177734
{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy144,0,0,0,0,
177821177735
SQLITE_IDXTYPE_UNIQUE);}
177822
-#line 3973 "parse.sql"
177823177736
break;
177824177737
case 41: /* ccons ::= CHECK LP expr RP */
177825
-#line 398 "parse.y"
177826177738
{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy454,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);}
177827
-#line 3978 "parse.sql"
177828177739
break;
177829177740
case 42: /* ccons ::= REFERENCES nm eidlist_opt refargs */
177830
-#line 400 "parse.y"
177831177741
{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy14,yymsp[0].minor.yy144);}
177832
-#line 3983 "parse.sql"
177833177742
break;
177834177743
case 43: /* ccons ::= defer_subclause */
177835
-#line 401 "parse.y"
177836177744
{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy144);}
177837
-#line 3988 "parse.sql"
177838177745
break;
177839177746
case 44: /* ccons ::= COLLATE ID|STRING */
177840
-#line 402 "parse.y"
177841177747
{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
177842
-#line 3993 "parse.sql"
177843177748
break;
177844177749
case 45: /* generated ::= LP expr RP */
177845
-#line 405 "parse.y"
177846177750
{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy454,0);}
177847
-#line 3998 "parse.sql"
177848177751
break;
177849177752
case 46: /* generated ::= LP expr RP ID */
177850
-#line 406 "parse.y"
177851177753
{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy454,&yymsp[0].minor.yy0);}
177852
-#line 4003 "parse.sql"
177853177754
break;
177854177755
case 48: /* autoinc ::= AUTOINCR */
177855
-#line 411 "parse.y"
177856177756
{yymsp[0].minor.yy144 = 1;}
177857
-#line 4008 "parse.sql"
177858177757
break;
177859177758
case 49: /* refargs ::= */
177860
-#line 419 "parse.y"
177861177759
{ yymsp[1].minor.yy144 = OE_None*0x0101; /* EV: R-19803-45884 */}
177862
-#line 4013 "parse.sql"
177863177760
break;
177864177761
case 50: /* refargs ::= refargs refarg */
177865
-#line 420 "parse.y"
177866177762
{ yymsp[-1].minor.yy144 = (yymsp[-1].minor.yy144 & ~yymsp[0].minor.yy383.mask) | yymsp[0].minor.yy383.value; }
177867
-#line 4018 "parse.sql"
177868177763
break;
177869177764
case 51: /* refarg ::= MATCH nm */
177870
-#line 422 "parse.y"
177871177765
{ yymsp[-1].minor.yy383.value = 0; yymsp[-1].minor.yy383.mask = 0x000000; }
177872
-#line 4023 "parse.sql"
177873177766
break;
177874177767
case 52: /* refarg ::= ON INSERT refact */
177875
-#line 423 "parse.y"
177876177768
{ yymsp[-2].minor.yy383.value = 0; yymsp[-2].minor.yy383.mask = 0x000000; }
177877
-#line 4028 "parse.sql"
177878177769
break;
177879177770
case 53: /* refarg ::= ON DELETE refact */
177880
-#line 424 "parse.y"
177881177771
{ yymsp[-2].minor.yy383.value = yymsp[0].minor.yy144; yymsp[-2].minor.yy383.mask = 0x0000ff; }
177882
-#line 4033 "parse.sql"
177883177772
break;
177884177773
case 54: /* refarg ::= ON UPDATE refact */
177885
-#line 425 "parse.y"
177886177774
{ yymsp[-2].minor.yy383.value = yymsp[0].minor.yy144<<8; yymsp[-2].minor.yy383.mask = 0x00ff00; }
177887
-#line 4038 "parse.sql"
177888177775
break;
177889177776
case 55: /* refact ::= SET NULL */
177890
-#line 427 "parse.y"
177891177777
{ yymsp[-1].minor.yy144 = OE_SetNull; /* EV: R-33326-45252 */}
177892
-#line 4043 "parse.sql"
177893177778
break;
177894177779
case 56: /* refact ::= SET DEFAULT */
177895
-#line 428 "parse.y"
177896177780
{ yymsp[-1].minor.yy144 = OE_SetDflt; /* EV: R-33326-45252 */}
177897
-#line 4048 "parse.sql"
177898177781
break;
177899177782
case 57: /* refact ::= CASCADE */
177900
-#line 429 "parse.y"
177901177783
{ yymsp[0].minor.yy144 = OE_Cascade; /* EV: R-33326-45252 */}
177902
-#line 4053 "parse.sql"
177903177784
break;
177904177785
case 58: /* refact ::= RESTRICT */
177905
-#line 430 "parse.y"
177906177786
{ yymsp[0].minor.yy144 = OE_Restrict; /* EV: R-33326-45252 */}
177907
-#line 4058 "parse.sql"
177908177787
break;
177909177788
case 59: /* refact ::= NO ACTION */
177910
-#line 431 "parse.y"
177911177789
{ yymsp[-1].minor.yy144 = OE_None; /* EV: R-33326-45252 */}
177912
-#line 4063 "parse.sql"
177913177790
break;
177914177791
case 60: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
177915
-#line 433 "parse.y"
177916177792
{yymsp[-2].minor.yy144 = 0;}
177917
-#line 4068 "parse.sql"
177918177793
break;
177919177794
case 61: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
177920177795
case 76: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==76);
177921177796
case 173: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==173);
177922
-#line 434 "parse.y"
177923177797
{yymsp[-1].minor.yy144 = yymsp[0].minor.yy144;}
177924
-#line 4075 "parse.sql"
177925177798
break;
177926177799
case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
177927177800
case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80);
177928177801
case 219: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==219);
177929177802
case 222: /* in_op ::= NOT IN */ yytestcase(yyruleno==222);
177930177803
case 247: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==247);
177931
-#line 437 "parse.y"
177932177804
{yymsp[-1].minor.yy144 = 1;}
177933
-#line 4084 "parse.sql"
177934177805
break;
177935177806
case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
177936
-#line 438 "parse.y"
177937177807
{yymsp[-1].minor.yy144 = 0;}
177938
-#line 4089 "parse.sql"
177939177808
break;
177940177809
case 66: /* tconscomma ::= COMMA */
177941
-#line 444 "parse.y"
177942177810
{pParse->constraintName.n = 0;}
177943
-#line 4094 "parse.sql"
177944177811
break;
177945177812
case 68: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
177946
-#line 448 "parse.y"
177947177813
{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy14,yymsp[0].minor.yy144,yymsp[-2].minor.yy144,0);}
177948
-#line 4099 "parse.sql"
177949177814
break;
177950177815
case 69: /* tcons ::= UNIQUE LP sortlist RP onconf */
177951
-#line 450 "parse.y"
177952177816
{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy14,yymsp[0].minor.yy144,0,0,0,0,
177953177817
SQLITE_IDXTYPE_UNIQUE);}
177954
-#line 4105 "parse.sql"
177955177818
break;
177956177819
case 70: /* tcons ::= CHECK LP expr RP onconf */
177957
-#line 453 "parse.y"
177958177820
{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy454,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);}
177959
-#line 4110 "parse.sql"
177960177821
break;
177961177822
case 71: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
177962
-#line 455 "parse.y"
177963177823
{
177964177824
sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy14, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[-1].minor.yy144);
177965177825
sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy144);
177966177826
}
177967
-#line 4118 "parse.sql"
177968177827
break;
177969177828
case 73: /* onconf ::= */
177970177829
case 75: /* orconf ::= */ yytestcase(yyruleno==75);
177971
-#line 469 "parse.y"
177972177830
{yymsp[1].minor.yy144 = OE_Default;}
177973
-#line 4124 "parse.sql"
177974177831
break;
177975177832
case 74: /* onconf ::= ON CONFLICT resolvetype */
177976
-#line 470 "parse.y"
177977177833
{yymsp[-2].minor.yy144 = yymsp[0].minor.yy144;}
177978
-#line 4129 "parse.sql"
177979177834
break;
177980177835
case 77: /* resolvetype ::= IGNORE */
177981
-#line 474 "parse.y"
177982177836
{yymsp[0].minor.yy144 = OE_Ignore;}
177983
-#line 4134 "parse.sql"
177984177837
break;
177985177838
case 78: /* resolvetype ::= REPLACE */
177986177839
case 174: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==174);
177987
-#line 475 "parse.y"
177988177840
{yymsp[0].minor.yy144 = OE_Replace;}
177989
-#line 4140 "parse.sql"
177990177841
break;
177991177842
case 79: /* cmd ::= DROP TABLE ifexists fullname */
177992
-#line 479 "parse.y"
177993177843
{
177994177844
sqlite3DropTable(pParse, yymsp[0].minor.yy203, 0, yymsp[-1].minor.yy144);
177995177845
}
177996
-#line 4147 "parse.sql"
177997177846
break;
177998177847
case 82: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
177999
-#line 490 "parse.y"
178000177848
{
178001177849
sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[0].minor.yy555, yymsp[-7].minor.yy144, yymsp[-5].minor.yy144);
178002177850
}
178003
-#line 4154 "parse.sql"
178004177851
break;
178005177852
case 83: /* cmd ::= DROP VIEW ifexists fullname */
178006
-#line 493 "parse.y"
178007177853
{
178008177854
sqlite3DropTable(pParse, yymsp[0].minor.yy203, 1, yymsp[-1].minor.yy144);
178009177855
}
178010
-#line 4161 "parse.sql"
178011177856
break;
178012177857
case 84: /* cmd ::= select */
178013
-#line 500 "parse.y"
178014177858
{
178015177859
SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0};
178016177860
if( (pParse->db->mDbFlags & DBFLAG_EncodingFixed)!=0
178017177861
|| sqlite3ReadSchema(pParse)==SQLITE_OK
178018177862
){
178019177863
sqlite3Select(pParse, yymsp[0].minor.yy555, &dest);
178020177864
}
178021177865
sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy555);
178022177866
}
178023
-#line 4174 "parse.sql"
178024177867
break;
178025177868
case 85: /* select ::= WITH wqlist selectnowith */
178026
-#line 574 "parse.y"
178027177869
{yymsp[-2].minor.yy555 = attachWithToSelect(pParse,yymsp[0].minor.yy555,yymsp[-1].minor.yy59);}
178028
-#line 4179 "parse.sql"
178029177870
break;
178030177871
case 86: /* select ::= WITH RECURSIVE wqlist selectnowith */
178031
-#line 576 "parse.y"
178032177872
{yymsp[-3].minor.yy555 = attachWithToSelect(pParse,yymsp[0].minor.yy555,yymsp[-1].minor.yy59);}
178033
-#line 4184 "parse.sql"
178034177873
break;
178035177874
case 87: /* select ::= selectnowith */
178036
-#line 579 "parse.y"
178037177875
{
178038177876
Select *p = yymsp[0].minor.yy555;
178039177877
if( p ){
178040177878
parserDoubleLinkSelect(pParse, p);
178041177879
}
178042177880
}
178043
-#line 4194 "parse.sql"
178044177881
break;
178045177882
case 88: /* selectnowith ::= selectnowith multiselect_op oneselect */
178046
-#line 588 "parse.y"
178047177883
{
178048177884
Select *pRhs = yymsp[0].minor.yy555;
178049177885
Select *pLhs = yymsp[-2].minor.yy555;
178050177886
if( pRhs && pRhs->pPrior ){
178051177887
SrcList *pFrom;
@@ -178064,175 +177900,131 @@
178064177900
}else{
178065177901
sqlite3SelectDelete(pParse->db, pLhs);
178066177902
}
178067177903
yymsp[-2].minor.yy555 = pRhs;
178068177904
}
178069
-#line 4220 "parse.sql"
178070177905
break;
178071177906
case 89: /* multiselect_op ::= UNION */
178072177907
case 91: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==91);
178073
-#line 611 "parse.y"
178074177908
{yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-OP*/}
178075
-#line 4226 "parse.sql"
178076177909
break;
178077177910
case 90: /* multiselect_op ::= UNION ALL */
178078
-#line 612 "parse.y"
178079177911
{yymsp[-1].minor.yy144 = TK_ALL;}
178080
-#line 4231 "parse.sql"
178081177912
break;
178082177913
case 92: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
178083
-#line 618 "parse.y"
178084177914
{
178085177915
yymsp[-8].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy203,yymsp[-4].minor.yy454,yymsp[-3].minor.yy14,yymsp[-2].minor.yy454,yymsp[-1].minor.yy14,yymsp[-7].minor.yy144,yymsp[0].minor.yy454);
178086177916
}
178087
-#line 4238 "parse.sql"
178088177917
break;
178089177918
case 93: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
178090
-#line 624 "parse.y"
178091177919
{
178092177920
yymsp[-9].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy14,yymsp[-6].minor.yy203,yymsp[-5].minor.yy454,yymsp[-4].minor.yy14,yymsp[-3].minor.yy454,yymsp[-1].minor.yy14,yymsp[-8].minor.yy144,yymsp[0].minor.yy454);
178093177921
if( yymsp[-9].minor.yy555 ){
178094177922
yymsp[-9].minor.yy555->pWinDefn = yymsp[-2].minor.yy211;
178095177923
}else{
178096177924
sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy211);
178097177925
}
178098177926
}
178099
-#line 4250 "parse.sql"
178100177927
break;
178101177928
case 94: /* values ::= VALUES LP nexprlist RP */
178102
-#line 640 "parse.y"
178103177929
{
178104177930
yymsp[-3].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0);
178105177931
}
178106
-#line 4257 "parse.sql"
178107177932
break;
178108177933
case 95: /* oneselect ::= mvalues */
178109
-#line 647 "parse.y"
178110177934
{
178111177935
sqlite3MultiValuesEnd(pParse, yymsp[0].minor.yy555);
178112177936
}
178113
-#line 4264 "parse.sql"
178114177937
break;
178115177938
case 96: /* mvalues ::= values COMMA LP nexprlist RP */
178116177939
case 97: /* mvalues ::= mvalues COMMA LP nexprlist RP */ yytestcase(yyruleno==97);
178117
-#line 651 "parse.y"
178118177940
{
178119177941
yymsp[-4].minor.yy555 = sqlite3MultiValues(pParse, yymsp[-4].minor.yy555, yymsp[-1].minor.yy14);
178120177942
}
178121
-#line 4272 "parse.sql"
178122177943
break;
178123177944
case 98: /* distinct ::= DISTINCT */
178124
-#line 662 "parse.y"
178125177945
{yymsp[0].minor.yy144 = SF_Distinct;}
178126
-#line 4277 "parse.sql"
178127177946
break;
178128177947
case 99: /* distinct ::= ALL */
178129
-#line 663 "parse.y"
178130177948
{yymsp[0].minor.yy144 = SF_All;}
178131
-#line 4282 "parse.sql"
178132177949
break;
178133177950
case 101: /* sclp ::= */
178134177951
case 134: /* orderby_opt ::= */ yytestcase(yyruleno==134);
178135177952
case 144: /* groupby_opt ::= */ yytestcase(yyruleno==144);
178136177953
case 234: /* exprlist ::= */ yytestcase(yyruleno==234);
178137177954
case 237: /* paren_exprlist ::= */ yytestcase(yyruleno==237);
178138177955
case 242: /* eidlist_opt ::= */ yytestcase(yyruleno==242);
178139
-#line 676 "parse.y"
178140177956
{yymsp[1].minor.yy14 = 0;}
178141
-#line 4292 "parse.sql"
178142177957
break;
178143177958
case 102: /* selcollist ::= sclp scanpt expr scanpt as */
178144
-#line 677 "parse.y"
178145177959
{
178146177960
yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[-2].minor.yy454);
178147177961
if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy14, &yymsp[0].minor.yy0, 1);
178148177962
sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy14,yymsp[-3].minor.yy168,yymsp[-1].minor.yy168);
178149177963
}
178150
-#line 4301 "parse.sql"
178151177964
break;
178152177965
case 103: /* selcollist ::= sclp scanpt STAR */
178153
-#line 682 "parse.y"
178154177966
{
178155177967
Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
178156177968
sqlite3ExprSetErrorOffset(p, (int)(yymsp[0].minor.yy0.z - pParse->zTail));
178157177969
yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy14, p);
178158177970
}
178159
-#line 4310 "parse.sql"
178160177971
break;
178161177972
case 104: /* selcollist ::= sclp scanpt nm DOT STAR */
178162
-#line 687 "parse.y"
178163177973
{
178164177974
Expr *pRight, *pLeft, *pDot;
178165177975
pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
178166177976
sqlite3ExprSetErrorOffset(pRight, (int)(yymsp[0].minor.yy0.z - pParse->zTail));
178167177977
pLeft = tokenExpr(pParse, TK_ID, yymsp[-2].minor.yy0);
178168177978
pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
178169177979
yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, pDot);
178170177980
}
178171
-#line 4322 "parse.sql"
178172177981
break;
178173177982
case 105: /* as ::= AS nm */
178174177983
case 117: /* dbnm ::= DOT nm */ yytestcase(yyruleno==117);
178175177984
case 258: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==258);
178176177985
case 259: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==259);
178177
-#line 700 "parse.y"
178178177986
{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
178179
-#line 4330 "parse.sql"
178180177987
break;
178181177988
case 107: /* from ::= */
178182177989
case 110: /* stl_prefix ::= */ yytestcase(yyruleno==110);
178183
-#line 714 "parse.y"
178184177990
{yymsp[1].minor.yy203 = 0;}
178185
-#line 4336 "parse.sql"
178186177991
break;
178187177992
case 108: /* from ::= FROM seltablist */
178188
-#line 715 "parse.y"
178189177993
{
178190177994
yymsp[-1].minor.yy203 = yymsp[0].minor.yy203;
178191177995
sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy203);
178192177996
}
178193
-#line 4344 "parse.sql"
178194177997
break;
178195177998
case 109: /* stl_prefix ::= seltablist joinop */
178196
-#line 723 "parse.y"
178197177999
{
178198178000
if( ALWAYS(yymsp[-1].minor.yy203 && yymsp[-1].minor.yy203->nSrc>0) ) yymsp[-1].minor.yy203->a[yymsp[-1].minor.yy203->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy144;
178199178001
}
178200
-#line 4351 "parse.sql"
178201178002
break;
178202178003
case 111: /* seltablist ::= stl_prefix nm dbnm as on_using */
178203
-#line 727 "parse.y"
178204178004
{
178205178005
yymsp[-4].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy203,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269);
178206178006
}
178207
-#line 4358 "parse.sql"
178208178007
break;
178209178008
case 112: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
178210
-#line 730 "parse.y"
178211178009
{
178212178010
yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy269);
178213178011
sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy203, &yymsp[-1].minor.yy0);
178214178012
}
178215
-#line 4366 "parse.sql"
178216178013
break;
178217178014
case 113: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
178218
-#line 734 "parse.y"
178219178015
{
178220178016
yymsp[-7].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy203,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269);
178221178017
sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy203, yymsp[-3].minor.yy14);
178222178018
}
178223
-#line 4374 "parse.sql"
178224178019
break;
178225178020
case 114: /* seltablist ::= stl_prefix LP select RP as on_using */
178226
-#line 739 "parse.y"
178227178021
{
178228178022
yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy555,&yymsp[0].minor.yy269);
178229178023
}
178230
-#line 4381 "parse.sql"
178231178024
break;
178232178025
case 115: /* seltablist ::= stl_prefix LP seltablist RP as on_using */
178233
-#line 742 "parse.y"
178234178026
{
178235178027
if( yymsp[-5].minor.yy203==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy269.pOn==0 && yymsp[0].minor.yy269.pUsing==0 ){
178236178028
yymsp[-5].minor.yy203 = yymsp[-3].minor.yy203;
178237178029
}else if( ALWAYS(yymsp[-3].minor.yy203!=0) && yymsp[-3].minor.yy203->nSrc==1 ){
178238178030
yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269);
@@ -178269,210 +178061,144 @@
178269178061
sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy203);
178270178062
pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy203,0,0,0,0,SF_NestedFrom,0);
178271178063
yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy269);
178272178064
}
178273178065
}
178274
-#line 4425 "parse.sql"
178275178066
break;
178276178067
case 116: /* dbnm ::= */
178277178068
case 131: /* indexed_opt ::= */ yytestcase(yyruleno==131);
178278
-#line 785 "parse.y"
178279178069
{yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;}
178280
-#line 4431 "parse.sql"
178281178070
break;
178282178071
case 118: /* fullname ::= nm */
178283
-#line 790 "parse.y"
178284178072
{
178285178073
yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0);
178286178074
if( IN_RENAME_OBJECT && yylhsminor.yy203 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[0].minor.yy0);
178287178075
}
178288
-#line 4439 "parse.sql"
178289178076
yymsp[0].minor.yy203 = yylhsminor.yy203;
178290178077
break;
178291178078
case 119: /* fullname ::= nm DOT nm */
178292
-#line 794 "parse.y"
178293178079
{
178294178080
yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
178295178081
if( IN_RENAME_OBJECT && yylhsminor.yy203 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[0].minor.yy0);
178296178082
}
178297
-#line 4448 "parse.sql"
178298178083
yymsp[-2].minor.yy203 = yylhsminor.yy203;
178299178084
break;
178300178085
case 120: /* xfullname ::= nm */
178301
-#line 802 "parse.y"
178302178086
{yymsp[0].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
178303
-#line 4454 "parse.sql"
178304178087
break;
178305178088
case 121: /* xfullname ::= nm DOT nm */
178306
-#line 804 "parse.y"
178307178089
{yymsp[-2].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
178308
-#line 4459 "parse.sql"
178309178090
break;
178310178091
case 122: /* xfullname ::= nm DOT nm AS nm */
178311
-#line 805 "parse.y"
178312178092
{
178313178093
yymsp[-4].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
178314178094
if( yymsp[-4].minor.yy203 ) yymsp[-4].minor.yy203->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
178315178095
}
178316
-#line 4467 "parse.sql"
178317178096
break;
178318178097
case 123: /* xfullname ::= nm AS nm */
178319
-#line 809 "parse.y"
178320178098
{
178321178099
yymsp[-2].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
178322178100
if( yymsp[-2].minor.yy203 ) yymsp[-2].minor.yy203->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
178323178101
}
178324
-#line 4475 "parse.sql"
178325178102
break;
178326178103
case 124: /* joinop ::= COMMA|JOIN */
178327
-#line 815 "parse.y"
178328178104
{ yymsp[0].minor.yy144 = JT_INNER; }
178329
-#line 4480 "parse.sql"
178330178105
break;
178331178106
case 125: /* joinop ::= JOIN_KW JOIN */
178332
-#line 817 "parse.y"
178333178107
{yymsp[-1].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/}
178334
-#line 4485 "parse.sql"
178335178108
break;
178336178109
case 126: /* joinop ::= JOIN_KW nm JOIN */
178337
-#line 819 "parse.y"
178338178110
{yymsp[-2].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
178339
-#line 4490 "parse.sql"
178340178111
break;
178341178112
case 127: /* joinop ::= JOIN_KW nm nm JOIN */
178342
-#line 821 "parse.y"
178343178113
{yymsp[-3].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
178344
-#line 4495 "parse.sql"
178345178114
break;
178346178115
case 128: /* on_using ::= ON expr */
178347
-#line 842 "parse.y"
178348178116
{yymsp[-1].minor.yy269.pOn = yymsp[0].minor.yy454; yymsp[-1].minor.yy269.pUsing = 0;}
178349
-#line 4500 "parse.sql"
178350178117
break;
178351178118
case 129: /* on_using ::= USING LP idlist RP */
178352
-#line 843 "parse.y"
178353178119
{yymsp[-3].minor.yy269.pOn = 0; yymsp[-3].minor.yy269.pUsing = yymsp[-1].minor.yy132;}
178354
-#line 4505 "parse.sql"
178355178120
break;
178356178121
case 130: /* on_using ::= */
178357
-#line 844 "parse.y"
178358178122
{yymsp[1].minor.yy269.pOn = 0; yymsp[1].minor.yy269.pUsing = 0;}
178359
-#line 4510 "parse.sql"
178360178123
break;
178361178124
case 132: /* indexed_by ::= INDEXED BY nm */
178362
-#line 860 "parse.y"
178363178125
{yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
178364
-#line 4515 "parse.sql"
178365178126
break;
178366178127
case 133: /* indexed_by ::= NOT INDEXED */
178367
-#line 861 "parse.y"
178368178128
{yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
178369
-#line 4520 "parse.sql"
178370178129
break;
178371178130
case 135: /* orderby_opt ::= ORDER BY sortlist */
178372178131
case 145: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==145);
178373
-#line 874 "parse.y"
178374178132
{yymsp[-2].minor.yy14 = yymsp[0].minor.yy14;}
178375
-#line 4526 "parse.sql"
178376178133
break;
178377178134
case 136: /* sortlist ::= sortlist COMMA expr sortorder nulls */
178378
-#line 875 "parse.y"
178379178135
{
178380178136
yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14,yymsp[-2].minor.yy454);
178381178137
sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy14,yymsp[-1].minor.yy144,yymsp[0].minor.yy144);
178382178138
}
178383
-#line 4534 "parse.sql"
178384178139
break;
178385178140
case 137: /* sortlist ::= expr sortorder nulls */
178386
-#line 879 "parse.y"
178387178141
{
178388178142
yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy454); /*A-overwrites-Y*/
178389178143
sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy14,yymsp[-1].minor.yy144,yymsp[0].minor.yy144);
178390178144
}
178391
-#line 4542 "parse.sql"
178392178145
break;
178393178146
case 138: /* sortorder ::= ASC */
178394
-#line 886 "parse.y"
178395178147
{yymsp[0].minor.yy144 = SQLITE_SO_ASC;}
178396
-#line 4547 "parse.sql"
178397178148
break;
178398178149
case 139: /* sortorder ::= DESC */
178399
-#line 887 "parse.y"
178400178150
{yymsp[0].minor.yy144 = SQLITE_SO_DESC;}
178401
-#line 4552 "parse.sql"
178402178151
break;
178403178152
case 140: /* sortorder ::= */
178404178153
case 143: /* nulls ::= */ yytestcase(yyruleno==143);
178405
-#line 888 "parse.y"
178406178154
{yymsp[1].minor.yy144 = SQLITE_SO_UNDEFINED;}
178407
-#line 4558 "parse.sql"
178408178155
break;
178409178156
case 141: /* nulls ::= NULLS FIRST */
178410
-#line 891 "parse.y"
178411178157
{yymsp[-1].minor.yy144 = SQLITE_SO_ASC;}
178412
-#line 4563 "parse.sql"
178413178158
break;
178414178159
case 142: /* nulls ::= NULLS LAST */
178415
-#line 892 "parse.y"
178416178160
{yymsp[-1].minor.yy144 = SQLITE_SO_DESC;}
178417
-#line 4568 "parse.sql"
178418178161
break;
178419178162
case 146: /* having_opt ::= */
178420178163
case 148: /* limit_opt ::= */ yytestcase(yyruleno==148);
178421178164
case 153: /* where_opt ::= */ yytestcase(yyruleno==153);
178422178165
case 155: /* where_opt_ret ::= */ yytestcase(yyruleno==155);
178423178166
case 232: /* case_else ::= */ yytestcase(yyruleno==232);
178424178167
case 233: /* case_operand ::= */ yytestcase(yyruleno==233);
178425178168
case 252: /* vinto ::= */ yytestcase(yyruleno==252);
178426
-#line 902 "parse.y"
178427178169
{yymsp[1].minor.yy454 = 0;}
178428
-#line 4579 "parse.sql"
178429178170
break;
178430178171
case 147: /* having_opt ::= HAVING expr */
178431178172
case 154: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==154);
178432178173
case 156: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==156);
178433178174
case 231: /* case_else ::= ELSE expr */ yytestcase(yyruleno==231);
178434178175
case 251: /* vinto ::= INTO expr */ yytestcase(yyruleno==251);
178435
-#line 903 "parse.y"
178436178176
{yymsp[-1].minor.yy454 = yymsp[0].minor.yy454;}
178437
-#line 4588 "parse.sql"
178438178177
break;
178439178178
case 149: /* limit_opt ::= LIMIT expr */
178440
-#line 917 "parse.y"
178441178179
{yymsp[-1].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy454,0);}
178442
-#line 4593 "parse.sql"
178443178180
break;
178444178181
case 150: /* limit_opt ::= LIMIT expr OFFSET expr */
178445
-#line 919 "parse.y"
178446178182
{yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);}
178447
-#line 4598 "parse.sql"
178448178183
break;
178449178184
case 151: /* limit_opt ::= LIMIT expr COMMA expr */
178450
-#line 921 "parse.y"
178451178185
{yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy454,yymsp[-2].minor.yy454);}
178452
-#line 4603 "parse.sql"
178453178186
break;
178454178187
case 152: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */
178455
-#line 939 "parse.y"
178456178188
{
178457178189
sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy203, &yymsp[-1].minor.yy0);
178458178190
sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy203,yymsp[0].minor.yy454,0,0);
178459178191
}
178460
-#line 4611 "parse.sql"
178461178192
break;
178462178193
case 157: /* where_opt_ret ::= RETURNING selcollist */
178463
-#line 955 "parse.y"
178464178194
{sqlite3AddReturning(pParse,yymsp[0].minor.yy14); yymsp[-1].minor.yy454 = 0;}
178465
-#line 4616 "parse.sql"
178466178195
break;
178467178196
case 158: /* where_opt_ret ::= WHERE expr RETURNING selcollist */
178468
-#line 957 "parse.y"
178469178197
{sqlite3AddReturning(pParse,yymsp[0].minor.yy14); yymsp[-3].minor.yy454 = yymsp[-2].minor.yy454;}
178470
-#line 4621 "parse.sql"
178471178198
break;
178472178199
case 159: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
178473
-#line 989 "parse.y"
178474178200
{
178475178201
sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy203, &yymsp[-4].minor.yy0);
178476178202
sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy14,"set list");
178477178203
if( yymsp[-1].minor.yy203 ){
178478178204
SrcList *pFromClause = yymsp[-1].minor.yy203;
@@ -178486,134 +178212,92 @@
178486178212
}
178487178213
yymsp[-5].minor.yy203 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy203, pFromClause);
178488178214
}
178489178215
sqlite3Update(pParse,yymsp[-5].minor.yy203,yymsp[-2].minor.yy14,yymsp[0].minor.yy454,yymsp[-6].minor.yy144,0,0,0);
178490178216
}
178491
-#line 4642 "parse.sql"
178492178217
break;
178493178218
case 160: /* setlist ::= setlist COMMA nm EQ expr */
178494
-#line 1013 "parse.y"
178495178219
{
178496178220
yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[0].minor.yy454);
178497178221
sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy14, &yymsp[-2].minor.yy0, 1);
178498178222
}
178499
-#line 4650 "parse.sql"
178500178223
break;
178501178224
case 161: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
178502
-#line 1017 "parse.y"
178503178225
{
178504178226
yymsp[-6].minor.yy14 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy14, yymsp[-3].minor.yy132, yymsp[0].minor.yy454);
178505178227
}
178506
-#line 4657 "parse.sql"
178507178228
break;
178508178229
case 162: /* setlist ::= nm EQ expr */
178509
-#line 1020 "parse.y"
178510178230
{
178511178231
yylhsminor.yy14 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy454);
178512178232
sqlite3ExprListSetName(pParse, yylhsminor.yy14, &yymsp[-2].minor.yy0, 1);
178513178233
}
178514
-#line 4665 "parse.sql"
178515178234
yymsp[-2].minor.yy14 = yylhsminor.yy14;
178516178235
break;
178517178236
case 163: /* setlist ::= LP idlist RP EQ expr */
178518
-#line 1024 "parse.y"
178519178237
{
178520178238
yymsp[-4].minor.yy14 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy132, yymsp[0].minor.yy454);
178521178239
}
178522
-#line 4673 "parse.sql"
178523178240
break;
178524178241
case 164: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
178525
-#line 1031 "parse.y"
178526178242
{
178527178243
sqlite3Insert(pParse, yymsp[-3].minor.yy203, yymsp[-1].minor.yy555, yymsp[-2].minor.yy132, yymsp[-5].minor.yy144, yymsp[0].minor.yy122);
178528178244
}
178529
-#line 4680 "parse.sql"
178530178245
break;
178531178246
case 165: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */
178532
-#line 1035 "parse.y"
178533178247
{
178534178248
sqlite3Insert(pParse, yymsp[-4].minor.yy203, 0, yymsp[-3].minor.yy132, yymsp[-6].minor.yy144, 0);
178535178249
}
178536
-#line 4687 "parse.sql"
178537178250
break;
178538178251
case 166: /* upsert ::= */
178539
-#line 1046 "parse.y"
178540178252
{ yymsp[1].minor.yy122 = 0; }
178541
-#line 4692 "parse.sql"
178542178253
break;
178543178254
case 167: /* upsert ::= RETURNING selcollist */
178544
-#line 1047 "parse.y"
178545178255
{ yymsp[-1].minor.yy122 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy14); }
178546
-#line 4697 "parse.sql"
178547178256
break;
178548178257
case 168: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */
178549
-#line 1050 "parse.y"
178550178258
{ yymsp[-11].minor.yy122 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy14,yymsp[-6].minor.yy454,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454,yymsp[0].minor.yy122);}
178551
-#line 4702 "parse.sql"
178552178259
break;
178553178260
case 169: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */
178554
-#line 1052 "parse.y"
178555178261
{ yymsp[-8].minor.yy122 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy14,yymsp[-3].minor.yy454,0,0,yymsp[0].minor.yy122); }
178556
-#line 4707 "parse.sql"
178557178262
break;
178558178263
case 170: /* upsert ::= ON CONFLICT DO NOTHING returning */
178559
-#line 1054 "parse.y"
178560178264
{ yymsp[-4].minor.yy122 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); }
178561
-#line 4712 "parse.sql"
178562178265
break;
178563178266
case 171: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
178564
-#line 1056 "parse.y"
178565178267
{ yymsp[-7].minor.yy122 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454,0);}
178566
-#line 4717 "parse.sql"
178567178268
break;
178568178269
case 172: /* returning ::= RETURNING selcollist */
178569
-#line 1058 "parse.y"
178570178270
{sqlite3AddReturning(pParse,yymsp[0].minor.yy14);}
178571
-#line 4722 "parse.sql"
178572178271
break;
178573178272
case 175: /* idlist_opt ::= */
178574
-#line 1070 "parse.y"
178575178273
{yymsp[1].minor.yy132 = 0;}
178576
-#line 4727 "parse.sql"
178577178274
break;
178578178275
case 176: /* idlist_opt ::= LP idlist RP */
178579
-#line 1071 "parse.y"
178580178276
{yymsp[-2].minor.yy132 = yymsp[-1].minor.yy132;}
178581
-#line 4732 "parse.sql"
178582178277
break;
178583178278
case 177: /* idlist ::= idlist COMMA nm */
178584
-#line 1073 "parse.y"
178585178279
{yymsp[-2].minor.yy132 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy132,&yymsp[0].minor.yy0);}
178586
-#line 4737 "parse.sql"
178587178280
break;
178588178281
case 178: /* idlist ::= nm */
178589
-#line 1075 "parse.y"
178590178282
{yymsp[0].minor.yy132 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
178591
-#line 4742 "parse.sql"
178592178283
break;
178593178284
case 179: /* expr ::= LP expr RP */
178594
-#line 1124 "parse.y"
178595178285
{yymsp[-2].minor.yy454 = yymsp[-1].minor.yy454;}
178596
-#line 4747 "parse.sql"
178597178286
break;
178598178287
case 180: /* expr ::= ID|INDEXED|JOIN_KW */
178599
-#line 1125 "parse.y"
178600178288
{yymsp[0].minor.yy454=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
178601
-#line 4752 "parse.sql"
178602178289
break;
178603178290
case 181: /* expr ::= nm DOT nm */
178604
-#line 1126 "parse.y"
178605178291
{
178606178292
Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0);
178607178293
Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0);
178608178294
yylhsminor.yy454 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
178609178295
}
178610
-#line 4761 "parse.sql"
178611178296
yymsp[-2].minor.yy454 = yylhsminor.yy454;
178612178297
break;
178613178298
case 182: /* expr ::= nm DOT nm DOT nm */
178614
-#line 1131 "parse.y"
178615178299
{
178616178300
Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-4].minor.yy0);
178617178301
Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0);
178618178302
Expr *temp3 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0);
178619178303
Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
@@ -178620,30 +178304,24 @@
178620178304
if( IN_RENAME_OBJECT ){
178621178305
sqlite3RenameTokenRemap(pParse, 0, temp1);
178622178306
}
178623178307
yylhsminor.yy454 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
178624178308
}
178625
-#line 4776 "parse.sql"
178626178309
yymsp[-4].minor.yy454 = yylhsminor.yy454;
178627178310
break;
178628178311
case 183: /* term ::= NULL|FLOAT|BLOB */
178629178312
case 184: /* term ::= STRING */ yytestcase(yyruleno==184);
178630
-#line 1141 "parse.y"
178631178313
{yymsp[0].minor.yy454=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
178632
-#line 4783 "parse.sql"
178633178314
break;
178634178315
case 185: /* term ::= INTEGER */
178635
-#line 1143 "parse.y"
178636178316
{
178637178317
yylhsminor.yy454 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
178638178318
if( yylhsminor.yy454 ) yylhsminor.yy454->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail);
178639178319
}
178640
-#line 4791 "parse.sql"
178641178320
yymsp[0].minor.yy454 = yylhsminor.yy454;
178642178321
break;
178643178322
case 186: /* expr ::= VARIABLE */
178644
-#line 1147 "parse.y"
178645178323
{
178646178324
if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){
178647178325
u32 n = yymsp[0].minor.yy0.n;
178648178326
yymsp[0].minor.yy454 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
178649178327
sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy454, n);
@@ -178652,98 +178330,78 @@
178652178330
** that look like this: #1 #2 ... These terms refer to registers
178653178331
** in the virtual machine. #N is the N-th register. */
178654178332
Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/
178655178333
assert( t.n>=2 );
178656178334
if( pParse->nested==0 ){
178657
- sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
178335
+ parserSyntaxError(pParse, &t);
178658178336
yymsp[0].minor.yy454 = 0;
178659178337
}else{
178660178338
yymsp[0].minor.yy454 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
178661178339
if( yymsp[0].minor.yy454 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy454->iTable);
178662178340
}
178663178341
}
178664178342
}
178665
-#line 4816 "parse.sql"
178666178343
break;
178667178344
case 187: /* expr ::= expr COLLATE ID|STRING */
178668
-#line 1167 "parse.y"
178669178345
{
178670178346
yymsp[-2].minor.yy454 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy454, &yymsp[0].minor.yy0, 1);
178671178347
}
178672
-#line 4823 "parse.sql"
178673178348
break;
178674178349
case 188: /* expr ::= CAST LP expr AS typetoken RP */
178675
-#line 1171 "parse.y"
178676178350
{
178677178351
yymsp[-5].minor.yy454 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
178678178352
sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy454, yymsp[-3].minor.yy454, 0);
178679178353
}
178680
-#line 4831 "parse.sql"
178681178354
break;
178682178355
case 189: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
178683
-#line 1178 "parse.y"
178684178356
{
178685178357
yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy144);
178686178358
}
178687
-#line 4838 "parse.sql"
178688178359
yymsp[-4].minor.yy454 = yylhsminor.yy454;
178689178360
break;
178690178361
case 190: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */
178691
-#line 1181 "parse.y"
178692178362
{
178693178363
yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-4].minor.yy14, &yymsp[-7].minor.yy0, yymsp[-5].minor.yy144);
178694178364
sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy454, yymsp[-1].minor.yy14);
178695178365
}
178696
-#line 4847 "parse.sql"
178697178366
yymsp[-7].minor.yy454 = yylhsminor.yy454;
178698178367
break;
178699178368
case 191: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
178700
-#line 1185 "parse.y"
178701178369
{
178702178370
yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0);
178703178371
}
178704
-#line 4855 "parse.sql"
178705178372
yymsp[-3].minor.yy454 = yylhsminor.yy454;
178706178373
break;
178707178374
case 192: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
178708
-#line 1249 "parse.y"
178709178375
{
178710178376
yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy14, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy144);
178711178377
sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211);
178712178378
}
178713
-#line 4864 "parse.sql"
178714178379
yymsp[-5].minor.yy454 = yylhsminor.yy454;
178715178380
break;
178716178381
case 193: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */
178717
-#line 1253 "parse.y"
178718178382
{
178719178383
yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-5].minor.yy14, &yymsp[-8].minor.yy0, yymsp[-6].minor.yy144);
178720178384
sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211);
178721178385
sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy454, yymsp[-2].minor.yy14);
178722178386
}
178723
-#line 4874 "parse.sql"
178724178387
yymsp[-8].minor.yy454 = yylhsminor.yy454;
178725178388
break;
178726178389
case 194: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
178727
-#line 1258 "parse.y"
178728178390
{
178729178391
yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
178730178392
sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211);
178731178393
}
178732
-#line 4883 "parse.sql"
178733178394
yymsp[-4].minor.yy454 = yylhsminor.yy454;
178734178395
break;
178735178396
case 195: /* term ::= CTIME_KW */
178736
-#line 1272 "parse.y"
178737178397
{
178738178398
yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0);
178739178399
}
178740
-#line 4891 "parse.sql"
178741178400
yymsp[0].minor.yy454 = yylhsminor.yy454;
178742178401
break;
178743178402
case 196: /* expr ::= LP nexprlist COMMA expr RP */
178744
-#line 1276 "parse.y"
178745178403
{
178746178404
ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454);
178747178405
yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
178748178406
if( yymsp[-4].minor.yy454 ){
178749178407
yymsp[-4].minor.yy454->x.pList = pList;
@@ -178752,35 +178410,27 @@
178752178410
}
178753178411
}else{
178754178412
sqlite3ExprListDelete(pParse->db, pList);
178755178413
}
178756178414
}
178757
-#line 4908 "parse.sql"
178758178415
break;
178759178416
case 197: /* expr ::= expr AND expr */
178760
-#line 1289 "parse.y"
178761178417
{yymsp[-2].minor.yy454=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);}
178762
-#line 4913 "parse.sql"
178763178418
break;
178764178419
case 198: /* expr ::= expr OR expr */
178765178420
case 199: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==199);
178766178421
case 200: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==200);
178767178422
case 201: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==201);
178768178423
case 202: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==202);
178769178424
case 203: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==203);
178770178425
case 204: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==204);
178771
-#line 1290 "parse.y"
178772178426
{yymsp[-2].minor.yy454=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);}
178773
-#line 4924 "parse.sql"
178774178427
break;
178775178428
case 205: /* likeop ::= NOT LIKE_KW|MATCH */
178776
-#line 1303 "parse.y"
178777178429
{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/}
178778
-#line 4929 "parse.sql"
178779178430
break;
178780178431
case 206: /* expr ::= expr likeop expr */
178781
-#line 1304 "parse.y"
178782178432
{
178783178433
ExprList *pList;
178784178434
int bNot = yymsp[-1].minor.yy0.n & 0x80000000;
178785178435
yymsp[-1].minor.yy0.n &= 0x7fffffff;
178786178436
pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy454);
@@ -178787,14 +178437,12 @@
178787178437
pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy454);
178788178438
yymsp[-2].minor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
178789178439
if( bNot ) yymsp[-2].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy454, 0);
178790178440
if( yymsp[-2].minor.yy454 ) yymsp[-2].minor.yy454->flags |= EP_InfixFunc;
178791178441
}
178792
-#line 4943 "parse.sql"
178793178442
break;
178794178443
case 207: /* expr ::= expr likeop expr ESCAPE expr */
178795
-#line 1314 "parse.y"
178796178444
{
178797178445
ExprList *pList;
178798178446
int bNot = yymsp[-3].minor.yy0.n & 0x80000000;
178799178447
yymsp[-3].minor.yy0.n &= 0x7fffffff;
178800178448
pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454);
@@ -178802,62 +178450,46 @@
178802178450
pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy454);
178803178451
yymsp[-4].minor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0);
178804178452
if( bNot ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
178805178453
if( yymsp[-4].minor.yy454 ) yymsp[-4].minor.yy454->flags |= EP_InfixFunc;
178806178454
}
178807
-#line 4958 "parse.sql"
178808178455
break;
178809178456
case 208: /* expr ::= expr ISNULL|NOTNULL */
178810
-#line 1326 "parse.y"
178811178457
{yymsp[-1].minor.yy454 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy454,0);}
178812
-#line 4963 "parse.sql"
178813178458
break;
178814178459
case 209: /* expr ::= expr NOT NULL */
178815
-#line 1327 "parse.y"
178816178460
{yymsp[-2].minor.yy454 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy454,0);}
178817
-#line 4968 "parse.sql"
178818178461
break;
178819178462
case 210: /* expr ::= expr IS expr */
178820
-#line 1348 "parse.y"
178821178463
{
178822178464
yymsp[-2].minor.yy454 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);
178823178465
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-2].minor.yy454, TK_ISNULL);
178824178466
}
178825
-#line 4976 "parse.sql"
178826178467
break;
178827178468
case 211: /* expr ::= expr IS NOT expr */
178828
-#line 1352 "parse.y"
178829178469
{
178830178470
yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy454,yymsp[0].minor.yy454);
178831178471
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-3].minor.yy454, TK_NOTNULL);
178832178472
}
178833
-#line 4984 "parse.sql"
178834178473
break;
178835178474
case 212: /* expr ::= expr IS NOT DISTINCT FROM expr */
178836
-#line 1356 "parse.y"
178837178475
{
178838178476
yymsp[-5].minor.yy454 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy454,yymsp[0].minor.yy454);
178839178477
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-5].minor.yy454, TK_ISNULL);
178840178478
}
178841
-#line 4992 "parse.sql"
178842178479
break;
178843178480
case 213: /* expr ::= expr IS DISTINCT FROM expr */
178844
-#line 1360 "parse.y"
178845178481
{
178846178482
yymsp[-4].minor.yy454 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy454,yymsp[0].minor.yy454);
178847178483
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-4].minor.yy454, TK_NOTNULL);
178848178484
}
178849
-#line 5000 "parse.sql"
178850178485
break;
178851178486
case 214: /* expr ::= NOT expr */
178852178487
case 215: /* expr ::= BITNOT expr */ yytestcase(yyruleno==215);
178853
-#line 1366 "parse.y"
178854178488
{yymsp[-1].minor.yy454 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy454, 0);/*A-overwrites-B*/}
178855
-#line 5006 "parse.sql"
178856178489
break;
178857178490
case 216: /* expr ::= PLUS|MINUS expr */
178858
-#line 1369 "parse.y"
178859178491
{
178860178492
Expr *p = yymsp[0].minor.yy454;
178861178493
u8 op = yymsp[-1].major + (TK_UPLUS-TK_PLUS);
178862178494
assert( TK_UPLUS>TK_PLUS );
178863178495
assert( TK_UMINUS == TK_MINUS + (TK_UPLUS - TK_PLUS) );
@@ -178867,30 +178499,24 @@
178867178499
}else{
178868178500
yymsp[-1].minor.yy454 = sqlite3PExpr(pParse, op, p, 0);
178869178501
/*A-overwrites-B*/
178870178502
}
178871178503
}
178872
-#line 5023 "parse.sql"
178873178504
break;
178874178505
case 217: /* expr ::= expr PTR expr */
178875
-#line 1383 "parse.y"
178876178506
{
178877178507
ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy454);
178878178508
pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy454);
178879178509
yylhsminor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
178880178510
}
178881
-#line 5032 "parse.sql"
178882178511
yymsp[-2].minor.yy454 = yylhsminor.yy454;
178883178512
break;
178884178513
case 218: /* between_op ::= BETWEEN */
178885178514
case 221: /* in_op ::= IN */ yytestcase(yyruleno==221);
178886
-#line 1390 "parse.y"
178887178515
{yymsp[0].minor.yy144 = 0;}
178888
-#line 5039 "parse.sql"
178889178516
break;
178890178517
case 220: /* expr ::= expr between_op expr AND expr */
178891
-#line 1392 "parse.y"
178892178518
{
178893178519
ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454);
178894178520
pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy454);
178895178521
yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy454, 0);
178896178522
if( yymsp[-4].minor.yy454 ){
@@ -178898,14 +178524,12 @@
178898178524
}else{
178899178525
sqlite3ExprListDelete(pParse->db, pList);
178900178526
}
178901178527
if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
178902178528
}
178903
-#line 5054 "parse.sql"
178904178529
break;
178905178530
case 223: /* expr ::= expr in_op LP exprlist RP */
178906
-#line 1407 "parse.y"
178907178531
{
178908178532
if( yymsp[-1].minor.yy14==0 ){
178909178533
/* Expressions of the form
178910178534
**
178911178535
** expr1 IN ()
@@ -178946,52 +178570,42 @@
178946178570
}
178947178571
}
178948178572
if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
178949178573
}
178950178574
}
178951
-#line 5102 "parse.sql"
178952178575
break;
178953178576
case 224: /* expr ::= LP select RP */
178954
-#line 1451 "parse.y"
178955178577
{
178956178578
yymsp[-2].minor.yy454 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
178957178579
sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy454, yymsp[-1].minor.yy555);
178958178580
}
178959
-#line 5110 "parse.sql"
178960178581
break;
178961178582
case 225: /* expr ::= expr in_op LP select RP */
178962
-#line 1455 "parse.y"
178963178583
{
178964178584
yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0);
178965178585
sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, yymsp[-1].minor.yy555);
178966178586
if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
178967178587
}
178968
-#line 5119 "parse.sql"
178969178588
break;
178970178589
case 226: /* expr ::= expr in_op nm dbnm paren_exprlist */
178971
-#line 1460 "parse.y"
178972178590
{
178973178591
SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
178974178592
Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0);
178975178593
if( yymsp[0].minor.yy14 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy14);
178976178594
yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0);
178977178595
sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pSelect);
178978178596
if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
178979178597
}
178980
-#line 5131 "parse.sql"
178981178598
break;
178982178599
case 227: /* expr ::= EXISTS LP select RP */
178983
-#line 1468 "parse.y"
178984178600
{
178985178601
Expr *p;
178986178602
p = yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
178987178603
sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy555);
178988178604
}
178989
-#line 5140 "parse.sql"
178990178605
break;
178991178606
case 228: /* expr ::= CASE case_operand case_exprlist case_else END */
178992
-#line 1476 "parse.y"
178993178607
{
178994178608
yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy454, 0);
178995178609
if( yymsp[-4].minor.yy454 ){
178996178610
yymsp[-4].minor.yy454->x.pList = yymsp[-1].minor.yy454 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454) : yymsp[-2].minor.yy14;
178997178611
sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy454);
@@ -178998,627 +178612,446 @@
178998178612
}else{
178999178613
sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy14);
179000178614
sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy454);
179001178615
}
179002178616
}
179003
-#line 5154 "parse.sql"
179004178617
break;
179005178618
case 229: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
179006
-#line 1488 "parse.y"
179007178619
{
179008178620
yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[-2].minor.yy454);
179009178621
yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[0].minor.yy454);
179010178622
}
179011
-#line 5162 "parse.sql"
179012178623
break;
179013178624
case 230: /* case_exprlist ::= WHEN expr THEN expr */
179014
-#line 1492 "parse.y"
179015178625
{
179016178626
yymsp[-3].minor.yy14 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454);
179017178627
yymsp[-3].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14, yymsp[0].minor.yy454);
179018178628
}
179019
-#line 5170 "parse.sql"
179020178629
break;
179021178630
case 235: /* nexprlist ::= nexprlist COMMA expr */
179022
-#line 1513 "parse.y"
179023178631
{yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[0].minor.yy454);}
179024
-#line 5175 "parse.sql"
179025178632
break;
179026178633
case 236: /* nexprlist ::= expr */
179027
-#line 1515 "parse.y"
179028178634
{yymsp[0].minor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy454); /*A-overwrites-Y*/}
179029
-#line 5180 "parse.sql"
179030178635
break;
179031178636
case 238: /* paren_exprlist ::= LP exprlist RP */
179032178637
case 243: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==243);
179033
-#line 1523 "parse.y"
179034178638
{yymsp[-2].minor.yy14 = yymsp[-1].minor.yy14;}
179035
-#line 5186 "parse.sql"
179036178639
break;
179037178640
case 239: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
179038
-#line 1530 "parse.y"
179039178641
{
179040178642
sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
179041178643
sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy14, yymsp[-10].minor.yy144,
179042178644
&yymsp[-11].minor.yy0, yymsp[0].minor.yy454, SQLITE_SO_ASC, yymsp[-8].minor.yy144, SQLITE_IDXTYPE_APPDEF);
179043178645
if( IN_RENAME_OBJECT && pParse->pNewIndex ){
179044178646
sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0);
179045178647
}
179046178648
}
179047
-#line 5198 "parse.sql"
179048178649
break;
179049178650
case 240: /* uniqueflag ::= UNIQUE */
179050178651
case 282: /* raisetype ::= ABORT */ yytestcase(yyruleno==282);
179051
-#line 1540 "parse.y"
179052178652
{yymsp[0].minor.yy144 = OE_Abort;}
179053
-#line 5204 "parse.sql"
179054178653
break;
179055178654
case 241: /* uniqueflag ::= */
179056
-#line 1541 "parse.y"
179057178655
{yymsp[1].minor.yy144 = OE_None;}
179058
-#line 5209 "parse.sql"
179059178656
break;
179060178657
case 244: /* eidlist ::= eidlist COMMA nm collate sortorder */
179061
-#line 1591 "parse.y"
179062178658
{
179063178659
yymsp[-4].minor.yy14 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy14, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy144, yymsp[0].minor.yy144);
179064178660
}
179065
-#line 5216 "parse.sql"
179066178661
break;
179067178662
case 245: /* eidlist ::= nm collate sortorder */
179068
-#line 1594 "parse.y"
179069178663
{
179070178664
yymsp[-2].minor.yy14 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy144, yymsp[0].minor.yy144); /*A-overwrites-Y*/
179071178665
}
179072
-#line 5223 "parse.sql"
179073178666
break;
179074178667
case 248: /* cmd ::= DROP INDEX ifexists fullname */
179075
-#line 1605 "parse.y"
179076178668
{sqlite3DropIndex(pParse, yymsp[0].minor.yy203, yymsp[-1].minor.yy144);}
179077
-#line 5228 "parse.sql"
179078178669
break;
179079178670
case 249: /* cmd ::= VACUUM vinto */
179080
-#line 1612 "parse.y"
179081178671
{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy454);}
179082
-#line 5233 "parse.sql"
179083178672
break;
179084178673
case 250: /* cmd ::= VACUUM nm vinto */
179085
-#line 1613 "parse.y"
179086178674
{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy454);}
179087
-#line 5238 "parse.sql"
179088178675
break;
179089178676
case 253: /* cmd ::= PRAGMA nm dbnm */
179090
-#line 1621 "parse.y"
179091178677
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
179092
-#line 5243 "parse.sql"
179093178678
break;
179094178679
case 254: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
179095
-#line 1622 "parse.y"
179096178680
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
179097
-#line 5248 "parse.sql"
179098178681
break;
179099178682
case 255: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
179100
-#line 1623 "parse.y"
179101178683
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
179102
-#line 5253 "parse.sql"
179103178684
break;
179104178685
case 256: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
179105
-#line 1625 "parse.y"
179106178686
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
179107
-#line 5258 "parse.sql"
179108178687
break;
179109178688
case 257: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
179110
-#line 1627 "parse.y"
179111178689
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
179112
-#line 5263 "parse.sql"
179113178690
break;
179114178691
case 260: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
179115
-#line 1643 "parse.y"
179116178692
{
179117178693
Token all;
179118178694
all.z = yymsp[-3].minor.yy0.z;
179119178695
all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
179120178696
sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy427, &all);
179121178697
}
179122
-#line 5273 "parse.sql"
179123178698
break;
179124178699
case 261: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
179125
-#line 1652 "parse.y"
179126178700
{
179127178701
sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy144, yymsp[-4].minor.yy286.a, yymsp[-4].minor.yy286.b, yymsp[-2].minor.yy203, yymsp[0].minor.yy454, yymsp[-10].minor.yy144, yymsp[-8].minor.yy144);
179128178702
yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
179129178703
}
179130
-#line 5281 "parse.sql"
179131178704
break;
179132178705
case 262: /* trigger_time ::= BEFORE|AFTER */
179133
-#line 1658 "parse.y"
179134178706
{ yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-X*/ }
179135
-#line 5286 "parse.sql"
179136178707
break;
179137178708
case 263: /* trigger_time ::= INSTEAD OF */
179138
-#line 1659 "parse.y"
179139178709
{ yymsp[-1].minor.yy144 = TK_INSTEAD;}
179140
-#line 5291 "parse.sql"
179141178710
break;
179142178711
case 264: /* trigger_time ::= */
179143
-#line 1660 "parse.y"
179144178712
{ yymsp[1].minor.yy144 = TK_BEFORE; }
179145
-#line 5296 "parse.sql"
179146178713
break;
179147178714
case 265: /* trigger_event ::= DELETE|INSERT */
179148178715
case 266: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==266);
179149
-#line 1664 "parse.y"
179150178716
{yymsp[0].minor.yy286.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy286.b = 0;}
179151
-#line 5302 "parse.sql"
179152178717
break;
179153178718
case 267: /* trigger_event ::= UPDATE OF idlist */
179154
-#line 1666 "parse.y"
179155178719
{yymsp[-2].minor.yy286.a = TK_UPDATE; yymsp[-2].minor.yy286.b = yymsp[0].minor.yy132;}
179156
-#line 5307 "parse.sql"
179157178720
break;
179158178721
case 268: /* when_clause ::= */
179159178722
case 287: /* key_opt ::= */ yytestcase(yyruleno==287);
179160
-#line 1673 "parse.y"
179161178723
{ yymsp[1].minor.yy454 = 0; }
179162
-#line 5313 "parse.sql"
179163178724
break;
179164178725
case 269: /* when_clause ::= WHEN expr */
179165178726
case 288: /* key_opt ::= KEY expr */ yytestcase(yyruleno==288);
179166
-#line 1674 "parse.y"
179167178727
{ yymsp[-1].minor.yy454 = yymsp[0].minor.yy454; }
179168
-#line 5319 "parse.sql"
179169178728
break;
179170178729
case 270: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
179171
-#line 1678 "parse.y"
179172178730
{
179173178731
assert( yymsp[-2].minor.yy427!=0 );
179174178732
yymsp[-2].minor.yy427->pLast->pNext = yymsp[-1].minor.yy427;
179175178733
yymsp[-2].minor.yy427->pLast = yymsp[-1].minor.yy427;
179176178734
}
179177
-#line 5328 "parse.sql"
179178178735
break;
179179178736
case 271: /* trigger_cmd_list ::= trigger_cmd SEMI */
179180
-#line 1683 "parse.y"
179181178737
{
179182178738
assert( yymsp[-1].minor.yy427!=0 );
179183178739
yymsp[-1].minor.yy427->pLast = yymsp[-1].minor.yy427;
179184178740
}
179185
-#line 5336 "parse.sql"
179186178741
break;
179187178742
case 272: /* trnm ::= nm DOT nm */
179188
-#line 1694 "parse.y"
179189178743
{
179190178744
yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
179191178745
sqlite3ErrorMsg(pParse,
179192178746
"qualified table names are not allowed on INSERT, UPDATE, and DELETE "
179193178747
"statements within triggers");
179194178748
}
179195
-#line 5346 "parse.sql"
179196178749
break;
179197178750
case 273: /* tridxby ::= INDEXED BY nm */
179198
-#line 1706 "parse.y"
179199178751
{
179200178752
sqlite3ErrorMsg(pParse,
179201178753
"the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
179202178754
"within triggers");
179203178755
}
179204
-#line 5355 "parse.sql"
179205178756
break;
179206178757
case 274: /* tridxby ::= NOT INDEXED */
179207
-#line 1711 "parse.y"
179208178758
{
179209178759
sqlite3ErrorMsg(pParse,
179210178760
"the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
179211178761
"within triggers");
179212178762
}
179213
-#line 5364 "parse.sql"
179214178763
break;
179215178764
case 275: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
179216
-#line 1724 "parse.y"
179217178765
{yylhsminor.yy427 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy203, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454, yymsp[-7].minor.yy144, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy168);}
179218
-#line 5369 "parse.sql"
179219178766
yymsp[-8].minor.yy427 = yylhsminor.yy427;
179220178767
break;
179221178768
case 276: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
179222
-#line 1728 "parse.y"
179223178769
{
179224178770
yylhsminor.yy427 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy132,yymsp[-2].minor.yy555,yymsp[-6].minor.yy144,yymsp[-1].minor.yy122,yymsp[-7].minor.yy168,yymsp[0].minor.yy168);/*yylhsminor.yy427-overwrites-yymsp[-6].minor.yy144*/
179225178771
}
179226
-#line 5377 "parse.sql"
179227178772
yymsp[-7].minor.yy427 = yylhsminor.yy427;
179228178773
break;
179229178774
case 277: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
179230
-#line 1733 "parse.y"
179231178775
{yylhsminor.yy427 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy454, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy168);}
179232
-#line 5383 "parse.sql"
179233178776
yymsp[-5].minor.yy427 = yylhsminor.yy427;
179234178777
break;
179235178778
case 278: /* trigger_cmd ::= scanpt select scanpt */
179236
-#line 1737 "parse.y"
179237178779
{yylhsminor.yy427 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy555, yymsp[-2].minor.yy168, yymsp[0].minor.yy168); /*yylhsminor.yy427-overwrites-yymsp[-1].minor.yy555*/}
179238
-#line 5389 "parse.sql"
179239178780
yymsp[-2].minor.yy427 = yylhsminor.yy427;
179240178781
break;
179241178782
case 279: /* expr ::= RAISE LP IGNORE RP */
179242
-#line 1740 "parse.y"
179243178783
{
179244178784
yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
179245178785
if( yymsp[-3].minor.yy454 ){
179246178786
yymsp[-3].minor.yy454->affExpr = OE_Ignore;
179247178787
}
179248178788
}
179249
-#line 5400 "parse.sql"
179250178789
break;
179251178790
case 280: /* expr ::= RAISE LP raisetype COMMA expr RP */
179252
-#line 1746 "parse.y"
179253178791
{
179254178792
yymsp[-5].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, yymsp[-1].minor.yy454, 0);
179255178793
if( yymsp[-5].minor.yy454 ) {
179256178794
yymsp[-5].minor.yy454->affExpr = (char)yymsp[-3].minor.yy144;
179257178795
}
179258178796
}
179259
-#line 5410 "parse.sql"
179260178797
break;
179261178798
case 281: /* raisetype ::= ROLLBACK */
179262
-#line 1755 "parse.y"
179263178799
{yymsp[0].minor.yy144 = OE_Rollback;}
179264
-#line 5415 "parse.sql"
179265178800
break;
179266178801
case 283: /* raisetype ::= FAIL */
179267
-#line 1757 "parse.y"
179268178802
{yymsp[0].minor.yy144 = OE_Fail;}
179269
-#line 5420 "parse.sql"
179270178803
break;
179271178804
case 284: /* cmd ::= DROP TRIGGER ifexists fullname */
179272
-#line 1762 "parse.y"
179273178805
{
179274178806
sqlite3DropTrigger(pParse,yymsp[0].minor.yy203,yymsp[-1].minor.yy144);
179275178807
}
179276
-#line 5427 "parse.sql"
179277178808
break;
179278178809
case 285: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
179279
-#line 1769 "parse.y"
179280178810
{
179281178811
sqlite3Attach(pParse, yymsp[-3].minor.yy454, yymsp[-1].minor.yy454, yymsp[0].minor.yy454);
179282178812
}
179283
-#line 5434 "parse.sql"
179284178813
break;
179285178814
case 286: /* cmd ::= DETACH database_kw_opt expr */
179286
-#line 1772 "parse.y"
179287178815
{
179288178816
sqlite3Detach(pParse, yymsp[0].minor.yy454);
179289178817
}
179290
-#line 5441 "parse.sql"
179291178818
break;
179292178819
case 289: /* cmd ::= REINDEX */
179293
-#line 1787 "parse.y"
179294178820
{sqlite3Reindex(pParse, 0, 0);}
179295
-#line 5446 "parse.sql"
179296178821
break;
179297178822
case 290: /* cmd ::= REINDEX nm dbnm */
179298
-#line 1788 "parse.y"
179299178823
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
179300
-#line 5451 "parse.sql"
179301178824
break;
179302178825
case 291: /* cmd ::= ANALYZE */
179303
-#line 1793 "parse.y"
179304178826
{sqlite3Analyze(pParse, 0, 0);}
179305
-#line 5456 "parse.sql"
179306178827
break;
179307178828
case 292: /* cmd ::= ANALYZE nm dbnm */
179308
-#line 1794 "parse.y"
179309178829
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
179310
-#line 5461 "parse.sql"
179311178830
break;
179312178831
case 293: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
179313
-#line 1800 "parse.y"
179314178832
{
179315178833
sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy203,&yymsp[0].minor.yy0);
179316178834
}
179317
-#line 5468 "parse.sql"
179318178835
break;
179319178836
case 294: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
179320
-#line 1804 "parse.y"
179321178837
{
179322178838
yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
179323178839
sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0);
179324178840
}
179325
-#line 5476 "parse.sql"
179326178841
break;
179327178842
case 295: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
179328
-#line 1808 "parse.y"
179329178843
{
179330178844
sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy203, &yymsp[0].minor.yy0);
179331178845
}
179332
-#line 5483 "parse.sql"
179333178846
break;
179334178847
case 296: /* add_column_fullname ::= fullname */
179335
-#line 1812 "parse.y"
179336178848
{
179337178849
disableLookaside(pParse);
179338178850
sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy203);
179339178851
}
179340
-#line 5491 "parse.sql"
179341178852
break;
179342178853
case 297: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
179343
-#line 1816 "parse.y"
179344178854
{
179345178855
sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy203, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
179346178856
}
179347
-#line 5498 "parse.sql"
179348178857
break;
179349178858
case 298: /* cmd ::= create_vtab */
179350
-#line 1828 "parse.y"
179351178859
{sqlite3VtabFinishParse(pParse,0);}
179352
-#line 5503 "parse.sql"
179353178860
break;
179354178861
case 299: /* cmd ::= create_vtab LP vtabarglist RP */
179355
-#line 1829 "parse.y"
179356178862
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
179357
-#line 5508 "parse.sql"
179358178863
break;
179359178864
case 300: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
179360
-#line 1831 "parse.y"
179361178865
{
179362178866
sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy144);
179363178867
}
179364
-#line 5515 "parse.sql"
179365178868
break;
179366178869
case 301: /* vtabarg ::= */
179367
-#line 1836 "parse.y"
179368178870
{sqlite3VtabArgInit(pParse);}
179369
-#line 5520 "parse.sql"
179370178871
break;
179371178872
case 302: /* vtabargtoken ::= ANY */
179372178873
case 303: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==303);
179373178874
case 304: /* lp ::= LP */ yytestcase(yyruleno==304);
179374
-#line 1838 "parse.y"
179375178875
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
179376
-#line 5527 "parse.sql"
179377178876
break;
179378178877
case 305: /* with ::= WITH wqlist */
179379178878
case 306: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==306);
179380
-#line 1855 "parse.y"
179381178879
{ sqlite3WithPush(pParse, yymsp[0].minor.yy59, 1); }
179382
-#line 5533 "parse.sql"
179383178880
break;
179384178881
case 307: /* wqas ::= AS */
179385
-#line 1859 "parse.y"
179386178882
{yymsp[0].minor.yy462 = M10d_Any;}
179387
-#line 5538 "parse.sql"
179388178883
break;
179389178884
case 308: /* wqas ::= AS MATERIALIZED */
179390
-#line 1860 "parse.y"
179391178885
{yymsp[-1].minor.yy462 = M10d_Yes;}
179392
-#line 5543 "parse.sql"
179393178886
break;
179394178887
case 309: /* wqas ::= AS NOT MATERIALIZED */
179395
-#line 1861 "parse.y"
179396178888
{yymsp[-2].minor.yy462 = M10d_No;}
179397
-#line 5548 "parse.sql"
179398178889
break;
179399178890
case 310: /* wqitem ::= withnm eidlist_opt wqas LP select RP */
179400
-#line 1862 "parse.y"
179401178891
{
179402178892
yymsp[-5].minor.yy67 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy14, yymsp[-1].minor.yy555, yymsp[-3].minor.yy462); /*A-overwrites-X*/
179403178893
}
179404
-#line 5555 "parse.sql"
179405178894
break;
179406178895
case 311: /* withnm ::= nm */
179407
-#line 1865 "parse.y"
179408178896
{pParse->bHasWith = 1;}
179409
-#line 5560 "parse.sql"
179410178897
break;
179411178898
case 312: /* wqlist ::= wqitem */
179412
-#line 1866 "parse.y"
179413178899
{
179414178900
yymsp[0].minor.yy59 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy67); /*A-overwrites-X*/
179415178901
}
179416
-#line 5567 "parse.sql"
179417178902
break;
179418178903
case 313: /* wqlist ::= wqlist COMMA wqitem */
179419
-#line 1869 "parse.y"
179420178904
{
179421178905
yymsp[-2].minor.yy59 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy59, yymsp[0].minor.yy67);
179422178906
}
179423
-#line 5574 "parse.sql"
179424178907
break;
179425178908
case 314: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
179426
-#line 1884 "parse.y"
179427178909
{
179428178910
assert( yymsp[0].minor.yy211!=0 );
179429178911
sqlite3WindowChain(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy211);
179430178912
yymsp[0].minor.yy211->pNextWin = yymsp[-2].minor.yy211;
179431178913
yylhsminor.yy211 = yymsp[0].minor.yy211;
179432178914
}
179433
-#line 5584 "parse.sql"
179434178915
yymsp[-2].minor.yy211 = yylhsminor.yy211;
179435178916
break;
179436178917
case 315: /* windowdefn ::= nm AS LP window RP */
179437
-#line 1893 "parse.y"
179438178918
{
179439178919
if( ALWAYS(yymsp[-1].minor.yy211) ){
179440178920
yymsp[-1].minor.yy211->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n);
179441178921
}
179442178922
yylhsminor.yy211 = yymsp[-1].minor.yy211;
179443178923
}
179444
-#line 5595 "parse.sql"
179445178924
yymsp[-4].minor.yy211 = yylhsminor.yy211;
179446178925
break;
179447178926
case 316: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */
179448
-#line 1927 "parse.y"
179449178927
{
179450178928
yymsp[-4].minor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy14, yymsp[-1].minor.yy14, 0);
179451178929
}
179452
-#line 5603 "parse.sql"
179453178930
break;
179454178931
case 317: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
179455
-#line 1930 "parse.y"
179456178932
{
179457178933
yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy14, yymsp[-1].minor.yy14, &yymsp[-5].minor.yy0);
179458178934
}
179459
-#line 5610 "parse.sql"
179460178935
yymsp[-5].minor.yy211 = yylhsminor.yy211;
179461178936
break;
179462178937
case 318: /* window ::= ORDER BY sortlist frame_opt */
179463
-#line 1933 "parse.y"
179464178938
{
179465178939
yymsp[-3].minor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, yymsp[-1].minor.yy14, 0);
179466178940
}
179467
-#line 5618 "parse.sql"
179468178941
break;
179469178942
case 319: /* window ::= nm ORDER BY sortlist frame_opt */
179470
-#line 1936 "parse.y"
179471178943
{
179472178944
yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0);
179473178945
}
179474
-#line 5625 "parse.sql"
179475178946
yymsp[-4].minor.yy211 = yylhsminor.yy211;
179476178947
break;
179477178948
case 320: /* window ::= nm frame_opt */
179478
-#line 1940 "parse.y"
179479178949
{
179480178950
yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, 0, &yymsp[-1].minor.yy0);
179481178951
}
179482
-#line 5633 "parse.sql"
179483178952
yymsp[-1].minor.yy211 = yylhsminor.yy211;
179484178953
break;
179485178954
case 321: /* frame_opt ::= */
179486
-#line 1944 "parse.y"
179487178955
{
179488178956
yymsp[1].minor.yy211 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
179489178957
}
179490
-#line 5641 "parse.sql"
179491178958
break;
179492178959
case 322: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
179493
-#line 1947 "parse.y"
179494178960
{
179495178961
yylhsminor.yy211 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy144, yymsp[-1].minor.yy509.eType, yymsp[-1].minor.yy509.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy462);
179496178962
}
179497
-#line 5648 "parse.sql"
179498178963
yymsp[-2].minor.yy211 = yylhsminor.yy211;
179499178964
break;
179500178965
case 323: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
179501
-#line 1951 "parse.y"
179502178966
{
179503178967
yylhsminor.yy211 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy144, yymsp[-3].minor.yy509.eType, yymsp[-3].minor.yy509.pExpr, yymsp[-1].minor.yy509.eType, yymsp[-1].minor.yy509.pExpr, yymsp[0].minor.yy462);
179504178968
}
179505
-#line 5656 "parse.sql"
179506178969
yymsp[-5].minor.yy211 = yylhsminor.yy211;
179507178970
break;
179508178971
case 325: /* frame_bound_s ::= frame_bound */
179509178972
case 327: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==327);
179510
-#line 1957 "parse.y"
179511178973
{yylhsminor.yy509 = yymsp[0].minor.yy509;}
179512
-#line 5663 "parse.sql"
179513178974
yymsp[0].minor.yy509 = yylhsminor.yy509;
179514178975
break;
179515178976
case 326: /* frame_bound_s ::= UNBOUNDED PRECEDING */
179516178977
case 328: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==328);
179517178978
case 330: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==330);
179518
-#line 1958 "parse.y"
179519178979
{yylhsminor.yy509.eType = yymsp[-1].major; yylhsminor.yy509.pExpr = 0;}
179520
-#line 5671 "parse.sql"
179521178980
yymsp[-1].minor.yy509 = yylhsminor.yy509;
179522178981
break;
179523178982
case 329: /* frame_bound ::= expr PRECEDING|FOLLOWING */
179524
-#line 1963 "parse.y"
179525178983
{yylhsminor.yy509.eType = yymsp[0].major; yylhsminor.yy509.pExpr = yymsp[-1].minor.yy454;}
179526
-#line 5677 "parse.sql"
179527178984
yymsp[-1].minor.yy509 = yylhsminor.yy509;
179528178985
break;
179529178986
case 331: /* frame_exclude_opt ::= */
179530
-#line 1967 "parse.y"
179531178987
{yymsp[1].minor.yy462 = 0;}
179532
-#line 5683 "parse.sql"
179533178988
break;
179534178989
case 332: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
179535
-#line 1968 "parse.y"
179536178990
{yymsp[-1].minor.yy462 = yymsp[0].minor.yy462;}
179537
-#line 5688 "parse.sql"
179538178991
break;
179539178992
case 333: /* frame_exclude ::= NO OTHERS */
179540178993
case 334: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==334);
179541
-#line 1971 "parse.y"
179542178994
{yymsp[-1].minor.yy462 = yymsp[-1].major; /*A-overwrites-X*/}
179543
-#line 5694 "parse.sql"
179544178995
break;
179545178996
case 335: /* frame_exclude ::= GROUP|TIES */
179546
-#line 1973 "parse.y"
179547178997
{yymsp[0].minor.yy462 = yymsp[0].major; /*A-overwrites-X*/}
179548
-#line 5699 "parse.sql"
179549178998
break;
179550178999
case 336: /* window_clause ::= WINDOW windowdefn_list */
179551
-#line 1978 "parse.y"
179552179000
{ yymsp[-1].minor.yy211 = yymsp[0].minor.yy211; }
179553
-#line 5704 "parse.sql"
179554179001
break;
179555179002
case 337: /* filter_over ::= filter_clause over_clause */
179556
-#line 1980 "parse.y"
179557179003
{
179558179004
if( yymsp[0].minor.yy211 ){
179559179005
yymsp[0].minor.yy211->pFilter = yymsp[-1].minor.yy454;
179560179006
}else{
179561179007
sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy454);
179562179008
}
179563179009
yylhsminor.yy211 = yymsp[0].minor.yy211;
179564179010
}
179565
-#line 5716 "parse.sql"
179566179011
yymsp[-1].minor.yy211 = yylhsminor.yy211;
179567179012
break;
179568179013
case 338: /* filter_over ::= over_clause */
179569
-#line 1988 "parse.y"
179570179014
{
179571179015
yylhsminor.yy211 = yymsp[0].minor.yy211;
179572179016
}
179573
-#line 5724 "parse.sql"
179574179017
yymsp[0].minor.yy211 = yylhsminor.yy211;
179575179018
break;
179576179019
case 339: /* filter_over ::= filter_clause */
179577
-#line 1991 "parse.y"
179578179020
{
179579179021
yylhsminor.yy211 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
179580179022
if( yylhsminor.yy211 ){
179581179023
yylhsminor.yy211->eFrmType = TK_FILTER;
179582179024
yylhsminor.yy211->pFilter = yymsp[0].minor.yy454;
179583179025
}else{
179584179026
sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy454);
179585179027
}
179586179028
}
179587
-#line 5738 "parse.sql"
179588179029
yymsp[0].minor.yy211 = yylhsminor.yy211;
179589179030
break;
179590179031
case 340: /* over_clause ::= OVER LP window RP */
179591
-#line 2001 "parse.y"
179592179032
{
179593179033
yymsp[-3].minor.yy211 = yymsp[-1].minor.yy211;
179594179034
assert( yymsp[-3].minor.yy211!=0 );
179595179035
}
179596
-#line 5747 "parse.sql"
179597179036
break;
179598179037
case 341: /* over_clause ::= OVER nm */
179599
-#line 2005 "parse.y"
179600179038
{
179601179039
yymsp[-1].minor.yy211 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
179602179040
if( yymsp[-1].minor.yy211 ){
179603179041
yymsp[-1].minor.yy211->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
179604179042
}
179605179043
}
179606
-#line 5757 "parse.sql"
179607179044
break;
179608179045
case 342: /* filter_clause ::= FILTER LP WHERE expr RP */
179609
-#line 2012 "parse.y"
179610179046
{ yymsp[-4].minor.yy454 = yymsp[-1].minor.yy454; }
179611
-#line 5762 "parse.sql"
179612179047
break;
179613179048
case 343: /* term ::= QNUMBER */
179614
-#line 2038 "parse.y"
179615179049
{
179616179050
yylhsminor.yy454=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0);
179617179051
sqlite3DequoteNumber(pParse, yylhsminor.yy454);
179618179052
}
179619
-#line 5770 "parse.sql"
179620179053
yymsp[0].minor.yy454 = yylhsminor.yy454;
179621179054
break;
179622179055
default:
179623179056
/* (344) input ::= cmdlist */ yytestcase(yyruleno==344);
179624179057
/* (345) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==345);
@@ -179742,19 +179175,17 @@
179742179175
){
179743179176
sqlite3ParserARG_FETCH
179744179177
sqlite3ParserCTX_FETCH
179745179178
#define TOKEN yyminor
179746179179
/************ Begin %syntax_error code ****************************************/
179747
-#line 43 "parse.y"
179748179180
179749179181
UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */
179750179182
if( TOKEN.z[0] ){
179751
- sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
179183
+ parserSyntaxError(pParse, &TOKEN);
179752179184
}else{
179753179185
sqlite3ErrorMsg(pParse, "incomplete input");
179754179186
}
179755
-#line 5906 "parse.sql"
179756179187
/************ End %syntax_error code ******************************************/
179757179188
sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
179758179189
sqlite3ParserCTX_STORE
179759179190
}
179760179191
@@ -180022,11 +179453,10 @@
180022179453
#endif
180023179454
}
180024179455
180025179456
/************** End of parse.c ***********************************************/
180026179457
/************** Begin file tokenize.c ****************************************/
180027
-#line 1 "tsrc/tokenize.c"
180028179458
/*
180029179459
** 2001 September 15
180030179460
**
180031179461
** The author disclaims copyright to this source code. In place of
180032179462
** a legal notice, here is a blessing:
@@ -180172,11 +179602,10 @@
180172179602
** named keywordhash.h and then included into this source file by
180173179603
** the #include below.
180174179604
*/
180175179605
/************** Include keywordhash.h in the middle of tokenize.c ************/
180176179606
/************** Begin file keywordhash.h *************************************/
180177
-#line 1 "tsrc/keywordhash.h"
180178179607
/***** This file contains automatically generated code ******
180179179608
**
180180179609
** The code in this file has been automatically generated by
180181179610
**
180182179611
** sqlite/tool/mkkeywordhash.c
@@ -180658,11 +180087,10 @@
180658180087
return TK_ID!=sqlite3KeywordCode((const u8*)zName, nName);
180659180088
}
180660180089
180661180090
/************** End of keywordhash.h *****************************************/
180662180091
/************** Continuing where we left off in tokenize.c *******************/
180663
-#line 149 "tsrc/tokenize.c"
180664180092
180665180093
180666180094
/*
180667180095
** If X is a character that can be used in an identifier then
180668180096
** IdChar(X) will be true. Otherwise it is false.
@@ -181241,11 +180669,13 @@
181241180669
}
181242180670
if( pParse->zErrMsg || (pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE) ){
181243180671
if( pParse->zErrMsg==0 ){
181244180672
pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc));
181245180673
}
181246
- sqlite3_log(pParse->rc, "%s in \"%s\"", pParse->zErrMsg, pParse->zTail);
180674
+ if( (pParse->prepFlags & SQLITE_PREPARE_DONT_LOG)==0 ){
180675
+ sqlite3_log(pParse->rc, "%s in \"%s\"", pParse->zErrMsg, pParse->zTail);
180676
+ }
181247180677
nErr++;
181248180678
}
181249180679
pParse->zTail = zSql;
181250180680
#ifndef SQLITE_OMIT_VIRTUALTABLE
181251180681
sqlite3_free(pParse->apVtabLock);
@@ -181402,11 +180832,10 @@
181402180832
}
181403180833
#endif /* SQLITE_ENABLE_NORMALIZE */
181404180834
181405180835
/************** End of tokenize.c ********************************************/
181406180836
/************** Begin file complete.c ****************************************/
181407
-#line 1 "tsrc/complete.c"
181408180837
/*
181409180838
** 2001 September 15
181410180839
**
181411180840
** The author disclaims copyright to this source code. In place of
181412180841
** a legal notice, here is a blessing:
@@ -181696,11 +181125,10 @@
181696181125
#endif /* SQLITE_OMIT_UTF16 */
181697181126
#endif /* SQLITE_OMIT_COMPLETE */
181698181127
181699181128
/************** End of complete.c ********************************************/
181700181129
/************** Begin file main.c ********************************************/
181701
-#line 1 "tsrc/main.c"
181702181130
/*
181703181131
** 2001 September 15
181704181132
**
181705181133
** The author disclaims copyright to this source code. In place of
181706181134
** a legal notice, here is a blessing:
@@ -181718,11 +181146,10 @@
181718181146
/* #include "sqliteInt.h" */
181719181147
181720181148
#ifdef SQLITE_ENABLE_FTS3
181721181149
/************** Include fts3.h in the middle of main.c ***********************/
181722181150
/************** Begin file fts3.h ********************************************/
181723
-#line 1 "tsrc/fts3.h"
181724181151
/*
181725181152
** 2006 Oct 10
181726181153
**
181727181154
** The author disclaims copyright to this source code. In place of
181728181155
** a legal notice, here is a blessing:
@@ -181748,16 +181175,14 @@
181748181175
} /* extern "C" */
181749181176
#endif /* __cplusplus */
181750181177
181751181178
/************** End of fts3.h ************************************************/
181752181179
/************** Continuing where we left off in main.c ***********************/
181753
-#line 21 "tsrc/main.c"
181754181180
#endif
181755181181
#ifdef SQLITE_ENABLE_RTREE
181756181182
/************** Include rtree.h in the middle of main.c **********************/
181757181183
/************** Begin file rtree.h *******************************************/
181758
-#line 1 "tsrc/rtree.h"
181759181184
/*
181760181185
** 2008 May 26
181761181186
**
181762181187
** The author disclaims copyright to this source code. In place of
181763181188
** a legal notice, here is a blessing:
@@ -181787,16 +181212,14 @@
181787181212
} /* extern "C" */
181788181213
#endif /* __cplusplus */
181789181214
181790181215
/************** End of rtree.h ***********************************************/
181791181216
/************** Continuing where we left off in main.c ***********************/
181792
-#line 24 "tsrc/main.c"
181793181217
#endif
181794181218
#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
181795181219
/************** Include sqliteicu.h in the middle of main.c ******************/
181796181220
/************** Begin file sqliteicu.h ***************************************/
181797
-#line 1 "tsrc/sqliteicu.h"
181798181221
/*
181799181222
** 2008 May 26
181800181223
**
181801181224
** The author disclaims copyright to this source code. In place of
181802181225
** a legal notice, here is a blessing:
@@ -181822,11 +181245,10 @@
181822181245
} /* extern "C" */
181823181246
#endif /* __cplusplus */
181824181247
181825181248
/************** End of sqliteicu.h *******************************************/
181826181249
/************** Continuing where we left off in main.c ***********************/
181827
-#line 27 "tsrc/main.c"
181828181250
#endif
181829181251
181830181252
/*
181831181253
** This is an extension initializer that is a no-op and always
181832181254
** succeeds, except that it fails if the fault-simulation is set
@@ -184724,12 +184146,12 @@
184724184146
}
184725184147
oldLimit = db->aLimit[limitId];
184726184148
if( newLimit>=0 ){ /* IMP: R-52476-28732 */
184727184149
if( newLimit>aHardLimit[limitId] ){
184728184150
newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */
184729
- }else if( newLimit<1 && limitId==SQLITE_LIMIT_LENGTH ){
184730
- newLimit = 1;
184151
+ }else if( newLimit<SQLITE_MIN_LENGTH && limitId==SQLITE_LIMIT_LENGTH ){
184152
+ newLimit = SQLITE_MIN_LENGTH;
184731184153
}
184732184154
db->aLimit[limitId] = newLimit;
184733184155
}
184734184156
return oldLimit; /* IMP: R-53341-35419 */
184735184157
}
@@ -186087,10 +185509,11 @@
186087185509
#ifndef SQLITE_OMIT_WINDOWFUNC
186088185510
sqlite3ShowWindow(0);
186089185511
sqlite3ShowWinFunc(0);
186090185512
#endif
186091185513
sqlite3ShowSelect(0);
185514
+ sqlite3ShowWhereTerm(0);
186092185515
}
186093185516
#endif
186094185517
break;
186095185518
}
186096185519
@@ -186873,11 +186296,10 @@
186873186296
}
186874186297
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
186875186298
186876186299
/************** End of main.c ************************************************/
186877186300
/************** Begin file notify.c ******************************************/
186878
-#line 1 "tsrc/notify.c"
186879186301
/*
186880186302
** 2009 March 3
186881186303
**
186882186304
** The author disclaims copyright to this source code. In place of
186883186305
** a legal notice, here is a blessing:
@@ -187212,11 +186634,10 @@
187212186634
}
187213186635
#endif
187214186636
187215186637
/************** End of notify.c **********************************************/
187216186638
/************** Begin file fts3.c ********************************************/
187217
-#line 1 "tsrc/fts3.c"
187218186639
/*
187219186640
** 2006 Oct 10
187220186641
**
187221186642
** The author disclaims copyright to this source code. In place of
187222186643
** a legal notice, here is a blessing:
@@ -187505,11 +186926,10 @@
187505186926
** older data.
187506186927
*/
187507186928
187508186929
/************** Include fts3Int.h in the middle of fts3.c ********************/
187509186930
/************** Begin file fts3Int.h *****************************************/
187510
-#line 1 "tsrc/fts3Int.h"
187511186931
/*
187512186932
** 2009 Nov 12
187513186933
**
187514186934
** The author disclaims copyright to this source code. In place of
187515186935
** a legal notice, here is a blessing:
@@ -187552,11 +186972,10 @@
187552186972
#endif
187553186973
187554186974
/* #include "sqlite3.h" */
187555186975
/************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/
187556186976
/************** Begin file fts3_tokenizer.h **********************************/
187557
-#line 1 "tsrc/fts3_tokenizer.h"
187558186977
/*
187559186978
** 2006 July 10
187560186979
**
187561186980
** The author disclaims copyright to this source code.
187562186981
**
@@ -187717,14 +187136,12 @@
187717187136
187718187137
#endif /* _FTS3_TOKENIZER_H_ */
187719187138
187720187139
/************** End of fts3_tokenizer.h **************************************/
187721187140
/************** Continuing where we left off in fts3Int.h ********************/
187722
-#line 46 "tsrc/fts3Int.h"
187723187141
/************** Include fts3_hash.h in the middle of fts3Int.h ***************/
187724187142
/************** Begin file fts3_hash.h ***************************************/
187725
-#line 1 "tsrc/fts3_hash.h"
187726187143
/*
187727187144
** 2001 September 22
187728187145
**
187729187146
** The author disclaims copyright to this source code. In place of
187730187147
** a legal notice, here is a blessing:
@@ -187836,11 +187253,10 @@
187836187253
187837187254
#endif /* _FTS3_HASH_H_ */
187838187255
187839187256
/************** End of fts3_hash.h *******************************************/
187840187257
/************** Continuing where we left off in fts3Int.h ********************/
187841
-#line 47 "tsrc/fts3Int.h"
187842187258
187843187259
/*
187844187260
** This constant determines the maximum depth of an FTS expression tree
187845187261
** that the library will create and use. FTS uses recursion to perform
187846187262
** various operations on the query tree, so the disadvantage of a large
@@ -188453,11 +187869,10 @@
188453187869
#endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */
188454187870
#endif /* _FTSINT_H */
188455187871
188456187872
/************** End of fts3Int.h *********************************************/
188457187873
/************** Continuing where we left off in fts3.c ***********************/
188458
-#line 292 "tsrc/fts3.c"
188459187874
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
188460187875
188461187876
#if defined(SQLITE_ENABLE_FTS3) && !defined(SQLITE_CORE)
188462187877
# define SQLITE_CORE 1
188463187878
#endif
@@ -190509,14 +189924,19 @@
190509189924
190510189925
assert_fts3_nc( p!=0 && *p1!=0 && *p2!=0 );
190511189926
if( *p1==POS_COLUMN ){
190512189927
p1++;
190513189928
p1 += fts3GetVarint32(p1, &iCol1);
189929
+ /* iCol1==0 indicates corruption. Column 0 does not have a POS_COLUMN
189930
+ ** entry, so this is actually end-of-doclist. */
189931
+ if( iCol1==0 ) return 0;
190514189932
}
190515189933
if( *p2==POS_COLUMN ){
190516189934
p2++;
190517189935
p2 += fts3GetVarint32(p2, &iCol2);
189936
+ /* As above, iCol2==0 indicates corruption. */
189937
+ if( iCol2==0 ) return 0;
190518189938
}
190519189939
190520189940
while( 1 ){
190521189941
if( iCol1==iCol2 ){
190522189942
char *pSave = p;
@@ -193683,11 +193103,11 @@
193683193103
for(p=pExpr; p->pLeft; p=p->pLeft){
193684193104
assert( p->pRight->pPhrase->doclist.nList>0 );
193685193105
nTmp += p->pRight->pPhrase->doclist.nList;
193686193106
}
193687193107
nTmp += p->pPhrase->doclist.nList;
193688
- aTmp = sqlite3_malloc64(nTmp*2);
193108
+ aTmp = sqlite3_malloc64(nTmp*2 + FTS3_VARINT_MAX);
193689193109
if( !aTmp ){
193690193110
*pRc = SQLITE_NOMEM;
193691193111
res = 0;
193692193112
}else{
193693193113
char *aPoslist = p->pPhrase->doclist.pList;
@@ -194355,11 +193775,10 @@
194355193775
194356193776
#endif
194357193777
194358193778
/************** End of fts3.c ************************************************/
194359193779
/************** Begin file fts3_aux.c ****************************************/
194360
-#line 1 "tsrc/fts3_aux.c"
194361193780
/*
194362193781
** 2011 Jan 27
194363193782
**
194364193783
** The author disclaims copyright to this source code. In place of
194365193784
** a legal notice, here is a blessing:
@@ -194916,11 +194335,10 @@
194916194335
194917194336
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
194918194337
194919194338
/************** End of fts3_aux.c ********************************************/
194920194339
/************** Begin file fts3_expr.c ***************************************/
194921
-#line 1 "tsrc/fts3_expr.c"
194922194340
/*
194923194341
** 2008 Nov 28
194924194342
**
194925194343
** The author disclaims copyright to this source code. In place of
194926194344
** a legal notice, here is a blessing:
@@ -195238,14 +194656,15 @@
195238194656
rc = pModule->xNext(pCursor, &zByte, &nByte, &iBegin, &iEnd, &iPos);
195239194657
if( rc==SQLITE_OK ){
195240194658
Fts3PhraseToken *pToken;
195241194659
195242194660
p = fts3ReallocOrFree(p, nSpace + ii*sizeof(Fts3PhraseToken));
195243
- if( !p ) goto no_mem;
195244
-
195245194661
zTemp = fts3ReallocOrFree(zTemp, nTemp + nByte);
195246
- if( !zTemp ) goto no_mem;
194662
+ if( !zTemp || !p ){
194663
+ rc = SQLITE_NOMEM;
194664
+ goto getnextstring_out;
194665
+ }
195247194666
195248194667
assert( nToken==ii );
195249194668
pToken = &((Fts3Phrase *)(&p[1]))->aToken[ii];
195250194669
memset(pToken, 0, sizeof(Fts3PhraseToken));
195251194670
@@ -195256,53 +194675,51 @@
195256194675
pToken->isPrefix = (iEnd<nInput && zInput[iEnd]=='*');
195257194676
pToken->bFirst = (iBegin>0 && zInput[iBegin-1]=='^');
195258194677
nToken = ii+1;
195259194678
}
195260194679
}
195261
-
195262
- pModule->xClose(pCursor);
195263
- pCursor = 0;
195264194680
}
195265194681
195266194682
if( rc==SQLITE_DONE ){
195267194683
int jj;
195268194684
char *zBuf = 0;
195269194685
195270194686
p = fts3ReallocOrFree(p, nSpace + nToken*sizeof(Fts3PhraseToken) + nTemp);
195271
- if( !p ) goto no_mem;
194687
+ if( !p ){
194688
+ rc = SQLITE_NOMEM;
194689
+ goto getnextstring_out;
194690
+ }
195272194691
memset(p, 0, (char *)&(((Fts3Phrase *)&p[1])->aToken[0])-(char *)p);
195273194692
p->eType = FTSQUERY_PHRASE;
195274194693
p->pPhrase = (Fts3Phrase *)&p[1];
195275194694
p->pPhrase->iColumn = pParse->iDefaultCol;
195276194695
p->pPhrase->nToken = nToken;
195277194696
195278194697
zBuf = (char *)&p->pPhrase->aToken[nToken];
194698
+ assert( nTemp==0 || zTemp );
195279194699
if( zTemp ){
195280194700
memcpy(zBuf, zTemp, nTemp);
195281
- sqlite3_free(zTemp);
195282
- }else{
195283
- assert( nTemp==0 );
195284194701
}
195285194702
195286194703
for(jj=0; jj<p->pPhrase->nToken; jj++){
195287194704
p->pPhrase->aToken[jj].z = zBuf;
195288194705
zBuf += p->pPhrase->aToken[jj].n;
195289194706
}
195290194707
rc = SQLITE_OK;
195291194708
}
195292194709
195293
- *ppExpr = p;
195294
- return rc;
195295
-no_mem:
195296
-
194710
+ getnextstring_out:
195297194711
if( pCursor ){
195298194712
pModule->xClose(pCursor);
195299194713
}
195300194714
sqlite3_free(zTemp);
195301
- sqlite3_free(p);
195302
- *ppExpr = 0;
195303
- return SQLITE_NOMEM;
194715
+ if( rc!=SQLITE_OK ){
194716
+ sqlite3_free(p);
194717
+ p = 0;
194718
+ }
194719
+ *ppExpr = p;
194720
+ return rc;
195304194721
}
195305194722
195306194723
/*
195307194724
** The output variable *ppExpr is populated with an allocated Fts3Expr
195308194725
** structure, or set to 0 if the end of the input buffer is reached.
@@ -196213,11 +195630,10 @@
196213195630
#endif
196214195631
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
196215195632
196216195633
/************** End of fts3_expr.c *******************************************/
196217195634
/************** Begin file fts3_hash.c ***************************************/
196218
-#line 1 "tsrc/fts3_hash.c"
196219195635
/*
196220195636
** 2001 September 22
196221195637
**
196222195638
** The author disclaims copyright to this source code. In place of
196223195639
** a legal notice, here is a blessing:
@@ -196600,11 +196016,10 @@
196600196016
196601196017
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
196602196018
196603196019
/************** End of fts3_hash.c *******************************************/
196604196020
/************** Begin file fts3_porter.c *************************************/
196605
-#line 1 "tsrc/fts3_porter.c"
196606196021
/*
196607196022
** 2006 September 30
196608196023
**
196609196024
** The author disclaims copyright to this source code. In place of
196610196025
** a legal notice, here is a blessing:
@@ -197266,11 +196681,10 @@
197266196681
197267196682
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
197268196683
197269196684
/************** End of fts3_porter.c *****************************************/
197270196685
/************** Begin file fts3_tokenizer.c **********************************/
197271
-#line 1 "tsrc/fts3_tokenizer.c"
197272196686
/*
197273196687
** 2007 June 22
197274196688
**
197275196689
** The author disclaims copyright to this source code. In place of
197276196690
** a legal notice, here is a blessing:
@@ -197786,11 +197200,10 @@
197786197200
197787197201
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
197788197202
197789197203
/************** End of fts3_tokenizer.c **************************************/
197790197204
/************** Begin file fts3_tokenizer1.c *********************************/
197791
-#line 1 "tsrc/fts3_tokenizer1.c"
197792197205
/*
197793197206
** 2006 Oct 10
197794197207
**
197795197208
** The author disclaims copyright to this source code. In place of
197796197209
** a legal notice, here is a blessing:
@@ -198024,11 +197437,10 @@
198024197437
198025197438
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
198026197439
198027197440
/************** End of fts3_tokenizer1.c *************************************/
198028197441
/************** Begin file fts3_tokenize_vtab.c ******************************/
198029
-#line 1 "tsrc/fts3_tokenize_vtab.c"
198030197442
/*
198031197443
** 2013 Apr 22
198032197444
**
198033197445
** The author disclaims copyright to this source code. In place of
198034197446
** a legal notice, here is a blessing:
@@ -198487,11 +197899,10 @@
198487197899
198488197900
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
198489197901
198490197902
/************** End of fts3_tokenize_vtab.c **********************************/
198491197903
/************** Begin file fts3_write.c **************************************/
198492
-#line 1 "tsrc/fts3_write.c"
198493197904
/*
198494197905
** 2009 Oct 23
198495197906
**
198496197907
** The author disclaims copyright to this source code. In place of
198497197908
** a legal notice, here is a blessing:
@@ -204325,11 +203736,10 @@
204325203736
204326203737
#endif
204327203738
204328203739
/************** End of fts3_write.c ******************************************/
204329203740
/************** Begin file fts3_snippet.c ************************************/
204330
-#line 1 "tsrc/fts3_snippet.c"
204331203741
/*
204332203742
** 2009 Oct 23
204333203743
**
204334203744
** The author disclaims copyright to this source code. In place of
204335203745
** a legal notice, here is a blessing:
@@ -206085,11 +205495,10 @@
206085205495
206086205496
#endif
206087205497
206088205498
/************** End of fts3_snippet.c ****************************************/
206089205499
/************** Begin file fts3_unicode.c ************************************/
206090
-#line 1 "tsrc/fts3_unicode.c"
206091205500
/*
206092205501
** 2012 May 24
206093205502
**
206094205503
** The author disclaims copyright to this source code. In place of
206095205504
** a legal notice, here is a blessing:
@@ -206486,11 +205895,10 @@
206486205895
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
206487205896
#endif /* ifndef SQLITE_DISABLE_FTS3_UNICODE */
206488205897
206489205898
/************** End of fts3_unicode.c ****************************************/
206490205899
/************** Begin file fts3_unicode2.c ***********************************/
206491
-#line 1 "tsrc/fts3_unicode2.c"
206492205900
/*
206493205901
** 2012-05-25
206494205902
**
206495205903
** The author disclaims copyright to this source code. In place of
206496205904
** a legal notice, here is a blessing:
@@ -206873,11 +206281,10 @@
206873206281
#endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */
206874206282
#endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */
206875206283
206876206284
/************** End of fts3_unicode2.c ***************************************/
206877206285
/************** Begin file json.c ********************************************/
206878
-#line 1 "tsrc/json.c"
206879206286
/*
206880206287
** 2015-08-12
206881206288
**
206882206289
** The author disclaims copyright to this source code. In place of
206883206290
** a legal notice, here is a blessing:
@@ -212343,11 +211750,10 @@
212343211750
}
212344211751
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) */
212345211752
212346211753
/************** End of json.c ************************************************/
212347211754
/************** Begin file rtree.c *******************************************/
212348
-#line 1 "tsrc/rtree.c"
212349211755
/*
212350211756
** 2001 September 15
212351211757
**
212352211758
** The author disclaims copyright to this source code. In place of
212353211759
** a legal notice, here is a blessing:
@@ -216632,11 +216038,10 @@
216632216038
216633216039
/* Conditionally include the geopoly code */
216634216040
#ifdef SQLITE_ENABLE_GEOPOLY
216635216041
/************** Include geopoly.c in the middle of rtree.c *******************/
216636216042
/************** Begin file geopoly.c *****************************************/
216637
-#line 1 "tsrc/geopoly.c"
216638216043
/*
216639216044
** 2018-05-25
216640216045
**
216641216046
** The author disclaims copyright to this source code. In place of
216642216047
** a legal notice, here is a blessing:
@@ -218475,11 +217880,10 @@
218475217880
return rc;
218476217881
}
218477217882
218478217883
/************** End of geopoly.c *********************************************/
218479217884
/************** Continuing where we left off in rtree.c **********************/
218480
-#line 4288 "tsrc/rtree.c"
218481217885
#endif
218482217886
218483217887
/*
218484217888
** Register the r-tree module with database handle db. This creates the
218485217889
** virtual table module "rtree" and the debugging/analysis scalar
@@ -218658,11 +218062,10 @@
218658218062
218659218063
#endif
218660218064
218661218065
/************** End of rtree.c ***********************************************/
218662218066
/************** Begin file icu.c *********************************************/
218663
-#line 1 "tsrc/icu.c"
218664218067
/*
218665218068
** 2007 May 6
218666218069
**
218667218070
** The author disclaims copyright to this source code. In place of
218668218071
** a legal notice, here is a blessing:
@@ -219250,11 +218653,10 @@
219250218653
219251218654
#endif
219252218655
219253218656
/************** End of icu.c *************************************************/
219254218657
/************** Begin file fts3_icu.c ****************************************/
219255
-#line 1 "tsrc/fts3_icu.c"
219256218658
/*
219257218659
** 2007 June 22
219258218660
**
219259218661
** The author disclaims copyright to this source code. In place of
219260218662
** a legal notice, here is a blessing:
@@ -219516,11 +218918,10 @@
219516218918
#endif /* defined(SQLITE_ENABLE_ICU) */
219517218919
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
219518218920
219519218921
/************** End of fts3_icu.c ********************************************/
219520218922
/************** Begin file sqlite3rbu.c **************************************/
219521
-#line 1 "tsrc/sqlite3rbu.c"
219522218923
/*
219523218924
** 2014 August 30
219524218925
**
219525218926
** The author disclaims copyright to this source code. In place of
219526218927
** a legal notice, here is a blessing:
@@ -219608,11 +219009,10 @@
219608219009
/* #include "sqlite3.h" */
219609219010
219610219011
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU)
219611219012
/************** Include sqlite3rbu.h in the middle of sqlite3rbu.c ***********/
219612219013
/************** Begin file sqlite3rbu.h **************************************/
219613
-#line 1 "tsrc/sqlite3rbu.h"
219614219014
/*
219615219015
** 2014 August 30
219616219016
**
219617219017
** The author disclaims copyright to this source code. In place of
219618219018
** a legal notice, here is a blessing:
@@ -220245,11 +219645,10 @@
220245219645
220246219646
#endif /* _SQLITE3RBU_H */
220247219647
220248219648
/************** End of sqlite3rbu.h ******************************************/
220249219649
/************** Continuing where we left off in sqlite3rbu.c *****************/
220250
-#line 91 "tsrc/sqlite3rbu.c"
220251219650
220252219651
#if defined(_WIN32_WCE)
220253219652
/* #include "windows.h" */
220254219653
#endif
220255219654
@@ -225606,11 +225005,10 @@
225606225005
225607225006
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) */
225608225007
225609225008
/************** End of sqlite3rbu.c ******************************************/
225610225009
/************** Begin file dbstat.c ******************************************/
225611
-#line 1 "tsrc/dbstat.c"
225612225010
/*
225613225011
** 2010 July 12
225614225012
**
225615225013
** The author disclaims copyright to this source code. In place of
225616225014
** a legal notice, here is a blessing:
@@ -226516,11 +225914,10 @@
226516225914
SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
226517225915
#endif /* SQLITE_ENABLE_DBSTAT_VTAB */
226518225916
226519225917
/************** End of dbstat.c **********************************************/
226520225918
/************** Begin file dbpage.c ******************************************/
226521
-#line 1 "tsrc/dbpage.c"
226522225919
/*
226523225920
** 2017-10-11
226524225921
**
226525225922
** The author disclaims copyright to this source code. In place of
226526225923
** a legal notice, here is a blessing:
@@ -226912,10 +226309,12 @@
226912226309
if( (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK && pData ){
226913226310
unsigned char *aPage = sqlite3PagerGetData(pDbPage);
226914226311
memcpy(aPage, pData, szPage);
226915226312
pTab->pgnoTrunc = 0;
226916226313
}
226314
+ }else{
226315
+ pTab->pgnoTrunc = 0;
226917226316
}
226918226317
sqlite3PagerUnref(pDbPage);
226919226318
return rc;
226920226319
226921226320
update_fail:
@@ -226999,11 +226398,10 @@
226999226398
SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; }
227000226399
#endif /* SQLITE_ENABLE_DBSTAT_VTAB */
227001226400
227002226401
/************** End of dbpage.c **********************************************/
227003226402
/************** Begin file sqlite3session.c **********************************/
227004
-#line 1 "tsrc/sqlite3session.c"
227005226403
227006226404
#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
227007226405
/* #include "sqlite3session.h" */
227008226406
/* #include <assert.h> */
227009226407
/* #include <string.h> */
@@ -233539,11 +232937,10 @@
233539232937
233540232938
#endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
233541232939
233542232940
/************** End of sqlite3session.c **************************************/
233543232941
/************** Begin file fts5.c ********************************************/
233544
-#line 1 "tsrc/fts5.c"
233545232942
233546232943
/*
233547232944
** This, the "fts5.c" source file, is a composite file that is itself
233548232945
** assembled from the following files:
233549232946
**
@@ -233577,11 +232974,10 @@
233577232974
/* #include <stdint.h> */
233578232975
#endif
233579232976
#ifdef HAVE_INTTYPES_H
233580232977
/* #include <inttypes.h> */
233581232978
#endif
233582
-#line 1 "fts5.h"
233583232979
/*
233584232980
** 2014 May 31
233585232981
**
233586232982
** The author disclaims copyright to this source code. In place of
233587232983
** a legal notice, here is a blessing:
@@ -233878,17 +233274,32 @@
233878233274
** This is used to access token iToken of phrase hit iIdx within the
233879233275
** current row. If iIdx is less than zero or greater than or equal to the
233880233276
** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise,
233881233277
** output variable (*ppToken) is set to point to a buffer containing the
233882233278
** matching document token, and (*pnToken) to the size of that buffer in
233883
-** bytes. This API is not available if the specified token matches a
233884
-** prefix query term. In that case both output variables are always set
233885
-** to 0.
233279
+** bytes.
233886233280
**
233887233281
** The output text is not a copy of the document text that was tokenized.
233888233282
** It is the output of the tokenizer module. For tokendata=1 tables, this
233889233283
** includes any embedded 0x00 and trailing data.
233284
+**
233285
+** This API may be slow in some cases if the token identified by parameters
233286
+** iIdx and iToken matched a prefix token in the query. In most cases, the
233287
+** first call to this API for each prefix token in the query is forced
233288
+** to scan the portion of the full-text index that matches the prefix
233289
+** token to collect the extra data required by this API. If the prefix
233290
+** token matches a large number of token instances in the document set,
233291
+** this may be a performance problem.
233292
+**
233293
+** If the user knows in advance that a query may use this API for a
233294
+** prefix token, FTS5 may be configured to collect all required data as part
233295
+** of the initial querying of the full-text index, avoiding the second scan
233296
+** entirely. This also causes prefix queries that do not use this API to
233297
+** run more slowly and use more memory. FTS5 may be configured in this way
233298
+** either on a per-table basis using the [FTS5 insttoken | 'insttoken']
233299
+** option, or on a per-query basis using the
233300
+** [fts5_insttoken | fts5_insttoken()] user function.
233890233301
**
233891233302
** This API can be quite slow if used with an FTS5 table created with the
233892233303
** "detail=none" or "detail=column" option.
233893233304
**
233894233305
** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale)
@@ -234318,11 +233729,10 @@
234318233729
} /* end of the 'extern "C"' block */
234319233730
#endif
234320233731
234321233732
#endif /* _FTS5_H */
234322233733
234323
-#line 1 "fts5Int.h"
234324233734
/*
234325233735
** 2014 May 31
234326233736
**
234327233737
** The author disclaims copyright to this source code. In place of
234328233738
** a legal notice, here is a blessing:
@@ -234568,11 +233978,12 @@
234568233978
int nUsermerge; /* 'usermerge' setting */
234569233979
int nHashSize; /* Bytes of memory for in-memory hash */
234570233980
char *zRank; /* Name of rank function */
234571233981
char *zRankArgs; /* Arguments to rank function */
234572233982
int bSecureDelete; /* 'secure-delete' */
234573
- int nDeleteMerge; /* 'deletemerge' */
233983
+ int nDeleteMerge; /* 'deletemerge' */
233984
+ int bPrefixInsttoken; /* 'prefix-insttoken' */
234574233985
234575233986
/* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */
234576233987
char **pzErrmsg;
234577233988
234578233989
#ifdef SQLITE_DEBUG
@@ -234825,11 +234236,18 @@
234825234236
static int sqlite3Fts5StructureTest(Fts5Index*, void*);
234826234237
234827234238
/*
234828234239
** Used by xInstToken():
234829234240
*/
234830
-static int sqlite3Fts5IterToken(Fts5IndexIter*, i64, int, int, const char**, int*);
234241
+static int sqlite3Fts5IterToken(
234242
+ Fts5IndexIter *pIndexIter,
234243
+ const char *pToken, int nToken,
234244
+ i64 iRowid,
234245
+ int iCol,
234246
+ int iOff,
234247
+ const char **ppOut, int *pnOut
234248
+);
234831234249
234832234250
/*
234833234251
** Insert or remove data to or from the index. Each time a document is
234834234252
** added to or removed from the index, this function is called one or more
234835234253
** times.
@@ -235258,11 +234676,10 @@
235258234676
** End of interface to code in fts5_unicode2.c.
235259234677
**************************************************************************/
235260234678
235261234679
#endif
235262234680
235263
-#line 1 "fts5parse.h"
235264234681
#define FTS5_OR 1
235265234682
#define FTS5_AND 2
235266234683
#define FTS5_NOT 3
235267234684
#define FTS5_TERM 4
235268234685
#define FTS5_COLON 5
@@ -235275,11 +234692,10 @@
235275234692
#define FTS5_CARET 12
235276234693
#define FTS5_COMMA 13
235277234694
#define FTS5_PLUS 14
235278234695
#define FTS5_STAR 15
235279234696
235280
-#line 1 "fts5parse.c"
235281234697
/* This file is automatically generated by Lemon from input grammar
235282234698
** source file "fts5parse.y".
235283234699
*/
235284234700
/*
235285234701
** 2000-05-29
@@ -235304,11 +234720,10 @@
235304234720
**
235305234721
** The following is the concatenation of all %include directives from the
235306234722
** input grammar file:
235307234723
*/
235308234724
/************ Begin %include sections from the grammar ************************/
235309
-#line 47 "fts5parse.y"
235310234725
235311234726
/* #include "fts5Int.h" */
235312234727
/* #include "fts5parse.h" */
235313234728
235314234729
/*
@@ -235332,11 +234747,10 @@
235332234747
** Alternative datatype for the argument to the malloc() routine passed
235333234748
** into sqlite3ParserAlloc(). The default is size_t.
235334234749
*/
235335234750
#define fts5YYMALLOCARGTYPE u64
235336234751
235337
-#line 58 "fts5parse.sql"
235338234752
/**************** End of %include directives **********************************/
235339234753
/* These constants specify the various numeric values for terminal symbols.
235340234754
***************** Begin token definitions *************************************/
235341234755
#ifndef FTS5_OR
235342234756
#define FTS5_OR 1
@@ -235879,45 +235293,35 @@
235879235293
** inside the C code.
235880235294
*/
235881235295
/********* Begin destructor definitions ***************************************/
235882235296
case 16: /* input */
235883235297
{
235884
-#line 83 "fts5parse.y"
235885235298
(void)pParse;
235886
-#line 606 "fts5parse.sql"
235887235299
}
235888235300
break;
235889235301
case 17: /* expr */
235890235302
case 18: /* cnearset */
235891235303
case 19: /* exprlist */
235892235304
{
235893
-#line 89 "fts5parse.y"
235894235305
sqlite3Fts5ParseNodeFree((fts5yypminor->fts5yy24));
235895
-#line 615 "fts5parse.sql"
235896235306
}
235897235307
break;
235898235308
case 20: /* colset */
235899235309
case 21: /* colsetlist */
235900235310
{
235901
-#line 93 "fts5parse.y"
235902235311
sqlite3_free((fts5yypminor->fts5yy11));
235903
-#line 623 "fts5parse.sql"
235904235312
}
235905235313
break;
235906235314
case 22: /* nearset */
235907235315
case 23: /* nearphrases */
235908235316
{
235909
-#line 148 "fts5parse.y"
235910235317
sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy46));
235911
-#line 631 "fts5parse.sql"
235912235318
}
235913235319
break;
235914235320
case 24: /* phrase */
235915235321
{
235916
-#line 183 "fts5parse.y"
235917235322
sqlite3Fts5ParsePhraseFree((fts5yypminor->fts5yy53));
235918
-#line 638 "fts5parse.sql"
235919235323
}
235920235324
break;
235921235325
/********* End destructor definitions *****************************************/
235922235326
default: break; /* If no destructor action specified: do nothing */
235923235327
}
@@ -236148,14 +235552,12 @@
236148235552
#endif
236149235553
while( fts5yypParser->fts5yytos>fts5yypParser->fts5yystack ) fts5yy_pop_parser_stack(fts5yypParser);
236150235554
/* Here code is inserted which will execute if the parser
236151235555
** stack every overflows */
236152235556
/******** Begin %stack_overflow code ******************************************/
236153
-#line 36 "fts5parse.y"
236154235557
236155235558
sqlite3Fts5ParseError(pParse, "fts5: parser stack overflow");
236156
-#line 876 "fts5parse.sql"
236157235559
/******** End %stack_overflow code ********************************************/
236158235560
sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument var */
236159235561
sqlite3Fts5ParserCTX_STORE
236160235562
}
236161235563
@@ -236320,202 +235722,148 @@
236320235722
** break;
236321235723
*/
236322235724
/********** Begin reduce actions **********************************************/
236323235725
fts5YYMINORTYPE fts5yylhsminor;
236324235726
case 0: /* input ::= expr */
236325
-#line 82 "fts5parse.y"
236326235727
{ sqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy24); }
236327
-#line 1047 "fts5parse.sql"
236328235728
break;
236329235729
case 1: /* colset ::= MINUS LCP colsetlist RCP */
236330
-#line 97 "fts5parse.y"
236331235730
{
236332235731
fts5yymsp[-3].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
236333235732
}
236334
-#line 1054 "fts5parse.sql"
236335235733
break;
236336235734
case 2: /* colset ::= LCP colsetlist RCP */
236337
-#line 100 "fts5parse.y"
236338235735
{ fts5yymsp[-2].minor.fts5yy11 = fts5yymsp[-1].minor.fts5yy11; }
236339
-#line 1059 "fts5parse.sql"
236340235736
break;
236341235737
case 3: /* colset ::= STRING */
236342
-#line 101 "fts5parse.y"
236343235738
{
236344235739
fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
236345235740
}
236346
-#line 1066 "fts5parse.sql"
236347235741
fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
236348235742
break;
236349235743
case 4: /* colset ::= MINUS STRING */
236350
-#line 104 "fts5parse.y"
236351235744
{
236352235745
fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
236353235746
fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
236354235747
}
236355
-#line 1075 "fts5parse.sql"
236356235748
break;
236357235749
case 5: /* colsetlist ::= colsetlist STRING */
236358
-#line 109 "fts5parse.y"
236359235750
{
236360235751
fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy11, &fts5yymsp[0].minor.fts5yy0); }
236361
-#line 1081 "fts5parse.sql"
236362235752
fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
236363235753
break;
236364235754
case 6: /* colsetlist ::= STRING */
236365
-#line 111 "fts5parse.y"
236366235755
{
236367235756
fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
236368235757
}
236369
-#line 1089 "fts5parse.sql"
236370235758
fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
236371235759
break;
236372235760
case 7: /* expr ::= expr AND expr */
236373
-#line 115 "fts5parse.y"
236374235761
{
236375235762
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
236376235763
}
236377
-#line 1097 "fts5parse.sql"
236378235764
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
236379235765
break;
236380235766
case 8: /* expr ::= expr OR expr */
236381
-#line 118 "fts5parse.y"
236382235767
{
236383235768
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
236384235769
}
236385
-#line 1105 "fts5parse.sql"
236386235770
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
236387235771
break;
236388235772
case 9: /* expr ::= expr NOT expr */
236389
-#line 121 "fts5parse.y"
236390235773
{
236391235774
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
236392235775
}
236393
-#line 1113 "fts5parse.sql"
236394235776
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
236395235777
break;
236396235778
case 10: /* expr ::= colset COLON LP expr RP */
236397
-#line 125 "fts5parse.y"
236398235779
{
236399235780
sqlite3Fts5ParseSetColset(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[-4].minor.fts5yy11);
236400235781
fts5yylhsminor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;
236401235782
}
236402
-#line 1122 "fts5parse.sql"
236403235783
fts5yymsp[-4].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
236404235784
break;
236405235785
case 11: /* expr ::= LP expr RP */
236406
-#line 129 "fts5parse.y"
236407235786
{fts5yymsp[-2].minor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;}
236408
-#line 1128 "fts5parse.sql"
236409235787
break;
236410235788
case 12: /* expr ::= exprlist */
236411235789
case 13: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==13);
236412
-#line 130 "fts5parse.y"
236413235790
{fts5yylhsminor.fts5yy24 = fts5yymsp[0].minor.fts5yy24;}
236414
-#line 1134 "fts5parse.sql"
236415235791
fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
236416235792
break;
236417235793
case 14: /* exprlist ::= exprlist cnearset */
236418
-#line 133 "fts5parse.y"
236419235794
{
236420235795
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24);
236421235796
}
236422
-#line 1142 "fts5parse.sql"
236423235797
fts5yymsp[-1].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
236424235798
break;
236425235799
case 15: /* cnearset ::= nearset */
236426
-#line 137 "fts5parse.y"
236427235800
{
236428235801
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46);
236429235802
}
236430
-#line 1150 "fts5parse.sql"
236431235803
fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
236432235804
break;
236433235805
case 16: /* cnearset ::= colset COLON nearset */
236434
-#line 140 "fts5parse.y"
236435235806
{
236436235807
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46);
236437235808
sqlite3Fts5ParseSetColset(pParse, fts5yylhsminor.fts5yy24, fts5yymsp[-2].minor.fts5yy11);
236438235809
}
236439
-#line 1159 "fts5parse.sql"
236440235810
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
236441235811
break;
236442235812
case 17: /* nearset ::= phrase */
236443
-#line 151 "fts5parse.y"
236444235813
{ fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); }
236445
-#line 1165 "fts5parse.sql"
236446235814
fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
236447235815
break;
236448235816
case 18: /* nearset ::= CARET phrase */
236449
-#line 152 "fts5parse.y"
236450235817
{
236451235818
sqlite3Fts5ParseSetCaret(fts5yymsp[0].minor.fts5yy53);
236452235819
fts5yymsp[-1].minor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53);
236453235820
}
236454
-#line 1174 "fts5parse.sql"
236455235821
break;
236456235822
case 19: /* nearset ::= STRING LP nearphrases neardist_opt RP */
236457
-#line 156 "fts5parse.y"
236458235823
{
236459235824
sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0);
236460235825
sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy46, &fts5yymsp[-1].minor.fts5yy0);
236461235826
fts5yylhsminor.fts5yy46 = fts5yymsp[-2].minor.fts5yy46;
236462235827
}
236463
-#line 1183 "fts5parse.sql"
236464235828
fts5yymsp[-4].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
236465235829
break;
236466235830
case 20: /* nearphrases ::= phrase */
236467
-#line 162 "fts5parse.y"
236468235831
{
236469235832
fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53);
236470235833
}
236471
-#line 1191 "fts5parse.sql"
236472235834
fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
236473235835
break;
236474235836
case 21: /* nearphrases ::= nearphrases phrase */
236475
-#line 165 "fts5parse.y"
236476235837
{
236477235838
fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy46, fts5yymsp[0].minor.fts5yy53);
236478235839
}
236479
-#line 1199 "fts5parse.sql"
236480235840
fts5yymsp[-1].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
236481235841
break;
236482235842
case 22: /* neardist_opt ::= */
236483
-#line 172 "fts5parse.y"
236484235843
{ fts5yymsp[1].minor.fts5yy0.p = 0; fts5yymsp[1].minor.fts5yy0.n = 0; }
236485
-#line 1205 "fts5parse.sql"
236486235844
break;
236487235845
case 23: /* neardist_opt ::= COMMA STRING */
236488
-#line 173 "fts5parse.y"
236489235846
{ fts5yymsp[-1].minor.fts5yy0 = fts5yymsp[0].minor.fts5yy0; }
236490
-#line 1210 "fts5parse.sql"
236491235847
break;
236492235848
case 24: /* phrase ::= phrase PLUS STRING star_opt */
236493
-#line 185 "fts5parse.y"
236494235849
{
236495235850
fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy53, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
236496235851
}
236497
-#line 1217 "fts5parse.sql"
236498235852
fts5yymsp[-3].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
236499235853
break;
236500235854
case 25: /* phrase ::= STRING star_opt */
236501
-#line 188 "fts5parse.y"
236502235855
{
236503235856
fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
236504235857
}
236505
-#line 1225 "fts5parse.sql"
236506235858
fts5yymsp[-1].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
236507235859
break;
236508235860
case 26: /* star_opt ::= STAR */
236509
-#line 196 "fts5parse.y"
236510235861
{ fts5yymsp[0].minor.fts5yy4 = 1; }
236511
-#line 1231 "fts5parse.sql"
236512235862
break;
236513235863
case 27: /* star_opt ::= */
236514
-#line 197 "fts5parse.y"
236515235864
{ fts5yymsp[1].minor.fts5yy4 = 0; }
236516
-#line 1236 "fts5parse.sql"
236517235865
break;
236518235866
default:
236519235867
break;
236520235868
/********** End reduce actions ************************************************/
236521235869
};
@@ -236573,17 +235921,15 @@
236573235921
){
236574235922
sqlite3Fts5ParserARG_FETCH
236575235923
sqlite3Fts5ParserCTX_FETCH
236576235924
#define FTS5TOKEN fts5yyminor
236577235925
/************ Begin %syntax_error code ****************************************/
236578
-#line 30 "fts5parse.y"
236579235926
236580235927
UNUSED_PARAM(fts5yymajor); /* Silence a compiler warning */
236581235928
sqlite3Fts5ParseError(
236582235929
pParse, "fts5: syntax error near \"%.*s\"",FTS5TOKEN.n,FTS5TOKEN.p
236583235930
);
236584
-#line 1304 "fts5parse.sql"
236585235931
/************ End %syntax_error code ******************************************/
236586235932
sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
236587235933
sqlite3Fts5ParserCTX_STORE
236588235934
}
236589235935
@@ -236849,11 +236195,10 @@
236849236195
(void)iToken;
236850236196
return 0;
236851236197
#endif
236852236198
}
236853236199
236854
-#line 1 "fts5_aux.c"
236855236200
/*
236856236201
** 2014 May 31
236857236202
**
236858236203
** The author disclaims copyright to this source code. In place of
236859236204
** a legal notice, here is a blessing:
@@ -237672,11 +237017,10 @@
237672237017
}
237673237018
237674237019
return rc;
237675237020
}
237676237021
237677
-#line 1 "fts5_buffer.c"
237678237022
/*
237679237023
** 2014 May 31
237680237024
**
237681237025
** The author disclaims copyright to this source code. In place of
237682237026
** a legal notice, here is a blessing:
@@ -238085,11 +237429,10 @@
238085237429
}
238086237430
sqlite3_free(p);
238087237431
}
238088237432
}
238089237433
238090
-#line 1 "fts5_config.c"
238091237434
/*
238092237435
** 2014 Jun 09
238093237436
**
238094237437
** The author disclaims copyright to this source code. In place of
238095237438
** a legal notice, here is a blessing:
@@ -239114,10 +238457,23 @@
239114238457
if( bVal<0 ){
239115238458
*pbBadkey = 1;
239116238459
}else{
239117238460
pConfig->bSecureDelete = (bVal ? 1 : 0);
239118238461
}
238462
+ }
238463
+
238464
+ else if( 0==sqlite3_stricmp(zKey, "insttoken") ){
238465
+ int bVal = -1;
238466
+ if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
238467
+ bVal = sqlite3_value_int(pVal);
238468
+ }
238469
+ if( bVal<0 ){
238470
+ *pbBadkey = 1;
238471
+ }else{
238472
+ pConfig->bPrefixInsttoken = (bVal ? 1 : 0);
238473
+ }
238474
+
239119238475
}else{
239120238476
*pbBadkey = 1;
239121238477
}
239122238478
return rc;
239123238479
}
@@ -239201,11 +238557,10 @@
239201238557
va_end(ap);
239202238558
}
239203238559
239204238560
239205238561
239206
-#line 1 "fts5_expr.c"
239207238562
/*
239208238563
** 2014 May 31
239209238564
**
239210238565
** The author disclaims copyright to this source code. In place of
239211238566
** a legal notice, here is a blessing:
@@ -242250,11 +241605,11 @@
242250241605
&& memcmp(pT->pTerm, pToken, pT->nQueryTerm)==0
242251241606
){
242252241607
int rc = sqlite3Fts5PoslistWriterAppend(
242253241608
&pExpr->apExprPhrase[i]->poslist, &p->aPopulator[i].writer, p->iOff
242254241609
);
242255
- if( rc==SQLITE_OK && pExpr->pConfig->bTokendata && !pT->bPrefix ){
241610
+ if( rc==SQLITE_OK && (pExpr->pConfig->bTokendata || pT->bPrefix) ){
242256241611
int iCol = p->iOff>>32;
242257241612
int iTokOff = p->iOff & 0x7FFFFFFF;
242258241613
rc = sqlite3Fts5IndexIterWriteTokendata(
242259241614
pT->pIter, pToken, nToken, iRowid, iCol, iTokOff
242260241615
);
@@ -242443,19 +241798,18 @@
242443241798
pPhrase = pExpr->apExprPhrase[iPhrase];
242444241799
if( iToken<0 || iToken>=pPhrase->nTerm ){
242445241800
return SQLITE_RANGE;
242446241801
}
242447241802
pTerm = &pPhrase->aTerm[iToken];
242448
- if( pTerm->bPrefix==0 ){
242449
- if( pExpr->pConfig->bTokendata ){
242450
- rc = sqlite3Fts5IterToken(
242451
- pTerm->pIter, iRowid, iCol, iOff+iToken, ppOut, pnOut
242452
- );
242453
- }else{
242454
- *ppOut = pTerm->pTerm;
242455
- *pnOut = pTerm->nFullTerm;
242456
- }
241803
+ if( pExpr->pConfig->bTokendata || pTerm->bPrefix ){
241804
+ rc = sqlite3Fts5IterToken(
241805
+ pTerm->pIter, pTerm->pTerm, pTerm->nQueryTerm,
241806
+ iRowid, iCol, iOff+iToken, ppOut, pnOut
241807
+ );
241808
+ }else{
241809
+ *ppOut = pTerm->pTerm;
241810
+ *pnOut = pTerm->nFullTerm;
242457241811
}
242458241812
return rc;
242459241813
}
242460241814
242461241815
/*
@@ -242470,11 +241824,10 @@
242470241824
sqlite3Fts5IndexIterClearTokendata(pT->pIter);
242471241825
}
242472241826
}
242473241827
}
242474241828
242475
-#line 1 "fts5_hash.c"
242476241829
/*
242477241830
** 2014 August 11
242478241831
**
242479241832
** The author disclaims copyright to this source code. In place of
242480241833
** a legal notice, here is a blessing:
@@ -243062,11 +242415,10 @@
243062242415
*ppDoclist = 0;
243063242416
*pnDoclist = 0;
243064242417
}
243065242418
}
243066242419
243067
-#line 1 "fts5_index.c"
243068242420
/*
243069242421
** 2014 May 31
243070242422
**
243071242423
** The author disclaims copyright to this source code. In place of
243072242424
** a legal notice, here is a blessing:
@@ -249268,10 +248620,387 @@
249268248620
fts5BufferFree(&tmp);
249269248621
memset(&out.p[out.n], 0, FTS5_DATA_ZERO_PADDING);
249270248622
*p1 = out;
249271248623
}
249272248624
248625
+
248626
+/*
248627
+** Iterate through a range of entries in the FTS index, invoking the xVisit
248628
+** callback for each of them.
248629
+**
248630
+** Parameter pToken points to an nToken buffer containing an FTS index term
248631
+** (i.e. a document term with the preceding 1 byte index identifier -
248632
+** FTS5_MAIN_PREFIX or similar). If bPrefix is true, then the call visits
248633
+** all entries for terms that have pToken/nToken as a prefix. If bPrefix
248634
+** is false, then only entries with pToken/nToken as the entire key are
248635
+** visited.
248636
+**
248637
+** If the current table is a tokendata=1 table, then if bPrefix is true then
248638
+** each index term is treated separately. However, if bPrefix is false, then
248639
+** all index terms corresponding to pToken/nToken are collapsed into a single
248640
+** term before the callback is invoked.
248641
+**
248642
+** The callback invoked for each entry visited is specified by paramter xVisit.
248643
+** Each time it is invoked, it is passed a pointer to the Fts5Index object,
248644
+** a copy of the 7th paramter to this function (pCtx) and a pointer to the
248645
+** iterator that indicates the current entry. If the current entry is the
248646
+** first with a new term (i.e. different from that of the previous entry,
248647
+** including the very first term), then the final two parameters are passed
248648
+** a pointer to the term and its size in bytes, respectively. If the current
248649
+** entry is not the first associated with its term, these two parameters
248650
+** are passed 0.
248651
+**
248652
+** If parameter pColset is not NULL, then it is used to filter entries before
248653
+** the callback is invoked.
248654
+*/
248655
+static int fts5VisitEntries(
248656
+ Fts5Index *p, /* Fts5 index object */
248657
+ Fts5Colset *pColset, /* Columns filter to apply, or NULL */
248658
+ u8 *pToken, /* Buffer containing token */
248659
+ int nToken, /* Size of buffer pToken in bytes */
248660
+ int bPrefix, /* True for a prefix scan */
248661
+ void (*xVisit)(Fts5Index*, void *pCtx, Fts5Iter *pIter, const u8*, int),
248662
+ void *pCtx /* Passed as second argument to xVisit() */
248663
+){
248664
+ const int flags = (bPrefix ? FTS5INDEX_QUERY_SCAN : 0)
248665
+ | FTS5INDEX_QUERY_SKIPEMPTY
248666
+ | FTS5INDEX_QUERY_NOOUTPUT;
248667
+ Fts5Iter *p1 = 0; /* Iterator used to gather data from index */
248668
+ int bNewTerm = 1;
248669
+ Fts5Structure *pStruct = fts5StructureRead(p);
248670
+
248671
+ fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1);
248672
+ fts5IterSetOutputCb(&p->rc, p1);
248673
+ for( /* no-op */ ;
248674
+ fts5MultiIterEof(p, p1)==0;
248675
+ fts5MultiIterNext2(p, p1, &bNewTerm)
248676
+ ){
248677
+ Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ];
248678
+ int nNew = 0;
248679
+ const u8 *pNew = 0;
248680
+
248681
+ p1->xSetOutputs(p1, pSeg);
248682
+ if( p->rc ) break;
248683
+
248684
+ if( bNewTerm ){
248685
+ nNew = pSeg->term.n;
248686
+ pNew = pSeg->term.p;
248687
+ if( nNew<nToken || memcmp(pToken, pNew, nToken) ) break;
248688
+ }
248689
+
248690
+ xVisit(p, pCtx, p1, pNew, nNew);
248691
+ }
248692
+ fts5MultiIterFree(p1);
248693
+
248694
+ fts5StructureRelease(pStruct);
248695
+ return p->rc;
248696
+}
248697
+
248698
+
248699
+/*
248700
+** Usually, a tokendata=1 iterator (struct Fts5TokenDataIter) accumulates an
248701
+** array of these for each row it visits (so all iRowid fields are the same).
248702
+** Or, for an iterator used by an "ORDER BY rank" query, it accumulates an
248703
+** array of these for the entire query (in which case iRowid fields may take
248704
+** a variety of values).
248705
+**
248706
+** Each instance in the array indicates the iterator (and therefore term)
248707
+** associated with position iPos of rowid iRowid. This is used by the
248708
+** xInstToken() API.
248709
+**
248710
+** iRowid:
248711
+** Rowid for the current entry.
248712
+**
248713
+** iPos:
248714
+** Position of current entry within row. In the usual ((iCol<<32)+iOff)
248715
+** format (e.g. see macros FTS5_POS2COLUMN() and FTS5_POS2OFFSET()).
248716
+**
248717
+** iIter:
248718
+** If the Fts5TokenDataIter iterator that the entry is part of is
248719
+** actually an iterator (i.e. with nIter>0, not just a container for
248720
+** Fts5TokenDataMap structures), then this variable is an index into
248721
+** the apIter[] array. The corresponding term is that which the iterator
248722
+** at apIter[iIter] currently points to.
248723
+**
248724
+** Or, if the Fts5TokenDataIter iterator is just a container object
248725
+** (nIter==0), then iIter is an index into the term.p[] buffer where
248726
+** the term is stored.
248727
+**
248728
+** nByte:
248729
+** In the case where iIter is an index into term.p[], this variable
248730
+** is the size of the term in bytes. If iIter is an index into apIter[],
248731
+** this variable is unused.
248732
+*/
248733
+struct Fts5TokenDataMap {
248734
+ i64 iRowid; /* Row this token is located in */
248735
+ i64 iPos; /* Position of token */
248736
+ int iIter; /* Iterator token was read from */
248737
+ int nByte; /* Length of token in bytes (or 0) */
248738
+};
248739
+
248740
+/*
248741
+** An object used to supplement Fts5Iter for tokendata=1 iterators.
248742
+**
248743
+** This object serves two purposes. The first is as a container for an array
248744
+** of Fts5TokenDataMap structures, which are used to find the token required
248745
+** when the xInstToken() API is used. This is done by the nMapAlloc, nMap and
248746
+** aMap[] variables.
248747
+*/
248748
+struct Fts5TokenDataIter {
248749
+ int nMapAlloc; /* Allocated size of aMap[] in entries */
248750
+ int nMap; /* Number of valid entries in aMap[] */
248751
+ Fts5TokenDataMap *aMap; /* Array of (rowid+pos -> token) mappings */
248752
+
248753
+ /* The following are used for prefix-queries only. */
248754
+ Fts5Buffer terms;
248755
+
248756
+ /* The following are used for other full-token tokendata queries only. */
248757
+ int nIter;
248758
+ int nIterAlloc;
248759
+ Fts5PoslistReader *aPoslistReader;
248760
+ int *aPoslistToIter;
248761
+ Fts5Iter *apIter[1];
248762
+};
248763
+
248764
+/*
248765
+** The two input arrays - a1[] and a2[] - are in sorted order. This function
248766
+** merges the two arrays together and writes the result to output array
248767
+** aOut[]. aOut[] is guaranteed to be large enough to hold the result.
248768
+**
248769
+** Duplicate entries are copied into the output. So the size of the output
248770
+** array is always (n1+n2) entries.
248771
+*/
248772
+static void fts5TokendataMerge(
248773
+ Fts5TokenDataMap *a1, int n1, /* Input array 1 */
248774
+ Fts5TokenDataMap *a2, int n2, /* Input array 2 */
248775
+ Fts5TokenDataMap *aOut /* Output array */
248776
+){
248777
+ int i1 = 0;
248778
+ int i2 = 0;
248779
+
248780
+ assert( n1>=0 && n2>=0 );
248781
+ while( i1<n1 || i2<n2 ){
248782
+ Fts5TokenDataMap *pOut = &aOut[i1+i2];
248783
+ if( i2>=n2 || (i1<n1 && (
248784
+ a1[i1].iRowid<a2[i2].iRowid
248785
+ || (a1[i1].iRowid==a2[i2].iRowid && a1[i1].iPos<=a2[i2].iPos)
248786
+ ))){
248787
+ memcpy(pOut, &a1[i1], sizeof(Fts5TokenDataMap));
248788
+ i1++;
248789
+ }else{
248790
+ memcpy(pOut, &a2[i2], sizeof(Fts5TokenDataMap));
248791
+ i2++;
248792
+ }
248793
+ }
248794
+}
248795
+
248796
+
248797
+/*
248798
+** Append a mapping to the token-map belonging to object pT.
248799
+*/
248800
+static void fts5TokendataIterAppendMap(
248801
+ Fts5Index *p,
248802
+ Fts5TokenDataIter *pT,
248803
+ int iIter,
248804
+ int nByte,
248805
+ i64 iRowid,
248806
+ i64 iPos
248807
+){
248808
+ if( p->rc==SQLITE_OK ){
248809
+ if( pT->nMap==pT->nMapAlloc ){
248810
+ int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64;
248811
+ int nAlloc = nNew * sizeof(Fts5TokenDataMap);
248812
+ Fts5TokenDataMap *aNew;
248813
+
248814
+ aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nAlloc);
248815
+ if( aNew==0 ){
248816
+ p->rc = SQLITE_NOMEM;
248817
+ return;
248818
+ }
248819
+
248820
+ pT->aMap = aNew;
248821
+ pT->nMapAlloc = nNew;
248822
+ }
248823
+
248824
+ pT->aMap[pT->nMap].iRowid = iRowid;
248825
+ pT->aMap[pT->nMap].iPos = iPos;
248826
+ pT->aMap[pT->nMap].iIter = iIter;
248827
+ pT->aMap[pT->nMap].nByte = nByte;
248828
+ pT->nMap++;
248829
+ }
248830
+}
248831
+
248832
+/*
248833
+** Sort the contents of the pT->aMap[] array.
248834
+**
248835
+** The sorting algorithm requries a malloc(). If this fails, an error code
248836
+** is left in Fts5Index.rc before returning.
248837
+*/
248838
+static void fts5TokendataIterSortMap(Fts5Index *p, Fts5TokenDataIter *pT){
248839
+ Fts5TokenDataMap *aTmp = 0;
248840
+ int nByte = pT->nMap * sizeof(Fts5TokenDataMap);
248841
+
248842
+ aTmp = (Fts5TokenDataMap*)sqlite3Fts5MallocZero(&p->rc, nByte);
248843
+ if( aTmp ){
248844
+ Fts5TokenDataMap *a1 = pT->aMap;
248845
+ Fts5TokenDataMap *a2 = aTmp;
248846
+ i64 nHalf;
248847
+
248848
+ for(nHalf=1; nHalf<pT->nMap; nHalf=nHalf*2){
248849
+ int i1;
248850
+ for(i1=0; i1<pT->nMap; i1+=(nHalf*2)){
248851
+ int n1 = MIN(nHalf, pT->nMap-i1);
248852
+ int n2 = MIN(nHalf, pT->nMap-i1-n1);
248853
+ fts5TokendataMerge(&a1[i1], n1, &a1[i1+n1], n2, &a2[i1]);
248854
+ }
248855
+ SWAPVAL(Fts5TokenDataMap*, a1, a2);
248856
+ }
248857
+
248858
+ if( a1!=pT->aMap ){
248859
+ memcpy(pT->aMap, a1, pT->nMap*sizeof(Fts5TokenDataMap));
248860
+ }
248861
+ sqlite3_free(aTmp);
248862
+
248863
+#ifdef SQLITE_DEBUG
248864
+ {
248865
+ int ii;
248866
+ for(ii=1; ii<pT->nMap; ii++){
248867
+ Fts5TokenDataMap *p1 = &pT->aMap[ii-1];
248868
+ Fts5TokenDataMap *p2 = &pT->aMap[ii];
248869
+ assert( p1->iRowid<p2->iRowid
248870
+ || (p1->iRowid==p2->iRowid && p1->iPos<=p2->iPos)
248871
+ );
248872
+ }
248873
+ }
248874
+#endif
248875
+ }
248876
+}
248877
+
248878
+/*
248879
+** Delete an Fts5TokenDataIter structure and its contents.
248880
+*/
248881
+static void fts5TokendataIterDelete(Fts5TokenDataIter *pSet){
248882
+ if( pSet ){
248883
+ int ii;
248884
+ for(ii=0; ii<pSet->nIter; ii++){
248885
+ fts5MultiIterFree(pSet->apIter[ii]);
248886
+ }
248887
+ fts5BufferFree(&pSet->terms);
248888
+ sqlite3_free(pSet->aPoslistReader);
248889
+ sqlite3_free(pSet->aMap);
248890
+ sqlite3_free(pSet);
248891
+ }
248892
+}
248893
+
248894
+
248895
+/*
248896
+** fts5VisitEntries() context object used by fts5SetupPrefixIterTokendata()
248897
+** to pass data to prefixIterSetupTokendataCb().
248898
+*/
248899
+typedef struct TokendataSetupCtx TokendataSetupCtx;
248900
+struct TokendataSetupCtx {
248901
+ Fts5TokenDataIter *pT; /* Object being populated with mappings */
248902
+ int iTermOff; /* Offset of current term in terms.p[] */
248903
+ int nTermByte; /* Size of current term in bytes */
248904
+};
248905
+
248906
+/*
248907
+** fts5VisitEntries() callback used by fts5SetupPrefixIterTokendata(). This
248908
+** callback adds an entry to the Fts5TokenDataIter.aMap[] array for each
248909
+** position in the current position-list. It doesn't matter that some of
248910
+** these may be out of order - they will be sorted later.
248911
+*/
248912
+static void prefixIterSetupTokendataCb(
248913
+ Fts5Index *p,
248914
+ void *pCtx,
248915
+ Fts5Iter *p1,
248916
+ const u8 *pNew,
248917
+ int nNew
248918
+){
248919
+ TokendataSetupCtx *pSetup = (TokendataSetupCtx*)pCtx;
248920
+ int iPosOff = 0;
248921
+ i64 iPos = 0;
248922
+
248923
+ if( pNew ){
248924
+ pSetup->nTermByte = nNew-1;
248925
+ pSetup->iTermOff = pSetup->pT->terms.n;
248926
+ fts5BufferAppendBlob(&p->rc, &pSetup->pT->terms, nNew-1, pNew+1);
248927
+ }
248928
+
248929
+ while( 0==sqlite3Fts5PoslistNext64(
248930
+ p1->base.pData, p1->base.nData, &iPosOff, &iPos
248931
+ ) ){
248932
+ fts5TokendataIterAppendMap(p,
248933
+ pSetup->pT, pSetup->iTermOff, pSetup->nTermByte, p1->base.iRowid, iPos
248934
+ );
248935
+ }
248936
+}
248937
+
248938
+
248939
+/*
248940
+** Context object passed by fts5SetupPrefixIter() to fts5VisitEntries().
248941
+*/
248942
+typedef struct PrefixSetupCtx PrefixSetupCtx;
248943
+struct PrefixSetupCtx {
248944
+ void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*);
248945
+ void (*xAppend)(Fts5Index*, u64, Fts5Iter*, Fts5Buffer*);
248946
+ i64 iLastRowid;
248947
+ int nMerge;
248948
+ Fts5Buffer *aBuf;
248949
+ int nBuf;
248950
+ Fts5Buffer doclist;
248951
+ TokendataSetupCtx *pTokendata;
248952
+};
248953
+
248954
+/*
248955
+** fts5VisitEntries() callback used by fts5SetupPrefixIter()
248956
+*/
248957
+static void prefixIterSetupCb(
248958
+ Fts5Index *p,
248959
+ void *pCtx,
248960
+ Fts5Iter *p1,
248961
+ const u8 *pNew,
248962
+ int nNew
248963
+){
248964
+ PrefixSetupCtx *pSetup = (PrefixSetupCtx*)pCtx;
248965
+ const int nMerge = pSetup->nMerge;
248966
+
248967
+ if( p1->base.nData>0 ){
248968
+ if( p1->base.iRowid<=pSetup->iLastRowid && pSetup->doclist.n>0 ){
248969
+ int i;
248970
+ for(i=0; p->rc==SQLITE_OK && pSetup->doclist.n; i++){
248971
+ int i1 = i*nMerge;
248972
+ int iStore;
248973
+ assert( i1+nMerge<=pSetup->nBuf );
248974
+ for(iStore=i1; iStore<i1+nMerge; iStore++){
248975
+ if( pSetup->aBuf[iStore].n==0 ){
248976
+ fts5BufferSwap(&pSetup->doclist, &pSetup->aBuf[iStore]);
248977
+ fts5BufferZero(&pSetup->doclist);
248978
+ break;
248979
+ }
248980
+ }
248981
+ if( iStore==i1+nMerge ){
248982
+ pSetup->xMerge(p, &pSetup->doclist, nMerge, &pSetup->aBuf[i1]);
248983
+ for(iStore=i1; iStore<i1+nMerge; iStore++){
248984
+ fts5BufferZero(&pSetup->aBuf[iStore]);
248985
+ }
248986
+ }
248987
+ }
248988
+ pSetup->iLastRowid = 0;
248989
+ }
248990
+
248991
+ pSetup->xAppend(
248992
+ p, (u64)p1->base.iRowid-(u64)pSetup->iLastRowid, p1, &pSetup->doclist
248993
+ );
248994
+ pSetup->iLastRowid = p1->base.iRowid;
248995
+ }
248996
+
248997
+ if( pSetup->pTokendata ){
248998
+ prefixIterSetupTokendataCb(p, (void*)pSetup->pTokendata, p1, pNew, nNew);
248999
+ }
249000
+}
249001
+
249273249002
static void fts5SetupPrefixIter(
249274249003
Fts5Index *p, /* Index to read from */
249275249004
int bDesc, /* True for "ORDER BY rowid DESC" */
249276249005
int iIdx, /* Index to scan for data */
249277249006
u8 *pToken, /* Buffer containing prefix to match */
@@ -249278,137 +249007,89 @@
249278249007
int nToken, /* Size of buffer pToken in bytes */
249279249008
Fts5Colset *pColset, /* Restrict matches to these columns */
249280249009
Fts5Iter **ppIter /* OUT: New iterator */
249281249010
){
249282249011
Fts5Structure *pStruct;
249283
- Fts5Buffer *aBuf;
249284
- int nBuf = 32;
249285
- int nMerge = 1;
249012
+ PrefixSetupCtx s;
249013
+ TokendataSetupCtx s2;
249286249014
249287
- void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*);
249288
- void (*xAppend)(Fts5Index*, u64, Fts5Iter*, Fts5Buffer*);
249015
+ memset(&s, 0, sizeof(s));
249016
+ memset(&s2, 0, sizeof(s2));
249017
+
249018
+ s.nMerge = 1;
249019
+ s.iLastRowid = 0;
249020
+ s.nBuf = 32;
249021
+ if( iIdx==0
249022
+ && p->pConfig->eDetail==FTS5_DETAIL_FULL
249023
+ && p->pConfig->bPrefixInsttoken
249024
+ ){
249025
+ s.pTokendata = &s2;
249026
+ s2.pT = (Fts5TokenDataIter*)fts5IdxMalloc(p, sizeof(*s2.pT));
249027
+ }
249028
+
249289249029
if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
249290
- xMerge = fts5MergeRowidLists;
249291
- xAppend = fts5AppendRowid;
249030
+ s.xMerge = fts5MergeRowidLists;
249031
+ s.xAppend = fts5AppendRowid;
249292249032
}else{
249293
- nMerge = FTS5_MERGE_NLIST-1;
249294
- nBuf = nMerge*8; /* Sufficient to merge (16^8)==(2^32) lists */
249295
- xMerge = fts5MergePrefixLists;
249296
- xAppend = fts5AppendPoslist;
249033
+ s.nMerge = FTS5_MERGE_NLIST-1;
249034
+ s.nBuf = s.nMerge*8; /* Sufficient to merge (16^8)==(2^32) lists */
249035
+ s.xMerge = fts5MergePrefixLists;
249036
+ s.xAppend = fts5AppendPoslist;
249297249037
}
249298249038
249299
- aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf);
249039
+ s.aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*s.nBuf);
249300249040
pStruct = fts5StructureRead(p);
249301
- assert( p->rc!=SQLITE_OK || (aBuf && pStruct) );
249041
+ assert( p->rc!=SQLITE_OK || (s.aBuf && pStruct) );
249302249042
249303249043
if( p->rc==SQLITE_OK ){
249304
- const int flags = FTS5INDEX_QUERY_SCAN
249305
- | FTS5INDEX_QUERY_SKIPEMPTY
249306
- | FTS5INDEX_QUERY_NOOUTPUT;
249044
+ void *pCtx = (void*)&s;
249307249045
int i;
249308
- i64 iLastRowid = 0;
249309
- Fts5Iter *p1 = 0; /* Iterator used to gather data from index */
249310249046
Fts5Data *pData;
249311
- Fts5Buffer doclist;
249312
- int bNewTerm = 1;
249313
-
249314
- memset(&doclist, 0, sizeof(doclist));
249315249047
249316249048
/* If iIdx is non-zero, then it is the number of a prefix-index for
249317249049
** prefixes 1 character longer than the prefix being queried for. That
249318249050
** index contains all the doclists required, except for the one
249319249051
** corresponding to the prefix itself. That one is extracted from the
249320249052
** main term index here. */
249321249053
if( iIdx!=0 ){
249322
- int dummy = 0;
249323
- const int f2 = FTS5INDEX_QUERY_SKIPEMPTY|FTS5INDEX_QUERY_NOOUTPUT;
249324249054
pToken[0] = FTS5_MAIN_PREFIX;
249325
- fts5MultiIterNew(p, pStruct, f2, pColset, pToken, nToken, -1, 0, &p1);
249326
- fts5IterSetOutputCb(&p->rc, p1);
249327
- for(;
249328
- fts5MultiIterEof(p, p1)==0;
249329
- fts5MultiIterNext2(p, p1, &dummy)
249330
- ){
249331
- Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ];
249332
- p1->xSetOutputs(p1, pSeg);
249333
- if( p1->base.nData ){
249334
- xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist);
249335
- iLastRowid = p1->base.iRowid;
249336
- }
249337
- }
249338
- fts5MultiIterFree(p1);
249055
+ fts5VisitEntries(p, pColset, pToken, nToken, 0, prefixIterSetupCb, pCtx);
249339249056
}
249340249057
249341249058
pToken[0] = FTS5_MAIN_PREFIX + iIdx;
249342
- fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1);
249343
- fts5IterSetOutputCb(&p->rc, p1);
249344
-
249345
- for( /* no-op */ ;
249346
- fts5MultiIterEof(p, p1)==0;
249347
- fts5MultiIterNext2(p, p1, &bNewTerm)
249348
- ){
249349
- Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ];
249350
- int nTerm = pSeg->term.n;
249351
- const u8 *pTerm = pSeg->term.p;
249352
- p1->xSetOutputs(p1, pSeg);
249353
-
249354
- assert_nc( memcmp(pToken, pTerm, MIN(nToken, nTerm))<=0 );
249355
- if( bNewTerm ){
249356
- if( nTerm<nToken || memcmp(pToken, pTerm, nToken) ) break;
249357
- }
249358
-
249359
- if( p1->base.nData==0 ) continue;
249360
- if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){
249361
- for(i=0; p->rc==SQLITE_OK && doclist.n; i++){
249362
- int i1 = i*nMerge;
249363
- int iStore;
249364
- assert( i1+nMerge<=nBuf );
249365
- for(iStore=i1; iStore<i1+nMerge; iStore++){
249366
- if( aBuf[iStore].n==0 ){
249367
- fts5BufferSwap(&doclist, &aBuf[iStore]);
249368
- fts5BufferZero(&doclist);
249369
- break;
249370
- }
249371
- }
249372
- if( iStore==i1+nMerge ){
249373
- xMerge(p, &doclist, nMerge, &aBuf[i1]);
249374
- for(iStore=i1; iStore<i1+nMerge; iStore++){
249375
- fts5BufferZero(&aBuf[iStore]);
249376
- }
249377
- }
249378
- }
249379
- iLastRowid = 0;
249380
- }
249381
-
249382
- xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist);
249383
- iLastRowid = p1->base.iRowid;
249384
- }
249385
-
249386
- assert( (nBuf%nMerge)==0 );
249387
- for(i=0; i<nBuf; i+=nMerge){
249059
+ fts5VisitEntries(p, pColset, pToken, nToken, 1, prefixIterSetupCb, pCtx);
249060
+
249061
+ assert( (s.nBuf%s.nMerge)==0 );
249062
+ for(i=0; i<s.nBuf; i+=s.nMerge){
249388249063
int iFree;
249389249064
if( p->rc==SQLITE_OK ){
249390
- xMerge(p, &doclist, nMerge, &aBuf[i]);
249065
+ s.xMerge(p, &s.doclist, s.nMerge, &s.aBuf[i]);
249391249066
}
249392
- for(iFree=i; iFree<i+nMerge; iFree++){
249393
- fts5BufferFree(&aBuf[iFree]);
249067
+ for(iFree=i; iFree<i+s.nMerge; iFree++){
249068
+ fts5BufferFree(&s.aBuf[iFree]);
249394249069
}
249395249070
}
249396
- fts5MultiIterFree(p1);
249397249071
249398
- pData = fts5IdxMalloc(p, sizeof(*pData)+doclist.n+FTS5_DATA_ZERO_PADDING);
249072
+ pData = fts5IdxMalloc(p, sizeof(*pData)+s.doclist.n+FTS5_DATA_ZERO_PADDING);
249399249073
if( pData ){
249400249074
pData->p = (u8*)&pData[1];
249401
- pData->nn = pData->szLeaf = doclist.n;
249402
- if( doclist.n ) memcpy(pData->p, doclist.p, doclist.n);
249075
+ pData->nn = pData->szLeaf = s.doclist.n;
249076
+ if( s.doclist.n ) memcpy(pData->p, s.doclist.p, s.doclist.n);
249403249077
fts5MultiIterNew2(p, pData, bDesc, ppIter);
249404249078
}
249405
- fts5BufferFree(&doclist);
249079
+
249080
+ if( p->rc==SQLITE_OK && s.pTokendata ){
249081
+ fts5TokendataIterSortMap(p, s2.pT);
249082
+ (*ppIter)->pTokenDataIter = s2.pT;
249083
+ s2.pT = 0;
249084
+ }
249406249085
}
249407249086
249087
+ fts5TokendataIterDelete(s2.pT);
249088
+ fts5BufferFree(&s.doclist);
249408249089
fts5StructureRelease(pStruct);
249409
- sqlite3_free(aBuf);
249090
+ sqlite3_free(s.aBuf);
249410249091
}
249411249092
249412249093
249413249094
/*
249414249095
** Indicate that all subsequent calls to sqlite3Fts5IndexWrite() pertain
@@ -249658,42 +249339,10 @@
249658249339
static void fts5SegIterSetEOF(Fts5SegIter *pSeg){
249659249340
fts5DataRelease(pSeg->pLeaf);
249660249341
pSeg->pLeaf = 0;
249661249342
}
249662249343
249663
-/*
249664
-** Usually, a tokendata=1 iterator (struct Fts5TokenDataIter) accumulates an
249665
-** array of these for each row it visits. Or, for an iterator used by an
249666
-** "ORDER BY rank" query, it accumulates an array of these for the entire
249667
-** query.
249668
-**
249669
-** Each instance in the array indicates the iterator (and therefore term)
249670
-** associated with position iPos of rowid iRowid. This is used by the
249671
-** xInstToken() API.
249672
-*/
249673
-struct Fts5TokenDataMap {
249674
- i64 iRowid; /* Row this token is located in */
249675
- i64 iPos; /* Position of token */
249676
- int iIter; /* Iterator token was read from */
249677
-};
249678
-
249679
-/*
249680
-** An object used to supplement Fts5Iter for tokendata=1 iterators.
249681
-*/
249682
-struct Fts5TokenDataIter {
249683
- int nIter;
249684
- int nIterAlloc;
249685
-
249686
- int nMap;
249687
- int nMapAlloc;
249688
- Fts5TokenDataMap *aMap;
249689
-
249690
- Fts5PoslistReader *aPoslistReader;
249691
- int *aPoslistToIter;
249692
- Fts5Iter *apIter[1];
249693
-};
249694
-
249695249344
/*
249696249345
** This function appends iterator pAppend to Fts5TokenDataIter pIn and
249697249346
** returns the result.
249698249347
*/
249699249348
static Fts5TokenDataIter *fts5AppendTokendataIter(
@@ -249726,58 +249375,10 @@
249726249375
assert( pRet==0 || pRet->nIter<=pRet->nIterAlloc );
249727249376
249728249377
return pRet;
249729249378
}
249730249379
249731
-/*
249732
-** Delete an Fts5TokenDataIter structure and its contents.
249733
-*/
249734
-static void fts5TokendataIterDelete(Fts5TokenDataIter *pSet){
249735
- if( pSet ){
249736
- int ii;
249737
- for(ii=0; ii<pSet->nIter; ii++){
249738
- fts5MultiIterFree(pSet->apIter[ii]);
249739
- }
249740
- sqlite3_free(pSet->aPoslistReader);
249741
- sqlite3_free(pSet->aMap);
249742
- sqlite3_free(pSet);
249743
- }
249744
-}
249745
-
249746
-/*
249747
-** Append a mapping to the token-map belonging to object pT.
249748
-*/
249749
-static void fts5TokendataIterAppendMap(
249750
- Fts5Index *p,
249751
- Fts5TokenDataIter *pT,
249752
- int iIter,
249753
- i64 iRowid,
249754
- i64 iPos
249755
-){
249756
- if( p->rc==SQLITE_OK ){
249757
- if( pT->nMap==pT->nMapAlloc ){
249758
- int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64;
249759
- int nByte = nNew * sizeof(Fts5TokenDataMap);
249760
- Fts5TokenDataMap *aNew;
249761
-
249762
- aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nByte);
249763
- if( aNew==0 ){
249764
- p->rc = SQLITE_NOMEM;
249765
- return;
249766
- }
249767
-
249768
- pT->aMap = aNew;
249769
- pT->nMapAlloc = nNew;
249770
- }
249771
-
249772
- pT->aMap[pT->nMap].iRowid = iRowid;
249773
- pT->aMap[pT->nMap].iPos = iPos;
249774
- pT->aMap[pT->nMap].iIter = iIter;
249775
- pT->nMap++;
249776
- }
249777
-}
249778
-
249779249380
/*
249780249381
** The iterator passed as the only argument must be a tokendata=1 iterator
249781249382
** (pIter->pTokenDataIter!=0). This function sets the iterator output
249782249383
** variables (pIter->base.*) according to the contents of the current
249783249384
** row.
@@ -249814,11 +249415,11 @@
249814249415
int eDetail = pIter->pIndex->pConfig->eDetail;
249815249416
pIter->base.bEof = 0;
249816249417
pIter->base.iRowid = iRowid;
249817249418
249818249419
if( nHit==1 && eDetail==FTS5_DETAIL_FULL ){
249819
- fts5TokendataIterAppendMap(pIter->pIndex, pT, iMin, iRowid, -1);
249420
+ fts5TokendataIterAppendMap(pIter->pIndex, pT, iMin, 0, iRowid, -1);
249820249421
}else
249821249422
if( nHit>1 && eDetail!=FTS5_DETAIL_NONE ){
249822249423
int nReader = 0;
249823249424
int nByte = 0;
249824249425
i64 iPrev = 0;
@@ -250067,10 +249668,11 @@
250067249668
250068249669
if( p->rc==SQLITE_OK ){
250069249670
pRet = fts5MultiIterAlloc(p, 0);
250070249671
}
250071249672
if( pRet ){
249673
+ pRet->nSeg = 0;
250072249674
pRet->pTokenDataIter = pSet;
250073249675
if( pSet ){
250074249676
fts5IterSetOutputsTokendata(pRet);
250075249677
}else{
250076249678
pRet->base.bEof = 1;
@@ -250081,11 +249683,10 @@
250081249683
250082249684
fts5StructureRelease(pStruct);
250083249685
fts5BufferFree(&bSeek);
250084249686
return pRet;
250085249687
}
250086
-
250087249688
250088249689
/*
250089249690
** Open a new iterator to iterate though all rowid that match the
250090249691
** specified token or token prefix.
250091249692
*/
@@ -250107,10 +249708,15 @@
250107249708
int iIdx = 0; /* Index to search */
250108249709
int iPrefixIdx = 0; /* +1 prefix index */
250109249710
int bTokendata = pConfig->bTokendata;
250110249711
if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken);
250111249712
249713
+ /* The NOTOKENDATA flag is set when each token in a tokendata=1 table
249714
+ ** should be treated individually, instead of merging all those with
249715
+ ** a common prefix into a single entry. This is used, for example, by
249716
+ ** queries performed as part of an integrity-check, or by the fts5vocab
249717
+ ** module. */
250112249718
if( flags & (FTS5INDEX_QUERY_NOTOKENDATA|FTS5INDEX_QUERY_SCAN) ){
250113249719
bTokendata = 0;
250114249720
}
250115249721
250116249722
/* Figure out which index to search and set iIdx accordingly. If this
@@ -250137,11 +249743,11 @@
250137249743
if( nIdxChar==nChar+1 ) iPrefixIdx = iIdx;
250138249744
}
250139249745
}
250140249746
250141249747
if( bTokendata && iIdx==0 ){
250142
- buf.p[0] = '0';
249748
+ buf.p[0] = FTS5_MAIN_PREFIX;
250143249749
pRet = fts5SetupTokendataIter(p, buf.p, nToken+1, pColset);
250144249750
}else if( iIdx<=pConfig->nPrefix ){
250145249751
/* Straight index lookup */
250146249752
Fts5Structure *pStruct = fts5StructureRead(p);
250147249753
buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx);
@@ -250150,11 +249756,11 @@
250150249756
pColset, buf.p, nToken+1, -1, 0, &pRet
250151249757
);
250152249758
fts5StructureRelease(pStruct);
250153249759
}
250154249760
}else{
250155
- /* Scan multiple terms in the main index */
249761
+ /* Scan multiple terms in the main index for a prefix query. */
250156249762
int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0;
250157249763
fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet);
250158249764
if( pRet==0 ){
250159249765
assert( p->rc!=SQLITE_OK );
250160249766
}else{
@@ -250186,11 +249792,12 @@
250186249792
** Move to the next matching rowid.
250187249793
*/
250188249794
static int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){
250189249795
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
250190249796
assert( pIter->pIndex->rc==SQLITE_OK );
250191
- if( pIter->pTokenDataIter ){
249797
+ if( pIter->nSeg==0 ){
249798
+ assert( pIter->pTokenDataIter );
250192249799
fts5TokendataIterNext(pIter, 0, 0);
250193249800
}else{
250194249801
fts5MultiIterNext(pIter->pIndex, pIter, 0, 0);
250195249802
}
250196249803
return fts5IndexReturn(pIter->pIndex);
@@ -250223,11 +249830,12 @@
250223249830
** definition of "at or after" depends on whether this iterator iterates
250224249831
** in ascending or descending rowid order.
250225249832
*/
250226249833
static int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){
250227249834
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
250228
- if( pIter->pTokenDataIter ){
249835
+ if( pIter->nSeg==0 ){
249836
+ assert( pIter->pTokenDataIter );
250229249837
fts5TokendataIterNext(pIter, 1, iMatch);
250230249838
}else{
250231249839
fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch);
250232249840
}
250233249841
return fts5IndexReturn(pIter->pIndex);
@@ -250241,32 +249849,87 @@
250241249849
const char *z = (const char*)fts5MultiIterTerm((Fts5Iter*)pIndexIter, &n);
250242249850
assert_nc( z || n<=1 );
250243249851
*pn = n-1;
250244249852
return (z ? &z[1] : 0);
250245249853
}
249854
+
249855
+/*
249856
+** pIter is a prefix query. This function populates pIter->pTokenDataIter
249857
+** with an Fts5TokenDataIter object containing mappings for all rows
249858
+** matched by the query.
249859
+*/
249860
+static int fts5SetupPrefixIterTokendata(
249861
+ Fts5Iter *pIter,
249862
+ const char *pToken, /* Token prefix to search for */
249863
+ int nToken /* Size of pToken in bytes */
249864
+){
249865
+ Fts5Index *p = pIter->pIndex;
249866
+ Fts5Buffer token = {0, 0, 0};
249867
+ TokendataSetupCtx ctx;
249868
+
249869
+ memset(&ctx, 0, sizeof(ctx));
249870
+
249871
+ fts5BufferGrow(&p->rc, &token, nToken+1);
249872
+ ctx.pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*ctx.pT));
249873
+
249874
+ if( p->rc==SQLITE_OK ){
249875
+
249876
+ /* Fill in the token prefix to search for */
249877
+ token.p[0] = FTS5_MAIN_PREFIX;
249878
+ memcpy(&token.p[1], pToken, nToken);
249879
+ token.n = nToken+1;
249880
+
249881
+ fts5VisitEntries(
249882
+ p, 0, token.p, token.n, 1, prefixIterSetupTokendataCb, (void*)&ctx
249883
+ );
249884
+
249885
+ fts5TokendataIterSortMap(p, ctx.pT);
249886
+ }
249887
+
249888
+ if( p->rc==SQLITE_OK ){
249889
+ pIter->pTokenDataIter = ctx.pT;
249890
+ }else{
249891
+ fts5TokendataIterDelete(ctx.pT);
249892
+ }
249893
+ fts5BufferFree(&token);
249894
+
249895
+ return fts5IndexReturn(p);
249896
+}
250246249897
250247249898
/*
250248249899
** This is used by xInstToken() to access the token at offset iOff, column
250249249900
** iCol of row iRowid. The token is returned via output variables *ppOut
250250249901
** and *pnOut. The iterator passed as the first argument must be a tokendata=1
250251249902
** iterator (pIter->pTokenDataIter!=0).
249903
+**
249904
+** pToken/nToken:
250252249905
*/
250253249906
static int sqlite3Fts5IterToken(
250254249907
Fts5IndexIter *pIndexIter,
249908
+ const char *pToken, int nToken,
250255249909
i64 iRowid,
250256249910
int iCol,
250257249911
int iOff,
250258249912
const char **ppOut, int *pnOut
250259249913
){
250260249914
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
250261249915
Fts5TokenDataIter *pT = pIter->pTokenDataIter;
250262
- Fts5TokenDataMap *aMap = pT->aMap;
250263249916
i64 iPos = (((i64)iCol)<<32) + iOff;
250264
-
249917
+ Fts5TokenDataMap *aMap = 0;
250265249918
int i1 = 0;
250266
- int i2 = pT->nMap;
249919
+ int i2 = 0;
250267249920
int iTest = 0;
249921
+
249922
+ assert( pT || (pToken && pIter->nSeg>0) );
249923
+ if( pT==0 ){
249924
+ int rc = fts5SetupPrefixIterTokendata(pIter, pToken, nToken);
249925
+ if( rc!=SQLITE_OK ) return rc;
249926
+ pT = pIter->pTokenDataIter;
249927
+ }
249928
+
249929
+ i2 = pT->nMap;
249930
+ aMap = pT->aMap;
250268249931
250269249932
while( i2>i1 ){
250270249933
iTest = (i1 + i2) / 2;
250271249934
250272249935
if( aMap[iTest].iRowid<iRowid ){
@@ -250286,13 +249949,19 @@
250286249949
}
250287249950
}
250288249951
}
250289249952
250290249953
if( i2>i1 ){
250291
- Fts5Iter *pMap = pT->apIter[aMap[iTest].iIter];
250292
- *ppOut = (const char*)pMap->aSeg[0].term.p+1;
250293
- *pnOut = pMap->aSeg[0].term.n-1;
249954
+ if( pIter->nSeg==0 ){
249955
+ Fts5Iter *pMap = pT->apIter[aMap[iTest].iIter];
249956
+ *ppOut = (const char*)pMap->aSeg[0].term.p+1;
249957
+ *pnOut = pMap->aSeg[0].term.n-1;
249958
+ }else{
249959
+ Fts5TokenDataMap *p = &aMap[iTest];
249960
+ *ppOut = (const char*)&pT->terms.p[p->iIter];
249961
+ *pnOut = aMap[iTest].nByte;
249962
+ }
250294249963
}
250295249964
250296249965
return SQLITE_OK;
250297249966
}
250298249967
@@ -250300,11 +249969,13 @@
250300249969
** Clear any existing entries from the token-map associated with the
250301249970
** iterator passed as the only argument.
250302249971
*/
250303249972
static void sqlite3Fts5IndexIterClearTokendata(Fts5IndexIter *pIndexIter){
250304249973
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
250305
- if( pIter && pIter->pTokenDataIter ){
249974
+ if( pIter && pIter->pTokenDataIter
249975
+ && (pIter->nSeg==0 || pIter->pIndex->pConfig->eDetail!=FTS5_DETAIL_FULL)
249976
+ ){
250306249977
pIter->pTokenDataIter->nMap = 0;
250307249978
}
250308249979
}
250309249980
250310249981
/*
@@ -250320,21 +249991,33 @@
250320249991
i64 iRowid, int iCol, int iOff
250321249992
){
250322249993
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
250323249994
Fts5TokenDataIter *pT = pIter->pTokenDataIter;
250324249995
Fts5Index *p = pIter->pIndex;
250325
- int ii;
249996
+ i64 iPos = (((i64)iCol)<<32) + iOff;
250326249997
250327249998
assert( p->pConfig->eDetail!=FTS5_DETAIL_FULL );
250328
- assert( pIter->pTokenDataIter );
250329
-
250330
- for(ii=0; ii<pT->nIter; ii++){
250331
- Fts5Buffer *pTerm = &pT->apIter[ii]->aSeg[0].term;
250332
- if( nToken==pTerm->n-1 && memcmp(pToken, pTerm->p+1, nToken)==0 ) break;
250333
- }
250334
- if( ii<pT->nIter ){
250335
- fts5TokendataIterAppendMap(p, pT, ii, iRowid, (((i64)iCol)<<32) + iOff);
249999
+ assert( pIter->pTokenDataIter || pIter->nSeg>0 );
250000
+ if( pIter->nSeg>0 ){
250001
+ /* This is a prefix term iterator. */
250002
+ if( pT==0 ){
250003
+ pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*pT));
250004
+ pIter->pTokenDataIter = pT;
250005
+ }
250006
+ if( pT ){
250007
+ fts5TokendataIterAppendMap(p, pT, pT->terms.n, nToken, iRowid, iPos);
250008
+ fts5BufferAppendBlob(&p->rc, &pT->terms, nToken, (const u8*)pToken);
250009
+ }
250010
+ }else{
250011
+ int ii;
250012
+ for(ii=0; ii<pT->nIter; ii++){
250013
+ Fts5Buffer *pTerm = &pT->apIter[ii]->aSeg[0].term;
250014
+ if( nToken==pTerm->n-1 && memcmp(pToken, pTerm->p+1, nToken)==0 ) break;
250015
+ }
250016
+ if( ii<pT->nIter ){
250017
+ fts5TokendataIterAppendMap(p, pT, ii, 0, iRowid, iPos);
250018
+ }
250336250019
}
250337250020
return fts5IndexReturn(p);
250338250021
}
250339250022
250340250023
/*
@@ -252140,11 +251823,10 @@
252140251823
fts5StructureInvalidate(p);
252141251824
}
252142251825
return fts5IndexReturn(p);
252143251826
}
252144251827
252145
-#line 1 "fts5_main.c"
252146251828
/*
252147251829
** 2014 Jun 09
252148251830
**
252149251831
** The author disclaims copyright to this source code. In place of
252150251832
** a legal notice, here is a blessing:
@@ -252236,10 +251918,11 @@
252236251918
** containing a copy of the header from an Fts5Config pointer.
252237251919
*/
252238251920
#define FTS5_LOCALE_HDR_SIZE ((int)sizeof( ((Fts5Global*)0)->aLocaleHdr ))
252239251921
#define FTS5_LOCALE_HDR(pConfig) ((const u8*)(pConfig->pGlobal->aLocaleHdr))
252240251922
251923
+#define FTS5_INSTTOKEN_SUBTYPE 73
252241251924
252242251925
/*
252243251926
** Each auxiliary function registered with the FTS5 module is represented
252244251927
** by an object of the following type. All such objects are stored as part
252245251928
** of the Fts5Global.pAux list.
@@ -252775,10 +252458,11 @@
252775252458
){
252776252459
/* A MATCH operator or equivalent */
252777252460
if( p->usable==0 || iCol<0 ){
252778252461
/* As there exists an unusable MATCH constraint this is an
252779252462
** unusable plan. Return SQLITE_CONSTRAINT. */
252463
+ idxStr[iIdxStr] = 0;
252780252464
return SQLITE_CONSTRAINT;
252781252465
}else{
252782252466
if( iCol==nCol+1 ){
252783252467
if( bSeenRank ) continue;
252784252468
idxStr[iIdxStr++] = 'r';
@@ -253560,10 +253244,11 @@
253560253244
sqlite3_value *pRowidEq = 0; /* rowid = ? expression (or NULL) */
253561253245
sqlite3_value *pRowidLe = 0; /* rowid <= ? expression (or NULL) */
253562253246
sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */
253563253247
int iCol; /* Column on LHS of MATCH operator */
253564253248
char **pzErrmsg = pConfig->pzErrmsg;
253249
+ int bPrefixInsttoken = pConfig->bPrefixInsttoken;
253565253250
int i;
253566253251
int iIdxStr = 0;
253567253252
Fts5Expr *pExpr = 0;
253568253253
253569253254
assert( pConfig->bLock==0 );
@@ -253595,10 +253280,13 @@
253595253280
int bInternal = 0;
253596253281
253597253282
rc = fts5ExtractExprText(pConfig, apVal[i], &zText, &bFreeAndReset);
253598253283
if( rc!=SQLITE_OK ) goto filter_out;
253599253284
if( zText==0 ) zText = "";
253285
+ if( sqlite3_value_subtype(apVal[i])==FTS5_INSTTOKEN_SUBTYPE ){
253286
+ pConfig->bPrefixInsttoken = 1;
253287
+ }
253600253288
253601253289
iCol = 0;
253602253290
do{
253603253291
iCol = iCol*10 + (idxStr[iIdxStr]-'0');
253604253292
iIdxStr++;
@@ -253735,10 +253423,11 @@
253735253423
}
253736253424
253737253425
filter_out:
253738253426
sqlite3Fts5ExprFree(pExpr);
253739253427
pConfig->pzErrmsg = pzErrmsg;
253428
+ pConfig->bPrefixInsttoken = bPrefixInsttoken;
253740253429
return rc;
253741253430
}
253742253431
253743253432
/*
253744253433
** This is the xEof method of the virtual table. SQLite calls this
@@ -255730,11 +255419,11 @@
255730255419
int nArg, /* Number of args */
255731255420
sqlite3_value **apUnused /* Function arguments */
255732255421
){
255733255422
assert( nArg==0 );
255734255423
UNUSED_PARAM2(nArg, apUnused);
255735
- sqlite3_result_text(pCtx, "fts5: 2024-11-06 12:58:31 5495b12569c318d5020b4b5a625a392ef8e777b81c0200624fbbc2a6b5eddef9", -1, SQLITE_TRANSIENT);
255424
+ sqlite3_result_text(pCtx, "fts5: 2024-12-09 20:46:36 e2bae4143afd07de1ae55a6d2606a3b541a5b94568aa41f6a96e5d1245471653", -1, SQLITE_TRANSIENT);
255736255425
}
255737255426
255738255427
/*
255739255428
** Implementation of fts5_locale(LOCALE, TEXT) function.
255740255429
**
@@ -255793,10 +255482,24 @@
255793255482
assert( &pCsr[nText]==&pBlob[nBlob] );
255794255483
255795255484
sqlite3_result_blob(pCtx, pBlob, nBlob, sqlite3_free);
255796255485
}
255797255486
}
255487
+
255488
+/*
255489
+** Implementation of fts5_insttoken() function.
255490
+*/
255491
+static void fts5InsttokenFunc(
255492
+ sqlite3_context *pCtx, /* Function call context */
255493
+ int nArg, /* Number of args */
255494
+ sqlite3_value **apArg /* Function arguments */
255495
+){
255496
+ assert( nArg==1 );
255497
+ (void)nArg;
255498
+ sqlite3_result_value(pCtx, apArg[0]);
255499
+ sqlite3_result_subtype(pCtx, FTS5_INSTTOKEN_SUBTYPE);
255500
+}
255798255501
255799255502
/*
255800255503
** Return true if zName is the extension on one of the shadow tables used
255801255504
** by this module.
255802255505
*/
@@ -255923,13 +255626,20 @@
255923255626
);
255924255627
}
255925255628
if( rc==SQLITE_OK ){
255926255629
rc = sqlite3_create_function(
255927255630
db, "fts5_locale", 2,
255928
- SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE,
255631
+ SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE|SQLITE_SUBTYPE,
255929255632
p, fts5LocaleFunc, 0, 0
255930255633
);
255634
+ }
255635
+ if( rc==SQLITE_OK ){
255636
+ rc = sqlite3_create_function(
255637
+ db, "fts5_insttoken", 1,
255638
+ SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE,
255639
+ p, fts5InsttokenFunc, 0, 0
255640
+ );
255931255641
}
255932255642
}
255933255643
255934255644
/* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file
255935255645
** fts5_test_mi.c is compiled and linked into the executable. And call
@@ -255983,11 +255693,10 @@
255983255693
SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3 *db){
255984255694
return fts5Init(db);
255985255695
}
255986255696
#endif
255987255697
255988
-#line 1 "fts5_storage.c"
255989255698
/*
255990255699
** 2014 May 31
255991255700
**
255992255701
** The author disclaims copyright to this source code. In place of
255993255702
** a legal notice, here is a blessing:
@@ -257497,11 +257206,10 @@
257497257206
}
257498257207
}
257499257208
return rc;
257500257209
}
257501257210
257502
-#line 1 "fts5_tokenize.c"
257503257211
/*
257504257212
** 2014 May 31
257505257213
**
257506257214
** The author disclaims copyright to this source code. In place of
257507257215
** a legal notice, here is a blessing:
@@ -258853,22 +258561,22 @@
258853258561
int rc = SQLITE_OK;
258854258562
char aBuf[32];
258855258563
char *zOut = aBuf;
258856258564
int ii;
258857258565
const unsigned char *zIn = (const unsigned char*)pText;
258858
- const unsigned char *zEof = &zIn[nText];
258859
- u32 iCode;
258566
+ const unsigned char *zEof = (zIn ? &zIn[nText] : 0);
258567
+ u32 iCode = 0;
258860258568
int aStart[3]; /* Input offset of each character in aBuf[] */
258861258569
258862258570
UNUSED_PARAM(unusedFlags);
258863258571
258864258572
/* Populate aBuf[] with the characters for the first trigram. */
258865258573
for(ii=0; ii<3; ii++){
258866258574
do {
258867258575
aStart[ii] = zIn - (const unsigned char*)pText;
258576
+ if( zIn>=zEof ) return SQLITE_OK;
258868258577
READ_UTF8(zIn, zEof, iCode);
258869
- if( iCode==0 ) return SQLITE_OK;
258870258578
if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam);
258871258579
}while( iCode==0 );
258872258580
WRITE_UTF8(zOut, iCode);
258873258581
}
258874258582
@@ -258885,12 +258593,15 @@
258885258593
const char *z1;
258886258594
258887258595
/* Read characters from the input up until the first non-diacritic */
258888258596
do {
258889258597
iNext = zIn - (const unsigned char*)pText;
258598
+ if( zIn>=zEof ){
258599
+ iCode = 0;
258600
+ break;
258601
+ }
258890258602
READ_UTF8(zIn, zEof, iCode);
258891
- if( iCode==0 ) break;
258892258603
if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam);
258893258604
}while( iCode==0 );
258894258605
258895258606
/* Pass the current trigram back to fts5 */
258896258607
rc = xToken(pCtx, 0, aBuf, zOut-aBuf, aStart[0], iNext);
@@ -258986,11 +258697,10 @@
258986258697
);
258987258698
}
258988258699
return rc;
258989258700
}
258990258701
258991
-#line 1 "fts5_unicode2.c"
258992258702
/*
258993258703
** 2012-05-25
258994258704
**
258995258705
** The author disclaims copyright to this source code. In place of
258996258706
** a legal notice, here is a blessing:
@@ -259769,11 +259479,10 @@
259769259479
}
259770259480
aAscii[0] = 0; /* 0x00 is never a token character */
259771259481
}
259772259482
259773259483
259774
-#line 1 "fts5_varint.c"
259775259484
/*
259776259485
** 2015 May 30
259777259486
**
259778259487
** The author disclaims copyright to this source code. In place of
259779259488
** a legal notice, here is a blessing:
@@ -260115,11 +259824,10 @@
260115259824
if( iVal<(1 << 21) ) return 3;
260116259825
if( iVal<(1 << 28) ) return 4;
260117259826
return 5;
260118259827
}
260119259828
260120
-#line 1 "fts5_vocab.c"
260121259829
/*
260122259830
** 2015 May 08
260123259831
**
260124259832
** The author disclaims copyright to this source code. In place of
260125259833
** a legal notice, here is a blessing:
@@ -260931,11 +260639,10 @@
260931260639
/* Here ends the fts5.c composite file. */
260932260640
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */
260933260641
260934260642
/************** End of fts5.c ************************************************/
260935260643
/************** Begin file stmt.c ********************************************/
260936
-#line 1 "tsrc/stmt.c"
260937260644
/*
260938260645
** 2017-05-31
260939260646
**
260940260647
** The author disclaims copyright to this source code. In place of
260941260648
** a legal notice, here is a blessing:
260942260649
--- 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 ** 5495b12569c318d5020b4b5a625a392ef8e7 with changes in files:
22 **
23 **
24 */
25 #ifndef SQLITE_AMALGAMATION
26 #define SQLITE_CORE 1
@@ -27,11 +27,10 @@
27 #define SQLITE_AMALGAMATION 1
28 #ifndef SQLITE_PRIVATE
29 # define SQLITE_PRIVATE static
30 #endif
31 /************** Begin file sqliteInt.h ***************************************/
32 #line 1 "tsrc/sqliteInt.h"
33 /*
34 ** 2001 September 15
35 **
36 ** The author disclaims copyright to this source code. In place of
37 ** a legal notice, here is a blessing:
@@ -88,11 +87,10 @@
88 ** compiler warnings due to subsequent content in this file and other files
89 ** that are included by this file.
90 */
91 /************** Include msvc.h in the middle of sqliteInt.h ******************/
92 /************** Begin file msvc.h ********************************************/
93 #line 1 "tsrc/msvc.h"
94 /*
95 ** 2015 January 12
96 **
97 ** The author disclaims copyright to this source code. In place of
98 ** a legal notice, here is a blessing:
@@ -137,18 +135,16 @@
137
138 #endif /* SQLITE_MSVC_H */
139
140 /************** End of msvc.h ************************************************/
141 /************** Continuing where we left off in sqliteInt.h ******************/
142 #line 60 "tsrc/sqliteInt.h"
143
144 /*
145 ** Special setup for VxWorks
146 */
147 /************** Include vxworks.h in the middle of sqliteInt.h ***************/
148 /************** Begin file vxworks.h *****************************************/
149 #line 1 "tsrc/vxworks.h"
150 /*
151 ** 2015-03-02
152 **
153 ** The author disclaims copyright to this source code. In place of
154 ** a legal notice, here is a blessing:
@@ -180,11 +176,10 @@
180 #define HAVE_LSTAT 1
181 #endif /* defined(_WRS_KERNEL) */
182
183 /************** End of vxworks.h *********************************************/
184 /************** Continuing where we left off in sqliteInt.h ******************/
185 #line 65 "tsrc/sqliteInt.h"
186
187 /*
188 ** These #defines should enable >2GB file support on POSIX if the
189 ** underlying operating system supports it. If the OS lacks
190 ** large file support, or if the OS is windows, these should be no-ops.
@@ -320,11 +315,10 @@
320 ** first in QNX. Also, the _USE_32BIT_TIME_T macro must appear first for
321 ** MinGW.
322 */
323 /************** Include sqlite3.h in the middle of sqliteInt.h ***************/
324 /************** Begin file sqlite3.h *****************************************/
325 #line 1 "tsrc/sqlite3.h"
326 /*
327 ** 2001-09-15
328 **
329 ** The author disclaims copyright to this source code. In place of
330 ** a legal notice, here is a blessing:
@@ -471,11 +465,11 @@
471 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
472 ** [sqlite_version()] and [sqlite_source_id()].
473 */
474 #define SQLITE_VERSION "3.48.0"
475 #define SQLITE_VERSION_NUMBER 3048000
476 #define SQLITE_SOURCE_ID "2024-11-06 12:58:31 5495b12569c318d5020b4b5a625a392ef8e777b81c0200624fbbc2a6b5eddef9"
477
478 /*
479 ** CAPI3REF: Run-Time Library Version Numbers
480 ** KEYWORDS: sqlite3_version sqlite3_sourceid
481 **
@@ -1423,10 +1417,15 @@
1423 ** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
1424 ** opcode causes the xFileControl method to swap the file handle with the one
1425 ** pointed to by the pArg argument. This capability is used during testing
1426 ** and only needs to be supported when SQLITE_TEST is defined.
1427 **
 
 
 
 
 
1428 ** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
1429 ** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
1430 ** be advantageous to block on the next WAL lock if the lock is not immediately
1431 ** available. The WAL subsystem issues this signal during rare
1432 ** circumstances in order to fix a problem with priority inversion.
@@ -1576,10 +1575,11 @@
1576 #define SQLITE_FCNTL_RESERVE_BYTES 38
1577 #define SQLITE_FCNTL_CKPT_START 39
1578 #define SQLITE_FCNTL_EXTERNAL_READER 40
1579 #define SQLITE_FCNTL_CKSM_FILE 41
1580 #define SQLITE_FCNTL_RESET_CACHE 42
 
1581
1582 /* deprecated names */
1583 #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
1584 #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
1585 #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -2954,14 +2954,18 @@
2954 **
2955 ** ^These functions return the number of rows modified, inserted or
2956 ** deleted by the most recently completed INSERT, UPDATE or DELETE
2957 ** statement on the database connection specified by the only parameter.
2958 ** The two functions are identical except for the type of the return value
2959 ** and that if the number of rows modified by the most recent INSERT, UPDATE
2960 ** or DELETE is greater than the maximum value supported by type "int", then
2961 ** the return value of sqlite3_changes() is undefined. ^Executing any other
2962 ** type of SQL statement does not modify the value returned by these functions.
 
 
 
 
2963 **
2964 ** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are
2965 ** considered - auxiliary changes caused by [CREATE TRIGGER | triggers],
2966 ** [foreign key actions] or [REPLACE] constraint resolution are not counted.
2967 **
@@ -4517,15 +4521,26 @@
4517 **
4518 ** [[SQLITE_PREPARE_NO_VTAB]] <dt>SQLITE_PREPARE_NO_VTAB</dt>
4519 ** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler
4520 ** to return an error (error code SQLITE_ERROR) if the statement uses
4521 ** any virtual tables.
 
 
 
 
 
 
 
 
 
 
4522 ** </dl>
4523 */
4524 #define SQLITE_PREPARE_PERSISTENT 0x01
4525 #define SQLITE_PREPARE_NORMALIZE 0x02
4526 #define SQLITE_PREPARE_NO_VTAB 0x04
 
4527
4528 /*
4529 ** CAPI3REF: Compiling An SQL Statement
4530 ** KEYWORDS: {SQL statement compiler}
4531 ** METHOD: sqlite3
@@ -13463,17 +13478,32 @@
13463 ** This is used to access token iToken of phrase hit iIdx within the
13464 ** current row. If iIdx is less than zero or greater than or equal to the
13465 ** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise,
13466 ** output variable (*ppToken) is set to point to a buffer containing the
13467 ** matching document token, and (*pnToken) to the size of that buffer in
13468 ** bytes. This API is not available if the specified token matches a
13469 ** prefix query term. In that case both output variables are always set
13470 ** to 0.
13471 **
13472 ** The output text is not a copy of the document text that was tokenized.
13473 ** It is the output of the tokenizer module. For tokendata=1 tables, this
13474 ** includes any embedded 0x00 and trailing data.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13475 **
13476 ** This API can be quite slow if used with an FTS5 table created with the
13477 ** "detail=none" or "detail=column" option.
13478 **
13479 ** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale)
@@ -13908,11 +13938,10 @@
13908 /******** End of fts5.h *********/
13909 #endif /* SQLITE3_H */
13910
13911 /************** End of sqlite3.h *********************************************/
13912 /************** Continuing where we left off in sqliteInt.h ******************/
13913 #line 203 "tsrc/sqliteInt.h"
13914
13915 /*
13916 ** Reuse the STATIC_LRU for mutex access to sqlite3_temp_directory.
13917 */
13918 #define SQLITE_MUTEX_STATIC_TEMPDIR SQLITE_MUTEX_STATIC_VFS1
@@ -13926,11 +13955,10 @@
13926 #define SQLITECONFIG_H 1
13927 #endif
13928
13929 /************** Include sqliteLimit.h in the middle of sqliteInt.h ***********/
13930 /************** Begin file sqliteLimit.h *************************************/
13931 #line 1 "tsrc/sqliteLimit.h"
13932 /*
13933 ** 2007 May 7
13934 **
13935 ** The author disclaims copyright to this source code. In place of
13936 ** a legal notice, here is a blessing:
@@ -13952,10 +13980,11 @@
13952 ** to count the size: 2^31-1 or 2147483647.
13953 */
13954 #ifndef SQLITE_MAX_LENGTH
13955 # define SQLITE_MAX_LENGTH 1000000000
13956 #endif
 
13957
13958 /*
13959 ** This is the maximum number of
13960 **
13961 ** * Columns in a table
@@ -14140,11 +14169,10 @@
14140 # define SQLITE_MAX_TRIGGER_DEPTH 1000
14141 #endif
14142
14143 /************** End of sqliteLimit.h *****************************************/
14144 /************** Continuing where we left off in sqliteInt.h ******************/
14145 #line 219 "tsrc/sqliteInt.h"
14146
14147 /* Disable nuisance warnings on Borland compilers */
14148 #if defined(__BORLANDC__)
14149 #pragma warn -rch /* unreachable code */
14150 #pragma warn -ccc /* Condition is always true or false */
@@ -14558,11 +14586,10 @@
14558 #define likely(X) (X)
14559 #define unlikely(X) (X)
14560
14561 /************** Include hash.h in the middle of sqliteInt.h ******************/
14562 /************** Begin file hash.h ********************************************/
14563 #line 1 "tsrc/hash.h"
14564 /*
14565 ** 2001 September 22
14566 **
14567 ** The author disclaims copyright to this source code. In place of
14568 ** a legal notice, here is a blessing:
@@ -14658,14 +14685,12 @@
14658
14659 #endif /* SQLITE_HASH_H */
14660
14661 /************** End of hash.h ************************************************/
14662 /************** Continuing where we left off in sqliteInt.h ******************/
14663 #line 635 "tsrc/sqliteInt.h"
14664 /************** Include parse.h in the middle of sqliteInt.h *****************/
14665 /************** Begin file parse.h *******************************************/
14666 #line 1 "tsrc/parse.h"
14667 #define TK_SEMI 1
14668 #define TK_EXPLAIN 2
14669 #define TK_QUERY 3
14670 #define TK_PLAN 4
14671 #define TK_BEGIN 5
@@ -14850,11 +14875,10 @@
14850 #define TK_SPACE 184
14851 #define TK_ILLEGAL 185
14852
14853 /************** End of parse.h ***********************************************/
14854 /************** Continuing where we left off in sqliteInt.h ******************/
14855 #line 636 "tsrc/sqliteInt.h"
14856 #include <stdio.h>
14857 #include <stdlib.h>
14858 #include <string.h>
14859 #include <assert.h>
14860 #include <stddef.h>
@@ -15616,11 +15640,10 @@
15616 ** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque
15617 ** pointer types (i.e. FuncDef) defined above.
15618 */
15619 /************** Include os.h in the middle of sqliteInt.h ********************/
15620 /************** Begin file os.h **********************************************/
15621 #line 1 "tsrc/os.h"
15622 /*
15623 ** 2001 September 16
15624 **
15625 ** The author disclaims copyright to this source code. In place of
15626 ** a legal notice, here is a blessing:
@@ -15645,11 +15668,10 @@
15645 ** Attempt to automatically detect the operating system and setup the
15646 ** necessary pre-processor macros for it.
15647 */
15648 /************** Include os_setup.h in the middle of os.h *********************/
15649 /************** Begin file os_setup.h ****************************************/
15650 #line 1 "tsrc/os_setup.h"
15651 /*
15652 ** 2013 November 25
15653 **
15654 ** The author disclaims copyright to this source code. In place of
15655 ** a legal notice, here is a blessing:
@@ -15740,11 +15762,10 @@
15740
15741 #endif /* SQLITE_OS_SETUP_H */
15742
15743 /************** End of os_setup.h ********************************************/
15744 /************** Continuing where we left off in os.h *************************/
15745 #line 28 "tsrc/os.h"
15746
15747 /* If the SET_FULLSYNC macro is not defined above, then make it
15748 ** a no-op
15749 */
15750 #ifndef SET_FULLSYNC
@@ -15942,14 +15963,12 @@
15942
15943 #endif /* _SQLITE_OS_H_ */
15944
15945 /************** End of os.h **************************************************/
15946 /************** Continuing where we left off in sqliteInt.h ******************/
15947 #line 1400 "tsrc/sqliteInt.h"
15948 /************** Include pager.h in the middle of sqliteInt.h *****************/
15949 /************** Begin file pager.h *******************************************/
15950 #line 1 "tsrc/pager.h"
15951 /*
15952 ** 2001 September 15
15953 **
15954 ** The author disclaims copyright to this source code. In place of
15955 ** a legal notice, here is a blessing:
@@ -16196,14 +16215,12 @@
16196
16197 #endif /* SQLITE_PAGER_H */
16198
16199 /************** End of pager.h ***********************************************/
16200 /************** Continuing where we left off in sqliteInt.h ******************/
16201 #line 1401 "tsrc/sqliteInt.h"
16202 /************** Include btree.h in the middle of sqliteInt.h *****************/
16203 /************** Begin file btree.h *******************************************/
16204 #line 1 "tsrc/btree.h"
16205 /*
16206 ** 2001 September 15
16207 **
16208 ** The author disclaims copyright to this source code. In place of
16209 ** a legal notice, here is a blessing:
@@ -16627,14 +16644,12 @@
16627
16628 #endif /* SQLITE_BTREE_H */
16629
16630 /************** End of btree.h ***********************************************/
16631 /************** Continuing where we left off in sqliteInt.h ******************/
16632 #line 1402 "tsrc/sqliteInt.h"
16633 /************** Include vdbe.h in the middle of sqliteInt.h ******************/
16634 /************** Begin file vdbe.h ********************************************/
16635 #line 1 "tsrc/vdbe.h"
16636 /*
16637 ** 2001 September 15
16638 **
16639 ** The author disclaims copyright to this source code. In place of
16640 ** a legal notice, here is a blessing:
@@ -16814,11 +16829,10 @@
16814 ** The makefile scans the vdbe.c source file and creates the "opcodes.h"
16815 ** header file that defines a number for each opcode used by the VDBE.
16816 */
16817 /************** Include opcodes.h in the middle of vdbe.h ********************/
16818 /************** Begin file opcodes.h *****************************************/
16819 #line 1 "tsrc/opcodes.h"
16820 /* Automatically generated. Do not edit */
16821 /* See the tool/mkopcodeh.tcl script for details */
16822 #define OP_Savepoint 0
16823 #define OP_AutoCommit 1
16824 #define OP_Transaction 2
@@ -17056,17 +17070,16 @@
17056 */
17057 #define SQLITE_MX_JUMP_OPCODE 64 /* Maximum JUMP opcode */
17058
17059 /************** End of opcodes.h *********************************************/
17060 /************** Continuing where we left off in vdbe.h ***********************/
17061 #line 183 "tsrc/vdbe.h"
17062
17063 /*
17064 ** Additional non-public SQLITE_PREPARE_* flags
17065 */
17066 #define SQLITE_PREPARE_SAVESQL 0x80 /* Preserve SQL text */
17067 #define SQLITE_PREPARE_MASK 0x0f /* Mask of public flags */
17068
17069 /*
17070 ** Prototypes for the VDBE interface. See comments on the implementation
17071 ** for a description of what each of these routines does.
17072 */
@@ -17306,14 +17319,12 @@
17306
17307 #endif /* SQLITE_VDBE_H */
17308
17309 /************** End of vdbe.h ************************************************/
17310 /************** Continuing where we left off in sqliteInt.h ******************/
17311 #line 1403 "tsrc/sqliteInt.h"
17312 /************** Include pcache.h in the middle of sqliteInt.h ****************/
17313 /************** Begin file pcache.h ******************************************/
17314 #line 1 "tsrc/pcache.h"
17315 /*
17316 ** 2008 August 05
17317 **
17318 ** The author disclaims copyright to this source code. In place of
17319 ** a legal notice, here is a blessing:
@@ -17503,14 +17514,12 @@
17503
17504 #endif /* _PCACHE_H_ */
17505
17506 /************** End of pcache.h **********************************************/
17507 /************** Continuing where we left off in sqliteInt.h ******************/
17508 #line 1404 "tsrc/sqliteInt.h"
17509 /************** Include mutex.h in the middle of sqliteInt.h *****************/
17510 /************** Begin file mutex.h *******************************************/
17511 #line 1 "tsrc/mutex.h"
17512 /*
17513 ** 2007 August 28
17514 **
17515 ** The author disclaims copyright to this source code. In place of
17516 ** a legal notice, here is a blessing:
@@ -17581,11 +17590,10 @@
17581 SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
17582 #endif /* defined(SQLITE_MUTEX_OMIT) */
17583
17584 /************** End of mutex.h ***********************************************/
17585 /************** Continuing where we left off in sqliteInt.h ******************/
17586 #line 1405 "tsrc/sqliteInt.h"
17587
17588 /* The SQLITE_EXTRA_DURABLE compile-time option used to set the default
17589 ** synchronous setting to EXTRA. It is no longer supported.
17590 */
17591 #ifdef SQLITE_EXTRA_DURABLE
@@ -21982,11 +21990,10 @@
21982
21983 #endif /* SQLITEINT_H */
21984
21985 /************** End of sqliteInt.h *******************************************/
21986 /************** Begin file os_common.h ***************************************/
21987 #line 1 "tsrc/os_common.h"
21988 /*
21989 ** 2004 May 22
21990 **
21991 ** The author disclaims copyright to this source code. In place of
21992 ** a legal notice, here is a blessing:
@@ -22085,11 +22092,10 @@
22085
22086 #endif /* !defined(_OS_COMMON_H_) */
22087
22088 /************** End of os_common.h *******************************************/
22089 /************** Begin file ctime.c *******************************************/
22090 #line 1 "tsrc/ctime.c"
22091 /* DO NOT EDIT!
22092 ** This file is automatically generated by the script in the canonical
22093 ** SQLite source tree at tool/mkctimec.tcl.
22094 **
22095 ** To modify this header, edit any of the various lists in that script
@@ -22885,11 +22891,10 @@
22885
22886 #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
22887
22888 /************** End of ctime.c ***********************************************/
22889 /************** Begin file global.c ******************************************/
22890 #line 1 "tsrc/global.c"
22891 /*
22892 ** 2008 June 13
22893 **
22894 ** The author disclaims copyright to this source code. In place of
22895 ** a legal notice, here is a blessing:
@@ -23290,11 +23295,10 @@
23290 "TEXT"
23291 };
23292
23293 /************** End of global.c **********************************************/
23294 /************** Begin file status.c ******************************************/
23295 #line 1 "tsrc/status.c"
23296 /*
23297 ** 2008 June 18
23298 **
23299 ** The author disclaims copyright to this source code. In place of
23300 ** a legal notice, here is a blessing:
@@ -23309,11 +23313,10 @@
23309 ** functionality.
23310 */
23311 /* #include "sqliteInt.h" */
23312 /************** Include vdbeInt.h in the middle of status.c ******************/
23313 /************** Begin file vdbeInt.h *****************************************/
23314 #line 1 "tsrc/vdbeInt.h"
23315 /*
23316 ** 2003 September 6
23317 **
23318 ** The author disclaims copyright to this source code. In place of
23319 ** a legal notice, here is a blessing:
@@ -24046,11 +24049,10 @@
24046
24047 #endif /* !defined(SQLITE_VDBEINT_H) */
24048
24049 /************** End of vdbeInt.h *********************************************/
24050 /************** Continuing where we left off in status.c *********************/
24051 #line 18 "tsrc/status.c"
24052
24053 /*
24054 ** Variables in which to record status information.
24055 */
24056 #if SQLITE_PTRSIZE>4
@@ -24431,11 +24433,10 @@
24431 return rc;
24432 }
24433
24434 /************** End of status.c **********************************************/
24435 /************** Begin file date.c ********************************************/
24436 #line 1 "tsrc/date.c"
24437 /*
24438 ** 2003 October 31
24439 **
24440 ** The author disclaims copyright to this source code. In place of
24441 ** a legal notice, here is a blessing:
@@ -26250,11 +26251,10 @@
26250 sqlite3InsertBuiltinFuncs(aDateTimeFuncs, ArraySize(aDateTimeFuncs));
26251 }
26252
26253 /************** End of date.c ************************************************/
26254 /************** Begin file os.c **********************************************/
26255 #line 1 "tsrc/os.c"
26256 /*
26257 ** 2005 November 29
26258 **
26259 ** The author disclaims copyright to this source code. In place of
26260 ** a legal notice, here is a blessing:
@@ -26701,11 +26701,10 @@
26701 return SQLITE_OK;
26702 }
26703
26704 /************** End of os.c **************************************************/
26705 /************** Begin file fault.c *******************************************/
26706 #line 1 "tsrc/fault.c"
26707 /*
26708 ** 2008 Jan 22
26709 **
26710 ** The author disclaims copyright to this source code. In place of
26711 ** a legal notice, here is a blessing:
@@ -26792,11 +26791,10 @@
26792
26793 #endif /* #ifndef SQLITE_UNTESTABLE */
26794
26795 /************** End of fault.c ***********************************************/
26796 /************** Begin file mem0.c ********************************************/
26797 #line 1 "tsrc/mem0.c"
26798 /*
26799 ** 2008 October 28
26800 **
26801 ** The author disclaims copyright to this source code. In place of
26802 ** a legal notice, here is a blessing:
@@ -26855,11 +26853,10 @@
26855
26856 #endif /* SQLITE_ZERO_MALLOC */
26857
26858 /************** End of mem0.c ************************************************/
26859 /************** Begin file mem1.c ********************************************/
26860 #line 1 "tsrc/mem1.c"
26861 /*
26862 ** 2007 August 14
26863 **
26864 ** The author disclaims copyright to this source code. In place of
26865 ** a legal notice, here is a blessing:
@@ -27150,11 +27147,10 @@
27150
27151 #endif /* SQLITE_SYSTEM_MALLOC */
27152
27153 /************** End of mem1.c ************************************************/
27154 /************** Begin file mem2.c ********************************************/
27155 #line 1 "tsrc/mem2.c"
27156 /*
27157 ** 2007 August 15
27158 **
27159 ** The author disclaims copyright to this source code. In place of
27160 ** a legal notice, here is a blessing:
@@ -27682,11 +27678,10 @@
27682
27683 #endif /* SQLITE_MEMDEBUG */
27684
27685 /************** End of mem2.c ************************************************/
27686 /************** Begin file mem3.c ********************************************/
27687 #line 1 "tsrc/mem3.c"
27688 /*
27689 ** 2007 October 14
27690 **
27691 ** The author disclaims copyright to this source code. In place of
27692 ** a legal notice, here is a blessing:
@@ -28373,11 +28368,10 @@
28373
28374 #endif /* SQLITE_ENABLE_MEMSYS3 */
28375
28376 /************** End of mem3.c ************************************************/
28377 /************** Begin file mem5.c ********************************************/
28378 #line 1 "tsrc/mem5.c"
28379 /*
28380 ** 2007 October 14
28381 **
28382 ** The author disclaims copyright to this source code. In place of
28383 ** a legal notice, here is a blessing:
@@ -28962,11 +28956,10 @@
28962
28963 #endif /* SQLITE_ENABLE_MEMSYS5 */
28964
28965 /************** End of mem5.c ************************************************/
28966 /************** Begin file mutex.c *******************************************/
28967 #line 1 "tsrc/mutex.c"
28968 /*
28969 ** 2007 August 14
28970 **
28971 ** The author disclaims copyright to this source code. In place of
28972 ** a legal notice, here is a blessing:
@@ -29340,11 +29333,10 @@
29340
29341 #endif /* !defined(SQLITE_MUTEX_OMIT) */
29342
29343 /************** End of mutex.c ***********************************************/
29344 /************** Begin file mutex_noop.c **************************************/
29345 #line 1 "tsrc/mutex_noop.c"
29346 /*
29347 ** 2008 October 07
29348 **
29349 ** The author disclaims copyright to this source code. In place of
29350 ** a legal notice, here is a blessing:
@@ -29559,11 +29551,10 @@
29559 #endif /* defined(SQLITE_MUTEX_NOOP) */
29560 #endif /* !defined(SQLITE_MUTEX_OMIT) */
29561
29562 /************** End of mutex_noop.c ******************************************/
29563 /************** Begin file mutex_unix.c **************************************/
29564 #line 1 "tsrc/mutex_unix.c"
29565 /*
29566 ** 2007 August 28
29567 **
29568 ** The author disclaims copyright to this source code. In place of
29569 ** a legal notice, here is a blessing:
@@ -29957,11 +29948,10 @@
29957
29958 #endif /* SQLITE_MUTEX_PTHREADS */
29959
29960 /************** End of mutex_unix.c ******************************************/
29961 /************** Begin file mutex_w32.c ***************************************/
29962 #line 1 "tsrc/mutex_w32.c"
29963 /*
29964 ** 2007 August 14
29965 **
29966 ** The author disclaims copyright to this source code. In place of
29967 ** a legal notice, here is a blessing:
@@ -29984,11 +29974,10 @@
29984 /*
29985 ** Include the header file for the Windows VFS.
29986 */
29987 /************** Include os_win.h in the middle of mutex_w32.c ****************/
29988 /************** Begin file os_win.h ******************************************/
29989 #line 1 "tsrc/os_win.h"
29990 /*
29991 ** 2013 November 25
29992 **
29993 ** The author disclaims copyright to this source code. In place of
29994 ** a legal notice, here is a blessing:
@@ -30076,11 +30065,10 @@
30076
30077 #endif /* SQLITE_OS_WIN_H */
30078
30079 /************** End of os_win.h **********************************************/
30080 /************** Continuing where we left off in mutex_w32.c ******************/
30081 #line 26 "tsrc/mutex_w32.c"
30082 #endif
30083
30084 /*
30085 ** The code in this file is only used if we are compiling multithreaded
30086 ** on a Win32 system.
@@ -30454,11 +30442,10 @@
30454
30455 #endif /* SQLITE_MUTEX_W32 */
30456
30457 /************** End of mutex_w32.c *******************************************/
30458 /************** Begin file malloc.c ******************************************/
30459 #line 1 "tsrc/malloc.c"
30460 /*
30461 ** 2001 September 15
30462 **
30463 ** The author disclaims copyright to this source code. In place of
30464 ** a legal notice, here is a blessing:
@@ -31378,11 +31365,10 @@
31378 return 0;
31379 }
31380
31381 /************** End of malloc.c **********************************************/
31382 /************** Begin file printf.c ******************************************/
31383 #line 1 "tsrc/printf.c"
31384 /*
31385 ** The "printf" code that follows dates from the 1980's. It is in
31386 ** the public domain.
31387 **
31388 **************************************************************************
@@ -32319,10 +32305,11 @@
32319 && (ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) || pExpr->w.iOfst<=0)
32320 ){
32321 pExpr = pExpr->pLeft;
32322 }
32323 if( pExpr==0 ) return;
 
32324 db->errByteOffset = pExpr->w.iOfst;
32325 }
32326
32327 /*
32328 ** Enlarge the memory allocation on a StrAccum object so that it is
@@ -32828,11 +32815,10 @@
32828 }
32829 }
32830
32831 /************** End of printf.c **********************************************/
32832 /************** Begin file treeview.c ****************************************/
32833 #line 1 "tsrc/treeview.c"
32834 /*
32835 ** 2015-06-08
32836 **
32837 ** The author disclaims copyright to this source code. In place of
32838 ** a legal notice, here is a blessing:
@@ -33049,11 +33035,11 @@
33049 }
33050 if( pItem->fg.isCte ){
33051 sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse);
33052 }
33053 if( pItem->fg.isOn || (pItem->fg.isUsing==0 && pItem->u3.pOn!=0) ){
33054 sqlite3_str_appendf(&x, " ON");
33055 }
33056 if( pItem->fg.isTabFunc ) sqlite3_str_appendf(&x, " isTabFunc");
33057 if( pItem->fg.isCorrelated ) sqlite3_str_appendf(&x, " isCorrelated");
33058 if( pItem->fg.isMaterialized ) sqlite3_str_appendf(&x, " isMaterialized");
33059 if( pItem->fg.viaCoroutine ) sqlite3_str_appendf(&x, " viaCoroutine");
@@ -34133,10 +34119,14 @@
34133 **
34134 ** This routines are given external linkage so that they will always be
34135 ** accessible to the debugging, and to avoid warnings about unused
34136 ** functions. But these routines only exist in debugging builds, so they
34137 ** do not contaminate the interface.
 
 
 
 
34138 */
34139 SQLITE_PRIVATE void sqlite3ShowExpr(const Expr *p){ sqlite3TreeViewExpr(0,p,0); }
34140 SQLITE_PRIVATE void sqlite3ShowExprList(const ExprList *p){ sqlite3TreeViewExprList(0,p,0,0);}
34141 SQLITE_PRIVATE void sqlite3ShowIdList(const IdList *p){ sqlite3TreeViewIdList(0,p,0,0); }
34142 SQLITE_PRIVATE void sqlite3ShowSrcList(const SrcList *p){ sqlite3TreeViewSrcList(0,p); }
@@ -34160,11 +34150,10 @@
34160
34161 #endif /* SQLITE_DEBUG */
34162
34163 /************** End of treeview.c ********************************************/
34164 /************** Begin file random.c ******************************************/
34165 #line 1 "tsrc/random.c"
34166 /*
34167 ** 2001 September 15
34168 **
34169 ** The author disclaims copyright to this source code. In place of
34170 ** a legal notice, here is a blessing:
@@ -34321,11 +34310,10 @@
34321 }
34322 #endif /* SQLITE_UNTESTABLE */
34323
34324 /************** End of random.c **********************************************/
34325 /************** Begin file threads.c *****************************************/
34326 #line 1 "tsrc/threads.c"
34327 /*
34328 ** 2012 July 21
34329 **
34330 ** The author disclaims copyright to this source code. In place of
34331 ** a legal notice, here is a blessing:
@@ -34599,11 +34587,10 @@
34599 /****************************** End Single-Threaded *************************/
34600 #endif /* SQLITE_MAX_WORKER_THREADS>0 */
34601
34602 /************** End of threads.c *********************************************/
34603 /************** Begin file utf.c *********************************************/
34604 #line 1 "tsrc/utf.c"
34605 /*
34606 ** 2004 April 13
34607 **
34608 ** The author disclaims copyright to this source code. In place of
34609 ** a legal notice, here is a blessing:
@@ -35171,11 +35158,10 @@
35171 #endif /* SQLITE_TEST */
35172 #endif /* SQLITE_OMIT_UTF16 */
35173
35174 /************** End of utf.c *************************************************/
35175 /************** Begin file util.c ********************************************/
35176 #line 1 "tsrc/util.c"
35177 /*
35178 ** 2001 September 15
35179 **
35180 ** The author disclaims copyright to this source code. In place of
35181 ** a legal notice, here is a blessing:
@@ -35713,12 +35699,12 @@
35713 int esign = 1; /* sign of exponent */
35714 int e = 0; /* exponent */
35715 int eValid = 1; /* True exponent is either not used or is well-formed */
35716 int nDigit = 0; /* Number of digits processed */
35717 int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */
 
35718 double rr[2];
35719 u64 s2;
35720
35721 assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
35722 *pResult = 0.0; /* Default return value, in case of an error */
35723 if( length==0 ) return 0;
35724
@@ -35817,25 +35803,36 @@
35817
35818 /* adjust exponent by d, and update sign */
35819 e = (e*esign) + d;
35820
35821 /* Try to adjust the exponent to make it smaller */
35822 while( e>0 && s<(LARGEST_UINT64/10) ){
35823 s *= 10;
35824 e--;
35825 }
35826 while( e<0 && (s%10)==0 ){
35827 s /= 10;
35828 e++;
35829 }
35830
35831 rr[0] = (double)s;
35832 s2 = (u64)rr[0];
35833 #if defined(_MSC_VER) && _MSC_VER<1700
35834 if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); }
 
 
35835 #endif
35836 rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s);
 
 
 
 
 
 
 
 
 
35837 if( e>0 ){
35838 while( e>=100 ){
35839 e -= 100;
35840 dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83);
35841 }
@@ -37023,11 +37020,10 @@
37023 return 0;
37024 }
37025
37026 /************** End of util.c ************************************************/
37027 /************** Begin file hash.c ********************************************/
37028 #line 1 "tsrc/hash.c"
37029 /*
37030 ** 2001 September 22
37031 **
37032 ** The author disclaims copyright to this source code. In place of
37033 ** a legal notice, here is a blessing:
@@ -37297,11 +37293,10 @@
37297 return 0;
37298 }
37299
37300 /************** End of hash.c ************************************************/
37301 /************** Begin file opcodes.c *****************************************/
37302 #line 1 "tsrc/opcodes.c"
37303 /* Automatically generated. Do not edit */
37304 /* See the tool/mkopcodec.tcl script for details. */
37305 #if !defined(SQLITE_OMIT_EXPLAIN) \
37306 || defined(VDBE_PROFILE) \
37307 || defined(SQLITE_DEBUG)
@@ -37507,11 +37502,10 @@
37507 }
37508 #endif
37509
37510 /************** End of opcodes.c *********************************************/
37511 /************** Begin file os_kv.c *******************************************/
37512 #line 1 "tsrc/os_kv.c"
37513 /*
37514 ** 2022-09-06
37515 **
37516 ** The author disclaims copyright to this source code. In place of
37517 ** a legal notice, here is a blessing:
@@ -38490,11 +38484,10 @@
38490 }
38491 #endif
38492
38493 /************** End of os_kv.c ***********************************************/
38494 /************** Begin file os_unix.c *****************************************/
38495 #line 1 "tsrc/os_unix.c"
38496 /*
38497 ** 2004 May 22
38498 **
38499 ** The author disclaims copyright to this source code. In place of
38500 ** a legal notice, here is a blessing:
@@ -42480,10 +42473,15 @@
42480 int rc = osIoctl(pFile->h, F2FS_IOC_ABORT_VOLATILE_WRITE);
42481 return rc ? SQLITE_IOERR_ROLLBACK_ATOMIC : SQLITE_OK;
42482 }
42483 #endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */
42484
 
 
 
 
 
42485 case SQLITE_FCNTL_LOCKSTATE: {
42486 *(int*)pArg = pFile->eFileLock;
42487 return SQLITE_OK;
42488 }
42489 case SQLITE_FCNTL_LAST_ERRNO: {
@@ -46760,11 +46758,10 @@
46760
46761 #endif /* SQLITE_OS_UNIX */
46762
46763 /************** End of os_unix.c *********************************************/
46764 /************** Begin file os_win.c ******************************************/
46765 #line 1 "tsrc/os_win.c"
46766 /*
46767 ** 2004 May 22
46768 **
46769 ** The author disclaims copyright to this source code. In place of
46770 ** a legal notice, here is a blessing:
@@ -50362,10 +50359,15 @@
50362 OSTRACE(("FCNTL oldFile=%p, newFile=%p, rc=SQLITE_OK\n",
50363 hOldFile, pFile->h));
50364 return SQLITE_OK;
50365 }
50366 #endif
 
 
 
 
 
50367 case SQLITE_FCNTL_TEMPFILENAME: {
50368 char *zTFile = 0;
50369 int rc = winGetTempname(pFile->pVfs, &zTFile);
50370 if( rc==SQLITE_OK ){
50371 *(char**)pArg = zTFile;
@@ -51811,11 +51813,11 @@
51811 */
51812 char *zTmpname = 0; /* For temporary filename, if necessary. */
51813
51814 int rc = SQLITE_OK; /* Function Return Code */
51815 #if !defined(NDEBUG) || SQLITE_OS_WINCE
51816 int eType = flags&0xFFFFFF00; /* Type of file to open */
51817 #endif
51818
51819 int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE);
51820 int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE);
51821 int isCreate = (flags & SQLITE_OPEN_CREATE);
@@ -52975,11 +52977,10 @@
52975
52976 #endif /* SQLITE_OS_WIN */
52977
52978 /************** End of os_win.c **********************************************/
52979 /************** Begin file memdb.c *******************************************/
52980 #line 1 "tsrc/memdb.c"
52981 /*
52982 ** 2016-09-07
52983 **
52984 ** The author disclaims copyright to this source code. In place of
52985 ** a legal notice, here is a blessing:
@@ -53915,11 +53916,10 @@
53915 }
53916 #endif /* SQLITE_OMIT_DESERIALIZE */
53917
53918 /************** End of memdb.c ***********************************************/
53919 /************** Begin file bitvec.c ******************************************/
53920 #line 1 "tsrc/bitvec.c"
53921 /*
53922 ** 2008 February 16
53923 **
53924 ** The author disclaims copyright to this source code. In place of
53925 ** a legal notice, here is a blessing:
@@ -54330,11 +54330,10 @@
54330 }
54331 #endif /* SQLITE_UNTESTABLE */
54332
54333 /************** End of bitvec.c **********************************************/
54334 /************** Begin file pcache.c ******************************************/
54335 #line 1 "tsrc/pcache.c"
54336 /*
54337 ** 2008 August 05
54338 **
54339 ** The author disclaims copyright to this source code. In place of
54340 ** a legal notice, here is a blessing:
@@ -55270,11 +55269,10 @@
55270 }
55271 #endif
55272
55273 /************** End of pcache.c **********************************************/
55274 /************** Begin file pcache1.c *****************************************/
55275 #line 1 "tsrc/pcache1.c"
55276 /*
55277 ** 2008 November 05
55278 **
55279 ** The author disclaims copyright to this source code. In place of
55280 ** a legal notice, here is a blessing:
@@ -56556,11 +56554,10 @@
56556 }
56557 #endif
56558
56559 /************** End of pcache1.c *********************************************/
56560 /************** Begin file rowset.c ******************************************/
56561 #line 1 "tsrc/rowset.c"
56562 /*
56563 ** 2008 December 3
56564 **
56565 ** The author disclaims copyright to this source code. In place of
56566 ** a legal notice, here is a blessing:
@@ -57062,11 +57059,10 @@
57062 return 0;
57063 }
57064
57065 /************** End of rowset.c **********************************************/
57066 /************** Begin file pager.c *******************************************/
57067 #line 1 "tsrc/pager.c"
57068 /*
57069 ** 2001 September 15
57070 **
57071 ** The author disclaims copyright to this source code. In place of
57072 ** a legal notice, here is a blessing:
@@ -57087,11 +57083,10 @@
57087 */
57088 #ifndef SQLITE_OMIT_DISKIO
57089 /* #include "sqliteInt.h" */
57090 /************** Include wal.h in the middle of pager.c ***********************/
57091 /************** Begin file wal.h *********************************************/
57092 #line 1 "tsrc/wal.h"
57093 /*
57094 ** 2010 February 1
57095 **
57096 ** The author disclaims copyright to this source code. In place of
57097 ** a legal notice, here is a blessing:
@@ -57251,11 +57246,10 @@
57251 #endif /* ifndef SQLITE_OMIT_WAL */
57252 #endif /* SQLITE_WAL_H */
57253
57254 /************** End of wal.h *************************************************/
57255 /************** Continuing where we left off in pager.c **********************/
57256 #line 24 "tsrc/pager.c"
57257
57258
57259 /******************* NOTES ON THE DESIGN OF THE PAGER ************************
57260 **
57261 ** This comment block describes invariants that hold when using a rollback
@@ -65041,11 +65035,10 @@
65041
65042 #endif /* SQLITE_OMIT_DISKIO */
65043
65044 /************** End of pager.c ***********************************************/
65045 /************** Begin file wal.c *********************************************/
65046 #line 1 "tsrc/wal.c"
65047 /*
65048 ** 2010 February 1
65049 **
65050 ** The author disclaims copyright to this source code. In place of
65051 ** a legal notice, here is a blessing:
@@ -69638,11 +69631,10 @@
69638
69639 #endif /* #ifndef SQLITE_OMIT_WAL */
69640
69641 /************** End of wal.c *************************************************/
69642 /************** Begin file btmutex.c *****************************************/
69643 #line 1 "tsrc/btmutex.c"
69644 /*
69645 ** 2007 August 27
69646 **
69647 ** The author disclaims copyright to this source code. In place of
69648 ** a legal notice, here is a blessing:
@@ -69658,11 +69650,10 @@
69658 ** big and we want to break it down some. This packaged seemed like
69659 ** a good breakout.
69660 */
69661 /************** Include btreeInt.h in the middle of btmutex.c ****************/
69662 /************** Begin file btreeInt.h ****************************************/
69663 #line 1 "tsrc/btreeInt.h"
69664 /*
69665 ** 2004 April 6
69666 **
69667 ** The author disclaims copyright to this source code. In place of
69668 ** a legal notice, here is a blessing:
@@ -70396,11 +70387,10 @@
70396 # define get2byteAligned(x) ((x)[0]<<8 | (x)[1])
70397 #endif
70398
70399 /************** End of btreeInt.h ********************************************/
70400 /************** Continuing where we left off in btmutex.c ********************/
70401 #line 19 "tsrc/btmutex.c"
70402 #ifndef SQLITE_OMIT_SHARED_CACHE
70403 #if SQLITE_THREADSAFE
70404
70405 /*
70406 ** Obtain the BtShared mutex associated with B-Tree handle p. Also,
@@ -70691,11 +70681,10 @@
70691
70692 #endif /* ifndef SQLITE_OMIT_SHARED_CACHE */
70693
70694 /************** End of btmutex.c *********************************************/
70695 /************** Begin file btree.c *******************************************/
70696 #line 1 "tsrc/btree.c"
70697 /*
70698 ** 2004 April 6
70699 **
70700 ** The author disclaims copyright to this source code. In place of
70701 ** a legal notice, here is a blessing:
@@ -82186,11 +82175,10 @@
82186 }
82187 #endif
82188
82189 /************** End of btree.c ***********************************************/
82190 /************** Begin file backup.c ******************************************/
82191 #line 1 "tsrc/backup.c"
82192 /*
82193 ** 2009 January 28
82194 **
82195 ** The author disclaims copyright to this source code. In place of
82196 ** a legal notice, here is a blessing:
@@ -82957,11 +82945,10 @@
82957 }
82958 #endif /* SQLITE_OMIT_VACUUM */
82959
82960 /************** End of backup.c **********************************************/
82961 /************** Begin file vdbemem.c *****************************************/
82962 #line 1 "tsrc/vdbemem.c"
82963 /*
82964 ** 2004 May 26
82965 **
82966 ** The author disclaims copyright to this source code. In place of
82967 ** a legal notice, here is a blessing:
@@ -85014,11 +85001,10 @@
85014 return valueBytes(pVal, enc);
85015 }
85016
85017 /************** End of vdbemem.c *********************************************/
85018 /************** Begin file vdbeaux.c *****************************************/
85019 #line 1 "tsrc/vdbeaux.c"
85020 /*
85021 ** 2003 September 6
85022 **
85023 ** The author disclaims copyright to this source code. In place of
85024 ** a legal notice, here is a blessing:
@@ -90566,11 +90552,10 @@
90566 }
90567 #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
90568
90569 /************** End of vdbeaux.c *********************************************/
90570 /************** Begin file vdbeapi.c *****************************************/
90571 #line 1 "tsrc/vdbeapi.c"
90572 /*
90573 ** 2004 May 26
90574 **
90575 ** The author disclaims copyright to this source code. In place of
90576 ** a legal notice, here is a blessing:
@@ -93153,11 +93138,10 @@
93153 }
93154 #endif /* SQLITE_ENABLE_STMT_SCANSTATUS */
93155
93156 /************** End of vdbeapi.c *********************************************/
93157 /************** Begin file vdbetrace.c ***************************************/
93158 #line 1 "tsrc/vdbetrace.c"
93159 /*
93160 ** 2009 November 25
93161 **
93162 ** The author disclaims copyright to this source code. In place of
93163 ** a legal notice, here is a blessing:
@@ -93349,11 +93333,10 @@
93349
93350 #endif /* #ifndef SQLITE_OMIT_TRACE */
93351
93352 /************** End of vdbetrace.c *******************************************/
93353 /************** Begin file vdbe.c ********************************************/
93354 #line 1 "tsrc/vdbe.c"
93355 /*
93356 ** 2001 September 15
93357 **
93358 ** The author disclaims copyright to this source code. In place of
93359 ** a legal notice, here is a blessing:
@@ -93381,11 +93364,10 @@
93381 #if defined(VDBE_PROFILE) \
93382 || defined(SQLITE_PERFORMANCE_TRACE) \
93383 || defined(SQLITE_ENABLE_STMT_SCANSTATUS)
93384 /************** Include hwtime.h in the middle of vdbe.c *********************/
93385 /************** Begin file hwtime.h ******************************************/
93386 #line 1 "tsrc/hwtime.h"
93387 /*
93388 ** 2008 May 27
93389 **
93390 ** The author disclaims copyright to this source code. In place of
93391 ** a legal notice, here is a blessing:
@@ -93470,11 +93452,10 @@
93470
93471 #endif /* !defined(SQLITE_HWTIME_H) */
93472
93473 /************** End of hwtime.h **********************************************/
93474 /************** Continuing where we left off in vdbe.c ***********************/
93475 #line 31 "tsrc/vdbe.c"
93476 #endif
93477
93478 /*
93479 ** Invoke this macro on memory cells just prior to changing the
93480 ** value of the cell. This macro verifies that shallow copies are
@@ -102664,11 +102645,10 @@
102664 }
102665
102666
102667 /************** End of vdbe.c ************************************************/
102668 /************** Begin file vdbeblob.c ****************************************/
102669 #line 1 "tsrc/vdbeblob.c"
102670 /*
102671 ** 2007 May 1
102672 **
102673 ** The author disclaims copyright to this source code. In place of
102674 ** a legal notice, here is a blessing:
@@ -103188,11 +103168,10 @@
103188
103189 #endif /* #ifndef SQLITE_OMIT_INCRBLOB */
103190
103191 /************** End of vdbeblob.c ********************************************/
103192 /************** Begin file vdbesort.c ****************************************/
103193 #line 1 "tsrc/vdbesort.c"
103194 /*
103195 ** 2011-07-09
103196 **
103197 ** The author disclaims copyright to this source code. In place of
103198 ** a legal notice, here is a blessing:
@@ -105959,11 +105938,10 @@
105959 return SQLITE_OK;
105960 }
105961
105962 /************** End of vdbesort.c ********************************************/
105963 /************** Begin file vdbevtab.c ****************************************/
105964 #line 1 "tsrc/vdbevtab.c"
105965 /*
105966 ** 2020-03-23
105967 **
105968 ** The author disclaims copyright to this source code. In place of
105969 ** a legal notice, here is a blessing:
@@ -106409,11 +106387,10 @@
106409 SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){ return SQLITE_OK; }
106410 #endif /* SQLITE_ENABLE_BYTECODE_VTAB */
106411
106412 /************** End of vdbevtab.c ********************************************/
106413 /************** Begin file memjournal.c **************************************/
106414 #line 1 "tsrc/memjournal.c"
106415 /*
106416 ** 2008 October 7
106417 **
106418 ** The author disclaims copyright to this source code. In place of
106419 ** a legal notice, here is a blessing:
@@ -106853,11 +106830,10 @@
106853 return MAX(pVfs->szOsFile, (int)sizeof(MemJournal));
106854 }
106855
106856 /************** End of memjournal.c ******************************************/
106857 /************** Begin file walker.c ******************************************/
106858 #line 1 "tsrc/walker.c"
106859 /*
106860 ** 2008 August 16
106861 **
106862 ** The author disclaims copyright to this source code. In place of
106863 ** a legal notice, here is a blessing:
@@ -107118,11 +107094,10 @@
107118 return WRC_Continue;
107119 }
107120
107121 /************** End of walker.c **********************************************/
107122 /************** Begin file resolve.c *****************************************/
107123 #line 1 "tsrc/resolve.c"
107124 /*
107125 ** 2008 August 18
107126 **
107127 ** The author disclaims copyright to this source code. In place of
107128 ** a legal notice, here is a blessing:
@@ -109440,11 +109415,10 @@
109440 return rc;
109441 }
109442
109443 /************** End of resolve.c *********************************************/
109444 /************** Begin file expr.c ********************************************/
109445 #line 1 "tsrc/expr.c"
109446 /*
109447 ** 2001 September 15
109448 **
109449 ** The author disclaims copyright to this source code. In place of
109450 ** a legal notice, here is a blessing:
@@ -112089,11 +112063,11 @@
112089 **
112090 ** (4) If pSrc is the right operand of a LEFT JOIN, then...
112091 ** (4a) pExpr must come from an ON clause..
112092 ** (4b) and specifically the ON clause associated with the LEFT JOIN.
112093 **
112094 ** (5) If pSrc is not the right operand of a LEFT JOIN or the left
112095 ** operand of a RIGHT JOIN, then pExpr must be from the WHERE
112096 ** clause, not an ON clause.
112097 **
112098 ** (6) Either:
112099 **
@@ -115623,35 +115597,41 @@
115623 **
115624 ** Additionally, if pExpr is a simple SQL value and the value is the
115625 ** same as that currently bound to variable pVar, non-zero is returned.
115626 ** Otherwise, if the values are not the same or if pExpr is not a simple
115627 ** SQL value, zero is returned.
 
 
 
115628 */
115629 static int exprCompareVariable(
115630 const Parse *pParse,
115631 const Expr *pVar,
115632 const Expr *pExpr
115633 ){
115634 int res = 0;
115635 int iVar;
115636 sqlite3_value *pL, *pR = 0;
115637
 
 
 
 
115638 sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR);
115639 if( pR ){
115640 iVar = pVar->iColumn;
115641 sqlite3VdbeSetVarmask(pParse->pVdbe, iVar);
115642 pL = sqlite3VdbeGetBoundValue(pParse->pReprepare, iVar, SQLITE_AFF_BLOB);
115643 if( pL ){
115644 if( sqlite3_value_type(pL)==SQLITE_TEXT ){
115645 sqlite3_value_text(pL); /* Make sure the encoding is UTF-8 */
115646 }
115647 res = 0==sqlite3MemCompare(pL, pR, 0);
115648 }
115649 sqlite3ValueFree(pR);
115650 sqlite3ValueFree(pL);
115651 }
115652
115653 return res;
115654 }
115655
115656 /*
115657 ** Do a deep comparison of two expression trees. Return 0 if the two
@@ -115673,16 +115653,14 @@
115673 ** can be sure the expressions are the same. In the places where
115674 ** this routine is used, it does not hurt to get an extra 2 - that
115675 ** just might result in some slightly slower code. But returning
115676 ** an incorrect 0 or 1 could lead to a malfunction.
115677 **
115678 ** If pParse is not NULL then TK_VARIABLE terms in pA with bindings in
115679 ** pParse->pReprepare can be matched against literals in pB. The
115680 ** pParse->pVdbe->expmask bitmask is updated for each variable referenced.
115681 ** If pParse is NULL (the normal case) then any TK_VARIABLE term in
115682 ** Argument pParse should normally be NULL. If it is not NULL and pA or
115683 ** pB causes a return value of 2.
115684 */
115685 SQLITE_PRIVATE int sqlite3ExprCompare(
115686 const Parse *pParse,
115687 const Expr *pA,
115688 const Expr *pB,
@@ -115690,12 +115668,12 @@
115690 ){
115691 u32 combinedFlags;
115692 if( pA==0 || pB==0 ){
115693 return pB==pA ? 0 : 2;
115694 }
115695 if( pParse && pA->op==TK_VARIABLE && exprCompareVariable(pParse, pA, pB) ){
115696 return 0;
115697 }
115698 combinedFlags = pA->flags | pB->flags;
115699 if( combinedFlags & EP_IntValue ){
115700 if( (pA->flags&pB->flags&EP_IntValue)!=0 && pA->u.iValue==pB->u.iValue ){
115701 return 0;
@@ -115885,23 +115863,75 @@
115885 return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
115886 }
115887 }
115888 return 0;
115889 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115890
115891 /*
115892 ** Return true if we can prove the pE2 will always be true if pE1 is
115893 ** true. Return false if we cannot complete the proof or if pE2 might
115894 ** be false. Examples:
115895 **
115896 ** pE1: x==5 pE2: x==5 Result: true
115897 ** pE1: x>0 pE2: x==5 Result: false
115898 ** pE1: x=21 pE2: x=21 OR y=43 Result: true
115899 ** pE1: x!=123 pE2: x IS NOT NULL Result: true
115900 ** pE1: x!=?1 pE2: x IS NOT NULL Result: true
115901 ** pE1: x IS NULL pE2: x IS NOT NULL Result: false
115902 ** pE1: x IS ?2 pE2: x IS NOT NULL Result: false
 
 
115903 **
115904 ** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has
115905 ** Expr.iTable<0 then assume a table number given by iTab.
115906 **
115907 ** If pParse is not NULL, then the values of bound variables in pE1 are
@@ -115931,10 +115961,13 @@
115931 if( pE2->op==TK_NOTNULL
115932 && exprImpliesNotNull(pParse, pE1, pE2->pLeft, iTab, 0)
115933 ){
115934 return 1;
115935 }
 
 
 
115936 return 0;
115937 }
115938
115939 /* This is a helper function to impliesNotNullRow(). In this routine,
115940 ** set pWalker->eCode to one only if *both* of the input expressions
@@ -116770,11 +116803,10 @@
116770 }
116771 #endif /* SQLITE_DEBUG */
116772
116773 /************** End of expr.c ************************************************/
116774 /************** Begin file alter.c *******************************************/
116775 #line 1 "tsrc/alter.c"
116776 /*
116777 ** 2005 February 15
116778 **
116779 ** The author disclaims copyright to this source code. In place of
116780 ** a legal notice, here is a blessing:
@@ -119090,11 +119122,10 @@
119090 }
119091 #endif /* SQLITE_ALTER_TABLE */
119092
119093 /************** End of alter.c ***********************************************/
119094 /************** Begin file analyze.c *****************************************/
119095 #line 1 "tsrc/analyze.c"
119096 /*
119097 ** 2005-07-08
119098 **
119099 ** The author disclaims copyright to this source code. In place of
119100 ** a legal notice, here is a blessing:
@@ -121115,11 +121146,10 @@
121115
121116 #endif /* SQLITE_OMIT_ANALYZE */
121117
121118 /************** End of analyze.c *********************************************/
121119 /************** Begin file attach.c ******************************************/
121120 #line 1 "tsrc/attach.c"
121121 /*
121122 ** 2003 April 6
121123 **
121124 ** The author disclaims copyright to this source code. In place of
121125 ** a legal notice, here is a blessing:
@@ -121728,11 +121758,10 @@
121728 }
121729 #endif
121730
121731 /************** End of attach.c **********************************************/
121732 /************** Begin file auth.c ********************************************/
121733 #line 1 "tsrc/auth.c"
121734 /*
121735 ** 2003 January 11
121736 **
121737 ** The author disclaims copyright to this source code. In place of
121738 ** a legal notice, here is a blessing:
@@ -121992,11 +122021,10 @@
121992
121993 #endif /* SQLITE_OMIT_AUTHORIZATION */
121994
121995 /************** End of auth.c ************************************************/
121996 /************** Begin file build.c *******************************************/
121997 #line 1 "tsrc/build.c"
121998 /*
121999 ** 2001 September 15
122000 **
122001 ** The author disclaims copyright to this source code. In place of
122002 ** a legal notice, here is a blessing:
@@ -127763,11 +127791,10 @@
127763 }
127764 #endif /* !defined(SQLITE_OMIT_CTE) */
127765
127766 /************** End of build.c ***********************************************/
127767 /************** Begin file callback.c ****************************************/
127768 #line 1 "tsrc/callback.c"
127769 /*
127770 ** 2005 May 23
127771 **
127772 ** The author disclaims copyright to this source code. In place of
127773 ** a legal notice, here is a blessing:
@@ -128307,11 +128334,10 @@
128307 return p;
128308 }
128309
128310 /************** End of callback.c ********************************************/
128311 /************** Begin file delete.c ******************************************/
128312 #line 1 "tsrc/delete.c"
128313 /*
128314 ** 2001 September 15
128315 **
128316 ** The author disclaims copyright to this source code. In place of
128317 ** a legal notice, here is a blessing:
@@ -129341,11 +129367,10 @@
129341 }
129342 }
129343
129344 /************** End of delete.c **********************************************/
129345 /************** Begin file func.c ********************************************/
129346 #line 1 "tsrc/func.c"
129347 /*
129348 ** 2002 February 23
129349 **
129350 ** The author disclaims copyright to this source code. In place of
129351 ** a legal notice, here is a blessing:
@@ -132158,11 +132183,14 @@
132158 MFUNCTION(degrees, 1, radToDeg, math1Func ),
132159 MFUNCTION(pi, 0, 0, piFunc ),
132160 #endif /* SQLITE_ENABLE_MATH_FUNCTIONS */
132161 FUNCTION(sign, 1, 0, 0, signFunc ),
132162 INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, 0 ),
 
132163 INLINE_FUNC(iif, 3, INLINEFUNC_iif, 0 ),
 
 
132164 };
132165 #ifndef SQLITE_OMIT_ALTERTABLE
132166 sqlite3AlterFunctions();
132167 #endif
132168 sqlite3WindowFunctions();
@@ -132188,11 +132216,10 @@
132188 #endif
132189 }
132190
132191 /************** End of func.c ************************************************/
132192 /************** Begin file fkey.c ********************************************/
132193 #line 1 "tsrc/fkey.c"
132194 /*
132195 **
132196 ** The author disclaims copyright to this source code. In place of
132197 ** a legal notice, here is a blessing:
132198 **
@@ -133676,11 +133703,10 @@
133676 }
133677 #endif /* ifndef SQLITE_OMIT_FOREIGN_KEY */
133678
133679 /************** End of fkey.c ************************************************/
133680 /************** Begin file insert.c ******************************************/
133681 #line 1 "tsrc/insert.c"
133682 /*
133683 ** 2001 September 15
133684 **
133685 ** The author disclaims copyright to this source code. In place of
133686 ** a legal notice, here is a blessing:
@@ -137072,11 +137098,10 @@
137072 }
137073 #endif /* SQLITE_OMIT_XFER_OPT */
137074
137075 /************** End of insert.c **********************************************/
137076 /************** Begin file legacy.c ******************************************/
137077 #line 1 "tsrc/legacy.c"
137078 /*
137079 ** 2001 September 15
137080 **
137081 ** The author disclaims copyright to this source code. In place of
137082 ** a legal notice, here is a blessing:
@@ -137217,11 +137242,10 @@
137217 return rc;
137218 }
137219
137220 /************** End of legacy.c **********************************************/
137221 /************** Begin file loadext.c *****************************************/
137222 #line 1 "tsrc/loadext.c"
137223 /*
137224 ** 2006 June 7
137225 **
137226 ** The author disclaims copyright to this source code. In place of
137227 ** a legal notice, here is a blessing:
@@ -137238,11 +137262,10 @@
137238 #ifndef SQLITE_CORE
137239 #define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */
137240 #endif
137241 /************** Include sqlite3ext.h in the middle of loadext.c **************/
137242 /************** Begin file sqlite3ext.h **************************************/
137243 #line 1 "tsrc/sqlite3ext.h"
137244 /*
137245 ** 2006 June 7
137246 **
137247 ** The author disclaims copyright to this source code. In place of
137248 ** a legal notice, here is a blessing:
@@ -137961,11 +137984,10 @@
137961
137962 #endif /* SQLITE3EXT_H */
137963
137964 /************** End of sqlite3ext.h ******************************************/
137965 /************** Continuing where we left off in loadext.c ********************/
137966 #line 20 "tsrc/loadext.c"
137967 /* #include "sqliteInt.h" */
137968
137969 #ifndef SQLITE_OMIT_LOAD_EXTENSION
137970 /*
137971 ** Some API routines are omitted when various features are
@@ -138867,11 +138889,10 @@
138867 }
138868 }
138869
138870 /************** End of loadext.c *********************************************/
138871 /************** Begin file pragma.c ******************************************/
138872 #line 1 "tsrc/pragma.c"
138873 /*
138874 ** 2003 April 6
138875 **
138876 ** The author disclaims copyright to this source code. In place of
138877 ** a legal notice, here is a blessing:
@@ -138900,11 +138921,10 @@
138900 ** lexicographical order to facility a binary search of the pragma name.
138901 ** Do not edit pragma.h directly. Edit and rerun the script in at
138902 ** ../tool/mkpragmatab.tcl. */
138903 /************** Include pragma.h in the middle of pragma.c *******************/
138904 /************** Begin file pragma.h ******************************************/
138905 #line 1 "tsrc/pragma.h"
138906 /* DO NOT EDIT!
138907 ** This file is automatically generated by the script at
138908 ** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit
138909 ** that script and rerun it.
138910 */
@@ -139564,11 +139584,10 @@
139564 };
139565 /* Number of pragmas: 68 on by default, 78 total. */
139566
139567 /************** End of pragma.h **********************************************/
139568 /************** Continuing where we left off in pragma.c *********************/
139569 #line 32 "tsrc/pragma.c"
139570
139571 /*
139572 ** When the 0x10 bit of PRAGMA optimize is set, any ANALYZE commands
139573 ** will be run with an analysis_limit set to the lessor of the value of
139574 ** the following macro or to the actual analysis_limit if it is non-zero,
@@ -140815,11 +140834,12 @@
140815 pTab = sqliteHashData(k);
140816 if( pTab->nCol==0 ){
140817 char *zSql = sqlite3MPrintf(db, "SELECT*FROM\"%w\"", pTab->zName);
140818 if( zSql ){
140819 sqlite3_stmt *pDummy = 0;
140820 (void)sqlite3_prepare(db, zSql, -1, &pDummy, 0);
 
140821 (void)sqlite3_finalize(pDummy);
140822 sqlite3DbFree(db, zSql);
140823 }
140824 if( db->mallocFailed ){
140825 sqlite3ErrorMsg(db->pParse, "out of memory");
@@ -142608,11 +142628,10 @@
142608
142609 #endif /* SQLITE_OMIT_PRAGMA */
142610
142611 /************** End of pragma.c **********************************************/
142612 /************** Begin file prepare.c *****************************************/
142613 #line 1 "tsrc/prepare.c"
142614 /*
142615 ** 2005 May 25
142616 **
142617 ** The author disclaims copyright to this source code. In place of
142618 ** a legal notice, here is a blessing:
@@ -143702,11 +143721,10 @@
143702
143703 #endif /* SQLITE_OMIT_UTF16 */
143704
143705 /************** End of prepare.c *********************************************/
143706 /************** Begin file select.c ******************************************/
143707 #line 1 "tsrc/select.c"
143708 /*
143709 ** 2001 September 15
143710 **
143711 ** The author disclaims copyright to this source code. In place of
143712 ** a legal notice, here is a blessing:
@@ -147616,36 +147634,36 @@
147616 return pExpr;
147617 }
147618 if( pSubst->isOuterJoin ){
147619 ExprSetProperty(pNew, EP_CanBeNull);
147620 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147621 if( ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) ){
147622 sqlite3SetJoinExpr(pNew, pExpr->w.iJoin,
147623 pExpr->flags & (EP_OuterON|EP_InnerON));
147624 }
147625 sqlite3ExprDelete(db, pExpr);
147626 pExpr = pNew;
147627 if( pExpr->op==TK_TRUEFALSE ){
147628 pExpr->u.iValue = sqlite3ExprTruthValue(pExpr);
147629 pExpr->op = TK_INTEGER;
147630 ExprSetProperty(pExpr, EP_IntValue);
147631 }
147632
147633 /* Ensure that the expression now has an implicit collation sequence,
147634 ** just as it did when it was a column of a view or sub-query. */
147635 {
147636 CollSeq *pNat = sqlite3ExprCollSeq(pSubst->pParse, pExpr);
147637 CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse,
147638 pSubst->pCList->a[iColumn].pExpr
147639 );
147640 if( pNat!=pColl || (pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE) ){
147641 pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr,
147642 (pColl ? pColl->zName : "BINARY")
147643 );
147644 }
147645 }
147646 ExprClearProperty(pExpr, EP_Collate);
147647 }
147648 }
147649 }else{
147650 if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){
147651 pExpr->iTable = pSubst->iNewTable;
@@ -148378,20 +148396,20 @@
148378 }
148379
148380 /* Transfer the FROM clause terms from the subquery into the
148381 ** outer query.
148382 */
 
148383 for(i=0; i<nSubSrc; i++){
148384 SrcItem *pItem = &pSrc->a[i+iFrom];
148385 assert( pItem->fg.isTabFunc==0 );
148386 assert( pItem->fg.isSubquery
148387 || pItem->fg.fixedSchema
148388 || pItem->u4.zDatabase==0 );
148389 if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing);
148390 *pItem = pSubSrc->a[i];
148391 pItem->fg.jointype |= ltorj;
148392 iNewParent = pSubSrc->a[i].iCursor;
148393 memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
148394 }
148395 pSrc->a[iFrom].fg.jointype &= JT_LTORJ;
148396 pSrc->a[iFrom].fg.jointype |= jointype | ltorj;
148397
@@ -148427,10 +148445,11 @@
148427 pSub->pOrderBy = 0;
148428 }
148429 pWhere = pSub->pWhere;
148430 pSub->pWhere = 0;
148431 if( isOuterJoin>0 ){
 
148432 sqlite3SetJoinExpr(pWhere, iNewParent, EP_OuterON);
148433 }
148434 if( pWhere ){
148435 if( pParent->pWhere ){
148436 pParent->pWhere = sqlite3PExpr(pParse, TK_AND, pWhere, pParent->pWhere);
@@ -151526,11 +151545,11 @@
151526 sqlite3TreeViewSelect(0, p, 0);
151527 }
151528 #endif
151529 assert( pSubq->pSelect && (pSub->selFlags & SF_PushDown)!=0 );
151530 }else{
151531 TREETRACE(0x4000,pParse,p,("WHERE-lcause push-down not possible\n"));
151532 }
151533
151534 /* Convert unused result columns of the subquery into simple NULL
151535 ** expressions, to avoid unneeded searching and computation.
151536 ** tag-select-0440
@@ -152475,11 +152494,10 @@
152475 return rc;
152476 }
152477
152478 /************** End of select.c **********************************************/
152479 /************** Begin file table.c *******************************************/
152480 #line 1 "tsrc/table.c"
152481 /*
152482 ** 2001 September 15
152483 **
152484 ** The author disclaims copyright to this source code. In place of
152485 ** a legal notice, here is a blessing:
@@ -152677,11 +152695,10 @@
152677
152678 #endif /* SQLITE_OMIT_GET_TABLE */
152679
152680 /************** End of table.c ***********************************************/
152681 /************** Begin file trigger.c *****************************************/
152682 #line 1 "tsrc/trigger.c"
152683 /*
152684 **
152685 ** The author disclaims copyright to this source code. In place of
152686 ** a legal notice, here is a blessing:
152687 **
@@ -154244,11 +154261,10 @@
154244
154245 #endif /* !defined(SQLITE_OMIT_TRIGGER) */
154246
154247 /************** End of trigger.c *********************************************/
154248 /************** Begin file update.c ******************************************/
154249 #line 1 "tsrc/update.c"
154250 /*
154251 ** 2001 September 15
154252 **
154253 ** The author disclaims copyright to this source code. In place of
154254 ** a legal notice, here is a blessing:
@@ -155616,11 +155632,10 @@
155616 }
155617 #endif /* SQLITE_OMIT_VIRTUALTABLE */
155618
155619 /************** End of update.c **********************************************/
155620 /************** Begin file upsert.c ******************************************/
155621 #line 1 "tsrc/upsert.c"
155622 /*
155623 ** 2018-04-12
155624 **
155625 ** The author disclaims copyright to this source code. In place of
155626 ** a legal notice, here is a blessing:
@@ -155949,11 +155964,10 @@
155949
155950 #endif /* SQLITE_OMIT_UPSERT */
155951
155952 /************** End of upsert.c **********************************************/
155953 /************** Begin file vacuum.c ******************************************/
155954 #line 1 "tsrc/vacuum.c"
155955 /*
155956 ** 2003 April 6
155957 **
155958 ** The author disclaims copyright to this source code. In place of
155959 ** a legal notice, here is a blessing:
@@ -156371,11 +156385,10 @@
156371
156372 #endif /* SQLITE_OMIT_VACUUM && SQLITE_OMIT_ATTACH */
156373
156374 /************** End of vacuum.c **********************************************/
156375 /************** Begin file vtab.c ********************************************/
156376 #line 1 "tsrc/vtab.c"
156377 /*
156378 ** 2006 June 10
156379 **
156380 ** The author disclaims copyright to this source code. In place of
156381 ** a legal notice, here is a blessing:
@@ -157749,11 +157762,10 @@
157749
157750 #endif /* SQLITE_OMIT_VIRTUALTABLE */
157751
157752 /************** End of vtab.c ************************************************/
157753 /************** Begin file wherecode.c ***************************************/
157754 #line 1 "tsrc/wherecode.c"
157755 /*
157756 ** 2015-06-06
157757 **
157758 ** The author disclaims copyright to this source code. In place of
157759 ** a legal notice, here is a blessing:
@@ -157772,11 +157784,10 @@
157772 ** file retains the code that does query planning and analysis.
157773 */
157774 /* #include "sqliteInt.h" */
157775 /************** Include whereInt.h in the middle of wherecode.c **************/
157776 /************** Begin file whereInt.h ****************************************/
157777 #line 1 "tsrc/whereInt.h"
157778 /*
157779 ** 2013-11-12
157780 **
157781 ** The author disclaims copyright to this source code. In place of
157782 ** a legal notice, here is a blessing:
@@ -158429,11 +158440,10 @@
158429
158430 #endif /* !defined(SQLITE_WHEREINT_H) */
158431
158432 /************** End of whereInt.h ********************************************/
158433 /************** Continuing where we left off in wherecode.c ******************/
158434 #line 22 "tsrc/wherecode.c"
158435
158436 #ifndef SQLITE_OMIT_EXPLAIN
158437
158438 /*
158439 ** Return the name of the i-th column of the pIdx index.
@@ -159026,10 +159036,11 @@
159026 if( pOrigLhs ){
159027 sqlite3ExprListDelete(db, pOrigLhs);
159028 pNew->pLeft->x.pList = pLhs;
159029 }
159030 pSelect->pEList = pRhs;
 
159031 if( pLhs && pLhs->nExpr==1 ){
159032 /* Take care here not to generate a TK_VECTOR containing only a
159033 ** single value. Since the parser never creates such a vector, some
159034 ** of the subroutines do not handle this case. */
159035 Expr *p = pLhs->a[0].pExpr;
@@ -161352,11 +161363,10 @@
161352 pParse->withinRJSubrtn--;
161353 }
161354
161355 /************** End of wherecode.c *******************************************/
161356 /************** Begin file whereexpr.c ***************************************/
161357 #line 1 "tsrc/whereexpr.c"
161358 /*
161359 ** 2015-06-08
161360 **
161361 ** The author disclaims copyright to this source code. In place of
161362 ** a legal notice, here is a blessing:
@@ -163258,11 +163268,10 @@
163258 }
163259 }
163260
163261 /************** End of whereexpr.c *******************************************/
163262 /************** Begin file where.c *******************************************/
163263 #line 1 "tsrc/where.c"
163264 /*
163265 ** 2001 September 15
163266 **
163267 ** The author disclaims copyright to this source code. In place of
163268 ** a legal notice, here is a blessing:
@@ -164100,11 +164109,11 @@
164100 || pTerm->pExpr->w.iJoin != pSrc->iCursor
164101 ){
164102 return 0;
164103 }
164104 if( (pSrc->fg.jointype & (JT_LEFT|JT_RIGHT))!=0
164105 && ExprHasProperty(pTerm->pExpr, EP_InnerON)
164106 ){
164107 return 0;
164108 }
164109 return 1;
164110 }
@@ -165593,11 +165602,11 @@
165593 return rc;
165594 }
165595 #endif /* SQLITE_ENABLE_STAT4 */
165596
165597
165598 #ifdef WHERETRACE_ENABLED
165599 /*
165600 ** Print the content of a WhereTerm object
165601 */
165602 SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){
165603 if( pTerm==0 ){
@@ -165636,10 +165645,13 @@
165636 sqlite3DebugPrintf(" iParent=%d", pTerm->iParent);
165637 }
165638 sqlite3DebugPrintf("\n");
165639 sqlite3TreeViewExpr(0, pTerm->pExpr, 0);
165640 }
 
 
 
165641 }
165642 #endif
165643
165644 #ifdef WHERETRACE_ENABLED
165645 /*
@@ -166822,11 +166834,10 @@
166822 pParse = pWC->pWInfo->pParse;
166823 while( pWhere->op==TK_AND ){
166824 if( !whereUsablePartialIndex(iTab,jointype,pWC,pWhere->pLeft) ) return 0;
166825 pWhere = pWhere->pRight;
166826 }
166827 if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
166828 for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
166829 Expr *pExpr;
166830 pExpr = pTerm->pExpr;
166831 if( (!ExprHasProperty(pExpr, EP_OuterON) || pExpr->w.iJoin==iTab)
166832 && ((jointype & JT_OUTER)==0 || ExprHasProperty(pExpr, EP_OuterON))
@@ -169483,11 +169494,11 @@
169483 break;
169484 }
169485 }
169486 if( hasRightJoin
169487 && ExprHasProperty(pTerm->pExpr, EP_InnerON)
169488 && pTerm->pExpr->w.iJoin==pItem->iCursor
169489 ){
169490 break; /* restriction (5) */
169491 }
169492 }
169493 if( pTerm<pEnd ) continue;
@@ -170759,11 +170770,10 @@
170759 return;
170760 }
170761
170762 /************** End of where.c ***********************************************/
170763 /************** Begin file window.c ******************************************/
170764 #line 1 "tsrc/window.c"
170765 /*
170766 ** 2018 May 08
170767 **
170768 ** The author disclaims copyright to this source code. In place of
170769 ** a legal notice, here is a blessing:
@@ -172432,10 +172442,11 @@
172432 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
172433 FuncDef *pFunc = pWin->pWFunc;
172434 int regArg;
172435 int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin);
172436 int i;
 
172437
172438 assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED );
172439
172440 /* All OVER clauses in the same window function aggregate step must
172441 ** be the same. */
@@ -172447,10 +172458,22 @@
172447 }else{
172448 sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+i, reg+i);
172449 }
172450 }
172451 regArg = reg;
 
 
 
 
 
 
 
 
 
 
 
 
172452
172453 if( pMWin->regStartRowid==0
172454 && (pFunc->funcFlags & SQLITE_FUNC_MINMAX)
172455 && (pWin->eStart!=TK_UNBOUNDED)
172456 ){
@@ -172467,29 +172490,17 @@
172467 sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp);
172468 sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
172469 }
172470 sqlite3VdbeJumpHere(v, addrIsNull);
172471 }else if( pWin->regApp ){
 
172472 assert( pFunc->zName==nth_valueName
172473 || pFunc->zName==first_valueName
172474 );
172475 assert( bInverse==0 || bInverse==1 );
172476 sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
172477 }else if( pFunc->xSFunc!=noopStepFunc ){
172478 int addrIf = 0;
172479 if( pWin->pFilter ){
172480 int regTmp;
172481 assert( ExprUseXList(pWin->pOwner) );
172482 assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr );
172483 assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 );
172484 regTmp = sqlite3GetTempReg(pParse);
172485 sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
172486 addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
172487 VdbeCoverage(v);
172488 sqlite3ReleaseTempReg(pParse, regTmp);
172489 }
172490
172491 if( pWin->bExprArgs ){
172492 int iOp = sqlite3VdbeCurrentAddr(v);
172493 int iEnd;
172494
172495 assert( ExprUseXList(pWin->pOwner) );
@@ -172516,12 +172527,13 @@
172516 sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF);
172517 sqlite3VdbeChangeP5(v, (u8)nArg);
172518 if( pWin->bExprArgs ){
172519 sqlite3ReleaseTempRange(pParse, regArg, nArg);
172520 }
172521 if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
172522 }
 
 
172523 }
172524 }
172525
172526 /*
172527 ** Values that may be passed as the second argument to windowCodeOp().
@@ -173869,11 +173881,10 @@
173869
173870 #endif /* SQLITE_OMIT_WINDOWFUNC */
173871
173872 /************** End of window.c **********************************************/
173873 /************** Begin file parse.c *******************************************/
173874 #line 1 "tsrc/parse.c"
173875 /* This file is automatically generated by Lemon from input grammar
173876 ** source file "parse.y".
173877 */
173878 /*
173879 ** 2001-09-15
@@ -173893,11 +173904,10 @@
173893 ** That input file is processed by Lemon to generate a C-language
173894 ** implementation of a parser for the given grammar. You might be reading
173895 ** this comment as part of the translated C-code. Edits should be made
173896 ** to the original parse.y sources.
173897 */
173898 #line 62 "parse.y"
173899
173900 /* #include "sqliteInt.h" */
173901
173902 /*
173903 ** Disable all error recovery processing in the parser push-down
@@ -173945,10 +173955,17 @@
173945 ** Then the "b" IdList records the list "a,b,c".
173946 */
173947 struct TrigEvent { int a; IdList * b; };
173948
173949 struct FrameBound { int eType; Expr *pExpr; };
 
 
 
 
 
 
 
173950
173951 /*
173952 ** Disable lookaside memory allocation for objects that might be
173953 ** shared across database connections.
173954 */
@@ -173977,11 +173994,10 @@
173977 sqlite3ExprListDelete(pParse->db, pOrderBy);
173978 sqlite3ExprDelete(pParse->db, pLimit);
173979 }
173980 #endif /* SQLITE_ENABLE_UPDATE_DELETE_LIMIT */
173981
173982 #line 517 "parse.y"
173983
173984 /*
173985 ** For a compound SELECT statement, make sure p->pPrior->pNext==p for
173986 ** all elements in the list. And make sure list length does not exceed
173987 ** SQLITE_LIMIT_COMPOUND_SELECT.
@@ -174032,11 +174048,10 @@
174032 ** testing.
174033 */
174034 static void *parserStackRealloc(void *pOld, sqlite3_uint64 newSize){
174035 return sqlite3FaultSim(700) ? 0 : sqlite3_realloc(pOld, newSize);
174036 }
174037 #line 1085 "parse.y"
174038
174039
174040 /* Construct a new Expr object from a single token */
174041 static Expr *tokenExpr(Parse *pParse, int op, Token t){
174042 Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
@@ -174069,11 +174084,10 @@
174069 }
174070 }
174071 return p;
174072 }
174073
174074 #line 1329 "parse.y"
174075
174076 /* A routine to convert a binary TK_IS or TK_ISNOT expression into a
174077 ** unary TK_ISNULL or TK_NOTNULL expression. */
174078 static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){
174079 sqlite3 *db = pParse->db;
@@ -174081,11 +174095,10 @@
174081 pA->op = (u8)op;
174082 sqlite3ExprDelete(db, pA->pRight);
174083 pA->pRight = 0;
174084 }
174085 }
174086 #line 1564 "parse.y"
174087
174088 /* Add a single new term to an ExprList that is used to store a
174089 ** list of identifiers. Report an error if the ID list contains
174090 ** a COLLATE clause or an ASC or DESC keyword, except ignore the
174091 ** error while parsing a legacy schema.
@@ -174105,16 +174118,14 @@
174105 pIdToken->n, pIdToken->z);
174106 }
174107 sqlite3ExprListSetName(pParse, p, pIdToken, 1);
174108 return p;
174109 }
174110 #line 2048 "parse.y"
174111
174112 #if TK_SPAN>255
174113 # error too many tokens in the grammar
174114 #endif
174115 #line 267 "parse.sql"
174116 /**************** End of %include directives **********************************/
174117 /* These constants specify the various numeric values for terminal symbols.
174118 ***************** Begin token definitions *************************************/
174119 #ifndef TK_SEMI
174120 #define TK_SEMI 1
@@ -176295,13 +176306,11 @@
176295 case 240: /* selectnowith */
176296 case 241: /* oneselect */
176297 case 253: /* values */
176298 case 255: /* mvalues */
176299 {
176300 #line 511 "parse.y"
176301 sqlite3SelectDelete(pParse->db, (yypminor->yy555));
176302 #line 2453 "parse.sql"
176303 }
176304 break;
176305 case 217: /* term */
176306 case 218: /* expr */
176307 case 247: /* where_opt */
@@ -176312,13 +176321,11 @@
176312 case 285: /* vinto */
176313 case 292: /* when_clause */
176314 case 297: /* key_opt */
176315 case 314: /* filter_clause */
176316 {
176317 #line 1083 "parse.y"
176318 sqlite3ExprDelete(pParse->db, (yypminor->yy454));
176319 #line 2470 "parse.sql"
176320 }
176321 break;
176322 case 222: /* eidlist_opt */
176323 case 232: /* sortlist */
176324 case 233: /* eidlist */
@@ -176331,82 +176338,64 @@
176331 case 270: /* setlist */
176332 case 279: /* paren_exprlist */
176333 case 281: /* case_exprlist */
176334 case 313: /* part_opt */
176335 {
176336 #line 1562 "parse.y"
176337 sqlite3ExprListDelete(pParse->db, (yypminor->yy14));
176338 #line 2489 "parse.sql"
176339 }
176340 break;
176341 case 239: /* fullname */
176342 case 246: /* from */
176343 case 258: /* seltablist */
176344 case 259: /* stl_prefix */
176345 case 264: /* xfullname */
176346 {
176347 #line 789 "parse.y"
176348 sqlite3SrcListDelete(pParse->db, (yypminor->yy203));
176349 #line 2500 "parse.sql"
176350 }
176351 break;
176352 case 242: /* wqlist */
176353 {
176354 #line 1849 "parse.y"
176355 sqlite3WithDelete(pParse->db, (yypminor->yy59));
176356 #line 2507 "parse.sql"
176357 }
176358 break;
176359 case 252: /* window_clause */
176360 case 309: /* windowdefn_list */
176361 {
176362 #line 1977 "parse.y"
176363 sqlite3WindowListDelete(pParse->db, (yypminor->yy211));
176364 #line 2515 "parse.sql"
176365 }
176366 break;
176367 case 265: /* idlist */
176368 case 272: /* idlist_opt */
176369 {
176370 #line 1068 "parse.y"
176371 sqlite3IdListDelete(pParse->db, (yypminor->yy132));
176372 #line 2523 "parse.sql"
176373 }
176374 break;
176375 case 275: /* filter_over */
176376 case 310: /* windowdefn */
176377 case 311: /* window */
176378 case 312: /* frame_opt */
176379 case 315: /* over_clause */
176380 {
176381 #line 1916 "parse.y"
176382 sqlite3WindowDelete(pParse->db, (yypminor->yy211));
176383 #line 2534 "parse.sql"
176384 }
176385 break;
176386 case 288: /* trigger_cmd_list */
176387 case 293: /* trigger_cmd */
176388 {
176389 #line 1677 "parse.y"
176390 sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy427));
176391 #line 2542 "parse.sql"
176392 }
176393 break;
176394 case 290: /* trigger_event */
176395 {
176396 #line 1663 "parse.y"
176397 sqlite3IdListDelete(pParse->db, (yypminor->yy286).b);
176398 #line 2549 "parse.sql"
176399 }
176400 break;
176401 case 317: /* frame_bound */
176402 case 318: /* frame_bound_s */
176403 case 319: /* frame_bound_e */
176404 {
176405 #line 1921 "parse.y"
176406 sqlite3ExprDelete(pParse->db, (yypminor->yy509).pExpr);
176407 #line 2558 "parse.sql"
176408 }
176409 break;
176410 /********* End destructor definitions *****************************************/
176411 default: break; /* If no destructor action specified: do nothing */
176412 }
@@ -176637,14 +176626,12 @@
176637 #endif
176638 while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
176639 /* Here code is inserted which will execute if the parser
176640 ** stack every overflows */
176641 /******** Begin %stack_overflow code ******************************************/
176642 #line 51 "parse.y"
176643
176644 sqlite3OomFault(pParse->db);
176645 #line 2796 "parse.sql"
176646 /******** End %stack_overflow code ********************************************/
176647 sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument var */
176648 sqlite3ParserCTX_STORE
176649 }
176650
@@ -177571,481 +177558,330 @@
177571 ** break;
177572 */
177573 /********** Begin reduce actions **********************************************/
177574 YYMINORTYPE yylhsminor;
177575 case 0: /* explain ::= EXPLAIN */
177576 #line 155 "parse.y"
177577 { if( pParse->pReprepare==0 ) pParse->explain = 1; }
177578 #line 3729 "parse.sql"
177579 break;
177580 case 1: /* explain ::= EXPLAIN QUERY PLAN */
177581 #line 156 "parse.y"
177582 { if( pParse->pReprepare==0 ) pParse->explain = 2; }
177583 #line 3734 "parse.sql"
177584 break;
177585 case 2: /* cmdx ::= cmd */
177586 #line 158 "parse.y"
177587 { sqlite3FinishCoding(pParse); }
177588 #line 3739 "parse.sql"
177589 break;
177590 case 3: /* cmd ::= BEGIN transtype trans_opt */
177591 #line 163 "parse.y"
177592 {sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy144);}
177593 #line 3744 "parse.sql"
177594 break;
177595 case 4: /* transtype ::= */
177596 #line 168 "parse.y"
177597 {yymsp[1].minor.yy144 = TK_DEFERRED;}
177598 #line 3749 "parse.sql"
177599 break;
177600 case 5: /* transtype ::= DEFERRED */
177601 case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
177602 case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
177603 case 324: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==324);
177604 #line 169 "parse.y"
177605 {yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-X*/}
177606 #line 3757 "parse.sql"
177607 break;
177608 case 8: /* cmd ::= COMMIT|END trans_opt */
177609 case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9);
177610 #line 172 "parse.y"
177611 {sqlite3EndTransaction(pParse,yymsp[-1].major);}
177612 #line 3763 "parse.sql"
177613 break;
177614 case 10: /* cmd ::= SAVEPOINT nm */
177615 #line 177 "parse.y"
177616 {
177617 sqlite3Savepoint(pParse, SAVEPOINT_BEGIN, &yymsp[0].minor.yy0);
177618 }
177619 #line 3770 "parse.sql"
177620 break;
177621 case 11: /* cmd ::= RELEASE savepoint_opt nm */
177622 #line 180 "parse.y"
177623 {
177624 sqlite3Savepoint(pParse, SAVEPOINT_RELEASE, &yymsp[0].minor.yy0);
177625 }
177626 #line 3777 "parse.sql"
177627 break;
177628 case 12: /* cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
177629 #line 183 "parse.y"
177630 {
177631 sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0);
177632 }
177633 #line 3784 "parse.sql"
177634 break;
177635 case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
177636 #line 190 "parse.y"
177637 {
177638 sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy144,0,0,yymsp[-2].minor.yy144);
177639 }
177640 #line 3791 "parse.sql"
177641 break;
177642 case 14: /* createkw ::= CREATE */
177643 #line 193 "parse.y"
177644 {disableLookaside(pParse);}
177645 #line 3796 "parse.sql"
177646 break;
177647 case 15: /* ifnotexists ::= */
177648 case 18: /* temp ::= */ yytestcase(yyruleno==18);
177649 case 47: /* autoinc ::= */ yytestcase(yyruleno==47);
177650 case 62: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==62);
177651 case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72);
177652 case 81: /* ifexists ::= */ yytestcase(yyruleno==81);
177653 case 100: /* distinct ::= */ yytestcase(yyruleno==100);
177654 case 246: /* collate ::= */ yytestcase(yyruleno==246);
177655 #line 196 "parse.y"
177656 {yymsp[1].minor.yy144 = 0;}
177657 #line 3808 "parse.sql"
177658 break;
177659 case 16: /* ifnotexists ::= IF NOT EXISTS */
177660 #line 197 "parse.y"
177661 {yymsp[-2].minor.yy144 = 1;}
177662 #line 3813 "parse.sql"
177663 break;
177664 case 17: /* temp ::= TEMP */
177665 #line 200 "parse.y"
177666 {yymsp[0].minor.yy144 = pParse->db->init.busy==0;}
177667 #line 3818 "parse.sql"
177668 break;
177669 case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_option_set */
177670 #line 203 "parse.y"
177671 {
177672 sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy391,0);
177673 }
177674 #line 3825 "parse.sql"
177675 break;
177676 case 20: /* create_table_args ::= AS select */
177677 #line 206 "parse.y"
177678 {
177679 sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy555);
177680 sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy555);
177681 }
177682 #line 3833 "parse.sql"
177683 break;
177684 case 21: /* table_option_set ::= */
177685 #line 212 "parse.y"
177686 {yymsp[1].minor.yy391 = 0;}
177687 #line 3838 "parse.sql"
177688 break;
177689 case 22: /* table_option_set ::= table_option_set COMMA table_option */
177690 #line 214 "parse.y"
177691 {yylhsminor.yy391 = yymsp[-2].minor.yy391|yymsp[0].minor.yy391;}
177692 #line 3843 "parse.sql"
177693 yymsp[-2].minor.yy391 = yylhsminor.yy391;
177694 break;
177695 case 23: /* table_option ::= WITHOUT nm */
177696 #line 215 "parse.y"
177697 {
177698 if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
177699 yymsp[-1].minor.yy391 = TF_WithoutRowid | TF_NoVisibleRowid;
177700 }else{
177701 yymsp[-1].minor.yy391 = 0;
177702 sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
177703 }
177704 }
177705 #line 3856 "parse.sql"
177706 break;
177707 case 24: /* table_option ::= nm */
177708 #line 223 "parse.y"
177709 {
177710 if( yymsp[0].minor.yy0.n==6 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"strict",6)==0 ){
177711 yylhsminor.yy391 = TF_Strict;
177712 }else{
177713 yylhsminor.yy391 = 0;
177714 sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
177715 }
177716 }
177717 #line 3868 "parse.sql"
177718 yymsp[0].minor.yy391 = yylhsminor.yy391;
177719 break;
177720 case 25: /* columnname ::= nm typetoken */
177721 #line 233 "parse.y"
177722 {sqlite3AddColumn(pParse,yymsp[-1].minor.yy0,yymsp[0].minor.yy0);}
177723 #line 3874 "parse.sql"
177724 break;
177725 case 26: /* typetoken ::= */
177726 case 65: /* conslist_opt ::= */ yytestcase(yyruleno==65);
177727 case 106: /* as ::= */ yytestcase(yyruleno==106);
177728 #line 327 "parse.y"
177729 {yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;}
177730 #line 3881 "parse.sql"
177731 break;
177732 case 27: /* typetoken ::= typename LP signed RP */
177733 #line 329 "parse.y"
177734 {
177735 yymsp[-3].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z);
177736 }
177737 #line 3888 "parse.sql"
177738 break;
177739 case 28: /* typetoken ::= typename LP signed COMMA signed RP */
177740 #line 332 "parse.y"
177741 {
177742 yymsp[-5].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z);
177743 }
177744 #line 3895 "parse.sql"
177745 break;
177746 case 29: /* typename ::= typename ID|STRING */
177747 #line 337 "parse.y"
177748 {yymsp[-1].minor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
177749 #line 3900 "parse.sql"
177750 break;
177751 case 30: /* scanpt ::= */
177752 #line 355 "parse.y"
177753 {
177754 assert( yyLookahead!=YYNOCODE );
177755 yymsp[1].minor.yy168 = yyLookaheadToken.z;
177756 }
177757 #line 3908 "parse.sql"
177758 break;
177759 case 31: /* scantok ::= */
177760 #line 359 "parse.y"
177761 {
177762 assert( yyLookahead!=YYNOCODE );
177763 yymsp[1].minor.yy0 = yyLookaheadToken;
177764 }
177765 #line 3916 "parse.sql"
177766 break;
177767 case 32: /* ccons ::= CONSTRAINT nm */
177768 case 67: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==67);
177769 #line 369 "parse.y"
177770 {pParse->constraintName = yymsp[0].minor.yy0;}
177771 #line 3922 "parse.sql"
177772 break;
177773 case 33: /* ccons ::= DEFAULT scantok term */
177774 #line 371 "parse.y"
177775 {sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
177776 #line 3927 "parse.sql"
177777 break;
177778 case 34: /* ccons ::= DEFAULT LP expr RP */
177779 #line 373 "parse.y"
177780 {sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy454,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
177781 #line 3932 "parse.sql"
177782 break;
177783 case 35: /* ccons ::= DEFAULT PLUS scantok term */
177784 #line 375 "parse.y"
177785 {sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
177786 #line 3937 "parse.sql"
177787 break;
177788 case 36: /* ccons ::= DEFAULT MINUS scantok term */
177789 #line 376 "parse.y"
177790 {
177791 Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy454, 0);
177792 sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);
177793 }
177794 #line 3945 "parse.sql"
177795 break;
177796 case 37: /* ccons ::= DEFAULT scantok ID|INDEXED */
177797 #line 380 "parse.y"
177798 {
177799 Expr *p = tokenExpr(pParse, TK_STRING, yymsp[0].minor.yy0);
177800 if( p ){
177801 sqlite3ExprIdToTrueFalse(p);
177802 testcase( p->op==TK_TRUEFALSE && sqlite3ExprTruthValue(p) );
177803 }
177804 sqlite3AddDefaultValue(pParse,p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.z+yymsp[0].minor.yy0.n);
177805 }
177806 #line 3957 "parse.sql"
177807 break;
177808 case 38: /* ccons ::= NOT NULL onconf */
177809 #line 393 "parse.y"
177810 {sqlite3AddNotNull(pParse, yymsp[0].minor.yy144);}
177811 #line 3962 "parse.sql"
177812 break;
177813 case 39: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
177814 #line 395 "parse.y"
177815 {sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy144,yymsp[0].minor.yy144,yymsp[-2].minor.yy144);}
177816 #line 3967 "parse.sql"
177817 break;
177818 case 40: /* ccons ::= UNIQUE onconf */
177819 #line 396 "parse.y"
177820 {sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy144,0,0,0,0,
177821 SQLITE_IDXTYPE_UNIQUE);}
177822 #line 3973 "parse.sql"
177823 break;
177824 case 41: /* ccons ::= CHECK LP expr RP */
177825 #line 398 "parse.y"
177826 {sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy454,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);}
177827 #line 3978 "parse.sql"
177828 break;
177829 case 42: /* ccons ::= REFERENCES nm eidlist_opt refargs */
177830 #line 400 "parse.y"
177831 {sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy14,yymsp[0].minor.yy144);}
177832 #line 3983 "parse.sql"
177833 break;
177834 case 43: /* ccons ::= defer_subclause */
177835 #line 401 "parse.y"
177836 {sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy144);}
177837 #line 3988 "parse.sql"
177838 break;
177839 case 44: /* ccons ::= COLLATE ID|STRING */
177840 #line 402 "parse.y"
177841 {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
177842 #line 3993 "parse.sql"
177843 break;
177844 case 45: /* generated ::= LP expr RP */
177845 #line 405 "parse.y"
177846 {sqlite3AddGenerated(pParse,yymsp[-1].minor.yy454,0);}
177847 #line 3998 "parse.sql"
177848 break;
177849 case 46: /* generated ::= LP expr RP ID */
177850 #line 406 "parse.y"
177851 {sqlite3AddGenerated(pParse,yymsp[-2].minor.yy454,&yymsp[0].minor.yy0);}
177852 #line 4003 "parse.sql"
177853 break;
177854 case 48: /* autoinc ::= AUTOINCR */
177855 #line 411 "parse.y"
177856 {yymsp[0].minor.yy144 = 1;}
177857 #line 4008 "parse.sql"
177858 break;
177859 case 49: /* refargs ::= */
177860 #line 419 "parse.y"
177861 { yymsp[1].minor.yy144 = OE_None*0x0101; /* EV: R-19803-45884 */}
177862 #line 4013 "parse.sql"
177863 break;
177864 case 50: /* refargs ::= refargs refarg */
177865 #line 420 "parse.y"
177866 { yymsp[-1].minor.yy144 = (yymsp[-1].minor.yy144 & ~yymsp[0].minor.yy383.mask) | yymsp[0].minor.yy383.value; }
177867 #line 4018 "parse.sql"
177868 break;
177869 case 51: /* refarg ::= MATCH nm */
177870 #line 422 "parse.y"
177871 { yymsp[-1].minor.yy383.value = 0; yymsp[-1].minor.yy383.mask = 0x000000; }
177872 #line 4023 "parse.sql"
177873 break;
177874 case 52: /* refarg ::= ON INSERT refact */
177875 #line 423 "parse.y"
177876 { yymsp[-2].minor.yy383.value = 0; yymsp[-2].minor.yy383.mask = 0x000000; }
177877 #line 4028 "parse.sql"
177878 break;
177879 case 53: /* refarg ::= ON DELETE refact */
177880 #line 424 "parse.y"
177881 { yymsp[-2].minor.yy383.value = yymsp[0].minor.yy144; yymsp[-2].minor.yy383.mask = 0x0000ff; }
177882 #line 4033 "parse.sql"
177883 break;
177884 case 54: /* refarg ::= ON UPDATE refact */
177885 #line 425 "parse.y"
177886 { yymsp[-2].minor.yy383.value = yymsp[0].minor.yy144<<8; yymsp[-2].minor.yy383.mask = 0x00ff00; }
177887 #line 4038 "parse.sql"
177888 break;
177889 case 55: /* refact ::= SET NULL */
177890 #line 427 "parse.y"
177891 { yymsp[-1].minor.yy144 = OE_SetNull; /* EV: R-33326-45252 */}
177892 #line 4043 "parse.sql"
177893 break;
177894 case 56: /* refact ::= SET DEFAULT */
177895 #line 428 "parse.y"
177896 { yymsp[-1].minor.yy144 = OE_SetDflt; /* EV: R-33326-45252 */}
177897 #line 4048 "parse.sql"
177898 break;
177899 case 57: /* refact ::= CASCADE */
177900 #line 429 "parse.y"
177901 { yymsp[0].minor.yy144 = OE_Cascade; /* EV: R-33326-45252 */}
177902 #line 4053 "parse.sql"
177903 break;
177904 case 58: /* refact ::= RESTRICT */
177905 #line 430 "parse.y"
177906 { yymsp[0].minor.yy144 = OE_Restrict; /* EV: R-33326-45252 */}
177907 #line 4058 "parse.sql"
177908 break;
177909 case 59: /* refact ::= NO ACTION */
177910 #line 431 "parse.y"
177911 { yymsp[-1].minor.yy144 = OE_None; /* EV: R-33326-45252 */}
177912 #line 4063 "parse.sql"
177913 break;
177914 case 60: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
177915 #line 433 "parse.y"
177916 {yymsp[-2].minor.yy144 = 0;}
177917 #line 4068 "parse.sql"
177918 break;
177919 case 61: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
177920 case 76: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==76);
177921 case 173: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==173);
177922 #line 434 "parse.y"
177923 {yymsp[-1].minor.yy144 = yymsp[0].minor.yy144;}
177924 #line 4075 "parse.sql"
177925 break;
177926 case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
177927 case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80);
177928 case 219: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==219);
177929 case 222: /* in_op ::= NOT IN */ yytestcase(yyruleno==222);
177930 case 247: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==247);
177931 #line 437 "parse.y"
177932 {yymsp[-1].minor.yy144 = 1;}
177933 #line 4084 "parse.sql"
177934 break;
177935 case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
177936 #line 438 "parse.y"
177937 {yymsp[-1].minor.yy144 = 0;}
177938 #line 4089 "parse.sql"
177939 break;
177940 case 66: /* tconscomma ::= COMMA */
177941 #line 444 "parse.y"
177942 {pParse->constraintName.n = 0;}
177943 #line 4094 "parse.sql"
177944 break;
177945 case 68: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
177946 #line 448 "parse.y"
177947 {sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy14,yymsp[0].minor.yy144,yymsp[-2].minor.yy144,0);}
177948 #line 4099 "parse.sql"
177949 break;
177950 case 69: /* tcons ::= UNIQUE LP sortlist RP onconf */
177951 #line 450 "parse.y"
177952 {sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy14,yymsp[0].minor.yy144,0,0,0,0,
177953 SQLITE_IDXTYPE_UNIQUE);}
177954 #line 4105 "parse.sql"
177955 break;
177956 case 70: /* tcons ::= CHECK LP expr RP onconf */
177957 #line 453 "parse.y"
177958 {sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy454,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);}
177959 #line 4110 "parse.sql"
177960 break;
177961 case 71: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
177962 #line 455 "parse.y"
177963 {
177964 sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy14, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[-1].minor.yy144);
177965 sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy144);
177966 }
177967 #line 4118 "parse.sql"
177968 break;
177969 case 73: /* onconf ::= */
177970 case 75: /* orconf ::= */ yytestcase(yyruleno==75);
177971 #line 469 "parse.y"
177972 {yymsp[1].minor.yy144 = OE_Default;}
177973 #line 4124 "parse.sql"
177974 break;
177975 case 74: /* onconf ::= ON CONFLICT resolvetype */
177976 #line 470 "parse.y"
177977 {yymsp[-2].minor.yy144 = yymsp[0].minor.yy144;}
177978 #line 4129 "parse.sql"
177979 break;
177980 case 77: /* resolvetype ::= IGNORE */
177981 #line 474 "parse.y"
177982 {yymsp[0].minor.yy144 = OE_Ignore;}
177983 #line 4134 "parse.sql"
177984 break;
177985 case 78: /* resolvetype ::= REPLACE */
177986 case 174: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==174);
177987 #line 475 "parse.y"
177988 {yymsp[0].minor.yy144 = OE_Replace;}
177989 #line 4140 "parse.sql"
177990 break;
177991 case 79: /* cmd ::= DROP TABLE ifexists fullname */
177992 #line 479 "parse.y"
177993 {
177994 sqlite3DropTable(pParse, yymsp[0].minor.yy203, 0, yymsp[-1].minor.yy144);
177995 }
177996 #line 4147 "parse.sql"
177997 break;
177998 case 82: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
177999 #line 490 "parse.y"
178000 {
178001 sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[0].minor.yy555, yymsp[-7].minor.yy144, yymsp[-5].minor.yy144);
178002 }
178003 #line 4154 "parse.sql"
178004 break;
178005 case 83: /* cmd ::= DROP VIEW ifexists fullname */
178006 #line 493 "parse.y"
178007 {
178008 sqlite3DropTable(pParse, yymsp[0].minor.yy203, 1, yymsp[-1].minor.yy144);
178009 }
178010 #line 4161 "parse.sql"
178011 break;
178012 case 84: /* cmd ::= select */
178013 #line 500 "parse.y"
178014 {
178015 SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0};
178016 if( (pParse->db->mDbFlags & DBFLAG_EncodingFixed)!=0
178017 || sqlite3ReadSchema(pParse)==SQLITE_OK
178018 ){
178019 sqlite3Select(pParse, yymsp[0].minor.yy555, &dest);
178020 }
178021 sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy555);
178022 }
178023 #line 4174 "parse.sql"
178024 break;
178025 case 85: /* select ::= WITH wqlist selectnowith */
178026 #line 574 "parse.y"
178027 {yymsp[-2].minor.yy555 = attachWithToSelect(pParse,yymsp[0].minor.yy555,yymsp[-1].minor.yy59);}
178028 #line 4179 "parse.sql"
178029 break;
178030 case 86: /* select ::= WITH RECURSIVE wqlist selectnowith */
178031 #line 576 "parse.y"
178032 {yymsp[-3].minor.yy555 = attachWithToSelect(pParse,yymsp[0].minor.yy555,yymsp[-1].minor.yy59);}
178033 #line 4184 "parse.sql"
178034 break;
178035 case 87: /* select ::= selectnowith */
178036 #line 579 "parse.y"
178037 {
178038 Select *p = yymsp[0].minor.yy555;
178039 if( p ){
178040 parserDoubleLinkSelect(pParse, p);
178041 }
178042 }
178043 #line 4194 "parse.sql"
178044 break;
178045 case 88: /* selectnowith ::= selectnowith multiselect_op oneselect */
178046 #line 588 "parse.y"
178047 {
178048 Select *pRhs = yymsp[0].minor.yy555;
178049 Select *pLhs = yymsp[-2].minor.yy555;
178050 if( pRhs && pRhs->pPrior ){
178051 SrcList *pFrom;
@@ -178064,175 +177900,131 @@
178064 }else{
178065 sqlite3SelectDelete(pParse->db, pLhs);
178066 }
178067 yymsp[-2].minor.yy555 = pRhs;
178068 }
178069 #line 4220 "parse.sql"
178070 break;
178071 case 89: /* multiselect_op ::= UNION */
178072 case 91: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==91);
178073 #line 611 "parse.y"
178074 {yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-OP*/}
178075 #line 4226 "parse.sql"
178076 break;
178077 case 90: /* multiselect_op ::= UNION ALL */
178078 #line 612 "parse.y"
178079 {yymsp[-1].minor.yy144 = TK_ALL;}
178080 #line 4231 "parse.sql"
178081 break;
178082 case 92: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
178083 #line 618 "parse.y"
178084 {
178085 yymsp[-8].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy203,yymsp[-4].minor.yy454,yymsp[-3].minor.yy14,yymsp[-2].minor.yy454,yymsp[-1].minor.yy14,yymsp[-7].minor.yy144,yymsp[0].minor.yy454);
178086 }
178087 #line 4238 "parse.sql"
178088 break;
178089 case 93: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
178090 #line 624 "parse.y"
178091 {
178092 yymsp[-9].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy14,yymsp[-6].minor.yy203,yymsp[-5].minor.yy454,yymsp[-4].minor.yy14,yymsp[-3].minor.yy454,yymsp[-1].minor.yy14,yymsp[-8].minor.yy144,yymsp[0].minor.yy454);
178093 if( yymsp[-9].minor.yy555 ){
178094 yymsp[-9].minor.yy555->pWinDefn = yymsp[-2].minor.yy211;
178095 }else{
178096 sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy211);
178097 }
178098 }
178099 #line 4250 "parse.sql"
178100 break;
178101 case 94: /* values ::= VALUES LP nexprlist RP */
178102 #line 640 "parse.y"
178103 {
178104 yymsp[-3].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0);
178105 }
178106 #line 4257 "parse.sql"
178107 break;
178108 case 95: /* oneselect ::= mvalues */
178109 #line 647 "parse.y"
178110 {
178111 sqlite3MultiValuesEnd(pParse, yymsp[0].minor.yy555);
178112 }
178113 #line 4264 "parse.sql"
178114 break;
178115 case 96: /* mvalues ::= values COMMA LP nexprlist RP */
178116 case 97: /* mvalues ::= mvalues COMMA LP nexprlist RP */ yytestcase(yyruleno==97);
178117 #line 651 "parse.y"
178118 {
178119 yymsp[-4].minor.yy555 = sqlite3MultiValues(pParse, yymsp[-4].minor.yy555, yymsp[-1].minor.yy14);
178120 }
178121 #line 4272 "parse.sql"
178122 break;
178123 case 98: /* distinct ::= DISTINCT */
178124 #line 662 "parse.y"
178125 {yymsp[0].minor.yy144 = SF_Distinct;}
178126 #line 4277 "parse.sql"
178127 break;
178128 case 99: /* distinct ::= ALL */
178129 #line 663 "parse.y"
178130 {yymsp[0].minor.yy144 = SF_All;}
178131 #line 4282 "parse.sql"
178132 break;
178133 case 101: /* sclp ::= */
178134 case 134: /* orderby_opt ::= */ yytestcase(yyruleno==134);
178135 case 144: /* groupby_opt ::= */ yytestcase(yyruleno==144);
178136 case 234: /* exprlist ::= */ yytestcase(yyruleno==234);
178137 case 237: /* paren_exprlist ::= */ yytestcase(yyruleno==237);
178138 case 242: /* eidlist_opt ::= */ yytestcase(yyruleno==242);
178139 #line 676 "parse.y"
178140 {yymsp[1].minor.yy14 = 0;}
178141 #line 4292 "parse.sql"
178142 break;
178143 case 102: /* selcollist ::= sclp scanpt expr scanpt as */
178144 #line 677 "parse.y"
178145 {
178146 yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[-2].minor.yy454);
178147 if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy14, &yymsp[0].minor.yy0, 1);
178148 sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy14,yymsp[-3].minor.yy168,yymsp[-1].minor.yy168);
178149 }
178150 #line 4301 "parse.sql"
178151 break;
178152 case 103: /* selcollist ::= sclp scanpt STAR */
178153 #line 682 "parse.y"
178154 {
178155 Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
178156 sqlite3ExprSetErrorOffset(p, (int)(yymsp[0].minor.yy0.z - pParse->zTail));
178157 yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy14, p);
178158 }
178159 #line 4310 "parse.sql"
178160 break;
178161 case 104: /* selcollist ::= sclp scanpt nm DOT STAR */
178162 #line 687 "parse.y"
178163 {
178164 Expr *pRight, *pLeft, *pDot;
178165 pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
178166 sqlite3ExprSetErrorOffset(pRight, (int)(yymsp[0].minor.yy0.z - pParse->zTail));
178167 pLeft = tokenExpr(pParse, TK_ID, yymsp[-2].minor.yy0);
178168 pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
178169 yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, pDot);
178170 }
178171 #line 4322 "parse.sql"
178172 break;
178173 case 105: /* as ::= AS nm */
178174 case 117: /* dbnm ::= DOT nm */ yytestcase(yyruleno==117);
178175 case 258: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==258);
178176 case 259: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==259);
178177 #line 700 "parse.y"
178178 {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
178179 #line 4330 "parse.sql"
178180 break;
178181 case 107: /* from ::= */
178182 case 110: /* stl_prefix ::= */ yytestcase(yyruleno==110);
178183 #line 714 "parse.y"
178184 {yymsp[1].minor.yy203 = 0;}
178185 #line 4336 "parse.sql"
178186 break;
178187 case 108: /* from ::= FROM seltablist */
178188 #line 715 "parse.y"
178189 {
178190 yymsp[-1].minor.yy203 = yymsp[0].minor.yy203;
178191 sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy203);
178192 }
178193 #line 4344 "parse.sql"
178194 break;
178195 case 109: /* stl_prefix ::= seltablist joinop */
178196 #line 723 "parse.y"
178197 {
178198 if( ALWAYS(yymsp[-1].minor.yy203 && yymsp[-1].minor.yy203->nSrc>0) ) yymsp[-1].minor.yy203->a[yymsp[-1].minor.yy203->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy144;
178199 }
178200 #line 4351 "parse.sql"
178201 break;
178202 case 111: /* seltablist ::= stl_prefix nm dbnm as on_using */
178203 #line 727 "parse.y"
178204 {
178205 yymsp[-4].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy203,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269);
178206 }
178207 #line 4358 "parse.sql"
178208 break;
178209 case 112: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
178210 #line 730 "parse.y"
178211 {
178212 yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy269);
178213 sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy203, &yymsp[-1].minor.yy0);
178214 }
178215 #line 4366 "parse.sql"
178216 break;
178217 case 113: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
178218 #line 734 "parse.y"
178219 {
178220 yymsp[-7].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy203,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269);
178221 sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy203, yymsp[-3].minor.yy14);
178222 }
178223 #line 4374 "parse.sql"
178224 break;
178225 case 114: /* seltablist ::= stl_prefix LP select RP as on_using */
178226 #line 739 "parse.y"
178227 {
178228 yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy555,&yymsp[0].minor.yy269);
178229 }
178230 #line 4381 "parse.sql"
178231 break;
178232 case 115: /* seltablist ::= stl_prefix LP seltablist RP as on_using */
178233 #line 742 "parse.y"
178234 {
178235 if( yymsp[-5].minor.yy203==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy269.pOn==0 && yymsp[0].minor.yy269.pUsing==0 ){
178236 yymsp[-5].minor.yy203 = yymsp[-3].minor.yy203;
178237 }else if( ALWAYS(yymsp[-3].minor.yy203!=0) && yymsp[-3].minor.yy203->nSrc==1 ){
178238 yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269);
@@ -178269,210 +178061,144 @@
178269 sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy203);
178270 pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy203,0,0,0,0,SF_NestedFrom,0);
178271 yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy269);
178272 }
178273 }
178274 #line 4425 "parse.sql"
178275 break;
178276 case 116: /* dbnm ::= */
178277 case 131: /* indexed_opt ::= */ yytestcase(yyruleno==131);
178278 #line 785 "parse.y"
178279 {yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;}
178280 #line 4431 "parse.sql"
178281 break;
178282 case 118: /* fullname ::= nm */
178283 #line 790 "parse.y"
178284 {
178285 yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0);
178286 if( IN_RENAME_OBJECT && yylhsminor.yy203 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[0].minor.yy0);
178287 }
178288 #line 4439 "parse.sql"
178289 yymsp[0].minor.yy203 = yylhsminor.yy203;
178290 break;
178291 case 119: /* fullname ::= nm DOT nm */
178292 #line 794 "parse.y"
178293 {
178294 yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
178295 if( IN_RENAME_OBJECT && yylhsminor.yy203 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[0].minor.yy0);
178296 }
178297 #line 4448 "parse.sql"
178298 yymsp[-2].minor.yy203 = yylhsminor.yy203;
178299 break;
178300 case 120: /* xfullname ::= nm */
178301 #line 802 "parse.y"
178302 {yymsp[0].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
178303 #line 4454 "parse.sql"
178304 break;
178305 case 121: /* xfullname ::= nm DOT nm */
178306 #line 804 "parse.y"
178307 {yymsp[-2].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
178308 #line 4459 "parse.sql"
178309 break;
178310 case 122: /* xfullname ::= nm DOT nm AS nm */
178311 #line 805 "parse.y"
178312 {
178313 yymsp[-4].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
178314 if( yymsp[-4].minor.yy203 ) yymsp[-4].minor.yy203->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
178315 }
178316 #line 4467 "parse.sql"
178317 break;
178318 case 123: /* xfullname ::= nm AS nm */
178319 #line 809 "parse.y"
178320 {
178321 yymsp[-2].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
178322 if( yymsp[-2].minor.yy203 ) yymsp[-2].minor.yy203->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
178323 }
178324 #line 4475 "parse.sql"
178325 break;
178326 case 124: /* joinop ::= COMMA|JOIN */
178327 #line 815 "parse.y"
178328 { yymsp[0].minor.yy144 = JT_INNER; }
178329 #line 4480 "parse.sql"
178330 break;
178331 case 125: /* joinop ::= JOIN_KW JOIN */
178332 #line 817 "parse.y"
178333 {yymsp[-1].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/}
178334 #line 4485 "parse.sql"
178335 break;
178336 case 126: /* joinop ::= JOIN_KW nm JOIN */
178337 #line 819 "parse.y"
178338 {yymsp[-2].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
178339 #line 4490 "parse.sql"
178340 break;
178341 case 127: /* joinop ::= JOIN_KW nm nm JOIN */
178342 #line 821 "parse.y"
178343 {yymsp[-3].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
178344 #line 4495 "parse.sql"
178345 break;
178346 case 128: /* on_using ::= ON expr */
178347 #line 842 "parse.y"
178348 {yymsp[-1].minor.yy269.pOn = yymsp[0].minor.yy454; yymsp[-1].minor.yy269.pUsing = 0;}
178349 #line 4500 "parse.sql"
178350 break;
178351 case 129: /* on_using ::= USING LP idlist RP */
178352 #line 843 "parse.y"
178353 {yymsp[-3].minor.yy269.pOn = 0; yymsp[-3].minor.yy269.pUsing = yymsp[-1].minor.yy132;}
178354 #line 4505 "parse.sql"
178355 break;
178356 case 130: /* on_using ::= */
178357 #line 844 "parse.y"
178358 {yymsp[1].minor.yy269.pOn = 0; yymsp[1].minor.yy269.pUsing = 0;}
178359 #line 4510 "parse.sql"
178360 break;
178361 case 132: /* indexed_by ::= INDEXED BY nm */
178362 #line 860 "parse.y"
178363 {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
178364 #line 4515 "parse.sql"
178365 break;
178366 case 133: /* indexed_by ::= NOT INDEXED */
178367 #line 861 "parse.y"
178368 {yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
178369 #line 4520 "parse.sql"
178370 break;
178371 case 135: /* orderby_opt ::= ORDER BY sortlist */
178372 case 145: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==145);
178373 #line 874 "parse.y"
178374 {yymsp[-2].minor.yy14 = yymsp[0].minor.yy14;}
178375 #line 4526 "parse.sql"
178376 break;
178377 case 136: /* sortlist ::= sortlist COMMA expr sortorder nulls */
178378 #line 875 "parse.y"
178379 {
178380 yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14,yymsp[-2].minor.yy454);
178381 sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy14,yymsp[-1].minor.yy144,yymsp[0].minor.yy144);
178382 }
178383 #line 4534 "parse.sql"
178384 break;
178385 case 137: /* sortlist ::= expr sortorder nulls */
178386 #line 879 "parse.y"
178387 {
178388 yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy454); /*A-overwrites-Y*/
178389 sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy14,yymsp[-1].minor.yy144,yymsp[0].minor.yy144);
178390 }
178391 #line 4542 "parse.sql"
178392 break;
178393 case 138: /* sortorder ::= ASC */
178394 #line 886 "parse.y"
178395 {yymsp[0].minor.yy144 = SQLITE_SO_ASC;}
178396 #line 4547 "parse.sql"
178397 break;
178398 case 139: /* sortorder ::= DESC */
178399 #line 887 "parse.y"
178400 {yymsp[0].minor.yy144 = SQLITE_SO_DESC;}
178401 #line 4552 "parse.sql"
178402 break;
178403 case 140: /* sortorder ::= */
178404 case 143: /* nulls ::= */ yytestcase(yyruleno==143);
178405 #line 888 "parse.y"
178406 {yymsp[1].minor.yy144 = SQLITE_SO_UNDEFINED;}
178407 #line 4558 "parse.sql"
178408 break;
178409 case 141: /* nulls ::= NULLS FIRST */
178410 #line 891 "parse.y"
178411 {yymsp[-1].minor.yy144 = SQLITE_SO_ASC;}
178412 #line 4563 "parse.sql"
178413 break;
178414 case 142: /* nulls ::= NULLS LAST */
178415 #line 892 "parse.y"
178416 {yymsp[-1].minor.yy144 = SQLITE_SO_DESC;}
178417 #line 4568 "parse.sql"
178418 break;
178419 case 146: /* having_opt ::= */
178420 case 148: /* limit_opt ::= */ yytestcase(yyruleno==148);
178421 case 153: /* where_opt ::= */ yytestcase(yyruleno==153);
178422 case 155: /* where_opt_ret ::= */ yytestcase(yyruleno==155);
178423 case 232: /* case_else ::= */ yytestcase(yyruleno==232);
178424 case 233: /* case_operand ::= */ yytestcase(yyruleno==233);
178425 case 252: /* vinto ::= */ yytestcase(yyruleno==252);
178426 #line 902 "parse.y"
178427 {yymsp[1].minor.yy454 = 0;}
178428 #line 4579 "parse.sql"
178429 break;
178430 case 147: /* having_opt ::= HAVING expr */
178431 case 154: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==154);
178432 case 156: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==156);
178433 case 231: /* case_else ::= ELSE expr */ yytestcase(yyruleno==231);
178434 case 251: /* vinto ::= INTO expr */ yytestcase(yyruleno==251);
178435 #line 903 "parse.y"
178436 {yymsp[-1].minor.yy454 = yymsp[0].minor.yy454;}
178437 #line 4588 "parse.sql"
178438 break;
178439 case 149: /* limit_opt ::= LIMIT expr */
178440 #line 917 "parse.y"
178441 {yymsp[-1].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy454,0);}
178442 #line 4593 "parse.sql"
178443 break;
178444 case 150: /* limit_opt ::= LIMIT expr OFFSET expr */
178445 #line 919 "parse.y"
178446 {yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);}
178447 #line 4598 "parse.sql"
178448 break;
178449 case 151: /* limit_opt ::= LIMIT expr COMMA expr */
178450 #line 921 "parse.y"
178451 {yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy454,yymsp[-2].minor.yy454);}
178452 #line 4603 "parse.sql"
178453 break;
178454 case 152: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */
178455 #line 939 "parse.y"
178456 {
178457 sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy203, &yymsp[-1].minor.yy0);
178458 sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy203,yymsp[0].minor.yy454,0,0);
178459 }
178460 #line 4611 "parse.sql"
178461 break;
178462 case 157: /* where_opt_ret ::= RETURNING selcollist */
178463 #line 955 "parse.y"
178464 {sqlite3AddReturning(pParse,yymsp[0].minor.yy14); yymsp[-1].minor.yy454 = 0;}
178465 #line 4616 "parse.sql"
178466 break;
178467 case 158: /* where_opt_ret ::= WHERE expr RETURNING selcollist */
178468 #line 957 "parse.y"
178469 {sqlite3AddReturning(pParse,yymsp[0].minor.yy14); yymsp[-3].minor.yy454 = yymsp[-2].minor.yy454;}
178470 #line 4621 "parse.sql"
178471 break;
178472 case 159: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
178473 #line 989 "parse.y"
178474 {
178475 sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy203, &yymsp[-4].minor.yy0);
178476 sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy14,"set list");
178477 if( yymsp[-1].minor.yy203 ){
178478 SrcList *pFromClause = yymsp[-1].minor.yy203;
@@ -178486,134 +178212,92 @@
178486 }
178487 yymsp[-5].minor.yy203 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy203, pFromClause);
178488 }
178489 sqlite3Update(pParse,yymsp[-5].minor.yy203,yymsp[-2].minor.yy14,yymsp[0].minor.yy454,yymsp[-6].minor.yy144,0,0,0);
178490 }
178491 #line 4642 "parse.sql"
178492 break;
178493 case 160: /* setlist ::= setlist COMMA nm EQ expr */
178494 #line 1013 "parse.y"
178495 {
178496 yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[0].minor.yy454);
178497 sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy14, &yymsp[-2].minor.yy0, 1);
178498 }
178499 #line 4650 "parse.sql"
178500 break;
178501 case 161: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
178502 #line 1017 "parse.y"
178503 {
178504 yymsp[-6].minor.yy14 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy14, yymsp[-3].minor.yy132, yymsp[0].minor.yy454);
178505 }
178506 #line 4657 "parse.sql"
178507 break;
178508 case 162: /* setlist ::= nm EQ expr */
178509 #line 1020 "parse.y"
178510 {
178511 yylhsminor.yy14 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy454);
178512 sqlite3ExprListSetName(pParse, yylhsminor.yy14, &yymsp[-2].minor.yy0, 1);
178513 }
178514 #line 4665 "parse.sql"
178515 yymsp[-2].minor.yy14 = yylhsminor.yy14;
178516 break;
178517 case 163: /* setlist ::= LP idlist RP EQ expr */
178518 #line 1024 "parse.y"
178519 {
178520 yymsp[-4].minor.yy14 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy132, yymsp[0].minor.yy454);
178521 }
178522 #line 4673 "parse.sql"
178523 break;
178524 case 164: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
178525 #line 1031 "parse.y"
178526 {
178527 sqlite3Insert(pParse, yymsp[-3].minor.yy203, yymsp[-1].minor.yy555, yymsp[-2].minor.yy132, yymsp[-5].minor.yy144, yymsp[0].minor.yy122);
178528 }
178529 #line 4680 "parse.sql"
178530 break;
178531 case 165: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */
178532 #line 1035 "parse.y"
178533 {
178534 sqlite3Insert(pParse, yymsp[-4].minor.yy203, 0, yymsp[-3].minor.yy132, yymsp[-6].minor.yy144, 0);
178535 }
178536 #line 4687 "parse.sql"
178537 break;
178538 case 166: /* upsert ::= */
178539 #line 1046 "parse.y"
178540 { yymsp[1].minor.yy122 = 0; }
178541 #line 4692 "parse.sql"
178542 break;
178543 case 167: /* upsert ::= RETURNING selcollist */
178544 #line 1047 "parse.y"
178545 { yymsp[-1].minor.yy122 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy14); }
178546 #line 4697 "parse.sql"
178547 break;
178548 case 168: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */
178549 #line 1050 "parse.y"
178550 { yymsp[-11].minor.yy122 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy14,yymsp[-6].minor.yy454,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454,yymsp[0].minor.yy122);}
178551 #line 4702 "parse.sql"
178552 break;
178553 case 169: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */
178554 #line 1052 "parse.y"
178555 { yymsp[-8].minor.yy122 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy14,yymsp[-3].minor.yy454,0,0,yymsp[0].minor.yy122); }
178556 #line 4707 "parse.sql"
178557 break;
178558 case 170: /* upsert ::= ON CONFLICT DO NOTHING returning */
178559 #line 1054 "parse.y"
178560 { yymsp[-4].minor.yy122 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); }
178561 #line 4712 "parse.sql"
178562 break;
178563 case 171: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
178564 #line 1056 "parse.y"
178565 { yymsp[-7].minor.yy122 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454,0);}
178566 #line 4717 "parse.sql"
178567 break;
178568 case 172: /* returning ::= RETURNING selcollist */
178569 #line 1058 "parse.y"
178570 {sqlite3AddReturning(pParse,yymsp[0].minor.yy14);}
178571 #line 4722 "parse.sql"
178572 break;
178573 case 175: /* idlist_opt ::= */
178574 #line 1070 "parse.y"
178575 {yymsp[1].minor.yy132 = 0;}
178576 #line 4727 "parse.sql"
178577 break;
178578 case 176: /* idlist_opt ::= LP idlist RP */
178579 #line 1071 "parse.y"
178580 {yymsp[-2].minor.yy132 = yymsp[-1].minor.yy132;}
178581 #line 4732 "parse.sql"
178582 break;
178583 case 177: /* idlist ::= idlist COMMA nm */
178584 #line 1073 "parse.y"
178585 {yymsp[-2].minor.yy132 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy132,&yymsp[0].minor.yy0);}
178586 #line 4737 "parse.sql"
178587 break;
178588 case 178: /* idlist ::= nm */
178589 #line 1075 "parse.y"
178590 {yymsp[0].minor.yy132 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
178591 #line 4742 "parse.sql"
178592 break;
178593 case 179: /* expr ::= LP expr RP */
178594 #line 1124 "parse.y"
178595 {yymsp[-2].minor.yy454 = yymsp[-1].minor.yy454;}
178596 #line 4747 "parse.sql"
178597 break;
178598 case 180: /* expr ::= ID|INDEXED|JOIN_KW */
178599 #line 1125 "parse.y"
178600 {yymsp[0].minor.yy454=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
178601 #line 4752 "parse.sql"
178602 break;
178603 case 181: /* expr ::= nm DOT nm */
178604 #line 1126 "parse.y"
178605 {
178606 Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0);
178607 Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0);
178608 yylhsminor.yy454 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
178609 }
178610 #line 4761 "parse.sql"
178611 yymsp[-2].minor.yy454 = yylhsminor.yy454;
178612 break;
178613 case 182: /* expr ::= nm DOT nm DOT nm */
178614 #line 1131 "parse.y"
178615 {
178616 Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-4].minor.yy0);
178617 Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0);
178618 Expr *temp3 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0);
178619 Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
@@ -178620,30 +178304,24 @@
178620 if( IN_RENAME_OBJECT ){
178621 sqlite3RenameTokenRemap(pParse, 0, temp1);
178622 }
178623 yylhsminor.yy454 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
178624 }
178625 #line 4776 "parse.sql"
178626 yymsp[-4].minor.yy454 = yylhsminor.yy454;
178627 break;
178628 case 183: /* term ::= NULL|FLOAT|BLOB */
178629 case 184: /* term ::= STRING */ yytestcase(yyruleno==184);
178630 #line 1141 "parse.y"
178631 {yymsp[0].minor.yy454=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
178632 #line 4783 "parse.sql"
178633 break;
178634 case 185: /* term ::= INTEGER */
178635 #line 1143 "parse.y"
178636 {
178637 yylhsminor.yy454 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
178638 if( yylhsminor.yy454 ) yylhsminor.yy454->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail);
178639 }
178640 #line 4791 "parse.sql"
178641 yymsp[0].minor.yy454 = yylhsminor.yy454;
178642 break;
178643 case 186: /* expr ::= VARIABLE */
178644 #line 1147 "parse.y"
178645 {
178646 if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){
178647 u32 n = yymsp[0].minor.yy0.n;
178648 yymsp[0].minor.yy454 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
178649 sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy454, n);
@@ -178652,98 +178330,78 @@
178652 ** that look like this: #1 #2 ... These terms refer to registers
178653 ** in the virtual machine. #N is the N-th register. */
178654 Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/
178655 assert( t.n>=2 );
178656 if( pParse->nested==0 ){
178657 sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
178658 yymsp[0].minor.yy454 = 0;
178659 }else{
178660 yymsp[0].minor.yy454 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
178661 if( yymsp[0].minor.yy454 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy454->iTable);
178662 }
178663 }
178664 }
178665 #line 4816 "parse.sql"
178666 break;
178667 case 187: /* expr ::= expr COLLATE ID|STRING */
178668 #line 1167 "parse.y"
178669 {
178670 yymsp[-2].minor.yy454 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy454, &yymsp[0].minor.yy0, 1);
178671 }
178672 #line 4823 "parse.sql"
178673 break;
178674 case 188: /* expr ::= CAST LP expr AS typetoken RP */
178675 #line 1171 "parse.y"
178676 {
178677 yymsp[-5].minor.yy454 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
178678 sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy454, yymsp[-3].minor.yy454, 0);
178679 }
178680 #line 4831 "parse.sql"
178681 break;
178682 case 189: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
178683 #line 1178 "parse.y"
178684 {
178685 yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy144);
178686 }
178687 #line 4838 "parse.sql"
178688 yymsp[-4].minor.yy454 = yylhsminor.yy454;
178689 break;
178690 case 190: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */
178691 #line 1181 "parse.y"
178692 {
178693 yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-4].minor.yy14, &yymsp[-7].minor.yy0, yymsp[-5].minor.yy144);
178694 sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy454, yymsp[-1].minor.yy14);
178695 }
178696 #line 4847 "parse.sql"
178697 yymsp[-7].minor.yy454 = yylhsminor.yy454;
178698 break;
178699 case 191: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
178700 #line 1185 "parse.y"
178701 {
178702 yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0);
178703 }
178704 #line 4855 "parse.sql"
178705 yymsp[-3].minor.yy454 = yylhsminor.yy454;
178706 break;
178707 case 192: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
178708 #line 1249 "parse.y"
178709 {
178710 yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy14, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy144);
178711 sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211);
178712 }
178713 #line 4864 "parse.sql"
178714 yymsp[-5].minor.yy454 = yylhsminor.yy454;
178715 break;
178716 case 193: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */
178717 #line 1253 "parse.y"
178718 {
178719 yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-5].minor.yy14, &yymsp[-8].minor.yy0, yymsp[-6].minor.yy144);
178720 sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211);
178721 sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy454, yymsp[-2].minor.yy14);
178722 }
178723 #line 4874 "parse.sql"
178724 yymsp[-8].minor.yy454 = yylhsminor.yy454;
178725 break;
178726 case 194: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
178727 #line 1258 "parse.y"
178728 {
178729 yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
178730 sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211);
178731 }
178732 #line 4883 "parse.sql"
178733 yymsp[-4].minor.yy454 = yylhsminor.yy454;
178734 break;
178735 case 195: /* term ::= CTIME_KW */
178736 #line 1272 "parse.y"
178737 {
178738 yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0);
178739 }
178740 #line 4891 "parse.sql"
178741 yymsp[0].minor.yy454 = yylhsminor.yy454;
178742 break;
178743 case 196: /* expr ::= LP nexprlist COMMA expr RP */
178744 #line 1276 "parse.y"
178745 {
178746 ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454);
178747 yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
178748 if( yymsp[-4].minor.yy454 ){
178749 yymsp[-4].minor.yy454->x.pList = pList;
@@ -178752,35 +178410,27 @@
178752 }
178753 }else{
178754 sqlite3ExprListDelete(pParse->db, pList);
178755 }
178756 }
178757 #line 4908 "parse.sql"
178758 break;
178759 case 197: /* expr ::= expr AND expr */
178760 #line 1289 "parse.y"
178761 {yymsp[-2].minor.yy454=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);}
178762 #line 4913 "parse.sql"
178763 break;
178764 case 198: /* expr ::= expr OR expr */
178765 case 199: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==199);
178766 case 200: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==200);
178767 case 201: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==201);
178768 case 202: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==202);
178769 case 203: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==203);
178770 case 204: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==204);
178771 #line 1290 "parse.y"
178772 {yymsp[-2].minor.yy454=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);}
178773 #line 4924 "parse.sql"
178774 break;
178775 case 205: /* likeop ::= NOT LIKE_KW|MATCH */
178776 #line 1303 "parse.y"
178777 {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/}
178778 #line 4929 "parse.sql"
178779 break;
178780 case 206: /* expr ::= expr likeop expr */
178781 #line 1304 "parse.y"
178782 {
178783 ExprList *pList;
178784 int bNot = yymsp[-1].minor.yy0.n & 0x80000000;
178785 yymsp[-1].minor.yy0.n &= 0x7fffffff;
178786 pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy454);
@@ -178787,14 +178437,12 @@
178787 pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy454);
178788 yymsp[-2].minor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
178789 if( bNot ) yymsp[-2].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy454, 0);
178790 if( yymsp[-2].minor.yy454 ) yymsp[-2].minor.yy454->flags |= EP_InfixFunc;
178791 }
178792 #line 4943 "parse.sql"
178793 break;
178794 case 207: /* expr ::= expr likeop expr ESCAPE expr */
178795 #line 1314 "parse.y"
178796 {
178797 ExprList *pList;
178798 int bNot = yymsp[-3].minor.yy0.n & 0x80000000;
178799 yymsp[-3].minor.yy0.n &= 0x7fffffff;
178800 pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454);
@@ -178802,62 +178450,46 @@
178802 pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy454);
178803 yymsp[-4].minor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0);
178804 if( bNot ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
178805 if( yymsp[-4].minor.yy454 ) yymsp[-4].minor.yy454->flags |= EP_InfixFunc;
178806 }
178807 #line 4958 "parse.sql"
178808 break;
178809 case 208: /* expr ::= expr ISNULL|NOTNULL */
178810 #line 1326 "parse.y"
178811 {yymsp[-1].minor.yy454 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy454,0);}
178812 #line 4963 "parse.sql"
178813 break;
178814 case 209: /* expr ::= expr NOT NULL */
178815 #line 1327 "parse.y"
178816 {yymsp[-2].minor.yy454 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy454,0);}
178817 #line 4968 "parse.sql"
178818 break;
178819 case 210: /* expr ::= expr IS expr */
178820 #line 1348 "parse.y"
178821 {
178822 yymsp[-2].minor.yy454 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);
178823 binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-2].minor.yy454, TK_ISNULL);
178824 }
178825 #line 4976 "parse.sql"
178826 break;
178827 case 211: /* expr ::= expr IS NOT expr */
178828 #line 1352 "parse.y"
178829 {
178830 yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy454,yymsp[0].minor.yy454);
178831 binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-3].minor.yy454, TK_NOTNULL);
178832 }
178833 #line 4984 "parse.sql"
178834 break;
178835 case 212: /* expr ::= expr IS NOT DISTINCT FROM expr */
178836 #line 1356 "parse.y"
178837 {
178838 yymsp[-5].minor.yy454 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy454,yymsp[0].minor.yy454);
178839 binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-5].minor.yy454, TK_ISNULL);
178840 }
178841 #line 4992 "parse.sql"
178842 break;
178843 case 213: /* expr ::= expr IS DISTINCT FROM expr */
178844 #line 1360 "parse.y"
178845 {
178846 yymsp[-4].minor.yy454 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy454,yymsp[0].minor.yy454);
178847 binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-4].minor.yy454, TK_NOTNULL);
178848 }
178849 #line 5000 "parse.sql"
178850 break;
178851 case 214: /* expr ::= NOT expr */
178852 case 215: /* expr ::= BITNOT expr */ yytestcase(yyruleno==215);
178853 #line 1366 "parse.y"
178854 {yymsp[-1].minor.yy454 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy454, 0);/*A-overwrites-B*/}
178855 #line 5006 "parse.sql"
178856 break;
178857 case 216: /* expr ::= PLUS|MINUS expr */
178858 #line 1369 "parse.y"
178859 {
178860 Expr *p = yymsp[0].minor.yy454;
178861 u8 op = yymsp[-1].major + (TK_UPLUS-TK_PLUS);
178862 assert( TK_UPLUS>TK_PLUS );
178863 assert( TK_UMINUS == TK_MINUS + (TK_UPLUS - TK_PLUS) );
@@ -178867,30 +178499,24 @@
178867 }else{
178868 yymsp[-1].minor.yy454 = sqlite3PExpr(pParse, op, p, 0);
178869 /*A-overwrites-B*/
178870 }
178871 }
178872 #line 5023 "parse.sql"
178873 break;
178874 case 217: /* expr ::= expr PTR expr */
178875 #line 1383 "parse.y"
178876 {
178877 ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy454);
178878 pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy454);
178879 yylhsminor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
178880 }
178881 #line 5032 "parse.sql"
178882 yymsp[-2].minor.yy454 = yylhsminor.yy454;
178883 break;
178884 case 218: /* between_op ::= BETWEEN */
178885 case 221: /* in_op ::= IN */ yytestcase(yyruleno==221);
178886 #line 1390 "parse.y"
178887 {yymsp[0].minor.yy144 = 0;}
178888 #line 5039 "parse.sql"
178889 break;
178890 case 220: /* expr ::= expr between_op expr AND expr */
178891 #line 1392 "parse.y"
178892 {
178893 ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454);
178894 pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy454);
178895 yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy454, 0);
178896 if( yymsp[-4].minor.yy454 ){
@@ -178898,14 +178524,12 @@
178898 }else{
178899 sqlite3ExprListDelete(pParse->db, pList);
178900 }
178901 if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
178902 }
178903 #line 5054 "parse.sql"
178904 break;
178905 case 223: /* expr ::= expr in_op LP exprlist RP */
178906 #line 1407 "parse.y"
178907 {
178908 if( yymsp[-1].minor.yy14==0 ){
178909 /* Expressions of the form
178910 **
178911 ** expr1 IN ()
@@ -178946,52 +178570,42 @@
178946 }
178947 }
178948 if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
178949 }
178950 }
178951 #line 5102 "parse.sql"
178952 break;
178953 case 224: /* expr ::= LP select RP */
178954 #line 1451 "parse.y"
178955 {
178956 yymsp[-2].minor.yy454 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
178957 sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy454, yymsp[-1].minor.yy555);
178958 }
178959 #line 5110 "parse.sql"
178960 break;
178961 case 225: /* expr ::= expr in_op LP select RP */
178962 #line 1455 "parse.y"
178963 {
178964 yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0);
178965 sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, yymsp[-1].minor.yy555);
178966 if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
178967 }
178968 #line 5119 "parse.sql"
178969 break;
178970 case 226: /* expr ::= expr in_op nm dbnm paren_exprlist */
178971 #line 1460 "parse.y"
178972 {
178973 SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
178974 Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0);
178975 if( yymsp[0].minor.yy14 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy14);
178976 yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0);
178977 sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pSelect);
178978 if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
178979 }
178980 #line 5131 "parse.sql"
178981 break;
178982 case 227: /* expr ::= EXISTS LP select RP */
178983 #line 1468 "parse.y"
178984 {
178985 Expr *p;
178986 p = yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
178987 sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy555);
178988 }
178989 #line 5140 "parse.sql"
178990 break;
178991 case 228: /* expr ::= CASE case_operand case_exprlist case_else END */
178992 #line 1476 "parse.y"
178993 {
178994 yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy454, 0);
178995 if( yymsp[-4].minor.yy454 ){
178996 yymsp[-4].minor.yy454->x.pList = yymsp[-1].minor.yy454 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454) : yymsp[-2].minor.yy14;
178997 sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy454);
@@ -178998,627 +178612,446 @@
178998 }else{
178999 sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy14);
179000 sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy454);
179001 }
179002 }
179003 #line 5154 "parse.sql"
179004 break;
179005 case 229: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
179006 #line 1488 "parse.y"
179007 {
179008 yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[-2].minor.yy454);
179009 yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[0].minor.yy454);
179010 }
179011 #line 5162 "parse.sql"
179012 break;
179013 case 230: /* case_exprlist ::= WHEN expr THEN expr */
179014 #line 1492 "parse.y"
179015 {
179016 yymsp[-3].minor.yy14 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454);
179017 yymsp[-3].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14, yymsp[0].minor.yy454);
179018 }
179019 #line 5170 "parse.sql"
179020 break;
179021 case 235: /* nexprlist ::= nexprlist COMMA expr */
179022 #line 1513 "parse.y"
179023 {yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[0].minor.yy454);}
179024 #line 5175 "parse.sql"
179025 break;
179026 case 236: /* nexprlist ::= expr */
179027 #line 1515 "parse.y"
179028 {yymsp[0].minor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy454); /*A-overwrites-Y*/}
179029 #line 5180 "parse.sql"
179030 break;
179031 case 238: /* paren_exprlist ::= LP exprlist RP */
179032 case 243: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==243);
179033 #line 1523 "parse.y"
179034 {yymsp[-2].minor.yy14 = yymsp[-1].minor.yy14;}
179035 #line 5186 "parse.sql"
179036 break;
179037 case 239: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
179038 #line 1530 "parse.y"
179039 {
179040 sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
179041 sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy14, yymsp[-10].minor.yy144,
179042 &yymsp[-11].minor.yy0, yymsp[0].minor.yy454, SQLITE_SO_ASC, yymsp[-8].minor.yy144, SQLITE_IDXTYPE_APPDEF);
179043 if( IN_RENAME_OBJECT && pParse->pNewIndex ){
179044 sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0);
179045 }
179046 }
179047 #line 5198 "parse.sql"
179048 break;
179049 case 240: /* uniqueflag ::= UNIQUE */
179050 case 282: /* raisetype ::= ABORT */ yytestcase(yyruleno==282);
179051 #line 1540 "parse.y"
179052 {yymsp[0].minor.yy144 = OE_Abort;}
179053 #line 5204 "parse.sql"
179054 break;
179055 case 241: /* uniqueflag ::= */
179056 #line 1541 "parse.y"
179057 {yymsp[1].minor.yy144 = OE_None;}
179058 #line 5209 "parse.sql"
179059 break;
179060 case 244: /* eidlist ::= eidlist COMMA nm collate sortorder */
179061 #line 1591 "parse.y"
179062 {
179063 yymsp[-4].minor.yy14 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy14, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy144, yymsp[0].minor.yy144);
179064 }
179065 #line 5216 "parse.sql"
179066 break;
179067 case 245: /* eidlist ::= nm collate sortorder */
179068 #line 1594 "parse.y"
179069 {
179070 yymsp[-2].minor.yy14 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy144, yymsp[0].minor.yy144); /*A-overwrites-Y*/
179071 }
179072 #line 5223 "parse.sql"
179073 break;
179074 case 248: /* cmd ::= DROP INDEX ifexists fullname */
179075 #line 1605 "parse.y"
179076 {sqlite3DropIndex(pParse, yymsp[0].minor.yy203, yymsp[-1].minor.yy144);}
179077 #line 5228 "parse.sql"
179078 break;
179079 case 249: /* cmd ::= VACUUM vinto */
179080 #line 1612 "parse.y"
179081 {sqlite3Vacuum(pParse,0,yymsp[0].minor.yy454);}
179082 #line 5233 "parse.sql"
179083 break;
179084 case 250: /* cmd ::= VACUUM nm vinto */
179085 #line 1613 "parse.y"
179086 {sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy454);}
179087 #line 5238 "parse.sql"
179088 break;
179089 case 253: /* cmd ::= PRAGMA nm dbnm */
179090 #line 1621 "parse.y"
179091 {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
179092 #line 5243 "parse.sql"
179093 break;
179094 case 254: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
179095 #line 1622 "parse.y"
179096 {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
179097 #line 5248 "parse.sql"
179098 break;
179099 case 255: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
179100 #line 1623 "parse.y"
179101 {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
179102 #line 5253 "parse.sql"
179103 break;
179104 case 256: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
179105 #line 1625 "parse.y"
179106 {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
179107 #line 5258 "parse.sql"
179108 break;
179109 case 257: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
179110 #line 1627 "parse.y"
179111 {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
179112 #line 5263 "parse.sql"
179113 break;
179114 case 260: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
179115 #line 1643 "parse.y"
179116 {
179117 Token all;
179118 all.z = yymsp[-3].minor.yy0.z;
179119 all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
179120 sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy427, &all);
179121 }
179122 #line 5273 "parse.sql"
179123 break;
179124 case 261: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
179125 #line 1652 "parse.y"
179126 {
179127 sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy144, yymsp[-4].minor.yy286.a, yymsp[-4].minor.yy286.b, yymsp[-2].minor.yy203, yymsp[0].minor.yy454, yymsp[-10].minor.yy144, yymsp[-8].minor.yy144);
179128 yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
179129 }
179130 #line 5281 "parse.sql"
179131 break;
179132 case 262: /* trigger_time ::= BEFORE|AFTER */
179133 #line 1658 "parse.y"
179134 { yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-X*/ }
179135 #line 5286 "parse.sql"
179136 break;
179137 case 263: /* trigger_time ::= INSTEAD OF */
179138 #line 1659 "parse.y"
179139 { yymsp[-1].minor.yy144 = TK_INSTEAD;}
179140 #line 5291 "parse.sql"
179141 break;
179142 case 264: /* trigger_time ::= */
179143 #line 1660 "parse.y"
179144 { yymsp[1].minor.yy144 = TK_BEFORE; }
179145 #line 5296 "parse.sql"
179146 break;
179147 case 265: /* trigger_event ::= DELETE|INSERT */
179148 case 266: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==266);
179149 #line 1664 "parse.y"
179150 {yymsp[0].minor.yy286.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy286.b = 0;}
179151 #line 5302 "parse.sql"
179152 break;
179153 case 267: /* trigger_event ::= UPDATE OF idlist */
179154 #line 1666 "parse.y"
179155 {yymsp[-2].minor.yy286.a = TK_UPDATE; yymsp[-2].minor.yy286.b = yymsp[0].minor.yy132;}
179156 #line 5307 "parse.sql"
179157 break;
179158 case 268: /* when_clause ::= */
179159 case 287: /* key_opt ::= */ yytestcase(yyruleno==287);
179160 #line 1673 "parse.y"
179161 { yymsp[1].minor.yy454 = 0; }
179162 #line 5313 "parse.sql"
179163 break;
179164 case 269: /* when_clause ::= WHEN expr */
179165 case 288: /* key_opt ::= KEY expr */ yytestcase(yyruleno==288);
179166 #line 1674 "parse.y"
179167 { yymsp[-1].minor.yy454 = yymsp[0].minor.yy454; }
179168 #line 5319 "parse.sql"
179169 break;
179170 case 270: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
179171 #line 1678 "parse.y"
179172 {
179173 assert( yymsp[-2].minor.yy427!=0 );
179174 yymsp[-2].minor.yy427->pLast->pNext = yymsp[-1].minor.yy427;
179175 yymsp[-2].minor.yy427->pLast = yymsp[-1].minor.yy427;
179176 }
179177 #line 5328 "parse.sql"
179178 break;
179179 case 271: /* trigger_cmd_list ::= trigger_cmd SEMI */
179180 #line 1683 "parse.y"
179181 {
179182 assert( yymsp[-1].minor.yy427!=0 );
179183 yymsp[-1].minor.yy427->pLast = yymsp[-1].minor.yy427;
179184 }
179185 #line 5336 "parse.sql"
179186 break;
179187 case 272: /* trnm ::= nm DOT nm */
179188 #line 1694 "parse.y"
179189 {
179190 yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
179191 sqlite3ErrorMsg(pParse,
179192 "qualified table names are not allowed on INSERT, UPDATE, and DELETE "
179193 "statements within triggers");
179194 }
179195 #line 5346 "parse.sql"
179196 break;
179197 case 273: /* tridxby ::= INDEXED BY nm */
179198 #line 1706 "parse.y"
179199 {
179200 sqlite3ErrorMsg(pParse,
179201 "the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
179202 "within triggers");
179203 }
179204 #line 5355 "parse.sql"
179205 break;
179206 case 274: /* tridxby ::= NOT INDEXED */
179207 #line 1711 "parse.y"
179208 {
179209 sqlite3ErrorMsg(pParse,
179210 "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
179211 "within triggers");
179212 }
179213 #line 5364 "parse.sql"
179214 break;
179215 case 275: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
179216 #line 1724 "parse.y"
179217 {yylhsminor.yy427 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy203, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454, yymsp[-7].minor.yy144, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy168);}
179218 #line 5369 "parse.sql"
179219 yymsp[-8].minor.yy427 = yylhsminor.yy427;
179220 break;
179221 case 276: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
179222 #line 1728 "parse.y"
179223 {
179224 yylhsminor.yy427 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy132,yymsp[-2].minor.yy555,yymsp[-6].minor.yy144,yymsp[-1].minor.yy122,yymsp[-7].minor.yy168,yymsp[0].minor.yy168);/*yylhsminor.yy427-overwrites-yymsp[-6].minor.yy144*/
179225 }
179226 #line 5377 "parse.sql"
179227 yymsp[-7].minor.yy427 = yylhsminor.yy427;
179228 break;
179229 case 277: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
179230 #line 1733 "parse.y"
179231 {yylhsminor.yy427 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy454, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy168);}
179232 #line 5383 "parse.sql"
179233 yymsp[-5].minor.yy427 = yylhsminor.yy427;
179234 break;
179235 case 278: /* trigger_cmd ::= scanpt select scanpt */
179236 #line 1737 "parse.y"
179237 {yylhsminor.yy427 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy555, yymsp[-2].minor.yy168, yymsp[0].minor.yy168); /*yylhsminor.yy427-overwrites-yymsp[-1].minor.yy555*/}
179238 #line 5389 "parse.sql"
179239 yymsp[-2].minor.yy427 = yylhsminor.yy427;
179240 break;
179241 case 279: /* expr ::= RAISE LP IGNORE RP */
179242 #line 1740 "parse.y"
179243 {
179244 yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
179245 if( yymsp[-3].minor.yy454 ){
179246 yymsp[-3].minor.yy454->affExpr = OE_Ignore;
179247 }
179248 }
179249 #line 5400 "parse.sql"
179250 break;
179251 case 280: /* expr ::= RAISE LP raisetype COMMA expr RP */
179252 #line 1746 "parse.y"
179253 {
179254 yymsp[-5].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, yymsp[-1].minor.yy454, 0);
179255 if( yymsp[-5].minor.yy454 ) {
179256 yymsp[-5].minor.yy454->affExpr = (char)yymsp[-3].minor.yy144;
179257 }
179258 }
179259 #line 5410 "parse.sql"
179260 break;
179261 case 281: /* raisetype ::= ROLLBACK */
179262 #line 1755 "parse.y"
179263 {yymsp[0].minor.yy144 = OE_Rollback;}
179264 #line 5415 "parse.sql"
179265 break;
179266 case 283: /* raisetype ::= FAIL */
179267 #line 1757 "parse.y"
179268 {yymsp[0].minor.yy144 = OE_Fail;}
179269 #line 5420 "parse.sql"
179270 break;
179271 case 284: /* cmd ::= DROP TRIGGER ifexists fullname */
179272 #line 1762 "parse.y"
179273 {
179274 sqlite3DropTrigger(pParse,yymsp[0].minor.yy203,yymsp[-1].minor.yy144);
179275 }
179276 #line 5427 "parse.sql"
179277 break;
179278 case 285: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
179279 #line 1769 "parse.y"
179280 {
179281 sqlite3Attach(pParse, yymsp[-3].minor.yy454, yymsp[-1].minor.yy454, yymsp[0].minor.yy454);
179282 }
179283 #line 5434 "parse.sql"
179284 break;
179285 case 286: /* cmd ::= DETACH database_kw_opt expr */
179286 #line 1772 "parse.y"
179287 {
179288 sqlite3Detach(pParse, yymsp[0].minor.yy454);
179289 }
179290 #line 5441 "parse.sql"
179291 break;
179292 case 289: /* cmd ::= REINDEX */
179293 #line 1787 "parse.y"
179294 {sqlite3Reindex(pParse, 0, 0);}
179295 #line 5446 "parse.sql"
179296 break;
179297 case 290: /* cmd ::= REINDEX nm dbnm */
179298 #line 1788 "parse.y"
179299 {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
179300 #line 5451 "parse.sql"
179301 break;
179302 case 291: /* cmd ::= ANALYZE */
179303 #line 1793 "parse.y"
179304 {sqlite3Analyze(pParse, 0, 0);}
179305 #line 5456 "parse.sql"
179306 break;
179307 case 292: /* cmd ::= ANALYZE nm dbnm */
179308 #line 1794 "parse.y"
179309 {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
179310 #line 5461 "parse.sql"
179311 break;
179312 case 293: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
179313 #line 1800 "parse.y"
179314 {
179315 sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy203,&yymsp[0].minor.yy0);
179316 }
179317 #line 5468 "parse.sql"
179318 break;
179319 case 294: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
179320 #line 1804 "parse.y"
179321 {
179322 yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
179323 sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0);
179324 }
179325 #line 5476 "parse.sql"
179326 break;
179327 case 295: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
179328 #line 1808 "parse.y"
179329 {
179330 sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy203, &yymsp[0].minor.yy0);
179331 }
179332 #line 5483 "parse.sql"
179333 break;
179334 case 296: /* add_column_fullname ::= fullname */
179335 #line 1812 "parse.y"
179336 {
179337 disableLookaside(pParse);
179338 sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy203);
179339 }
179340 #line 5491 "parse.sql"
179341 break;
179342 case 297: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
179343 #line 1816 "parse.y"
179344 {
179345 sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy203, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
179346 }
179347 #line 5498 "parse.sql"
179348 break;
179349 case 298: /* cmd ::= create_vtab */
179350 #line 1828 "parse.y"
179351 {sqlite3VtabFinishParse(pParse,0);}
179352 #line 5503 "parse.sql"
179353 break;
179354 case 299: /* cmd ::= create_vtab LP vtabarglist RP */
179355 #line 1829 "parse.y"
179356 {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
179357 #line 5508 "parse.sql"
179358 break;
179359 case 300: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
179360 #line 1831 "parse.y"
179361 {
179362 sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy144);
179363 }
179364 #line 5515 "parse.sql"
179365 break;
179366 case 301: /* vtabarg ::= */
179367 #line 1836 "parse.y"
179368 {sqlite3VtabArgInit(pParse);}
179369 #line 5520 "parse.sql"
179370 break;
179371 case 302: /* vtabargtoken ::= ANY */
179372 case 303: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==303);
179373 case 304: /* lp ::= LP */ yytestcase(yyruleno==304);
179374 #line 1838 "parse.y"
179375 {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
179376 #line 5527 "parse.sql"
179377 break;
179378 case 305: /* with ::= WITH wqlist */
179379 case 306: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==306);
179380 #line 1855 "parse.y"
179381 { sqlite3WithPush(pParse, yymsp[0].minor.yy59, 1); }
179382 #line 5533 "parse.sql"
179383 break;
179384 case 307: /* wqas ::= AS */
179385 #line 1859 "parse.y"
179386 {yymsp[0].minor.yy462 = M10d_Any;}
179387 #line 5538 "parse.sql"
179388 break;
179389 case 308: /* wqas ::= AS MATERIALIZED */
179390 #line 1860 "parse.y"
179391 {yymsp[-1].minor.yy462 = M10d_Yes;}
179392 #line 5543 "parse.sql"
179393 break;
179394 case 309: /* wqas ::= AS NOT MATERIALIZED */
179395 #line 1861 "parse.y"
179396 {yymsp[-2].minor.yy462 = M10d_No;}
179397 #line 5548 "parse.sql"
179398 break;
179399 case 310: /* wqitem ::= withnm eidlist_opt wqas LP select RP */
179400 #line 1862 "parse.y"
179401 {
179402 yymsp[-5].minor.yy67 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy14, yymsp[-1].minor.yy555, yymsp[-3].minor.yy462); /*A-overwrites-X*/
179403 }
179404 #line 5555 "parse.sql"
179405 break;
179406 case 311: /* withnm ::= nm */
179407 #line 1865 "parse.y"
179408 {pParse->bHasWith = 1;}
179409 #line 5560 "parse.sql"
179410 break;
179411 case 312: /* wqlist ::= wqitem */
179412 #line 1866 "parse.y"
179413 {
179414 yymsp[0].minor.yy59 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy67); /*A-overwrites-X*/
179415 }
179416 #line 5567 "parse.sql"
179417 break;
179418 case 313: /* wqlist ::= wqlist COMMA wqitem */
179419 #line 1869 "parse.y"
179420 {
179421 yymsp[-2].minor.yy59 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy59, yymsp[0].minor.yy67);
179422 }
179423 #line 5574 "parse.sql"
179424 break;
179425 case 314: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
179426 #line 1884 "parse.y"
179427 {
179428 assert( yymsp[0].minor.yy211!=0 );
179429 sqlite3WindowChain(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy211);
179430 yymsp[0].minor.yy211->pNextWin = yymsp[-2].minor.yy211;
179431 yylhsminor.yy211 = yymsp[0].minor.yy211;
179432 }
179433 #line 5584 "parse.sql"
179434 yymsp[-2].minor.yy211 = yylhsminor.yy211;
179435 break;
179436 case 315: /* windowdefn ::= nm AS LP window RP */
179437 #line 1893 "parse.y"
179438 {
179439 if( ALWAYS(yymsp[-1].minor.yy211) ){
179440 yymsp[-1].minor.yy211->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n);
179441 }
179442 yylhsminor.yy211 = yymsp[-1].minor.yy211;
179443 }
179444 #line 5595 "parse.sql"
179445 yymsp[-4].minor.yy211 = yylhsminor.yy211;
179446 break;
179447 case 316: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */
179448 #line 1927 "parse.y"
179449 {
179450 yymsp[-4].minor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy14, yymsp[-1].minor.yy14, 0);
179451 }
179452 #line 5603 "parse.sql"
179453 break;
179454 case 317: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
179455 #line 1930 "parse.y"
179456 {
179457 yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy14, yymsp[-1].minor.yy14, &yymsp[-5].minor.yy0);
179458 }
179459 #line 5610 "parse.sql"
179460 yymsp[-5].minor.yy211 = yylhsminor.yy211;
179461 break;
179462 case 318: /* window ::= ORDER BY sortlist frame_opt */
179463 #line 1933 "parse.y"
179464 {
179465 yymsp[-3].minor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, yymsp[-1].minor.yy14, 0);
179466 }
179467 #line 5618 "parse.sql"
179468 break;
179469 case 319: /* window ::= nm ORDER BY sortlist frame_opt */
179470 #line 1936 "parse.y"
179471 {
179472 yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0);
179473 }
179474 #line 5625 "parse.sql"
179475 yymsp[-4].minor.yy211 = yylhsminor.yy211;
179476 break;
179477 case 320: /* window ::= nm frame_opt */
179478 #line 1940 "parse.y"
179479 {
179480 yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, 0, &yymsp[-1].minor.yy0);
179481 }
179482 #line 5633 "parse.sql"
179483 yymsp[-1].minor.yy211 = yylhsminor.yy211;
179484 break;
179485 case 321: /* frame_opt ::= */
179486 #line 1944 "parse.y"
179487 {
179488 yymsp[1].minor.yy211 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
179489 }
179490 #line 5641 "parse.sql"
179491 break;
179492 case 322: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
179493 #line 1947 "parse.y"
179494 {
179495 yylhsminor.yy211 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy144, yymsp[-1].minor.yy509.eType, yymsp[-1].minor.yy509.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy462);
179496 }
179497 #line 5648 "parse.sql"
179498 yymsp[-2].minor.yy211 = yylhsminor.yy211;
179499 break;
179500 case 323: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
179501 #line 1951 "parse.y"
179502 {
179503 yylhsminor.yy211 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy144, yymsp[-3].minor.yy509.eType, yymsp[-3].minor.yy509.pExpr, yymsp[-1].minor.yy509.eType, yymsp[-1].minor.yy509.pExpr, yymsp[0].minor.yy462);
179504 }
179505 #line 5656 "parse.sql"
179506 yymsp[-5].minor.yy211 = yylhsminor.yy211;
179507 break;
179508 case 325: /* frame_bound_s ::= frame_bound */
179509 case 327: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==327);
179510 #line 1957 "parse.y"
179511 {yylhsminor.yy509 = yymsp[0].minor.yy509;}
179512 #line 5663 "parse.sql"
179513 yymsp[0].minor.yy509 = yylhsminor.yy509;
179514 break;
179515 case 326: /* frame_bound_s ::= UNBOUNDED PRECEDING */
179516 case 328: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==328);
179517 case 330: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==330);
179518 #line 1958 "parse.y"
179519 {yylhsminor.yy509.eType = yymsp[-1].major; yylhsminor.yy509.pExpr = 0;}
179520 #line 5671 "parse.sql"
179521 yymsp[-1].minor.yy509 = yylhsminor.yy509;
179522 break;
179523 case 329: /* frame_bound ::= expr PRECEDING|FOLLOWING */
179524 #line 1963 "parse.y"
179525 {yylhsminor.yy509.eType = yymsp[0].major; yylhsminor.yy509.pExpr = yymsp[-1].minor.yy454;}
179526 #line 5677 "parse.sql"
179527 yymsp[-1].minor.yy509 = yylhsminor.yy509;
179528 break;
179529 case 331: /* frame_exclude_opt ::= */
179530 #line 1967 "parse.y"
179531 {yymsp[1].minor.yy462 = 0;}
179532 #line 5683 "parse.sql"
179533 break;
179534 case 332: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
179535 #line 1968 "parse.y"
179536 {yymsp[-1].minor.yy462 = yymsp[0].minor.yy462;}
179537 #line 5688 "parse.sql"
179538 break;
179539 case 333: /* frame_exclude ::= NO OTHERS */
179540 case 334: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==334);
179541 #line 1971 "parse.y"
179542 {yymsp[-1].minor.yy462 = yymsp[-1].major; /*A-overwrites-X*/}
179543 #line 5694 "parse.sql"
179544 break;
179545 case 335: /* frame_exclude ::= GROUP|TIES */
179546 #line 1973 "parse.y"
179547 {yymsp[0].minor.yy462 = yymsp[0].major; /*A-overwrites-X*/}
179548 #line 5699 "parse.sql"
179549 break;
179550 case 336: /* window_clause ::= WINDOW windowdefn_list */
179551 #line 1978 "parse.y"
179552 { yymsp[-1].minor.yy211 = yymsp[0].minor.yy211; }
179553 #line 5704 "parse.sql"
179554 break;
179555 case 337: /* filter_over ::= filter_clause over_clause */
179556 #line 1980 "parse.y"
179557 {
179558 if( yymsp[0].minor.yy211 ){
179559 yymsp[0].minor.yy211->pFilter = yymsp[-1].minor.yy454;
179560 }else{
179561 sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy454);
179562 }
179563 yylhsminor.yy211 = yymsp[0].minor.yy211;
179564 }
179565 #line 5716 "parse.sql"
179566 yymsp[-1].minor.yy211 = yylhsminor.yy211;
179567 break;
179568 case 338: /* filter_over ::= over_clause */
179569 #line 1988 "parse.y"
179570 {
179571 yylhsminor.yy211 = yymsp[0].minor.yy211;
179572 }
179573 #line 5724 "parse.sql"
179574 yymsp[0].minor.yy211 = yylhsminor.yy211;
179575 break;
179576 case 339: /* filter_over ::= filter_clause */
179577 #line 1991 "parse.y"
179578 {
179579 yylhsminor.yy211 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
179580 if( yylhsminor.yy211 ){
179581 yylhsminor.yy211->eFrmType = TK_FILTER;
179582 yylhsminor.yy211->pFilter = yymsp[0].minor.yy454;
179583 }else{
179584 sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy454);
179585 }
179586 }
179587 #line 5738 "parse.sql"
179588 yymsp[0].minor.yy211 = yylhsminor.yy211;
179589 break;
179590 case 340: /* over_clause ::= OVER LP window RP */
179591 #line 2001 "parse.y"
179592 {
179593 yymsp[-3].minor.yy211 = yymsp[-1].minor.yy211;
179594 assert( yymsp[-3].minor.yy211!=0 );
179595 }
179596 #line 5747 "parse.sql"
179597 break;
179598 case 341: /* over_clause ::= OVER nm */
179599 #line 2005 "parse.y"
179600 {
179601 yymsp[-1].minor.yy211 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
179602 if( yymsp[-1].minor.yy211 ){
179603 yymsp[-1].minor.yy211->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
179604 }
179605 }
179606 #line 5757 "parse.sql"
179607 break;
179608 case 342: /* filter_clause ::= FILTER LP WHERE expr RP */
179609 #line 2012 "parse.y"
179610 { yymsp[-4].minor.yy454 = yymsp[-1].minor.yy454; }
179611 #line 5762 "parse.sql"
179612 break;
179613 case 343: /* term ::= QNUMBER */
179614 #line 2038 "parse.y"
179615 {
179616 yylhsminor.yy454=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0);
179617 sqlite3DequoteNumber(pParse, yylhsminor.yy454);
179618 }
179619 #line 5770 "parse.sql"
179620 yymsp[0].minor.yy454 = yylhsminor.yy454;
179621 break;
179622 default:
179623 /* (344) input ::= cmdlist */ yytestcase(yyruleno==344);
179624 /* (345) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==345);
@@ -179742,19 +179175,17 @@
179742 ){
179743 sqlite3ParserARG_FETCH
179744 sqlite3ParserCTX_FETCH
179745 #define TOKEN yyminor
179746 /************ Begin %syntax_error code ****************************************/
179747 #line 43 "parse.y"
179748
179749 UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */
179750 if( TOKEN.z[0] ){
179751 sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
179752 }else{
179753 sqlite3ErrorMsg(pParse, "incomplete input");
179754 }
179755 #line 5906 "parse.sql"
179756 /************ End %syntax_error code ******************************************/
179757 sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
179758 sqlite3ParserCTX_STORE
179759 }
179760
@@ -180022,11 +179453,10 @@
180022 #endif
180023 }
180024
180025 /************** End of parse.c ***********************************************/
180026 /************** Begin file tokenize.c ****************************************/
180027 #line 1 "tsrc/tokenize.c"
180028 /*
180029 ** 2001 September 15
180030 **
180031 ** The author disclaims copyright to this source code. In place of
180032 ** a legal notice, here is a blessing:
@@ -180172,11 +179602,10 @@
180172 ** named keywordhash.h and then included into this source file by
180173 ** the #include below.
180174 */
180175 /************** Include keywordhash.h in the middle of tokenize.c ************/
180176 /************** Begin file keywordhash.h *************************************/
180177 #line 1 "tsrc/keywordhash.h"
180178 /***** This file contains automatically generated code ******
180179 **
180180 ** The code in this file has been automatically generated by
180181 **
180182 ** sqlite/tool/mkkeywordhash.c
@@ -180658,11 +180087,10 @@
180658 return TK_ID!=sqlite3KeywordCode((const u8*)zName, nName);
180659 }
180660
180661 /************** End of keywordhash.h *****************************************/
180662 /************** Continuing where we left off in tokenize.c *******************/
180663 #line 149 "tsrc/tokenize.c"
180664
180665
180666 /*
180667 ** If X is a character that can be used in an identifier then
180668 ** IdChar(X) will be true. Otherwise it is false.
@@ -181241,11 +180669,13 @@
181241 }
181242 if( pParse->zErrMsg || (pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE) ){
181243 if( pParse->zErrMsg==0 ){
181244 pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc));
181245 }
181246 sqlite3_log(pParse->rc, "%s in \"%s\"", pParse->zErrMsg, pParse->zTail);
 
 
181247 nErr++;
181248 }
181249 pParse->zTail = zSql;
181250 #ifndef SQLITE_OMIT_VIRTUALTABLE
181251 sqlite3_free(pParse->apVtabLock);
@@ -181402,11 +180832,10 @@
181402 }
181403 #endif /* SQLITE_ENABLE_NORMALIZE */
181404
181405 /************** End of tokenize.c ********************************************/
181406 /************** Begin file complete.c ****************************************/
181407 #line 1 "tsrc/complete.c"
181408 /*
181409 ** 2001 September 15
181410 **
181411 ** The author disclaims copyright to this source code. In place of
181412 ** a legal notice, here is a blessing:
@@ -181696,11 +181125,10 @@
181696 #endif /* SQLITE_OMIT_UTF16 */
181697 #endif /* SQLITE_OMIT_COMPLETE */
181698
181699 /************** End of complete.c ********************************************/
181700 /************** Begin file main.c ********************************************/
181701 #line 1 "tsrc/main.c"
181702 /*
181703 ** 2001 September 15
181704 **
181705 ** The author disclaims copyright to this source code. In place of
181706 ** a legal notice, here is a blessing:
@@ -181718,11 +181146,10 @@
181718 /* #include "sqliteInt.h" */
181719
181720 #ifdef SQLITE_ENABLE_FTS3
181721 /************** Include fts3.h in the middle of main.c ***********************/
181722 /************** Begin file fts3.h ********************************************/
181723 #line 1 "tsrc/fts3.h"
181724 /*
181725 ** 2006 Oct 10
181726 **
181727 ** The author disclaims copyright to this source code. In place of
181728 ** a legal notice, here is a blessing:
@@ -181748,16 +181175,14 @@
181748 } /* extern "C" */
181749 #endif /* __cplusplus */
181750
181751 /************** End of fts3.h ************************************************/
181752 /************** Continuing where we left off in main.c ***********************/
181753 #line 21 "tsrc/main.c"
181754 #endif
181755 #ifdef SQLITE_ENABLE_RTREE
181756 /************** Include rtree.h in the middle of main.c **********************/
181757 /************** Begin file rtree.h *******************************************/
181758 #line 1 "tsrc/rtree.h"
181759 /*
181760 ** 2008 May 26
181761 **
181762 ** The author disclaims copyright to this source code. In place of
181763 ** a legal notice, here is a blessing:
@@ -181787,16 +181212,14 @@
181787 } /* extern "C" */
181788 #endif /* __cplusplus */
181789
181790 /************** End of rtree.h ***********************************************/
181791 /************** Continuing where we left off in main.c ***********************/
181792 #line 24 "tsrc/main.c"
181793 #endif
181794 #if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
181795 /************** Include sqliteicu.h in the middle of main.c ******************/
181796 /************** Begin file sqliteicu.h ***************************************/
181797 #line 1 "tsrc/sqliteicu.h"
181798 /*
181799 ** 2008 May 26
181800 **
181801 ** The author disclaims copyright to this source code. In place of
181802 ** a legal notice, here is a blessing:
@@ -181822,11 +181245,10 @@
181822 } /* extern "C" */
181823 #endif /* __cplusplus */
181824
181825 /************** End of sqliteicu.h *******************************************/
181826 /************** Continuing where we left off in main.c ***********************/
181827 #line 27 "tsrc/main.c"
181828 #endif
181829
181830 /*
181831 ** This is an extension initializer that is a no-op and always
181832 ** succeeds, except that it fails if the fault-simulation is set
@@ -184724,12 +184146,12 @@
184724 }
184725 oldLimit = db->aLimit[limitId];
184726 if( newLimit>=0 ){ /* IMP: R-52476-28732 */
184727 if( newLimit>aHardLimit[limitId] ){
184728 newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */
184729 }else if( newLimit<1 && limitId==SQLITE_LIMIT_LENGTH ){
184730 newLimit = 1;
184731 }
184732 db->aLimit[limitId] = newLimit;
184733 }
184734 return oldLimit; /* IMP: R-53341-35419 */
184735 }
@@ -186087,10 +185509,11 @@
186087 #ifndef SQLITE_OMIT_WINDOWFUNC
186088 sqlite3ShowWindow(0);
186089 sqlite3ShowWinFunc(0);
186090 #endif
186091 sqlite3ShowSelect(0);
 
186092 }
186093 #endif
186094 break;
186095 }
186096
@@ -186873,11 +186296,10 @@
186873 }
186874 #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
186875
186876 /************** End of main.c ************************************************/
186877 /************** Begin file notify.c ******************************************/
186878 #line 1 "tsrc/notify.c"
186879 /*
186880 ** 2009 March 3
186881 **
186882 ** The author disclaims copyright to this source code. In place of
186883 ** a legal notice, here is a blessing:
@@ -187212,11 +186634,10 @@
187212 }
187213 #endif
187214
187215 /************** End of notify.c **********************************************/
187216 /************** Begin file fts3.c ********************************************/
187217 #line 1 "tsrc/fts3.c"
187218 /*
187219 ** 2006 Oct 10
187220 **
187221 ** The author disclaims copyright to this source code. In place of
187222 ** a legal notice, here is a blessing:
@@ -187505,11 +186926,10 @@
187505 ** older data.
187506 */
187507
187508 /************** Include fts3Int.h in the middle of fts3.c ********************/
187509 /************** Begin file fts3Int.h *****************************************/
187510 #line 1 "tsrc/fts3Int.h"
187511 /*
187512 ** 2009 Nov 12
187513 **
187514 ** The author disclaims copyright to this source code. In place of
187515 ** a legal notice, here is a blessing:
@@ -187552,11 +186972,10 @@
187552 #endif
187553
187554 /* #include "sqlite3.h" */
187555 /************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/
187556 /************** Begin file fts3_tokenizer.h **********************************/
187557 #line 1 "tsrc/fts3_tokenizer.h"
187558 /*
187559 ** 2006 July 10
187560 **
187561 ** The author disclaims copyright to this source code.
187562 **
@@ -187717,14 +187136,12 @@
187717
187718 #endif /* _FTS3_TOKENIZER_H_ */
187719
187720 /************** End of fts3_tokenizer.h **************************************/
187721 /************** Continuing where we left off in fts3Int.h ********************/
187722 #line 46 "tsrc/fts3Int.h"
187723 /************** Include fts3_hash.h in the middle of fts3Int.h ***************/
187724 /************** Begin file fts3_hash.h ***************************************/
187725 #line 1 "tsrc/fts3_hash.h"
187726 /*
187727 ** 2001 September 22
187728 **
187729 ** The author disclaims copyright to this source code. In place of
187730 ** a legal notice, here is a blessing:
@@ -187836,11 +187253,10 @@
187836
187837 #endif /* _FTS3_HASH_H_ */
187838
187839 /************** End of fts3_hash.h *******************************************/
187840 /************** Continuing where we left off in fts3Int.h ********************/
187841 #line 47 "tsrc/fts3Int.h"
187842
187843 /*
187844 ** This constant determines the maximum depth of an FTS expression tree
187845 ** that the library will create and use. FTS uses recursion to perform
187846 ** various operations on the query tree, so the disadvantage of a large
@@ -188453,11 +187869,10 @@
188453 #endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */
188454 #endif /* _FTSINT_H */
188455
188456 /************** End of fts3Int.h *********************************************/
188457 /************** Continuing where we left off in fts3.c ***********************/
188458 #line 292 "tsrc/fts3.c"
188459 #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
188460
188461 #if defined(SQLITE_ENABLE_FTS3) && !defined(SQLITE_CORE)
188462 # define SQLITE_CORE 1
188463 #endif
@@ -190509,14 +189924,19 @@
190509
190510 assert_fts3_nc( p!=0 && *p1!=0 && *p2!=0 );
190511 if( *p1==POS_COLUMN ){
190512 p1++;
190513 p1 += fts3GetVarint32(p1, &iCol1);
 
 
 
190514 }
190515 if( *p2==POS_COLUMN ){
190516 p2++;
190517 p2 += fts3GetVarint32(p2, &iCol2);
 
 
190518 }
190519
190520 while( 1 ){
190521 if( iCol1==iCol2 ){
190522 char *pSave = p;
@@ -193683,11 +193103,11 @@
193683 for(p=pExpr; p->pLeft; p=p->pLeft){
193684 assert( p->pRight->pPhrase->doclist.nList>0 );
193685 nTmp += p->pRight->pPhrase->doclist.nList;
193686 }
193687 nTmp += p->pPhrase->doclist.nList;
193688 aTmp = sqlite3_malloc64(nTmp*2);
193689 if( !aTmp ){
193690 *pRc = SQLITE_NOMEM;
193691 res = 0;
193692 }else{
193693 char *aPoslist = p->pPhrase->doclist.pList;
@@ -194355,11 +193775,10 @@
194355
194356 #endif
194357
194358 /************** End of fts3.c ************************************************/
194359 /************** Begin file fts3_aux.c ****************************************/
194360 #line 1 "tsrc/fts3_aux.c"
194361 /*
194362 ** 2011 Jan 27
194363 **
194364 ** The author disclaims copyright to this source code. In place of
194365 ** a legal notice, here is a blessing:
@@ -194916,11 +194335,10 @@
194916
194917 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
194918
194919 /************** End of fts3_aux.c ********************************************/
194920 /************** Begin file fts3_expr.c ***************************************/
194921 #line 1 "tsrc/fts3_expr.c"
194922 /*
194923 ** 2008 Nov 28
194924 **
194925 ** The author disclaims copyright to this source code. In place of
194926 ** a legal notice, here is a blessing:
@@ -195238,14 +194656,15 @@
195238 rc = pModule->xNext(pCursor, &zByte, &nByte, &iBegin, &iEnd, &iPos);
195239 if( rc==SQLITE_OK ){
195240 Fts3PhraseToken *pToken;
195241
195242 p = fts3ReallocOrFree(p, nSpace + ii*sizeof(Fts3PhraseToken));
195243 if( !p ) goto no_mem;
195244
195245 zTemp = fts3ReallocOrFree(zTemp, nTemp + nByte);
195246 if( !zTemp ) goto no_mem;
 
 
 
195247
195248 assert( nToken==ii );
195249 pToken = &((Fts3Phrase *)(&p[1]))->aToken[ii];
195250 memset(pToken, 0, sizeof(Fts3PhraseToken));
195251
@@ -195256,53 +194675,51 @@
195256 pToken->isPrefix = (iEnd<nInput && zInput[iEnd]=='*');
195257 pToken->bFirst = (iBegin>0 && zInput[iBegin-1]=='^');
195258 nToken = ii+1;
195259 }
195260 }
195261
195262 pModule->xClose(pCursor);
195263 pCursor = 0;
195264 }
195265
195266 if( rc==SQLITE_DONE ){
195267 int jj;
195268 char *zBuf = 0;
195269
195270 p = fts3ReallocOrFree(p, nSpace + nToken*sizeof(Fts3PhraseToken) + nTemp);
195271 if( !p ) goto no_mem;
 
 
 
195272 memset(p, 0, (char *)&(((Fts3Phrase *)&p[1])->aToken[0])-(char *)p);
195273 p->eType = FTSQUERY_PHRASE;
195274 p->pPhrase = (Fts3Phrase *)&p[1];
195275 p->pPhrase->iColumn = pParse->iDefaultCol;
195276 p->pPhrase->nToken = nToken;
195277
195278 zBuf = (char *)&p->pPhrase->aToken[nToken];
 
195279 if( zTemp ){
195280 memcpy(zBuf, zTemp, nTemp);
195281 sqlite3_free(zTemp);
195282 }else{
195283 assert( nTemp==0 );
195284 }
195285
195286 for(jj=0; jj<p->pPhrase->nToken; jj++){
195287 p->pPhrase->aToken[jj].z = zBuf;
195288 zBuf += p->pPhrase->aToken[jj].n;
195289 }
195290 rc = SQLITE_OK;
195291 }
195292
195293 *ppExpr = p;
195294 return rc;
195295 no_mem:
195296
195297 if( pCursor ){
195298 pModule->xClose(pCursor);
195299 }
195300 sqlite3_free(zTemp);
195301 sqlite3_free(p);
195302 *ppExpr = 0;
195303 return SQLITE_NOMEM;
 
 
 
195304 }
195305
195306 /*
195307 ** The output variable *ppExpr is populated with an allocated Fts3Expr
195308 ** structure, or set to 0 if the end of the input buffer is reached.
@@ -196213,11 +195630,10 @@
196213 #endif
196214 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
196215
196216 /************** End of fts3_expr.c *******************************************/
196217 /************** Begin file fts3_hash.c ***************************************/
196218 #line 1 "tsrc/fts3_hash.c"
196219 /*
196220 ** 2001 September 22
196221 **
196222 ** The author disclaims copyright to this source code. In place of
196223 ** a legal notice, here is a blessing:
@@ -196600,11 +196016,10 @@
196600
196601 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
196602
196603 /************** End of fts3_hash.c *******************************************/
196604 /************** Begin file fts3_porter.c *************************************/
196605 #line 1 "tsrc/fts3_porter.c"
196606 /*
196607 ** 2006 September 30
196608 **
196609 ** The author disclaims copyright to this source code. In place of
196610 ** a legal notice, here is a blessing:
@@ -197266,11 +196681,10 @@
197266
197267 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
197268
197269 /************** End of fts3_porter.c *****************************************/
197270 /************** Begin file fts3_tokenizer.c **********************************/
197271 #line 1 "tsrc/fts3_tokenizer.c"
197272 /*
197273 ** 2007 June 22
197274 **
197275 ** The author disclaims copyright to this source code. In place of
197276 ** a legal notice, here is a blessing:
@@ -197786,11 +197200,10 @@
197786
197787 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
197788
197789 /************** End of fts3_tokenizer.c **************************************/
197790 /************** Begin file fts3_tokenizer1.c *********************************/
197791 #line 1 "tsrc/fts3_tokenizer1.c"
197792 /*
197793 ** 2006 Oct 10
197794 **
197795 ** The author disclaims copyright to this source code. In place of
197796 ** a legal notice, here is a blessing:
@@ -198024,11 +197437,10 @@
198024
198025 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
198026
198027 /************** End of fts3_tokenizer1.c *************************************/
198028 /************** Begin file fts3_tokenize_vtab.c ******************************/
198029 #line 1 "tsrc/fts3_tokenize_vtab.c"
198030 /*
198031 ** 2013 Apr 22
198032 **
198033 ** The author disclaims copyright to this source code. In place of
198034 ** a legal notice, here is a blessing:
@@ -198487,11 +197899,10 @@
198487
198488 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
198489
198490 /************** End of fts3_tokenize_vtab.c **********************************/
198491 /************** Begin file fts3_write.c **************************************/
198492 #line 1 "tsrc/fts3_write.c"
198493 /*
198494 ** 2009 Oct 23
198495 **
198496 ** The author disclaims copyright to this source code. In place of
198497 ** a legal notice, here is a blessing:
@@ -204325,11 +203736,10 @@
204325
204326 #endif
204327
204328 /************** End of fts3_write.c ******************************************/
204329 /************** Begin file fts3_snippet.c ************************************/
204330 #line 1 "tsrc/fts3_snippet.c"
204331 /*
204332 ** 2009 Oct 23
204333 **
204334 ** The author disclaims copyright to this source code. In place of
204335 ** a legal notice, here is a blessing:
@@ -206085,11 +205495,10 @@
206085
206086 #endif
206087
206088 /************** End of fts3_snippet.c ****************************************/
206089 /************** Begin file fts3_unicode.c ************************************/
206090 #line 1 "tsrc/fts3_unicode.c"
206091 /*
206092 ** 2012 May 24
206093 **
206094 ** The author disclaims copyright to this source code. In place of
206095 ** a legal notice, here is a blessing:
@@ -206486,11 +205895,10 @@
206486 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
206487 #endif /* ifndef SQLITE_DISABLE_FTS3_UNICODE */
206488
206489 /************** End of fts3_unicode.c ****************************************/
206490 /************** Begin file fts3_unicode2.c ***********************************/
206491 #line 1 "tsrc/fts3_unicode2.c"
206492 /*
206493 ** 2012-05-25
206494 **
206495 ** The author disclaims copyright to this source code. In place of
206496 ** a legal notice, here is a blessing:
@@ -206873,11 +206281,10 @@
206873 #endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */
206874 #endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */
206875
206876 /************** End of fts3_unicode2.c ***************************************/
206877 /************** Begin file json.c ********************************************/
206878 #line 1 "tsrc/json.c"
206879 /*
206880 ** 2015-08-12
206881 **
206882 ** The author disclaims copyright to this source code. In place of
206883 ** a legal notice, here is a blessing:
@@ -212343,11 +211750,10 @@
212343 }
212344 #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) */
212345
212346 /************** End of json.c ************************************************/
212347 /************** Begin file rtree.c *******************************************/
212348 #line 1 "tsrc/rtree.c"
212349 /*
212350 ** 2001 September 15
212351 **
212352 ** The author disclaims copyright to this source code. In place of
212353 ** a legal notice, here is a blessing:
@@ -216632,11 +216038,10 @@
216632
216633 /* Conditionally include the geopoly code */
216634 #ifdef SQLITE_ENABLE_GEOPOLY
216635 /************** Include geopoly.c in the middle of rtree.c *******************/
216636 /************** Begin file geopoly.c *****************************************/
216637 #line 1 "tsrc/geopoly.c"
216638 /*
216639 ** 2018-05-25
216640 **
216641 ** The author disclaims copyright to this source code. In place of
216642 ** a legal notice, here is a blessing:
@@ -218475,11 +217880,10 @@
218475 return rc;
218476 }
218477
218478 /************** End of geopoly.c *********************************************/
218479 /************** Continuing where we left off in rtree.c **********************/
218480 #line 4288 "tsrc/rtree.c"
218481 #endif
218482
218483 /*
218484 ** Register the r-tree module with database handle db. This creates the
218485 ** virtual table module "rtree" and the debugging/analysis scalar
@@ -218658,11 +218062,10 @@
218658
218659 #endif
218660
218661 /************** End of rtree.c ***********************************************/
218662 /************** Begin file icu.c *********************************************/
218663 #line 1 "tsrc/icu.c"
218664 /*
218665 ** 2007 May 6
218666 **
218667 ** The author disclaims copyright to this source code. In place of
218668 ** a legal notice, here is a blessing:
@@ -219250,11 +218653,10 @@
219250
219251 #endif
219252
219253 /************** End of icu.c *************************************************/
219254 /************** Begin file fts3_icu.c ****************************************/
219255 #line 1 "tsrc/fts3_icu.c"
219256 /*
219257 ** 2007 June 22
219258 **
219259 ** The author disclaims copyright to this source code. In place of
219260 ** a legal notice, here is a blessing:
@@ -219516,11 +218918,10 @@
219516 #endif /* defined(SQLITE_ENABLE_ICU) */
219517 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
219518
219519 /************** End of fts3_icu.c ********************************************/
219520 /************** Begin file sqlite3rbu.c **************************************/
219521 #line 1 "tsrc/sqlite3rbu.c"
219522 /*
219523 ** 2014 August 30
219524 **
219525 ** The author disclaims copyright to this source code. In place of
219526 ** a legal notice, here is a blessing:
@@ -219608,11 +219009,10 @@
219608 /* #include "sqlite3.h" */
219609
219610 #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU)
219611 /************** Include sqlite3rbu.h in the middle of sqlite3rbu.c ***********/
219612 /************** Begin file sqlite3rbu.h **************************************/
219613 #line 1 "tsrc/sqlite3rbu.h"
219614 /*
219615 ** 2014 August 30
219616 **
219617 ** The author disclaims copyright to this source code. In place of
219618 ** a legal notice, here is a blessing:
@@ -220245,11 +219645,10 @@
220245
220246 #endif /* _SQLITE3RBU_H */
220247
220248 /************** End of sqlite3rbu.h ******************************************/
220249 /************** Continuing where we left off in sqlite3rbu.c *****************/
220250 #line 91 "tsrc/sqlite3rbu.c"
220251
220252 #if defined(_WIN32_WCE)
220253 /* #include "windows.h" */
220254 #endif
220255
@@ -225606,11 +225005,10 @@
225606
225607 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) */
225608
225609 /************** End of sqlite3rbu.c ******************************************/
225610 /************** Begin file dbstat.c ******************************************/
225611 #line 1 "tsrc/dbstat.c"
225612 /*
225613 ** 2010 July 12
225614 **
225615 ** The author disclaims copyright to this source code. In place of
225616 ** a legal notice, here is a blessing:
@@ -226516,11 +225914,10 @@
226516 SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
226517 #endif /* SQLITE_ENABLE_DBSTAT_VTAB */
226518
226519 /************** End of dbstat.c **********************************************/
226520 /************** Begin file dbpage.c ******************************************/
226521 #line 1 "tsrc/dbpage.c"
226522 /*
226523 ** 2017-10-11
226524 **
226525 ** The author disclaims copyright to this source code. In place of
226526 ** a legal notice, here is a blessing:
@@ -226912,10 +226309,12 @@
226912 if( (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK && pData ){
226913 unsigned char *aPage = sqlite3PagerGetData(pDbPage);
226914 memcpy(aPage, pData, szPage);
226915 pTab->pgnoTrunc = 0;
226916 }
 
 
226917 }
226918 sqlite3PagerUnref(pDbPage);
226919 return rc;
226920
226921 update_fail:
@@ -226999,11 +226398,10 @@
226999 SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; }
227000 #endif /* SQLITE_ENABLE_DBSTAT_VTAB */
227001
227002 /************** End of dbpage.c **********************************************/
227003 /************** Begin file sqlite3session.c **********************************/
227004 #line 1 "tsrc/sqlite3session.c"
227005
227006 #if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
227007 /* #include "sqlite3session.h" */
227008 /* #include <assert.h> */
227009 /* #include <string.h> */
@@ -233539,11 +232937,10 @@
233539
233540 #endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
233541
233542 /************** End of sqlite3session.c **************************************/
233543 /************** Begin file fts5.c ********************************************/
233544 #line 1 "tsrc/fts5.c"
233545
233546 /*
233547 ** This, the "fts5.c" source file, is a composite file that is itself
233548 ** assembled from the following files:
233549 **
@@ -233577,11 +232974,10 @@
233577 /* #include <stdint.h> */
233578 #endif
233579 #ifdef HAVE_INTTYPES_H
233580 /* #include <inttypes.h> */
233581 #endif
233582 #line 1 "fts5.h"
233583 /*
233584 ** 2014 May 31
233585 **
233586 ** The author disclaims copyright to this source code. In place of
233587 ** a legal notice, here is a blessing:
@@ -233878,17 +233274,32 @@
233878 ** This is used to access token iToken of phrase hit iIdx within the
233879 ** current row. If iIdx is less than zero or greater than or equal to the
233880 ** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise,
233881 ** output variable (*ppToken) is set to point to a buffer containing the
233882 ** matching document token, and (*pnToken) to the size of that buffer in
233883 ** bytes. This API is not available if the specified token matches a
233884 ** prefix query term. In that case both output variables are always set
233885 ** to 0.
233886 **
233887 ** The output text is not a copy of the document text that was tokenized.
233888 ** It is the output of the tokenizer module. For tokendata=1 tables, this
233889 ** includes any embedded 0x00 and trailing data.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233890 **
233891 ** This API can be quite slow if used with an FTS5 table created with the
233892 ** "detail=none" or "detail=column" option.
233893 **
233894 ** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale)
@@ -234318,11 +233729,10 @@
234318 } /* end of the 'extern "C"' block */
234319 #endif
234320
234321 #endif /* _FTS5_H */
234322
234323 #line 1 "fts5Int.h"
234324 /*
234325 ** 2014 May 31
234326 **
234327 ** The author disclaims copyright to this source code. In place of
234328 ** a legal notice, here is a blessing:
@@ -234568,11 +233978,12 @@
234568 int nUsermerge; /* 'usermerge' setting */
234569 int nHashSize; /* Bytes of memory for in-memory hash */
234570 char *zRank; /* Name of rank function */
234571 char *zRankArgs; /* Arguments to rank function */
234572 int bSecureDelete; /* 'secure-delete' */
234573 int nDeleteMerge; /* 'deletemerge' */
 
234574
234575 /* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */
234576 char **pzErrmsg;
234577
234578 #ifdef SQLITE_DEBUG
@@ -234825,11 +234236,18 @@
234825 static int sqlite3Fts5StructureTest(Fts5Index*, void*);
234826
234827 /*
234828 ** Used by xInstToken():
234829 */
234830 static int sqlite3Fts5IterToken(Fts5IndexIter*, i64, int, int, const char**, int*);
 
 
 
 
 
 
 
234831
234832 /*
234833 ** Insert or remove data to or from the index. Each time a document is
234834 ** added to or removed from the index, this function is called one or more
234835 ** times.
@@ -235258,11 +234676,10 @@
235258 ** End of interface to code in fts5_unicode2.c.
235259 **************************************************************************/
235260
235261 #endif
235262
235263 #line 1 "fts5parse.h"
235264 #define FTS5_OR 1
235265 #define FTS5_AND 2
235266 #define FTS5_NOT 3
235267 #define FTS5_TERM 4
235268 #define FTS5_COLON 5
@@ -235275,11 +234692,10 @@
235275 #define FTS5_CARET 12
235276 #define FTS5_COMMA 13
235277 #define FTS5_PLUS 14
235278 #define FTS5_STAR 15
235279
235280 #line 1 "fts5parse.c"
235281 /* This file is automatically generated by Lemon from input grammar
235282 ** source file "fts5parse.y".
235283 */
235284 /*
235285 ** 2000-05-29
@@ -235304,11 +234720,10 @@
235304 **
235305 ** The following is the concatenation of all %include directives from the
235306 ** input grammar file:
235307 */
235308 /************ Begin %include sections from the grammar ************************/
235309 #line 47 "fts5parse.y"
235310
235311 /* #include "fts5Int.h" */
235312 /* #include "fts5parse.h" */
235313
235314 /*
@@ -235332,11 +234747,10 @@
235332 ** Alternative datatype for the argument to the malloc() routine passed
235333 ** into sqlite3ParserAlloc(). The default is size_t.
235334 */
235335 #define fts5YYMALLOCARGTYPE u64
235336
235337 #line 58 "fts5parse.sql"
235338 /**************** End of %include directives **********************************/
235339 /* These constants specify the various numeric values for terminal symbols.
235340 ***************** Begin token definitions *************************************/
235341 #ifndef FTS5_OR
235342 #define FTS5_OR 1
@@ -235879,45 +235293,35 @@
235879 ** inside the C code.
235880 */
235881 /********* Begin destructor definitions ***************************************/
235882 case 16: /* input */
235883 {
235884 #line 83 "fts5parse.y"
235885 (void)pParse;
235886 #line 606 "fts5parse.sql"
235887 }
235888 break;
235889 case 17: /* expr */
235890 case 18: /* cnearset */
235891 case 19: /* exprlist */
235892 {
235893 #line 89 "fts5parse.y"
235894 sqlite3Fts5ParseNodeFree((fts5yypminor->fts5yy24));
235895 #line 615 "fts5parse.sql"
235896 }
235897 break;
235898 case 20: /* colset */
235899 case 21: /* colsetlist */
235900 {
235901 #line 93 "fts5parse.y"
235902 sqlite3_free((fts5yypminor->fts5yy11));
235903 #line 623 "fts5parse.sql"
235904 }
235905 break;
235906 case 22: /* nearset */
235907 case 23: /* nearphrases */
235908 {
235909 #line 148 "fts5parse.y"
235910 sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy46));
235911 #line 631 "fts5parse.sql"
235912 }
235913 break;
235914 case 24: /* phrase */
235915 {
235916 #line 183 "fts5parse.y"
235917 sqlite3Fts5ParsePhraseFree((fts5yypminor->fts5yy53));
235918 #line 638 "fts5parse.sql"
235919 }
235920 break;
235921 /********* End destructor definitions *****************************************/
235922 default: break; /* If no destructor action specified: do nothing */
235923 }
@@ -236148,14 +235552,12 @@
236148 #endif
236149 while( fts5yypParser->fts5yytos>fts5yypParser->fts5yystack ) fts5yy_pop_parser_stack(fts5yypParser);
236150 /* Here code is inserted which will execute if the parser
236151 ** stack every overflows */
236152 /******** Begin %stack_overflow code ******************************************/
236153 #line 36 "fts5parse.y"
236154
236155 sqlite3Fts5ParseError(pParse, "fts5: parser stack overflow");
236156 #line 876 "fts5parse.sql"
236157 /******** End %stack_overflow code ********************************************/
236158 sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument var */
236159 sqlite3Fts5ParserCTX_STORE
236160 }
236161
@@ -236320,202 +235722,148 @@
236320 ** break;
236321 */
236322 /********** Begin reduce actions **********************************************/
236323 fts5YYMINORTYPE fts5yylhsminor;
236324 case 0: /* input ::= expr */
236325 #line 82 "fts5parse.y"
236326 { sqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy24); }
236327 #line 1047 "fts5parse.sql"
236328 break;
236329 case 1: /* colset ::= MINUS LCP colsetlist RCP */
236330 #line 97 "fts5parse.y"
236331 {
236332 fts5yymsp[-3].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
236333 }
236334 #line 1054 "fts5parse.sql"
236335 break;
236336 case 2: /* colset ::= LCP colsetlist RCP */
236337 #line 100 "fts5parse.y"
236338 { fts5yymsp[-2].minor.fts5yy11 = fts5yymsp[-1].minor.fts5yy11; }
236339 #line 1059 "fts5parse.sql"
236340 break;
236341 case 3: /* colset ::= STRING */
236342 #line 101 "fts5parse.y"
236343 {
236344 fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
236345 }
236346 #line 1066 "fts5parse.sql"
236347 fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
236348 break;
236349 case 4: /* colset ::= MINUS STRING */
236350 #line 104 "fts5parse.y"
236351 {
236352 fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
236353 fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
236354 }
236355 #line 1075 "fts5parse.sql"
236356 break;
236357 case 5: /* colsetlist ::= colsetlist STRING */
236358 #line 109 "fts5parse.y"
236359 {
236360 fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy11, &fts5yymsp[0].minor.fts5yy0); }
236361 #line 1081 "fts5parse.sql"
236362 fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
236363 break;
236364 case 6: /* colsetlist ::= STRING */
236365 #line 111 "fts5parse.y"
236366 {
236367 fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
236368 }
236369 #line 1089 "fts5parse.sql"
236370 fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
236371 break;
236372 case 7: /* expr ::= expr AND expr */
236373 #line 115 "fts5parse.y"
236374 {
236375 fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
236376 }
236377 #line 1097 "fts5parse.sql"
236378 fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
236379 break;
236380 case 8: /* expr ::= expr OR expr */
236381 #line 118 "fts5parse.y"
236382 {
236383 fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
236384 }
236385 #line 1105 "fts5parse.sql"
236386 fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
236387 break;
236388 case 9: /* expr ::= expr NOT expr */
236389 #line 121 "fts5parse.y"
236390 {
236391 fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
236392 }
236393 #line 1113 "fts5parse.sql"
236394 fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
236395 break;
236396 case 10: /* expr ::= colset COLON LP expr RP */
236397 #line 125 "fts5parse.y"
236398 {
236399 sqlite3Fts5ParseSetColset(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[-4].minor.fts5yy11);
236400 fts5yylhsminor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;
236401 }
236402 #line 1122 "fts5parse.sql"
236403 fts5yymsp[-4].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
236404 break;
236405 case 11: /* expr ::= LP expr RP */
236406 #line 129 "fts5parse.y"
236407 {fts5yymsp[-2].minor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;}
236408 #line 1128 "fts5parse.sql"
236409 break;
236410 case 12: /* expr ::= exprlist */
236411 case 13: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==13);
236412 #line 130 "fts5parse.y"
236413 {fts5yylhsminor.fts5yy24 = fts5yymsp[0].minor.fts5yy24;}
236414 #line 1134 "fts5parse.sql"
236415 fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
236416 break;
236417 case 14: /* exprlist ::= exprlist cnearset */
236418 #line 133 "fts5parse.y"
236419 {
236420 fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24);
236421 }
236422 #line 1142 "fts5parse.sql"
236423 fts5yymsp[-1].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
236424 break;
236425 case 15: /* cnearset ::= nearset */
236426 #line 137 "fts5parse.y"
236427 {
236428 fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46);
236429 }
236430 #line 1150 "fts5parse.sql"
236431 fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
236432 break;
236433 case 16: /* cnearset ::= colset COLON nearset */
236434 #line 140 "fts5parse.y"
236435 {
236436 fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46);
236437 sqlite3Fts5ParseSetColset(pParse, fts5yylhsminor.fts5yy24, fts5yymsp[-2].minor.fts5yy11);
236438 }
236439 #line 1159 "fts5parse.sql"
236440 fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
236441 break;
236442 case 17: /* nearset ::= phrase */
236443 #line 151 "fts5parse.y"
236444 { fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); }
236445 #line 1165 "fts5parse.sql"
236446 fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
236447 break;
236448 case 18: /* nearset ::= CARET phrase */
236449 #line 152 "fts5parse.y"
236450 {
236451 sqlite3Fts5ParseSetCaret(fts5yymsp[0].minor.fts5yy53);
236452 fts5yymsp[-1].minor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53);
236453 }
236454 #line 1174 "fts5parse.sql"
236455 break;
236456 case 19: /* nearset ::= STRING LP nearphrases neardist_opt RP */
236457 #line 156 "fts5parse.y"
236458 {
236459 sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0);
236460 sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy46, &fts5yymsp[-1].minor.fts5yy0);
236461 fts5yylhsminor.fts5yy46 = fts5yymsp[-2].minor.fts5yy46;
236462 }
236463 #line 1183 "fts5parse.sql"
236464 fts5yymsp[-4].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
236465 break;
236466 case 20: /* nearphrases ::= phrase */
236467 #line 162 "fts5parse.y"
236468 {
236469 fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53);
236470 }
236471 #line 1191 "fts5parse.sql"
236472 fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
236473 break;
236474 case 21: /* nearphrases ::= nearphrases phrase */
236475 #line 165 "fts5parse.y"
236476 {
236477 fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy46, fts5yymsp[0].minor.fts5yy53);
236478 }
236479 #line 1199 "fts5parse.sql"
236480 fts5yymsp[-1].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
236481 break;
236482 case 22: /* neardist_opt ::= */
236483 #line 172 "fts5parse.y"
236484 { fts5yymsp[1].minor.fts5yy0.p = 0; fts5yymsp[1].minor.fts5yy0.n = 0; }
236485 #line 1205 "fts5parse.sql"
236486 break;
236487 case 23: /* neardist_opt ::= COMMA STRING */
236488 #line 173 "fts5parse.y"
236489 { fts5yymsp[-1].minor.fts5yy0 = fts5yymsp[0].minor.fts5yy0; }
236490 #line 1210 "fts5parse.sql"
236491 break;
236492 case 24: /* phrase ::= phrase PLUS STRING star_opt */
236493 #line 185 "fts5parse.y"
236494 {
236495 fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy53, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
236496 }
236497 #line 1217 "fts5parse.sql"
236498 fts5yymsp[-3].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
236499 break;
236500 case 25: /* phrase ::= STRING star_opt */
236501 #line 188 "fts5parse.y"
236502 {
236503 fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
236504 }
236505 #line 1225 "fts5parse.sql"
236506 fts5yymsp[-1].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
236507 break;
236508 case 26: /* star_opt ::= STAR */
236509 #line 196 "fts5parse.y"
236510 { fts5yymsp[0].minor.fts5yy4 = 1; }
236511 #line 1231 "fts5parse.sql"
236512 break;
236513 case 27: /* star_opt ::= */
236514 #line 197 "fts5parse.y"
236515 { fts5yymsp[1].minor.fts5yy4 = 0; }
236516 #line 1236 "fts5parse.sql"
236517 break;
236518 default:
236519 break;
236520 /********** End reduce actions ************************************************/
236521 };
@@ -236573,17 +235921,15 @@
236573 ){
236574 sqlite3Fts5ParserARG_FETCH
236575 sqlite3Fts5ParserCTX_FETCH
236576 #define FTS5TOKEN fts5yyminor
236577 /************ Begin %syntax_error code ****************************************/
236578 #line 30 "fts5parse.y"
236579
236580 UNUSED_PARAM(fts5yymajor); /* Silence a compiler warning */
236581 sqlite3Fts5ParseError(
236582 pParse, "fts5: syntax error near \"%.*s\"",FTS5TOKEN.n,FTS5TOKEN.p
236583 );
236584 #line 1304 "fts5parse.sql"
236585 /************ End %syntax_error code ******************************************/
236586 sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
236587 sqlite3Fts5ParserCTX_STORE
236588 }
236589
@@ -236849,11 +236195,10 @@
236849 (void)iToken;
236850 return 0;
236851 #endif
236852 }
236853
236854 #line 1 "fts5_aux.c"
236855 /*
236856 ** 2014 May 31
236857 **
236858 ** The author disclaims copyright to this source code. In place of
236859 ** a legal notice, here is a blessing:
@@ -237672,11 +237017,10 @@
237672 }
237673
237674 return rc;
237675 }
237676
237677 #line 1 "fts5_buffer.c"
237678 /*
237679 ** 2014 May 31
237680 **
237681 ** The author disclaims copyright to this source code. In place of
237682 ** a legal notice, here is a blessing:
@@ -238085,11 +237429,10 @@
238085 }
238086 sqlite3_free(p);
238087 }
238088 }
238089
238090 #line 1 "fts5_config.c"
238091 /*
238092 ** 2014 Jun 09
238093 **
238094 ** The author disclaims copyright to this source code. In place of
238095 ** a legal notice, here is a blessing:
@@ -239114,10 +238457,23 @@
239114 if( bVal<0 ){
239115 *pbBadkey = 1;
239116 }else{
239117 pConfig->bSecureDelete = (bVal ? 1 : 0);
239118 }
 
 
 
 
 
 
 
 
 
 
 
 
 
239119 }else{
239120 *pbBadkey = 1;
239121 }
239122 return rc;
239123 }
@@ -239201,11 +238557,10 @@
239201 va_end(ap);
239202 }
239203
239204
239205
239206 #line 1 "fts5_expr.c"
239207 /*
239208 ** 2014 May 31
239209 **
239210 ** The author disclaims copyright to this source code. In place of
239211 ** a legal notice, here is a blessing:
@@ -242250,11 +241605,11 @@
242250 && memcmp(pT->pTerm, pToken, pT->nQueryTerm)==0
242251 ){
242252 int rc = sqlite3Fts5PoslistWriterAppend(
242253 &pExpr->apExprPhrase[i]->poslist, &p->aPopulator[i].writer, p->iOff
242254 );
242255 if( rc==SQLITE_OK && pExpr->pConfig->bTokendata && !pT->bPrefix ){
242256 int iCol = p->iOff>>32;
242257 int iTokOff = p->iOff & 0x7FFFFFFF;
242258 rc = sqlite3Fts5IndexIterWriteTokendata(
242259 pT->pIter, pToken, nToken, iRowid, iCol, iTokOff
242260 );
@@ -242443,19 +241798,18 @@
242443 pPhrase = pExpr->apExprPhrase[iPhrase];
242444 if( iToken<0 || iToken>=pPhrase->nTerm ){
242445 return SQLITE_RANGE;
242446 }
242447 pTerm = &pPhrase->aTerm[iToken];
242448 if( pTerm->bPrefix==0 ){
242449 if( pExpr->pConfig->bTokendata ){
242450 rc = sqlite3Fts5IterToken(
242451 pTerm->pIter, iRowid, iCol, iOff+iToken, ppOut, pnOut
242452 );
242453 }else{
242454 *ppOut = pTerm->pTerm;
242455 *pnOut = pTerm->nFullTerm;
242456 }
242457 }
242458 return rc;
242459 }
242460
242461 /*
@@ -242470,11 +241824,10 @@
242470 sqlite3Fts5IndexIterClearTokendata(pT->pIter);
242471 }
242472 }
242473 }
242474
242475 #line 1 "fts5_hash.c"
242476 /*
242477 ** 2014 August 11
242478 **
242479 ** The author disclaims copyright to this source code. In place of
242480 ** a legal notice, here is a blessing:
@@ -243062,11 +242415,10 @@
243062 *ppDoclist = 0;
243063 *pnDoclist = 0;
243064 }
243065 }
243066
243067 #line 1 "fts5_index.c"
243068 /*
243069 ** 2014 May 31
243070 **
243071 ** The author disclaims copyright to this source code. In place of
243072 ** a legal notice, here is a blessing:
@@ -249268,10 +248620,387 @@
249268 fts5BufferFree(&tmp);
249269 memset(&out.p[out.n], 0, FTS5_DATA_ZERO_PADDING);
249270 *p1 = out;
249271 }
249272
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249273 static void fts5SetupPrefixIter(
249274 Fts5Index *p, /* Index to read from */
249275 int bDesc, /* True for "ORDER BY rowid DESC" */
249276 int iIdx, /* Index to scan for data */
249277 u8 *pToken, /* Buffer containing prefix to match */
@@ -249278,137 +249007,89 @@
249278 int nToken, /* Size of buffer pToken in bytes */
249279 Fts5Colset *pColset, /* Restrict matches to these columns */
249280 Fts5Iter **ppIter /* OUT: New iterator */
249281 ){
249282 Fts5Structure *pStruct;
249283 Fts5Buffer *aBuf;
249284 int nBuf = 32;
249285 int nMerge = 1;
249286
249287 void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*);
249288 void (*xAppend)(Fts5Index*, u64, Fts5Iter*, Fts5Buffer*);
 
 
 
 
 
 
 
 
 
 
 
 
249289 if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
249290 xMerge = fts5MergeRowidLists;
249291 xAppend = fts5AppendRowid;
249292 }else{
249293 nMerge = FTS5_MERGE_NLIST-1;
249294 nBuf = nMerge*8; /* Sufficient to merge (16^8)==(2^32) lists */
249295 xMerge = fts5MergePrefixLists;
249296 xAppend = fts5AppendPoslist;
249297 }
249298
249299 aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf);
249300 pStruct = fts5StructureRead(p);
249301 assert( p->rc!=SQLITE_OK || (aBuf && pStruct) );
249302
249303 if( p->rc==SQLITE_OK ){
249304 const int flags = FTS5INDEX_QUERY_SCAN
249305 | FTS5INDEX_QUERY_SKIPEMPTY
249306 | FTS5INDEX_QUERY_NOOUTPUT;
249307 int i;
249308 i64 iLastRowid = 0;
249309 Fts5Iter *p1 = 0; /* Iterator used to gather data from index */
249310 Fts5Data *pData;
249311 Fts5Buffer doclist;
249312 int bNewTerm = 1;
249313
249314 memset(&doclist, 0, sizeof(doclist));
249315
249316 /* If iIdx is non-zero, then it is the number of a prefix-index for
249317 ** prefixes 1 character longer than the prefix being queried for. That
249318 ** index contains all the doclists required, except for the one
249319 ** corresponding to the prefix itself. That one is extracted from the
249320 ** main term index here. */
249321 if( iIdx!=0 ){
249322 int dummy = 0;
249323 const int f2 = FTS5INDEX_QUERY_SKIPEMPTY|FTS5INDEX_QUERY_NOOUTPUT;
249324 pToken[0] = FTS5_MAIN_PREFIX;
249325 fts5MultiIterNew(p, pStruct, f2, pColset, pToken, nToken, -1, 0, &p1);
249326 fts5IterSetOutputCb(&p->rc, p1);
249327 for(;
249328 fts5MultiIterEof(p, p1)==0;
249329 fts5MultiIterNext2(p, p1, &dummy)
249330 ){
249331 Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ];
249332 p1->xSetOutputs(p1, pSeg);
249333 if( p1->base.nData ){
249334 xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist);
249335 iLastRowid = p1->base.iRowid;
249336 }
249337 }
249338 fts5MultiIterFree(p1);
249339 }
249340
249341 pToken[0] = FTS5_MAIN_PREFIX + iIdx;
249342 fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1);
249343 fts5IterSetOutputCb(&p->rc, p1);
249344
249345 for( /* no-op */ ;
249346 fts5MultiIterEof(p, p1)==0;
249347 fts5MultiIterNext2(p, p1, &bNewTerm)
249348 ){
249349 Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ];
249350 int nTerm = pSeg->term.n;
249351 const u8 *pTerm = pSeg->term.p;
249352 p1->xSetOutputs(p1, pSeg);
249353
249354 assert_nc( memcmp(pToken, pTerm, MIN(nToken, nTerm))<=0 );
249355 if( bNewTerm ){
249356 if( nTerm<nToken || memcmp(pToken, pTerm, nToken) ) break;
249357 }
249358
249359 if( p1->base.nData==0 ) continue;
249360 if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){
249361 for(i=0; p->rc==SQLITE_OK && doclist.n; i++){
249362 int i1 = i*nMerge;
249363 int iStore;
249364 assert( i1+nMerge<=nBuf );
249365 for(iStore=i1; iStore<i1+nMerge; iStore++){
249366 if( aBuf[iStore].n==0 ){
249367 fts5BufferSwap(&doclist, &aBuf[iStore]);
249368 fts5BufferZero(&doclist);
249369 break;
249370 }
249371 }
249372 if( iStore==i1+nMerge ){
249373 xMerge(p, &doclist, nMerge, &aBuf[i1]);
249374 for(iStore=i1; iStore<i1+nMerge; iStore++){
249375 fts5BufferZero(&aBuf[iStore]);
249376 }
249377 }
249378 }
249379 iLastRowid = 0;
249380 }
249381
249382 xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist);
249383 iLastRowid = p1->base.iRowid;
249384 }
249385
249386 assert( (nBuf%nMerge)==0 );
249387 for(i=0; i<nBuf; i+=nMerge){
249388 int iFree;
249389 if( p->rc==SQLITE_OK ){
249390 xMerge(p, &doclist, nMerge, &aBuf[i]);
249391 }
249392 for(iFree=i; iFree<i+nMerge; iFree++){
249393 fts5BufferFree(&aBuf[iFree]);
249394 }
249395 }
249396 fts5MultiIterFree(p1);
249397
249398 pData = fts5IdxMalloc(p, sizeof(*pData)+doclist.n+FTS5_DATA_ZERO_PADDING);
249399 if( pData ){
249400 pData->p = (u8*)&pData[1];
249401 pData->nn = pData->szLeaf = doclist.n;
249402 if( doclist.n ) memcpy(pData->p, doclist.p, doclist.n);
249403 fts5MultiIterNew2(p, pData, bDesc, ppIter);
249404 }
249405 fts5BufferFree(&doclist);
 
 
 
 
 
249406 }
249407
 
 
249408 fts5StructureRelease(pStruct);
249409 sqlite3_free(aBuf);
249410 }
249411
249412
249413 /*
249414 ** Indicate that all subsequent calls to sqlite3Fts5IndexWrite() pertain
@@ -249658,42 +249339,10 @@
249658 static void fts5SegIterSetEOF(Fts5SegIter *pSeg){
249659 fts5DataRelease(pSeg->pLeaf);
249660 pSeg->pLeaf = 0;
249661 }
249662
249663 /*
249664 ** Usually, a tokendata=1 iterator (struct Fts5TokenDataIter) accumulates an
249665 ** array of these for each row it visits. Or, for an iterator used by an
249666 ** "ORDER BY rank" query, it accumulates an array of these for the entire
249667 ** query.
249668 **
249669 ** Each instance in the array indicates the iterator (and therefore term)
249670 ** associated with position iPos of rowid iRowid. This is used by the
249671 ** xInstToken() API.
249672 */
249673 struct Fts5TokenDataMap {
249674 i64 iRowid; /* Row this token is located in */
249675 i64 iPos; /* Position of token */
249676 int iIter; /* Iterator token was read from */
249677 };
249678
249679 /*
249680 ** An object used to supplement Fts5Iter for tokendata=1 iterators.
249681 */
249682 struct Fts5TokenDataIter {
249683 int nIter;
249684 int nIterAlloc;
249685
249686 int nMap;
249687 int nMapAlloc;
249688 Fts5TokenDataMap *aMap;
249689
249690 Fts5PoslistReader *aPoslistReader;
249691 int *aPoslistToIter;
249692 Fts5Iter *apIter[1];
249693 };
249694
249695 /*
249696 ** This function appends iterator pAppend to Fts5TokenDataIter pIn and
249697 ** returns the result.
249698 */
249699 static Fts5TokenDataIter *fts5AppendTokendataIter(
@@ -249726,58 +249375,10 @@
249726 assert( pRet==0 || pRet->nIter<=pRet->nIterAlloc );
249727
249728 return pRet;
249729 }
249730
249731 /*
249732 ** Delete an Fts5TokenDataIter structure and its contents.
249733 */
249734 static void fts5TokendataIterDelete(Fts5TokenDataIter *pSet){
249735 if( pSet ){
249736 int ii;
249737 for(ii=0; ii<pSet->nIter; ii++){
249738 fts5MultiIterFree(pSet->apIter[ii]);
249739 }
249740 sqlite3_free(pSet->aPoslistReader);
249741 sqlite3_free(pSet->aMap);
249742 sqlite3_free(pSet);
249743 }
249744 }
249745
249746 /*
249747 ** Append a mapping to the token-map belonging to object pT.
249748 */
249749 static void fts5TokendataIterAppendMap(
249750 Fts5Index *p,
249751 Fts5TokenDataIter *pT,
249752 int iIter,
249753 i64 iRowid,
249754 i64 iPos
249755 ){
249756 if( p->rc==SQLITE_OK ){
249757 if( pT->nMap==pT->nMapAlloc ){
249758 int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64;
249759 int nByte = nNew * sizeof(Fts5TokenDataMap);
249760 Fts5TokenDataMap *aNew;
249761
249762 aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nByte);
249763 if( aNew==0 ){
249764 p->rc = SQLITE_NOMEM;
249765 return;
249766 }
249767
249768 pT->aMap = aNew;
249769 pT->nMapAlloc = nNew;
249770 }
249771
249772 pT->aMap[pT->nMap].iRowid = iRowid;
249773 pT->aMap[pT->nMap].iPos = iPos;
249774 pT->aMap[pT->nMap].iIter = iIter;
249775 pT->nMap++;
249776 }
249777 }
249778
249779 /*
249780 ** The iterator passed as the only argument must be a tokendata=1 iterator
249781 ** (pIter->pTokenDataIter!=0). This function sets the iterator output
249782 ** variables (pIter->base.*) according to the contents of the current
249783 ** row.
@@ -249814,11 +249415,11 @@
249814 int eDetail = pIter->pIndex->pConfig->eDetail;
249815 pIter->base.bEof = 0;
249816 pIter->base.iRowid = iRowid;
249817
249818 if( nHit==1 && eDetail==FTS5_DETAIL_FULL ){
249819 fts5TokendataIterAppendMap(pIter->pIndex, pT, iMin, iRowid, -1);
249820 }else
249821 if( nHit>1 && eDetail!=FTS5_DETAIL_NONE ){
249822 int nReader = 0;
249823 int nByte = 0;
249824 i64 iPrev = 0;
@@ -250067,10 +249668,11 @@
250067
250068 if( p->rc==SQLITE_OK ){
250069 pRet = fts5MultiIterAlloc(p, 0);
250070 }
250071 if( pRet ){
 
250072 pRet->pTokenDataIter = pSet;
250073 if( pSet ){
250074 fts5IterSetOutputsTokendata(pRet);
250075 }else{
250076 pRet->base.bEof = 1;
@@ -250081,11 +249683,10 @@
250081
250082 fts5StructureRelease(pStruct);
250083 fts5BufferFree(&bSeek);
250084 return pRet;
250085 }
250086
250087
250088 /*
250089 ** Open a new iterator to iterate though all rowid that match the
250090 ** specified token or token prefix.
250091 */
@@ -250107,10 +249708,15 @@
250107 int iIdx = 0; /* Index to search */
250108 int iPrefixIdx = 0; /* +1 prefix index */
250109 int bTokendata = pConfig->bTokendata;
250110 if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken);
250111
 
 
 
 
 
250112 if( flags & (FTS5INDEX_QUERY_NOTOKENDATA|FTS5INDEX_QUERY_SCAN) ){
250113 bTokendata = 0;
250114 }
250115
250116 /* Figure out which index to search and set iIdx accordingly. If this
@@ -250137,11 +249743,11 @@
250137 if( nIdxChar==nChar+1 ) iPrefixIdx = iIdx;
250138 }
250139 }
250140
250141 if( bTokendata && iIdx==0 ){
250142 buf.p[0] = '0';
250143 pRet = fts5SetupTokendataIter(p, buf.p, nToken+1, pColset);
250144 }else if( iIdx<=pConfig->nPrefix ){
250145 /* Straight index lookup */
250146 Fts5Structure *pStruct = fts5StructureRead(p);
250147 buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx);
@@ -250150,11 +249756,11 @@
250150 pColset, buf.p, nToken+1, -1, 0, &pRet
250151 );
250152 fts5StructureRelease(pStruct);
250153 }
250154 }else{
250155 /* Scan multiple terms in the main index */
250156 int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0;
250157 fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet);
250158 if( pRet==0 ){
250159 assert( p->rc!=SQLITE_OK );
250160 }else{
@@ -250186,11 +249792,12 @@
250186 ** Move to the next matching rowid.
250187 */
250188 static int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){
250189 Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
250190 assert( pIter->pIndex->rc==SQLITE_OK );
250191 if( pIter->pTokenDataIter ){
 
250192 fts5TokendataIterNext(pIter, 0, 0);
250193 }else{
250194 fts5MultiIterNext(pIter->pIndex, pIter, 0, 0);
250195 }
250196 return fts5IndexReturn(pIter->pIndex);
@@ -250223,11 +249830,12 @@
250223 ** definition of "at or after" depends on whether this iterator iterates
250224 ** in ascending or descending rowid order.
250225 */
250226 static int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){
250227 Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
250228 if( pIter->pTokenDataIter ){
 
250229 fts5TokendataIterNext(pIter, 1, iMatch);
250230 }else{
250231 fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch);
250232 }
250233 return fts5IndexReturn(pIter->pIndex);
@@ -250241,32 +249849,87 @@
250241 const char *z = (const char*)fts5MultiIterTerm((Fts5Iter*)pIndexIter, &n);
250242 assert_nc( z || n<=1 );
250243 *pn = n-1;
250244 return (z ? &z[1] : 0);
250245 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250246
250247 /*
250248 ** This is used by xInstToken() to access the token at offset iOff, column
250249 ** iCol of row iRowid. The token is returned via output variables *ppOut
250250 ** and *pnOut. The iterator passed as the first argument must be a tokendata=1
250251 ** iterator (pIter->pTokenDataIter!=0).
 
 
250252 */
250253 static int sqlite3Fts5IterToken(
250254 Fts5IndexIter *pIndexIter,
 
250255 i64 iRowid,
250256 int iCol,
250257 int iOff,
250258 const char **ppOut, int *pnOut
250259 ){
250260 Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
250261 Fts5TokenDataIter *pT = pIter->pTokenDataIter;
250262 Fts5TokenDataMap *aMap = pT->aMap;
250263 i64 iPos = (((i64)iCol)<<32) + iOff;
250264
250265 int i1 = 0;
250266 int i2 = pT->nMap;
250267 int iTest = 0;
 
 
 
 
 
 
 
 
 
 
250268
250269 while( i2>i1 ){
250270 iTest = (i1 + i2) / 2;
250271
250272 if( aMap[iTest].iRowid<iRowid ){
@@ -250286,13 +249949,19 @@
250286 }
250287 }
250288 }
250289
250290 if( i2>i1 ){
250291 Fts5Iter *pMap = pT->apIter[aMap[iTest].iIter];
250292 *ppOut = (const char*)pMap->aSeg[0].term.p+1;
250293 *pnOut = pMap->aSeg[0].term.n-1;
 
 
 
 
 
 
250294 }
250295
250296 return SQLITE_OK;
250297 }
250298
@@ -250300,11 +249969,13 @@
250300 ** Clear any existing entries from the token-map associated with the
250301 ** iterator passed as the only argument.
250302 */
250303 static void sqlite3Fts5IndexIterClearTokendata(Fts5IndexIter *pIndexIter){
250304 Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
250305 if( pIter && pIter->pTokenDataIter ){
 
 
250306 pIter->pTokenDataIter->nMap = 0;
250307 }
250308 }
250309
250310 /*
@@ -250320,21 +249991,33 @@
250320 i64 iRowid, int iCol, int iOff
250321 ){
250322 Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
250323 Fts5TokenDataIter *pT = pIter->pTokenDataIter;
250324 Fts5Index *p = pIter->pIndex;
250325 int ii;
250326
250327 assert( p->pConfig->eDetail!=FTS5_DETAIL_FULL );
250328 assert( pIter->pTokenDataIter );
250329
250330 for(ii=0; ii<pT->nIter; ii++){
250331 Fts5Buffer *pTerm = &pT->apIter[ii]->aSeg[0].term;
250332 if( nToken==pTerm->n-1 && memcmp(pToken, pTerm->p+1, nToken)==0 ) break;
250333 }
250334 if( ii<pT->nIter ){
250335 fts5TokendataIterAppendMap(p, pT, ii, iRowid, (((i64)iCol)<<32) + iOff);
 
 
 
 
 
 
 
 
 
 
 
 
250336 }
250337 return fts5IndexReturn(p);
250338 }
250339
250340 /*
@@ -252140,11 +251823,10 @@
252140 fts5StructureInvalidate(p);
252141 }
252142 return fts5IndexReturn(p);
252143 }
252144
252145 #line 1 "fts5_main.c"
252146 /*
252147 ** 2014 Jun 09
252148 **
252149 ** The author disclaims copyright to this source code. In place of
252150 ** a legal notice, here is a blessing:
@@ -252236,10 +251918,11 @@
252236 ** containing a copy of the header from an Fts5Config pointer.
252237 */
252238 #define FTS5_LOCALE_HDR_SIZE ((int)sizeof( ((Fts5Global*)0)->aLocaleHdr ))
252239 #define FTS5_LOCALE_HDR(pConfig) ((const u8*)(pConfig->pGlobal->aLocaleHdr))
252240
 
252241
252242 /*
252243 ** Each auxiliary function registered with the FTS5 module is represented
252244 ** by an object of the following type. All such objects are stored as part
252245 ** of the Fts5Global.pAux list.
@@ -252775,10 +252458,11 @@
252775 ){
252776 /* A MATCH operator or equivalent */
252777 if( p->usable==0 || iCol<0 ){
252778 /* As there exists an unusable MATCH constraint this is an
252779 ** unusable plan. Return SQLITE_CONSTRAINT. */
 
252780 return SQLITE_CONSTRAINT;
252781 }else{
252782 if( iCol==nCol+1 ){
252783 if( bSeenRank ) continue;
252784 idxStr[iIdxStr++] = 'r';
@@ -253560,10 +253244,11 @@
253560 sqlite3_value *pRowidEq = 0; /* rowid = ? expression (or NULL) */
253561 sqlite3_value *pRowidLe = 0; /* rowid <= ? expression (or NULL) */
253562 sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */
253563 int iCol; /* Column on LHS of MATCH operator */
253564 char **pzErrmsg = pConfig->pzErrmsg;
 
253565 int i;
253566 int iIdxStr = 0;
253567 Fts5Expr *pExpr = 0;
253568
253569 assert( pConfig->bLock==0 );
@@ -253595,10 +253280,13 @@
253595 int bInternal = 0;
253596
253597 rc = fts5ExtractExprText(pConfig, apVal[i], &zText, &bFreeAndReset);
253598 if( rc!=SQLITE_OK ) goto filter_out;
253599 if( zText==0 ) zText = "";
 
 
 
253600
253601 iCol = 0;
253602 do{
253603 iCol = iCol*10 + (idxStr[iIdxStr]-'0');
253604 iIdxStr++;
@@ -253735,10 +253423,11 @@
253735 }
253736
253737 filter_out:
253738 sqlite3Fts5ExprFree(pExpr);
253739 pConfig->pzErrmsg = pzErrmsg;
 
253740 return rc;
253741 }
253742
253743 /*
253744 ** This is the xEof method of the virtual table. SQLite calls this
@@ -255730,11 +255419,11 @@
255730 int nArg, /* Number of args */
255731 sqlite3_value **apUnused /* Function arguments */
255732 ){
255733 assert( nArg==0 );
255734 UNUSED_PARAM2(nArg, apUnused);
255735 sqlite3_result_text(pCtx, "fts5: 2024-11-06 12:58:31 5495b12569c318d5020b4b5a625a392ef8e777b81c0200624fbbc2a6b5eddef9", -1, SQLITE_TRANSIENT);
255736 }
255737
255738 /*
255739 ** Implementation of fts5_locale(LOCALE, TEXT) function.
255740 **
@@ -255793,10 +255482,24 @@
255793 assert( &pCsr[nText]==&pBlob[nBlob] );
255794
255795 sqlite3_result_blob(pCtx, pBlob, nBlob, sqlite3_free);
255796 }
255797 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255798
255799 /*
255800 ** Return true if zName is the extension on one of the shadow tables used
255801 ** by this module.
255802 */
@@ -255923,13 +255626,20 @@
255923 );
255924 }
255925 if( rc==SQLITE_OK ){
255926 rc = sqlite3_create_function(
255927 db, "fts5_locale", 2,
255928 SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE,
255929 p, fts5LocaleFunc, 0, 0
255930 );
 
 
 
 
 
 
 
255931 }
255932 }
255933
255934 /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file
255935 ** fts5_test_mi.c is compiled and linked into the executable. And call
@@ -255983,11 +255693,10 @@
255983 SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3 *db){
255984 return fts5Init(db);
255985 }
255986 #endif
255987
255988 #line 1 "fts5_storage.c"
255989 /*
255990 ** 2014 May 31
255991 **
255992 ** The author disclaims copyright to this source code. In place of
255993 ** a legal notice, here is a blessing:
@@ -257497,11 +257206,10 @@
257497 }
257498 }
257499 return rc;
257500 }
257501
257502 #line 1 "fts5_tokenize.c"
257503 /*
257504 ** 2014 May 31
257505 **
257506 ** The author disclaims copyright to this source code. In place of
257507 ** a legal notice, here is a blessing:
@@ -258853,22 +258561,22 @@
258853 int rc = SQLITE_OK;
258854 char aBuf[32];
258855 char *zOut = aBuf;
258856 int ii;
258857 const unsigned char *zIn = (const unsigned char*)pText;
258858 const unsigned char *zEof = &zIn[nText];
258859 u32 iCode;
258860 int aStart[3]; /* Input offset of each character in aBuf[] */
258861
258862 UNUSED_PARAM(unusedFlags);
258863
258864 /* Populate aBuf[] with the characters for the first trigram. */
258865 for(ii=0; ii<3; ii++){
258866 do {
258867 aStart[ii] = zIn - (const unsigned char*)pText;
 
258868 READ_UTF8(zIn, zEof, iCode);
258869 if( iCode==0 ) return SQLITE_OK;
258870 if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam);
258871 }while( iCode==0 );
258872 WRITE_UTF8(zOut, iCode);
258873 }
258874
@@ -258885,12 +258593,15 @@
258885 const char *z1;
258886
258887 /* Read characters from the input up until the first non-diacritic */
258888 do {
258889 iNext = zIn - (const unsigned char*)pText;
 
 
 
 
258890 READ_UTF8(zIn, zEof, iCode);
258891 if( iCode==0 ) break;
258892 if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam);
258893 }while( iCode==0 );
258894
258895 /* Pass the current trigram back to fts5 */
258896 rc = xToken(pCtx, 0, aBuf, zOut-aBuf, aStart[0], iNext);
@@ -258986,11 +258697,10 @@
258986 );
258987 }
258988 return rc;
258989 }
258990
258991 #line 1 "fts5_unicode2.c"
258992 /*
258993 ** 2012-05-25
258994 **
258995 ** The author disclaims copyright to this source code. In place of
258996 ** a legal notice, here is a blessing:
@@ -259769,11 +259479,10 @@
259769 }
259770 aAscii[0] = 0; /* 0x00 is never a token character */
259771 }
259772
259773
259774 #line 1 "fts5_varint.c"
259775 /*
259776 ** 2015 May 30
259777 **
259778 ** The author disclaims copyright to this source code. In place of
259779 ** a legal notice, here is a blessing:
@@ -260115,11 +259824,10 @@
260115 if( iVal<(1 << 21) ) return 3;
260116 if( iVal<(1 << 28) ) return 4;
260117 return 5;
260118 }
260119
260120 #line 1 "fts5_vocab.c"
260121 /*
260122 ** 2015 May 08
260123 **
260124 ** The author disclaims copyright to this source code. In place of
260125 ** a legal notice, here is a blessing:
@@ -260931,11 +260639,10 @@
260931 /* Here ends the fts5.c composite file. */
260932 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */
260933
260934 /************** End of fts5.c ************************************************/
260935 /************** Begin file stmt.c ********************************************/
260936 #line 1 "tsrc/stmt.c"
260937 /*
260938 ** 2017-05-31
260939 **
260940 ** The author disclaims copyright to this source code. In place of
260941 ** a legal notice, here is a blessing:
260942
--- 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 ** e2bae4143afd07de1ae55a6d2606a3b541a5 with changes in files:
22 **
23 **
24 */
25 #ifndef SQLITE_AMALGAMATION
26 #define SQLITE_CORE 1
@@ -27,11 +27,10 @@
27 #define SQLITE_AMALGAMATION 1
28 #ifndef SQLITE_PRIVATE
29 # define SQLITE_PRIVATE static
30 #endif
31 /************** Begin file sqliteInt.h ***************************************/
 
32 /*
33 ** 2001 September 15
34 **
35 ** The author disclaims copyright to this source code. In place of
36 ** a legal notice, here is a blessing:
@@ -88,11 +87,10 @@
87 ** compiler warnings due to subsequent content in this file and other files
88 ** that are included by this file.
89 */
90 /************** Include msvc.h in the middle of sqliteInt.h ******************/
91 /************** Begin file msvc.h ********************************************/
 
92 /*
93 ** 2015 January 12
94 **
95 ** The author disclaims copyright to this source code. In place of
96 ** a legal notice, here is a blessing:
@@ -137,18 +135,16 @@
135
136 #endif /* SQLITE_MSVC_H */
137
138 /************** End of msvc.h ************************************************/
139 /************** Continuing where we left off in sqliteInt.h ******************/
 
140
141 /*
142 ** Special setup for VxWorks
143 */
144 /************** Include vxworks.h in the middle of sqliteInt.h ***************/
145 /************** Begin file vxworks.h *****************************************/
 
146 /*
147 ** 2015-03-02
148 **
149 ** The author disclaims copyright to this source code. In place of
150 ** a legal notice, here is a blessing:
@@ -180,11 +176,10 @@
176 #define HAVE_LSTAT 1
177 #endif /* defined(_WRS_KERNEL) */
178
179 /************** End of vxworks.h *********************************************/
180 /************** Continuing where we left off in sqliteInt.h ******************/
 
181
182 /*
183 ** These #defines should enable >2GB file support on POSIX if the
184 ** underlying operating system supports it. If the OS lacks
185 ** large file support, or if the OS is windows, these should be no-ops.
@@ -320,11 +315,10 @@
315 ** first in QNX. Also, the _USE_32BIT_TIME_T macro must appear first for
316 ** MinGW.
317 */
318 /************** Include sqlite3.h in the middle of sqliteInt.h ***************/
319 /************** Begin file sqlite3.h *****************************************/
 
320 /*
321 ** 2001-09-15
322 **
323 ** The author disclaims copyright to this source code. In place of
324 ** a legal notice, here is a blessing:
@@ -471,11 +465,11 @@
465 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
466 ** [sqlite_version()] and [sqlite_source_id()].
467 */
468 #define SQLITE_VERSION "3.48.0"
469 #define SQLITE_VERSION_NUMBER 3048000
470 #define SQLITE_SOURCE_ID "2024-12-09 20:46:36 e2bae4143afd07de1ae55a6d2606a3b541a5b94568aa41f6a96e5d1245471653"
471
472 /*
473 ** CAPI3REF: Run-Time Library Version Numbers
474 ** KEYWORDS: sqlite3_version sqlite3_sourceid
475 **
@@ -1423,10 +1417,15 @@
1417 ** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
1418 ** opcode causes the xFileControl method to swap the file handle with the one
1419 ** pointed to by the pArg argument. This capability is used during testing
1420 ** and only needs to be supported when SQLITE_TEST is defined.
1421 **
1422 ** <li>[[SQLITE_FCNTL_NULL_IO]]
1423 ** The [SQLITE_FCNTL_NULL_IO] opcode sets the low-level file descriptor
1424 ** or file handle for the [sqlite3_file] object such that it will no longer
1425 ** read or write to the database file.
1426 **
1427 ** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
1428 ** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
1429 ** be advantageous to block on the next WAL lock if the lock is not immediately
1430 ** available. The WAL subsystem issues this signal during rare
1431 ** circumstances in order to fix a problem with priority inversion.
@@ -1576,10 +1575,11 @@
1575 #define SQLITE_FCNTL_RESERVE_BYTES 38
1576 #define SQLITE_FCNTL_CKPT_START 39
1577 #define SQLITE_FCNTL_EXTERNAL_READER 40
1578 #define SQLITE_FCNTL_CKSM_FILE 41
1579 #define SQLITE_FCNTL_RESET_CACHE 42
1580 #define SQLITE_FCNTL_NULL_IO 43
1581
1582 /* deprecated names */
1583 #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
1584 #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
1585 #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -2954,14 +2954,18 @@
2954 **
2955 ** ^These functions return the number of rows modified, inserted or
2956 ** deleted by the most recently completed INSERT, UPDATE or DELETE
2957 ** statement on the database connection specified by the only parameter.
2958 ** The two functions are identical except for the type of the return value
2959 ** and that if the number of rows modified by the most recent INSERT, UPDATE,
2960 ** or DELETE is greater than the maximum value supported by type "int", then
2961 ** the return value of sqlite3_changes() is undefined. ^Executing any other
2962 ** type of SQL statement does not modify the value returned by these functions.
2963 ** For the purposes of this interface, a CREATE TABLE AS SELECT statement
2964 ** does not count as an INSERT, UPDATE or DELETE statement and hence the rows
2965 ** added to the new table by the CREATE TABLE AS SELECT statement are not
2966 ** counted.
2967 **
2968 ** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are
2969 ** considered - auxiliary changes caused by [CREATE TRIGGER | triggers],
2970 ** [foreign key actions] or [REPLACE] constraint resolution are not counted.
2971 **
@@ -4517,15 +4521,26 @@
4521 **
4522 ** [[SQLITE_PREPARE_NO_VTAB]] <dt>SQLITE_PREPARE_NO_VTAB</dt>
4523 ** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler
4524 ** to return an error (error code SQLITE_ERROR) if the statement uses
4525 ** any virtual tables.
4526 **
4527 ** [[SQLITE_PREPARE_DONT_LOG]] <dt>SQLITE_PREPARE_DONT_LOG</dt>
4528 ** <dd>The SQLITE_PREPARE_DONT_LOG flag prevents SQL compiler
4529 ** errors from being sent to the error log defined by
4530 ** [SQLITE_CONFIG_LOG]. This can be used, for example, to do test
4531 ** compiles to see if some SQL syntax is well-formed, without generating
4532 ** messages on the global error log when it is not. If the test compile
4533 ** fails, the sqlite3_prepare_v3() call returns the same error indications
4534 ** with or without this flag; it just omits the call to [sqlite3_log()] that
4535 ** logs the error.
4536 ** </dl>
4537 */
4538 #define SQLITE_PREPARE_PERSISTENT 0x01
4539 #define SQLITE_PREPARE_NORMALIZE 0x02
4540 #define SQLITE_PREPARE_NO_VTAB 0x04
4541 #define SQLITE_PREPARE_DONT_LOG 0x10
4542
4543 /*
4544 ** CAPI3REF: Compiling An SQL Statement
4545 ** KEYWORDS: {SQL statement compiler}
4546 ** METHOD: sqlite3
@@ -13463,17 +13478,32 @@
13478 ** This is used to access token iToken of phrase hit iIdx within the
13479 ** current row. If iIdx is less than zero or greater than or equal to the
13480 ** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise,
13481 ** output variable (*ppToken) is set to point to a buffer containing the
13482 ** matching document token, and (*pnToken) to the size of that buffer in
13483 ** bytes.
 
 
13484 **
13485 ** The output text is not a copy of the document text that was tokenized.
13486 ** It is the output of the tokenizer module. For tokendata=1 tables, this
13487 ** includes any embedded 0x00 and trailing data.
13488 **
13489 ** This API may be slow in some cases if the token identified by parameters
13490 ** iIdx and iToken matched a prefix token in the query. In most cases, the
13491 ** first call to this API for each prefix token in the query is forced
13492 ** to scan the portion of the full-text index that matches the prefix
13493 ** token to collect the extra data required by this API. If the prefix
13494 ** token matches a large number of token instances in the document set,
13495 ** this may be a performance problem.
13496 **
13497 ** If the user knows in advance that a query may use this API for a
13498 ** prefix token, FTS5 may be configured to collect all required data as part
13499 ** of the initial querying of the full-text index, avoiding the second scan
13500 ** entirely. This also causes prefix queries that do not use this API to
13501 ** run more slowly and use more memory. FTS5 may be configured in this way
13502 ** either on a per-table basis using the [FTS5 insttoken | 'insttoken']
13503 ** option, or on a per-query basis using the
13504 ** [fts5_insttoken | fts5_insttoken()] user function.
13505 **
13506 ** This API can be quite slow if used with an FTS5 table created with the
13507 ** "detail=none" or "detail=column" option.
13508 **
13509 ** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale)
@@ -13908,11 +13938,10 @@
13938 /******** End of fts5.h *********/
13939 #endif /* SQLITE3_H */
13940
13941 /************** End of sqlite3.h *********************************************/
13942 /************** Continuing where we left off in sqliteInt.h ******************/
 
13943
13944 /*
13945 ** Reuse the STATIC_LRU for mutex access to sqlite3_temp_directory.
13946 */
13947 #define SQLITE_MUTEX_STATIC_TEMPDIR SQLITE_MUTEX_STATIC_VFS1
@@ -13926,11 +13955,10 @@
13955 #define SQLITECONFIG_H 1
13956 #endif
13957
13958 /************** Include sqliteLimit.h in the middle of sqliteInt.h ***********/
13959 /************** Begin file sqliteLimit.h *************************************/
 
13960 /*
13961 ** 2007 May 7
13962 **
13963 ** The author disclaims copyright to this source code. In place of
13964 ** a legal notice, here is a blessing:
@@ -13952,10 +13980,11 @@
13980 ** to count the size: 2^31-1 or 2147483647.
13981 */
13982 #ifndef SQLITE_MAX_LENGTH
13983 # define SQLITE_MAX_LENGTH 1000000000
13984 #endif
13985 #define SQLITE_MIN_LENGTH 30 /* Minimum value for the length limit */
13986
13987 /*
13988 ** This is the maximum number of
13989 **
13990 ** * Columns in a table
@@ -14140,11 +14169,10 @@
14169 # define SQLITE_MAX_TRIGGER_DEPTH 1000
14170 #endif
14171
14172 /************** End of sqliteLimit.h *****************************************/
14173 /************** Continuing where we left off in sqliteInt.h ******************/
 
14174
14175 /* Disable nuisance warnings on Borland compilers */
14176 #if defined(__BORLANDC__)
14177 #pragma warn -rch /* unreachable code */
14178 #pragma warn -ccc /* Condition is always true or false */
@@ -14558,11 +14586,10 @@
14586 #define likely(X) (X)
14587 #define unlikely(X) (X)
14588
14589 /************** Include hash.h in the middle of sqliteInt.h ******************/
14590 /************** Begin file hash.h ********************************************/
 
14591 /*
14592 ** 2001 September 22
14593 **
14594 ** The author disclaims copyright to this source code. In place of
14595 ** a legal notice, here is a blessing:
@@ -14658,14 +14685,12 @@
14685
14686 #endif /* SQLITE_HASH_H */
14687
14688 /************** End of hash.h ************************************************/
14689 /************** Continuing where we left off in sqliteInt.h ******************/
 
14690 /************** Include parse.h in the middle of sqliteInt.h *****************/
14691 /************** Begin file parse.h *******************************************/
 
14692 #define TK_SEMI 1
14693 #define TK_EXPLAIN 2
14694 #define TK_QUERY 3
14695 #define TK_PLAN 4
14696 #define TK_BEGIN 5
@@ -14850,11 +14875,10 @@
14875 #define TK_SPACE 184
14876 #define TK_ILLEGAL 185
14877
14878 /************** End of parse.h ***********************************************/
14879 /************** Continuing where we left off in sqliteInt.h ******************/
 
14880 #include <stdio.h>
14881 #include <stdlib.h>
14882 #include <string.h>
14883 #include <assert.h>
14884 #include <stddef.h>
@@ -15616,11 +15640,10 @@
15640 ** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque
15641 ** pointer types (i.e. FuncDef) defined above.
15642 */
15643 /************** Include os.h in the middle of sqliteInt.h ********************/
15644 /************** Begin file os.h **********************************************/
 
15645 /*
15646 ** 2001 September 16
15647 **
15648 ** The author disclaims copyright to this source code. In place of
15649 ** a legal notice, here is a blessing:
@@ -15645,11 +15668,10 @@
15668 ** Attempt to automatically detect the operating system and setup the
15669 ** necessary pre-processor macros for it.
15670 */
15671 /************** Include os_setup.h in the middle of os.h *********************/
15672 /************** Begin file os_setup.h ****************************************/
 
15673 /*
15674 ** 2013 November 25
15675 **
15676 ** The author disclaims copyright to this source code. In place of
15677 ** a legal notice, here is a blessing:
@@ -15740,11 +15762,10 @@
15762
15763 #endif /* SQLITE_OS_SETUP_H */
15764
15765 /************** End of os_setup.h ********************************************/
15766 /************** Continuing where we left off in os.h *************************/
 
15767
15768 /* If the SET_FULLSYNC macro is not defined above, then make it
15769 ** a no-op
15770 */
15771 #ifndef SET_FULLSYNC
@@ -15942,14 +15963,12 @@
15963
15964 #endif /* _SQLITE_OS_H_ */
15965
15966 /************** End of os.h **************************************************/
15967 /************** Continuing where we left off in sqliteInt.h ******************/
 
15968 /************** Include pager.h in the middle of sqliteInt.h *****************/
15969 /************** Begin file pager.h *******************************************/
 
15970 /*
15971 ** 2001 September 15
15972 **
15973 ** The author disclaims copyright to this source code. In place of
15974 ** a legal notice, here is a blessing:
@@ -16196,14 +16215,12 @@
16215
16216 #endif /* SQLITE_PAGER_H */
16217
16218 /************** End of pager.h ***********************************************/
16219 /************** Continuing where we left off in sqliteInt.h ******************/
 
16220 /************** Include btree.h in the middle of sqliteInt.h *****************/
16221 /************** Begin file btree.h *******************************************/
 
16222 /*
16223 ** 2001 September 15
16224 **
16225 ** The author disclaims copyright to this source code. In place of
16226 ** a legal notice, here is a blessing:
@@ -16627,14 +16644,12 @@
16644
16645 #endif /* SQLITE_BTREE_H */
16646
16647 /************** End of btree.h ***********************************************/
16648 /************** Continuing where we left off in sqliteInt.h ******************/
 
16649 /************** Include vdbe.h in the middle of sqliteInt.h ******************/
16650 /************** Begin file vdbe.h ********************************************/
 
16651 /*
16652 ** 2001 September 15
16653 **
16654 ** The author disclaims copyright to this source code. In place of
16655 ** a legal notice, here is a blessing:
@@ -16814,11 +16829,10 @@
16829 ** The makefile scans the vdbe.c source file and creates the "opcodes.h"
16830 ** header file that defines a number for each opcode used by the VDBE.
16831 */
16832 /************** Include opcodes.h in the middle of vdbe.h ********************/
16833 /************** Begin file opcodes.h *****************************************/
 
16834 /* Automatically generated. Do not edit */
16835 /* See the tool/mkopcodeh.tcl script for details */
16836 #define OP_Savepoint 0
16837 #define OP_AutoCommit 1
16838 #define OP_Transaction 2
@@ -17056,17 +17070,16 @@
17070 */
17071 #define SQLITE_MX_JUMP_OPCODE 64 /* Maximum JUMP opcode */
17072
17073 /************** End of opcodes.h *********************************************/
17074 /************** Continuing where we left off in vdbe.h ***********************/
 
17075
17076 /*
17077 ** Additional non-public SQLITE_PREPARE_* flags
17078 */
17079 #define SQLITE_PREPARE_SAVESQL 0x80 /* Preserve SQL text */
17080 #define SQLITE_PREPARE_MASK 0x1f /* Mask of public flags */
17081
17082 /*
17083 ** Prototypes for the VDBE interface. See comments on the implementation
17084 ** for a description of what each of these routines does.
17085 */
@@ -17306,14 +17319,12 @@
17319
17320 #endif /* SQLITE_VDBE_H */
17321
17322 /************** End of vdbe.h ************************************************/
17323 /************** Continuing where we left off in sqliteInt.h ******************/
 
17324 /************** Include pcache.h in the middle of sqliteInt.h ****************/
17325 /************** Begin file pcache.h ******************************************/
 
17326 /*
17327 ** 2008 August 05
17328 **
17329 ** The author disclaims copyright to this source code. In place of
17330 ** a legal notice, here is a blessing:
@@ -17503,14 +17514,12 @@
17514
17515 #endif /* _PCACHE_H_ */
17516
17517 /************** End of pcache.h **********************************************/
17518 /************** Continuing where we left off in sqliteInt.h ******************/
 
17519 /************** Include mutex.h in the middle of sqliteInt.h *****************/
17520 /************** Begin file mutex.h *******************************************/
 
17521 /*
17522 ** 2007 August 28
17523 **
17524 ** The author disclaims copyright to this source code. In place of
17525 ** a legal notice, here is a blessing:
@@ -17581,11 +17590,10 @@
17590 SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
17591 #endif /* defined(SQLITE_MUTEX_OMIT) */
17592
17593 /************** End of mutex.h ***********************************************/
17594 /************** Continuing where we left off in sqliteInt.h ******************/
 
17595
17596 /* The SQLITE_EXTRA_DURABLE compile-time option used to set the default
17597 ** synchronous setting to EXTRA. It is no longer supported.
17598 */
17599 #ifdef SQLITE_EXTRA_DURABLE
@@ -21982,11 +21990,10 @@
21990
21991 #endif /* SQLITEINT_H */
21992
21993 /************** End of sqliteInt.h *******************************************/
21994 /************** Begin file os_common.h ***************************************/
 
21995 /*
21996 ** 2004 May 22
21997 **
21998 ** The author disclaims copyright to this source code. In place of
21999 ** a legal notice, here is a blessing:
@@ -22085,11 +22092,10 @@
22092
22093 #endif /* !defined(_OS_COMMON_H_) */
22094
22095 /************** End of os_common.h *******************************************/
22096 /************** Begin file ctime.c *******************************************/
 
22097 /* DO NOT EDIT!
22098 ** This file is automatically generated by the script in the canonical
22099 ** SQLite source tree at tool/mkctimec.tcl.
22100 **
22101 ** To modify this header, edit any of the various lists in that script
@@ -22885,11 +22891,10 @@
22891
22892 #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
22893
22894 /************** End of ctime.c ***********************************************/
22895 /************** Begin file global.c ******************************************/
 
22896 /*
22897 ** 2008 June 13
22898 **
22899 ** The author disclaims copyright to this source code. In place of
22900 ** a legal notice, here is a blessing:
@@ -23290,11 +23295,10 @@
23295 "TEXT"
23296 };
23297
23298 /************** End of global.c **********************************************/
23299 /************** Begin file status.c ******************************************/
 
23300 /*
23301 ** 2008 June 18
23302 **
23303 ** The author disclaims copyright to this source code. In place of
23304 ** a legal notice, here is a blessing:
@@ -23309,11 +23313,10 @@
23313 ** functionality.
23314 */
23315 /* #include "sqliteInt.h" */
23316 /************** Include vdbeInt.h in the middle of status.c ******************/
23317 /************** Begin file vdbeInt.h *****************************************/
 
23318 /*
23319 ** 2003 September 6
23320 **
23321 ** The author disclaims copyright to this source code. In place of
23322 ** a legal notice, here is a blessing:
@@ -24046,11 +24049,10 @@
24049
24050 #endif /* !defined(SQLITE_VDBEINT_H) */
24051
24052 /************** End of vdbeInt.h *********************************************/
24053 /************** Continuing where we left off in status.c *********************/
 
24054
24055 /*
24056 ** Variables in which to record status information.
24057 */
24058 #if SQLITE_PTRSIZE>4
@@ -24431,11 +24433,10 @@
24433 return rc;
24434 }
24435
24436 /************** End of status.c **********************************************/
24437 /************** Begin file date.c ********************************************/
 
24438 /*
24439 ** 2003 October 31
24440 **
24441 ** The author disclaims copyright to this source code. In place of
24442 ** a legal notice, here is a blessing:
@@ -26250,11 +26251,10 @@
26251 sqlite3InsertBuiltinFuncs(aDateTimeFuncs, ArraySize(aDateTimeFuncs));
26252 }
26253
26254 /************** End of date.c ************************************************/
26255 /************** Begin file os.c **********************************************/
 
26256 /*
26257 ** 2005 November 29
26258 **
26259 ** The author disclaims copyright to this source code. In place of
26260 ** a legal notice, here is a blessing:
@@ -26701,11 +26701,10 @@
26701 return SQLITE_OK;
26702 }
26703
26704 /************** End of os.c **************************************************/
26705 /************** Begin file fault.c *******************************************/
 
26706 /*
26707 ** 2008 Jan 22
26708 **
26709 ** The author disclaims copyright to this source code. In place of
26710 ** a legal notice, here is a blessing:
@@ -26792,11 +26791,10 @@
26791
26792 #endif /* #ifndef SQLITE_UNTESTABLE */
26793
26794 /************** End of fault.c ***********************************************/
26795 /************** Begin file mem0.c ********************************************/
 
26796 /*
26797 ** 2008 October 28
26798 **
26799 ** The author disclaims copyright to this source code. In place of
26800 ** a legal notice, here is a blessing:
@@ -26855,11 +26853,10 @@
26853
26854 #endif /* SQLITE_ZERO_MALLOC */
26855
26856 /************** End of mem0.c ************************************************/
26857 /************** Begin file mem1.c ********************************************/
 
26858 /*
26859 ** 2007 August 14
26860 **
26861 ** The author disclaims copyright to this source code. In place of
26862 ** a legal notice, here is a blessing:
@@ -27150,11 +27147,10 @@
27147
27148 #endif /* SQLITE_SYSTEM_MALLOC */
27149
27150 /************** End of mem1.c ************************************************/
27151 /************** Begin file mem2.c ********************************************/
 
27152 /*
27153 ** 2007 August 15
27154 **
27155 ** The author disclaims copyright to this source code. In place of
27156 ** a legal notice, here is a blessing:
@@ -27682,11 +27678,10 @@
27678
27679 #endif /* SQLITE_MEMDEBUG */
27680
27681 /************** End of mem2.c ************************************************/
27682 /************** Begin file mem3.c ********************************************/
 
27683 /*
27684 ** 2007 October 14
27685 **
27686 ** The author disclaims copyright to this source code. In place of
27687 ** a legal notice, here is a blessing:
@@ -28373,11 +28368,10 @@
28368
28369 #endif /* SQLITE_ENABLE_MEMSYS3 */
28370
28371 /************** End of mem3.c ************************************************/
28372 /************** Begin file mem5.c ********************************************/
 
28373 /*
28374 ** 2007 October 14
28375 **
28376 ** The author disclaims copyright to this source code. In place of
28377 ** a legal notice, here is a blessing:
@@ -28962,11 +28956,10 @@
28956
28957 #endif /* SQLITE_ENABLE_MEMSYS5 */
28958
28959 /************** End of mem5.c ************************************************/
28960 /************** Begin file mutex.c *******************************************/
 
28961 /*
28962 ** 2007 August 14
28963 **
28964 ** The author disclaims copyright to this source code. In place of
28965 ** a legal notice, here is a blessing:
@@ -29340,11 +29333,10 @@
29333
29334 #endif /* !defined(SQLITE_MUTEX_OMIT) */
29335
29336 /************** End of mutex.c ***********************************************/
29337 /************** Begin file mutex_noop.c **************************************/
 
29338 /*
29339 ** 2008 October 07
29340 **
29341 ** The author disclaims copyright to this source code. In place of
29342 ** a legal notice, here is a blessing:
@@ -29559,11 +29551,10 @@
29551 #endif /* defined(SQLITE_MUTEX_NOOP) */
29552 #endif /* !defined(SQLITE_MUTEX_OMIT) */
29553
29554 /************** End of mutex_noop.c ******************************************/
29555 /************** Begin file mutex_unix.c **************************************/
 
29556 /*
29557 ** 2007 August 28
29558 **
29559 ** The author disclaims copyright to this source code. In place of
29560 ** a legal notice, here is a blessing:
@@ -29957,11 +29948,10 @@
29948
29949 #endif /* SQLITE_MUTEX_PTHREADS */
29950
29951 /************** End of mutex_unix.c ******************************************/
29952 /************** Begin file mutex_w32.c ***************************************/
 
29953 /*
29954 ** 2007 August 14
29955 **
29956 ** The author disclaims copyright to this source code. In place of
29957 ** a legal notice, here is a blessing:
@@ -29984,11 +29974,10 @@
29974 /*
29975 ** Include the header file for the Windows VFS.
29976 */
29977 /************** Include os_win.h in the middle of mutex_w32.c ****************/
29978 /************** Begin file os_win.h ******************************************/
 
29979 /*
29980 ** 2013 November 25
29981 **
29982 ** The author disclaims copyright to this source code. In place of
29983 ** a legal notice, here is a blessing:
@@ -30076,11 +30065,10 @@
30065
30066 #endif /* SQLITE_OS_WIN_H */
30067
30068 /************** End of os_win.h **********************************************/
30069 /************** Continuing where we left off in mutex_w32.c ******************/
 
30070 #endif
30071
30072 /*
30073 ** The code in this file is only used if we are compiling multithreaded
30074 ** on a Win32 system.
@@ -30454,11 +30442,10 @@
30442
30443 #endif /* SQLITE_MUTEX_W32 */
30444
30445 /************** End of mutex_w32.c *******************************************/
30446 /************** Begin file malloc.c ******************************************/
 
30447 /*
30448 ** 2001 September 15
30449 **
30450 ** The author disclaims copyright to this source code. In place of
30451 ** a legal notice, here is a blessing:
@@ -31378,11 +31365,10 @@
31365 return 0;
31366 }
31367
31368 /************** End of malloc.c **********************************************/
31369 /************** Begin file printf.c ******************************************/
 
31370 /*
31371 ** The "printf" code that follows dates from the 1980's. It is in
31372 ** the public domain.
31373 **
31374 **************************************************************************
@@ -32319,10 +32305,11 @@
32305 && (ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) || pExpr->w.iOfst<=0)
32306 ){
32307 pExpr = pExpr->pLeft;
32308 }
32309 if( pExpr==0 ) return;
32310 if( ExprHasProperty(pExpr, EP_FromDDL) ) return;
32311 db->errByteOffset = pExpr->w.iOfst;
32312 }
32313
32314 /*
32315 ** Enlarge the memory allocation on a StrAccum object so that it is
@@ -32828,11 +32815,10 @@
32815 }
32816 }
32817
32818 /************** End of printf.c **********************************************/
32819 /************** Begin file treeview.c ****************************************/
 
32820 /*
32821 ** 2015-06-08
32822 **
32823 ** The author disclaims copyright to this source code. In place of
32824 ** a legal notice, here is a blessing:
@@ -33049,11 +33035,11 @@
33035 }
33036 if( pItem->fg.isCte ){
33037 sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse);
33038 }
33039 if( pItem->fg.isOn || (pItem->fg.isUsing==0 && pItem->u3.pOn!=0) ){
33040 sqlite3_str_appendf(&x, " isOn");
33041 }
33042 if( pItem->fg.isTabFunc ) sqlite3_str_appendf(&x, " isTabFunc");
33043 if( pItem->fg.isCorrelated ) sqlite3_str_appendf(&x, " isCorrelated");
33044 if( pItem->fg.isMaterialized ) sqlite3_str_appendf(&x, " isMaterialized");
33045 if( pItem->fg.viaCoroutine ) sqlite3_str_appendf(&x, " viaCoroutine");
@@ -34133,10 +34119,14 @@
34119 **
34120 ** This routines are given external linkage so that they will always be
34121 ** accessible to the debugging, and to avoid warnings about unused
34122 ** functions. But these routines only exist in debugging builds, so they
34123 ** do not contaminate the interface.
34124 **
34125 ** See Also:
34126 **
34127 ** sqlite3ShowWhereTerm() in where.c
34128 */
34129 SQLITE_PRIVATE void sqlite3ShowExpr(const Expr *p){ sqlite3TreeViewExpr(0,p,0); }
34130 SQLITE_PRIVATE void sqlite3ShowExprList(const ExprList *p){ sqlite3TreeViewExprList(0,p,0,0);}
34131 SQLITE_PRIVATE void sqlite3ShowIdList(const IdList *p){ sqlite3TreeViewIdList(0,p,0,0); }
34132 SQLITE_PRIVATE void sqlite3ShowSrcList(const SrcList *p){ sqlite3TreeViewSrcList(0,p); }
@@ -34160,11 +34150,10 @@
34150
34151 #endif /* SQLITE_DEBUG */
34152
34153 /************** End of treeview.c ********************************************/
34154 /************** Begin file random.c ******************************************/
 
34155 /*
34156 ** 2001 September 15
34157 **
34158 ** The author disclaims copyright to this source code. In place of
34159 ** a legal notice, here is a blessing:
@@ -34321,11 +34310,10 @@
34310 }
34311 #endif /* SQLITE_UNTESTABLE */
34312
34313 /************** End of random.c **********************************************/
34314 /************** Begin file threads.c *****************************************/
 
34315 /*
34316 ** 2012 July 21
34317 **
34318 ** The author disclaims copyright to this source code. In place of
34319 ** a legal notice, here is a blessing:
@@ -34599,11 +34587,10 @@
34587 /****************************** End Single-Threaded *************************/
34588 #endif /* SQLITE_MAX_WORKER_THREADS>0 */
34589
34590 /************** End of threads.c *********************************************/
34591 /************** Begin file utf.c *********************************************/
 
34592 /*
34593 ** 2004 April 13
34594 **
34595 ** The author disclaims copyright to this source code. In place of
34596 ** a legal notice, here is a blessing:
@@ -35171,11 +35158,10 @@
35158 #endif /* SQLITE_TEST */
35159 #endif /* SQLITE_OMIT_UTF16 */
35160
35161 /************** End of utf.c *************************************************/
35162 /************** Begin file util.c ********************************************/
 
35163 /*
35164 ** 2001 September 15
35165 **
35166 ** The author disclaims copyright to this source code. In place of
35167 ** a legal notice, here is a blessing:
@@ -35713,12 +35699,12 @@
35699 int esign = 1; /* sign of exponent */
35700 int e = 0; /* exponent */
35701 int eValid = 1; /* True exponent is either not used or is well-formed */
35702 int nDigit = 0; /* Number of digits processed */
35703 int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */
35704 u64 s2; /* round-tripped significand */
35705 double rr[2];
 
35706
35707 assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
35708 *pResult = 0.0; /* Default return value, in case of an error */
35709 if( length==0 ) return 0;
35710
@@ -35817,25 +35803,36 @@
35803
35804 /* adjust exponent by d, and update sign */
35805 e = (e*esign) + d;
35806
35807 /* Try to adjust the exponent to make it smaller */
35808 while( e>0 && s<((LARGEST_UINT64-0x7ff)/10) ){
35809 s *= 10;
35810 e--;
35811 }
35812 while( e<0 && (s%10)==0 ){
35813 s /= 10;
35814 e++;
35815 }
35816
35817 rr[0] = (double)s;
35818 assert( sizeof(s2)==sizeof(rr[0]) );
35819 #ifdef SQLITE_DEBUG
35820 rr[1] = 18446744073709549568.0;
35821 memcpy(&s2, &rr[1], sizeof(s2));
35822 assert( s2==0x43efffffffffffffLL );
35823 #endif
35824 /* Largest double that can be safely converted to u64
35825 ** vvvvvvvvvvvvvvvvvvvvvv */
35826 if( rr[0]<=18446744073709549568.0 ){
35827 s2 = (u64)rr[0];
35828 rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s);
35829 }else{
35830 rr[1] = 0.0;
35831 }
35832 assert( rr[1]<=1.0e-10*rr[0] ); /* Equal only when rr[0]==0.0 */
35833
35834 if( e>0 ){
35835 while( e>=100 ){
35836 e -= 100;
35837 dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83);
35838 }
@@ -37023,11 +37020,10 @@
37020 return 0;
37021 }
37022
37023 /************** End of util.c ************************************************/
37024 /************** Begin file hash.c ********************************************/
 
37025 /*
37026 ** 2001 September 22
37027 **
37028 ** The author disclaims copyright to this source code. In place of
37029 ** a legal notice, here is a blessing:
@@ -37297,11 +37293,10 @@
37293 return 0;
37294 }
37295
37296 /************** End of hash.c ************************************************/
37297 /************** Begin file opcodes.c *****************************************/
 
37298 /* Automatically generated. Do not edit */
37299 /* See the tool/mkopcodec.tcl script for details. */
37300 #if !defined(SQLITE_OMIT_EXPLAIN) \
37301 || defined(VDBE_PROFILE) \
37302 || defined(SQLITE_DEBUG)
@@ -37507,11 +37502,10 @@
37502 }
37503 #endif
37504
37505 /************** End of opcodes.c *********************************************/
37506 /************** Begin file os_kv.c *******************************************/
 
37507 /*
37508 ** 2022-09-06
37509 **
37510 ** The author disclaims copyright to this source code. In place of
37511 ** a legal notice, here is a blessing:
@@ -38490,11 +38484,10 @@
38484 }
38485 #endif
38486
38487 /************** End of os_kv.c ***********************************************/
38488 /************** Begin file os_unix.c *****************************************/
 
38489 /*
38490 ** 2004 May 22
38491 **
38492 ** The author disclaims copyright to this source code. In place of
38493 ** a legal notice, here is a blessing:
@@ -42480,10 +42473,15 @@
42473 int rc = osIoctl(pFile->h, F2FS_IOC_ABORT_VOLATILE_WRITE);
42474 return rc ? SQLITE_IOERR_ROLLBACK_ATOMIC : SQLITE_OK;
42475 }
42476 #endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */
42477
42478 case SQLITE_FCNTL_NULL_IO: {
42479 osClose(pFile->h);
42480 pFile->h = -1;
42481 return SQLITE_OK;
42482 }
42483 case SQLITE_FCNTL_LOCKSTATE: {
42484 *(int*)pArg = pFile->eFileLock;
42485 return SQLITE_OK;
42486 }
42487 case SQLITE_FCNTL_LAST_ERRNO: {
@@ -46760,11 +46758,10 @@
46758
46759 #endif /* SQLITE_OS_UNIX */
46760
46761 /************** End of os_unix.c *********************************************/
46762 /************** Begin file os_win.c ******************************************/
 
46763 /*
46764 ** 2004 May 22
46765 **
46766 ** The author disclaims copyright to this source code. In place of
46767 ** a legal notice, here is a blessing:
@@ -50362,10 +50359,15 @@
50359 OSTRACE(("FCNTL oldFile=%p, newFile=%p, rc=SQLITE_OK\n",
50360 hOldFile, pFile->h));
50361 return SQLITE_OK;
50362 }
50363 #endif
50364 case SQLITE_FCNTL_NULL_IO: {
50365 (void)osCloseHandle(pFile->h);
50366 pFile->h = NULL;
50367 return SQLITE_OK;
50368 }
50369 case SQLITE_FCNTL_TEMPFILENAME: {
50370 char *zTFile = 0;
50371 int rc = winGetTempname(pFile->pVfs, &zTFile);
50372 if( rc==SQLITE_OK ){
50373 *(char**)pArg = zTFile;
@@ -51811,11 +51813,11 @@
51813 */
51814 char *zTmpname = 0; /* For temporary filename, if necessary. */
51815
51816 int rc = SQLITE_OK; /* Function Return Code */
51817 #if !defined(NDEBUG) || SQLITE_OS_WINCE
51818 int eType = flags&0x0FFF00; /* Type of file to open */
51819 #endif
51820
51821 int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE);
51822 int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE);
51823 int isCreate = (flags & SQLITE_OPEN_CREATE);
@@ -52975,11 +52977,10 @@
52977
52978 #endif /* SQLITE_OS_WIN */
52979
52980 /************** End of os_win.c **********************************************/
52981 /************** Begin file memdb.c *******************************************/
 
52982 /*
52983 ** 2016-09-07
52984 **
52985 ** The author disclaims copyright to this source code. In place of
52986 ** a legal notice, here is a blessing:
@@ -53915,11 +53916,10 @@
53916 }
53917 #endif /* SQLITE_OMIT_DESERIALIZE */
53918
53919 /************** End of memdb.c ***********************************************/
53920 /************** Begin file bitvec.c ******************************************/
 
53921 /*
53922 ** 2008 February 16
53923 **
53924 ** The author disclaims copyright to this source code. In place of
53925 ** a legal notice, here is a blessing:
@@ -54330,11 +54330,10 @@
54330 }
54331 #endif /* SQLITE_UNTESTABLE */
54332
54333 /************** End of bitvec.c **********************************************/
54334 /************** Begin file pcache.c ******************************************/
 
54335 /*
54336 ** 2008 August 05
54337 **
54338 ** The author disclaims copyright to this source code. In place of
54339 ** a legal notice, here is a blessing:
@@ -55270,11 +55269,10 @@
55269 }
55270 #endif
55271
55272 /************** End of pcache.c **********************************************/
55273 /************** Begin file pcache1.c *****************************************/
 
55274 /*
55275 ** 2008 November 05
55276 **
55277 ** The author disclaims copyright to this source code. In place of
55278 ** a legal notice, here is a blessing:
@@ -56556,11 +56554,10 @@
56554 }
56555 #endif
56556
56557 /************** End of pcache1.c *********************************************/
56558 /************** Begin file rowset.c ******************************************/
 
56559 /*
56560 ** 2008 December 3
56561 **
56562 ** The author disclaims copyright to this source code. In place of
56563 ** a legal notice, here is a blessing:
@@ -57062,11 +57059,10 @@
57059 return 0;
57060 }
57061
57062 /************** End of rowset.c **********************************************/
57063 /************** Begin file pager.c *******************************************/
 
57064 /*
57065 ** 2001 September 15
57066 **
57067 ** The author disclaims copyright to this source code. In place of
57068 ** a legal notice, here is a blessing:
@@ -57087,11 +57083,10 @@
57083 */
57084 #ifndef SQLITE_OMIT_DISKIO
57085 /* #include "sqliteInt.h" */
57086 /************** Include wal.h in the middle of pager.c ***********************/
57087 /************** Begin file wal.h *********************************************/
 
57088 /*
57089 ** 2010 February 1
57090 **
57091 ** The author disclaims copyright to this source code. In place of
57092 ** a legal notice, here is a blessing:
@@ -57251,11 +57246,10 @@
57246 #endif /* ifndef SQLITE_OMIT_WAL */
57247 #endif /* SQLITE_WAL_H */
57248
57249 /************** End of wal.h *************************************************/
57250 /************** Continuing where we left off in pager.c **********************/
 
57251
57252
57253 /******************* NOTES ON THE DESIGN OF THE PAGER ************************
57254 **
57255 ** This comment block describes invariants that hold when using a rollback
@@ -65041,11 +65035,10 @@
65035
65036 #endif /* SQLITE_OMIT_DISKIO */
65037
65038 /************** End of pager.c ***********************************************/
65039 /************** Begin file wal.c *********************************************/
 
65040 /*
65041 ** 2010 February 1
65042 **
65043 ** The author disclaims copyright to this source code. In place of
65044 ** a legal notice, here is a blessing:
@@ -69638,11 +69631,10 @@
69631
69632 #endif /* #ifndef SQLITE_OMIT_WAL */
69633
69634 /************** End of wal.c *************************************************/
69635 /************** Begin file btmutex.c *****************************************/
 
69636 /*
69637 ** 2007 August 27
69638 **
69639 ** The author disclaims copyright to this source code. In place of
69640 ** a legal notice, here is a blessing:
@@ -69658,11 +69650,10 @@
69650 ** big and we want to break it down some. This packaged seemed like
69651 ** a good breakout.
69652 */
69653 /************** Include btreeInt.h in the middle of btmutex.c ****************/
69654 /************** Begin file btreeInt.h ****************************************/
 
69655 /*
69656 ** 2004 April 6
69657 **
69658 ** The author disclaims copyright to this source code. In place of
69659 ** a legal notice, here is a blessing:
@@ -70396,11 +70387,10 @@
70387 # define get2byteAligned(x) ((x)[0]<<8 | (x)[1])
70388 #endif
70389
70390 /************** End of btreeInt.h ********************************************/
70391 /************** Continuing where we left off in btmutex.c ********************/
 
70392 #ifndef SQLITE_OMIT_SHARED_CACHE
70393 #if SQLITE_THREADSAFE
70394
70395 /*
70396 ** Obtain the BtShared mutex associated with B-Tree handle p. Also,
@@ -70691,11 +70681,10 @@
70681
70682 #endif /* ifndef SQLITE_OMIT_SHARED_CACHE */
70683
70684 /************** End of btmutex.c *********************************************/
70685 /************** Begin file btree.c *******************************************/
 
70686 /*
70687 ** 2004 April 6
70688 **
70689 ** The author disclaims copyright to this source code. In place of
70690 ** a legal notice, here is a blessing:
@@ -82186,11 +82175,10 @@
82175 }
82176 #endif
82177
82178 /************** End of btree.c ***********************************************/
82179 /************** Begin file backup.c ******************************************/
 
82180 /*
82181 ** 2009 January 28
82182 **
82183 ** The author disclaims copyright to this source code. In place of
82184 ** a legal notice, here is a blessing:
@@ -82957,11 +82945,10 @@
82945 }
82946 #endif /* SQLITE_OMIT_VACUUM */
82947
82948 /************** End of backup.c **********************************************/
82949 /************** Begin file vdbemem.c *****************************************/
 
82950 /*
82951 ** 2004 May 26
82952 **
82953 ** The author disclaims copyright to this source code. In place of
82954 ** a legal notice, here is a blessing:
@@ -85014,11 +85001,10 @@
85001 return valueBytes(pVal, enc);
85002 }
85003
85004 /************** End of vdbemem.c *********************************************/
85005 /************** Begin file vdbeaux.c *****************************************/
 
85006 /*
85007 ** 2003 September 6
85008 **
85009 ** The author disclaims copyright to this source code. In place of
85010 ** a legal notice, here is a blessing:
@@ -90566,11 +90552,10 @@
90552 }
90553 #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
90554
90555 /************** End of vdbeaux.c *********************************************/
90556 /************** Begin file vdbeapi.c *****************************************/
 
90557 /*
90558 ** 2004 May 26
90559 **
90560 ** The author disclaims copyright to this source code. In place of
90561 ** a legal notice, here is a blessing:
@@ -93153,11 +93138,10 @@
93138 }
93139 #endif /* SQLITE_ENABLE_STMT_SCANSTATUS */
93140
93141 /************** End of vdbeapi.c *********************************************/
93142 /************** Begin file vdbetrace.c ***************************************/
 
93143 /*
93144 ** 2009 November 25
93145 **
93146 ** The author disclaims copyright to this source code. In place of
93147 ** a legal notice, here is a blessing:
@@ -93349,11 +93333,10 @@
93333
93334 #endif /* #ifndef SQLITE_OMIT_TRACE */
93335
93336 /************** End of vdbetrace.c *******************************************/
93337 /************** Begin file vdbe.c ********************************************/
 
93338 /*
93339 ** 2001 September 15
93340 **
93341 ** The author disclaims copyright to this source code. In place of
93342 ** a legal notice, here is a blessing:
@@ -93381,11 +93364,10 @@
93364 #if defined(VDBE_PROFILE) \
93365 || defined(SQLITE_PERFORMANCE_TRACE) \
93366 || defined(SQLITE_ENABLE_STMT_SCANSTATUS)
93367 /************** Include hwtime.h in the middle of vdbe.c *********************/
93368 /************** Begin file hwtime.h ******************************************/
 
93369 /*
93370 ** 2008 May 27
93371 **
93372 ** The author disclaims copyright to this source code. In place of
93373 ** a legal notice, here is a blessing:
@@ -93470,11 +93452,10 @@
93452
93453 #endif /* !defined(SQLITE_HWTIME_H) */
93454
93455 /************** End of hwtime.h **********************************************/
93456 /************** Continuing where we left off in vdbe.c ***********************/
 
93457 #endif
93458
93459 /*
93460 ** Invoke this macro on memory cells just prior to changing the
93461 ** value of the cell. This macro verifies that shallow copies are
@@ -102664,11 +102645,10 @@
102645 }
102646
102647
102648 /************** End of vdbe.c ************************************************/
102649 /************** Begin file vdbeblob.c ****************************************/
 
102650 /*
102651 ** 2007 May 1
102652 **
102653 ** The author disclaims copyright to this source code. In place of
102654 ** a legal notice, here is a blessing:
@@ -103188,11 +103168,10 @@
103168
103169 #endif /* #ifndef SQLITE_OMIT_INCRBLOB */
103170
103171 /************** End of vdbeblob.c ********************************************/
103172 /************** Begin file vdbesort.c ****************************************/
 
103173 /*
103174 ** 2011-07-09
103175 **
103176 ** The author disclaims copyright to this source code. In place of
103177 ** a legal notice, here is a blessing:
@@ -105959,11 +105938,10 @@
105938 return SQLITE_OK;
105939 }
105940
105941 /************** End of vdbesort.c ********************************************/
105942 /************** Begin file vdbevtab.c ****************************************/
 
105943 /*
105944 ** 2020-03-23
105945 **
105946 ** The author disclaims copyright to this source code. In place of
105947 ** a legal notice, here is a blessing:
@@ -106409,11 +106387,10 @@
106387 SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){ return SQLITE_OK; }
106388 #endif /* SQLITE_ENABLE_BYTECODE_VTAB */
106389
106390 /************** End of vdbevtab.c ********************************************/
106391 /************** Begin file memjournal.c **************************************/
 
106392 /*
106393 ** 2008 October 7
106394 **
106395 ** The author disclaims copyright to this source code. In place of
106396 ** a legal notice, here is a blessing:
@@ -106853,11 +106830,10 @@
106830 return MAX(pVfs->szOsFile, (int)sizeof(MemJournal));
106831 }
106832
106833 /************** End of memjournal.c ******************************************/
106834 /************** Begin file walker.c ******************************************/
 
106835 /*
106836 ** 2008 August 16
106837 **
106838 ** The author disclaims copyright to this source code. In place of
106839 ** a legal notice, here is a blessing:
@@ -107118,11 +107094,10 @@
107094 return WRC_Continue;
107095 }
107096
107097 /************** End of walker.c **********************************************/
107098 /************** Begin file resolve.c *****************************************/
 
107099 /*
107100 ** 2008 August 18
107101 **
107102 ** The author disclaims copyright to this source code. In place of
107103 ** a legal notice, here is a blessing:
@@ -109440,11 +109415,10 @@
109415 return rc;
109416 }
109417
109418 /************** End of resolve.c *********************************************/
109419 /************** Begin file expr.c ********************************************/
 
109420 /*
109421 ** 2001 September 15
109422 **
109423 ** The author disclaims copyright to this source code. In place of
109424 ** a legal notice, here is a blessing:
@@ -112089,11 +112063,11 @@
112063 **
112064 ** (4) If pSrc is the right operand of a LEFT JOIN, then...
112065 ** (4a) pExpr must come from an ON clause..
112066 ** (4b) and specifically the ON clause associated with the LEFT JOIN.
112067 **
112068 ** (5) If pSrc is the right operand of a LEFT JOIN or the left
112069 ** operand of a RIGHT JOIN, then pExpr must be from the WHERE
112070 ** clause, not an ON clause.
112071 **
112072 ** (6) Either:
112073 **
@@ -115623,35 +115597,41 @@
115597 **
115598 ** Additionally, if pExpr is a simple SQL value and the value is the
115599 ** same as that currently bound to variable pVar, non-zero is returned.
115600 ** Otherwise, if the values are not the same or if pExpr is not a simple
115601 ** SQL value, zero is returned.
115602 **
115603 ** If the SQLITE_EnableQPSG flag is set on the database connection, then
115604 ** this routine always returns false.
115605 */
115606 static SQLITE_NOINLINE int exprCompareVariable(
115607 const Parse *pParse,
115608 const Expr *pVar,
115609 const Expr *pExpr
115610 ){
115611 int res = 2;
115612 int iVar;
115613 sqlite3_value *pL, *pR = 0;
115614
115615 if( pExpr->op==TK_VARIABLE && pVar->iColumn==pExpr->iColumn ){
115616 return 0;
115617 }
115618 if( (pParse->db->flags & SQLITE_EnableQPSG)!=0 ) return 2;
115619 sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR);
115620 if( pR ){
115621 iVar = pVar->iColumn;
115622 sqlite3VdbeSetVarmask(pParse->pVdbe, iVar);
115623 pL = sqlite3VdbeGetBoundValue(pParse->pReprepare, iVar, SQLITE_AFF_BLOB);
115624 if( pL ){
115625 if( sqlite3_value_type(pL)==SQLITE_TEXT ){
115626 sqlite3_value_text(pL); /* Make sure the encoding is UTF-8 */
115627 }
115628 res = sqlite3MemCompare(pL, pR, 0) ? 2 : 0;
115629 }
115630 sqlite3ValueFree(pR);
115631 sqlite3ValueFree(pL);
115632 }
 
115633 return res;
115634 }
115635
115636 /*
115637 ** Do a deep comparison of two expression trees. Return 0 if the two
@@ -115673,16 +115653,14 @@
115653 ** can be sure the expressions are the same. In the places where
115654 ** this routine is used, it does not hurt to get an extra 2 - that
115655 ** just might result in some slightly slower code. But returning
115656 ** an incorrect 0 or 1 could lead to a malfunction.
115657 **
115658 ** If pParse is not NULL and SQLITE_EnableQPSG is off then TK_VARIABLE
115659 ** terms in pA with bindings in pParse->pReprepare can be matched against
115660 ** literals in pB. The pParse->pVdbe->expmask bitmask is updated for
115661 ** each variable referenced.
 
 
115662 */
115663 SQLITE_PRIVATE int sqlite3ExprCompare(
115664 const Parse *pParse,
115665 const Expr *pA,
115666 const Expr *pB,
@@ -115690,12 +115668,12 @@
115668 ){
115669 u32 combinedFlags;
115670 if( pA==0 || pB==0 ){
115671 return pB==pA ? 0 : 2;
115672 }
115673 if( pParse && pA->op==TK_VARIABLE ){
115674 return exprCompareVariable(pParse, pA, pB);
115675 }
115676 combinedFlags = pA->flags | pB->flags;
115677 if( combinedFlags & EP_IntValue ){
115678 if( (pA->flags&pB->flags&EP_IntValue)!=0 && pA->u.iValue==pB->u.iValue ){
115679 return 0;
@@ -115885,23 +115863,75 @@
115863 return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
115864 }
115865 }
115866 return 0;
115867 }
115868
115869 /*
115870 ** Return true if the boolean value of the expression is always either
115871 ** FALSE or NULL.
115872 */
115873 static int sqlite3ExprIsNotTrue(Expr *pExpr){
115874 int v;
115875 if( pExpr->op==TK_NULL ) return 1;
115876 if( pExpr->op==TK_TRUEFALSE && sqlite3ExprTruthValue(pExpr)==0 ) return 1;
115877 v = 1;
115878 if( sqlite3ExprIsInteger(pExpr, &v, 0) && v==0 ) return 1;
115879 return 0;
115880 }
115881
115882 /*
115883 ** Return true if the expression is one of the following:
115884 **
115885 ** CASE WHEN x THEN y END
115886 ** CASE WHEN x THEN y ELSE NULL END
115887 ** CASE WHEN x THEN y ELSE false END
115888 ** iif(x,y)
115889 ** iif(x,y,NULL)
115890 ** iif(x,y,false)
115891 */
115892 static int sqlite3ExprIsIIF(sqlite3 *db, const Expr *pExpr){
115893 ExprList *pList;
115894 if( pExpr->op==TK_FUNCTION ){
115895 const char *z = pExpr->u.zToken;
115896 FuncDef *pDef;
115897 if( (z[0]!='i' && z[0]!='I') ) return 0;
115898 if( pExpr->x.pList==0 ) return 0;
115899 pDef = sqlite3FindFunction(db, z, pExpr->x.pList->nExpr, ENC(db), 0);
115900 #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
115901 if( pDef==0 ) return 0;
115902 #else
115903 if( NEVER(pDef==0) ) return 0;
115904 #endif
115905 if( (pDef->funcFlags & SQLITE_FUNC_INLINE)==0 ) return 0;
115906 if( SQLITE_PTR_TO_INT(pDef->pUserData)!=INLINEFUNC_iif ) return 0;
115907 }else if( pExpr->op==TK_CASE ){
115908 if( pExpr->pLeft!=0 ) return 0;
115909 }else{
115910 return 0;
115911 }
115912 pList = pExpr->x.pList;
115913 assert( pList!=0 );
115914 if( pList->nExpr==2 ) return 1;
115915 if( pList->nExpr==3 && sqlite3ExprIsNotTrue(pList->a[2].pExpr) ) return 1;
115916 return 0;
115917 }
115918
115919 /*
115920 ** Return true if we can prove the pE2 will always be true if pE1 is
115921 ** true. Return false if we cannot complete the proof or if pE2 might
115922 ** be false. Examples:
115923 **
115924 ** pE1: x==5 pE2: x==5 Result: true
115925 ** pE1: x>0 pE2: x==5 Result: false
115926 ** pE1: x=21 pE2: x=21 OR y=43 Result: true
115927 ** pE1: x!=123 pE2: x IS NOT NULL Result: true
115928 ** pE1: x!=?1 pE2: x IS NOT NULL Result: true
115929 ** pE1: x IS NULL pE2: x IS NOT NULL Result: false
115930 ** pE1: x IS ?2 pE2: x IS NOT NULL Result: false
115931 ** pE1: iif(x,y) pE2: x Result: true
115932 ** PE1: iif(x,y,0) pE2: x Result: true
115933 **
115934 ** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has
115935 ** Expr.iTable<0 then assume a table number given by iTab.
115936 **
115937 ** If pParse is not NULL, then the values of bound variables in pE1 are
@@ -115931,10 +115961,13 @@
115961 if( pE2->op==TK_NOTNULL
115962 && exprImpliesNotNull(pParse, pE1, pE2->pLeft, iTab, 0)
115963 ){
115964 return 1;
115965 }
115966 if( sqlite3ExprIsIIF(pParse->db, pE1) ){
115967 return sqlite3ExprImpliesExpr(pParse,pE1->x.pList->a[0].pExpr,pE2,iTab);
115968 }
115969 return 0;
115970 }
115971
115972 /* This is a helper function to impliesNotNullRow(). In this routine,
115973 ** set pWalker->eCode to one only if *both* of the input expressions
@@ -116770,11 +116803,10 @@
116803 }
116804 #endif /* SQLITE_DEBUG */
116805
116806 /************** End of expr.c ************************************************/
116807 /************** Begin file alter.c *******************************************/
 
116808 /*
116809 ** 2005 February 15
116810 **
116811 ** The author disclaims copyright to this source code. In place of
116812 ** a legal notice, here is a blessing:
@@ -119090,11 +119122,10 @@
119122 }
119123 #endif /* SQLITE_ALTER_TABLE */
119124
119125 /************** End of alter.c ***********************************************/
119126 /************** Begin file analyze.c *****************************************/
 
119127 /*
119128 ** 2005-07-08
119129 **
119130 ** The author disclaims copyright to this source code. In place of
119131 ** a legal notice, here is a blessing:
@@ -121115,11 +121146,10 @@
121146
121147 #endif /* SQLITE_OMIT_ANALYZE */
121148
121149 /************** End of analyze.c *********************************************/
121150 /************** Begin file attach.c ******************************************/
 
121151 /*
121152 ** 2003 April 6
121153 **
121154 ** The author disclaims copyright to this source code. In place of
121155 ** a legal notice, here is a blessing:
@@ -121728,11 +121758,10 @@
121758 }
121759 #endif
121760
121761 /************** End of attach.c **********************************************/
121762 /************** Begin file auth.c ********************************************/
 
121763 /*
121764 ** 2003 January 11
121765 **
121766 ** The author disclaims copyright to this source code. In place of
121767 ** a legal notice, here is a blessing:
@@ -121992,11 +122021,10 @@
122021
122022 #endif /* SQLITE_OMIT_AUTHORIZATION */
122023
122024 /************** End of auth.c ************************************************/
122025 /************** Begin file build.c *******************************************/
 
122026 /*
122027 ** 2001 September 15
122028 **
122029 ** The author disclaims copyright to this source code. In place of
122030 ** a legal notice, here is a blessing:
@@ -127763,11 +127791,10 @@
127791 }
127792 #endif /* !defined(SQLITE_OMIT_CTE) */
127793
127794 /************** End of build.c ***********************************************/
127795 /************** Begin file callback.c ****************************************/
 
127796 /*
127797 ** 2005 May 23
127798 **
127799 ** The author disclaims copyright to this source code. In place of
127800 ** a legal notice, here is a blessing:
@@ -128307,11 +128334,10 @@
128334 return p;
128335 }
128336
128337 /************** End of callback.c ********************************************/
128338 /************** Begin file delete.c ******************************************/
 
128339 /*
128340 ** 2001 September 15
128341 **
128342 ** The author disclaims copyright to this source code. In place of
128343 ** a legal notice, here is a blessing:
@@ -129341,11 +129367,10 @@
129367 }
129368 }
129369
129370 /************** End of delete.c **********************************************/
129371 /************** Begin file func.c ********************************************/
 
129372 /*
129373 ** 2002 February 23
129374 **
129375 ** The author disclaims copyright to this source code. In place of
129376 ** a legal notice, here is a blessing:
@@ -132158,11 +132183,14 @@
132183 MFUNCTION(degrees, 1, radToDeg, math1Func ),
132184 MFUNCTION(pi, 0, 0, piFunc ),
132185 #endif /* SQLITE_ENABLE_MATH_FUNCTIONS */
132186 FUNCTION(sign, 1, 0, 0, signFunc ),
132187 INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, 0 ),
132188 INLINE_FUNC(iif, 2, INLINEFUNC_iif, 0 ),
132189 INLINE_FUNC(iif, 3, INLINEFUNC_iif, 0 ),
132190 INLINE_FUNC(if, 2, INLINEFUNC_iif, 0 ),
132191 INLINE_FUNC(if, 3, INLINEFUNC_iif, 0 ),
132192 };
132193 #ifndef SQLITE_OMIT_ALTERTABLE
132194 sqlite3AlterFunctions();
132195 #endif
132196 sqlite3WindowFunctions();
@@ -132188,11 +132216,10 @@
132216 #endif
132217 }
132218
132219 /************** End of func.c ************************************************/
132220 /************** Begin file fkey.c ********************************************/
 
132221 /*
132222 **
132223 ** The author disclaims copyright to this source code. In place of
132224 ** a legal notice, here is a blessing:
132225 **
@@ -133676,11 +133703,10 @@
133703 }
133704 #endif /* ifndef SQLITE_OMIT_FOREIGN_KEY */
133705
133706 /************** End of fkey.c ************************************************/
133707 /************** Begin file insert.c ******************************************/
 
133708 /*
133709 ** 2001 September 15
133710 **
133711 ** The author disclaims copyright to this source code. In place of
133712 ** a legal notice, here is a blessing:
@@ -137072,11 +137098,10 @@
137098 }
137099 #endif /* SQLITE_OMIT_XFER_OPT */
137100
137101 /************** End of insert.c **********************************************/
137102 /************** Begin file legacy.c ******************************************/
 
137103 /*
137104 ** 2001 September 15
137105 **
137106 ** The author disclaims copyright to this source code. In place of
137107 ** a legal notice, here is a blessing:
@@ -137217,11 +137242,10 @@
137242 return rc;
137243 }
137244
137245 /************** End of legacy.c **********************************************/
137246 /************** Begin file loadext.c *****************************************/
 
137247 /*
137248 ** 2006 June 7
137249 **
137250 ** The author disclaims copyright to this source code. In place of
137251 ** a legal notice, here is a blessing:
@@ -137238,11 +137262,10 @@
137262 #ifndef SQLITE_CORE
137263 #define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */
137264 #endif
137265 /************** Include sqlite3ext.h in the middle of loadext.c **************/
137266 /************** Begin file sqlite3ext.h **************************************/
 
137267 /*
137268 ** 2006 June 7
137269 **
137270 ** The author disclaims copyright to this source code. In place of
137271 ** a legal notice, here is a blessing:
@@ -137961,11 +137984,10 @@
137984
137985 #endif /* SQLITE3EXT_H */
137986
137987 /************** End of sqlite3ext.h ******************************************/
137988 /************** Continuing where we left off in loadext.c ********************/
 
137989 /* #include "sqliteInt.h" */
137990
137991 #ifndef SQLITE_OMIT_LOAD_EXTENSION
137992 /*
137993 ** Some API routines are omitted when various features are
@@ -138867,11 +138889,10 @@
138889 }
138890 }
138891
138892 /************** End of loadext.c *********************************************/
138893 /************** Begin file pragma.c ******************************************/
 
138894 /*
138895 ** 2003 April 6
138896 **
138897 ** The author disclaims copyright to this source code. In place of
138898 ** a legal notice, here is a blessing:
@@ -138900,11 +138921,10 @@
138921 ** lexicographical order to facility a binary search of the pragma name.
138922 ** Do not edit pragma.h directly. Edit and rerun the script in at
138923 ** ../tool/mkpragmatab.tcl. */
138924 /************** Include pragma.h in the middle of pragma.c *******************/
138925 /************** Begin file pragma.h ******************************************/
 
138926 /* DO NOT EDIT!
138927 ** This file is automatically generated by the script at
138928 ** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit
138929 ** that script and rerun it.
138930 */
@@ -139564,11 +139584,10 @@
139584 };
139585 /* Number of pragmas: 68 on by default, 78 total. */
139586
139587 /************** End of pragma.h **********************************************/
139588 /************** Continuing where we left off in pragma.c *********************/
 
139589
139590 /*
139591 ** When the 0x10 bit of PRAGMA optimize is set, any ANALYZE commands
139592 ** will be run with an analysis_limit set to the lessor of the value of
139593 ** the following macro or to the actual analysis_limit if it is non-zero,
@@ -140815,11 +140834,12 @@
140834 pTab = sqliteHashData(k);
140835 if( pTab->nCol==0 ){
140836 char *zSql = sqlite3MPrintf(db, "SELECT*FROM\"%w\"", pTab->zName);
140837 if( zSql ){
140838 sqlite3_stmt *pDummy = 0;
140839 (void)sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_DONT_LOG,
140840 &pDummy, 0);
140841 (void)sqlite3_finalize(pDummy);
140842 sqlite3DbFree(db, zSql);
140843 }
140844 if( db->mallocFailed ){
140845 sqlite3ErrorMsg(db->pParse, "out of memory");
@@ -142608,11 +142628,10 @@
142628
142629 #endif /* SQLITE_OMIT_PRAGMA */
142630
142631 /************** End of pragma.c **********************************************/
142632 /************** Begin file prepare.c *****************************************/
 
142633 /*
142634 ** 2005 May 25
142635 **
142636 ** The author disclaims copyright to this source code. In place of
142637 ** a legal notice, here is a blessing:
@@ -143702,11 +143721,10 @@
143721
143722 #endif /* SQLITE_OMIT_UTF16 */
143723
143724 /************** End of prepare.c *********************************************/
143725 /************** Begin file select.c ******************************************/
 
143726 /*
143727 ** 2001 September 15
143728 **
143729 ** The author disclaims copyright to this source code. In place of
143730 ** a legal notice, here is a blessing:
@@ -147616,36 +147634,36 @@
147634 return pExpr;
147635 }
147636 if( pSubst->isOuterJoin ){
147637 ExprSetProperty(pNew, EP_CanBeNull);
147638 }
147639 if( pNew->op==TK_TRUEFALSE ){
147640 pNew->u.iValue = sqlite3ExprTruthValue(pNew);
147641 pNew->op = TK_INTEGER;
147642 ExprSetProperty(pNew, EP_IntValue);
147643 }
147644
147645 /* Ensure that the expression now has an implicit collation sequence,
147646 ** just as it did when it was a column of a view or sub-query. */
147647 {
147648 CollSeq *pNat = sqlite3ExprCollSeq(pSubst->pParse, pNew);
147649 CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse,
147650 pSubst->pCList->a[iColumn].pExpr
147651 );
147652 if( pNat!=pColl || (pNew->op!=TK_COLUMN && pNew->op!=TK_COLLATE) ){
147653 pNew = sqlite3ExprAddCollateString(pSubst->pParse, pNew,
147654 (pColl ? pColl->zName : "BINARY")
147655 );
147656 }
147657 }
147658 ExprClearProperty(pNew, EP_Collate);
147659 if( ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) ){
147660 sqlite3SetJoinExpr(pNew, pExpr->w.iJoin,
147661 pExpr->flags & (EP_OuterON|EP_InnerON));
147662 }
147663 sqlite3ExprDelete(db, pExpr);
147664 pExpr = pNew;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147665 }
147666 }
147667 }else{
147668 if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){
147669 pExpr->iTable = pSubst->iNewTable;
@@ -148378,20 +148396,20 @@
148396 }
148397
148398 /* Transfer the FROM clause terms from the subquery into the
148399 ** outer query.
148400 */
148401 iNewParent = pSubSrc->a[0].iCursor;
148402 for(i=0; i<nSubSrc; i++){
148403 SrcItem *pItem = &pSrc->a[i+iFrom];
148404 assert( pItem->fg.isTabFunc==0 );
148405 assert( pItem->fg.isSubquery
148406 || pItem->fg.fixedSchema
148407 || pItem->u4.zDatabase==0 );
148408 if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing);
148409 *pItem = pSubSrc->a[i];
148410 pItem->fg.jointype |= ltorj;
 
148411 memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
148412 }
148413 pSrc->a[iFrom].fg.jointype &= JT_LTORJ;
148414 pSrc->a[iFrom].fg.jointype |= jointype | ltorj;
148415
@@ -148427,10 +148445,11 @@
148445 pSub->pOrderBy = 0;
148446 }
148447 pWhere = pSub->pWhere;
148448 pSub->pWhere = 0;
148449 if( isOuterJoin>0 ){
148450 assert( pSubSrc->nSrc==1 );
148451 sqlite3SetJoinExpr(pWhere, iNewParent, EP_OuterON);
148452 }
148453 if( pWhere ){
148454 if( pParent->pWhere ){
148455 pParent->pWhere = sqlite3PExpr(pParse, TK_AND, pWhere, pParent->pWhere);
@@ -151526,11 +151545,11 @@
151545 sqlite3TreeViewSelect(0, p, 0);
151546 }
151547 #endif
151548 assert( pSubq->pSelect && (pSub->selFlags & SF_PushDown)!=0 );
151549 }else{
151550 TREETRACE(0x4000,pParse,p,("WHERE-clause push-down not possible\n"));
151551 }
151552
151553 /* Convert unused result columns of the subquery into simple NULL
151554 ** expressions, to avoid unneeded searching and computation.
151555 ** tag-select-0440
@@ -152475,11 +152494,10 @@
152494 return rc;
152495 }
152496
152497 /************** End of select.c **********************************************/
152498 /************** Begin file table.c *******************************************/
 
152499 /*
152500 ** 2001 September 15
152501 **
152502 ** The author disclaims copyright to this source code. In place of
152503 ** a legal notice, here is a blessing:
@@ -152677,11 +152695,10 @@
152695
152696 #endif /* SQLITE_OMIT_GET_TABLE */
152697
152698 /************** End of table.c ***********************************************/
152699 /************** Begin file trigger.c *****************************************/
 
152700 /*
152701 **
152702 ** The author disclaims copyright to this source code. In place of
152703 ** a legal notice, here is a blessing:
152704 **
@@ -154244,11 +154261,10 @@
154261
154262 #endif /* !defined(SQLITE_OMIT_TRIGGER) */
154263
154264 /************** End of trigger.c *********************************************/
154265 /************** Begin file update.c ******************************************/
 
154266 /*
154267 ** 2001 September 15
154268 **
154269 ** The author disclaims copyright to this source code. In place of
154270 ** a legal notice, here is a blessing:
@@ -155616,11 +155632,10 @@
155632 }
155633 #endif /* SQLITE_OMIT_VIRTUALTABLE */
155634
155635 /************** End of update.c **********************************************/
155636 /************** Begin file upsert.c ******************************************/
 
155637 /*
155638 ** 2018-04-12
155639 **
155640 ** The author disclaims copyright to this source code. In place of
155641 ** a legal notice, here is a blessing:
@@ -155949,11 +155964,10 @@
155964
155965 #endif /* SQLITE_OMIT_UPSERT */
155966
155967 /************** End of upsert.c **********************************************/
155968 /************** Begin file vacuum.c ******************************************/
 
155969 /*
155970 ** 2003 April 6
155971 **
155972 ** The author disclaims copyright to this source code. In place of
155973 ** a legal notice, here is a blessing:
@@ -156371,11 +156385,10 @@
156385
156386 #endif /* SQLITE_OMIT_VACUUM && SQLITE_OMIT_ATTACH */
156387
156388 /************** End of vacuum.c **********************************************/
156389 /************** Begin file vtab.c ********************************************/
 
156390 /*
156391 ** 2006 June 10
156392 **
156393 ** The author disclaims copyright to this source code. In place of
156394 ** a legal notice, here is a blessing:
@@ -157749,11 +157762,10 @@
157762
157763 #endif /* SQLITE_OMIT_VIRTUALTABLE */
157764
157765 /************** End of vtab.c ************************************************/
157766 /************** Begin file wherecode.c ***************************************/
 
157767 /*
157768 ** 2015-06-06
157769 **
157770 ** The author disclaims copyright to this source code. In place of
157771 ** a legal notice, here is a blessing:
@@ -157772,11 +157784,10 @@
157784 ** file retains the code that does query planning and analysis.
157785 */
157786 /* #include "sqliteInt.h" */
157787 /************** Include whereInt.h in the middle of wherecode.c **************/
157788 /************** Begin file whereInt.h ****************************************/
 
157789 /*
157790 ** 2013-11-12
157791 **
157792 ** The author disclaims copyright to this source code. In place of
157793 ** a legal notice, here is a blessing:
@@ -158429,11 +158440,10 @@
158440
158441 #endif /* !defined(SQLITE_WHEREINT_H) */
158442
158443 /************** End of whereInt.h ********************************************/
158444 /************** Continuing where we left off in wherecode.c ******************/
 
158445
158446 #ifndef SQLITE_OMIT_EXPLAIN
158447
158448 /*
158449 ** Return the name of the i-th column of the pIdx index.
@@ -159026,10 +159036,11 @@
159036 if( pOrigLhs ){
159037 sqlite3ExprListDelete(db, pOrigLhs);
159038 pNew->pLeft->x.pList = pLhs;
159039 }
159040 pSelect->pEList = pRhs;
159041 pSelect->selId = ++pParse->nSelect; /* Req'd for SubrtnSig validity */
159042 if( pLhs && pLhs->nExpr==1 ){
159043 /* Take care here not to generate a TK_VECTOR containing only a
159044 ** single value. Since the parser never creates such a vector, some
159045 ** of the subroutines do not handle this case. */
159046 Expr *p = pLhs->a[0].pExpr;
@@ -161352,11 +161363,10 @@
161363 pParse->withinRJSubrtn--;
161364 }
161365
161366 /************** End of wherecode.c *******************************************/
161367 /************** Begin file whereexpr.c ***************************************/
 
161368 /*
161369 ** 2015-06-08
161370 **
161371 ** The author disclaims copyright to this source code. In place of
161372 ** a legal notice, here is a blessing:
@@ -163258,11 +163268,10 @@
163268 }
163269 }
163270
163271 /************** End of whereexpr.c *******************************************/
163272 /************** Begin file where.c *******************************************/
 
163273 /*
163274 ** 2001 September 15
163275 **
163276 ** The author disclaims copyright to this source code. In place of
163277 ** a legal notice, here is a blessing:
@@ -164100,11 +164109,11 @@
164109 || pTerm->pExpr->w.iJoin != pSrc->iCursor
164110 ){
164111 return 0;
164112 }
164113 if( (pSrc->fg.jointype & (JT_LEFT|JT_RIGHT))!=0
164114 && NEVER(ExprHasProperty(pTerm->pExpr, EP_InnerON))
164115 ){
164116 return 0;
164117 }
164118 return 1;
164119 }
@@ -165593,11 +165602,11 @@
165602 return rc;
165603 }
165604 #endif /* SQLITE_ENABLE_STAT4 */
165605
165606
165607 #if defined(WHERETRACE_ENABLED) || defined(SQLITE_DEBUG)
165608 /*
165609 ** Print the content of a WhereTerm object
165610 */
165611 SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){
165612 if( pTerm==0 ){
@@ -165636,10 +165645,13 @@
165645 sqlite3DebugPrintf(" iParent=%d", pTerm->iParent);
165646 }
165647 sqlite3DebugPrintf("\n");
165648 sqlite3TreeViewExpr(0, pTerm->pExpr, 0);
165649 }
165650 }
165651 SQLITE_PRIVATE void sqlite3ShowWhereTerm(WhereTerm *pTerm){
165652 sqlite3WhereTermPrint(pTerm, 0);
165653 }
165654 #endif
165655
165656 #ifdef WHERETRACE_ENABLED
165657 /*
@@ -166822,11 +166834,10 @@
166834 pParse = pWC->pWInfo->pParse;
166835 while( pWhere->op==TK_AND ){
166836 if( !whereUsablePartialIndex(iTab,jointype,pWC,pWhere->pLeft) ) return 0;
166837 pWhere = pWhere->pRight;
166838 }
 
166839 for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
166840 Expr *pExpr;
166841 pExpr = pTerm->pExpr;
166842 if( (!ExprHasProperty(pExpr, EP_OuterON) || pExpr->w.iJoin==iTab)
166843 && ((jointype & JT_OUTER)==0 || ExprHasProperty(pExpr, EP_OuterON))
@@ -169483,11 +169494,11 @@
169494 break;
169495 }
169496 }
169497 if( hasRightJoin
169498 && ExprHasProperty(pTerm->pExpr, EP_InnerON)
169499 && NEVER(pTerm->pExpr->w.iJoin==pItem->iCursor)
169500 ){
169501 break; /* restriction (5) */
169502 }
169503 }
169504 if( pTerm<pEnd ) continue;
@@ -170759,11 +170770,10 @@
170770 return;
170771 }
170772
170773 /************** End of where.c ***********************************************/
170774 /************** Begin file window.c ******************************************/
 
170775 /*
170776 ** 2018 May 08
170777 **
170778 ** The author disclaims copyright to this source code. In place of
170779 ** a legal notice, here is a blessing:
@@ -172432,10 +172442,11 @@
172442 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
172443 FuncDef *pFunc = pWin->pWFunc;
172444 int regArg;
172445 int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin);
172446 int i;
172447 int addrIf = 0;
172448
172449 assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED );
172450
172451 /* All OVER clauses in the same window function aggregate step must
172452 ** be the same. */
@@ -172447,10 +172458,22 @@
172458 }else{
172459 sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+i, reg+i);
172460 }
172461 }
172462 regArg = reg;
172463
172464 if( pWin->pFilter ){
172465 int regTmp;
172466 assert( ExprUseXList(pWin->pOwner) );
172467 assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr );
172468 assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 );
172469 regTmp = sqlite3GetTempReg(pParse);
172470 sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
172471 addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
172472 VdbeCoverage(v);
172473 sqlite3ReleaseTempReg(pParse, regTmp);
172474 }
172475
172476 if( pMWin->regStartRowid==0
172477 && (pFunc->funcFlags & SQLITE_FUNC_MINMAX)
172478 && (pWin->eStart!=TK_UNBOUNDED)
172479 ){
@@ -172467,29 +172490,17 @@
172490 sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp);
172491 sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
172492 }
172493 sqlite3VdbeJumpHere(v, addrIsNull);
172494 }else if( pWin->regApp ){
172495 assert( pWin->pFilter==0 );
172496 assert( pFunc->zName==nth_valueName
172497 || pFunc->zName==first_valueName
172498 );
172499 assert( bInverse==0 || bInverse==1 );
172500 sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
172501 }else if( pFunc->xSFunc!=noopStepFunc ){
 
 
 
 
 
 
 
 
 
 
 
 
 
172502 if( pWin->bExprArgs ){
172503 int iOp = sqlite3VdbeCurrentAddr(v);
172504 int iEnd;
172505
172506 assert( ExprUseXList(pWin->pOwner) );
@@ -172516,12 +172527,13 @@
172527 sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF);
172528 sqlite3VdbeChangeP5(v, (u8)nArg);
172529 if( pWin->bExprArgs ){
172530 sqlite3ReleaseTempRange(pParse, regArg, nArg);
172531 }
 
172532 }
172533
172534 if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
172535 }
172536 }
172537
172538 /*
172539 ** Values that may be passed as the second argument to windowCodeOp().
@@ -173869,11 +173881,10 @@
173881
173882 #endif /* SQLITE_OMIT_WINDOWFUNC */
173883
173884 /************** End of window.c **********************************************/
173885 /************** Begin file parse.c *******************************************/
 
173886 /* This file is automatically generated by Lemon from input grammar
173887 ** source file "parse.y".
173888 */
173889 /*
173890 ** 2001-09-15
@@ -173893,11 +173904,10 @@
173904 ** That input file is processed by Lemon to generate a C-language
173905 ** implementation of a parser for the given grammar. You might be reading
173906 ** this comment as part of the translated C-code. Edits should be made
173907 ** to the original parse.y sources.
173908 */
 
173909
173910 /* #include "sqliteInt.h" */
173911
173912 /*
173913 ** Disable all error recovery processing in the parser push-down
@@ -173945,10 +173955,17 @@
173955 ** Then the "b" IdList records the list "a,b,c".
173956 */
173957 struct TrigEvent { int a; IdList * b; };
173958
173959 struct FrameBound { int eType; Expr *pExpr; };
173960
173961 /*
173962 ** Generate a syntax error
173963 */
173964 static void parserSyntaxError(Parse *pParse, Token *p){
173965 sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", p);
173966 }
173967
173968 /*
173969 ** Disable lookaside memory allocation for objects that might be
173970 ** shared across database connections.
173971 */
@@ -173977,11 +173994,10 @@
173994 sqlite3ExprListDelete(pParse->db, pOrderBy);
173995 sqlite3ExprDelete(pParse->db, pLimit);
173996 }
173997 #endif /* SQLITE_ENABLE_UPDATE_DELETE_LIMIT */
173998
 
173999
174000 /*
174001 ** For a compound SELECT statement, make sure p->pPrior->pNext==p for
174002 ** all elements in the list. And make sure list length does not exceed
174003 ** SQLITE_LIMIT_COMPOUND_SELECT.
@@ -174032,11 +174048,10 @@
174048 ** testing.
174049 */
174050 static void *parserStackRealloc(void *pOld, sqlite3_uint64 newSize){
174051 return sqlite3FaultSim(700) ? 0 : sqlite3_realloc(pOld, newSize);
174052 }
 
174053
174054
174055 /* Construct a new Expr object from a single token */
174056 static Expr *tokenExpr(Parse *pParse, int op, Token t){
174057 Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
@@ -174069,11 +174084,10 @@
174084 }
174085 }
174086 return p;
174087 }
174088
 
174089
174090 /* A routine to convert a binary TK_IS or TK_ISNOT expression into a
174091 ** unary TK_ISNULL or TK_NOTNULL expression. */
174092 static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){
174093 sqlite3 *db = pParse->db;
@@ -174081,11 +174095,10 @@
174095 pA->op = (u8)op;
174096 sqlite3ExprDelete(db, pA->pRight);
174097 pA->pRight = 0;
174098 }
174099 }
 
174100
174101 /* Add a single new term to an ExprList that is used to store a
174102 ** list of identifiers. Report an error if the ID list contains
174103 ** a COLLATE clause or an ASC or DESC keyword, except ignore the
174104 ** error while parsing a legacy schema.
@@ -174105,16 +174118,14 @@
174118 pIdToken->n, pIdToken->z);
174119 }
174120 sqlite3ExprListSetName(pParse, p, pIdToken, 1);
174121 return p;
174122 }
 
174123
174124 #if TK_SPAN>255
174125 # error too many tokens in the grammar
174126 #endif
 
174127 /**************** End of %include directives **********************************/
174128 /* These constants specify the various numeric values for terminal symbols.
174129 ***************** Begin token definitions *************************************/
174130 #ifndef TK_SEMI
174131 #define TK_SEMI 1
@@ -176295,13 +176306,11 @@
176306 case 240: /* selectnowith */
176307 case 241: /* oneselect */
176308 case 253: /* values */
176309 case 255: /* mvalues */
176310 {
 
176311 sqlite3SelectDelete(pParse->db, (yypminor->yy555));
 
176312 }
176313 break;
176314 case 217: /* term */
176315 case 218: /* expr */
176316 case 247: /* where_opt */
@@ -176312,13 +176321,11 @@
176321 case 285: /* vinto */
176322 case 292: /* when_clause */
176323 case 297: /* key_opt */
176324 case 314: /* filter_clause */
176325 {
 
176326 sqlite3ExprDelete(pParse->db, (yypminor->yy454));
 
176327 }
176328 break;
176329 case 222: /* eidlist_opt */
176330 case 232: /* sortlist */
176331 case 233: /* eidlist */
@@ -176331,82 +176338,64 @@
176338 case 270: /* setlist */
176339 case 279: /* paren_exprlist */
176340 case 281: /* case_exprlist */
176341 case 313: /* part_opt */
176342 {
 
176343 sqlite3ExprListDelete(pParse->db, (yypminor->yy14));
 
176344 }
176345 break;
176346 case 239: /* fullname */
176347 case 246: /* from */
176348 case 258: /* seltablist */
176349 case 259: /* stl_prefix */
176350 case 264: /* xfullname */
176351 {
 
176352 sqlite3SrcListDelete(pParse->db, (yypminor->yy203));
 
176353 }
176354 break;
176355 case 242: /* wqlist */
176356 {
 
176357 sqlite3WithDelete(pParse->db, (yypminor->yy59));
 
176358 }
176359 break;
176360 case 252: /* window_clause */
176361 case 309: /* windowdefn_list */
176362 {
 
176363 sqlite3WindowListDelete(pParse->db, (yypminor->yy211));
 
176364 }
176365 break;
176366 case 265: /* idlist */
176367 case 272: /* idlist_opt */
176368 {
 
176369 sqlite3IdListDelete(pParse->db, (yypminor->yy132));
 
176370 }
176371 break;
176372 case 275: /* filter_over */
176373 case 310: /* windowdefn */
176374 case 311: /* window */
176375 case 312: /* frame_opt */
176376 case 315: /* over_clause */
176377 {
 
176378 sqlite3WindowDelete(pParse->db, (yypminor->yy211));
 
176379 }
176380 break;
176381 case 288: /* trigger_cmd_list */
176382 case 293: /* trigger_cmd */
176383 {
 
176384 sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy427));
 
176385 }
176386 break;
176387 case 290: /* trigger_event */
176388 {
 
176389 sqlite3IdListDelete(pParse->db, (yypminor->yy286).b);
 
176390 }
176391 break;
176392 case 317: /* frame_bound */
176393 case 318: /* frame_bound_s */
176394 case 319: /* frame_bound_e */
176395 {
 
176396 sqlite3ExprDelete(pParse->db, (yypminor->yy509).pExpr);
 
176397 }
176398 break;
176399 /********* End destructor definitions *****************************************/
176400 default: break; /* If no destructor action specified: do nothing */
176401 }
@@ -176637,14 +176626,12 @@
176626 #endif
176627 while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
176628 /* Here code is inserted which will execute if the parser
176629 ** stack every overflows */
176630 /******** Begin %stack_overflow code ******************************************/
 
176631
176632 sqlite3OomFault(pParse->db);
 
176633 /******** End %stack_overflow code ********************************************/
176634 sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument var */
176635 sqlite3ParserCTX_STORE
176636 }
176637
@@ -177571,481 +177558,330 @@
177558 ** break;
177559 */
177560 /********** Begin reduce actions **********************************************/
177561 YYMINORTYPE yylhsminor;
177562 case 0: /* explain ::= EXPLAIN */
 
177563 { if( pParse->pReprepare==0 ) pParse->explain = 1; }
 
177564 break;
177565 case 1: /* explain ::= EXPLAIN QUERY PLAN */
 
177566 { if( pParse->pReprepare==0 ) pParse->explain = 2; }
 
177567 break;
177568 case 2: /* cmdx ::= cmd */
 
177569 { sqlite3FinishCoding(pParse); }
 
177570 break;
177571 case 3: /* cmd ::= BEGIN transtype trans_opt */
 
177572 {sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy144);}
 
177573 break;
177574 case 4: /* transtype ::= */
 
177575 {yymsp[1].minor.yy144 = TK_DEFERRED;}
 
177576 break;
177577 case 5: /* transtype ::= DEFERRED */
177578 case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
177579 case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
177580 case 324: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==324);
 
177581 {yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-X*/}
 
177582 break;
177583 case 8: /* cmd ::= COMMIT|END trans_opt */
177584 case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9);
 
177585 {sqlite3EndTransaction(pParse,yymsp[-1].major);}
 
177586 break;
177587 case 10: /* cmd ::= SAVEPOINT nm */
 
177588 {
177589 sqlite3Savepoint(pParse, SAVEPOINT_BEGIN, &yymsp[0].minor.yy0);
177590 }
 
177591 break;
177592 case 11: /* cmd ::= RELEASE savepoint_opt nm */
 
177593 {
177594 sqlite3Savepoint(pParse, SAVEPOINT_RELEASE, &yymsp[0].minor.yy0);
177595 }
 
177596 break;
177597 case 12: /* cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
 
177598 {
177599 sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0);
177600 }
 
177601 break;
177602 case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
 
177603 {
177604 sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy144,0,0,yymsp[-2].minor.yy144);
177605 }
 
177606 break;
177607 case 14: /* createkw ::= CREATE */
 
177608 {disableLookaside(pParse);}
 
177609 break;
177610 case 15: /* ifnotexists ::= */
177611 case 18: /* temp ::= */ yytestcase(yyruleno==18);
177612 case 47: /* autoinc ::= */ yytestcase(yyruleno==47);
177613 case 62: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==62);
177614 case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72);
177615 case 81: /* ifexists ::= */ yytestcase(yyruleno==81);
177616 case 100: /* distinct ::= */ yytestcase(yyruleno==100);
177617 case 246: /* collate ::= */ yytestcase(yyruleno==246);
 
177618 {yymsp[1].minor.yy144 = 0;}
 
177619 break;
177620 case 16: /* ifnotexists ::= IF NOT EXISTS */
 
177621 {yymsp[-2].minor.yy144 = 1;}
 
177622 break;
177623 case 17: /* temp ::= TEMP */
 
177624 {yymsp[0].minor.yy144 = pParse->db->init.busy==0;}
 
177625 break;
177626 case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_option_set */
 
177627 {
177628 sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy391,0);
177629 }
 
177630 break;
177631 case 20: /* create_table_args ::= AS select */
 
177632 {
177633 sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy555);
177634 sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy555);
177635 }
 
177636 break;
177637 case 21: /* table_option_set ::= */
 
177638 {yymsp[1].minor.yy391 = 0;}
 
177639 break;
177640 case 22: /* table_option_set ::= table_option_set COMMA table_option */
 
177641 {yylhsminor.yy391 = yymsp[-2].minor.yy391|yymsp[0].minor.yy391;}
 
177642 yymsp[-2].minor.yy391 = yylhsminor.yy391;
177643 break;
177644 case 23: /* table_option ::= WITHOUT nm */
 
177645 {
177646 if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
177647 yymsp[-1].minor.yy391 = TF_WithoutRowid | TF_NoVisibleRowid;
177648 }else{
177649 yymsp[-1].minor.yy391 = 0;
177650 sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
177651 }
177652 }
 
177653 break;
177654 case 24: /* table_option ::= nm */
 
177655 {
177656 if( yymsp[0].minor.yy0.n==6 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"strict",6)==0 ){
177657 yylhsminor.yy391 = TF_Strict;
177658 }else{
177659 yylhsminor.yy391 = 0;
177660 sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
177661 }
177662 }
 
177663 yymsp[0].minor.yy391 = yylhsminor.yy391;
177664 break;
177665 case 25: /* columnname ::= nm typetoken */
 
177666 {sqlite3AddColumn(pParse,yymsp[-1].minor.yy0,yymsp[0].minor.yy0);}
 
177667 break;
177668 case 26: /* typetoken ::= */
177669 case 65: /* conslist_opt ::= */ yytestcase(yyruleno==65);
177670 case 106: /* as ::= */ yytestcase(yyruleno==106);
 
177671 {yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;}
 
177672 break;
177673 case 27: /* typetoken ::= typename LP signed RP */
 
177674 {
177675 yymsp[-3].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z);
177676 }
 
177677 break;
177678 case 28: /* typetoken ::= typename LP signed COMMA signed RP */
 
177679 {
177680 yymsp[-5].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z);
177681 }
 
177682 break;
177683 case 29: /* typename ::= typename ID|STRING */
 
177684 {yymsp[-1].minor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
 
177685 break;
177686 case 30: /* scanpt ::= */
 
177687 {
177688 assert( yyLookahead!=YYNOCODE );
177689 yymsp[1].minor.yy168 = yyLookaheadToken.z;
177690 }
 
177691 break;
177692 case 31: /* scantok ::= */
 
177693 {
177694 assert( yyLookahead!=YYNOCODE );
177695 yymsp[1].minor.yy0 = yyLookaheadToken;
177696 }
 
177697 break;
177698 case 32: /* ccons ::= CONSTRAINT nm */
177699 case 67: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==67);
 
177700 {pParse->constraintName = yymsp[0].minor.yy0;}
 
177701 break;
177702 case 33: /* ccons ::= DEFAULT scantok term */
 
177703 {sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
 
177704 break;
177705 case 34: /* ccons ::= DEFAULT LP expr RP */
 
177706 {sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy454,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
 
177707 break;
177708 case 35: /* ccons ::= DEFAULT PLUS scantok term */
 
177709 {sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
 
177710 break;
177711 case 36: /* ccons ::= DEFAULT MINUS scantok term */
 
177712 {
177713 Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy454, 0);
177714 sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);
177715 }
 
177716 break;
177717 case 37: /* ccons ::= DEFAULT scantok ID|INDEXED */
 
177718 {
177719 Expr *p = tokenExpr(pParse, TK_STRING, yymsp[0].minor.yy0);
177720 if( p ){
177721 sqlite3ExprIdToTrueFalse(p);
177722 testcase( p->op==TK_TRUEFALSE && sqlite3ExprTruthValue(p) );
177723 }
177724 sqlite3AddDefaultValue(pParse,p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.z+yymsp[0].minor.yy0.n);
177725 }
 
177726 break;
177727 case 38: /* ccons ::= NOT NULL onconf */
 
177728 {sqlite3AddNotNull(pParse, yymsp[0].minor.yy144);}
 
177729 break;
177730 case 39: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
 
177731 {sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy144,yymsp[0].minor.yy144,yymsp[-2].minor.yy144);}
 
177732 break;
177733 case 40: /* ccons ::= UNIQUE onconf */
 
177734 {sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy144,0,0,0,0,
177735 SQLITE_IDXTYPE_UNIQUE);}
 
177736 break;
177737 case 41: /* ccons ::= CHECK LP expr RP */
 
177738 {sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy454,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);}
 
177739 break;
177740 case 42: /* ccons ::= REFERENCES nm eidlist_opt refargs */
 
177741 {sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy14,yymsp[0].minor.yy144);}
 
177742 break;
177743 case 43: /* ccons ::= defer_subclause */
 
177744 {sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy144);}
 
177745 break;
177746 case 44: /* ccons ::= COLLATE ID|STRING */
 
177747 {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
 
177748 break;
177749 case 45: /* generated ::= LP expr RP */
 
177750 {sqlite3AddGenerated(pParse,yymsp[-1].minor.yy454,0);}
 
177751 break;
177752 case 46: /* generated ::= LP expr RP ID */
 
177753 {sqlite3AddGenerated(pParse,yymsp[-2].minor.yy454,&yymsp[0].minor.yy0);}
 
177754 break;
177755 case 48: /* autoinc ::= AUTOINCR */
 
177756 {yymsp[0].minor.yy144 = 1;}
 
177757 break;
177758 case 49: /* refargs ::= */
 
177759 { yymsp[1].minor.yy144 = OE_None*0x0101; /* EV: R-19803-45884 */}
 
177760 break;
177761 case 50: /* refargs ::= refargs refarg */
 
177762 { yymsp[-1].minor.yy144 = (yymsp[-1].minor.yy144 & ~yymsp[0].minor.yy383.mask) | yymsp[0].minor.yy383.value; }
 
177763 break;
177764 case 51: /* refarg ::= MATCH nm */
 
177765 { yymsp[-1].minor.yy383.value = 0; yymsp[-1].minor.yy383.mask = 0x000000; }
 
177766 break;
177767 case 52: /* refarg ::= ON INSERT refact */
 
177768 { yymsp[-2].minor.yy383.value = 0; yymsp[-2].minor.yy383.mask = 0x000000; }
 
177769 break;
177770 case 53: /* refarg ::= ON DELETE refact */
 
177771 { yymsp[-2].minor.yy383.value = yymsp[0].minor.yy144; yymsp[-2].minor.yy383.mask = 0x0000ff; }
 
177772 break;
177773 case 54: /* refarg ::= ON UPDATE refact */
 
177774 { yymsp[-2].minor.yy383.value = yymsp[0].minor.yy144<<8; yymsp[-2].minor.yy383.mask = 0x00ff00; }
 
177775 break;
177776 case 55: /* refact ::= SET NULL */
 
177777 { yymsp[-1].minor.yy144 = OE_SetNull; /* EV: R-33326-45252 */}
 
177778 break;
177779 case 56: /* refact ::= SET DEFAULT */
 
177780 { yymsp[-1].minor.yy144 = OE_SetDflt; /* EV: R-33326-45252 */}
 
177781 break;
177782 case 57: /* refact ::= CASCADE */
 
177783 { yymsp[0].minor.yy144 = OE_Cascade; /* EV: R-33326-45252 */}
 
177784 break;
177785 case 58: /* refact ::= RESTRICT */
 
177786 { yymsp[0].minor.yy144 = OE_Restrict; /* EV: R-33326-45252 */}
 
177787 break;
177788 case 59: /* refact ::= NO ACTION */
 
177789 { yymsp[-1].minor.yy144 = OE_None; /* EV: R-33326-45252 */}
 
177790 break;
177791 case 60: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
 
177792 {yymsp[-2].minor.yy144 = 0;}
 
177793 break;
177794 case 61: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
177795 case 76: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==76);
177796 case 173: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==173);
 
177797 {yymsp[-1].minor.yy144 = yymsp[0].minor.yy144;}
 
177798 break;
177799 case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
177800 case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80);
177801 case 219: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==219);
177802 case 222: /* in_op ::= NOT IN */ yytestcase(yyruleno==222);
177803 case 247: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==247);
 
177804 {yymsp[-1].minor.yy144 = 1;}
 
177805 break;
177806 case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
 
177807 {yymsp[-1].minor.yy144 = 0;}
 
177808 break;
177809 case 66: /* tconscomma ::= COMMA */
 
177810 {pParse->constraintName.n = 0;}
 
177811 break;
177812 case 68: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
 
177813 {sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy14,yymsp[0].minor.yy144,yymsp[-2].minor.yy144,0);}
 
177814 break;
177815 case 69: /* tcons ::= UNIQUE LP sortlist RP onconf */
 
177816 {sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy14,yymsp[0].minor.yy144,0,0,0,0,
177817 SQLITE_IDXTYPE_UNIQUE);}
 
177818 break;
177819 case 70: /* tcons ::= CHECK LP expr RP onconf */
 
177820 {sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy454,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);}
 
177821 break;
177822 case 71: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
 
177823 {
177824 sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy14, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[-1].minor.yy144);
177825 sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy144);
177826 }
 
177827 break;
177828 case 73: /* onconf ::= */
177829 case 75: /* orconf ::= */ yytestcase(yyruleno==75);
 
177830 {yymsp[1].minor.yy144 = OE_Default;}
 
177831 break;
177832 case 74: /* onconf ::= ON CONFLICT resolvetype */
 
177833 {yymsp[-2].minor.yy144 = yymsp[0].minor.yy144;}
 
177834 break;
177835 case 77: /* resolvetype ::= IGNORE */
 
177836 {yymsp[0].minor.yy144 = OE_Ignore;}
 
177837 break;
177838 case 78: /* resolvetype ::= REPLACE */
177839 case 174: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==174);
 
177840 {yymsp[0].minor.yy144 = OE_Replace;}
 
177841 break;
177842 case 79: /* cmd ::= DROP TABLE ifexists fullname */
 
177843 {
177844 sqlite3DropTable(pParse, yymsp[0].minor.yy203, 0, yymsp[-1].minor.yy144);
177845 }
 
177846 break;
177847 case 82: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
 
177848 {
177849 sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[0].minor.yy555, yymsp[-7].minor.yy144, yymsp[-5].minor.yy144);
177850 }
 
177851 break;
177852 case 83: /* cmd ::= DROP VIEW ifexists fullname */
 
177853 {
177854 sqlite3DropTable(pParse, yymsp[0].minor.yy203, 1, yymsp[-1].minor.yy144);
177855 }
 
177856 break;
177857 case 84: /* cmd ::= select */
 
177858 {
177859 SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0};
177860 if( (pParse->db->mDbFlags & DBFLAG_EncodingFixed)!=0
177861 || sqlite3ReadSchema(pParse)==SQLITE_OK
177862 ){
177863 sqlite3Select(pParse, yymsp[0].minor.yy555, &dest);
177864 }
177865 sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy555);
177866 }
 
177867 break;
177868 case 85: /* select ::= WITH wqlist selectnowith */
 
177869 {yymsp[-2].minor.yy555 = attachWithToSelect(pParse,yymsp[0].minor.yy555,yymsp[-1].minor.yy59);}
 
177870 break;
177871 case 86: /* select ::= WITH RECURSIVE wqlist selectnowith */
 
177872 {yymsp[-3].minor.yy555 = attachWithToSelect(pParse,yymsp[0].minor.yy555,yymsp[-1].minor.yy59);}
 
177873 break;
177874 case 87: /* select ::= selectnowith */
 
177875 {
177876 Select *p = yymsp[0].minor.yy555;
177877 if( p ){
177878 parserDoubleLinkSelect(pParse, p);
177879 }
177880 }
 
177881 break;
177882 case 88: /* selectnowith ::= selectnowith multiselect_op oneselect */
 
177883 {
177884 Select *pRhs = yymsp[0].minor.yy555;
177885 Select *pLhs = yymsp[-2].minor.yy555;
177886 if( pRhs && pRhs->pPrior ){
177887 SrcList *pFrom;
@@ -178064,175 +177900,131 @@
177900 }else{
177901 sqlite3SelectDelete(pParse->db, pLhs);
177902 }
177903 yymsp[-2].minor.yy555 = pRhs;
177904 }
 
177905 break;
177906 case 89: /* multiselect_op ::= UNION */
177907 case 91: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==91);
 
177908 {yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-OP*/}
 
177909 break;
177910 case 90: /* multiselect_op ::= UNION ALL */
 
177911 {yymsp[-1].minor.yy144 = TK_ALL;}
 
177912 break;
177913 case 92: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
 
177914 {
177915 yymsp[-8].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy203,yymsp[-4].minor.yy454,yymsp[-3].minor.yy14,yymsp[-2].minor.yy454,yymsp[-1].minor.yy14,yymsp[-7].minor.yy144,yymsp[0].minor.yy454);
177916 }
 
177917 break;
177918 case 93: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
 
177919 {
177920 yymsp[-9].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy14,yymsp[-6].minor.yy203,yymsp[-5].minor.yy454,yymsp[-4].minor.yy14,yymsp[-3].minor.yy454,yymsp[-1].minor.yy14,yymsp[-8].minor.yy144,yymsp[0].minor.yy454);
177921 if( yymsp[-9].minor.yy555 ){
177922 yymsp[-9].minor.yy555->pWinDefn = yymsp[-2].minor.yy211;
177923 }else{
177924 sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy211);
177925 }
177926 }
 
177927 break;
177928 case 94: /* values ::= VALUES LP nexprlist RP */
 
177929 {
177930 yymsp[-3].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0);
177931 }
 
177932 break;
177933 case 95: /* oneselect ::= mvalues */
 
177934 {
177935 sqlite3MultiValuesEnd(pParse, yymsp[0].minor.yy555);
177936 }
 
177937 break;
177938 case 96: /* mvalues ::= values COMMA LP nexprlist RP */
177939 case 97: /* mvalues ::= mvalues COMMA LP nexprlist RP */ yytestcase(yyruleno==97);
 
177940 {
177941 yymsp[-4].minor.yy555 = sqlite3MultiValues(pParse, yymsp[-4].minor.yy555, yymsp[-1].minor.yy14);
177942 }
 
177943 break;
177944 case 98: /* distinct ::= DISTINCT */
 
177945 {yymsp[0].minor.yy144 = SF_Distinct;}
 
177946 break;
177947 case 99: /* distinct ::= ALL */
 
177948 {yymsp[0].minor.yy144 = SF_All;}
 
177949 break;
177950 case 101: /* sclp ::= */
177951 case 134: /* orderby_opt ::= */ yytestcase(yyruleno==134);
177952 case 144: /* groupby_opt ::= */ yytestcase(yyruleno==144);
177953 case 234: /* exprlist ::= */ yytestcase(yyruleno==234);
177954 case 237: /* paren_exprlist ::= */ yytestcase(yyruleno==237);
177955 case 242: /* eidlist_opt ::= */ yytestcase(yyruleno==242);
 
177956 {yymsp[1].minor.yy14 = 0;}
 
177957 break;
177958 case 102: /* selcollist ::= sclp scanpt expr scanpt as */
 
177959 {
177960 yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[-2].minor.yy454);
177961 if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy14, &yymsp[0].minor.yy0, 1);
177962 sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy14,yymsp[-3].minor.yy168,yymsp[-1].minor.yy168);
177963 }
 
177964 break;
177965 case 103: /* selcollist ::= sclp scanpt STAR */
 
177966 {
177967 Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
177968 sqlite3ExprSetErrorOffset(p, (int)(yymsp[0].minor.yy0.z - pParse->zTail));
177969 yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy14, p);
177970 }
 
177971 break;
177972 case 104: /* selcollist ::= sclp scanpt nm DOT STAR */
 
177973 {
177974 Expr *pRight, *pLeft, *pDot;
177975 pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
177976 sqlite3ExprSetErrorOffset(pRight, (int)(yymsp[0].minor.yy0.z - pParse->zTail));
177977 pLeft = tokenExpr(pParse, TK_ID, yymsp[-2].minor.yy0);
177978 pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
177979 yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, pDot);
177980 }
 
177981 break;
177982 case 105: /* as ::= AS nm */
177983 case 117: /* dbnm ::= DOT nm */ yytestcase(yyruleno==117);
177984 case 258: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==258);
177985 case 259: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==259);
 
177986 {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
 
177987 break;
177988 case 107: /* from ::= */
177989 case 110: /* stl_prefix ::= */ yytestcase(yyruleno==110);
 
177990 {yymsp[1].minor.yy203 = 0;}
 
177991 break;
177992 case 108: /* from ::= FROM seltablist */
 
177993 {
177994 yymsp[-1].minor.yy203 = yymsp[0].minor.yy203;
177995 sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy203);
177996 }
 
177997 break;
177998 case 109: /* stl_prefix ::= seltablist joinop */
 
177999 {
178000 if( ALWAYS(yymsp[-1].minor.yy203 && yymsp[-1].minor.yy203->nSrc>0) ) yymsp[-1].minor.yy203->a[yymsp[-1].minor.yy203->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy144;
178001 }
 
178002 break;
178003 case 111: /* seltablist ::= stl_prefix nm dbnm as on_using */
 
178004 {
178005 yymsp[-4].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy203,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269);
178006 }
 
178007 break;
178008 case 112: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
 
178009 {
178010 yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy269);
178011 sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy203, &yymsp[-1].minor.yy0);
178012 }
 
178013 break;
178014 case 113: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
 
178015 {
178016 yymsp[-7].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy203,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269);
178017 sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy203, yymsp[-3].minor.yy14);
178018 }
 
178019 break;
178020 case 114: /* seltablist ::= stl_prefix LP select RP as on_using */
 
178021 {
178022 yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy555,&yymsp[0].minor.yy269);
178023 }
 
178024 break;
178025 case 115: /* seltablist ::= stl_prefix LP seltablist RP as on_using */
 
178026 {
178027 if( yymsp[-5].minor.yy203==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy269.pOn==0 && yymsp[0].minor.yy269.pUsing==0 ){
178028 yymsp[-5].minor.yy203 = yymsp[-3].minor.yy203;
178029 }else if( ALWAYS(yymsp[-3].minor.yy203!=0) && yymsp[-3].minor.yy203->nSrc==1 ){
178030 yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269);
@@ -178269,210 +178061,144 @@
178061 sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy203);
178062 pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy203,0,0,0,0,SF_NestedFrom,0);
178063 yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy269);
178064 }
178065 }
 
178066 break;
178067 case 116: /* dbnm ::= */
178068 case 131: /* indexed_opt ::= */ yytestcase(yyruleno==131);
 
178069 {yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;}
 
178070 break;
178071 case 118: /* fullname ::= nm */
 
178072 {
178073 yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0);
178074 if( IN_RENAME_OBJECT && yylhsminor.yy203 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[0].minor.yy0);
178075 }
 
178076 yymsp[0].minor.yy203 = yylhsminor.yy203;
178077 break;
178078 case 119: /* fullname ::= nm DOT nm */
 
178079 {
178080 yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
178081 if( IN_RENAME_OBJECT && yylhsminor.yy203 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[0].minor.yy0);
178082 }
 
178083 yymsp[-2].minor.yy203 = yylhsminor.yy203;
178084 break;
178085 case 120: /* xfullname ::= nm */
 
178086 {yymsp[0].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
 
178087 break;
178088 case 121: /* xfullname ::= nm DOT nm */
 
178089 {yymsp[-2].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
 
178090 break;
178091 case 122: /* xfullname ::= nm DOT nm AS nm */
 
178092 {
178093 yymsp[-4].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
178094 if( yymsp[-4].minor.yy203 ) yymsp[-4].minor.yy203->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
178095 }
 
178096 break;
178097 case 123: /* xfullname ::= nm AS nm */
 
178098 {
178099 yymsp[-2].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
178100 if( yymsp[-2].minor.yy203 ) yymsp[-2].minor.yy203->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
178101 }
 
178102 break;
178103 case 124: /* joinop ::= COMMA|JOIN */
 
178104 { yymsp[0].minor.yy144 = JT_INNER; }
 
178105 break;
178106 case 125: /* joinop ::= JOIN_KW JOIN */
 
178107 {yymsp[-1].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/}
 
178108 break;
178109 case 126: /* joinop ::= JOIN_KW nm JOIN */
 
178110 {yymsp[-2].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
 
178111 break;
178112 case 127: /* joinop ::= JOIN_KW nm nm JOIN */
 
178113 {yymsp[-3].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
 
178114 break;
178115 case 128: /* on_using ::= ON expr */
 
178116 {yymsp[-1].minor.yy269.pOn = yymsp[0].minor.yy454; yymsp[-1].minor.yy269.pUsing = 0;}
 
178117 break;
178118 case 129: /* on_using ::= USING LP idlist RP */
 
178119 {yymsp[-3].minor.yy269.pOn = 0; yymsp[-3].minor.yy269.pUsing = yymsp[-1].minor.yy132;}
 
178120 break;
178121 case 130: /* on_using ::= */
 
178122 {yymsp[1].minor.yy269.pOn = 0; yymsp[1].minor.yy269.pUsing = 0;}
 
178123 break;
178124 case 132: /* indexed_by ::= INDEXED BY nm */
 
178125 {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
 
178126 break;
178127 case 133: /* indexed_by ::= NOT INDEXED */
 
178128 {yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
 
178129 break;
178130 case 135: /* orderby_opt ::= ORDER BY sortlist */
178131 case 145: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==145);
 
178132 {yymsp[-2].minor.yy14 = yymsp[0].minor.yy14;}
 
178133 break;
178134 case 136: /* sortlist ::= sortlist COMMA expr sortorder nulls */
 
178135 {
178136 yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14,yymsp[-2].minor.yy454);
178137 sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy14,yymsp[-1].minor.yy144,yymsp[0].minor.yy144);
178138 }
 
178139 break;
178140 case 137: /* sortlist ::= expr sortorder nulls */
 
178141 {
178142 yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy454); /*A-overwrites-Y*/
178143 sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy14,yymsp[-1].minor.yy144,yymsp[0].minor.yy144);
178144 }
 
178145 break;
178146 case 138: /* sortorder ::= ASC */
 
178147 {yymsp[0].minor.yy144 = SQLITE_SO_ASC;}
 
178148 break;
178149 case 139: /* sortorder ::= DESC */
 
178150 {yymsp[0].minor.yy144 = SQLITE_SO_DESC;}
 
178151 break;
178152 case 140: /* sortorder ::= */
178153 case 143: /* nulls ::= */ yytestcase(yyruleno==143);
 
178154 {yymsp[1].minor.yy144 = SQLITE_SO_UNDEFINED;}
 
178155 break;
178156 case 141: /* nulls ::= NULLS FIRST */
 
178157 {yymsp[-1].minor.yy144 = SQLITE_SO_ASC;}
 
178158 break;
178159 case 142: /* nulls ::= NULLS LAST */
 
178160 {yymsp[-1].minor.yy144 = SQLITE_SO_DESC;}
 
178161 break;
178162 case 146: /* having_opt ::= */
178163 case 148: /* limit_opt ::= */ yytestcase(yyruleno==148);
178164 case 153: /* where_opt ::= */ yytestcase(yyruleno==153);
178165 case 155: /* where_opt_ret ::= */ yytestcase(yyruleno==155);
178166 case 232: /* case_else ::= */ yytestcase(yyruleno==232);
178167 case 233: /* case_operand ::= */ yytestcase(yyruleno==233);
178168 case 252: /* vinto ::= */ yytestcase(yyruleno==252);
 
178169 {yymsp[1].minor.yy454 = 0;}
 
178170 break;
178171 case 147: /* having_opt ::= HAVING expr */
178172 case 154: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==154);
178173 case 156: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==156);
178174 case 231: /* case_else ::= ELSE expr */ yytestcase(yyruleno==231);
178175 case 251: /* vinto ::= INTO expr */ yytestcase(yyruleno==251);
 
178176 {yymsp[-1].minor.yy454 = yymsp[0].minor.yy454;}
 
178177 break;
178178 case 149: /* limit_opt ::= LIMIT expr */
 
178179 {yymsp[-1].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy454,0);}
 
178180 break;
178181 case 150: /* limit_opt ::= LIMIT expr OFFSET expr */
 
178182 {yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);}
 
178183 break;
178184 case 151: /* limit_opt ::= LIMIT expr COMMA expr */
 
178185 {yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy454,yymsp[-2].minor.yy454);}
 
178186 break;
178187 case 152: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */
 
178188 {
178189 sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy203, &yymsp[-1].minor.yy0);
178190 sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy203,yymsp[0].minor.yy454,0,0);
178191 }
 
178192 break;
178193 case 157: /* where_opt_ret ::= RETURNING selcollist */
 
178194 {sqlite3AddReturning(pParse,yymsp[0].minor.yy14); yymsp[-1].minor.yy454 = 0;}
 
178195 break;
178196 case 158: /* where_opt_ret ::= WHERE expr RETURNING selcollist */
 
178197 {sqlite3AddReturning(pParse,yymsp[0].minor.yy14); yymsp[-3].minor.yy454 = yymsp[-2].minor.yy454;}
 
178198 break;
178199 case 159: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
 
178200 {
178201 sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy203, &yymsp[-4].minor.yy0);
178202 sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy14,"set list");
178203 if( yymsp[-1].minor.yy203 ){
178204 SrcList *pFromClause = yymsp[-1].minor.yy203;
@@ -178486,134 +178212,92 @@
178212 }
178213 yymsp[-5].minor.yy203 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy203, pFromClause);
178214 }
178215 sqlite3Update(pParse,yymsp[-5].minor.yy203,yymsp[-2].minor.yy14,yymsp[0].minor.yy454,yymsp[-6].minor.yy144,0,0,0);
178216 }
 
178217 break;
178218 case 160: /* setlist ::= setlist COMMA nm EQ expr */
 
178219 {
178220 yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[0].minor.yy454);
178221 sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy14, &yymsp[-2].minor.yy0, 1);
178222 }
 
178223 break;
178224 case 161: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
 
178225 {
178226 yymsp[-6].minor.yy14 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy14, yymsp[-3].minor.yy132, yymsp[0].minor.yy454);
178227 }
 
178228 break;
178229 case 162: /* setlist ::= nm EQ expr */
 
178230 {
178231 yylhsminor.yy14 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy454);
178232 sqlite3ExprListSetName(pParse, yylhsminor.yy14, &yymsp[-2].minor.yy0, 1);
178233 }
 
178234 yymsp[-2].minor.yy14 = yylhsminor.yy14;
178235 break;
178236 case 163: /* setlist ::= LP idlist RP EQ expr */
 
178237 {
178238 yymsp[-4].minor.yy14 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy132, yymsp[0].minor.yy454);
178239 }
 
178240 break;
178241 case 164: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
 
178242 {
178243 sqlite3Insert(pParse, yymsp[-3].minor.yy203, yymsp[-1].minor.yy555, yymsp[-2].minor.yy132, yymsp[-5].minor.yy144, yymsp[0].minor.yy122);
178244 }
 
178245 break;
178246 case 165: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */
 
178247 {
178248 sqlite3Insert(pParse, yymsp[-4].minor.yy203, 0, yymsp[-3].minor.yy132, yymsp[-6].minor.yy144, 0);
178249 }
 
178250 break;
178251 case 166: /* upsert ::= */
 
178252 { yymsp[1].minor.yy122 = 0; }
 
178253 break;
178254 case 167: /* upsert ::= RETURNING selcollist */
 
178255 { yymsp[-1].minor.yy122 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy14); }
 
178256 break;
178257 case 168: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */
 
178258 { yymsp[-11].minor.yy122 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy14,yymsp[-6].minor.yy454,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454,yymsp[0].minor.yy122);}
 
178259 break;
178260 case 169: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */
 
178261 { yymsp[-8].minor.yy122 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy14,yymsp[-3].minor.yy454,0,0,yymsp[0].minor.yy122); }
 
178262 break;
178263 case 170: /* upsert ::= ON CONFLICT DO NOTHING returning */
 
178264 { yymsp[-4].minor.yy122 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); }
 
178265 break;
178266 case 171: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
 
178267 { yymsp[-7].minor.yy122 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454,0);}
 
178268 break;
178269 case 172: /* returning ::= RETURNING selcollist */
 
178270 {sqlite3AddReturning(pParse,yymsp[0].minor.yy14);}
 
178271 break;
178272 case 175: /* idlist_opt ::= */
 
178273 {yymsp[1].minor.yy132 = 0;}
 
178274 break;
178275 case 176: /* idlist_opt ::= LP idlist RP */
 
178276 {yymsp[-2].minor.yy132 = yymsp[-1].minor.yy132;}
 
178277 break;
178278 case 177: /* idlist ::= idlist COMMA nm */
 
178279 {yymsp[-2].minor.yy132 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy132,&yymsp[0].minor.yy0);}
 
178280 break;
178281 case 178: /* idlist ::= nm */
 
178282 {yymsp[0].minor.yy132 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
 
178283 break;
178284 case 179: /* expr ::= LP expr RP */
 
178285 {yymsp[-2].minor.yy454 = yymsp[-1].minor.yy454;}
 
178286 break;
178287 case 180: /* expr ::= ID|INDEXED|JOIN_KW */
 
178288 {yymsp[0].minor.yy454=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
 
178289 break;
178290 case 181: /* expr ::= nm DOT nm */
 
178291 {
178292 Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0);
178293 Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0);
178294 yylhsminor.yy454 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
178295 }
 
178296 yymsp[-2].minor.yy454 = yylhsminor.yy454;
178297 break;
178298 case 182: /* expr ::= nm DOT nm DOT nm */
 
178299 {
178300 Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-4].minor.yy0);
178301 Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0);
178302 Expr *temp3 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0);
178303 Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
@@ -178620,30 +178304,24 @@
178304 if( IN_RENAME_OBJECT ){
178305 sqlite3RenameTokenRemap(pParse, 0, temp1);
178306 }
178307 yylhsminor.yy454 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
178308 }
 
178309 yymsp[-4].minor.yy454 = yylhsminor.yy454;
178310 break;
178311 case 183: /* term ::= NULL|FLOAT|BLOB */
178312 case 184: /* term ::= STRING */ yytestcase(yyruleno==184);
 
178313 {yymsp[0].minor.yy454=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
 
178314 break;
178315 case 185: /* term ::= INTEGER */
 
178316 {
178317 yylhsminor.yy454 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
178318 if( yylhsminor.yy454 ) yylhsminor.yy454->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail);
178319 }
 
178320 yymsp[0].minor.yy454 = yylhsminor.yy454;
178321 break;
178322 case 186: /* expr ::= VARIABLE */
 
178323 {
178324 if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){
178325 u32 n = yymsp[0].minor.yy0.n;
178326 yymsp[0].minor.yy454 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
178327 sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy454, n);
@@ -178652,98 +178330,78 @@
178330 ** that look like this: #1 #2 ... These terms refer to registers
178331 ** in the virtual machine. #N is the N-th register. */
178332 Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/
178333 assert( t.n>=2 );
178334 if( pParse->nested==0 ){
178335 parserSyntaxError(pParse, &t);
178336 yymsp[0].minor.yy454 = 0;
178337 }else{
178338 yymsp[0].minor.yy454 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
178339 if( yymsp[0].minor.yy454 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy454->iTable);
178340 }
178341 }
178342 }
 
178343 break;
178344 case 187: /* expr ::= expr COLLATE ID|STRING */
 
178345 {
178346 yymsp[-2].minor.yy454 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy454, &yymsp[0].minor.yy0, 1);
178347 }
 
178348 break;
178349 case 188: /* expr ::= CAST LP expr AS typetoken RP */
 
178350 {
178351 yymsp[-5].minor.yy454 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
178352 sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy454, yymsp[-3].minor.yy454, 0);
178353 }
 
178354 break;
178355 case 189: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
 
178356 {
178357 yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy144);
178358 }
 
178359 yymsp[-4].minor.yy454 = yylhsminor.yy454;
178360 break;
178361 case 190: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */
 
178362 {
178363 yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-4].minor.yy14, &yymsp[-7].minor.yy0, yymsp[-5].minor.yy144);
178364 sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy454, yymsp[-1].minor.yy14);
178365 }
 
178366 yymsp[-7].minor.yy454 = yylhsminor.yy454;
178367 break;
178368 case 191: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
 
178369 {
178370 yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0);
178371 }
 
178372 yymsp[-3].minor.yy454 = yylhsminor.yy454;
178373 break;
178374 case 192: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
 
178375 {
178376 yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy14, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy144);
178377 sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211);
178378 }
 
178379 yymsp[-5].minor.yy454 = yylhsminor.yy454;
178380 break;
178381 case 193: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */
 
178382 {
178383 yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-5].minor.yy14, &yymsp[-8].minor.yy0, yymsp[-6].minor.yy144);
178384 sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211);
178385 sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy454, yymsp[-2].minor.yy14);
178386 }
 
178387 yymsp[-8].minor.yy454 = yylhsminor.yy454;
178388 break;
178389 case 194: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
 
178390 {
178391 yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
178392 sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211);
178393 }
 
178394 yymsp[-4].minor.yy454 = yylhsminor.yy454;
178395 break;
178396 case 195: /* term ::= CTIME_KW */
 
178397 {
178398 yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0);
178399 }
 
178400 yymsp[0].minor.yy454 = yylhsminor.yy454;
178401 break;
178402 case 196: /* expr ::= LP nexprlist COMMA expr RP */
 
178403 {
178404 ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454);
178405 yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
178406 if( yymsp[-4].minor.yy454 ){
178407 yymsp[-4].minor.yy454->x.pList = pList;
@@ -178752,35 +178410,27 @@
178410 }
178411 }else{
178412 sqlite3ExprListDelete(pParse->db, pList);
178413 }
178414 }
 
178415 break;
178416 case 197: /* expr ::= expr AND expr */
 
178417 {yymsp[-2].minor.yy454=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);}
 
178418 break;
178419 case 198: /* expr ::= expr OR expr */
178420 case 199: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==199);
178421 case 200: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==200);
178422 case 201: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==201);
178423 case 202: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==202);
178424 case 203: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==203);
178425 case 204: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==204);
 
178426 {yymsp[-2].minor.yy454=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);}
 
178427 break;
178428 case 205: /* likeop ::= NOT LIKE_KW|MATCH */
 
178429 {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/}
 
178430 break;
178431 case 206: /* expr ::= expr likeop expr */
 
178432 {
178433 ExprList *pList;
178434 int bNot = yymsp[-1].minor.yy0.n & 0x80000000;
178435 yymsp[-1].minor.yy0.n &= 0x7fffffff;
178436 pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy454);
@@ -178787,14 +178437,12 @@
178437 pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy454);
178438 yymsp[-2].minor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
178439 if( bNot ) yymsp[-2].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy454, 0);
178440 if( yymsp[-2].minor.yy454 ) yymsp[-2].minor.yy454->flags |= EP_InfixFunc;
178441 }
 
178442 break;
178443 case 207: /* expr ::= expr likeop expr ESCAPE expr */
 
178444 {
178445 ExprList *pList;
178446 int bNot = yymsp[-3].minor.yy0.n & 0x80000000;
178447 yymsp[-3].minor.yy0.n &= 0x7fffffff;
178448 pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454);
@@ -178802,62 +178450,46 @@
178450 pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy454);
178451 yymsp[-4].minor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0);
178452 if( bNot ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
178453 if( yymsp[-4].minor.yy454 ) yymsp[-4].minor.yy454->flags |= EP_InfixFunc;
178454 }
 
178455 break;
178456 case 208: /* expr ::= expr ISNULL|NOTNULL */
 
178457 {yymsp[-1].minor.yy454 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy454,0);}
 
178458 break;
178459 case 209: /* expr ::= expr NOT NULL */
 
178460 {yymsp[-2].minor.yy454 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy454,0);}
 
178461 break;
178462 case 210: /* expr ::= expr IS expr */
 
178463 {
178464 yymsp[-2].minor.yy454 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);
178465 binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-2].minor.yy454, TK_ISNULL);
178466 }
 
178467 break;
178468 case 211: /* expr ::= expr IS NOT expr */
 
178469 {
178470 yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy454,yymsp[0].minor.yy454);
178471 binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-3].minor.yy454, TK_NOTNULL);
178472 }
 
178473 break;
178474 case 212: /* expr ::= expr IS NOT DISTINCT FROM expr */
 
178475 {
178476 yymsp[-5].minor.yy454 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy454,yymsp[0].minor.yy454);
178477 binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-5].minor.yy454, TK_ISNULL);
178478 }
 
178479 break;
178480 case 213: /* expr ::= expr IS DISTINCT FROM expr */
 
178481 {
178482 yymsp[-4].minor.yy454 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy454,yymsp[0].minor.yy454);
178483 binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-4].minor.yy454, TK_NOTNULL);
178484 }
 
178485 break;
178486 case 214: /* expr ::= NOT expr */
178487 case 215: /* expr ::= BITNOT expr */ yytestcase(yyruleno==215);
 
178488 {yymsp[-1].minor.yy454 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy454, 0);/*A-overwrites-B*/}
 
178489 break;
178490 case 216: /* expr ::= PLUS|MINUS expr */
 
178491 {
178492 Expr *p = yymsp[0].minor.yy454;
178493 u8 op = yymsp[-1].major + (TK_UPLUS-TK_PLUS);
178494 assert( TK_UPLUS>TK_PLUS );
178495 assert( TK_UMINUS == TK_MINUS + (TK_UPLUS - TK_PLUS) );
@@ -178867,30 +178499,24 @@
178499 }else{
178500 yymsp[-1].minor.yy454 = sqlite3PExpr(pParse, op, p, 0);
178501 /*A-overwrites-B*/
178502 }
178503 }
 
178504 break;
178505 case 217: /* expr ::= expr PTR expr */
 
178506 {
178507 ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy454);
178508 pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy454);
178509 yylhsminor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
178510 }
 
178511 yymsp[-2].minor.yy454 = yylhsminor.yy454;
178512 break;
178513 case 218: /* between_op ::= BETWEEN */
178514 case 221: /* in_op ::= IN */ yytestcase(yyruleno==221);
 
178515 {yymsp[0].minor.yy144 = 0;}
 
178516 break;
178517 case 220: /* expr ::= expr between_op expr AND expr */
 
178518 {
178519 ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454);
178520 pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy454);
178521 yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy454, 0);
178522 if( yymsp[-4].minor.yy454 ){
@@ -178898,14 +178524,12 @@
178524 }else{
178525 sqlite3ExprListDelete(pParse->db, pList);
178526 }
178527 if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
178528 }
 
178529 break;
178530 case 223: /* expr ::= expr in_op LP exprlist RP */
 
178531 {
178532 if( yymsp[-1].minor.yy14==0 ){
178533 /* Expressions of the form
178534 **
178535 ** expr1 IN ()
@@ -178946,52 +178570,42 @@
178570 }
178571 }
178572 if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
178573 }
178574 }
 
178575 break;
178576 case 224: /* expr ::= LP select RP */
 
178577 {
178578 yymsp[-2].minor.yy454 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
178579 sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy454, yymsp[-1].minor.yy555);
178580 }
 
178581 break;
178582 case 225: /* expr ::= expr in_op LP select RP */
 
178583 {
178584 yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0);
178585 sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, yymsp[-1].minor.yy555);
178586 if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
178587 }
 
178588 break;
178589 case 226: /* expr ::= expr in_op nm dbnm paren_exprlist */
 
178590 {
178591 SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
178592 Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0);
178593 if( yymsp[0].minor.yy14 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy14);
178594 yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0);
178595 sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pSelect);
178596 if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
178597 }
 
178598 break;
178599 case 227: /* expr ::= EXISTS LP select RP */
 
178600 {
178601 Expr *p;
178602 p = yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
178603 sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy555);
178604 }
 
178605 break;
178606 case 228: /* expr ::= CASE case_operand case_exprlist case_else END */
 
178607 {
178608 yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy454, 0);
178609 if( yymsp[-4].minor.yy454 ){
178610 yymsp[-4].minor.yy454->x.pList = yymsp[-1].minor.yy454 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454) : yymsp[-2].minor.yy14;
178611 sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy454);
@@ -178998,627 +178612,446 @@
178612 }else{
178613 sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy14);
178614 sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy454);
178615 }
178616 }
 
178617 break;
178618 case 229: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
 
178619 {
178620 yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[-2].minor.yy454);
178621 yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[0].minor.yy454);
178622 }
 
178623 break;
178624 case 230: /* case_exprlist ::= WHEN expr THEN expr */
 
178625 {
178626 yymsp[-3].minor.yy14 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454);
178627 yymsp[-3].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14, yymsp[0].minor.yy454);
178628 }
 
178629 break;
178630 case 235: /* nexprlist ::= nexprlist COMMA expr */
 
178631 {yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[0].minor.yy454);}
 
178632 break;
178633 case 236: /* nexprlist ::= expr */
 
178634 {yymsp[0].minor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy454); /*A-overwrites-Y*/}
 
178635 break;
178636 case 238: /* paren_exprlist ::= LP exprlist RP */
178637 case 243: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==243);
 
178638 {yymsp[-2].minor.yy14 = yymsp[-1].minor.yy14;}
 
178639 break;
178640 case 239: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
 
178641 {
178642 sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
178643 sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy14, yymsp[-10].minor.yy144,
178644 &yymsp[-11].minor.yy0, yymsp[0].minor.yy454, SQLITE_SO_ASC, yymsp[-8].minor.yy144, SQLITE_IDXTYPE_APPDEF);
178645 if( IN_RENAME_OBJECT && pParse->pNewIndex ){
178646 sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0);
178647 }
178648 }
 
178649 break;
178650 case 240: /* uniqueflag ::= UNIQUE */
178651 case 282: /* raisetype ::= ABORT */ yytestcase(yyruleno==282);
 
178652 {yymsp[0].minor.yy144 = OE_Abort;}
 
178653 break;
178654 case 241: /* uniqueflag ::= */
 
178655 {yymsp[1].minor.yy144 = OE_None;}
 
178656 break;
178657 case 244: /* eidlist ::= eidlist COMMA nm collate sortorder */
 
178658 {
178659 yymsp[-4].minor.yy14 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy14, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy144, yymsp[0].minor.yy144);
178660 }
 
178661 break;
178662 case 245: /* eidlist ::= nm collate sortorder */
 
178663 {
178664 yymsp[-2].minor.yy14 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy144, yymsp[0].minor.yy144); /*A-overwrites-Y*/
178665 }
 
178666 break;
178667 case 248: /* cmd ::= DROP INDEX ifexists fullname */
 
178668 {sqlite3DropIndex(pParse, yymsp[0].minor.yy203, yymsp[-1].minor.yy144);}
 
178669 break;
178670 case 249: /* cmd ::= VACUUM vinto */
 
178671 {sqlite3Vacuum(pParse,0,yymsp[0].minor.yy454);}
 
178672 break;
178673 case 250: /* cmd ::= VACUUM nm vinto */
 
178674 {sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy454);}
 
178675 break;
178676 case 253: /* cmd ::= PRAGMA nm dbnm */
 
178677 {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
 
178678 break;
178679 case 254: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
 
178680 {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
 
178681 break;
178682 case 255: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
 
178683 {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
 
178684 break;
178685 case 256: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
 
178686 {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
 
178687 break;
178688 case 257: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
 
178689 {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
 
178690 break;
178691 case 260: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
 
178692 {
178693 Token all;
178694 all.z = yymsp[-3].minor.yy0.z;
178695 all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
178696 sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy427, &all);
178697 }
 
178698 break;
178699 case 261: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
 
178700 {
178701 sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy144, yymsp[-4].minor.yy286.a, yymsp[-4].minor.yy286.b, yymsp[-2].minor.yy203, yymsp[0].minor.yy454, yymsp[-10].minor.yy144, yymsp[-8].minor.yy144);
178702 yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
178703 }
 
178704 break;
178705 case 262: /* trigger_time ::= BEFORE|AFTER */
 
178706 { yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-X*/ }
 
178707 break;
178708 case 263: /* trigger_time ::= INSTEAD OF */
 
178709 { yymsp[-1].minor.yy144 = TK_INSTEAD;}
 
178710 break;
178711 case 264: /* trigger_time ::= */
 
178712 { yymsp[1].minor.yy144 = TK_BEFORE; }
 
178713 break;
178714 case 265: /* trigger_event ::= DELETE|INSERT */
178715 case 266: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==266);
 
178716 {yymsp[0].minor.yy286.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy286.b = 0;}
 
178717 break;
178718 case 267: /* trigger_event ::= UPDATE OF idlist */
 
178719 {yymsp[-2].minor.yy286.a = TK_UPDATE; yymsp[-2].minor.yy286.b = yymsp[0].minor.yy132;}
 
178720 break;
178721 case 268: /* when_clause ::= */
178722 case 287: /* key_opt ::= */ yytestcase(yyruleno==287);
 
178723 { yymsp[1].minor.yy454 = 0; }
 
178724 break;
178725 case 269: /* when_clause ::= WHEN expr */
178726 case 288: /* key_opt ::= KEY expr */ yytestcase(yyruleno==288);
 
178727 { yymsp[-1].minor.yy454 = yymsp[0].minor.yy454; }
 
178728 break;
178729 case 270: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
 
178730 {
178731 assert( yymsp[-2].minor.yy427!=0 );
178732 yymsp[-2].minor.yy427->pLast->pNext = yymsp[-1].minor.yy427;
178733 yymsp[-2].minor.yy427->pLast = yymsp[-1].minor.yy427;
178734 }
 
178735 break;
178736 case 271: /* trigger_cmd_list ::= trigger_cmd SEMI */
 
178737 {
178738 assert( yymsp[-1].minor.yy427!=0 );
178739 yymsp[-1].minor.yy427->pLast = yymsp[-1].minor.yy427;
178740 }
 
178741 break;
178742 case 272: /* trnm ::= nm DOT nm */
 
178743 {
178744 yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
178745 sqlite3ErrorMsg(pParse,
178746 "qualified table names are not allowed on INSERT, UPDATE, and DELETE "
178747 "statements within triggers");
178748 }
 
178749 break;
178750 case 273: /* tridxby ::= INDEXED BY nm */
 
178751 {
178752 sqlite3ErrorMsg(pParse,
178753 "the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
178754 "within triggers");
178755 }
 
178756 break;
178757 case 274: /* tridxby ::= NOT INDEXED */
 
178758 {
178759 sqlite3ErrorMsg(pParse,
178760 "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
178761 "within triggers");
178762 }
 
178763 break;
178764 case 275: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
 
178765 {yylhsminor.yy427 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy203, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454, yymsp[-7].minor.yy144, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy168);}
 
178766 yymsp[-8].minor.yy427 = yylhsminor.yy427;
178767 break;
178768 case 276: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
 
178769 {
178770 yylhsminor.yy427 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy132,yymsp[-2].minor.yy555,yymsp[-6].minor.yy144,yymsp[-1].minor.yy122,yymsp[-7].minor.yy168,yymsp[0].minor.yy168);/*yylhsminor.yy427-overwrites-yymsp[-6].minor.yy144*/
178771 }
 
178772 yymsp[-7].minor.yy427 = yylhsminor.yy427;
178773 break;
178774 case 277: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
 
178775 {yylhsminor.yy427 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy454, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy168);}
 
178776 yymsp[-5].minor.yy427 = yylhsminor.yy427;
178777 break;
178778 case 278: /* trigger_cmd ::= scanpt select scanpt */
 
178779 {yylhsminor.yy427 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy555, yymsp[-2].minor.yy168, yymsp[0].minor.yy168); /*yylhsminor.yy427-overwrites-yymsp[-1].minor.yy555*/}
 
178780 yymsp[-2].minor.yy427 = yylhsminor.yy427;
178781 break;
178782 case 279: /* expr ::= RAISE LP IGNORE RP */
 
178783 {
178784 yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
178785 if( yymsp[-3].minor.yy454 ){
178786 yymsp[-3].minor.yy454->affExpr = OE_Ignore;
178787 }
178788 }
 
178789 break;
178790 case 280: /* expr ::= RAISE LP raisetype COMMA expr RP */
 
178791 {
178792 yymsp[-5].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, yymsp[-1].minor.yy454, 0);
178793 if( yymsp[-5].minor.yy454 ) {
178794 yymsp[-5].minor.yy454->affExpr = (char)yymsp[-3].minor.yy144;
178795 }
178796 }
 
178797 break;
178798 case 281: /* raisetype ::= ROLLBACK */
 
178799 {yymsp[0].minor.yy144 = OE_Rollback;}
 
178800 break;
178801 case 283: /* raisetype ::= FAIL */
 
178802 {yymsp[0].minor.yy144 = OE_Fail;}
 
178803 break;
178804 case 284: /* cmd ::= DROP TRIGGER ifexists fullname */
 
178805 {
178806 sqlite3DropTrigger(pParse,yymsp[0].minor.yy203,yymsp[-1].minor.yy144);
178807 }
 
178808 break;
178809 case 285: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
 
178810 {
178811 sqlite3Attach(pParse, yymsp[-3].minor.yy454, yymsp[-1].minor.yy454, yymsp[0].minor.yy454);
178812 }
 
178813 break;
178814 case 286: /* cmd ::= DETACH database_kw_opt expr */
 
178815 {
178816 sqlite3Detach(pParse, yymsp[0].minor.yy454);
178817 }
 
178818 break;
178819 case 289: /* cmd ::= REINDEX */
 
178820 {sqlite3Reindex(pParse, 0, 0);}
 
178821 break;
178822 case 290: /* cmd ::= REINDEX nm dbnm */
 
178823 {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
 
178824 break;
178825 case 291: /* cmd ::= ANALYZE */
 
178826 {sqlite3Analyze(pParse, 0, 0);}
 
178827 break;
178828 case 292: /* cmd ::= ANALYZE nm dbnm */
 
178829 {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
 
178830 break;
178831 case 293: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
 
178832 {
178833 sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy203,&yymsp[0].minor.yy0);
178834 }
 
178835 break;
178836 case 294: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
 
178837 {
178838 yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
178839 sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0);
178840 }
 
178841 break;
178842 case 295: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
 
178843 {
178844 sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy203, &yymsp[0].minor.yy0);
178845 }
 
178846 break;
178847 case 296: /* add_column_fullname ::= fullname */
 
178848 {
178849 disableLookaside(pParse);
178850 sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy203);
178851 }
 
178852 break;
178853 case 297: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
 
178854 {
178855 sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy203, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
178856 }
 
178857 break;
178858 case 298: /* cmd ::= create_vtab */
 
178859 {sqlite3VtabFinishParse(pParse,0);}
 
178860 break;
178861 case 299: /* cmd ::= create_vtab LP vtabarglist RP */
 
178862 {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
 
178863 break;
178864 case 300: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
 
178865 {
178866 sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy144);
178867 }
 
178868 break;
178869 case 301: /* vtabarg ::= */
 
178870 {sqlite3VtabArgInit(pParse);}
 
178871 break;
178872 case 302: /* vtabargtoken ::= ANY */
178873 case 303: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==303);
178874 case 304: /* lp ::= LP */ yytestcase(yyruleno==304);
 
178875 {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
 
178876 break;
178877 case 305: /* with ::= WITH wqlist */
178878 case 306: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==306);
 
178879 { sqlite3WithPush(pParse, yymsp[0].minor.yy59, 1); }
 
178880 break;
178881 case 307: /* wqas ::= AS */
 
178882 {yymsp[0].minor.yy462 = M10d_Any;}
 
178883 break;
178884 case 308: /* wqas ::= AS MATERIALIZED */
 
178885 {yymsp[-1].minor.yy462 = M10d_Yes;}
 
178886 break;
178887 case 309: /* wqas ::= AS NOT MATERIALIZED */
 
178888 {yymsp[-2].minor.yy462 = M10d_No;}
 
178889 break;
178890 case 310: /* wqitem ::= withnm eidlist_opt wqas LP select RP */
 
178891 {
178892 yymsp[-5].minor.yy67 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy14, yymsp[-1].minor.yy555, yymsp[-3].minor.yy462); /*A-overwrites-X*/
178893 }
 
178894 break;
178895 case 311: /* withnm ::= nm */
 
178896 {pParse->bHasWith = 1;}
 
178897 break;
178898 case 312: /* wqlist ::= wqitem */
 
178899 {
178900 yymsp[0].minor.yy59 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy67); /*A-overwrites-X*/
178901 }
 
178902 break;
178903 case 313: /* wqlist ::= wqlist COMMA wqitem */
 
178904 {
178905 yymsp[-2].minor.yy59 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy59, yymsp[0].minor.yy67);
178906 }
 
178907 break;
178908 case 314: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
 
178909 {
178910 assert( yymsp[0].minor.yy211!=0 );
178911 sqlite3WindowChain(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy211);
178912 yymsp[0].minor.yy211->pNextWin = yymsp[-2].minor.yy211;
178913 yylhsminor.yy211 = yymsp[0].minor.yy211;
178914 }
 
178915 yymsp[-2].minor.yy211 = yylhsminor.yy211;
178916 break;
178917 case 315: /* windowdefn ::= nm AS LP window RP */
 
178918 {
178919 if( ALWAYS(yymsp[-1].minor.yy211) ){
178920 yymsp[-1].minor.yy211->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n);
178921 }
178922 yylhsminor.yy211 = yymsp[-1].minor.yy211;
178923 }
 
178924 yymsp[-4].minor.yy211 = yylhsminor.yy211;
178925 break;
178926 case 316: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */
 
178927 {
178928 yymsp[-4].minor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy14, yymsp[-1].minor.yy14, 0);
178929 }
 
178930 break;
178931 case 317: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
 
178932 {
178933 yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy14, yymsp[-1].minor.yy14, &yymsp[-5].minor.yy0);
178934 }
 
178935 yymsp[-5].minor.yy211 = yylhsminor.yy211;
178936 break;
178937 case 318: /* window ::= ORDER BY sortlist frame_opt */
 
178938 {
178939 yymsp[-3].minor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, yymsp[-1].minor.yy14, 0);
178940 }
 
178941 break;
178942 case 319: /* window ::= nm ORDER BY sortlist frame_opt */
 
178943 {
178944 yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0);
178945 }
 
178946 yymsp[-4].minor.yy211 = yylhsminor.yy211;
178947 break;
178948 case 320: /* window ::= nm frame_opt */
 
178949 {
178950 yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, 0, &yymsp[-1].minor.yy0);
178951 }
 
178952 yymsp[-1].minor.yy211 = yylhsminor.yy211;
178953 break;
178954 case 321: /* frame_opt ::= */
 
178955 {
178956 yymsp[1].minor.yy211 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
178957 }
 
178958 break;
178959 case 322: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
 
178960 {
178961 yylhsminor.yy211 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy144, yymsp[-1].minor.yy509.eType, yymsp[-1].minor.yy509.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy462);
178962 }
 
178963 yymsp[-2].minor.yy211 = yylhsminor.yy211;
178964 break;
178965 case 323: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
 
178966 {
178967 yylhsminor.yy211 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy144, yymsp[-3].minor.yy509.eType, yymsp[-3].minor.yy509.pExpr, yymsp[-1].minor.yy509.eType, yymsp[-1].minor.yy509.pExpr, yymsp[0].minor.yy462);
178968 }
 
178969 yymsp[-5].minor.yy211 = yylhsminor.yy211;
178970 break;
178971 case 325: /* frame_bound_s ::= frame_bound */
178972 case 327: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==327);
 
178973 {yylhsminor.yy509 = yymsp[0].minor.yy509;}
 
178974 yymsp[0].minor.yy509 = yylhsminor.yy509;
178975 break;
178976 case 326: /* frame_bound_s ::= UNBOUNDED PRECEDING */
178977 case 328: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==328);
178978 case 330: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==330);
 
178979 {yylhsminor.yy509.eType = yymsp[-1].major; yylhsminor.yy509.pExpr = 0;}
 
178980 yymsp[-1].minor.yy509 = yylhsminor.yy509;
178981 break;
178982 case 329: /* frame_bound ::= expr PRECEDING|FOLLOWING */
 
178983 {yylhsminor.yy509.eType = yymsp[0].major; yylhsminor.yy509.pExpr = yymsp[-1].minor.yy454;}
 
178984 yymsp[-1].minor.yy509 = yylhsminor.yy509;
178985 break;
178986 case 331: /* frame_exclude_opt ::= */
 
178987 {yymsp[1].minor.yy462 = 0;}
 
178988 break;
178989 case 332: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
 
178990 {yymsp[-1].minor.yy462 = yymsp[0].minor.yy462;}
 
178991 break;
178992 case 333: /* frame_exclude ::= NO OTHERS */
178993 case 334: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==334);
 
178994 {yymsp[-1].minor.yy462 = yymsp[-1].major; /*A-overwrites-X*/}
 
178995 break;
178996 case 335: /* frame_exclude ::= GROUP|TIES */
 
178997 {yymsp[0].minor.yy462 = yymsp[0].major; /*A-overwrites-X*/}
 
178998 break;
178999 case 336: /* window_clause ::= WINDOW windowdefn_list */
 
179000 { yymsp[-1].minor.yy211 = yymsp[0].minor.yy211; }
 
179001 break;
179002 case 337: /* filter_over ::= filter_clause over_clause */
 
179003 {
179004 if( yymsp[0].minor.yy211 ){
179005 yymsp[0].minor.yy211->pFilter = yymsp[-1].minor.yy454;
179006 }else{
179007 sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy454);
179008 }
179009 yylhsminor.yy211 = yymsp[0].minor.yy211;
179010 }
 
179011 yymsp[-1].minor.yy211 = yylhsminor.yy211;
179012 break;
179013 case 338: /* filter_over ::= over_clause */
 
179014 {
179015 yylhsminor.yy211 = yymsp[0].minor.yy211;
179016 }
 
179017 yymsp[0].minor.yy211 = yylhsminor.yy211;
179018 break;
179019 case 339: /* filter_over ::= filter_clause */
 
179020 {
179021 yylhsminor.yy211 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
179022 if( yylhsminor.yy211 ){
179023 yylhsminor.yy211->eFrmType = TK_FILTER;
179024 yylhsminor.yy211->pFilter = yymsp[0].minor.yy454;
179025 }else{
179026 sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy454);
179027 }
179028 }
 
179029 yymsp[0].minor.yy211 = yylhsminor.yy211;
179030 break;
179031 case 340: /* over_clause ::= OVER LP window RP */
 
179032 {
179033 yymsp[-3].minor.yy211 = yymsp[-1].minor.yy211;
179034 assert( yymsp[-3].minor.yy211!=0 );
179035 }
 
179036 break;
179037 case 341: /* over_clause ::= OVER nm */
 
179038 {
179039 yymsp[-1].minor.yy211 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
179040 if( yymsp[-1].minor.yy211 ){
179041 yymsp[-1].minor.yy211->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
179042 }
179043 }
 
179044 break;
179045 case 342: /* filter_clause ::= FILTER LP WHERE expr RP */
 
179046 { yymsp[-4].minor.yy454 = yymsp[-1].minor.yy454; }
 
179047 break;
179048 case 343: /* term ::= QNUMBER */
 
179049 {
179050 yylhsminor.yy454=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0);
179051 sqlite3DequoteNumber(pParse, yylhsminor.yy454);
179052 }
 
179053 yymsp[0].minor.yy454 = yylhsminor.yy454;
179054 break;
179055 default:
179056 /* (344) input ::= cmdlist */ yytestcase(yyruleno==344);
179057 /* (345) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==345);
@@ -179742,19 +179175,17 @@
179175 ){
179176 sqlite3ParserARG_FETCH
179177 sqlite3ParserCTX_FETCH
179178 #define TOKEN yyminor
179179 /************ Begin %syntax_error code ****************************************/
 
179180
179181 UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */
179182 if( TOKEN.z[0] ){
179183 parserSyntaxError(pParse, &TOKEN);
179184 }else{
179185 sqlite3ErrorMsg(pParse, "incomplete input");
179186 }
 
179187 /************ End %syntax_error code ******************************************/
179188 sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
179189 sqlite3ParserCTX_STORE
179190 }
179191
@@ -180022,11 +179453,10 @@
179453 #endif
179454 }
179455
179456 /************** End of parse.c ***********************************************/
179457 /************** Begin file tokenize.c ****************************************/
 
179458 /*
179459 ** 2001 September 15
179460 **
179461 ** The author disclaims copyright to this source code. In place of
179462 ** a legal notice, here is a blessing:
@@ -180172,11 +179602,10 @@
179602 ** named keywordhash.h and then included into this source file by
179603 ** the #include below.
179604 */
179605 /************** Include keywordhash.h in the middle of tokenize.c ************/
179606 /************** Begin file keywordhash.h *************************************/
 
179607 /***** This file contains automatically generated code ******
179608 **
179609 ** The code in this file has been automatically generated by
179610 **
179611 ** sqlite/tool/mkkeywordhash.c
@@ -180658,11 +180087,10 @@
180087 return TK_ID!=sqlite3KeywordCode((const u8*)zName, nName);
180088 }
180089
180090 /************** End of keywordhash.h *****************************************/
180091 /************** Continuing where we left off in tokenize.c *******************/
 
180092
180093
180094 /*
180095 ** If X is a character that can be used in an identifier then
180096 ** IdChar(X) will be true. Otherwise it is false.
@@ -181241,11 +180669,13 @@
180669 }
180670 if( pParse->zErrMsg || (pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE) ){
180671 if( pParse->zErrMsg==0 ){
180672 pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc));
180673 }
180674 if( (pParse->prepFlags & SQLITE_PREPARE_DONT_LOG)==0 ){
180675 sqlite3_log(pParse->rc, "%s in \"%s\"", pParse->zErrMsg, pParse->zTail);
180676 }
180677 nErr++;
180678 }
180679 pParse->zTail = zSql;
180680 #ifndef SQLITE_OMIT_VIRTUALTABLE
180681 sqlite3_free(pParse->apVtabLock);
@@ -181402,11 +180832,10 @@
180832 }
180833 #endif /* SQLITE_ENABLE_NORMALIZE */
180834
180835 /************** End of tokenize.c ********************************************/
180836 /************** Begin file complete.c ****************************************/
 
180837 /*
180838 ** 2001 September 15
180839 **
180840 ** The author disclaims copyright to this source code. In place of
180841 ** a legal notice, here is a blessing:
@@ -181696,11 +181125,10 @@
181125 #endif /* SQLITE_OMIT_UTF16 */
181126 #endif /* SQLITE_OMIT_COMPLETE */
181127
181128 /************** End of complete.c ********************************************/
181129 /************** Begin file main.c ********************************************/
 
181130 /*
181131 ** 2001 September 15
181132 **
181133 ** The author disclaims copyright to this source code. In place of
181134 ** a legal notice, here is a blessing:
@@ -181718,11 +181146,10 @@
181146 /* #include "sqliteInt.h" */
181147
181148 #ifdef SQLITE_ENABLE_FTS3
181149 /************** Include fts3.h in the middle of main.c ***********************/
181150 /************** Begin file fts3.h ********************************************/
 
181151 /*
181152 ** 2006 Oct 10
181153 **
181154 ** The author disclaims copyright to this source code. In place of
181155 ** a legal notice, here is a blessing:
@@ -181748,16 +181175,14 @@
181175 } /* extern "C" */
181176 #endif /* __cplusplus */
181177
181178 /************** End of fts3.h ************************************************/
181179 /************** Continuing where we left off in main.c ***********************/
 
181180 #endif
181181 #ifdef SQLITE_ENABLE_RTREE
181182 /************** Include rtree.h in the middle of main.c **********************/
181183 /************** Begin file rtree.h *******************************************/
 
181184 /*
181185 ** 2008 May 26
181186 **
181187 ** The author disclaims copyright to this source code. In place of
181188 ** a legal notice, here is a blessing:
@@ -181787,16 +181212,14 @@
181212 } /* extern "C" */
181213 #endif /* __cplusplus */
181214
181215 /************** End of rtree.h ***********************************************/
181216 /************** Continuing where we left off in main.c ***********************/
 
181217 #endif
181218 #if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
181219 /************** Include sqliteicu.h in the middle of main.c ******************/
181220 /************** Begin file sqliteicu.h ***************************************/
 
181221 /*
181222 ** 2008 May 26
181223 **
181224 ** The author disclaims copyright to this source code. In place of
181225 ** a legal notice, here is a blessing:
@@ -181822,11 +181245,10 @@
181245 } /* extern "C" */
181246 #endif /* __cplusplus */
181247
181248 /************** End of sqliteicu.h *******************************************/
181249 /************** Continuing where we left off in main.c ***********************/
 
181250 #endif
181251
181252 /*
181253 ** This is an extension initializer that is a no-op and always
181254 ** succeeds, except that it fails if the fault-simulation is set
@@ -184724,12 +184146,12 @@
184146 }
184147 oldLimit = db->aLimit[limitId];
184148 if( newLimit>=0 ){ /* IMP: R-52476-28732 */
184149 if( newLimit>aHardLimit[limitId] ){
184150 newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */
184151 }else if( newLimit<SQLITE_MIN_LENGTH && limitId==SQLITE_LIMIT_LENGTH ){
184152 newLimit = SQLITE_MIN_LENGTH;
184153 }
184154 db->aLimit[limitId] = newLimit;
184155 }
184156 return oldLimit; /* IMP: R-53341-35419 */
184157 }
@@ -186087,10 +185509,11 @@
185509 #ifndef SQLITE_OMIT_WINDOWFUNC
185510 sqlite3ShowWindow(0);
185511 sqlite3ShowWinFunc(0);
185512 #endif
185513 sqlite3ShowSelect(0);
185514 sqlite3ShowWhereTerm(0);
185515 }
185516 #endif
185517 break;
185518 }
185519
@@ -186873,11 +186296,10 @@
186296 }
186297 #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
186298
186299 /************** End of main.c ************************************************/
186300 /************** Begin file notify.c ******************************************/
 
186301 /*
186302 ** 2009 March 3
186303 **
186304 ** The author disclaims copyright to this source code. In place of
186305 ** a legal notice, here is a blessing:
@@ -187212,11 +186634,10 @@
186634 }
186635 #endif
186636
186637 /************** End of notify.c **********************************************/
186638 /************** Begin file fts3.c ********************************************/
 
186639 /*
186640 ** 2006 Oct 10
186641 **
186642 ** The author disclaims copyright to this source code. In place of
186643 ** a legal notice, here is a blessing:
@@ -187505,11 +186926,10 @@
186926 ** older data.
186927 */
186928
186929 /************** Include fts3Int.h in the middle of fts3.c ********************/
186930 /************** Begin file fts3Int.h *****************************************/
 
186931 /*
186932 ** 2009 Nov 12
186933 **
186934 ** The author disclaims copyright to this source code. In place of
186935 ** a legal notice, here is a blessing:
@@ -187552,11 +186972,10 @@
186972 #endif
186973
186974 /* #include "sqlite3.h" */
186975 /************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/
186976 /************** Begin file fts3_tokenizer.h **********************************/
 
186977 /*
186978 ** 2006 July 10
186979 **
186980 ** The author disclaims copyright to this source code.
186981 **
@@ -187717,14 +187136,12 @@
187136
187137 #endif /* _FTS3_TOKENIZER_H_ */
187138
187139 /************** End of fts3_tokenizer.h **************************************/
187140 /************** Continuing where we left off in fts3Int.h ********************/
 
187141 /************** Include fts3_hash.h in the middle of fts3Int.h ***************/
187142 /************** Begin file fts3_hash.h ***************************************/
 
187143 /*
187144 ** 2001 September 22
187145 **
187146 ** The author disclaims copyright to this source code. In place of
187147 ** a legal notice, here is a blessing:
@@ -187836,11 +187253,10 @@
187253
187254 #endif /* _FTS3_HASH_H_ */
187255
187256 /************** End of fts3_hash.h *******************************************/
187257 /************** Continuing where we left off in fts3Int.h ********************/
 
187258
187259 /*
187260 ** This constant determines the maximum depth of an FTS expression tree
187261 ** that the library will create and use. FTS uses recursion to perform
187262 ** various operations on the query tree, so the disadvantage of a large
@@ -188453,11 +187869,10 @@
187869 #endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */
187870 #endif /* _FTSINT_H */
187871
187872 /************** End of fts3Int.h *********************************************/
187873 /************** Continuing where we left off in fts3.c ***********************/
 
187874 #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
187875
187876 #if defined(SQLITE_ENABLE_FTS3) && !defined(SQLITE_CORE)
187877 # define SQLITE_CORE 1
187878 #endif
@@ -190509,14 +189924,19 @@
189924
189925 assert_fts3_nc( p!=0 && *p1!=0 && *p2!=0 );
189926 if( *p1==POS_COLUMN ){
189927 p1++;
189928 p1 += fts3GetVarint32(p1, &iCol1);
189929 /* iCol1==0 indicates corruption. Column 0 does not have a POS_COLUMN
189930 ** entry, so this is actually end-of-doclist. */
189931 if( iCol1==0 ) return 0;
189932 }
189933 if( *p2==POS_COLUMN ){
189934 p2++;
189935 p2 += fts3GetVarint32(p2, &iCol2);
189936 /* As above, iCol2==0 indicates corruption. */
189937 if( iCol2==0 ) return 0;
189938 }
189939
189940 while( 1 ){
189941 if( iCol1==iCol2 ){
189942 char *pSave = p;
@@ -193683,11 +193103,11 @@
193103 for(p=pExpr; p->pLeft; p=p->pLeft){
193104 assert( p->pRight->pPhrase->doclist.nList>0 );
193105 nTmp += p->pRight->pPhrase->doclist.nList;
193106 }
193107 nTmp += p->pPhrase->doclist.nList;
193108 aTmp = sqlite3_malloc64(nTmp*2 + FTS3_VARINT_MAX);
193109 if( !aTmp ){
193110 *pRc = SQLITE_NOMEM;
193111 res = 0;
193112 }else{
193113 char *aPoslist = p->pPhrase->doclist.pList;
@@ -194355,11 +193775,10 @@
193775
193776 #endif
193777
193778 /************** End of fts3.c ************************************************/
193779 /************** Begin file fts3_aux.c ****************************************/
 
193780 /*
193781 ** 2011 Jan 27
193782 **
193783 ** The author disclaims copyright to this source code. In place of
193784 ** a legal notice, here is a blessing:
@@ -194916,11 +194335,10 @@
194335
194336 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
194337
194338 /************** End of fts3_aux.c ********************************************/
194339 /************** Begin file fts3_expr.c ***************************************/
 
194340 /*
194341 ** 2008 Nov 28
194342 **
194343 ** The author disclaims copyright to this source code. In place of
194344 ** a legal notice, here is a blessing:
@@ -195238,14 +194656,15 @@
194656 rc = pModule->xNext(pCursor, &zByte, &nByte, &iBegin, &iEnd, &iPos);
194657 if( rc==SQLITE_OK ){
194658 Fts3PhraseToken *pToken;
194659
194660 p = fts3ReallocOrFree(p, nSpace + ii*sizeof(Fts3PhraseToken));
 
 
194661 zTemp = fts3ReallocOrFree(zTemp, nTemp + nByte);
194662 if( !zTemp || !p ){
194663 rc = SQLITE_NOMEM;
194664 goto getnextstring_out;
194665 }
194666
194667 assert( nToken==ii );
194668 pToken = &((Fts3Phrase *)(&p[1]))->aToken[ii];
194669 memset(pToken, 0, sizeof(Fts3PhraseToken));
194670
@@ -195256,53 +194675,51 @@
194675 pToken->isPrefix = (iEnd<nInput && zInput[iEnd]=='*');
194676 pToken->bFirst = (iBegin>0 && zInput[iBegin-1]=='^');
194677 nToken = ii+1;
194678 }
194679 }
 
 
 
194680 }
194681
194682 if( rc==SQLITE_DONE ){
194683 int jj;
194684 char *zBuf = 0;
194685
194686 p = fts3ReallocOrFree(p, nSpace + nToken*sizeof(Fts3PhraseToken) + nTemp);
194687 if( !p ){
194688 rc = SQLITE_NOMEM;
194689 goto getnextstring_out;
194690 }
194691 memset(p, 0, (char *)&(((Fts3Phrase *)&p[1])->aToken[0])-(char *)p);
194692 p->eType = FTSQUERY_PHRASE;
194693 p->pPhrase = (Fts3Phrase *)&p[1];
194694 p->pPhrase->iColumn = pParse->iDefaultCol;
194695 p->pPhrase->nToken = nToken;
194696
194697 zBuf = (char *)&p->pPhrase->aToken[nToken];
194698 assert( nTemp==0 || zTemp );
194699 if( zTemp ){
194700 memcpy(zBuf, zTemp, nTemp);
 
 
 
194701 }
194702
194703 for(jj=0; jj<p->pPhrase->nToken; jj++){
194704 p->pPhrase->aToken[jj].z = zBuf;
194705 zBuf += p->pPhrase->aToken[jj].n;
194706 }
194707 rc = SQLITE_OK;
194708 }
194709
194710 getnextstring_out:
 
 
 
194711 if( pCursor ){
194712 pModule->xClose(pCursor);
194713 }
194714 sqlite3_free(zTemp);
194715 if( rc!=SQLITE_OK ){
194716 sqlite3_free(p);
194717 p = 0;
194718 }
194719 *ppExpr = p;
194720 return rc;
194721 }
194722
194723 /*
194724 ** The output variable *ppExpr is populated with an allocated Fts3Expr
194725 ** structure, or set to 0 if the end of the input buffer is reached.
@@ -196213,11 +195630,10 @@
195630 #endif
195631 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
195632
195633 /************** End of fts3_expr.c *******************************************/
195634 /************** Begin file fts3_hash.c ***************************************/
 
195635 /*
195636 ** 2001 September 22
195637 **
195638 ** The author disclaims copyright to this source code. In place of
195639 ** a legal notice, here is a blessing:
@@ -196600,11 +196016,10 @@
196016
196017 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
196018
196019 /************** End of fts3_hash.c *******************************************/
196020 /************** Begin file fts3_porter.c *************************************/
 
196021 /*
196022 ** 2006 September 30
196023 **
196024 ** The author disclaims copyright to this source code. In place of
196025 ** a legal notice, here is a blessing:
@@ -197266,11 +196681,10 @@
196681
196682 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
196683
196684 /************** End of fts3_porter.c *****************************************/
196685 /************** Begin file fts3_tokenizer.c **********************************/
 
196686 /*
196687 ** 2007 June 22
196688 **
196689 ** The author disclaims copyright to this source code. In place of
196690 ** a legal notice, here is a blessing:
@@ -197786,11 +197200,10 @@
197200
197201 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
197202
197203 /************** End of fts3_tokenizer.c **************************************/
197204 /************** Begin file fts3_tokenizer1.c *********************************/
 
197205 /*
197206 ** 2006 Oct 10
197207 **
197208 ** The author disclaims copyright to this source code. In place of
197209 ** a legal notice, here is a blessing:
@@ -198024,11 +197437,10 @@
197437
197438 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
197439
197440 /************** End of fts3_tokenizer1.c *************************************/
197441 /************** Begin file fts3_tokenize_vtab.c ******************************/
 
197442 /*
197443 ** 2013 Apr 22
197444 **
197445 ** The author disclaims copyright to this source code. In place of
197446 ** a legal notice, here is a blessing:
@@ -198487,11 +197899,10 @@
197899
197900 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
197901
197902 /************** End of fts3_tokenize_vtab.c **********************************/
197903 /************** Begin file fts3_write.c **************************************/
 
197904 /*
197905 ** 2009 Oct 23
197906 **
197907 ** The author disclaims copyright to this source code. In place of
197908 ** a legal notice, here is a blessing:
@@ -204325,11 +203736,10 @@
203736
203737 #endif
203738
203739 /************** End of fts3_write.c ******************************************/
203740 /************** Begin file fts3_snippet.c ************************************/
 
203741 /*
203742 ** 2009 Oct 23
203743 **
203744 ** The author disclaims copyright to this source code. In place of
203745 ** a legal notice, here is a blessing:
@@ -206085,11 +205495,10 @@
205495
205496 #endif
205497
205498 /************** End of fts3_snippet.c ****************************************/
205499 /************** Begin file fts3_unicode.c ************************************/
 
205500 /*
205501 ** 2012 May 24
205502 **
205503 ** The author disclaims copyright to this source code. In place of
205504 ** a legal notice, here is a blessing:
@@ -206486,11 +205895,10 @@
205895 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
205896 #endif /* ifndef SQLITE_DISABLE_FTS3_UNICODE */
205897
205898 /************** End of fts3_unicode.c ****************************************/
205899 /************** Begin file fts3_unicode2.c ***********************************/
 
205900 /*
205901 ** 2012-05-25
205902 **
205903 ** The author disclaims copyright to this source code. In place of
205904 ** a legal notice, here is a blessing:
@@ -206873,11 +206281,10 @@
206281 #endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */
206282 #endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */
206283
206284 /************** End of fts3_unicode2.c ***************************************/
206285 /************** Begin file json.c ********************************************/
 
206286 /*
206287 ** 2015-08-12
206288 **
206289 ** The author disclaims copyright to this source code. In place of
206290 ** a legal notice, here is a blessing:
@@ -212343,11 +211750,10 @@
211750 }
211751 #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) */
211752
211753 /************** End of json.c ************************************************/
211754 /************** Begin file rtree.c *******************************************/
 
211755 /*
211756 ** 2001 September 15
211757 **
211758 ** The author disclaims copyright to this source code. In place of
211759 ** a legal notice, here is a blessing:
@@ -216632,11 +216038,10 @@
216038
216039 /* Conditionally include the geopoly code */
216040 #ifdef SQLITE_ENABLE_GEOPOLY
216041 /************** Include geopoly.c in the middle of rtree.c *******************/
216042 /************** Begin file geopoly.c *****************************************/
 
216043 /*
216044 ** 2018-05-25
216045 **
216046 ** The author disclaims copyright to this source code. In place of
216047 ** a legal notice, here is a blessing:
@@ -218475,11 +217880,10 @@
217880 return rc;
217881 }
217882
217883 /************** End of geopoly.c *********************************************/
217884 /************** Continuing where we left off in rtree.c **********************/
 
217885 #endif
217886
217887 /*
217888 ** Register the r-tree module with database handle db. This creates the
217889 ** virtual table module "rtree" and the debugging/analysis scalar
@@ -218658,11 +218062,10 @@
218062
218063 #endif
218064
218065 /************** End of rtree.c ***********************************************/
218066 /************** Begin file icu.c *********************************************/
 
218067 /*
218068 ** 2007 May 6
218069 **
218070 ** The author disclaims copyright to this source code. In place of
218071 ** a legal notice, here is a blessing:
@@ -219250,11 +218653,10 @@
218653
218654 #endif
218655
218656 /************** End of icu.c *************************************************/
218657 /************** Begin file fts3_icu.c ****************************************/
 
218658 /*
218659 ** 2007 June 22
218660 **
218661 ** The author disclaims copyright to this source code. In place of
218662 ** a legal notice, here is a blessing:
@@ -219516,11 +218918,10 @@
218918 #endif /* defined(SQLITE_ENABLE_ICU) */
218919 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
218920
218921 /************** End of fts3_icu.c ********************************************/
218922 /************** Begin file sqlite3rbu.c **************************************/
 
218923 /*
218924 ** 2014 August 30
218925 **
218926 ** The author disclaims copyright to this source code. In place of
218927 ** a legal notice, here is a blessing:
@@ -219608,11 +219009,10 @@
219009 /* #include "sqlite3.h" */
219010
219011 #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU)
219012 /************** Include sqlite3rbu.h in the middle of sqlite3rbu.c ***********/
219013 /************** Begin file sqlite3rbu.h **************************************/
 
219014 /*
219015 ** 2014 August 30
219016 **
219017 ** The author disclaims copyright to this source code. In place of
219018 ** a legal notice, here is a blessing:
@@ -220245,11 +219645,10 @@
219645
219646 #endif /* _SQLITE3RBU_H */
219647
219648 /************** End of sqlite3rbu.h ******************************************/
219649 /************** Continuing where we left off in sqlite3rbu.c *****************/
 
219650
219651 #if defined(_WIN32_WCE)
219652 /* #include "windows.h" */
219653 #endif
219654
@@ -225606,11 +225005,10 @@
225005
225006 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) */
225007
225008 /************** End of sqlite3rbu.c ******************************************/
225009 /************** Begin file dbstat.c ******************************************/
 
225010 /*
225011 ** 2010 July 12
225012 **
225013 ** The author disclaims copyright to this source code. In place of
225014 ** a legal notice, here is a blessing:
@@ -226516,11 +225914,10 @@
225914 SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
225915 #endif /* SQLITE_ENABLE_DBSTAT_VTAB */
225916
225917 /************** End of dbstat.c **********************************************/
225918 /************** Begin file dbpage.c ******************************************/
 
225919 /*
225920 ** 2017-10-11
225921 **
225922 ** The author disclaims copyright to this source code. In place of
225923 ** a legal notice, here is a blessing:
@@ -226912,10 +226309,12 @@
226309 if( (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK && pData ){
226310 unsigned char *aPage = sqlite3PagerGetData(pDbPage);
226311 memcpy(aPage, pData, szPage);
226312 pTab->pgnoTrunc = 0;
226313 }
226314 }else{
226315 pTab->pgnoTrunc = 0;
226316 }
226317 sqlite3PagerUnref(pDbPage);
226318 return rc;
226319
226320 update_fail:
@@ -226999,11 +226398,10 @@
226398 SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; }
226399 #endif /* SQLITE_ENABLE_DBSTAT_VTAB */
226400
226401 /************** End of dbpage.c **********************************************/
226402 /************** Begin file sqlite3session.c **********************************/
 
226403
226404 #if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
226405 /* #include "sqlite3session.h" */
226406 /* #include <assert.h> */
226407 /* #include <string.h> */
@@ -233539,11 +232937,10 @@
232937
232938 #endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
232939
232940 /************** End of sqlite3session.c **************************************/
232941 /************** Begin file fts5.c ********************************************/
 
232942
232943 /*
232944 ** This, the "fts5.c" source file, is a composite file that is itself
232945 ** assembled from the following files:
232946 **
@@ -233577,11 +232974,10 @@
232974 /* #include <stdint.h> */
232975 #endif
232976 #ifdef HAVE_INTTYPES_H
232977 /* #include <inttypes.h> */
232978 #endif
 
232979 /*
232980 ** 2014 May 31
232981 **
232982 ** The author disclaims copyright to this source code. In place of
232983 ** a legal notice, here is a blessing:
@@ -233878,17 +233274,32 @@
233274 ** This is used to access token iToken of phrase hit iIdx within the
233275 ** current row. If iIdx is less than zero or greater than or equal to the
233276 ** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise,
233277 ** output variable (*ppToken) is set to point to a buffer containing the
233278 ** matching document token, and (*pnToken) to the size of that buffer in
233279 ** bytes.
 
 
233280 **
233281 ** The output text is not a copy of the document text that was tokenized.
233282 ** It is the output of the tokenizer module. For tokendata=1 tables, this
233283 ** includes any embedded 0x00 and trailing data.
233284 **
233285 ** This API may be slow in some cases if the token identified by parameters
233286 ** iIdx and iToken matched a prefix token in the query. In most cases, the
233287 ** first call to this API for each prefix token in the query is forced
233288 ** to scan the portion of the full-text index that matches the prefix
233289 ** token to collect the extra data required by this API. If the prefix
233290 ** token matches a large number of token instances in the document set,
233291 ** this may be a performance problem.
233292 **
233293 ** If the user knows in advance that a query may use this API for a
233294 ** prefix token, FTS5 may be configured to collect all required data as part
233295 ** of the initial querying of the full-text index, avoiding the second scan
233296 ** entirely. This also causes prefix queries that do not use this API to
233297 ** run more slowly and use more memory. FTS5 may be configured in this way
233298 ** either on a per-table basis using the [FTS5 insttoken | 'insttoken']
233299 ** option, or on a per-query basis using the
233300 ** [fts5_insttoken | fts5_insttoken()] user function.
233301 **
233302 ** This API can be quite slow if used with an FTS5 table created with the
233303 ** "detail=none" or "detail=column" option.
233304 **
233305 ** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale)
@@ -234318,11 +233729,10 @@
233729 } /* end of the 'extern "C"' block */
233730 #endif
233731
233732 #endif /* _FTS5_H */
233733
 
233734 /*
233735 ** 2014 May 31
233736 **
233737 ** The author disclaims copyright to this source code. In place of
233738 ** a legal notice, here is a blessing:
@@ -234568,11 +233978,12 @@
233978 int nUsermerge; /* 'usermerge' setting */
233979 int nHashSize; /* Bytes of memory for in-memory hash */
233980 char *zRank; /* Name of rank function */
233981 char *zRankArgs; /* Arguments to rank function */
233982 int bSecureDelete; /* 'secure-delete' */
233983 int nDeleteMerge; /* 'deletemerge' */
233984 int bPrefixInsttoken; /* 'prefix-insttoken' */
233985
233986 /* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */
233987 char **pzErrmsg;
233988
233989 #ifdef SQLITE_DEBUG
@@ -234825,11 +234236,18 @@
234236 static int sqlite3Fts5StructureTest(Fts5Index*, void*);
234237
234238 /*
234239 ** Used by xInstToken():
234240 */
234241 static int sqlite3Fts5IterToken(
234242 Fts5IndexIter *pIndexIter,
234243 const char *pToken, int nToken,
234244 i64 iRowid,
234245 int iCol,
234246 int iOff,
234247 const char **ppOut, int *pnOut
234248 );
234249
234250 /*
234251 ** Insert or remove data to or from the index. Each time a document is
234252 ** added to or removed from the index, this function is called one or more
234253 ** times.
@@ -235258,11 +234676,10 @@
234676 ** End of interface to code in fts5_unicode2.c.
234677 **************************************************************************/
234678
234679 #endif
234680
 
234681 #define FTS5_OR 1
234682 #define FTS5_AND 2
234683 #define FTS5_NOT 3
234684 #define FTS5_TERM 4
234685 #define FTS5_COLON 5
@@ -235275,11 +234692,10 @@
234692 #define FTS5_CARET 12
234693 #define FTS5_COMMA 13
234694 #define FTS5_PLUS 14
234695 #define FTS5_STAR 15
234696
 
234697 /* This file is automatically generated by Lemon from input grammar
234698 ** source file "fts5parse.y".
234699 */
234700 /*
234701 ** 2000-05-29
@@ -235304,11 +234720,10 @@
234720 **
234721 ** The following is the concatenation of all %include directives from the
234722 ** input grammar file:
234723 */
234724 /************ Begin %include sections from the grammar ************************/
 
234725
234726 /* #include "fts5Int.h" */
234727 /* #include "fts5parse.h" */
234728
234729 /*
@@ -235332,11 +234747,10 @@
234747 ** Alternative datatype for the argument to the malloc() routine passed
234748 ** into sqlite3ParserAlloc(). The default is size_t.
234749 */
234750 #define fts5YYMALLOCARGTYPE u64
234751
 
234752 /**************** End of %include directives **********************************/
234753 /* These constants specify the various numeric values for terminal symbols.
234754 ***************** Begin token definitions *************************************/
234755 #ifndef FTS5_OR
234756 #define FTS5_OR 1
@@ -235879,45 +235293,35 @@
235293 ** inside the C code.
235294 */
235295 /********* Begin destructor definitions ***************************************/
235296 case 16: /* input */
235297 {
 
235298 (void)pParse;
 
235299 }
235300 break;
235301 case 17: /* expr */
235302 case 18: /* cnearset */
235303 case 19: /* exprlist */
235304 {
 
235305 sqlite3Fts5ParseNodeFree((fts5yypminor->fts5yy24));
 
235306 }
235307 break;
235308 case 20: /* colset */
235309 case 21: /* colsetlist */
235310 {
 
235311 sqlite3_free((fts5yypminor->fts5yy11));
 
235312 }
235313 break;
235314 case 22: /* nearset */
235315 case 23: /* nearphrases */
235316 {
 
235317 sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy46));
 
235318 }
235319 break;
235320 case 24: /* phrase */
235321 {
 
235322 sqlite3Fts5ParsePhraseFree((fts5yypminor->fts5yy53));
 
235323 }
235324 break;
235325 /********* End destructor definitions *****************************************/
235326 default: break; /* If no destructor action specified: do nothing */
235327 }
@@ -236148,14 +235552,12 @@
235552 #endif
235553 while( fts5yypParser->fts5yytos>fts5yypParser->fts5yystack ) fts5yy_pop_parser_stack(fts5yypParser);
235554 /* Here code is inserted which will execute if the parser
235555 ** stack every overflows */
235556 /******** Begin %stack_overflow code ******************************************/
 
235557
235558 sqlite3Fts5ParseError(pParse, "fts5: parser stack overflow");
 
235559 /******** End %stack_overflow code ********************************************/
235560 sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument var */
235561 sqlite3Fts5ParserCTX_STORE
235562 }
235563
@@ -236320,202 +235722,148 @@
235722 ** break;
235723 */
235724 /********** Begin reduce actions **********************************************/
235725 fts5YYMINORTYPE fts5yylhsminor;
235726 case 0: /* input ::= expr */
 
235727 { sqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy24); }
 
235728 break;
235729 case 1: /* colset ::= MINUS LCP colsetlist RCP */
 
235730 {
235731 fts5yymsp[-3].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
235732 }
 
235733 break;
235734 case 2: /* colset ::= LCP colsetlist RCP */
 
235735 { fts5yymsp[-2].minor.fts5yy11 = fts5yymsp[-1].minor.fts5yy11; }
 
235736 break;
235737 case 3: /* colset ::= STRING */
 
235738 {
235739 fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
235740 }
 
235741 fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
235742 break;
235743 case 4: /* colset ::= MINUS STRING */
 
235744 {
235745 fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
235746 fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
235747 }
 
235748 break;
235749 case 5: /* colsetlist ::= colsetlist STRING */
 
235750 {
235751 fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy11, &fts5yymsp[0].minor.fts5yy0); }
 
235752 fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
235753 break;
235754 case 6: /* colsetlist ::= STRING */
 
235755 {
235756 fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
235757 }
 
235758 fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
235759 break;
235760 case 7: /* expr ::= expr AND expr */
 
235761 {
235762 fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
235763 }
 
235764 fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
235765 break;
235766 case 8: /* expr ::= expr OR expr */
 
235767 {
235768 fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
235769 }
 
235770 fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
235771 break;
235772 case 9: /* expr ::= expr NOT expr */
 
235773 {
235774 fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
235775 }
 
235776 fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
235777 break;
235778 case 10: /* expr ::= colset COLON LP expr RP */
 
235779 {
235780 sqlite3Fts5ParseSetColset(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[-4].minor.fts5yy11);
235781 fts5yylhsminor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;
235782 }
 
235783 fts5yymsp[-4].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
235784 break;
235785 case 11: /* expr ::= LP expr RP */
 
235786 {fts5yymsp[-2].minor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;}
 
235787 break;
235788 case 12: /* expr ::= exprlist */
235789 case 13: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==13);
 
235790 {fts5yylhsminor.fts5yy24 = fts5yymsp[0].minor.fts5yy24;}
 
235791 fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
235792 break;
235793 case 14: /* exprlist ::= exprlist cnearset */
 
235794 {
235795 fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24);
235796 }
 
235797 fts5yymsp[-1].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
235798 break;
235799 case 15: /* cnearset ::= nearset */
 
235800 {
235801 fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46);
235802 }
 
235803 fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
235804 break;
235805 case 16: /* cnearset ::= colset COLON nearset */
 
235806 {
235807 fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46);
235808 sqlite3Fts5ParseSetColset(pParse, fts5yylhsminor.fts5yy24, fts5yymsp[-2].minor.fts5yy11);
235809 }
 
235810 fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
235811 break;
235812 case 17: /* nearset ::= phrase */
 
235813 { fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); }
 
235814 fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
235815 break;
235816 case 18: /* nearset ::= CARET phrase */
 
235817 {
235818 sqlite3Fts5ParseSetCaret(fts5yymsp[0].minor.fts5yy53);
235819 fts5yymsp[-1].minor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53);
235820 }
 
235821 break;
235822 case 19: /* nearset ::= STRING LP nearphrases neardist_opt RP */
 
235823 {
235824 sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0);
235825 sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy46, &fts5yymsp[-1].minor.fts5yy0);
235826 fts5yylhsminor.fts5yy46 = fts5yymsp[-2].minor.fts5yy46;
235827 }
 
235828 fts5yymsp[-4].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
235829 break;
235830 case 20: /* nearphrases ::= phrase */
 
235831 {
235832 fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53);
235833 }
 
235834 fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
235835 break;
235836 case 21: /* nearphrases ::= nearphrases phrase */
 
235837 {
235838 fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy46, fts5yymsp[0].minor.fts5yy53);
235839 }
 
235840 fts5yymsp[-1].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
235841 break;
235842 case 22: /* neardist_opt ::= */
 
235843 { fts5yymsp[1].minor.fts5yy0.p = 0; fts5yymsp[1].minor.fts5yy0.n = 0; }
 
235844 break;
235845 case 23: /* neardist_opt ::= COMMA STRING */
 
235846 { fts5yymsp[-1].minor.fts5yy0 = fts5yymsp[0].minor.fts5yy0; }
 
235847 break;
235848 case 24: /* phrase ::= phrase PLUS STRING star_opt */
 
235849 {
235850 fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy53, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
235851 }
 
235852 fts5yymsp[-3].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
235853 break;
235854 case 25: /* phrase ::= STRING star_opt */
 
235855 {
235856 fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
235857 }
 
235858 fts5yymsp[-1].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
235859 break;
235860 case 26: /* star_opt ::= STAR */
 
235861 { fts5yymsp[0].minor.fts5yy4 = 1; }
 
235862 break;
235863 case 27: /* star_opt ::= */
 
235864 { fts5yymsp[1].minor.fts5yy4 = 0; }
 
235865 break;
235866 default:
235867 break;
235868 /********** End reduce actions ************************************************/
235869 };
@@ -236573,17 +235921,15 @@
235921 ){
235922 sqlite3Fts5ParserARG_FETCH
235923 sqlite3Fts5ParserCTX_FETCH
235924 #define FTS5TOKEN fts5yyminor
235925 /************ Begin %syntax_error code ****************************************/
 
235926
235927 UNUSED_PARAM(fts5yymajor); /* Silence a compiler warning */
235928 sqlite3Fts5ParseError(
235929 pParse, "fts5: syntax error near \"%.*s\"",FTS5TOKEN.n,FTS5TOKEN.p
235930 );
 
235931 /************ End %syntax_error code ******************************************/
235932 sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
235933 sqlite3Fts5ParserCTX_STORE
235934 }
235935
@@ -236849,11 +236195,10 @@
236195 (void)iToken;
236196 return 0;
236197 #endif
236198 }
236199
 
236200 /*
236201 ** 2014 May 31
236202 **
236203 ** The author disclaims copyright to this source code. In place of
236204 ** a legal notice, here is a blessing:
@@ -237672,11 +237017,10 @@
237017 }
237018
237019 return rc;
237020 }
237021
 
237022 /*
237023 ** 2014 May 31
237024 **
237025 ** The author disclaims copyright to this source code. In place of
237026 ** a legal notice, here is a blessing:
@@ -238085,11 +237429,10 @@
237429 }
237430 sqlite3_free(p);
237431 }
237432 }
237433
 
237434 /*
237435 ** 2014 Jun 09
237436 **
237437 ** The author disclaims copyright to this source code. In place of
237438 ** a legal notice, here is a blessing:
@@ -239114,10 +238457,23 @@
238457 if( bVal<0 ){
238458 *pbBadkey = 1;
238459 }else{
238460 pConfig->bSecureDelete = (bVal ? 1 : 0);
238461 }
238462 }
238463
238464 else if( 0==sqlite3_stricmp(zKey, "insttoken") ){
238465 int bVal = -1;
238466 if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
238467 bVal = sqlite3_value_int(pVal);
238468 }
238469 if( bVal<0 ){
238470 *pbBadkey = 1;
238471 }else{
238472 pConfig->bPrefixInsttoken = (bVal ? 1 : 0);
238473 }
238474
238475 }else{
238476 *pbBadkey = 1;
238477 }
238478 return rc;
238479 }
@@ -239201,11 +238557,10 @@
238557 va_end(ap);
238558 }
238559
238560
238561
 
238562 /*
238563 ** 2014 May 31
238564 **
238565 ** The author disclaims copyright to this source code. In place of
238566 ** a legal notice, here is a blessing:
@@ -242250,11 +241605,11 @@
241605 && memcmp(pT->pTerm, pToken, pT->nQueryTerm)==0
241606 ){
241607 int rc = sqlite3Fts5PoslistWriterAppend(
241608 &pExpr->apExprPhrase[i]->poslist, &p->aPopulator[i].writer, p->iOff
241609 );
241610 if( rc==SQLITE_OK && (pExpr->pConfig->bTokendata || pT->bPrefix) ){
241611 int iCol = p->iOff>>32;
241612 int iTokOff = p->iOff & 0x7FFFFFFF;
241613 rc = sqlite3Fts5IndexIterWriteTokendata(
241614 pT->pIter, pToken, nToken, iRowid, iCol, iTokOff
241615 );
@@ -242443,19 +241798,18 @@
241798 pPhrase = pExpr->apExprPhrase[iPhrase];
241799 if( iToken<0 || iToken>=pPhrase->nTerm ){
241800 return SQLITE_RANGE;
241801 }
241802 pTerm = &pPhrase->aTerm[iToken];
241803 if( pExpr->pConfig->bTokendata || pTerm->bPrefix ){
241804 rc = sqlite3Fts5IterToken(
241805 pTerm->pIter, pTerm->pTerm, pTerm->nQueryTerm,
241806 iRowid, iCol, iOff+iToken, ppOut, pnOut
241807 );
241808 }else{
241809 *ppOut = pTerm->pTerm;
241810 *pnOut = pTerm->nFullTerm;
 
241811 }
241812 return rc;
241813 }
241814
241815 /*
@@ -242470,11 +241824,10 @@
241824 sqlite3Fts5IndexIterClearTokendata(pT->pIter);
241825 }
241826 }
241827 }
241828
 
241829 /*
241830 ** 2014 August 11
241831 **
241832 ** The author disclaims copyright to this source code. In place of
241833 ** a legal notice, here is a blessing:
@@ -243062,11 +242415,10 @@
242415 *ppDoclist = 0;
242416 *pnDoclist = 0;
242417 }
242418 }
242419
 
242420 /*
242421 ** 2014 May 31
242422 **
242423 ** The author disclaims copyright to this source code. In place of
242424 ** a legal notice, here is a blessing:
@@ -249268,10 +248620,387 @@
248620 fts5BufferFree(&tmp);
248621 memset(&out.p[out.n], 0, FTS5_DATA_ZERO_PADDING);
248622 *p1 = out;
248623 }
248624
248625
248626 /*
248627 ** Iterate through a range of entries in the FTS index, invoking the xVisit
248628 ** callback for each of them.
248629 **
248630 ** Parameter pToken points to an nToken buffer containing an FTS index term
248631 ** (i.e. a document term with the preceding 1 byte index identifier -
248632 ** FTS5_MAIN_PREFIX or similar). If bPrefix is true, then the call visits
248633 ** all entries for terms that have pToken/nToken as a prefix. If bPrefix
248634 ** is false, then only entries with pToken/nToken as the entire key are
248635 ** visited.
248636 **
248637 ** If the current table is a tokendata=1 table, then if bPrefix is true then
248638 ** each index term is treated separately. However, if bPrefix is false, then
248639 ** all index terms corresponding to pToken/nToken are collapsed into a single
248640 ** term before the callback is invoked.
248641 **
248642 ** The callback invoked for each entry visited is specified by paramter xVisit.
248643 ** Each time it is invoked, it is passed a pointer to the Fts5Index object,
248644 ** a copy of the 7th paramter to this function (pCtx) and a pointer to the
248645 ** iterator that indicates the current entry. If the current entry is the
248646 ** first with a new term (i.e. different from that of the previous entry,
248647 ** including the very first term), then the final two parameters are passed
248648 ** a pointer to the term and its size in bytes, respectively. If the current
248649 ** entry is not the first associated with its term, these two parameters
248650 ** are passed 0.
248651 **
248652 ** If parameter pColset is not NULL, then it is used to filter entries before
248653 ** the callback is invoked.
248654 */
248655 static int fts5VisitEntries(
248656 Fts5Index *p, /* Fts5 index object */
248657 Fts5Colset *pColset, /* Columns filter to apply, or NULL */
248658 u8 *pToken, /* Buffer containing token */
248659 int nToken, /* Size of buffer pToken in bytes */
248660 int bPrefix, /* True for a prefix scan */
248661 void (*xVisit)(Fts5Index*, void *pCtx, Fts5Iter *pIter, const u8*, int),
248662 void *pCtx /* Passed as second argument to xVisit() */
248663 ){
248664 const int flags = (bPrefix ? FTS5INDEX_QUERY_SCAN : 0)
248665 | FTS5INDEX_QUERY_SKIPEMPTY
248666 | FTS5INDEX_QUERY_NOOUTPUT;
248667 Fts5Iter *p1 = 0; /* Iterator used to gather data from index */
248668 int bNewTerm = 1;
248669 Fts5Structure *pStruct = fts5StructureRead(p);
248670
248671 fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1);
248672 fts5IterSetOutputCb(&p->rc, p1);
248673 for( /* no-op */ ;
248674 fts5MultiIterEof(p, p1)==0;
248675 fts5MultiIterNext2(p, p1, &bNewTerm)
248676 ){
248677 Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ];
248678 int nNew = 0;
248679 const u8 *pNew = 0;
248680
248681 p1->xSetOutputs(p1, pSeg);
248682 if( p->rc ) break;
248683
248684 if( bNewTerm ){
248685 nNew = pSeg->term.n;
248686 pNew = pSeg->term.p;
248687 if( nNew<nToken || memcmp(pToken, pNew, nToken) ) break;
248688 }
248689
248690 xVisit(p, pCtx, p1, pNew, nNew);
248691 }
248692 fts5MultiIterFree(p1);
248693
248694 fts5StructureRelease(pStruct);
248695 return p->rc;
248696 }
248697
248698
248699 /*
248700 ** Usually, a tokendata=1 iterator (struct Fts5TokenDataIter) accumulates an
248701 ** array of these for each row it visits (so all iRowid fields are the same).
248702 ** Or, for an iterator used by an "ORDER BY rank" query, it accumulates an
248703 ** array of these for the entire query (in which case iRowid fields may take
248704 ** a variety of values).
248705 **
248706 ** Each instance in the array indicates the iterator (and therefore term)
248707 ** associated with position iPos of rowid iRowid. This is used by the
248708 ** xInstToken() API.
248709 **
248710 ** iRowid:
248711 ** Rowid for the current entry.
248712 **
248713 ** iPos:
248714 ** Position of current entry within row. In the usual ((iCol<<32)+iOff)
248715 ** format (e.g. see macros FTS5_POS2COLUMN() and FTS5_POS2OFFSET()).
248716 **
248717 ** iIter:
248718 ** If the Fts5TokenDataIter iterator that the entry is part of is
248719 ** actually an iterator (i.e. with nIter>0, not just a container for
248720 ** Fts5TokenDataMap structures), then this variable is an index into
248721 ** the apIter[] array. The corresponding term is that which the iterator
248722 ** at apIter[iIter] currently points to.
248723 **
248724 ** Or, if the Fts5TokenDataIter iterator is just a container object
248725 ** (nIter==0), then iIter is an index into the term.p[] buffer where
248726 ** the term is stored.
248727 **
248728 ** nByte:
248729 ** In the case where iIter is an index into term.p[], this variable
248730 ** is the size of the term in bytes. If iIter is an index into apIter[],
248731 ** this variable is unused.
248732 */
248733 struct Fts5TokenDataMap {
248734 i64 iRowid; /* Row this token is located in */
248735 i64 iPos; /* Position of token */
248736 int iIter; /* Iterator token was read from */
248737 int nByte; /* Length of token in bytes (or 0) */
248738 };
248739
248740 /*
248741 ** An object used to supplement Fts5Iter for tokendata=1 iterators.
248742 **
248743 ** This object serves two purposes. The first is as a container for an array
248744 ** of Fts5TokenDataMap structures, which are used to find the token required
248745 ** when the xInstToken() API is used. This is done by the nMapAlloc, nMap and
248746 ** aMap[] variables.
248747 */
248748 struct Fts5TokenDataIter {
248749 int nMapAlloc; /* Allocated size of aMap[] in entries */
248750 int nMap; /* Number of valid entries in aMap[] */
248751 Fts5TokenDataMap *aMap; /* Array of (rowid+pos -> token) mappings */
248752
248753 /* The following are used for prefix-queries only. */
248754 Fts5Buffer terms;
248755
248756 /* The following are used for other full-token tokendata queries only. */
248757 int nIter;
248758 int nIterAlloc;
248759 Fts5PoslistReader *aPoslistReader;
248760 int *aPoslistToIter;
248761 Fts5Iter *apIter[1];
248762 };
248763
248764 /*
248765 ** The two input arrays - a1[] and a2[] - are in sorted order. This function
248766 ** merges the two arrays together and writes the result to output array
248767 ** aOut[]. aOut[] is guaranteed to be large enough to hold the result.
248768 **
248769 ** Duplicate entries are copied into the output. So the size of the output
248770 ** array is always (n1+n2) entries.
248771 */
248772 static void fts5TokendataMerge(
248773 Fts5TokenDataMap *a1, int n1, /* Input array 1 */
248774 Fts5TokenDataMap *a2, int n2, /* Input array 2 */
248775 Fts5TokenDataMap *aOut /* Output array */
248776 ){
248777 int i1 = 0;
248778 int i2 = 0;
248779
248780 assert( n1>=0 && n2>=0 );
248781 while( i1<n1 || i2<n2 ){
248782 Fts5TokenDataMap *pOut = &aOut[i1+i2];
248783 if( i2>=n2 || (i1<n1 && (
248784 a1[i1].iRowid<a2[i2].iRowid
248785 || (a1[i1].iRowid==a2[i2].iRowid && a1[i1].iPos<=a2[i2].iPos)
248786 ))){
248787 memcpy(pOut, &a1[i1], sizeof(Fts5TokenDataMap));
248788 i1++;
248789 }else{
248790 memcpy(pOut, &a2[i2], sizeof(Fts5TokenDataMap));
248791 i2++;
248792 }
248793 }
248794 }
248795
248796
248797 /*
248798 ** Append a mapping to the token-map belonging to object pT.
248799 */
248800 static void fts5TokendataIterAppendMap(
248801 Fts5Index *p,
248802 Fts5TokenDataIter *pT,
248803 int iIter,
248804 int nByte,
248805 i64 iRowid,
248806 i64 iPos
248807 ){
248808 if( p->rc==SQLITE_OK ){
248809 if( pT->nMap==pT->nMapAlloc ){
248810 int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64;
248811 int nAlloc = nNew * sizeof(Fts5TokenDataMap);
248812 Fts5TokenDataMap *aNew;
248813
248814 aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nAlloc);
248815 if( aNew==0 ){
248816 p->rc = SQLITE_NOMEM;
248817 return;
248818 }
248819
248820 pT->aMap = aNew;
248821 pT->nMapAlloc = nNew;
248822 }
248823
248824 pT->aMap[pT->nMap].iRowid = iRowid;
248825 pT->aMap[pT->nMap].iPos = iPos;
248826 pT->aMap[pT->nMap].iIter = iIter;
248827 pT->aMap[pT->nMap].nByte = nByte;
248828 pT->nMap++;
248829 }
248830 }
248831
248832 /*
248833 ** Sort the contents of the pT->aMap[] array.
248834 **
248835 ** The sorting algorithm requries a malloc(). If this fails, an error code
248836 ** is left in Fts5Index.rc before returning.
248837 */
248838 static void fts5TokendataIterSortMap(Fts5Index *p, Fts5TokenDataIter *pT){
248839 Fts5TokenDataMap *aTmp = 0;
248840 int nByte = pT->nMap * sizeof(Fts5TokenDataMap);
248841
248842 aTmp = (Fts5TokenDataMap*)sqlite3Fts5MallocZero(&p->rc, nByte);
248843 if( aTmp ){
248844 Fts5TokenDataMap *a1 = pT->aMap;
248845 Fts5TokenDataMap *a2 = aTmp;
248846 i64 nHalf;
248847
248848 for(nHalf=1; nHalf<pT->nMap; nHalf=nHalf*2){
248849 int i1;
248850 for(i1=0; i1<pT->nMap; i1+=(nHalf*2)){
248851 int n1 = MIN(nHalf, pT->nMap-i1);
248852 int n2 = MIN(nHalf, pT->nMap-i1-n1);
248853 fts5TokendataMerge(&a1[i1], n1, &a1[i1+n1], n2, &a2[i1]);
248854 }
248855 SWAPVAL(Fts5TokenDataMap*, a1, a2);
248856 }
248857
248858 if( a1!=pT->aMap ){
248859 memcpy(pT->aMap, a1, pT->nMap*sizeof(Fts5TokenDataMap));
248860 }
248861 sqlite3_free(aTmp);
248862
248863 #ifdef SQLITE_DEBUG
248864 {
248865 int ii;
248866 for(ii=1; ii<pT->nMap; ii++){
248867 Fts5TokenDataMap *p1 = &pT->aMap[ii-1];
248868 Fts5TokenDataMap *p2 = &pT->aMap[ii];
248869 assert( p1->iRowid<p2->iRowid
248870 || (p1->iRowid==p2->iRowid && p1->iPos<=p2->iPos)
248871 );
248872 }
248873 }
248874 #endif
248875 }
248876 }
248877
248878 /*
248879 ** Delete an Fts5TokenDataIter structure and its contents.
248880 */
248881 static void fts5TokendataIterDelete(Fts5TokenDataIter *pSet){
248882 if( pSet ){
248883 int ii;
248884 for(ii=0; ii<pSet->nIter; ii++){
248885 fts5MultiIterFree(pSet->apIter[ii]);
248886 }
248887 fts5BufferFree(&pSet->terms);
248888 sqlite3_free(pSet->aPoslistReader);
248889 sqlite3_free(pSet->aMap);
248890 sqlite3_free(pSet);
248891 }
248892 }
248893
248894
248895 /*
248896 ** fts5VisitEntries() context object used by fts5SetupPrefixIterTokendata()
248897 ** to pass data to prefixIterSetupTokendataCb().
248898 */
248899 typedef struct TokendataSetupCtx TokendataSetupCtx;
248900 struct TokendataSetupCtx {
248901 Fts5TokenDataIter *pT; /* Object being populated with mappings */
248902 int iTermOff; /* Offset of current term in terms.p[] */
248903 int nTermByte; /* Size of current term in bytes */
248904 };
248905
248906 /*
248907 ** fts5VisitEntries() callback used by fts5SetupPrefixIterTokendata(). This
248908 ** callback adds an entry to the Fts5TokenDataIter.aMap[] array for each
248909 ** position in the current position-list. It doesn't matter that some of
248910 ** these may be out of order - they will be sorted later.
248911 */
248912 static void prefixIterSetupTokendataCb(
248913 Fts5Index *p,
248914 void *pCtx,
248915 Fts5Iter *p1,
248916 const u8 *pNew,
248917 int nNew
248918 ){
248919 TokendataSetupCtx *pSetup = (TokendataSetupCtx*)pCtx;
248920 int iPosOff = 0;
248921 i64 iPos = 0;
248922
248923 if( pNew ){
248924 pSetup->nTermByte = nNew-1;
248925 pSetup->iTermOff = pSetup->pT->terms.n;
248926 fts5BufferAppendBlob(&p->rc, &pSetup->pT->terms, nNew-1, pNew+1);
248927 }
248928
248929 while( 0==sqlite3Fts5PoslistNext64(
248930 p1->base.pData, p1->base.nData, &iPosOff, &iPos
248931 ) ){
248932 fts5TokendataIterAppendMap(p,
248933 pSetup->pT, pSetup->iTermOff, pSetup->nTermByte, p1->base.iRowid, iPos
248934 );
248935 }
248936 }
248937
248938
248939 /*
248940 ** Context object passed by fts5SetupPrefixIter() to fts5VisitEntries().
248941 */
248942 typedef struct PrefixSetupCtx PrefixSetupCtx;
248943 struct PrefixSetupCtx {
248944 void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*);
248945 void (*xAppend)(Fts5Index*, u64, Fts5Iter*, Fts5Buffer*);
248946 i64 iLastRowid;
248947 int nMerge;
248948 Fts5Buffer *aBuf;
248949 int nBuf;
248950 Fts5Buffer doclist;
248951 TokendataSetupCtx *pTokendata;
248952 };
248953
248954 /*
248955 ** fts5VisitEntries() callback used by fts5SetupPrefixIter()
248956 */
248957 static void prefixIterSetupCb(
248958 Fts5Index *p,
248959 void *pCtx,
248960 Fts5Iter *p1,
248961 const u8 *pNew,
248962 int nNew
248963 ){
248964 PrefixSetupCtx *pSetup = (PrefixSetupCtx*)pCtx;
248965 const int nMerge = pSetup->nMerge;
248966
248967 if( p1->base.nData>0 ){
248968 if( p1->base.iRowid<=pSetup->iLastRowid && pSetup->doclist.n>0 ){
248969 int i;
248970 for(i=0; p->rc==SQLITE_OK && pSetup->doclist.n; i++){
248971 int i1 = i*nMerge;
248972 int iStore;
248973 assert( i1+nMerge<=pSetup->nBuf );
248974 for(iStore=i1; iStore<i1+nMerge; iStore++){
248975 if( pSetup->aBuf[iStore].n==0 ){
248976 fts5BufferSwap(&pSetup->doclist, &pSetup->aBuf[iStore]);
248977 fts5BufferZero(&pSetup->doclist);
248978 break;
248979 }
248980 }
248981 if( iStore==i1+nMerge ){
248982 pSetup->xMerge(p, &pSetup->doclist, nMerge, &pSetup->aBuf[i1]);
248983 for(iStore=i1; iStore<i1+nMerge; iStore++){
248984 fts5BufferZero(&pSetup->aBuf[iStore]);
248985 }
248986 }
248987 }
248988 pSetup->iLastRowid = 0;
248989 }
248990
248991 pSetup->xAppend(
248992 p, (u64)p1->base.iRowid-(u64)pSetup->iLastRowid, p1, &pSetup->doclist
248993 );
248994 pSetup->iLastRowid = p1->base.iRowid;
248995 }
248996
248997 if( pSetup->pTokendata ){
248998 prefixIterSetupTokendataCb(p, (void*)pSetup->pTokendata, p1, pNew, nNew);
248999 }
249000 }
249001
249002 static void fts5SetupPrefixIter(
249003 Fts5Index *p, /* Index to read from */
249004 int bDesc, /* True for "ORDER BY rowid DESC" */
249005 int iIdx, /* Index to scan for data */
249006 u8 *pToken, /* Buffer containing prefix to match */
@@ -249278,137 +249007,89 @@
249007 int nToken, /* Size of buffer pToken in bytes */
249008 Fts5Colset *pColset, /* Restrict matches to these columns */
249009 Fts5Iter **ppIter /* OUT: New iterator */
249010 ){
249011 Fts5Structure *pStruct;
249012 PrefixSetupCtx s;
249013 TokendataSetupCtx s2;
 
249014
249015 memset(&s, 0, sizeof(s));
249016 memset(&s2, 0, sizeof(s2));
249017
249018 s.nMerge = 1;
249019 s.iLastRowid = 0;
249020 s.nBuf = 32;
249021 if( iIdx==0
249022 && p->pConfig->eDetail==FTS5_DETAIL_FULL
249023 && p->pConfig->bPrefixInsttoken
249024 ){
249025 s.pTokendata = &s2;
249026 s2.pT = (Fts5TokenDataIter*)fts5IdxMalloc(p, sizeof(*s2.pT));
249027 }
249028
249029 if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
249030 s.xMerge = fts5MergeRowidLists;
249031 s.xAppend = fts5AppendRowid;
249032 }else{
249033 s.nMerge = FTS5_MERGE_NLIST-1;
249034 s.nBuf = s.nMerge*8; /* Sufficient to merge (16^8)==(2^32) lists */
249035 s.xMerge = fts5MergePrefixLists;
249036 s.xAppend = fts5AppendPoslist;
249037 }
249038
249039 s.aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*s.nBuf);
249040 pStruct = fts5StructureRead(p);
249041 assert( p->rc!=SQLITE_OK || (s.aBuf && pStruct) );
249042
249043 if( p->rc==SQLITE_OK ){
249044 void *pCtx = (void*)&s;
 
 
249045 int i;
 
 
249046 Fts5Data *pData;
 
 
 
 
249047
249048 /* If iIdx is non-zero, then it is the number of a prefix-index for
249049 ** prefixes 1 character longer than the prefix being queried for. That
249050 ** index contains all the doclists required, except for the one
249051 ** corresponding to the prefix itself. That one is extracted from the
249052 ** main term index here. */
249053 if( iIdx!=0 ){
 
 
249054 pToken[0] = FTS5_MAIN_PREFIX;
249055 fts5VisitEntries(p, pColset, pToken, nToken, 0, prefixIterSetupCb, pCtx);
 
 
 
 
 
 
 
 
 
 
 
 
 
249056 }
249057
249058 pToken[0] = FTS5_MAIN_PREFIX + iIdx;
249059 fts5VisitEntries(p, pColset, pToken, nToken, 1, prefixIterSetupCb, pCtx);
249060
249061 assert( (s.nBuf%s.nMerge)==0 );
249062 for(i=0; i<s.nBuf; i+=s.nMerge){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249063 int iFree;
249064 if( p->rc==SQLITE_OK ){
249065 s.xMerge(p, &s.doclist, s.nMerge, &s.aBuf[i]);
249066 }
249067 for(iFree=i; iFree<i+s.nMerge; iFree++){
249068 fts5BufferFree(&s.aBuf[iFree]);
249069 }
249070 }
 
249071
249072 pData = fts5IdxMalloc(p, sizeof(*pData)+s.doclist.n+FTS5_DATA_ZERO_PADDING);
249073 if( pData ){
249074 pData->p = (u8*)&pData[1];
249075 pData->nn = pData->szLeaf = s.doclist.n;
249076 if( s.doclist.n ) memcpy(pData->p, s.doclist.p, s.doclist.n);
249077 fts5MultiIterNew2(p, pData, bDesc, ppIter);
249078 }
249079
249080 if( p->rc==SQLITE_OK && s.pTokendata ){
249081 fts5TokendataIterSortMap(p, s2.pT);
249082 (*ppIter)->pTokenDataIter = s2.pT;
249083 s2.pT = 0;
249084 }
249085 }
249086
249087 fts5TokendataIterDelete(s2.pT);
249088 fts5BufferFree(&s.doclist);
249089 fts5StructureRelease(pStruct);
249090 sqlite3_free(s.aBuf);
249091 }
249092
249093
249094 /*
249095 ** Indicate that all subsequent calls to sqlite3Fts5IndexWrite() pertain
@@ -249658,42 +249339,10 @@
249339 static void fts5SegIterSetEOF(Fts5SegIter *pSeg){
249340 fts5DataRelease(pSeg->pLeaf);
249341 pSeg->pLeaf = 0;
249342 }
249343
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249344 /*
249345 ** This function appends iterator pAppend to Fts5TokenDataIter pIn and
249346 ** returns the result.
249347 */
249348 static Fts5TokenDataIter *fts5AppendTokendataIter(
@@ -249726,58 +249375,10 @@
249375 assert( pRet==0 || pRet->nIter<=pRet->nIterAlloc );
249376
249377 return pRet;
249378 }
249379
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249380 /*
249381 ** The iterator passed as the only argument must be a tokendata=1 iterator
249382 ** (pIter->pTokenDataIter!=0). This function sets the iterator output
249383 ** variables (pIter->base.*) according to the contents of the current
249384 ** row.
@@ -249814,11 +249415,11 @@
249415 int eDetail = pIter->pIndex->pConfig->eDetail;
249416 pIter->base.bEof = 0;
249417 pIter->base.iRowid = iRowid;
249418
249419 if( nHit==1 && eDetail==FTS5_DETAIL_FULL ){
249420 fts5TokendataIterAppendMap(pIter->pIndex, pT, iMin, 0, iRowid, -1);
249421 }else
249422 if( nHit>1 && eDetail!=FTS5_DETAIL_NONE ){
249423 int nReader = 0;
249424 int nByte = 0;
249425 i64 iPrev = 0;
@@ -250067,10 +249668,11 @@
249668
249669 if( p->rc==SQLITE_OK ){
249670 pRet = fts5MultiIterAlloc(p, 0);
249671 }
249672 if( pRet ){
249673 pRet->nSeg = 0;
249674 pRet->pTokenDataIter = pSet;
249675 if( pSet ){
249676 fts5IterSetOutputsTokendata(pRet);
249677 }else{
249678 pRet->base.bEof = 1;
@@ -250081,11 +249683,10 @@
249683
249684 fts5StructureRelease(pStruct);
249685 fts5BufferFree(&bSeek);
249686 return pRet;
249687 }
 
249688
249689 /*
249690 ** Open a new iterator to iterate though all rowid that match the
249691 ** specified token or token prefix.
249692 */
@@ -250107,10 +249708,15 @@
249708 int iIdx = 0; /* Index to search */
249709 int iPrefixIdx = 0; /* +1 prefix index */
249710 int bTokendata = pConfig->bTokendata;
249711 if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken);
249712
249713 /* The NOTOKENDATA flag is set when each token in a tokendata=1 table
249714 ** should be treated individually, instead of merging all those with
249715 ** a common prefix into a single entry. This is used, for example, by
249716 ** queries performed as part of an integrity-check, or by the fts5vocab
249717 ** module. */
249718 if( flags & (FTS5INDEX_QUERY_NOTOKENDATA|FTS5INDEX_QUERY_SCAN) ){
249719 bTokendata = 0;
249720 }
249721
249722 /* Figure out which index to search and set iIdx accordingly. If this
@@ -250137,11 +249743,11 @@
249743 if( nIdxChar==nChar+1 ) iPrefixIdx = iIdx;
249744 }
249745 }
249746
249747 if( bTokendata && iIdx==0 ){
249748 buf.p[0] = FTS5_MAIN_PREFIX;
249749 pRet = fts5SetupTokendataIter(p, buf.p, nToken+1, pColset);
249750 }else if( iIdx<=pConfig->nPrefix ){
249751 /* Straight index lookup */
249752 Fts5Structure *pStruct = fts5StructureRead(p);
249753 buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx);
@@ -250150,11 +249756,11 @@
249756 pColset, buf.p, nToken+1, -1, 0, &pRet
249757 );
249758 fts5StructureRelease(pStruct);
249759 }
249760 }else{
249761 /* Scan multiple terms in the main index for a prefix query. */
249762 int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0;
249763 fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet);
249764 if( pRet==0 ){
249765 assert( p->rc!=SQLITE_OK );
249766 }else{
@@ -250186,11 +249792,12 @@
249792 ** Move to the next matching rowid.
249793 */
249794 static int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){
249795 Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
249796 assert( pIter->pIndex->rc==SQLITE_OK );
249797 if( pIter->nSeg==0 ){
249798 assert( pIter->pTokenDataIter );
249799 fts5TokendataIterNext(pIter, 0, 0);
249800 }else{
249801 fts5MultiIterNext(pIter->pIndex, pIter, 0, 0);
249802 }
249803 return fts5IndexReturn(pIter->pIndex);
@@ -250223,11 +249830,12 @@
249830 ** definition of "at or after" depends on whether this iterator iterates
249831 ** in ascending or descending rowid order.
249832 */
249833 static int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){
249834 Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
249835 if( pIter->nSeg==0 ){
249836 assert( pIter->pTokenDataIter );
249837 fts5TokendataIterNext(pIter, 1, iMatch);
249838 }else{
249839 fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch);
249840 }
249841 return fts5IndexReturn(pIter->pIndex);
@@ -250241,32 +249849,87 @@
249849 const char *z = (const char*)fts5MultiIterTerm((Fts5Iter*)pIndexIter, &n);
249850 assert_nc( z || n<=1 );
249851 *pn = n-1;
249852 return (z ? &z[1] : 0);
249853 }
249854
249855 /*
249856 ** pIter is a prefix query. This function populates pIter->pTokenDataIter
249857 ** with an Fts5TokenDataIter object containing mappings for all rows
249858 ** matched by the query.
249859 */
249860 static int fts5SetupPrefixIterTokendata(
249861 Fts5Iter *pIter,
249862 const char *pToken, /* Token prefix to search for */
249863 int nToken /* Size of pToken in bytes */
249864 ){
249865 Fts5Index *p = pIter->pIndex;
249866 Fts5Buffer token = {0, 0, 0};
249867 TokendataSetupCtx ctx;
249868
249869 memset(&ctx, 0, sizeof(ctx));
249870
249871 fts5BufferGrow(&p->rc, &token, nToken+1);
249872 ctx.pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*ctx.pT));
249873
249874 if( p->rc==SQLITE_OK ){
249875
249876 /* Fill in the token prefix to search for */
249877 token.p[0] = FTS5_MAIN_PREFIX;
249878 memcpy(&token.p[1], pToken, nToken);
249879 token.n = nToken+1;
249880
249881 fts5VisitEntries(
249882 p, 0, token.p, token.n, 1, prefixIterSetupTokendataCb, (void*)&ctx
249883 );
249884
249885 fts5TokendataIterSortMap(p, ctx.pT);
249886 }
249887
249888 if( p->rc==SQLITE_OK ){
249889 pIter->pTokenDataIter = ctx.pT;
249890 }else{
249891 fts5TokendataIterDelete(ctx.pT);
249892 }
249893 fts5BufferFree(&token);
249894
249895 return fts5IndexReturn(p);
249896 }
249897
249898 /*
249899 ** This is used by xInstToken() to access the token at offset iOff, column
249900 ** iCol of row iRowid. The token is returned via output variables *ppOut
249901 ** and *pnOut. The iterator passed as the first argument must be a tokendata=1
249902 ** iterator (pIter->pTokenDataIter!=0).
249903 **
249904 ** pToken/nToken:
249905 */
249906 static int sqlite3Fts5IterToken(
249907 Fts5IndexIter *pIndexIter,
249908 const char *pToken, int nToken,
249909 i64 iRowid,
249910 int iCol,
249911 int iOff,
249912 const char **ppOut, int *pnOut
249913 ){
249914 Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
249915 Fts5TokenDataIter *pT = pIter->pTokenDataIter;
 
249916 i64 iPos = (((i64)iCol)<<32) + iOff;
249917 Fts5TokenDataMap *aMap = 0;
249918 int i1 = 0;
249919 int i2 = 0;
249920 int iTest = 0;
249921
249922 assert( pT || (pToken && pIter->nSeg>0) );
249923 if( pT==0 ){
249924 int rc = fts5SetupPrefixIterTokendata(pIter, pToken, nToken);
249925 if( rc!=SQLITE_OK ) return rc;
249926 pT = pIter->pTokenDataIter;
249927 }
249928
249929 i2 = pT->nMap;
249930 aMap = pT->aMap;
249931
249932 while( i2>i1 ){
249933 iTest = (i1 + i2) / 2;
249934
249935 if( aMap[iTest].iRowid<iRowid ){
@@ -250286,13 +249949,19 @@
249949 }
249950 }
249951 }
249952
249953 if( i2>i1 ){
249954 if( pIter->nSeg==0 ){
249955 Fts5Iter *pMap = pT->apIter[aMap[iTest].iIter];
249956 *ppOut = (const char*)pMap->aSeg[0].term.p+1;
249957 *pnOut = pMap->aSeg[0].term.n-1;
249958 }else{
249959 Fts5TokenDataMap *p = &aMap[iTest];
249960 *ppOut = (const char*)&pT->terms.p[p->iIter];
249961 *pnOut = aMap[iTest].nByte;
249962 }
249963 }
249964
249965 return SQLITE_OK;
249966 }
249967
@@ -250300,11 +249969,13 @@
249969 ** Clear any existing entries from the token-map associated with the
249970 ** iterator passed as the only argument.
249971 */
249972 static void sqlite3Fts5IndexIterClearTokendata(Fts5IndexIter *pIndexIter){
249973 Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
249974 if( pIter && pIter->pTokenDataIter
249975 && (pIter->nSeg==0 || pIter->pIndex->pConfig->eDetail!=FTS5_DETAIL_FULL)
249976 ){
249977 pIter->pTokenDataIter->nMap = 0;
249978 }
249979 }
249980
249981 /*
@@ -250320,21 +249991,33 @@
249991 i64 iRowid, int iCol, int iOff
249992 ){
249993 Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
249994 Fts5TokenDataIter *pT = pIter->pTokenDataIter;
249995 Fts5Index *p = pIter->pIndex;
249996 i64 iPos = (((i64)iCol)<<32) + iOff;
249997
249998 assert( p->pConfig->eDetail!=FTS5_DETAIL_FULL );
249999 assert( pIter->pTokenDataIter || pIter->nSeg>0 );
250000 if( pIter->nSeg>0 ){
250001 /* This is a prefix term iterator. */
250002 if( pT==0 ){
250003 pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*pT));
250004 pIter->pTokenDataIter = pT;
250005 }
250006 if( pT ){
250007 fts5TokendataIterAppendMap(p, pT, pT->terms.n, nToken, iRowid, iPos);
250008 fts5BufferAppendBlob(&p->rc, &pT->terms, nToken, (const u8*)pToken);
250009 }
250010 }else{
250011 int ii;
250012 for(ii=0; ii<pT->nIter; ii++){
250013 Fts5Buffer *pTerm = &pT->apIter[ii]->aSeg[0].term;
250014 if( nToken==pTerm->n-1 && memcmp(pToken, pTerm->p+1, nToken)==0 ) break;
250015 }
250016 if( ii<pT->nIter ){
250017 fts5TokendataIterAppendMap(p, pT, ii, 0, iRowid, iPos);
250018 }
250019 }
250020 return fts5IndexReturn(p);
250021 }
250022
250023 /*
@@ -252140,11 +251823,10 @@
251823 fts5StructureInvalidate(p);
251824 }
251825 return fts5IndexReturn(p);
251826 }
251827
 
251828 /*
251829 ** 2014 Jun 09
251830 **
251831 ** The author disclaims copyright to this source code. In place of
251832 ** a legal notice, here is a blessing:
@@ -252236,10 +251918,11 @@
251918 ** containing a copy of the header from an Fts5Config pointer.
251919 */
251920 #define FTS5_LOCALE_HDR_SIZE ((int)sizeof( ((Fts5Global*)0)->aLocaleHdr ))
251921 #define FTS5_LOCALE_HDR(pConfig) ((const u8*)(pConfig->pGlobal->aLocaleHdr))
251922
251923 #define FTS5_INSTTOKEN_SUBTYPE 73
251924
251925 /*
251926 ** Each auxiliary function registered with the FTS5 module is represented
251927 ** by an object of the following type. All such objects are stored as part
251928 ** of the Fts5Global.pAux list.
@@ -252775,10 +252458,11 @@
252458 ){
252459 /* A MATCH operator or equivalent */
252460 if( p->usable==0 || iCol<0 ){
252461 /* As there exists an unusable MATCH constraint this is an
252462 ** unusable plan. Return SQLITE_CONSTRAINT. */
252463 idxStr[iIdxStr] = 0;
252464 return SQLITE_CONSTRAINT;
252465 }else{
252466 if( iCol==nCol+1 ){
252467 if( bSeenRank ) continue;
252468 idxStr[iIdxStr++] = 'r';
@@ -253560,10 +253244,11 @@
253244 sqlite3_value *pRowidEq = 0; /* rowid = ? expression (or NULL) */
253245 sqlite3_value *pRowidLe = 0; /* rowid <= ? expression (or NULL) */
253246 sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */
253247 int iCol; /* Column on LHS of MATCH operator */
253248 char **pzErrmsg = pConfig->pzErrmsg;
253249 int bPrefixInsttoken = pConfig->bPrefixInsttoken;
253250 int i;
253251 int iIdxStr = 0;
253252 Fts5Expr *pExpr = 0;
253253
253254 assert( pConfig->bLock==0 );
@@ -253595,10 +253280,13 @@
253280 int bInternal = 0;
253281
253282 rc = fts5ExtractExprText(pConfig, apVal[i], &zText, &bFreeAndReset);
253283 if( rc!=SQLITE_OK ) goto filter_out;
253284 if( zText==0 ) zText = "";
253285 if( sqlite3_value_subtype(apVal[i])==FTS5_INSTTOKEN_SUBTYPE ){
253286 pConfig->bPrefixInsttoken = 1;
253287 }
253288
253289 iCol = 0;
253290 do{
253291 iCol = iCol*10 + (idxStr[iIdxStr]-'0');
253292 iIdxStr++;
@@ -253735,10 +253423,11 @@
253423 }
253424
253425 filter_out:
253426 sqlite3Fts5ExprFree(pExpr);
253427 pConfig->pzErrmsg = pzErrmsg;
253428 pConfig->bPrefixInsttoken = bPrefixInsttoken;
253429 return rc;
253430 }
253431
253432 /*
253433 ** This is the xEof method of the virtual table. SQLite calls this
@@ -255730,11 +255419,11 @@
255419 int nArg, /* Number of args */
255420 sqlite3_value **apUnused /* Function arguments */
255421 ){
255422 assert( nArg==0 );
255423 UNUSED_PARAM2(nArg, apUnused);
255424 sqlite3_result_text(pCtx, "fts5: 2024-12-09 20:46:36 e2bae4143afd07de1ae55a6d2606a3b541a5b94568aa41f6a96e5d1245471653", -1, SQLITE_TRANSIENT);
255425 }
255426
255427 /*
255428 ** Implementation of fts5_locale(LOCALE, TEXT) function.
255429 **
@@ -255793,10 +255482,24 @@
255482 assert( &pCsr[nText]==&pBlob[nBlob] );
255483
255484 sqlite3_result_blob(pCtx, pBlob, nBlob, sqlite3_free);
255485 }
255486 }
255487
255488 /*
255489 ** Implementation of fts5_insttoken() function.
255490 */
255491 static void fts5InsttokenFunc(
255492 sqlite3_context *pCtx, /* Function call context */
255493 int nArg, /* Number of args */
255494 sqlite3_value **apArg /* Function arguments */
255495 ){
255496 assert( nArg==1 );
255497 (void)nArg;
255498 sqlite3_result_value(pCtx, apArg[0]);
255499 sqlite3_result_subtype(pCtx, FTS5_INSTTOKEN_SUBTYPE);
255500 }
255501
255502 /*
255503 ** Return true if zName is the extension on one of the shadow tables used
255504 ** by this module.
255505 */
@@ -255923,13 +255626,20 @@
255626 );
255627 }
255628 if( rc==SQLITE_OK ){
255629 rc = sqlite3_create_function(
255630 db, "fts5_locale", 2,
255631 SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE|SQLITE_SUBTYPE,
255632 p, fts5LocaleFunc, 0, 0
255633 );
255634 }
255635 if( rc==SQLITE_OK ){
255636 rc = sqlite3_create_function(
255637 db, "fts5_insttoken", 1,
255638 SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE,
255639 p, fts5InsttokenFunc, 0, 0
255640 );
255641 }
255642 }
255643
255644 /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file
255645 ** fts5_test_mi.c is compiled and linked into the executable. And call
@@ -255983,11 +255693,10 @@
255693 SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3 *db){
255694 return fts5Init(db);
255695 }
255696 #endif
255697
 
255698 /*
255699 ** 2014 May 31
255700 **
255701 ** The author disclaims copyright to this source code. In place of
255702 ** a legal notice, here is a blessing:
@@ -257497,11 +257206,10 @@
257206 }
257207 }
257208 return rc;
257209 }
257210
 
257211 /*
257212 ** 2014 May 31
257213 **
257214 ** The author disclaims copyright to this source code. In place of
257215 ** a legal notice, here is a blessing:
@@ -258853,22 +258561,22 @@
258561 int rc = SQLITE_OK;
258562 char aBuf[32];
258563 char *zOut = aBuf;
258564 int ii;
258565 const unsigned char *zIn = (const unsigned char*)pText;
258566 const unsigned char *zEof = (zIn ? &zIn[nText] : 0);
258567 u32 iCode = 0;
258568 int aStart[3]; /* Input offset of each character in aBuf[] */
258569
258570 UNUSED_PARAM(unusedFlags);
258571
258572 /* Populate aBuf[] with the characters for the first trigram. */
258573 for(ii=0; ii<3; ii++){
258574 do {
258575 aStart[ii] = zIn - (const unsigned char*)pText;
258576 if( zIn>=zEof ) return SQLITE_OK;
258577 READ_UTF8(zIn, zEof, iCode);
 
258578 if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam);
258579 }while( iCode==0 );
258580 WRITE_UTF8(zOut, iCode);
258581 }
258582
@@ -258885,12 +258593,15 @@
258593 const char *z1;
258594
258595 /* Read characters from the input up until the first non-diacritic */
258596 do {
258597 iNext = zIn - (const unsigned char*)pText;
258598 if( zIn>=zEof ){
258599 iCode = 0;
258600 break;
258601 }
258602 READ_UTF8(zIn, zEof, iCode);
 
258603 if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam);
258604 }while( iCode==0 );
258605
258606 /* Pass the current trigram back to fts5 */
258607 rc = xToken(pCtx, 0, aBuf, zOut-aBuf, aStart[0], iNext);
@@ -258986,11 +258697,10 @@
258697 );
258698 }
258699 return rc;
258700 }
258701
 
258702 /*
258703 ** 2012-05-25
258704 **
258705 ** The author disclaims copyright to this source code. In place of
258706 ** a legal notice, here is a blessing:
@@ -259769,11 +259479,10 @@
259479 }
259480 aAscii[0] = 0; /* 0x00 is never a token character */
259481 }
259482
259483
 
259484 /*
259485 ** 2015 May 30
259486 **
259487 ** The author disclaims copyright to this source code. In place of
259488 ** a legal notice, here is a blessing:
@@ -260115,11 +259824,10 @@
259824 if( iVal<(1 << 21) ) return 3;
259825 if( iVal<(1 << 28) ) return 4;
259826 return 5;
259827 }
259828
 
259829 /*
259830 ** 2015 May 08
259831 **
259832 ** The author disclaims copyright to this source code. In place of
259833 ** a legal notice, here is a blessing:
@@ -260931,11 +260639,10 @@
260639 /* Here ends the fts5.c composite file. */
260640 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */
260641
260642 /************** End of fts5.c ************************************************/
260643 /************** Begin file stmt.c ********************************************/
 
260644 /*
260645 ** 2017-05-31
260646 **
260647 ** The author disclaims copyright to this source code. In place of
260648 ** a legal notice, here is a blessing:
260649
+41 -5
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,11 @@
146146
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147147
** [sqlite_version()] and [sqlite_source_id()].
148148
*/
149149
#define SQLITE_VERSION "3.48.0"
150150
#define SQLITE_VERSION_NUMBER 3048000
151
-#define SQLITE_SOURCE_ID "2024-11-06 12:58:31 5495b12569c318d5020b4b5a625a392ef8e777b81c0200624fbbc2a6b5eddef9"
151
+#define SQLITE_SOURCE_ID "2024-12-09 20:46:36 e2bae4143afd07de1ae55a6d2606a3b541a5b94568aa41f6a96e5d1245471653"
152152
153153
/*
154154
** CAPI3REF: Run-Time Library Version Numbers
155155
** KEYWORDS: sqlite3_version sqlite3_sourceid
156156
**
@@ -1098,10 +1098,15 @@
10981098
** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
10991099
** opcode causes the xFileControl method to swap the file handle with the one
11001100
** pointed to by the pArg argument. This capability is used during testing
11011101
** and only needs to be supported when SQLITE_TEST is defined.
11021102
**
1103
+** <li>[[SQLITE_FCNTL_NULL_IO]]
1104
+** The [SQLITE_FCNTL_NULL_IO] opcode sets the low-level file descriptor
1105
+** or file handle for the [sqlite3_file] object such that it will no longer
1106
+** read or write to the database file.
1107
+**
11031108
** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
11041109
** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
11051110
** be advantageous to block on the next WAL lock if the lock is not immediately
11061111
** available. The WAL subsystem issues this signal during rare
11071112
** circumstances in order to fix a problem with priority inversion.
@@ -1251,10 +1256,11 @@
12511256
#define SQLITE_FCNTL_RESERVE_BYTES 38
12521257
#define SQLITE_FCNTL_CKPT_START 39
12531258
#define SQLITE_FCNTL_EXTERNAL_READER 40
12541259
#define SQLITE_FCNTL_CKSM_FILE 41
12551260
#define SQLITE_FCNTL_RESET_CACHE 42
1261
+#define SQLITE_FCNTL_NULL_IO 43
12561262
12571263
/* deprecated names */
12581264
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
12591265
#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
12601266
#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -2629,14 +2635,18 @@
26292635
**
26302636
** ^These functions return the number of rows modified, inserted or
26312637
** deleted by the most recently completed INSERT, UPDATE or DELETE
26322638
** statement on the database connection specified by the only parameter.
26332639
** The two functions are identical except for the type of the return value
2634
-** and that if the number of rows modified by the most recent INSERT, UPDATE
2640
+** and that if the number of rows modified by the most recent INSERT, UPDATE,
26352641
** or DELETE is greater than the maximum value supported by type "int", then
26362642
** the return value of sqlite3_changes() is undefined. ^Executing any other
26372643
** type of SQL statement does not modify the value returned by these functions.
2644
+** For the purposes of this interface, a CREATE TABLE AS SELECT statement
2645
+** does not count as an INSERT, UPDATE or DELETE statement and hence the rows
2646
+** added to the new table by the CREATE TABLE AS SELECT statement are not
2647
+** counted.
26382648
**
26392649
** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are
26402650
** considered - auxiliary changes caused by [CREATE TRIGGER | triggers],
26412651
** [foreign key actions] or [REPLACE] constraint resolution are not counted.
26422652
**
@@ -4192,15 +4202,26 @@
41924202
**
41934203
** [[SQLITE_PREPARE_NO_VTAB]] <dt>SQLITE_PREPARE_NO_VTAB</dt>
41944204
** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler
41954205
** to return an error (error code SQLITE_ERROR) if the statement uses
41964206
** any virtual tables.
4207
+**
4208
+** [[SQLITE_PREPARE_DONT_LOG]] <dt>SQLITE_PREPARE_DONT_LOG</dt>
4209
+** <dd>The SQLITE_PREPARE_DONT_LOG flag prevents SQL compiler
4210
+** errors from being sent to the error log defined by
4211
+** [SQLITE_CONFIG_LOG]. This can be used, for example, to do test
4212
+** compiles to see if some SQL syntax is well-formed, without generating
4213
+** messages on the global error log when it is not. If the test compile
4214
+** fails, the sqlite3_prepare_v3() call returns the same error indications
4215
+** with or without this flag; it just omits the call to [sqlite3_log()] that
4216
+** logs the error.
41974217
** </dl>
41984218
*/
41994219
#define SQLITE_PREPARE_PERSISTENT 0x01
42004220
#define SQLITE_PREPARE_NORMALIZE 0x02
42014221
#define SQLITE_PREPARE_NO_VTAB 0x04
4222
+#define SQLITE_PREPARE_DONT_LOG 0x10
42024223
42034224
/*
42044225
** CAPI3REF: Compiling An SQL Statement
42054226
** KEYWORDS: {SQL statement compiler}
42064227
** METHOD: sqlite3
@@ -13138,17 +13159,32 @@
1313813159
** This is used to access token iToken of phrase hit iIdx within the
1313913160
** current row. If iIdx is less than zero or greater than or equal to the
1314013161
** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise,
1314113162
** output variable (*ppToken) is set to point to a buffer containing the
1314213163
** matching document token, and (*pnToken) to the size of that buffer in
13143
-** bytes. This API is not available if the specified token matches a
13144
-** prefix query term. In that case both output variables are always set
13145
-** to 0.
13164
+** bytes.
1314613165
**
1314713166
** The output text is not a copy of the document text that was tokenized.
1314813167
** It is the output of the tokenizer module. For tokendata=1 tables, this
1314913168
** includes any embedded 0x00 and trailing data.
13169
+**
13170
+** This API may be slow in some cases if the token identified by parameters
13171
+** iIdx and iToken matched a prefix token in the query. In most cases, the
13172
+** first call to this API for each prefix token in the query is forced
13173
+** to scan the portion of the full-text index that matches the prefix
13174
+** token to collect the extra data required by this API. If the prefix
13175
+** token matches a large number of token instances in the document set,
13176
+** this may be a performance problem.
13177
+**
13178
+** If the user knows in advance that a query may use this API for a
13179
+** prefix token, FTS5 may be configured to collect all required data as part
13180
+** of the initial querying of the full-text index, avoiding the second scan
13181
+** entirely. This also causes prefix queries that do not use this API to
13182
+** run more slowly and use more memory. FTS5 may be configured in this way
13183
+** either on a per-table basis using the [FTS5 insttoken | 'insttoken']
13184
+** option, or on a per-query basis using the
13185
+** [fts5_insttoken | fts5_insttoken()] user function.
1315013186
**
1315113187
** This API can be quite slow if used with an FTS5 table created with the
1315213188
** "detail=none" or "detail=column" option.
1315313189
**
1315413190
** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale)
1315513191
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,11 @@
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.48.0"
150 #define SQLITE_VERSION_NUMBER 3048000
151 #define SQLITE_SOURCE_ID "2024-11-06 12:58:31 5495b12569c318d5020b4b5a625a392ef8e777b81c0200624fbbc2a6b5eddef9"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -1098,10 +1098,15 @@
1098 ** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
1099 ** opcode causes the xFileControl method to swap the file handle with the one
1100 ** pointed to by the pArg argument. This capability is used during testing
1101 ** and only needs to be supported when SQLITE_TEST is defined.
1102 **
 
 
 
 
 
1103 ** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
1104 ** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
1105 ** be advantageous to block on the next WAL lock if the lock is not immediately
1106 ** available. The WAL subsystem issues this signal during rare
1107 ** circumstances in order to fix a problem with priority inversion.
@@ -1251,10 +1256,11 @@
1251 #define SQLITE_FCNTL_RESERVE_BYTES 38
1252 #define SQLITE_FCNTL_CKPT_START 39
1253 #define SQLITE_FCNTL_EXTERNAL_READER 40
1254 #define SQLITE_FCNTL_CKSM_FILE 41
1255 #define SQLITE_FCNTL_RESET_CACHE 42
 
1256
1257 /* deprecated names */
1258 #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
1259 #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
1260 #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -2629,14 +2635,18 @@
2629 **
2630 ** ^These functions return the number of rows modified, inserted or
2631 ** deleted by the most recently completed INSERT, UPDATE or DELETE
2632 ** statement on the database connection specified by the only parameter.
2633 ** The two functions are identical except for the type of the return value
2634 ** and that if the number of rows modified by the most recent INSERT, UPDATE
2635 ** or DELETE is greater than the maximum value supported by type "int", then
2636 ** the return value of sqlite3_changes() is undefined. ^Executing any other
2637 ** type of SQL statement does not modify the value returned by these functions.
 
 
 
 
2638 **
2639 ** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are
2640 ** considered - auxiliary changes caused by [CREATE TRIGGER | triggers],
2641 ** [foreign key actions] or [REPLACE] constraint resolution are not counted.
2642 **
@@ -4192,15 +4202,26 @@
4192 **
4193 ** [[SQLITE_PREPARE_NO_VTAB]] <dt>SQLITE_PREPARE_NO_VTAB</dt>
4194 ** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler
4195 ** to return an error (error code SQLITE_ERROR) if the statement uses
4196 ** any virtual tables.
 
 
 
 
 
 
 
 
 
 
4197 ** </dl>
4198 */
4199 #define SQLITE_PREPARE_PERSISTENT 0x01
4200 #define SQLITE_PREPARE_NORMALIZE 0x02
4201 #define SQLITE_PREPARE_NO_VTAB 0x04
 
4202
4203 /*
4204 ** CAPI3REF: Compiling An SQL Statement
4205 ** KEYWORDS: {SQL statement compiler}
4206 ** METHOD: sqlite3
@@ -13138,17 +13159,32 @@
13138 ** This is used to access token iToken of phrase hit iIdx within the
13139 ** current row. If iIdx is less than zero or greater than or equal to the
13140 ** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise,
13141 ** output variable (*ppToken) is set to point to a buffer containing the
13142 ** matching document token, and (*pnToken) to the size of that buffer in
13143 ** bytes. This API is not available if the specified token matches a
13144 ** prefix query term. In that case both output variables are always set
13145 ** to 0.
13146 **
13147 ** The output text is not a copy of the document text that was tokenized.
13148 ** It is the output of the tokenizer module. For tokendata=1 tables, this
13149 ** includes any embedded 0x00 and trailing data.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13150 **
13151 ** This API can be quite slow if used with an FTS5 table created with the
13152 ** "detail=none" or "detail=column" option.
13153 **
13154 ** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale)
13155
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,11 @@
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.48.0"
150 #define SQLITE_VERSION_NUMBER 3048000
151 #define SQLITE_SOURCE_ID "2024-12-09 20:46:36 e2bae4143afd07de1ae55a6d2606a3b541a5b94568aa41f6a96e5d1245471653"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -1098,10 +1098,15 @@
1098 ** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
1099 ** opcode causes the xFileControl method to swap the file handle with the one
1100 ** pointed to by the pArg argument. This capability is used during testing
1101 ** and only needs to be supported when SQLITE_TEST is defined.
1102 **
1103 ** <li>[[SQLITE_FCNTL_NULL_IO]]
1104 ** The [SQLITE_FCNTL_NULL_IO] opcode sets the low-level file descriptor
1105 ** or file handle for the [sqlite3_file] object such that it will no longer
1106 ** read or write to the database file.
1107 **
1108 ** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
1109 ** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
1110 ** be advantageous to block on the next WAL lock if the lock is not immediately
1111 ** available. The WAL subsystem issues this signal during rare
1112 ** circumstances in order to fix a problem with priority inversion.
@@ -1251,10 +1256,11 @@
1256 #define SQLITE_FCNTL_RESERVE_BYTES 38
1257 #define SQLITE_FCNTL_CKPT_START 39
1258 #define SQLITE_FCNTL_EXTERNAL_READER 40
1259 #define SQLITE_FCNTL_CKSM_FILE 41
1260 #define SQLITE_FCNTL_RESET_CACHE 42
1261 #define SQLITE_FCNTL_NULL_IO 43
1262
1263 /* deprecated names */
1264 #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
1265 #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
1266 #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -2629,14 +2635,18 @@
2635 **
2636 ** ^These functions return the number of rows modified, inserted or
2637 ** deleted by the most recently completed INSERT, UPDATE or DELETE
2638 ** statement on the database connection specified by the only parameter.
2639 ** The two functions are identical except for the type of the return value
2640 ** and that if the number of rows modified by the most recent INSERT, UPDATE,
2641 ** or DELETE is greater than the maximum value supported by type "int", then
2642 ** the return value of sqlite3_changes() is undefined. ^Executing any other
2643 ** type of SQL statement does not modify the value returned by these functions.
2644 ** For the purposes of this interface, a CREATE TABLE AS SELECT statement
2645 ** does not count as an INSERT, UPDATE or DELETE statement and hence the rows
2646 ** added to the new table by the CREATE TABLE AS SELECT statement are not
2647 ** counted.
2648 **
2649 ** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are
2650 ** considered - auxiliary changes caused by [CREATE TRIGGER | triggers],
2651 ** [foreign key actions] or [REPLACE] constraint resolution are not counted.
2652 **
@@ -4192,15 +4202,26 @@
4202 **
4203 ** [[SQLITE_PREPARE_NO_VTAB]] <dt>SQLITE_PREPARE_NO_VTAB</dt>
4204 ** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler
4205 ** to return an error (error code SQLITE_ERROR) if the statement uses
4206 ** any virtual tables.
4207 **
4208 ** [[SQLITE_PREPARE_DONT_LOG]] <dt>SQLITE_PREPARE_DONT_LOG</dt>
4209 ** <dd>The SQLITE_PREPARE_DONT_LOG flag prevents SQL compiler
4210 ** errors from being sent to the error log defined by
4211 ** [SQLITE_CONFIG_LOG]. This can be used, for example, to do test
4212 ** compiles to see if some SQL syntax is well-formed, without generating
4213 ** messages on the global error log when it is not. If the test compile
4214 ** fails, the sqlite3_prepare_v3() call returns the same error indications
4215 ** with or without this flag; it just omits the call to [sqlite3_log()] that
4216 ** logs the error.
4217 ** </dl>
4218 */
4219 #define SQLITE_PREPARE_PERSISTENT 0x01
4220 #define SQLITE_PREPARE_NORMALIZE 0x02
4221 #define SQLITE_PREPARE_NO_VTAB 0x04
4222 #define SQLITE_PREPARE_DONT_LOG 0x10
4223
4224 /*
4225 ** CAPI3REF: Compiling An SQL Statement
4226 ** KEYWORDS: {SQL statement compiler}
4227 ** METHOD: sqlite3
@@ -13138,17 +13159,32 @@
13159 ** This is used to access token iToken of phrase hit iIdx within the
13160 ** current row. If iIdx is less than zero or greater than or equal to the
13161 ** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise,
13162 ** output variable (*ppToken) is set to point to a buffer containing the
13163 ** matching document token, and (*pnToken) to the size of that buffer in
13164 ** bytes.
 
 
13165 **
13166 ** The output text is not a copy of the document text that was tokenized.
13167 ** It is the output of the tokenizer module. For tokendata=1 tables, this
13168 ** includes any embedded 0x00 and trailing data.
13169 **
13170 ** This API may be slow in some cases if the token identified by parameters
13171 ** iIdx and iToken matched a prefix token in the query. In most cases, the
13172 ** first call to this API for each prefix token in the query is forced
13173 ** to scan the portion of the full-text index that matches the prefix
13174 ** token to collect the extra data required by this API. If the prefix
13175 ** token matches a large number of token instances in the document set,
13176 ** this may be a performance problem.
13177 **
13178 ** If the user knows in advance that a query may use this API for a
13179 ** prefix token, FTS5 may be configured to collect all required data as part
13180 ** of the initial querying of the full-text index, avoiding the second scan
13181 ** entirely. This also causes prefix queries that do not use this API to
13182 ** run more slowly and use more memory. FTS5 may be configured in this way
13183 ** either on a per-table basis using the [FTS5 insttoken | 'insttoken']
13184 ** option, or on a per-query basis using the
13185 ** [fts5_insttoken | fts5_insttoken()] user function.
13186 **
13187 ** This API can be quite slow if used with an FTS5 table created with the
13188 ** "detail=none" or "detail=column" option.
13189 **
13190 ** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale)
13191
--- skins/darkmode/css.txt
+++ skins/darkmode/css.txt
@@ -98,14 +98,17 @@
9898
}
9999
.fileage tr:hover,
100100
div.filetreeline:hover {
101101
background-color: #333;
102102
}
103
+div.file-change-line button {
104
+ background-color: #484848
105
+}
103106
.button,
104107
button {
105108
color: #aaa;
106
- background-color: #444;
109
+ background-color: #484848;
107110
border-radius: 5px;
108111
border: 0
109112
}
110113
.button:hover,
111114
button:hover {
112115
--- skins/darkmode/css.txt
+++ skins/darkmode/css.txt
@@ -98,14 +98,17 @@
98 }
99 .fileage tr:hover,
100 div.filetreeline:hover {
101 background-color: #333;
102 }
 
 
 
103 .button,
104 button {
105 color: #aaa;
106 background-color: #444;
107 border-radius: 5px;
108 border: 0
109 }
110 .button:hover,
111 button:hover {
112
--- skins/darkmode/css.txt
+++ skins/darkmode/css.txt
@@ -98,14 +98,17 @@
98 }
99 .fileage tr:hover,
100 div.filetreeline:hover {
101 background-color: #333;
102 }
103 div.file-change-line button {
104 background-color: #484848
105 }
106 .button,
107 button {
108 color: #aaa;
109 background-color: #484848;
110 border-radius: 5px;
111 border: 0
112 }
113 .button:hover,
114 button:hover {
115
+2 -3
--- src/add.c
+++ src/add.c
@@ -353,11 +353,11 @@
353353
** for files to be excluded. Example: '*.o,*.obj,*.exe' If the --ignore
354354
** option does not appear on the command line then the "ignore-glob" setting
355355
** is used. If the --clean option does not appear on the command line then
356356
** the "clean-glob" setting is used.
357357
**
358
-** If files are attempted to be added explicitly on the command line which
358
+** When attempting to explicitly add files on the commandline, and if those
359359
** match "ignore-glob", a confirmation is asked first. This can be prevented
360360
** using the -f|--force option.
361361
**
362362
** The --case-sensitive option determines whether or not filenames should
363363
** be treated case sensitive or not. If the option is not given, the default
@@ -753,12 +753,11 @@
753753
**
754754
** * All files in the repository but missing from the check-out (that is,
755755
** all files that show as MISSING with the "status" command) are
756756
** removed as if by the "[[rm]]" command.
757757
**
758
-** The command does not "[[commit]]". You must run the "[[commit]]" separately
759
-** as a separate step.
758
+** Note that this command does not "commit", as that is a separate step.
760759
**
761760
** Files and directories whose names begin with "." are ignored unless
762761
** the --dotfiles option is used.
763762
**
764763
** The --ignore option overrides the "ignore-glob" setting, as do the
765764
--- src/add.c
+++ src/add.c
@@ -353,11 +353,11 @@
353 ** for files to be excluded. Example: '*.o,*.obj,*.exe' If the --ignore
354 ** option does not appear on the command line then the "ignore-glob" setting
355 ** is used. If the --clean option does not appear on the command line then
356 ** the "clean-glob" setting is used.
357 **
358 ** If files are attempted to be added explicitly on the command line which
359 ** match "ignore-glob", a confirmation is asked first. This can be prevented
360 ** using the -f|--force option.
361 **
362 ** The --case-sensitive option determines whether or not filenames should
363 ** be treated case sensitive or not. If the option is not given, the default
@@ -753,12 +753,11 @@
753 **
754 ** * All files in the repository but missing from the check-out (that is,
755 ** all files that show as MISSING with the "status" command) are
756 ** removed as if by the "[[rm]]" command.
757 **
758 ** The command does not "[[commit]]". You must run the "[[commit]]" separately
759 ** as a separate step.
760 **
761 ** Files and directories whose names begin with "." are ignored unless
762 ** the --dotfiles option is used.
763 **
764 ** The --ignore option overrides the "ignore-glob" setting, as do the
765
--- src/add.c
+++ src/add.c
@@ -353,11 +353,11 @@
353 ** for files to be excluded. Example: '*.o,*.obj,*.exe' If the --ignore
354 ** option does not appear on the command line then the "ignore-glob" setting
355 ** is used. If the --clean option does not appear on the command line then
356 ** the "clean-glob" setting is used.
357 **
358 ** When attempting to explicitly add files on the commandline, and if those
359 ** match "ignore-glob", a confirmation is asked first. This can be prevented
360 ** using the -f|--force option.
361 **
362 ** The --case-sensitive option determines whether or not filenames should
363 ** be treated case sensitive or not. If the option is not given, the default
@@ -753,12 +753,11 @@
753 **
754 ** * All files in the repository but missing from the check-out (that is,
755 ** all files that show as MISSING with the "status" command) are
756 ** removed as if by the "[[rm]]" command.
757 **
758 ** Note that this command does not "commit", as that is a separate step.
 
759 **
760 ** Files and directories whose names begin with "." are ignored unless
761 ** the --dotfiles option is used.
762 **
763 ** The --ignore option overrides the "ignore-glob" setting, as do the
764
+23 -6
--- src/allrepo.c
+++ src/allrepo.c
@@ -50,11 +50,10 @@
5050
for(i=iStart; i<g.argc; i++){
5151
blob_appendf(pExtra, " %s", g.argv[i]);
5252
}
5353
}
5454
55
-
5655
/*
5756
** COMMAND: all
5857
**
5958
** Usage: %fossil all SUBCOMMAND ...
6059
**
@@ -429,44 +428,62 @@
429428
"add cache changes clean dbstat extras fts-config git ignore "
430429
"info list ls pull push rebuild remote "
431430
"server settings sync ui unset whatis");
432431
}
433432
verify_all_options();
434
- db_multi_exec("CREATE TEMP TABLE repolist(name,tag);");
433
+ db_multi_exec(
434
+ "CREATE TEMP TABLE repolist(\n"
435
+ " name TEXT, -- Filename\n"
436
+ " tag TEXT, -- Key for the GLOBAL_CONFIG table entry\n"
437
+ " inode TEXT -- Unique identifier for this file\n"
438
+ ");\n"
439
+
440
+ /* The seenFile() table holds inode names for entries that have
441
+ ** already been processed. */
442
+ "CREATE TEMP TABLE seenFile(x TEXT COLLATE nocase);\n"
443
+
444
+ /* The toDel() table holds the "tag" for entries that need to be
445
+ ** deleted because they are redundant or no longer exist */
446
+ "CREATE TEMP TABLE toDel(x TEXT);\n"
447
+ );
448
+ sqlite3_create_function(g.db, "inode", 1, SQLITE_UTF8, 0,
449
+ file_inode_sql_func, 0, 0);
435450
if( useCheckouts ){
436451
db_multi_exec(
437452
"INSERT INTO repolist "
438
- "SELECT DISTINCT substr(name, 7), name COLLATE nocase"
453
+ "SELECT substr(name, 7), name, inode(substr(name,7))"
439454
" FROM global_config"
440455
" WHERE substr(name, 1, 6)=='ckout:'"
441456
" ORDER BY 1"
442457
);
443458
}else{
444459
db_multi_exec(
445460
"INSERT INTO repolist "
446
- "SELECT DISTINCT substr(name, 6), name COLLATE nocase"
461
+ "SELECT substr(name, 6), name, inode(substr(name,6))"
447462
" FROM global_config"
448463
" WHERE substr(name, 1, 5)=='repo:'"
449464
" ORDER BY 1"
450465
);
451466
}
452
- db_multi_exec("CREATE TEMP TABLE toDel(x TEXT)");
453
- db_prepare(&q, "SELECT name, tag FROM repolist ORDER BY 1");
467
+ db_prepare(&q,"SELECT name, tag, inode FROM repolist ORDER BY 1");
454468
while( db_step(&q)==SQLITE_ROW ){
455469
int rc;
456470
const char *zFilename = db_column_text(&q, 0);
471
+ const char *zInode = db_column_text(&q,2);
457472
#if !USE_SEE
458473
if( sqlite3_strglob("*.efossil", zFilename)==0 ) continue;
459474
#endif
460475
if( file_access(zFilename, F_OK)
461476
|| !file_is_canonical(zFilename)
462477
|| (useCheckouts && file_isdir(zFilename, ExtFILE)!=1)
478
+ || db_exists("SELECT 1 FROM temp.seenFile where x=%Q", zInode)
463479
){
464480
db_multi_exec("INSERT INTO toDel VALUES(%Q)", db_column_text(&q, 1));
465481
nToDel++;
466482
continue;
467483
}
484
+ db_multi_exec("INSERT INTO seenFile(x) VALUES(%Q)", zInode);
468485
if( zCmd[0]=='l' ){
469486
fossil_print("%s\n", zFilename);
470487
continue;
471488
}else if( showFile ){
472489
fossil_print("%s: %s\n", useCheckouts ? "check-out" : "repository",
473490
--- src/allrepo.c
+++ src/allrepo.c
@@ -50,11 +50,10 @@
50 for(i=iStart; i<g.argc; i++){
51 blob_appendf(pExtra, " %s", g.argv[i]);
52 }
53 }
54
55
56 /*
57 ** COMMAND: all
58 **
59 ** Usage: %fossil all SUBCOMMAND ...
60 **
@@ -429,44 +428,62 @@
429 "add cache changes clean dbstat extras fts-config git ignore "
430 "info list ls pull push rebuild remote "
431 "server settings sync ui unset whatis");
432 }
433 verify_all_options();
434 db_multi_exec("CREATE TEMP TABLE repolist(name,tag);");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
435 if( useCheckouts ){
436 db_multi_exec(
437 "INSERT INTO repolist "
438 "SELECT DISTINCT substr(name, 7), name COLLATE nocase"
439 " FROM global_config"
440 " WHERE substr(name, 1, 6)=='ckout:'"
441 " ORDER BY 1"
442 );
443 }else{
444 db_multi_exec(
445 "INSERT INTO repolist "
446 "SELECT DISTINCT substr(name, 6), name COLLATE nocase"
447 " FROM global_config"
448 " WHERE substr(name, 1, 5)=='repo:'"
449 " ORDER BY 1"
450 );
451 }
452 db_multi_exec("CREATE TEMP TABLE toDel(x TEXT)");
453 db_prepare(&q, "SELECT name, tag FROM repolist ORDER BY 1");
454 while( db_step(&q)==SQLITE_ROW ){
455 int rc;
456 const char *zFilename = db_column_text(&q, 0);
 
457 #if !USE_SEE
458 if( sqlite3_strglob("*.efossil", zFilename)==0 ) continue;
459 #endif
460 if( file_access(zFilename, F_OK)
461 || !file_is_canonical(zFilename)
462 || (useCheckouts && file_isdir(zFilename, ExtFILE)!=1)
 
463 ){
464 db_multi_exec("INSERT INTO toDel VALUES(%Q)", db_column_text(&q, 1));
465 nToDel++;
466 continue;
467 }
 
468 if( zCmd[0]=='l' ){
469 fossil_print("%s\n", zFilename);
470 continue;
471 }else if( showFile ){
472 fossil_print("%s: %s\n", useCheckouts ? "check-out" : "repository",
473
--- src/allrepo.c
+++ src/allrepo.c
@@ -50,11 +50,10 @@
50 for(i=iStart; i<g.argc; i++){
51 blob_appendf(pExtra, " %s", g.argv[i]);
52 }
53 }
54
 
55 /*
56 ** COMMAND: all
57 **
58 ** Usage: %fossil all SUBCOMMAND ...
59 **
@@ -429,44 +428,62 @@
428 "add cache changes clean dbstat extras fts-config git ignore "
429 "info list ls pull push rebuild remote "
430 "server settings sync ui unset whatis");
431 }
432 verify_all_options();
433 db_multi_exec(
434 "CREATE TEMP TABLE repolist(\n"
435 " name TEXT, -- Filename\n"
436 " tag TEXT, -- Key for the GLOBAL_CONFIG table entry\n"
437 " inode TEXT -- Unique identifier for this file\n"
438 ");\n"
439
440 /* The seenFile() table holds inode names for entries that have
441 ** already been processed. */
442 "CREATE TEMP TABLE seenFile(x TEXT COLLATE nocase);\n"
443
444 /* The toDel() table holds the "tag" for entries that need to be
445 ** deleted because they are redundant or no longer exist */
446 "CREATE TEMP TABLE toDel(x TEXT);\n"
447 );
448 sqlite3_create_function(g.db, "inode", 1, SQLITE_UTF8, 0,
449 file_inode_sql_func, 0, 0);
450 if( useCheckouts ){
451 db_multi_exec(
452 "INSERT INTO repolist "
453 "SELECT substr(name, 7), name, inode(substr(name,7))"
454 " FROM global_config"
455 " WHERE substr(name, 1, 6)=='ckout:'"
456 " ORDER BY 1"
457 );
458 }else{
459 db_multi_exec(
460 "INSERT INTO repolist "
461 "SELECT substr(name, 6), name, inode(substr(name,6))"
462 " FROM global_config"
463 " WHERE substr(name, 1, 5)=='repo:'"
464 " ORDER BY 1"
465 );
466 }
467 db_prepare(&q,"SELECT name, tag, inode FROM repolist ORDER BY 1");
 
468 while( db_step(&q)==SQLITE_ROW ){
469 int rc;
470 const char *zFilename = db_column_text(&q, 0);
471 const char *zInode = db_column_text(&q,2);
472 #if !USE_SEE
473 if( sqlite3_strglob("*.efossil", zFilename)==0 ) continue;
474 #endif
475 if( file_access(zFilename, F_OK)
476 || !file_is_canonical(zFilename)
477 || (useCheckouts && file_isdir(zFilename, ExtFILE)!=1)
478 || db_exists("SELECT 1 FROM temp.seenFile where x=%Q", zInode)
479 ){
480 db_multi_exec("INSERT INTO toDel VALUES(%Q)", db_column_text(&q, 1));
481 nToDel++;
482 continue;
483 }
484 db_multi_exec("INSERT INTO seenFile(x) VALUES(%Q)", zInode);
485 if( zCmd[0]=='l' ){
486 fossil_print("%s\n", zFilename);
487 continue;
488 }else if( showFile ){
489 fossil_print("%s: %s\n", useCheckouts ? "check-out" : "repository",
490
+8 -1
--- src/attach.c
+++ src/attach.c
@@ -634,11 +634,12 @@
634634
/*
635635
** Output HTML to show a list of attachments.
636636
*/
637637
void attachment_list(
638638
const char *zTarget, /* Object that things are attached to */
639
- const char *zHeader /* Header to display with attachments */
639
+ const char *zHeader, /* Header to display with attachments */
640
+ int fHorizontalRule /* Insert <hr> separator above header */
640641
){
641642
int cnt = 0;
642643
Stmt q;
643644
db_prepare(&q,
644645
"SELECT datetime(mtime,toLocal()), filename, user,"
@@ -654,11 +655,16 @@
654655
const char *zUser = db_column_text(&q, 2);
655656
const char *zUuid = db_column_text(&q, 3);
656657
const char *zSrc = db_column_text(&q, 4);
657658
const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous";
658659
if( cnt==0 ){
660
+ @ <section class='attachlist'>
661
+ if( fHorizontalRule ){
662
+ @ <hr>
663
+ }
659664
@ %s(zHeader)
665
+ @ <ul>
660666
}
661667
cnt++;
662668
@ <li>
663669
@ %z(href("%R/artifact/%!S",zSrc))%h(zFile)</a>
664670
@ [<a href="%R/attachdownload/%t(zFile)?page=%t(zTarget)&file=%t(zFile)">download</a>]
@@ -667,10 +673,11 @@
667673
@ [%z(href("%R/ainfo/%!S",zUuid))details</a>]
668674
@ </li>
669675
}
670676
if( cnt ){
671677
@ </ul>
678
+ @ </section>
672679
}
673680
db_finalize(&q);
674681
675682
}
676683
677684
--- src/attach.c
+++ src/attach.c
@@ -634,11 +634,12 @@
634 /*
635 ** Output HTML to show a list of attachments.
636 */
637 void attachment_list(
638 const char *zTarget, /* Object that things are attached to */
639 const char *zHeader /* Header to display with attachments */
 
640 ){
641 int cnt = 0;
642 Stmt q;
643 db_prepare(&q,
644 "SELECT datetime(mtime,toLocal()), filename, user,"
@@ -654,11 +655,16 @@
654 const char *zUser = db_column_text(&q, 2);
655 const char *zUuid = db_column_text(&q, 3);
656 const char *zSrc = db_column_text(&q, 4);
657 const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous";
658 if( cnt==0 ){
 
 
 
 
659 @ %s(zHeader)
 
660 }
661 cnt++;
662 @ <li>
663 @ %z(href("%R/artifact/%!S",zSrc))%h(zFile)</a>
664 @ [<a href="%R/attachdownload/%t(zFile)?page=%t(zTarget)&file=%t(zFile)">download</a>]
@@ -667,10 +673,11 @@
667 @ [%z(href("%R/ainfo/%!S",zUuid))details</a>]
668 @ </li>
669 }
670 if( cnt ){
671 @ </ul>
 
672 }
673 db_finalize(&q);
674
675 }
676
677
--- src/attach.c
+++ src/attach.c
@@ -634,11 +634,12 @@
634 /*
635 ** Output HTML to show a list of attachments.
636 */
637 void attachment_list(
638 const char *zTarget, /* Object that things are attached to */
639 const char *zHeader, /* Header to display with attachments */
640 int fHorizontalRule /* Insert <hr> separator above header */
641 ){
642 int cnt = 0;
643 Stmt q;
644 db_prepare(&q,
645 "SELECT datetime(mtime,toLocal()), filename, user,"
@@ -654,11 +655,16 @@
655 const char *zUser = db_column_text(&q, 2);
656 const char *zUuid = db_column_text(&q, 3);
657 const char *zSrc = db_column_text(&q, 4);
658 const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous";
659 if( cnt==0 ){
660 @ <section class='attachlist'>
661 if( fHorizontalRule ){
662 @ <hr>
663 }
664 @ %s(zHeader)
665 @ <ul>
666 }
667 cnt++;
668 @ <li>
669 @ %z(href("%R/artifact/%!S",zSrc))%h(zFile)</a>
670 @ [<a href="%R/attachdownload/%t(zFile)?page=%t(zTarget)&file=%t(zFile)">download</a>]
@@ -667,10 +673,11 @@
673 @ [%z(href("%R/ainfo/%!S",zUuid))details</a>]
674 @ </li>
675 }
676 if( cnt ){
677 @ </ul>
678 @ </section>
679 }
680 db_finalize(&q);
681
682 }
683
684
+12 -4
--- src/bisect.c
+++ src/bisect.c
@@ -543,14 +543,16 @@
543543
**
544544
** > fossil bisect vlist|ls|status ?-a|--all?
545545
**
546546
** List the versions in between the inner-most "bad" and "good".
547547
**
548
-** > fossil bisect ui
548
+** > fossil bisect ui ?HOST@USER:PATH?
549549
**
550550
** Like "fossil ui" except start on a timeline that shows only the
551
-** check-ins that are part of the current bisect.
551
+** check-ins that are part of the current bisect. If the optional
552
+** fourth term is added, then information is shown for the bisect that
553
+** occurred in the PATH directory by USER on remote machine HOST.
552554
**
553555
** > fossil bisect undo
554556
**
555557
** Undo the most recent "good", "bad", or "skip" command.
556558
*/
@@ -719,17 +721,23 @@
719721
}
720722
}else if( strncmp(zCmd, "reset", n)==0 ){
721723
bisect_reset();
722724
}else if( strcmp(zCmd, "ui")==0 ){
723725
char *newArgv[8];
726
+ verify_all_options();
724727
newArgv[0] = g.argv[0];
725728
newArgv[1] = "ui";
726729
newArgv[2] = "--page";
727730
newArgv[3] = "timeline?bisect";
728
- newArgv[4] = 0;
731
+ if( g.argc==4 ){
732
+ newArgv[4] = g.argv[3];
733
+ g.argc = 5;
734
+ }else{
735
+ g.argc = 4;
736
+ }
737
+ newArgv[g.argc] = 0;
729738
g.argv = newArgv;
730
- g.argc = 4;
731739
cmd_webserver();
732740
}else if( strncmp(zCmd, "vlist", n)==0
733741
|| strncmp(zCmd, "ls", n)==0
734742
|| strncmp(zCmd, "status", n)==0
735743
){
736744
--- src/bisect.c
+++ src/bisect.c
@@ -543,14 +543,16 @@
543 **
544 ** > fossil bisect vlist|ls|status ?-a|--all?
545 **
546 ** List the versions in between the inner-most "bad" and "good".
547 **
548 ** > fossil bisect ui
549 **
550 ** Like "fossil ui" except start on a timeline that shows only the
551 ** check-ins that are part of the current bisect.
 
 
552 **
553 ** > fossil bisect undo
554 **
555 ** Undo the most recent "good", "bad", or "skip" command.
556 */
@@ -719,17 +721,23 @@
719 }
720 }else if( strncmp(zCmd, "reset", n)==0 ){
721 bisect_reset();
722 }else if( strcmp(zCmd, "ui")==0 ){
723 char *newArgv[8];
 
724 newArgv[0] = g.argv[0];
725 newArgv[1] = "ui";
726 newArgv[2] = "--page";
727 newArgv[3] = "timeline?bisect";
728 newArgv[4] = 0;
 
 
 
 
 
 
729 g.argv = newArgv;
730 g.argc = 4;
731 cmd_webserver();
732 }else if( strncmp(zCmd, "vlist", n)==0
733 || strncmp(zCmd, "ls", n)==0
734 || strncmp(zCmd, "status", n)==0
735 ){
736
--- src/bisect.c
+++ src/bisect.c
@@ -543,14 +543,16 @@
543 **
544 ** > fossil bisect vlist|ls|status ?-a|--all?
545 **
546 ** List the versions in between the inner-most "bad" and "good".
547 **
548 ** > fossil bisect ui ?HOST@USER:PATH?
549 **
550 ** Like "fossil ui" except start on a timeline that shows only the
551 ** check-ins that are part of the current bisect. If the optional
552 ** fourth term is added, then information is shown for the bisect that
553 ** occurred in the PATH directory by USER on remote machine HOST.
554 **
555 ** > fossil bisect undo
556 **
557 ** Undo the most recent "good", "bad", or "skip" command.
558 */
@@ -719,17 +721,23 @@
721 }
722 }else if( strncmp(zCmd, "reset", n)==0 ){
723 bisect_reset();
724 }else if( strcmp(zCmd, "ui")==0 ){
725 char *newArgv[8];
726 verify_all_options();
727 newArgv[0] = g.argv[0];
728 newArgv[1] = "ui";
729 newArgv[2] = "--page";
730 newArgv[3] = "timeline?bisect";
731 if( g.argc==4 ){
732 newArgv[4] = g.argv[3];
733 g.argc = 5;
734 }else{
735 g.argc = 4;
736 }
737 newArgv[g.argc] = 0;
738 g.argv = newArgv;
 
739 cmd_webserver();
740 }else if( strncmp(zCmd, "vlist", n)==0
741 || strncmp(zCmd, "ls", n)==0
742 || strncmp(zCmd, "status", n)==0
743 ){
744
+49 -1
--- src/blob.c
+++ src/blob.c
@@ -665,11 +665,12 @@
665665
pBlob->nUsed = dehttpize(pBlob->aData);
666666
}
667667
668668
/*
669669
** Extract N bytes from blob pFrom and use it to initialize blob pTo.
670
-** Return the actual number of bytes extracted.
670
+** Return the actual number of bytes extracted. The cursor position
671
+** is advanced by the number of bytes extracted.
671672
**
672673
** After this call completes, pTo will be an ephemeral blob.
673674
*/
674675
int blob_extract(Blob *pFrom, int N, Blob *pTo){
675676
blob_is_init(pFrom);
@@ -687,10 +688,57 @@
687688
pTo->iCursor = 0;
688689
pTo->xRealloc = blobReallocStatic;
689690
pFrom->iCursor += N;
690691
return N;
691692
}
693
+
694
+/*
695
+** Extract N **lines** of text from blob pFrom beginning at the current
696
+** cursor position and use that text to initialize blob pTo. Unlike the
697
+** blob_extract() routine, the cursor position is unchanged.
698
+**
699
+** pTo is assumed to be uninitialized.
700
+**
701
+** After this call completes, pTo will be an ephemeral blob.
702
+*/
703
+int blob_extract_lines(Blob *pFrom, int N, Blob *pTo){
704
+ int i;
705
+ int mx;
706
+ int iStart;
707
+ int n;
708
+ const char *z;
709
+
710
+ blob_zero(pTo);
711
+ z = pFrom->aData;
712
+ i = pFrom->iCursor;
713
+ mx = pFrom->nUsed;
714
+ while( N>0 ){
715
+ while( i<mx && z[i]!='\n' ){ i++; }
716
+ if( i>=mx ) break;
717
+ i++;
718
+ N--;
719
+ }
720
+ iStart = pFrom->iCursor;
721
+ n = blob_extract(pFrom, i-pFrom->iCursor, pTo);
722
+ pFrom->iCursor = iStart;
723
+ return n;
724
+}
725
+
726
+/*
727
+** Return the number of lines of text in the blob. If the last
728
+** line is incomplete (if it does not have a \n at the end) then
729
+** it still counts.
730
+*/
731
+int blob_linecount(Blob *p){
732
+ int n = 0;
733
+ int i;
734
+ for(i=0; i<p->nUsed; i++){
735
+ if( p->aData[i]=='\n' ) n++;
736
+ }
737
+ if( p->nUsed>0 && p->aData[p->nUsed-1]!='\n' ) n++;
738
+ return n;
739
+}
692740
693741
/*
694742
** Rewind the cursor on a blob back to the beginning.
695743
*/
696744
void blob_rewind(Blob *p){
697745
--- src/blob.c
+++ src/blob.c
@@ -665,11 +665,12 @@
665 pBlob->nUsed = dehttpize(pBlob->aData);
666 }
667
668 /*
669 ** Extract N bytes from blob pFrom and use it to initialize blob pTo.
670 ** Return the actual number of bytes extracted.
 
671 **
672 ** After this call completes, pTo will be an ephemeral blob.
673 */
674 int blob_extract(Blob *pFrom, int N, Blob *pTo){
675 blob_is_init(pFrom);
@@ -687,10 +688,57 @@
687 pTo->iCursor = 0;
688 pTo->xRealloc = blobReallocStatic;
689 pFrom->iCursor += N;
690 return N;
691 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
692
693 /*
694 ** Rewind the cursor on a blob back to the beginning.
695 */
696 void blob_rewind(Blob *p){
697
--- src/blob.c
+++ src/blob.c
@@ -665,11 +665,12 @@
665 pBlob->nUsed = dehttpize(pBlob->aData);
666 }
667
668 /*
669 ** Extract N bytes from blob pFrom and use it to initialize blob pTo.
670 ** Return the actual number of bytes extracted. The cursor position
671 ** is advanced by the number of bytes extracted.
672 **
673 ** After this call completes, pTo will be an ephemeral blob.
674 */
675 int blob_extract(Blob *pFrom, int N, Blob *pTo){
676 blob_is_init(pFrom);
@@ -687,10 +688,57 @@
688 pTo->iCursor = 0;
689 pTo->xRealloc = blobReallocStatic;
690 pFrom->iCursor += N;
691 return N;
692 }
693
694 /*
695 ** Extract N **lines** of text from blob pFrom beginning at the current
696 ** cursor position and use that text to initialize blob pTo. Unlike the
697 ** blob_extract() routine, the cursor position is unchanged.
698 **
699 ** pTo is assumed to be uninitialized.
700 **
701 ** After this call completes, pTo will be an ephemeral blob.
702 */
703 int blob_extract_lines(Blob *pFrom, int N, Blob *pTo){
704 int i;
705 int mx;
706 int iStart;
707 int n;
708 const char *z;
709
710 blob_zero(pTo);
711 z = pFrom->aData;
712 i = pFrom->iCursor;
713 mx = pFrom->nUsed;
714 while( N>0 ){
715 while( i<mx && z[i]!='\n' ){ i++; }
716 if( i>=mx ) break;
717 i++;
718 N--;
719 }
720 iStart = pFrom->iCursor;
721 n = blob_extract(pFrom, i-pFrom->iCursor, pTo);
722 pFrom->iCursor = iStart;
723 return n;
724 }
725
726 /*
727 ** Return the number of lines of text in the blob. If the last
728 ** line is incomplete (if it does not have a \n at the end) then
729 ** it still counts.
730 */
731 int blob_linecount(Blob *p){
732 int n = 0;
733 int i;
734 for(i=0; i<p->nUsed; i++){
735 if( p->aData[i]=='\n' ) n++;
736 }
737 if( p->nUsed>0 && p->aData[p->nUsed-1]!='\n' ) n++;
738 return n;
739 }
740
741 /*
742 ** Rewind the cursor on a blob back to the beginning.
743 */
744 void blob_rewind(Blob *p){
745
+2 -2
--- src/branch.c
+++ src/branch.c
@@ -640,12 +640,12 @@
640640
** -M|--unmerged List branches not merged into the current branch
641641
** -p List only private branches
642642
** -r Reverse the sort order
643643
** -t Show recently changed branches first
644644
** --self List only branches where you participate
645
-** --username USER List only branches where USER participate
646
-** --users N List up to N users partipiating
645
+** --username USER List only branches where USER participates
646
+** --users N List up to N users participating
647647
**
648648
** The current branch is marked with an asterisk. Private branches are
649649
** marked with a hash sign.
650650
**
651651
** If GLOB is given, show only branches matching the pattern.
652652
--- src/branch.c
+++ src/branch.c
@@ -640,12 +640,12 @@
640 ** -M|--unmerged List branches not merged into the current branch
641 ** -p List only private branches
642 ** -r Reverse the sort order
643 ** -t Show recently changed branches first
644 ** --self List only branches where you participate
645 ** --username USER List only branches where USER participate
646 ** --users N List up to N users partipiating
647 **
648 ** The current branch is marked with an asterisk. Private branches are
649 ** marked with a hash sign.
650 **
651 ** If GLOB is given, show only branches matching the pattern.
652
--- src/branch.c
+++ src/branch.c
@@ -640,12 +640,12 @@
640 ** -M|--unmerged List branches not merged into the current branch
641 ** -p List only private branches
642 ** -r Reverse the sort order
643 ** -t Show recently changed branches first
644 ** --self List only branches where you participate
645 ** --username USER List only branches where USER participates
646 ** --users N List up to N users participating
647 **
648 ** The current branch is marked with an asterisk. Private branches are
649 ** marked with a hash sign.
650 **
651 ** If GLOB is given, show only branches matching the pattern.
652
+71 -10
--- src/checkin.c
+++ src/checkin.c
@@ -1563,17 +1563,17 @@
15631563
break;
15641564
}
15651565
diffFiles[i].nName = strlen(diffFiles[i].zName);
15661566
diffFiles[i].nUsed = 0;
15671567
}
1568
- diff_against_disk(0, &DCfg, diffFiles, &prompt);
1568
+ diff_version_to_checkout(0, &DCfg, diffFiles, &prompt);
15691569
for( i=0; diffFiles[i].zName; ++i ){
15701570
fossil_free(diffFiles[i].zName);
15711571
}
15721572
fossil_free(diffFiles);
15731573
}else{
1574
- diff_against_disk(0, &DCfg, 0, &prompt);
1574
+ diff_version_to_checkout(0, &DCfg, 0, &prompt);
15751575
}
15761576
}
15771577
prompt_for_user_comment(pComment, &prompt);
15781578
blob_reset(&prompt);
15791579
}
@@ -2434,10 +2434,12 @@
24342434
Blob ans; /* Answer to continuation prompts */
24352435
char cReply; /* First character of ans */
24362436
int bRecheck = 0; /* Repeat fork and closed-branch checks*/
24372437
int bIgnoreSkew = 0; /* --ignore-clock-skew flag */
24382438
int mxSize;
2439
+ char *zCurBranch = 0; /* The current branch name of checkout */
2440
+ char *zNewBranch = 0; /* The branch name after update */
24392441
24402442
memset(&sCiInfo, 0, sizeof(sCiInfo));
24412443
url_proxy_options();
24422444
/* --sha1sum is an undocumented alias for --hash for backwards compatiblity */
24432445
useHash = find_option("hash",0,0)!=0 || find_option("sha1sum",0,0)!=0;
@@ -2508,10 +2510,55 @@
25082510
}
25092511
}else{
25102512
privateParent = content_is_private(vid);
25112513
}
25122514
2515
+ user_select();
2516
+ /*
2517
+ ** Check that the user exists.
2518
+ */
2519
+ if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.zLogin) ){
2520
+ fossil_fatal("no such user: %s", g.zLogin);
2521
+ }
2522
+
2523
+ /*
2524
+ ** Detect if the branch name has changed from the parent check-in
2525
+ ** and prompt if necessary
2526
+ **/
2527
+ zCurBranch = db_text(0,
2528
+ " SELECT value FROM tagxref AS tx"
2529
+ " WHERE rid=(SELECT pid"
2530
+ " FROM tagxref LEFT JOIN event ON srcid=objid"
2531
+ " LEFT JOIN plink ON rid=cid"
2532
+ " WHERE rid=%d AND tagxref.tagid=%d"
2533
+ " AND srcid!=origid"
2534
+ " AND tagtype=2 AND coalesce(euser,user)!=%Q)"
2535
+ " AND tx.tagid=%d",
2536
+ vid, TAG_BRANCH, g.zLogin, TAG_BRANCH
2537
+ );
2538
+ if( zCurBranch!=0 && zCurBranch[0]!=0
2539
+ && forceFlag==0
2540
+ && noPrompt==0
2541
+ ){
2542
+ zNewBranch = branch_of_rid(vid);
2543
+ fossil_warning(
2544
+ "WARNING: The parent check-in [%.10s] has been moved from branch\n"
2545
+ " '%s' over to branch '%s'.",
2546
+ rid_to_uuid(vid), zCurBranch, zNewBranch
2547
+ );
2548
+ prompt_user("Commit anyway? (y/N) ", &ans);
2549
+ cReply = blob_str(&ans)[0];
2550
+ blob_reset(&ans);
2551
+ if( cReply!='y' && cReply!='Y' ){
2552
+ fossil_fatal("Abandoning commit because branch has changed");
2553
+ }
2554
+ fossil_free(zNewBranch);
2555
+ fossil_free(zCurBranch);
2556
+ zCurBranch = branch_of_rid(vid);
2557
+ }
2558
+ if( zCurBranch==0 ) zCurBranch = branch_of_rid(vid);
2559
+
25132560
/* Track the "private" status */
25142561
g.markPrivate = privateFlag || privateParent;
25152562
if( privateFlag && !privateParent ){
25162563
/* Apply default branch name ("private") and color ("orange") if not
25172564
** specified otherwise on the command-line, and if the parent is not
@@ -2639,18 +2686,10 @@
26392686
"'%s' was renamed to '%s'", zFrom, zTo, zFrom, zTo);
26402687
}
26412688
db_finalize(&q);
26422689
}
26432690
2644
- user_select();
2645
- /*
2646
- ** Check that the user exists.
2647
- */
2648
- if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.zLogin) ){
2649
- fossil_fatal("no such user: %s", g.zLogin);
2650
- }
2651
-
26522691
hasChanges = unsaved_changes(useHash ? CKSIG_HASH : 0);
26532692
db_begin_transaction();
26542693
db_record_repository_filename(0);
26552694
if( hasChanges==0 && !isAMerge && !allowEmpty && !forceFlag ){
26562695
fossil_fatal("nothing has changed; use --allow-empty to override");
@@ -2713,10 +2752,32 @@
27132752
" WHERE tagid=%d AND rid=%d AND tagtype>0"
27142753
" AND value=%Q", TAG_BRANCH, vid, sCiInfo.zBranch))
27152754
){
27162755
fossil_fatal("cannot commit against a closed leaf");
27172756
}
2757
+
2758
+ /* Require confirmation to continue with the check-in if the branch
2759
+ ** has changed and the committer did not provide the same branch
2760
+ */
2761
+ zNewBranch = branch_of_rid(vid);
2762
+ if( fossil_strcmp(zCurBranch, zNewBranch)!=0
2763
+ && fossil_strcmp(sCiInfo.zBranch, zNewBranch)!=0
2764
+ && forceFlag==0
2765
+ && noPrompt==0
2766
+ ){
2767
+ fossil_warning("parent check-in [%.10s] branch changed from '%s' to '%s'",
2768
+ rid_to_uuid(vid), zCurBranch, zNewBranch);
2769
+ prompt_user("continue (y/N)? ", &ans);
2770
+ cReply = blob_str(&ans)[0];
2771
+ blob_reset(&ans);
2772
+ if( cReply!='y' && cReply!='Y' ){
2773
+ fossil_fatal("Abandoning commit because branch has changed");
2774
+ }
2775
+ fossil_free(zCurBranch);
2776
+ zCurBranch = branch_of_rid(vid);
2777
+ }
2778
+ fossil_free(zNewBranch);
27182779
27192780
/* Always exit the loop on the second pass */
27202781
if( bRecheck ) break;
27212782
27222783
27232784
--- src/checkin.c
+++ src/checkin.c
@@ -1563,17 +1563,17 @@
1563 break;
1564 }
1565 diffFiles[i].nName = strlen(diffFiles[i].zName);
1566 diffFiles[i].nUsed = 0;
1567 }
1568 diff_against_disk(0, &DCfg, diffFiles, &prompt);
1569 for( i=0; diffFiles[i].zName; ++i ){
1570 fossil_free(diffFiles[i].zName);
1571 }
1572 fossil_free(diffFiles);
1573 }else{
1574 diff_against_disk(0, &DCfg, 0, &prompt);
1575 }
1576 }
1577 prompt_for_user_comment(pComment, &prompt);
1578 blob_reset(&prompt);
1579 }
@@ -2434,10 +2434,12 @@
2434 Blob ans; /* Answer to continuation prompts */
2435 char cReply; /* First character of ans */
2436 int bRecheck = 0; /* Repeat fork and closed-branch checks*/
2437 int bIgnoreSkew = 0; /* --ignore-clock-skew flag */
2438 int mxSize;
 
 
2439
2440 memset(&sCiInfo, 0, sizeof(sCiInfo));
2441 url_proxy_options();
2442 /* --sha1sum is an undocumented alias for --hash for backwards compatiblity */
2443 useHash = find_option("hash",0,0)!=0 || find_option("sha1sum",0,0)!=0;
@@ -2508,10 +2510,55 @@
2508 }
2509 }else{
2510 privateParent = content_is_private(vid);
2511 }
2512
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2513 /* Track the "private" status */
2514 g.markPrivate = privateFlag || privateParent;
2515 if( privateFlag && !privateParent ){
2516 /* Apply default branch name ("private") and color ("orange") if not
2517 ** specified otherwise on the command-line, and if the parent is not
@@ -2639,18 +2686,10 @@
2639 "'%s' was renamed to '%s'", zFrom, zTo, zFrom, zTo);
2640 }
2641 db_finalize(&q);
2642 }
2643
2644 user_select();
2645 /*
2646 ** Check that the user exists.
2647 */
2648 if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.zLogin) ){
2649 fossil_fatal("no such user: %s", g.zLogin);
2650 }
2651
2652 hasChanges = unsaved_changes(useHash ? CKSIG_HASH : 0);
2653 db_begin_transaction();
2654 db_record_repository_filename(0);
2655 if( hasChanges==0 && !isAMerge && !allowEmpty && !forceFlag ){
2656 fossil_fatal("nothing has changed; use --allow-empty to override");
@@ -2713,10 +2752,32 @@
2713 " WHERE tagid=%d AND rid=%d AND tagtype>0"
2714 " AND value=%Q", TAG_BRANCH, vid, sCiInfo.zBranch))
2715 ){
2716 fossil_fatal("cannot commit against a closed leaf");
2717 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2718
2719 /* Always exit the loop on the second pass */
2720 if( bRecheck ) break;
2721
2722
2723
--- src/checkin.c
+++ src/checkin.c
@@ -1563,17 +1563,17 @@
1563 break;
1564 }
1565 diffFiles[i].nName = strlen(diffFiles[i].zName);
1566 diffFiles[i].nUsed = 0;
1567 }
1568 diff_version_to_checkout(0, &DCfg, diffFiles, &prompt);
1569 for( i=0; diffFiles[i].zName; ++i ){
1570 fossil_free(diffFiles[i].zName);
1571 }
1572 fossil_free(diffFiles);
1573 }else{
1574 diff_version_to_checkout(0, &DCfg, 0, &prompt);
1575 }
1576 }
1577 prompt_for_user_comment(pComment, &prompt);
1578 blob_reset(&prompt);
1579 }
@@ -2434,10 +2434,12 @@
2434 Blob ans; /* Answer to continuation prompts */
2435 char cReply; /* First character of ans */
2436 int bRecheck = 0; /* Repeat fork and closed-branch checks*/
2437 int bIgnoreSkew = 0; /* --ignore-clock-skew flag */
2438 int mxSize;
2439 char *zCurBranch = 0; /* The current branch name of checkout */
2440 char *zNewBranch = 0; /* The branch name after update */
2441
2442 memset(&sCiInfo, 0, sizeof(sCiInfo));
2443 url_proxy_options();
2444 /* --sha1sum is an undocumented alias for --hash for backwards compatiblity */
2445 useHash = find_option("hash",0,0)!=0 || find_option("sha1sum",0,0)!=0;
@@ -2508,10 +2510,55 @@
2510 }
2511 }else{
2512 privateParent = content_is_private(vid);
2513 }
2514
2515 user_select();
2516 /*
2517 ** Check that the user exists.
2518 */
2519 if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.zLogin) ){
2520 fossil_fatal("no such user: %s", g.zLogin);
2521 }
2522
2523 /*
2524 ** Detect if the branch name has changed from the parent check-in
2525 ** and prompt if necessary
2526 **/
2527 zCurBranch = db_text(0,
2528 " SELECT value FROM tagxref AS tx"
2529 " WHERE rid=(SELECT pid"
2530 " FROM tagxref LEFT JOIN event ON srcid=objid"
2531 " LEFT JOIN plink ON rid=cid"
2532 " WHERE rid=%d AND tagxref.tagid=%d"
2533 " AND srcid!=origid"
2534 " AND tagtype=2 AND coalesce(euser,user)!=%Q)"
2535 " AND tx.tagid=%d",
2536 vid, TAG_BRANCH, g.zLogin, TAG_BRANCH
2537 );
2538 if( zCurBranch!=0 && zCurBranch[0]!=0
2539 && forceFlag==0
2540 && noPrompt==0
2541 ){
2542 zNewBranch = branch_of_rid(vid);
2543 fossil_warning(
2544 "WARNING: The parent check-in [%.10s] has been moved from branch\n"
2545 " '%s' over to branch '%s'.",
2546 rid_to_uuid(vid), zCurBranch, zNewBranch
2547 );
2548 prompt_user("Commit anyway? (y/N) ", &ans);
2549 cReply = blob_str(&ans)[0];
2550 blob_reset(&ans);
2551 if( cReply!='y' && cReply!='Y' ){
2552 fossil_fatal("Abandoning commit because branch has changed");
2553 }
2554 fossil_free(zNewBranch);
2555 fossil_free(zCurBranch);
2556 zCurBranch = branch_of_rid(vid);
2557 }
2558 if( zCurBranch==0 ) zCurBranch = branch_of_rid(vid);
2559
2560 /* Track the "private" status */
2561 g.markPrivate = privateFlag || privateParent;
2562 if( privateFlag && !privateParent ){
2563 /* Apply default branch name ("private") and color ("orange") if not
2564 ** specified otherwise on the command-line, and if the parent is not
@@ -2639,18 +2686,10 @@
2686 "'%s' was renamed to '%s'", zFrom, zTo, zFrom, zTo);
2687 }
2688 db_finalize(&q);
2689 }
2690
 
 
 
 
 
 
 
 
2691 hasChanges = unsaved_changes(useHash ? CKSIG_HASH : 0);
2692 db_begin_transaction();
2693 db_record_repository_filename(0);
2694 if( hasChanges==0 && !isAMerge && !allowEmpty && !forceFlag ){
2695 fossil_fatal("nothing has changed; use --allow-empty to override");
@@ -2713,10 +2752,32 @@
2752 " WHERE tagid=%d AND rid=%d AND tagtype>0"
2753 " AND value=%Q", TAG_BRANCH, vid, sCiInfo.zBranch))
2754 ){
2755 fossil_fatal("cannot commit against a closed leaf");
2756 }
2757
2758 /* Require confirmation to continue with the check-in if the branch
2759 ** has changed and the committer did not provide the same branch
2760 */
2761 zNewBranch = branch_of_rid(vid);
2762 if( fossil_strcmp(zCurBranch, zNewBranch)!=0
2763 && fossil_strcmp(sCiInfo.zBranch, zNewBranch)!=0
2764 && forceFlag==0
2765 && noPrompt==0
2766 ){
2767 fossil_warning("parent check-in [%.10s] branch changed from '%s' to '%s'",
2768 rid_to_uuid(vid), zCurBranch, zNewBranch);
2769 prompt_user("continue (y/N)? ", &ans);
2770 cReply = blob_str(&ans)[0];
2771 blob_reset(&ans);
2772 if( cReply!='y' && cReply!='Y' ){
2773 fossil_fatal("Abandoning commit because branch has changed");
2774 }
2775 fossil_free(zCurBranch);
2776 zCurBranch = branch_of_rid(vid);
2777 }
2778 fossil_free(zNewBranch);
2779
2780 /* Always exit the loop on the second pass */
2781 if( bRecheck ) break;
2782
2783
2784
+2 -7
--- src/db.c
+++ src/db.c
@@ -1557,10 +1557,12 @@
15571557
sqlite3_create_function(db, "url_nouser", 1, SQLITE_UTF8, 0,
15581558
url_nouser_func,0,0);
15591559
sqlite3_create_function(db, "chat_msg_from_event", 4,
15601560
SQLITE_UTF8 | SQLITE_INNOCUOUS, 0,
15611561
chat_msg_from_event, 0, 0);
1562
+ sqlite3_create_function(db, "inode", 1, SQLITE_UTF8, 0,
1563
+ file_inode_sql_func,0,0);
15621564
15631565
}
15641566
15651567
#if USE_SEE
15661568
/*
@@ -4681,17 +4683,10 @@
46814683
** to obtain a check-in lock during auto-sync, the server will
46824684
** send the "pragma avoid-delta-manifests" statement in its reply,
46834685
** which will cause the client to avoid generating a delta
46844686
** manifest.
46854687
*/
4686
-/*
4687
-** SETTING: forum-close-policy boolean default=off
4688
-** If true, forum moderators may close/re-open forum posts, and reply
4689
-** to closed posts. If false, only administrators may do so. Note that
4690
-** this only affects the forum web UI, not post-closing tags which
4691
-** arrive via the command-line or from synchronization with a remote.
4692
-*/
46934688
/*
46944689
** SETTING: gdiff-command width=40 default=gdiff sensitive
46954690
** The value is an external command to run when performing a graphical
46964691
** diff. If undefined, text diff will be used.
46974692
*/
46984693
--- src/db.c
+++ src/db.c
@@ -1557,10 +1557,12 @@
1557 sqlite3_create_function(db, "url_nouser", 1, SQLITE_UTF8, 0,
1558 url_nouser_func,0,0);
1559 sqlite3_create_function(db, "chat_msg_from_event", 4,
1560 SQLITE_UTF8 | SQLITE_INNOCUOUS, 0,
1561 chat_msg_from_event, 0, 0);
 
 
1562
1563 }
1564
1565 #if USE_SEE
1566 /*
@@ -4681,17 +4683,10 @@
4681 ** to obtain a check-in lock during auto-sync, the server will
4682 ** send the "pragma avoid-delta-manifests" statement in its reply,
4683 ** which will cause the client to avoid generating a delta
4684 ** manifest.
4685 */
4686 /*
4687 ** SETTING: forum-close-policy boolean default=off
4688 ** If true, forum moderators may close/re-open forum posts, and reply
4689 ** to closed posts. If false, only administrators may do so. Note that
4690 ** this only affects the forum web UI, not post-closing tags which
4691 ** arrive via the command-line or from synchronization with a remote.
4692 */
4693 /*
4694 ** SETTING: gdiff-command width=40 default=gdiff sensitive
4695 ** The value is an external command to run when performing a graphical
4696 ** diff. If undefined, text diff will be used.
4697 */
4698
--- src/db.c
+++ src/db.c
@@ -1557,10 +1557,12 @@
1557 sqlite3_create_function(db, "url_nouser", 1, SQLITE_UTF8, 0,
1558 url_nouser_func,0,0);
1559 sqlite3_create_function(db, "chat_msg_from_event", 4,
1560 SQLITE_UTF8 | SQLITE_INNOCUOUS, 0,
1561 chat_msg_from_event, 0, 0);
1562 sqlite3_create_function(db, "inode", 1, SQLITE_UTF8, 0,
1563 file_inode_sql_func,0,0);
1564
1565 }
1566
1567 #if USE_SEE
1568 /*
@@ -4681,17 +4683,10 @@
4683 ** to obtain a check-in lock during auto-sync, the server will
4684 ** send the "pragma avoid-delta-manifests" statement in its reply,
4685 ** which will cause the client to avoid generating a delta
4686 ** manifest.
4687 */
 
 
 
 
 
 
 
4688 /*
4689 ** SETTING: gdiff-command width=40 default=gdiff sensitive
4690 ** The value is an external command to run when performing a graphical
4691 ** diff. If undefined, text diff will be used.
4692 */
4693
+10 -4
--- src/default.css
+++ src/default.css
@@ -748,10 +748,20 @@
748748
border-bottom: 3px solid gold;
749749
}
750750
body.tkt div.content ol.tkt-changes > li:target > ol {
751751
border-left: 1px solid gold;
752752
}
753
+body.cpage-ckout .file-change-line,
754
+body.cpage-info .file-change-line,
755
+body.cpage-vdiff .file-change-line {
756
+ margin-top: 16px;
757
+ margin-bottom: 16px;
758
+ margin-right: 1em /* keep it from nudging right up against the scrollbar-reveal zone */;
759
+ display: flex;
760
+ flex-direction: row;
761
+ justify-content: space-between;
762
+}
753763
754764
span.modpending {
755765
color: #b03800;
756766
font-style: italic;
757767
}
@@ -1818,14 +1828,10 @@
18181828
}
18191829
body.fossil-dark-style .settings-icon {
18201830
filter: invert(100%);
18211831
}
18221832
1823
-input[type="checkbox"].diff-toggle {
1824
- float: right;
1825
-}
1826
-
18271833
body.branch .brlist > table > tbody > tr:hover:not(.selected),
18281834
body.branch .brlist > table > tbody > tr.selected {
18291835
background-color: #ffc;
18301836
}
18311837
body.branch .brlist > table > tbody td:first-child > input {
18321838
--- src/default.css
+++ src/default.css
@@ -748,10 +748,20 @@
748 border-bottom: 3px solid gold;
749 }
750 body.tkt div.content ol.tkt-changes > li:target > ol {
751 border-left: 1px solid gold;
752 }
 
 
 
 
 
 
 
 
 
 
753
754 span.modpending {
755 color: #b03800;
756 font-style: italic;
757 }
@@ -1818,14 +1828,10 @@
1818 }
1819 body.fossil-dark-style .settings-icon {
1820 filter: invert(100%);
1821 }
1822
1823 input[type="checkbox"].diff-toggle {
1824 float: right;
1825 }
1826
1827 body.branch .brlist > table > tbody > tr:hover:not(.selected),
1828 body.branch .brlist > table > tbody > tr.selected {
1829 background-color: #ffc;
1830 }
1831 body.branch .brlist > table > tbody td:first-child > input {
1832
--- src/default.css
+++ src/default.css
@@ -748,10 +748,20 @@
748 border-bottom: 3px solid gold;
749 }
750 body.tkt div.content ol.tkt-changes > li:target > ol {
751 border-left: 1px solid gold;
752 }
753 body.cpage-ckout .file-change-line,
754 body.cpage-info .file-change-line,
755 body.cpage-vdiff .file-change-line {
756 margin-top: 16px;
757 margin-bottom: 16px;
758 margin-right: 1em /* keep it from nudging right up against the scrollbar-reveal zone */;
759 display: flex;
760 flex-direction: row;
761 justify-content: space-between;
762 }
763
764 span.modpending {
765 color: #b03800;
766 font-style: italic;
767 }
@@ -1818,14 +1828,10 @@
1828 }
1829 body.fossil-dark-style .settings-icon {
1830 filter: invert(100%);
1831 }
1832
 
 
 
 
1833 body.branch .brlist > table > tbody > tr:hover:not(.selected),
1834 body.branch .brlist > table > tbody > tr.selected {
1835 background-color: #ffc;
1836 }
1837 body.branch .brlist > table > tbody td:first-child > input {
1838
+50 -48
--- src/delta.c
+++ src/delta.c
@@ -225,59 +225,61 @@
225225
** of four bytes.
226226
*/
227227
static unsigned int checksum(const char *zIn, size_t N){
228228
static const int byteOrderTest = 1;
229229
const unsigned char *z = (const unsigned char *)zIn;
230
- const unsigned char *zEnd = (const unsigned char*)&zIn[N&~3];
231230
unsigned sum = 0;
232
- assert( (z - (const unsigned char*)0)%4==0 ); /* Four-byte alignment */
233
- if( 0==*(char*)&byteOrderTest ){
234
- /* This is a big-endian machine */
235
- while( z<zEnd ){
236
- sum += *(unsigned*)z;
237
- z += 4;
238
- }
239
- }else{
240
- /* A little-endian machine */
241
-#if GCC_VERSION>=4003000
242
- while( z<zEnd ){
243
- sum += __builtin_bswap32(*(unsigned*)z);
244
- z += 4;
245
- }
246
-#elif defined(_MSC_VER) && _MSC_VER>=1300
247
- while( z<zEnd ){
248
- sum += _byteswap_ulong(*(unsigned*)z);
249
- z += 4;
250
- }
251
-#else
252
- unsigned sum0 = 0;
253
- unsigned sum1 = 0;
254
- unsigned sum2 = 0;
255
- while(N >= 16){
256
- sum0 += ((unsigned)z[0] + z[4] + z[8] + z[12]);
257
- sum1 += ((unsigned)z[1] + z[5] + z[9] + z[13]);
258
- sum2 += ((unsigned)z[2] + z[6] + z[10]+ z[14]);
259
- sum += ((unsigned)z[3] + z[7] + z[11]+ z[15]);
260
- z += 16;
261
- N -= 16;
262
- }
263
- while(N >= 4){
264
- sum0 += z[0];
265
- sum1 += z[1];
266
- sum2 += z[2];
267
- sum += z[3];
268
- z += 4;
269
- N -= 4;
270
- }
271
- sum += (sum2 << 8) + (sum1 << 16) + (sum0 << 24);
272
-#endif
273
- }
274
- switch(N&3){
275
- case 3: sum += (z[2] << 8);
276
- case 2: sum += (z[1] << 16);
277
- case 1: sum += (z[0] << 24);
278
- default: ;
231
+ if( N>0 ){
232
+ const unsigned char *zEnd = (const unsigned char*)&zIn[N&~3];
233
+ assert( (z - (const unsigned char*)0)%4==0 ); /* Four-byte alignment */
234
+ if( 0==*(char*)&byteOrderTest ){
235
+ /* This is a big-endian machine */
236
+ while( z<zEnd ){
237
+ sum += *(unsigned*)z;
238
+ z += 4;
239
+ }
240
+ }else{
241
+ /* A little-endian machine */
242
+ #if GCC_VERSION>=4003000
243
+ while( z<zEnd ){
244
+ sum += __builtin_bswap32(*(unsigned*)z);
245
+ z += 4;
246
+ }
247
+ #elif defined(_MSC_VER) && _MSC_VER>=1300
248
+ while( z<zEnd ){
249
+ sum += _byteswap_ulong(*(unsigned*)z);
250
+ z += 4;
251
+ }
252
+ #else
253
+ unsigned sum0 = 0;
254
+ unsigned sum1 = 0;
255
+ unsigned sum2 = 0;
256
+ while(N >= 16){
257
+ sum0 += ((unsigned)z[0] + z[4] + z[8] + z[12]);
258
+ sum1 += ((unsigned)z[1] + z[5] + z[9] + z[13]);
259
+ sum2 += ((unsigned)z[2] + z[6] + z[10]+ z[14]);
260
+ sum += ((unsigned)z[3] + z[7] + z[11]+ z[15]);
261
+ z += 16;
262
+ N -= 16;
263
+ }
264
+ while(N >= 4){
265
+ sum0 += z[0];
266
+ sum1 += z[1];
267
+ sum2 += z[2];
268
+ sum += z[3];
269
+ z += 4;
270
+ N -= 4;
271
+ }
272
+ sum += (sum2 << 8) + (sum1 << 16) + (sum0 << 24);
273
+ #endif
274
+ }
275
+ switch(N&3){
276
+ case 3: sum += (z[2] << 8);
277
+ case 2: sum += (z[1] << 16);
278
+ case 1: sum += (z[0] << 24);
279
+ default: ;
280
+ }
279281
}
280282
return sum;
281283
}
282284
283285
/*
284286
--- src/delta.c
+++ src/delta.c
@@ -225,59 +225,61 @@
225 ** of four bytes.
226 */
227 static unsigned int checksum(const char *zIn, size_t N){
228 static const int byteOrderTest = 1;
229 const unsigned char *z = (const unsigned char *)zIn;
230 const unsigned char *zEnd = (const unsigned char*)&zIn[N&~3];
231 unsigned sum = 0;
232 assert( (z - (const unsigned char*)0)%4==0 ); /* Four-byte alignment */
233 if( 0==*(char*)&byteOrderTest ){
234 /* This is a big-endian machine */
235 while( z<zEnd ){
236 sum += *(unsigned*)z;
237 z += 4;
238 }
239 }else{
240 /* A little-endian machine */
241 #if GCC_VERSION>=4003000
242 while( z<zEnd ){
243 sum += __builtin_bswap32(*(unsigned*)z);
244 z += 4;
245 }
246 #elif defined(_MSC_VER) && _MSC_VER>=1300
247 while( z<zEnd ){
248 sum += _byteswap_ulong(*(unsigned*)z);
249 z += 4;
250 }
251 #else
252 unsigned sum0 = 0;
253 unsigned sum1 = 0;
254 unsigned sum2 = 0;
255 while(N >= 16){
256 sum0 += ((unsigned)z[0] + z[4] + z[8] + z[12]);
257 sum1 += ((unsigned)z[1] + z[5] + z[9] + z[13]);
258 sum2 += ((unsigned)z[2] + z[6] + z[10]+ z[14]);
259 sum += ((unsigned)z[3] + z[7] + z[11]+ z[15]);
260 z += 16;
261 N -= 16;
262 }
263 while(N >= 4){
264 sum0 += z[0];
265 sum1 += z[1];
266 sum2 += z[2];
267 sum += z[3];
268 z += 4;
269 N -= 4;
270 }
271 sum += (sum2 << 8) + (sum1 << 16) + (sum0 << 24);
272 #endif
273 }
274 switch(N&3){
275 case 3: sum += (z[2] << 8);
276 case 2: sum += (z[1] << 16);
277 case 1: sum += (z[0] << 24);
278 default: ;
 
 
 
279 }
280 return sum;
281 }
282
283 /*
284
--- src/delta.c
+++ src/delta.c
@@ -225,59 +225,61 @@
225 ** of four bytes.
226 */
227 static unsigned int checksum(const char *zIn, size_t N){
228 static const int byteOrderTest = 1;
229 const unsigned char *z = (const unsigned char *)zIn;
 
230 unsigned sum = 0;
231 if( N>0 ){
232 const unsigned char *zEnd = (const unsigned char*)&zIn[N&~3];
233 assert( (z - (const unsigned char*)0)%4==0 ); /* Four-byte alignment */
234 if( 0==*(char*)&byteOrderTest ){
235 /* This is a big-endian machine */
236 while( z<zEnd ){
237 sum += *(unsigned*)z;
238 z += 4;
239 }
240 }else{
241 /* A little-endian machine */
242 #if GCC_VERSION>=4003000
243 while( z<zEnd ){
244 sum += __builtin_bswap32(*(unsigned*)z);
245 z += 4;
246 }
247 #elif defined(_MSC_VER) && _MSC_VER>=1300
248 while( z<zEnd ){
249 sum += _byteswap_ulong(*(unsigned*)z);
250 z += 4;
251 }
252 #else
253 unsigned sum0 = 0;
254 unsigned sum1 = 0;
255 unsigned sum2 = 0;
256 while(N >= 16){
257 sum0 += ((unsigned)z[0] + z[4] + z[8] + z[12]);
258 sum1 += ((unsigned)z[1] + z[5] + z[9] + z[13]);
259 sum2 += ((unsigned)z[2] + z[6] + z[10]+ z[14]);
260 sum += ((unsigned)z[3] + z[7] + z[11]+ z[15]);
261 z += 16;
262 N -= 16;
263 }
264 while(N >= 4){
265 sum0 += z[0];
266 sum1 += z[1];
267 sum2 += z[2];
268 sum += z[3];
269 z += 4;
270 N -= 4;
271 }
272 sum += (sum2 << 8) + (sum1 << 16) + (sum0 << 24);
273 #endif
274 }
275 switch(N&3){
276 case 3: sum += (z[2] << 8);
277 case 2: sum += (z[1] << 16);
278 case 1: sum += (z[0] << 24);
279 default: ;
280 }
281 }
282 return sum;
283 }
284
285 /*
286
+144 -5
--- src/diff.c
+++ src/diff.c
@@ -50,10 +50,11 @@
5050
#define DIFF_RAW 0x00040000 /* Raw triples - for debugging */
5151
#define DIFF_TCL 0x00080000 /* For the --tk option */
5252
#define DIFF_INCBINARY 0x00100000 /* The --diff-binary option */
5353
#define DIFF_SHOW_VERS 0x00200000 /* Show compared versions */
5454
#define DIFF_DARKMODE 0x00400000 /* Use dark mode for HTML */
55
+#define DIFF_BY_TOKEN 0x01000000 /* Split on tokens, not lines */
5556
5657
/*
5758
** Per file information that may influence output.
5859
*/
5960
#define DIFF_FILE_ADDED 0x40000000 /* Added or rename destination */
@@ -319,10 +320,113 @@
319320
320321
/* Return results */
321322
*pnLine = nLine;
322323
return a;
323324
}
325
+
326
+/*
327
+** Character classes for the purpose of tokenization.
328
+**
329
+** 1 - alphanumeric
330
+** 2 - whitespace
331
+** 3 - punctuation
332
+*/
333
+static char aTCharClass[256] = {
334
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
335
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
336
+ 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
337
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3,
338
+
339
+ 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
340
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3,
341
+ 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
342
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3,
343
+
344
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
345
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
346
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
347
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
348
+
349
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
350
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
351
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
352
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
353
+};
354
+
355
+/*
356
+** Count the number of tokens in the given string.
357
+*/
358
+static int count_tokens(const unsigned char *p, int n){
359
+ int nToken = 0;
360
+ int iPrev = 0;
361
+ int i;
362
+ for(i=0; i<n; i++){
363
+ char x = aTCharClass[p[i]];
364
+ if( x!=iPrev ){
365
+ iPrev = x;
366
+ nToken++;
367
+ }
368
+ }
369
+ return nToken;
370
+}
371
+
372
+/*
373
+** Return an array of DLine objects containing a pointer to the
374
+** start of each token and a hash of that token. The lower
375
+** bits of the hash store the length of each token.
376
+**
377
+** This is like break_into_lines() except that it works with tokens
378
+** instead of lines. A token is:
379
+**
380
+** * A contiguous sequence of alphanumeric characters.
381
+** * A contiguous sequence of whitespace
382
+** * A contiguous sequence of punctuation characters.
383
+**
384
+** Return 0 if the file is binary or contains a line that is
385
+** too long.
386
+*/
387
+static DLine *break_into_tokens(
388
+ const char *z,
389
+ int n,
390
+ int *pnToken,
391
+ u64 diffFlags
392
+){
393
+ int nToken, i, k;
394
+ u64 h, h2;
395
+ DLine *a;
396
+ unsigned char *p = (unsigned char*)z;
397
+
398
+ nToken = count_tokens(p, n);
399
+ a = fossil_malloc( sizeof(a[0])*(nToken+1) );
400
+ memset(a, 0, sizeof(a[0])*(nToken+1));
401
+ if( n==0 ){
402
+ *pnToken = 0;
403
+ return a;
404
+ }
405
+ i = 0;
406
+ while( n>0 ){
407
+ char x = aTCharClass[*p];
408
+ h = 0xcbf29ce484222325LL;
409
+ for(k=1; k<n && aTCharClass[p[k]]==x; k++){
410
+ h ^= p[k];
411
+ h *= 0x100000001b3LL;
412
+ }
413
+ a[i].z = (char*)p;
414
+ a[i].n = k;
415
+ a[i].h = h = ((h%281474976710597LL)<<LENGTH_MASK_SZ) | k;
416
+ h2 = h % nToken;
417
+ a[i].iNext = a[h2].iHash;
418
+ a[h2].iHash = i+1;
419
+ p += k; n -= k;
420
+ i++;
421
+ };
422
+ assert( i==nToken );
423
+
424
+ /* Return results */
425
+ *pnToken = nToken;
426
+ return a;
427
+}
324428
325429
/*
326430
** Return zero if two DLine elements are identical.
327431
*/
328432
static int compare_dline(const DLine *pA, const DLine *pB){
@@ -2997,14 +3101,21 @@
29973101
if( (pCfg->diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
29983102
c.xDiffer = compare_dline_ignore_allws;
29993103
}else{
30003104
c.xDiffer = compare_dline;
30013105
}
3002
- c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
3003
- &c.nFrom, pCfg->diffFlags);
3004
- c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob),
3005
- &c.nTo, pCfg->diffFlags);
3106
+ if( pCfg->diffFlags & DIFF_BY_TOKEN ){
3107
+ c.aFrom = break_into_tokens(blob_str(pA_Blob), blob_size(pA_Blob),
3108
+ &c.nFrom, pCfg->diffFlags);
3109
+ c.aTo = break_into_tokens(blob_str(pB_Blob), blob_size(pB_Blob),
3110
+ &c.nTo, pCfg->diffFlags);
3111
+ }else{
3112
+ c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
3113
+ &c.nFrom, pCfg->diffFlags);
3114
+ c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob),
3115
+ &c.nTo, pCfg->diffFlags);
3116
+ }
30063117
if( c.aFrom==0 || c.aTo==0 ){
30073118
fossil_free(c.aFrom);
30083119
fossil_free(c.aTo);
30093120
if( pOut ){
30103121
diff_errmsg(pOut, DIFF_CANNOT_COMPUTE_BINARY, pCfg->diffFlags);
@@ -3035,10 +3146,26 @@
30353146
}
30363147
}
30373148
if( (pCfg->diffFlags & DIFF_NOOPT)==0 ){
30383149
diff_optimize(&c);
30393150
}
3151
+ if( (pCfg->diffFlags & DIFF_BY_TOKEN)!=0 ){
3152
+ /* Convert token counts into byte counts. */
3153
+ int i;
3154
+ int iA = 0;
3155
+ int iB = 0;
3156
+ for(i=0; c.aEdit[i] || c.aEdit[i+1] || c.aEdit[i+2]; i+=3){
3157
+ int k, sum;
3158
+ for(k=0, sum=0; k<c.aEdit[i]; k++) sum += c.aFrom[iA++].n;
3159
+ iB += c.aEdit[i];
3160
+ c.aEdit[i] = sum;
3161
+ for(k=0, sum=0; k<c.aEdit[i+1]; k++) sum += c.aFrom[iA++].n;
3162
+ c.aEdit[i+1] = sum;
3163
+ for(k=0, sum=0; k<c.aEdit[i+2]; k++) sum += c.aTo[iB++].n;
3164
+ c.aEdit[i+2] = sum;
3165
+ }
3166
+ }
30403167
30413168
if( pOut ){
30423169
if( pCfg->diffFlags & DIFF_NUMSTAT ){
30433170
int nDel = 0, nIns = 0, i;
30443171
for(i=0; c.aEdit[i] || c.aEdit[i+1] || c.aEdit[i+2]; i+=3){
@@ -3049,11 +3176,11 @@
30493176
g.diffCnt[2] += nDel;
30503177
if( nIns+nDel ){
30513178
g.diffCnt[0]++;
30523179
blob_appendf(pOut, "%10d %10d", nIns, nDel);
30533180
}
3054
- }else if( pCfg->diffFlags & DIFF_RAW ){
3181
+ }else if( pCfg->diffFlags & (DIFF_RAW|DIFF_BY_TOKEN) ){
30553182
const int *R = c.aEdit;
30563183
unsigned int r;
30573184
for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){
30583185
blob_appendf(pOut, " copy %6d delete %6d insert %6d\n",
30593186
R[r], R[r+1], R[r+2]);
@@ -3100,20 +3227,29 @@
31003227
** Initialize the DiffConfig object using command-line options.
31013228
**
31023229
** Process diff-related command-line options and return an appropriate
31033230
** "diffFlags" integer.
31043231
**
3232
+** -b|--browser Show the diff output in a web-browser
31053233
** --brief Show filenames only DIFF_BRIEF
3234
+** --by Shorthand for "--browser -y"
31063235
** -c|--context N N lines of context. nContext
3236
+** --dark Use dark mode for Tcl/Tk and HTML output
31073237
** --html Format for HTML DIFF_HTML
3238
+** -i|--internal Use built-in diff, not an external tool
31083239
** --invert Invert the diff DIFF_INVERT
3240
+** --json Output formatted as JSON
31093241
** -n|--linenum Show line numbers DIFF_LINENO
3242
+** -N|--new-file Alias for --verbose
31103243
** --noopt Disable optimization DIFF_NOOPT
31113244
** --numstat Show change counts DIFF_NUMSTAT
31123245
** --strip-trailing-cr Strip trailing CR DIFF_STRIP_EOLCR
3246
+** --tcl Tcl-formatted output used internally by --tk
31133247
** --unified Unified diff. ~DIFF_SIDEBYSIDE
3248
+** -v|--verbose Show complete text of added or deleted files
31143249
** -w|--ignore-all-space Ignore all whitespaces DIFF_IGNORE_ALLWS
3250
+** --webpage Format output as a stand-alone HTML webpage
31153251
** -W|--width N N character lines. wColumn
31163252
** -y|--side-by-side Side-by-side diff. DIFF_SIDEBYSIDE
31173253
** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS
31183254
*/
31193255
void diff_options(DiffConfig *pCfg, int isGDiff, int bUnifiedTextOnly){
@@ -3157,10 +3293,13 @@
31573293
31583294
/* Undocumented and unsupported flags used for development
31593295
** debugging and analysis: */
31603296
if( find_option("debug",0,0)!=0 ) diffFlags |= DIFF_DEBUG;
31613297
if( find_option("raw",0,0)!=0 ) diffFlags |= DIFF_RAW;
3298
+ if( find_option("bytoken",0,0)!=0 ){
3299
+ diffFlags = DIFF_RAW|DIFF_BY_TOKEN;
3300
+ }
31623301
}
31633302
if( (z = find_option("context","c",1))!=0 ){
31643303
char *zEnd;
31653304
f = (int)strtol(z, &zEnd, 10);
31663305
if( zEnd[0]==0 && errno!=ERANGE ){
31673306
--- src/diff.c
+++ src/diff.c
@@ -50,10 +50,11 @@
50 #define DIFF_RAW 0x00040000 /* Raw triples - for debugging */
51 #define DIFF_TCL 0x00080000 /* For the --tk option */
52 #define DIFF_INCBINARY 0x00100000 /* The --diff-binary option */
53 #define DIFF_SHOW_VERS 0x00200000 /* Show compared versions */
54 #define DIFF_DARKMODE 0x00400000 /* Use dark mode for HTML */
 
55
56 /*
57 ** Per file information that may influence output.
58 */
59 #define DIFF_FILE_ADDED 0x40000000 /* Added or rename destination */
@@ -319,10 +320,113 @@
319
320 /* Return results */
321 *pnLine = nLine;
322 return a;
323 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
324
325 /*
326 ** Return zero if two DLine elements are identical.
327 */
328 static int compare_dline(const DLine *pA, const DLine *pB){
@@ -2997,14 +3101,21 @@
2997 if( (pCfg->diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
2998 c.xDiffer = compare_dline_ignore_allws;
2999 }else{
3000 c.xDiffer = compare_dline;
3001 }
3002 c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
3003 &c.nFrom, pCfg->diffFlags);
3004 c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob),
3005 &c.nTo, pCfg->diffFlags);
 
 
 
 
 
 
 
3006 if( c.aFrom==0 || c.aTo==0 ){
3007 fossil_free(c.aFrom);
3008 fossil_free(c.aTo);
3009 if( pOut ){
3010 diff_errmsg(pOut, DIFF_CANNOT_COMPUTE_BINARY, pCfg->diffFlags);
@@ -3035,10 +3146,26 @@
3035 }
3036 }
3037 if( (pCfg->diffFlags & DIFF_NOOPT)==0 ){
3038 diff_optimize(&c);
3039 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3040
3041 if( pOut ){
3042 if( pCfg->diffFlags & DIFF_NUMSTAT ){
3043 int nDel = 0, nIns = 0, i;
3044 for(i=0; c.aEdit[i] || c.aEdit[i+1] || c.aEdit[i+2]; i+=3){
@@ -3049,11 +3176,11 @@
3049 g.diffCnt[2] += nDel;
3050 if( nIns+nDel ){
3051 g.diffCnt[0]++;
3052 blob_appendf(pOut, "%10d %10d", nIns, nDel);
3053 }
3054 }else if( pCfg->diffFlags & DIFF_RAW ){
3055 const int *R = c.aEdit;
3056 unsigned int r;
3057 for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){
3058 blob_appendf(pOut, " copy %6d delete %6d insert %6d\n",
3059 R[r], R[r+1], R[r+2]);
@@ -3100,20 +3227,29 @@
3100 ** Initialize the DiffConfig object using command-line options.
3101 **
3102 ** Process diff-related command-line options and return an appropriate
3103 ** "diffFlags" integer.
3104 **
 
3105 ** --brief Show filenames only DIFF_BRIEF
 
3106 ** -c|--context N N lines of context. nContext
 
3107 ** --html Format for HTML DIFF_HTML
 
3108 ** --invert Invert the diff DIFF_INVERT
 
3109 ** -n|--linenum Show line numbers DIFF_LINENO
 
3110 ** --noopt Disable optimization DIFF_NOOPT
3111 ** --numstat Show change counts DIFF_NUMSTAT
3112 ** --strip-trailing-cr Strip trailing CR DIFF_STRIP_EOLCR
 
3113 ** --unified Unified diff. ~DIFF_SIDEBYSIDE
 
3114 ** -w|--ignore-all-space Ignore all whitespaces DIFF_IGNORE_ALLWS
 
3115 ** -W|--width N N character lines. wColumn
3116 ** -y|--side-by-side Side-by-side diff. DIFF_SIDEBYSIDE
3117 ** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS
3118 */
3119 void diff_options(DiffConfig *pCfg, int isGDiff, int bUnifiedTextOnly){
@@ -3157,10 +3293,13 @@
3157
3158 /* Undocumented and unsupported flags used for development
3159 ** debugging and analysis: */
3160 if( find_option("debug",0,0)!=0 ) diffFlags |= DIFF_DEBUG;
3161 if( find_option("raw",0,0)!=0 ) diffFlags |= DIFF_RAW;
 
 
 
3162 }
3163 if( (z = find_option("context","c",1))!=0 ){
3164 char *zEnd;
3165 f = (int)strtol(z, &zEnd, 10);
3166 if( zEnd[0]==0 && errno!=ERANGE ){
3167
--- src/diff.c
+++ src/diff.c
@@ -50,10 +50,11 @@
50 #define DIFF_RAW 0x00040000 /* Raw triples - for debugging */
51 #define DIFF_TCL 0x00080000 /* For the --tk option */
52 #define DIFF_INCBINARY 0x00100000 /* The --diff-binary option */
53 #define DIFF_SHOW_VERS 0x00200000 /* Show compared versions */
54 #define DIFF_DARKMODE 0x00400000 /* Use dark mode for HTML */
55 #define DIFF_BY_TOKEN 0x01000000 /* Split on tokens, not lines */
56
57 /*
58 ** Per file information that may influence output.
59 */
60 #define DIFF_FILE_ADDED 0x40000000 /* Added or rename destination */
@@ -319,10 +320,113 @@
320
321 /* Return results */
322 *pnLine = nLine;
323 return a;
324 }
325
326 /*
327 ** Character classes for the purpose of tokenization.
328 **
329 ** 1 - alphanumeric
330 ** 2 - whitespace
331 ** 3 - punctuation
332 */
333 static char aTCharClass[256] = {
334 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
335 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
336 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
337 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3,
338
339 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
340 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3,
341 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
342 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3,
343
344 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
345 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
346 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
347 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
348
349 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
350 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
351 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
352 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
353 };
354
355 /*
356 ** Count the number of tokens in the given string.
357 */
358 static int count_tokens(const unsigned char *p, int n){
359 int nToken = 0;
360 int iPrev = 0;
361 int i;
362 for(i=0; i<n; i++){
363 char x = aTCharClass[p[i]];
364 if( x!=iPrev ){
365 iPrev = x;
366 nToken++;
367 }
368 }
369 return nToken;
370 }
371
372 /*
373 ** Return an array of DLine objects containing a pointer to the
374 ** start of each token and a hash of that token. The lower
375 ** bits of the hash store the length of each token.
376 **
377 ** This is like break_into_lines() except that it works with tokens
378 ** instead of lines. A token is:
379 **
380 ** * A contiguous sequence of alphanumeric characters.
381 ** * A contiguous sequence of whitespace
382 ** * A contiguous sequence of punctuation characters.
383 **
384 ** Return 0 if the file is binary or contains a line that is
385 ** too long.
386 */
387 static DLine *break_into_tokens(
388 const char *z,
389 int n,
390 int *pnToken,
391 u64 diffFlags
392 ){
393 int nToken, i, k;
394 u64 h, h2;
395 DLine *a;
396 unsigned char *p = (unsigned char*)z;
397
398 nToken = count_tokens(p, n);
399 a = fossil_malloc( sizeof(a[0])*(nToken+1) );
400 memset(a, 0, sizeof(a[0])*(nToken+1));
401 if( n==0 ){
402 *pnToken = 0;
403 return a;
404 }
405 i = 0;
406 while( n>0 ){
407 char x = aTCharClass[*p];
408 h = 0xcbf29ce484222325LL;
409 for(k=1; k<n && aTCharClass[p[k]]==x; k++){
410 h ^= p[k];
411 h *= 0x100000001b3LL;
412 }
413 a[i].z = (char*)p;
414 a[i].n = k;
415 a[i].h = h = ((h%281474976710597LL)<<LENGTH_MASK_SZ) | k;
416 h2 = h % nToken;
417 a[i].iNext = a[h2].iHash;
418 a[h2].iHash = i+1;
419 p += k; n -= k;
420 i++;
421 };
422 assert( i==nToken );
423
424 /* Return results */
425 *pnToken = nToken;
426 return a;
427 }
428
429 /*
430 ** Return zero if two DLine elements are identical.
431 */
432 static int compare_dline(const DLine *pA, const DLine *pB){
@@ -2997,14 +3101,21 @@
3101 if( (pCfg->diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
3102 c.xDiffer = compare_dline_ignore_allws;
3103 }else{
3104 c.xDiffer = compare_dline;
3105 }
3106 if( pCfg->diffFlags & DIFF_BY_TOKEN ){
3107 c.aFrom = break_into_tokens(blob_str(pA_Blob), blob_size(pA_Blob),
3108 &c.nFrom, pCfg->diffFlags);
3109 c.aTo = break_into_tokens(blob_str(pB_Blob), blob_size(pB_Blob),
3110 &c.nTo, pCfg->diffFlags);
3111 }else{
3112 c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
3113 &c.nFrom, pCfg->diffFlags);
3114 c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob),
3115 &c.nTo, pCfg->diffFlags);
3116 }
3117 if( c.aFrom==0 || c.aTo==0 ){
3118 fossil_free(c.aFrom);
3119 fossil_free(c.aTo);
3120 if( pOut ){
3121 diff_errmsg(pOut, DIFF_CANNOT_COMPUTE_BINARY, pCfg->diffFlags);
@@ -3035,10 +3146,26 @@
3146 }
3147 }
3148 if( (pCfg->diffFlags & DIFF_NOOPT)==0 ){
3149 diff_optimize(&c);
3150 }
3151 if( (pCfg->diffFlags & DIFF_BY_TOKEN)!=0 ){
3152 /* Convert token counts into byte counts. */
3153 int i;
3154 int iA = 0;
3155 int iB = 0;
3156 for(i=0; c.aEdit[i] || c.aEdit[i+1] || c.aEdit[i+2]; i+=3){
3157 int k, sum;
3158 for(k=0, sum=0; k<c.aEdit[i]; k++) sum += c.aFrom[iA++].n;
3159 iB += c.aEdit[i];
3160 c.aEdit[i] = sum;
3161 for(k=0, sum=0; k<c.aEdit[i+1]; k++) sum += c.aFrom[iA++].n;
3162 c.aEdit[i+1] = sum;
3163 for(k=0, sum=0; k<c.aEdit[i+2]; k++) sum += c.aTo[iB++].n;
3164 c.aEdit[i+2] = sum;
3165 }
3166 }
3167
3168 if( pOut ){
3169 if( pCfg->diffFlags & DIFF_NUMSTAT ){
3170 int nDel = 0, nIns = 0, i;
3171 for(i=0; c.aEdit[i] || c.aEdit[i+1] || c.aEdit[i+2]; i+=3){
@@ -3049,11 +3176,11 @@
3176 g.diffCnt[2] += nDel;
3177 if( nIns+nDel ){
3178 g.diffCnt[0]++;
3179 blob_appendf(pOut, "%10d %10d", nIns, nDel);
3180 }
3181 }else if( pCfg->diffFlags & (DIFF_RAW|DIFF_BY_TOKEN) ){
3182 const int *R = c.aEdit;
3183 unsigned int r;
3184 for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){
3185 blob_appendf(pOut, " copy %6d delete %6d insert %6d\n",
3186 R[r], R[r+1], R[r+2]);
@@ -3100,20 +3227,29 @@
3227 ** Initialize the DiffConfig object using command-line options.
3228 **
3229 ** Process diff-related command-line options and return an appropriate
3230 ** "diffFlags" integer.
3231 **
3232 ** -b|--browser Show the diff output in a web-browser
3233 ** --brief Show filenames only DIFF_BRIEF
3234 ** --by Shorthand for "--browser -y"
3235 ** -c|--context N N lines of context. nContext
3236 ** --dark Use dark mode for Tcl/Tk and HTML output
3237 ** --html Format for HTML DIFF_HTML
3238 ** -i|--internal Use built-in diff, not an external tool
3239 ** --invert Invert the diff DIFF_INVERT
3240 ** --json Output formatted as JSON
3241 ** -n|--linenum Show line numbers DIFF_LINENO
3242 ** -N|--new-file Alias for --verbose
3243 ** --noopt Disable optimization DIFF_NOOPT
3244 ** --numstat Show change counts DIFF_NUMSTAT
3245 ** --strip-trailing-cr Strip trailing CR DIFF_STRIP_EOLCR
3246 ** --tcl Tcl-formatted output used internally by --tk
3247 ** --unified Unified diff. ~DIFF_SIDEBYSIDE
3248 ** -v|--verbose Show complete text of added or deleted files
3249 ** -w|--ignore-all-space Ignore all whitespaces DIFF_IGNORE_ALLWS
3250 ** --webpage Format output as a stand-alone HTML webpage
3251 ** -W|--width N N character lines. wColumn
3252 ** -y|--side-by-side Side-by-side diff. DIFF_SIDEBYSIDE
3253 ** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS
3254 */
3255 void diff_options(DiffConfig *pCfg, int isGDiff, int bUnifiedTextOnly){
@@ -3157,10 +3293,13 @@
3293
3294 /* Undocumented and unsupported flags used for development
3295 ** debugging and analysis: */
3296 if( find_option("debug",0,0)!=0 ) diffFlags |= DIFF_DEBUG;
3297 if( find_option("raw",0,0)!=0 ) diffFlags |= DIFF_RAW;
3298 if( find_option("bytoken",0,0)!=0 ){
3299 diffFlags = DIFF_RAW|DIFF_BY_TOKEN;
3300 }
3301 }
3302 if( (z = find_option("context","c",1))!=0 ){
3303 char *zEnd;
3304 f = (int)strtol(z, &zEnd, 10);
3305 if( zEnd[0]==0 && errno!=ERANGE ){
3306
+6 -2
--- src/diff.tcl
+++ src/diff.tcl
@@ -1,11 +1,11 @@
11
# The "diff --tk" command outputs prepends a "set fossilcmd {...}" line
22
# to this file, then runs this file using "tclsh" in order to display the
33
# graphical diff in a separate window. A typical "set fossilcmd" line
44
# looks like this:
55
#
6
-# set fossilcmd {| "./fossil" diff --html -y -i -v}
6
+# set fossilcmd {| "./fossil" diff --tcl -i -v}
77
#
88
# This header comment is stripped off by the "mkbuiltin.c" program.
99
#
1010
set prog {
1111
package require Tk
@@ -110,11 +110,15 @@
110110
111111
set fromIndex [lsearch -glob $fossilcmd *-from]
112112
set toIndex [lsearch -glob $fossilcmd *-to]
113113
set branchIndex [lsearch -glob $fossilcmd *-branch]
114114
set checkinIndex [lsearch -glob $fossilcmd *-checkin]
115
- set fA {base check-in}
115
+ if {[string match *?--external-baseline* $fossilcmd]} {
116
+ set fA {external baseline}
117
+ } else {
118
+ set fA {base check-in}
119
+ }
116120
set fB {current check-out}
117121
if {$fromIndex > -1} {set fA [lindex $fossilcmd $fromIndex+1]}
118122
if {$toIndex > -1} {set fB [lindex $fossilcmd $toIndex+1]}
119123
if {$branchIndex > -1} {set fA "branch point"; set fB "leaf of branch '[lindex $fossilcmd $branchIndex+1]'"}
120124
if {$checkinIndex > -1} {set fA "primary parent"; set fB [lindex $fossilcmd $checkinIndex+1]}
121125
--- src/diff.tcl
+++ src/diff.tcl
@@ -1,11 +1,11 @@
1 # The "diff --tk" command outputs prepends a "set fossilcmd {...}" line
2 # to this file, then runs this file using "tclsh" in order to display the
3 # graphical diff in a separate window. A typical "set fossilcmd" line
4 # looks like this:
5 #
6 # set fossilcmd {| "./fossil" diff --html -y -i -v}
7 #
8 # This header comment is stripped off by the "mkbuiltin.c" program.
9 #
10 set prog {
11 package require Tk
@@ -110,11 +110,15 @@
110
111 set fromIndex [lsearch -glob $fossilcmd *-from]
112 set toIndex [lsearch -glob $fossilcmd *-to]
113 set branchIndex [lsearch -glob $fossilcmd *-branch]
114 set checkinIndex [lsearch -glob $fossilcmd *-checkin]
115 set fA {base check-in}
 
 
 
 
116 set fB {current check-out}
117 if {$fromIndex > -1} {set fA [lindex $fossilcmd $fromIndex+1]}
118 if {$toIndex > -1} {set fB [lindex $fossilcmd $toIndex+1]}
119 if {$branchIndex > -1} {set fA "branch point"; set fB "leaf of branch '[lindex $fossilcmd $branchIndex+1]'"}
120 if {$checkinIndex > -1} {set fA "primary parent"; set fB [lindex $fossilcmd $checkinIndex+1]}
121
--- src/diff.tcl
+++ src/diff.tcl
@@ -1,11 +1,11 @@
1 # The "diff --tk" command outputs prepends a "set fossilcmd {...}" line
2 # to this file, then runs this file using "tclsh" in order to display the
3 # graphical diff in a separate window. A typical "set fossilcmd" line
4 # looks like this:
5 #
6 # set fossilcmd {| "./fossil" diff --tcl -i -v}
7 #
8 # This header comment is stripped off by the "mkbuiltin.c" program.
9 #
10 set prog {
11 package require Tk
@@ -110,11 +110,15 @@
110
111 set fromIndex [lsearch -glob $fossilcmd *-from]
112 set toIndex [lsearch -glob $fossilcmd *-to]
113 set branchIndex [lsearch -glob $fossilcmd *-branch]
114 set checkinIndex [lsearch -glob $fossilcmd *-checkin]
115 if {[string match *?--external-baseline* $fossilcmd]} {
116 set fA {external baseline}
117 } else {
118 set fA {base check-in}
119 }
120 set fB {current check-out}
121 if {$fromIndex > -1} {set fA [lindex $fossilcmd $fromIndex+1]}
122 if {$toIndex > -1} {set fB [lindex $fossilcmd $toIndex+1]}
123 if {$branchIndex > -1} {set fA "branch point"; set fB "leaf of branch '[lindex $fossilcmd $branchIndex+1]'"}
124 if {$checkinIndex > -1} {set fA "primary parent"; set fB [lindex $fossilcmd $checkinIndex+1]}
125
+96 -20
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -249,19 +249,19 @@
249249
@ margin: 0 0 0 0;
250250
@ line-height: inherit;
251251
@ font-size: inherit;
252252
@ }
253253
@ td.diffln {
254
-@ width: 1px;
254
+@ width: fit-content;
255255
@ text-align: right;
256256
@ padding: 0 1em 0 0;
257257
@ }
258258
@ td.difflne {
259259
@ padding-bottom: 0.4em;
260260
@ }
261261
@ td.diffsep {
262
-@ width: 1px;
262
+@ width: fit-content;
263263
@ padding: 0 0.3em 0 1em;
264264
@ line-height: inherit;
265265
@ font-size: inherit;
266266
@ }
267267
@ td.diffsep pre {
@@ -379,19 +379,19 @@
379379
@ margin: 0 0 0 0;
380380
@ line-height: inherit;
381381
@ font-size: inherit;
382382
@ }
383383
@ td.diffln {
384
-@ width: 1px;
384
+@ width: fit-content;
385385
@ text-align: right;
386386
@ padding: 0 1em 0 0;
387387
@ }
388388
@ td.difflne {
389389
@ padding-bottom: 0.4em;
390390
@ }
391391
@ td.diffsep {
392
-@ width: 1px;
392
+@ width: fit-content;
393393
@ padding: 0 0.3em 0 1em;
394394
@ line-height: inherit;
395395
@ font-size: inherit;
396396
@ }
397397
@ td.diffsep pre {
@@ -784,26 +784,27 @@
784784
blob_reset(&file);
785785
return rc;
786786
}
787787
788788
/*
789
-** Run a diff between the version zFrom and files on disk. zFrom might
790
-** be NULL which means to simply show the difference between the edited
791
-** files on disk and the check-out on which they are based.
789
+** Run a diff between the version zFrom and files on disk in the current
790
+** working checkout. zFrom might be NULL which means to simply show the
791
+** difference between the edited files on disk and the check-out on which
792
+** they are based.
792793
**
793794
** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the
794795
** command zDiffCmd to do the diffing.
795796
**
796797
** When using an external diff program, zBinGlob contains the GLOB patterns
797798
** for file names to treat as binary. If fIncludeBinary is zero, these files
798799
** will be skipped in addition to files that may contain binary content.
799800
*/
800
-void diff_against_disk(
801
+void diff_version_to_checkout(
801802
const char *zFrom, /* Version to difference from */
802803
DiffConfig *pCfg, /* Flags controlling diff output */
803804
FileDirList *pFileDir, /* Which files to diff */
804
- Blob *pOut /* Blob to output diff instead of stdout */
805
+ Blob *pOut /* Blob to output diff instead of stdout */
805806
){
806807
int vid;
807808
Blob sql;
808809
Stmt q;
809810
int asNewFile; /* Treat non-existant files as empty files */
@@ -928,20 +929,20 @@
928929
db_finalize(&q);
929930
db_end_transaction(1); /* ROLLBACK */
930931
}
931932
932933
/*
933
-** Run a diff between the undo buffer and files on disk.
934
+** Run a diff from the undo buffer to files on disk.
934935
**
935936
** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the
936937
** command zDiffCmd to do the diffing.
937938
**
938939
** When using an external diff program, zBinGlob contains the GLOB patterns
939940
** for file names to treat as binary. If fIncludeBinary is zero, these files
940941
** will be skipped in addition to files that may contain binary content.
941942
*/
942
-static void diff_against_undo(
943
+static void diff_undo_to_checkout(
943944
DiffConfig *pCfg, /* Flags controlling diff output */
944945
FileDirList *pFileDir /* List of files and directories to diff */
945946
){
946947
Stmt q;
947948
Blob content;
@@ -1088,10 +1089,67 @@
10881089
}
10891090
}
10901091
manifest_destroy(pFrom);
10911092
manifest_destroy(pTo);
10921093
}
1094
+
1095
+/*
1096
+** Compute the difference from an external tree of files to the current
1097
+** working checkout with its edits.
1098
+**
1099
+** To put it another way: Every managed file in the current working
1100
+** checkout is compared to the file with same name under zExternBase. The
1101
+** zExternBase files are on the left and the files in the current working
1102
+** directory are on the right.
1103
+*/
1104
+void diff_externbase_to_checkout(
1105
+ const char *zExternBase, /* Remote tree to use as the baseline */
1106
+ DiffConfig *pCfg, /* Diff settings */
1107
+ FileDirList *pFileDir /* Only look at these files */
1108
+){
1109
+ int vid;
1110
+ Stmt q;
1111
+
1112
+ vid = db_lget_int("checkout",0);
1113
+ if( file_isdir(zExternBase, ExtFILE)!=1 ){
1114
+ fossil_fatal("\"%s\" is not a directory", zExternBase);
1115
+ }
1116
+ db_prepare(&q,
1117
+ "SELECT pathname FROM vfile WHERE vid=%d ORDER BY pathname",
1118
+ vid
1119
+ );
1120
+ while( db_step(&q)==SQLITE_ROW ){
1121
+ const char *zFile; /* Name of file in the repository */
1122
+ char *zLhs; /* Full name of left-hand side file */
1123
+ char *zRhs; /* Full name of right-hand side file */
1124
+ Blob rhs; /* Full text of RHS */
1125
+ Blob lhs; /* Full text of LHS */
1126
+
1127
+ zFile = db_column_text(&q,0);
1128
+ if( !file_dir_match(pFileDir, zFile) ) continue;
1129
+ zLhs = mprintf("%s/%s", zExternBase, zFile);
1130
+ zRhs = mprintf("%s%s", g.zLocalRoot, zFile);
1131
+ if( file_size(zLhs, ExtFILE)<0 ){
1132
+ blob_zero(&lhs);
1133
+ }else{
1134
+ blob_read_from_file(&lhs, zLhs, ExtFILE);
1135
+ }
1136
+ blob_read_from_file(&rhs, zRhs, ExtFILE);
1137
+ if( blob_size(&lhs)!=blob_size(&rhs)
1138
+ || memcmp(blob_buffer(&lhs), blob_buffer(&rhs), blob_size(&lhs))!=0
1139
+ ){
1140
+ diff_print_index(zFile, pCfg, 0);
1141
+ diff_file_mem(&lhs, &rhs, zFile, pCfg);
1142
+ }
1143
+ blob_reset(&lhs);
1144
+ blob_reset(&rhs);
1145
+ fossil_free(zLhs);
1146
+ fossil_free(zRhs);
1147
+ }
1148
+ db_finalize(&q);
1149
+}
1150
+
10931151
10941152
/*
10951153
** Return the name of the external diff command, or return NULL if
10961154
** no external diff command is defined.
10971155
*/
@@ -1224,10 +1282,14 @@
12241282
** option specifies the check-in from which the second version of the file
12251283
** or files is taken. If there is no "--to" option then the (possibly edited)
12261284
** files in the current check-out are used. The "--checkin VERSION" option
12271285
** shows the changes made by check-in VERSION relative to its primary parent.
12281286
** The "--branch BRANCHNAME" shows all the changes on the branch BRANCHNAME.
1287
+**
1288
+** With the "--from VERSION" option, if VERSION is actually a directory name
1289
+** (not a tag or check-in hash) then the files under that directory are used
1290
+** as the baseline for the diff.
12291291
**
12301292
** The "-i" command-line option forces the use of Fossil's own internal
12311293
** diff logic rather than any external diff program that might be configured
12321294
** using the "setting" command. If no external diff program is configured,
12331295
** then the "-i" option is a no-op. The "-i" option converts "gdiff" into
@@ -1256,11 +1318,13 @@
12561318
** with negative N meaning show all content
12571319
** --dark Use dark mode for the Tcl/Tk-based GUI and HTML
12581320
** --diff-binary BOOL Include binary files with external commands
12591321
** --exec-abs-paths Force absolute path names on external commands
12601322
** --exec-rel-paths Force relative path names on external commands
1261
-** -r|--from VERSION Select VERSION as source for the diff
1323
+** -r|--from VERSION Use VERSION as the baseline for the diff, or
1324
+** if VERSION is a directory name, use files in
1325
+** that directory as the baseline.
12621326
** -w|--ignore-all-space Ignore white space when comparing lines
12631327
** -i|--internal Use internal diff logic
12641328
** --invert Invert the diff
12651329
** --json Output formatted as JSON
12661330
** -n|--linenum Show line numbers
@@ -1270,11 +1334,11 @@
12701334
** --strip-trailing-cr Strip trailing CR
12711335
** --tcl Tcl-formatted output used internally by --tk
12721336
** --tclsh PATH Tcl/Tk shell used for --tk (default: "tclsh")
12731337
** --tk Launch a Tcl/Tk GUI for display
12741338
** --to VERSION Select VERSION as target for the diff
1275
-** --undo Diff against the "undo" buffer
1339
+** --undo Use the undo buffer as the baseline
12761340
** --unified Unified diff
12771341
** -v|--verbose Output complete text of added or deleted files
12781342
** -h|--versions Show compared versions in the diff header
12791343
** --webpage Format output as a stand-alone HTML webpage
12801344
** -W|--width N Width of lines in side-by-side diff
@@ -1287,10 +1351,11 @@
12871351
const char *zCheckin; /* Check-in version number */
12881352
const char *zBranch; /* Branch to diff */
12891353
int againstUndo = 0; /* Diff against files in the undo buffer */
12901354
FileDirList *pFileDir = 0; /* Restrict the diff to these files */
12911355
DiffConfig DCfg; /* Diff configuration object */
1356
+ int bFromIsDir = 0; /* True if zFrom is a directory name */
12921357
12931358
if( find_option("tk",0,0)!=0 || has_option("tclsh") ){
12941359
diff_tk("diff", 2);
12951360
return;
12961361
}
@@ -1298,11 +1363,11 @@
12981363
zFrom = find_option("from", "r", 1);
12991364
zTo = find_option("to", 0, 1);
13001365
zCheckin = find_option("checkin", "ci", 1);
13011366
zBranch = find_option("branch", 0, 1);
13021367
againstUndo = find_option("undo",0,0)!=0;
1303
- if( againstUndo && ( zFrom!=0 || zTo!=0 || zCheckin!=0 || zBranch!=0) ){
1368
+ if( againstUndo && (zFrom!=0 || zTo!=0 || zCheckin!=0 || zBranch!=0) ){
13041369
fossil_fatal("cannot use --undo together with --from, --to, --checkin,"
13051370
" or --branch");
13061371
}
13071372
if( zBranch ){
13081373
if( zTo || zFrom || zCheckin ){
@@ -1309,14 +1374,13 @@
13091374
fossil_fatal("cannot use --from, --to, or --checkin with --branch");
13101375
}
13111376
zTo = zBranch;
13121377
zFrom = mprintf("root:%s", zBranch);
13131378
}
1314
- if( zCheckin!=0 && ( zFrom!=0 || zTo!=0 ) ){
1379
+ if( zCheckin!=0 && (zFrom!=0 || zTo!=0) ){
13151380
fossil_fatal("cannot use --checkin together with --from or --to");
13161381
}
1317
- g.diffCnt[0] = g.diffCnt[1] = g.diffCnt[2] = 0;
13181382
if( 0==zCheckin ){
13191383
if( zTo==0 || againstUndo ){
13201384
db_must_be_within_tree();
13211385
}else if( zFrom==0 ){
13221386
fossil_fatal("must use --from if --to is present");
@@ -1324,13 +1388,23 @@
13241388
db_find_and_open_repository(0, 0);
13251389
}
13261390
}else{
13271391
db_find_and_open_repository(0, 0);
13281392
}
1329
- diff_options(&DCfg, isGDiff, 0);
13301393
determine_exec_relative_option(1);
1394
+ if( zFrom!=file_tail(zFrom)
1395
+ && file_isdir(zFrom, ExtFILE)==1
1396
+ && !db_exists("SELECT 1 FROM tag WHERE tagname='sym-%q'", zFrom)
1397
+ ){
1398
+ bFromIsDir = 1;
1399
+ if( zTo ){
1400
+ fossil_fatal("cannot use --to together with \"--from PATH\"");
1401
+ }
1402
+ }
1403
+ diff_options(&DCfg, isGDiff, 0);
13311404
verify_all_options();
1405
+ g.diffCnt[0] = g.diffCnt[1] = g.diffCnt[2] = 0;
13321406
if( g.argc>=3 ){
13331407
int i;
13341408
Blob fname;
13351409
pFileDir = fossil_malloc( sizeof(*pFileDir) * (g.argc-1) );
13361410
memset(pFileDir, 0, sizeof(*pFileDir) * (g.argc-1));
@@ -1357,18 +1431,20 @@
13571431
if( zFrom==0 ){
13581432
fossil_fatal("check-in %s has no parent", zTo);
13591433
}
13601434
}
13611435
diff_begin(&DCfg);
1362
- if( againstUndo ){
1436
+ if( bFromIsDir ){
1437
+ diff_externbase_to_checkout(zFrom, &DCfg, pFileDir);
1438
+ }else if( againstUndo ){
13631439
if( db_lget_int("undo_available",0)==0 ){
13641440
fossil_print("No undo or redo is available\n");
13651441
return;
13661442
}
1367
- diff_against_undo(&DCfg, pFileDir);
1443
+ diff_undo_to_checkout(&DCfg, pFileDir);
13681444
}else if( zTo==0 ){
1369
- diff_against_disk(zFrom, &DCfg, pFileDir, 0);
1445
+ diff_version_to_checkout(zFrom, &DCfg, pFileDir, 0);
13701446
}else{
13711447
diff_two_versions(zFrom, zTo, &DCfg, pFileDir);
13721448
}
13731449
if( pFileDir ){
13741450
int i;
13751451
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -249,19 +249,19 @@
249 @ margin: 0 0 0 0;
250 @ line-height: inherit;
251 @ font-size: inherit;
252 @ }
253 @ td.diffln {
254 @ width: 1px;
255 @ text-align: right;
256 @ padding: 0 1em 0 0;
257 @ }
258 @ td.difflne {
259 @ padding-bottom: 0.4em;
260 @ }
261 @ td.diffsep {
262 @ width: 1px;
263 @ padding: 0 0.3em 0 1em;
264 @ line-height: inherit;
265 @ font-size: inherit;
266 @ }
267 @ td.diffsep pre {
@@ -379,19 +379,19 @@
379 @ margin: 0 0 0 0;
380 @ line-height: inherit;
381 @ font-size: inherit;
382 @ }
383 @ td.diffln {
384 @ width: 1px;
385 @ text-align: right;
386 @ padding: 0 1em 0 0;
387 @ }
388 @ td.difflne {
389 @ padding-bottom: 0.4em;
390 @ }
391 @ td.diffsep {
392 @ width: 1px;
393 @ padding: 0 0.3em 0 1em;
394 @ line-height: inherit;
395 @ font-size: inherit;
396 @ }
397 @ td.diffsep pre {
@@ -784,26 +784,27 @@
784 blob_reset(&file);
785 return rc;
786 }
787
788 /*
789 ** Run a diff between the version zFrom and files on disk. zFrom might
790 ** be NULL which means to simply show the difference between the edited
791 ** files on disk and the check-out on which they are based.
 
792 **
793 ** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the
794 ** command zDiffCmd to do the diffing.
795 **
796 ** When using an external diff program, zBinGlob contains the GLOB patterns
797 ** for file names to treat as binary. If fIncludeBinary is zero, these files
798 ** will be skipped in addition to files that may contain binary content.
799 */
800 void diff_against_disk(
801 const char *zFrom, /* Version to difference from */
802 DiffConfig *pCfg, /* Flags controlling diff output */
803 FileDirList *pFileDir, /* Which files to diff */
804 Blob *pOut /* Blob to output diff instead of stdout */
805 ){
806 int vid;
807 Blob sql;
808 Stmt q;
809 int asNewFile; /* Treat non-existant files as empty files */
@@ -928,20 +929,20 @@
928 db_finalize(&q);
929 db_end_transaction(1); /* ROLLBACK */
930 }
931
932 /*
933 ** Run a diff between the undo buffer and files on disk.
934 **
935 ** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the
936 ** command zDiffCmd to do the diffing.
937 **
938 ** When using an external diff program, zBinGlob contains the GLOB patterns
939 ** for file names to treat as binary. If fIncludeBinary is zero, these files
940 ** will be skipped in addition to files that may contain binary content.
941 */
942 static void diff_against_undo(
943 DiffConfig *pCfg, /* Flags controlling diff output */
944 FileDirList *pFileDir /* List of files and directories to diff */
945 ){
946 Stmt q;
947 Blob content;
@@ -1088,10 +1089,67 @@
1088 }
1089 }
1090 manifest_destroy(pFrom);
1091 manifest_destroy(pTo);
1092 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1093
1094 /*
1095 ** Return the name of the external diff command, or return NULL if
1096 ** no external diff command is defined.
1097 */
@@ -1224,10 +1282,14 @@
1224 ** option specifies the check-in from which the second version of the file
1225 ** or files is taken. If there is no "--to" option then the (possibly edited)
1226 ** files in the current check-out are used. The "--checkin VERSION" option
1227 ** shows the changes made by check-in VERSION relative to its primary parent.
1228 ** The "--branch BRANCHNAME" shows all the changes on the branch BRANCHNAME.
 
 
 
 
1229 **
1230 ** The "-i" command-line option forces the use of Fossil's own internal
1231 ** diff logic rather than any external diff program that might be configured
1232 ** using the "setting" command. If no external diff program is configured,
1233 ** then the "-i" option is a no-op. The "-i" option converts "gdiff" into
@@ -1256,11 +1318,13 @@
1256 ** with negative N meaning show all content
1257 ** --dark Use dark mode for the Tcl/Tk-based GUI and HTML
1258 ** --diff-binary BOOL Include binary files with external commands
1259 ** --exec-abs-paths Force absolute path names on external commands
1260 ** --exec-rel-paths Force relative path names on external commands
1261 ** -r|--from VERSION Select VERSION as source for the diff
 
 
1262 ** -w|--ignore-all-space Ignore white space when comparing lines
1263 ** -i|--internal Use internal diff logic
1264 ** --invert Invert the diff
1265 ** --json Output formatted as JSON
1266 ** -n|--linenum Show line numbers
@@ -1270,11 +1334,11 @@
1270 ** --strip-trailing-cr Strip trailing CR
1271 ** --tcl Tcl-formatted output used internally by --tk
1272 ** --tclsh PATH Tcl/Tk shell used for --tk (default: "tclsh")
1273 ** --tk Launch a Tcl/Tk GUI for display
1274 ** --to VERSION Select VERSION as target for the diff
1275 ** --undo Diff against the "undo" buffer
1276 ** --unified Unified diff
1277 ** -v|--verbose Output complete text of added or deleted files
1278 ** -h|--versions Show compared versions in the diff header
1279 ** --webpage Format output as a stand-alone HTML webpage
1280 ** -W|--width N Width of lines in side-by-side diff
@@ -1287,10 +1351,11 @@
1287 const char *zCheckin; /* Check-in version number */
1288 const char *zBranch; /* Branch to diff */
1289 int againstUndo = 0; /* Diff against files in the undo buffer */
1290 FileDirList *pFileDir = 0; /* Restrict the diff to these files */
1291 DiffConfig DCfg; /* Diff configuration object */
 
1292
1293 if( find_option("tk",0,0)!=0 || has_option("tclsh") ){
1294 diff_tk("diff", 2);
1295 return;
1296 }
@@ -1298,11 +1363,11 @@
1298 zFrom = find_option("from", "r", 1);
1299 zTo = find_option("to", 0, 1);
1300 zCheckin = find_option("checkin", "ci", 1);
1301 zBranch = find_option("branch", 0, 1);
1302 againstUndo = find_option("undo",0,0)!=0;
1303 if( againstUndo && ( zFrom!=0 || zTo!=0 || zCheckin!=0 || zBranch!=0) ){
1304 fossil_fatal("cannot use --undo together with --from, --to, --checkin,"
1305 " or --branch");
1306 }
1307 if( zBranch ){
1308 if( zTo || zFrom || zCheckin ){
@@ -1309,14 +1374,13 @@
1309 fossil_fatal("cannot use --from, --to, or --checkin with --branch");
1310 }
1311 zTo = zBranch;
1312 zFrom = mprintf("root:%s", zBranch);
1313 }
1314 if( zCheckin!=0 && ( zFrom!=0 || zTo!=0 ) ){
1315 fossil_fatal("cannot use --checkin together with --from or --to");
1316 }
1317 g.diffCnt[0] = g.diffCnt[1] = g.diffCnt[2] = 0;
1318 if( 0==zCheckin ){
1319 if( zTo==0 || againstUndo ){
1320 db_must_be_within_tree();
1321 }else if( zFrom==0 ){
1322 fossil_fatal("must use --from if --to is present");
@@ -1324,13 +1388,23 @@
1324 db_find_and_open_repository(0, 0);
1325 }
1326 }else{
1327 db_find_and_open_repository(0, 0);
1328 }
1329 diff_options(&DCfg, isGDiff, 0);
1330 determine_exec_relative_option(1);
 
 
 
 
 
 
 
 
 
 
1331 verify_all_options();
 
1332 if( g.argc>=3 ){
1333 int i;
1334 Blob fname;
1335 pFileDir = fossil_malloc( sizeof(*pFileDir) * (g.argc-1) );
1336 memset(pFileDir, 0, sizeof(*pFileDir) * (g.argc-1));
@@ -1357,18 +1431,20 @@
1357 if( zFrom==0 ){
1358 fossil_fatal("check-in %s has no parent", zTo);
1359 }
1360 }
1361 diff_begin(&DCfg);
1362 if( againstUndo ){
 
 
1363 if( db_lget_int("undo_available",0)==0 ){
1364 fossil_print("No undo or redo is available\n");
1365 return;
1366 }
1367 diff_against_undo(&DCfg, pFileDir);
1368 }else if( zTo==0 ){
1369 diff_against_disk(zFrom, &DCfg, pFileDir, 0);
1370 }else{
1371 diff_two_versions(zFrom, zTo, &DCfg, pFileDir);
1372 }
1373 if( pFileDir ){
1374 int i;
1375
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -249,19 +249,19 @@
249 @ margin: 0 0 0 0;
250 @ line-height: inherit;
251 @ font-size: inherit;
252 @ }
253 @ td.diffln {
254 @ width: fit-content;
255 @ text-align: right;
256 @ padding: 0 1em 0 0;
257 @ }
258 @ td.difflne {
259 @ padding-bottom: 0.4em;
260 @ }
261 @ td.diffsep {
262 @ width: fit-content;
263 @ padding: 0 0.3em 0 1em;
264 @ line-height: inherit;
265 @ font-size: inherit;
266 @ }
267 @ td.diffsep pre {
@@ -379,19 +379,19 @@
379 @ margin: 0 0 0 0;
380 @ line-height: inherit;
381 @ font-size: inherit;
382 @ }
383 @ td.diffln {
384 @ width: fit-content;
385 @ text-align: right;
386 @ padding: 0 1em 0 0;
387 @ }
388 @ td.difflne {
389 @ padding-bottom: 0.4em;
390 @ }
391 @ td.diffsep {
392 @ width: fit-content;
393 @ padding: 0 0.3em 0 1em;
394 @ line-height: inherit;
395 @ font-size: inherit;
396 @ }
397 @ td.diffsep pre {
@@ -784,26 +784,27 @@
784 blob_reset(&file);
785 return rc;
786 }
787
788 /*
789 ** Run a diff between the version zFrom and files on disk in the current
790 ** working checkout. zFrom might be NULL which means to simply show the
791 ** difference between the edited files on disk and the check-out on which
792 ** they are based.
793 **
794 ** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the
795 ** command zDiffCmd to do the diffing.
796 **
797 ** When using an external diff program, zBinGlob contains the GLOB patterns
798 ** for file names to treat as binary. If fIncludeBinary is zero, these files
799 ** will be skipped in addition to files that may contain binary content.
800 */
801 void diff_version_to_checkout(
802 const char *zFrom, /* Version to difference from */
803 DiffConfig *pCfg, /* Flags controlling diff output */
804 FileDirList *pFileDir, /* Which files to diff */
805 Blob *pOut /* Blob to output diff instead of stdout */
806 ){
807 int vid;
808 Blob sql;
809 Stmt q;
810 int asNewFile; /* Treat non-existant files as empty files */
@@ -928,20 +929,20 @@
929 db_finalize(&q);
930 db_end_transaction(1); /* ROLLBACK */
931 }
932
933 /*
934 ** Run a diff from the undo buffer to files on disk.
935 **
936 ** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the
937 ** command zDiffCmd to do the diffing.
938 **
939 ** When using an external diff program, zBinGlob contains the GLOB patterns
940 ** for file names to treat as binary. If fIncludeBinary is zero, these files
941 ** will be skipped in addition to files that may contain binary content.
942 */
943 static void diff_undo_to_checkout(
944 DiffConfig *pCfg, /* Flags controlling diff output */
945 FileDirList *pFileDir /* List of files and directories to diff */
946 ){
947 Stmt q;
948 Blob content;
@@ -1088,10 +1089,67 @@
1089 }
1090 }
1091 manifest_destroy(pFrom);
1092 manifest_destroy(pTo);
1093 }
1094
1095 /*
1096 ** Compute the difference from an external tree of files to the current
1097 ** working checkout with its edits.
1098 **
1099 ** To put it another way: Every managed file in the current working
1100 ** checkout is compared to the file with same name under zExternBase. The
1101 ** zExternBase files are on the left and the files in the current working
1102 ** directory are on the right.
1103 */
1104 void diff_externbase_to_checkout(
1105 const char *zExternBase, /* Remote tree to use as the baseline */
1106 DiffConfig *pCfg, /* Diff settings */
1107 FileDirList *pFileDir /* Only look at these files */
1108 ){
1109 int vid;
1110 Stmt q;
1111
1112 vid = db_lget_int("checkout",0);
1113 if( file_isdir(zExternBase, ExtFILE)!=1 ){
1114 fossil_fatal("\"%s\" is not a directory", zExternBase);
1115 }
1116 db_prepare(&q,
1117 "SELECT pathname FROM vfile WHERE vid=%d ORDER BY pathname",
1118 vid
1119 );
1120 while( db_step(&q)==SQLITE_ROW ){
1121 const char *zFile; /* Name of file in the repository */
1122 char *zLhs; /* Full name of left-hand side file */
1123 char *zRhs; /* Full name of right-hand side file */
1124 Blob rhs; /* Full text of RHS */
1125 Blob lhs; /* Full text of LHS */
1126
1127 zFile = db_column_text(&q,0);
1128 if( !file_dir_match(pFileDir, zFile) ) continue;
1129 zLhs = mprintf("%s/%s", zExternBase, zFile);
1130 zRhs = mprintf("%s%s", g.zLocalRoot, zFile);
1131 if( file_size(zLhs, ExtFILE)<0 ){
1132 blob_zero(&lhs);
1133 }else{
1134 blob_read_from_file(&lhs, zLhs, ExtFILE);
1135 }
1136 blob_read_from_file(&rhs, zRhs, ExtFILE);
1137 if( blob_size(&lhs)!=blob_size(&rhs)
1138 || memcmp(blob_buffer(&lhs), blob_buffer(&rhs), blob_size(&lhs))!=0
1139 ){
1140 diff_print_index(zFile, pCfg, 0);
1141 diff_file_mem(&lhs, &rhs, zFile, pCfg);
1142 }
1143 blob_reset(&lhs);
1144 blob_reset(&rhs);
1145 fossil_free(zLhs);
1146 fossil_free(zRhs);
1147 }
1148 db_finalize(&q);
1149 }
1150
1151
1152 /*
1153 ** Return the name of the external diff command, or return NULL if
1154 ** no external diff command is defined.
1155 */
@@ -1224,10 +1282,14 @@
1282 ** option specifies the check-in from which the second version of the file
1283 ** or files is taken. If there is no "--to" option then the (possibly edited)
1284 ** files in the current check-out are used. The "--checkin VERSION" option
1285 ** shows the changes made by check-in VERSION relative to its primary parent.
1286 ** The "--branch BRANCHNAME" shows all the changes on the branch BRANCHNAME.
1287 **
1288 ** With the "--from VERSION" option, if VERSION is actually a directory name
1289 ** (not a tag or check-in hash) then the files under that directory are used
1290 ** as the baseline for the diff.
1291 **
1292 ** The "-i" command-line option forces the use of Fossil's own internal
1293 ** diff logic rather than any external diff program that might be configured
1294 ** using the "setting" command. If no external diff program is configured,
1295 ** then the "-i" option is a no-op. The "-i" option converts "gdiff" into
@@ -1256,11 +1318,13 @@
1318 ** with negative N meaning show all content
1319 ** --dark Use dark mode for the Tcl/Tk-based GUI and HTML
1320 ** --diff-binary BOOL Include binary files with external commands
1321 ** --exec-abs-paths Force absolute path names on external commands
1322 ** --exec-rel-paths Force relative path names on external commands
1323 ** -r|--from VERSION Use VERSION as the baseline for the diff, or
1324 ** if VERSION is a directory name, use files in
1325 ** that directory as the baseline.
1326 ** -w|--ignore-all-space Ignore white space when comparing lines
1327 ** -i|--internal Use internal diff logic
1328 ** --invert Invert the diff
1329 ** --json Output formatted as JSON
1330 ** -n|--linenum Show line numbers
@@ -1270,11 +1334,11 @@
1334 ** --strip-trailing-cr Strip trailing CR
1335 ** --tcl Tcl-formatted output used internally by --tk
1336 ** --tclsh PATH Tcl/Tk shell used for --tk (default: "tclsh")
1337 ** --tk Launch a Tcl/Tk GUI for display
1338 ** --to VERSION Select VERSION as target for the diff
1339 ** --undo Use the undo buffer as the baseline
1340 ** --unified Unified diff
1341 ** -v|--verbose Output complete text of added or deleted files
1342 ** -h|--versions Show compared versions in the diff header
1343 ** --webpage Format output as a stand-alone HTML webpage
1344 ** -W|--width N Width of lines in side-by-side diff
@@ -1287,10 +1351,11 @@
1351 const char *zCheckin; /* Check-in version number */
1352 const char *zBranch; /* Branch to diff */
1353 int againstUndo = 0; /* Diff against files in the undo buffer */
1354 FileDirList *pFileDir = 0; /* Restrict the diff to these files */
1355 DiffConfig DCfg; /* Diff configuration object */
1356 int bFromIsDir = 0; /* True if zFrom is a directory name */
1357
1358 if( find_option("tk",0,0)!=0 || has_option("tclsh") ){
1359 diff_tk("diff", 2);
1360 return;
1361 }
@@ -1298,11 +1363,11 @@
1363 zFrom = find_option("from", "r", 1);
1364 zTo = find_option("to", 0, 1);
1365 zCheckin = find_option("checkin", "ci", 1);
1366 zBranch = find_option("branch", 0, 1);
1367 againstUndo = find_option("undo",0,0)!=0;
1368 if( againstUndo && (zFrom!=0 || zTo!=0 || zCheckin!=0 || zBranch!=0) ){
1369 fossil_fatal("cannot use --undo together with --from, --to, --checkin,"
1370 " or --branch");
1371 }
1372 if( zBranch ){
1373 if( zTo || zFrom || zCheckin ){
@@ -1309,14 +1374,13 @@
1374 fossil_fatal("cannot use --from, --to, or --checkin with --branch");
1375 }
1376 zTo = zBranch;
1377 zFrom = mprintf("root:%s", zBranch);
1378 }
1379 if( zCheckin!=0 && (zFrom!=0 || zTo!=0) ){
1380 fossil_fatal("cannot use --checkin together with --from or --to");
1381 }
 
1382 if( 0==zCheckin ){
1383 if( zTo==0 || againstUndo ){
1384 db_must_be_within_tree();
1385 }else if( zFrom==0 ){
1386 fossil_fatal("must use --from if --to is present");
@@ -1324,13 +1388,23 @@
1388 db_find_and_open_repository(0, 0);
1389 }
1390 }else{
1391 db_find_and_open_repository(0, 0);
1392 }
 
1393 determine_exec_relative_option(1);
1394 if( zFrom!=file_tail(zFrom)
1395 && file_isdir(zFrom, ExtFILE)==1
1396 && !db_exists("SELECT 1 FROM tag WHERE tagname='sym-%q'", zFrom)
1397 ){
1398 bFromIsDir = 1;
1399 if( zTo ){
1400 fossil_fatal("cannot use --to together with \"--from PATH\"");
1401 }
1402 }
1403 diff_options(&DCfg, isGDiff, 0);
1404 verify_all_options();
1405 g.diffCnt[0] = g.diffCnt[1] = g.diffCnt[2] = 0;
1406 if( g.argc>=3 ){
1407 int i;
1408 Blob fname;
1409 pFileDir = fossil_malloc( sizeof(*pFileDir) * (g.argc-1) );
1410 memset(pFileDir, 0, sizeof(*pFileDir) * (g.argc-1));
@@ -1357,18 +1431,20 @@
1431 if( zFrom==0 ){
1432 fossil_fatal("check-in %s has no parent", zTo);
1433 }
1434 }
1435 diff_begin(&DCfg);
1436 if( bFromIsDir ){
1437 diff_externbase_to_checkout(zFrom, &DCfg, pFileDir);
1438 }else if( againstUndo ){
1439 if( db_lget_int("undo_available",0)==0 ){
1440 fossil_print("No undo or redo is available\n");
1441 return;
1442 }
1443 diff_undo_to_checkout(&DCfg, pFileDir);
1444 }else if( zTo==0 ){
1445 diff_version_to_checkout(zFrom, &DCfg, pFileDir, 0);
1446 }else{
1447 diff_two_versions(zFrom, zTo, &DCfg, pFileDir);
1448 }
1449 if( pFileDir ){
1450 int i;
1451
+26 -1
--- src/dispatch.c
+++ src/dispatch.c
@@ -1307,17 +1307,42 @@
13071307
}
13081308
13091309
/*
13101310
** Return a pointer to the setting information array.
13111311
**
1312
-** This routine provides access to the aSetting2[] array which is created
1312
+** This routine provides access to the aSetting[] array which is created
13131313
** by the mkindex utility program and included with <page_index.h>.
13141314
*/
13151315
const Setting *setting_info(int *pnCount){
13161316
if( pnCount ) *pnCount = (int)(sizeof(aSetting)/sizeof(aSetting[0])) - 1;
13171317
return aSetting;
13181318
}
1319
+
1320
+/*
1321
+** Return a pointer to a specific Setting entry for the setting named
1322
+** in the argument. Or return NULL if no such setting exists.
1323
+**
1324
+** The pointer returned points into the middle of the global aSetting[]
1325
+** array that is generated by mkindex. Use setting_info() to fetch the
1326
+** whole array. Use this routine to fetch a specific entry.
1327
+*/
1328
+const Setting *setting_find(const char *zName){
1329
+ int iFirst = 0;
1330
+ int iLast = ArraySize(aSetting)-1;
1331
+ while( iFirst<=iLast ){
1332
+ int iCur = (iFirst+iLast)/2;
1333
+ int c = strcmp(aSetting[iCur].name, zName);
1334
+ if( c<0 ){
1335
+ iFirst = iCur+1;
1336
+ }else if( c>0 ){
1337
+ iLast = iCur-1;
1338
+ }else{
1339
+ return &aSetting[iCur];
1340
+ }
1341
+ }
1342
+ return 0;
1343
+}
13191344
13201345
/*****************************************************************************
13211346
** A virtual table for accessing the information in aCommand[], and
13221347
** especially the help-text
13231348
*/
13241349
--- src/dispatch.c
+++ src/dispatch.c
@@ -1307,17 +1307,42 @@
1307 }
1308
1309 /*
1310 ** Return a pointer to the setting information array.
1311 **
1312 ** This routine provides access to the aSetting2[] array which is created
1313 ** by the mkindex utility program and included with <page_index.h>.
1314 */
1315 const Setting *setting_info(int *pnCount){
1316 if( pnCount ) *pnCount = (int)(sizeof(aSetting)/sizeof(aSetting[0])) - 1;
1317 return aSetting;
1318 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1319
1320 /*****************************************************************************
1321 ** A virtual table for accessing the information in aCommand[], and
1322 ** especially the help-text
1323 */
1324
--- src/dispatch.c
+++ src/dispatch.c
@@ -1307,17 +1307,42 @@
1307 }
1308
1309 /*
1310 ** Return a pointer to the setting information array.
1311 **
1312 ** This routine provides access to the aSetting[] array which is created
1313 ** by the mkindex utility program and included with <page_index.h>.
1314 */
1315 const Setting *setting_info(int *pnCount){
1316 if( pnCount ) *pnCount = (int)(sizeof(aSetting)/sizeof(aSetting[0])) - 1;
1317 return aSetting;
1318 }
1319
1320 /*
1321 ** Return a pointer to a specific Setting entry for the setting named
1322 ** in the argument. Or return NULL if no such setting exists.
1323 **
1324 ** The pointer returned points into the middle of the global aSetting[]
1325 ** array that is generated by mkindex. Use setting_info() to fetch the
1326 ** whole array. Use this routine to fetch a specific entry.
1327 */
1328 const Setting *setting_find(const char *zName){
1329 int iFirst = 0;
1330 int iLast = ArraySize(aSetting)-1;
1331 while( iFirst<=iLast ){
1332 int iCur = (iFirst+iLast)/2;
1333 int c = strcmp(aSetting[iCur].name, zName);
1334 if( c<0 ){
1335 iFirst = iCur+1;
1336 }else if( c>0 ){
1337 iLast = iCur-1;
1338 }else{
1339 return &aSetting[iCur];
1340 }
1341 }
1342 return 0;
1343 }
1344
1345 /*****************************************************************************
1346 ** A virtual table for accessing the information in aCommand[], and
1347 ** especially the help-text
1348 */
1349
+1 -1
--- src/event.c
+++ src/event.c
@@ -229,11 +229,11 @@
229229
}
230230
zFullId = db_text(0, "SELECT SUBSTR(tagname,7)"
231231
" FROM tag"
232232
" WHERE tagname GLOB 'event-%q*'",
233233
zId);
234
- attachment_list(zFullId, "<hr><h2>Attachments:</h2><ul>");
234
+ attachment_list(zFullId, "<h2>Attachments:</h2>", 1);
235235
document_emit_js();
236236
style_finish_page();
237237
manifest_destroy(pTNote);
238238
}
239239
240240
--- src/event.c
+++ src/event.c
@@ -229,11 +229,11 @@
229 }
230 zFullId = db_text(0, "SELECT SUBSTR(tagname,7)"
231 " FROM tag"
232 " WHERE tagname GLOB 'event-%q*'",
233 zId);
234 attachment_list(zFullId, "<hr><h2>Attachments:</h2><ul>");
235 document_emit_js();
236 style_finish_page();
237 manifest_destroy(pTNote);
238 }
239
240
--- src/event.c
+++ src/event.c
@@ -229,11 +229,11 @@
229 }
230 zFullId = db_text(0, "SELECT SUBSTR(tagname,7)"
231 " FROM tag"
232 " WHERE tagname GLOB 'event-%q*'",
233 zId);
234 attachment_list(zFullId, "<h2>Attachments:</h2>", 1);
235 document_emit_js();
236 style_finish_page();
237 manifest_destroy(pTNote);
238 }
239
240
+94 -8
--- src/file.c
+++ src/file.c
@@ -1302,25 +1302,37 @@
13021302
}
13031303
}
13041304
13051305
/*
13061306
** Compute a canonical pathname for a file or directory.
1307
-** Make the name absolute if it is relative.
1308
-** Remove redundant / characters
1309
-** Remove all /./ path elements.
1310
-** Convert /A/../ to just /
1307
+**
1308
+** * Make the name absolute if it is relative.
1309
+** * Remove redundant / characters
1310
+** * Remove all /./ path elements.
1311
+** * Convert /A/../ to just /
1312
+** * On windows, add the drive letter prefix.
1313
+**
13111314
** If the slash parameter is non-zero, the trailing slash, if any,
13121315
** is retained.
13131316
**
13141317
** See also: file_canonical_name_dup()
13151318
*/
13161319
void file_canonical_name(const char *zOrigName, Blob *pOut, int slash){
1320
+ char zPwd[2000];
13171321
blob_zero(pOut);
13181322
if( file_is_absolute_path(zOrigName) ){
1319
- blob_appendf(pOut, "%/", zOrigName);
1323
+#if defined(_WIN32)
1324
+ if( fossil_isdirsep(zOrigName[0]) ){
1325
+ /* Add the drive letter to the full pathname */
1326
+ file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName));
1327
+ blob_appendf(pOut, "%.2s%/", zPwd, zOrigName);
1328
+ }else
1329
+#endif
1330
+ {
1331
+ blob_appendf(pOut, "%/", zOrigName);
1332
+ }
13201333
}else{
1321
- char zPwd[2000];
13221334
file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName));
13231335
if( zPwd[0]=='/' && strlen(zPwd)==1 ){
13241336
/* when on '/', don't add an extra '/' */
13251337
if( zOrigName[0]=='.' && strlen(zOrigName)==1 ){
13261338
/* '.' when on '/' mean '/' */
@@ -1644,10 +1656,13 @@
16441656
g.allowSymlinks = !is_false(zAllow);
16451657
}
16461658
if( zRoot==0 ) zRoot = g.zLocalRoot==0 ? "" : g.zLocalRoot;
16471659
fossil_print("db_allow_symlinks() = %d\n", db_allow_symlinks());
16481660
fossil_print("local-root = [%s]\n", zRoot);
1661
+ if( g.db==0 ) sqlite3_open(":memory:", &g.db);
1662
+ sqlite3_create_function(g.db, "inode", 1, SQLITE_UTF8, 0,
1663
+ file_inode_sql_func, 0, 0);
16491664
for(i=2; i<g.argc; i++){
16501665
char *z;
16511666
emitFileStat(g.argv[i], slashFlag, resetFlag);
16521667
z = file_canonical_name_dup(g.argv[i]);
16531668
fossil_print(" file_canonical_name = %s\n", z);
@@ -1657,10 +1672,13 @@
16571672
}else{
16581673
int n = file_nondir_objects_on_path(zRoot, z);
16591674
fossil_print("%.*s\n", n, z);
16601675
}
16611676
fossil_free(z);
1677
+ z = db_text(0, "SELECT inode(%Q)", g.argv[i]);
1678
+ fossil_print(" file_inode_sql_func = \"%s\"\n", z);
1679
+ fossil_free(z);
16621680
}
16631681
}
16641682
16651683
/*
16661684
** COMMAND: test-canonical-name
@@ -1699,13 +1717,15 @@
16991717
** Canonical names are full pathnames using "/" not "\" and which
17001718
** contain no "/./" or "/../" terms.
17011719
*/
17021720
int file_is_canonical(const char *z){
17031721
int i;
1704
- if( z[0]!='/'
1722
+ if(
17051723
#if defined(_WIN32) || defined(__CYGWIN__)
1706
- && (!fossil_isupper(z[0]) || z[1]!=':' || z[2]!='/')
1724
+ !fossil_isupper(z[0]) || z[1]!=':' || !fossil_isdirsep(z[2])
1725
+#else
1726
+ z[0]!='/'
17071727
#endif
17081728
) return 0;
17091729
17101730
for(i=0; z[i]; i++){
17111731
if( z[i]=='\\' ) return 0;
@@ -2953,18 +2973,84 @@
29532973
** Returns 1 if the given directory contains a file named .fslckout, 2
29542974
** if it contains a file named _FOSSIL_, else returns 0.
29552975
*/
29562976
int dir_has_ckout_db(const char *zDir){
29572977
int rc = 0;
2978
+ i64 sz;
29582979
char * zCkoutDb = mprintf("%//.fslckout", zDir);
29592980
if(file_isfile(zCkoutDb, ExtFILE)){
29602981
rc = 1;
29612982
}else{
29622983
fossil_free(zCkoutDb);
29632984
zCkoutDb = mprintf("%//_FOSSIL_", zDir);
29642985
if(file_isfile(zCkoutDb, ExtFILE)){
29652986
rc = 2;
29662987
}
2988
+ }
2989
+ if( rc && ((sz = file_size(zCkoutDb, ExtFILE))<1024 || (sz%512)!=0) ){
2990
+ rc = 0;
29672991
}
29682992
fossil_free(zCkoutDb);
29692993
return rc;
29702994
}
2995
+
2996
+/*
2997
+** This is the implementation of inode(FILENAME) SQL function.
2998
+**
2999
+** dev_inode(FILENAME) returns a string. If FILENAME exists and is
3000
+** a regular file, then the return string is of the form:
3001
+**
3002
+** DEV/INODE
3003
+**
3004
+** Where DEV and INODE are the device number and inode number for
3005
+** the file. On Windows, the volume serial number (DEV) and file
3006
+** identifier (INODE) are used to compute the value, see comments
3007
+** on the win32_file_id() function.
3008
+**
3009
+** If FILENAME does not exist, then the return is an empty string.
3010
+**
3011
+** The value of inode() can be used to eliminate files from a list
3012
+** that have duplicates because they have differing names due to links.
3013
+**
3014
+** Code that wants to use this SQL function needs to first register
3015
+** it using a call such as the following:
3016
+**
3017
+** sqlite3_create_function(g.db, "inode", 1, SQLITE_UTF8, 0,
3018
+** file_inode_sql_func, 0, 0);
3019
+*/
3020
+void file_inode_sql_func(
3021
+ sqlite3_context *context,
3022
+ int argc,
3023
+ sqlite3_value **argv
3024
+){
3025
+ const char *zFilename;
3026
+ assert( argc==1 );
3027
+ zFilename = (const char*)sqlite3_value_text(argv[0]);
3028
+ if( zFilename==0 || zFilename[0]==0 || file_access(zFilename,F_OK) ){
3029
+ sqlite3_result_text(context, "", 0, SQLITE_STATIC);
3030
+ return;
3031
+ }
3032
+#if defined(_WIN32)
3033
+ {
3034
+ char *zFileId = win32_file_id(zFilename);
3035
+ if( zFileId ){
3036
+ sqlite3_result_text(context, zFileId, -1, fossil_free);
3037
+ }else{
3038
+ sqlite3_result_text(context, "", 0, SQLITE_STATIC);
3039
+ }
3040
+ }
3041
+#else
3042
+ {
3043
+ struct stat buf;
3044
+ int rc;
3045
+ memset(&buf, 0, sizeof(buf));
3046
+ rc = stat(zFilename, &buf);
3047
+ if( rc ){
3048
+ sqlite3_result_text(context, "", 0, SQLITE_STATIC);
3049
+ }else{
3050
+ sqlite3_result_text(context,
3051
+ mprintf("%lld/%lld", (i64)buf.st_dev, (i64)buf.st_ino), -1,
3052
+ fossil_free);
3053
+ }
3054
+ }
3055
+#endif
3056
+}
29713057
--- src/file.c
+++ src/file.c
@@ -1302,25 +1302,37 @@
1302 }
1303 }
1304
1305 /*
1306 ** Compute a canonical pathname for a file or directory.
1307 ** Make the name absolute if it is relative.
1308 ** Remove redundant / characters
1309 ** Remove all /./ path elements.
1310 ** Convert /A/../ to just /
 
 
 
1311 ** If the slash parameter is non-zero, the trailing slash, if any,
1312 ** is retained.
1313 **
1314 ** See also: file_canonical_name_dup()
1315 */
1316 void file_canonical_name(const char *zOrigName, Blob *pOut, int slash){
 
1317 blob_zero(pOut);
1318 if( file_is_absolute_path(zOrigName) ){
1319 blob_appendf(pOut, "%/", zOrigName);
 
 
 
 
 
 
 
 
 
1320 }else{
1321 char zPwd[2000];
1322 file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName));
1323 if( zPwd[0]=='/' && strlen(zPwd)==1 ){
1324 /* when on '/', don't add an extra '/' */
1325 if( zOrigName[0]=='.' && strlen(zOrigName)==1 ){
1326 /* '.' when on '/' mean '/' */
@@ -1644,10 +1656,13 @@
1644 g.allowSymlinks = !is_false(zAllow);
1645 }
1646 if( zRoot==0 ) zRoot = g.zLocalRoot==0 ? "" : g.zLocalRoot;
1647 fossil_print("db_allow_symlinks() = %d\n", db_allow_symlinks());
1648 fossil_print("local-root = [%s]\n", zRoot);
 
 
 
1649 for(i=2; i<g.argc; i++){
1650 char *z;
1651 emitFileStat(g.argv[i], slashFlag, resetFlag);
1652 z = file_canonical_name_dup(g.argv[i]);
1653 fossil_print(" file_canonical_name = %s\n", z);
@@ -1657,10 +1672,13 @@
1657 }else{
1658 int n = file_nondir_objects_on_path(zRoot, z);
1659 fossil_print("%.*s\n", n, z);
1660 }
1661 fossil_free(z);
 
 
 
1662 }
1663 }
1664
1665 /*
1666 ** COMMAND: test-canonical-name
@@ -1699,13 +1717,15 @@
1699 ** Canonical names are full pathnames using "/" not "\" and which
1700 ** contain no "/./" or "/../" terms.
1701 */
1702 int file_is_canonical(const char *z){
1703 int i;
1704 if( z[0]!='/'
1705 #if defined(_WIN32) || defined(__CYGWIN__)
1706 && (!fossil_isupper(z[0]) || z[1]!=':' || z[2]!='/')
 
 
1707 #endif
1708 ) return 0;
1709
1710 for(i=0; z[i]; i++){
1711 if( z[i]=='\\' ) return 0;
@@ -2953,18 +2973,84 @@
2953 ** Returns 1 if the given directory contains a file named .fslckout, 2
2954 ** if it contains a file named _FOSSIL_, else returns 0.
2955 */
2956 int dir_has_ckout_db(const char *zDir){
2957 int rc = 0;
 
2958 char * zCkoutDb = mprintf("%//.fslckout", zDir);
2959 if(file_isfile(zCkoutDb, ExtFILE)){
2960 rc = 1;
2961 }else{
2962 fossil_free(zCkoutDb);
2963 zCkoutDb = mprintf("%//_FOSSIL_", zDir);
2964 if(file_isfile(zCkoutDb, ExtFILE)){
2965 rc = 2;
2966 }
 
 
 
2967 }
2968 fossil_free(zCkoutDb);
2969 return rc;
2970 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2971
--- src/file.c
+++ src/file.c
@@ -1302,25 +1302,37 @@
1302 }
1303 }
1304
1305 /*
1306 ** Compute a canonical pathname for a file or directory.
1307 **
1308 ** * Make the name absolute if it is relative.
1309 ** * Remove redundant / characters
1310 ** * Remove all /./ path elements.
1311 ** * Convert /A/../ to just /
1312 ** * On windows, add the drive letter prefix.
1313 **
1314 ** If the slash parameter is non-zero, the trailing slash, if any,
1315 ** is retained.
1316 **
1317 ** See also: file_canonical_name_dup()
1318 */
1319 void file_canonical_name(const char *zOrigName, Blob *pOut, int slash){
1320 char zPwd[2000];
1321 blob_zero(pOut);
1322 if( file_is_absolute_path(zOrigName) ){
1323 #if defined(_WIN32)
1324 if( fossil_isdirsep(zOrigName[0]) ){
1325 /* Add the drive letter to the full pathname */
1326 file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName));
1327 blob_appendf(pOut, "%.2s%/", zPwd, zOrigName);
1328 }else
1329 #endif
1330 {
1331 blob_appendf(pOut, "%/", zOrigName);
1332 }
1333 }else{
 
1334 file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName));
1335 if( zPwd[0]=='/' && strlen(zPwd)==1 ){
1336 /* when on '/', don't add an extra '/' */
1337 if( zOrigName[0]=='.' && strlen(zOrigName)==1 ){
1338 /* '.' when on '/' mean '/' */
@@ -1644,10 +1656,13 @@
1656 g.allowSymlinks = !is_false(zAllow);
1657 }
1658 if( zRoot==0 ) zRoot = g.zLocalRoot==0 ? "" : g.zLocalRoot;
1659 fossil_print("db_allow_symlinks() = %d\n", db_allow_symlinks());
1660 fossil_print("local-root = [%s]\n", zRoot);
1661 if( g.db==0 ) sqlite3_open(":memory:", &g.db);
1662 sqlite3_create_function(g.db, "inode", 1, SQLITE_UTF8, 0,
1663 file_inode_sql_func, 0, 0);
1664 for(i=2; i<g.argc; i++){
1665 char *z;
1666 emitFileStat(g.argv[i], slashFlag, resetFlag);
1667 z = file_canonical_name_dup(g.argv[i]);
1668 fossil_print(" file_canonical_name = %s\n", z);
@@ -1657,10 +1672,13 @@
1672 }else{
1673 int n = file_nondir_objects_on_path(zRoot, z);
1674 fossil_print("%.*s\n", n, z);
1675 }
1676 fossil_free(z);
1677 z = db_text(0, "SELECT inode(%Q)", g.argv[i]);
1678 fossil_print(" file_inode_sql_func = \"%s\"\n", z);
1679 fossil_free(z);
1680 }
1681 }
1682
1683 /*
1684 ** COMMAND: test-canonical-name
@@ -1699,13 +1717,15 @@
1717 ** Canonical names are full pathnames using "/" not "\" and which
1718 ** contain no "/./" or "/../" terms.
1719 */
1720 int file_is_canonical(const char *z){
1721 int i;
1722 if(
1723 #if defined(_WIN32) || defined(__CYGWIN__)
1724 !fossil_isupper(z[0]) || z[1]!=':' || !fossil_isdirsep(z[2])
1725 #else
1726 z[0]!='/'
1727 #endif
1728 ) return 0;
1729
1730 for(i=0; z[i]; i++){
1731 if( z[i]=='\\' ) return 0;
@@ -2953,18 +2973,84 @@
2973 ** Returns 1 if the given directory contains a file named .fslckout, 2
2974 ** if it contains a file named _FOSSIL_, else returns 0.
2975 */
2976 int dir_has_ckout_db(const char *zDir){
2977 int rc = 0;
2978 i64 sz;
2979 char * zCkoutDb = mprintf("%//.fslckout", zDir);
2980 if(file_isfile(zCkoutDb, ExtFILE)){
2981 rc = 1;
2982 }else{
2983 fossil_free(zCkoutDb);
2984 zCkoutDb = mprintf("%//_FOSSIL_", zDir);
2985 if(file_isfile(zCkoutDb, ExtFILE)){
2986 rc = 2;
2987 }
2988 }
2989 if( rc && ((sz = file_size(zCkoutDb, ExtFILE))<1024 || (sz%512)!=0) ){
2990 rc = 0;
2991 }
2992 fossil_free(zCkoutDb);
2993 return rc;
2994 }
2995
2996 /*
2997 ** This is the implementation of inode(FILENAME) SQL function.
2998 **
2999 ** dev_inode(FILENAME) returns a string. If FILENAME exists and is
3000 ** a regular file, then the return string is of the form:
3001 **
3002 ** DEV/INODE
3003 **
3004 ** Where DEV and INODE are the device number and inode number for
3005 ** the file. On Windows, the volume serial number (DEV) and file
3006 ** identifier (INODE) are used to compute the value, see comments
3007 ** on the win32_file_id() function.
3008 **
3009 ** If FILENAME does not exist, then the return is an empty string.
3010 **
3011 ** The value of inode() can be used to eliminate files from a list
3012 ** that have duplicates because they have differing names due to links.
3013 **
3014 ** Code that wants to use this SQL function needs to first register
3015 ** it using a call such as the following:
3016 **
3017 ** sqlite3_create_function(g.db, "inode", 1, SQLITE_UTF8, 0,
3018 ** file_inode_sql_func, 0, 0);
3019 */
3020 void file_inode_sql_func(
3021 sqlite3_context *context,
3022 int argc,
3023 sqlite3_value **argv
3024 ){
3025 const char *zFilename;
3026 assert( argc==1 );
3027 zFilename = (const char*)sqlite3_value_text(argv[0]);
3028 if( zFilename==0 || zFilename[0]==0 || file_access(zFilename,F_OK) ){
3029 sqlite3_result_text(context, "", 0, SQLITE_STATIC);
3030 return;
3031 }
3032 #if defined(_WIN32)
3033 {
3034 char *zFileId = win32_file_id(zFilename);
3035 if( zFileId ){
3036 sqlite3_result_text(context, zFileId, -1, fossil_free);
3037 }else{
3038 sqlite3_result_text(context, "", 0, SQLITE_STATIC);
3039 }
3040 }
3041 #else
3042 {
3043 struct stat buf;
3044 int rc;
3045 memset(&buf, 0, sizeof(buf));
3046 rc = stat(zFilename, &buf);
3047 if( rc ){
3048 sqlite3_result_text(context, "", 0, SQLITE_STATIC);
3049 }else{
3050 sqlite3_result_text(context,
3051 mprintf("%lld/%lld", (i64)buf.st_dev, (i64)buf.st_ino), -1,
3052 fossil_free);
3053 }
3054 }
3055 #endif
3056 }
3057
+60 -33
--- src/forum.c
+++ src/forum.c
@@ -1761,20 +1761,35 @@
17611761
@ </form>
17621762
forum_emit_js();
17631763
style_finish_page();
17641764
}
17651765
1766
+/*
1767
+** SETTING: forum-close-policy boolean default=off
1768
+** If true, forum moderators may close/re-open forum posts, and reply
1769
+** to closed posts. If false, only administrators may do so. Note that
1770
+** this only affects the forum web UI, not post-closing tags which
1771
+** arrive via the command-line or from synchronization with a remote.
1772
+*/
1773
+/*
1774
+** SETTING: forum-title width=20 default=Forum
1775
+** This is the name or "title" of the Forum for this repository. The
1776
+** default is just "Forum". But in some setups, admins might want to
1777
+** change it to "Developer Forum" or "User Forum" or whatever other name
1778
+** seems more appropriate for the particular usage.
1779
+*/
1780
+
17661781
/*
17671782
** WEBPAGE: setup_forum
17681783
**
17691784
** Forum configuration and metrics.
17701785
*/
17711786
void forum_setup(void){
17721787
/* boolean config settings specific to the forum. */
1773
- const char * zSettingsBool[] = {
1774
- "forum-close-policy",
1775
- NULL /* sentinel entry */
1788
+ static const char *azForumSettings[] = {
1789
+ "forum-close-policy",
1790
+ "forum-title",
17761791
};
17771792
17781793
login_check_credentials();
17791794
if( !g.perm.Setup ){
17801795
login_needed(g.anon.Setup);
@@ -1789,45 +1804,40 @@
17891804
@ <p><a href='%R/forum'>Forum posts</a>:
17901805
@ <a href='%R/timeline?y=f'>%d(nPosts)</a></p>
17911806
}
17921807
17931808
@ <h2>Supervisors</h2>
1794
- @ <p>Users with capabilities 's', 'a', or '6'.</p>
17951809
{
17961810
Stmt q = empty_Stmt;
1797
- int nRows = 0;
17981811
db_prepare(&q, "SELECT uid, login, cap FROM user "
17991812
"WHERE cap GLOB '*[as6]*' ORDER BY login");
18001813
@ <table class='bordered'>
18011814
@ <thead><tr><th>User</th><th>Capabilities</th></tr></thead>
18021815
@ <tbody>
18031816
while( SQLITE_ROW==db_step(&q) ){
18041817
const int iUid = db_column_int(&q, 0);
18051818
const char *zUser = db_column_text(&q, 1);
18061819
const char *zCap = db_column_text(&q, 2);
1807
- ++nRows;
18081820
@ <tr>
18091821
@ <td><a href='%R/setup_uedit?id=%d(iUid)'>%h(zUser)</a></td>
18101822
@ <td>(%h(zCap))</td>
18111823
@ </tr>
18121824
}
18131825
db_finalize(&q);
18141826
@</tbody></table>
1815
- if( 0==nRows ){
1816
- @ No supervisors
1817
- }else{
1818
- @ %d(nRows) supervisor(s)
1819
- }
18201827
}
18211828
18221829
@ <h2>Moderators</h2>
1823
- @ <p>Users with capability '5'.</p>
1824
- {
1830
+ if( db_int(0, "SELECT count(*) FROM user "
1831
+ " WHERE cap GLOB '*5*' AND cap NOT GLOB '*[as6]*'")==0 ){
1832
+ @ <p>No non-supervisor moderators
1833
+ }else{
18251834
Stmt q = empty_Stmt;
18261835
int nRows = 0;
18271836
db_prepare(&q, "SELECT uid, login, cap FROM user "
1828
- "WHERE cap GLOB '*5*' ORDER BY login");
1837
+ "WHERE cap GLOB '*5*' AND cap NOT GLOB '*[as6]*'"
1838
+ " ORDER BY login");
18291839
@ <table class='bordered'>
18301840
@ <thead><tr><th>User</th><th>Capabilities</th></tr></thead>
18311841
@ <tbody>
18321842
while( SQLITE_ROW==db_step(&q) ){
18331843
const int iUid = db_column_int(&q, 0);
@@ -1839,43 +1849,59 @@
18391849
@ <td>(%h(zCap))</td>
18401850
@ </tr>
18411851
}
18421852
db_finalize(&q);
18431853
@ </tbody></table>
1844
- if( 0==nRows ){
1845
- @ No non-supervisor moderators
1846
- }else{
1847
- @ %d(nRows) moderator(s)
1848
- }
18491854
}
18501855
18511856
@ <h2>Settings</h2>
1852
- @ <p>Configuration settings specific to the forum.</p>
18531857
if( P("submit") && cgi_csrf_safe(2) ){
18541858
int i = 0;
1855
- const char *zSetting;
18561859
db_begin_transaction();
1857
- while( (zSetting = zSettingsBool[i++]) ){
1858
- const char *z = P(zSetting);
1859
- if( !z || !z[0] ) z = "off";
1860
- db_set(zSetting/*works-like:"x"*/, z, 0);
1860
+ for(i=0; i<ArraySize(azForumSettings); i++){
1861
+ char zQP[4];
1862
+ const char *z;
1863
+ const Setting *pSetting = setting_find(azForumSettings[i]);
1864
+ if( pSetting==0 ) continue;
1865
+ zQP[0] = 'a'+i;
1866
+ zQP[1] = zQP[0];
1867
+ zQP[2] = 0;
1868
+ z = P(zQP);
1869
+ if( z==0 || z[0]==0 ) continue;
1870
+ db_set(pSetting->name/*works-like:"x"*/, z, 0);
18611871
}
18621872
db_end_transaction(0);
18631873
@ <p><em>Settings saved.</em></p>
18641874
}
18651875
{
18661876
int i = 0;
1867
- const char *zSetting;
18681877
@ <form action="%R/setup_forum" method="post">
18691878
login_insert_csrf_secret();
18701879
@ <table class='forum-settings-list'><tbody>
1871
- while( (zSetting = zSettingsBool[i++]) ){
1872
- @ <tr><td>
1873
- onoff_attribute("", zSetting, zSetting/*works-like:"x"*/, 0, 0);
1874
- @ </td><td>
1875
- @ <a href='%R/help?cmd=%h(zSetting)'>%h(zSetting)</a>
1876
- @ </td></tr>
1880
+ for(i=0; i<ArraySize(azForumSettings); i++){
1881
+ char zQP[4];
1882
+ const Setting *pSetting = setting_find(azForumSettings[i]);
1883
+ if( pSetting==0 ) continue;
1884
+ zQP[0] = 'a'+i;
1885
+ zQP[1] = zQP[0];
1886
+ zQP[2] = 0;
1887
+ if( pSetting->width==0 ){
1888
+ /* Boolean setting */
1889
+ @ <tr><td align="right">
1890
+ @ <a href='%R/help?cmd=%h(pSetting->name)'>%h(pSetting->name)</a>:
1891
+ @ </td><td>
1892
+ onoff_attribute("", zQP, pSetting->name/*works-like:"x"*/, 0, 0);
1893
+ @ </td></tr>
1894
+ }else{
1895
+ /* Text value setting */
1896
+ @ <tr><td align="right">
1897
+ @ <a href='%R/help?cmd=%h(pSetting->name)'>%h(pSetting->name)</a>:
1898
+ @ </td><td>
1899
+ entry_attribute("", 25, pSetting->name, zQP/*works-like:""*/,
1900
+ pSetting->def, 0);
1901
+ @ </td></tr>
1902
+ }
18771903
}
18781904
@ </tbody></table>
18791905
@ <input type='submit' name='submit' value='Apply changes'>
18801906
@ </form>
18811907
}
@@ -1910,11 +1936,12 @@
19101936
login_needed(g.anon.RdForum);
19111937
return;
19121938
}
19131939
cgi_check_for_malice();
19141940
style_set_current_feature("forum");
1915
- style_header( "%s", isSearch ? "Forum Search Results" : "Forum" );
1941
+ style_header("%s%s", db_get("forum-title","Forum"),
1942
+ isSearch ? " Search Results" : "");
19161943
style_submenu_element("Timeline", "%R/timeline?ss=v&y=f&vfx");
19171944
if( g.perm.WrForum ){
19181945
style_submenu_element("New Thread","%R/forumnew");
19191946
}else{
19201947
/* Can't combine this with previous case using the ternary operator
19211948
--- src/forum.c
+++ src/forum.c
@@ -1761,20 +1761,35 @@
1761 @ </form>
1762 forum_emit_js();
1763 style_finish_page();
1764 }
1765
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1766 /*
1767 ** WEBPAGE: setup_forum
1768 **
1769 ** Forum configuration and metrics.
1770 */
1771 void forum_setup(void){
1772 /* boolean config settings specific to the forum. */
1773 const char * zSettingsBool[] = {
1774 "forum-close-policy",
1775 NULL /* sentinel entry */
1776 };
1777
1778 login_check_credentials();
1779 if( !g.perm.Setup ){
1780 login_needed(g.anon.Setup);
@@ -1789,45 +1804,40 @@
1789 @ <p><a href='%R/forum'>Forum posts</a>:
1790 @ <a href='%R/timeline?y=f'>%d(nPosts)</a></p>
1791 }
1792
1793 @ <h2>Supervisors</h2>
1794 @ <p>Users with capabilities 's', 'a', or '6'.</p>
1795 {
1796 Stmt q = empty_Stmt;
1797 int nRows = 0;
1798 db_prepare(&q, "SELECT uid, login, cap FROM user "
1799 "WHERE cap GLOB '*[as6]*' ORDER BY login");
1800 @ <table class='bordered'>
1801 @ <thead><tr><th>User</th><th>Capabilities</th></tr></thead>
1802 @ <tbody>
1803 while( SQLITE_ROW==db_step(&q) ){
1804 const int iUid = db_column_int(&q, 0);
1805 const char *zUser = db_column_text(&q, 1);
1806 const char *zCap = db_column_text(&q, 2);
1807 ++nRows;
1808 @ <tr>
1809 @ <td><a href='%R/setup_uedit?id=%d(iUid)'>%h(zUser)</a></td>
1810 @ <td>(%h(zCap))</td>
1811 @ </tr>
1812 }
1813 db_finalize(&q);
1814 @</tbody></table>
1815 if( 0==nRows ){
1816 @ No supervisors
1817 }else{
1818 @ %d(nRows) supervisor(s)
1819 }
1820 }
1821
1822 @ <h2>Moderators</h2>
1823 @ <p>Users with capability '5'.</p>
1824 {
 
 
1825 Stmt q = empty_Stmt;
1826 int nRows = 0;
1827 db_prepare(&q, "SELECT uid, login, cap FROM user "
1828 "WHERE cap GLOB '*5*' ORDER BY login");
 
1829 @ <table class='bordered'>
1830 @ <thead><tr><th>User</th><th>Capabilities</th></tr></thead>
1831 @ <tbody>
1832 while( SQLITE_ROW==db_step(&q) ){
1833 const int iUid = db_column_int(&q, 0);
@@ -1839,43 +1849,59 @@
1839 @ <td>(%h(zCap))</td>
1840 @ </tr>
1841 }
1842 db_finalize(&q);
1843 @ </tbody></table>
1844 if( 0==nRows ){
1845 @ No non-supervisor moderators
1846 }else{
1847 @ %d(nRows) moderator(s)
1848 }
1849 }
1850
1851 @ <h2>Settings</h2>
1852 @ <p>Configuration settings specific to the forum.</p>
1853 if( P("submit") && cgi_csrf_safe(2) ){
1854 int i = 0;
1855 const char *zSetting;
1856 db_begin_transaction();
1857 while( (zSetting = zSettingsBool[i++]) ){
1858 const char *z = P(zSetting);
1859 if( !z || !z[0] ) z = "off";
1860 db_set(zSetting/*works-like:"x"*/, z, 0);
 
 
 
 
 
 
 
1861 }
1862 db_end_transaction(0);
1863 @ <p><em>Settings saved.</em></p>
1864 }
1865 {
1866 int i = 0;
1867 const char *zSetting;
1868 @ <form action="%R/setup_forum" method="post">
1869 login_insert_csrf_secret();
1870 @ <table class='forum-settings-list'><tbody>
1871 while( (zSetting = zSettingsBool[i++]) ){
1872 @ <tr><td>
1873 onoff_attribute("", zSetting, zSetting/*works-like:"x"*/, 0, 0);
1874 @ </td><td>
1875 @ <a href='%R/help?cmd=%h(zSetting)'>%h(zSetting)</a>
1876 @ </td></tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1877 }
1878 @ </tbody></table>
1879 @ <input type='submit' name='submit' value='Apply changes'>
1880 @ </form>
1881 }
@@ -1910,11 +1936,12 @@
1910 login_needed(g.anon.RdForum);
1911 return;
1912 }
1913 cgi_check_for_malice();
1914 style_set_current_feature("forum");
1915 style_header( "%s", isSearch ? "Forum Search Results" : "Forum" );
 
1916 style_submenu_element("Timeline", "%R/timeline?ss=v&y=f&vfx");
1917 if( g.perm.WrForum ){
1918 style_submenu_element("New Thread","%R/forumnew");
1919 }else{
1920 /* Can't combine this with previous case using the ternary operator
1921
--- src/forum.c
+++ src/forum.c
@@ -1761,20 +1761,35 @@
1761 @ </form>
1762 forum_emit_js();
1763 style_finish_page();
1764 }
1765
1766 /*
1767 ** SETTING: forum-close-policy boolean default=off
1768 ** If true, forum moderators may close/re-open forum posts, and reply
1769 ** to closed posts. If false, only administrators may do so. Note that
1770 ** this only affects the forum web UI, not post-closing tags which
1771 ** arrive via the command-line or from synchronization with a remote.
1772 */
1773 /*
1774 ** SETTING: forum-title width=20 default=Forum
1775 ** This is the name or "title" of the Forum for this repository. The
1776 ** default is just "Forum". But in some setups, admins might want to
1777 ** change it to "Developer Forum" or "User Forum" or whatever other name
1778 ** seems more appropriate for the particular usage.
1779 */
1780
1781 /*
1782 ** WEBPAGE: setup_forum
1783 **
1784 ** Forum configuration and metrics.
1785 */
1786 void forum_setup(void){
1787 /* boolean config settings specific to the forum. */
1788 static const char *azForumSettings[] = {
1789 "forum-close-policy",
1790 "forum-title",
1791 };
1792
1793 login_check_credentials();
1794 if( !g.perm.Setup ){
1795 login_needed(g.anon.Setup);
@@ -1789,45 +1804,40 @@
1804 @ <p><a href='%R/forum'>Forum posts</a>:
1805 @ <a href='%R/timeline?y=f'>%d(nPosts)</a></p>
1806 }
1807
1808 @ <h2>Supervisors</h2>
 
1809 {
1810 Stmt q = empty_Stmt;
 
1811 db_prepare(&q, "SELECT uid, login, cap FROM user "
1812 "WHERE cap GLOB '*[as6]*' ORDER BY login");
1813 @ <table class='bordered'>
1814 @ <thead><tr><th>User</th><th>Capabilities</th></tr></thead>
1815 @ <tbody>
1816 while( SQLITE_ROW==db_step(&q) ){
1817 const int iUid = db_column_int(&q, 0);
1818 const char *zUser = db_column_text(&q, 1);
1819 const char *zCap = db_column_text(&q, 2);
 
1820 @ <tr>
1821 @ <td><a href='%R/setup_uedit?id=%d(iUid)'>%h(zUser)</a></td>
1822 @ <td>(%h(zCap))</td>
1823 @ </tr>
1824 }
1825 db_finalize(&q);
1826 @</tbody></table>
 
 
 
 
 
1827 }
1828
1829 @ <h2>Moderators</h2>
1830 if( db_int(0, "SELECT count(*) FROM user "
1831 " WHERE cap GLOB '*5*' AND cap NOT GLOB '*[as6]*'")==0 ){
1832 @ <p>No non-supervisor moderators
1833 }else{
1834 Stmt q = empty_Stmt;
1835 int nRows = 0;
1836 db_prepare(&q, "SELECT uid, login, cap FROM user "
1837 "WHERE cap GLOB '*5*' AND cap NOT GLOB '*[as6]*'"
1838 " ORDER BY login");
1839 @ <table class='bordered'>
1840 @ <thead><tr><th>User</th><th>Capabilities</th></tr></thead>
1841 @ <tbody>
1842 while( SQLITE_ROW==db_step(&q) ){
1843 const int iUid = db_column_int(&q, 0);
@@ -1839,43 +1849,59 @@
1849 @ <td>(%h(zCap))</td>
1850 @ </tr>
1851 }
1852 db_finalize(&q);
1853 @ </tbody></table>
 
 
 
 
 
1854 }
1855
1856 @ <h2>Settings</h2>
 
1857 if( P("submit") && cgi_csrf_safe(2) ){
1858 int i = 0;
 
1859 db_begin_transaction();
1860 for(i=0; i<ArraySize(azForumSettings); i++){
1861 char zQP[4];
1862 const char *z;
1863 const Setting *pSetting = setting_find(azForumSettings[i]);
1864 if( pSetting==0 ) continue;
1865 zQP[0] = 'a'+i;
1866 zQP[1] = zQP[0];
1867 zQP[2] = 0;
1868 z = P(zQP);
1869 if( z==0 || z[0]==0 ) continue;
1870 db_set(pSetting->name/*works-like:"x"*/, z, 0);
1871 }
1872 db_end_transaction(0);
1873 @ <p><em>Settings saved.</em></p>
1874 }
1875 {
1876 int i = 0;
 
1877 @ <form action="%R/setup_forum" method="post">
1878 login_insert_csrf_secret();
1879 @ <table class='forum-settings-list'><tbody>
1880 for(i=0; i<ArraySize(azForumSettings); i++){
1881 char zQP[4];
1882 const Setting *pSetting = setting_find(azForumSettings[i]);
1883 if( pSetting==0 ) continue;
1884 zQP[0] = 'a'+i;
1885 zQP[1] = zQP[0];
1886 zQP[2] = 0;
1887 if( pSetting->width==0 ){
1888 /* Boolean setting */
1889 @ <tr><td align="right">
1890 @ <a href='%R/help?cmd=%h(pSetting->name)'>%h(pSetting->name)</a>:
1891 @ </td><td>
1892 onoff_attribute("", zQP, pSetting->name/*works-like:"x"*/, 0, 0);
1893 @ </td></tr>
1894 }else{
1895 /* Text value setting */
1896 @ <tr><td align="right">
1897 @ <a href='%R/help?cmd=%h(pSetting->name)'>%h(pSetting->name)</a>:
1898 @ </td><td>
1899 entry_attribute("", 25, pSetting->name, zQP/*works-like:""*/,
1900 pSetting->def, 0);
1901 @ </td></tr>
1902 }
1903 }
1904 @ </tbody></table>
1905 @ <input type='submit' name='submit' value='Apply changes'>
1906 @ </form>
1907 }
@@ -1910,11 +1936,12 @@
1936 login_needed(g.anon.RdForum);
1937 return;
1938 }
1939 cgi_check_for_malice();
1940 style_set_current_feature("forum");
1941 style_header("%s%s", db_get("forum-title","Forum"),
1942 isSearch ? " Search Results" : "");
1943 style_submenu_element("Timeline", "%R/timeline?ss=v&y=f&vfx");
1944 if( g.perm.WrForum ){
1945 style_submenu_element("New Thread","%R/forumnew");
1946 }else{
1947 /* Can't combine this with previous case using the ternary operator
1948
+71 -26
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -1,28 +1,84 @@
11
/**
22
diff-related JS APIs for fossil.
33
*/
44
"use strict";
5
+/* Locate the UI element (if any) into which we can inject some diff-related
6
+ UI controls. */
7
+window.fossil.onPageLoad(function(){
8
+ const potentialParents = window.fossil.page.diffControlContainers = [
9
+ /* CSS selectors for possible parents for injected diff-related UI
10
+ controls. */
11
+ /* Put the most likely pages at the end, as array.pop() is more
12
+ efficient than array.shift() (see loop below). */
13
+ /* /filedit */ 'body.cpage-fileedit #fileedit-tab-diff-buttons',
14
+ /* /wikiedit */ 'body.cpage-wikiedit #wikiedit-tab-diff-buttons',
15
+ /* /fdiff */ 'body.fdiff form div.submenu',
16
+ /* /vdiff */ 'body.vdiff form div.submenu',
17
+ /* /info, /vinfo, /ckout */ 'body.vinfo div.sectionmenu.info-changes-menu'
18
+ ];
19
+ window.fossil.page.diffControlContainer = undefined;
20
+ while( potentialParents.length ){
21
+ if( (window.fossil.page.diffControlContainer
22
+ = document.querySelector(potentialParents.pop())) ){
23
+ break;
24
+ }
25
+ }
26
+});
27
+
528
window.fossil.onPageLoad(function(){
629
/**
730
Adds toggle checkboxes to each file entry in the diff views for
831
/info and similar pages.
932
*/
1033
const D = window.fossil.dom;
11
- const isFdiff = !!document.querySelector('body.fdiff');
34
+ const allToggles = [/*collection of all diff-toggle checkboxes*/];
35
+ let checkedCount =
36
+ 0 /* When showing more than one diff, keep track of how many
37
+ "show/hide" checkboxes are are checked so we can update the
38
+ "show/hide all" label dynamically. */;
39
+ let btnAll /* show/hide all diffs UI control */;
1240
const addToggle = function(diffElem){
1341
const sib = diffElem.previousElementSibling,
14
- btn = sib ? D.addClass(D.checkbox(true), 'diff-toggle') : 0;
42
+ ckbox = sib ? D.addClass(D.checkbox(true), 'diff-toggle') : 0;
1543
if(!sib) return;
16
- if(isFdiff) sib.parentElement.insertBefore(
17
- D.append(D.div(),btn),sib.nextElementSibling);
18
- else D.append(sib,btn);
19
- btn.addEventListener('click', function(){
20
- diffElem.classList.toggle('hidden');
44
+ const lblToggle = D.label();
45
+ D.append(lblToggle, ckbox, D.text(" show/hide "));
46
+ const wrapper = D.append(D.span(), lblToggle);
47
+ allToggles.push(ckbox);
48
+ ++checkedCount;
49
+ D.append(sib, D.append(wrapper, lblToggle));
50
+ ckbox.addEventListener('change', function(){
51
+ diffElem.classList[this.checked ? 'remove' : 'add']('hidden');
52
+ if(btnAll){
53
+ checkedCount += (this.checked ? 1 : -1);
54
+ btnAll.innerText = (checkedCount < allToggles.length)
55
+ ? "Show diffs" : "Hide diffs";
56
+ }
57
+ }, false);
58
+ };
59
+ if( !document.querySelector('body.fdiff') ){
60
+ /* Don't show the diff toggle button for /fdiff because it only
61
+ has a single file to show (and also a different DOM layout). */
62
+ document.querySelectorAll('table.diff').forEach(addToggle);
63
+ }
64
+ const icm = allToggles.length>1 ? window.fossil.page.diffControlContainer : 0;
65
+ if(icm) {
66
+ btnAll = D.addClass(D.a("#", "Hide diffs"), "button");
67
+ D.append( icm, btnAll );
68
+ btnAll.addEventListener('click', function(ev){
69
+ ev.preventDefault();
70
+ ev.stopPropagation();
71
+ const show = checkedCount < allToggles.length;
72
+ for( const ckbox of allToggles ){
73
+ /* Toggle all entries to match this new state. We use click()
74
+ instead of ckbox.checked=... so that the on-change event handler
75
+ fires. */
76
+ if(ckbox.checked!==show) ckbox.click();
77
+ }
2178
}, false);
22
- };
23
- document.querySelectorAll('table.diff').forEach(addToggle);
79
+ }
2480
});
2581
2682
window.fossil.onPageLoad(function(){
2783
const F = window.fossil, D = F.dom;
2884
const Diff = F.diff = {
@@ -635,26 +691,15 @@
635691
/* Look for a parent element to hold the sbs-sync-scroll toggle
636692
checkbox. This differs per page. If we don't find one, simply
637693
elide that toggle and use whatever preference the user last
638694
specified (defaulting to on). */
639695
let cbSync /* scroll-sync checkbox */;
640
- let eToggleParent /* element to put the sync-scroll checkbox in */;
641
- const potentialParents = [ /* possible parents for the checkbox */
642
- /* Put the most likely pages at the end, as array.pop() is more
643
- efficient than array.shift() (see loop below). */
644
- /* /filedit */ 'body.cpage-fileedit #fileedit-tab-diff-buttons',
645
- /* /wikiedit */ 'body.cpage-wikiedit #wikiedit-tab-diff-buttons',
646
- /* /fdiff */ 'body.fdiff form div.submenu',
647
- /* /vdiff */ 'body.vdiff form div.submenu',
648
- /* /info, /vinfo */ 'body.vinfo div.sectionmenu.info-changes-menu'
649
- ];
650
- while( potentialParents.length ){
651
- if( (eToggleParent = document.querySelector(potentialParents.pop())) ){
652
- break;
653
- }
654
- }
655
- const keySbsScroll = 'sync-diff-scroll' /* F.storage key */;
696
+ let eToggleParent = /* element to put the sync-scroll checkbox in */
697
+ document.querySelector('table.diff.splitdiff')
698
+ ? window.fossil.page.diffControlContainer
699
+ : undefined;
700
+ const keySbsScroll = 'sync-diff-scroll' /* F.storage key for persistent user preference */;
656701
if( eToggleParent ){
657702
/* Add a checkbox to toggle sbs scroll sync. Remember that in
658703
order to be UI-consistent in the /vdiff page we have to ensure
659704
that the checkbox is to the LEFT of of its label. We store the
660705
sync-scroll preference in F.storage (not a cookie) so that it
@@ -661,11 +706,11 @@
661706
persists across page loads and different apps. */
662707
cbSync = D.checkbox(keySbsScroll, F.storage.getBool(keySbsScroll,true));
663708
D.append(eToggleParent, D.append(
664709
D.addClass(D.create('span'), 'input-with-label'),
665710
D.append(D.create('label'),
666
- cbSync, "Sync side-by-side scrolling")
711
+ cbSync, "Scroll Sync")
667712
));
668713
cbSync.addEventListener('change', function(e){
669714
F.storage.set(keySbsScroll, e.target.checked);
670715
});
671716
}
672717
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -1,28 +1,84 @@
1 /**
2 diff-related JS APIs for fossil.
3 */
4 "use strict";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5 window.fossil.onPageLoad(function(){
6 /**
7 Adds toggle checkboxes to each file entry in the diff views for
8 /info and similar pages.
9 */
10 const D = window.fossil.dom;
11 const isFdiff = !!document.querySelector('body.fdiff');
 
 
 
 
 
12 const addToggle = function(diffElem){
13 const sib = diffElem.previousElementSibling,
14 btn = sib ? D.addClass(D.checkbox(true), 'diff-toggle') : 0;
15 if(!sib) return;
16 if(isFdiff) sib.parentElement.insertBefore(
17 D.append(D.div(),btn),sib.nextElementSibling);
18 else D.append(sib,btn);
19 btn.addEventListener('click', function(){
20 diffElem.classList.toggle('hidden');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21 }, false);
22 };
23 document.querySelectorAll('table.diff').forEach(addToggle);
24 });
25
26 window.fossil.onPageLoad(function(){
27 const F = window.fossil, D = F.dom;
28 const Diff = F.diff = {
@@ -635,26 +691,15 @@
635 /* Look for a parent element to hold the sbs-sync-scroll toggle
636 checkbox. This differs per page. If we don't find one, simply
637 elide that toggle and use whatever preference the user last
638 specified (defaulting to on). */
639 let cbSync /* scroll-sync checkbox */;
640 let eToggleParent /* element to put the sync-scroll checkbox in */;
641 const potentialParents = [ /* possible parents for the checkbox */
642 /* Put the most likely pages at the end, as array.pop() is more
643 efficient than array.shift() (see loop below). */
644 /* /filedit */ 'body.cpage-fileedit #fileedit-tab-diff-buttons',
645 /* /wikiedit */ 'body.cpage-wikiedit #wikiedit-tab-diff-buttons',
646 /* /fdiff */ 'body.fdiff form div.submenu',
647 /* /vdiff */ 'body.vdiff form div.submenu',
648 /* /info, /vinfo */ 'body.vinfo div.sectionmenu.info-changes-menu'
649 ];
650 while( potentialParents.length ){
651 if( (eToggleParent = document.querySelector(potentialParents.pop())) ){
652 break;
653 }
654 }
655 const keySbsScroll = 'sync-diff-scroll' /* F.storage key */;
656 if( eToggleParent ){
657 /* Add a checkbox to toggle sbs scroll sync. Remember that in
658 order to be UI-consistent in the /vdiff page we have to ensure
659 that the checkbox is to the LEFT of of its label. We store the
660 sync-scroll preference in F.storage (not a cookie) so that it
@@ -661,11 +706,11 @@
661 persists across page loads and different apps. */
662 cbSync = D.checkbox(keySbsScroll, F.storage.getBool(keySbsScroll,true));
663 D.append(eToggleParent, D.append(
664 D.addClass(D.create('span'), 'input-with-label'),
665 D.append(D.create('label'),
666 cbSync, "Sync side-by-side scrolling")
667 ));
668 cbSync.addEventListener('change', function(e){
669 F.storage.set(keySbsScroll, e.target.checked);
670 });
671 }
672
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -1,28 +1,84 @@
1 /**
2 diff-related JS APIs for fossil.
3 */
4 "use strict";
5 /* Locate the UI element (if any) into which we can inject some diff-related
6 UI controls. */
7 window.fossil.onPageLoad(function(){
8 const potentialParents = window.fossil.page.diffControlContainers = [
9 /* CSS selectors for possible parents for injected diff-related UI
10 controls. */
11 /* Put the most likely pages at the end, as array.pop() is more
12 efficient than array.shift() (see loop below). */
13 /* /filedit */ 'body.cpage-fileedit #fileedit-tab-diff-buttons',
14 /* /wikiedit */ 'body.cpage-wikiedit #wikiedit-tab-diff-buttons',
15 /* /fdiff */ 'body.fdiff form div.submenu',
16 /* /vdiff */ 'body.vdiff form div.submenu',
17 /* /info, /vinfo, /ckout */ 'body.vinfo div.sectionmenu.info-changes-menu'
18 ];
19 window.fossil.page.diffControlContainer = undefined;
20 while( potentialParents.length ){
21 if( (window.fossil.page.diffControlContainer
22 = document.querySelector(potentialParents.pop())) ){
23 break;
24 }
25 }
26 });
27
28 window.fossil.onPageLoad(function(){
29 /**
30 Adds toggle checkboxes to each file entry in the diff views for
31 /info and similar pages.
32 */
33 const D = window.fossil.dom;
34 const allToggles = [/*collection of all diff-toggle checkboxes*/];
35 let checkedCount =
36 0 /* When showing more than one diff, keep track of how many
37 "show/hide" checkboxes are are checked so we can update the
38 "show/hide all" label dynamically. */;
39 let btnAll /* show/hide all diffs UI control */;
40 const addToggle = function(diffElem){
41 const sib = diffElem.previousElementSibling,
42 ckbox = sib ? D.addClass(D.checkbox(true), 'diff-toggle') : 0;
43 if(!sib) return;
44 const lblToggle = D.label();
45 D.append(lblToggle, ckbox, D.text(" show/hide "));
46 const wrapper = D.append(D.span(), lblToggle);
47 allToggles.push(ckbox);
48 ++checkedCount;
49 D.append(sib, D.append(wrapper, lblToggle));
50 ckbox.addEventListener('change', function(){
51 diffElem.classList[this.checked ? 'remove' : 'add']('hidden');
52 if(btnAll){
53 checkedCount += (this.checked ? 1 : -1);
54 btnAll.innerText = (checkedCount < allToggles.length)
55 ? "Show diffs" : "Hide diffs";
56 }
57 }, false);
58 };
59 if( !document.querySelector('body.fdiff') ){
60 /* Don't show the diff toggle button for /fdiff because it only
61 has a single file to show (and also a different DOM layout). */
62 document.querySelectorAll('table.diff').forEach(addToggle);
63 }
64 const icm = allToggles.length>1 ? window.fossil.page.diffControlContainer : 0;
65 if(icm) {
66 btnAll = D.addClass(D.a("#", "Hide diffs"), "button");
67 D.append( icm, btnAll );
68 btnAll.addEventListener('click', function(ev){
69 ev.preventDefault();
70 ev.stopPropagation();
71 const show = checkedCount < allToggles.length;
72 for( const ckbox of allToggles ){
73 /* Toggle all entries to match this new state. We use click()
74 instead of ckbox.checked=... so that the on-change event handler
75 fires. */
76 if(ckbox.checked!==show) ckbox.click();
77 }
78 }, false);
79 }
 
80 });
81
82 window.fossil.onPageLoad(function(){
83 const F = window.fossil, D = F.dom;
84 const Diff = F.diff = {
@@ -635,26 +691,15 @@
691 /* Look for a parent element to hold the sbs-sync-scroll toggle
692 checkbox. This differs per page. If we don't find one, simply
693 elide that toggle and use whatever preference the user last
694 specified (defaulting to on). */
695 let cbSync /* scroll-sync checkbox */;
696 let eToggleParent = /* element to put the sync-scroll checkbox in */
697 document.querySelector('table.diff.splitdiff')
698 ? window.fossil.page.diffControlContainer
699 : undefined;
700 const keySbsScroll = 'sync-diff-scroll' /* F.storage key for persistent user preference */;
 
 
 
 
 
 
 
 
 
 
 
701 if( eToggleParent ){
702 /* Add a checkbox to toggle sbs scroll sync. Remember that in
703 order to be UI-consistent in the /vdiff page we have to ensure
704 that the checkbox is to the LEFT of of its label. We store the
705 sync-scroll preference in F.storage (not a cookie) so that it
@@ -661,11 +706,11 @@
706 persists across page loads and different apps. */
707 cbSync = D.checkbox(keySbsScroll, F.storage.getBool(keySbsScroll,true));
708 D.append(eToggleParent, D.append(
709 D.addClass(D.create('span'), 'input-with-label'),
710 D.append(D.create('label'),
711 cbSync, "Scroll Sync")
712 ));
713 cbSync.addEventListener('change', function(e){
714 F.storage.set(keySbsScroll, e.target.checked);
715 });
716 }
717
--- src/fossil.dom.js
+++ src/fossil.dom.js
@@ -87,11 +87,13 @@
8787
const rc = document.createElement('label');
8888
if(forElem){
8989
if(forElem instanceof HTMLElement){
9090
forElem = this.attr(forElem, 'id');
9191
}
92
- dom.attr(rc, 'for', forElem);
92
+ if(forElem){
93
+ dom.attr(rc, 'for', forElem);
94
+ }
9395
}
9496
if(text) this.append(rc, text);
9597
return rc;
9698
};
9799
/**
98100
--- src/fossil.dom.js
+++ src/fossil.dom.js
@@ -87,11 +87,13 @@
87 const rc = document.createElement('label');
88 if(forElem){
89 if(forElem instanceof HTMLElement){
90 forElem = this.attr(forElem, 'id');
91 }
92 dom.attr(rc, 'for', forElem);
 
 
93 }
94 if(text) this.append(rc, text);
95 return rc;
96 };
97 /**
98
--- src/fossil.dom.js
+++ src/fossil.dom.js
@@ -87,11 +87,13 @@
87 const rc = document.createElement('label');
88 if(forElem){
89 if(forElem instanceof HTMLElement){
90 forElem = this.attr(forElem, 'id');
91 }
92 if(forElem){
93 dom.attr(rc, 'for', forElem);
94 }
95 }
96 if(text) this.append(rc, text);
97 return rc;
98 };
99 /**
100
+2
--- src/http.c
+++ src/http.c
@@ -785,11 +785,13 @@
785785
zMimetype = find_option("mimetype",0,1);
786786
zOutFile = find_option("out","o",1);
787787
if( find_option("verbose","v",0)!=0 ) mHttpFlags |= HTTP_VERBOSE;
788788
if( find_option("compress",0,0)!=0 ) mHttpFlags &= ~HTTP_NOCOMPRESS;
789789
if( find_option("no-cert-verify",0,0)!=0 ){
790
+ #ifdef FOSSIL_ENABLE_SSL
790791
ssl_disable_cert_verification();
792
+ #endif
791793
}
792794
if( find_option("xfer",0,0)!=0 ){
793795
mHttpFlags |= HTTP_USE_LOGIN;
794796
mHttpFlags &= ~HTTP_GENERIC;
795797
}
796798
--- src/http.c
+++ src/http.c
@@ -785,11 +785,13 @@
785 zMimetype = find_option("mimetype",0,1);
786 zOutFile = find_option("out","o",1);
787 if( find_option("verbose","v",0)!=0 ) mHttpFlags |= HTTP_VERBOSE;
788 if( find_option("compress",0,0)!=0 ) mHttpFlags &= ~HTTP_NOCOMPRESS;
789 if( find_option("no-cert-verify",0,0)!=0 ){
 
790 ssl_disable_cert_verification();
 
791 }
792 if( find_option("xfer",0,0)!=0 ){
793 mHttpFlags |= HTTP_USE_LOGIN;
794 mHttpFlags &= ~HTTP_GENERIC;
795 }
796
--- src/http.c
+++ src/http.c
@@ -785,11 +785,13 @@
785 zMimetype = find_option("mimetype",0,1);
786 zOutFile = find_option("out","o",1);
787 if( find_option("verbose","v",0)!=0 ) mHttpFlags |= HTTP_VERBOSE;
788 if( find_option("compress",0,0)!=0 ) mHttpFlags &= ~HTTP_NOCOMPRESS;
789 if( find_option("no-cert-verify",0,0)!=0 ){
790 #ifdef FOSSIL_ENABLE_SSL
791 ssl_disable_cert_verification();
792 #endif
793 }
794 if( find_option("xfer",0,0)!=0 ){
795 mHttpFlags |= HTTP_USE_LOGIN;
796 mHttpFlags &= ~HTTP_GENERIC;
797 }
798
--- src/http_transport.c
+++ src/http_transport.c
@@ -103,11 +103,14 @@
103103
/*
104104
** Initialize a Blob to the name of the configured SSH command.
105105
*/
106106
void transport_ssh_command(Blob *p){
107107
char *zSsh; /* The base SSH command */
108
- zSsh = db_get("ssh-command", zDefaultSshCmd);
108
+ zSsh = g.zSshCmd;
109
+ if( zSsh==0 || zSsh[0]==0 ){
110
+ zSsh = db_get("ssh-command", zDefaultSshCmd);
111
+ }
109112
blob_init(p, zSsh, -1);
110113
}
111114
112115
/*
113116
** SSH initialization of the transport layer
114117
--- src/http_transport.c
+++ src/http_transport.c
@@ -103,11 +103,14 @@
103 /*
104 ** Initialize a Blob to the name of the configured SSH command.
105 */
106 void transport_ssh_command(Blob *p){
107 char *zSsh; /* The base SSH command */
108 zSsh = db_get("ssh-command", zDefaultSshCmd);
 
 
 
109 blob_init(p, zSsh, -1);
110 }
111
112 /*
113 ** SSH initialization of the transport layer
114
--- src/http_transport.c
+++ src/http_transport.c
@@ -103,11 +103,14 @@
103 /*
104 ** Initialize a Blob to the name of the configured SSH command.
105 */
106 void transport_ssh_command(Blob *p){
107 char *zSsh; /* The base SSH command */
108 zSsh = g.zSshCmd;
109 if( zSsh==0 || zSsh[0]==0 ){
110 zSsh = db_get("ssh-command", zDefaultSshCmd);
111 }
112 blob_init(p, zSsh, -1);
113 }
114
115 /*
116 ** SSH initialization of the transport layer
117
+328 -35
--- src/info.c
+++ src/info.c
@@ -372,11 +372,13 @@
372372
const char *zNew, /* blob.uuid after change. NULL for deletes */
373373
const char *zOldName, /* Prior name. NULL if no name change. */
374374
DiffConfig *pCfg, /* Flags for text_diff() or NULL to omit all */
375375
int mperm /* executable or symlink permission for zNew */
376376
){
377
- @ <p>
377
+ @ <div class='file-change-line'><span>
378
+ /* Maintenance reminder: the extra level of SPAN is for
379
+ ** arranging new elements via JS. */
378380
if( !g.perm.Hyperlink ){
379381
if( zNew==0 ){
380382
@ Deleted %h(zName).
381383
}else if( zOld==0 ){
382384
@ Added %h(zName).
@@ -391,10 +393,11 @@
391393
@ %h(zName) became a regular file.
392394
}
393395
}else{
394396
@ Changes to %h(zName).
395397
}
398
+ @ </span></div>
396399
if( pCfg ){
397400
append_diff(zOld, zNew, pCfg);
398401
}
399402
}else{
400403
if( zOld && zNew ){
@@ -438,18 +441,20 @@
438441
@ Added %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
439442
@ %h(zName)</a> version %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
440443
}
441444
if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
442445
if( pCfg ){
446
+ @ </span></div>
443447
append_diff(zOld, zNew, pCfg);
444
- }else{
445
- @ &nbsp;&nbsp;
448
+ }else{
446449
@ %z(href("%R/fdiff?v1=%!S&v2=%!S",zOld,zNew))[diff]</a>
450
+ @ </span></div>
447451
}
452
+ }else{
453
+ @ </span></div>
448454
}
449455
}
450
- @ </p>
451456
}
452457
453458
/*
454459
** Generate javascript to enhance HTML diffs.
455460
*/
@@ -602,10 +607,278 @@
602607
www_print_timeline(&q, TIMELINE_DISJOINT|TIMELINE_GRAPH|TIMELINE_NOSCROLL,
603608
0, 0, 0, rid, 0, 0);
604609
db_finalize(&q);
605610
style_finish_page();
606611
}
612
+
613
+/*
614
+** Render a web-page diff of the changes in the working check-out
615
+*/
616
+static void ckout_normal_diff(int vid){
617
+ int diffType; /* 0: no diff, 1: unified, 2: side-by-side */
618
+ DiffConfig DCfg,*pCfg; /* Diff details */
619
+ const char *zW; /* The "w" query parameter */
620
+ int nChng; /* Number of changes */
621
+ Stmt q;
622
+
623
+ diffType = preferred_diff_type();
624
+ pCfg = construct_diff_flags(diffType, &DCfg);
625
+ nChng = db_int(0, "SELECT count(*) FROM vfile"
626
+ " WHERE vid=%d AND (deleted OR chnged OR rid==0)", vid);
627
+ if( nChng==0 ){
628
+ @ <p>No uncommitted changes</p>
629
+ style_finish_page();
630
+ return;
631
+ }
632
+ db_prepare(&q,
633
+ /* 0 1 2 3 4 5 6 */
634
+ "SELECT pathname, deleted, chnged , rid==0, rid, islink, uuid"
635
+ " FROM vfile LEFT JOIN blob USING(rid)"
636
+ " WHERE vid=%d"
637
+ " AND (deleted OR chnged OR rid==0)"
638
+ " ORDER BY pathname /*scan*/",
639
+ vid
640
+ );
641
+ if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
642
+ DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
643
+ }else{
644
+ DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
645
+ }
646
+ @ <div class="sectionmenu info-changes-menu">
647
+ zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
648
+ if( diffType!=1 ){
649
+ @ %z(chref("button","%R?diff=1%s",zW))Unified&nbsp;Diff</a>
650
+ }
651
+ if( diffType!=2 ){
652
+ @ %z(chref("button","%R?diff=2%s",zW))Side-by-Side&nbsp;Diff</a>
653
+ }
654
+ if( diffType!=0 ){
655
+ if( *zW ){
656
+ @ %z(chref("button","%R?diff=%d",diffType))\
657
+ @ Show&nbsp;Whitespace&nbsp;Changes</a>
658
+ }else{
659
+ @ %z(chref("button","%R?diff=%d&w",diffType))Ignore&nbsp;Whitespace</a>
660
+ }
661
+ }
662
+ @ </div>
663
+ while( db_step(&q)==SQLITE_ROW ){
664
+ const char *zTreename = db_column_text(&q,0);
665
+ int isDeleted = db_column_int(&q, 1);
666
+ int isChnged = db_column_int(&q,2);
667
+ int isNew = db_column_int(&q,3);
668
+ int srcid = db_column_int(&q, 4);
669
+ int isLink = db_column_int(&q, 5);
670
+ const char *zUuid = db_column_text(&q, 6);
671
+ int showDiff = 1;
672
+
673
+ DCfg.diffFlags &= (~DIFF_FILE_MASK);
674
+ @ <div class='file-change-line'><span>
675
+ if( isDeleted ){
676
+ @ DELETED %h(zTreename)
677
+ DCfg.diffFlags |= DIFF_FILE_DELETED;
678
+ showDiff = 0;
679
+ }else if( file_access(zTreename, F_OK) ){
680
+ @ MISSING %h(zTreename)
681
+ showDiff = 0;
682
+ }else if( isNew ){
683
+ @ ADDED %h(zTreename)
684
+ DCfg.diffFlags |= DIFF_FILE_ADDED;
685
+ srcid = 0;
686
+ showDiff = 0;
687
+ }else if( isChnged==3 ){
688
+ @ ADDED_BY_MERGE %h(zTreename)
689
+ DCfg.diffFlags |= DIFF_FILE_ADDED;
690
+ srcid = 0;
691
+ showDiff = 0;
692
+ }else if( isChnged==5 ){
693
+ @ ADDED_BY_INTEGRATE %h(zTreename)
694
+ DCfg.diffFlags |= DIFF_FILE_ADDED;
695
+ srcid = 0;
696
+ showDiff = 0;
697
+ }else{
698
+ @ CHANGED %h(zTreename)
699
+ }
700
+ @ </span></div>
701
+ if( showDiff && pCfg ){
702
+ Blob old, new;
703
+ if( !isLink != !file_islink(zTreename) ){
704
+ @ %s(DIFF_CANNOT_COMPUTE_SYMLINK)
705
+ continue;
706
+ }
707
+ if( srcid>0 ){
708
+ content_get(srcid, &old);
709
+ pCfg->zLeftHash = zUuid;
710
+ }else{
711
+ blob_zero(&old);
712
+ pCfg->zLeftHash = 0;
713
+ }
714
+ blob_read_from_file(&new, zTreename, ExtFILE);
715
+ text_diff(&old, &new, cgi_output_blob(), pCfg);
716
+ blob_reset(&old);
717
+ blob_reset(&new);
718
+ }
719
+ }
720
+ db_finalize(&q);
721
+ append_diff_javascript(diffType);
722
+}
723
+
724
+/*
725
+** Render a web-page diff of the changes in the working check-out to
726
+** an external reference.
727
+*/
728
+static void ckout_external_base_diff(int vid, const char *zExBase){
729
+ int diffType; /* 0: no diff, 1: unified, 2: side-by-side */
730
+ DiffConfig DCfg,*pCfg; /* Diff details */
731
+ const char *zW; /* The "w" query parameter */
732
+ Stmt q;
733
+
734
+ diffType = preferred_diff_type();
735
+ pCfg = construct_diff_flags(diffType, &DCfg);
736
+ db_prepare(&q,
737
+ "SELECT pathname FROM vfile WHERE vid=%d ORDER BY pathname", vid
738
+ );
739
+ if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
740
+ DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
741
+ }else{
742
+ DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
743
+ }
744
+ @ <div class="sectionmenu info-changes-menu">
745
+ zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
746
+ if( diffType!=1 ){
747
+ @ %z(chref("button","%R?diff=1&exbase=%h%s",zExBase,zW))\
748
+ @ Unified&nbsp;Diff</a>
749
+ }
750
+ if( diffType!=2 ){
751
+ @ %z(chref("button","%R?diff=2&exbase=%h%s",zExBase,zW))\
752
+ @ Side-by-Side&nbsp;Diff</a>
753
+ }
754
+ if( diffType!=0 ){
755
+ if( *zW ){
756
+ @ %z(chref("button","%R?diff=%d&exbase=%h",diffType,zExBase))\
757
+ @ Show&nbsp;Whitespace&nbsp;Changes</a>
758
+ }else{
759
+ @ %z(chref("button","%R?diff=%d&exbase=%h&w",diffType,zExBase))\
760
+ @ Ignore&nbsp;Whitespace</a>
761
+ }
762
+ }
763
+ @ </div>
764
+ while( db_step(&q)==SQLITE_ROW ){
765
+ const char *zFile; /* Name of file in the repository */
766
+ char *zLhs; /* Full name of left-hand side file */
767
+ char *zRhs; /* Full name of right-hand side file */
768
+ Blob rhs; /* Full text of RHS */
769
+ Blob lhs; /* Full text of LHS */
770
+
771
+ zFile = db_column_text(&q,0);
772
+ zLhs = mprintf("%s/%s", zExBase, zFile);
773
+ zRhs = mprintf("%s%s", g.zLocalRoot, zFile);
774
+ if( file_size(zLhs, ExtFILE)<0 ){
775
+ @ <div class='file-change-line'><span>
776
+ @ Missing from external baseline: %h(zFile)
777
+ @ </span></div>
778
+ }else{
779
+ blob_read_from_file(&lhs, zLhs, ExtFILE);
780
+ blob_read_from_file(&rhs, zRhs, ExtFILE);
781
+ if( blob_size(&lhs)!=blob_size(&rhs)
782
+ || memcmp(blob_buffer(&lhs), blob_buffer(&rhs), blob_size(&lhs))!=0
783
+ ){
784
+ @ <div class='file-change-line'><span>
785
+ @ Changes to %h(zFile)
786
+ @ </span></div>
787
+ if( pCfg ){
788
+ char *zFullFN;
789
+ char *zHexFN;
790
+ int nFullFN;
791
+ zFullFN = file_canonical_name_dup(zLhs);
792
+ nFullFN = (int)strlen(zFullFN);
793
+ zHexFN = fossil_malloc( nFullFN*2 + 5 );
794
+ zHexFN[0] = 'x';
795
+ encode16((const u8*)zFullFN, (u8*)(zHexFN+1), nFullFN);
796
+ zHexFN[1+nFullFN*2] = 0;
797
+ fossil_free(zFullFN);
798
+ pCfg->zLeftHash = zHexFN;
799
+ text_diff(&lhs, &rhs, cgi_output_blob(), pCfg);
800
+ pCfg->zLeftHash = 0;
801
+ fossil_free(zHexFN);
802
+ }
803
+ }
804
+ blob_reset(&lhs);
805
+ blob_reset(&rhs);
806
+ }
807
+ fossil_free(zLhs);
808
+ fossil_free(zRhs);
809
+ }
810
+ db_finalize(&q);
811
+ append_diff_javascript(diffType);
812
+}
813
+
814
+/*
815
+** WEBPAGE: ckout
816
+**
817
+** Show information about the current checkout. This page only functions
818
+** if the web server is run on a loopback interface (in other words, was
819
+** started using "fossil ui" or similar) from within an open check-out.
820
+**
821
+** If the "exbase=PATH" query parameter is provided, then the diff shown
822
+** uses the files in PATH as the baseline. This is the same as using
823
+** the "--from PATH" argument to the "fossil diff" command-line. In fact,
824
+** when using "fossil ui --from PATH", the --from argument becomes the value
825
+** of the exbase query parameter for the start page.
826
+**
827
+** Other query parameters related to diffs are also accepted.
828
+*/
829
+void ckout_page(void){
830
+ int vid;
831
+ const char *zHome; /* Home directory */
832
+ int nHome;
833
+ const char *zExBase;
834
+ char *zHostname;
835
+ char *zCwd;
836
+
837
+ if( !db_open_local(0) || !cgi_is_loopback(g.zIpAddr) ){
838
+ cgi_redirectf("%R/home");
839
+ return;
840
+ }
841
+ file_chdir(g.zLocalRoot, 0);
842
+ vid = db_lget_int("checkout", 0);
843
+ db_unprotect(PROTECT_ALL);
844
+ vfile_check_signature(vid, CKSIG_ENOTFILE);
845
+ db_protect_pop();
846
+ style_set_current_feature("vinfo");
847
+ zHostname = fossil_hostname();
848
+ zCwd = file_getcwd(0,0);
849
+ zHome = fossil_getenv("HOME");
850
+ if( zHome ){
851
+ nHome = (int)strlen(zHome);
852
+ if( strncmp(zCwd, zHome, nHome)==0 && zCwd[nHome]=='/' ){
853
+ zCwd = mprintf("~%s", zCwd+nHome);
854
+ }
855
+ }else{
856
+ nHome = 0;
857
+ }
858
+ if( zHostname ){
859
+ style_header("Checkout Status: %h on %h", zCwd, zHostname);
860
+ }else{
861
+ style_header("Checkout Status: %h", zCwd);
862
+ }
863
+ render_checkin_context(vid, 0, 0, 0);
864
+ @ <hr>
865
+ zExBase = P("exbase");
866
+ if( zExBase && zExBase[0] ){
867
+ char *zCBase = file_canonical_name_dup(zExBase);
868
+ if( nHome && strncmp(zCBase, zHome, nHome)==0 && zCBase[nHome]=='/' ){
869
+ @ <p>Using external baseline: ~%h(zCBase+nHome)</p>
870
+ }else{
871
+ @ <p>Using external baseline: %h(zCBase)</p>
872
+ }
873
+ ckout_external_base_diff(vid, zCBase);
874
+ fossil_free(zCBase);
875
+ }else{
876
+ ckout_normal_diff(vid);
877
+ }
878
+ style_finish_page();
879
+}
607880
608881
/*
609882
** WEBPAGE: vinfo
610883
** WEBPAGE: ci
611884
** URL: /ci/ARTIFACTID
@@ -628,11 +901,10 @@
628901
const char *zParent; /* Hash of the parent check-in (if any) */
629902
const char *zRe; /* regex parameter */
630903
ReCompiled *pRe = 0; /* regex */
631904
const char *zW; /* URL param for ignoring whitespace */
632905
const char *zPage = "vinfo"; /* Page that shows diffs */
633
- const char *zPageHide = "ci"; /* Page that hides diffs */
634906
const char *zBrName; /* Branch name */
635907
DiffConfig DCfg,*pCfg; /* Type of diff */
636908
637909
login_check_credentials();
638910
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
@@ -898,21 +1170,17 @@
8981170
@ <div class="sectionmenu info-changes-menu">
8991171
/* ^^^ .info-changes-menu is used by diff scroll sync */
9001172
pCfg = construct_diff_flags(diffType, &DCfg);
9011173
DCfg.pRe = pRe;
9021174
zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
903
- if( diffType!=0 ){
904
- @ %z(chref("button","%R/%s/%T?diff=0",zPageHide,zName))\
905
- @ Hide&nbsp;Diffs</a>
906
- }
9071175
if( diffType!=1 ){
9081176
@ %z(chref("button","%R/%s/%T?diff=1%s",zPage,zName,zW))\
909
- @ Unified&nbsp;Diffs</a>
1177
+ @ Unified&nbsp;Diff</a>
9101178
}
9111179
if( diffType!=2 ){
9121180
@ %z(chref("button","%R/%s/%T?diff=2%s",zPage,zName,zW))\
913
- @ Side-by-Side&nbsp;Diffs</a>
1181
+ @ Side-by-Side&nbsp;Diff</a>
9141182
}
9151183
if( diffType!=0 ){
9161184
if( *zW ){
9171185
@ %z(chref("button","%R/%s/%T",zPage,zName))
9181186
@ Show&nbsp;Whitespace&nbsp;Changes</a>
@@ -1268,13 +1536,10 @@
12681536
cgi_check_for_malice();
12691537
style_set_current_feature("vdiff");
12701538
if( zBranch==0 ){
12711539
style_submenu_element("Path", "%R/timeline?me=%T&you=%T", zFrom, zTo);
12721540
}
1273
- if( diffType!=0 ){
1274
- style_submenu_element("Hide Diff", "%R/vdiff?diff=0&%b%b", &qp, &qpGlob);
1275
- }
12761541
if( diffType!=2 ){
12771542
style_submenu_element("Side-by-Side Diff", "%R/vdiff?diff=2&%b%b", &qp,
12781543
&qpGlob);
12791544
}
12801545
if( diffType!=1 ) {
@@ -1933,10 +2198,16 @@
19332198
** WEBPAGE: jchunk hidden
19342199
** URL: /jchunk/HASH?from=N&to=M
19352200
**
19362201
** Return lines of text from a file as a JSON array - one entry in the
19372202
** array for each line of text.
2203
+**
2204
+** The HASH is normally a sha1 or sha3 hash that identifies an artifact
2205
+** in the BLOB table of the database. However, if HASH starts with an "x"
2206
+** and is followed by valid hexadecimal, and if we are running in a
2207
+** "fossil ui" situation (locally and with privilege), then decode the hex
2208
+** into a filename and read the file content from that name.
19382209
**
19392210
** **Warning:** This is an internal-use-only interface that is subject to
19402211
** change at any moment. External application should not use this interface
19412212
** since the application will break when this interface changes, and this
19422213
** interface will undoubtedly change.
@@ -1948,10 +2219,11 @@
19482219
** ajax_route_error().
19492220
*/
19502221
void jchunk_page(void){
19512222
int rid = 0;
19522223
const char *zName = PD("name", "");
2224
+ int nName = (int)(strlen(zName)&0x7fffffff);
19532225
int iFrom = atoi(PD("from","0"));
19542226
int iTo = atoi(PD("to","0"));
19552227
int ln;
19562228
int go = 1;
19572229
const char *zSep;
@@ -1968,36 +2240,57 @@
19682240
cgi_check_for_malice();
19692241
if( !g.perm.Read ){
19702242
ajax_route_error(403, "Access requires Read permissions.");
19712243
return;
19722244
}
1973
-#if 1
1974
- /* Re-enable this block once this code is integrated somewhere into
1975
- the UI. */
1976
- rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zName);
1977
- if( rid==0 ){
1978
- ajax_route_error(404, "Unknown artifact: %h", zName);
1979
- return;
1980
- }
1981
-#else
1982
- /* This impl is only to simplify "manual" testing via the JS
1983
- console. */
1984
- rid = symbolic_name_to_rid(zName, "*");
1985
- if( rid==0 ){
1986
- ajax_route_error(404, "Unknown artifact: %h", zName);
1987
- return;
1988
- }else if( rid<0 ){
1989
- ajax_route_error(418, "Ambiguous artifact name: %h", zName);
1990
- return;
1991
- }
1992
-#endif
19932245
if( iFrom<1 || iTo<iFrom ){
19942246
ajax_route_error(500, "Invalid line range from=%d, to=%d.",
19952247
iFrom, iTo);
19962248
return;
19972249
}
1998
- content_get(rid, &content);
2250
+ if( zName[0]=='x'
2251
+ && ((nName-1)&1)==0
2252
+ && validate16(&zName[1],nName-1)
2253
+ && g.perm.Admin
2254
+ && db_open_local(0)
2255
+ && cgi_is_loopback(g.zIpAddr)
2256
+ ){
2257
+ /* Treat the HASH as a hex-encoded filename */
2258
+ int n = (nName-1)/2;
2259
+ char *zFN = fossil_malloc(n+1);
2260
+ decode16((const u8*)&zName[1], (u8*)zFN, nName-1);
2261
+ zFN[n] = 0;
2262
+ if( file_size(zFN, ExtFILE)<0 ){
2263
+ blob_zero(&content);
2264
+ }else{
2265
+ blob_read_from_file(&content, zFN, ExtFILE);
2266
+ }
2267
+ fossil_free(zFN);
2268
+ }else{
2269
+ /* Treat the HASH as an artifact hash matching BLOB.UUID */
2270
+#if 1
2271
+ /* Re-enable this block once this code is integrated somewhere into
2272
+ the UI. */
2273
+ rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zName);
2274
+ if( rid==0 ){
2275
+ ajax_route_error(404, "Unknown artifact: %h", zName);
2276
+ return;
2277
+ }
2278
+#else
2279
+ /* This impl is only to simplify "manual" testing via the JS
2280
+ console. */
2281
+ rid = symbolic_name_to_rid(zName, "*");
2282
+ if( rid==0 ){
2283
+ ajax_route_error(404, "Unknown artifact: %h", zName);
2284
+ return;
2285
+ }else if( rid<0 ){
2286
+ ajax_route_error(418, "Ambiguous artifact name: %h", zName);
2287
+ return;
2288
+ }
2289
+#endif
2290
+ content_get(rid, &content);
2291
+ }
19992292
g.isConst = 1;
20002293
cgi_set_content_type("application/json");
20012294
ln = 0;
20022295
while( go && ln<iFrom ){
20032296
go = blob_line(&content, &line);
20042297
--- src/info.c
+++ src/info.c
@@ -372,11 +372,13 @@
372 const char *zNew, /* blob.uuid after change. NULL for deletes */
373 const char *zOldName, /* Prior name. NULL if no name change. */
374 DiffConfig *pCfg, /* Flags for text_diff() or NULL to omit all */
375 int mperm /* executable or symlink permission for zNew */
376 ){
377 @ <p>
 
 
378 if( !g.perm.Hyperlink ){
379 if( zNew==0 ){
380 @ Deleted %h(zName).
381 }else if( zOld==0 ){
382 @ Added %h(zName).
@@ -391,10 +393,11 @@
391 @ %h(zName) became a regular file.
392 }
393 }else{
394 @ Changes to %h(zName).
395 }
 
396 if( pCfg ){
397 append_diff(zOld, zNew, pCfg);
398 }
399 }else{
400 if( zOld && zNew ){
@@ -438,18 +441,20 @@
438 @ Added %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
439 @ %h(zName)</a> version %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
440 }
441 if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
442 if( pCfg ){
 
443 append_diff(zOld, zNew, pCfg);
444 }else{
445 @ &nbsp;&nbsp;
446 @ %z(href("%R/fdiff?v1=%!S&v2=%!S",zOld,zNew))[diff]</a>
 
447 }
 
 
448 }
449 }
450 @ </p>
451 }
452
453 /*
454 ** Generate javascript to enhance HTML diffs.
455 */
@@ -602,10 +607,278 @@
602 www_print_timeline(&q, TIMELINE_DISJOINT|TIMELINE_GRAPH|TIMELINE_NOSCROLL,
603 0, 0, 0, rid, 0, 0);
604 db_finalize(&q);
605 style_finish_page();
606 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
607
608 /*
609 ** WEBPAGE: vinfo
610 ** WEBPAGE: ci
611 ** URL: /ci/ARTIFACTID
@@ -628,11 +901,10 @@
628 const char *zParent; /* Hash of the parent check-in (if any) */
629 const char *zRe; /* regex parameter */
630 ReCompiled *pRe = 0; /* regex */
631 const char *zW; /* URL param for ignoring whitespace */
632 const char *zPage = "vinfo"; /* Page that shows diffs */
633 const char *zPageHide = "ci"; /* Page that hides diffs */
634 const char *zBrName; /* Branch name */
635 DiffConfig DCfg,*pCfg; /* Type of diff */
636
637 login_check_credentials();
638 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
@@ -898,21 +1170,17 @@
898 @ <div class="sectionmenu info-changes-menu">
899 /* ^^^ .info-changes-menu is used by diff scroll sync */
900 pCfg = construct_diff_flags(diffType, &DCfg);
901 DCfg.pRe = pRe;
902 zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
903 if( diffType!=0 ){
904 @ %z(chref("button","%R/%s/%T?diff=0",zPageHide,zName))\
905 @ Hide&nbsp;Diffs</a>
906 }
907 if( diffType!=1 ){
908 @ %z(chref("button","%R/%s/%T?diff=1%s",zPage,zName,zW))\
909 @ Unified&nbsp;Diffs</a>
910 }
911 if( diffType!=2 ){
912 @ %z(chref("button","%R/%s/%T?diff=2%s",zPage,zName,zW))\
913 @ Side-by-Side&nbsp;Diffs</a>
914 }
915 if( diffType!=0 ){
916 if( *zW ){
917 @ %z(chref("button","%R/%s/%T",zPage,zName))
918 @ Show&nbsp;Whitespace&nbsp;Changes</a>
@@ -1268,13 +1536,10 @@
1268 cgi_check_for_malice();
1269 style_set_current_feature("vdiff");
1270 if( zBranch==0 ){
1271 style_submenu_element("Path", "%R/timeline?me=%T&you=%T", zFrom, zTo);
1272 }
1273 if( diffType!=0 ){
1274 style_submenu_element("Hide Diff", "%R/vdiff?diff=0&%b%b", &qp, &qpGlob);
1275 }
1276 if( diffType!=2 ){
1277 style_submenu_element("Side-by-Side Diff", "%R/vdiff?diff=2&%b%b", &qp,
1278 &qpGlob);
1279 }
1280 if( diffType!=1 ) {
@@ -1933,10 +2198,16 @@
1933 ** WEBPAGE: jchunk hidden
1934 ** URL: /jchunk/HASH?from=N&to=M
1935 **
1936 ** Return lines of text from a file as a JSON array - one entry in the
1937 ** array for each line of text.
 
 
 
 
 
 
1938 **
1939 ** **Warning:** This is an internal-use-only interface that is subject to
1940 ** change at any moment. External application should not use this interface
1941 ** since the application will break when this interface changes, and this
1942 ** interface will undoubtedly change.
@@ -1948,10 +2219,11 @@
1948 ** ajax_route_error().
1949 */
1950 void jchunk_page(void){
1951 int rid = 0;
1952 const char *zName = PD("name", "");
 
1953 int iFrom = atoi(PD("from","0"));
1954 int iTo = atoi(PD("to","0"));
1955 int ln;
1956 int go = 1;
1957 const char *zSep;
@@ -1968,36 +2240,57 @@
1968 cgi_check_for_malice();
1969 if( !g.perm.Read ){
1970 ajax_route_error(403, "Access requires Read permissions.");
1971 return;
1972 }
1973 #if 1
1974 /* Re-enable this block once this code is integrated somewhere into
1975 the UI. */
1976 rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zName);
1977 if( rid==0 ){
1978 ajax_route_error(404, "Unknown artifact: %h", zName);
1979 return;
1980 }
1981 #else
1982 /* This impl is only to simplify "manual" testing via the JS
1983 console. */
1984 rid = symbolic_name_to_rid(zName, "*");
1985 if( rid==0 ){
1986 ajax_route_error(404, "Unknown artifact: %h", zName);
1987 return;
1988 }else if( rid<0 ){
1989 ajax_route_error(418, "Ambiguous artifact name: %h", zName);
1990 return;
1991 }
1992 #endif
1993 if( iFrom<1 || iTo<iFrom ){
1994 ajax_route_error(500, "Invalid line range from=%d, to=%d.",
1995 iFrom, iTo);
1996 return;
1997 }
1998 content_get(rid, &content);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1999 g.isConst = 1;
2000 cgi_set_content_type("application/json");
2001 ln = 0;
2002 while( go && ln<iFrom ){
2003 go = blob_line(&content, &line);
2004
--- src/info.c
+++ src/info.c
@@ -372,11 +372,13 @@
372 const char *zNew, /* blob.uuid after change. NULL for deletes */
373 const char *zOldName, /* Prior name. NULL if no name change. */
374 DiffConfig *pCfg, /* Flags for text_diff() or NULL to omit all */
375 int mperm /* executable or symlink permission for zNew */
376 ){
377 @ <div class='file-change-line'><span>
378 /* Maintenance reminder: the extra level of SPAN is for
379 ** arranging new elements via JS. */
380 if( !g.perm.Hyperlink ){
381 if( zNew==0 ){
382 @ Deleted %h(zName).
383 }else if( zOld==0 ){
384 @ Added %h(zName).
@@ -391,10 +393,11 @@
393 @ %h(zName) became a regular file.
394 }
395 }else{
396 @ Changes to %h(zName).
397 }
398 @ </span></div>
399 if( pCfg ){
400 append_diff(zOld, zNew, pCfg);
401 }
402 }else{
403 if( zOld && zNew ){
@@ -438,18 +441,20 @@
441 @ Added %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
442 @ %h(zName)</a> version %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
443 }
444 if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
445 if( pCfg ){
446 @ </span></div>
447 append_diff(zOld, zNew, pCfg);
448 }else{
 
449 @ %z(href("%R/fdiff?v1=%!S&v2=%!S",zOld,zNew))[diff]</a>
450 @ </span></div>
451 }
452 }else{
453 @ </span></div>
454 }
455 }
 
456 }
457
458 /*
459 ** Generate javascript to enhance HTML diffs.
460 */
@@ -602,10 +607,278 @@
607 www_print_timeline(&q, TIMELINE_DISJOINT|TIMELINE_GRAPH|TIMELINE_NOSCROLL,
608 0, 0, 0, rid, 0, 0);
609 db_finalize(&q);
610 style_finish_page();
611 }
612
613 /*
614 ** Render a web-page diff of the changes in the working check-out
615 */
616 static void ckout_normal_diff(int vid){
617 int diffType; /* 0: no diff, 1: unified, 2: side-by-side */
618 DiffConfig DCfg,*pCfg; /* Diff details */
619 const char *zW; /* The "w" query parameter */
620 int nChng; /* Number of changes */
621 Stmt q;
622
623 diffType = preferred_diff_type();
624 pCfg = construct_diff_flags(diffType, &DCfg);
625 nChng = db_int(0, "SELECT count(*) FROM vfile"
626 " WHERE vid=%d AND (deleted OR chnged OR rid==0)", vid);
627 if( nChng==0 ){
628 @ <p>No uncommitted changes</p>
629 style_finish_page();
630 return;
631 }
632 db_prepare(&q,
633 /* 0 1 2 3 4 5 6 */
634 "SELECT pathname, deleted, chnged , rid==0, rid, islink, uuid"
635 " FROM vfile LEFT JOIN blob USING(rid)"
636 " WHERE vid=%d"
637 " AND (deleted OR chnged OR rid==0)"
638 " ORDER BY pathname /*scan*/",
639 vid
640 );
641 if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
642 DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
643 }else{
644 DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
645 }
646 @ <div class="sectionmenu info-changes-menu">
647 zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
648 if( diffType!=1 ){
649 @ %z(chref("button","%R?diff=1%s",zW))Unified&nbsp;Diff</a>
650 }
651 if( diffType!=2 ){
652 @ %z(chref("button","%R?diff=2%s",zW))Side-by-Side&nbsp;Diff</a>
653 }
654 if( diffType!=0 ){
655 if( *zW ){
656 @ %z(chref("button","%R?diff=%d",diffType))\
657 @ Show&nbsp;Whitespace&nbsp;Changes</a>
658 }else{
659 @ %z(chref("button","%R?diff=%d&w",diffType))Ignore&nbsp;Whitespace</a>
660 }
661 }
662 @ </div>
663 while( db_step(&q)==SQLITE_ROW ){
664 const char *zTreename = db_column_text(&q,0);
665 int isDeleted = db_column_int(&q, 1);
666 int isChnged = db_column_int(&q,2);
667 int isNew = db_column_int(&q,3);
668 int srcid = db_column_int(&q, 4);
669 int isLink = db_column_int(&q, 5);
670 const char *zUuid = db_column_text(&q, 6);
671 int showDiff = 1;
672
673 DCfg.diffFlags &= (~DIFF_FILE_MASK);
674 @ <div class='file-change-line'><span>
675 if( isDeleted ){
676 @ DELETED %h(zTreename)
677 DCfg.diffFlags |= DIFF_FILE_DELETED;
678 showDiff = 0;
679 }else if( file_access(zTreename, F_OK) ){
680 @ MISSING %h(zTreename)
681 showDiff = 0;
682 }else if( isNew ){
683 @ ADDED %h(zTreename)
684 DCfg.diffFlags |= DIFF_FILE_ADDED;
685 srcid = 0;
686 showDiff = 0;
687 }else if( isChnged==3 ){
688 @ ADDED_BY_MERGE %h(zTreename)
689 DCfg.diffFlags |= DIFF_FILE_ADDED;
690 srcid = 0;
691 showDiff = 0;
692 }else if( isChnged==5 ){
693 @ ADDED_BY_INTEGRATE %h(zTreename)
694 DCfg.diffFlags |= DIFF_FILE_ADDED;
695 srcid = 0;
696 showDiff = 0;
697 }else{
698 @ CHANGED %h(zTreename)
699 }
700 @ </span></div>
701 if( showDiff && pCfg ){
702 Blob old, new;
703 if( !isLink != !file_islink(zTreename) ){
704 @ %s(DIFF_CANNOT_COMPUTE_SYMLINK)
705 continue;
706 }
707 if( srcid>0 ){
708 content_get(srcid, &old);
709 pCfg->zLeftHash = zUuid;
710 }else{
711 blob_zero(&old);
712 pCfg->zLeftHash = 0;
713 }
714 blob_read_from_file(&new, zTreename, ExtFILE);
715 text_diff(&old, &new, cgi_output_blob(), pCfg);
716 blob_reset(&old);
717 blob_reset(&new);
718 }
719 }
720 db_finalize(&q);
721 append_diff_javascript(diffType);
722 }
723
724 /*
725 ** Render a web-page diff of the changes in the working check-out to
726 ** an external reference.
727 */
728 static void ckout_external_base_diff(int vid, const char *zExBase){
729 int diffType; /* 0: no diff, 1: unified, 2: side-by-side */
730 DiffConfig DCfg,*pCfg; /* Diff details */
731 const char *zW; /* The "w" query parameter */
732 Stmt q;
733
734 diffType = preferred_diff_type();
735 pCfg = construct_diff_flags(diffType, &DCfg);
736 db_prepare(&q,
737 "SELECT pathname FROM vfile WHERE vid=%d ORDER BY pathname", vid
738 );
739 if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
740 DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
741 }else{
742 DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
743 }
744 @ <div class="sectionmenu info-changes-menu">
745 zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
746 if( diffType!=1 ){
747 @ %z(chref("button","%R?diff=1&exbase=%h%s",zExBase,zW))\
748 @ Unified&nbsp;Diff</a>
749 }
750 if( diffType!=2 ){
751 @ %z(chref("button","%R?diff=2&exbase=%h%s",zExBase,zW))\
752 @ Side-by-Side&nbsp;Diff</a>
753 }
754 if( diffType!=0 ){
755 if( *zW ){
756 @ %z(chref("button","%R?diff=%d&exbase=%h",diffType,zExBase))\
757 @ Show&nbsp;Whitespace&nbsp;Changes</a>
758 }else{
759 @ %z(chref("button","%R?diff=%d&exbase=%h&w",diffType,zExBase))\
760 @ Ignore&nbsp;Whitespace</a>
761 }
762 }
763 @ </div>
764 while( db_step(&q)==SQLITE_ROW ){
765 const char *zFile; /* Name of file in the repository */
766 char *zLhs; /* Full name of left-hand side file */
767 char *zRhs; /* Full name of right-hand side file */
768 Blob rhs; /* Full text of RHS */
769 Blob lhs; /* Full text of LHS */
770
771 zFile = db_column_text(&q,0);
772 zLhs = mprintf("%s/%s", zExBase, zFile);
773 zRhs = mprintf("%s%s", g.zLocalRoot, zFile);
774 if( file_size(zLhs, ExtFILE)<0 ){
775 @ <div class='file-change-line'><span>
776 @ Missing from external baseline: %h(zFile)
777 @ </span></div>
778 }else{
779 blob_read_from_file(&lhs, zLhs, ExtFILE);
780 blob_read_from_file(&rhs, zRhs, ExtFILE);
781 if( blob_size(&lhs)!=blob_size(&rhs)
782 || memcmp(blob_buffer(&lhs), blob_buffer(&rhs), blob_size(&lhs))!=0
783 ){
784 @ <div class='file-change-line'><span>
785 @ Changes to %h(zFile)
786 @ </span></div>
787 if( pCfg ){
788 char *zFullFN;
789 char *zHexFN;
790 int nFullFN;
791 zFullFN = file_canonical_name_dup(zLhs);
792 nFullFN = (int)strlen(zFullFN);
793 zHexFN = fossil_malloc( nFullFN*2 + 5 );
794 zHexFN[0] = 'x';
795 encode16((const u8*)zFullFN, (u8*)(zHexFN+1), nFullFN);
796 zHexFN[1+nFullFN*2] = 0;
797 fossil_free(zFullFN);
798 pCfg->zLeftHash = zHexFN;
799 text_diff(&lhs, &rhs, cgi_output_blob(), pCfg);
800 pCfg->zLeftHash = 0;
801 fossil_free(zHexFN);
802 }
803 }
804 blob_reset(&lhs);
805 blob_reset(&rhs);
806 }
807 fossil_free(zLhs);
808 fossil_free(zRhs);
809 }
810 db_finalize(&q);
811 append_diff_javascript(diffType);
812 }
813
814 /*
815 ** WEBPAGE: ckout
816 **
817 ** Show information about the current checkout. This page only functions
818 ** if the web server is run on a loopback interface (in other words, was
819 ** started using "fossil ui" or similar) from within an open check-out.
820 **
821 ** If the "exbase=PATH" query parameter is provided, then the diff shown
822 ** uses the files in PATH as the baseline. This is the same as using
823 ** the "--from PATH" argument to the "fossil diff" command-line. In fact,
824 ** when using "fossil ui --from PATH", the --from argument becomes the value
825 ** of the exbase query parameter for the start page.
826 **
827 ** Other query parameters related to diffs are also accepted.
828 */
829 void ckout_page(void){
830 int vid;
831 const char *zHome; /* Home directory */
832 int nHome;
833 const char *zExBase;
834 char *zHostname;
835 char *zCwd;
836
837 if( !db_open_local(0) || !cgi_is_loopback(g.zIpAddr) ){
838 cgi_redirectf("%R/home");
839 return;
840 }
841 file_chdir(g.zLocalRoot, 0);
842 vid = db_lget_int("checkout", 0);
843 db_unprotect(PROTECT_ALL);
844 vfile_check_signature(vid, CKSIG_ENOTFILE);
845 db_protect_pop();
846 style_set_current_feature("vinfo");
847 zHostname = fossil_hostname();
848 zCwd = file_getcwd(0,0);
849 zHome = fossil_getenv("HOME");
850 if( zHome ){
851 nHome = (int)strlen(zHome);
852 if( strncmp(zCwd, zHome, nHome)==0 && zCwd[nHome]=='/' ){
853 zCwd = mprintf("~%s", zCwd+nHome);
854 }
855 }else{
856 nHome = 0;
857 }
858 if( zHostname ){
859 style_header("Checkout Status: %h on %h", zCwd, zHostname);
860 }else{
861 style_header("Checkout Status: %h", zCwd);
862 }
863 render_checkin_context(vid, 0, 0, 0);
864 @ <hr>
865 zExBase = P("exbase");
866 if( zExBase && zExBase[0] ){
867 char *zCBase = file_canonical_name_dup(zExBase);
868 if( nHome && strncmp(zCBase, zHome, nHome)==0 && zCBase[nHome]=='/' ){
869 @ <p>Using external baseline: ~%h(zCBase+nHome)</p>
870 }else{
871 @ <p>Using external baseline: %h(zCBase)</p>
872 }
873 ckout_external_base_diff(vid, zCBase);
874 fossil_free(zCBase);
875 }else{
876 ckout_normal_diff(vid);
877 }
878 style_finish_page();
879 }
880
881 /*
882 ** WEBPAGE: vinfo
883 ** WEBPAGE: ci
884 ** URL: /ci/ARTIFACTID
@@ -628,11 +901,10 @@
901 const char *zParent; /* Hash of the parent check-in (if any) */
902 const char *zRe; /* regex parameter */
903 ReCompiled *pRe = 0; /* regex */
904 const char *zW; /* URL param for ignoring whitespace */
905 const char *zPage = "vinfo"; /* Page that shows diffs */
 
906 const char *zBrName; /* Branch name */
907 DiffConfig DCfg,*pCfg; /* Type of diff */
908
909 login_check_credentials();
910 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
@@ -898,21 +1170,17 @@
1170 @ <div class="sectionmenu info-changes-menu">
1171 /* ^^^ .info-changes-menu is used by diff scroll sync */
1172 pCfg = construct_diff_flags(diffType, &DCfg);
1173 DCfg.pRe = pRe;
1174 zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
 
 
 
 
1175 if( diffType!=1 ){
1176 @ %z(chref("button","%R/%s/%T?diff=1%s",zPage,zName,zW))\
1177 @ Unified&nbsp;Diff</a>
1178 }
1179 if( diffType!=2 ){
1180 @ %z(chref("button","%R/%s/%T?diff=2%s",zPage,zName,zW))\
1181 @ Side-by-Side&nbsp;Diff</a>
1182 }
1183 if( diffType!=0 ){
1184 if( *zW ){
1185 @ %z(chref("button","%R/%s/%T",zPage,zName))
1186 @ Show&nbsp;Whitespace&nbsp;Changes</a>
@@ -1268,13 +1536,10 @@
1536 cgi_check_for_malice();
1537 style_set_current_feature("vdiff");
1538 if( zBranch==0 ){
1539 style_submenu_element("Path", "%R/timeline?me=%T&you=%T", zFrom, zTo);
1540 }
 
 
 
1541 if( diffType!=2 ){
1542 style_submenu_element("Side-by-Side Diff", "%R/vdiff?diff=2&%b%b", &qp,
1543 &qpGlob);
1544 }
1545 if( diffType!=1 ) {
@@ -1933,10 +2198,16 @@
2198 ** WEBPAGE: jchunk hidden
2199 ** URL: /jchunk/HASH?from=N&to=M
2200 **
2201 ** Return lines of text from a file as a JSON array - one entry in the
2202 ** array for each line of text.
2203 **
2204 ** The HASH is normally a sha1 or sha3 hash that identifies an artifact
2205 ** in the BLOB table of the database. However, if HASH starts with an "x"
2206 ** and is followed by valid hexadecimal, and if we are running in a
2207 ** "fossil ui" situation (locally and with privilege), then decode the hex
2208 ** into a filename and read the file content from that name.
2209 **
2210 ** **Warning:** This is an internal-use-only interface that is subject to
2211 ** change at any moment. External application should not use this interface
2212 ** since the application will break when this interface changes, and this
2213 ** interface will undoubtedly change.
@@ -1948,10 +2219,11 @@
2219 ** ajax_route_error().
2220 */
2221 void jchunk_page(void){
2222 int rid = 0;
2223 const char *zName = PD("name", "");
2224 int nName = (int)(strlen(zName)&0x7fffffff);
2225 int iFrom = atoi(PD("from","0"));
2226 int iTo = atoi(PD("to","0"));
2227 int ln;
2228 int go = 1;
2229 const char *zSep;
@@ -1968,36 +2240,57 @@
2240 cgi_check_for_malice();
2241 if( !g.perm.Read ){
2242 ajax_route_error(403, "Access requires Read permissions.");
2243 return;
2244 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2245 if( iFrom<1 || iTo<iFrom ){
2246 ajax_route_error(500, "Invalid line range from=%d, to=%d.",
2247 iFrom, iTo);
2248 return;
2249 }
2250 if( zName[0]=='x'
2251 && ((nName-1)&1)==0
2252 && validate16(&zName[1],nName-1)
2253 && g.perm.Admin
2254 && db_open_local(0)
2255 && cgi_is_loopback(g.zIpAddr)
2256 ){
2257 /* Treat the HASH as a hex-encoded filename */
2258 int n = (nName-1)/2;
2259 char *zFN = fossil_malloc(n+1);
2260 decode16((const u8*)&zName[1], (u8*)zFN, nName-1);
2261 zFN[n] = 0;
2262 if( file_size(zFN, ExtFILE)<0 ){
2263 blob_zero(&content);
2264 }else{
2265 blob_read_from_file(&content, zFN, ExtFILE);
2266 }
2267 fossil_free(zFN);
2268 }else{
2269 /* Treat the HASH as an artifact hash matching BLOB.UUID */
2270 #if 1
2271 /* Re-enable this block once this code is integrated somewhere into
2272 the UI. */
2273 rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zName);
2274 if( rid==0 ){
2275 ajax_route_error(404, "Unknown artifact: %h", zName);
2276 return;
2277 }
2278 #else
2279 /* This impl is only to simplify "manual" testing via the JS
2280 console. */
2281 rid = symbolic_name_to_rid(zName, "*");
2282 if( rid==0 ){
2283 ajax_route_error(404, "Unknown artifact: %h", zName);
2284 return;
2285 }else if( rid<0 ){
2286 ajax_route_error(418, "Ambiguous artifact name: %h", zName);
2287 return;
2288 }
2289 #endif
2290 content_get(rid, &content);
2291 }
2292 g.isConst = 1;
2293 cgi_set_content_type("application/json");
2294 ln = 0;
2295 while( go && ln<iFrom ){
2296 go = blob_line(&content, &line);
2297
+2 -1
--- src/interwiki.c
+++ src/interwiki.c
@@ -275,13 +275,14 @@
275275
db_prepare(&q,
276276
"SELECT substr(name,11), value->>'base'"
277277
" FROM config WHERE name glob 'interwiki:*' AND json_valid(value)"
278278
" ORDER BY name;"
279279
);
280
+ blob_append(out, "<blockquote>", -1);
280281
while( db_step(&q)==SQLITE_ROW ){
281282
if( n==0 ){
282
- blob_appendf(out, "<blockquote><table>\n");
283
+ blob_appendf(out, "<table>\n");
283284
}
284285
blob_appendf(out,"<tr><td>%h</td><td>&nbsp;&rarr;&nbsp;</td>",
285286
db_column_text(&q,0));
286287
blob_appendf(out,"<td>%h</td></tr>\n",
287288
db_column_text(&q,1));
288289
--- src/interwiki.c
+++ src/interwiki.c
@@ -275,13 +275,14 @@
275 db_prepare(&q,
276 "SELECT substr(name,11), value->>'base'"
277 " FROM config WHERE name glob 'interwiki:*' AND json_valid(value)"
278 " ORDER BY name;"
279 );
 
280 while( db_step(&q)==SQLITE_ROW ){
281 if( n==0 ){
282 blob_appendf(out, "<blockquote><table>\n");
283 }
284 blob_appendf(out,"<tr><td>%h</td><td>&nbsp;&rarr;&nbsp;</td>",
285 db_column_text(&q,0));
286 blob_appendf(out,"<td>%h</td></tr>\n",
287 db_column_text(&q,1));
288
--- src/interwiki.c
+++ src/interwiki.c
@@ -275,13 +275,14 @@
275 db_prepare(&q,
276 "SELECT substr(name,11), value->>'base'"
277 " FROM config WHERE name glob 'interwiki:*' AND json_valid(value)"
278 " ORDER BY name;"
279 );
280 blob_append(out, "<blockquote>", -1);
281 while( db_step(&q)==SQLITE_ROW ){
282 if( n==0 ){
283 blob_appendf(out, "<table>\n");
284 }
285 blob_appendf(out,"<tr><td>%h</td><td>&nbsp;&rarr;&nbsp;</td>",
286 db_column_text(&q,0));
287 blob_appendf(out,"<td>%h</td></tr>\n",
288 db_column_text(&q,1));
289
+13 -1
--- src/login.c
+++ src/login.c
@@ -1302,20 +1302,32 @@
13021302
*/
13031303
void login_restrict_robot_access(void){
13041304
const char *zReferer;
13051305
const char *zGlob;
13061306
int isMatch = 1;
1307
+ int nQP; /* Number of query parameters other than name= */
13071308
if( g.zLogin!=0 ) return;
13081309
zGlob = db_get("robot-restrict",0);
13091310
if( zGlob==0 || zGlob[0]==0 ) return;
13101311
if( g.isHuman ){
13111312
zReferer = P("HTTP_REFERER");
13121313
if( zReferer && zReferer[0]!=0 ) return;
13131314
}
1314
- if( cgi_qp_count()<1 ) return;
1315
+ nQP = cgi_qp_count();
1316
+ if( nQP<1 ) return;
13151317
isMatch = glob_multi_match(zGlob, g.zPath);
13161318
if( !isMatch ) return;
1319
+
1320
+ /* Check for exceptions to the restriction on the number of query
1321
+ ** parameters. */
1322
+ zGlob = db_get("robot-restrict-qp",0);
1323
+ if( zGlob && zGlob[0] ){
1324
+ char *zPath = mprintf("%s/%d", g.zPath, nQP);
1325
+ isMatch = glob_multi_match(zGlob, zPath);
1326
+ fossil_free(zPath);
1327
+ if( isMatch ) return;
1328
+ }
13171329
13181330
/* If we reach this point, it means we have a situation where we
13191331
** want to restrict the activity of a robot.
13201332
*/
13211333
g.isHuman = 0;
13221334
--- src/login.c
+++ src/login.c
@@ -1302,20 +1302,32 @@
1302 */
1303 void login_restrict_robot_access(void){
1304 const char *zReferer;
1305 const char *zGlob;
1306 int isMatch = 1;
 
1307 if( g.zLogin!=0 ) return;
1308 zGlob = db_get("robot-restrict",0);
1309 if( zGlob==0 || zGlob[0]==0 ) return;
1310 if( g.isHuman ){
1311 zReferer = P("HTTP_REFERER");
1312 if( zReferer && zReferer[0]!=0 ) return;
1313 }
1314 if( cgi_qp_count()<1 ) return;
 
1315 isMatch = glob_multi_match(zGlob, g.zPath);
1316 if( !isMatch ) return;
 
 
 
 
 
 
 
 
 
 
1317
1318 /* If we reach this point, it means we have a situation where we
1319 ** want to restrict the activity of a robot.
1320 */
1321 g.isHuman = 0;
1322
--- src/login.c
+++ src/login.c
@@ -1302,20 +1302,32 @@
1302 */
1303 void login_restrict_robot_access(void){
1304 const char *zReferer;
1305 const char *zGlob;
1306 int isMatch = 1;
1307 int nQP; /* Number of query parameters other than name= */
1308 if( g.zLogin!=0 ) return;
1309 zGlob = db_get("robot-restrict",0);
1310 if( zGlob==0 || zGlob[0]==0 ) return;
1311 if( g.isHuman ){
1312 zReferer = P("HTTP_REFERER");
1313 if( zReferer && zReferer[0]!=0 ) return;
1314 }
1315 nQP = cgi_qp_count();
1316 if( nQP<1 ) return;
1317 isMatch = glob_multi_match(zGlob, g.zPath);
1318 if( !isMatch ) return;
1319
1320 /* Check for exceptions to the restriction on the number of query
1321 ** parameters. */
1322 zGlob = db_get("robot-restrict-qp",0);
1323 if( zGlob && zGlob[0] ){
1324 char *zPath = mprintf("%s/%d", g.zPath, nQP);
1325 isMatch = glob_multi_match(zGlob, zPath);
1326 fossil_free(zPath);
1327 if( isMatch ) return;
1328 }
1329
1330 /* If we reach this point, it means we have a situation where we
1331 ** want to restrict the activity of a robot.
1332 */
1333 g.isHuman = 0;
1334
+23 -10
--- src/main.c
+++ src/main.c
@@ -2040,20 +2040,27 @@
20402040
*/
20412041
set_base_url(0);
20422042
if( fossil_redirect_to_https_if_needed(2) ) return;
20432043
if( zPathInfo==0 || zPathInfo[0]==0
20442044
|| (zPathInfo[0]=='/' && zPathInfo[1]==0) ){
2045
- /* Second special case: If the PATH_INFO is blank, issue a redirect to
2046
- ** the home page identified by the "index-page" setting in the repository
2047
- ** CONFIG table, to "/index" if there no "index-page" setting. */
2045
+ /* Second special case: If the PATH_INFO is blank, issue a redirect:
2046
+ ** (1) to "/ckout" if g.useLocalauth and g.localOpen are both set.
2047
+ ** (2) to the home page identified by the "index-page" setting
2048
+ ** in the repository CONFIG table
2049
+ ** (3) to "/index" if there no "index-page" setting in CONFIG
2050
+ */
20482051
#ifdef FOSSIL_ENABLE_JSON
20492052
if(g.json.isJsonMode){
20502053
json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
20512054
fossil_exit(0);
20522055
}
20532056
#endif
2054
- fossil_redirect_home() /*does not return*/;
2057
+ if( g.useLocalauth && g.localOpen ){
2058
+ cgi_redirectf("%R/ckout");
2059
+ }else{
2060
+ fossil_redirect_home() /*does not return*/;
2061
+ }
20552062
}else{
20562063
zPath = mprintf("%s", zPathInfo);
20572064
}
20582065
20592066
/* Make g.zPath point to the first element of the path. Make
@@ -3171,10 +3178,11 @@
31713178
** --errorlog FILE Append HTTP error messages to FILE
31723179
** --extroot DIR Document root for the /ext extension mechanism
31733180
** --files GLOBLIST Comma-separated list of glob patterns for static files
31743181
** --fossilcmd PATH The pathname of the "fossil" executable on the remote
31753182
** system when REPOSITORY is remote.
3183
+** --from PATH Use PATH as the diff baseline for the /ckout page
31763184
** --localauth Enable automatic login for requests from localhost
31773185
** --localhost Listen on 127.0.0.1 only (always true for "ui")
31783186
** --https Indicates that the input is coming through a reverse
31793187
** proxy that has already translated HTTPS into HTTP.
31803188
** --jsmode MODE Determine how JavaScript is delivered with pages.
@@ -3243,10 +3251,11 @@
32433251
const char *zInitPage = 0; /* Start on this page. --page option */
32443252
int findServerArg = 2; /* argv index for find_server_repository() */
32453253
char *zRemote = 0; /* Remote host on which to run "fossil ui" */
32463254
const char *zJsMode; /* The --jsmode parameter */
32473255
const char *zFossilCmd =0; /* Name of "fossil" binary on remote system */
3256
+ const char *zFrom; /* Value for --from */
32483257
32493258
32503259
#if USE_SEE
32513260
db_setup_for_saved_encryption_key();
32523261
#endif
@@ -3279,13 +3288,21 @@
32793288
g.useLocalauth = find_option("localauth", 0, 0)!=0;
32803289
Th_InitTraceLog();
32813290
zPort = find_option("port", "P", 1);
32823291
isUiCmd = g.argv[1][0]=='u';
32833292
if( isUiCmd ){
3293
+ zFrom = find_option("from", 0, 1);
3294
+ if( zFrom && zFrom==file_tail(zFrom) ){
3295
+ fossil_fatal("the argument to --from must be a pathname for"
3296
+ " the \"ui\" command");
3297
+ }
32843298
zInitPage = find_option("page", "p", 1);
32853299
if( zInitPage && zInitPage[0]=='/' ) zInitPage++;
32863300
zFossilCmd = find_option("fossilcmd", 0, 1);
3301
+ if( zFrom && zInitPage==0 ){
3302
+ zInitPage = mprintf("ckout?exbase=%T", zFrom);
3303
+ }
32873304
}
32883305
zNotFound = find_option("notfound", 0, 1);
32893306
allowRepoList = find_option("repolist",0,0)!=0;
32903307
if( find_option("nocompress",0,0)!=0 ) g.fNoHttpCompress = 1;
32913308
zAltBase = find_option("baseurl", 0, 1);
@@ -3356,11 +3373,11 @@
33563373
const char * zDir = g.argv[2];
33573374
if(dir_has_ckout_db(zDir)){
33583375
if(0!=file_chdir(zDir, 0)){
33593376
fossil_fatal("Cannot chdir to %s", zDir);
33603377
}
3361
- findServerArg = 99;
3378
+ findServerArg = g.argc;
33623379
fCreate = 0;
33633380
g.argv[2] = 0;
33643381
--g.argc;
33653382
}
33663383
}
@@ -3384,15 +3401,11 @@
33843401
}
33853402
if( !zRemote ){
33863403
find_server_repository(findServerArg, fCreate);
33873404
}
33883405
if( zInitPage==0 ){
3389
- if( isUiCmd && g.localOpen ){
3390
- zInitPage = "timeline?c=current";
3391
- }else{
3392
- zInitPage = "";
3393
- }
3406
+ zInitPage = "";
33943407
}
33953408
if( zPort ){
33963409
if( strchr(zPort,':') ){
33973410
int i;
33983411
for(i=strlen(zPort)-1; i>=0 && zPort[i]!=':'; i--){}
33993412
--- src/main.c
+++ src/main.c
@@ -2040,20 +2040,27 @@
2040 */
2041 set_base_url(0);
2042 if( fossil_redirect_to_https_if_needed(2) ) return;
2043 if( zPathInfo==0 || zPathInfo[0]==0
2044 || (zPathInfo[0]=='/' && zPathInfo[1]==0) ){
2045 /* Second special case: If the PATH_INFO is blank, issue a redirect to
2046 ** the home page identified by the "index-page" setting in the repository
2047 ** CONFIG table, to "/index" if there no "index-page" setting. */
 
 
 
2048 #ifdef FOSSIL_ENABLE_JSON
2049 if(g.json.isJsonMode){
2050 json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
2051 fossil_exit(0);
2052 }
2053 #endif
2054 fossil_redirect_home() /*does not return*/;
 
 
 
 
2055 }else{
2056 zPath = mprintf("%s", zPathInfo);
2057 }
2058
2059 /* Make g.zPath point to the first element of the path. Make
@@ -3171,10 +3178,11 @@
3171 ** --errorlog FILE Append HTTP error messages to FILE
3172 ** --extroot DIR Document root for the /ext extension mechanism
3173 ** --files GLOBLIST Comma-separated list of glob patterns for static files
3174 ** --fossilcmd PATH The pathname of the "fossil" executable on the remote
3175 ** system when REPOSITORY is remote.
 
3176 ** --localauth Enable automatic login for requests from localhost
3177 ** --localhost Listen on 127.0.0.1 only (always true for "ui")
3178 ** --https Indicates that the input is coming through a reverse
3179 ** proxy that has already translated HTTPS into HTTP.
3180 ** --jsmode MODE Determine how JavaScript is delivered with pages.
@@ -3243,10 +3251,11 @@
3243 const char *zInitPage = 0; /* Start on this page. --page option */
3244 int findServerArg = 2; /* argv index for find_server_repository() */
3245 char *zRemote = 0; /* Remote host on which to run "fossil ui" */
3246 const char *zJsMode; /* The --jsmode parameter */
3247 const char *zFossilCmd =0; /* Name of "fossil" binary on remote system */
 
3248
3249
3250 #if USE_SEE
3251 db_setup_for_saved_encryption_key();
3252 #endif
@@ -3279,13 +3288,21 @@
3279 g.useLocalauth = find_option("localauth", 0, 0)!=0;
3280 Th_InitTraceLog();
3281 zPort = find_option("port", "P", 1);
3282 isUiCmd = g.argv[1][0]=='u';
3283 if( isUiCmd ){
 
 
 
 
 
3284 zInitPage = find_option("page", "p", 1);
3285 if( zInitPage && zInitPage[0]=='/' ) zInitPage++;
3286 zFossilCmd = find_option("fossilcmd", 0, 1);
 
 
 
3287 }
3288 zNotFound = find_option("notfound", 0, 1);
3289 allowRepoList = find_option("repolist",0,0)!=0;
3290 if( find_option("nocompress",0,0)!=0 ) g.fNoHttpCompress = 1;
3291 zAltBase = find_option("baseurl", 0, 1);
@@ -3356,11 +3373,11 @@
3356 const char * zDir = g.argv[2];
3357 if(dir_has_ckout_db(zDir)){
3358 if(0!=file_chdir(zDir, 0)){
3359 fossil_fatal("Cannot chdir to %s", zDir);
3360 }
3361 findServerArg = 99;
3362 fCreate = 0;
3363 g.argv[2] = 0;
3364 --g.argc;
3365 }
3366 }
@@ -3384,15 +3401,11 @@
3384 }
3385 if( !zRemote ){
3386 find_server_repository(findServerArg, fCreate);
3387 }
3388 if( zInitPage==0 ){
3389 if( isUiCmd && g.localOpen ){
3390 zInitPage = "timeline?c=current";
3391 }else{
3392 zInitPage = "";
3393 }
3394 }
3395 if( zPort ){
3396 if( strchr(zPort,':') ){
3397 int i;
3398 for(i=strlen(zPort)-1; i>=0 && zPort[i]!=':'; i--){}
3399
--- src/main.c
+++ src/main.c
@@ -2040,20 +2040,27 @@
2040 */
2041 set_base_url(0);
2042 if( fossil_redirect_to_https_if_needed(2) ) return;
2043 if( zPathInfo==0 || zPathInfo[0]==0
2044 || (zPathInfo[0]=='/' && zPathInfo[1]==0) ){
2045 /* Second special case: If the PATH_INFO is blank, issue a redirect:
2046 ** (1) to "/ckout" if g.useLocalauth and g.localOpen are both set.
2047 ** (2) to the home page identified by the "index-page" setting
2048 ** in the repository CONFIG table
2049 ** (3) to "/index" if there no "index-page" setting in CONFIG
2050 */
2051 #ifdef FOSSIL_ENABLE_JSON
2052 if(g.json.isJsonMode){
2053 json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
2054 fossil_exit(0);
2055 }
2056 #endif
2057 if( g.useLocalauth && g.localOpen ){
2058 cgi_redirectf("%R/ckout");
2059 }else{
2060 fossil_redirect_home() /*does not return*/;
2061 }
2062 }else{
2063 zPath = mprintf("%s", zPathInfo);
2064 }
2065
2066 /* Make g.zPath point to the first element of the path. Make
@@ -3171,10 +3178,11 @@
3178 ** --errorlog FILE Append HTTP error messages to FILE
3179 ** --extroot DIR Document root for the /ext extension mechanism
3180 ** --files GLOBLIST Comma-separated list of glob patterns for static files
3181 ** --fossilcmd PATH The pathname of the "fossil" executable on the remote
3182 ** system when REPOSITORY is remote.
3183 ** --from PATH Use PATH as the diff baseline for the /ckout page
3184 ** --localauth Enable automatic login for requests from localhost
3185 ** --localhost Listen on 127.0.0.1 only (always true for "ui")
3186 ** --https Indicates that the input is coming through a reverse
3187 ** proxy that has already translated HTTPS into HTTP.
3188 ** --jsmode MODE Determine how JavaScript is delivered with pages.
@@ -3243,10 +3251,11 @@
3251 const char *zInitPage = 0; /* Start on this page. --page option */
3252 int findServerArg = 2; /* argv index for find_server_repository() */
3253 char *zRemote = 0; /* Remote host on which to run "fossil ui" */
3254 const char *zJsMode; /* The --jsmode parameter */
3255 const char *zFossilCmd =0; /* Name of "fossil" binary on remote system */
3256 const char *zFrom; /* Value for --from */
3257
3258
3259 #if USE_SEE
3260 db_setup_for_saved_encryption_key();
3261 #endif
@@ -3279,13 +3288,21 @@
3288 g.useLocalauth = find_option("localauth", 0, 0)!=0;
3289 Th_InitTraceLog();
3290 zPort = find_option("port", "P", 1);
3291 isUiCmd = g.argv[1][0]=='u';
3292 if( isUiCmd ){
3293 zFrom = find_option("from", 0, 1);
3294 if( zFrom && zFrom==file_tail(zFrom) ){
3295 fossil_fatal("the argument to --from must be a pathname for"
3296 " the \"ui\" command");
3297 }
3298 zInitPage = find_option("page", "p", 1);
3299 if( zInitPage && zInitPage[0]=='/' ) zInitPage++;
3300 zFossilCmd = find_option("fossilcmd", 0, 1);
3301 if( zFrom && zInitPage==0 ){
3302 zInitPage = mprintf("ckout?exbase=%T", zFrom);
3303 }
3304 }
3305 zNotFound = find_option("notfound", 0, 1);
3306 allowRepoList = find_option("repolist",0,0)!=0;
3307 if( find_option("nocompress",0,0)!=0 ) g.fNoHttpCompress = 1;
3308 zAltBase = find_option("baseurl", 0, 1);
@@ -3356,11 +3373,11 @@
3373 const char * zDir = g.argv[2];
3374 if(dir_has_ckout_db(zDir)){
3375 if(0!=file_chdir(zDir, 0)){
3376 fossil_fatal("Cannot chdir to %s", zDir);
3377 }
3378 findServerArg = g.argc;
3379 fCreate = 0;
3380 g.argv[2] = 0;
3381 --g.argc;
3382 }
3383 }
@@ -3384,15 +3401,11 @@
3401 }
3402 if( !zRemote ){
3403 find_server_repository(findServerArg, fCreate);
3404 }
3405 if( zInitPage==0 ){
3406 zInitPage = "";
 
 
 
 
3407 }
3408 if( zPort ){
3409 if( strchr(zPort,':') ){
3410 int i;
3411 for(i=strlen(zPort)-1; i>=0 && zPort[i]!=':'; i--){}
3412
--- src/main.mk
+++ src/main.mk
@@ -248,10 +248,11 @@
248248
$(SRCDIR)/hbmenu.js \
249249
$(SRCDIR)/href.js \
250250
$(SRCDIR)/login.js \
251251
$(SRCDIR)/markdown.md \
252252
$(SRCDIR)/menu.js \
253
+ $(SRCDIR)/merge.tcl \
253254
$(SRCDIR)/scroll.js \
254255
$(SRCDIR)/skin.js \
255256
$(SRCDIR)/sorttable.js \
256257
$(SRCDIR)/sounds/0.wav \
257258
$(SRCDIR)/sounds/1.wav \
258259
--- src/main.mk
+++ src/main.mk
@@ -248,10 +248,11 @@
248 $(SRCDIR)/hbmenu.js \
249 $(SRCDIR)/href.js \
250 $(SRCDIR)/login.js \
251 $(SRCDIR)/markdown.md \
252 $(SRCDIR)/menu.js \
 
253 $(SRCDIR)/scroll.js \
254 $(SRCDIR)/skin.js \
255 $(SRCDIR)/sorttable.js \
256 $(SRCDIR)/sounds/0.wav \
257 $(SRCDIR)/sounds/1.wav \
258
--- src/main.mk
+++ src/main.mk
@@ -248,10 +248,11 @@
248 $(SRCDIR)/hbmenu.js \
249 $(SRCDIR)/href.js \
250 $(SRCDIR)/login.js \
251 $(SRCDIR)/markdown.md \
252 $(SRCDIR)/menu.js \
253 $(SRCDIR)/merge.tcl \
254 $(SRCDIR)/scroll.js \
255 $(SRCDIR)/skin.js \
256 $(SRCDIR)/sorttable.js \
257 $(SRCDIR)/sounds/0.wav \
258 $(SRCDIR)/sounds/1.wav \
259
+462 -6
--- src/merge.c
+++ src/merge.c
@@ -20,10 +20,372 @@
2020
*/
2121
#include "config.h"
2222
#include "merge.h"
2323
#include <assert.h>
2424
25
+
26
+/*
27
+** Bring up a Tcl/Tk GUI to show details of the most recent merge.
28
+*/
29
+static void merge_info_tk(int bDark, int bAll, int nContext){
30
+ int i;
31
+ Blob script;
32
+ const char *zTempFile = 0;
33
+ char *zCmd;
34
+ const char *zTclsh;
35
+ zTclsh = find_option("tclsh",0,1);
36
+ if( zTclsh==0 ){
37
+ zTclsh = db_get("tclsh",0);
38
+ }
39
+ /* The undocumented --script FILENAME option causes the Tk script to
40
+ ** be written into the FILENAME instead of being run. This is used
41
+ ** for testing and debugging. */
42
+ zTempFile = find_option("script",0,1);
43
+ verify_all_options();
44
+
45
+ blob_zero(&script);
46
+ blob_appendf(&script, "set ncontext %d\n", nContext);
47
+ blob_appendf(&script, "set fossilcmd {| \"%/\" merge-info}\n",
48
+ g.nameOfExe);
49
+ blob_appendf(&script, "set filelist [list");
50
+ if( g.argc==2 ){
51
+ /* No files named on the command-line. Use every file mentioned
52
+ ** in the MERGESTAT table to generate the file list. */
53
+ Stmt q;
54
+ int cnt = 0;
55
+ db_prepare(&q,
56
+ "WITH priority(op,pri) AS (VALUES('CONFLICT',0),('ERROR',0),"
57
+ "('MERGE',1),('ADDED',2),('UPDATE',2))"
58
+ "SELECT coalesce(fnr,fn), op FROM mergestat JOIN priority USING(op)"
59
+ " %s ORDER BY pri, 1",
60
+ bAll ? "" : "WHERE op IN ('MERGE','CONFLICT')" /*safe-for-%s*/
61
+ );
62
+ while( db_step(&q)==SQLITE_ROW ){
63
+ blob_appendf(&script," %s ", db_column_text(&q,1));
64
+ blob_append_tcl_literal(&script, db_column_text(&q,0),
65
+ db_column_bytes(&q,0));
66
+ cnt++;
67
+ }
68
+ db_finalize(&q);
69
+ if( cnt==0 ){
70
+ fossil_print(
71
+ "No interesting changes in this merge. Use --all to see everything\n"
72
+ );
73
+ return;
74
+ }
75
+ }else{
76
+ /* Use only files named on the command-line in the file list.
77
+ ** But verify each file named is actually found in the MERGESTAT
78
+ ** table first. */
79
+ for(i=2; i<g.argc; i++){
80
+ char *zFile; /* Input filename */
81
+ char *zTreename; /* Name of the file in the tree */
82
+ Blob fname; /* Filename relative to root */
83
+ char *zOp; /* Operation on this file */
84
+ zFile = mprintf("%/", g.argv[i]);
85
+ file_tree_name(zFile, &fname, 0, 1);
86
+ fossil_free(zFile);
87
+ zTreename = blob_str(&fname);
88
+ zOp = db_text(0, "SELECT op FROM mergestat WHERE fn=%Q or fnr=%Q",
89
+ zTreename, zTreename);
90
+ blob_appendf(&script, " %s ", zOp);
91
+ fossil_free(zOp);
92
+ blob_append_tcl_literal(&script, zTreename, (int)strlen(zTreename));
93
+ blob_reset(&fname);
94
+ }
95
+ }
96
+ blob_appendf(&script, "]\n");
97
+ blob_appendf(&script, "set darkmode %d\n", bDark!=0);
98
+ blob_appendf(&script, "%s", builtin_file("merge.tcl", 0));
99
+ if( zTempFile ){
100
+ blob_write_to_file(&script, zTempFile);
101
+ fossil_print("To see the merge, run: %s \"%s\"\n", zTclsh, zTempFile);
102
+ }else{
103
+#if defined(FOSSIL_ENABLE_TCL)
104
+ Th_FossilInit(TH_INIT_DEFAULT);
105
+ if( evaluateTclWithEvents(g.interp, &g.tcl, blob_str(&script),
106
+ blob_size(&script), 1, 1, 0)==TCL_OK ){
107
+ blob_reset(&script);
108
+ return;
109
+ }
110
+ /*
111
+ * If evaluation of the Tcl script fails, the reason may be that Tk
112
+ * could not be found by the loaded Tcl, or that Tcl cannot be loaded
113
+ * dynamically (e.g. x64 Tcl with x86 Fossil). Therefore, fallback
114
+ * to using the external "tclsh", if available.
115
+ */
116
+#endif
117
+ zTempFile = write_blob_to_temp_file(&script);
118
+ zCmd = mprintf("%$ %$", zTclsh, zTempFile);
119
+ fossil_system(zCmd);
120
+ file_delete(zTempFile);
121
+ fossil_free(zCmd);
122
+ }
123
+ blob_reset(&script);
124
+}
125
+
126
+/*
127
+** Generate a TCL list on standard output that can be fed into the
128
+** merge.tcl script to show the details of the most recent merge
129
+** command associated with file "zFName". zFName must be the filename
130
+** relative to the root of the check-in - in other words a "tree name".
131
+**
132
+** When this routine is called, we know that the mergestat table
133
+** exists, but we do not know if zFName is mentioned in that table.
134
+*/
135
+static void merge_info_tcl(const char *zFName, int nContext){
136
+ const char *zTreename;/* Name of the file in the tree */
137
+ Stmt q; /* To query the MERGESTAT table */
138
+ MergeBuilder mb; /* The merge builder object */
139
+ Blob pivot,v1,v2,out; /* Blobs for holding content */
140
+ const char *zFN; /* A filename */
141
+ int rid; /* RID value */
142
+ int sz; /* File size value */
143
+
144
+ zTreename = zFName;
145
+ db_prepare(&q,
146
+ /* 0 1 2 3 4 5 6 7 */
147
+ "SELECT fnp, ridp, fn, ridv, sz, fnm, ridm, fnr"
148
+ " FROM mergestat"
149
+ " WHERE fnp=%Q OR fnr=%Q",
150
+ zTreename, zTreename
151
+ );
152
+ if( db_step(&q)!=SQLITE_ROW ){
153
+ db_finalize(&q);
154
+ fossil_print("ERROR {don't know anything about file: %s}\n", zTreename);
155
+ return;
156
+ }
157
+ mergebuilder_init_tcl(&mb);
158
+ mb.nContext = nContext;
159
+
160
+ /* Set up the pivot */
161
+ zFN = db_column_text(&q, 0);
162
+ if( zFN==0 ){
163
+ /* No pivot because the file was added */
164
+ mb.zPivot = "(no baseline)";
165
+ blob_zero(&pivot);
166
+ }else{
167
+ mb.zPivot = mprintf("%s (baseline)", file_tail(zFN));
168
+ rid = db_column_int(&q, 1);
169
+ content_get(rid, &pivot);
170
+ }
171
+ mb.pPivot = &pivot;
172
+
173
+ /* Set up the merge-in as V2 */
174
+ zFN = db_column_text(&q, 5);
175
+ if( zFN==0 ){
176
+ /* File deleted in the merged-in branch */
177
+ mb.zV2 = "(deleted file)";
178
+ blob_zero(&v2);
179
+ }else{
180
+ mb.zV2 = mprintf("%s (merge-in)", file_tail(zFN));
181
+ rid = db_column_int(&q, 6);
182
+ content_get(rid, &v2);
183
+ }
184
+ mb.pV2 = &v2;
185
+
186
+ /* Set up the local content as V1 */
187
+ zFN = db_column_text(&q, 2);
188
+ if( zFN==0 ){
189
+ /* File added by merge */
190
+ mb.zV1 = "(no original)";
191
+ blob_zero(&v1);
192
+ }else{
193
+ mb.zV1 = mprintf("%s (local)", file_tail(zFN));
194
+ rid = db_column_int(&q, 3);
195
+ sz = db_column_int(&q, 4);
196
+ if( rid==0 && sz>0 ){
197
+ /* The origin file had been edited so we'll have to pull its
198
+ ** original content out of the undo buffer */
199
+ Stmt q2;
200
+ db_prepare(&q2,
201
+ "SELECT content FROM undo"
202
+ " WHERE pathname=%Q AND octet_length(content)=%d",
203
+ zFN, sz
204
+ );
205
+ blob_zero(&v1);
206
+ if( db_step(&q2)==SQLITE_ROW ){
207
+ db_column_blob(&q2, 0, &v1);
208
+ }else{
209
+ mb.zV1 = "(local content missing)";
210
+ }
211
+ db_finalize(&q2);
212
+ }else{
213
+ /* The origin file was unchanged when the merge first occurred */
214
+ content_get(rid, &v1);
215
+ }
216
+ }
217
+ mb.pV1 = &v1;
218
+
219
+ /* Set up the output */
220
+ zFN = db_column_text(&q, 7);
221
+ if( zFN==0 ){
222
+ mb.zOut = "(Merge Result)";
223
+ }else{
224
+ mb.zOut = mprintf("%s (after merge)", file_tail(zFN));
225
+ }
226
+ blob_zero(&out);
227
+ mb.pOut = &out;
228
+
229
+ merge_three_blobs(&mb);
230
+ blob_write_to_file(&out, "-");
231
+
232
+ mb.xDestroy(&mb);
233
+ blob_reset(&pivot);
234
+ blob_reset(&v1);
235
+ blob_reset(&v2);
236
+ blob_reset(&out);
237
+ db_finalize(&q);
238
+}
239
+
240
+/*
241
+** COMMAND: merge-info
242
+**
243
+** Usage: %fossil merge-info [OPTIONS]
244
+**
245
+** Display information about the most recent merge operation.
246
+**
247
+** Options:
248
+** -a|--all Show all file changes that happened because of
249
+** the merge. Normally only MERGE, CONFLICT, and ERROR
250
+** lines are shown
251
+** -c|--context N Show N lines of context around each change,
252
+** with negative N meaning show all content. Only
253
+** meaningful in combination with --tcl or --tk.
254
+** --dark Use dark mode for the Tcl/Tk-based GUI
255
+** --tcl FILE Generate (to stdout) a TCL list containing
256
+** information needed to display the changes to
257
+** FILE caused by the most recent merge. FILE must
258
+** be a pathname relative to the root of the check-out.
259
+** --tk Bring up a Tcl/Tk GUI that shows the changes
260
+** associated with the most recent merge.
261
+**
262
+*/
263
+void merge_info_cmd(void){
264
+ const char *zCnt;
265
+ const char *zTcl;
266
+ int bTk;
267
+ int bDark;
268
+ int bAll;
269
+ int nContext;
270
+ Stmt q;
271
+ const char *zWhere;
272
+ int cnt = 0;
273
+
274
+ db_must_be_within_tree();
275
+ zTcl = find_option("tcl", 0, 1);
276
+ bTk = find_option("tk", 0, 0)!=0;
277
+ zCnt = find_option("context", "c", 1);
278
+ bDark = find_option("dark", 0, 0)!=0;
279
+ bAll = find_option("all", "a", 0)!=0;
280
+ if( bTk==0 ){
281
+ verify_all_options();
282
+ if( g.argc>2 ){
283
+ usage("[OPTIONS]");
284
+ }
285
+ }
286
+ if( zCnt ){
287
+ nContext = atoi(zCnt);
288
+ if( nContext<0 ) nContext = 0xfffffff;
289
+ }else{
290
+ nContext = 6;
291
+ }
292
+ if( !db_table_exists("localdb","mergestat") ){
293
+ if( zTcl ){
294
+ fossil_print("ERROR {no merge data available}\n");
295
+ }else{
296
+ fossil_print("No merge data is available\n");
297
+ }
298
+ return;
299
+ }
300
+ if( bTk ){
301
+ merge_info_tk(bDark, bAll, nContext);
302
+ return;
303
+ }
304
+ if( zTcl ){
305
+ merge_info_tcl(zTcl, nContext);
306
+ return;
307
+ }
308
+ if( bAll ){
309
+ zWhere = "";
310
+ }else{
311
+ zWhere = "WHERE op IN ('MERGE','CONFLICT','ERROR')";
312
+ }
313
+ db_prepare(&q,
314
+ "WITH priority(op,pri) AS (VALUES('CONFLICT',0),('ERROR',0),"
315
+ "('MERGE',1),('ADDED',2),('UPDATE',2))"
316
+
317
+ /* 0 1 2 */
318
+ "SELECT op, coalesce(fnr,fn), msg"
319
+ " FROM mergestat JOIN priority USING(op)"
320
+ " %s"
321
+ " ORDER BY pri, coalesce(fnr,fn)",
322
+ zWhere /*safe-for-%s*/
323
+ );
324
+ while( db_step(&q)==SQLITE_ROW ){
325
+ const char *zOp = db_column_text(&q, 0);
326
+ const char *zName = db_column_text(&q, 1);
327
+ const char *zErr = db_column_text(&q, 2);
328
+ if( zErr && fossil_strcmp(zOp,"CONFLICT")!=0 ){
329
+ fossil_print("%-9s %s (%s)\n", zOp, zName, zErr);
330
+ }else{
331
+ fossil_print("%-9s %s\n", zOp, zName);
332
+ }
333
+ cnt++;
334
+ }
335
+ db_finalize(&q);
336
+ if( !bAll && cnt==0 ){
337
+ fossil_print(
338
+ "No interesting changes in this merge. Use --all to see everything.\n"
339
+ );
340
+ }
341
+}
342
+
343
+/*
344
+** Erase all information about prior merges. Do this, for example, after
345
+** a commit.
346
+*/
347
+void merge_info_forget(void){
348
+ db_multi_exec(
349
+ "DROP TABLE IF EXISTS localdb.mergestat;"
350
+ "DELETE FROM localdb.vvar WHERE name glob 'mergestat-*';"
351
+ );
352
+}
353
+
354
+
355
+/*
356
+** Initialize the MERGESTAT table.
357
+**
358
+** Notes about mergestat:
359
+**
360
+** * ridv is a positive integer and sz is NULL if the V file contained
361
+** no local edits prior to the merge. If the V file was modified prior
362
+** to the merge then ridv is NULL and sz is the size of the file prior
363
+** to merge.
364
+**
365
+** * fnp, ridp, fn, ridv, and sz are all NULL for a file that was
366
+** added by merge.
367
+*/
368
+void merge_info_init(void){
369
+ merge_info_forget();
370
+ db_multi_exec(
371
+ "CREATE TABLE localdb.mergestat(\n"
372
+ " op TEXT, -- 'UPDATE', 'ADDED', 'MERGE', etc...\n"
373
+ " fnp TEXT, -- Name of the pivot file (P)\n"
374
+ " ridp INT, -- RID for the pivot file\n"
375
+ " fn TEXT, -- Name of origin file (V)\n"
376
+ " ridv INT, -- RID for origin file, or NULL if previously edited\n"
377
+ " sz INT, -- Size of origin file in bytes, NULL if unedited\n"
378
+ " fnm TEXT, -- Name of the file being merged in (M)\n"
379
+ " ridm INT, -- RID for the merge-in file\n"
380
+ " fnr TEXT, -- Name of the final output file, after all renaming\n"
381
+ " nc INT DEFAULT 0, -- Number of conflicts\n"
382
+ " msg TEXT -- Error message\n"
383
+ ");"
384
+ );
385
+}
386
+
25387
/*
26388
** Print information about a particular check-in.
27389
*/
28390
void print_checkin_description(int rid, int indent, const char *zLabel){
29391
Stmt q;
@@ -323,11 +685,11 @@
323685
** --force-missing Force the merge even if there is missing content
324686
** --integrate Merged branch will be closed when committing
325687
** -K|--keep-merge-files On merge conflict, retain the temporary files
326688
** used for merging, named *-baseline, *-original,
327689
** and *-merge.
328
-** -n|--dry-run If given, display instead of run actions
690
+** -n|--dry-run Do not actually change files on disk
329691
** --nosync Do not auto-sync prior to merging
330692
** -v|--verbose Show additional details of the merge
331693
*/
332694
void merge_cmd(void){
333695
int vid; /* Current version "V" */
@@ -800,15 +1162,21 @@
8001162
8011163
/************************************************************************
8021164
** All of the information needed to do the merge is now contained in the
8031165
** FV table. Starting here, we begin to actually carry out the merge.
8041166
**
805
- ** First, find files that have changed from P->M but not P->V.
1167
+ ** Begin by constructing the localdb.mergestat table.
1168
+ */
1169
+ merge_info_init();
1170
+
1171
+ /*
1172
+ ** Find files that have changed from P->M but not P->V.
8061173
** Copy the M content over into V.
8071174
*/
8081175
db_prepare(&q,
809
- "SELECT idv, ridm, fn, islinkm FROM fv"
1176
+ /* 0 1 2 3 4 5 6 7 */
1177
+ "SELECT idv, ridm, fn, islinkm, fnp, ridp, ridv, fnm FROM fv"
8101178
" WHERE idp>0 AND idv>0 AND idm>0"
8111179
" AND ridm!=ridp AND ridv=ridp AND NOT chnged"
8121180
);
8131181
while( db_step(&q)==SQLITE_ROW ){
8141182
int idv = db_column_int(&q, 0);
@@ -825,10 +1193,21 @@
8251193
" THEN (SELECT uuid FROM blob WHERE blob.rid=%d) END"
8261194
" WHERE id=%d", ridm, integrateFlag?4:2, islinkm, ridm, ridm, idv
8271195
);
8281196
vfile_to_disk(0, idv, 0, 0);
8291197
}
1198
+ db_multi_exec(
1199
+ "INSERT INTO mergestat(op,fnp,ridp,fn,ridv,fnm,ridm,fnr)"
1200
+ "VALUES('UPDATE',%Q,%d,%Q,%d,%Q,%d,%Q)",
1201
+ /* fnp */ db_column_text(&q, 4),
1202
+ /* ridp */ db_column_int(&q,5),
1203
+ /* fn */ zName,
1204
+ /* ridv */ db_column_int(&q,6),
1205
+ /* fnm */ db_column_text(&q, 7),
1206
+ /* ridm */ ridm,
1207
+ /* fnr */ zName
1208
+ );
8301209
}
8311210
db_finalize(&q);
8321211
8331212
/*
8341213
** Do a three-way merge on files that have changes on both P->M and P->V.
@@ -836,11 +1215,15 @@
8361215
** Proceed even if the file doesn't exist on P, just like the common ancestor
8371216
** of M and V is an empty file. In this case, merge conflict marks will be
8381217
** added to the file and user will be forced to take a decision.
8391218
*/
8401219
db_prepare(&q,
841
- "SELECT ridm, idv, ridp, ridv, %s, fn, isexe, islinkv, islinkm FROM fv"
1220
+ /* 0 1 2 3 4 5 6 7 8 */
1221
+ "SELECT ridm, idv, ridp, ridv, %z, fn, isexe, islinkv, islinkm,"
1222
+ /* 9 10 11 */
1223
+ " fnp, fnm, chnged"
1224
+ " FROM fv"
8421225
" WHERE idv>0 AND idm>0"
8431226
" AND ridm!=ridp AND (ridv!=ridp OR chnged)",
8441227
glob_expr("fv.fn", zBinGlob)
8451228
);
8461229
while( db_step(&q)==SQLITE_ROW ){
@@ -851,12 +1234,14 @@
8511234
int isBinary = db_column_int(&q, 4);
8521235
const char *zName = db_column_text(&q, 5);
8531236
int isExe = db_column_int(&q, 6);
8541237
int islinkv = db_column_int(&q, 7);
8551238
int islinkm = db_column_int(&q, 8);
1239
+ int chnged = db_column_int(&q, 11);
8561240
int rc;
8571241
char *zFullPath;
1242
+ const char *zType = "MERGE";
8581243
Blob m, p, r;
8591244
/* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */
8601245
if( verboseFlag ){
8611246
fossil_print("MERGE %s (pivot=%d v1=%d v2=%d)\n",
8621247
zName, ridp, ridm, ridv);
@@ -864,13 +1249,29 @@
8641249
fossil_print("MERGE %s\n", zName);
8651250
}
8661251
if( islinkv || islinkm ){
8671252
fossil_print("***** Cannot merge symlink %s\n", zName);
8681253
nConflict++;
1254
+ db_multi_exec(
1255
+ "INSERT INTO mergestat(op,fnp,ridp,fn,ridv,fnm,ridm,fnr,nc,msg)"
1256
+ "VALUES('ERROR',%Q,%d,%Q,%d,%Q,%d,%Q,1,'cannot merge symlink')",
1257
+ /* fnp */ db_column_text(&q, 9),
1258
+ /* ridp */ ridp,
1259
+ /* fn */ zName,
1260
+ /* ridv */ ridv,
1261
+ /* fnm */ db_column_text(&q, 10),
1262
+ /* ridm */ ridm,
1263
+ /* fnr */ zName
1264
+ );
8691265
}else{
1266
+ i64 sz;
1267
+ const char *zErrMsg = 0;
1268
+ int nc = 0;
1269
+
8701270
if( !dryRunFlag ) undo_save(zName);
8711271
zFullPath = mprintf("%s/%s", g.zLocalRoot, zName);
1272
+ sz = file_size(zFullPath, ExtFILE);
8721273
content_get(ridp, &p);
8731274
content_get(ridm, &m);
8741275
if( isBinary ){
8751276
rc = -1;
8761277
blob_zero(&r);
@@ -887,15 +1288,38 @@
8871288
db_multi_exec("UPDATE vfile SET mtime=0 WHERE id=%d", idv);
8881289
if( rc>0 ){
8891290
fossil_print("***** %d merge conflict%s in %s\n",
8901291
rc, rc>1 ? "s" : "", zName);
8911292
nConflict++;
1293
+ nc = rc;
1294
+ zErrMsg = "merge conflicts";
1295
+ zType = "CONFLICT";
8921296
}
8931297
}else{
8941298
fossil_print("***** Cannot merge binary file %s\n", zName);
8951299
nConflict++;
1300
+ nc = 1;
1301
+ zErrMsg = "cannot merge binary file";
1302
+ zType = "ERROR";
8961303
}
1304
+ db_multi_exec(
1305
+ "INSERT INTO mergestat(op,fnp,ridp,fn,ridv,sz,fnm,ridm,fnr,nc,msg)"
1306
+ "VALUES(%Q,%Q,%d,%Q,iif(%d,%d,NULL),iif(%d,%lld,NULL),%Q,%d,"
1307
+ "%Q,%d,%Q)",
1308
+ /* op */ zType,
1309
+ /* fnp */ db_column_text(&q, 9),
1310
+ /* ridp */ ridp,
1311
+ /* fn */ zName,
1312
+ /* ridv */ chnged==0, ridv,
1313
+ /* sz */ chnged!=0, sz,
1314
+ /* fnm */ db_column_text(&q, 10),
1315
+ /* ridm */ ridm,
1316
+ /* fnr */ zName,
1317
+ /* nc */ nc,
1318
+ /* msg */ zErrMsg
1319
+ );
1320
+ fossil_free(zFullPath);
8971321
blob_reset(&p);
8981322
blob_reset(&m);
8991323
blob_reset(&r);
9001324
}
9011325
vmerge_insert(idv, ridm);
@@ -904,22 +1328,33 @@
9041328
9051329
/*
9061330
** Drop files that are in P and V but not in M
9071331
*/
9081332
db_prepare(&q,
909
- "SELECT idv, fn, chnged FROM fv"
1333
+ "SELECT idv, fn, chnged, ridv FROM fv"
9101334
" WHERE idp>0 AND idv>0 AND idm=0"
9111335
);
9121336
while( db_step(&q)==SQLITE_ROW ){
9131337
int idv = db_column_int(&q, 0);
9141338
const char *zName = db_column_text(&q, 1);
9151339
int chnged = db_column_int(&q, 2);
1340
+ int ridv = db_column_int(&q, 3);
1341
+ int sz = -1;
1342
+ const char *zErrMsg = 0;
1343
+ int nc = 0;
9161344
/* Delete the file idv */
9171345
fossil_print("DELETE %s\n", zName);
9181346
if( chnged ){
1347
+ char *zFullPath;
9191348
fossil_warning("WARNING: local edits lost for %s", zName);
9201349
nConflict++;
1350
+ ridv = 0;
1351
+ nc = 1;
1352
+ zErrMsg = "local edits lost";
1353
+ zFullPath = mprintf("%s/%s", g.zLocalRoot, zName);
1354
+ sz = file_size(zFullPath, ExtFILE);
1355
+ fossil_free(zFullPath);
9211356
}
9221357
if( !dryRunFlag ) undo_save(zName);
9231358
db_multi_exec(
9241359
"UPDATE vfile SET deleted=1 WHERE id=%d", idv
9251360
);
@@ -926,10 +1361,20 @@
9261361
if( !dryRunFlag ){
9271362
char *zFullPath = mprintf("%s%s", g.zLocalRoot, zName);
9281363
file_delete(zFullPath);
9291364
free(zFullPath);
9301365
}
1366
+ db_multi_exec(
1367
+ "INSERT INTO localdb.mergestat(op,fnp,ridp,fn,ridv,sz,fnm,ridm,nc,msg)"
1368
+ "VALUES('DELETE',NULL,NULL,%Q,iif(%d,%d,NULL),iif(%d,%d,NULL),"
1369
+ "NULL,NULL,%d,%Q)",
1370
+ /* fn */ zName,
1371
+ /* ridv */ chnged==0, ridv,
1372
+ /* sz */ chnged!=0, sz,
1373
+ /* nc */ nc,
1374
+ /* msg */ zErrMsg
1375
+ );
9311376
}
9321377
db_finalize(&q);
9331378
9341379
/* For certain sets of renames (e.g. A -> B and B -> A), a file that is
9351380
** being renamed must first be moved to a temporary location to avoid
@@ -956,10 +1401,14 @@
9561401
const char *zNewName = db_column_text(&q, 2);
9571402
int isExe = db_column_int(&q, 3);
9581403
fossil_print("RENAME %s -> %s\n", zOldName, zNewName);
9591404
if( !dryRunFlag ) undo_save(zOldName);
9601405
if( !dryRunFlag ) undo_save(zNewName);
1406
+ db_multi_exec(
1407
+ "UPDATE mergestat SET fnr=fnm WHERE fnp=%Q",
1408
+ zOldName
1409
+ );
9611410
db_multi_exec(
9621411
"UPDATE vfile SET pathname=NULL, origname=pathname"
9631412
" WHERE vid=%d AND pathname=%Q;"
9641413
"UPDATE vfile SET pathname=%Q, origname=coalesce(origname,pathname)"
9651414
" WHERE id=%d;",
@@ -1009,11 +1458,11 @@
10091458
10101459
/*
10111460
** Insert into V any files that are not in V or P but are in M.
10121461
*/
10131462
db_prepare(&q,
1014
- "SELECT idm, fnm FROM fv"
1463
+ "SELECT idm, fnm, ridm FROM fv"
10151464
" WHERE idp=0 AND idv=0 AND idm>0"
10161465
);
10171466
while( db_step(&q)==SQLITE_ROW ){
10181467
int idm = db_column_int(&q, 0);
10191468
const char *zName;
@@ -1042,10 +1491,17 @@
10421491
nOverwrite++;
10431492
}else{
10441493
fossil_print("ADDED %s\n", zName);
10451494
}
10461495
fossil_free(zFullName);
1496
+ db_multi_exec(
1497
+ "INSERT INTO mergestat(op,fnm,ridm,fnr)"
1498
+ "VALUES('ADDED',%Q,%d,%Q)",
1499
+ /* fnm */ zName,
1500
+ /* ridm */ db_column_int(&q,2),
1501
+ /* fnr */ zName
1502
+ );
10471503
if( !dryRunFlag ){
10481504
undo_save(zName);
10491505
vfile_to_disk(0, idm, 0, 0);
10501506
}
10511507
}
10521508
10531509
ADDED src/merge.tcl
--- src/merge.c
+++ src/merge.c
@@ -20,10 +20,372 @@
20 */
21 #include "config.h"
22 #include "merge.h"
23 #include <assert.h>
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25 /*
26 ** Print information about a particular check-in.
27 */
28 void print_checkin_description(int rid, int indent, const char *zLabel){
29 Stmt q;
@@ -323,11 +685,11 @@
323 ** --force-missing Force the merge even if there is missing content
324 ** --integrate Merged branch will be closed when committing
325 ** -K|--keep-merge-files On merge conflict, retain the temporary files
326 ** used for merging, named *-baseline, *-original,
327 ** and *-merge.
328 ** -n|--dry-run If given, display instead of run actions
329 ** --nosync Do not auto-sync prior to merging
330 ** -v|--verbose Show additional details of the merge
331 */
332 void merge_cmd(void){
333 int vid; /* Current version "V" */
@@ -800,15 +1162,21 @@
800
801 /************************************************************************
802 ** All of the information needed to do the merge is now contained in the
803 ** FV table. Starting here, we begin to actually carry out the merge.
804 **
805 ** First, find files that have changed from P->M but not P->V.
 
 
 
 
 
806 ** Copy the M content over into V.
807 */
808 db_prepare(&q,
809 "SELECT idv, ridm, fn, islinkm FROM fv"
 
810 " WHERE idp>0 AND idv>0 AND idm>0"
811 " AND ridm!=ridp AND ridv=ridp AND NOT chnged"
812 );
813 while( db_step(&q)==SQLITE_ROW ){
814 int idv = db_column_int(&q, 0);
@@ -825,10 +1193,21 @@
825 " THEN (SELECT uuid FROM blob WHERE blob.rid=%d) END"
826 " WHERE id=%d", ridm, integrateFlag?4:2, islinkm, ridm, ridm, idv
827 );
828 vfile_to_disk(0, idv, 0, 0);
829 }
 
 
 
 
 
 
 
 
 
 
 
830 }
831 db_finalize(&q);
832
833 /*
834 ** Do a three-way merge on files that have changes on both P->M and P->V.
@@ -836,11 +1215,15 @@
836 ** Proceed even if the file doesn't exist on P, just like the common ancestor
837 ** of M and V is an empty file. In this case, merge conflict marks will be
838 ** added to the file and user will be forced to take a decision.
839 */
840 db_prepare(&q,
841 "SELECT ridm, idv, ridp, ridv, %s, fn, isexe, islinkv, islinkm FROM fv"
 
 
 
 
842 " WHERE idv>0 AND idm>0"
843 " AND ridm!=ridp AND (ridv!=ridp OR chnged)",
844 glob_expr("fv.fn", zBinGlob)
845 );
846 while( db_step(&q)==SQLITE_ROW ){
@@ -851,12 +1234,14 @@
851 int isBinary = db_column_int(&q, 4);
852 const char *zName = db_column_text(&q, 5);
853 int isExe = db_column_int(&q, 6);
854 int islinkv = db_column_int(&q, 7);
855 int islinkm = db_column_int(&q, 8);
 
856 int rc;
857 char *zFullPath;
 
858 Blob m, p, r;
859 /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */
860 if( verboseFlag ){
861 fossil_print("MERGE %s (pivot=%d v1=%d v2=%d)\n",
862 zName, ridp, ridm, ridv);
@@ -864,13 +1249,29 @@
864 fossil_print("MERGE %s\n", zName);
865 }
866 if( islinkv || islinkm ){
867 fossil_print("***** Cannot merge symlink %s\n", zName);
868 nConflict++;
 
 
 
 
 
 
 
 
 
 
 
869 }else{
 
 
 
 
870 if( !dryRunFlag ) undo_save(zName);
871 zFullPath = mprintf("%s/%s", g.zLocalRoot, zName);
 
872 content_get(ridp, &p);
873 content_get(ridm, &m);
874 if( isBinary ){
875 rc = -1;
876 blob_zero(&r);
@@ -887,15 +1288,38 @@
887 db_multi_exec("UPDATE vfile SET mtime=0 WHERE id=%d", idv);
888 if( rc>0 ){
889 fossil_print("***** %d merge conflict%s in %s\n",
890 rc, rc>1 ? "s" : "", zName);
891 nConflict++;
 
 
 
892 }
893 }else{
894 fossil_print("***** Cannot merge binary file %s\n", zName);
895 nConflict++;
 
 
 
896 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
897 blob_reset(&p);
898 blob_reset(&m);
899 blob_reset(&r);
900 }
901 vmerge_insert(idv, ridm);
@@ -904,22 +1328,33 @@
904
905 /*
906 ** Drop files that are in P and V but not in M
907 */
908 db_prepare(&q,
909 "SELECT idv, fn, chnged FROM fv"
910 " WHERE idp>0 AND idv>0 AND idm=0"
911 );
912 while( db_step(&q)==SQLITE_ROW ){
913 int idv = db_column_int(&q, 0);
914 const char *zName = db_column_text(&q, 1);
915 int chnged = db_column_int(&q, 2);
 
 
 
 
916 /* Delete the file idv */
917 fossil_print("DELETE %s\n", zName);
918 if( chnged ){
 
919 fossil_warning("WARNING: local edits lost for %s", zName);
920 nConflict++;
 
 
 
 
 
 
921 }
922 if( !dryRunFlag ) undo_save(zName);
923 db_multi_exec(
924 "UPDATE vfile SET deleted=1 WHERE id=%d", idv
925 );
@@ -926,10 +1361,20 @@
926 if( !dryRunFlag ){
927 char *zFullPath = mprintf("%s%s", g.zLocalRoot, zName);
928 file_delete(zFullPath);
929 free(zFullPath);
930 }
 
 
 
 
 
 
 
 
 
 
931 }
932 db_finalize(&q);
933
934 /* For certain sets of renames (e.g. A -> B and B -> A), a file that is
935 ** being renamed must first be moved to a temporary location to avoid
@@ -956,10 +1401,14 @@
956 const char *zNewName = db_column_text(&q, 2);
957 int isExe = db_column_int(&q, 3);
958 fossil_print("RENAME %s -> %s\n", zOldName, zNewName);
959 if( !dryRunFlag ) undo_save(zOldName);
960 if( !dryRunFlag ) undo_save(zNewName);
 
 
 
 
961 db_multi_exec(
962 "UPDATE vfile SET pathname=NULL, origname=pathname"
963 " WHERE vid=%d AND pathname=%Q;"
964 "UPDATE vfile SET pathname=%Q, origname=coalesce(origname,pathname)"
965 " WHERE id=%d;",
@@ -1009,11 +1458,11 @@
1009
1010 /*
1011 ** Insert into V any files that are not in V or P but are in M.
1012 */
1013 db_prepare(&q,
1014 "SELECT idm, fnm FROM fv"
1015 " WHERE idp=0 AND idv=0 AND idm>0"
1016 );
1017 while( db_step(&q)==SQLITE_ROW ){
1018 int idm = db_column_int(&q, 0);
1019 const char *zName;
@@ -1042,10 +1491,17 @@
1042 nOverwrite++;
1043 }else{
1044 fossil_print("ADDED %s\n", zName);
1045 }
1046 fossil_free(zFullName);
 
 
 
 
 
 
 
1047 if( !dryRunFlag ){
1048 undo_save(zName);
1049 vfile_to_disk(0, idm, 0, 0);
1050 }
1051 }
1052
1053 DDED src/merge.tcl
--- src/merge.c
+++ src/merge.c
@@ -20,10 +20,372 @@
20 */
21 #include "config.h"
22 #include "merge.h"
23 #include <assert.h>
24
25
26 /*
27 ** Bring up a Tcl/Tk GUI to show details of the most recent merge.
28 */
29 static void merge_info_tk(int bDark, int bAll, int nContext){
30 int i;
31 Blob script;
32 const char *zTempFile = 0;
33 char *zCmd;
34 const char *zTclsh;
35 zTclsh = find_option("tclsh",0,1);
36 if( zTclsh==0 ){
37 zTclsh = db_get("tclsh",0);
38 }
39 /* The undocumented --script FILENAME option causes the Tk script to
40 ** be written into the FILENAME instead of being run. This is used
41 ** for testing and debugging. */
42 zTempFile = find_option("script",0,1);
43 verify_all_options();
44
45 blob_zero(&script);
46 blob_appendf(&script, "set ncontext %d\n", nContext);
47 blob_appendf(&script, "set fossilcmd {| \"%/\" merge-info}\n",
48 g.nameOfExe);
49 blob_appendf(&script, "set filelist [list");
50 if( g.argc==2 ){
51 /* No files named on the command-line. Use every file mentioned
52 ** in the MERGESTAT table to generate the file list. */
53 Stmt q;
54 int cnt = 0;
55 db_prepare(&q,
56 "WITH priority(op,pri) AS (VALUES('CONFLICT',0),('ERROR',0),"
57 "('MERGE',1),('ADDED',2),('UPDATE',2))"
58 "SELECT coalesce(fnr,fn), op FROM mergestat JOIN priority USING(op)"
59 " %s ORDER BY pri, 1",
60 bAll ? "" : "WHERE op IN ('MERGE','CONFLICT')" /*safe-for-%s*/
61 );
62 while( db_step(&q)==SQLITE_ROW ){
63 blob_appendf(&script," %s ", db_column_text(&q,1));
64 blob_append_tcl_literal(&script, db_column_text(&q,0),
65 db_column_bytes(&q,0));
66 cnt++;
67 }
68 db_finalize(&q);
69 if( cnt==0 ){
70 fossil_print(
71 "No interesting changes in this merge. Use --all to see everything\n"
72 );
73 return;
74 }
75 }else{
76 /* Use only files named on the command-line in the file list.
77 ** But verify each file named is actually found in the MERGESTAT
78 ** table first. */
79 for(i=2; i<g.argc; i++){
80 char *zFile; /* Input filename */
81 char *zTreename; /* Name of the file in the tree */
82 Blob fname; /* Filename relative to root */
83 char *zOp; /* Operation on this file */
84 zFile = mprintf("%/", g.argv[i]);
85 file_tree_name(zFile, &fname, 0, 1);
86 fossil_free(zFile);
87 zTreename = blob_str(&fname);
88 zOp = db_text(0, "SELECT op FROM mergestat WHERE fn=%Q or fnr=%Q",
89 zTreename, zTreename);
90 blob_appendf(&script, " %s ", zOp);
91 fossil_free(zOp);
92 blob_append_tcl_literal(&script, zTreename, (int)strlen(zTreename));
93 blob_reset(&fname);
94 }
95 }
96 blob_appendf(&script, "]\n");
97 blob_appendf(&script, "set darkmode %d\n", bDark!=0);
98 blob_appendf(&script, "%s", builtin_file("merge.tcl", 0));
99 if( zTempFile ){
100 blob_write_to_file(&script, zTempFile);
101 fossil_print("To see the merge, run: %s \"%s\"\n", zTclsh, zTempFile);
102 }else{
103 #if defined(FOSSIL_ENABLE_TCL)
104 Th_FossilInit(TH_INIT_DEFAULT);
105 if( evaluateTclWithEvents(g.interp, &g.tcl, blob_str(&script),
106 blob_size(&script), 1, 1, 0)==TCL_OK ){
107 blob_reset(&script);
108 return;
109 }
110 /*
111 * If evaluation of the Tcl script fails, the reason may be that Tk
112 * could not be found by the loaded Tcl, or that Tcl cannot be loaded
113 * dynamically (e.g. x64 Tcl with x86 Fossil). Therefore, fallback
114 * to using the external "tclsh", if available.
115 */
116 #endif
117 zTempFile = write_blob_to_temp_file(&script);
118 zCmd = mprintf("%$ %$", zTclsh, zTempFile);
119 fossil_system(zCmd);
120 file_delete(zTempFile);
121 fossil_free(zCmd);
122 }
123 blob_reset(&script);
124 }
125
126 /*
127 ** Generate a TCL list on standard output that can be fed into the
128 ** merge.tcl script to show the details of the most recent merge
129 ** command associated with file "zFName". zFName must be the filename
130 ** relative to the root of the check-in - in other words a "tree name".
131 **
132 ** When this routine is called, we know that the mergestat table
133 ** exists, but we do not know if zFName is mentioned in that table.
134 */
135 static void merge_info_tcl(const char *zFName, int nContext){
136 const char *zTreename;/* Name of the file in the tree */
137 Stmt q; /* To query the MERGESTAT table */
138 MergeBuilder mb; /* The merge builder object */
139 Blob pivot,v1,v2,out; /* Blobs for holding content */
140 const char *zFN; /* A filename */
141 int rid; /* RID value */
142 int sz; /* File size value */
143
144 zTreename = zFName;
145 db_prepare(&q,
146 /* 0 1 2 3 4 5 6 7 */
147 "SELECT fnp, ridp, fn, ridv, sz, fnm, ridm, fnr"
148 " FROM mergestat"
149 " WHERE fnp=%Q OR fnr=%Q",
150 zTreename, zTreename
151 );
152 if( db_step(&q)!=SQLITE_ROW ){
153 db_finalize(&q);
154 fossil_print("ERROR {don't know anything about file: %s}\n", zTreename);
155 return;
156 }
157 mergebuilder_init_tcl(&mb);
158 mb.nContext = nContext;
159
160 /* Set up the pivot */
161 zFN = db_column_text(&q, 0);
162 if( zFN==0 ){
163 /* No pivot because the file was added */
164 mb.zPivot = "(no baseline)";
165 blob_zero(&pivot);
166 }else{
167 mb.zPivot = mprintf("%s (baseline)", file_tail(zFN));
168 rid = db_column_int(&q, 1);
169 content_get(rid, &pivot);
170 }
171 mb.pPivot = &pivot;
172
173 /* Set up the merge-in as V2 */
174 zFN = db_column_text(&q, 5);
175 if( zFN==0 ){
176 /* File deleted in the merged-in branch */
177 mb.zV2 = "(deleted file)";
178 blob_zero(&v2);
179 }else{
180 mb.zV2 = mprintf("%s (merge-in)", file_tail(zFN));
181 rid = db_column_int(&q, 6);
182 content_get(rid, &v2);
183 }
184 mb.pV2 = &v2;
185
186 /* Set up the local content as V1 */
187 zFN = db_column_text(&q, 2);
188 if( zFN==0 ){
189 /* File added by merge */
190 mb.zV1 = "(no original)";
191 blob_zero(&v1);
192 }else{
193 mb.zV1 = mprintf("%s (local)", file_tail(zFN));
194 rid = db_column_int(&q, 3);
195 sz = db_column_int(&q, 4);
196 if( rid==0 && sz>0 ){
197 /* The origin file had been edited so we'll have to pull its
198 ** original content out of the undo buffer */
199 Stmt q2;
200 db_prepare(&q2,
201 "SELECT content FROM undo"
202 " WHERE pathname=%Q AND octet_length(content)=%d",
203 zFN, sz
204 );
205 blob_zero(&v1);
206 if( db_step(&q2)==SQLITE_ROW ){
207 db_column_blob(&q2, 0, &v1);
208 }else{
209 mb.zV1 = "(local content missing)";
210 }
211 db_finalize(&q2);
212 }else{
213 /* The origin file was unchanged when the merge first occurred */
214 content_get(rid, &v1);
215 }
216 }
217 mb.pV1 = &v1;
218
219 /* Set up the output */
220 zFN = db_column_text(&q, 7);
221 if( zFN==0 ){
222 mb.zOut = "(Merge Result)";
223 }else{
224 mb.zOut = mprintf("%s (after merge)", file_tail(zFN));
225 }
226 blob_zero(&out);
227 mb.pOut = &out;
228
229 merge_three_blobs(&mb);
230 blob_write_to_file(&out, "-");
231
232 mb.xDestroy(&mb);
233 blob_reset(&pivot);
234 blob_reset(&v1);
235 blob_reset(&v2);
236 blob_reset(&out);
237 db_finalize(&q);
238 }
239
240 /*
241 ** COMMAND: merge-info
242 **
243 ** Usage: %fossil merge-info [OPTIONS]
244 **
245 ** Display information about the most recent merge operation.
246 **
247 ** Options:
248 ** -a|--all Show all file changes that happened because of
249 ** the merge. Normally only MERGE, CONFLICT, and ERROR
250 ** lines are shown
251 ** -c|--context N Show N lines of context around each change,
252 ** with negative N meaning show all content. Only
253 ** meaningful in combination with --tcl or --tk.
254 ** --dark Use dark mode for the Tcl/Tk-based GUI
255 ** --tcl FILE Generate (to stdout) a TCL list containing
256 ** information needed to display the changes to
257 ** FILE caused by the most recent merge. FILE must
258 ** be a pathname relative to the root of the check-out.
259 ** --tk Bring up a Tcl/Tk GUI that shows the changes
260 ** associated with the most recent merge.
261 **
262 */
263 void merge_info_cmd(void){
264 const char *zCnt;
265 const char *zTcl;
266 int bTk;
267 int bDark;
268 int bAll;
269 int nContext;
270 Stmt q;
271 const char *zWhere;
272 int cnt = 0;
273
274 db_must_be_within_tree();
275 zTcl = find_option("tcl", 0, 1);
276 bTk = find_option("tk", 0, 0)!=0;
277 zCnt = find_option("context", "c", 1);
278 bDark = find_option("dark", 0, 0)!=0;
279 bAll = find_option("all", "a", 0)!=0;
280 if( bTk==0 ){
281 verify_all_options();
282 if( g.argc>2 ){
283 usage("[OPTIONS]");
284 }
285 }
286 if( zCnt ){
287 nContext = atoi(zCnt);
288 if( nContext<0 ) nContext = 0xfffffff;
289 }else{
290 nContext = 6;
291 }
292 if( !db_table_exists("localdb","mergestat") ){
293 if( zTcl ){
294 fossil_print("ERROR {no merge data available}\n");
295 }else{
296 fossil_print("No merge data is available\n");
297 }
298 return;
299 }
300 if( bTk ){
301 merge_info_tk(bDark, bAll, nContext);
302 return;
303 }
304 if( zTcl ){
305 merge_info_tcl(zTcl, nContext);
306 return;
307 }
308 if( bAll ){
309 zWhere = "";
310 }else{
311 zWhere = "WHERE op IN ('MERGE','CONFLICT','ERROR')";
312 }
313 db_prepare(&q,
314 "WITH priority(op,pri) AS (VALUES('CONFLICT',0),('ERROR',0),"
315 "('MERGE',1),('ADDED',2),('UPDATE',2))"
316
317 /* 0 1 2 */
318 "SELECT op, coalesce(fnr,fn), msg"
319 " FROM mergestat JOIN priority USING(op)"
320 " %s"
321 " ORDER BY pri, coalesce(fnr,fn)",
322 zWhere /*safe-for-%s*/
323 );
324 while( db_step(&q)==SQLITE_ROW ){
325 const char *zOp = db_column_text(&q, 0);
326 const char *zName = db_column_text(&q, 1);
327 const char *zErr = db_column_text(&q, 2);
328 if( zErr && fossil_strcmp(zOp,"CONFLICT")!=0 ){
329 fossil_print("%-9s %s (%s)\n", zOp, zName, zErr);
330 }else{
331 fossil_print("%-9s %s\n", zOp, zName);
332 }
333 cnt++;
334 }
335 db_finalize(&q);
336 if( !bAll && cnt==0 ){
337 fossil_print(
338 "No interesting changes in this merge. Use --all to see everything.\n"
339 );
340 }
341 }
342
343 /*
344 ** Erase all information about prior merges. Do this, for example, after
345 ** a commit.
346 */
347 void merge_info_forget(void){
348 db_multi_exec(
349 "DROP TABLE IF EXISTS localdb.mergestat;"
350 "DELETE FROM localdb.vvar WHERE name glob 'mergestat-*';"
351 );
352 }
353
354
355 /*
356 ** Initialize the MERGESTAT table.
357 **
358 ** Notes about mergestat:
359 **
360 ** * ridv is a positive integer and sz is NULL if the V file contained
361 ** no local edits prior to the merge. If the V file was modified prior
362 ** to the merge then ridv is NULL and sz is the size of the file prior
363 ** to merge.
364 **
365 ** * fnp, ridp, fn, ridv, and sz are all NULL for a file that was
366 ** added by merge.
367 */
368 void merge_info_init(void){
369 merge_info_forget();
370 db_multi_exec(
371 "CREATE TABLE localdb.mergestat(\n"
372 " op TEXT, -- 'UPDATE', 'ADDED', 'MERGE', etc...\n"
373 " fnp TEXT, -- Name of the pivot file (P)\n"
374 " ridp INT, -- RID for the pivot file\n"
375 " fn TEXT, -- Name of origin file (V)\n"
376 " ridv INT, -- RID for origin file, or NULL if previously edited\n"
377 " sz INT, -- Size of origin file in bytes, NULL if unedited\n"
378 " fnm TEXT, -- Name of the file being merged in (M)\n"
379 " ridm INT, -- RID for the merge-in file\n"
380 " fnr TEXT, -- Name of the final output file, after all renaming\n"
381 " nc INT DEFAULT 0, -- Number of conflicts\n"
382 " msg TEXT -- Error message\n"
383 ");"
384 );
385 }
386
387 /*
388 ** Print information about a particular check-in.
389 */
390 void print_checkin_description(int rid, int indent, const char *zLabel){
391 Stmt q;
@@ -323,11 +685,11 @@
685 ** --force-missing Force the merge even if there is missing content
686 ** --integrate Merged branch will be closed when committing
687 ** -K|--keep-merge-files On merge conflict, retain the temporary files
688 ** used for merging, named *-baseline, *-original,
689 ** and *-merge.
690 ** -n|--dry-run Do not actually change files on disk
691 ** --nosync Do not auto-sync prior to merging
692 ** -v|--verbose Show additional details of the merge
693 */
694 void merge_cmd(void){
695 int vid; /* Current version "V" */
@@ -800,15 +1162,21 @@
1162
1163 /************************************************************************
1164 ** All of the information needed to do the merge is now contained in the
1165 ** FV table. Starting here, we begin to actually carry out the merge.
1166 **
1167 ** Begin by constructing the localdb.mergestat table.
1168 */
1169 merge_info_init();
1170
1171 /*
1172 ** Find files that have changed from P->M but not P->V.
1173 ** Copy the M content over into V.
1174 */
1175 db_prepare(&q,
1176 /* 0 1 2 3 4 5 6 7 */
1177 "SELECT idv, ridm, fn, islinkm, fnp, ridp, ridv, fnm FROM fv"
1178 " WHERE idp>0 AND idv>0 AND idm>0"
1179 " AND ridm!=ridp AND ridv=ridp AND NOT chnged"
1180 );
1181 while( db_step(&q)==SQLITE_ROW ){
1182 int idv = db_column_int(&q, 0);
@@ -825,10 +1193,21 @@
1193 " THEN (SELECT uuid FROM blob WHERE blob.rid=%d) END"
1194 " WHERE id=%d", ridm, integrateFlag?4:2, islinkm, ridm, ridm, idv
1195 );
1196 vfile_to_disk(0, idv, 0, 0);
1197 }
1198 db_multi_exec(
1199 "INSERT INTO mergestat(op,fnp,ridp,fn,ridv,fnm,ridm,fnr)"
1200 "VALUES('UPDATE',%Q,%d,%Q,%d,%Q,%d,%Q)",
1201 /* fnp */ db_column_text(&q, 4),
1202 /* ridp */ db_column_int(&q,5),
1203 /* fn */ zName,
1204 /* ridv */ db_column_int(&q,6),
1205 /* fnm */ db_column_text(&q, 7),
1206 /* ridm */ ridm,
1207 /* fnr */ zName
1208 );
1209 }
1210 db_finalize(&q);
1211
1212 /*
1213 ** Do a three-way merge on files that have changes on both P->M and P->V.
@@ -836,11 +1215,15 @@
1215 ** Proceed even if the file doesn't exist on P, just like the common ancestor
1216 ** of M and V is an empty file. In this case, merge conflict marks will be
1217 ** added to the file and user will be forced to take a decision.
1218 */
1219 db_prepare(&q,
1220 /* 0 1 2 3 4 5 6 7 8 */
1221 "SELECT ridm, idv, ridp, ridv, %z, fn, isexe, islinkv, islinkm,"
1222 /* 9 10 11 */
1223 " fnp, fnm, chnged"
1224 " FROM fv"
1225 " WHERE idv>0 AND idm>0"
1226 " AND ridm!=ridp AND (ridv!=ridp OR chnged)",
1227 glob_expr("fv.fn", zBinGlob)
1228 );
1229 while( db_step(&q)==SQLITE_ROW ){
@@ -851,12 +1234,14 @@
1234 int isBinary = db_column_int(&q, 4);
1235 const char *zName = db_column_text(&q, 5);
1236 int isExe = db_column_int(&q, 6);
1237 int islinkv = db_column_int(&q, 7);
1238 int islinkm = db_column_int(&q, 8);
1239 int chnged = db_column_int(&q, 11);
1240 int rc;
1241 char *zFullPath;
1242 const char *zType = "MERGE";
1243 Blob m, p, r;
1244 /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */
1245 if( verboseFlag ){
1246 fossil_print("MERGE %s (pivot=%d v1=%d v2=%d)\n",
1247 zName, ridp, ridm, ridv);
@@ -864,13 +1249,29 @@
1249 fossil_print("MERGE %s\n", zName);
1250 }
1251 if( islinkv || islinkm ){
1252 fossil_print("***** Cannot merge symlink %s\n", zName);
1253 nConflict++;
1254 db_multi_exec(
1255 "INSERT INTO mergestat(op,fnp,ridp,fn,ridv,fnm,ridm,fnr,nc,msg)"
1256 "VALUES('ERROR',%Q,%d,%Q,%d,%Q,%d,%Q,1,'cannot merge symlink')",
1257 /* fnp */ db_column_text(&q, 9),
1258 /* ridp */ ridp,
1259 /* fn */ zName,
1260 /* ridv */ ridv,
1261 /* fnm */ db_column_text(&q, 10),
1262 /* ridm */ ridm,
1263 /* fnr */ zName
1264 );
1265 }else{
1266 i64 sz;
1267 const char *zErrMsg = 0;
1268 int nc = 0;
1269
1270 if( !dryRunFlag ) undo_save(zName);
1271 zFullPath = mprintf("%s/%s", g.zLocalRoot, zName);
1272 sz = file_size(zFullPath, ExtFILE);
1273 content_get(ridp, &p);
1274 content_get(ridm, &m);
1275 if( isBinary ){
1276 rc = -1;
1277 blob_zero(&r);
@@ -887,15 +1288,38 @@
1288 db_multi_exec("UPDATE vfile SET mtime=0 WHERE id=%d", idv);
1289 if( rc>0 ){
1290 fossil_print("***** %d merge conflict%s in %s\n",
1291 rc, rc>1 ? "s" : "", zName);
1292 nConflict++;
1293 nc = rc;
1294 zErrMsg = "merge conflicts";
1295 zType = "CONFLICT";
1296 }
1297 }else{
1298 fossil_print("***** Cannot merge binary file %s\n", zName);
1299 nConflict++;
1300 nc = 1;
1301 zErrMsg = "cannot merge binary file";
1302 zType = "ERROR";
1303 }
1304 db_multi_exec(
1305 "INSERT INTO mergestat(op,fnp,ridp,fn,ridv,sz,fnm,ridm,fnr,nc,msg)"
1306 "VALUES(%Q,%Q,%d,%Q,iif(%d,%d,NULL),iif(%d,%lld,NULL),%Q,%d,"
1307 "%Q,%d,%Q)",
1308 /* op */ zType,
1309 /* fnp */ db_column_text(&q, 9),
1310 /* ridp */ ridp,
1311 /* fn */ zName,
1312 /* ridv */ chnged==0, ridv,
1313 /* sz */ chnged!=0, sz,
1314 /* fnm */ db_column_text(&q, 10),
1315 /* ridm */ ridm,
1316 /* fnr */ zName,
1317 /* nc */ nc,
1318 /* msg */ zErrMsg
1319 );
1320 fossil_free(zFullPath);
1321 blob_reset(&p);
1322 blob_reset(&m);
1323 blob_reset(&r);
1324 }
1325 vmerge_insert(idv, ridm);
@@ -904,22 +1328,33 @@
1328
1329 /*
1330 ** Drop files that are in P and V but not in M
1331 */
1332 db_prepare(&q,
1333 "SELECT idv, fn, chnged, ridv FROM fv"
1334 " WHERE idp>0 AND idv>0 AND idm=0"
1335 );
1336 while( db_step(&q)==SQLITE_ROW ){
1337 int idv = db_column_int(&q, 0);
1338 const char *zName = db_column_text(&q, 1);
1339 int chnged = db_column_int(&q, 2);
1340 int ridv = db_column_int(&q, 3);
1341 int sz = -1;
1342 const char *zErrMsg = 0;
1343 int nc = 0;
1344 /* Delete the file idv */
1345 fossil_print("DELETE %s\n", zName);
1346 if( chnged ){
1347 char *zFullPath;
1348 fossil_warning("WARNING: local edits lost for %s", zName);
1349 nConflict++;
1350 ridv = 0;
1351 nc = 1;
1352 zErrMsg = "local edits lost";
1353 zFullPath = mprintf("%s/%s", g.zLocalRoot, zName);
1354 sz = file_size(zFullPath, ExtFILE);
1355 fossil_free(zFullPath);
1356 }
1357 if( !dryRunFlag ) undo_save(zName);
1358 db_multi_exec(
1359 "UPDATE vfile SET deleted=1 WHERE id=%d", idv
1360 );
@@ -926,10 +1361,20 @@
1361 if( !dryRunFlag ){
1362 char *zFullPath = mprintf("%s%s", g.zLocalRoot, zName);
1363 file_delete(zFullPath);
1364 free(zFullPath);
1365 }
1366 db_multi_exec(
1367 "INSERT INTO localdb.mergestat(op,fnp,ridp,fn,ridv,sz,fnm,ridm,nc,msg)"
1368 "VALUES('DELETE',NULL,NULL,%Q,iif(%d,%d,NULL),iif(%d,%d,NULL),"
1369 "NULL,NULL,%d,%Q)",
1370 /* fn */ zName,
1371 /* ridv */ chnged==0, ridv,
1372 /* sz */ chnged!=0, sz,
1373 /* nc */ nc,
1374 /* msg */ zErrMsg
1375 );
1376 }
1377 db_finalize(&q);
1378
1379 /* For certain sets of renames (e.g. A -> B and B -> A), a file that is
1380 ** being renamed must first be moved to a temporary location to avoid
@@ -956,10 +1401,14 @@
1401 const char *zNewName = db_column_text(&q, 2);
1402 int isExe = db_column_int(&q, 3);
1403 fossil_print("RENAME %s -> %s\n", zOldName, zNewName);
1404 if( !dryRunFlag ) undo_save(zOldName);
1405 if( !dryRunFlag ) undo_save(zNewName);
1406 db_multi_exec(
1407 "UPDATE mergestat SET fnr=fnm WHERE fnp=%Q",
1408 zOldName
1409 );
1410 db_multi_exec(
1411 "UPDATE vfile SET pathname=NULL, origname=pathname"
1412 " WHERE vid=%d AND pathname=%Q;"
1413 "UPDATE vfile SET pathname=%Q, origname=coalesce(origname,pathname)"
1414 " WHERE id=%d;",
@@ -1009,11 +1458,11 @@
1458
1459 /*
1460 ** Insert into V any files that are not in V or P but are in M.
1461 */
1462 db_prepare(&q,
1463 "SELECT idm, fnm, ridm FROM fv"
1464 " WHERE idp=0 AND idv=0 AND idm>0"
1465 );
1466 while( db_step(&q)==SQLITE_ROW ){
1467 int idm = db_column_int(&q, 0);
1468 const char *zName;
@@ -1042,10 +1491,17 @@
1491 nOverwrite++;
1492 }else{
1493 fossil_print("ADDED %s\n", zName);
1494 }
1495 fossil_free(zFullName);
1496 db_multi_exec(
1497 "INSERT INTO mergestat(op,fnm,ridm,fnr)"
1498 "VALUES('ADDED',%Q,%d,%Q)",
1499 /* fnm */ zName,
1500 /* ridm */ db_column_int(&q,2),
1501 /* fnr */ zName
1502 );
1503 if( !dryRunFlag ){
1504 undo_save(zName);
1505 vfile_to_disk(0, idm, 0, 0);
1506 }
1507 }
1508
1509 DDED src/merge.tcl
+581
--- a/src/merge.tcl
+++ b/src/merge.tcl
@@ -0,0 +1,581 @@
1
+# Show details of a 3-way merge operation. The left-most column is the
2
+# common ancestor. The next two columns are edits of that common ancestor.
3
+# The right-most column is the result of the merge.
4
+#
5
+# There is always a "fossilcmd" variable which tells the script how to
6
+# invoke Fossil to get the information it needs. This script will
7
+# automatically append "-c N" to tell Fossil how much context it wants. True for debugging output
8
+#
9
+# If the "filelist" global variable is defined, then it is a list of
10
+# alternating "merge-type names" (ex: UPDATE, MERGE, CONFLICT, ERROR) and
11
+# filenames. In that case, the initial display shows the changes for
12
+# the first pair on the list and there is a optionmenu that allows the
13
+# useelect otheere should also be a global variable named "ncontext" which is the
14
+# number of lines of context to display. The value of this variable
15
+# controls the "-c N" argument that is appended to fossilcmdht {
16
+ TITLE {Fossil Merge}
17
+ LN_COL_BG #dddddd
18
+ LN_COL_FG #444444
19
+ TXT_COL_BG #ffffff
20
+ TXT_COL_FG #000000
21
+ MKR_COL_BG #444444
22
+ MKR_COL_FG #dddddd
23
+ CHNG_BG #d0d070
24
+ ADD_BG #c0ffc0
25
+ RM_BG #ffc0c0
26
+ HR_FG #444444
27
+ HR_PAD_TOP 4
28
+ HR_PAD_BTM 8
29
+ FN_BG #444444
30
+ FN_FG #ffffff
31
+ FN_PAD 5
32
+ ERR_FG #ee0000
33
+ PADX 5
34
+ WIDTH 80
35
+ HEIGHT 45
36
+ LB_HEIGHT 25
37
+}
38
+
39
+array set CFG_dark {
40
+ TITLE {Fossil Merge}
41
+ LN_COL_BG #dddddd
42
+ LN_COL_FG #444444
43
+ TXT_COL_BG #3f3f3f
44
+ TXT_COL_FG #dcdccc
45
+ MKR_COL_BG #444444
46
+ MKR_COL_FG #dddddd
47
+ CHNG_BG #6a6a00
48
+ ADD_BG #57934c
49
+ RM_BG #ef6767
50
+ HR_FG #444444
51
+ HR_PAD_TOP 4
52
+ HR_PAD_BTM 8
53
+ FN_BG #5e5e5e
54
+ FN_FG #ffffff
55
+ FN_PAD 5
56
+ ERR_FG #ee0000
57
+ PADX 5
58
+ WIDTH 80
59
+ HEIGHT 45
60
+ LB_HEIGHT 25
61
+}
62
+
63
+array set CFG_arr {
64
+ 0 CFG_light
65
+ 1 CFG_dark
66
+}
67
+
68
+array set CFG [array get $CFG_arr($darkmode)]
69
+
70
+if {![namespace exists ttk]} {
71
+ interp alias {} ::ttk::scrollbar {} ::scrollbar
72
+ interp alias {} ::ttk::menubutton {} ::menubutton
73
+}
74
+
75
+proc dehtml {x} {
76
+ set x [regsub -all {<[^>]*>} $x {}]
77
+ return [string map {&amp; & &lt; < &gt; > &#39; ' &quot; \"} $x]
78
+}
79
+
80
+proc cols {} {
81
+ return [list .lnA .txtA .lnB .txtB .lnC .txtC .lnD .txtD]
82
+}
83
+
84
+proc colType {c} {
85
+ regexp {[a-z]+} $c type
86
+ return $type
87
+}
88
+
89
+proc readMercmdes currentails of a 3-way merge operation# Show det for
90
+# the first pair on the list and there is a optionmenu that allows the
91
+# user to select other fiels on the list.
92
+#
93
+# This header comment is stripped off by the "mkbuiltin.c" program.
94
+#
95
+package require Tk
96
+
97
+array set CFG_light {
98
+ TITLE {Fossil Merge}
99
+ LN_COL_BG #dddddd
100
+ LN_COL_FG #444444
101
+ TXT_COL_BG #ffffff
102
+ TXT_COL_FG #000000
103
+ MKR_COL_BG #444444
104
+ MKR_COL_FG #dddddd
105
+ CHNG_BG #d0d070
106
+ ADD_BG #c0ffc0
107
+ RM_BG #ffc0c0
108
+ HR_FG #444444
109
+ HR_PAD_TOP 4
110
+ HR_PAD_BTM 8
111
+ FN_BG #444444
112
+ FN_FG #ffffff
113
+ FN_PAD 5
114
+ ERR_FG #ee0000
115
+ PADX 5
116
+ WIDTH 80
117
+ HEIGHT 45
118
+ LB_HEIGHT 25
119
+}
120
+
121
+array set CFG_dark {
122
+ TITLE {Fossil Merge}
123
+ LN_COL_BG #dddddd
124
+ LN_COL_FG #444444
125
+ TXT_COL_BG #3f3f3f
126
+ TXT_COL_FG #dcdccc
127
+ MKR_COL_BG #444444
128
+ MKR_COL_FG #dddddd
129
+ CHNG_BG #6a6a00
130
+ ADD_BG #57934c
131
+ RM_BG #ef6767
132
+ HR_FG #444444
133
+ HR_PAD_TOP 4
134
+ HR_PAD_BTM 8
135
+ FN_BG #5e5e5e
136
+ FN_FG #ffffff
137
+ FN_PAD 5
138
+ ERR_FG #ee0000
139
+ PADX 5
140
+ WIDTH 80
141
+ HEIGHT 45
142
+ LB_HEIGHT 25
143
+}
144
+
145
+array set CFG_arr {
146
+ 0 CFG_light
147
+ 1 CFG_dark
148
+}
149
+
150
+array set CFG [array get $CFG_arr($darkmode)]
151
+
152
+if {![namespace exists ttk]} {
153
+ interp alias {} ::ttk::scrollbar {} ::scrollbar
154
+ interp alias {} ::ttk::menubutton {} ::menubutton
155
+}
156
+
157
+proc dehtml {x} {
158
+ set x [regsub -all {<[^>]*>} $x {}]
159
+ return [string map {&amp; & &lt; < &gt; > &#39; ' &quot; \"} $x]
160
+}
161
+
162
+proc cols {} {
163
+ return [list .lnA .txtA .lnB .txtB .lnC .txtC .lnD .txtD]
164
+}
165
+
166
+proc colType {c} {
167
+ regexp {[a-z]+} $c type
168
+ return $type
169
+}
170
+
171
+proc readMerge {args} {
172
+ global fossilexe ncontext current_file debug
173
+ if {$ncontext=="All"} {
174
+ set cmd "| $fossilexe merge-info -c -1"
175
+ } else {
176
+ set cmd "| $fossilexe merge-info -c $ncontext"
177
+ }
178
+ if {[info exists current_file]} {
179
+ regsub {^[A-Z]+ } $current_file {} fn
180
+ lappend cmd -tcl $fn
181
+ }
182
+ if {$debug} {
183
+ regsub {^\| +} $cmd {} cmd2
184
+ puts $cmd2
185
+ flush stdout
186
+ }
187
+ if {[catch {
188
+ set in [open $cmd r]
189
+ fconfigure $in -encoding utf-8
190
+ set mergetxt [read $in]
191
+ close $in
192
+ } msg]} {
193
+ tk_messageBox -message "Unable to run command: \"$cmd\""
194
+ set mergetxt {}
195
+ }
196
+ foreach c [cols] {
197
+ $c config -state normal
198
+ $c delete 1.0 end
199
+ }
200
+ set lnA 1
201
+ set lnB 1
202
+ set lnC 1
203
+ set lnD 1
204
+ foreach {A B C D} $mergetxt {
205
+ set key1 [string index $A 0]
206
+ if {$key1=="S"} {
207
+ scan [string range $A 1 end] "%d %d %d %d" nA nB nC nD
208
+ foreach x {A B C D} {
209
+ set N [set n$x]
210
+ incr ln$x $N
211
+ if {$N>0} {
212
+ .ln$x insert end ...\n hrln
213
+ .txt$x insert end [string repeat . 30]\n hrtxt
214
+ } else {
215
+ .ln$x insert end \n hrln
216
+ .txt$x insert end \n hrtxt
217
+ }
218
+ }
219
+ continue
220
+ }
221
+ set key2 [string index $B 0]
222
+ set key3 [string index $C 0]
223
+ set key4 [string index $D 0]
224
+ if {$key1=="."} {
225
+ .lnA insert end \n -
226
+ .txtA insert end \n -
227
+ } elseif {$key1=="N"} {
228
+ .nameA config -text [string range $A 1 end]
229
+ } else {
230
+ .lnA insert end $lnA\n -
231
+ incr lnA
232
+ if {$key1=="X"} {
233
+ .txtA insert end [string range $A 1 end]\n rm
234
+ } else {
235
+ .txtA insert end [string range $A 1 end]\n -
236
+ }
237
+ }
238
+ if {$key2=="."} {
239
+ .lnB insert end \n -
240
+ .txtB insert end \n -
241
+ } elseif {$key2=="N"} {
242
+ .nameB config -text [string range $B 1 end]
243
+ } else {
244
+ .lnB insert end $lnB\n -
245
+ incr lnB
246
+ if {$key4=="2"} {set tag chng} {set tag -}
247
+ if {$key2=="1"} {
248
+ .txtB insert end [string range $A 1 end]\n $tag
249
+ } elseif {$key2=="X"} {
250
+ .txtB insert end [string range $B 1 end]\n rm
251
+ } else {
252
+ .txtB insert end [string range $B 1 end]\n $tag
253
+ }
254
+ }
255
+ if {$key3=="."} {
256
+ .lnC insert end \n -
257
+ .txtC insert end \n -
258
+ } elseif {$key3=="N"} {
259
+ .nameC config -text [string range $C 1 end]
260
+ } else {
261
+ .lnC insert end $lnC\n -
262
+ incr lnC
263
+ if {$key4=="3"} {set tag add} {set tag -}
264
+ if {$key3=="1"} {
265
+ .txtC insert end [string range $A 1 end]\n $tag
266
+ } elseif {$key3=="2"} {
267
+ .txtC insert end [string range $B 1 end]\n chng
268
+ } elseif {$key3=="X"} {
269
+ .txtC insert end [string range $C 1 end]\n rm
270
+ } else {
271
+ .txtC insert end [string range $C 1 end]\n $tag
272
+ }
273
+ }
274
+ if {$key4=="."} {
275
+ .lnD insert end \n -
276
+ .txtD insert end \n -
277
+ } elseif {$key4=="N"} {
278
+ .nameD config -text [string range $D 1 end]
279
+ } else {
280
+ .lnD insert end $lnD\n -
281
+ incr lnD
282
+ if {$key4=="1"} {
283
+ .txtD insert end [string range $A 1 end]\n -
284
+ } elseif {$key4=="2"} {
285
+ .txtD insert end [string range $B 1 end]\n chng
286
+ } elseif {$key4=="3"} {
287
+ .txtD insert end [string range $C 1 end]\n add
288
+ } elseif {$key4=="X"} {
289
+ .txtD insert end [string range $D 1 end]\n rm
290
+ } else {
291
+ .txtD insert end [string range $D 1 end]\n -
292
+ }
293
+ }
294
+ }
295
+ foreach c [cols] {
296
+ set type [colType $c]
297
+ if {$type ne "txt"} {
298
+ $c config -width 6; # $widths($type)
299
+ }
300
+ $c config -state disabled
301
+ }
302
+ set mx $lnA
303
+ if {$lnB>$mx} {set mx $lnB}
304
+ if {$lnC>$mx} {set mx $lnC}
305
+ if {$lnD>$mx} {set mx $lnD}
306
+ global lnWidth
307
+ set lnWidth [string length [format +%d $mx]]
308
+ .lnA config -width $lnWidth
309
+ .lnB config -width $lnWidth
310
+ .lnC config -width $lnWidth
311
+ .lnD config -width $lnWidth
312
+ grid columnconfig . {0 2 4 6} -minsize $lnWidth
313
+}
314
+
315
+proc viewDiff {idx} {
316
+ .txtA yview $idx
317
+ .txtA xview moveto 0
318
+}
319
+
320
+proc cycleDiffs {{reverse 0}} {
321
+ if {$reverse} {
322
+ set range [.txtA tag prevrange fn @0,0 1.0]
323
+ if {$range eq ""} {
324
+ viewDiff {fn.last -1c}
325
+ } else {
326
+ viewDiff [lindex $range 0]
327
+ }
328
+ } else {
329
+ set range [.txtA tag nextrange fn {@0,0 +1c} end]
330
+ if {$range eq "" || [lindex [.txtA yview] 1] == 1} {
331
+ viewDiff fn.first
332
+ } else {
333
+ viewDiff [lindex $range 0]
334
+ }
335
+ }
336
+}
337
+
338
+proc xvis {col} {
339
+ set view [$col xview]
340
+ return [expr {[lindex $view 1]-[lindex $view 0]}]
341
+}
342
+
343
+proc scroll-x {args} {
344
+ set c .txt[expr {[xvis .txtA] < [xvis .txtB] ? "A" : "B"}]
345
+ eval $c xview $args
346
+}
347
+
348
+interp alias {} scroll-y {} .txtA yview
349
+
350
+proc noop {args} {}
351
+
352
+proc enableSync {axis} {
353
+ update idletasks
354
+ interp alias {} sync-$axis {}
355
+ rename _sync-$axis sync-$axis
356
+}
357
+
358
+proc disableSync {axis} {
359
+ rename sync-$axis _sync-$axis
360
+ interp alias {} sync-$axis {} noop
361
+}
362
+
363
+proc sync-y {first last} {
364
+ disableSync y
365
+ foreach c [cols] {
366
+ $c yview moveto $first
367
+ }
368
+ if {$first > 0 || $last < 1} {
369
+ grid .sby
370
+ .sby set $first $last
371
+ } else {
372
+ grid remove .sby
373
+ }
374
+ enableSync y
375
+}
376
+
377
+wm withdraw .
378
+wm title . $CFG(TITLE)
379
+wm iconname . $CFG(TITLE)
380
+# Keystroke bindings for on the top-level window for navigation and
381
+# control also fire when those same keystrokes are pressed in the
382
+# Search entry box. Disable them, to prevent the diff screen from
383
+# disappearing abruptly and unexpectedly when searching for "q".
384
+#
385
+bind . <Control-q> exit
386
+bind . <Control-p> {catch searchPrev; break}
387
+bind . <Control-n> {catch searchNext; break}
388
+bind . <Escape><Escape> exit
389
+bind . <Destroy> {after 0 exit}
390
+bind . <Tab> {cycleDiffs; break}
391
+bind . <<PrevWindow>> {cycleDiffs 1; break}
392
+bind . <Control-f> {searchOnOff; break}
393
+bind . <Control-g> {catch searchNext; break}
394
+bind . <Return> {
395
+ event generate .bb.files <1>
396
+ event generate .bb.files <ButtonRelease-1>
397
+ break
398
+}
399
+foreach {key axis args} {
400
+ Up y {scroll -5 units}
401
+ k y {scroll -5 units}
402
+ Down y {scroll 5 units}
403
+ j y {scroll 5 units}
404
+ Left x {scroll -5 units}
405
+ h x {scroll -5 units}
406
+ Right x {scroll 5 units}
407
+ l x {scroll 5 units}
408
+ Prior y {scroll -1 page}
409
+ b y {scroll -1 page}
410
+ Next y {scroll 1 page}
411
+ space y {scroll 1 page}
412
+ Home y {moveto 0}
413
+ g y {moveto 0}
414
+ End y {moveto 1}
415
+} {
416
+ bind . <$key> "scroll-$axis $args; break"
417
+ bind . <Shift-$key> continue
418
+}
419
+
420
+frame .bb
421
+::ttk::menubutton .bb.diff2 -text {2-way diffs
422
+.bb.diff2.m add command -label {baseline vs. local} -command {two-way 12}
423
+.bb.diff2.m add command -label {baseline vs. merge-in} -command {two-way 13}
424
+.bb.diff2.m add command -label {local vs. merge-in} -command {two-way 23}
425
+
426
+# Bring up a separate two-way diff between a pair of columns
427
+# the argument is one of:
428
+# 12 Baseline versus Local
429
+# 13 Baseline versus Merge-in
430
+# 23 Local versus Merge-in
431
+#
432
+proc two-way {mode} {
433
+ global current_file fossilexe debug darkmode ncontext
434
+ regsub {^[A-Z]+ } $current_file {} fn
435
+ set cmd $fossilexe
436
+ lappend cmd merge-info --diff$mode $fn -c $ncontext
437
+ if {$darkmode} {
438
+ lappend cmd --dark
439
+ }
440
+ if {$debug} {
441
+ lappend cc {*}$cmd &
442
+}
443
+
444
+set useOptionMenu 1
445
+if {[info exists filelist]} {
446
+ set current_file "[lindex $filelist 0] [lindex $filelist 1]"
447
+ if {[llength $filelist]>2} {
448
+ trace add variable current_file write readMerge
449
+
450
+ if {$tcl_platform(os)=="Darwin" || [llength $filelist]<30} {
451
+ set fnlist {}
452
+ foreach {op fn} $filelist {lappend fnlist "$op $fn"}
453
+ tk_optionMenu .bb.files current_file {*}$fnlist
454
+ } else {
455
+ set useOptionMenu 0
456
+ ::ttk::menubutton .bb.files -text $current_file
457
+ if {[tk windowingsystem] eq "win32"} {
458
+ ::ttk::style theme use winnative
459
+ .bb.files configure -padding {20 1 10 2}
460
+ }
461
+ toplevel .wfiles
462
+ wm withdraw .wfiles
463
+ update idletasks
464
+ wm transient .wfiles .
465
+ wm overrideredirect .wfiles 1
466
+ set ht [expr {[llength $filelist]/2}]
467
+ if {$ht>$CFG(LB_HEIGHT)} {set ht $CFG(LB_HEIGHT)}
468
+ listbox .wfiles.lb -width 0 -height $ht -activestyle none \
469
+ -yscroll {.wfiles.sb set}
470
+ set mx 1
471
+ foreach {op fn} $filelist {
472
+ set n [string length $fn]
473
+ if {$n>$mx} {set mx $n}
474
+ .wfiles.lb insert end "$op $fn"
475
+ }
476
+ .bb.files config -width $mx
477
+ ::ttk::scrollbar .wfiles.sb -command {.wfiles.lb yview}
478
+ grid .wfiles.lb .wfiles.sb -sticky ns
479
+ bind .bb.files <1> {
480
+ set x [winfo rootx %W]
481
+ set y [expr {[winfo rooty %W]+[winfo height %W]}]
482
+ wm geometry .wfiles +$x+$y
483
+ wm deiconify .wfiles
484
+ focus .wfiles.lb
485
+ }
486
+ bind .wfiles <FocusOut> {wm withdraw .wfiles}
487
+ bind .wfiles <Escape> {focus .}
488
+ foreach evt {1 Return} {
489
+ bind .wfiles.lb <$evt> {
490
+ set ii [%W curselection]
491
+ set ::current_file [%W get $ii]
492
+ .bb.files config -text $::current_file
493
+ focus .
494
+ break
495
+ }
496
+ }
497
+ bind .wfiles.lb <Motion> {
498
+ %W selection clear 0 end
499
+ %W selection set @%x,%y
500
+ }
501
+ }
502
+ }
503
+}
504
+
505
+label .bb.ctxtag -text "Context:"
506
+set context_choices {3 6 12 25 50 100 All}
507
+if {$ncontext<0} {set ncontext All}
508
+trace add variable ncontext write readMerge
509
+if {$tcl_platform(os)=="Darwin" || $useOptionMenu} {
510
+ tk_optionMenu .bb.ctx ncontext {*}$context_choices
511
+} else {
512
+ ::ttk::menubutton .bb.ctx -text $ncontext
513
+ if {[tk windowingsystem] eq "win32"} {
514
+ ::ttk::style theme use winnative
515
+ .bb.ctx configure -padding {20 1 10 2}
516
+ }
517
+ toplevel .wctx
518
+ wm withdraw .wctx
519
+ update idletasks
520
+ wm transient .wctx .
521
+ wm overrideredirect .wctx 1
522
+ listbox .wctx.lb -width 0 -height 7 -activestyle none
523
+ .wctx.lb insert end {*}$context_choices
524
+ pack .wctx.lb
525
+ bind .bb.ctx <1> {
526
+ set x [winfo rootx %W]
527
+ set y [expr {[winfo rooty %W]+[winfo height %W]}]
528
+ wm geometry .wctx +$x+$y
529
+ wm deiconify .wctx
530
+ focus .wctx.lb
531
+ }
532
+ bind .wctx <FocusOut> {wm withdraw .wctx}
533
+ bind .wctx <Escape> {focus .}
534
+ foreach evt {1 Return} {
535
+ bind .wctx.lb <$evt> {
536
+ set ::ncontext [lindex $::context_choices [%W curselection]]
537
+ .bb.ctx config -text $::ncontext
538
+ focus .
539
+ break
540
+ }
541
+ }
542
+ bind .wctx.lb <Motion> {
543
+ %W selection clear 0 end
544
+ %W selection set @%x,%y
545
+ }
546
+}
547
+
548
+foreach {side syncCol} {A .txtA B .txtB C .txtC D .txtD} {
549
+ set ln .ln$side
550
+ text $ln -width 6
551
+ $ln tag config - -justify right
552
+
553
+ set txt .txt$side
554
+ text $txt -width $CFG(WIDTH) -height $CFG(HEIGHT) -wrap none \
555
+ -xscroll ".sbx$side set"
556
+ catch {$txt config -tabstyle wordprocessor} ;# Required for Tk>=8.5
557
+ foreach tag {add rm chng} {
558
+ $txt tag config $tag -background $CFG([string toupper $tag]_BG)
559
+ $txt tag lower $tag
560
+ }
561
+ $txt tag config fn -background $CFG(FN_BG) -foreground $CFG(FN_FG) \
562
+ -justify center
563
+ $txt tag config err -foreground $CFG(ERR_FG)
564
+}
565
+text .mkr
566
+
567
+set mxwidth [lindex [wm maxsize .] 0]
568
+while {$CFG(WIDTH)>=40} {
569
+ set wanted [expr {([winfo reqwidth .lnA]+[winfo reqwidth .txtA])*4+30}]
570
+ if {$wanted<=$mxwidth} break
571
+ incr CFG(WIDTH) -10
572
+ .txtA config -width $CFG(WIDTH)
573
+ .txtB config -width $CFG(WIDTH)
574
+ .txtC config -width $CFG(WIDTH)
575
+ .txtD config -width $CFG(WIDTH)
576
+}
577
+
578
+foreach c [cols] {
579
+ set keyPrefix [string toupper [colType $c]]_COL_
580
+ if {[tk windowingsystem] eq "win32"} {$c config -font {courier 9}}
581
+ $c co
--- a/src/merge.tcl
+++ b/src/merge.tcl
@@ -0,0 +1,581 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/src/merge.tcl
+++ b/src/merge.tcl
@@ -0,0 +1,581 @@
1 # Show details of a 3-way merge operation. The left-most column is the
2 # common ancestor. The next two columns are edits of that common ancestor.
3 # The right-most column is the result of the merge.
4 #
5 # There is always a "fossilcmd" variable which tells the script how to
6 # invoke Fossil to get the information it needs. This script will
7 # automatically append "-c N" to tell Fossil how much context it wants. True for debugging output
8 #
9 # If the "filelist" global variable is defined, then it is a list of
10 # alternating "merge-type names" (ex: UPDATE, MERGE, CONFLICT, ERROR) and
11 # filenames. In that case, the initial display shows the changes for
12 # the first pair on the list and there is a optionmenu that allows the
13 # useelect otheere should also be a global variable named "ncontext" which is the
14 # number of lines of context to display. The value of this variable
15 # controls the "-c N" argument that is appended to fossilcmdht {
16 TITLE {Fossil Merge}
17 LN_COL_BG #dddddd
18 LN_COL_FG #444444
19 TXT_COL_BG #ffffff
20 TXT_COL_FG #000000
21 MKR_COL_BG #444444
22 MKR_COL_FG #dddddd
23 CHNG_BG #d0d070
24 ADD_BG #c0ffc0
25 RM_BG #ffc0c0
26 HR_FG #444444
27 HR_PAD_TOP 4
28 HR_PAD_BTM 8
29 FN_BG #444444
30 FN_FG #ffffff
31 FN_PAD 5
32 ERR_FG #ee0000
33 PADX 5
34 WIDTH 80
35 HEIGHT 45
36 LB_HEIGHT 25
37 }
38
39 array set CFG_dark {
40 TITLE {Fossil Merge}
41 LN_COL_BG #dddddd
42 LN_COL_FG #444444
43 TXT_COL_BG #3f3f3f
44 TXT_COL_FG #dcdccc
45 MKR_COL_BG #444444
46 MKR_COL_FG #dddddd
47 CHNG_BG #6a6a00
48 ADD_BG #57934c
49 RM_BG #ef6767
50 HR_FG #444444
51 HR_PAD_TOP 4
52 HR_PAD_BTM 8
53 FN_BG #5e5e5e
54 FN_FG #ffffff
55 FN_PAD 5
56 ERR_FG #ee0000
57 PADX 5
58 WIDTH 80
59 HEIGHT 45
60 LB_HEIGHT 25
61 }
62
63 array set CFG_arr {
64 0 CFG_light
65 1 CFG_dark
66 }
67
68 array set CFG [array get $CFG_arr($darkmode)]
69
70 if {![namespace exists ttk]} {
71 interp alias {} ::ttk::scrollbar {} ::scrollbar
72 interp alias {} ::ttk::menubutton {} ::menubutton
73 }
74
75 proc dehtml {x} {
76 set x [regsub -all {<[^>]*>} $x {}]
77 return [string map {&amp; & &lt; < &gt; > &#39; ' &quot; \"} $x]
78 }
79
80 proc cols {} {
81 return [list .lnA .txtA .lnB .txtB .lnC .txtC .lnD .txtD]
82 }
83
84 proc colType {c} {
85 regexp {[a-z]+} $c type
86 return $type
87 }
88
89 proc readMercmdes currentails of a 3-way merge operation# Show det for
90 # the first pair on the list and there is a optionmenu that allows the
91 # user to select other fiels on the list.
92 #
93 # This header comment is stripped off by the "mkbuiltin.c" program.
94 #
95 package require Tk
96
97 array set CFG_light {
98 TITLE {Fossil Merge}
99 LN_COL_BG #dddddd
100 LN_COL_FG #444444
101 TXT_COL_BG #ffffff
102 TXT_COL_FG #000000
103 MKR_COL_BG #444444
104 MKR_COL_FG #dddddd
105 CHNG_BG #d0d070
106 ADD_BG #c0ffc0
107 RM_BG #ffc0c0
108 HR_FG #444444
109 HR_PAD_TOP 4
110 HR_PAD_BTM 8
111 FN_BG #444444
112 FN_FG #ffffff
113 FN_PAD 5
114 ERR_FG #ee0000
115 PADX 5
116 WIDTH 80
117 HEIGHT 45
118 LB_HEIGHT 25
119 }
120
121 array set CFG_dark {
122 TITLE {Fossil Merge}
123 LN_COL_BG #dddddd
124 LN_COL_FG #444444
125 TXT_COL_BG #3f3f3f
126 TXT_COL_FG #dcdccc
127 MKR_COL_BG #444444
128 MKR_COL_FG #dddddd
129 CHNG_BG #6a6a00
130 ADD_BG #57934c
131 RM_BG #ef6767
132 HR_FG #444444
133 HR_PAD_TOP 4
134 HR_PAD_BTM 8
135 FN_BG #5e5e5e
136 FN_FG #ffffff
137 FN_PAD 5
138 ERR_FG #ee0000
139 PADX 5
140 WIDTH 80
141 HEIGHT 45
142 LB_HEIGHT 25
143 }
144
145 array set CFG_arr {
146 0 CFG_light
147 1 CFG_dark
148 }
149
150 array set CFG [array get $CFG_arr($darkmode)]
151
152 if {![namespace exists ttk]} {
153 interp alias {} ::ttk::scrollbar {} ::scrollbar
154 interp alias {} ::ttk::menubutton {} ::menubutton
155 }
156
157 proc dehtml {x} {
158 set x [regsub -all {<[^>]*>} $x {}]
159 return [string map {&amp; & &lt; < &gt; > &#39; ' &quot; \"} $x]
160 }
161
162 proc cols {} {
163 return [list .lnA .txtA .lnB .txtB .lnC .txtC .lnD .txtD]
164 }
165
166 proc colType {c} {
167 regexp {[a-z]+} $c type
168 return $type
169 }
170
171 proc readMerge {args} {
172 global fossilexe ncontext current_file debug
173 if {$ncontext=="All"} {
174 set cmd "| $fossilexe merge-info -c -1"
175 } else {
176 set cmd "| $fossilexe merge-info -c $ncontext"
177 }
178 if {[info exists current_file]} {
179 regsub {^[A-Z]+ } $current_file {} fn
180 lappend cmd -tcl $fn
181 }
182 if {$debug} {
183 regsub {^\| +} $cmd {} cmd2
184 puts $cmd2
185 flush stdout
186 }
187 if {[catch {
188 set in [open $cmd r]
189 fconfigure $in -encoding utf-8
190 set mergetxt [read $in]
191 close $in
192 } msg]} {
193 tk_messageBox -message "Unable to run command: \"$cmd\""
194 set mergetxt {}
195 }
196 foreach c [cols] {
197 $c config -state normal
198 $c delete 1.0 end
199 }
200 set lnA 1
201 set lnB 1
202 set lnC 1
203 set lnD 1
204 foreach {A B C D} $mergetxt {
205 set key1 [string index $A 0]
206 if {$key1=="S"} {
207 scan [string range $A 1 end] "%d %d %d %d" nA nB nC nD
208 foreach x {A B C D} {
209 set N [set n$x]
210 incr ln$x $N
211 if {$N>0} {
212 .ln$x insert end ...\n hrln
213 .txt$x insert end [string repeat . 30]\n hrtxt
214 } else {
215 .ln$x insert end \n hrln
216 .txt$x insert end \n hrtxt
217 }
218 }
219 continue
220 }
221 set key2 [string index $B 0]
222 set key3 [string index $C 0]
223 set key4 [string index $D 0]
224 if {$key1=="."} {
225 .lnA insert end \n -
226 .txtA insert end \n -
227 } elseif {$key1=="N"} {
228 .nameA config -text [string range $A 1 end]
229 } else {
230 .lnA insert end $lnA\n -
231 incr lnA
232 if {$key1=="X"} {
233 .txtA insert end [string range $A 1 end]\n rm
234 } else {
235 .txtA insert end [string range $A 1 end]\n -
236 }
237 }
238 if {$key2=="."} {
239 .lnB insert end \n -
240 .txtB insert end \n -
241 } elseif {$key2=="N"} {
242 .nameB config -text [string range $B 1 end]
243 } else {
244 .lnB insert end $lnB\n -
245 incr lnB
246 if {$key4=="2"} {set tag chng} {set tag -}
247 if {$key2=="1"} {
248 .txtB insert end [string range $A 1 end]\n $tag
249 } elseif {$key2=="X"} {
250 .txtB insert end [string range $B 1 end]\n rm
251 } else {
252 .txtB insert end [string range $B 1 end]\n $tag
253 }
254 }
255 if {$key3=="."} {
256 .lnC insert end \n -
257 .txtC insert end \n -
258 } elseif {$key3=="N"} {
259 .nameC config -text [string range $C 1 end]
260 } else {
261 .lnC insert end $lnC\n -
262 incr lnC
263 if {$key4=="3"} {set tag add} {set tag -}
264 if {$key3=="1"} {
265 .txtC insert end [string range $A 1 end]\n $tag
266 } elseif {$key3=="2"} {
267 .txtC insert end [string range $B 1 end]\n chng
268 } elseif {$key3=="X"} {
269 .txtC insert end [string range $C 1 end]\n rm
270 } else {
271 .txtC insert end [string range $C 1 end]\n $tag
272 }
273 }
274 if {$key4=="."} {
275 .lnD insert end \n -
276 .txtD insert end \n -
277 } elseif {$key4=="N"} {
278 .nameD config -text [string range $D 1 end]
279 } else {
280 .lnD insert end $lnD\n -
281 incr lnD
282 if {$key4=="1"} {
283 .txtD insert end [string range $A 1 end]\n -
284 } elseif {$key4=="2"} {
285 .txtD insert end [string range $B 1 end]\n chng
286 } elseif {$key4=="3"} {
287 .txtD insert end [string range $C 1 end]\n add
288 } elseif {$key4=="X"} {
289 .txtD insert end [string range $D 1 end]\n rm
290 } else {
291 .txtD insert end [string range $D 1 end]\n -
292 }
293 }
294 }
295 foreach c [cols] {
296 set type [colType $c]
297 if {$type ne "txt"} {
298 $c config -width 6; # $widths($type)
299 }
300 $c config -state disabled
301 }
302 set mx $lnA
303 if {$lnB>$mx} {set mx $lnB}
304 if {$lnC>$mx} {set mx $lnC}
305 if {$lnD>$mx} {set mx $lnD}
306 global lnWidth
307 set lnWidth [string length [format +%d $mx]]
308 .lnA config -width $lnWidth
309 .lnB config -width $lnWidth
310 .lnC config -width $lnWidth
311 .lnD config -width $lnWidth
312 grid columnconfig . {0 2 4 6} -minsize $lnWidth
313 }
314
315 proc viewDiff {idx} {
316 .txtA yview $idx
317 .txtA xview moveto 0
318 }
319
320 proc cycleDiffs {{reverse 0}} {
321 if {$reverse} {
322 set range [.txtA tag prevrange fn @0,0 1.0]
323 if {$range eq ""} {
324 viewDiff {fn.last -1c}
325 } else {
326 viewDiff [lindex $range 0]
327 }
328 } else {
329 set range [.txtA tag nextrange fn {@0,0 +1c} end]
330 if {$range eq "" || [lindex [.txtA yview] 1] == 1} {
331 viewDiff fn.first
332 } else {
333 viewDiff [lindex $range 0]
334 }
335 }
336 }
337
338 proc xvis {col} {
339 set view [$col xview]
340 return [expr {[lindex $view 1]-[lindex $view 0]}]
341 }
342
343 proc scroll-x {args} {
344 set c .txt[expr {[xvis .txtA] < [xvis .txtB] ? "A" : "B"}]
345 eval $c xview $args
346 }
347
348 interp alias {} scroll-y {} .txtA yview
349
350 proc noop {args} {}
351
352 proc enableSync {axis} {
353 update idletasks
354 interp alias {} sync-$axis {}
355 rename _sync-$axis sync-$axis
356 }
357
358 proc disableSync {axis} {
359 rename sync-$axis _sync-$axis
360 interp alias {} sync-$axis {} noop
361 }
362
363 proc sync-y {first last} {
364 disableSync y
365 foreach c [cols] {
366 $c yview moveto $first
367 }
368 if {$first > 0 || $last < 1} {
369 grid .sby
370 .sby set $first $last
371 } else {
372 grid remove .sby
373 }
374 enableSync y
375 }
376
377 wm withdraw .
378 wm title . $CFG(TITLE)
379 wm iconname . $CFG(TITLE)
380 # Keystroke bindings for on the top-level window for navigation and
381 # control also fire when those same keystrokes are pressed in the
382 # Search entry box. Disable them, to prevent the diff screen from
383 # disappearing abruptly and unexpectedly when searching for "q".
384 #
385 bind . <Control-q> exit
386 bind . <Control-p> {catch searchPrev; break}
387 bind . <Control-n> {catch searchNext; break}
388 bind . <Escape><Escape> exit
389 bind . <Destroy> {after 0 exit}
390 bind . <Tab> {cycleDiffs; break}
391 bind . <<PrevWindow>> {cycleDiffs 1; break}
392 bind . <Control-f> {searchOnOff; break}
393 bind . <Control-g> {catch searchNext; break}
394 bind . <Return> {
395 event generate .bb.files <1>
396 event generate .bb.files <ButtonRelease-1>
397 break
398 }
399 foreach {key axis args} {
400 Up y {scroll -5 units}
401 k y {scroll -5 units}
402 Down y {scroll 5 units}
403 j y {scroll 5 units}
404 Left x {scroll -5 units}
405 h x {scroll -5 units}
406 Right x {scroll 5 units}
407 l x {scroll 5 units}
408 Prior y {scroll -1 page}
409 b y {scroll -1 page}
410 Next y {scroll 1 page}
411 space y {scroll 1 page}
412 Home y {moveto 0}
413 g y {moveto 0}
414 End y {moveto 1}
415 } {
416 bind . <$key> "scroll-$axis $args; break"
417 bind . <Shift-$key> continue
418 }
419
420 frame .bb
421 ::ttk::menubutton .bb.diff2 -text {2-way diffs
422 .bb.diff2.m add command -label {baseline vs. local} -command {two-way 12}
423 .bb.diff2.m add command -label {baseline vs. merge-in} -command {two-way 13}
424 .bb.diff2.m add command -label {local vs. merge-in} -command {two-way 23}
425
426 # Bring up a separate two-way diff between a pair of columns
427 # the argument is one of:
428 # 12 Baseline versus Local
429 # 13 Baseline versus Merge-in
430 # 23 Local versus Merge-in
431 #
432 proc two-way {mode} {
433 global current_file fossilexe debug darkmode ncontext
434 regsub {^[A-Z]+ } $current_file {} fn
435 set cmd $fossilexe
436 lappend cmd merge-info --diff$mode $fn -c $ncontext
437 if {$darkmode} {
438 lappend cmd --dark
439 }
440 if {$debug} {
441 lappend cc {*}$cmd &
442 }
443
444 set useOptionMenu 1
445 if {[info exists filelist]} {
446 set current_file "[lindex $filelist 0] [lindex $filelist 1]"
447 if {[llength $filelist]>2} {
448 trace add variable current_file write readMerge
449
450 if {$tcl_platform(os)=="Darwin" || [llength $filelist]<30} {
451 set fnlist {}
452 foreach {op fn} $filelist {lappend fnlist "$op $fn"}
453 tk_optionMenu .bb.files current_file {*}$fnlist
454 } else {
455 set useOptionMenu 0
456 ::ttk::menubutton .bb.files -text $current_file
457 if {[tk windowingsystem] eq "win32"} {
458 ::ttk::style theme use winnative
459 .bb.files configure -padding {20 1 10 2}
460 }
461 toplevel .wfiles
462 wm withdraw .wfiles
463 update idletasks
464 wm transient .wfiles .
465 wm overrideredirect .wfiles 1
466 set ht [expr {[llength $filelist]/2}]
467 if {$ht>$CFG(LB_HEIGHT)} {set ht $CFG(LB_HEIGHT)}
468 listbox .wfiles.lb -width 0 -height $ht -activestyle none \
469 -yscroll {.wfiles.sb set}
470 set mx 1
471 foreach {op fn} $filelist {
472 set n [string length $fn]
473 if {$n>$mx} {set mx $n}
474 .wfiles.lb insert end "$op $fn"
475 }
476 .bb.files config -width $mx
477 ::ttk::scrollbar .wfiles.sb -command {.wfiles.lb yview}
478 grid .wfiles.lb .wfiles.sb -sticky ns
479 bind .bb.files <1> {
480 set x [winfo rootx %W]
481 set y [expr {[winfo rooty %W]+[winfo height %W]}]
482 wm geometry .wfiles +$x+$y
483 wm deiconify .wfiles
484 focus .wfiles.lb
485 }
486 bind .wfiles <FocusOut> {wm withdraw .wfiles}
487 bind .wfiles <Escape> {focus .}
488 foreach evt {1 Return} {
489 bind .wfiles.lb <$evt> {
490 set ii [%W curselection]
491 set ::current_file [%W get $ii]
492 .bb.files config -text $::current_file
493 focus .
494 break
495 }
496 }
497 bind .wfiles.lb <Motion> {
498 %W selection clear 0 end
499 %W selection set @%x,%y
500 }
501 }
502 }
503 }
504
505 label .bb.ctxtag -text "Context:"
506 set context_choices {3 6 12 25 50 100 All}
507 if {$ncontext<0} {set ncontext All}
508 trace add variable ncontext write readMerge
509 if {$tcl_platform(os)=="Darwin" || $useOptionMenu} {
510 tk_optionMenu .bb.ctx ncontext {*}$context_choices
511 } else {
512 ::ttk::menubutton .bb.ctx -text $ncontext
513 if {[tk windowingsystem] eq "win32"} {
514 ::ttk::style theme use winnative
515 .bb.ctx configure -padding {20 1 10 2}
516 }
517 toplevel .wctx
518 wm withdraw .wctx
519 update idletasks
520 wm transient .wctx .
521 wm overrideredirect .wctx 1
522 listbox .wctx.lb -width 0 -height 7 -activestyle none
523 .wctx.lb insert end {*}$context_choices
524 pack .wctx.lb
525 bind .bb.ctx <1> {
526 set x [winfo rootx %W]
527 set y [expr {[winfo rooty %W]+[winfo height %W]}]
528 wm geometry .wctx +$x+$y
529 wm deiconify .wctx
530 focus .wctx.lb
531 }
532 bind .wctx <FocusOut> {wm withdraw .wctx}
533 bind .wctx <Escape> {focus .}
534 foreach evt {1 Return} {
535 bind .wctx.lb <$evt> {
536 set ::ncontext [lindex $::context_choices [%W curselection]]
537 .bb.ctx config -text $::ncontext
538 focus .
539 break
540 }
541 }
542 bind .wctx.lb <Motion> {
543 %W selection clear 0 end
544 %W selection set @%x,%y
545 }
546 }
547
548 foreach {side syncCol} {A .txtA B .txtB C .txtC D .txtD} {
549 set ln .ln$side
550 text $ln -width 6
551 $ln tag config - -justify right
552
553 set txt .txt$side
554 text $txt -width $CFG(WIDTH) -height $CFG(HEIGHT) -wrap none \
555 -xscroll ".sbx$side set"
556 catch {$txt config -tabstyle wordprocessor} ;# Required for Tk>=8.5
557 foreach tag {add rm chng} {
558 $txt tag config $tag -background $CFG([string toupper $tag]_BG)
559 $txt tag lower $tag
560 }
561 $txt tag config fn -background $CFG(FN_BG) -foreground $CFG(FN_FG) \
562 -justify center
563 $txt tag config err -foreground $CFG(ERR_FG)
564 }
565 text .mkr
566
567 set mxwidth [lindex [wm maxsize .] 0]
568 while {$CFG(WIDTH)>=40} {
569 set wanted [expr {([winfo reqwidth .lnA]+[winfo reqwidth .txtA])*4+30}]
570 if {$wanted<=$mxwidth} break
571 incr CFG(WIDTH) -10
572 .txtA config -width $CFG(WIDTH)
573 .txtB config -width $CFG(WIDTH)
574 .txtC config -width $CFG(WIDTH)
575 .txtD config -width $CFG(WIDTH)
576 }
577
578 foreach c [cols] {
579 set keyPrefix [string toupper [colType $c]]_COL_
580 if {[tk windowingsystem] eq "win32"} {$c config -font {courier 9}}
581 $c co
+804 -168
--- src/merge3.c
+++ src/merge3.c
@@ -75,75 +75,17 @@
7575
if( aC1[2]!=aC2[2] ) return 0;
7676
if( sameLines(pV1, pV2, aC1[2]) ) return 1;
7777
return 0;
7878
}
7979
80
-/*
81
-** The aC[] array contains triples of integers. Within each triple, the
82
-** elements are:
83
-**
84
-** (0) The number of lines to copy
85
-** (1) The number of lines to delete
86
-** (2) The number of liens to insert
87
-**
88
-** Suppose we want to advance over sz lines of the original file. This routine
89
-** returns true if that advance would land us on a copy operation. It
90
-** returns false if the advance would end on a delete.
91
-*/
92
-static int ends_at_CPY(int *aC, int sz){
93
- while( sz>0 && (aC[0]>0 || aC[1]>0 || aC[2]>0) ){
94
- if( aC[0]>=sz ) return 1;
95
- sz -= aC[0];
96
- if( aC[1]>sz ) return 0;
97
- sz -= aC[1];
98
- aC += 3;
99
- }
100
- return 1;
101
-}
102
-
103
-/*
104
-** pSrc contains an edited file where aC[] describes the edit. Part of
105
-** pSrc has already been output. This routine outputs additional lines
106
-** of pSrc - lines that correspond to the next sz lines of the original
107
-** unedited file.
108
-**
109
-** Note that sz counts the number of lines of text in the original file.
110
-** But text is output from the edited file. So the number of lines transfer
111
-** to pOut might be different from sz. Fewer lines appear in pOut if there
112
-** are deletes. More lines appear if there are inserts.
113
-**
114
-** The aC[] array is updated and the new index into aC[] is returned.
115
-*/
116
-static int output_one_side(
117
- Blob *pOut, /* Write to this blob */
118
- Blob *pSrc, /* The edited file that is to be copied to pOut */
119
- int *aC, /* Array of integer triples describing the edit */
120
- int i, /* Index in aC[] of current location in pSrc */
121
- int sz, /* Number of lines in unedited source to output */
122
- int *pLn /* Line number counter */
123
-){
124
- while( sz>0 ){
125
- if( aC[i]==0 && aC[i+1]==0 && aC[i+2]==0 ) break;
126
- if( aC[i]>=sz ){
127
- blob_copy_lines(pOut, pSrc, sz); *pLn += sz;
128
- aC[i] -= sz;
129
- break;
130
- }
131
- blob_copy_lines(pOut, pSrc, aC[i]); *pLn += aC[i];
132
- blob_copy_lines(pOut, pSrc, aC[i+2]); *pLn += aC[i+2];
133
- sz -= aC[i] + aC[i+1];
134
- i += 3;
135
- }
136
- return i;
137
-}
138
-
13980
/*
14081
** Text of boundary markers for merge conflicts.
14182
*/
14283
static const char *const mergeMarker[] = {
14384
/*123456789 123456789 123456789 123456789 123456789 123456789 123456789*/
14485
"<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<<",
86
+ "####### SUGGESTED CONFLICT RESOLUTION follows ###################",
14587
"||||||| COMMON ANCESTOR content follows |||||||||||||||||||||||||",
14688
"======= MERGED IN content follows ===============================",
14789
">>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
14890
};
14991
@@ -186,10 +128,615 @@
186128
ensure_line_end(pOut, useCrLf);
187129
blob_append(pOut, mergeMarker[iMark], -1);
188130
if( ln>0 ) blob_appendf(pOut, " (line %d)", ln);
189131
ensure_line_end(pOut, useCrLf);
190132
}
133
+
134
+#if INTERFACE
135
+/*
136
+** This is an abstract class for constructing a merge.
137
+** Subclasses of this object format the merge output in different ways.
138
+**
139
+** To subclass, create an instance of the MergeBuilder object and fill
140
+** in appropriate method implementations.
141
+*/
142
+struct MergeBuilder {
143
+ void (*xStart)(MergeBuilder*);
144
+ void (*xSame)(MergeBuilder*, unsigned int);
145
+ void (*xChngV1)(MergeBuilder*, unsigned int, unsigned int);
146
+ void (*xChngV2)(MergeBuilder*, unsigned int, unsigned int);
147
+ void (*xChngBoth)(MergeBuilder*, unsigned int, unsigned int);
148
+ void (*xConflict)(MergeBuilder*, unsigned int, unsigned int, unsigned int);
149
+ void (*xEnd)(MergeBuilder*);
150
+ void (*xDestroy)(MergeBuilder*);
151
+ const char *zPivot; /* Label or name for the pivot */
152
+ const char *zV1; /* Label or name for the V1 file */
153
+ const char *zV2; /* Label or name for the V2 file */
154
+ const char *zOut; /* Label or name for the output */
155
+ Blob *pPivot; /* The common ancestor */
156
+ Blob *pV1; /* First variant (local copy) */
157
+ Blob *pV2; /* Second variant (merged in) */
158
+ Blob *pOut; /* Write merge results here */
159
+ int useCrLf; /* Use CRLF line endings */
160
+ int nContext; /* Size of unchanged line boundaries */
161
+ unsigned int mxPivot; /* Number of lines in the pivot */
162
+ unsigned int mxV1; /* Number of lines in V1 */
163
+ unsigned int mxV2; /* Number of lines in V2 */
164
+ unsigned int lnPivot; /* Lines read from pivot */
165
+ unsigned int lnV1; /* Lines read from v1 */
166
+ unsigned int lnV2; /* Lines read from v2 */
167
+ unsigned int lnOut; /* Lines written to out */
168
+ unsigned int nConflict; /* Number of conflicts seen */
169
+ u64 diffFlags; /* Flags for difference engine */
170
+};
171
+#endif /* INTERFACE */
172
+
173
+
174
+/************************* Generic MergeBuilder ******************************/
175
+/* These are generic methods for MergeBuilder. They just output debugging
176
+** information. But some of them are useful as base methods for other useful
177
+** implementations of MergeBuilder.
178
+*/
179
+
180
+/* xStart() and xEnd() are called to generate header and fotter information
181
+** in the output. This is a no-op in the generic implementation.
182
+*/
183
+static void dbgStartEnd(MergeBuilder *p){ (void)p; }
184
+
185
+/* The next N lines of PIVOT are unchanged in both V1 and V2
186
+*/
187
+static void dbgSame(MergeBuilder *p, unsigned int N){
188
+ blob_appendf(p->pOut,
189
+ "COPY %u from BASELINE(%u..%u) or V1(%u..%u) or V2(%u..%u)\n",
190
+ N, p->lnPivot+1, p->lnPivot+N, p->lnV1+1, p->lnV1+N,
191
+ p->lnV2+1, p->lnV2+N);
192
+ p->lnPivot += N;
193
+ p->lnV1 += N;
194
+ p->lnV2 += N;
195
+}
196
+
197
+/* The next nPivot lines of the PIVOT are changed into nV1 lines by V1
198
+*/
199
+static void dbgChngV1(MergeBuilder *p, unsigned int nPivot, unsigned int nV1){
200
+ blob_appendf(p->pOut, "COPY %u from V1(%u..%u)\n",
201
+ nV1, p->lnV1+1, p->lnV1+nV1);
202
+ p->lnPivot += nPivot;
203
+ p->lnV2 += nPivot;
204
+ p->lnV1 += nV1;
205
+}
206
+
207
+/* The next nPivot lines of the PIVOT are changed into nV2 lines by V2
208
+*/
209
+static void dbgChngV2(MergeBuilder *p, unsigned int nPivot, unsigned int nV2){
210
+ blob_appendf(p->pOut, "COPY %u lines FROM V2(%u..%u)\n",
211
+ nV2, p->lnV2+1, p->lnV2+nV2);
212
+ p->lnPivot += nPivot;
213
+ p->lnV1 += nPivot;
214
+ p->lnV2 += nV2;
215
+}
216
+
217
+/* The next nPivot lines of the PIVOT are changed into nV lines from V1 and
218
+** V2, which should be the same. In other words, the same change is found
219
+** in both V1 and V2.
220
+*/
221
+static void dbgChngBoth(MergeBuilder *p, unsigned int nPivot, unsigned int nV){
222
+ blob_appendf(p->pOut, "COPY %u lines from V1(%u..%u) or V2(%u..%u)\n",
223
+ nV, p->lnV1+1, p->lnV1+nV, p->lnV2+1, p->lnV2+nV);
224
+ p->lnPivot += nPivot;
225
+ p->lnV1 += nV;
226
+ p->lnV2 += nV;
227
+}
228
+
229
+/* V1 and V2 have different and overlapping changes. The next nPivot lines
230
+** of the PIVOT are converted into nV1 lines of V1 and nV2 lines of V2.
231
+*/
232
+static void dbgConflict(
233
+ MergeBuilder *p,
234
+ unsigned int nPivot,
235
+ unsigned int nV1,
236
+ unsigned int nV2
237
+){
238
+ blob_appendf(p->pOut,
239
+ "CONFLICT %u,%u,%u BASELINE(%u..%u) versus V1(%u..%u) versus V2(%u..%u)\n",
240
+ nPivot, nV1, nV2,
241
+ p->lnPivot+1, p->lnPivot+nPivot,
242
+ p->lnV1+1, p->lnV1+nV1,
243
+ p->lnV2+1, p->lnV2+nV2);
244
+ p->lnV1 += nV1;
245
+ p->lnPivot += nPivot;
246
+ p->lnV2 += nV2;
247
+}
248
+
249
+/* Generic destructor for the MergeBuilder object
250
+*/
251
+static void dbgDestroy(MergeBuilder *p){
252
+ memset(p, 0, sizeof(*p));
253
+}
254
+
255
+/* Generic initializer for a MergeBuilder object
256
+*/
257
+static void mergebuilder_init(MergeBuilder *p){
258
+ memset(p, 0, sizeof(*p));
259
+ p->xStart = dbgStartEnd;
260
+ p->xSame = dbgSame;
261
+ p->xChngV1 = dbgChngV1;
262
+ p->xChngV2 = dbgChngV2;
263
+ p->xChngBoth = dbgChngBoth;
264
+ p->xConflict = dbgConflict;
265
+ p->xEnd = dbgStartEnd;
266
+ p->xDestroy = dbgDestroy;
267
+}
268
+
269
+/************************* MergeBuilderToken ********************************/
270
+/* This version of MergeBuilder actually performs a merge on file that
271
+** are broken up into tokens instead of lines, and puts the result in pOut.
272
+*/
273
+static void tokenSame(MergeBuilder *p, unsigned int N){
274
+ blob_append(p->pOut, p->pPivot->aData+p->pPivot->iCursor, N);
275
+ p->pPivot->iCursor += N;
276
+ p->pV1->iCursor += N;
277
+ p->pV2->iCursor += N;
278
+}
279
+static void tokenChngV1(MergeBuilder *p, unsigned int nPivot, unsigned nV1){
280
+ blob_append(p->pOut, p->pV1->aData+p->pV1->iCursor, nV1);
281
+ p->pPivot->iCursor += nPivot;
282
+ p->pV1->iCursor += nV1;
283
+ p->pV2->iCursor += nPivot;
284
+}
285
+static void tokenChngV2(MergeBuilder *p, unsigned int nPivot, unsigned nV2){
286
+ blob_append(p->pOut, p->pV2->aData+p->pV2->iCursor, nV2);
287
+ p->pPivot->iCursor += nPivot;
288
+ p->pV1->iCursor += nPivot;
289
+ p->pV2->iCursor += nV2;
290
+}
291
+static void tokenChngBoth(MergeBuilder *p, unsigned int nPivot, unsigned nV){
292
+ blob_append(p->pOut, p->pV2->aData+p->pV2->iCursor, nV);
293
+ p->pPivot->iCursor += nPivot;
294
+ p->pV1->iCursor += nV;
295
+ p->pV2->iCursor += nV;
296
+}
297
+static void tokenConflict(
298
+ MergeBuilder *p,
299
+ unsigned int nPivot,
300
+ unsigned int nV1,
301
+ unsigned int nV2
302
+){
303
+ /* For a token-merge conflict, use the text from the merge-in */
304
+ blob_append(p->pOut, p->pV2->aData+p->pV2->iCursor, nV2);
305
+ p->pPivot->iCursor += nPivot;
306
+ p->pV1->iCursor += nV1;
307
+ p->pV2->iCursor += nV2;
308
+}
309
+static void mergebuilder_init_token(MergeBuilder *p){
310
+ mergebuilder_init(p);
311
+ p->xSame = tokenSame;
312
+ p->xChngV1 = tokenChngV1;
313
+ p->xChngV2 = tokenChngV2;
314
+ p->xChngBoth = tokenChngBoth;
315
+ p->xConflict = tokenConflict;
316
+ p->diffFlags = DIFF_BY_TOKEN;
317
+}
318
+
319
+/*
320
+** Attempt to do a low-level merge on a conflict. The conflict is
321
+** described by the first four parameters, which are the same as the
322
+** arguments to the xConflict method of the MergeBuilder object.
323
+** This routine attempts to resolve the conflict by looking at
324
+** elements of the conflict region that are finer grain than complete
325
+** lines of text.
326
+**
327
+** The result is written into Blob pOut. pOut is initialized by this
328
+** routine.
329
+*/
330
+int merge_try_to_resolve_conflict(
331
+ MergeBuilder *pMB, /* MergeBuilder that encounter conflict */
332
+ unsigned int nPivot, /* Lines of conflict in the pivot */
333
+ unsigned int nV1, /* Lines of conflict in V1 */
334
+ unsigned int nV2, /* Lines of conflict in V2 */
335
+ Blob *pOut /* Write resolution text here */
336
+){
337
+ int nConflict;
338
+ MergeBuilder mb;
339
+ Blob pv, v1, v2;
340
+ mergebuilder_init_token(&mb);
341
+ blob_extract_lines(pMB->pPivot, nPivot, &pv);
342
+ blob_extract_lines(pMB->pV1, nV1, &v1);
343
+ blob_extract_lines(pMB->pV2, nV2, &v2);
344
+ blob_zero(pOut);
345
+ blob_materialize(&pv);
346
+ blob_materialize(&v1);
347
+ blob_materialize(&v2);
348
+ mb.pPivot = &pv;
349
+ mb.pV1 = &v1;
350
+ mb.pV2 = &v2;
351
+ mb.pOut = pOut;
352
+ nConflict = merge_three_blobs(&mb);
353
+ blob_reset(&pv);
354
+ blob_reset(&v1);
355
+ blob_reset(&v2);
356
+ /* mb has not allocated any resources, so we do not need to invoke
357
+ ** the xDestroy method. */
358
+ blob_add_final_newline(pOut);
359
+ return nConflict;
360
+}
361
+
362
+
363
+/************************* MergeBuilderText **********************************/
364
+/* This version of MergeBuilder actually performs a merge on file and puts
365
+** the result in pOut
366
+*/
367
+static void txtStart(MergeBuilder *p){
368
+ /* If both pV1 and pV2 start with a UTF-8 byte-order-mark (BOM),
369
+ ** keep it in the output. This should be secure enough not to cause
370
+ ** unintended changes to the merged file and consistent with what
371
+ ** users are using in their source files.
372
+ */
373
+ if( starts_with_utf8_bom(p->pV1, 0) && starts_with_utf8_bom(p->pV2, 0) ){
374
+ blob_append(p->pOut, (char*)get_utf8_bom(0), -1);
375
+ }
376
+ if( contains_crlf(p->pV1) && contains_crlf(p->pV2) ){
377
+ p->useCrLf = 1;
378
+ }
379
+}
380
+static void txtSame(MergeBuilder *p, unsigned int N){
381
+ blob_copy_lines(p->pOut, p->pPivot, N); p->lnPivot += N;
382
+ blob_copy_lines(0, p->pV1, N); p->lnV1 += N;
383
+ blob_copy_lines(0, p->pV2, N); p->lnV2 += N;
384
+}
385
+static void txtChngV1(MergeBuilder *p, unsigned int nPivot, unsigned int nV1){
386
+ blob_copy_lines(0, p->pPivot, nPivot); p->lnPivot += nPivot;
387
+ blob_copy_lines(0, p->pV2, nPivot); p->lnV2 += nPivot;
388
+ blob_copy_lines(p->pOut, p->pV1, nV1); p->lnV1 += nV1;
389
+}
390
+static void txtChngV2(MergeBuilder *p, unsigned int nPivot, unsigned int nV2){
391
+ blob_copy_lines(0, p->pPivot, nPivot); p->lnPivot += nPivot;
392
+ blob_copy_lines(0, p->pV1, nPivot); p->lnV1 += nPivot;
393
+ blob_copy_lines(p->pOut, p->pV2, nV2); p->lnV2 += nV2;
394
+}
395
+static void txtChngBoth(MergeBuilder *p, unsigned int nPivot, unsigned int nV){
396
+ blob_copy_lines(0, p->pPivot, nPivot); p->lnPivot += nPivot;
397
+ blob_copy_lines(0, p->pV1, nV); p->lnV1 += nV;
398
+ blob_copy_lines(p->pOut, p->pV2, nV); p->lnV2 += nV;
399
+}
400
+static void txtConflict(
401
+ MergeBuilder *p,
402
+ unsigned int nPivot,
403
+ unsigned int nV1,
404
+ unsigned int nV2
405
+){
406
+ int nRes; /* Lines in the computed conflict resolution */
407
+ Blob res; /* Text of the conflict resolution */
408
+
409
+ merge_try_to_resolve_conflict(p, nPivot, nV1, nV2, &res);
410
+ nRes = blob_linecount(&res);
411
+
412
+ append_merge_mark(p->pOut, 0, p->lnV1+1, p->useCrLf);
413
+ blob_copy_lines(p->pOut, p->pV1, nV1); p->lnV1 += nV1;
414
+
415
+ if( nRes>0 ){
416
+ append_merge_mark(p->pOut, 1, 0, p->useCrLf);
417
+ blob_copy_lines(p->pOut, &res, nRes);
418
+ }
419
+ blob_reset(&res);
420
+
421
+ append_merge_mark(p->pOut, 2, p->lnPivot+1, p->useCrLf);
422
+ blob_copy_lines(p->pOut, p->pPivot, nPivot); p->lnPivot += nPivot;
423
+
424
+ append_merge_mark(p->pOut, 3, p->lnV2+1, p->useCrLf);
425
+ blob_copy_lines(p->pOut, p->pV2, nV2); p->lnV2 += nV2;
426
+
427
+ append_merge_mark(p->pOut, 4, -1, p->useCrLf);
428
+}
429
+static void mergebuilder_init_text(MergeBuilder *p){
430
+ mergebuilder_init(p);
431
+ p->xStart = txtStart;
432
+ p->xSame = txtSame;
433
+ p->xChngV1 = txtChngV1;
434
+ p->xChngV2 = txtChngV2;
435
+ p->xChngBoth = txtChngBoth;
436
+ p->xConflict = txtConflict;
437
+}
438
+
439
+/************************* MergeBuilderTcl **********************************/
440
+/* Generate merge output formatted for reading by a TCL script.
441
+**
442
+** The output consists of lines of text, each with 4 tokens. The tokens
443
+** represent the content for one line from baseline, v1, v2, and output
444
+** respectively. The first character of each token provides auxiliary
445
+** information:
446
+**
447
+** . This line is omitted.
448
+** N Name of the file.
449
+** T Literal text follows that should have a \n terminator.
450
+** R Literal text follows that needs a \r\n terminator.
451
+** X Merge conflict.
452
+** Z Literal text without a line terminator.
453
+** S Skipped lines. Followed by number of lines to skip.
454
+** 1 Text is a copy of token 1
455
+** 2 Use data from data-token 2
456
+** 3 Use data from data-token 3
457
+*/
458
+
459
+/* Write text that goes into the interior of a double-quoted string in TCL */
460
+static void tclWriteQuotedText(Blob *pOut, const char *zIn, int nIn){
461
+ int j;
462
+ for(j=0; j<nIn; j++){
463
+ char c = zIn[j];
464
+ if( c=='\\' ){
465
+ blob_append(pOut, "\\\\", 2);
466
+ }else if( c=='"' ){
467
+ blob_append(pOut, "\\\"", 2);
468
+ }else if( c<' ' || c>0x7e ){
469
+ char z[5];
470
+ z[0] = '\\';
471
+ z[1] = "01234567"[(c>>6)&0x3];
472
+ z[2] = "01234567"[(c>>3)&0x7];
473
+ z[3] = "01234567"[c&0x7];
474
+ z[4] = 0;
475
+ blob_append(pOut, z, 4);
476
+ }else{
477
+ blob_append_char(pOut, c);
478
+ }
479
+ }
480
+}
481
+
482
+/* Copy one line of text from pIn and append to pOut, encoded as TCL */
483
+static void tclLineOfText(Blob *pOut, Blob *pIn, char cType){
484
+ int i, k;
485
+ for(i=pIn->iCursor; i<pIn->nUsed && pIn->aData[i]!='\n'; i++){}
486
+ if( i==pIn->nUsed ){
487
+ k = i;
488
+ }else if( i>pIn->iCursor && pIn->aData[i-1]=='\r' ){
489
+ k = i-1;
490
+ i++;
491
+ }else{
492
+ k = i;
493
+ i++;
494
+ }
495
+ blob_append_char(pOut, '"');
496
+ blob_append_char(pOut, cType);
497
+ tclWriteQuotedText(pOut, pIn->aData+pIn->iCursor, k-pIn->iCursor);
498
+ pIn->iCursor = i;
499
+ blob_append_char(pOut, '"');
500
+}
501
+static void tclStart(MergeBuilder *p){
502
+ Blob *pOut = p->pOut;
503
+ blob_append(pOut, "\"N", 2);
504
+ tclWriteQuotedText(pOut, p->zPivot, (int)strlen(p->zPivot));
505
+ blob_append(pOut, "\" \"N", 4);
506
+ tclWriteQuotedText(pOut, p->zV1, (int)strlen(p->zV1));
507
+ blob_append(pOut, "\" \"N", 4);
508
+ tclWriteQuotedText(pOut, p->zV2, (int)strlen(p->zV2));
509
+ blob_append(pOut, "\" \"N", 4);
510
+ if( p->zOut ){
511
+ tclWriteQuotedText(pOut, p->zOut, (int)strlen(p->zOut));
512
+ }else{
513
+ blob_append(pOut, "(Merge Result)", -1);
514
+ }
515
+ blob_append(pOut, "\"\n", 2);
516
+}
517
+static void tclSame(MergeBuilder *p, unsigned int N){
518
+ int i = 0;
519
+ int nSkip;
520
+
521
+ if( p->lnPivot>=2 || p->lnV1>2 || p->lnV2>2 ){
522
+ while( i<N && i<p->nContext ){
523
+ tclLineOfText(p->pOut, p->pPivot, 'T');
524
+ blob_append(p->pOut, " 1 1 1\n", 7);
525
+ i++;
526
+ }
527
+ nSkip = N - p->nContext*2;
528
+ }else{
529
+ nSkip = N - p->nContext;
530
+ }
531
+ if( nSkip>0 ){
532
+ blob_appendf(p->pOut, "\"S%d %d %d %d\" . . .\n",
533
+ nSkip, nSkip, nSkip, nSkip);
534
+ blob_copy_lines(0, p->pPivot, nSkip);
535
+ i += nSkip;
536
+ }
537
+
538
+ p->lnPivot += N;
539
+ p->lnV1 += N;
540
+ p->lnV2 += N;
541
+
542
+ if( p->lnPivot<p->mxPivot || p->lnV1<p->mxV1 || p->lnV2<p->mxV2 ){
543
+ while( i<N ){
544
+ tclLineOfText(p->pOut, p->pPivot, 'T');
545
+ blob_append(p->pOut, " 1 1 1\n", 7);
546
+ i++;
547
+ }
548
+ }
549
+
550
+ blob_copy_lines(0, p->pV1, N);
551
+ blob_copy_lines(0, p->pV2, N);
552
+}
553
+static void tclChngV1(MergeBuilder *p, unsigned int nPivot, unsigned int nV1){
554
+ int i;
555
+ for(i=0; i<nPivot && i<nV1; i++){
556
+ tclLineOfText(p->pOut, p->pPivot, 'T');
557
+ blob_append_char(p->pOut, ' ');
558
+ tclLineOfText(p->pOut, p->pV1, 'T');
559
+ blob_append(p->pOut, " 1 2\n", 5);
560
+ }
561
+ while( i<nPivot ){
562
+ tclLineOfText(p->pOut, p->pPivot, 'T');
563
+ blob_append(p->pOut, " . 1 .\n", 7);
564
+ i++;
565
+ }
566
+ while( i<nV1 ){
567
+ blob_append(p->pOut, ". ", 2);
568
+ tclLineOfText(p->pOut, p->pV1, 'T');
569
+ blob_append(p->pOut, " . 2\n", 5);
570
+ i++;
571
+ }
572
+ p->lnPivot += nPivot;
573
+ p->lnV1 += nV1;
574
+ p->lnV2 += nPivot;
575
+ blob_copy_lines(0, p->pV2, nPivot);
576
+}
577
+static void tclChngV2(MergeBuilder *p, unsigned int nPivot, unsigned int nV2){
578
+ int i;
579
+ for(i=0; i<nPivot && i<nV2; i++){
580
+ tclLineOfText(p->pOut, p->pPivot, 'T');
581
+ blob_append(p->pOut, " 1 ", 3);
582
+ tclLineOfText(p->pOut, p->pV2, 'T');
583
+ blob_append(p->pOut, " 3\n", 3);
584
+ }
585
+ while( i<nPivot ){
586
+ tclLineOfText(p->pOut, p->pPivot, 'T');
587
+ blob_append(p->pOut, " 1 . .\n", 7);
588
+ i++;
589
+ }
590
+ while( i<nV2 ){
591
+ blob_append(p->pOut, ". . ", 4);
592
+ tclLineOfText(p->pOut, p->pV2, 'T');
593
+ blob_append(p->pOut, " 3\n", 3);
594
+ i++;
595
+ }
596
+ p->lnPivot += nPivot;
597
+ p->lnV1 += nPivot;
598
+ p->lnV2 += nV2;
599
+ blob_copy_lines(0, p->pV1, nPivot);
600
+}
601
+static void tclChngBoth(MergeBuilder *p, unsigned int nPivot, unsigned int nV){
602
+ int i;
603
+ for(i=0; i<nPivot && i<nV; i++){
604
+ tclLineOfText(p->pOut, p->pPivot, 'T');
605
+ blob_append_char(p->pOut, ' ');
606
+ tclLineOfText(p->pOut, p->pV1, 'T');
607
+ blob_append(p->pOut, " 2 2\n", 5);
608
+ }
609
+ while( i<nPivot ){
610
+ tclLineOfText(p->pOut, p->pPivot, 'T');
611
+ blob_append(p->pOut, " . . .\n", 7);
612
+ i++;
613
+ }
614
+ while( i<nV ){
615
+ blob_append(p->pOut, ". ", 2);
616
+ tclLineOfText(p->pOut, p->pV1, 'T');
617
+ blob_append(p->pOut, " 2 2\n", 5);
618
+ i++;
619
+ }
620
+ p->lnPivot += nPivot;
621
+ p->lnV1 += nV;
622
+ p->lnV2 += nV;
623
+ blob_copy_lines(0, p->pV2, nV);
624
+}
625
+static void tclConflict(
626
+ MergeBuilder *p,
627
+ unsigned int nPivot,
628
+ unsigned int nV1,
629
+ unsigned int nV2
630
+){
631
+ int mx = nPivot;
632
+ int i;
633
+ int nRes;
634
+ Blob res;
635
+
636
+ merge_try_to_resolve_conflict(p, nPivot, nV1, nV2, &res);
637
+ nRes = blob_linecount(&res);
638
+ if( nV1>mx ) mx = nV1;
639
+ if( nV2>mx ) mx = nV2;
640
+ if( nRes>mx ) mx = nRes;
641
+ if( nRes>0 ){
642
+ blob_appendf(p->pOut, "\"S0 0 0 %d\" . . .\n", nV2+2);
643
+ }
644
+ for(i=0; i<mx; i++){
645
+ if( i<nPivot ){
646
+ tclLineOfText(p->pOut, p->pPivot, 'X');
647
+ }else{
648
+ blob_append_char(p->pOut, '.');
649
+ }
650
+ blob_append_char(p->pOut, ' ');
651
+ if( i<nV1 ){
652
+ tclLineOfText(p->pOut, p->pV1, 'X');
653
+ }else{
654
+ blob_append_char(p->pOut, '.');
655
+ }
656
+ blob_append_char(p->pOut, ' ');
657
+ if( i<nV2 ){
658
+ tclLineOfText(p->pOut, p->pV2, 'X');
659
+ }else{
660
+ blob_append_char(p->pOut, '.');
661
+ }
662
+ if( i<nRes ){
663
+ blob_append_char(p->pOut, ' ');
664
+ tclLineOfText(p->pOut, &res, 'X');
665
+ blob_append_char(p->pOut, '\n');
666
+ }else{
667
+ blob_append(p->pOut, " .\n", 3);
668
+ }
669
+ if( i==mx-1 ){
670
+ blob_appendf(p->pOut, "\"S0 0 0 %d\" . . .\n", nPivot+nV1+3);
671
+ }
672
+ }
673
+ blob_reset(&res);
674
+ p->lnPivot += nPivot;
675
+ p->lnV1 += nV1;
676
+ p->lnV2 += nV2;
677
+}
678
+void mergebuilder_init_tcl(MergeBuilder *p){
679
+ mergebuilder_init(p);
680
+ p->xStart = tclStart;
681
+ p->xSame = tclSame;
682
+ p->xChngV1 = tclChngV1;
683
+ p->xChngV2 = tclChngV2;
684
+ p->xChngBoth = tclChngBoth;
685
+ p->xConflict = tclConflict;
686
+}
687
+/*****************************************************************************/
688
+
689
+/*
690
+** The aC[] array contains triples of integers. Within each triple, the
691
+** elements are:
692
+**
693
+** (0) The number of lines to copy
694
+** (1) The number of lines to delete
695
+** (2) The number of liens to insert
696
+**
697
+** Suppose we want to advance over sz lines of the original file. This routine
698
+** returns true if that advance would land us on a copy operation. It
699
+** returns false if the advance would end on a delete.
700
+*/
701
+static int ends_with_copy(int *aC, int sz){
702
+ while( sz>0 && (aC[0]>0 || aC[1]>0 || aC[2]>0) ){
703
+ if( aC[0]>=sz ) return 1;
704
+ sz -= aC[0];
705
+ if( aC[1]>sz ) return 0;
706
+ sz -= aC[1];
707
+ aC += 3;
708
+ }
709
+ return 1;
710
+}
711
+
712
+/*
713
+** aC[] is an "edit triple" for changes from A to B. Advance through
714
+** this triple to determine the number of lines to bypass on B in order
715
+** to match an advance of sz lines on A.
716
+*/
717
+static int skip_conflict(
718
+ int *aC, /* Array of integer triples describing the edit */
719
+ int i, /* Index in aC[] of current location */
720
+ int sz, /* Lines of A that have been skipped */
721
+ unsigned int *pLn /* OUT: Lines of B to skip to keep aligment with A */
722
+){
723
+ *pLn = 0;
724
+ while( sz>0 ){
725
+ if( aC[i]==0 && aC[i+1]==0 && aC[i+2]==0 ) break;
726
+ if( aC[i]>=sz ){
727
+ aC[i] -= sz;
728
+ *pLn += sz;
729
+ break;
730
+ }
731
+ *pLn += aC[i];
732
+ *pLn += aC[i+2];
733
+ sz -= aC[i] + aC[i+1];
734
+ i += 3;
735
+ }
736
+ return i;
737
+}
191738
192739
/*
193740
** Do a three-way merge. Initialize pOut to contain the result.
194741
**
195742
** The merge is an edit against pV2. Both pV1 and pV2 have a
@@ -199,156 +746,113 @@
199746
** The return is 0 upon complete success. If any input file is binary,
200747
** -1 is returned and pOut is unmodified. If there are merge
201748
** conflicts, the merge proceeds as best as it can and the number
202749
** of conflicts is returns
203750
*/
204
-static int blob_merge(Blob *pPivot, Blob *pV1, Blob *pV2, Blob *pOut){
751
+int merge_three_blobs(MergeBuilder *p){
205752
int *aC1; /* Changes from pPivot to pV1 */
206753
int *aC2; /* Changes from pPivot to pV2 */
207754
int i1, i2; /* Index into aC1[] and aC2[] */
208755
int nCpy, nDel, nIns; /* Number of lines to copy, delete, or insert */
209756
int limit1, limit2; /* Sizes of aC1[] and aC2[] */
210757
int nConflict = 0; /* Number of merge conflicts seen so far */
211
- int useCrLf = 0;
212
- int ln1, ln2, lnPivot; /* Line numbers for all files */
213758
DiffConfig DCfg;
214759
215
- blob_zero(pOut); /* Merge results stored in pOut */
216
-
217
- /* If both pV1 and pV2 start with a UTF-8 byte-order-mark (BOM),
218
- ** keep it in the output. This should be secure enough not to cause
219
- ** unintended changes to the merged file and consistent with what
220
- ** users are using in their source files.
221
- */
222
- if( starts_with_utf8_bom(pV1, 0) && starts_with_utf8_bom(pV2, 0) ){
223
- blob_append(pOut, (char*)get_utf8_bom(0), -1);
224
- }
225
-
226
- /* Check once to see if both pV1 and pV2 contains CR/LF endings.
227
- ** If true, CR/LF pair will be used later to append the
228
- ** boundary markers for merge conflicts.
229
- */
230
- if( contains_crlf(pV1) && contains_crlf(pV2) ){
231
- useCrLf = 1;
232
- }
233
-
234760
/* Compute the edits that occur from pPivot => pV1 (into aC1)
235761
** and pPivot => pV2 (into aC2). Each of the aC1 and aC2 arrays is
236762
** an array of integer triples. Within each triple, the first integer
237763
** is the number of lines of text to copy directly from the pivot,
238764
** the second integer is the number of lines of text to omit from the
239765
** pivot, and the third integer is the number of lines of text that are
240766
** inserted. The edit array ends with a triple of 0,0,0.
241767
*/
242768
diff_config_init(&DCfg, 0);
243
- aC1 = text_diff(pPivot, pV1, 0, &DCfg);
244
- aC2 = text_diff(pPivot, pV2, 0, &DCfg);
769
+ DCfg.diffFlags = p->diffFlags;
770
+ aC1 = text_diff(p->pPivot, p->pV1, 0, &DCfg);
771
+ aC2 = text_diff(p->pPivot, p->pV2, 0, &DCfg);
245772
if( aC1==0 || aC2==0 ){
246773
free(aC1);
247774
free(aC2);
248775
return -1;
249776
}
250777
251
- blob_rewind(pV1); /* Rewind inputs: Needed to reconstruct output */
252
- blob_rewind(pV2);
253
- blob_rewind(pPivot);
778
+ blob_rewind(p->pV1); /* Rewind inputs: Needed to reconstruct output */
779
+ blob_rewind(p->pV2);
780
+ blob_rewind(p->pPivot);
254781
255782
/* Determine the length of the aC1[] and aC2[] change vectors */
256
- for(i1=0; aC1[i1] || aC1[i1+1] || aC1[i1+2]; i1+=3){}
783
+ p->mxPivot = 0;
784
+ p->mxV1 = 0;
785
+ for(i1=0; aC1[i1] || aC1[i1+1] || aC1[i1+2]; i1+=3){
786
+ p->mxPivot += aC1[i1] + aC1[i1+1];
787
+ p->mxV1 += aC1[i1] + aC1[i1+2];
788
+ }
257789
limit1 = i1;
258
- for(i2=0; aC2[i2] || aC2[i2+1] || aC2[i2+2]; i2+=3){}
790
+ p->mxV2 = 0;
791
+ for(i2=0; aC2[i2] || aC2[i2+1] || aC2[i2+2]; i2+=3){
792
+ p->mxV2 += aC2[i2] + aC2[i2+2];
793
+ }
259794
limit2 = i2;
260795
261
- DEBUG(
262
- for(i1=0; i1<limit1; i1+=3){
263
- printf("c1: %4d %4d %4d\n", aC1[i1], aC1[i1+1], aC1[i1+2]);
264
- }
265
- for(i2=0; i2<limit2; i2+=3){
266
- printf("c2: %4d %4d %4d\n", aC2[i2], aC2[i2+1], aC2[i2+2]);
267
- }
268
- )
796
+ /* Output header text and do any other required initialization */
797
+ p->xStart(p);
269798
270799
/* Loop over the two edit vectors and use them to compute merged text
271800
** which is written into pOut. i1 and i2 are multiples of 3 which are
272801
** indices into aC1[] and aC2[] to the edit triple currently being
273802
** processed
274803
*/
275804
i1 = i2 = 0;
276
- ln1 = ln2 = lnPivot = 1;
277805
while( i1<limit1 && i2<limit2 ){
278
- DEBUG( printf("%d: %2d %2d %2d %d: %2d %2d %2d\n",
279
- i1/3, aC1[i1], aC1[i1+1], aC1[i1+2],
280
- i2/3, aC2[i2], aC2[i2+1], aC2[i2+2]); )
281
-
282806
if( aC1[i1]>0 && aC2[i2]>0 ){
283807
/* Output text that is unchanged in both V1 and V2 */
284808
nCpy = min(aC1[i1], aC2[i2]);
285
- DEBUG( printf("COPY %d\n", nCpy); )
286
- blob_copy_lines(pOut, pPivot, nCpy); lnPivot += nCpy;
287
- blob_copy_lines(0, pV1, nCpy); ln1 += nCpy;
288
- blob_copy_lines(0, pV2, nCpy); ln2 += nCpy;
809
+ p->xSame(p, nCpy);
289810
aC1[i1] -= nCpy;
290811
aC2[i2] -= nCpy;
291812
}else
292813
if( aC1[i1] >= aC2[i2+1] && aC1[i1]>0 && aC2[i2+1]+aC2[i2+2]>0 ){
293814
/* Output edits to V2 that occurs within unchanged regions of V1 */
294815
nDel = aC2[i2+1];
295816
nIns = aC2[i2+2];
296
- DEBUG( printf("EDIT -%d+%d left\n", nDel, nIns); )
297
- blob_copy_lines(0, pPivot, nDel); lnPivot += nDel;
298
- blob_copy_lines(0, pV1, nDel); ln1 += nDel;
299
- blob_copy_lines(pOut, pV2, nIns); ln2 += nIns;
817
+ p->xChngV2(p, nDel, nIns);
300818
aC1[i1] -= nDel;
301819
i2 += 3;
302820
}else
303821
if( aC2[i2] >= aC1[i1+1] && aC2[i2]>0 && aC1[i1+1]+aC1[i1+2]>0 ){
304822
/* Output edits to V1 that occur within unchanged regions of V2 */
305823
nDel = aC1[i1+1];
306824
nIns = aC1[i1+2];
307
- DEBUG( printf("EDIT -%d+%d right\n", nDel, nIns); )
308
- blob_copy_lines(0, pPivot, nDel); lnPivot += nDel;
309
- blob_copy_lines(0, pV2, nDel); ln2 += nDel;
310
- blob_copy_lines(pOut, pV1, nIns); ln1 += nIns;
825
+ p->xChngV1(p, nDel, nIns);
311826
aC2[i2] -= nDel;
312827
i1 += 3;
313828
}else
314
- if( sameEdit(&aC1[i1], &aC2[i2], pV1, pV2) ){
829
+ if( sameEdit(&aC1[i1], &aC2[i2], p->pV1, p->pV2) ){
315830
/* Output edits that are identical in both V1 and V2. */
316831
assert( aC1[i1]==0 );
317832
nDel = aC1[i1+1];
318833
nIns = aC1[i1+2];
319
- DEBUG( printf("EDIT -%d+%d both\n", nDel, nIns); )
320
- blob_copy_lines(0, pPivot, nDel); lnPivot += nDel;
321
- blob_copy_lines(pOut, pV1, nIns); ln1 += nIns;
322
- blob_copy_lines(0, pV2, nIns); ln2 += nIns;
834
+ p->xChngBoth(p, nDel, nIns);
323835
i1 += 3;
324836
i2 += 3;
325837
}else
326838
{
327839
/* We have found a region where different edits to V1 and V2 overlap.
328840
** This is a merge conflict. Find the size of the conflict, then
329841
** output both possible edits separated by distinctive marks.
330842
*/
331
- int sz = 1; /* Size of the conflict in lines */
843
+ unsigned int sz = 1; /* Size of the conflict in the pivot, in lines */
844
+ unsigned int nV1, nV2; /* Size of conflict in V1 and V2, in lines */
332845
nConflict++;
333
- while( !ends_at_CPY(&aC1[i1], sz) || !ends_at_CPY(&aC2[i2], sz) ){
846
+ while( !ends_with_copy(&aC1[i1], sz) || !ends_with_copy(&aC2[i2], sz) ){
334847
sz++;
335848
}
336
- DEBUG( printf("CONFLICT %d\n", sz); )
337
-
338
- append_merge_mark(pOut, 0, ln1, useCrLf);
339
- i1 = output_one_side(pOut, pV1, aC1, i1, sz, &ln1);
340
-
341
- append_merge_mark(pOut, 1, lnPivot, useCrLf);
342
- blob_copy_lines(pOut, pPivot, sz); lnPivot += sz;
343
-
344
- append_merge_mark(pOut, 2, ln2, useCrLf);
345
- i2 = output_one_side(pOut, pV2, aC2, i2, sz, &ln2);
346
-
347
- append_merge_mark(pOut, 3, -1, useCrLf);
348
- }
349
-
849
+ i1 = skip_conflict(aC1, i1, sz, &nV1);
850
+ i2 = skip_conflict(aC2, i2, sz, &nV2);
851
+ p->xConflict(p, sz, nV1, nV2);
852
+ }
853
+
350854
/* If we are finished with an edit triple, advance to the next
351855
** triple.
352856
*/
353857
if( i1<limit1 && aC1[i1]==0 && aC1[i1+1]==0 && aC1[i1+2]==0 ) i1+=3;
354858
if( i2<limit2 && aC2[i2]==0 && aC2[i2+1]==0 && aC2[i2+2]==0 ) i2+=3;
@@ -356,20 +860,18 @@
356860
357861
/* When one of the two edit vectors reaches its end, there might still
358862
** be an insert in the other edit vector. Output this remaining
359863
** insert.
360864
*/
361
- DEBUG( printf("%d: %2d %2d %2d %d: %2d %2d %2d\n",
362
- i1/3, aC1[i1], aC1[i1+1], aC1[i1+2],
363
- i2/3, aC2[i2], aC2[i2+1], aC2[i2+2]); )
364865
if( i1<limit1 && aC1[i1+2]>0 ){
365
- DEBUG( printf("INSERT +%d left\n", aC1[i1+2]); )
366
- blob_copy_lines(pOut, pV1, aC1[i1+2]);
866
+ p->xChngV1(p, 0, aC1[i1+2]);
367867
}else if( i2<limit2 && aC2[i2+2]>0 ){
368
- DEBUG( printf("INSERT +%d right\n", aC2[i2+2]); )
369
- blob_copy_lines(pOut, pV2, aC2[i2+2]);
868
+ p->xChngV2(p, 0, aC2[i2+2]);
370869
}
870
+
871
+ /* Output footer text */
872
+ p->xEnd(p);
371873
372874
free(aC1);
373875
free(aC2);
374876
return nConflict;
375877
}
@@ -384,11 +886,12 @@
384886
const char *z = blob_buffer(p);
385887
int n = blob_size(p) - len + 1;
386888
assert( len==(int)strlen(mergeMarker[1]) );
387889
assert( len==(int)strlen(mergeMarker[2]) );
388890
assert( len==(int)strlen(mergeMarker[3]) );
389
- assert( count(mergeMarker)==4 );
891
+ assert( len==(int)strlen(mergeMarker[4]) );
892
+ assert( count(mergeMarker)==5 );
390893
for(i=0; i<n; ){
391894
for(j=0; j<4; j++){
392895
if( (memcmp(&z[i], mergeMarker[j], len)==0) ){
393896
return 1;
394897
}
@@ -408,18 +911,106 @@
408911
blob_read_from_file(&file, zFullpath, ExtFILE);
409912
rc = contains_merge_marker(&file);
410913
blob_reset(&file);
411914
return rc;
412915
}
916
+
917
+/*
918
+** Show merge output in a Tcl/Tk window, in response to the --tk option
919
+** to the "merge" or "3-way-merge" command.
920
+**
921
+** If fossil has direct access to a Tcl interpreter (either loaded
922
+** dynamically through stubs or linked in statically), we can use it
923
+** directly. Otherwise:
924
+** (1) Write the Tcl/Tk script used for rendering into a temp file.
925
+** (2) Invoke "tclsh" on the temp file using fossil_system().
926
+** (3) Delete the temp file.
927
+*/
928
+void merge_tk(const char *zSubCmd, int firstArg){
929
+ int i;
930
+ Blob script;
931
+ const char *zTempFile = 0;
932
+ char *zCmd;
933
+ const char *zTclsh;
934
+ const char *zCnt;
935
+ int bDarkMode = find_option("dark",0,0)!=0;
936
+ int nContext;
937
+ zCnt = find_option("context", "c", 1);
938
+ if( zCnt==0 ){
939
+ nContext = 6;
940
+ }else{
941
+ nContext = atoi(zCnt);
942
+ if( nContext<0 ) nContext = 0xfffffff;
943
+ }
944
+ blob_zero(&script);
945
+ blob_appendf(&script, "set ncontext %d\n", nContext);
946
+ blob_appendf(&script, "set fossilcmd {| \"%/\" %s -tcl",
947
+ g.nameOfExe, zSubCmd);
948
+ find_option("tcl",0,0);
949
+ find_option("debug",0,0);
950
+ zTclsh = find_option("tclsh",0,1);
951
+ if( zTclsh==0 ){
952
+ zTclsh = db_get("tclsh",0);
953
+ }
954
+ /* The undocumented --script FILENAME option causes the Tk script to
955
+ ** be written into the FILENAME instead of being run. This is used
956
+ ** for testing and debugging. */
957
+ zTempFile = find_option("script",0,1);
958
+ verify_all_options();
959
+
960
+ if( (g.argc - firstArg)!=3 ){
961
+ fossil_fatal("Requires 3 filename arguments");
962
+ }
963
+
964
+ for(i=firstArg; i<g.argc; i++){
965
+ const char *z = g.argv[i];
966
+ if( sqlite3_strglob("*}*",z) ){
967
+ blob_appendf(&script, " {%/}", z);
968
+ }else{
969
+ int j;
970
+ blob_append(&script, " ", 1);
971
+ for(j=0; z[j]; j++) blob_appendf(&script, "\\%03o", (unsigned char)z[j]);
972
+ }
973
+ }
974
+ blob_appendf(&script, "}\nset darkmode %d\n", bDarkMode);
975
+ blob_appendf(&script, "%s", builtin_file("merge.tcl", 0));
976
+ if( zTempFile ){
977
+ blob_write_to_file(&script, zTempFile);
978
+ fossil_print("To see the merge, run: %s \"%s\"\n", zTclsh, zTempFile);
979
+ }else{
980
+#if defined(FOSSIL_ENABLE_TCL)
981
+ Th_FossilInit(TH_INIT_DEFAULT);
982
+ if( evaluateTclWithEvents(g.interp, &g.tcl, blob_str(&script),
983
+ blob_size(&script), 1, 1, 0)==TCL_OK ){
984
+ blob_reset(&script);
985
+ return;
986
+ }
987
+ /*
988
+ * If evaluation of the Tcl script fails, the reason may be that Tk
989
+ * could not be found by the loaded Tcl, or that Tcl cannot be loaded
990
+ * dynamically (e.g. x64 Tcl with x86 Fossil). Therefore, fallback
991
+ * to using the external "tclsh", if available.
992
+ */
993
+#endif
994
+ zTempFile = write_blob_to_temp_file(&script);
995
+ zCmd = mprintf("%$ %$", zTclsh, zTempFile);
996
+ fossil_system(zCmd);
997
+ file_delete(zTempFile);
998
+ fossil_free(zCmd);
999
+ }
1000
+ blob_reset(&script);
1001
+}
1002
+
4131003
4141004
/*
4151005
** COMMAND: 3-way-merge*
4161006
**
417
-** Usage: %fossil 3-way-merge BASELINE V1 V2 MERGED
1007
+** Usage: %fossil 3-way-merge BASELINE V1 V2 [MERGED]
4181008
**
4191009
** Inputs are files BASELINE, V1, and V2. The file MERGED is generated
420
-** as output.
1010
+** as output. If no MERGED file is specified, output is sent to
1011
+** stdout.
4211012
**
4221013
** BASELINE is a common ancestor of two files V1 and V2 that have diverging
4231014
** edits. The generated output file MERGED is the combination of all
4241015
** changes in both V1 and V2.
4251016
**
@@ -436,38 +1027,75 @@
4361027
** cp Xup.c Xbase.c
4371028
** # Verify that everything still works
4381029
** fossil commit
4391030
**
4401031
*/
441
-void delta_3waymerge_cmd(void){
442
- Blob pivot, v1, v2, merged;
1032
+void merge_3way_cmd(void){
1033
+ MergeBuilder s;
4431034
int nConflict;
1035
+ Blob pivot, v1, v2, out;
1036
+ int noWarn = 0;
1037
+ const char *zCnt;
1038
+
1039
+ if( find_option("tk", 0, 0)!=0 ){
1040
+ merge_tk("3-way-merge", 2);
1041
+ return;
1042
+ }
1043
+ mergebuilder_init_text(&s);
1044
+ if( find_option("debug", 0, 0) ){
1045
+ mergebuilder_init(&s);
1046
+ }
1047
+ if( find_option("tcl", 0, 0) ){
1048
+ mergebuilder_init_tcl(&s);
1049
+ noWarn = 1;
1050
+ }
1051
+ zCnt = find_option("context", "c", 1);
1052
+ if( zCnt ){
1053
+ s.nContext = atoi(zCnt);
1054
+ if( s.nContext<0 ) s.nContext = 0xfffffff;
1055
+ }else{
1056
+ s.nContext = 6;
1057
+ }
1058
+ blob_zero(&pivot); s.pPivot = &pivot;
1059
+ blob_zero(&v1); s.pV1 = &v1;
1060
+ blob_zero(&v2); s.pV2 = &v2;
1061
+ blob_zero(&out); s.pOut = &out;
4441062
4451063
/* We should be done with options.. */
4461064
verify_all_options();
4471065
448
- if( g.argc!=6 ){
449
- usage("PIVOT V1 V2 MERGED");
1066
+ if( g.argc!=6 && g.argc!=5 ){
1067
+ usage("[OPTIONS] PIVOT V1 V2 [MERGED]");
4501068
}
451
- if( blob_read_from_file(&pivot, g.argv[2], ExtFILE)<0 ){
1069
+ s.zPivot = file_tail(g.argv[2]);
1070
+ s.zV1 = file_tail(g.argv[3]);
1071
+ s.zV2 = file_tail(g.argv[4]);
1072
+ if( blob_read_from_file(s.pPivot, g.argv[2], ExtFILE)<0 ){
4521073
fossil_fatal("cannot read %s", g.argv[2]);
4531074
}
454
- if( blob_read_from_file(&v1, g.argv[3], ExtFILE)<0 ){
1075
+ if( blob_read_from_file(s.pV1, g.argv[3], ExtFILE)<0 ){
4551076
fossil_fatal("cannot read %s", g.argv[3]);
4561077
}
457
- if( blob_read_from_file(&v2, g.argv[4], ExtFILE)<0 ){
1078
+ if( blob_read_from_file(s.pV2, g.argv[4], ExtFILE)<0 ){
4581079
fossil_fatal("cannot read %s", g.argv[4]);
4591080
}
460
- nConflict = blob_merge(&pivot, &v1, &v2, &merged);
461
- if( blob_write_to_file(&merged, g.argv[5])<(int)blob_size(&merged) ){
462
- fossil_fatal("cannot write %s", g.argv[4]);
1081
+ nConflict = merge_three_blobs(&s);
1082
+ if( g.argc==6 ){
1083
+ s.zOut = file_tail(g.argv[5]);
1084
+ blob_write_to_file(s.pOut, g.argv[5]);
1085
+ }else{
1086
+ s.zOut = "(Merge Result)";
1087
+ blob_write_to_file(s.pOut, "-");
4631088
}
1089
+ s.xDestroy(&s);
4641090
blob_reset(&pivot);
4651091
blob_reset(&v1);
4661092
blob_reset(&v2);
467
- blob_reset(&merged);
468
- if( nConflict>0 ) fossil_warning("WARNING: %d merge conflicts", nConflict);
1093
+ blob_reset(&out);
1094
+ if( nConflict>0 && !noWarn ){
1095
+ fossil_warning("WARNING: %d merge conflicts", nConflict);
1096
+ }
4691097
}
4701098
4711099
/*
4721100
** aSubst is an array of string pairs. The first element of each pair is
4731101
** a string that begins with %. The second element is a replacement for that
@@ -505,32 +1133,32 @@
5051133
5061134
#if INTERFACE
5071135
/*
5081136
** Flags to the 3-way merger
5091137
*/
510
-#define MERGE_DRYRUN 0x0001
1138
+#define MERGE_DRYRUN 0x0001
5111139
/*
5121140
** The MERGE_KEEP_FILES flag specifies that merge_3way() should retain
5131141
** its temporary files on error. By default they are removed after the
5141142
** merge, regardless of success or failure.
5151143
*/
516
-#define MERGE_KEEP_FILES 0x0002
1144
+#define MERGE_KEEP_FILES 0x0002
5171145
#endif
5181146
5191147
5201148
/*
521
-** This routine is a wrapper around blob_merge() with the following
1149
+** This routine is a wrapper around merge_three_blobs() with the following
5221150
** enhancements:
5231151
**
5241152
** (1) If the merge-command is defined, then use the external merging
5251153
** program specified instead of the built-in blob-merge to do the
5261154
** merging. Panic if the external merger fails.
5271155
** ** Not currently implemented **
5281156
**
5291157
** (2) If gmerge-command is defined and there are merge conflicts in
530
-** blob_merge() then invoke the external graphical merger to resolve
531
-** the conflicts.
1158
+** merge_three_blobs() then invoke the external graphical merger
1159
+** to resolve the conflicts.
5321160
**
5331161
** (3) If a merge conflict occurs and gmerge-command is not defined,
5341162
** then write the pivot, original, and merge-in files to the
5351163
** filesystem.
5361164
*/
@@ -539,30 +1167,37 @@
5391167
const char *zV1, /* Name of file for version merging into (mine) */
5401168
Blob *pV2, /* Version merging from (yours) */
5411169
Blob *pOut, /* Output written here */
5421170
unsigned mergeFlags /* Flags that control operation */
5431171
){
544
- Blob v1; /* Content of zV1 */
545
- int rc; /* Return code of subroutines and this routine */
1172
+ Blob v1; /* Content of zV1 */
1173
+ int rc; /* Return code of subroutines and this routine */
5461174
const char *zGMerge; /* Name of the gmerge command */
1175
+ MergeBuilder s; /* The merge state */
5471176
548
- blob_read_from_file(&v1, zV1, ExtFILE);
549
- rc = blob_merge(pPivot, &v1, pV2, pOut);
1177
+ mergebuilder_init_text(&s);
1178
+ s.pPivot = pPivot;
1179
+ s.pV1 = &v1;
1180
+ s.pV2 = pV2;
1181
+ blob_zero(pOut);
1182
+ s.pOut = pOut;
1183
+ blob_read_from_file(s.pV1, zV1, ExtFILE);
1184
+ rc = merge_three_blobs(&s);
5501185
zGMerge = rc<=0 ? 0 : db_get("gmerge-command", 0);
5511186
if( (mergeFlags & MERGE_DRYRUN)==0
5521187
&& ((zGMerge!=0 && zGMerge[0]!=0)
5531188
|| (rc!=0 && (mergeFlags & MERGE_KEEP_FILES)!=0)) ){
5541189
char *zPivot; /* Name of the pivot file */
5551190
char *zOrig; /* Name of the original content file */
5561191
char *zOther; /* Name of the merge file */
5571192
5581193
zPivot = file_newname(zV1, "baseline", 1);
559
- blob_write_to_file(pPivot, zPivot);
1194
+ blob_write_to_file(s.pPivot, zPivot);
5601195
zOrig = file_newname(zV1, "original", 1);
561
- blob_write_to_file(&v1, zOrig);
1196
+ blob_write_to_file(s.pV1, zOrig);
5621197
zOther = file_newname(zV1, "merge", 1);
563
- blob_write_to_file(pV2, zOther);
1198
+ blob_write_to_file(s.pV2, zOther);
5641199
if( rc>0 ){
5651200
if( zGMerge && zGMerge[0] ){
5661201
char *zOut; /* Temporary output file */
5671202
char *zCmd; /* Command to invoke */
5681203
const char *azSubst[8]; /* Strings to be substituted */
@@ -590,7 +1225,8 @@
5901225
fossil_free(zPivot);
5911226
fossil_free(zOrig);
5921227
fossil_free(zOther);
5931228
}
5941229
blob_reset(&v1);
1230
+ s.xDestroy(&s);
5951231
return rc;
5961232
}
5971233
--- src/merge3.c
+++ src/merge3.c
@@ -75,75 +75,17 @@
75 if( aC1[2]!=aC2[2] ) return 0;
76 if( sameLines(pV1, pV2, aC1[2]) ) return 1;
77 return 0;
78 }
79
80 /*
81 ** The aC[] array contains triples of integers. Within each triple, the
82 ** elements are:
83 **
84 ** (0) The number of lines to copy
85 ** (1) The number of lines to delete
86 ** (2) The number of liens to insert
87 **
88 ** Suppose we want to advance over sz lines of the original file. This routine
89 ** returns true if that advance would land us on a copy operation. It
90 ** returns false if the advance would end on a delete.
91 */
92 static int ends_at_CPY(int *aC, int sz){
93 while( sz>0 && (aC[0]>0 || aC[1]>0 || aC[2]>0) ){
94 if( aC[0]>=sz ) return 1;
95 sz -= aC[0];
96 if( aC[1]>sz ) return 0;
97 sz -= aC[1];
98 aC += 3;
99 }
100 return 1;
101 }
102
103 /*
104 ** pSrc contains an edited file where aC[] describes the edit. Part of
105 ** pSrc has already been output. This routine outputs additional lines
106 ** of pSrc - lines that correspond to the next sz lines of the original
107 ** unedited file.
108 **
109 ** Note that sz counts the number of lines of text in the original file.
110 ** But text is output from the edited file. So the number of lines transfer
111 ** to pOut might be different from sz. Fewer lines appear in pOut if there
112 ** are deletes. More lines appear if there are inserts.
113 **
114 ** The aC[] array is updated and the new index into aC[] is returned.
115 */
116 static int output_one_side(
117 Blob *pOut, /* Write to this blob */
118 Blob *pSrc, /* The edited file that is to be copied to pOut */
119 int *aC, /* Array of integer triples describing the edit */
120 int i, /* Index in aC[] of current location in pSrc */
121 int sz, /* Number of lines in unedited source to output */
122 int *pLn /* Line number counter */
123 ){
124 while( sz>0 ){
125 if( aC[i]==0 && aC[i+1]==0 && aC[i+2]==0 ) break;
126 if( aC[i]>=sz ){
127 blob_copy_lines(pOut, pSrc, sz); *pLn += sz;
128 aC[i] -= sz;
129 break;
130 }
131 blob_copy_lines(pOut, pSrc, aC[i]); *pLn += aC[i];
132 blob_copy_lines(pOut, pSrc, aC[i+2]); *pLn += aC[i+2];
133 sz -= aC[i] + aC[i+1];
134 i += 3;
135 }
136 return i;
137 }
138
139 /*
140 ** Text of boundary markers for merge conflicts.
141 */
142 static const char *const mergeMarker[] = {
143 /*123456789 123456789 123456789 123456789 123456789 123456789 123456789*/
144 "<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<<",
 
145 "||||||| COMMON ANCESTOR content follows |||||||||||||||||||||||||",
146 "======= MERGED IN content follows ===============================",
147 ">>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
148 };
149
@@ -186,10 +128,615 @@
186 ensure_line_end(pOut, useCrLf);
187 blob_append(pOut, mergeMarker[iMark], -1);
188 if( ln>0 ) blob_appendf(pOut, " (line %d)", ln);
189 ensure_line_end(pOut, useCrLf);
190 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
192 /*
193 ** Do a three-way merge. Initialize pOut to contain the result.
194 **
195 ** The merge is an edit against pV2. Both pV1 and pV2 have a
@@ -199,156 +746,113 @@
199 ** The return is 0 upon complete success. If any input file is binary,
200 ** -1 is returned and pOut is unmodified. If there are merge
201 ** conflicts, the merge proceeds as best as it can and the number
202 ** of conflicts is returns
203 */
204 static int blob_merge(Blob *pPivot, Blob *pV1, Blob *pV2, Blob *pOut){
205 int *aC1; /* Changes from pPivot to pV1 */
206 int *aC2; /* Changes from pPivot to pV2 */
207 int i1, i2; /* Index into aC1[] and aC2[] */
208 int nCpy, nDel, nIns; /* Number of lines to copy, delete, or insert */
209 int limit1, limit2; /* Sizes of aC1[] and aC2[] */
210 int nConflict = 0; /* Number of merge conflicts seen so far */
211 int useCrLf = 0;
212 int ln1, ln2, lnPivot; /* Line numbers for all files */
213 DiffConfig DCfg;
214
215 blob_zero(pOut); /* Merge results stored in pOut */
216
217 /* If both pV1 and pV2 start with a UTF-8 byte-order-mark (BOM),
218 ** keep it in the output. This should be secure enough not to cause
219 ** unintended changes to the merged file and consistent with what
220 ** users are using in their source files.
221 */
222 if( starts_with_utf8_bom(pV1, 0) && starts_with_utf8_bom(pV2, 0) ){
223 blob_append(pOut, (char*)get_utf8_bom(0), -1);
224 }
225
226 /* Check once to see if both pV1 and pV2 contains CR/LF endings.
227 ** If true, CR/LF pair will be used later to append the
228 ** boundary markers for merge conflicts.
229 */
230 if( contains_crlf(pV1) && contains_crlf(pV2) ){
231 useCrLf = 1;
232 }
233
234 /* Compute the edits that occur from pPivot => pV1 (into aC1)
235 ** and pPivot => pV2 (into aC2). Each of the aC1 and aC2 arrays is
236 ** an array of integer triples. Within each triple, the first integer
237 ** is the number of lines of text to copy directly from the pivot,
238 ** the second integer is the number of lines of text to omit from the
239 ** pivot, and the third integer is the number of lines of text that are
240 ** inserted. The edit array ends with a triple of 0,0,0.
241 */
242 diff_config_init(&DCfg, 0);
243 aC1 = text_diff(pPivot, pV1, 0, &DCfg);
244 aC2 = text_diff(pPivot, pV2, 0, &DCfg);
 
245 if( aC1==0 || aC2==0 ){
246 free(aC1);
247 free(aC2);
248 return -1;
249 }
250
251 blob_rewind(pV1); /* Rewind inputs: Needed to reconstruct output */
252 blob_rewind(pV2);
253 blob_rewind(pPivot);
254
255 /* Determine the length of the aC1[] and aC2[] change vectors */
256 for(i1=0; aC1[i1] || aC1[i1+1] || aC1[i1+2]; i1+=3){}
 
 
 
 
 
257 limit1 = i1;
258 for(i2=0; aC2[i2] || aC2[i2+1] || aC2[i2+2]; i2+=3){}
 
 
 
259 limit2 = i2;
260
261 DEBUG(
262 for(i1=0; i1<limit1; i1+=3){
263 printf("c1: %4d %4d %4d\n", aC1[i1], aC1[i1+1], aC1[i1+2]);
264 }
265 for(i2=0; i2<limit2; i2+=3){
266 printf("c2: %4d %4d %4d\n", aC2[i2], aC2[i2+1], aC2[i2+2]);
267 }
268 )
269
270 /* Loop over the two edit vectors and use them to compute merged text
271 ** which is written into pOut. i1 and i2 are multiples of 3 which are
272 ** indices into aC1[] and aC2[] to the edit triple currently being
273 ** processed
274 */
275 i1 = i2 = 0;
276 ln1 = ln2 = lnPivot = 1;
277 while( i1<limit1 && i2<limit2 ){
278 DEBUG( printf("%d: %2d %2d %2d %d: %2d %2d %2d\n",
279 i1/3, aC1[i1], aC1[i1+1], aC1[i1+2],
280 i2/3, aC2[i2], aC2[i2+1], aC2[i2+2]); )
281
282 if( aC1[i1]>0 && aC2[i2]>0 ){
283 /* Output text that is unchanged in both V1 and V2 */
284 nCpy = min(aC1[i1], aC2[i2]);
285 DEBUG( printf("COPY %d\n", nCpy); )
286 blob_copy_lines(pOut, pPivot, nCpy); lnPivot += nCpy;
287 blob_copy_lines(0, pV1, nCpy); ln1 += nCpy;
288 blob_copy_lines(0, pV2, nCpy); ln2 += nCpy;
289 aC1[i1] -= nCpy;
290 aC2[i2] -= nCpy;
291 }else
292 if( aC1[i1] >= aC2[i2+1] && aC1[i1]>0 && aC2[i2+1]+aC2[i2+2]>0 ){
293 /* Output edits to V2 that occurs within unchanged regions of V1 */
294 nDel = aC2[i2+1];
295 nIns = aC2[i2+2];
296 DEBUG( printf("EDIT -%d+%d left\n", nDel, nIns); )
297 blob_copy_lines(0, pPivot, nDel); lnPivot += nDel;
298 blob_copy_lines(0, pV1, nDel); ln1 += nDel;
299 blob_copy_lines(pOut, pV2, nIns); ln2 += nIns;
300 aC1[i1] -= nDel;
301 i2 += 3;
302 }else
303 if( aC2[i2] >= aC1[i1+1] && aC2[i2]>0 && aC1[i1+1]+aC1[i1+2]>0 ){
304 /* Output edits to V1 that occur within unchanged regions of V2 */
305 nDel = aC1[i1+1];
306 nIns = aC1[i1+2];
307 DEBUG( printf("EDIT -%d+%d right\n", nDel, nIns); )
308 blob_copy_lines(0, pPivot, nDel); lnPivot += nDel;
309 blob_copy_lines(0, pV2, nDel); ln2 += nDel;
310 blob_copy_lines(pOut, pV1, nIns); ln1 += nIns;
311 aC2[i2] -= nDel;
312 i1 += 3;
313 }else
314 if( sameEdit(&aC1[i1], &aC2[i2], pV1, pV2) ){
315 /* Output edits that are identical in both V1 and V2. */
316 assert( aC1[i1]==0 );
317 nDel = aC1[i1+1];
318 nIns = aC1[i1+2];
319 DEBUG( printf("EDIT -%d+%d both\n", nDel, nIns); )
320 blob_copy_lines(0, pPivot, nDel); lnPivot += nDel;
321 blob_copy_lines(pOut, pV1, nIns); ln1 += nIns;
322 blob_copy_lines(0, pV2, nIns); ln2 += nIns;
323 i1 += 3;
324 i2 += 3;
325 }else
326 {
327 /* We have found a region where different edits to V1 and V2 overlap.
328 ** This is a merge conflict. Find the size of the conflict, then
329 ** output both possible edits separated by distinctive marks.
330 */
331 int sz = 1; /* Size of the conflict in lines */
 
332 nConflict++;
333 while( !ends_at_CPY(&aC1[i1], sz) || !ends_at_CPY(&aC2[i2], sz) ){
334 sz++;
335 }
336 DEBUG( printf("CONFLICT %d\n", sz); )
337
338 append_merge_mark(pOut, 0, ln1, useCrLf);
339 i1 = output_one_side(pOut, pV1, aC1, i1, sz, &ln1);
340
341 append_merge_mark(pOut, 1, lnPivot, useCrLf);
342 blob_copy_lines(pOut, pPivot, sz); lnPivot += sz;
343
344 append_merge_mark(pOut, 2, ln2, useCrLf);
345 i2 = output_one_side(pOut, pV2, aC2, i2, sz, &ln2);
346
347 append_merge_mark(pOut, 3, -1, useCrLf);
348 }
349
350 /* If we are finished with an edit triple, advance to the next
351 ** triple.
352 */
353 if( i1<limit1 && aC1[i1]==0 && aC1[i1+1]==0 && aC1[i1+2]==0 ) i1+=3;
354 if( i2<limit2 && aC2[i2]==0 && aC2[i2+1]==0 && aC2[i2+2]==0 ) i2+=3;
@@ -356,20 +860,18 @@
356
357 /* When one of the two edit vectors reaches its end, there might still
358 ** be an insert in the other edit vector. Output this remaining
359 ** insert.
360 */
361 DEBUG( printf("%d: %2d %2d %2d %d: %2d %2d %2d\n",
362 i1/3, aC1[i1], aC1[i1+1], aC1[i1+2],
363 i2/3, aC2[i2], aC2[i2+1], aC2[i2+2]); )
364 if( i1<limit1 && aC1[i1+2]>0 ){
365 DEBUG( printf("INSERT +%d left\n", aC1[i1+2]); )
366 blob_copy_lines(pOut, pV1, aC1[i1+2]);
367 }else if( i2<limit2 && aC2[i2+2]>0 ){
368 DEBUG( printf("INSERT +%d right\n", aC2[i2+2]); )
369 blob_copy_lines(pOut, pV2, aC2[i2+2]);
370 }
 
 
 
371
372 free(aC1);
373 free(aC2);
374 return nConflict;
375 }
@@ -384,11 +886,12 @@
384 const char *z = blob_buffer(p);
385 int n = blob_size(p) - len + 1;
386 assert( len==(int)strlen(mergeMarker[1]) );
387 assert( len==(int)strlen(mergeMarker[2]) );
388 assert( len==(int)strlen(mergeMarker[3]) );
389 assert( count(mergeMarker)==4 );
 
390 for(i=0; i<n; ){
391 for(j=0; j<4; j++){
392 if( (memcmp(&z[i], mergeMarker[j], len)==0) ){
393 return 1;
394 }
@@ -408,18 +911,106 @@
408 blob_read_from_file(&file, zFullpath, ExtFILE);
409 rc = contains_merge_marker(&file);
410 blob_reset(&file);
411 return rc;
412 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
413
414 /*
415 ** COMMAND: 3-way-merge*
416 **
417 ** Usage: %fossil 3-way-merge BASELINE V1 V2 MERGED
418 **
419 ** Inputs are files BASELINE, V1, and V2. The file MERGED is generated
420 ** as output.
 
421 **
422 ** BASELINE is a common ancestor of two files V1 and V2 that have diverging
423 ** edits. The generated output file MERGED is the combination of all
424 ** changes in both V1 and V2.
425 **
@@ -436,38 +1027,75 @@
436 ** cp Xup.c Xbase.c
437 ** # Verify that everything still works
438 ** fossil commit
439 **
440 */
441 void delta_3waymerge_cmd(void){
442 Blob pivot, v1, v2, merged;
443 int nConflict;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
444
445 /* We should be done with options.. */
446 verify_all_options();
447
448 if( g.argc!=6 ){
449 usage("PIVOT V1 V2 MERGED");
450 }
451 if( blob_read_from_file(&pivot, g.argv[2], ExtFILE)<0 ){
 
 
 
452 fossil_fatal("cannot read %s", g.argv[2]);
453 }
454 if( blob_read_from_file(&v1, g.argv[3], ExtFILE)<0 ){
455 fossil_fatal("cannot read %s", g.argv[3]);
456 }
457 if( blob_read_from_file(&v2, g.argv[4], ExtFILE)<0 ){
458 fossil_fatal("cannot read %s", g.argv[4]);
459 }
460 nConflict = blob_merge(&pivot, &v1, &v2, &merged);
461 if( blob_write_to_file(&merged, g.argv[5])<(int)blob_size(&merged) ){
462 fossil_fatal("cannot write %s", g.argv[4]);
 
 
 
 
463 }
 
464 blob_reset(&pivot);
465 blob_reset(&v1);
466 blob_reset(&v2);
467 blob_reset(&merged);
468 if( nConflict>0 ) fossil_warning("WARNING: %d merge conflicts", nConflict);
 
 
469 }
470
471 /*
472 ** aSubst is an array of string pairs. The first element of each pair is
473 ** a string that begins with %. The second element is a replacement for that
@@ -505,32 +1133,32 @@
505
506 #if INTERFACE
507 /*
508 ** Flags to the 3-way merger
509 */
510 #define MERGE_DRYRUN 0x0001
511 /*
512 ** The MERGE_KEEP_FILES flag specifies that merge_3way() should retain
513 ** its temporary files on error. By default they are removed after the
514 ** merge, regardless of success or failure.
515 */
516 #define MERGE_KEEP_FILES 0x0002
517 #endif
518
519
520 /*
521 ** This routine is a wrapper around blob_merge() with the following
522 ** enhancements:
523 **
524 ** (1) If the merge-command is defined, then use the external merging
525 ** program specified instead of the built-in blob-merge to do the
526 ** merging. Panic if the external merger fails.
527 ** ** Not currently implemented **
528 **
529 ** (2) If gmerge-command is defined and there are merge conflicts in
530 ** blob_merge() then invoke the external graphical merger to resolve
531 ** the conflicts.
532 **
533 ** (3) If a merge conflict occurs and gmerge-command is not defined,
534 ** then write the pivot, original, and merge-in files to the
535 ** filesystem.
536 */
@@ -539,30 +1167,37 @@
539 const char *zV1, /* Name of file for version merging into (mine) */
540 Blob *pV2, /* Version merging from (yours) */
541 Blob *pOut, /* Output written here */
542 unsigned mergeFlags /* Flags that control operation */
543 ){
544 Blob v1; /* Content of zV1 */
545 int rc; /* Return code of subroutines and this routine */
546 const char *zGMerge; /* Name of the gmerge command */
 
547
548 blob_read_from_file(&v1, zV1, ExtFILE);
549 rc = blob_merge(pPivot, &v1, pV2, pOut);
 
 
 
 
 
 
550 zGMerge = rc<=0 ? 0 : db_get("gmerge-command", 0);
551 if( (mergeFlags & MERGE_DRYRUN)==0
552 && ((zGMerge!=0 && zGMerge[0]!=0)
553 || (rc!=0 && (mergeFlags & MERGE_KEEP_FILES)!=0)) ){
554 char *zPivot; /* Name of the pivot file */
555 char *zOrig; /* Name of the original content file */
556 char *zOther; /* Name of the merge file */
557
558 zPivot = file_newname(zV1, "baseline", 1);
559 blob_write_to_file(pPivot, zPivot);
560 zOrig = file_newname(zV1, "original", 1);
561 blob_write_to_file(&v1, zOrig);
562 zOther = file_newname(zV1, "merge", 1);
563 blob_write_to_file(pV2, zOther);
564 if( rc>0 ){
565 if( zGMerge && zGMerge[0] ){
566 char *zOut; /* Temporary output file */
567 char *zCmd; /* Command to invoke */
568 const char *azSubst[8]; /* Strings to be substituted */
@@ -590,7 +1225,8 @@
590 fossil_free(zPivot);
591 fossil_free(zOrig);
592 fossil_free(zOther);
593 }
594 blob_reset(&v1);
 
595 return rc;
596 }
597
--- src/merge3.c
+++ src/merge3.c
@@ -75,75 +75,17 @@
75 if( aC1[2]!=aC2[2] ) return 0;
76 if( sameLines(pV1, pV2, aC1[2]) ) return 1;
77 return 0;
78 }
79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80 /*
81 ** Text of boundary markers for merge conflicts.
82 */
83 static const char *const mergeMarker[] = {
84 /*123456789 123456789 123456789 123456789 123456789 123456789 123456789*/
85 "<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<<",
86 "####### SUGGESTED CONFLICT RESOLUTION follows ###################",
87 "||||||| COMMON ANCESTOR content follows |||||||||||||||||||||||||",
88 "======= MERGED IN content follows ===============================",
89 ">>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
90 };
91
@@ -186,10 +128,615 @@
128 ensure_line_end(pOut, useCrLf);
129 blob_append(pOut, mergeMarker[iMark], -1);
130 if( ln>0 ) blob_appendf(pOut, " (line %d)", ln);
131 ensure_line_end(pOut, useCrLf);
132 }
133
134 #if INTERFACE
135 /*
136 ** This is an abstract class for constructing a merge.
137 ** Subclasses of this object format the merge output in different ways.
138 **
139 ** To subclass, create an instance of the MergeBuilder object and fill
140 ** in appropriate method implementations.
141 */
142 struct MergeBuilder {
143 void (*xStart)(MergeBuilder*);
144 void (*xSame)(MergeBuilder*, unsigned int);
145 void (*xChngV1)(MergeBuilder*, unsigned int, unsigned int);
146 void (*xChngV2)(MergeBuilder*, unsigned int, unsigned int);
147 void (*xChngBoth)(MergeBuilder*, unsigned int, unsigned int);
148 void (*xConflict)(MergeBuilder*, unsigned int, unsigned int, unsigned int);
149 void (*xEnd)(MergeBuilder*);
150 void (*xDestroy)(MergeBuilder*);
151 const char *zPivot; /* Label or name for the pivot */
152 const char *zV1; /* Label or name for the V1 file */
153 const char *zV2; /* Label or name for the V2 file */
154 const char *zOut; /* Label or name for the output */
155 Blob *pPivot; /* The common ancestor */
156 Blob *pV1; /* First variant (local copy) */
157 Blob *pV2; /* Second variant (merged in) */
158 Blob *pOut; /* Write merge results here */
159 int useCrLf; /* Use CRLF line endings */
160 int nContext; /* Size of unchanged line boundaries */
161 unsigned int mxPivot; /* Number of lines in the pivot */
162 unsigned int mxV1; /* Number of lines in V1 */
163 unsigned int mxV2; /* Number of lines in V2 */
164 unsigned int lnPivot; /* Lines read from pivot */
165 unsigned int lnV1; /* Lines read from v1 */
166 unsigned int lnV2; /* Lines read from v2 */
167 unsigned int lnOut; /* Lines written to out */
168 unsigned int nConflict; /* Number of conflicts seen */
169 u64 diffFlags; /* Flags for difference engine */
170 };
171 #endif /* INTERFACE */
172
173
174 /************************* Generic MergeBuilder ******************************/
175 /* These are generic methods for MergeBuilder. They just output debugging
176 ** information. But some of them are useful as base methods for other useful
177 ** implementations of MergeBuilder.
178 */
179
180 /* xStart() and xEnd() are called to generate header and fotter information
181 ** in the output. This is a no-op in the generic implementation.
182 */
183 static void dbgStartEnd(MergeBuilder *p){ (void)p; }
184
185 /* The next N lines of PIVOT are unchanged in both V1 and V2
186 */
187 static void dbgSame(MergeBuilder *p, unsigned int N){
188 blob_appendf(p->pOut,
189 "COPY %u from BASELINE(%u..%u) or V1(%u..%u) or V2(%u..%u)\n",
190 N, p->lnPivot+1, p->lnPivot+N, p->lnV1+1, p->lnV1+N,
191 p->lnV2+1, p->lnV2+N);
192 p->lnPivot += N;
193 p->lnV1 += N;
194 p->lnV2 += N;
195 }
196
197 /* The next nPivot lines of the PIVOT are changed into nV1 lines by V1
198 */
199 static void dbgChngV1(MergeBuilder *p, unsigned int nPivot, unsigned int nV1){
200 blob_appendf(p->pOut, "COPY %u from V1(%u..%u)\n",
201 nV1, p->lnV1+1, p->lnV1+nV1);
202 p->lnPivot += nPivot;
203 p->lnV2 += nPivot;
204 p->lnV1 += nV1;
205 }
206
207 /* The next nPivot lines of the PIVOT are changed into nV2 lines by V2
208 */
209 static void dbgChngV2(MergeBuilder *p, unsigned int nPivot, unsigned int nV2){
210 blob_appendf(p->pOut, "COPY %u lines FROM V2(%u..%u)\n",
211 nV2, p->lnV2+1, p->lnV2+nV2);
212 p->lnPivot += nPivot;
213 p->lnV1 += nPivot;
214 p->lnV2 += nV2;
215 }
216
217 /* The next nPivot lines of the PIVOT are changed into nV lines from V1 and
218 ** V2, which should be the same. In other words, the same change is found
219 ** in both V1 and V2.
220 */
221 static void dbgChngBoth(MergeBuilder *p, unsigned int nPivot, unsigned int nV){
222 blob_appendf(p->pOut, "COPY %u lines from V1(%u..%u) or V2(%u..%u)\n",
223 nV, p->lnV1+1, p->lnV1+nV, p->lnV2+1, p->lnV2+nV);
224 p->lnPivot += nPivot;
225 p->lnV1 += nV;
226 p->lnV2 += nV;
227 }
228
229 /* V1 and V2 have different and overlapping changes. The next nPivot lines
230 ** of the PIVOT are converted into nV1 lines of V1 and nV2 lines of V2.
231 */
232 static void dbgConflict(
233 MergeBuilder *p,
234 unsigned int nPivot,
235 unsigned int nV1,
236 unsigned int nV2
237 ){
238 blob_appendf(p->pOut,
239 "CONFLICT %u,%u,%u BASELINE(%u..%u) versus V1(%u..%u) versus V2(%u..%u)\n",
240 nPivot, nV1, nV2,
241 p->lnPivot+1, p->lnPivot+nPivot,
242 p->lnV1+1, p->lnV1+nV1,
243 p->lnV2+1, p->lnV2+nV2);
244 p->lnV1 += nV1;
245 p->lnPivot += nPivot;
246 p->lnV2 += nV2;
247 }
248
249 /* Generic destructor for the MergeBuilder object
250 */
251 static void dbgDestroy(MergeBuilder *p){
252 memset(p, 0, sizeof(*p));
253 }
254
255 /* Generic initializer for a MergeBuilder object
256 */
257 static void mergebuilder_init(MergeBuilder *p){
258 memset(p, 0, sizeof(*p));
259 p->xStart = dbgStartEnd;
260 p->xSame = dbgSame;
261 p->xChngV1 = dbgChngV1;
262 p->xChngV2 = dbgChngV2;
263 p->xChngBoth = dbgChngBoth;
264 p->xConflict = dbgConflict;
265 p->xEnd = dbgStartEnd;
266 p->xDestroy = dbgDestroy;
267 }
268
269 /************************* MergeBuilderToken ********************************/
270 /* This version of MergeBuilder actually performs a merge on file that
271 ** are broken up into tokens instead of lines, and puts the result in pOut.
272 */
273 static void tokenSame(MergeBuilder *p, unsigned int N){
274 blob_append(p->pOut, p->pPivot->aData+p->pPivot->iCursor, N);
275 p->pPivot->iCursor += N;
276 p->pV1->iCursor += N;
277 p->pV2->iCursor += N;
278 }
279 static void tokenChngV1(MergeBuilder *p, unsigned int nPivot, unsigned nV1){
280 blob_append(p->pOut, p->pV1->aData+p->pV1->iCursor, nV1);
281 p->pPivot->iCursor += nPivot;
282 p->pV1->iCursor += nV1;
283 p->pV2->iCursor += nPivot;
284 }
285 static void tokenChngV2(MergeBuilder *p, unsigned int nPivot, unsigned nV2){
286 blob_append(p->pOut, p->pV2->aData+p->pV2->iCursor, nV2);
287 p->pPivot->iCursor += nPivot;
288 p->pV1->iCursor += nPivot;
289 p->pV2->iCursor += nV2;
290 }
291 static void tokenChngBoth(MergeBuilder *p, unsigned int nPivot, unsigned nV){
292 blob_append(p->pOut, p->pV2->aData+p->pV2->iCursor, nV);
293 p->pPivot->iCursor += nPivot;
294 p->pV1->iCursor += nV;
295 p->pV2->iCursor += nV;
296 }
297 static void tokenConflict(
298 MergeBuilder *p,
299 unsigned int nPivot,
300 unsigned int nV1,
301 unsigned int nV2
302 ){
303 /* For a token-merge conflict, use the text from the merge-in */
304 blob_append(p->pOut, p->pV2->aData+p->pV2->iCursor, nV2);
305 p->pPivot->iCursor += nPivot;
306 p->pV1->iCursor += nV1;
307 p->pV2->iCursor += nV2;
308 }
309 static void mergebuilder_init_token(MergeBuilder *p){
310 mergebuilder_init(p);
311 p->xSame = tokenSame;
312 p->xChngV1 = tokenChngV1;
313 p->xChngV2 = tokenChngV2;
314 p->xChngBoth = tokenChngBoth;
315 p->xConflict = tokenConflict;
316 p->diffFlags = DIFF_BY_TOKEN;
317 }
318
319 /*
320 ** Attempt to do a low-level merge on a conflict. The conflict is
321 ** described by the first four parameters, which are the same as the
322 ** arguments to the xConflict method of the MergeBuilder object.
323 ** This routine attempts to resolve the conflict by looking at
324 ** elements of the conflict region that are finer grain than complete
325 ** lines of text.
326 **
327 ** The result is written into Blob pOut. pOut is initialized by this
328 ** routine.
329 */
330 int merge_try_to_resolve_conflict(
331 MergeBuilder *pMB, /* MergeBuilder that encounter conflict */
332 unsigned int nPivot, /* Lines of conflict in the pivot */
333 unsigned int nV1, /* Lines of conflict in V1 */
334 unsigned int nV2, /* Lines of conflict in V2 */
335 Blob *pOut /* Write resolution text here */
336 ){
337 int nConflict;
338 MergeBuilder mb;
339 Blob pv, v1, v2;
340 mergebuilder_init_token(&mb);
341 blob_extract_lines(pMB->pPivot, nPivot, &pv);
342 blob_extract_lines(pMB->pV1, nV1, &v1);
343 blob_extract_lines(pMB->pV2, nV2, &v2);
344 blob_zero(pOut);
345 blob_materialize(&pv);
346 blob_materialize(&v1);
347 blob_materialize(&v2);
348 mb.pPivot = &pv;
349 mb.pV1 = &v1;
350 mb.pV2 = &v2;
351 mb.pOut = pOut;
352 nConflict = merge_three_blobs(&mb);
353 blob_reset(&pv);
354 blob_reset(&v1);
355 blob_reset(&v2);
356 /* mb has not allocated any resources, so we do not need to invoke
357 ** the xDestroy method. */
358 blob_add_final_newline(pOut);
359 return nConflict;
360 }
361
362
363 /************************* MergeBuilderText **********************************/
364 /* This version of MergeBuilder actually performs a merge on file and puts
365 ** the result in pOut
366 */
367 static void txtStart(MergeBuilder *p){
368 /* If both pV1 and pV2 start with a UTF-8 byte-order-mark (BOM),
369 ** keep it in the output. This should be secure enough not to cause
370 ** unintended changes to the merged file and consistent with what
371 ** users are using in their source files.
372 */
373 if( starts_with_utf8_bom(p->pV1, 0) && starts_with_utf8_bom(p->pV2, 0) ){
374 blob_append(p->pOut, (char*)get_utf8_bom(0), -1);
375 }
376 if( contains_crlf(p->pV1) && contains_crlf(p->pV2) ){
377 p->useCrLf = 1;
378 }
379 }
380 static void txtSame(MergeBuilder *p, unsigned int N){
381 blob_copy_lines(p->pOut, p->pPivot, N); p->lnPivot += N;
382 blob_copy_lines(0, p->pV1, N); p->lnV1 += N;
383 blob_copy_lines(0, p->pV2, N); p->lnV2 += N;
384 }
385 static void txtChngV1(MergeBuilder *p, unsigned int nPivot, unsigned int nV1){
386 blob_copy_lines(0, p->pPivot, nPivot); p->lnPivot += nPivot;
387 blob_copy_lines(0, p->pV2, nPivot); p->lnV2 += nPivot;
388 blob_copy_lines(p->pOut, p->pV1, nV1); p->lnV1 += nV1;
389 }
390 static void txtChngV2(MergeBuilder *p, unsigned int nPivot, unsigned int nV2){
391 blob_copy_lines(0, p->pPivot, nPivot); p->lnPivot += nPivot;
392 blob_copy_lines(0, p->pV1, nPivot); p->lnV1 += nPivot;
393 blob_copy_lines(p->pOut, p->pV2, nV2); p->lnV2 += nV2;
394 }
395 static void txtChngBoth(MergeBuilder *p, unsigned int nPivot, unsigned int nV){
396 blob_copy_lines(0, p->pPivot, nPivot); p->lnPivot += nPivot;
397 blob_copy_lines(0, p->pV1, nV); p->lnV1 += nV;
398 blob_copy_lines(p->pOut, p->pV2, nV); p->lnV2 += nV;
399 }
400 static void txtConflict(
401 MergeBuilder *p,
402 unsigned int nPivot,
403 unsigned int nV1,
404 unsigned int nV2
405 ){
406 int nRes; /* Lines in the computed conflict resolution */
407 Blob res; /* Text of the conflict resolution */
408
409 merge_try_to_resolve_conflict(p, nPivot, nV1, nV2, &res);
410 nRes = blob_linecount(&res);
411
412 append_merge_mark(p->pOut, 0, p->lnV1+1, p->useCrLf);
413 blob_copy_lines(p->pOut, p->pV1, nV1); p->lnV1 += nV1;
414
415 if( nRes>0 ){
416 append_merge_mark(p->pOut, 1, 0, p->useCrLf);
417 blob_copy_lines(p->pOut, &res, nRes);
418 }
419 blob_reset(&res);
420
421 append_merge_mark(p->pOut, 2, p->lnPivot+1, p->useCrLf);
422 blob_copy_lines(p->pOut, p->pPivot, nPivot); p->lnPivot += nPivot;
423
424 append_merge_mark(p->pOut, 3, p->lnV2+1, p->useCrLf);
425 blob_copy_lines(p->pOut, p->pV2, nV2); p->lnV2 += nV2;
426
427 append_merge_mark(p->pOut, 4, -1, p->useCrLf);
428 }
429 static void mergebuilder_init_text(MergeBuilder *p){
430 mergebuilder_init(p);
431 p->xStart = txtStart;
432 p->xSame = txtSame;
433 p->xChngV1 = txtChngV1;
434 p->xChngV2 = txtChngV2;
435 p->xChngBoth = txtChngBoth;
436 p->xConflict = txtConflict;
437 }
438
439 /************************* MergeBuilderTcl **********************************/
440 /* Generate merge output formatted for reading by a TCL script.
441 **
442 ** The output consists of lines of text, each with 4 tokens. The tokens
443 ** represent the content for one line from baseline, v1, v2, and output
444 ** respectively. The first character of each token provides auxiliary
445 ** information:
446 **
447 ** . This line is omitted.
448 ** N Name of the file.
449 ** T Literal text follows that should have a \n terminator.
450 ** R Literal text follows that needs a \r\n terminator.
451 ** X Merge conflict.
452 ** Z Literal text without a line terminator.
453 ** S Skipped lines. Followed by number of lines to skip.
454 ** 1 Text is a copy of token 1
455 ** 2 Use data from data-token 2
456 ** 3 Use data from data-token 3
457 */
458
459 /* Write text that goes into the interior of a double-quoted string in TCL */
460 static void tclWriteQuotedText(Blob *pOut, const char *zIn, int nIn){
461 int j;
462 for(j=0; j<nIn; j++){
463 char c = zIn[j];
464 if( c=='\\' ){
465 blob_append(pOut, "\\\\", 2);
466 }else if( c=='"' ){
467 blob_append(pOut, "\\\"", 2);
468 }else if( c<' ' || c>0x7e ){
469 char z[5];
470 z[0] = '\\';
471 z[1] = "01234567"[(c>>6)&0x3];
472 z[2] = "01234567"[(c>>3)&0x7];
473 z[3] = "01234567"[c&0x7];
474 z[4] = 0;
475 blob_append(pOut, z, 4);
476 }else{
477 blob_append_char(pOut, c);
478 }
479 }
480 }
481
482 /* Copy one line of text from pIn and append to pOut, encoded as TCL */
483 static void tclLineOfText(Blob *pOut, Blob *pIn, char cType){
484 int i, k;
485 for(i=pIn->iCursor; i<pIn->nUsed && pIn->aData[i]!='\n'; i++){}
486 if( i==pIn->nUsed ){
487 k = i;
488 }else if( i>pIn->iCursor && pIn->aData[i-1]=='\r' ){
489 k = i-1;
490 i++;
491 }else{
492 k = i;
493 i++;
494 }
495 blob_append_char(pOut, '"');
496 blob_append_char(pOut, cType);
497 tclWriteQuotedText(pOut, pIn->aData+pIn->iCursor, k-pIn->iCursor);
498 pIn->iCursor = i;
499 blob_append_char(pOut, '"');
500 }
501 static void tclStart(MergeBuilder *p){
502 Blob *pOut = p->pOut;
503 blob_append(pOut, "\"N", 2);
504 tclWriteQuotedText(pOut, p->zPivot, (int)strlen(p->zPivot));
505 blob_append(pOut, "\" \"N", 4);
506 tclWriteQuotedText(pOut, p->zV1, (int)strlen(p->zV1));
507 blob_append(pOut, "\" \"N", 4);
508 tclWriteQuotedText(pOut, p->zV2, (int)strlen(p->zV2));
509 blob_append(pOut, "\" \"N", 4);
510 if( p->zOut ){
511 tclWriteQuotedText(pOut, p->zOut, (int)strlen(p->zOut));
512 }else{
513 blob_append(pOut, "(Merge Result)", -1);
514 }
515 blob_append(pOut, "\"\n", 2);
516 }
517 static void tclSame(MergeBuilder *p, unsigned int N){
518 int i = 0;
519 int nSkip;
520
521 if( p->lnPivot>=2 || p->lnV1>2 || p->lnV2>2 ){
522 while( i<N && i<p->nContext ){
523 tclLineOfText(p->pOut, p->pPivot, 'T');
524 blob_append(p->pOut, " 1 1 1\n", 7);
525 i++;
526 }
527 nSkip = N - p->nContext*2;
528 }else{
529 nSkip = N - p->nContext;
530 }
531 if( nSkip>0 ){
532 blob_appendf(p->pOut, "\"S%d %d %d %d\" . . .\n",
533 nSkip, nSkip, nSkip, nSkip);
534 blob_copy_lines(0, p->pPivot, nSkip);
535 i += nSkip;
536 }
537
538 p->lnPivot += N;
539 p->lnV1 += N;
540 p->lnV2 += N;
541
542 if( p->lnPivot<p->mxPivot || p->lnV1<p->mxV1 || p->lnV2<p->mxV2 ){
543 while( i<N ){
544 tclLineOfText(p->pOut, p->pPivot, 'T');
545 blob_append(p->pOut, " 1 1 1\n", 7);
546 i++;
547 }
548 }
549
550 blob_copy_lines(0, p->pV1, N);
551 blob_copy_lines(0, p->pV2, N);
552 }
553 static void tclChngV1(MergeBuilder *p, unsigned int nPivot, unsigned int nV1){
554 int i;
555 for(i=0; i<nPivot && i<nV1; i++){
556 tclLineOfText(p->pOut, p->pPivot, 'T');
557 blob_append_char(p->pOut, ' ');
558 tclLineOfText(p->pOut, p->pV1, 'T');
559 blob_append(p->pOut, " 1 2\n", 5);
560 }
561 while( i<nPivot ){
562 tclLineOfText(p->pOut, p->pPivot, 'T');
563 blob_append(p->pOut, " . 1 .\n", 7);
564 i++;
565 }
566 while( i<nV1 ){
567 blob_append(p->pOut, ". ", 2);
568 tclLineOfText(p->pOut, p->pV1, 'T');
569 blob_append(p->pOut, " . 2\n", 5);
570 i++;
571 }
572 p->lnPivot += nPivot;
573 p->lnV1 += nV1;
574 p->lnV2 += nPivot;
575 blob_copy_lines(0, p->pV2, nPivot);
576 }
577 static void tclChngV2(MergeBuilder *p, unsigned int nPivot, unsigned int nV2){
578 int i;
579 for(i=0; i<nPivot && i<nV2; i++){
580 tclLineOfText(p->pOut, p->pPivot, 'T');
581 blob_append(p->pOut, " 1 ", 3);
582 tclLineOfText(p->pOut, p->pV2, 'T');
583 blob_append(p->pOut, " 3\n", 3);
584 }
585 while( i<nPivot ){
586 tclLineOfText(p->pOut, p->pPivot, 'T');
587 blob_append(p->pOut, " 1 . .\n", 7);
588 i++;
589 }
590 while( i<nV2 ){
591 blob_append(p->pOut, ". . ", 4);
592 tclLineOfText(p->pOut, p->pV2, 'T');
593 blob_append(p->pOut, " 3\n", 3);
594 i++;
595 }
596 p->lnPivot += nPivot;
597 p->lnV1 += nPivot;
598 p->lnV2 += nV2;
599 blob_copy_lines(0, p->pV1, nPivot);
600 }
601 static void tclChngBoth(MergeBuilder *p, unsigned int nPivot, unsigned int nV){
602 int i;
603 for(i=0; i<nPivot && i<nV; i++){
604 tclLineOfText(p->pOut, p->pPivot, 'T');
605 blob_append_char(p->pOut, ' ');
606 tclLineOfText(p->pOut, p->pV1, 'T');
607 blob_append(p->pOut, " 2 2\n", 5);
608 }
609 while( i<nPivot ){
610 tclLineOfText(p->pOut, p->pPivot, 'T');
611 blob_append(p->pOut, " . . .\n", 7);
612 i++;
613 }
614 while( i<nV ){
615 blob_append(p->pOut, ". ", 2);
616 tclLineOfText(p->pOut, p->pV1, 'T');
617 blob_append(p->pOut, " 2 2\n", 5);
618 i++;
619 }
620 p->lnPivot += nPivot;
621 p->lnV1 += nV;
622 p->lnV2 += nV;
623 blob_copy_lines(0, p->pV2, nV);
624 }
625 static void tclConflict(
626 MergeBuilder *p,
627 unsigned int nPivot,
628 unsigned int nV1,
629 unsigned int nV2
630 ){
631 int mx = nPivot;
632 int i;
633 int nRes;
634 Blob res;
635
636 merge_try_to_resolve_conflict(p, nPivot, nV1, nV2, &res);
637 nRes = blob_linecount(&res);
638 if( nV1>mx ) mx = nV1;
639 if( nV2>mx ) mx = nV2;
640 if( nRes>mx ) mx = nRes;
641 if( nRes>0 ){
642 blob_appendf(p->pOut, "\"S0 0 0 %d\" . . .\n", nV2+2);
643 }
644 for(i=0; i<mx; i++){
645 if( i<nPivot ){
646 tclLineOfText(p->pOut, p->pPivot, 'X');
647 }else{
648 blob_append_char(p->pOut, '.');
649 }
650 blob_append_char(p->pOut, ' ');
651 if( i<nV1 ){
652 tclLineOfText(p->pOut, p->pV1, 'X');
653 }else{
654 blob_append_char(p->pOut, '.');
655 }
656 blob_append_char(p->pOut, ' ');
657 if( i<nV2 ){
658 tclLineOfText(p->pOut, p->pV2, 'X');
659 }else{
660 blob_append_char(p->pOut, '.');
661 }
662 if( i<nRes ){
663 blob_append_char(p->pOut, ' ');
664 tclLineOfText(p->pOut, &res, 'X');
665 blob_append_char(p->pOut, '\n');
666 }else{
667 blob_append(p->pOut, " .\n", 3);
668 }
669 if( i==mx-1 ){
670 blob_appendf(p->pOut, "\"S0 0 0 %d\" . . .\n", nPivot+nV1+3);
671 }
672 }
673 blob_reset(&res);
674 p->lnPivot += nPivot;
675 p->lnV1 += nV1;
676 p->lnV2 += nV2;
677 }
678 void mergebuilder_init_tcl(MergeBuilder *p){
679 mergebuilder_init(p);
680 p->xStart = tclStart;
681 p->xSame = tclSame;
682 p->xChngV1 = tclChngV1;
683 p->xChngV2 = tclChngV2;
684 p->xChngBoth = tclChngBoth;
685 p->xConflict = tclConflict;
686 }
687 /*****************************************************************************/
688
689 /*
690 ** The aC[] array contains triples of integers. Within each triple, the
691 ** elements are:
692 **
693 ** (0) The number of lines to copy
694 ** (1) The number of lines to delete
695 ** (2) The number of liens to insert
696 **
697 ** Suppose we want to advance over sz lines of the original file. This routine
698 ** returns true if that advance would land us on a copy operation. It
699 ** returns false if the advance would end on a delete.
700 */
701 static int ends_with_copy(int *aC, int sz){
702 while( sz>0 && (aC[0]>0 || aC[1]>0 || aC[2]>0) ){
703 if( aC[0]>=sz ) return 1;
704 sz -= aC[0];
705 if( aC[1]>sz ) return 0;
706 sz -= aC[1];
707 aC += 3;
708 }
709 return 1;
710 }
711
712 /*
713 ** aC[] is an "edit triple" for changes from A to B. Advance through
714 ** this triple to determine the number of lines to bypass on B in order
715 ** to match an advance of sz lines on A.
716 */
717 static int skip_conflict(
718 int *aC, /* Array of integer triples describing the edit */
719 int i, /* Index in aC[] of current location */
720 int sz, /* Lines of A that have been skipped */
721 unsigned int *pLn /* OUT: Lines of B to skip to keep aligment with A */
722 ){
723 *pLn = 0;
724 while( sz>0 ){
725 if( aC[i]==0 && aC[i+1]==0 && aC[i+2]==0 ) break;
726 if( aC[i]>=sz ){
727 aC[i] -= sz;
728 *pLn += sz;
729 break;
730 }
731 *pLn += aC[i];
732 *pLn += aC[i+2];
733 sz -= aC[i] + aC[i+1];
734 i += 3;
735 }
736 return i;
737 }
738
739 /*
740 ** Do a three-way merge. Initialize pOut to contain the result.
741 **
742 ** The merge is an edit against pV2. Both pV1 and pV2 have a
@@ -199,156 +746,113 @@
746 ** The return is 0 upon complete success. If any input file is binary,
747 ** -1 is returned and pOut is unmodified. If there are merge
748 ** conflicts, the merge proceeds as best as it can and the number
749 ** of conflicts is returns
750 */
751 int merge_three_blobs(MergeBuilder *p){
752 int *aC1; /* Changes from pPivot to pV1 */
753 int *aC2; /* Changes from pPivot to pV2 */
754 int i1, i2; /* Index into aC1[] and aC2[] */
755 int nCpy, nDel, nIns; /* Number of lines to copy, delete, or insert */
756 int limit1, limit2; /* Sizes of aC1[] and aC2[] */
757 int nConflict = 0; /* Number of merge conflicts seen so far */
 
 
758 DiffConfig DCfg;
759
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
760 /* Compute the edits that occur from pPivot => pV1 (into aC1)
761 ** and pPivot => pV2 (into aC2). Each of the aC1 and aC2 arrays is
762 ** an array of integer triples. Within each triple, the first integer
763 ** is the number of lines of text to copy directly from the pivot,
764 ** the second integer is the number of lines of text to omit from the
765 ** pivot, and the third integer is the number of lines of text that are
766 ** inserted. The edit array ends with a triple of 0,0,0.
767 */
768 diff_config_init(&DCfg, 0);
769 DCfg.diffFlags = p->diffFlags;
770 aC1 = text_diff(p->pPivot, p->pV1, 0, &DCfg);
771 aC2 = text_diff(p->pPivot, p->pV2, 0, &DCfg);
772 if( aC1==0 || aC2==0 ){
773 free(aC1);
774 free(aC2);
775 return -1;
776 }
777
778 blob_rewind(p->pV1); /* Rewind inputs: Needed to reconstruct output */
779 blob_rewind(p->pV2);
780 blob_rewind(p->pPivot);
781
782 /* Determine the length of the aC1[] and aC2[] change vectors */
783 p->mxPivot = 0;
784 p->mxV1 = 0;
785 for(i1=0; aC1[i1] || aC1[i1+1] || aC1[i1+2]; i1+=3){
786 p->mxPivot += aC1[i1] + aC1[i1+1];
787 p->mxV1 += aC1[i1] + aC1[i1+2];
788 }
789 limit1 = i1;
790 p->mxV2 = 0;
791 for(i2=0; aC2[i2] || aC2[i2+1] || aC2[i2+2]; i2+=3){
792 p->mxV2 += aC2[i2] + aC2[i2+2];
793 }
794 limit2 = i2;
795
796 /* Output header text and do any other required initialization */
797 p->xStart(p);
 
 
 
 
 
 
798
799 /* Loop over the two edit vectors and use them to compute merged text
800 ** which is written into pOut. i1 and i2 are multiples of 3 which are
801 ** indices into aC1[] and aC2[] to the edit triple currently being
802 ** processed
803 */
804 i1 = i2 = 0;
 
805 while( i1<limit1 && i2<limit2 ){
 
 
 
 
806 if( aC1[i1]>0 && aC2[i2]>0 ){
807 /* Output text that is unchanged in both V1 and V2 */
808 nCpy = min(aC1[i1], aC2[i2]);
809 p->xSame(p, nCpy);
 
 
 
810 aC1[i1] -= nCpy;
811 aC2[i2] -= nCpy;
812 }else
813 if( aC1[i1] >= aC2[i2+1] && aC1[i1]>0 && aC2[i2+1]+aC2[i2+2]>0 ){
814 /* Output edits to V2 that occurs within unchanged regions of V1 */
815 nDel = aC2[i2+1];
816 nIns = aC2[i2+2];
817 p->xChngV2(p, nDel, nIns);
 
 
 
818 aC1[i1] -= nDel;
819 i2 += 3;
820 }else
821 if( aC2[i2] >= aC1[i1+1] && aC2[i2]>0 && aC1[i1+1]+aC1[i1+2]>0 ){
822 /* Output edits to V1 that occur within unchanged regions of V2 */
823 nDel = aC1[i1+1];
824 nIns = aC1[i1+2];
825 p->xChngV1(p, nDel, nIns);
 
 
 
826 aC2[i2] -= nDel;
827 i1 += 3;
828 }else
829 if( sameEdit(&aC1[i1], &aC2[i2], p->pV1, p->pV2) ){
830 /* Output edits that are identical in both V1 and V2. */
831 assert( aC1[i1]==0 );
832 nDel = aC1[i1+1];
833 nIns = aC1[i1+2];
834 p->xChngBoth(p, nDel, nIns);
 
 
 
835 i1 += 3;
836 i2 += 3;
837 }else
838 {
839 /* We have found a region where different edits to V1 and V2 overlap.
840 ** This is a merge conflict. Find the size of the conflict, then
841 ** output both possible edits separated by distinctive marks.
842 */
843 unsigned int sz = 1; /* Size of the conflict in the pivot, in lines */
844 unsigned int nV1, nV2; /* Size of conflict in V1 and V2, in lines */
845 nConflict++;
846 while( !ends_with_copy(&aC1[i1], sz) || !ends_with_copy(&aC2[i2], sz) ){
847 sz++;
848 }
849 i1 = skip_conflict(aC1, i1, sz, &nV1);
850 i2 = skip_conflict(aC2, i2, sz, &nV2);
851 p->xConflict(p, sz, nV1, nV2);
852 }
853
 
 
 
 
 
 
 
 
 
854 /* If we are finished with an edit triple, advance to the next
855 ** triple.
856 */
857 if( i1<limit1 && aC1[i1]==0 && aC1[i1+1]==0 && aC1[i1+2]==0 ) i1+=3;
858 if( i2<limit2 && aC2[i2]==0 && aC2[i2+1]==0 && aC2[i2+2]==0 ) i2+=3;
@@ -356,20 +860,18 @@
860
861 /* When one of the two edit vectors reaches its end, there might still
862 ** be an insert in the other edit vector. Output this remaining
863 ** insert.
864 */
 
 
 
865 if( i1<limit1 && aC1[i1+2]>0 ){
866 p->xChngV1(p, 0, aC1[i1+2]);
 
867 }else if( i2<limit2 && aC2[i2+2]>0 ){
868 p->xChngV2(p, 0, aC2[i2+2]);
 
869 }
870
871 /* Output footer text */
872 p->xEnd(p);
873
874 free(aC1);
875 free(aC2);
876 return nConflict;
877 }
@@ -384,11 +886,12 @@
886 const char *z = blob_buffer(p);
887 int n = blob_size(p) - len + 1;
888 assert( len==(int)strlen(mergeMarker[1]) );
889 assert( len==(int)strlen(mergeMarker[2]) );
890 assert( len==(int)strlen(mergeMarker[3]) );
891 assert( len==(int)strlen(mergeMarker[4]) );
892 assert( count(mergeMarker)==5 );
893 for(i=0; i<n; ){
894 for(j=0; j<4; j++){
895 if( (memcmp(&z[i], mergeMarker[j], len)==0) ){
896 return 1;
897 }
@@ -408,18 +911,106 @@
911 blob_read_from_file(&file, zFullpath, ExtFILE);
912 rc = contains_merge_marker(&file);
913 blob_reset(&file);
914 return rc;
915 }
916
917 /*
918 ** Show merge output in a Tcl/Tk window, in response to the --tk option
919 ** to the "merge" or "3-way-merge" command.
920 **
921 ** If fossil has direct access to a Tcl interpreter (either loaded
922 ** dynamically through stubs or linked in statically), we can use it
923 ** directly. Otherwise:
924 ** (1) Write the Tcl/Tk script used for rendering into a temp file.
925 ** (2) Invoke "tclsh" on the temp file using fossil_system().
926 ** (3) Delete the temp file.
927 */
928 void merge_tk(const char *zSubCmd, int firstArg){
929 int i;
930 Blob script;
931 const char *zTempFile = 0;
932 char *zCmd;
933 const char *zTclsh;
934 const char *zCnt;
935 int bDarkMode = find_option("dark",0,0)!=0;
936 int nContext;
937 zCnt = find_option("context", "c", 1);
938 if( zCnt==0 ){
939 nContext = 6;
940 }else{
941 nContext = atoi(zCnt);
942 if( nContext<0 ) nContext = 0xfffffff;
943 }
944 blob_zero(&script);
945 blob_appendf(&script, "set ncontext %d\n", nContext);
946 blob_appendf(&script, "set fossilcmd {| \"%/\" %s -tcl",
947 g.nameOfExe, zSubCmd);
948 find_option("tcl",0,0);
949 find_option("debug",0,0);
950 zTclsh = find_option("tclsh",0,1);
951 if( zTclsh==0 ){
952 zTclsh = db_get("tclsh",0);
953 }
954 /* The undocumented --script FILENAME option causes the Tk script to
955 ** be written into the FILENAME instead of being run. This is used
956 ** for testing and debugging. */
957 zTempFile = find_option("script",0,1);
958 verify_all_options();
959
960 if( (g.argc - firstArg)!=3 ){
961 fossil_fatal("Requires 3 filename arguments");
962 }
963
964 for(i=firstArg; i<g.argc; i++){
965 const char *z = g.argv[i];
966 if( sqlite3_strglob("*}*",z) ){
967 blob_appendf(&script, " {%/}", z);
968 }else{
969 int j;
970 blob_append(&script, " ", 1);
971 for(j=0; z[j]; j++) blob_appendf(&script, "\\%03o", (unsigned char)z[j]);
972 }
973 }
974 blob_appendf(&script, "}\nset darkmode %d\n", bDarkMode);
975 blob_appendf(&script, "%s", builtin_file("merge.tcl", 0));
976 if( zTempFile ){
977 blob_write_to_file(&script, zTempFile);
978 fossil_print("To see the merge, run: %s \"%s\"\n", zTclsh, zTempFile);
979 }else{
980 #if defined(FOSSIL_ENABLE_TCL)
981 Th_FossilInit(TH_INIT_DEFAULT);
982 if( evaluateTclWithEvents(g.interp, &g.tcl, blob_str(&script),
983 blob_size(&script), 1, 1, 0)==TCL_OK ){
984 blob_reset(&script);
985 return;
986 }
987 /*
988 * If evaluation of the Tcl script fails, the reason may be that Tk
989 * could not be found by the loaded Tcl, or that Tcl cannot be loaded
990 * dynamically (e.g. x64 Tcl with x86 Fossil). Therefore, fallback
991 * to using the external "tclsh", if available.
992 */
993 #endif
994 zTempFile = write_blob_to_temp_file(&script);
995 zCmd = mprintf("%$ %$", zTclsh, zTempFile);
996 fossil_system(zCmd);
997 file_delete(zTempFile);
998 fossil_free(zCmd);
999 }
1000 blob_reset(&script);
1001 }
1002
1003
1004 /*
1005 ** COMMAND: 3-way-merge*
1006 **
1007 ** Usage: %fossil 3-way-merge BASELINE V1 V2 [MERGED]
1008 **
1009 ** Inputs are files BASELINE, V1, and V2. The file MERGED is generated
1010 ** as output. If no MERGED file is specified, output is sent to
1011 ** stdout.
1012 **
1013 ** BASELINE is a common ancestor of two files V1 and V2 that have diverging
1014 ** edits. The generated output file MERGED is the combination of all
1015 ** changes in both V1 and V2.
1016 **
@@ -436,38 +1027,75 @@
1027 ** cp Xup.c Xbase.c
1028 ** # Verify that everything still works
1029 ** fossil commit
1030 **
1031 */
1032 void merge_3way_cmd(void){
1033 MergeBuilder s;
1034 int nConflict;
1035 Blob pivot, v1, v2, out;
1036 int noWarn = 0;
1037 const char *zCnt;
1038
1039 if( find_option("tk", 0, 0)!=0 ){
1040 merge_tk("3-way-merge", 2);
1041 return;
1042 }
1043 mergebuilder_init_text(&s);
1044 if( find_option("debug", 0, 0) ){
1045 mergebuilder_init(&s);
1046 }
1047 if( find_option("tcl", 0, 0) ){
1048 mergebuilder_init_tcl(&s);
1049 noWarn = 1;
1050 }
1051 zCnt = find_option("context", "c", 1);
1052 if( zCnt ){
1053 s.nContext = atoi(zCnt);
1054 if( s.nContext<0 ) s.nContext = 0xfffffff;
1055 }else{
1056 s.nContext = 6;
1057 }
1058 blob_zero(&pivot); s.pPivot = &pivot;
1059 blob_zero(&v1); s.pV1 = &v1;
1060 blob_zero(&v2); s.pV2 = &v2;
1061 blob_zero(&out); s.pOut = &out;
1062
1063 /* We should be done with options.. */
1064 verify_all_options();
1065
1066 if( g.argc!=6 && g.argc!=5 ){
1067 usage("[OPTIONS] PIVOT V1 V2 [MERGED]");
1068 }
1069 s.zPivot = file_tail(g.argv[2]);
1070 s.zV1 = file_tail(g.argv[3]);
1071 s.zV2 = file_tail(g.argv[4]);
1072 if( blob_read_from_file(s.pPivot, g.argv[2], ExtFILE)<0 ){
1073 fossil_fatal("cannot read %s", g.argv[2]);
1074 }
1075 if( blob_read_from_file(s.pV1, g.argv[3], ExtFILE)<0 ){
1076 fossil_fatal("cannot read %s", g.argv[3]);
1077 }
1078 if( blob_read_from_file(s.pV2, g.argv[4], ExtFILE)<0 ){
1079 fossil_fatal("cannot read %s", g.argv[4]);
1080 }
1081 nConflict = merge_three_blobs(&s);
1082 if( g.argc==6 ){
1083 s.zOut = file_tail(g.argv[5]);
1084 blob_write_to_file(s.pOut, g.argv[5]);
1085 }else{
1086 s.zOut = "(Merge Result)";
1087 blob_write_to_file(s.pOut, "-");
1088 }
1089 s.xDestroy(&s);
1090 blob_reset(&pivot);
1091 blob_reset(&v1);
1092 blob_reset(&v2);
1093 blob_reset(&out);
1094 if( nConflict>0 && !noWarn ){
1095 fossil_warning("WARNING: %d merge conflicts", nConflict);
1096 }
1097 }
1098
1099 /*
1100 ** aSubst is an array of string pairs. The first element of each pair is
1101 ** a string that begins with %. The second element is a replacement for that
@@ -505,32 +1133,32 @@
1133
1134 #if INTERFACE
1135 /*
1136 ** Flags to the 3-way merger
1137 */
1138 #define MERGE_DRYRUN 0x0001
1139 /*
1140 ** The MERGE_KEEP_FILES flag specifies that merge_3way() should retain
1141 ** its temporary files on error. By default they are removed after the
1142 ** merge, regardless of success or failure.
1143 */
1144 #define MERGE_KEEP_FILES 0x0002
1145 #endif
1146
1147
1148 /*
1149 ** This routine is a wrapper around merge_three_blobs() with the following
1150 ** enhancements:
1151 **
1152 ** (1) If the merge-command is defined, then use the external merging
1153 ** program specified instead of the built-in blob-merge to do the
1154 ** merging. Panic if the external merger fails.
1155 ** ** Not currently implemented **
1156 **
1157 ** (2) If gmerge-command is defined and there are merge conflicts in
1158 ** merge_three_blobs() then invoke the external graphical merger
1159 ** to resolve the conflicts.
1160 **
1161 ** (3) If a merge conflict occurs and gmerge-command is not defined,
1162 ** then write the pivot, original, and merge-in files to the
1163 ** filesystem.
1164 */
@@ -539,30 +1167,37 @@
1167 const char *zV1, /* Name of file for version merging into (mine) */
1168 Blob *pV2, /* Version merging from (yours) */
1169 Blob *pOut, /* Output written here */
1170 unsigned mergeFlags /* Flags that control operation */
1171 ){
1172 Blob v1; /* Content of zV1 */
1173 int rc; /* Return code of subroutines and this routine */
1174 const char *zGMerge; /* Name of the gmerge command */
1175 MergeBuilder s; /* The merge state */
1176
1177 mergebuilder_init_text(&s);
1178 s.pPivot = pPivot;
1179 s.pV1 = &v1;
1180 s.pV2 = pV2;
1181 blob_zero(pOut);
1182 s.pOut = pOut;
1183 blob_read_from_file(s.pV1, zV1, ExtFILE);
1184 rc = merge_three_blobs(&s);
1185 zGMerge = rc<=0 ? 0 : db_get("gmerge-command", 0);
1186 if( (mergeFlags & MERGE_DRYRUN)==0
1187 && ((zGMerge!=0 && zGMerge[0]!=0)
1188 || (rc!=0 && (mergeFlags & MERGE_KEEP_FILES)!=0)) ){
1189 char *zPivot; /* Name of the pivot file */
1190 char *zOrig; /* Name of the original content file */
1191 char *zOther; /* Name of the merge file */
1192
1193 zPivot = file_newname(zV1, "baseline", 1);
1194 blob_write_to_file(s.pPivot, zPivot);
1195 zOrig = file_newname(zV1, "original", 1);
1196 blob_write_to_file(s.pV1, zOrig);
1197 zOther = file_newname(zV1, "merge", 1);
1198 blob_write_to_file(s.pV2, zOther);
1199 if( rc>0 ){
1200 if( zGMerge && zGMerge[0] ){
1201 char *zOut; /* Temporary output file */
1202 char *zCmd; /* Command to invoke */
1203 const char *azSubst[8]; /* Strings to be substituted */
@@ -590,7 +1225,8 @@
1225 fossil_free(zPivot);
1226 fossil_free(zOrig);
1227 fossil_free(zOther);
1228 }
1229 blob_reset(&v1);
1230 s.xDestroy(&s);
1231 return rc;
1232 }
1233
+1
--- src/path.c
+++ src/path.c
@@ -542,10 +542,11 @@
542542
pChng = pAll;
543543
pAll = pAll->pNext;
544544
fossil_free(pChng);
545545
}
546546
}
547
+ path_reset();
547548
}
548549
549550
/*
550551
** COMMAND: test-name-changes
551552
**
552553
--- src/path.c
+++ src/path.c
@@ -542,10 +542,11 @@
542 pChng = pAll;
543 pAll = pAll->pNext;
544 fossil_free(pChng);
545 }
546 }
 
547 }
548
549 /*
550 ** COMMAND: test-name-changes
551 **
552
--- src/path.c
+++ src/path.c
@@ -542,10 +542,11 @@
542 pChng = pAll;
543 pAll = pAll->pNext;
544 fossil_free(pChng);
545 }
546 }
547 path_reset();
548 }
549
550 /*
551 ** COMMAND: test-name-changes
552 **
553
+9 -3
--- src/rebuild.c
+++ src/rebuild.c
@@ -390,25 +390,31 @@
390390
}
391391
manifest_disable_event_triggers();
392392
rebuild_update_schema();
393393
blob_init(&sql, 0, 0);
394394
db_unprotect(PROTECT_ALL);
395
+#ifndef SQLITE_PREPARE_DONT_LOG
396
+ g.dbIgnoreErrors++;
397
+#endif
395398
db_prepare(&q,
396
- "SELECT name FROM sqlite_schema /*scan*/"
397
- " WHERE type='table'"
399
+ "SELECT name FROM pragma_table_list /*scan*/"
400
+ " WHERE schema='repository' AND type IN ('table','virtual')"
398401
" AND name NOT IN ('admin_log', 'blob','delta','rcvfrom','user','alias',"
399402
"'config','shun','private','reportfmt',"
400403
"'concealed','accesslog','modreq',"
401404
"'purgeevent','purgeitem','unversioned',"
402405
"'subscriber','pending_alert','chat')"
403406
" AND name NOT GLOB 'sqlite_*'"
404
- " AND name NOT GLOB 'fx_*'"
407
+ " AND name NOT GLOB 'fx_*';"
405408
);
406409
while( db_step(&q)==SQLITE_ROW ){
407410
blob_appendf(&sql, "DROP TABLE IF EXISTS \"%w\";\n", db_column_text(&q,0));
408411
}
409412
db_finalize(&q);
413
+#ifndef SQLITE_PREPARE_DONT_LOG
414
+ g.dbIgnoreErrors--;
415
+#endif
410416
db_multi_exec("%s", blob_str(&sql)/*safe-for-%s*/);
411417
blob_reset(&sql);
412418
db_multi_exec("%s", zRepositorySchema2/*safe-for-%s*/);
413419
ticket_create_table(0);
414420
shun_artifacts();
415421
--- src/rebuild.c
+++ src/rebuild.c
@@ -390,25 +390,31 @@
390 }
391 manifest_disable_event_triggers();
392 rebuild_update_schema();
393 blob_init(&sql, 0, 0);
394 db_unprotect(PROTECT_ALL);
 
 
 
395 db_prepare(&q,
396 "SELECT name FROM sqlite_schema /*scan*/"
397 " WHERE type='table'"
398 " AND name NOT IN ('admin_log', 'blob','delta','rcvfrom','user','alias',"
399 "'config','shun','private','reportfmt',"
400 "'concealed','accesslog','modreq',"
401 "'purgeevent','purgeitem','unversioned',"
402 "'subscriber','pending_alert','chat')"
403 " AND name NOT GLOB 'sqlite_*'"
404 " AND name NOT GLOB 'fx_*'"
405 );
406 while( db_step(&q)==SQLITE_ROW ){
407 blob_appendf(&sql, "DROP TABLE IF EXISTS \"%w\";\n", db_column_text(&q,0));
408 }
409 db_finalize(&q);
 
 
 
410 db_multi_exec("%s", blob_str(&sql)/*safe-for-%s*/);
411 blob_reset(&sql);
412 db_multi_exec("%s", zRepositorySchema2/*safe-for-%s*/);
413 ticket_create_table(0);
414 shun_artifacts();
415
--- src/rebuild.c
+++ src/rebuild.c
@@ -390,25 +390,31 @@
390 }
391 manifest_disable_event_triggers();
392 rebuild_update_schema();
393 blob_init(&sql, 0, 0);
394 db_unprotect(PROTECT_ALL);
395 #ifndef SQLITE_PREPARE_DONT_LOG
396 g.dbIgnoreErrors++;
397 #endif
398 db_prepare(&q,
399 "SELECT name FROM pragma_table_list /*scan*/"
400 " WHERE schema='repository' AND type IN ('table','virtual')"
401 " AND name NOT IN ('admin_log', 'blob','delta','rcvfrom','user','alias',"
402 "'config','shun','private','reportfmt',"
403 "'concealed','accesslog','modreq',"
404 "'purgeevent','purgeitem','unversioned',"
405 "'subscriber','pending_alert','chat')"
406 " AND name NOT GLOB 'sqlite_*'"
407 " AND name NOT GLOB 'fx_*';"
408 );
409 while( db_step(&q)==SQLITE_ROW ){
410 blob_appendf(&sql, "DROP TABLE IF EXISTS \"%w\";\n", db_column_text(&q,0));
411 }
412 db_finalize(&q);
413 #ifndef SQLITE_PREPARE_DONT_LOG
414 g.dbIgnoreErrors--;
415 #endif
416 db_multi_exec("%s", blob_str(&sql)/*safe-for-%s*/);
417 blob_reset(&sql);
418 db_multi_exec("%s", zRepositorySchema2/*safe-for-%s*/);
419 ticket_create_table(0);
420 shun_artifacts();
421
+7 -7
--- src/schema.c
+++ src/schema.c
@@ -28,11 +28,11 @@
2828
@ -- ~/.fossil file and that stores information about the users setup.
2929
@ --
3030
@ CREATE TABLE global_config(
3131
@ name TEXT PRIMARY KEY,
3232
@ value TEXT
33
-@ );
33
+@ ) WITHOUT ROWID;
3434
@
3535
@ -- Identifier for this file type.
3636
@ -- The integer is the same as 'FSLG'.
3737
@ PRAGMA application_id=252006675;
3838
;
@@ -138,11 +138,11 @@
138138
@ CREATE TABLE config(
139139
@ name TEXT PRIMARY KEY NOT NULL, -- Primary name of the entry
140140
@ value CLOB, -- Content of the named parameter
141141
@ mtime DATE, -- last modified. seconds since 1970
142142
@ CHECK( typeof(name)='text' AND length(name)>=1 )
143
-@ );
143
+@ ) WITHOUT ROWID;
144144
@
145145
@ -- Artifacts that should not be processed are identified in the
146146
@ -- "shun" table. Artifacts that are control-file forgeries or
147147
@ -- spam or artifacts whose contents violate administrative policy
148148
@ -- can be shunned in order to prevent them from contaminating
@@ -151,14 +151,14 @@
151151
@ -- Shunned artifacts do not exist in the blob table. Hence they
152152
@ -- have not artifact ID (rid) and we thus must store their full
153153
@ -- UUID.
154154
@ --
155155
@ CREATE TABLE shun(
156
-@ uuid UNIQUE, -- UUID of artifact to be shunned. Canonical form
156
+@ uuid TEXT PRIMARY KEY,-- UUID of artifact to be shunned. Canonical form
157157
@ mtime DATE, -- When added. seconds since 1970
158158
@ scom TEXT -- Optional text explaining why the shun occurred
159
-@ );
159
+@ ) WITHOUT ROWID;
160160
@
161161
@ -- Artifacts that should not be pushed are stored in the "private"
162162
@ -- table. Private artifacts are omitted from the "unclustered" and
163163
@ -- "unsent" tables.
164164
@ --
@@ -193,11 +193,11 @@
193193
@ --
194194
@ CREATE TABLE concealed(
195195
@ hash TEXT PRIMARY KEY, -- The SHA1 hash of content
196196
@ mtime DATE, -- Time created. Seconds since 1970
197197
@ content TEXT -- Content intended to be concealed
198
-@ );
198
+@ ) WITHOUT ROWID;
199199
@
200200
@ -- The application ID helps the unix "file" command to identify the
201201
@ -- database as a fossil repository.
202202
@ PRAGMA application_id=252006673;
203203
;
@@ -528,11 +528,11 @@
528528
** The schema for the local FOSSIL database file found at the root
529529
** of every check-out. This database contains the complete state of
530530
** the check-out. See also the addendum in zLocalSchemaVmerge[].
531531
*/
532532
const char zLocalSchema[] =
533
-@ -- The VVAR table holds miscellanous information about the local database
533
+@ -- The VVAR table holds miscellanous information about the local checkout
534534
@ -- in the form of name-value pairs. This is similar to the VAR table
535535
@ -- table in the repository except that this table holds information that
536536
@ -- is specific to the local check-out.
537537
@ --
538538
@ -- Important Variables:
@@ -542,11 +542,11 @@
542542
@ --
543543
@ CREATE TABLE vvar(
544544
@ name TEXT PRIMARY KEY NOT NULL, -- Primary name of the entry
545545
@ value CLOB, -- Content of the named parameter
546546
@ CHECK( typeof(name)='text' AND length(name)>=1 )
547
-@ );
547
+@ ) WITHOUT ROWID;
548548
@
549549
@ -- Each entry in the vfile table represents a single file in the
550550
@ -- current check-out.
551551
@ --
552552
@ -- The file.rid field is 0 for files or folders that have been
553553
--- src/schema.c
+++ src/schema.c
@@ -28,11 +28,11 @@
28 @ -- ~/.fossil file and that stores information about the users setup.
29 @ --
30 @ CREATE TABLE global_config(
31 @ name TEXT PRIMARY KEY,
32 @ value TEXT
33 @ );
34 @
35 @ -- Identifier for this file type.
36 @ -- The integer is the same as 'FSLG'.
37 @ PRAGMA application_id=252006675;
38 ;
@@ -138,11 +138,11 @@
138 @ CREATE TABLE config(
139 @ name TEXT PRIMARY KEY NOT NULL, -- Primary name of the entry
140 @ value CLOB, -- Content of the named parameter
141 @ mtime DATE, -- last modified. seconds since 1970
142 @ CHECK( typeof(name)='text' AND length(name)>=1 )
143 @ );
144 @
145 @ -- Artifacts that should not be processed are identified in the
146 @ -- "shun" table. Artifacts that are control-file forgeries or
147 @ -- spam or artifacts whose contents violate administrative policy
148 @ -- can be shunned in order to prevent them from contaminating
@@ -151,14 +151,14 @@
151 @ -- Shunned artifacts do not exist in the blob table. Hence they
152 @ -- have not artifact ID (rid) and we thus must store their full
153 @ -- UUID.
154 @ --
155 @ CREATE TABLE shun(
156 @ uuid UNIQUE, -- UUID of artifact to be shunned. Canonical form
157 @ mtime DATE, -- When added. seconds since 1970
158 @ scom TEXT -- Optional text explaining why the shun occurred
159 @ );
160 @
161 @ -- Artifacts that should not be pushed are stored in the "private"
162 @ -- table. Private artifacts are omitted from the "unclustered" and
163 @ -- "unsent" tables.
164 @ --
@@ -193,11 +193,11 @@
193 @ --
194 @ CREATE TABLE concealed(
195 @ hash TEXT PRIMARY KEY, -- The SHA1 hash of content
196 @ mtime DATE, -- Time created. Seconds since 1970
197 @ content TEXT -- Content intended to be concealed
198 @ );
199 @
200 @ -- The application ID helps the unix "file" command to identify the
201 @ -- database as a fossil repository.
202 @ PRAGMA application_id=252006673;
203 ;
@@ -528,11 +528,11 @@
528 ** The schema for the local FOSSIL database file found at the root
529 ** of every check-out. This database contains the complete state of
530 ** the check-out. See also the addendum in zLocalSchemaVmerge[].
531 */
532 const char zLocalSchema[] =
533 @ -- The VVAR table holds miscellanous information about the local database
534 @ -- in the form of name-value pairs. This is similar to the VAR table
535 @ -- table in the repository except that this table holds information that
536 @ -- is specific to the local check-out.
537 @ --
538 @ -- Important Variables:
@@ -542,11 +542,11 @@
542 @ --
543 @ CREATE TABLE vvar(
544 @ name TEXT PRIMARY KEY NOT NULL, -- Primary name of the entry
545 @ value CLOB, -- Content of the named parameter
546 @ CHECK( typeof(name)='text' AND length(name)>=1 )
547 @ );
548 @
549 @ -- Each entry in the vfile table represents a single file in the
550 @ -- current check-out.
551 @ --
552 @ -- The file.rid field is 0 for files or folders that have been
553
--- src/schema.c
+++ src/schema.c
@@ -28,11 +28,11 @@
28 @ -- ~/.fossil file and that stores information about the users setup.
29 @ --
30 @ CREATE TABLE global_config(
31 @ name TEXT PRIMARY KEY,
32 @ value TEXT
33 @ ) WITHOUT ROWID;
34 @
35 @ -- Identifier for this file type.
36 @ -- The integer is the same as 'FSLG'.
37 @ PRAGMA application_id=252006675;
38 ;
@@ -138,11 +138,11 @@
138 @ CREATE TABLE config(
139 @ name TEXT PRIMARY KEY NOT NULL, -- Primary name of the entry
140 @ value CLOB, -- Content of the named parameter
141 @ mtime DATE, -- last modified. seconds since 1970
142 @ CHECK( typeof(name)='text' AND length(name)>=1 )
143 @ ) WITHOUT ROWID;
144 @
145 @ -- Artifacts that should not be processed are identified in the
146 @ -- "shun" table. Artifacts that are control-file forgeries or
147 @ -- spam or artifacts whose contents violate administrative policy
148 @ -- can be shunned in order to prevent them from contaminating
@@ -151,14 +151,14 @@
151 @ -- Shunned artifacts do not exist in the blob table. Hence they
152 @ -- have not artifact ID (rid) and we thus must store their full
153 @ -- UUID.
154 @ --
155 @ CREATE TABLE shun(
156 @ uuid TEXT PRIMARY KEY,-- UUID of artifact to be shunned. Canonical form
157 @ mtime DATE, -- When added. seconds since 1970
158 @ scom TEXT -- Optional text explaining why the shun occurred
159 @ ) WITHOUT ROWID;
160 @
161 @ -- Artifacts that should not be pushed are stored in the "private"
162 @ -- table. Private artifacts are omitted from the "unclustered" and
163 @ -- "unsent" tables.
164 @ --
@@ -193,11 +193,11 @@
193 @ --
194 @ CREATE TABLE concealed(
195 @ hash TEXT PRIMARY KEY, -- The SHA1 hash of content
196 @ mtime DATE, -- Time created. Seconds since 1970
197 @ content TEXT -- Content intended to be concealed
198 @ ) WITHOUT ROWID;
199 @
200 @ -- The application ID helps the unix "file" command to identify the
201 @ -- database as a fossil repository.
202 @ PRAGMA application_id=252006673;
203 ;
@@ -528,11 +528,11 @@
528 ** The schema for the local FOSSIL database file found at the root
529 ** of every check-out. This database contains the complete state of
530 ** the check-out. See also the addendum in zLocalSchemaVmerge[].
531 */
532 const char zLocalSchema[] =
533 @ -- The VVAR table holds miscellanous information about the local checkout
534 @ -- in the form of name-value pairs. This is similar to the VAR table
535 @ -- table in the repository except that this table holds information that
536 @ -- is specific to the local check-out.
537 @ --
538 @ -- Important Variables:
@@ -542,11 +542,11 @@
542 @ --
543 @ CREATE TABLE vvar(
544 @ name TEXT PRIMARY KEY NOT NULL, -- Primary name of the entry
545 @ value CLOB, -- Content of the named parameter
546 @ CHECK( typeof(name)='text' AND length(name)>=1 )
547 @ ) WITHOUT ROWID;
548 @
549 @ -- Each entry in the vfile table represents a single file in the
550 @ -- current check-out.
551 @ --
552 @ -- The file.rid field is 0 for files or folders that have been
553
+12 -1
--- src/setup.c
+++ src/setup.c
@@ -501,13 +501,24 @@
501501
@ behavior or to find an SQL injection opportunity or similar. This can
502502
@ waste hours of CPU time and gigabytes of bandwidth on the server. A
503503
@ suggested value for this setting is:
504504
@ "<tt>timeline,*diff,vpatch,annotate,blame,praise,dir,tree</tt>".
505505
@ (Property: robot-restrict)
506
- @ <p>
506
+ @ <br>
507507
textarea_attribute("", 2, 80,
508508
"robot-restrict", "rbrestrict", "", 0);
509
+ @ <br> The following comma-separated GLOB pattern allows for exceptions
510
+ @ in the maximum number of query parameters before a request is considered
511
+ @ complex. If this GLOB pattern exists and is non-empty and if it
512
+ @ matches against the pagename followed by "/" and the number of query
513
+ @ parameters, then the request is allowed through. For example, the
514
+ @ suggested pattern of "timeline/[012]" allows the /timeline page to
515
+ @ pass with up to 2 query parameters besides "name".
516
+ @ (Property: robot-restrict-qp)
517
+ @ <br>
518
+ textarea_attribute("", 2, 80,
519
+ "robot-restrict-qp", "rbrestrictqp", "", 0);
509520
510521
@ <hr>
511522
@ <p><input type="submit" name="submit" value="Apply Changes"></p>
512523
@ </div></form>
513524
db_end_transaction(0);
514525
--- src/setup.c
+++ src/setup.c
@@ -501,13 +501,24 @@
501 @ behavior or to find an SQL injection opportunity or similar. This can
502 @ waste hours of CPU time and gigabytes of bandwidth on the server. A
503 @ suggested value for this setting is:
504 @ "<tt>timeline,*diff,vpatch,annotate,blame,praise,dir,tree</tt>".
505 @ (Property: robot-restrict)
506 @ <p>
507 textarea_attribute("", 2, 80,
508 "robot-restrict", "rbrestrict", "", 0);
 
 
 
 
 
 
 
 
 
 
 
509
510 @ <hr>
511 @ <p><input type="submit" name="submit" value="Apply Changes"></p>
512 @ </div></form>
513 db_end_transaction(0);
514
--- src/setup.c
+++ src/setup.c
@@ -501,13 +501,24 @@
501 @ behavior or to find an SQL injection opportunity or similar. This can
502 @ waste hours of CPU time and gigabytes of bandwidth on the server. A
503 @ suggested value for this setting is:
504 @ "<tt>timeline,*diff,vpatch,annotate,blame,praise,dir,tree</tt>".
505 @ (Property: robot-restrict)
506 @ <br>
507 textarea_attribute("", 2, 80,
508 "robot-restrict", "rbrestrict", "", 0);
509 @ <br> The following comma-separated GLOB pattern allows for exceptions
510 @ in the maximum number of query parameters before a request is considered
511 @ complex. If this GLOB pattern exists and is non-empty and if it
512 @ matches against the pagename followed by "/" and the number of query
513 @ parameters, then the request is allowed through. For example, the
514 @ suggested pattern of "timeline/[012]" allows the /timeline page to
515 @ pass with up to 2 query parameters besides "name".
516 @ (Property: robot-restrict-qp)
517 @ <br>
518 textarea_attribute("", 2, 80,
519 "robot-restrict-qp", "rbrestrictqp", "", 0);
520
521 @ <hr>
522 @ <p><input type="submit" name="submit" value="Apply Changes"></p>
523 @ </div></form>
524 db_end_transaction(0);
525
+7 -5
--- src/setupuser.c
+++ src/setupuser.c
@@ -115,11 +115,11 @@
115115
}
116116
if( !bUnusedOnly ){
117117
style_submenu_element("Unused", "setup_ulist?unused");
118118
}
119119
@ <table border=1 cellpadding=2 cellspacing=0 class='userTable sortable' \
120
- @ data-column-types='ktxTTKt' data-init-sort='2'>
120
+ @ data-column-types='ktxKTKt' data-init-sort='4'>
121121
@ <thead><tr>
122122
@ <th>Login Name<th>Caps<th>Info<th>Date<th>Expire<th>Last Login\
123123
@ <th>Alerts</tr></thead>
124124
@ <tbody>
125125
db_multi_exec(
@@ -161,15 +161,16 @@
161161
" lower(login) AS sortkey, "
162162
" CASE WHEN info LIKE '%%expires 20%%'"
163163
" THEN substr(info,instr(lower(info),'expires')+8,10)"
164164
" END AS exp,"
165165
"atime,"
166
- " subscriber.ssub, subscriber.subscriberId"
166
+ " subscriber.ssub, subscriber.subscriberId,"
167
+ " user.mtime AS sorttime"
167168
" FROM user LEFT JOIN lastAccess ON login=uname"
168169
" LEFT JOIN subscriber ON login=suname"
169170
" WHERE login NOT IN ('anonymous','nobody','developer','reader') %s"
170
- " ORDER BY sortkey", zWith/*safe-for-%s*/
171
+ " ORDER BY sorttime DESC", zWith/*safe-for-%s*/
171172
);
172173
rNow = db_double(0.0, "SELECT julianday('now');");
173174
while( db_step(&s)==SQLITE_ROW ){
174175
int uid = db_column_int(&s, 0);
175176
const char *zLogin = db_column_text(&s, 1);
@@ -180,10 +181,11 @@
180181
const char *zExp = db_column_text(&s,6);
181182
double rATime = db_column_double(&s,7);
182183
char *zAge = 0;
183184
const char *zSub;
184185
int sid = db_column_int(&s,9);
186
+ sqlite3_int64 sorttime = db_column_int64(&s, 10);
185187
if( rATime>0.0 ){
186188
zAge = human_readable_age(rNow - rATime);
187189
}
188190
if( bUbg ){
189191
@ <tr style='background-color: %h(user_color(zLogin));'>
@@ -192,11 +194,11 @@
192194
}
193195
@ <td data-sortkey='%h(zSortKey)'>\
194196
@ <a href='setup_uedit?id=%d(uid)'>%h(zLogin)</a>
195197
@ <td>%h(zCap)
196198
@ <td>%h(zInfo)
197
- @ <td>%h(zDate?zDate:"")
199
+ @ <td data-sortkey='%09llx(sorttime)'>%h(zDate?zDate:"")
198200
@ <td>%h(zExp?zExp:"")
199201
@ <td data-sortkey='%f(rATime)' style='white-space:nowrap'>%s(zAge?zAge:"")
200202
if( db_column_type(&s,8)==SQLITE_NULL ){
201203
@ <td>
202204
}else if( (zSub = db_column_text(&s,8))==0 || zSub[0]==0 ){
@@ -1016,11 +1018,11 @@
10161018
style_header("User %h", db_column_text(&q,1));
10171019
@ <table class="label-value">
10181020
@ <tr><th>uid:</th><td>%d(db_column_int(&q,0))
10191021
@ (<a href="%R/setup_uedit?id=%d(db_column_int(&q,0))">edit</a>)</td></tr>
10201022
@ <tr><th>login:</th><td>%h(db_column_text(&q,1))</td></tr>
1021
- @ <tr><th>capabilities:</th><td>%h(db_column_text(&q,2))</th></tr>
1023
+ @ <tr><th>capabilities:</th><td>%h(db_column_text(&q,2))</td></tr>
10221024
@ <tr><th valign="top">info:</th>
10231025
@ <td valign="top"><span style='white-space:pre-line;'>\
10241026
@ %h(db_column_text(&q,5))</span></td></tr>
10251027
@ <tr><th>user.mtime:</th><td>%h(db_column_text(&q,6))</td></tr>
10261028
if( db_column_type(&q,7)!=SQLITE_NULL ){
10271029
--- src/setupuser.c
+++ src/setupuser.c
@@ -115,11 +115,11 @@
115 }
116 if( !bUnusedOnly ){
117 style_submenu_element("Unused", "setup_ulist?unused");
118 }
119 @ <table border=1 cellpadding=2 cellspacing=0 class='userTable sortable' \
120 @ data-column-types='ktxTTKt' data-init-sort='2'>
121 @ <thead><tr>
122 @ <th>Login Name<th>Caps<th>Info<th>Date<th>Expire<th>Last Login\
123 @ <th>Alerts</tr></thead>
124 @ <tbody>
125 db_multi_exec(
@@ -161,15 +161,16 @@
161 " lower(login) AS sortkey, "
162 " CASE WHEN info LIKE '%%expires 20%%'"
163 " THEN substr(info,instr(lower(info),'expires')+8,10)"
164 " END AS exp,"
165 "atime,"
166 " subscriber.ssub, subscriber.subscriberId"
 
167 " FROM user LEFT JOIN lastAccess ON login=uname"
168 " LEFT JOIN subscriber ON login=suname"
169 " WHERE login NOT IN ('anonymous','nobody','developer','reader') %s"
170 " ORDER BY sortkey", zWith/*safe-for-%s*/
171 );
172 rNow = db_double(0.0, "SELECT julianday('now');");
173 while( db_step(&s)==SQLITE_ROW ){
174 int uid = db_column_int(&s, 0);
175 const char *zLogin = db_column_text(&s, 1);
@@ -180,10 +181,11 @@
180 const char *zExp = db_column_text(&s,6);
181 double rATime = db_column_double(&s,7);
182 char *zAge = 0;
183 const char *zSub;
184 int sid = db_column_int(&s,9);
 
185 if( rATime>0.0 ){
186 zAge = human_readable_age(rNow - rATime);
187 }
188 if( bUbg ){
189 @ <tr style='background-color: %h(user_color(zLogin));'>
@@ -192,11 +194,11 @@
192 }
193 @ <td data-sortkey='%h(zSortKey)'>\
194 @ <a href='setup_uedit?id=%d(uid)'>%h(zLogin)</a>
195 @ <td>%h(zCap)
196 @ <td>%h(zInfo)
197 @ <td>%h(zDate?zDate:"")
198 @ <td>%h(zExp?zExp:"")
199 @ <td data-sortkey='%f(rATime)' style='white-space:nowrap'>%s(zAge?zAge:"")
200 if( db_column_type(&s,8)==SQLITE_NULL ){
201 @ <td>
202 }else if( (zSub = db_column_text(&s,8))==0 || zSub[0]==0 ){
@@ -1016,11 +1018,11 @@
1016 style_header("User %h", db_column_text(&q,1));
1017 @ <table class="label-value">
1018 @ <tr><th>uid:</th><td>%d(db_column_int(&q,0))
1019 @ (<a href="%R/setup_uedit?id=%d(db_column_int(&q,0))">edit</a>)</td></tr>
1020 @ <tr><th>login:</th><td>%h(db_column_text(&q,1))</td></tr>
1021 @ <tr><th>capabilities:</th><td>%h(db_column_text(&q,2))</th></tr>
1022 @ <tr><th valign="top">info:</th>
1023 @ <td valign="top"><span style='white-space:pre-line;'>\
1024 @ %h(db_column_text(&q,5))</span></td></tr>
1025 @ <tr><th>user.mtime:</th><td>%h(db_column_text(&q,6))</td></tr>
1026 if( db_column_type(&q,7)!=SQLITE_NULL ){
1027
--- src/setupuser.c
+++ src/setupuser.c
@@ -115,11 +115,11 @@
115 }
116 if( !bUnusedOnly ){
117 style_submenu_element("Unused", "setup_ulist?unused");
118 }
119 @ <table border=1 cellpadding=2 cellspacing=0 class='userTable sortable' \
120 @ data-column-types='ktxKTKt' data-init-sort='4'>
121 @ <thead><tr>
122 @ <th>Login Name<th>Caps<th>Info<th>Date<th>Expire<th>Last Login\
123 @ <th>Alerts</tr></thead>
124 @ <tbody>
125 db_multi_exec(
@@ -161,15 +161,16 @@
161 " lower(login) AS sortkey, "
162 " CASE WHEN info LIKE '%%expires 20%%'"
163 " THEN substr(info,instr(lower(info),'expires')+8,10)"
164 " END AS exp,"
165 "atime,"
166 " subscriber.ssub, subscriber.subscriberId,"
167 " user.mtime AS sorttime"
168 " FROM user LEFT JOIN lastAccess ON login=uname"
169 " LEFT JOIN subscriber ON login=suname"
170 " WHERE login NOT IN ('anonymous','nobody','developer','reader') %s"
171 " ORDER BY sorttime DESC", zWith/*safe-for-%s*/
172 );
173 rNow = db_double(0.0, "SELECT julianday('now');");
174 while( db_step(&s)==SQLITE_ROW ){
175 int uid = db_column_int(&s, 0);
176 const char *zLogin = db_column_text(&s, 1);
@@ -180,10 +181,11 @@
181 const char *zExp = db_column_text(&s,6);
182 double rATime = db_column_double(&s,7);
183 char *zAge = 0;
184 const char *zSub;
185 int sid = db_column_int(&s,9);
186 sqlite3_int64 sorttime = db_column_int64(&s, 10);
187 if( rATime>0.0 ){
188 zAge = human_readable_age(rNow - rATime);
189 }
190 if( bUbg ){
191 @ <tr style='background-color: %h(user_color(zLogin));'>
@@ -192,11 +194,11 @@
194 }
195 @ <td data-sortkey='%h(zSortKey)'>\
196 @ <a href='setup_uedit?id=%d(uid)'>%h(zLogin)</a>
197 @ <td>%h(zCap)
198 @ <td>%h(zInfo)
199 @ <td data-sortkey='%09llx(sorttime)'>%h(zDate?zDate:"")
200 @ <td>%h(zExp?zExp:"")
201 @ <td data-sortkey='%f(rATime)' style='white-space:nowrap'>%s(zAge?zAge:"")
202 if( db_column_type(&s,8)==SQLITE_NULL ){
203 @ <td>
204 }else if( (zSub = db_column_text(&s,8))==0 || zSub[0]==0 ){
@@ -1016,11 +1018,11 @@
1018 style_header("User %h", db_column_text(&q,1));
1019 @ <table class="label-value">
1020 @ <tr><th>uid:</th><td>%d(db_column_int(&q,0))
1021 @ (<a href="%R/setup_uedit?id=%d(db_column_int(&q,0))">edit</a>)</td></tr>
1022 @ <tr><th>login:</th><td>%h(db_column_text(&q,1))</td></tr>
1023 @ <tr><th>capabilities:</th><td>%h(db_column_text(&q,2))</td></tr>
1024 @ <tr><th valign="top">info:</th>
1025 @ <td valign="top"><span style='white-space:pre-line;'>\
1026 @ %h(db_column_text(&q,5))</span></td></tr>
1027 @ <tr><th>user.mtime:</th><td>%h(db_column_text(&q,6))</td></tr>
1028 if( db_column_type(&q,7)!=SQLITE_NULL ){
1029
+5 -40
--- src/sitemap.c
+++ src/sitemap.c
@@ -56,22 +56,10 @@
5656
int i;
5757
int isPopup = 0; /* This is an XMLHttpRequest() for /sitemap */
5858
int e = atoi(PD("e","0"));
5959
const char *zExtra;
6060
61
-#if 0 /* Removed 2021-01-26 */
62
- const struct {
63
- const char *zTitle;
64
- const char *zProperty;
65
- } aExtra[] = {
66
- { "Documentation", "sitemap-docidx" },
67
- { "Download", "sitemap-download" },
68
- { "License", "sitemap-license" },
69
- { "Contact", "sitemap-contact" },
70
- };
71
-#endif
72
-
7361
login_check_credentials();
7462
if( P("popup")!=0 ){
7563
/* The "popup" query parameter
7664
** then disable anti-robot defenses */
7765
isPopup = 1;
@@ -87,26 +75,10 @@
8775
@ <ul id="sitemap" class="columns" style="column-width:20em">
8876
if( (e&1)==0 ){
8977
@ <li>%z(href("%R/home"))Home Page</a>
9078
}
9179
92
-#if 0 /* Removed 2021-01-26 */
93
- for(i=0; i<sizeof(aExtra)/sizeof(aExtra[0]); i++){
94
- char *z = db_get(aExtra[i].zProperty,0);
95
- if( z==0 || z[0]==0 ) continue;
96
- if( !inSublist ){
97
- @ <ul>
98
- inSublist = 1;
99
- }
100
- if( z[0]=='/' ){
101
- @ <li>%z(href("%R%s",z))%s(aExtra[i].zTitle)</a></li>
102
- }else{
103
- @ <li>%z(href("%s",z))%s(aExtra[i].zTitle)</a></li>
104
- }
105
- }
106
-#endif
107
-
10880
zExtra = db_get("sitemap-extra",0);
10981
if( zExtra && (e&2)==0 ){
11082
int rc;
11183
char **azExtra = 0;
11284
int *anExtra;
@@ -139,26 +111,18 @@
139111
}
140112
Th_Free(g.interp, azExtra);
141113
}
142114
if( (e&1)!=0 ) goto end_of_sitemap;
143115
144
-#if 0 /* Removed on 2021-02-11. Make a sitemap-extra entry if you */
145
- /* really want this */
146
- if( srchFlags & SRCH_DOC ){
147
- if( !inSublist ){
148
- @ <ul>
149
- inSublist = 1;
150
- }
151
- @ <li>%z(href("%R/docsrch"))Documentation Search</a></li>
152
- }
153
-#endif
154
-
155116
if( inSublist ){
156117
@ </ul>
157118
inSublist = 0;
158119
}
159120
@ </li>
121
+ if( db_open_local(0) && cgi_is_loopback(g.zIpAddr) ){
122
+ @ <li>%z(href("%R/ckout"))Checkout Status</a></li>
123
+ }
160124
if( g.perm.Read ){
161125
const char *zEditGlob = db_get("fileedit-glob","");
162126
@ <li>%z(href("%R/tree"))File Browser</a>
163127
@ <ul>
164128
@ <li>%z(href("%R/tree?type=tree&ci=trunk"))Tree-view,
@@ -192,11 +156,12 @@
192156
}
193157
if( g.perm.Chat ){
194158
@ <li>%z(href("%R/chat"))Chat</a></li>
195159
}
196160
if( g.perm.RdForum ){
197
- @ <li>%z(href("%R/forum"))Forum</a>
161
+ const char *zTitle = db_get("forum-title","Forum");
162
+ @ <li>%z(href("%R/forum"))%h(zTitle)</a>
198163
@ <ul>
199164
@ <li>%z(href("%R/timeline?y=f"))Recent activity</a></li>
200165
@ </ul>
201166
@ </li>
202167
}
203168
--- src/sitemap.c
+++ src/sitemap.c
@@ -56,22 +56,10 @@
56 int i;
57 int isPopup = 0; /* This is an XMLHttpRequest() for /sitemap */
58 int e = atoi(PD("e","0"));
59 const char *zExtra;
60
61 #if 0 /* Removed 2021-01-26 */
62 const struct {
63 const char *zTitle;
64 const char *zProperty;
65 } aExtra[] = {
66 { "Documentation", "sitemap-docidx" },
67 { "Download", "sitemap-download" },
68 { "License", "sitemap-license" },
69 { "Contact", "sitemap-contact" },
70 };
71 #endif
72
73 login_check_credentials();
74 if( P("popup")!=0 ){
75 /* The "popup" query parameter
76 ** then disable anti-robot defenses */
77 isPopup = 1;
@@ -87,26 +75,10 @@
87 @ <ul id="sitemap" class="columns" style="column-width:20em">
88 if( (e&1)==0 ){
89 @ <li>%z(href("%R/home"))Home Page</a>
90 }
91
92 #if 0 /* Removed 2021-01-26 */
93 for(i=0; i<sizeof(aExtra)/sizeof(aExtra[0]); i++){
94 char *z = db_get(aExtra[i].zProperty,0);
95 if( z==0 || z[0]==0 ) continue;
96 if( !inSublist ){
97 @ <ul>
98 inSublist = 1;
99 }
100 if( z[0]=='/' ){
101 @ <li>%z(href("%R%s",z))%s(aExtra[i].zTitle)</a></li>
102 }else{
103 @ <li>%z(href("%s",z))%s(aExtra[i].zTitle)</a></li>
104 }
105 }
106 #endif
107
108 zExtra = db_get("sitemap-extra",0);
109 if( zExtra && (e&2)==0 ){
110 int rc;
111 char **azExtra = 0;
112 int *anExtra;
@@ -139,26 +111,18 @@
139 }
140 Th_Free(g.interp, azExtra);
141 }
142 if( (e&1)!=0 ) goto end_of_sitemap;
143
144 #if 0 /* Removed on 2021-02-11. Make a sitemap-extra entry if you */
145 /* really want this */
146 if( srchFlags & SRCH_DOC ){
147 if( !inSublist ){
148 @ <ul>
149 inSublist = 1;
150 }
151 @ <li>%z(href("%R/docsrch"))Documentation Search</a></li>
152 }
153 #endif
154
155 if( inSublist ){
156 @ </ul>
157 inSublist = 0;
158 }
159 @ </li>
 
 
 
160 if( g.perm.Read ){
161 const char *zEditGlob = db_get("fileedit-glob","");
162 @ <li>%z(href("%R/tree"))File Browser</a>
163 @ <ul>
164 @ <li>%z(href("%R/tree?type=tree&ci=trunk"))Tree-view,
@@ -192,11 +156,12 @@
192 }
193 if( g.perm.Chat ){
194 @ <li>%z(href("%R/chat"))Chat</a></li>
195 }
196 if( g.perm.RdForum ){
197 @ <li>%z(href("%R/forum"))Forum</a>
 
198 @ <ul>
199 @ <li>%z(href("%R/timeline?y=f"))Recent activity</a></li>
200 @ </ul>
201 @ </li>
202 }
203
--- src/sitemap.c
+++ src/sitemap.c
@@ -56,22 +56,10 @@
56 int i;
57 int isPopup = 0; /* This is an XMLHttpRequest() for /sitemap */
58 int e = atoi(PD("e","0"));
59 const char *zExtra;
60
 
 
 
 
 
 
 
 
 
 
 
 
61 login_check_credentials();
62 if( P("popup")!=0 ){
63 /* The "popup" query parameter
64 ** then disable anti-robot defenses */
65 isPopup = 1;
@@ -87,26 +75,10 @@
75 @ <ul id="sitemap" class="columns" style="column-width:20em">
76 if( (e&1)==0 ){
77 @ <li>%z(href("%R/home"))Home Page</a>
78 }
79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80 zExtra = db_get("sitemap-extra",0);
81 if( zExtra && (e&2)==0 ){
82 int rc;
83 char **azExtra = 0;
84 int *anExtra;
@@ -139,26 +111,18 @@
111 }
112 Th_Free(g.interp, azExtra);
113 }
114 if( (e&1)!=0 ) goto end_of_sitemap;
115
 
 
 
 
 
 
 
 
 
 
 
116 if( inSublist ){
117 @ </ul>
118 inSublist = 0;
119 }
120 @ </li>
121 if( db_open_local(0) && cgi_is_loopback(g.zIpAddr) ){
122 @ <li>%z(href("%R/ckout"))Checkout Status</a></li>
123 }
124 if( g.perm.Read ){
125 const char *zEditGlob = db_get("fileedit-glob","");
126 @ <li>%z(href("%R/tree"))File Browser</a>
127 @ <ul>
128 @ <li>%z(href("%R/tree?type=tree&ci=trunk"))Tree-view,
@@ -192,11 +156,12 @@
156 }
157 if( g.perm.Chat ){
158 @ <li>%z(href("%R/chat"))Chat</a></li>
159 }
160 if( g.perm.RdForum ){
161 const char *zTitle = db_get("forum-title","Forum");
162 @ <li>%z(href("%R/forum"))%h(zTitle)</a>
163 @ <ul>
164 @ <li>%z(href("%R/timeline?y=f"))Recent activity</a></li>
165 @ </ul>
166 @ </li>
167 }
168
+2 -1
--- src/timeline.c
+++ src/timeline.c
@@ -1863,10 +1863,11 @@
18631863
char *zPlural; /* Ending for plural forms */
18641864
int showCherrypicks = 1; /* True to show cherrypick merges */
18651865
int haveParameterN; /* True if n= query parameter present */
18661866
int from_to_mode = 0; /* 0: from,to. 1: from,ft 2: from,bt */
18671867
1868
+ login_check_credentials();
18681869
url_initialize(&url, "timeline");
18691870
cgi_query_parameters_to_url(&url);
18701871
18711872
(void)P_NoBot("ss")
18721873
/* "ss" is processed via the udc but at least one spider likes to
@@ -1943,11 +1944,10 @@
19431944
*/
19441945
pd_rid = name_choice("dp","dp2",&zDPName);
19451946
if( pd_rid ){
19461947
p_rid = d_rid = pd_rid;
19471948
}
1948
- login_check_credentials();
19491949
if( (!g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki && !g.perm.RdForum)
19501950
|| (bisectLocal && !g.perm.Setup)
19511951
){
19521952
login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
19531953
return;
@@ -1990,10 +1990,11 @@
19901990
zTagName = z;
19911991
zMatchStyle = "brlist";
19921992
}
19931993
if( (z = P("rl"))!=0 ){
19941994
zBrName = z;
1995
+ related = 1;
19951996
zMatchStyle = "brlist";
19961997
}
19971998
}
19981999
19992000
/* Convert r=TAG to t=TAG&rel in order to populate the UI style widgets. */
20002001
--- src/timeline.c
+++ src/timeline.c
@@ -1863,10 +1863,11 @@
1863 char *zPlural; /* Ending for plural forms */
1864 int showCherrypicks = 1; /* True to show cherrypick merges */
1865 int haveParameterN; /* True if n= query parameter present */
1866 int from_to_mode = 0; /* 0: from,to. 1: from,ft 2: from,bt */
1867
 
1868 url_initialize(&url, "timeline");
1869 cgi_query_parameters_to_url(&url);
1870
1871 (void)P_NoBot("ss")
1872 /* "ss" is processed via the udc but at least one spider likes to
@@ -1943,11 +1944,10 @@
1943 */
1944 pd_rid = name_choice("dp","dp2",&zDPName);
1945 if( pd_rid ){
1946 p_rid = d_rid = pd_rid;
1947 }
1948 login_check_credentials();
1949 if( (!g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki && !g.perm.RdForum)
1950 || (bisectLocal && !g.perm.Setup)
1951 ){
1952 login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
1953 return;
@@ -1990,10 +1990,11 @@
1990 zTagName = z;
1991 zMatchStyle = "brlist";
1992 }
1993 if( (z = P("rl"))!=0 ){
1994 zBrName = z;
 
1995 zMatchStyle = "brlist";
1996 }
1997 }
1998
1999 /* Convert r=TAG to t=TAG&rel in order to populate the UI style widgets. */
2000
--- src/timeline.c
+++ src/timeline.c
@@ -1863,10 +1863,11 @@
1863 char *zPlural; /* Ending for plural forms */
1864 int showCherrypicks = 1; /* True to show cherrypick merges */
1865 int haveParameterN; /* True if n= query parameter present */
1866 int from_to_mode = 0; /* 0: from,to. 1: from,ft 2: from,bt */
1867
1868 login_check_credentials();
1869 url_initialize(&url, "timeline");
1870 cgi_query_parameters_to_url(&url);
1871
1872 (void)P_NoBot("ss")
1873 /* "ss" is processed via the udc but at least one spider likes to
@@ -1943,11 +1944,10 @@
1944 */
1945 pd_rid = name_choice("dp","dp2",&zDPName);
1946 if( pd_rid ){
1947 p_rid = d_rid = pd_rid;
1948 }
 
1949 if( (!g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki && !g.perm.RdForum)
1950 || (bisectLocal && !g.perm.Setup)
1951 ){
1952 login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
1953 return;
@@ -1990,10 +1990,11 @@
1990 zTagName = z;
1991 zMatchStyle = "brlist";
1992 }
1993 if( (z = P("rl"))!=0 ){
1994 zBrName = z;
1995 related = 1;
1996 zMatchStyle = "brlist";
1997 }
1998 }
1999
2000 /* Convert r=TAG to t=TAG&rel in order to populate the UI style widgets. */
2001
+1 -1
--- src/tkt.c
+++ src/tkt.c
@@ -781,11 +781,11 @@
781781
782782
zFullName = db_text(0,
783783
"SELECT tkt_uuid FROM ticket"
784784
" WHERE tkt_uuid GLOB '%q*'", zUuid);
785785
if( zFullName ){
786
- attachment_list(zFullName, "<hr><h2>Attachments:</h2><ul>");
786
+ attachment_list(zFullName, "<h2>Attachments:</h2>", 1);
787787
}
788788
789789
style_finish_page();
790790
}
791791
792792
--- src/tkt.c
+++ src/tkt.c
@@ -781,11 +781,11 @@
781
782 zFullName = db_text(0,
783 "SELECT tkt_uuid FROM ticket"
784 " WHERE tkt_uuid GLOB '%q*'", zUuid);
785 if( zFullName ){
786 attachment_list(zFullName, "<hr><h2>Attachments:</h2><ul>");
787 }
788
789 style_finish_page();
790 }
791
792
--- src/tkt.c
+++ src/tkt.c
@@ -781,11 +781,11 @@
781
782 zFullName = db_text(0,
783 "SELECT tkt_uuid FROM ticket"
784 " WHERE tkt_uuid GLOB '%q*'", zUuid);
785 if( zFullName ){
786 attachment_list(zFullName, "<h2>Attachments:</h2>", 1);
787 }
788
789 style_finish_page();
790 }
791
792
+55 -3
--- src/update.c
+++ src/update.c
@@ -132,10 +132,13 @@
132132
int nUpdate = 0; /* Number of changes of any kind */
133133
int bNosync = 0; /* --nosync. Omit the auto-sync */
134134
int width; /* Width of printed comment lines */
135135
Stmt mtimeXfer; /* Statement to transfer mtimes */
136136
const char *zWidth; /* Width option string value */
137
+ const char *zCurBrName; /* Current branch name */
138
+ const char *zNewBrName; /* New branch name */
139
+ const char *zBrChgMsg = ""; /* Message to display if branch changes */
137140
138141
if( !internalUpdate ){
139142
undo_capture_command_line();
140143
url_proxy_options();
141144
}
@@ -163,10 +166,11 @@
163166
/* We should be done with options.. */
164167
verify_all_options();
165168
166169
db_must_be_within_tree();
167170
vid = db_lget_int("checkout", 0);
171
+ zCurBrName = branch_of_rid(vid);
168172
user_select();
169173
if( !dryRunFlag && !internalUpdate && !bNosync ){
170174
if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag, 1, "update") ){
171175
fossil_fatal("update abandoned due to sync failure");
172176
}
@@ -403,10 +407,11 @@
403407
" WHERE id=:idt"
404408
);
405409
assert( g.zLocalRoot!=0 );
406410
assert( strlen(g.zLocalRoot)>0 );
407411
assert( g.zLocalRoot[strlen(g.zLocalRoot)-1]=='/' );
412
+ merge_info_init();
408413
while( db_step(&q)==SQLITE_ROW ){
409414
const char *zName = db_column_text(&q, 0); /* The filename from root */
410415
int idv = db_column_int(&q, 1); /* VFILE entry for current */
411416
int ridv = db_column_int(&q, 2); /* RecordID for current */
412417
int idt = db_column_int(&q, 3); /* VFILE entry for target */
@@ -418,13 +423,18 @@
418423
int islinkt = db_column_int(&q, 9); /* Is target file is a link */
419424
int deleted = db_column_int(&q, 10); /* Marked for deletion */
420425
char *zFullPath; /* Full pathname of the file */
421426
char *zFullNewPath; /* Full pathname of dest */
422427
char nameChng; /* True if the name changed */
428
+ const char *zOp = 0; /* Type of change. */
429
+ i64 sz = 0; /* Size of the file */
430
+ int nc = 0; /* Number of conflicts */
431
+ const char *zErrMsg = 0; /* Error message */
423432
424433
zFullPath = mprintf("%s%s", g.zLocalRoot, zName);
425434
zFullNewPath = mprintf("%s%s", g.zLocalRoot, zNewName);
435
+ sz = file_size(zFullNewPath, ExtFILE);
426436
nameChng = fossil_strcmp(zName, zNewName);
427437
nUpdate++;
428438
if( deleted ){
429439
db_multi_exec("UPDATE vfile SET deleted=1 WHERE id=%d", idt);
430440
}
@@ -432,10 +442,13 @@
432442
/* Conflict. This file has been added to the current check-out
433443
** but also exists in the target check-out. Use the current version.
434444
*/
435445
fossil_print("CONFLICT %s\n", zName);
436446
nConflict++;
447
+ zOp = "CONFLICT";
448
+ nc = 1;
449
+ zErrMsg = "duplicate file";
437450
}else if( idt>0 && idv==0 ){
438451
/* File added in the target. */
439452
if( file_isfile_or_link(zFullPath) ){
440453
/* Name of backup file with Original content */
441454
char *zOrig = file_newname(zFullPath, "original", 1);
@@ -444,10 +457,13 @@
444457
fossil_free(zOrig);
445458
fossil_print("ADD %s - overwrites an unmanaged file", zName);
446459
if( !dryRunFlag ) fossil_print(", original copy backed up locally");
447460
fossil_print("\n");
448461
nOverwrite++;
462
+ nc = 1;
463
+ zOp = "CONFLICT";
464
+ zErrMsg = "new file overwrites unmanaged file";
449465
}else{
450466
fossil_print("ADD %s\n", zName);
451467
}
452468
if( !dryRunFlag && !internalUpdate ) undo_save(zName);
453469
if( !dryRunFlag ) vfile_to_disk(0, idt, 0, 0);
@@ -458,16 +474,18 @@
458474
}else{
459475
fossil_print("UPDATE %s\n", zName);
460476
}
461477
if( !dryRunFlag && !internalUpdate ) undo_save(zName);
462478
if( !dryRunFlag ) vfile_to_disk(0, idt, 0, 0);
479
+ zOp = "UPDATE";
463480
}else if( idt>0 && idv>0 && !deleted && file_size(zFullPath, RepoFILE)<0 ){
464481
/* The file missing from the local check-out. Restore it to the
465482
** version that appears in the target. */
466483
fossil_print("UPDATE %s\n", zName);
467484
if( !dryRunFlag && !internalUpdate ) undo_save(zName);
468485
if( !dryRunFlag ) vfile_to_disk(0, idt, 0, 0);
486
+ zOp = "UPDATE";
469487
}else if( idt==0 && idv>0 ){
470488
if( ridv==0 ){
471489
/* Added in current check-out. Continue to hold the file as
472490
** as an addition */
473491
db_multi_exec("UPDATE vfile SET vid=%d WHERE id=%d", tid, idv);
@@ -474,10 +492,13 @@
474492
}else if( chnged ){
475493
/* Edited locally but deleted from the target. Do not track the
476494
** file but keep the edited version around. */
477495
fossil_print("CONFLICT %s - edited locally but deleted by update\n",
478496
zName);
497
+ zOp = "CONFLICT";
498
+ zErrMsg = "edited locally but deleted by update";
499
+ nc = 1;
479500
nConflict++;
480501
}else{
481502
fossil_print("REMOVE %s\n", zName);
482503
if( !dryRunFlag && !internalUpdate ) undo_save(zName);
483504
if( !dryRunFlag ){
@@ -496,17 +517,19 @@
496517
}
497518
}else if( idt>0 && idv>0 && ridt!=ridv && chnged ){
498519
/* Merge the changes in the current tree into the target version */
499520
Blob r, t, v;
500521
int rc;
522
+
501523
if( nameChng ){
502524
fossil_print("MERGE %s -> %s\n", zName, zNewName);
503525
}else{
504526
fossil_print("MERGE %s\n", zName);
505527
}
506528
if( islinkv || islinkt ){
507529
fossil_print("***** Cannot merge symlink %s\n", zNewName);
530
+ zOp = "CONFLICT";
508531
nConflict++;
509532
}else{
510533
unsigned mergeFlags = dryRunFlag ? MERGE_DRYRUN : 0;
511534
if(keepMergeFlag!=0) mergeFlags |= MERGE_KEEP_FILES;
512535
if( !dryRunFlag && !internalUpdate ) undo_save(zName);
@@ -517,12 +540,17 @@
517540
if( !dryRunFlag ){
518541
blob_write_to_file(&r, zFullNewPath);
519542
file_setexe(zFullNewPath, isexe);
520543
}
521544
if( rc>0 ){
545
+ nc = rc;
546
+ zOp = "CONFLICT";
547
+ zErrMsg = "merge conflicts";
522548
fossil_print("***** %d merge conflicts in %s\n", rc, zNewName);
523549
nConflict++;
550
+ }else{
551
+ zOp = "MERGE";
524552
}
525553
}else{
526554
if( !dryRunFlag ){
527555
if( !keepMergeFlag ){
528556
/* Name of backup file with Original content */
@@ -539,10 +567,13 @@
539567
if( !dryRunFlag ){
540568
fossil_print(", original copy backed up locally");
541569
}
542570
fossil_print("\n");
543571
nConflict++;
572
+ zOp = "ERROR";
573
+ zErrMsg = "cannot merge binary file";
574
+ nc = 1;
544575
}
545576
}
546577
if( nameChng && !dryRunFlag ) file_delete(zFullPath);
547578
blob_reset(&v);
548579
blob_reset(&t);
@@ -556,27 +587,48 @@
556587
db_bind_int(&mtimeXfer, ":idt", idt);
557588
db_step(&mtimeXfer);
558589
db_reset(&mtimeXfer);
559590
if( verboseFlag ) fossil_print("UNCHANGED %s\n", zName);
560591
}
592
+ }
593
+ if( zOp!=0 ){
594
+ db_multi_exec(
595
+ "INSERT INTO mergestat(op,fnp,ridp,fn,ridv,sz,fnm,ridm,fnr,nc,msg)"
596
+ "VALUES(%Q,%Q,%d,%Q,NULL,%lld,%Q,%d,%Q,%d,%Q)",
597
+ /* op */ zOp,
598
+ /* fnp */ zName,
599
+ /* ridp */ ridv,
600
+ /* fn */ zNewName,
601
+ /* sz */ sz,
602
+ /* fnm */ zName,
603
+ /* ridm */ ridt,
604
+ /* fnr */ zNewName,
605
+ /* nc */ nc,
606
+ /* msg */ zErrMsg
607
+ );
561608
}
562609
free(zFullPath);
563610
free(zFullNewPath);
564611
}
565612
db_finalize(&q);
566613
db_finalize(&mtimeXfer);
567614
fossil_print("%.79c\n",'-');
615
+ zNewBrName = branch_of_rid(tid);
616
+ if( g.argc<3 && fossil_strcmp(zCurBrName, zNewBrName)!=0 ){
617
+ zBrChgMsg = mprintf(" Branch changed from %s to %s.",
618
+ zCurBrName, zNewBrName);
619
+ }
568620
if( nUpdate==0 ){
569621
show_common_info(tid, "checkout:", 1, 0);
570
- fossil_print("%-13s None. Already up-to-date\n", "changes:");
622
+ fossil_print("%-13s None. Already up-to-date.%s\n", "changes:", zBrChgMsg);
571623
}else{
572624
fossil_print("%-13s %.40s %s\n", "updated-from:", rid_to_uuid(vid),
573625
db_text("", "SELECT datetime(mtime) || ' UTC' FROM event "
574626
" WHERE objid=%d", vid));
575627
show_common_info(tid, "updated-to:", 1, 0);
576
- fossil_print("%-13s %d file%s modified.\n", "changes:",
577
- nUpdate, nUpdate>1 ? "s" : "");
628
+ fossil_print("%-13s %d file%s modified.%s\n", "changes:",
629
+ nUpdate, nUpdate>1 ? "s" : "", zBrChgMsg);
578630
}
579631
580632
/* Report on conflicts
581633
*/
582634
if( !dryRunFlag ){
583635
--- src/update.c
+++ src/update.c
@@ -132,10 +132,13 @@
132 int nUpdate = 0; /* Number of changes of any kind */
133 int bNosync = 0; /* --nosync. Omit the auto-sync */
134 int width; /* Width of printed comment lines */
135 Stmt mtimeXfer; /* Statement to transfer mtimes */
136 const char *zWidth; /* Width option string value */
 
 
 
137
138 if( !internalUpdate ){
139 undo_capture_command_line();
140 url_proxy_options();
141 }
@@ -163,10 +166,11 @@
163 /* We should be done with options.. */
164 verify_all_options();
165
166 db_must_be_within_tree();
167 vid = db_lget_int("checkout", 0);
 
168 user_select();
169 if( !dryRunFlag && !internalUpdate && !bNosync ){
170 if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag, 1, "update") ){
171 fossil_fatal("update abandoned due to sync failure");
172 }
@@ -403,10 +407,11 @@
403 " WHERE id=:idt"
404 );
405 assert( g.zLocalRoot!=0 );
406 assert( strlen(g.zLocalRoot)>0 );
407 assert( g.zLocalRoot[strlen(g.zLocalRoot)-1]=='/' );
 
408 while( db_step(&q)==SQLITE_ROW ){
409 const char *zName = db_column_text(&q, 0); /* The filename from root */
410 int idv = db_column_int(&q, 1); /* VFILE entry for current */
411 int ridv = db_column_int(&q, 2); /* RecordID for current */
412 int idt = db_column_int(&q, 3); /* VFILE entry for target */
@@ -418,13 +423,18 @@
418 int islinkt = db_column_int(&q, 9); /* Is target file is a link */
419 int deleted = db_column_int(&q, 10); /* Marked for deletion */
420 char *zFullPath; /* Full pathname of the file */
421 char *zFullNewPath; /* Full pathname of dest */
422 char nameChng; /* True if the name changed */
 
 
 
 
423
424 zFullPath = mprintf("%s%s", g.zLocalRoot, zName);
425 zFullNewPath = mprintf("%s%s", g.zLocalRoot, zNewName);
 
426 nameChng = fossil_strcmp(zName, zNewName);
427 nUpdate++;
428 if( deleted ){
429 db_multi_exec("UPDATE vfile SET deleted=1 WHERE id=%d", idt);
430 }
@@ -432,10 +442,13 @@
432 /* Conflict. This file has been added to the current check-out
433 ** but also exists in the target check-out. Use the current version.
434 */
435 fossil_print("CONFLICT %s\n", zName);
436 nConflict++;
 
 
 
437 }else if( idt>0 && idv==0 ){
438 /* File added in the target. */
439 if( file_isfile_or_link(zFullPath) ){
440 /* Name of backup file with Original content */
441 char *zOrig = file_newname(zFullPath, "original", 1);
@@ -444,10 +457,13 @@
444 fossil_free(zOrig);
445 fossil_print("ADD %s - overwrites an unmanaged file", zName);
446 if( !dryRunFlag ) fossil_print(", original copy backed up locally");
447 fossil_print("\n");
448 nOverwrite++;
 
 
 
449 }else{
450 fossil_print("ADD %s\n", zName);
451 }
452 if( !dryRunFlag && !internalUpdate ) undo_save(zName);
453 if( !dryRunFlag ) vfile_to_disk(0, idt, 0, 0);
@@ -458,16 +474,18 @@
458 }else{
459 fossil_print("UPDATE %s\n", zName);
460 }
461 if( !dryRunFlag && !internalUpdate ) undo_save(zName);
462 if( !dryRunFlag ) vfile_to_disk(0, idt, 0, 0);
 
463 }else if( idt>0 && idv>0 && !deleted && file_size(zFullPath, RepoFILE)<0 ){
464 /* The file missing from the local check-out. Restore it to the
465 ** version that appears in the target. */
466 fossil_print("UPDATE %s\n", zName);
467 if( !dryRunFlag && !internalUpdate ) undo_save(zName);
468 if( !dryRunFlag ) vfile_to_disk(0, idt, 0, 0);
 
469 }else if( idt==0 && idv>0 ){
470 if( ridv==0 ){
471 /* Added in current check-out. Continue to hold the file as
472 ** as an addition */
473 db_multi_exec("UPDATE vfile SET vid=%d WHERE id=%d", tid, idv);
@@ -474,10 +492,13 @@
474 }else if( chnged ){
475 /* Edited locally but deleted from the target. Do not track the
476 ** file but keep the edited version around. */
477 fossil_print("CONFLICT %s - edited locally but deleted by update\n",
478 zName);
 
 
 
479 nConflict++;
480 }else{
481 fossil_print("REMOVE %s\n", zName);
482 if( !dryRunFlag && !internalUpdate ) undo_save(zName);
483 if( !dryRunFlag ){
@@ -496,17 +517,19 @@
496 }
497 }else if( idt>0 && idv>0 && ridt!=ridv && chnged ){
498 /* Merge the changes in the current tree into the target version */
499 Blob r, t, v;
500 int rc;
 
501 if( nameChng ){
502 fossil_print("MERGE %s -> %s\n", zName, zNewName);
503 }else{
504 fossil_print("MERGE %s\n", zName);
505 }
506 if( islinkv || islinkt ){
507 fossil_print("***** Cannot merge symlink %s\n", zNewName);
 
508 nConflict++;
509 }else{
510 unsigned mergeFlags = dryRunFlag ? MERGE_DRYRUN : 0;
511 if(keepMergeFlag!=0) mergeFlags |= MERGE_KEEP_FILES;
512 if( !dryRunFlag && !internalUpdate ) undo_save(zName);
@@ -517,12 +540,17 @@
517 if( !dryRunFlag ){
518 blob_write_to_file(&r, zFullNewPath);
519 file_setexe(zFullNewPath, isexe);
520 }
521 if( rc>0 ){
 
 
 
522 fossil_print("***** %d merge conflicts in %s\n", rc, zNewName);
523 nConflict++;
 
 
524 }
525 }else{
526 if( !dryRunFlag ){
527 if( !keepMergeFlag ){
528 /* Name of backup file with Original content */
@@ -539,10 +567,13 @@
539 if( !dryRunFlag ){
540 fossil_print(", original copy backed up locally");
541 }
542 fossil_print("\n");
543 nConflict++;
 
 
 
544 }
545 }
546 if( nameChng && !dryRunFlag ) file_delete(zFullPath);
547 blob_reset(&v);
548 blob_reset(&t);
@@ -556,27 +587,48 @@
556 db_bind_int(&mtimeXfer, ":idt", idt);
557 db_step(&mtimeXfer);
558 db_reset(&mtimeXfer);
559 if( verboseFlag ) fossil_print("UNCHANGED %s\n", zName);
560 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
561 }
562 free(zFullPath);
563 free(zFullNewPath);
564 }
565 db_finalize(&q);
566 db_finalize(&mtimeXfer);
567 fossil_print("%.79c\n",'-');
 
 
 
 
 
568 if( nUpdate==0 ){
569 show_common_info(tid, "checkout:", 1, 0);
570 fossil_print("%-13s None. Already up-to-date\n", "changes:");
571 }else{
572 fossil_print("%-13s %.40s %s\n", "updated-from:", rid_to_uuid(vid),
573 db_text("", "SELECT datetime(mtime) || ' UTC' FROM event "
574 " WHERE objid=%d", vid));
575 show_common_info(tid, "updated-to:", 1, 0);
576 fossil_print("%-13s %d file%s modified.\n", "changes:",
577 nUpdate, nUpdate>1 ? "s" : "");
578 }
579
580 /* Report on conflicts
581 */
582 if( !dryRunFlag ){
583
--- src/update.c
+++ src/update.c
@@ -132,10 +132,13 @@
132 int nUpdate = 0; /* Number of changes of any kind */
133 int bNosync = 0; /* --nosync. Omit the auto-sync */
134 int width; /* Width of printed comment lines */
135 Stmt mtimeXfer; /* Statement to transfer mtimes */
136 const char *zWidth; /* Width option string value */
137 const char *zCurBrName; /* Current branch name */
138 const char *zNewBrName; /* New branch name */
139 const char *zBrChgMsg = ""; /* Message to display if branch changes */
140
141 if( !internalUpdate ){
142 undo_capture_command_line();
143 url_proxy_options();
144 }
@@ -163,10 +166,11 @@
166 /* We should be done with options.. */
167 verify_all_options();
168
169 db_must_be_within_tree();
170 vid = db_lget_int("checkout", 0);
171 zCurBrName = branch_of_rid(vid);
172 user_select();
173 if( !dryRunFlag && !internalUpdate && !bNosync ){
174 if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag, 1, "update") ){
175 fossil_fatal("update abandoned due to sync failure");
176 }
@@ -403,10 +407,11 @@
407 " WHERE id=:idt"
408 );
409 assert( g.zLocalRoot!=0 );
410 assert( strlen(g.zLocalRoot)>0 );
411 assert( g.zLocalRoot[strlen(g.zLocalRoot)-1]=='/' );
412 merge_info_init();
413 while( db_step(&q)==SQLITE_ROW ){
414 const char *zName = db_column_text(&q, 0); /* The filename from root */
415 int idv = db_column_int(&q, 1); /* VFILE entry for current */
416 int ridv = db_column_int(&q, 2); /* RecordID for current */
417 int idt = db_column_int(&q, 3); /* VFILE entry for target */
@@ -418,13 +423,18 @@
423 int islinkt = db_column_int(&q, 9); /* Is target file is a link */
424 int deleted = db_column_int(&q, 10); /* Marked for deletion */
425 char *zFullPath; /* Full pathname of the file */
426 char *zFullNewPath; /* Full pathname of dest */
427 char nameChng; /* True if the name changed */
428 const char *zOp = 0; /* Type of change. */
429 i64 sz = 0; /* Size of the file */
430 int nc = 0; /* Number of conflicts */
431 const char *zErrMsg = 0; /* Error message */
432
433 zFullPath = mprintf("%s%s", g.zLocalRoot, zName);
434 zFullNewPath = mprintf("%s%s", g.zLocalRoot, zNewName);
435 sz = file_size(zFullNewPath, ExtFILE);
436 nameChng = fossil_strcmp(zName, zNewName);
437 nUpdate++;
438 if( deleted ){
439 db_multi_exec("UPDATE vfile SET deleted=1 WHERE id=%d", idt);
440 }
@@ -432,10 +442,13 @@
442 /* Conflict. This file has been added to the current check-out
443 ** but also exists in the target check-out. Use the current version.
444 */
445 fossil_print("CONFLICT %s\n", zName);
446 nConflict++;
447 zOp = "CONFLICT";
448 nc = 1;
449 zErrMsg = "duplicate file";
450 }else if( idt>0 && idv==0 ){
451 /* File added in the target. */
452 if( file_isfile_or_link(zFullPath) ){
453 /* Name of backup file with Original content */
454 char *zOrig = file_newname(zFullPath, "original", 1);
@@ -444,10 +457,13 @@
457 fossil_free(zOrig);
458 fossil_print("ADD %s - overwrites an unmanaged file", zName);
459 if( !dryRunFlag ) fossil_print(", original copy backed up locally");
460 fossil_print("\n");
461 nOverwrite++;
462 nc = 1;
463 zOp = "CONFLICT";
464 zErrMsg = "new file overwrites unmanaged file";
465 }else{
466 fossil_print("ADD %s\n", zName);
467 }
468 if( !dryRunFlag && !internalUpdate ) undo_save(zName);
469 if( !dryRunFlag ) vfile_to_disk(0, idt, 0, 0);
@@ -458,16 +474,18 @@
474 }else{
475 fossil_print("UPDATE %s\n", zName);
476 }
477 if( !dryRunFlag && !internalUpdate ) undo_save(zName);
478 if( !dryRunFlag ) vfile_to_disk(0, idt, 0, 0);
479 zOp = "UPDATE";
480 }else if( idt>0 && idv>0 && !deleted && file_size(zFullPath, RepoFILE)<0 ){
481 /* The file missing from the local check-out. Restore it to the
482 ** version that appears in the target. */
483 fossil_print("UPDATE %s\n", zName);
484 if( !dryRunFlag && !internalUpdate ) undo_save(zName);
485 if( !dryRunFlag ) vfile_to_disk(0, idt, 0, 0);
486 zOp = "UPDATE";
487 }else if( idt==0 && idv>0 ){
488 if( ridv==0 ){
489 /* Added in current check-out. Continue to hold the file as
490 ** as an addition */
491 db_multi_exec("UPDATE vfile SET vid=%d WHERE id=%d", tid, idv);
@@ -474,10 +492,13 @@
492 }else if( chnged ){
493 /* Edited locally but deleted from the target. Do not track the
494 ** file but keep the edited version around. */
495 fossil_print("CONFLICT %s - edited locally but deleted by update\n",
496 zName);
497 zOp = "CONFLICT";
498 zErrMsg = "edited locally but deleted by update";
499 nc = 1;
500 nConflict++;
501 }else{
502 fossil_print("REMOVE %s\n", zName);
503 if( !dryRunFlag && !internalUpdate ) undo_save(zName);
504 if( !dryRunFlag ){
@@ -496,17 +517,19 @@
517 }
518 }else if( idt>0 && idv>0 && ridt!=ridv && chnged ){
519 /* Merge the changes in the current tree into the target version */
520 Blob r, t, v;
521 int rc;
522
523 if( nameChng ){
524 fossil_print("MERGE %s -> %s\n", zName, zNewName);
525 }else{
526 fossil_print("MERGE %s\n", zName);
527 }
528 if( islinkv || islinkt ){
529 fossil_print("***** Cannot merge symlink %s\n", zNewName);
530 zOp = "CONFLICT";
531 nConflict++;
532 }else{
533 unsigned mergeFlags = dryRunFlag ? MERGE_DRYRUN : 0;
534 if(keepMergeFlag!=0) mergeFlags |= MERGE_KEEP_FILES;
535 if( !dryRunFlag && !internalUpdate ) undo_save(zName);
@@ -517,12 +540,17 @@
540 if( !dryRunFlag ){
541 blob_write_to_file(&r, zFullNewPath);
542 file_setexe(zFullNewPath, isexe);
543 }
544 if( rc>0 ){
545 nc = rc;
546 zOp = "CONFLICT";
547 zErrMsg = "merge conflicts";
548 fossil_print("***** %d merge conflicts in %s\n", rc, zNewName);
549 nConflict++;
550 }else{
551 zOp = "MERGE";
552 }
553 }else{
554 if( !dryRunFlag ){
555 if( !keepMergeFlag ){
556 /* Name of backup file with Original content */
@@ -539,10 +567,13 @@
567 if( !dryRunFlag ){
568 fossil_print(", original copy backed up locally");
569 }
570 fossil_print("\n");
571 nConflict++;
572 zOp = "ERROR";
573 zErrMsg = "cannot merge binary file";
574 nc = 1;
575 }
576 }
577 if( nameChng && !dryRunFlag ) file_delete(zFullPath);
578 blob_reset(&v);
579 blob_reset(&t);
@@ -556,27 +587,48 @@
587 db_bind_int(&mtimeXfer, ":idt", idt);
588 db_step(&mtimeXfer);
589 db_reset(&mtimeXfer);
590 if( verboseFlag ) fossil_print("UNCHANGED %s\n", zName);
591 }
592 }
593 if( zOp!=0 ){
594 db_multi_exec(
595 "INSERT INTO mergestat(op,fnp,ridp,fn,ridv,sz,fnm,ridm,fnr,nc,msg)"
596 "VALUES(%Q,%Q,%d,%Q,NULL,%lld,%Q,%d,%Q,%d,%Q)",
597 /* op */ zOp,
598 /* fnp */ zName,
599 /* ridp */ ridv,
600 /* fn */ zNewName,
601 /* sz */ sz,
602 /* fnm */ zName,
603 /* ridm */ ridt,
604 /* fnr */ zNewName,
605 /* nc */ nc,
606 /* msg */ zErrMsg
607 );
608 }
609 free(zFullPath);
610 free(zFullNewPath);
611 }
612 db_finalize(&q);
613 db_finalize(&mtimeXfer);
614 fossil_print("%.79c\n",'-');
615 zNewBrName = branch_of_rid(tid);
616 if( g.argc<3 && fossil_strcmp(zCurBrName, zNewBrName)!=0 ){
617 zBrChgMsg = mprintf(" Branch changed from %s to %s.",
618 zCurBrName, zNewBrName);
619 }
620 if( nUpdate==0 ){
621 show_common_info(tid, "checkout:", 1, 0);
622 fossil_print("%-13s None. Already up-to-date.%s\n", "changes:", zBrChgMsg);
623 }else{
624 fossil_print("%-13s %.40s %s\n", "updated-from:", rid_to_uuid(vid),
625 db_text("", "SELECT datetime(mtime) || ' UTC' FROM event "
626 " WHERE objid=%d", vid));
627 show_common_info(tid, "updated-to:", 1, 0);
628 fossil_print("%-13s %d file%s modified.%s\n", "changes:",
629 nUpdate, nUpdate>1 ? "s" : "", zBrChgMsg);
630 }
631
632 /* Report on conflicts
633 */
634 if( !dryRunFlag ){
635
+4 -4
--- src/wiki.c
+++ src/wiki.c
@@ -622,14 +622,14 @@
622622
wiki_render_by_mimetype(&wiki, zMimetype);
623623
blob_reset(&wiki);
624624
}
625625
manifest_destroy(pWiki);
626626
if( !isPopup ){
627
- char * zLabel = mprintf("<hr><h2><a href='%R/attachlist?name=%T'>"
628
- "Attachments</a>:</h2><ul>",
627
+ char * zLabel = mprintf("<h2><a href='%R/attachlist?page=%T'>"
628
+ "Attachments</a>:</h2>",
629629
zPageName);
630
- attachment_list(zPageName, zLabel);
630
+ attachment_list(zPageName, zLabel, 1);
631631
fossil_free(zLabel);
632632
document_emit_js(/*for optional pikchr support*/);
633633
style_finish_page();
634634
}
635635
}
@@ -1331,11 +1331,11 @@
13311331
CX("<div id='fossil-status-bar' "
13321332
"title='Status message area. Double-click to clear them.'>"
13331333
"Status messages will go here.</div>\n"
13341334
/* will be moved into the tab container via JS */);
13351335
1336
- CX("<div id='wikiedit-edit-status''>"
1336
+ CX("<div id='wikiedit-edit-status'>"
13371337
"<span class='name'></span>"
13381338
"<span class='links'></span>"
13391339
"</div>");
13401340
13411341
/* Main tab container... */
13421342
--- src/wiki.c
+++ src/wiki.c
@@ -622,14 +622,14 @@
622 wiki_render_by_mimetype(&wiki, zMimetype);
623 blob_reset(&wiki);
624 }
625 manifest_destroy(pWiki);
626 if( !isPopup ){
627 char * zLabel = mprintf("<hr><h2><a href='%R/attachlist?name=%T'>"
628 "Attachments</a>:</h2><ul>",
629 zPageName);
630 attachment_list(zPageName, zLabel);
631 fossil_free(zLabel);
632 document_emit_js(/*for optional pikchr support*/);
633 style_finish_page();
634 }
635 }
@@ -1331,11 +1331,11 @@
1331 CX("<div id='fossil-status-bar' "
1332 "title='Status message area. Double-click to clear them.'>"
1333 "Status messages will go here.</div>\n"
1334 /* will be moved into the tab container via JS */);
1335
1336 CX("<div id='wikiedit-edit-status''>"
1337 "<span class='name'></span>"
1338 "<span class='links'></span>"
1339 "</div>");
1340
1341 /* Main tab container... */
1342
--- src/wiki.c
+++ src/wiki.c
@@ -622,14 +622,14 @@
622 wiki_render_by_mimetype(&wiki, zMimetype);
623 blob_reset(&wiki);
624 }
625 manifest_destroy(pWiki);
626 if( !isPopup ){
627 char * zLabel = mprintf("<h2><a href='%R/attachlist?page=%T'>"
628 "Attachments</a>:</h2>",
629 zPageName);
630 attachment_list(zPageName, zLabel, 1);
631 fossil_free(zLabel);
632 document_emit_js(/*for optional pikchr support*/);
633 style_finish_page();
634 }
635 }
@@ -1331,11 +1331,11 @@
1331 CX("<div id='fossil-status-bar' "
1332 "title='Status message area. Double-click to clear them.'>"
1333 "Status messages will go here.</div>\n"
1334 /* will be moved into the tab container via JS */);
1335
1336 CX("<div id='wikiedit-edit-status'>"
1337 "<span class='name'></span>"
1338 "<span class='links'></span>"
1339 "</div>");
1340
1341 /* Main tab container... */
1342
--- src/winfile.c
+++ src/winfile.c
@@ -451,6 +451,74 @@
451451
i = j;
452452
}
453453
fossil_free(zBuf);
454454
return zRes;
455455
}
456
+
457
+/* Return the unique identifier (UID) for a file, made up of the file identifier
458
+** (equal to "inode" for Unix-style file systems) plus the volume serial number.
459
+** Call the GetFileInformationByHandleEx() function on Windows Vista, and resort
460
+** to the GetFileInformationByHandle() function on Windows XP. The result string
461
+** is allocated by mprintf(), or NULL on failure.
462
+*/
463
+char *win32_file_id(
464
+ const char *zFileName
465
+){
466
+ static FARPROC fnGetFileInformationByHandleEx;
467
+ static int loaded_fnGetFileInformationByHandleEx;
468
+ wchar_t *wzFileName = fossil_utf8_to_path(zFileName,0);
469
+ HANDLE hFile;
470
+ char *zFileId = 0;
471
+ hFile = CreateFileW(
472
+ wzFileName,
473
+ 0,
474
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
475
+ NULL,
476
+ OPEN_EXISTING,
477
+ FILE_FLAG_BACKUP_SEMANTICS,
478
+ NULL);
479
+ if( hFile!=INVALID_HANDLE_VALUE ){
480
+ BY_HANDLE_FILE_INFORMATION fi;
481
+ struct { /* FILE_ID_INFO from <winbase.h> */
482
+ u64 VolumeSerialNumber;
483
+ unsigned char FileId[16];
484
+ } fi2;
485
+ if( !loaded_fnGetFileInformationByHandleEx ){
486
+ fnGetFileInformationByHandleEx = GetProcAddress(
487
+ GetModuleHandleA("kernel32"),"GetFileInformationByHandleEx");
488
+ loaded_fnGetFileInformationByHandleEx = 1;
489
+ }
490
+ if( fnGetFileInformationByHandleEx ){
491
+ if( fnGetFileInformationByHandleEx(
492
+ hFile,/*FileIdInfo*/0x12,&fi2,sizeof(fi2)) ){
493
+ zFileId = mprintf(
494
+ "%016llx/"
495
+ "%02x%02x%02x%02x%02x%02x%02x%02x"
496
+ "%02x%02x%02x%02x%02x%02x%02x%02x",
497
+ fi2.VolumeSerialNumber,
498
+ fi2.FileId[15], fi2.FileId[14],
499
+ fi2.FileId[13], fi2.FileId[12],
500
+ fi2.FileId[11], fi2.FileId[10],
501
+ fi2.FileId[9], fi2.FileId[8],
502
+ fi2.FileId[7], fi2.FileId[6],
503
+ fi2.FileId[5], fi2.FileId[4],
504
+ fi2.FileId[3], fi2.FileId[2],
505
+ fi2.FileId[1], fi2.FileId[0]);
506
+ }
507
+ }
508
+ if( zFileId==0 ){
509
+ if( GetFileInformationByHandle(hFile,&fi) ){
510
+ ULARGE_INTEGER FileId = {
511
+ /*.LowPart = */ fi.nFileIndexLow,
512
+ /*.HighPart = */ fi.nFileIndexHigh
513
+ };
514
+ zFileId = mprintf(
515
+ "%08x/%016llx",
516
+ fi.dwVolumeSerialNumber,(u64)FileId.QuadPart);
517
+ }
518
+ }
519
+ CloseHandle(hFile);
520
+ }
521
+ fossil_path_free(wzFileName);
522
+ return zFileId;
523
+}
456524
#endif /* _WIN32 -- This code is for win32 only */
457525
--- src/winfile.c
+++ src/winfile.c
@@ -451,6 +451,74 @@
451 i = j;
452 }
453 fossil_free(zBuf);
454 return zRes;
455 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
456 #endif /* _WIN32 -- This code is for win32 only */
457
--- src/winfile.c
+++ src/winfile.c
@@ -451,6 +451,74 @@
451 i = j;
452 }
453 fossil_free(zBuf);
454 return zRes;
455 }
456
457 /* Return the unique identifier (UID) for a file, made up of the file identifier
458 ** (equal to "inode" for Unix-style file systems) plus the volume serial number.
459 ** Call the GetFileInformationByHandleEx() function on Windows Vista, and resort
460 ** to the GetFileInformationByHandle() function on Windows XP. The result string
461 ** is allocated by mprintf(), or NULL on failure.
462 */
463 char *win32_file_id(
464 const char *zFileName
465 ){
466 static FARPROC fnGetFileInformationByHandleEx;
467 static int loaded_fnGetFileInformationByHandleEx;
468 wchar_t *wzFileName = fossil_utf8_to_path(zFileName,0);
469 HANDLE hFile;
470 char *zFileId = 0;
471 hFile = CreateFileW(
472 wzFileName,
473 0,
474 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
475 NULL,
476 OPEN_EXISTING,
477 FILE_FLAG_BACKUP_SEMANTICS,
478 NULL);
479 if( hFile!=INVALID_HANDLE_VALUE ){
480 BY_HANDLE_FILE_INFORMATION fi;
481 struct { /* FILE_ID_INFO from <winbase.h> */
482 u64 VolumeSerialNumber;
483 unsigned char FileId[16];
484 } fi2;
485 if( !loaded_fnGetFileInformationByHandleEx ){
486 fnGetFileInformationByHandleEx = GetProcAddress(
487 GetModuleHandleA("kernel32"),"GetFileInformationByHandleEx");
488 loaded_fnGetFileInformationByHandleEx = 1;
489 }
490 if( fnGetFileInformationByHandleEx ){
491 if( fnGetFileInformationByHandleEx(
492 hFile,/*FileIdInfo*/0x12,&fi2,sizeof(fi2)) ){
493 zFileId = mprintf(
494 "%016llx/"
495 "%02x%02x%02x%02x%02x%02x%02x%02x"
496 "%02x%02x%02x%02x%02x%02x%02x%02x",
497 fi2.VolumeSerialNumber,
498 fi2.FileId[15], fi2.FileId[14],
499 fi2.FileId[13], fi2.FileId[12],
500 fi2.FileId[11], fi2.FileId[10],
501 fi2.FileId[9], fi2.FileId[8],
502 fi2.FileId[7], fi2.FileId[6],
503 fi2.FileId[5], fi2.FileId[4],
504 fi2.FileId[3], fi2.FileId[2],
505 fi2.FileId[1], fi2.FileId[0]);
506 }
507 }
508 if( zFileId==0 ){
509 if( GetFileInformationByHandle(hFile,&fi) ){
510 ULARGE_INTEGER FileId = {
511 /*.LowPart = */ fi.nFileIndexLow,
512 /*.HighPart = */ fi.nFileIndexHigh
513 };
514 zFileId = mprintf(
515 "%08x/%016llx",
516 fi.dwVolumeSerialNumber,(u64)FileId.QuadPart);
517 }
518 }
519 CloseHandle(hFile);
520 }
521 fossil_path_free(wzFileName);
522 return zFileId;
523 }
524 #endif /* _WIN32 -- This code is for win32 only */
525
--- tools/makemake.tcl
+++ tools/makemake.tcl
@@ -209,10 +209,11 @@
209209
# Additional resource files that get built into the executable.
210210
# These paths are all resolved from the src/ directory, so must
211211
# be relative to that.
212212
set extra_files {
213213
diff.tcl
214
+ merge.tcl
214215
markdown.md
215216
wiki.wiki
216217
*.js
217218
default.css
218219
style.*.css
219220
--- tools/makemake.tcl
+++ tools/makemake.tcl
@@ -209,10 +209,11 @@
209 # Additional resource files that get built into the executable.
210 # These paths are all resolved from the src/ directory, so must
211 # be relative to that.
212 set extra_files {
213 diff.tcl
 
214 markdown.md
215 wiki.wiki
216 *.js
217 default.css
218 style.*.css
219
--- tools/makemake.tcl
+++ tools/makemake.tcl
@@ -209,10 +209,11 @@
209 # Additional resource files that get built into the executable.
210 # These paths are all resolved from the src/ directory, so must
211 # be relative to that.
212 set extra_files {
213 diff.tcl
214 merge.tcl
215 markdown.md
216 wiki.wiki
217 *.js
218 default.css
219 style.*.css
220
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -634,10 +634,11 @@
634634
$(SRCDIR)/hbmenu.js \
635635
$(SRCDIR)/href.js \
636636
$(SRCDIR)/login.js \
637637
$(SRCDIR)/markdown.md \
638638
$(SRCDIR)/menu.js \
639
+ $(SRCDIR)/merge.tcl \
639640
$(SRCDIR)/scroll.js \
640641
$(SRCDIR)/skin.js \
641642
$(SRCDIR)/sorttable.js \
642643
$(SRCDIR)/sounds/0.wav \
643644
$(SRCDIR)/sounds/1.wav \
644645
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -634,10 +634,11 @@
634 $(SRCDIR)/hbmenu.js \
635 $(SRCDIR)/href.js \
636 $(SRCDIR)/login.js \
637 $(SRCDIR)/markdown.md \
638 $(SRCDIR)/menu.js \
 
639 $(SRCDIR)/scroll.js \
640 $(SRCDIR)/skin.js \
641 $(SRCDIR)/sorttable.js \
642 $(SRCDIR)/sounds/0.wav \
643 $(SRCDIR)/sounds/1.wav \
644
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -634,10 +634,11 @@
634 $(SRCDIR)/hbmenu.js \
635 $(SRCDIR)/href.js \
636 $(SRCDIR)/login.js \
637 $(SRCDIR)/markdown.md \
638 $(SRCDIR)/menu.js \
639 $(SRCDIR)/merge.tcl \
640 $(SRCDIR)/scroll.js \
641 $(SRCDIR)/skin.js \
642 $(SRCDIR)/sorttable.js \
643 $(SRCDIR)/sounds/0.wav \
644 $(SRCDIR)/sounds/1.wav \
645
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -592,10 +592,11 @@
592592
"$(SRCDIR)\hbmenu.js" \
593593
"$(SRCDIR)\href.js" \
594594
"$(SRCDIR)\login.js" \
595595
"$(SRCDIR)\markdown.md" \
596596
"$(SRCDIR)\menu.js" \
597
+ "$(SRCDIR)\merge.tcl" \
597598
"$(SRCDIR)\scroll.js" \
598599
"$(SRCDIR)\skin.js" \
599600
"$(SRCDIR)\sorttable.js" \
600601
"$(SRCDIR)\sounds\0.wav" \
601602
"$(SRCDIR)\sounds\1.wav" \
@@ -1222,10 +1223,11 @@
12221223
echo "$(SRCDIR)\hbmenu.js" >> $@
12231224
echo "$(SRCDIR)\href.js" >> $@
12241225
echo "$(SRCDIR)\login.js" >> $@
12251226
echo "$(SRCDIR)\markdown.md" >> $@
12261227
echo "$(SRCDIR)\menu.js" >> $@
1228
+ echo "$(SRCDIR)\merge.tcl" >> $@
12271229
echo "$(SRCDIR)\scroll.js" >> $@
12281230
echo "$(SRCDIR)\skin.js" >> $@
12291231
echo "$(SRCDIR)\sorttable.js" >> $@
12301232
echo "$(SRCDIR)\sounds/0.wav" >> $@
12311233
echo "$(SRCDIR)\sounds/1.wav" >> $@
12321234
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -592,10 +592,11 @@
592 "$(SRCDIR)\hbmenu.js" \
593 "$(SRCDIR)\href.js" \
594 "$(SRCDIR)\login.js" \
595 "$(SRCDIR)\markdown.md" \
596 "$(SRCDIR)\menu.js" \
 
597 "$(SRCDIR)\scroll.js" \
598 "$(SRCDIR)\skin.js" \
599 "$(SRCDIR)\sorttable.js" \
600 "$(SRCDIR)\sounds\0.wav" \
601 "$(SRCDIR)\sounds\1.wav" \
@@ -1222,10 +1223,11 @@
1222 echo "$(SRCDIR)\hbmenu.js" >> $@
1223 echo "$(SRCDIR)\href.js" >> $@
1224 echo "$(SRCDIR)\login.js" >> $@
1225 echo "$(SRCDIR)\markdown.md" >> $@
1226 echo "$(SRCDIR)\menu.js" >> $@
 
1227 echo "$(SRCDIR)\scroll.js" >> $@
1228 echo "$(SRCDIR)\skin.js" >> $@
1229 echo "$(SRCDIR)\sorttable.js" >> $@
1230 echo "$(SRCDIR)\sounds/0.wav" >> $@
1231 echo "$(SRCDIR)\sounds/1.wav" >> $@
1232
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -592,10 +592,11 @@
592 "$(SRCDIR)\hbmenu.js" \
593 "$(SRCDIR)\href.js" \
594 "$(SRCDIR)\login.js" \
595 "$(SRCDIR)\markdown.md" \
596 "$(SRCDIR)\menu.js" \
597 "$(SRCDIR)\merge.tcl" \
598 "$(SRCDIR)\scroll.js" \
599 "$(SRCDIR)\skin.js" \
600 "$(SRCDIR)\sorttable.js" \
601 "$(SRCDIR)\sounds\0.wav" \
602 "$(SRCDIR)\sounds\1.wav" \
@@ -1222,10 +1223,11 @@
1223 echo "$(SRCDIR)\hbmenu.js" >> $@
1224 echo "$(SRCDIR)\href.js" >> $@
1225 echo "$(SRCDIR)\login.js" >> $@
1226 echo "$(SRCDIR)\markdown.md" >> $@
1227 echo "$(SRCDIR)\menu.js" >> $@
1228 echo "$(SRCDIR)\merge.tcl" >> $@
1229 echo "$(SRCDIR)\scroll.js" >> $@
1230 echo "$(SRCDIR)\skin.js" >> $@
1231 echo "$(SRCDIR)\sorttable.js" >> $@
1232 echo "$(SRCDIR)\sounds/0.wav" >> $@
1233 echo "$(SRCDIR)\sounds/1.wav" >> $@
1234
+16 -1
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,10 +1,25 @@
11
<title>Change Log</title>
22
33
<h2 id='v2_26'>Changes for version 2.26 (pending)</h2>
44
5
- * <i>(pending)</i>
5
+ * Enhanced the --from option on "[/help?cmd=diff|fossil diff]" so that
6
+ it optionally accepts a directory name as its argument, and uses files
7
+ under that directory as the baseline for the diff.
8
+ * Added the [/help?cmd=/ckout|/ckout web page] to provide information
9
+ about pending changes in a working check-out
10
+ * The [/help?cmd=ui|fossil ui] command defaults to using the
11
+ [/help?cmd=/ckout|/ckout page] as its start page. Or, if the
12
+ "--from PATH" option is present, the default start page becomes
13
+ "/ckout?exbase=PATH".
14
+ * Added the [/help?cmd=merge-info|fossil merge-info] command and especially
15
+ the --tk option to that command, to provide analysis of the most recent
16
+ merge or update operation.
17
+ * Issue a warning if a user tries to commit on a check-in where the
18
+ branch has been changed.
19
+ * When a merge conflict occurs, a new section is added to the conflict
20
+ text that shows Fossil's suggested resolution to the conflict.
621
722
<h2 id='v2_25'>Changes for version 2.25 (2024-11-06)</h2>
823
924
* The "[/help?cmd=ui|fossil ui /]" command now works even for repositories
1025
that have non-ASCII filenames
1126
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,10 +1,25 @@
1 <title>Change Log</title>
2
3 <h2 id='v2_26'>Changes for version 2.26 (pending)</h2>
4
5 * <i>(pending)</i>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
7 <h2 id='v2_25'>Changes for version 2.25 (2024-11-06)</h2>
8
9 * The "[/help?cmd=ui|fossil ui /]" command now works even for repositories
10 that have non-ASCII filenames
11
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,10 +1,25 @@
1 <title>Change Log</title>
2
3 <h2 id='v2_26'>Changes for version 2.26 (pending)</h2>
4
5 * Enhanced the --from option on "[/help?cmd=diff|fossil diff]" so that
6 it optionally accepts a directory name as its argument, and uses files
7 under that directory as the baseline for the diff.
8 * Added the [/help?cmd=/ckout|/ckout web page] to provide information
9 about pending changes in a working check-out
10 * The [/help?cmd=ui|fossil ui] command defaults to using the
11 [/help?cmd=/ckout|/ckout page] as its start page. Or, if the
12 "--from PATH" option is present, the default start page becomes
13 "/ckout?exbase=PATH".
14 * Added the [/help?cmd=merge-info|fossil merge-info] command and especially
15 the --tk option to that command, to provide analysis of the most recent
16 merge or update operation.
17 * Issue a warning if a user tries to commit on a check-in where the
18 branch has been changed.
19 * When a merge conflict occurs, a new section is added to the conflict
20 text that shows Fossil's suggested resolution to the conflict.
21
22 <h2 id='v2_25'>Changes for version 2.25 (2024-11-06)</h2>
23
24 * The "[/help?cmd=ui|fossil ui /]" command now works even for repositories
25 that have non-ASCII filenames
26

Keyboard Shortcuts

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