extralite-bundle 2.8 → 2.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +1 -1
- data/examples/pubsub_store_polyphony.rb +5 -5
- data/ext/extralite/database.c +6 -0
- data/ext/sqlite3/sqlite3.c +494 -198
- data/ext/sqlite3/sqlite3.h +22 -3
- data/lib/extralite/version.rb +1 -1
- data/test/test_database.rb +45 -3
- metadata +2 -2
data/ext/sqlite3/sqlite3.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/******************************************************************************
|
2
2
|
** This file is an amalgamation of many separate C source files from SQLite
|
3
|
-
** version 3.45.
|
3
|
+
** version 3.45.3. 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
|
+
** 8653b758870e6ef0c98d46b3ace27849054a.
|
22
22
|
*/
|
23
23
|
#define SQLITE_CORE 1
|
24
24
|
#define SQLITE_AMALGAMATION 1
|
@@ -459,9 +459,9 @@ extern "C" {
|
|
459
459
|
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
460
460
|
** [sqlite_version()] and [sqlite_source_id()].
|
461
461
|
*/
|
462
|
-
#define SQLITE_VERSION "3.45.
|
463
|
-
#define SQLITE_VERSION_NUMBER
|
464
|
-
#define SQLITE_SOURCE_ID "2024-
|
462
|
+
#define SQLITE_VERSION "3.45.3"
|
463
|
+
#define SQLITE_VERSION_NUMBER 3045003
|
464
|
+
#define SQLITE_SOURCE_ID "2024-04-15 13:34:05 8653b758870e6ef0c98d46b3ace27849054af85da891eb121e9aaa537f1e8355"
|
465
465
|
|
466
466
|
/*
|
467
467
|
** CAPI3REF: Run-Time Library Version Numbers
|
@@ -733,6 +733,8 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
|
|
733
733
|
** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running.
|
734
734
|
** <li> The application must not modify the SQL statement text passed into
|
735
735
|
** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
|
736
|
+
** <li> The application must not dereference the arrays or string pointers
|
737
|
+
** passed as the 3rd and 4th callback parameters after it returns.
|
736
738
|
** </ul>
|
737
739
|
*/
|
738
740
|
SQLITE_API int sqlite3_exec(
|
@@ -2454,6 +2456,22 @@ struct sqlite3_mem_methods {
|
|
2454
2456
|
** configuration setting is never used, then the default maximum is determined
|
2455
2457
|
** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option. If that
|
2456
2458
|
** compile-time option is not set, then the default maximum is 1073741824.
|
2459
|
+
**
|
2460
|
+
** [[SQLITE_CONFIG_ROWID_IN_VIEW]]
|
2461
|
+
** <dt>SQLITE_CONFIG_ROWID_IN_VIEW
|
2462
|
+
** <dd>The SQLITE_CONFIG_ROWID_IN_VIEW option enables or disables the ability
|
2463
|
+
** for VIEWs to have a ROWID. The capability can only be enabled if SQLite is
|
2464
|
+
** compiled with -DSQLITE_ALLOW_ROWID_IN_VIEW, in which case the capability
|
2465
|
+
** defaults to on. This configuration option queries the current setting or
|
2466
|
+
** changes the setting to off or on. The argument is a pointer to an integer.
|
2467
|
+
** If that integer initially holds a value of 1, then the ability for VIEWs to
|
2468
|
+
** have ROWIDs is activated. If the integer initially holds zero, then the
|
2469
|
+
** ability is deactivated. Any other initial value for the integer leaves the
|
2470
|
+
** setting unchanged. After changes, if any, the integer is written with
|
2471
|
+
** a 1 or 0, if the ability for VIEWs to have ROWIDs is on or off. If SQLite
|
2472
|
+
** is compiled without -DSQLITE_ALLOW_ROWID_IN_VIEW (which is the usual and
|
2473
|
+
** recommended case) then the integer is always filled with zero, regardless
|
2474
|
+
** if its initial value.
|
2457
2475
|
** </dl>
|
2458
2476
|
*/
|
2459
2477
|
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
|
@@ -2485,6 +2503,7 @@ struct sqlite3_mem_methods {
|
|
2485
2503
|
#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */
|
2486
2504
|
#define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */
|
2487
2505
|
#define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */
|
2506
|
+
#define SQLITE_CONFIG_ROWID_IN_VIEW 30 /* int* */
|
2488
2507
|
|
2489
2508
|
/*
|
2490
2509
|
** CAPI3REF: Database Connection Configuration Options
|
@@ -15097,6 +15116,7 @@ SQLITE_PRIVATE u32 sqlite3TreeTrace;
|
|
15097
15116
|
** 0x00010000 Beginning of DELETE/INSERT/UPDATE processing
|
15098
15117
|
** 0x00020000 Transform DISTINCT into GROUP BY
|
15099
15118
|
** 0x00040000 SELECT tree dump after all code has been generated
|
15119
|
+
** 0x00080000 NOT NULL strength reduction
|
15100
15120
|
*/
|
15101
15121
|
|
15102
15122
|
/*
|
@@ -18427,6 +18447,15 @@ struct Table {
|
|
18427
18447
|
#define HasRowid(X) (((X)->tabFlags & TF_WithoutRowid)==0)
|
18428
18448
|
#define VisibleRowid(X) (((X)->tabFlags & TF_NoVisibleRowid)==0)
|
18429
18449
|
|
18450
|
+
/* Macro is true if the SQLITE_ALLOW_ROWID_IN_VIEW (mis-)feature is
|
18451
|
+
** available. By default, this macro is false
|
18452
|
+
*/
|
18453
|
+
#ifndef SQLITE_ALLOW_ROWID_IN_VIEW
|
18454
|
+
# define ViewCanHaveRowid 0
|
18455
|
+
#else
|
18456
|
+
# define ViewCanHaveRowid (sqlite3Config.mNoVisibleRowid==0)
|
18457
|
+
#endif
|
18458
|
+
|
18430
18459
|
/*
|
18431
18460
|
** Each foreign key constraint is an instance of the following structure.
|
18432
18461
|
**
|
@@ -19346,6 +19375,7 @@ struct NameContext {
|
|
19346
19375
|
#define NC_InAggFunc 0x020000 /* True if analyzing arguments to an agg func */
|
19347
19376
|
#define NC_FromDDL 0x040000 /* SQL text comes from sqlite_schema */
|
19348
19377
|
#define NC_NoSelect 0x080000 /* Do not descend into sub-selects */
|
19378
|
+
#define NC_Where 0x100000 /* Processing WHERE clause of a SELECT */
|
19349
19379
|
#define NC_OrderAgg 0x8000000 /* Has an aggregate other than count/min/max */
|
19350
19380
|
|
19351
19381
|
/*
|
@@ -19369,6 +19399,7 @@ struct Upsert {
|
|
19369
19399
|
Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */
|
19370
19400
|
Upsert *pNextUpsert; /* Next ON CONFLICT clause in the list */
|
19371
19401
|
u8 isDoUpdate; /* True for DO UPDATE. False for DO NOTHING */
|
19402
|
+
u8 isDup; /* True if 2nd or later with same pUpsertIdx */
|
19372
19403
|
/* Above this point is the parse tree for the ON CONFLICT clauses.
|
19373
19404
|
** The next group of fields stores intermediate data. */
|
19374
19405
|
void *pToFree; /* Free memory when deleting the Upsert object */
|
@@ -20139,6 +20170,11 @@ struct Sqlite3Config {
|
|
20139
20170
|
#endif
|
20140
20171
|
#ifndef SQLITE_UNTESTABLE
|
20141
20172
|
int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
|
20173
|
+
#endif
|
20174
|
+
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
|
20175
|
+
u32 mNoVisibleRowid; /* TF_NoVisibleRowid if the ROWID_IN_VIEW
|
20176
|
+
** feature is disabled. 0 if rowids can
|
20177
|
+
** occur in views. */
|
20142
20178
|
#endif
|
20143
20179
|
int bLocaltimeFault; /* True to fail localtime() calls */
|
20144
20180
|
int (*xAltLocaltime)(const void*,void*); /* Alternative localtime() routine */
|
@@ -20595,10 +20631,13 @@ SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex*);
|
|
20595
20631
|
# define EXP754 (((u64)0x7ff)<<52)
|
20596
20632
|
# define MAN754 ((((u64)1)<<52)-1)
|
20597
20633
|
# define IsNaN(X) (((X)&EXP754)==EXP754 && ((X)&MAN754)!=0)
|
20634
|
+
# define IsOvfl(X) (((X)&EXP754)==EXP754)
|
20598
20635
|
SQLITE_PRIVATE int sqlite3IsNaN(double);
|
20636
|
+
SQLITE_PRIVATE int sqlite3IsOverflow(double);
|
20599
20637
|
#else
|
20600
|
-
# define IsNaN(X)
|
20601
|
-
# define sqlite3IsNaN(X)
|
20638
|
+
# define IsNaN(X) 0
|
20639
|
+
# define sqlite3IsNaN(X) 0
|
20640
|
+
# define sqlite3IsOVerflow(X) 0
|
20602
20641
|
#endif
|
20603
20642
|
|
20604
20643
|
/*
|
@@ -21444,7 +21483,7 @@ SQLITE_PRIVATE With *sqlite3WithPush(Parse*, With*, u8);
|
|
21444
21483
|
SQLITE_PRIVATE Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*,Upsert*);
|
21445
21484
|
SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3*,Upsert*);
|
21446
21485
|
SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3*,Upsert*);
|
21447
|
-
SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*);
|
21486
|
+
SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*,Upsert*);
|
21448
21487
|
SQLITE_PRIVATE void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int);
|
21449
21488
|
SQLITE_PRIVATE Upsert *sqlite3UpsertOfIndex(Upsert*,Index*);
|
21450
21489
|
SQLITE_PRIVATE int sqlite3UpsertNextIsIPK(Upsert*);
|
@@ -21834,6 +21873,9 @@ static const char * const sqlite3azCompileOpt[] = {
|
|
21834
21873
|
"ALLOW_COVERING_INDEX_SCAN=" CTIMEOPT_VAL(SQLITE_ALLOW_COVERING_INDEX_SCAN),
|
21835
21874
|
# endif
|
21836
21875
|
#endif
|
21876
|
+
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
|
21877
|
+
"ALLOW_ROWID_IN_VIEW",
|
21878
|
+
#endif
|
21837
21879
|
#ifdef SQLITE_ALLOW_URI_AUTHORITY
|
21838
21880
|
"ALLOW_URI_AUTHORITY",
|
21839
21881
|
#endif
|
@@ -22853,6 +22895,9 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
|
|
22853
22895
|
#endif
|
22854
22896
|
#ifndef SQLITE_UNTESTABLE
|
22855
22897
|
0, /* xTestCallback */
|
22898
|
+
#endif
|
22899
|
+
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
|
22900
|
+
0, /* mNoVisibleRowid. 0 == allow rowid-in-view */
|
22856
22901
|
#endif
|
22857
22902
|
0, /* bLocaltimeFault */
|
22858
22903
|
0, /* xAltLocaltime */
|
@@ -31309,6 +31354,7 @@ SQLITE_API void sqlite3_str_vappendf(
|
|
31309
31354
|
if( xtype==etFLOAT ){
|
31310
31355
|
iRound = -precision;
|
31311
31356
|
}else if( xtype==etGENERIC ){
|
31357
|
+
if( precision==0 ) precision = 1;
|
31312
31358
|
iRound = precision;
|
31313
31359
|
}else{
|
31314
31360
|
iRound = precision+1;
|
@@ -34640,6 +34686,19 @@ SQLITE_PRIVATE int sqlite3IsNaN(double x){
|
|
34640
34686
|
}
|
34641
34687
|
#endif /* SQLITE_OMIT_FLOATING_POINT */
|
34642
34688
|
|
34689
|
+
#ifndef SQLITE_OMIT_FLOATING_POINT
|
34690
|
+
/*
|
34691
|
+
** Return true if the floating point value is NaN or +Inf or -Inf.
|
34692
|
+
*/
|
34693
|
+
SQLITE_PRIVATE int sqlite3IsOverflow(double x){
|
34694
|
+
int rc; /* The value return */
|
34695
|
+
u64 y;
|
34696
|
+
memcpy(&y,&x,sizeof(y));
|
34697
|
+
rc = IsOvfl(y);
|
34698
|
+
return rc;
|
34699
|
+
}
|
34700
|
+
#endif /* SQLITE_OMIT_FLOATING_POINT */
|
34701
|
+
|
34643
34702
|
/*
|
34644
34703
|
** Compute a string length that is limited to what can be stored in
|
34645
34704
|
** lower 30 bits of a 32-bit signed integer.
|
@@ -35199,6 +35258,9 @@ do_atof_calc:
|
|
35199
35258
|
u64 s2;
|
35200
35259
|
rr[0] = (double)s;
|
35201
35260
|
s2 = (u64)rr[0];
|
35261
|
+
#if defined(_MSC_VER) && _MSC_VER<1700
|
35262
|
+
if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); }
|
35263
|
+
#endif
|
35202
35264
|
rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s);
|
35203
35265
|
if( e>0 ){
|
35204
35266
|
while( e>=100 ){
|
@@ -35641,7 +35703,7 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou
|
|
35641
35703
|
assert( p->n>0 );
|
35642
35704
|
assert( p->n<sizeof(p->zBuf) );
|
35643
35705
|
p->iDP = p->n + exp;
|
35644
|
-
if( iRound
|
35706
|
+
if( iRound<=0 ){
|
35645
35707
|
iRound = p->iDP - iRound;
|
35646
35708
|
if( iRound==0 && p->zBuf[i+1]>='5' ){
|
35647
35709
|
iRound = 1;
|
@@ -43408,11 +43470,16 @@ static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
|
|
43408
43470
|
|
43409
43471
|
#if SQLITE_MAX_MMAP_SIZE>0
|
43410
43472
|
if( pFd->mmapSizeMax>0 ){
|
43473
|
+
/* Ensure that there is always at least a 256 byte buffer of addressable
|
43474
|
+
** memory following the returned page. If the database is corrupt,
|
43475
|
+
** SQLite may overread the page slightly (in practice only a few bytes,
|
43476
|
+
** but 256 is safe, round, number). */
|
43477
|
+
const int nEofBuffer = 256;
|
43411
43478
|
if( pFd->pMapRegion==0 ){
|
43412
43479
|
int rc = unixMapfile(pFd, -1);
|
43413
43480
|
if( rc!=SQLITE_OK ) return rc;
|
43414
43481
|
}
|
43415
|
-
if( pFd->mmapSize >= iOff+nAmt ){
|
43482
|
+
if( pFd->mmapSize >= (iOff+nAmt+nEofBuffer) ){
|
43416
43483
|
*pp = &((u8 *)pFd->pMapRegion)[iOff];
|
43417
43484
|
pFd->nFetchOut++;
|
43418
43485
|
}
|
@@ -50765,6 +50832,11 @@ static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
|
|
50765
50832
|
|
50766
50833
|
#if SQLITE_MAX_MMAP_SIZE>0
|
50767
50834
|
if( pFd->mmapSizeMax>0 ){
|
50835
|
+
/* Ensure that there is always at least a 256 byte buffer of addressable
|
50836
|
+
** memory following the returned page. If the database is corrupt,
|
50837
|
+
** SQLite may overread the page slightly (in practice only a few bytes,
|
50838
|
+
** but 256 is safe, round, number). */
|
50839
|
+
const int nEofBuffer = 256;
|
50768
50840
|
if( pFd->pMapRegion==0 ){
|
50769
50841
|
int rc = winMapfile(pFd, -1);
|
50770
50842
|
if( rc!=SQLITE_OK ){
|
@@ -50773,7 +50845,7 @@ static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
|
|
50773
50845
|
return rc;
|
50774
50846
|
}
|
50775
50847
|
}
|
50776
|
-
if( pFd->mmapSize >= iOff+nAmt ){
|
50848
|
+
if( pFd->mmapSize >= (iOff+nAmt+nEofBuffer) ){
|
50777
50849
|
assert( pFd->pMapRegion!=0 );
|
50778
50850
|
*pp = &((u8 *)pFd->pMapRegion)[iOff];
|
50779
50851
|
pFd->nFetchOut++;
|
@@ -53252,6 +53324,14 @@ SQLITE_API unsigned char *sqlite3_serialize(
|
|
53252
53324
|
pOut = 0;
|
53253
53325
|
}else{
|
53254
53326
|
sz = sqlite3_column_int64(pStmt, 0)*szPage;
|
53327
|
+
if( sz==0 ){
|
53328
|
+
sqlite3_reset(pStmt);
|
53329
|
+
sqlite3_exec(db, "BEGIN IMMEDIATE; COMMIT;", 0, 0, 0);
|
53330
|
+
rc = sqlite3_step(pStmt);
|
53331
|
+
if( rc==SQLITE_ROW ){
|
53332
|
+
sz = sqlite3_column_int64(pStmt, 0)*szPage;
|
53333
|
+
}
|
53334
|
+
}
|
53255
53335
|
if( piSize ) *piSize = sz;
|
53256
53336
|
if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
|
53257
53337
|
pOut = 0;
|
@@ -63775,7 +63855,7 @@ SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){
|
|
63775
63855
|
** This will be either the rollback journal or the WAL file.
|
63776
63856
|
*/
|
63777
63857
|
SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){
|
63778
|
-
#
|
63858
|
+
#ifdef SQLITE_OMIT_WAL
|
63779
63859
|
return pPager->jfd;
|
63780
63860
|
#else
|
63781
63861
|
return pPager->pWal ? sqlite3WalFile(pPager->pWal) : pPager->jfd;
|
@@ -76402,7 +76482,10 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){
|
|
76402
76482
|
}
|
76403
76483
|
|
76404
76484
|
pPage = pCur->pPage;
|
76405
|
-
|
76485
|
+
if( sqlite3FaultSim(412) ) pPage->isInit = 0;
|
76486
|
+
if( !pPage->isInit ){
|
76487
|
+
return SQLITE_CORRUPT_BKPT;
|
76488
|
+
}
|
76406
76489
|
if( !pPage->leaf ){
|
76407
76490
|
int idx = pCur->ix;
|
76408
76491
|
rc = moveToChild(pCur, get4byte(findCell(pPage, idx)));
|
@@ -77075,7 +77158,10 @@ static int fillInCell(
|
|
77075
77158
|
n = nHeader + nPayload;
|
77076
77159
|
testcase( n==3 );
|
77077
77160
|
testcase( n==4 );
|
77078
|
-
if( n<4 )
|
77161
|
+
if( n<4 ){
|
77162
|
+
n = 4;
|
77163
|
+
pPayload[nPayload] = 0;
|
77164
|
+
}
|
77079
77165
|
*pnSize = n;
|
77080
77166
|
assert( nSrc<=nPayload );
|
77081
77167
|
testcase( nSrc<nPayload );
|
@@ -79521,7 +79607,10 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
|
|
79521
79607
|
if( flags & BTREE_PREFORMAT ){
|
79522
79608
|
rc = SQLITE_OK;
|
79523
79609
|
szNew = p->pBt->nPreformatSize;
|
79524
|
-
if( szNew<4 )
|
79610
|
+
if( szNew<4 ){
|
79611
|
+
szNew = 4;
|
79612
|
+
newCell[3] = 0;
|
79613
|
+
}
|
79525
79614
|
if( ISAUTOVACUUM(p->pBt) && szNew>pPage->maxLocal ){
|
79526
79615
|
CellInfo info;
|
79527
79616
|
pPage->xParseCell(pPage, newCell, &info);
|
@@ -79583,7 +79672,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
|
|
79583
79672
|
}else if( loc<0 && pPage->nCell>0 ){
|
79584
79673
|
assert( pPage->leaf );
|
79585
79674
|
idx = ++pCur->ix;
|
79586
|
-
pCur->curFlags &= ~BTCF_ValidNKey;
|
79675
|
+
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
|
79587
79676
|
}else{
|
79588
79677
|
assert( pPage->leaf );
|
79589
79678
|
}
|
@@ -79613,7 +79702,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
|
|
79613
79702
|
*/
|
79614
79703
|
if( pPage->nOverflow ){
|
79615
79704
|
assert( rc==SQLITE_OK );
|
79616
|
-
pCur->curFlags &= ~(BTCF_ValidNKey);
|
79705
|
+
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
|
79617
79706
|
rc = balance(pCur);
|
79618
79707
|
|
79619
79708
|
/* Must make sure nOverflow is reset to zero even if the balance()
|
@@ -88366,6 +88455,23 @@ static void serialGet(
|
|
88366
88455
|
pMem->flags = IsNaN(x) ? MEM_Null : MEM_Real;
|
88367
88456
|
}
|
88368
88457
|
}
|
88458
|
+
static int serialGet7(
|
88459
|
+
const unsigned char *buf, /* Buffer to deserialize from */
|
88460
|
+
Mem *pMem /* Memory cell to write value into */
|
88461
|
+
){
|
88462
|
+
u64 x = FOUR_BYTE_UINT(buf);
|
88463
|
+
u32 y = FOUR_BYTE_UINT(buf+4);
|
88464
|
+
x = (x<<32) + y;
|
88465
|
+
assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 );
|
88466
|
+
swapMixedEndianFloat(x);
|
88467
|
+
memcpy(&pMem->u.r, &x, sizeof(x));
|
88468
|
+
if( IsNaN(x) ){
|
88469
|
+
pMem->flags = MEM_Null;
|
88470
|
+
return 1;
|
88471
|
+
}
|
88472
|
+
pMem->flags = MEM_Real;
|
88473
|
+
return 0;
|
88474
|
+
}
|
88369
88475
|
SQLITE_PRIVATE void sqlite3VdbeSerialGet(
|
88370
88476
|
const unsigned char *buf, /* Buffer to deserialize from */
|
88371
88477
|
u32 serial_type, /* Serial type to deserialize */
|
@@ -89045,7 +89151,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
|
|
89045
89151
|
}else if( serial_type==0 ){
|
89046
89152
|
rc = -1;
|
89047
89153
|
}else if( serial_type==7 ){
|
89048
|
-
|
89154
|
+
serialGet7(&aKey1[d1], &mem1);
|
89049
89155
|
rc = -sqlite3IntFloatCompare(pRhs->u.i, mem1.u.r);
|
89050
89156
|
}else{
|
89051
89157
|
i64 lhs = vdbeRecordDecodeInt(serial_type, &aKey1[d1]);
|
@@ -89070,14 +89176,18 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
|
|
89070
89176
|
}else if( serial_type==0 ){
|
89071
89177
|
rc = -1;
|
89072
89178
|
}else{
|
89073
|
-
sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
|
89074
89179
|
if( serial_type==7 ){
|
89075
|
-
if( mem1
|
89180
|
+
if( serialGet7(&aKey1[d1], &mem1) ){
|
89181
|
+
rc = -1; /* mem1 is a NaN */
|
89182
|
+
}else if( mem1.u.r<pRhs->u.r ){
|
89076
89183
|
rc = -1;
|
89077
89184
|
}else if( mem1.u.r>pRhs->u.r ){
|
89078
89185
|
rc = +1;
|
89186
|
+
}else{
|
89187
|
+
assert( rc==0 );
|
89079
89188
|
}
|
89080
89189
|
}else{
|
89190
|
+
sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
|
89081
89191
|
rc = sqlite3IntFloatCompare(mem1.u.i, pRhs->u.r);
|
89082
89192
|
}
|
89083
89193
|
}
|
@@ -89147,7 +89257,14 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
|
|
89147
89257
|
/* RHS is null */
|
89148
89258
|
else{
|
89149
89259
|
serial_type = aKey1[idx1];
|
89150
|
-
|
89260
|
+
if( serial_type==0
|
89261
|
+
|| serial_type==10
|
89262
|
+
|| (serial_type==7 && serialGet7(&aKey1[d1], &mem1)!=0)
|
89263
|
+
){
|
89264
|
+
assert( rc==0 );
|
89265
|
+
}else{
|
89266
|
+
rc = 1;
|
89267
|
+
}
|
89151
89268
|
}
|
89152
89269
|
|
89153
89270
|
if( rc!=0 ){
|
@@ -94845,7 +94962,9 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
|
|
94845
94962
|
}
|
94846
94963
|
}
|
94847
94964
|
}else if( affinity==SQLITE_AFF_TEXT && ((flags1 | flags3) & MEM_Str)!=0 ){
|
94848
|
-
if( (flags1 & MEM_Str)
|
94965
|
+
if( (flags1 & MEM_Str)!=0 ){
|
94966
|
+
pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal);
|
94967
|
+
}else if( (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
|
94849
94968
|
testcase( pIn1->flags & MEM_Int );
|
94850
94969
|
testcase( pIn1->flags & MEM_Real );
|
94851
94970
|
testcase( pIn1->flags & MEM_IntReal );
|
@@ -94854,7 +94973,9 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
|
|
94854
94973
|
flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
|
94855
94974
|
if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str;
|
94856
94975
|
}
|
94857
|
-
if( (flags3 & MEM_Str)
|
94976
|
+
if( (flags3 & MEM_Str)!=0 ){
|
94977
|
+
pIn3->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal);
|
94978
|
+
}else if( (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
|
94858
94979
|
testcase( pIn3->flags & MEM_Int );
|
94859
94980
|
testcase( pIn3->flags & MEM_Real );
|
94860
94981
|
testcase( pIn3->flags & MEM_IntReal );
|
@@ -106199,6 +106320,8 @@ static void resolveAlias(
|
|
106199
106320
|
assert( iCol>=0 && iCol<pEList->nExpr );
|
106200
106321
|
pOrig = pEList->a[iCol].pExpr;
|
106201
106322
|
assert( pOrig!=0 );
|
106323
|
+
assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) );
|
106324
|
+
if( pExpr->pAggInfo ) return;
|
106202
106325
|
db = pParse->db;
|
106203
106326
|
pDup = sqlite3ExprDup(db, pOrig, 0);
|
106204
106327
|
if( db->mallocFailed ){
|
@@ -106586,8 +106709,37 @@ static int lookupName(
|
|
106586
106709
|
}
|
106587
106710
|
}
|
106588
106711
|
if( 0==cnt && VisibleRowid(pTab) ){
|
106712
|
+
/* pTab is a potential ROWID match. Keep track of it and match
|
106713
|
+
** the ROWID later if that seems appropriate. (Search for "cntTab"
|
106714
|
+
** to find related code.) Only allow a ROWID match if there is
|
106715
|
+
** a single ROWID match candidate.
|
106716
|
+
*/
|
106717
|
+
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
|
106718
|
+
/* In SQLITE_ALLOW_ROWID_IN_VIEW mode, allow a ROWID match
|
106719
|
+
** if there is a single VIEW candidate or if there is a single
|
106720
|
+
** non-VIEW candidate plus multiple VIEW candidates. In other
|
106721
|
+
** words non-VIEW candidate terms take precedence over VIEWs.
|
106722
|
+
*/
|
106723
|
+
if( cntTab==0
|
106724
|
+
|| (cntTab==1
|
106725
|
+
&& ALWAYS(pMatch!=0)
|
106726
|
+
&& ALWAYS(pMatch->pTab!=0)
|
106727
|
+
&& (pMatch->pTab->tabFlags & TF_Ephemeral)!=0
|
106728
|
+
&& (pTab->tabFlags & TF_Ephemeral)==0)
|
106729
|
+
){
|
106730
|
+
cntTab = 1;
|
106731
|
+
pMatch = pItem;
|
106732
|
+
}else{
|
106733
|
+
cntTab++;
|
106734
|
+
}
|
106735
|
+
#else
|
106736
|
+
/* The (much more common) non-SQLITE_ALLOW_ROWID_IN_VIEW case is
|
106737
|
+
** simpler since we require exactly one candidate, which will
|
106738
|
+
** always be a non-VIEW
|
106739
|
+
*/
|
106589
106740
|
cntTab++;
|
106590
106741
|
pMatch = pItem;
|
106742
|
+
#endif
|
106591
106743
|
}
|
106592
106744
|
}
|
106593
106745
|
if( pMatch ){
|
@@ -106713,13 +106865,13 @@ static int lookupName(
|
|
106713
106865
|
** Perhaps the name is a reference to the ROWID
|
106714
106866
|
*/
|
106715
106867
|
if( cnt==0
|
106716
|
-
&& cntTab
|
106868
|
+
&& cntTab>=1
|
106717
106869
|
&& pMatch
|
106718
106870
|
&& (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0
|
106719
106871
|
&& sqlite3IsRowid(zCol)
|
106720
106872
|
&& ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom)
|
106721
106873
|
){
|
106722
|
-
cnt =
|
106874
|
+
cnt = cntTab;
|
106723
106875
|
if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1;
|
106724
106876
|
pExpr->affExpr = SQLITE_AFF_INTEGER;
|
106725
106877
|
}
|
@@ -107084,6 +107236,19 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
|
107084
107236
|
** resolved. This prevents "column" from being counted as having been
|
107085
107237
|
** referenced, which might prevent a SELECT from being erroneously
|
107086
107238
|
** marked as correlated.
|
107239
|
+
**
|
107240
|
+
** 2024-03-28: Beware of aggregates. A bare column of aggregated table
|
107241
|
+
** can still evaluate to NULL even though it is marked as NOT NULL.
|
107242
|
+
** Example:
|
107243
|
+
**
|
107244
|
+
** CREATE TABLE t1(a INT NOT NULL);
|
107245
|
+
** SELECT a, a IS NULL, a IS NOT NULL, count(*) FROM t1;
|
107246
|
+
**
|
107247
|
+
** The "a IS NULL" and "a IS NOT NULL" expressions cannot be optimized
|
107248
|
+
** here because at the time this case is hit, we do not yet know whether
|
107249
|
+
** or not t1 is being aggregated. We have to assume the worst and omit
|
107250
|
+
** the optimization. The only time it is safe to apply this optimization
|
107251
|
+
** is within the WHERE clause.
|
107087
107252
|
*/
|
107088
107253
|
case TK_NOTNULL:
|
107089
107254
|
case TK_ISNULL: {
|
@@ -107094,19 +107259,36 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
|
107094
107259
|
anRef[i] = p->nRef;
|
107095
107260
|
}
|
107096
107261
|
sqlite3WalkExpr(pWalker, pExpr->pLeft);
|
107097
|
-
if(
|
107098
|
-
|
107099
|
-
|
107100
|
-
|
107101
|
-
|
107102
|
-
pExpr->op = TK_INTEGER;
|
107262
|
+
if( IN_RENAME_OBJECT ) return WRC_Prune;
|
107263
|
+
if( sqlite3ExprCanBeNull(pExpr->pLeft) ){
|
107264
|
+
/* The expression can be NULL. So the optimization does not apply */
|
107265
|
+
return WRC_Prune;
|
107266
|
+
}
|
107103
107267
|
|
107104
|
-
|
107105
|
-
|
107268
|
+
for(i=0, p=pNC; p; p=p->pNext, i++){
|
107269
|
+
if( (p->ncFlags & NC_Where)==0 ){
|
107270
|
+
return WRC_Prune; /* Not in a WHERE clause. Unsafe to optimize. */
|
107106
107271
|
}
|
107107
|
-
sqlite3ExprDelete(pParse->db, pExpr->pLeft);
|
107108
|
-
pExpr->pLeft = 0;
|
107109
107272
|
}
|
107273
|
+
testcase( ExprHasProperty(pExpr, EP_OuterON) );
|
107274
|
+
assert( !ExprHasProperty(pExpr, EP_IntValue) );
|
107275
|
+
#if TREETRACE_ENABLED
|
107276
|
+
if( sqlite3TreeTrace & 0x80000 ){
|
107277
|
+
sqlite3DebugPrintf(
|
107278
|
+
"NOT NULL strength reduction converts the following to %d:\n",
|
107279
|
+
pExpr->op==TK_NOTNULL
|
107280
|
+
);
|
107281
|
+
sqlite3ShowExpr(pExpr);
|
107282
|
+
}
|
107283
|
+
#endif /* TREETRACE_ENABLED */
|
107284
|
+
pExpr->u.iValue = (pExpr->op==TK_NOTNULL);
|
107285
|
+
pExpr->flags |= EP_IntValue;
|
107286
|
+
pExpr->op = TK_INTEGER;
|
107287
|
+
for(i=0, p=pNC; p && i<ArraySize(anRef); p=p->pNext, i++){
|
107288
|
+
p->nRef = anRef[i];
|
107289
|
+
}
|
107290
|
+
sqlite3ExprDelete(pParse->db, pExpr->pLeft);
|
107291
|
+
pExpr->pLeft = 0;
|
107110
107292
|
return WRC_Prune;
|
107111
107293
|
}
|
107112
107294
|
|
@@ -108006,7 +108188,9 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
|
108006
108188
|
}
|
108007
108189
|
if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort;
|
108008
108190
|
}
|
108191
|
+
sNC.ncFlags |= NC_Where;
|
108009
108192
|
if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;
|
108193
|
+
sNC.ncFlags &= ~NC_Where;
|
108010
108194
|
|
108011
108195
|
/* Resolve names in table-valued-function arguments */
|
108012
108196
|
for(i=0; i<p->pSrc->nSrc; i++){
|
@@ -108545,9 +108729,10 @@ SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
|
|
108545
108729
|
assert( pExpr->x.pList->nExpr>0 );
|
108546
108730
|
assert( pExpr->op==TK_FUNCTION );
|
108547
108731
|
pExpr = pExpr->x.pList->a[0].pExpr;
|
108548
|
-
}else{
|
108549
|
-
assert( pExpr->op==TK_COLLATE );
|
108732
|
+
}else if( pExpr->op==TK_COLLATE ){
|
108550
108733
|
pExpr = pExpr->pLeft;
|
108734
|
+
}else{
|
108735
|
+
break;
|
108551
108736
|
}
|
108552
108737
|
}
|
108553
108738
|
return pExpr;
|
@@ -111066,9 +111251,12 @@ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){
|
|
111066
111251
|
return 0;
|
111067
111252
|
case TK_COLUMN:
|
111068
111253
|
assert( ExprUseYTab(p) );
|
111069
|
-
return ExprHasProperty(p, EP_CanBeNull)
|
111070
|
-
|
111071
|
-
|
111254
|
+
return ExprHasProperty(p, EP_CanBeNull)
|
111255
|
+
|| NEVER(p->y.pTab==0) /* Reference to column of index on expr */
|
111256
|
+
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
|
111257
|
+
|| (p->iColumn==XN_ROWID && IsView(p->y.pTab))
|
111258
|
+
#endif
|
111259
|
+
|| (p->iColumn>=0
|
111072
111260
|
&& p->y.pTab->aCol!=0 /* Possible due to prior error */
|
111073
111261
|
&& ALWAYS(p->iColumn<p->y.pTab->nCol)
|
111074
111262
|
&& p->y.pTab->aCol[p->iColumn].notNull==0);
|
@@ -123559,9 +123747,12 @@ SQLITE_PRIVATE void sqlite3CreateView(
|
|
123559
123747
|
** on a view, even though views do not have rowids. The following flag
|
123560
123748
|
** setting fixes this problem. But the fix can be disabled by compiling
|
123561
123749
|
** with -DSQLITE_ALLOW_ROWID_IN_VIEW in case there are legacy apps that
|
123562
|
-
** depend upon the old buggy behavior.
|
123563
|
-
|
123564
|
-
|
123750
|
+
** depend upon the old buggy behavior. The ability can also be toggled
|
123751
|
+
** using sqlite3_config(SQLITE_CONFIG_ROWID_IN_VIEW,...) */
|
123752
|
+
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
|
123753
|
+
p->tabFlags |= sqlite3Config.mNoVisibleRowid; /* Optional. Allow by default */
|
123754
|
+
#else
|
123755
|
+
p->tabFlags |= TF_NoVisibleRowid; /* Never allow rowid in view */
|
123565
123756
|
#endif
|
123566
123757
|
|
123567
123758
|
sqlite3TwoPartName(pParse, pName1, pName2, &pName);
|
@@ -128934,13 +129125,13 @@ SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue){
|
|
128934
129125
|
double r1, r2;
|
128935
129126
|
const char *zVal;
|
128936
129127
|
r1 = sqlite3_value_double(pValue);
|
128937
|
-
sqlite3_str_appendf(pStr, "
|
129128
|
+
sqlite3_str_appendf(pStr, "%!0.15g", r1);
|
128938
129129
|
zVal = sqlite3_str_value(pStr);
|
128939
129130
|
if( zVal ){
|
128940
129131
|
sqlite3AtoF(zVal, &r2, pStr->nChar, SQLITE_UTF8);
|
128941
129132
|
if( r1!=r2 ){
|
128942
129133
|
sqlite3_str_reset(pStr);
|
128943
|
-
sqlite3_str_appendf(pStr, "
|
129134
|
+
sqlite3_str_appendf(pStr, "%!0.20e", r1);
|
128944
129135
|
}
|
128945
129136
|
}
|
128946
129137
|
break;
|
@@ -129242,7 +129433,7 @@ static void replaceFunc(
|
|
129242
129433
|
}
|
129243
129434
|
if( zPattern[0]==0 ){
|
129244
129435
|
assert( sqlite3_value_type(argv[1])!=SQLITE_NULL );
|
129245
|
-
|
129436
|
+
sqlite3_result_text(context, (const char*)zStr, nStr, SQLITE_TRANSIENT);
|
129246
129437
|
return;
|
129247
129438
|
}
|
129248
129439
|
nPattern = sqlite3_value_bytes(argv[1]);
|
@@ -129725,7 +129916,7 @@ static void sumFinalize(sqlite3_context *context){
|
|
129725
129916
|
if( p->approx ){
|
129726
129917
|
if( p->ovrfl ){
|
129727
129918
|
sqlite3_result_error(context,"integer overflow",-1);
|
129728
|
-
}else if( !
|
129919
|
+
}else if( !sqlite3IsOverflow(p->rErr) ){
|
129729
129920
|
sqlite3_result_double(context, p->rSum+p->rErr);
|
129730
129921
|
}else{
|
129731
129922
|
sqlite3_result_double(context, p->rSum);
|
@@ -129742,7 +129933,7 @@ static void avgFinalize(sqlite3_context *context){
|
|
129742
129933
|
double r;
|
129743
129934
|
if( p->approx ){
|
129744
129935
|
r = p->rSum;
|
129745
|
-
if( !
|
129936
|
+
if( !sqlite3IsOverflow(p->rErr) ) r += p->rErr;
|
129746
129937
|
}else{
|
129747
129938
|
r = (double)(p->iSum);
|
129748
129939
|
}
|
@@ -129756,7 +129947,7 @@ static void totalFinalize(sqlite3_context *context){
|
|
129756
129947
|
if( p ){
|
129757
129948
|
if( p->approx ){
|
129758
129949
|
r = p->rSum;
|
129759
|
-
if( !
|
129950
|
+
if( !sqlite3IsOverflow(p->rErr) ) r += p->rErr;
|
129760
129951
|
}else{
|
129761
129952
|
r = (double)(p->iSum);
|
129762
129953
|
}
|
@@ -133162,7 +133353,7 @@ SQLITE_PRIVATE void sqlite3Insert(
|
|
133162
133353
|
pNx->iDataCur = iDataCur;
|
133163
133354
|
pNx->iIdxCur = iIdxCur;
|
133164
133355
|
if( pNx->pUpsertTarget ){
|
133165
|
-
if( sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx) ){
|
133356
|
+
if( sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx, pUpsert) ){
|
133166
133357
|
goto insert_cleanup;
|
133167
133358
|
}
|
133168
133359
|
}
|
@@ -135054,7 +135245,10 @@ static int xferOptimization(
|
|
135054
135245
|
}
|
135055
135246
|
}
|
135056
135247
|
#ifndef SQLITE_OMIT_CHECK
|
135057
|
-
if( pDest->pCheck
|
135248
|
+
if( pDest->pCheck
|
135249
|
+
&& (db->mDbFlags & DBFLAG_Vacuum)==0
|
135250
|
+
&& sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1)
|
135251
|
+
){
|
135058
135252
|
return 0; /* Tables have different CHECK constraints. Ticket #2252 */
|
135059
135253
|
}
|
135060
135254
|
#endif
|
@@ -139461,31 +139655,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
|
|
139461
139655
|
int mxCol; /* Maximum non-virtual column number */
|
139462
139656
|
|
139463
139657
|
if( pObjTab && pObjTab!=pTab ) continue;
|
139464
|
-
if( !IsOrdinaryTable(pTab) )
|
139465
|
-
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
139466
|
-
sqlite3_vtab *pVTab;
|
139467
|
-
int a1;
|
139468
|
-
if( !IsVirtual(pTab) ) continue;
|
139469
|
-
if( pTab->nCol<=0 ){
|
139470
|
-
const char *zMod = pTab->u.vtab.azArg[0];
|
139471
|
-
if( sqlite3HashFind(&db->aModule, zMod)==0 ) continue;
|
139472
|
-
}
|
139473
|
-
sqlite3ViewGetColumnNames(pParse, pTab);
|
139474
|
-
if( pTab->u.vtab.p==0 ) continue;
|
139475
|
-
pVTab = pTab->u.vtab.p->pVtab;
|
139476
|
-
if( NEVER(pVTab==0) ) continue;
|
139477
|
-
if( NEVER(pVTab->pModule==0) ) continue;
|
139478
|
-
if( pVTab->pModule->iVersion<4 ) continue;
|
139479
|
-
if( pVTab->pModule->xIntegrity==0 ) continue;
|
139480
|
-
sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick);
|
139481
|
-
pTab->nTabRef++;
|
139482
|
-
sqlite3VdbeAppendP4(v, pTab, P4_TABLEREF);
|
139483
|
-
a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v);
|
139484
|
-
integrityCheckResultRow(v);
|
139485
|
-
sqlite3VdbeJumpHere(v, a1);
|
139486
|
-
#endif
|
139487
|
-
continue;
|
139488
|
-
}
|
139658
|
+
if( !IsOrdinaryTable(pTab) ) continue;
|
139489
139659
|
if( isQuick || HasRowid(pTab) ){
|
139490
139660
|
pPk = 0;
|
139491
139661
|
r2 = 0;
|
@@ -139620,6 +139790,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
|
|
139620
139790
|
** is REAL, we have to load the actual data using OP_Column
|
139621
139791
|
** to reliably determine if the value is a NULL. */
|
139622
139792
|
sqlite3VdbeAddOp3(v, OP_Column, p1, p3, 3);
|
139793
|
+
sqlite3ColumnDefault(v, pTab, j, 3);
|
139623
139794
|
jmp3 = sqlite3VdbeAddOp2(v, OP_NotNull, 3, labelOk);
|
139624
139795
|
VdbeCoverage(v);
|
139625
139796
|
}
|
@@ -139810,6 +139981,38 @@ SQLITE_PRIVATE void sqlite3Pragma(
|
|
139810
139981
|
}
|
139811
139982
|
}
|
139812
139983
|
}
|
139984
|
+
|
139985
|
+
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
139986
|
+
/* Second pass to invoke the xIntegrity method on all virtual
|
139987
|
+
** tables.
|
139988
|
+
*/
|
139989
|
+
for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
|
139990
|
+
Table *pTab = sqliteHashData(x);
|
139991
|
+
sqlite3_vtab *pVTab;
|
139992
|
+
int a1;
|
139993
|
+
if( pObjTab && pObjTab!=pTab ) continue;
|
139994
|
+
if( IsOrdinaryTable(pTab) ) continue;
|
139995
|
+
if( !IsVirtual(pTab) ) continue;
|
139996
|
+
if( pTab->nCol<=0 ){
|
139997
|
+
const char *zMod = pTab->u.vtab.azArg[0];
|
139998
|
+
if( sqlite3HashFind(&db->aModule, zMod)==0 ) continue;
|
139999
|
+
}
|
140000
|
+
sqlite3ViewGetColumnNames(pParse, pTab);
|
140001
|
+
if( pTab->u.vtab.p==0 ) continue;
|
140002
|
+
pVTab = pTab->u.vtab.p->pVtab;
|
140003
|
+
if( NEVER(pVTab==0) ) continue;
|
140004
|
+
if( NEVER(pVTab->pModule==0) ) continue;
|
140005
|
+
if( pVTab->pModule->iVersion<4 ) continue;
|
140006
|
+
if( pVTab->pModule->xIntegrity==0 ) continue;
|
140007
|
+
sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick);
|
140008
|
+
pTab->nTabRef++;
|
140009
|
+
sqlite3VdbeAppendP4(v, pTab, P4_TABLEREF);
|
140010
|
+
a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v);
|
140011
|
+
integrityCheckResultRow(v);
|
140012
|
+
sqlite3VdbeJumpHere(v, a1);
|
140013
|
+
continue;
|
140014
|
+
}
|
140015
|
+
#endif
|
139813
140016
|
}
|
139814
140017
|
{
|
139815
140018
|
static const int iLn = VDBE_OFFSET_LINENO(2);
|
@@ -140446,7 +140649,11 @@ static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
|
140446
140649
|
j = seen[0]-1;
|
140447
140650
|
pIdxInfo->aConstraintUsage[j].argvIndex = 1;
|
140448
140651
|
pIdxInfo->aConstraintUsage[j].omit = 1;
|
140449
|
-
if( seen[1]==0 )
|
140652
|
+
if( seen[1]==0 ){
|
140653
|
+
pIdxInfo->estimatedCost = (double)1000;
|
140654
|
+
pIdxInfo->estimatedRows = 1000;
|
140655
|
+
return SQLITE_OK;
|
140656
|
+
}
|
140450
140657
|
pIdxInfo->estimatedCost = (double)20;
|
140451
140658
|
pIdxInfo->estimatedRows = 20;
|
140452
140659
|
j = seen[1]-1;
|
@@ -143673,11 +143880,7 @@ static const char *columnTypeImpl(
|
|
143673
143880
|
** data for the result-set column of the sub-select.
|
143674
143881
|
*/
|
143675
143882
|
if( iCol<pS->pEList->nExpr
|
143676
|
-
|
143677
|
-
&& iCol>=0
|
143678
|
-
#else
|
143679
|
-
&& ALWAYS(iCol>=0)
|
143680
|
-
#endif
|
143883
|
+
&& (!ViewCanHaveRowid || iCol>=0)
|
143681
143884
|
){
|
143682
143885
|
/* If iCol is less than zero, then the expression requests the
|
143683
143886
|
** rowid of the sub-select or view. This expression is legal (see
|
@@ -146852,6 +147055,10 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){
|
|
146852
147055
|
**
|
146853
147056
|
** (11) The subquery is not a VALUES clause
|
146854
147057
|
**
|
147058
|
+
** (12) The WHERE clause is not "rowid ISNULL" or the equivalent. This
|
147059
|
+
** case only comes up if SQLite is compiled using
|
147060
|
+
** SQLITE_ALLOW_ROWID_IN_VIEW.
|
147061
|
+
**
|
146855
147062
|
** Return 0 if no changes are made and non-zero if one or more WHERE clause
|
146856
147063
|
** terms are duplicated into the subquery.
|
146857
147064
|
*/
|
@@ -146962,6 +147169,18 @@ static int pushDownWhereTerms(
|
|
146962
147169
|
}
|
146963
147170
|
#endif
|
146964
147171
|
|
147172
|
+
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
|
147173
|
+
if( ViewCanHaveRowid && (pWhere->op==TK_ISNULL || pWhere->op==TK_NOTNULL) ){
|
147174
|
+
Expr *pLeft = pWhere->pLeft;
|
147175
|
+
if( ALWAYS(pLeft)
|
147176
|
+
&& pLeft->op==TK_COLUMN
|
147177
|
+
&& pLeft->iColumn < 0
|
147178
|
+
){
|
147179
|
+
return 0; /* Restriction (12) */
|
147180
|
+
}
|
147181
|
+
}
|
147182
|
+
#endif
|
147183
|
+
|
146965
147184
|
if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc) ){
|
146966
147185
|
nChng++;
|
146967
147186
|
pSubq->selFlags |= SF_PushDown;
|
@@ -147589,12 +147808,14 @@ SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){
|
|
147589
147808
|
while( pSel->pPrior ){ pSel = pSel->pPrior; }
|
147590
147809
|
sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
|
147591
147810
|
pTab->iPKey = -1;
|
147811
|
+
pTab->eTabType = TABTYP_VIEW;
|
147592
147812
|
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
|
147593
147813
|
#ifndef SQLITE_ALLOW_ROWID_IN_VIEW
|
147594
147814
|
/* The usual case - do not allow ROWID on a subquery */
|
147595
147815
|
pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
|
147596
147816
|
#else
|
147597
|
-
|
147817
|
+
/* Legacy compatibility mode */
|
147818
|
+
pTab->tabFlags |= TF_Ephemeral | sqlite3Config.mNoVisibleRowid;
|
147598
147819
|
#endif
|
147599
147820
|
return pParse->nErr ? SQLITE_ERROR : SQLITE_OK;
|
147600
147821
|
}
|
@@ -147862,7 +148083,7 @@ static int selectExpander(Walker *pWalker, Select *p){
|
|
147862
148083
|
pNestedFrom = pFrom->pSelect->pEList;
|
147863
148084
|
assert( pNestedFrom!=0 );
|
147864
148085
|
assert( pNestedFrom->nExpr==pTab->nCol );
|
147865
|
-
assert( VisibleRowid(pTab)==0 );
|
148086
|
+
assert( VisibleRowid(pTab)==0 || ViewCanHaveRowid );
|
147866
148087
|
}else{
|
147867
148088
|
if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
|
147868
148089
|
continue;
|
@@ -147894,7 +148115,8 @@ static int selectExpander(Walker *pWalker, Select *p){
|
|
147894
148115
|
pUsing = 0;
|
147895
148116
|
}
|
147896
148117
|
|
147897
|
-
nAdd = pTab->nCol
|
148118
|
+
nAdd = pTab->nCol;
|
148119
|
+
if( VisibleRowid(pTab) && (selFlags & SF_NestedFrom)!=0 ) nAdd++;
|
147898
148120
|
for(j=0; j<nAdd; j++){
|
147899
148121
|
const char *zName;
|
147900
148122
|
struct ExprList_item *pX; /* Newly added ExprList term */
|
@@ -147976,7 +148198,8 @@ static int selectExpander(Walker *pWalker, Select *p){
|
|
147976
148198
|
pX = &pNew->a[pNew->nExpr-1];
|
147977
148199
|
assert( pX->zEName==0 );
|
147978
148200
|
if( (selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){
|
147979
|
-
if( pNestedFrom ){
|
148201
|
+
if( pNestedFrom && (!ViewCanHaveRowid || j<pNestedFrom->nExpr) ){
|
148202
|
+
assert( j<pNestedFrom->nExpr );
|
147980
148203
|
pX->zEName = sqlite3DbStrDup(db, pNestedFrom->a[j].zEName);
|
147981
148204
|
testcase( pX->zEName==0 );
|
147982
148205
|
}else{
|
@@ -152910,6 +153133,9 @@ SQLITE_PRIVATE void sqlite3Update(
|
|
152910
153133
|
}
|
152911
153134
|
}
|
152912
153135
|
if( chngRowid==0 && pPk==0 ){
|
153136
|
+
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
|
153137
|
+
if( isView ) sqlite3VdbeAddOp2(v, OP_Null, 0, regOldRowid);
|
153138
|
+
#endif
|
152913
153139
|
sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid);
|
152914
153140
|
}
|
152915
153141
|
}
|
@@ -153447,7 +153673,8 @@ SQLITE_PRIVATE Upsert *sqlite3UpsertNew(
|
|
153447
153673
|
SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(
|
153448
153674
|
Parse *pParse, /* The parsing context */
|
153449
153675
|
SrcList *pTabList, /* Table into which we are inserting */
|
153450
|
-
Upsert *pUpsert
|
153676
|
+
Upsert *pUpsert, /* The ON CONFLICT clauses */
|
153677
|
+
Upsert *pAll /* Complete list of all ON CONFLICT clauses */
|
153451
153678
|
){
|
153452
153679
|
Table *pTab; /* That table into which we are inserting */
|
153453
153680
|
int rc; /* Result code */
|
@@ -153550,6 +153777,14 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(
|
|
153550
153777
|
continue;
|
153551
153778
|
}
|
153552
153779
|
pUpsert->pUpsertIdx = pIdx;
|
153780
|
+
if( sqlite3UpsertOfIndex(pAll,pIdx)!=pUpsert ){
|
153781
|
+
/* Really this should be an error. The isDup ON CONFLICT clause will
|
153782
|
+
** never fire. But this problem was not discovered until three years
|
153783
|
+
** after multi-CONFLICT upsert was added, and so we silently ignore
|
153784
|
+
** the problem to prevent breaking applications that might actually
|
153785
|
+
** have redundant ON CONFLICT clauses. */
|
153786
|
+
pUpsert->isDup = 1;
|
153787
|
+
}
|
153553
153788
|
break;
|
153554
153789
|
}
|
153555
153790
|
if( pUpsert->pUpsertIdx==0 ){
|
@@ -153576,9 +153811,13 @@ SQLITE_PRIVATE int sqlite3UpsertNextIsIPK(Upsert *pUpsert){
|
|
153576
153811
|
Upsert *pNext;
|
153577
153812
|
if( NEVER(pUpsert==0) ) return 0;
|
153578
153813
|
pNext = pUpsert->pNextUpsert;
|
153579
|
-
|
153580
|
-
|
153581
|
-
|
153814
|
+
while( 1 /*exit-by-return*/ ){
|
153815
|
+
if( pNext==0 ) return 1;
|
153816
|
+
if( pNext->pUpsertTarget==0 ) return 1;
|
153817
|
+
if( pNext->pUpsertIdx==0 ) return 1;
|
153818
|
+
if( !pNext->isDup ) return 0;
|
153819
|
+
pNext = pNext->pNextUpsert;
|
153820
|
+
}
|
153582
153821
|
return 0;
|
153583
153822
|
}
|
153584
153823
|
|
@@ -166606,16 +166845,10 @@ static SQLITE_NOINLINE void whereAddIndexedExpr(
|
|
166606
166845
|
for(i=0; i<pIdx->nColumn; i++){
|
166607
166846
|
Expr *pExpr;
|
166608
166847
|
int j = pIdx->aiColumn[i];
|
166609
|
-
int bMaybeNullRow;
|
166610
166848
|
if( j==XN_EXPR ){
|
166611
166849
|
pExpr = pIdx->aColExpr->a[i].pExpr;
|
166612
|
-
testcase( pTabItem->fg.jointype & JT_LEFT );
|
166613
|
-
testcase( pTabItem->fg.jointype & JT_RIGHT );
|
166614
|
-
testcase( pTabItem->fg.jointype & JT_LTORJ );
|
166615
|
-
bMaybeNullRow = (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0;
|
166616
166850
|
}else if( j>=0 && (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)!=0 ){
|
166617
166851
|
pExpr = sqlite3ColumnExpr(pTab, &pTab->aCol[j]);
|
166618
|
-
bMaybeNullRow = 0;
|
166619
166852
|
}else{
|
166620
166853
|
continue;
|
166621
166854
|
}
|
@@ -166647,7 +166880,7 @@ static SQLITE_NOINLINE void whereAddIndexedExpr(
|
|
166647
166880
|
p->iDataCur = pTabItem->iCursor;
|
166648
166881
|
p->iIdxCur = iIdxCur;
|
166649
166882
|
p->iIdxCol = i;
|
166650
|
-
p->bMaybeNullRow =
|
166883
|
+
p->bMaybeNullRow = (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0;
|
166651
166884
|
if( sqlite3IndexAffinityStr(pParse->db, pIdx) ){
|
166652
166885
|
p->aff = pIdx->zColAff[i];
|
166653
166886
|
}
|
@@ -166812,7 +167045,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
|
|
166812
167045
|
|
166813
167046
|
/* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */
|
166814
167047
|
testcase( pOrderBy && pOrderBy->nExpr==BMS-1 );
|
166815
|
-
if( pOrderBy && pOrderBy->nExpr>=BMS )
|
167048
|
+
if( pOrderBy && pOrderBy->nExpr>=BMS ){
|
167049
|
+
pOrderBy = 0;
|
167050
|
+
wctrlFlags &= ~WHERE_WANT_DISTINCT;
|
167051
|
+
}
|
166816
167052
|
|
166817
167053
|
/* The number of tables in the FROM clause is limited by the number of
|
166818
167054
|
** bits in a Bitmask
|
@@ -178849,6 +179085,18 @@ SQLITE_API int sqlite3_config(int op, ...){
|
|
178849
179085
|
}
|
178850
179086
|
#endif /* SQLITE_OMIT_DESERIALIZE */
|
178851
179087
|
|
179088
|
+
case SQLITE_CONFIG_ROWID_IN_VIEW: {
|
179089
|
+
int *pVal = va_arg(ap,int*);
|
179090
|
+
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
|
179091
|
+
if( 0==*pVal ) sqlite3GlobalConfig.mNoVisibleRowid = TF_NoVisibleRowid;
|
179092
|
+
if( 1==*pVal ) sqlite3GlobalConfig.mNoVisibleRowid = 0;
|
179093
|
+
*pVal = (sqlite3GlobalConfig.mNoVisibleRowid==0);
|
179094
|
+
#else
|
179095
|
+
*pVal = 0;
|
179096
|
+
#endif
|
179097
|
+
break;
|
179098
|
+
}
|
179099
|
+
|
178852
179100
|
default: {
|
178853
179101
|
rc = SQLITE_ERROR;
|
178854
179102
|
break;
|
@@ -184749,6 +184997,8 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int);
|
|
184749
184997
|
|
184750
184998
|
SQLITE_PRIVATE int sqlite3Fts3ExprIterate(Fts3Expr*, int (*x)(Fts3Expr*,int,void*), void*);
|
184751
184999
|
|
185000
|
+
SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk);
|
185001
|
+
|
184752
185002
|
#endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */
|
184753
185003
|
#endif /* _FTSINT_H */
|
184754
185004
|
|
@@ -188471,7 +188721,7 @@ static int fts3ShadowName(const char *zName){
|
|
188471
188721
|
** Implementation of the xIntegrity() method on the FTS3/FTS4 virtual
|
188472
188722
|
** table.
|
188473
188723
|
*/
|
188474
|
-
static int
|
188724
|
+
static int fts3IntegrityMethod(
|
188475
188725
|
sqlite3_vtab *pVtab, /* The virtual table to be checked */
|
188476
188726
|
const char *zSchema, /* Name of schema in which pVtab lives */
|
188477
188727
|
const char *zTabname, /* Name of the pVTab table */
|
@@ -188479,30 +188729,21 @@ static int fts3Integrity(
|
|
188479
188729
|
char **pzErr /* Write error message here */
|
188480
188730
|
){
|
188481
188731
|
Fts3Table *p = (Fts3Table*)pVtab;
|
188482
|
-
char *zSql;
|
188483
188732
|
int rc;
|
188484
|
-
|
188733
|
+
int bOk = 0;
|
188485
188734
|
|
188486
|
-
assert( pzErr!=0 );
|
188487
|
-
assert( *pzErr==0 );
|
188488
188735
|
UNUSED_PARAMETER(isQuick);
|
188489
|
-
|
188490
|
-
|
188491
|
-
|
188492
|
-
if( zSql==0 ){
|
188493
|
-
return SQLITE_NOMEM;
|
188494
|
-
}
|
188495
|
-
rc = sqlite3_exec(p->db, zSql, 0, 0, &zErr);
|
188496
|
-
sqlite3_free(zSql);
|
188497
|
-
if( (rc&0xff)==SQLITE_CORRUPT ){
|
188498
|
-
*pzErr = sqlite3_mprintf("malformed inverted index for FTS%d table %s.%s",
|
188499
|
-
p->bFts4 ? 4 : 3, zSchema, zTabname);
|
188500
|
-
}else if( rc!=SQLITE_OK ){
|
188736
|
+
rc = sqlite3Fts3IntegrityCheck(p, &bOk);
|
188737
|
+
assert( rc!=SQLITE_CORRUPT_VTAB || bOk==0 );
|
188738
|
+
if( rc!=SQLITE_OK && rc!=SQLITE_CORRUPT_VTAB ){
|
188501
188739
|
*pzErr = sqlite3_mprintf("unable to validate the inverted index for"
|
188502
188740
|
" FTS%d table %s.%s: %s",
|
188503
|
-
p->bFts4 ? 4 : 3, zSchema, zTabname,
|
188741
|
+
p->bFts4 ? 4 : 3, zSchema, zTabname, sqlite3_errstr(rc));
|
188742
|
+
}else if( bOk==0 ){
|
188743
|
+
*pzErr = sqlite3_mprintf("malformed inverted index for FTS%d table %s.%s",
|
188744
|
+
p->bFts4 ? 4 : 3, zSchema, zTabname);
|
188504
188745
|
}
|
188505
|
-
|
188746
|
+
sqlite3Fts3SegmentsClose(p);
|
188506
188747
|
return SQLITE_OK;
|
188507
188748
|
}
|
188508
188749
|
|
@@ -188533,7 +188774,7 @@ static const sqlite3_module fts3Module = {
|
|
188533
188774
|
/* xRelease */ fts3ReleaseMethod,
|
188534
188775
|
/* xRollbackTo */ fts3RollbackToMethod,
|
188535
188776
|
/* xShadowName */ fts3ShadowName,
|
188536
|
-
/* xIntegrity */
|
188777
|
+
/* xIntegrity */ fts3IntegrityMethod,
|
188537
188778
|
};
|
188538
188779
|
|
188539
188780
|
/*
|
@@ -200087,7 +200328,7 @@ static u64 fts3ChecksumIndex(
|
|
200087
200328
|
** If an error occurs (e.g. an OOM or IO error), return an SQLite error
|
200088
200329
|
** code. The final value of *pbOk is undefined in this case.
|
200089
200330
|
*/
|
200090
|
-
|
200331
|
+
SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk){
|
200091
200332
|
int rc = SQLITE_OK; /* Return code */
|
200092
200333
|
u64 cksum1 = 0; /* Checksum based on FTS index contents */
|
200093
200334
|
u64 cksum2 = 0; /* Checksum based on %_content contents */
|
@@ -200165,7 +200406,7 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){
|
|
200165
200406
|
sqlite3_finalize(pStmt);
|
200166
200407
|
}
|
200167
200408
|
|
200168
|
-
*pbOk = (cksum1==cksum2);
|
200409
|
+
*pbOk = (rc==SQLITE_OK && cksum1==cksum2);
|
200169
200410
|
return rc;
|
200170
200411
|
}
|
200171
200412
|
|
@@ -200205,7 +200446,7 @@ static int fts3DoIntegrityCheck(
|
|
200205
200446
|
){
|
200206
200447
|
int rc;
|
200207
200448
|
int bOk = 0;
|
200208
|
-
rc =
|
200449
|
+
rc = sqlite3Fts3IntegrityCheck(p, &bOk);
|
200209
200450
|
if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB;
|
200210
200451
|
return rc;
|
200211
200452
|
}
|
@@ -203758,6 +203999,16 @@ static void jsonAppendChar(JsonString *p, char c){
|
|
203758
203999
|
}
|
203759
204000
|
}
|
203760
204001
|
|
204002
|
+
/* Remove a single character from the end of the string
|
204003
|
+
*/
|
204004
|
+
static void jsonStringTrimOneChar(JsonString *p){
|
204005
|
+
if( p->eErr==0 ){
|
204006
|
+
assert( p->nUsed>0 );
|
204007
|
+
p->nUsed--;
|
204008
|
+
}
|
204009
|
+
}
|
204010
|
+
|
204011
|
+
|
203761
204012
|
/* Make sure there is a zero terminator on p->zBuf[]
|
203762
204013
|
**
|
203763
204014
|
** Return true on success. Return false if an OOM prevents this
|
@@ -203765,7 +204016,7 @@ static void jsonAppendChar(JsonString *p, char c){
|
|
203765
204016
|
*/
|
203766
204017
|
static int jsonStringTerminate(JsonString *p){
|
203767
204018
|
jsonAppendChar(p, 0);
|
203768
|
-
p
|
204019
|
+
jsonStringTrimOneChar(p);
|
203769
204020
|
return p->eErr==0;
|
203770
204021
|
}
|
203771
204022
|
|
@@ -204766,6 +205017,7 @@ json_parse_restart:
|
|
204766
205017
|
case '[': {
|
204767
205018
|
/* Parse array */
|
204768
205019
|
iThis = pParse->nBlob;
|
205020
|
+
assert( i<=(u32)pParse->nJson );
|
204769
205021
|
jsonBlobAppendNode(pParse, JSONB_ARRAY, pParse->nJson - i, 0);
|
204770
205022
|
iStart = pParse->nBlob;
|
204771
205023
|
if( pParse->oom ) return -1;
|
@@ -205164,6 +205416,10 @@ static void jsonReturnStringAsBlob(JsonString *pStr){
|
|
205164
205416
|
JsonParse px;
|
205165
205417
|
memset(&px, 0, sizeof(px));
|
205166
205418
|
jsonStringTerminate(pStr);
|
205419
|
+
if( pStr->eErr ){
|
205420
|
+
sqlite3_result_error_nomem(pStr->pCtx);
|
205421
|
+
return;
|
205422
|
+
}
|
205167
205423
|
px.zJson = pStr->zBuf;
|
205168
205424
|
px.nJson = pStr->nUsed;
|
205169
205425
|
px.db = sqlite3_context_db_handle(pStr->pCtx);
|
@@ -205231,8 +205487,8 @@ static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){
|
|
205231
205487
|
(pParse->aBlob[i+7]<<8) + pParse->aBlob[i+8];
|
205232
205488
|
n = 9;
|
205233
205489
|
}
|
205234
|
-
if( i+sz+n > pParse->nBlob
|
205235
|
-
&& i+sz+n > pParse->nBlob-pParse->delta
|
205490
|
+
if( (i64)i+sz+n > pParse->nBlob
|
205491
|
+
&& (i64)i+sz+n > pParse->nBlob-pParse->delta
|
205236
205492
|
){
|
205237
205493
|
sz = 0;
|
205238
205494
|
n = 0;
|
@@ -205282,6 +205538,7 @@ static u32 jsonTranslateBlobToText(
|
|
205282
205538
|
}
|
205283
205539
|
case JSONB_INT:
|
205284
205540
|
case JSONB_FLOAT: {
|
205541
|
+
if( sz==0 ) goto malformed_jsonb;
|
205285
205542
|
jsonAppendRaw(pOut, (const char*)&pParse->aBlob[i+n], sz);
|
205286
205543
|
break;
|
205287
205544
|
}
|
@@ -205290,6 +205547,7 @@ static u32 jsonTranslateBlobToText(
|
|
205290
205547
|
sqlite3_uint64 u = 0;
|
205291
205548
|
const char *zIn = (const char*)&pParse->aBlob[i+n];
|
205292
205549
|
int bOverflow = 0;
|
205550
|
+
if( sz==0 ) goto malformed_jsonb;
|
205293
205551
|
if( zIn[0]=='-' ){
|
205294
205552
|
jsonAppendChar(pOut, '-');
|
205295
205553
|
k++;
|
@@ -205312,6 +205570,7 @@ static u32 jsonTranslateBlobToText(
|
|
205312
205570
|
case JSONB_FLOAT5: { /* Float literal missing digits beside "." */
|
205313
205571
|
u32 k = 0;
|
205314
205572
|
const char *zIn = (const char*)&pParse->aBlob[i+n];
|
205573
|
+
if( sz==0 ) goto malformed_jsonb;
|
205315
205574
|
if( zIn[0]=='-' ){
|
205316
205575
|
jsonAppendChar(pOut, '-');
|
205317
205576
|
k++;
|
@@ -205425,11 +205684,12 @@ static u32 jsonTranslateBlobToText(
|
|
205425
205684
|
jsonAppendChar(pOut, '[');
|
205426
205685
|
j = i+n;
|
205427
205686
|
iEnd = j+sz;
|
205428
|
-
while( j<iEnd ){
|
205687
|
+
while( j<iEnd && pOut->eErr==0 ){
|
205429
205688
|
j = jsonTranslateBlobToText(pParse, j, pOut);
|
205430
205689
|
jsonAppendChar(pOut, ',');
|
205431
205690
|
}
|
205432
|
-
if(
|
205691
|
+
if( j>iEnd ) pOut->eErr |= JSTRING_MALFORMED;
|
205692
|
+
if( sz>0 ) jsonStringTrimOneChar(pOut);
|
205433
205693
|
jsonAppendChar(pOut, ']');
|
205434
205694
|
break;
|
205435
205695
|
}
|
@@ -205438,17 +205698,18 @@ static u32 jsonTranslateBlobToText(
|
|
205438
205698
|
jsonAppendChar(pOut, '{');
|
205439
205699
|
j = i+n;
|
205440
205700
|
iEnd = j+sz;
|
205441
|
-
while( j<iEnd ){
|
205701
|
+
while( j<iEnd && pOut->eErr==0 ){
|
205442
205702
|
j = jsonTranslateBlobToText(pParse, j, pOut);
|
205443
205703
|
jsonAppendChar(pOut, (x++ & 1) ? ',' : ':');
|
205444
205704
|
}
|
205445
|
-
if( x & 1 ) pOut->eErr |= JSTRING_MALFORMED;
|
205446
|
-
if( sz>0 ) pOut
|
205705
|
+
if( (x & 1)!=0 || j>iEnd ) pOut->eErr |= JSTRING_MALFORMED;
|
205706
|
+
if( sz>0 ) jsonStringTrimOneChar(pOut);
|
205447
205707
|
jsonAppendChar(pOut, '}');
|
205448
205708
|
break;
|
205449
205709
|
}
|
205450
205710
|
|
205451
205711
|
default: {
|
205712
|
+
malformed_jsonb:
|
205452
205713
|
pOut->eErr |= JSTRING_MALFORMED;
|
205453
205714
|
break;
|
205454
205715
|
}
|
@@ -206375,6 +206636,38 @@ jsonInsertIntoBlob_patherror:
|
|
206375
206636
|
return;
|
206376
206637
|
}
|
206377
206638
|
|
206639
|
+
/*
|
206640
|
+
** If pArg is a blob that seems like a JSONB blob, then initialize
|
206641
|
+
** p to point to that JSONB and return TRUE. If pArg does not seem like
|
206642
|
+
** a JSONB blob, then return FALSE;
|
206643
|
+
**
|
206644
|
+
** This routine is only called if it is already known that pArg is a
|
206645
|
+
** blob. The only open question is whether or not the blob appears
|
206646
|
+
** to be a JSONB blob.
|
206647
|
+
*/
|
206648
|
+
static int jsonArgIsJsonb(sqlite3_value *pArg, JsonParse *p){
|
206649
|
+
u32 n, sz = 0;
|
206650
|
+
p->aBlob = (u8*)sqlite3_value_blob(pArg);
|
206651
|
+
p->nBlob = (u32)sqlite3_value_bytes(pArg);
|
206652
|
+
if( p->nBlob==0 ){
|
206653
|
+
p->aBlob = 0;
|
206654
|
+
return 0;
|
206655
|
+
}
|
206656
|
+
if( NEVER(p->aBlob==0) ){
|
206657
|
+
return 0;
|
206658
|
+
}
|
206659
|
+
if( (p->aBlob[0] & 0x0f)<=JSONB_OBJECT
|
206660
|
+
&& (n = jsonbPayloadSize(p, 0, &sz))>0
|
206661
|
+
&& sz+n==p->nBlob
|
206662
|
+
&& ((p->aBlob[0] & 0x0f)>JSONB_FALSE || sz==0)
|
206663
|
+
){
|
206664
|
+
return 1;
|
206665
|
+
}
|
206666
|
+
p->aBlob = 0;
|
206667
|
+
p->nBlob = 0;
|
206668
|
+
return 0;
|
206669
|
+
}
|
206670
|
+
|
206378
206671
|
/*
|
206379
206672
|
** Generate a JsonParse object, containing valid JSONB in aBlob and nBlob,
|
206380
206673
|
** from the SQL function argument pArg. Return a pointer to the new
|
@@ -206431,34 +206724,30 @@ rebuild_from_cache:
|
|
206431
206724
|
return p;
|
206432
206725
|
}
|
206433
206726
|
if( eType==SQLITE_BLOB ){
|
206434
|
-
|
206435
|
-
|
206436
|
-
|
206437
|
-
|
206438
|
-
|
206439
|
-
}
|
206440
|
-
if( NEVER(p->aBlob==0) ){
|
206441
|
-
goto json_pfa_oom;
|
206442
|
-
}
|
206443
|
-
if( (p->aBlob[0] & 0x0f)>JSONB_OBJECT ){
|
206444
|
-
goto json_pfa_malformed;
|
206445
|
-
}
|
206446
|
-
n = jsonbPayloadSize(p, 0, &sz);
|
206447
|
-
if( n==0
|
206448
|
-
|| sz+n!=p->nBlob
|
206449
|
-
|| ((p->aBlob[0] & 0x0f)<=JSONB_FALSE && sz>0)
|
206450
|
-
){
|
206451
|
-
goto json_pfa_malformed;
|
206452
|
-
}
|
206453
|
-
if( (flgs & JSON_EDITABLE)!=0 && jsonBlobMakeEditable(p, 0)==0 ){
|
206454
|
-
goto json_pfa_oom;
|
206727
|
+
if( jsonArgIsJsonb(pArg,p) ){
|
206728
|
+
if( (flgs & JSON_EDITABLE)!=0 && jsonBlobMakeEditable(p, 0)==0 ){
|
206729
|
+
goto json_pfa_oom;
|
206730
|
+
}
|
206731
|
+
return p;
|
206455
206732
|
}
|
206456
|
-
|
206733
|
+
/* If the blob is not valid JSONB, fall through into trying to cast
|
206734
|
+
** the blob into text which is then interpreted as JSON. (tag-20240123-a)
|
206735
|
+
**
|
206736
|
+
** This goes against all historical documentation about how the SQLite
|
206737
|
+
** JSON functions were suppose to work. From the beginning, blob was
|
206738
|
+
** reserved for expansion and a blob value should have raised an error.
|
206739
|
+
** But it did not, due to a bug. And many applications came to depend
|
206740
|
+
** upon this buggy behavior, espeically when using the CLI and reading
|
206741
|
+
** JSON text using readfile(), which returns a blob. For this reason
|
206742
|
+
** we will continue to support the bug moving forward.
|
206743
|
+
** See for example https://sqlite.org/forum/forumpost/012136abd5292b8d
|
206744
|
+
*/
|
206457
206745
|
}
|
206458
206746
|
p->zJson = (char*)sqlite3_value_text(pArg);
|
206459
206747
|
p->nJson = sqlite3_value_bytes(pArg);
|
206748
|
+
if( db->mallocFailed ) goto json_pfa_oom;
|
206460
206749
|
if( p->nJson==0 ) goto json_pfa_malformed;
|
206461
|
-
|
206750
|
+
assert( p->zJson!=0 );
|
206462
206751
|
if( jsonConvertTextToBlob(p, (flgs & JSON_KEEPERROR) ? 0 : ctx) ){
|
206463
206752
|
if( flgs & JSON_KEEPERROR ){
|
206464
206753
|
p->nErr = 1;
|
@@ -206624,10 +206913,10 @@ static void jsonDebugPrintBlob(
|
|
206624
206913
|
if( sz==0 && x<=JSONB_FALSE ){
|
206625
206914
|
sqlite3_str_append(pOut, "\n", 1);
|
206626
206915
|
}else{
|
206627
|
-
u32
|
206916
|
+
u32 j;
|
206628
206917
|
sqlite3_str_appendall(pOut, ": \"");
|
206629
|
-
for(
|
206630
|
-
u8 c = pParse->aBlob[
|
206918
|
+
for(j=iStart+n; j<iStart+n+sz; j++){
|
206919
|
+
u8 c = pParse->aBlob[j];
|
206631
206920
|
if( c<0x20 || c>=0x7f ) c = '.';
|
206632
206921
|
sqlite3_str_append(pOut, (char*)&c, 1);
|
206633
206922
|
}
|
@@ -207429,12 +207718,12 @@ static void jsonValidFunc(
|
|
207429
207718
|
return;
|
207430
207719
|
}
|
207431
207720
|
case SQLITE_BLOB: {
|
207432
|
-
if(
|
207721
|
+
if( jsonFuncArgMightBeBinary(argv[0]) ){
|
207433
207722
|
if( flags & 0x04 ){
|
207434
207723
|
/* Superficial checking only - accomplished by the
|
207435
207724
|
** jsonFuncArgMightBeBinary() call above. */
|
207436
207725
|
res = 1;
|
207437
|
-
}else{
|
207726
|
+
}else if( flags & 0x08 ){
|
207438
207727
|
/* Strict checking. Check by translating BLOB->TEXT->BLOB. If
|
207439
207728
|
** no errors occur, call that a "strict check". */
|
207440
207729
|
JsonParse px;
|
@@ -207445,8 +207734,11 @@ static void jsonValidFunc(
|
|
207445
207734
|
iErr = jsonbValidityCheck(&px, 0, px.nBlob, 1);
|
207446
207735
|
res = iErr==0;
|
207447
207736
|
}
|
207737
|
+
break;
|
207448
207738
|
}
|
207449
|
-
|
207739
|
+
/* Fall through into interpreting the input as text. See note
|
207740
|
+
** above at tag-20240123-a. */
|
207741
|
+
/* no break */ deliberate_fall_through
|
207450
207742
|
}
|
207451
207743
|
default: {
|
207452
207744
|
JsonParse px;
|
@@ -207571,7 +207863,7 @@ static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){
|
|
207571
207863
|
if( isFinal ){
|
207572
207864
|
if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf);
|
207573
207865
|
}else{
|
207574
|
-
pStr
|
207866
|
+
jsonStringTrimOneChar(pStr);
|
207575
207867
|
}
|
207576
207868
|
return;
|
207577
207869
|
}else if( isFinal ){
|
@@ -207581,7 +207873,7 @@ static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){
|
|
207581
207873
|
pStr->bStatic = 1;
|
207582
207874
|
}else{
|
207583
207875
|
sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);
|
207584
|
-
pStr
|
207876
|
+
jsonStringTrimOneChar(pStr);
|
207585
207877
|
}
|
207586
207878
|
}else{
|
207587
207879
|
sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC);
|
@@ -207691,7 +207983,7 @@ static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){
|
|
207691
207983
|
if( isFinal ){
|
207692
207984
|
if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf);
|
207693
207985
|
}else{
|
207694
|
-
pStr
|
207986
|
+
jsonStringTrimOneChar(pStr);
|
207695
207987
|
}
|
207696
207988
|
return;
|
207697
207989
|
}else if( isFinal ){
|
@@ -207701,7 +207993,7 @@ static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){
|
|
207701
207993
|
pStr->bStatic = 1;
|
207702
207994
|
}else{
|
207703
207995
|
sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);
|
207704
|
-
pStr
|
207996
|
+
jsonStringTrimOneChar(pStr);
|
207705
207997
|
}
|
207706
207998
|
}else{
|
207707
207999
|
sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC);
|
@@ -208032,6 +208324,9 @@ static int jsonEachColumn(
|
|
208032
208324
|
case JEACH_VALUE: {
|
208033
208325
|
u32 i = jsonSkipLabel(p);
|
208034
208326
|
jsonReturnFromBlob(&p->sParse, i, ctx, 1);
|
208327
|
+
if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY ){
|
208328
|
+
sqlite3_result_subtype(ctx, JSON_SUBTYPE);
|
208329
|
+
}
|
208035
208330
|
break;
|
208036
208331
|
}
|
208037
208332
|
case JEACH_TYPE: {
|
@@ -208078,9 +208373,9 @@ static int jsonEachColumn(
|
|
208078
208373
|
case JEACH_JSON: {
|
208079
208374
|
if( p->sParse.zJson==0 ){
|
208080
208375
|
sqlite3_result_blob(ctx, p->sParse.aBlob, p->sParse.nBlob,
|
208081
|
-
|
208376
|
+
SQLITE_TRANSIENT);
|
208082
208377
|
}else{
|
208083
|
-
sqlite3_result_text(ctx, p->sParse.zJson, -1,
|
208378
|
+
sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_TRANSIENT);
|
208084
208379
|
}
|
208085
208380
|
break;
|
208086
208381
|
}
|
@@ -208182,13 +208477,9 @@ static int jsonEachFilter(
|
|
208182
208477
|
memset(&p->sParse, 0, sizeof(p->sParse));
|
208183
208478
|
p->sParse.nJPRef = 1;
|
208184
208479
|
p->sParse.db = p->db;
|
208185
|
-
if(
|
208186
|
-
|
208187
|
-
|
208188
|
-
p->sParse.aBlob = (u8*)sqlite3_value_blob(argv[0]);
|
208189
|
-
}else{
|
208190
|
-
goto json_each_malformed_input;
|
208191
|
-
}
|
208480
|
+
if( jsonFuncArgMightBeBinary(argv[0]) ){
|
208481
|
+
p->sParse.nBlob = sqlite3_value_bytes(argv[0]);
|
208482
|
+
p->sParse.aBlob = (u8*)sqlite3_value_blob(argv[0]);
|
208192
208483
|
}else{
|
208193
208484
|
p->sParse.zJson = (char*)sqlite3_value_text(argv[0]);
|
208194
208485
|
p->sParse.nJson = sqlite3_value_bytes(argv[0]);
|
@@ -209110,11 +209401,9 @@ static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){
|
|
209110
209401
|
** Clear the Rtree.pNodeBlob object
|
209111
209402
|
*/
|
209112
209403
|
static void nodeBlobReset(Rtree *pRtree){
|
209113
|
-
|
209114
|
-
|
209115
|
-
|
209116
|
-
sqlite3_blob_close(pBlob);
|
209117
|
-
}
|
209404
|
+
sqlite3_blob *pBlob = pRtree->pNodeBlob;
|
209405
|
+
pRtree->pNodeBlob = 0;
|
209406
|
+
sqlite3_blob_close(pBlob);
|
209118
209407
|
}
|
209119
209408
|
|
209120
209409
|
/*
|
@@ -209158,7 +209447,6 @@ static int nodeAcquire(
|
|
209158
209447
|
&pRtree->pNodeBlob);
|
209159
209448
|
}
|
209160
209449
|
if( rc ){
|
209161
|
-
nodeBlobReset(pRtree);
|
209162
209450
|
*ppNode = 0;
|
209163
209451
|
/* If unable to open an sqlite3_blob on the desired row, that can only
|
209164
209452
|
** be because the shadow tables hold erroneous data. */
|
@@ -209218,6 +209506,7 @@ static int nodeAcquire(
|
|
209218
209506
|
}
|
209219
209507
|
*ppNode = pNode;
|
209220
209508
|
}else{
|
209509
|
+
nodeBlobReset(pRtree);
|
209221
209510
|
if( pNode ){
|
209222
209511
|
pRtree->nNodeRef--;
|
209223
209512
|
sqlite3_free(pNode);
|
@@ -209362,6 +209651,7 @@ static void nodeGetCoord(
|
|
209362
209651
|
int iCoord, /* Which coordinate to extract */
|
209363
209652
|
RtreeCoord *pCoord /* OUT: Space to write result to */
|
209364
209653
|
){
|
209654
|
+
assert( iCell<NCELL(pNode) );
|
209365
209655
|
readCoord(&pNode->zData[12 + pRtree->nBytesPerCell*iCell + 4*iCoord], pCoord);
|
209366
209656
|
}
|
209367
209657
|
|
@@ -209551,7 +209841,9 @@ static int rtreeClose(sqlite3_vtab_cursor *cur){
|
|
209551
209841
|
sqlite3_finalize(pCsr->pReadAux);
|
209552
209842
|
sqlite3_free(pCsr);
|
209553
209843
|
pRtree->nCursor--;
|
209554
|
-
|
209844
|
+
if( pRtree->nCursor==0 && pRtree->inWrTrans==0 ){
|
209845
|
+
nodeBlobReset(pRtree);
|
209846
|
+
}
|
209555
209847
|
return SQLITE_OK;
|
209556
209848
|
}
|
209557
209849
|
|
@@ -210136,7 +210428,11 @@ static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){
|
|
210136
210428
|
int rc = SQLITE_OK;
|
210137
210429
|
RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc);
|
210138
210430
|
if( rc==SQLITE_OK && ALWAYS(p) ){
|
210139
|
-
|
210431
|
+
if( p->iCell>=NCELL(pNode) ){
|
210432
|
+
rc = SQLITE_ABORT;
|
210433
|
+
}else{
|
210434
|
+
*pRowid = nodeGetRowid(RTREE_OF_CURSOR(pCsr), pNode, p->iCell);
|
210435
|
+
}
|
210140
210436
|
}
|
210141
210437
|
return rc;
|
210142
210438
|
}
|
@@ -210154,6 +210450,7 @@ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
|
|
210154
210450
|
|
210155
210451
|
if( rc ) return rc;
|
210156
210452
|
if( NEVER(p==0) ) return SQLITE_OK;
|
210453
|
+
if( p->iCell>=NCELL(pNode) ) return SQLITE_ABORT;
|
210157
210454
|
if( i==0 ){
|
210158
210455
|
sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell));
|
210159
210456
|
}else if( i<=pRtree->nDim2 ){
|
@@ -211635,8 +211932,7 @@ constraint:
|
|
211635
211932
|
*/
|
211636
211933
|
static int rtreeBeginTransaction(sqlite3_vtab *pVtab){
|
211637
211934
|
Rtree *pRtree = (Rtree *)pVtab;
|
211638
|
-
|
211639
|
-
pRtree->inWrTrans++;
|
211935
|
+
pRtree->inWrTrans = 1;
|
211640
211936
|
return SQLITE_OK;
|
211641
211937
|
}
|
211642
211938
|
|
@@ -211650,6 +211946,9 @@ static int rtreeEndTransaction(sqlite3_vtab *pVtab){
|
|
211650
211946
|
nodeBlobReset(pRtree);
|
211651
211947
|
return SQLITE_OK;
|
211652
211948
|
}
|
211949
|
+
static int rtreeRollback(sqlite3_vtab *pVtab){
|
211950
|
+
return rtreeEndTransaction(pVtab);
|
211951
|
+
}
|
211653
211952
|
|
211654
211953
|
/*
|
211655
211954
|
** The xRename method for rtree module virtual tables.
|
@@ -211768,7 +212067,7 @@ static sqlite3_module rtreeModule = {
|
|
211768
212067
|
rtreeBeginTransaction, /* xBegin - begin transaction */
|
211769
212068
|
rtreeEndTransaction, /* xSync - sync transaction */
|
211770
212069
|
rtreeEndTransaction, /* xCommit - commit transaction */
|
211771
|
-
|
212070
|
+
rtreeRollback, /* xRollback - rollback transaction */
|
211772
212071
|
0, /* xFindFunction - function overloading */
|
211773
212072
|
rtreeRename, /* xRename - rename the table */
|
211774
212073
|
rtreeSavepoint, /* xSavepoint */
|
@@ -245327,23 +245626,26 @@ static void fts5IterSetOutputsTokendata(Fts5Iter *pIter){
|
|
245327
245626
|
static void fts5TokendataIterNext(Fts5Iter *pIter, int bFrom, i64 iFrom){
|
245328
245627
|
int ii;
|
245329
245628
|
Fts5TokenDataIter *pT = pIter->pTokenDataIter;
|
245629
|
+
Fts5Index *pIndex = pIter->pIndex;
|
245330
245630
|
|
245331
245631
|
for(ii=0; ii<pT->nIter; ii++){
|
245332
245632
|
Fts5Iter *p = pT->apIter[ii];
|
245333
245633
|
if( p->base.bEof==0
|
245334
245634
|
&& (p->base.iRowid==pIter->base.iRowid || (bFrom && p->base.iRowid<iFrom))
|
245335
245635
|
){
|
245336
|
-
fts5MultiIterNext(
|
245636
|
+
fts5MultiIterNext(pIndex, p, bFrom, iFrom);
|
245337
245637
|
while( bFrom && p->base.bEof==0
|
245338
245638
|
&& p->base.iRowid<iFrom
|
245339
|
-
&&
|
245639
|
+
&& pIndex->rc==SQLITE_OK
|
245340
245640
|
){
|
245341
|
-
fts5MultiIterNext(
|
245641
|
+
fts5MultiIterNext(pIndex, p, 0, 0);
|
245342
245642
|
}
|
245343
245643
|
}
|
245344
245644
|
}
|
245345
245645
|
|
245346
|
-
|
245646
|
+
if( pIndex->rc==SQLITE_OK ){
|
245647
|
+
fts5IterSetOutputsTokendata(pIter);
|
245648
|
+
}
|
245347
245649
|
}
|
245348
245650
|
|
245349
245651
|
/*
|
@@ -250497,7 +250799,7 @@ static void fts5SourceIdFunc(
|
|
250497
250799
|
){
|
250498
250800
|
assert( nArg==0 );
|
250499
250801
|
UNUSED_PARAM2(nArg, apUnused);
|
250500
|
-
sqlite3_result_text(pCtx, "fts5: 2024-
|
250802
|
+
sqlite3_result_text(pCtx, "fts5: 2024-04-15 13:34:05 8653b758870e6ef0c98d46b3ace27849054af85da891eb121e9aaa537f1e8355", -1, SQLITE_TRANSIENT);
|
250501
250803
|
}
|
250502
250804
|
|
250503
250805
|
/*
|
@@ -250528,27 +250830,21 @@ static int fts5IntegrityMethod(
|
|
250528
250830
|
char **pzErr /* Write error message here */
|
250529
250831
|
){
|
250530
250832
|
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
|
250531
|
-
Fts5Config *pConfig = pTab->p.pConfig;
|
250532
|
-
char *zSql;
|
250533
|
-
char *zErr = 0;
|
250534
250833
|
int rc;
|
250834
|
+
|
250535
250835
|
assert( pzErr!=0 && *pzErr==0 );
|
250536
250836
|
UNUSED_PARAM(isQuick);
|
250537
|
-
|
250538
|
-
"INSERT INTO \"%w\".\"%w\"(\"%w\") VALUES('integrity-check');",
|
250539
|
-
zSchema, zTabname, pConfig->zName);
|
250540
|
-
if( zSql==0 ) return SQLITE_NOMEM;
|
250541
|
-
rc = sqlite3_exec(pConfig->db, zSql, 0, 0, &zErr);
|
250542
|
-
sqlite3_free(zSql);
|
250837
|
+
rc = sqlite3Fts5StorageIntegrity(pTab->pStorage, 0);
|
250543
250838
|
if( (rc&0xff)==SQLITE_CORRUPT ){
|
250544
250839
|
*pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s",
|
250545
250840
|
zSchema, zTabname);
|
250546
250841
|
}else if( rc!=SQLITE_OK ){
|
250547
250842
|
*pzErr = sqlite3_mprintf("unable to validate the inverted index for"
|
250548
250843
|
" FTS5 table %s.%s: %s",
|
250549
|
-
zSchema, zTabname,
|
250844
|
+
zSchema, zTabname, sqlite3_errstr(rc));
|
250550
250845
|
}
|
250551
|
-
|
250846
|
+
sqlite3Fts5IndexCloseReader(pTab->p.pIndex);
|
250847
|
+
|
250552
250848
|
return SQLITE_OK;
|
250553
250849
|
}
|
250554
250850
|
|