erdbpro 2.4.5 → 2.5.2-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -8
- package/dist/assets/{index-DgkcaXbc.js → index-DWOX2re7.js} +332 -332
- package/dist/index.html +1 -1
- package/dist-server/index.js +94 -94
- package/dist-server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/better_sqlite3/src/better_sqlite3.o.d.raw +82 -0
- package/dist-server/node_modules/better-sqlite3/build/Release/.deps/Release/obj.target/sqlite3/gen/sqlite3/sqlite3.o.d +4 -0
- package/dist-server/node_modules/better-sqlite3/build/Release/.deps/Release/sqlite3.a.d +1 -0
- package/dist-server/node_modules/better-sqlite3/build/Release/better_sqlite3.node +0 -0
- package/dist-server/node_modules/better-sqlite3/build/Release/obj/gen/sqlite3/sqlite3.c +692 -176
- package/dist-server/node_modules/better-sqlite3/build/Release/obj/gen/sqlite3/sqlite3.h +17 -5
- package/dist-server/node_modules/better-sqlite3/build/Release/obj.target/sqlite3/gen/sqlite3/sqlite3.o +0 -0
- package/dist-server/node_modules/better-sqlite3/build/Release/sqlite3.a +0 -0
- package/dist-server/node_modules/better-sqlite3/deps/download.sh +1 -1
- package/dist-server/node_modules/better-sqlite3/deps/sqlite3/sqlite3.c +692 -176
- package/dist-server/node_modules/better-sqlite3/deps/sqlite3/sqlite3.h +17 -5
- package/dist-server/node_modules/better-sqlite3/package.json +1 -1
- package/dist-server/node_modules/better-sqlite3/src/better_sqlite3.cpp +1 -1
- package/dist-server/node_modules/better-sqlite3/src/util/helpers.cpp +1 -1
- package/dist-server/node_modules/better-sqlite3/src/util/macros.cpp +8 -1
- package/menubar/ERDBProTray.app/Contents/Info.plist +20 -0
- package/menubar/ERDBProTray.app/Contents/MacOS/ERDBProTray +0 -0
- package/menubar/ERDBProTray.swift +129 -0
- package/menubar/erdbpro-tray +0 -0
- package/menubar/icon.svg +14 -0
- package/menubar/launch.sh +4 -0
- package/menubar/tray.sh +59 -0
- package/package.json +10 -8
- package/src/cli.mjs +197 -28
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/******************************************************************************
|
|
2
2
|
** This file is an amalgamation of many separate C source files from SQLite
|
|
3
|
-
** version 3.53.
|
|
3
|
+
** version 3.53.2. By combining all the individual C code files into this
|
|
4
4
|
** single large file, the entire code can be compiled as a single translation
|
|
5
5
|
** unit. This allows many compilers to do optimizations that would not be
|
|
6
6
|
** possible if the files were compiled separately. Performance improvements
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
** separate file. This file contains only code for the core SQLite library.
|
|
19
19
|
**
|
|
20
20
|
** The content in this amalgamation comes from Fossil check-in
|
|
21
|
-
**
|
|
21
|
+
** d6e03d8c777cfa2d35e3b60d8ec3e0187f3e with changes in files:
|
|
22
22
|
**
|
|
23
23
|
**
|
|
24
24
|
*/
|
|
@@ -468,12 +468,12 @@ extern "C" {
|
|
|
468
468
|
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
|
469
469
|
** [sqlite_version()] and [sqlite_source_id()].
|
|
470
470
|
*/
|
|
471
|
-
#define SQLITE_VERSION "3.53.
|
|
472
|
-
#define SQLITE_VERSION_NUMBER
|
|
473
|
-
#define SQLITE_SOURCE_ID "2026-
|
|
471
|
+
#define SQLITE_VERSION "3.53.2"
|
|
472
|
+
#define SQLITE_VERSION_NUMBER 3053002
|
|
473
|
+
#define SQLITE_SOURCE_ID "2026-06-03 19:12:13 d6e03d8c777cfa2d35e3b60d8ec3e0187f3e9f99d8e2ee9cac695fd6fcdf1a24"
|
|
474
474
|
#define SQLITE_SCM_BRANCH "branch-3.53"
|
|
475
|
-
#define SQLITE_SCM_TAGS "release version-3.53.
|
|
476
|
-
#define SQLITE_SCM_DATETIME "2026-
|
|
475
|
+
#define SQLITE_SCM_TAGS "release version-3.53.2"
|
|
476
|
+
#define SQLITE_SCM_DATETIME "2026-06-03T19:12:13.350Z"
|
|
477
477
|
|
|
478
478
|
/*
|
|
479
479
|
** CAPI3REF: Run-Time Library Version Numbers
|
|
@@ -13175,11 +13175,23 @@ SQLITE_API int sqlite3changeset_apply_v3(
|
|
|
13175
13175
|
** database behave as if they were declared with "ON UPDATE NO ACTION ON
|
|
13176
13176
|
** DELETE NO ACTION", even if they are actually CASCADE, RESTRICT, SET NULL
|
|
13177
13177
|
** or SET DEFAULT.
|
|
13178
|
+
**
|
|
13179
|
+
** <dt>SQLITE_CHANGESETAPPLY_NOUPDATELOOP <dd>
|
|
13180
|
+
** Sometimes, a changeset contains two or more update statements such that
|
|
13181
|
+
** although after applying all updates the database will contain no
|
|
13182
|
+
** constraint violations, no single update can be applied before the others.
|
|
13183
|
+
** The simplest example of this is a pair of UPDATEs that have "swapped"
|
|
13184
|
+
** two column values with a UNIQUE constraint.
|
|
13185
|
+
** <p>
|
|
13186
|
+
** Usually, sqlite3changeset_apply() and similar functions work hard to try
|
|
13187
|
+
** to find a way to apply such a changeset. However, if this flag is set,
|
|
13188
|
+
** then all such updates are considered CONSTRAINT conflicts.
|
|
13178
13189
|
*/
|
|
13179
13190
|
#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
|
|
13180
13191
|
#define SQLITE_CHANGESETAPPLY_INVERT 0x0002
|
|
13181
13192
|
#define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004
|
|
13182
13193
|
#define SQLITE_CHANGESETAPPLY_FKNOACTION 0x0008
|
|
13194
|
+
#define SQLITE_CHANGESETAPPLY_NOUPDATELOOP 0x0010
|
|
13183
13195
|
|
|
13184
13196
|
/*
|
|
13185
13197
|
** CAPI3REF: Constants Passed To The Conflict Handler
|
|
@@ -22449,7 +22461,15 @@ SQLITE_PRIVATE void sqlite3AlterFunctions(void);
|
|
|
22449
22461
|
SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
|
|
22450
22462
|
SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
|
|
22451
22463
|
SQLITE_PRIVATE void sqlite3AlterDropConstraint(Parse*,SrcList*,Token*,Token*);
|
|
22452
|
-
SQLITE_PRIVATE void sqlite3AlterAddConstraint(
|
|
22464
|
+
SQLITE_PRIVATE void sqlite3AlterAddConstraint(
|
|
22465
|
+
Parse *pParse, /* Parse context */
|
|
22466
|
+
SrcList *pSrc, /* Table to add constraint to */
|
|
22467
|
+
Token *pFirst, /* First token of new constraint */
|
|
22468
|
+
Token *pName, /* Name of new constraint. NULL if name omitted. */
|
|
22469
|
+
const char *zExpr, /* Text of CHECK expression */
|
|
22470
|
+
int nExpr, /* Size of pExpr in bytes */
|
|
22471
|
+
Expr *pExpr /* The parsed CHECK expression */
|
|
22472
|
+
);
|
|
22453
22473
|
SQLITE_PRIVATE void sqlite3AlterSetNotNull(Parse*, SrcList*, Token*, Token*);
|
|
22454
22474
|
SQLITE_PRIVATE i64 sqlite3GetToken(const unsigned char *, int *);
|
|
22455
22475
|
SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
|
|
@@ -33258,8 +33278,8 @@ SQLITE_API void sqlite3_str_vappendf(
|
|
|
33258
33278
|
** all control characters, and for backslash itself.
|
|
33259
33279
|
** For %#Q, do the same but only if there is at least
|
|
33260
33280
|
** one control character. */
|
|
33261
|
-
|
|
33262
|
-
|
|
33281
|
+
i64 nBack = 0;
|
|
33282
|
+
i64 nCtrl = 0;
|
|
33263
33283
|
for(k=0; k<i; k++){
|
|
33264
33284
|
if( escarg[k]=='\\' ){
|
|
33265
33285
|
nBack++;
|
|
@@ -45308,9 +45328,9 @@ static int unixShmMap(
|
|
|
45308
45328
|
nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap;
|
|
45309
45329
|
|
|
45310
45330
|
if( pShmNode->nRegion<nReqRegion ){
|
|
45311
|
-
char **apNew;
|
|
45312
|
-
|
|
45313
|
-
struct stat sStat;
|
|
45331
|
+
char **apNew; /* New apRegion[] array */
|
|
45332
|
+
i64 nByte = nReqRegion*(i64)szRegion; /* Minimum required file size */
|
|
45333
|
+
struct stat sStat; /* Used by fstat() */
|
|
45314
45334
|
|
|
45315
45335
|
pShmNode->szRegion = szRegion;
|
|
45316
45336
|
|
|
@@ -45341,7 +45361,7 @@ static int unixShmMap(
|
|
|
45341
45361
|
*/
|
|
45342
45362
|
else{
|
|
45343
45363
|
static const int pgsz = 4096;
|
|
45344
|
-
|
|
45364
|
+
i64 iPg;
|
|
45345
45365
|
|
|
45346
45366
|
/* Write to the last byte of each newly allocated or extended page */
|
|
45347
45367
|
assert( (nByte % pgsz)==0 );
|
|
@@ -45367,8 +45387,8 @@ static int unixShmMap(
|
|
|
45367
45387
|
}
|
|
45368
45388
|
pShmNode->apRegion = apNew;
|
|
45369
45389
|
while( pShmNode->nRegion<nReqRegion ){
|
|
45370
|
-
|
|
45371
|
-
|
|
45390
|
+
i64 nMap = (i64)szRegion*(i64)nShmPerMap;
|
|
45391
|
+
i64 i;
|
|
45372
45392
|
void *pMem;
|
|
45373
45393
|
if( pShmNode->hShm>=0 ){
|
|
45374
45394
|
pMem = osMmap(0, nMap,
|
|
@@ -53342,7 +53362,7 @@ static int winShmMap(
|
|
|
53342
53362
|
if( pShmNode->nRegion<=iRegion ){
|
|
53343
53363
|
HANDLE hShared = pShmNode->hSharedShm;
|
|
53344
53364
|
struct ShmRegion *apNew; /* New aRegion[] array */
|
|
53345
|
-
|
|
53365
|
+
i64 nByte = ((i64)iRegion+1)*(i64)szRegion; /* Minimum file size */
|
|
53346
53366
|
sqlite3_int64 sz; /* Current size of wal-index file */
|
|
53347
53367
|
|
|
53348
53368
|
pShmNode->szRegion = szRegion;
|
|
@@ -53373,7 +53393,7 @@ static int winShmMap(
|
|
|
53373
53393
|
|
|
53374
53394
|
/* Map the requested memory region into this processes address space. */
|
|
53375
53395
|
apNew = (struct ShmRegion*)sqlite3_realloc64(
|
|
53376
|
-
pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
|
|
53396
|
+
pShmNode->aRegion, ((i64)iRegion+1)*sizeof(apNew[0])
|
|
53377
53397
|
);
|
|
53378
53398
|
if( !apNew ){
|
|
53379
53399
|
rc = SQLITE_IOERR_NOMEM_BKPT;
|
|
@@ -53395,15 +53415,14 @@ static int winShmMap(
|
|
|
53395
53415
|
#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA
|
|
53396
53416
|
hMap = osCreateFileMappingA(hShared, NULL, protect, 0, nByte, NULL);
|
|
53397
53417
|
#endif
|
|
53398
|
-
|
|
53399
|
-
OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n",
|
|
53418
|
+
OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%lld, rc=%s\n",
|
|
53400
53419
|
osGetCurrentProcessId(), pShmNode->nRegion, nByte,
|
|
53401
53420
|
hMap ? "ok" : "failed"));
|
|
53402
53421
|
if( hMap ){
|
|
53403
|
-
|
|
53422
|
+
i64 iOffset = pShmNode->nRegion*szRegion;
|
|
53404
53423
|
int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
|
|
53405
53424
|
pMap = osMapViewOfFile(hMap, flags,
|
|
53406
|
-
0, iOffset - iOffsetShift, szRegion + iOffsetShift
|
|
53425
|
+
0, iOffset - iOffsetShift, (i64)szRegion + iOffsetShift
|
|
53407
53426
|
);
|
|
53408
53427
|
OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n",
|
|
53409
53428
|
osGetCurrentProcessId(), pShmNode->nRegion, iOffset,
|
|
@@ -53425,7 +53444,7 @@ static int winShmMap(
|
|
|
53425
53444
|
|
|
53426
53445
|
shmpage_out:
|
|
53427
53446
|
if( pShmNode->nRegion>iRegion ){
|
|
53428
|
-
|
|
53447
|
+
i64 iOffset = (i64)iRegion*(i64)szRegion;
|
|
53429
53448
|
int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
|
|
53430
53449
|
char *p = (char *)pShmNode->aRegion[iRegion].pMap;
|
|
53431
53450
|
*pp = (void *)&p[iOffsetShift];
|
|
@@ -62153,7 +62172,7 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){
|
|
|
62153
62172
|
if( rc!=SQLITE_OK ) goto delsuper_out;
|
|
62154
62173
|
nSuperPtr = 1 + (i64)pVfs->mxPathname;
|
|
62155
62174
|
assert( nSuperJournal>=0 && nSuperPtr>0 );
|
|
62156
|
-
zFree = sqlite3Malloc(4 + nSuperJournal + nSuperPtr + 2);
|
|
62175
|
+
zFree = sqlite3Malloc(4 + nSuperJournal + 2 + nSuperPtr + 2);
|
|
62157
62176
|
if( !zFree ){
|
|
62158
62177
|
rc = SQLITE_NOMEM_BKPT;
|
|
62159
62178
|
goto delsuper_out;
|
|
@@ -62414,10 +62433,10 @@ static int pager_playback(Pager *pPager, int isHot){
|
|
|
62414
62433
|
**
|
|
62415
62434
|
** TODO: Technically the following is an error because it assumes that
|
|
62416
62435
|
** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that
|
|
62417
|
-
** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c,
|
|
62436
|
+
** ((pPager->pageSize+8) >= pPager->pVfs->mxPathname+1). Using os_unix.c,
|
|
62418
62437
|
** mxPathname is 512, which is the same as the minimum allowable value
|
|
62419
|
-
** for pageSize.
|
|
62420
|
-
*/
|
|
62438
|
+
** for pageSize, and so this assumption holds. But it might not for some
|
|
62439
|
+
** custom VFS. */
|
|
62421
62440
|
zSuper = pPager->pTmpSpace;
|
|
62422
62441
|
rc = readSuperJournal(pPager->jfd, zSuper, 1+(i64)pPager->pVfs->mxPathname);
|
|
62423
62442
|
if( rc==SQLITE_OK && zSuper[0] ){
|
|
@@ -78307,7 +78326,9 @@ static int accessPayload(
|
|
|
78307
78326
|
** means "not yet known" (the cache is lazily populated).
|
|
78308
78327
|
*/
|
|
78309
78328
|
if( (pCur->curFlags & BTCF_ValidOvfl)==0 ){
|
|
78310
|
-
|
|
78329
|
+
i64 nOvfl = pCur->info.nPayload;
|
|
78330
|
+
testcase( nOvfl - pCur->info.nLocal + ovflSize - 1 > 0xffffffffU );
|
|
78331
|
+
nOvfl = (nOvfl - pCur->info.nLocal + ovflSize-1)/ovflSize;
|
|
78311
78332
|
if( pCur->aOverflow==0
|
|
78312
78333
|
|| nOvfl*(int)sizeof(Pgno) > sqlite3MallocSize(pCur->aOverflow)
|
|
78313
78334
|
){
|
|
@@ -78412,6 +78433,12 @@ static int accessPayload(
|
|
|
78412
78433
|
(eOp==0 ? PAGER_GET_READONLY : 0)
|
|
78413
78434
|
);
|
|
78414
78435
|
if( rc==SQLITE_OK ){
|
|
78436
|
+
if( eOp!=0
|
|
78437
|
+
&& (sqlite3PagerPageRefcount(pDbPage)!=1
|
|
78438
|
+
|| NEVER(((MemPage*)sqlite3PagerGetExtra(pDbPage))->isInit)) ){
|
|
78439
|
+
sqlite3PagerUnref(pDbPage);
|
|
78440
|
+
return SQLITE_CORRUPT_PAGE(pPage);
|
|
78441
|
+
}
|
|
78415
78442
|
aPayload = sqlite3PagerGetData(pDbPage);
|
|
78416
78443
|
nextPage = get4byte(aPayload);
|
|
78417
78444
|
rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage);
|
|
@@ -111100,6 +111127,7 @@ static int lookupName(
|
|
|
111100
111127
|
pExpr->op = TK_FUNCTION;
|
|
111101
111128
|
pExpr->u.zToken = "coalesce";
|
|
111102
111129
|
pExpr->x.pList = pFJMatch;
|
|
111130
|
+
pExpr->affExpr = SQLITE_AFF_DEFER;
|
|
111103
111131
|
cnt = 1;
|
|
111104
111132
|
goto lookupname_end;
|
|
111105
111133
|
}else{
|
|
@@ -111268,6 +111296,26 @@ static int exprProbability(Expr *p){
|
|
|
111268
111296
|
return (int)(r*134217728.0);
|
|
111269
111297
|
}
|
|
111270
111298
|
|
|
111299
|
+
/*
|
|
111300
|
+
** Set the EP_SubtArg property on every expression inside of
|
|
111301
|
+
** pList. If any subexpression is actually a subquery, then
|
|
111302
|
+
** also set the EP_SubtArg property on the first result-set
|
|
111303
|
+
** column of that subquery.
|
|
111304
|
+
*/
|
|
111305
|
+
static SQLITE_NOINLINE void resolveSetExprSubtypeArg(ExprList *pList){
|
|
111306
|
+
int nn, ii;
|
|
111307
|
+
nn = pList ? pList->nExpr : 0;
|
|
111308
|
+
for(ii=0; ii<nn; ii++){
|
|
111309
|
+
Expr *pExpr = pList->a[ii].pExpr;
|
|
111310
|
+
ExprSetProperty(pExpr, EP_SubtArg);
|
|
111311
|
+
if( pExpr->op==TK_SELECT ){
|
|
111312
|
+
assert( ExprUseXSelect(pExpr) );
|
|
111313
|
+
assert( pExpr->x.pSelect!=0 );
|
|
111314
|
+
resolveSetExprSubtypeArg(pExpr->x.pSelect->pEList);
|
|
111315
|
+
}
|
|
111316
|
+
}
|
|
111317
|
+
}
|
|
111318
|
+
|
|
111271
111319
|
/*
|
|
111272
111320
|
** This routine is callback for sqlite3WalkExpr().
|
|
111273
111321
|
**
|
|
@@ -111512,10 +111560,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
|
|
111512
111560
|
if( (pDef->funcFlags & SQLITE_SUBTYPE)
|
|
111513
111561
|
|| ExprHasProperty(pExpr, EP_SubtArg)
|
|
111514
111562
|
){
|
|
111515
|
-
|
|
111516
|
-
for(ii=0; ii<n; ii++){
|
|
111517
|
-
ExprSetProperty(pList->a[ii].pExpr, EP_SubtArg);
|
|
111518
|
-
}
|
|
111563
|
+
resolveSetExprSubtypeArg(pList);
|
|
111519
111564
|
}
|
|
111520
111565
|
|
|
111521
111566
|
if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){
|
|
@@ -116910,7 +116955,16 @@ static void sqlite3ExprCodeIN(
|
|
|
116910
116955
|
CollSeq *pColl;
|
|
116911
116956
|
int r3 = sqlite3GetTempReg(pParse);
|
|
116912
116957
|
p = sqlite3VectorFieldSubexpr(pLeft, i);
|
|
116913
|
-
|
|
116958
|
+
if( ExprUseXSelect(pExpr) ){
|
|
116959
|
+
Expr *pRhs = pExpr->x.pSelect->pEList->a[i].pExpr;
|
|
116960
|
+
pColl = sqlite3BinaryCompareCollSeq(pParse, p, pRhs);
|
|
116961
|
+
}else{
|
|
116962
|
+
/* If the RHS of the IN(...) expression are scalar expressions, do
|
|
116963
|
+
** not consider their collation sequences. The documentation says
|
|
116964
|
+
** "The collating sequence used for expressions of the form "x IN (y, z,
|
|
116965
|
+
** ...)" is the collating sequence of x.". */
|
|
116966
|
+
pColl = sqlite3ExprCollSeq(pParse, p);
|
|
116967
|
+
}
|
|
116914
116968
|
sqlite3VdbeAddOp3(v, OP_Column, iTab, i, r3);
|
|
116915
116969
|
sqlite3VdbeAddOp4(v, OP_Ne, rLhs+i, destNotNull, r3,
|
|
116916
116970
|
(void*)pColl, P4_COLLSEQ);
|
|
@@ -117333,26 +117387,37 @@ static int exprCodeInlineFunction(
|
|
|
117333
117387
|
}
|
|
117334
117388
|
|
|
117335
117389
|
/*
|
|
117336
|
-
** Expression Node callback for sqlite3ExprCanReturnSubtype().
|
|
117390
|
+
** Expression Node callback for sqlite3ExprCanReturnSubtype(). If
|
|
117391
|
+
** pExpr is able to return a subtype, set pWalker->eCode and abort
|
|
117392
|
+
** the search. If pExpr can never return a subtype, prune search.
|
|
117393
|
+
**
|
|
117394
|
+
** The only expressions that can return a subtype are:
|
|
117395
|
+
**
|
|
117396
|
+
** 1. A function
|
|
117397
|
+
** 2. The no-op "+" operator
|
|
117398
|
+
** 3. A CASE...END expression
|
|
117399
|
+
** 4. A CAST() expression
|
|
117400
|
+
** 5. A "expr COLLATE colseq" expression.
|
|
117337
117401
|
**
|
|
117338
|
-
**
|
|
117339
|
-
** is not a function call, return WRC_Prune immediately.
|
|
117402
|
+
** For any other kind of expression, prune the search.
|
|
117340
117403
|
**
|
|
117341
|
-
**
|
|
117342
|
-
** SQLITE_RESULT_SUBTYPE property.
|
|
117404
|
+
** For case 1, the expression can yield a subtype if the function has
|
|
117405
|
+
** the SQLITE_RESULT_SUBTYPE property. Functions can also return
|
|
117406
|
+
** a subtype (via sqlite3_result_value()) if any of the arguments can
|
|
117407
|
+
** return a subtype.
|
|
117343
117408
|
**
|
|
117344
|
-
**
|
|
117345
|
-
**
|
|
117346
|
-
** are not this way, but we don't have a mechanism to distinguish those
|
|
117347
|
-
** that are from those that are not, so assume they all work this way.
|
|
117348
|
-
** That means that if one of its arguments is another function and that
|
|
117349
|
-
** other function is able to return a subtype, then this function is
|
|
117350
|
-
** able to return a subtype.
|
|
117409
|
+
** In all cases 1 through 5, the expression might also return a subtype
|
|
117410
|
+
** if any operand can return a subtype.
|
|
117351
117411
|
*/
|
|
117352
117412
|
static int exprNodeCanReturnSubtype(Walker *pWalker, Expr *pExpr){
|
|
117353
117413
|
int n;
|
|
117354
117414
|
FuncDef *pDef;
|
|
117355
117415
|
sqlite3 *db;
|
|
117416
|
+
if( pExpr->op==TK_CASE || pExpr->op==TK_UPLUS
|
|
117417
|
+
|| pExpr->op==TK_COLLATE || pExpr->op==TK_CAST
|
|
117418
|
+
){
|
|
117419
|
+
return WRC_Continue;
|
|
117420
|
+
}
|
|
117356
117421
|
if( pExpr->op!=TK_FUNCTION ){
|
|
117357
117422
|
return WRC_Prune;
|
|
117358
117423
|
}
|
|
@@ -117362,7 +117427,7 @@ static int exprNodeCanReturnSubtype(Walker *pWalker, Expr *pExpr){
|
|
|
117362
117427
|
pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0);
|
|
117363
117428
|
if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){
|
|
117364
117429
|
pWalker->eCode = 1;
|
|
117365
|
-
return
|
|
117430
|
+
return WRC_Abort;
|
|
117366
117431
|
}
|
|
117367
117432
|
return WRC_Continue;
|
|
117368
117433
|
}
|
|
@@ -123340,19 +123405,31 @@ SQLITE_PRIVATE void sqlite3AlterAddConstraint(
|
|
|
123340
123405
|
SrcList *pSrc, /* Table to add constraint to */
|
|
123341
123406
|
Token *pFirst, /* First token of new constraint */
|
|
123342
123407
|
Token *pName, /* Name of new constraint. NULL if name omitted. */
|
|
123343
|
-
const char *
|
|
123344
|
-
int nExpr
|
|
123408
|
+
const char *zExpr, /* Text of CHECK expression */
|
|
123409
|
+
int nExpr, /* Size of pExpr in bytes */
|
|
123410
|
+
Expr *pExpr /* The parsed CHECK expression */
|
|
123345
123411
|
){
|
|
123346
123412
|
Table *pTab = 0; /* Table identified by pSrc */
|
|
123347
123413
|
int iDb = 0; /* Which schema does pTab live in */
|
|
123348
123414
|
const char *zDb = 0; /* Name of the schema in which pTab lives */
|
|
123349
123415
|
const char *pCons = 0; /* Text of the constraint */
|
|
123350
123416
|
int nCons; /* Bytes of text to use from pCons[] */
|
|
123417
|
+
int rc; /* Result from error checking pExpr */
|
|
123351
123418
|
|
|
123352
123419
|
/* Look up the table being altered. */
|
|
123353
123420
|
assert( pSrc->nSrc==1 );
|
|
123354
123421
|
pTab = alterFindTable(pParse, pSrc, &iDb, &zDb, 1);
|
|
123355
|
-
if( !pTab )
|
|
123422
|
+
if( !pTab ){
|
|
123423
|
+
sqlite3ExprDelete(pParse->db, pExpr);
|
|
123424
|
+
return;
|
|
123425
|
+
}
|
|
123426
|
+
|
|
123427
|
+
/* Verify that the new CHECK constraint does not contain any
|
|
123428
|
+
** internal-use-only function. Forum post 2026-05-10T01:11:28Z
|
|
123429
|
+
*/
|
|
123430
|
+
rc = sqlite3ResolveSelfReference(pParse, pTab, NC_IsCheck, pExpr, 0);
|
|
123431
|
+
sqlite3ExprDelete(pParse->db, pExpr);
|
|
123432
|
+
if( rc ) return;
|
|
123356
123433
|
|
|
123357
123434
|
/* If this new constraint has a name, check that it is not a duplicate of
|
|
123358
123435
|
** an existing constraint. It is an error if it is. */
|
|
@@ -123373,7 +123450,7 @@ SQLITE_PRIVATE void sqlite3AlterAddConstraint(
|
|
|
123373
123450
|
sqlite3NestedParse(pParse,
|
|
123374
123451
|
"SELECT sqlite_fail('constraint failed', %d) "
|
|
123375
123452
|
"FROM %Q.%Q WHERE (%.*s) IS NOT TRUE",
|
|
123376
|
-
SQLITE_CONSTRAINT, zDb, pTab->zName, nExpr,
|
|
123453
|
+
SQLITE_CONSTRAINT, zDb, pTab->zName, nExpr, zExpr
|
|
123377
123454
|
);
|
|
123378
123455
|
|
|
123379
123456
|
/* Edit the SQL for the named table. */
|
|
@@ -134050,9 +134127,18 @@ static void printfFunc(
|
|
|
134050
134127
|
sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
|
|
134051
134128
|
str.printfFlags = SQLITE_PRINTF_SQLFUNC;
|
|
134052
134129
|
sqlite3_str_appendf(&str, zFormat, &x);
|
|
134053
|
-
|
|
134054
|
-
|
|
134055
|
-
|
|
134130
|
+
if( str.accError==SQLITE_OK ){
|
|
134131
|
+
n = str.nChar;
|
|
134132
|
+
sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
|
|
134133
|
+
SQLITE_DYNAMIC);
|
|
134134
|
+
}else{
|
|
134135
|
+
if( str.accError==SQLITE_NOMEM ){
|
|
134136
|
+
sqlite3_result_error_nomem(context);
|
|
134137
|
+
}else{
|
|
134138
|
+
sqlite3_result_error_toobig(context);
|
|
134139
|
+
}
|
|
134140
|
+
sqlite3_str_reset(&str);
|
|
134141
|
+
}
|
|
134056
134142
|
}
|
|
134057
134143
|
}
|
|
134058
134144
|
|
|
@@ -135690,11 +135776,16 @@ static void sumInverse(sqlite3_context *context, int argc, sqlite3_value**argv){
|
|
|
135690
135776
|
assert( p->cnt>0 );
|
|
135691
135777
|
p->cnt--;
|
|
135692
135778
|
if( !p->approx ){
|
|
135693
|
-
|
|
135694
|
-
|
|
135695
|
-
p->
|
|
135779
|
+
i64 x = p->iSum;
|
|
135780
|
+
if( sqlite3SubInt64(&x, sqlite3_value_int64(argv[0]))==0 ){
|
|
135781
|
+
p->iSum = x;
|
|
135782
|
+
return;
|
|
135696
135783
|
}
|
|
135697
|
-
|
|
135784
|
+
p->ovrfl = 1;
|
|
135785
|
+
p->approx = 1;
|
|
135786
|
+
kahanBabuskaNeumaierInit(p, p->iSum);
|
|
135787
|
+
}
|
|
135788
|
+
if( type==SQLITE_INTEGER ){
|
|
135698
135789
|
i64 iVal = sqlite3_value_int64(argv[0]);
|
|
135699
135790
|
if( iVal!=SMALLEST_INT64 ){
|
|
135700
135791
|
kahanBabuskaNeumaierStepInt64(p, -iVal);
|
|
@@ -136667,47 +136758,46 @@ static void percentSort(double *a, unsigned int n){
|
|
|
136667
136758
|
int i; /* Loop counter */
|
|
136668
136759
|
double rPivot; /* The pivot value */
|
|
136669
136760
|
|
|
136670
|
-
|
|
136671
|
-
|
|
136672
|
-
|
|
136673
|
-
|
|
136674
|
-
|
|
136675
|
-
|
|
136676
|
-
|
|
136677
|
-
|
|
136678
|
-
|
|
136679
|
-
|
|
136680
|
-
SWAP_DOUBLE(a[i],a[iGt])
|
|
136681
|
-
}
|
|
136682
|
-
if( n==3 ) return;
|
|
136683
|
-
rPivot = a[i];
|
|
136684
|
-
iLt = i = 1;
|
|
136685
|
-
do{
|
|
136686
|
-
if( a[i]<rPivot ){
|
|
136687
|
-
if( i>iLt ) SWAP_DOUBLE(a[i],a[iLt])
|
|
136688
|
-
iLt++;
|
|
136689
|
-
i++;
|
|
136690
|
-
}else if( a[i]>rPivot ){
|
|
136691
|
-
do{
|
|
136692
|
-
iGt--;
|
|
136693
|
-
}while( iGt>i && a[iGt]>rPivot );
|
|
136761
|
+
while( n>=2 ){
|
|
136762
|
+
if( a[0]>a[n-1] ){
|
|
136763
|
+
SWAP_DOUBLE(a[0],a[n-1])
|
|
136764
|
+
}
|
|
136765
|
+
if( n==2 ) return;
|
|
136766
|
+
iGt = n-1;
|
|
136767
|
+
i = n/2;
|
|
136768
|
+
if( a[0]>a[i] ){
|
|
136769
|
+
SWAP_DOUBLE(a[0],a[i])
|
|
136770
|
+
}else if( a[i]>a[iGt] ){
|
|
136694
136771
|
SWAP_DOUBLE(a[i],a[iGt])
|
|
136772
|
+
}
|
|
136773
|
+
if( n==3 ) return;
|
|
136774
|
+
rPivot = a[i];
|
|
136775
|
+
iLt = i = 1;
|
|
136776
|
+
do{
|
|
136777
|
+
if( a[i]<rPivot ){
|
|
136778
|
+
if( i>iLt ) SWAP_DOUBLE(a[i],a[iLt])
|
|
136779
|
+
iLt++;
|
|
136780
|
+
i++;
|
|
136781
|
+
}else if( a[i]>rPivot ){
|
|
136782
|
+
do{
|
|
136783
|
+
iGt--;
|
|
136784
|
+
}while( iGt>i && a[iGt]>rPivot );
|
|
136785
|
+
SWAP_DOUBLE(a[i],a[iGt])
|
|
136786
|
+
}else{
|
|
136787
|
+
i++;
|
|
136788
|
+
}
|
|
136789
|
+
}while( i<iGt );
|
|
136790
|
+
if( iLt>n/2 ){
|
|
136791
|
+
if( n-iGt>=2 ) percentSort(a+iGt, n-iGt);
|
|
136792
|
+
n = iLt;
|
|
136695
136793
|
}else{
|
|
136696
|
-
|
|
136794
|
+
if( iLt>=2 ) percentSort(a, iLt);
|
|
136795
|
+
a += iGt;
|
|
136796
|
+
n -= iGt;
|
|
136697
136797
|
}
|
|
136698
|
-
}while( i<iGt );
|
|
136699
|
-
if( iLt>=2 ) percentSort(a, iLt);
|
|
136700
|
-
if( n-iGt>=2 ) percentSort(a+iGt, n-iGt);
|
|
136701
|
-
|
|
136702
|
-
/* Uncomment for testing */
|
|
136703
|
-
#if 0
|
|
136704
|
-
for(i=0; i<n-1; i++){
|
|
136705
|
-
assert( a[i]<=a[i+1] );
|
|
136706
136798
|
}
|
|
136707
|
-
#endif
|
|
136708
136799
|
}
|
|
136709
136800
|
|
|
136710
|
-
|
|
136711
136801
|
/*
|
|
136712
136802
|
** The "inverse" function for percentile(Y,P) is called to remove a
|
|
136713
136803
|
** row that was previously inserted by "step".
|
|
@@ -156205,8 +156295,11 @@ static int selectCheckOnClausesExpr(Walker *pWalker, Expr *pExpr){
|
|
|
156205
156295
|
** does not refer to a table to the right of CheckOnCtx.iJoin. */
|
|
156206
156296
|
do {
|
|
156207
156297
|
SrcList *pSrc = pCtx->pSrc;
|
|
156298
|
+
int nSrc = pSrc->nSrc;
|
|
156208
156299
|
int iTab = pExpr->iTable;
|
|
156209
|
-
|
|
156300
|
+
int ii;
|
|
156301
|
+
for(ii=0; ii<nSrc && pSrc->a[ii].iCursor!=iTab; ii++){}
|
|
156302
|
+
if( ii<nSrc ){
|
|
156210
156303
|
if( pCtx->iJoin && iTab>pCtx->iJoin ){
|
|
156211
156304
|
sqlite3ErrorMsg(pWalker->pParse,
|
|
156212
156305
|
"%s references tables to its right",
|
|
@@ -166406,6 +166499,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
|
|
|
166406
166499
|
WO_EQ|WO_IN|WO_IS, 0);
|
|
166407
166500
|
if( pAlt==0 ) continue;
|
|
166408
166501
|
if( pAlt->wtFlags & (TERM_CODED) ) continue;
|
|
166502
|
+
if( ExprHasProperty(pAlt->pExpr, EP_Collate) ) continue;
|
|
166409
166503
|
if( (pAlt->eOperator & WO_IN)
|
|
166410
166504
|
&& ExprUseXSelect(pAlt->pExpr)
|
|
166411
166505
|
&& (pAlt->pExpr->x.pSelect->pEList->nExpr>1)
|
|
@@ -167598,8 +167692,8 @@ static void exprAnalyzeOrTerm(
|
|
|
167598
167692
|
** 3. Not originating in the ON clause of an OUTER JOIN
|
|
167599
167693
|
** 4. The operator is not IS or else the query does not contain RIGHT JOIN
|
|
167600
167694
|
** 5. The affinities of A and B must be compatible
|
|
167601
|
-
**
|
|
167602
|
-
**
|
|
167695
|
+
** 6. Both operands use the same collating sequence, and they must not
|
|
167696
|
+
** use explicit COLLATE clauses.
|
|
167603
167697
|
** If this routine returns TRUE, that means that the RHS can be substituted
|
|
167604
167698
|
** for the LHS anyplace else in the WHERE clause where the LHS column occurs.
|
|
167605
167699
|
** This is an optimization. No harm comes from returning 0. But if 1 is
|
|
@@ -167607,10 +167701,9 @@ static void exprAnalyzeOrTerm(
|
|
|
167607
167701
|
*/
|
|
167608
167702
|
static int termIsEquivalence(Parse *pParse, Expr *pExpr, SrcList *pSrc){
|
|
167609
167703
|
char aff1, aff2;
|
|
167610
|
-
CollSeq *pColl;
|
|
167611
167704
|
if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; /* (1) */
|
|
167612
167705
|
if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; /* (2) */
|
|
167613
|
-
if( ExprHasProperty(pExpr, EP_OuterON) ) return 0;
|
|
167706
|
+
if( ExprHasProperty(pExpr, EP_OuterON|EP_Collate) ) return 0; /* (3) */
|
|
167614
167707
|
assert( pSrc!=0 );
|
|
167615
167708
|
if( pExpr->op==TK_IS
|
|
167616
167709
|
&& pSrc->nSrc>=2
|
|
@@ -167625,10 +167718,7 @@ static int termIsEquivalence(Parse *pParse, Expr *pExpr, SrcList *pSrc){
|
|
|
167625
167718
|
){
|
|
167626
167719
|
return 0; /* (5) */
|
|
167627
167720
|
}
|
|
167628
|
-
|
|
167629
|
-
if( !sqlite3IsBinary(pColl)
|
|
167630
|
-
&& !sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight)
|
|
167631
|
-
){
|
|
167721
|
+
if( !sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight) ){
|
|
167632
167722
|
return 0; /* (6) */
|
|
167633
167723
|
}
|
|
167634
167724
|
return 1;
|
|
@@ -167960,7 +168050,7 @@ static void exprAnalyze(
|
|
|
167960
168050
|
/* Analyze a term that is composed of two or more subterms connected by
|
|
167961
168051
|
** an OR operator.
|
|
167962
168052
|
*/
|
|
167963
|
-
else if( pExpr->op==TK_OR ){
|
|
168053
|
+
else if( pExpr->op==TK_OR && !ExprHasProperty(pExpr, EP_Collate) ){
|
|
167964
168054
|
assert( pWC->op==TK_AND );
|
|
167965
168055
|
exprAnalyzeOrTerm(pSrc, pWC, idxTerm);
|
|
167966
168056
|
pTerm = &pWC->a[idxTerm];
|
|
@@ -171778,7 +171868,8 @@ static int whereRangeVectorLen(
|
|
|
171778
171868
|
idxaff = sqlite3TableColumnAffinity(pIdx->pTable, pLhs->iColumn);
|
|
171779
171869
|
if( aff!=idxaff ) break;
|
|
171780
171870
|
|
|
171781
|
-
|
|
171871
|
+
if( ExprHasProperty(pTerm->pExpr, EP_Commuted) ) SWAP(Expr*, pRhs, pLhs);
|
|
171872
|
+
pColl = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
|
|
171782
171873
|
if( pColl==0 ) break;
|
|
171783
171874
|
if( sqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break;
|
|
171784
171875
|
}
|
|
@@ -184270,9 +184361,11 @@ static YYACTIONTYPE yy_reduce(
|
|
|
184270
184361
|
ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454);
|
|
184271
184362
|
yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
|
|
184272
184363
|
if( yymsp[-4].minor.yy454 ){
|
|
184364
|
+
int i;
|
|
184273
184365
|
yymsp[-4].minor.yy454->x.pList = pList;
|
|
184274
|
-
|
|
184275
|
-
|
|
184366
|
+
for(i=0; i<pList->nExpr; i++){
|
|
184367
|
+
assert( pList->a[i].pExpr!=0 );
|
|
184368
|
+
yymsp[-4].minor.yy454->flags |= pList->a[i].pExpr->flags & EP_Propagate;
|
|
184276
184369
|
}
|
|
184277
184370
|
}else{
|
|
184278
184371
|
sqlite3ExprListDelete(pParse->db, pList);
|
|
@@ -184740,15 +184833,13 @@ static YYACTIONTYPE yy_reduce(
|
|
|
184740
184833
|
break;
|
|
184741
184834
|
case 300: /* cmd ::= ALTER TABLE fullname ADD CONSTRAINT nm CHECK LP expr RP onconf */
|
|
184742
184835
|
{
|
|
184743
|
-
sqlite3AlterAddConstraint(pParse, yymsp[-8].minor.yy203, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy0.z+1, (yymsp[-1].minor.yy0.z-yymsp[-3].minor.yy0.z-1));
|
|
184836
|
+
sqlite3AlterAddConstraint(pParse, yymsp[-8].minor.yy203, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy0.z+1, (yymsp[-1].minor.yy0.z-yymsp[-3].minor.yy0.z-1), yymsp[-2].minor.yy454);
|
|
184744
184837
|
}
|
|
184745
|
-
yy_destructor(yypParser,219,&yymsp[-2].minor);
|
|
184746
184838
|
break;
|
|
184747
184839
|
case 301: /* cmd ::= ALTER TABLE fullname ADD CHECK LP expr RP onconf */
|
|
184748
184840
|
{
|
|
184749
|
-
sqlite3AlterAddConstraint(pParse, yymsp[-6].minor.yy203, &yymsp[-4].minor.yy0, 0, yymsp[-3].minor.yy0.z+1, (yymsp[-1].minor.yy0.z-yymsp[-3].minor.yy0.z-1));
|
|
184841
|
+
sqlite3AlterAddConstraint(pParse, yymsp[-6].minor.yy203, &yymsp[-4].minor.yy0, 0, yymsp[-3].minor.yy0.z+1, (yymsp[-1].minor.yy0.z-yymsp[-3].minor.yy0.z-1), yymsp[-2].minor.yy454);
|
|
184750
184842
|
}
|
|
184751
|
-
yy_destructor(yypParser,219,&yymsp[-2].minor);
|
|
184752
184843
|
break;
|
|
184753
184844
|
case 302: /* cmd ::= create_vtab */
|
|
184754
184845
|
{sqlite3VtabFinishParse(pParse,0);}
|
|
@@ -193952,6 +194043,12 @@ SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk);
|
|
|
193952
194043
|
SQLITE_EXTENSION_INIT1
|
|
193953
194044
|
#endif
|
|
193954
194045
|
|
|
194046
|
+
|
|
194047
|
+
/*
|
|
194048
|
+
** Assume any b-tree layer with more levels than this is corrupt.
|
|
194049
|
+
*/
|
|
194050
|
+
#define FTS3_MAX_BTREE_HEIGHT 48
|
|
194051
|
+
|
|
193955
194052
|
typedef struct Fts3HashWrapper Fts3HashWrapper;
|
|
193956
194053
|
struct Fts3HashWrapper {
|
|
193957
194054
|
Fts3Hash hash; /* Hash table */
|
|
@@ -195668,7 +195765,11 @@ static int fts3SelectLeaf(
|
|
|
195668
195765
|
assert( piLeaf || piLeaf2 );
|
|
195669
195766
|
|
|
195670
195767
|
fts3GetVarint32(zNode, &iHeight);
|
|
195671
|
-
|
|
195768
|
+
if( iHeight>FTS3_MAX_BTREE_HEIGHT ){
|
|
195769
|
+
rc = FTS_CORRUPT_VTAB;
|
|
195770
|
+
}else{
|
|
195771
|
+
rc = fts3ScanInteriorNode(zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2);
|
|
195772
|
+
}
|
|
195672
195773
|
assert_fts3_nc( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) );
|
|
195673
195774
|
|
|
195674
195775
|
if( rc==SQLITE_OK && iHeight>1 ){
|
|
@@ -200197,7 +200298,7 @@ static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){
|
|
|
200197
200298
|
/* State 3. The integer just read is a column number. */
|
|
200198
200299
|
default: assert( eState==3 );
|
|
200199
200300
|
iCol = (int)v;
|
|
200200
|
-
if( iCol<1 ){
|
|
200301
|
+
if( iCol<1 || iCol>(pFts3->nColumn+1) ){
|
|
200201
200302
|
rc = SQLITE_CORRUPT_VTAB;
|
|
200202
200303
|
break;
|
|
200203
200304
|
}
|
|
@@ -200887,6 +200988,7 @@ static int getNextNode(
|
|
|
200887
200988
|
assert( nKey==4 );
|
|
200888
200989
|
if( zInput[4]=='/' && zInput[5]>='0' && zInput[5]<='9' ){
|
|
200889
200990
|
nKey += 1+sqlite3Fts3ReadInt(&zInput[nKey+1], &nNear);
|
|
200991
|
+
if( nNear>=1000000000 ) nNear = 1000000000;
|
|
200890
200992
|
}
|
|
200891
200993
|
}
|
|
200892
200994
|
|
|
@@ -210750,7 +210852,7 @@ static int fts3ExprLHits(
|
|
|
210750
210852
|
if( p->flag==FTS3_MATCHINFO_LHITS ){
|
|
210751
210853
|
p->aMatchinfo[iStart + iCol] = (u32)nHit;
|
|
210752
210854
|
}else if( nHit ){
|
|
210753
|
-
p->aMatchinfo[iStart +
|
|
210855
|
+
p->aMatchinfo[iStart + iCol/32] |= (1U << (iCol&0x1F));
|
|
210754
210856
|
}
|
|
210755
210857
|
}
|
|
210756
210858
|
assert( *pIter==0x00 || *pIter==0x01 );
|
|
@@ -213240,7 +213342,7 @@ static void jsonAppendSqlValue(
|
|
|
213240
213342
|
break;
|
|
213241
213343
|
}
|
|
213242
213344
|
case SQLITE_FLOAT: {
|
|
213243
|
-
jsonPrintf(100, p, "%!0.
|
|
213345
|
+
jsonPrintf(100, p, "%!0.17g", sqlite3_value_double(pValue));
|
|
213244
213346
|
break;
|
|
213245
213347
|
}
|
|
213246
213348
|
case SQLITE_INTEGER: {
|
|
@@ -214554,9 +214656,10 @@ static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){
|
|
|
214554
214656
|
u8 x;
|
|
214555
214657
|
u32 sz;
|
|
214556
214658
|
u32 n;
|
|
214557
|
-
|
|
214558
|
-
|
|
214559
|
-
|
|
214659
|
+
if( i>=pParse->nBlob ){
|
|
214660
|
+
*pSz = 0;
|
|
214661
|
+
return 0;
|
|
214662
|
+
}else if( (x = pParse->aBlob[i]>>4)<=11 ){
|
|
214560
214663
|
sz = x;
|
|
214561
214664
|
n = 1;
|
|
214562
214665
|
}else if( x==12 ){
|
|
@@ -217339,11 +217442,9 @@ static void jsonGroupInverse(
|
|
|
217339
217442
|
UNUSED_PARAMETER(argc);
|
|
217340
217443
|
UNUSED_PARAMETER(argv);
|
|
217341
217444
|
pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
|
|
217342
|
-
#ifdef NEVER
|
|
217343
217445
|
/* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will
|
|
217344
217446
|
** always have been called to initialize it */
|
|
217345
217447
|
if( NEVER(!pStr) ) return;
|
|
217346
|
-
#endif
|
|
217347
217448
|
z = pStr->zBuf;
|
|
217348
217449
|
for(i=1; i<pStr->nUsed && ((c = z[i])!=',' || inStr || nNest); i++){
|
|
217349
217450
|
if( c=='"' ){
|
|
@@ -217372,6 +217473,13 @@ static void jsonGroupInverse(
|
|
|
217372
217473
|
** json_group_obj(NAME,VALUE)
|
|
217373
217474
|
**
|
|
217374
217475
|
** Return a JSON object composed of all names and values in the aggregate.
|
|
217476
|
+
**
|
|
217477
|
+
** Rows for which NAME is NULL do not result in a new entry. However, we
|
|
217478
|
+
** do initially insert a "@" entry into the growing string for each null entry
|
|
217479
|
+
** and change the first character of the string to "@" to signal that the
|
|
217480
|
+
** string contains null entries. The "@" markers are needed in order to
|
|
217481
|
+
** correctly process xInverse() requests. The initial "@" is converted
|
|
217482
|
+
** back into "{" and the "@" null values are removed by jsonObjectCompute().
|
|
217375
217483
|
*/
|
|
217376
217484
|
static void jsonObjectStep(
|
|
217377
217485
|
sqlite3_context *ctx,
|
|
@@ -217389,7 +217497,7 @@ static void jsonObjectStep(
|
|
|
217389
217497
|
if( pStr->zBuf==0 ){
|
|
217390
217498
|
jsonStringInit(pStr, ctx);
|
|
217391
217499
|
jsonAppendChar(pStr, '{');
|
|
217392
|
-
}else if( pStr->nUsed>1
|
|
217500
|
+
}else if( pStr->nUsed>1 ){
|
|
217393
217501
|
jsonAppendChar(pStr, ',');
|
|
217394
217502
|
}
|
|
217395
217503
|
pStr->pCtx = ctx;
|
|
@@ -217397,6 +217505,9 @@ static void jsonObjectStep(
|
|
|
217397
217505
|
jsonAppendString(pStr, z, n);
|
|
217398
217506
|
jsonAppendChar(pStr, ':');
|
|
217399
217507
|
jsonAppendSqlValue(pStr, argv[1]);
|
|
217508
|
+
}else{
|
|
217509
|
+
pStr->zBuf[0] = '@';
|
|
217510
|
+
jsonAppendRawNZ(pStr, "@", 1);
|
|
217400
217511
|
}
|
|
217401
217512
|
}
|
|
217402
217513
|
}
|
|
@@ -217405,20 +217516,64 @@ static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){
|
|
|
217405
217516
|
int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
|
|
217406
217517
|
pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
|
|
217407
217518
|
if( pStr ){
|
|
217408
|
-
|
|
217409
|
-
|
|
217519
|
+
JsonString *pOgStr = pStr;
|
|
217520
|
+
JsonString tmpStr;
|
|
217521
|
+
jsonAppendRawNZ(pOgStr, "}", 2); /* Ensure it is zero-terminated */
|
|
217522
|
+
jsonStringTrimOneChar(pOgStr); /* Remove the zero terminator */
|
|
217410
217523
|
pStr->pCtx = ctx;
|
|
217411
217524
|
if( pStr->eErr ){
|
|
217412
217525
|
jsonReturnString(pStr, 0, 0);
|
|
217413
217526
|
return;
|
|
217414
|
-
}
|
|
217527
|
+
}
|
|
217528
|
+
if( pStr->zBuf[0]!='{' ){
|
|
217529
|
+
/* The string contains null entries that need to be removed */
|
|
217530
|
+
u64 i, j;
|
|
217531
|
+
int inStr = 0;
|
|
217532
|
+
if( !isFinal ){
|
|
217533
|
+
/* Work with a temporary copy of the string if this is not the
|
|
217534
|
+
** final result */
|
|
217535
|
+
jsonStringInit(&tmpStr, ctx);
|
|
217536
|
+
jsonAppendRawNZ(&tmpStr, pStr->zBuf, pStr->nUsed+1);
|
|
217537
|
+
pStr = &tmpStr;
|
|
217538
|
+
if( pStr->eErr ){
|
|
217539
|
+
jsonReturnString(pStr, 0, 0);
|
|
217540
|
+
return;
|
|
217541
|
+
}
|
|
217542
|
+
jsonStringTrimOneChar(pStr); /* Remove zero terminator */
|
|
217543
|
+
}
|
|
217544
|
+
/* Fix up the string by changing the initial "@" flag back to
|
|
217545
|
+
** to "{" and removing all subsequence "@" entries, with their
|
|
217546
|
+
** associated comma delimeters. */
|
|
217547
|
+
pStr->zBuf[0] = '{';
|
|
217548
|
+
for(i=j=1; i<pStr->nUsed; i++){
|
|
217549
|
+
char c = pStr->zBuf[i];
|
|
217550
|
+
if( c=='"' ){
|
|
217551
|
+
inStr = !inStr;
|
|
217552
|
+
pStr->zBuf[j++] = '"';
|
|
217553
|
+
}else if( c=='\\' ){
|
|
217554
|
+
pStr->zBuf[j++] = '\\';
|
|
217555
|
+
pStr->zBuf[j++] = pStr->zBuf[++i];
|
|
217556
|
+
}else if( c=='@' && !inStr ){
|
|
217557
|
+
assert( i+1<pStr->nUsed );
|
|
217558
|
+
if( pStr->zBuf[i+1]==',' ){
|
|
217559
|
+
i++;
|
|
217560
|
+
}else if( pStr->zBuf[j-1]==',' ){
|
|
217561
|
+
j--;
|
|
217562
|
+
}
|
|
217563
|
+
}else{
|
|
217564
|
+
pStr->zBuf[j++] = c;
|
|
217565
|
+
}
|
|
217566
|
+
}
|
|
217567
|
+
pStr->zBuf[j] = 0; /* Restore zero terminator */
|
|
217568
|
+
pStr->nUsed = j; /* Truncate the string */
|
|
217569
|
+
}
|
|
217570
|
+
if( flags & JSON_BLOB ){
|
|
217415
217571
|
jsonReturnStringAsBlob(pStr);
|
|
217416
217572
|
if( isFinal ){
|
|
217417
217573
|
if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf);
|
|
217418
217574
|
}else{
|
|
217419
|
-
jsonStringTrimOneChar(
|
|
217575
|
+
jsonStringTrimOneChar(pOgStr);
|
|
217420
217576
|
}
|
|
217421
|
-
return;
|
|
217422
217577
|
}else if( isFinal ){
|
|
217423
217578
|
sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
|
|
217424
217579
|
pStr->bStatic ? SQLITE_TRANSIENT :
|
|
@@ -217426,8 +217581,9 @@ static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){
|
|
|
217426
217581
|
pStr->bStatic = 1;
|
|
217427
217582
|
}else{
|
|
217428
217583
|
sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);
|
|
217429
|
-
jsonStringTrimOneChar(
|
|
217584
|
+
jsonStringTrimOneChar(pOgStr);
|
|
217430
217585
|
}
|
|
217586
|
+
if( pStr!=pOgStr ) jsonStringReset(pStr);
|
|
217431
217587
|
}else if( flags & JSON_BLOB ){
|
|
217432
217588
|
static const unsigned char emptyObject = 0x0c;
|
|
217433
217589
|
sqlite3_result_blob(ctx, &emptyObject, 1, SQLITE_STATIC);
|
|
@@ -218279,7 +218435,7 @@ struct Rtree {
|
|
|
218279
218435
|
u8 eCoordType; /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */
|
|
218280
218436
|
u8 nBytesPerCell; /* Bytes consumed per cell */
|
|
218281
218437
|
u8 inWrTrans; /* True if inside write transaction */
|
|
218282
|
-
|
|
218438
|
+
u16 nAux; /* # of auxiliary columns in %_rowid */
|
|
218283
218439
|
#ifdef SQLITE_ENABLE_GEOPOLY
|
|
218284
218440
|
u8 nAuxNotNull; /* Number of initial not-null aux columns */
|
|
218285
218441
|
#endif
|
|
@@ -219515,7 +219671,7 @@ static int nodeRowidIndex(
|
|
|
219515
219671
|
){
|
|
219516
219672
|
int ii;
|
|
219517
219673
|
int nCell = NCELL(pNode);
|
|
219518
|
-
assert( nCell<
|
|
219674
|
+
assert( nCell<65536 && nCell>=0 );
|
|
219519
219675
|
for(ii=0; ii<nCell; ii++){
|
|
219520
219676
|
if( nodeGetRowid(pRtree, pNode, ii)==iRowid ){
|
|
219521
219677
|
*piIndex = ii;
|
|
@@ -219777,7 +219933,10 @@ static int rtreeStepToLeaf(RtreeCursor *pCur){
|
|
|
219777
219933
|
pNode = rtreeNodeOfFirstSearchPoint(pCur, &rc);
|
|
219778
219934
|
if( rc ) return rc;
|
|
219779
219935
|
nCell = NCELL(pNode);
|
|
219780
|
-
|
|
219936
|
+
if( nCell>RTREE_MAXCELLS ){
|
|
219937
|
+
RTREE_IS_CORRUPT(pRtree);
|
|
219938
|
+
return SQLITE_CORRUPT_VTAB;
|
|
219939
|
+
}
|
|
219781
219940
|
pCellData = pNode->zData + (4+pRtree->nBytesPerCell*p->iCell);
|
|
219782
219941
|
while( p->iCell<nCell ){
|
|
219783
219942
|
sqlite3_rtree_dbl rScore = (sqlite3_rtree_dbl)-1;
|
|
@@ -221754,7 +221913,7 @@ static int rtreeInit(
|
|
|
221754
221913
|
"Auxiliary rtree columns must be last" /* 4 */
|
|
221755
221914
|
};
|
|
221756
221915
|
|
|
221757
|
-
assert( RTREE_MAX_AUX_COLUMN<256 );
|
|
221916
|
+
assert( RTREE_MAX_AUX_COLUMN<256 );
|
|
221758
221917
|
if( argc<6 || argc>RTREE_MAX_AUX_COLUMN+3 ){
|
|
221759
221918
|
*pzErr = sqlite3_mprintf("%s", aErrMsg[2 + (argc>=6)]);
|
|
221760
221919
|
return SQLITE_ERROR;
|
|
@@ -223673,6 +223832,11 @@ static int geopolyInit(
|
|
|
223673
223832
|
int ii;
|
|
223674
223833
|
(void)pAux;
|
|
223675
223834
|
|
|
223835
|
+
if( argc>=RTREE_MAX_AUX_COLUMN+4 ){
|
|
223836
|
+
*pzErr = sqlite3_mprintf("Too many columns for a geopoly table");
|
|
223837
|
+
return SQLITE_ERROR;
|
|
223838
|
+
}
|
|
223839
|
+
|
|
223676
223840
|
sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1);
|
|
223677
223841
|
sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
|
|
223678
223842
|
|
|
@@ -224807,7 +224971,7 @@ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
|
|
|
224807
224971
|
const UChar *zInput; /* Pointer to input string */
|
|
224808
224972
|
UChar *zOutput = 0; /* Pointer to output buffer */
|
|
224809
224973
|
int nInput; /* Size of utf-16 input string in bytes */
|
|
224810
|
-
|
|
224974
|
+
sqlite3_int64 nOut; /* Size of output buffer in bytes */
|
|
224811
224975
|
int cnt;
|
|
224812
224976
|
int bToUpper; /* True for toupper(), false for tolower() */
|
|
224813
224977
|
UErrorCode status;
|
|
@@ -224830,7 +224994,7 @@ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
|
|
|
224830
224994
|
}
|
|
224831
224995
|
|
|
224832
224996
|
for(cnt=0; cnt<2; cnt++){
|
|
224833
|
-
UChar *zNew =
|
|
224997
|
+
UChar *zNew = sqlite3_realloc64(zOutput, nOut);
|
|
224834
224998
|
if( zNew==0 ){
|
|
224835
224999
|
sqlite3_free(zOutput);
|
|
224836
225000
|
sqlite3_result_error_nomem(p);
|
|
@@ -224839,9 +225003,9 @@ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
|
|
|
224839
225003
|
zOutput = zNew;
|
|
224840
225004
|
status = U_ZERO_ERROR;
|
|
224841
225005
|
if( bToUpper ){
|
|
224842
|
-
nOut =
|
|
225006
|
+
nOut = 2LL*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status);
|
|
224843
225007
|
}else{
|
|
224844
|
-
nOut =
|
|
225008
|
+
nOut = 2LL*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status);
|
|
224845
225009
|
}
|
|
224846
225010
|
|
|
224847
225011
|
if( U_SUCCESS(status) ){
|
|
@@ -232556,12 +232720,13 @@ static int dbpageFilter(
|
|
|
232556
232720
|
pCsr->szPage = sqlite3BtreeGetPageSize(pBt);
|
|
232557
232721
|
pCsr->mxPgno = sqlite3BtreeLastPage(pBt);
|
|
232558
232722
|
if( idxNum & 1 ){
|
|
232723
|
+
i64 iPg = sqlite3_value_int64(argv[idxNum>>1]);
|
|
232559
232724
|
assert( argc>(idxNum>>1) );
|
|
232560
|
-
pCsr->
|
|
232561
|
-
if( pCsr->pgno<1 || pCsr->pgno>pCsr->mxPgno ){
|
|
232725
|
+
if( iPg<1 || iPg>pCsr->mxPgno ){
|
|
232562
232726
|
pCsr->pgno = 1;
|
|
232563
232727
|
pCsr->mxPgno = 0;
|
|
232564
232728
|
}else{
|
|
232729
|
+
pCsr->pgno = (Pgno)iPg;
|
|
232565
232730
|
pCsr->mxPgno = pCsr->pgno;
|
|
232566
232731
|
}
|
|
232567
232732
|
}else{
|
|
@@ -234908,6 +235073,16 @@ static int sessionPrepareDfltStmt(
|
|
|
234908
235073
|
return rc;
|
|
234909
235074
|
}
|
|
234910
235075
|
|
|
235076
|
+
/*
|
|
235077
|
+
** Finalize statement pStmt. If (*pRc) is SQLITE_OK when this function is
|
|
235078
|
+
** called, set it to the results of the sqlite3_finalize() call. Or, if
|
|
235079
|
+
** it is already set to an error code, leave it as is.
|
|
235080
|
+
*/
|
|
235081
|
+
static void sessionFinalizeStmt(sqlite3_stmt *pStmt, int *pRc){
|
|
235082
|
+
int rc = sqlite3_finalize(pStmt);
|
|
235083
|
+
if( *pRc==SQLITE_OK ) *pRc = rc;
|
|
235084
|
+
}
|
|
235085
|
+
|
|
234911
235086
|
/*
|
|
234912
235087
|
** Table pTab has one or more existing change-records with old.* records
|
|
234913
235088
|
** with fewer than pTab->nCol columns. This function updates all such
|
|
@@ -234930,9 +235105,8 @@ static int sessionUpdateChanges(sqlite3_session *pSession, SessionTable *pTab){
|
|
|
234930
235105
|
}
|
|
234931
235106
|
}
|
|
234932
235107
|
|
|
235108
|
+
sessionFinalizeStmt(pStmt, &rc);
|
|
234933
235109
|
pSession->rc = rc;
|
|
234934
|
-
rc = sqlite3_finalize(pStmt);
|
|
234935
|
-
if( pSession->rc==SQLITE_OK ) pSession->rc = rc;
|
|
234936
235110
|
return pSession->rc;
|
|
234937
235111
|
}
|
|
234938
235112
|
|
|
@@ -235500,7 +235674,7 @@ static int sessionDiffFindNew(
|
|
|
235500
235674
|
rc = SQLITE_NOMEM;
|
|
235501
235675
|
}else{
|
|
235502
235676
|
sqlite3_stmt *pStmt;
|
|
235503
|
-
rc =
|
|
235677
|
+
rc = sqlite3_prepare_v2(pSession->db, zStmt, -1, &pStmt, 0);
|
|
235504
235678
|
if( rc==SQLITE_OK ){
|
|
235505
235679
|
SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx;
|
|
235506
235680
|
pDiffCtx->pStmt = pStmt;
|
|
@@ -235563,7 +235737,7 @@ static int sessionDiffFindModified(
|
|
|
235563
235737
|
rc = SQLITE_NOMEM;
|
|
235564
235738
|
}else{
|
|
235565
235739
|
sqlite3_stmt *pStmt;
|
|
235566
|
-
rc =
|
|
235740
|
+
rc = sqlite3_prepare_v2(pSession->db, zStmt, -1, &pStmt, 0);
|
|
235567
235741
|
|
|
235568
235742
|
if( rc==SQLITE_OK ){
|
|
235569
235743
|
SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx;
|
|
@@ -236258,11 +236432,11 @@ static int sessionSelectStmt(
|
|
|
236258
236432
|
);
|
|
236259
236433
|
sessionAppendStr(&cols, "tbl, ?2, stat", &rc);
|
|
236260
236434
|
}else{
|
|
236261
|
-
|
|
236435
|
+
#if 0
|
|
236262
236436
|
if( bRowid ){
|
|
236263
236437
|
sessionAppendStr(&cols, SESSIONS_ROWID, &rc);
|
|
236264
236438
|
}
|
|
236265
|
-
|
|
236439
|
+
#endif
|
|
236266
236440
|
for(i=0; i<nCol; i++){
|
|
236267
236441
|
if( cols.nBuf ) sessionAppendStr(&cols, ", ", &rc);
|
|
236268
236442
|
sessionAppendIdent(&cols, azCol[i], &rc);
|
|
@@ -237516,7 +237690,13 @@ static int sessionChangesetInvert(
|
|
|
237516
237690
|
|
|
237517
237691
|
/* Test for EOF. */
|
|
237518
237692
|
if( (rc = sessionInputBuffer(pInput, 2)) ) goto finished_invert;
|
|
237519
|
-
if( pInput->iNext>=pInput->nData )
|
|
237693
|
+
if( pInput->iNext+1>=pInput->nData ){
|
|
237694
|
+
if( pInput->iNext!=pInput->nData ){
|
|
237695
|
+
rc = SQLITE_CORRUPT_BKPT;
|
|
237696
|
+
goto finished_invert;
|
|
237697
|
+
}
|
|
237698
|
+
break;
|
|
237699
|
+
}
|
|
237520
237700
|
eType = pInput->aData[pInput->iNext];
|
|
237521
237701
|
|
|
237522
237702
|
switch( eType ){
|
|
@@ -237712,6 +237892,7 @@ struct SessionApplyCtx {
|
|
|
237712
237892
|
u8 bRebaseStarted; /* If table header is already in rebase */
|
|
237713
237893
|
u8 bRebase; /* True to collect rebase information */
|
|
237714
237894
|
u8 bIgnoreNoop; /* True to ignore no-op conflicts */
|
|
237895
|
+
u8 bNoUpdateLoop; /* No update-loop processing */
|
|
237715
237896
|
int bRowid;
|
|
237716
237897
|
char *zErr; /* Error message, if any */
|
|
237717
237898
|
};
|
|
@@ -238285,7 +238466,7 @@ static int sessionConflictHandler(
|
|
|
238285
238466
|
u8 *aBlob = &pIter->in.aData[pIter->in.iCurrent];
|
|
238286
238467
|
int nBlob = pIter->in.iNext - pIter->in.iCurrent;
|
|
238287
238468
|
sessionAppendBlob(&p->constraints, aBlob, nBlob, &rc);
|
|
238288
|
-
return
|
|
238469
|
+
return rc;
|
|
238289
238470
|
}else if( p->bIgnoreNoop==0 || op!=SQLITE_DELETE
|
|
238290
238471
|
|| eType==SQLITE_CHANGESET_CONFLICT
|
|
238291
238472
|
){
|
|
@@ -238407,7 +238588,7 @@ static int sessionApplyOneOp(
|
|
|
238407
238588
|
for(i=0; rc==SQLITE_OK && i<nCol; i++){
|
|
238408
238589
|
sqlite3_value *pOld = sessionChangesetOld(pIter, i);
|
|
238409
238590
|
sqlite3_value *pNew = sessionChangesetNew(pIter, i);
|
|
238410
|
-
if( p->abPK[i] ||
|
|
238591
|
+
if( pOld && (p->abPK[i] || bPatchset==0) ){
|
|
238411
238592
|
rc = sessionBindValue(pUp, i*2+2, pOld);
|
|
238412
238593
|
}
|
|
238413
238594
|
if( rc==SQLITE_OK && pNew ){
|
|
@@ -238533,7 +238714,264 @@ static int sessionApplyOneWithRetry(
|
|
|
238533
238714
|
}
|
|
238534
238715
|
|
|
238535
238716
|
/*
|
|
238536
|
-
**
|
|
238717
|
+
** Create an iterator to iterate through the retry buffer pRetry.
|
|
238718
|
+
*/
|
|
238719
|
+
static int sessionRetryIterInit(
|
|
238720
|
+
SessionBuffer *pRetry, /* Buffer to iterate through */
|
|
238721
|
+
int bPatchset, /* True for patchset, false for changeset */
|
|
238722
|
+
const char *zTab, /* Table name */
|
|
238723
|
+
SessionApplyCtx *pApply, /* Session apply context */
|
|
238724
|
+
sqlite3_changeset_iter **ppIter /* OUT: New iterator */
|
|
238725
|
+
){
|
|
238726
|
+
sqlite3_changeset_iter *pRet = 0;
|
|
238727
|
+
int rc = SQLITE_OK;
|
|
238728
|
+
|
|
238729
|
+
rc = sessionChangesetStart(
|
|
238730
|
+
&pRet, 0, 0, pRetry->nBuf, pRetry->aBuf, pApply->bInvertConstraints, 1
|
|
238731
|
+
);
|
|
238732
|
+
if( rc==SQLITE_OK ){
|
|
238733
|
+
size_t nByte = 2*pApply->nCol*sizeof(sqlite3_value*);
|
|
238734
|
+
pRet->bPatchset = bPatchset;
|
|
238735
|
+
pRet->zTab = (char*)zTab;
|
|
238736
|
+
pRet->nCol = pApply->nCol;
|
|
238737
|
+
pRet->abPK = pApply->abPK;
|
|
238738
|
+
sessionBufferGrow(&pRet->tblhdr, nByte, &rc);
|
|
238739
|
+
pRet->apValue = (sqlite3_value**)pRet->tblhdr.aBuf;
|
|
238740
|
+
if( rc==SQLITE_OK ){
|
|
238741
|
+
memset(pRet->apValue, 0, nByte);
|
|
238742
|
+
}else{
|
|
238743
|
+
sqlite3changeset_finalize(pRet);
|
|
238744
|
+
pRet = 0;
|
|
238745
|
+
}
|
|
238746
|
+
}
|
|
238747
|
+
|
|
238748
|
+
*ppIter = pRet;
|
|
238749
|
+
return rc;
|
|
238750
|
+
}
|
|
238751
|
+
|
|
238752
|
+
/*
|
|
238753
|
+
** Attempt to apply all the changes in retry buffer pRetry to the database.
|
|
238754
|
+
** Except, if parameter iSkip is greater than or equal to 0, skip change
|
|
238755
|
+
** iSkip.
|
|
238756
|
+
*/
|
|
238757
|
+
static int sessionApplyRetryBuffer(
|
|
238758
|
+
SessionBuffer *pRetry, /* Buffer to apply changes from */
|
|
238759
|
+
int iSkip, /* If >=0, index of change to omit */
|
|
238760
|
+
sqlite3 *db, /* Database handle */
|
|
238761
|
+
int bPatchset, /* True for patchset, false for changeset */
|
|
238762
|
+
const char *zTab, /* Name of table to write to */
|
|
238763
|
+
SessionApplyCtx *pApply, /* Apply context */
|
|
238764
|
+
int(*xConflict)(void*, int, sqlite3_changeset_iter*),
|
|
238765
|
+
void *pCtx /* First argument passed to xConflict */
|
|
238766
|
+
){
|
|
238767
|
+
int rc = SQLITE_OK;
|
|
238768
|
+
int rc2 = SQLITE_OK;
|
|
238769
|
+
int ii = 0;
|
|
238770
|
+
sqlite3_changeset_iter *pIter = 0;
|
|
238771
|
+
|
|
238772
|
+
assert( pApply->constraints.nBuf==0 );
|
|
238773
|
+
|
|
238774
|
+
rc = sessionRetryIterInit(pRetry, bPatchset, zTab, pApply, &pIter);
|
|
238775
|
+
|
|
238776
|
+
for(ii=0; rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter); ii++){
|
|
238777
|
+
if( ii!=iSkip ){
|
|
238778
|
+
rc = sessionApplyOneWithRetry(db, pIter, pApply, xConflict, pCtx);
|
|
238779
|
+
}
|
|
238780
|
+
}
|
|
238781
|
+
|
|
238782
|
+
rc2 = sqlite3changeset_finalize(pIter);
|
|
238783
|
+
if( rc==SQLITE_OK ) rc = rc2;
|
|
238784
|
+
assert( pApply->bDeferConstraints || pApply->constraints.nBuf==0 );
|
|
238785
|
+
|
|
238786
|
+
return rc;
|
|
238787
|
+
}
|
|
238788
|
+
|
|
238789
|
+
/*
|
|
238790
|
+
** Check if table zTab in the "main" database of db is a WITHOUT ROWID
|
|
238791
|
+
** table.
|
|
238792
|
+
**
|
|
238793
|
+
** If no error occurs, return SQLITE_OK and set output variable (*pbWR) to
|
|
238794
|
+
** true if zTab is a WITHOUT ROWID table, or false otherwise. Or, if an
|
|
238795
|
+
** error does occur, return an SQLite error code. The final value of (*pbWR)
|
|
238796
|
+
** is undefined in this case.
|
|
238797
|
+
*/
|
|
238798
|
+
static int sessionTableIsWithoutRowid(sqlite3 *db, const char *zTab, int *pbWR){
|
|
238799
|
+
sqlite3_stmt *pList = 0;
|
|
238800
|
+
char *zSql = 0;
|
|
238801
|
+
int rc = SQLITE_OK;
|
|
238802
|
+
|
|
238803
|
+
zSql = sqlite3_mprintf("PRAGMA table_list = %Q", zTab);
|
|
238804
|
+
if( zSql==0 ){
|
|
238805
|
+
rc = SQLITE_NOMEM;
|
|
238806
|
+
}else{
|
|
238807
|
+
rc = sqlite3_prepare_v2(db, zSql, -1, &pList, 0);
|
|
238808
|
+
sqlite3_free(zSql);
|
|
238809
|
+
}
|
|
238810
|
+
|
|
238811
|
+
if( rc==SQLITE_OK ){
|
|
238812
|
+
sqlite3_step(pList);
|
|
238813
|
+
*pbWR = sqlite3_column_int(pList, 4);
|
|
238814
|
+
rc = sqlite3_finalize(pList);
|
|
238815
|
+
}
|
|
238816
|
+
|
|
238817
|
+
return rc;
|
|
238818
|
+
}
|
|
238819
|
+
|
|
238820
|
+
/*
|
|
238821
|
+
** Iterator pUp points to an UPDATE change. This function deletes the
|
|
238822
|
+
** affected row from the database and creates an INSERT statement that
|
|
238823
|
+
** may be used to reinsert the row as it is after the UPDATE change
|
|
238824
|
+
** has been applied.
|
|
238825
|
+
**
|
|
238826
|
+
** If successful, SQLITE_OK is returned and output variable (*ppInsert)
|
|
238827
|
+
** is left pointing to a prepared INSERT statement. It is the responsibility
|
|
238828
|
+
** of the caller to eventually free this statement using sqlite3_finalize().
|
|
238829
|
+
** Or, if an error occurs, an SQLite error code is returned and (*ppInsert)
|
|
238830
|
+
** set to NULL. pApply->zErr may be set to an error message in this case.
|
|
238831
|
+
*/
|
|
238832
|
+
static int sessionUpdateToDeleteInsert(
|
|
238833
|
+
sqlite3 *db, /* Database to write to */
|
|
238834
|
+
const char *zTab, /* Table name */
|
|
238835
|
+
SessionApplyCtx *pApply, /* Apply context */
|
|
238836
|
+
sqlite3_changeset_iter *pUp, /* Iterator pointing to UPDATE change */
|
|
238837
|
+
sqlite3_stmt **ppInsert /* OUT: INSERT statement */
|
|
238838
|
+
){
|
|
238839
|
+
sqlite3_stmt *pRet = 0; /* The INSERT statement */
|
|
238840
|
+
sqlite3_stmt *pSelect = 0; /* SELECT to read current values of row */
|
|
238841
|
+
int rc = SQLITE_OK;
|
|
238842
|
+
int bWR = 0;
|
|
238843
|
+
|
|
238844
|
+
rc = sessionTableIsWithoutRowid(db, zTab, &bWR);
|
|
238845
|
+
if( rc==SQLITE_OK ){
|
|
238846
|
+
char *zSelect = 0;
|
|
238847
|
+
char *zInsert = 0;
|
|
238848
|
+
SessionBuffer cols = {0, 0, 0};
|
|
238849
|
+
SessionBuffer insbind = {0, 0, 0};
|
|
238850
|
+
SessionBuffer pkcols = {0, 0, 0};
|
|
238851
|
+
SessionBuffer selbind = {0, 0, 0};
|
|
238852
|
+
|
|
238853
|
+
const char *zComma = "";
|
|
238854
|
+
const char *zComma2 = "";
|
|
238855
|
+
int ii;
|
|
238856
|
+
for(ii=0; ii<pApply->nCol; ii++){
|
|
238857
|
+
sessionAppendStr(&cols, zComma, &rc);
|
|
238858
|
+
sessionAppendIdent(&cols, pApply->azCol[ii], &rc);
|
|
238859
|
+
sessionAppendStr(&insbind, zComma, &rc);
|
|
238860
|
+
sessionAppendStr(&insbind, "?", &rc);
|
|
238861
|
+
zComma = ", ";
|
|
238862
|
+
|
|
238863
|
+
if( pApply->abPK[ii] ){
|
|
238864
|
+
sessionAppendStr(&pkcols, zComma2, &rc);
|
|
238865
|
+
sessionAppendIdent(&pkcols, pApply->azCol[ii], &rc);
|
|
238866
|
+
sessionAppendStr(&selbind, zComma2, &rc);
|
|
238867
|
+
sessionAppendPrintf(&selbind, &rc, "?%d", ii+1);
|
|
238868
|
+
zComma2 = ", ";
|
|
238869
|
+
}
|
|
238870
|
+
}
|
|
238871
|
+
if( bWR==0 ){
|
|
238872
|
+
sessionAppendStr(&cols, zComma, &rc);
|
|
238873
|
+
sessionAppendStr(&cols, SESSIONS_ROWID, &rc);
|
|
238874
|
+
sessionAppendStr(&insbind, zComma, &rc);
|
|
238875
|
+
sessionAppendStr(&insbind, "?", &rc);
|
|
238876
|
+
}
|
|
238877
|
+
|
|
238878
|
+
if( rc==SQLITE_OK ){
|
|
238879
|
+
zSelect = sqlite3_mprintf("SELECT %s FROM %Q WHERE (%s) IS (%s)",
|
|
238880
|
+
cols.aBuf, zTab, pkcols.aBuf, selbind.aBuf
|
|
238881
|
+
);
|
|
238882
|
+
if( zSelect==0 ) rc = SQLITE_NOMEM;
|
|
238883
|
+
}
|
|
238884
|
+
if( rc==SQLITE_OK ){
|
|
238885
|
+
zInsert = sqlite3_mprintf("INSERT INTO %Q(%s) VALUES(%s)",
|
|
238886
|
+
zTab, cols.aBuf, insbind.aBuf
|
|
238887
|
+
);
|
|
238888
|
+
if( zInsert==0 ) rc = SQLITE_NOMEM;
|
|
238889
|
+
}
|
|
238890
|
+
|
|
238891
|
+
if( rc==SQLITE_OK ){
|
|
238892
|
+
rc = sessionPrepare(db, &pSelect, &pApply->zErr, zSelect);
|
|
238893
|
+
}
|
|
238894
|
+
if( rc==SQLITE_OK ){
|
|
238895
|
+
rc = sessionPrepare(db, &pRet, &pApply->zErr, zInsert);
|
|
238896
|
+
}
|
|
238897
|
+
|
|
238898
|
+
sqlite3_free(zSelect);
|
|
238899
|
+
sqlite3_free(zInsert);
|
|
238900
|
+
sqlite3_free(cols.aBuf);
|
|
238901
|
+
sqlite3_free(insbind.aBuf);
|
|
238902
|
+
sqlite3_free(pkcols.aBuf);
|
|
238903
|
+
sqlite3_free(selbind.aBuf);
|
|
238904
|
+
}
|
|
238905
|
+
|
|
238906
|
+
if( rc==SQLITE_OK ){
|
|
238907
|
+
rc = sessionBindRow(
|
|
238908
|
+
pUp, sqlite3changeset_old, pApply->nCol, pApply->abPK, pSelect
|
|
238909
|
+
);
|
|
238910
|
+
}
|
|
238911
|
+
|
|
238912
|
+
if( rc==SQLITE_OK && sqlite3_step(pSelect)==SQLITE_ROW ){
|
|
238913
|
+
int iCol;
|
|
238914
|
+
for(iCol=0; iCol<pApply->nCol; iCol++){
|
|
238915
|
+
sqlite3_value *pVal = pUp->apValue[iCol+pApply->nCol];
|
|
238916
|
+
if( pVal==0 ){
|
|
238917
|
+
pVal = sqlite3_column_value(pSelect, iCol);
|
|
238918
|
+
}
|
|
238919
|
+
rc = sqlite3_bind_value(pRet, iCol+1, pVal);
|
|
238920
|
+
}
|
|
238921
|
+
if( bWR==0 ){
|
|
238922
|
+
sqlite3_bind_int64(pRet, iCol+1, sqlite3_column_int64(pSelect, iCol));
|
|
238923
|
+
}
|
|
238924
|
+
}
|
|
238925
|
+
sessionFinalizeStmt(pSelect, &rc);
|
|
238926
|
+
|
|
238927
|
+
/* Delete the row from the database. */
|
|
238928
|
+
if( rc==SQLITE_OK ){
|
|
238929
|
+
rc = sessionBindRow(
|
|
238930
|
+
pUp, sqlite3changeset_old, pApply->nCol, pApply->abPK, pApply->pDelete
|
|
238931
|
+
);
|
|
238932
|
+
sqlite3_bind_int(pApply->pDelete, pApply->nCol+1, 1);
|
|
238933
|
+
}
|
|
238934
|
+
if( rc==SQLITE_OK ){
|
|
238935
|
+
sqlite3_step(pApply->pDelete);
|
|
238936
|
+
rc = sqlite3_reset(pApply->pDelete);
|
|
238937
|
+
}
|
|
238938
|
+
|
|
238939
|
+
if( rc!=SQLITE_OK ){
|
|
238940
|
+
sqlite3_finalize(pRet);
|
|
238941
|
+
pRet = 0;
|
|
238942
|
+
}
|
|
238943
|
+
|
|
238944
|
+
*ppInsert = pRet;
|
|
238945
|
+
return rc;
|
|
238946
|
+
}
|
|
238947
|
+
|
|
238948
|
+
/*
|
|
238949
|
+
** Retry the changes accumulated in the pApply->constraints buffer. The
|
|
238950
|
+
** pApply->constraints buffer contains all changes to table zTab that
|
|
238951
|
+
** could not be applied due to SQLITE_CONSTRAINT errors. This function
|
|
238952
|
+
** attempts to apply them as follows:
|
|
238953
|
+
**
|
|
238954
|
+
** 1) It runs through the buffer and attempts to retry each change,
|
|
238955
|
+
** removing any that are successfully applied from the buffer. This
|
|
238956
|
+
** is repeated until no further progress can be made.
|
|
238957
|
+
**
|
|
238958
|
+
** 2) For each UPDATE change in the buffer, try the following in a
|
|
238959
|
+
** savepoint transaction:
|
|
238960
|
+
**
|
|
238961
|
+
** a) DELETE the affected row,
|
|
238962
|
+
** b) Attempt step (1) with remaining changes,
|
|
238963
|
+
** c) Attempt to INSERT a row equivalent to the one that would be
|
|
238964
|
+
** created by applying this UPDATE change.
|
|
238965
|
+
**
|
|
238966
|
+
** If the INSERT in (c) succeeds, the savepoint is committed and all
|
|
238967
|
+
** successfully applied changes are removed from the buffer. Step (2)
|
|
238968
|
+
** is then repeated.
|
|
238969
|
+
**
|
|
238970
|
+
** 3) Once step (2) has been attempted for each UPDATE in the change,
|
|
238971
|
+
** a final attempt is made to apply each remaining change. This time,
|
|
238972
|
+
** if an SQLITE_CONSTRAINT error is encountered, the conflict handler
|
|
238973
|
+
** is invoked and the user has to decide whether to omit the change
|
|
238974
|
+
** or rollback the entire _apply() operation.
|
|
238537
238975
|
*/
|
|
238538
238976
|
static int sessionRetryConstraints(
|
|
238539
238977
|
sqlite3 *db,
|
|
@@ -238544,41 +238982,101 @@ static int sessionRetryConstraints(
|
|
|
238544
238982
|
void *pCtx /* First argument passed to xConflict */
|
|
238545
238983
|
){
|
|
238546
238984
|
int rc = SQLITE_OK;
|
|
238985
|
+
int iUpdate = 0;
|
|
238547
238986
|
|
|
238987
|
+
/* Step (1) */
|
|
238548
238988
|
while( pApply->constraints.nBuf ){
|
|
238549
|
-
sqlite3_changeset_iter *pIter2 = 0;
|
|
238550
238989
|
SessionBuffer cons = pApply->constraints;
|
|
238551
238990
|
memset(&pApply->constraints, 0, sizeof(SessionBuffer));
|
|
238552
238991
|
|
|
238553
|
-
rc =
|
|
238554
|
-
&
|
|
238992
|
+
rc = sessionApplyRetryBuffer(
|
|
238993
|
+
&cons, -1, db, bPatchset, zTab, pApply, xConflict, pCtx
|
|
238994
|
+
);
|
|
238995
|
+
|
|
238996
|
+
sqlite3_free(cons.aBuf);
|
|
238997
|
+
if( rc!=SQLITE_OK ) break;
|
|
238998
|
+
|
|
238999
|
+
/* If no progress has been made this round, break out of the loop. */
|
|
239000
|
+
if( pApply->constraints.nBuf>=cons.nBuf ) break;
|
|
239001
|
+
}
|
|
239002
|
+
|
|
239003
|
+
/* Step (2) */
|
|
239004
|
+
while( rc==SQLITE_OK && pApply->constraints.nBuf && !pApply->bNoUpdateLoop ){
|
|
239005
|
+
SessionBuffer cons = {0, 0, 0};
|
|
239006
|
+
sqlite3_changeset_iter *pUp = 0;
|
|
239007
|
+
sqlite3_stmt *pInsert = 0;
|
|
239008
|
+
int iSkip = 0;
|
|
239009
|
+
|
|
239010
|
+
rc = sessionRetryIterInit(
|
|
239011
|
+
&pApply->constraints, bPatchset, zTab, pApply, &pUp
|
|
238555
239012
|
);
|
|
238556
239013
|
if( rc==SQLITE_OK ){
|
|
238557
|
-
|
|
238558
|
-
|
|
238559
|
-
|
|
238560
|
-
|
|
238561
|
-
|
|
238562
|
-
|
|
238563
|
-
|
|
238564
|
-
|
|
238565
|
-
|
|
239014
|
+
int iThis = -1;
|
|
239015
|
+
while( SQLITE_ROW==sqlite3changeset_next(pUp) ){
|
|
239016
|
+
if( pUp->op==SQLITE_UPDATE ) iThis++;
|
|
239017
|
+
if( iThis==iUpdate ) break;
|
|
239018
|
+
iSkip++;
|
|
239019
|
+
}
|
|
239020
|
+
if( iThis==iUpdate ){
|
|
239021
|
+
rc = sqlite3_exec(db, "SAVEPOINT update_op", 0, 0, 0);
|
|
239022
|
+
if( rc==SQLITE_OK ){
|
|
239023
|
+
rc = sessionUpdateToDeleteInsert(db, zTab, pApply, pUp, &pInsert);
|
|
239024
|
+
}
|
|
239025
|
+
}
|
|
239026
|
+
sqlite3changeset_finalize(pUp);
|
|
239027
|
+
if( iThis!=iUpdate ) break;
|
|
239028
|
+
}
|
|
239029
|
+
|
|
239030
|
+
if( rc==SQLITE_OK ){
|
|
239031
|
+
cons = pApply->constraints;
|
|
238566
239032
|
|
|
238567
|
-
while( rc==SQLITE_OK &&
|
|
238568
|
-
|
|
239033
|
+
while( rc==SQLITE_OK && pApply->constraints.nBuf>0 ){
|
|
239034
|
+
SessionBuffer app = pApply->constraints;
|
|
239035
|
+
memset(&pApply->constraints, 0, sizeof(SessionBuffer));
|
|
239036
|
+
rc = sessionApplyRetryBuffer(
|
|
239037
|
+
&app, iSkip, db, bPatchset, zTab, pApply, xConflict, pCtx
|
|
239038
|
+
);
|
|
239039
|
+
if( app.aBuf!=cons.aBuf ){
|
|
239040
|
+
sqlite3_free(app.aBuf);
|
|
239041
|
+
}
|
|
239042
|
+
if( pApply->constraints.nBuf>=app.nBuf ){
|
|
239043
|
+
break;
|
|
239044
|
+
}
|
|
239045
|
+
iSkip = -1;
|
|
238569
239046
|
}
|
|
239047
|
+
}
|
|
238570
239048
|
|
|
238571
|
-
|
|
238572
|
-
|
|
239049
|
+
iUpdate++;
|
|
239050
|
+
if( rc==SQLITE_OK ){
|
|
239051
|
+
sqlite3_step(pInsert);
|
|
239052
|
+
rc = sqlite3_finalize(pInsert);
|
|
239053
|
+
if( rc==SQLITE_CONSTRAINT ){
|
|
239054
|
+
rc = sqlite3_exec(db, "ROLLBACK TO update_op", 0, 0, 0);
|
|
239055
|
+
sqlite3_free(pApply->constraints.aBuf);
|
|
239056
|
+
pApply->constraints = cons;
|
|
239057
|
+
memset(&cons, 0, sizeof(cons));
|
|
239058
|
+
}else if( rc==SQLITE_OK ){
|
|
239059
|
+
iUpdate = 0;
|
|
239060
|
+
}
|
|
239061
|
+
if( rc==SQLITE_OK ){
|
|
239062
|
+
rc = sqlite3_exec(db, "RELEASE update_op", 0, 0, 0);
|
|
239063
|
+
}
|
|
239064
|
+
}else{
|
|
239065
|
+
sqlite3_finalize(pInsert);
|
|
238573
239066
|
}
|
|
238574
|
-
assert( pApply->bDeferConstraints || pApply->constraints.nBuf==0 );
|
|
238575
239067
|
|
|
238576
239068
|
sqlite3_free(cons.aBuf);
|
|
238577
|
-
|
|
238578
|
-
|
|
238579
|
-
|
|
238580
|
-
|
|
238581
|
-
|
|
239069
|
+
}
|
|
239070
|
+
|
|
239071
|
+
/* Step (3) */
|
|
239072
|
+
if( rc==SQLITE_OK && pApply->constraints.nBuf ){
|
|
239073
|
+
SessionBuffer cons = pApply->constraints;
|
|
239074
|
+
memset(&pApply->constraints, 0, sizeof(SessionBuffer));
|
|
239075
|
+
pApply->bDeferConstraints = 0;
|
|
239076
|
+
rc = sessionApplyRetryBuffer(
|
|
239077
|
+
&cons, -1, db, bPatchset, zTab, pApply, xConflict, pCtx
|
|
239078
|
+
);
|
|
239079
|
+
sqlite3_free(cons.aBuf);
|
|
238582
239080
|
}
|
|
238583
239081
|
|
|
238584
239082
|
return rc;
|
|
@@ -238632,6 +239130,7 @@ static int sessionChangesetApply(
|
|
|
238632
239130
|
sApply.bRebase = (ppRebase && pnRebase);
|
|
238633
239131
|
sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
|
|
238634
239132
|
sApply.bIgnoreNoop = !!(flags & SQLITE_CHANGESETAPPLY_IGNORENOOP);
|
|
239133
|
+
sApply.bNoUpdateLoop = !!(flags & SQLITE_CHANGESETAPPLY_NOUPDATELOOP);
|
|
238635
239134
|
if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
|
|
238636
239135
|
rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0);
|
|
238637
239136
|
}
|
|
@@ -240443,7 +240942,7 @@ SQLITE_API int sqlite3changegroup_change_blob(
|
|
|
240443
240942
|
const void *pVal,
|
|
240444
240943
|
int nVal
|
|
240445
240944
|
){
|
|
240446
|
-
sqlite3_int64 nByte = 1 + sessionVarintLen(nVal) + nVal;
|
|
240945
|
+
sqlite3_int64 nByte = 1 + sessionVarintLen(nVal) + (i64)nVal;
|
|
240447
240946
|
int rc = SQLITE_OK;
|
|
240448
240947
|
SessionBuffer *pBuf = 0;
|
|
240449
240948
|
|
|
@@ -251027,7 +251526,7 @@ static void fts5DataRelease(Fts5Data *pData){
|
|
|
251027
251526
|
static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){
|
|
251028
251527
|
Fts5Data *pRet = fts5DataRead(p, iRowid);
|
|
251029
251528
|
if( pRet ){
|
|
251030
|
-
if( pRet->
|
|
251529
|
+
if( pRet->szLeaf<4 || pRet->szLeaf>pRet->nn ){
|
|
251031
251530
|
FTS5_CORRUPT_ROWID(p, iRowid);
|
|
251032
251531
|
fts5DataRelease(pRet);
|
|
251033
251532
|
pRet = 0;
|
|
@@ -252681,6 +253180,10 @@ static void fts5LeafSeek(
|
|
|
252681
253180
|
if( nKeep<nMatch ){
|
|
252682
253181
|
goto search_failed;
|
|
252683
253182
|
}
|
|
253183
|
+
if( (iOff+nNew)>n ){
|
|
253184
|
+
FTS5_CORRUPT_ITER(p, pIter);
|
|
253185
|
+
return;
|
|
253186
|
+
}
|
|
252684
253187
|
|
|
252685
253188
|
assert( nKeep>=nMatch );
|
|
252686
253189
|
if( nKeep==nMatch ){
|
|
@@ -253657,8 +254160,7 @@ static void fts5PoslistFilterCallback(
|
|
|
253657
254160
|
|
|
253658
254161
|
do {
|
|
253659
254162
|
while( i<nChunk && pChunk[i]!=0x01 ){
|
|
253660
|
-
|
|
253661
|
-
i++;
|
|
254163
|
+
fts5IndexSkipVarint(pChunk, i);
|
|
253662
254164
|
}
|
|
253663
254165
|
if( pCtx->eState ){
|
|
253664
254166
|
fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart);
|
|
@@ -253807,7 +254309,7 @@ static void fts5IndexExtractColset(
|
|
|
253807
254309
|
/* Advance pointer p until it points to pEnd or an 0x01 byte that is
|
|
253808
254310
|
** not part of a varint */
|
|
253809
254311
|
while( p<pEnd && *p!=0x01 ){
|
|
253810
|
-
while( *p++ & 0x80 );
|
|
254312
|
+
while( p<pEnd && (*p++ & 0x80) );
|
|
253811
254313
|
}
|
|
253812
254314
|
|
|
253813
254315
|
if( pColset->aiCol[i]==iCurrent ){
|
|
@@ -253904,8 +254406,11 @@ static void fts5IterSetOutputs_Col100(Fts5Iter *pIter, Fts5SegIter *pSeg){
|
|
|
253904
254406
|
|
|
253905
254407
|
assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS );
|
|
253906
254408
|
assert( pIter->pColset );
|
|
254409
|
+
assert( pIter->poslist.nSpace>=pIter->pIndex->pConfig->nCol );
|
|
253907
254410
|
|
|
253908
|
-
if( pSeg->iLeafOffset+pSeg->nPos>pSeg->pLeaf->szLeaf
|
|
254411
|
+
if( pSeg->iLeafOffset+pSeg->nPos>pSeg->pLeaf->szLeaf
|
|
254412
|
+
|| pSeg->nPos>pIter->pIndex->pConfig->nCol
|
|
254413
|
+
){
|
|
253909
254414
|
fts5IterSetOutputs_Col(pIter, pSeg);
|
|
253910
254415
|
}else{
|
|
253911
254416
|
u8 *a = (u8*)&pSeg->pLeaf->p[pSeg->iLeafOffset];
|
|
@@ -255399,6 +255904,11 @@ static void fts5DoSecureDelete(
|
|
|
255399
255904
|
}else{
|
|
255400
255905
|
iStart = fts5GetU16(&aPg[0]);
|
|
255401
255906
|
}
|
|
255907
|
+
if( iStart>nPg ){
|
|
255908
|
+
FTS5_CORRUPT_IDX(p);
|
|
255909
|
+
sqlite3_free(aIdx);
|
|
255910
|
+
return;
|
|
255911
|
+
}
|
|
255402
255912
|
|
|
255403
255913
|
iSOP = iStart + fts5GetVarint(&aPg[iStart], &iDelta);
|
|
255404
255914
|
assert_nc( iSOP<=pSeg->iLeafOffset );
|
|
@@ -263275,7 +263785,7 @@ static void fts5SourceIdFunc(
|
|
|
263275
263785
|
){
|
|
263276
263786
|
assert( nArg==0 );
|
|
263277
263787
|
UNUSED_PARAM2(nArg, apUnused);
|
|
263278
|
-
sqlite3_result_text(pCtx, "fts5: 2026-
|
|
263788
|
+
sqlite3_result_text(pCtx, "fts5: 2026-06-03 19:12:13 d6e03d8c777cfa2d35e3b60d8ec3e0187f3e9f99d8e2ee9cac695fd6fcdf1a24", -1, SQLITE_TRANSIENT);
|
|
263279
263789
|
}
|
|
263280
263790
|
|
|
263281
263791
|
/*
|
|
@@ -265669,8 +266179,14 @@ static int fts5PorterCreate(
|
|
|
265669
266179
|
const char *zBase = "unicode61";
|
|
265670
266180
|
fts5_tokenizer_v2 *pV2 = 0;
|
|
265671
266181
|
|
|
265672
|
-
|
|
265673
|
-
|
|
266182
|
+
while( nArg>0 ){
|
|
266183
|
+
if( sqlite3_stricmp(azArg[0],"porter")==0 ){
|
|
266184
|
+
nArg--;
|
|
266185
|
+
azArg++;
|
|
266186
|
+
}else{
|
|
266187
|
+
zBase = azArg[0];
|
|
266188
|
+
break;
|
|
266189
|
+
}
|
|
265674
266190
|
}
|
|
265675
266191
|
|
|
265676
266192
|
pRet = (PorterTokenizer*)sqlite3_malloc64(sizeof(PorterTokenizer));
|