Fossil SCM

Update the built-in SQLite to version 3.9.0 final.

drh 2015-10-14 12:35 trunk
Commit 82d84295a8b4d6c00be028b80829409f0d554da4
2 files changed +244 -220 +12 -4
+244 -220
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -325,11 +325,11 @@
325325
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
326326
** [sqlite_version()] and [sqlite_source_id()].
327327
*/
328328
#define SQLITE_VERSION "3.9.0"
329329
#define SQLITE_VERSION_NUMBER 3009000
330
-#define SQLITE_SOURCE_ID "2015-10-10 15:57:20 35e6248abb4435a8b26d270092b856beff867406"
330
+#define SQLITE_SOURCE_ID "2015-10-14 12:29:53 a721fc0d89495518fe5612e2e3bbc60befd2e90d"
331331
332332
/*
333333
** CAPI3REF: Run-Time Library Version Numbers
334334
** KEYWORDS: sqlite3_version, sqlite3_sourceid
335335
**
@@ -5868,13 +5868,13 @@
58685868
** used with an SQLite version earlier than 3.8.2, the results of attempting
58695869
** to read or write the estimatedRows field are undefined (but are likely
58705870
** to included crashing the application). The estimatedRows field should
58715871
** therefore only be used if [sqlite3_libversion_number()] returns a
58725872
** value greater than or equal to 3008002. Similarly, the idxFlags field
5873
-** was added for version 3.8.12. It may therefore only be used if
5873
+** was added for version 3.9.0. It may therefore only be used if
58745874
** sqlite3_libversion_number() returns a value greater than or equal to
5875
-** 3008012.
5875
+** 3009000.
58765876
*/
58775877
struct sqlite3_index_info {
58785878
/* Inputs */
58795879
int nConstraint; /* Number of entries in aConstraint */
58805880
struct sqlite3_index_constraint {
@@ -5898,11 +5898,11 @@
58985898
int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */
58995899
int orderByConsumed; /* True if output is already ordered */
59005900
double estimatedCost; /* Estimated cost of using this index */
59015901
/* Fields below are only available in SQLite 3.8.2 and later */
59025902
sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
5903
- /* Fields below are only available in SQLite 3.8.12 and later */
5903
+ /* Fields below are only available in SQLite 3.9.0 and later */
59045904
int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */
59055905
};
59065906
59075907
/*
59085908
** CAPI3REF: Virtual Table Scan Flags
@@ -8158,10 +8158,14 @@
81588158
#ifndef _FTS5_H
81598159
#define _FTS5_H
81608160
81618161
/* #include "sqlite3.h" */
81628162
8163
+#if 0
8164
+extern "C" {
8165
+#endif
8166
+
81638167
/*************************************************************************
81648168
** CUSTOM AUXILIARY FUNCTIONS
81658169
**
81668170
** Virtual table implementations may overload SQL functions by implementing
81678171
** the sqlite3_module.xFindFunction() method.
@@ -8643,10 +8647,14 @@
86438647
86448648
/*
86458649
** END OF REGISTRATION API
86468650
*************************************************************************/
86478651
8652
+#if 0
8653
+} /* end of the 'extern "C"' block */
8654
+#endif
8655
+
86488656
#endif /* _FTS5_H */
86498657
86508658
86518659
86528660
/************** End of sqlite3.h *********************************************/
@@ -60993,11 +61001,17 @@
6099361001
if( (aData[1]==0 && aData[2]==0) || (pSlot = pageFindSlot(pPg,sz,&rc))==0 ){
6099461002
pData -= sz;
6099561003
if( pData<pBegin ) return 1;
6099661004
pSlot = pData;
6099761005
}
60998
- memcpy(pSlot, pCArray->apCell[i], sz);
61006
+ /* pSlot and pCArray->apCell[i] will never overlap on a well-formed
61007
+ ** database. But they might for a corrupt database. Hence use memmove()
61008
+ ** since memcpy() sends SIGABORT with overlapping buffers on OpenBSD */
61009
+ assert( (pSlot+sz)<=pCArray->apCell[i]
61010
+ || pSlot>=(pCArray->apCell[i]+sz)
61011
+ || CORRUPT_DB );
61012
+ memmove(pSlot, pCArray->apCell[i], sz);
6099961013
put2byte(pCellptr, (pSlot - aData));
6100061014
pCellptr += 2;
6100161015
}
6100261016
*ppData = pData;
6100361017
return 0;
@@ -104303,11 +104317,11 @@
104303104317
/* Version 3.8.11 and later */
104304104318
sqlite3_value *(*value_dup)(const sqlite3_value*);
104305104319
void (*value_free)(sqlite3_value*);
104306104320
int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
104307104321
int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
104308
- /* Version 3.8.12 and later */
104322
+ /* Version 3.9.0 and later */
104309104323
unsigned int (*value_subtype)(sqlite3_value*);
104310104324
void (*result_subtype)(sqlite3_context*,unsigned int);
104311104325
};
104312104326
104313104327
/*
@@ -104542,11 +104556,11 @@
104542104556
/* Version 3.8.11 and later */
104543104557
#define sqlite3_value_dup sqlite3_api->value_dup
104544104558
#define sqlite3_value_free sqlite3_api->value_free
104545104559
#define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64
104546104560
#define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64
104547
-/* Version 3.8.12 and later */
104561
+/* Version 3.9.0 and later */
104548104562
#define sqlite3_value_subtype sqlite3_api->value_subtype
104549104563
#define sqlite3_result_subtype sqlite3_api->result_subtype
104550104564
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
104551104565
104552104566
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
@@ -104957,11 +104971,11 @@
104957104971
/* Version 3.8.11 and later */
104958104972
(sqlite3_value*(*)(const sqlite3_value*))sqlite3_value_dup,
104959104973
sqlite3_value_free,
104960104974
sqlite3_result_zeroblob64,
104961104975
sqlite3_bind_zeroblob64,
104962
- /* Version 3.8.12 and later */
104976
+ /* Version 3.9.0 and later */
104963104977
sqlite3_value_subtype,
104964104978
sqlite3_result_subtype
104965104979
};
104966104980
104967104981
/*
@@ -111703,11 +111717,11 @@
111703111717
#endif
111704111718
111705111719
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
111706111720
/* Forward Declarations */
111707111721
static void substExprList(sqlite3*, ExprList*, int, ExprList*);
111708
-static void substSelect(sqlite3*, Select *, int, ExprList *);
111722
+static void substSelect(sqlite3*, Select *, int, ExprList*, int);
111709111723
111710111724
/*
111711111725
** Scan through the expression pExpr. Replace every reference to
111712111726
** a column in table number iTable with a copy of the iColumn-th
111713111727
** entry in pEList. (But leave references to the ROWID column
@@ -111740,11 +111754,11 @@
111740111754
}
111741111755
}else{
111742111756
pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList);
111743111757
pExpr->pRight = substExpr(db, pExpr->pRight, iTable, pEList);
111744111758
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
111745
- substSelect(db, pExpr->x.pSelect, iTable, pEList);
111759
+ substSelect(db, pExpr->x.pSelect, iTable, pEList, 1);
111746111760
}else{
111747111761
substExprList(db, pExpr->x.pList, iTable, pEList);
111748111762
}
111749111763
}
111750111764
return pExpr;
@@ -111763,29 +111777,32 @@
111763111777
}
111764111778
static void substSelect(
111765111779
sqlite3 *db, /* Report malloc errors here */
111766111780
Select *p, /* SELECT statement in which to make substitutions */
111767111781
int iTable, /* Table to be replaced */
111768
- ExprList *pEList /* Substitute values */
111782
+ ExprList *pEList, /* Substitute values */
111783
+ int doPrior /* Do substitutes on p->pPrior too */
111769111784
){
111770111785
SrcList *pSrc;
111771111786
struct SrcList_item *pItem;
111772111787
int i;
111773111788
if( !p ) return;
111774
- substExprList(db, p->pEList, iTable, pEList);
111775
- substExprList(db, p->pGroupBy, iTable, pEList);
111776
- substExprList(db, p->pOrderBy, iTable, pEList);
111777
- p->pHaving = substExpr(db, p->pHaving, iTable, pEList);
111778
- p->pWhere = substExpr(db, p->pWhere, iTable, pEList);
111779
- substSelect(db, p->pPrior, iTable, pEList);
111780
- pSrc = p->pSrc;
111781
- assert( pSrc ); /* Even for (SELECT 1) we have: pSrc!=0 but pSrc->nSrc==0 */
111782
- if( ALWAYS(pSrc) ){
111789
+ do{
111790
+ substExprList(db, p->pEList, iTable, pEList);
111791
+ substExprList(db, p->pGroupBy, iTable, pEList);
111792
+ substExprList(db, p->pOrderBy, iTable, pEList);
111793
+ p->pHaving = substExpr(db, p->pHaving, iTable, pEList);
111794
+ p->pWhere = substExpr(db, p->pWhere, iTable, pEList);
111795
+ pSrc = p->pSrc;
111796
+ assert( pSrc!=0 );
111783111797
for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
111784
- substSelect(db, pItem->pSelect, iTable, pEList);
111798
+ substSelect(db, pItem->pSelect, iTable, pEList, 1);
111799
+ if( pItem->fg.isTabFunc ){
111800
+ substExprList(db, pItem->u1.pFuncArg, iTable, pEList);
111801
+ }
111785111802
}
111786
- }
111803
+ }while( doPrior && (p = p->pPrior)!=0 );
111787111804
}
111788111805
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
111789111806
111790111807
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
111791111808
/*
@@ -111933,11 +111950,11 @@
111933111950
int iFrom, /* Index in p->pSrc->a[] of the inner subquery */
111934111951
int isAgg, /* True if outer SELECT uses aggregate functions */
111935111952
int subqueryIsAgg /* True if the subquery uses aggregate functions */
111936111953
){
111937111954
const char *zSavedAuthContext = pParse->zAuthContext;
111938
- Select *pParent;
111955
+ Select *pParent; /* Current UNION ALL term of the other query */
111939111956
Select *pSub; /* The inner query or "subquery" */
111940111957
Select *pSub1; /* Pointer to the rightmost select in sub-query */
111941111958
SrcList *pSrc; /* The FROM clause of the outer query */
111942111959
SrcList *pSubSrc; /* The FROM clause of the subquery */
111943111960
ExprList *pList; /* The result set of the outer query */
@@ -112228,13 +112245,13 @@
112228112245
**
112229112246
** SELECT * FROM tabA, (SELECT * FROM sub1, sub2), tabB;
112230112247
**
112231112248
** The outer query has 3 slots in its FROM clause. One slot of the
112232112249
** outer query (the middle slot) is used by the subquery. The next
112233
- ** block of code will expand the out query to 4 slots. The middle
112234
- ** slot is expanded to two slots in order to make space for the
112235
- ** two elements in the FROM clause of the subquery.
112250
+ ** block of code will expand the outer query FROM clause to 4 slots.
112251
+ ** The middle slot is expanded to two slots in order to make space
112252
+ ** for the two elements in the FROM clause of the subquery.
112236112253
*/
112237112254
if( nSubSrc>1 ){
112238112255
pParent->pSrc = pSrc = sqlite3SrcListEnlarge(db, pSrc, nSubSrc-1,iFrom+1);
112239112256
if( db->mallocFailed ){
112240112257
break;
@@ -112269,15 +112286,10 @@
112269112286
char *zName = sqlite3DbStrDup(db, pList->a[i].zSpan);
112270112287
sqlite3Dequote(zName);
112271112288
pList->a[i].zName = zName;
112272112289
}
112273112290
}
112274
- substExprList(db, pParent->pEList, iParent, pSub->pEList);
112275
- if( isAgg ){
112276
- substExprList(db, pParent->pGroupBy, iParent, pSub->pEList);
112277
- pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
112278
- }
112279112291
if( pSub->pOrderBy ){
112280112292
/* At this point, any non-zero iOrderByCol values indicate that the
112281112293
** ORDER BY column expression is identical to the iOrderByCol'th
112282112294
** expression returned by SELECT statement pSub. Since these values
112283112295
** do not necessarily correspond to columns in SELECT statement pParent,
@@ -112293,31 +112305,24 @@
112293112305
}
112294112306
assert( pParent->pOrderBy==0 );
112295112307
assert( pSub->pPrior==0 );
112296112308
pParent->pOrderBy = pOrderBy;
112297112309
pSub->pOrderBy = 0;
112298
- }else if( pParent->pOrderBy ){
112299
- substExprList(db, pParent->pOrderBy, iParent, pSub->pEList);
112300
- }
112301
- if( pSub->pWhere ){
112302
- pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
112303
- }else{
112304
- pWhere = 0;
112305
- }
112310
+ }
112311
+ pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
112306112312
if( subqueryIsAgg ){
112307112313
assert( pParent->pHaving==0 );
112308112314
pParent->pHaving = pParent->pWhere;
112309112315
pParent->pWhere = pWhere;
112310
- pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
112311112316
pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving,
112312112317
sqlite3ExprDup(db, pSub->pHaving, 0));
112313112318
assert( pParent->pGroupBy==0 );
112314112319
pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0);
112315112320
}else{
112316
- pParent->pWhere = substExpr(db, pParent->pWhere, iParent, pSub->pEList);
112317112321
pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere);
112318112322
}
112323
+ substSelect(db, pParent, iParent, pSub->pEList, 0);
112319112324
112320112325
/* The flattened query is distinct if either the inner or the
112321112326
** outer query is distinct.
112322112327
*/
112323112328
pParent->selFlags |= pSub->selFlags & SF_Distinct;
@@ -112878,19 +112883,23 @@
112878112883
return WRC_Abort;
112879112884
}
112880112885
pTab->nRef++;
112881112886
#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
112882112887
if( pTab->pSelect || IsVirtual(pTab) ){
112888
+ i16 nCol;
112883112889
if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
112884112890
assert( pFrom->pSelect==0 );
112885112891
if( pFrom->fg.isTabFunc && !IsVirtual(pTab) ){
112886112892
sqlite3ErrorMsg(pParse, "'%s' is not a function", pTab->zName);
112887112893
return WRC_Abort;
112888112894
}
112889112895
pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
112890112896
sqlite3SelectSetName(pFrom->pSelect, pTab->zName);
112897
+ nCol = pTab->nCol;
112898
+ pTab->nCol = -1;
112891112899
sqlite3WalkSelect(pWalker, pFrom->pSelect);
112900
+ pTab->nCol = nCol;
112892112901
}
112893112902
#endif
112894112903
}
112895112904
112896112905
/* Locate the index named by the INDEXED BY clause, if any. */
@@ -158656,10 +158665,14 @@
158656158665
#ifndef _SQLITE3RBU_H
158657158666
#define _SQLITE3RBU_H
158658158667
158659158668
/* #include "sqlite3.h" ** Required for error code definitions ** */
158660158669
158670
+#if 0
158671
+extern "C" {
158672
+#endif
158673
+
158661158674
typedef struct sqlite3rbu sqlite3rbu;
158662158675
158663158676
/*
158664158677
** Open an RBU handle.
158665158678
**
@@ -158834,10 +158847,14 @@
158834158847
** before all database handles that use it have been closed, the results
158835158848
** are undefined.
158836158849
*/
158837158850
SQLITE_API void SQLITE_STDCALL sqlite3rbu_destroy_vfs(const char *zName);
158838158851
158852
+#if 0
158853
+} /* end of the 'extern "C"' block */
158854
+#endif
158855
+
158839158856
#endif /* _SQLITE3RBU_H */
158840158857
158841158858
/************** End of sqlite3rbu.h ******************************************/
158842158859
/************** Continuing where we left off in sqlite3rbu.c *****************/
158843158860
@@ -164400,11 +164417,11 @@
164400164417
164401164418
/*
164402164419
** Compare the OBJECT label at pNode against zKey,nKey. Return true on
164403164420
** a match.
164404164421
*/
164405
-static int jsonLabelCompare(JsonNode *pNode, const char *zKey, int nKey){
164422
+static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){
164406164423
if( pNode->jnFlags & JNODE_RAW ){
164407164424
if( pNode->n!=nKey ) return 0;
164408164425
return strncmp(pNode->u.zJContent, zKey, nKey)==0;
164409164426
}else{
164410164427
if( pNode->n!=nKey+2 ) return 0;
@@ -165589,10 +165606,14 @@
165589165606
#ifndef _FTS5_H
165590165607
#define _FTS5_H
165591165608
165592165609
/* #include "sqlite3.h" */
165593165610
165611
+#if 0
165612
+extern "C" {
165613
+#endif
165614
+
165594165615
/*************************************************************************
165595165616
** CUSTOM AUXILIARY FUNCTIONS
165596165617
**
165597165618
** Virtual table implementations may overload SQL functions by implementing
165598165619
** the sqlite3_module.xFindFunction() method.
@@ -166074,10 +166095,14 @@
166074166095
166075166096
/*
166076166097
** END OF REGISTRATION API
166077166098
*************************************************************************/
166078166099
166100
+#if 0
166101
+} /* end of the 'extern "C"' block */
166102
+#endif
166103
+
166079166104
#endif /* _FTS5_H */
166080166105
166081166106
166082166107
/*
166083166108
** 2014 May 31
@@ -166332,11 +166357,10 @@
166332166357
#define FTS5_POS2OFFSET(iPos) (int)(iPos & 0xFFFFFFFF)
166333166358
166334166359
typedef struct Fts5PoslistReader Fts5PoslistReader;
166335166360
struct Fts5PoslistReader {
166336166361
/* Variables used only by sqlite3Fts5PoslistIterXXX() functions. */
166337
- int iCol; /* If (iCol>=0), this column only */
166338166362
const u8 *a; /* Position list to iterate through */
166339166363
int n; /* Size of buffer at a[] in bytes */
166340166364
int i; /* Current offset in a[] */
166341166365
166342166366
u8 bFlag; /* For client use (any custom purpose) */
@@ -166344,11 +166368,10 @@
166344166368
/* Output variables */
166345166369
u8 bEof; /* Set to true at EOF */
166346166370
i64 iPos; /* (iCol<<32) + iPos */
166347166371
};
166348166372
static int sqlite3Fts5PoslistReaderInit(
166349
- int iCol, /* If (iCol>=0), this column only */
166350166373
const u8 *a, int n, /* Poslist buffer to iterate through */
166351166374
Fts5PoslistReader *pIter /* Iterator object to initialize */
166352166375
);
166353166376
static int sqlite3Fts5PoslistReaderNext(Fts5PoslistReader*);
166354166377
@@ -166425,11 +166448,11 @@
166425166448
*/
166426166449
static int sqlite3Fts5IterEof(Fts5IndexIter*);
166427166450
static int sqlite3Fts5IterNext(Fts5IndexIter*);
166428166451
static int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch);
166429166452
static i64 sqlite3Fts5IterRowid(Fts5IndexIter*);
166430
-static int sqlite3Fts5IterPoslist(Fts5IndexIter*, const u8 **pp, int *pn, i64 *pi);
166453
+static int sqlite3Fts5IterPoslist(Fts5IndexIter*,Fts5Colset*, const u8**, int*, i64*);
166431166454
static int sqlite3Fts5IterPoslistBuffer(Fts5IndexIter *pIter, Fts5Buffer *pBuf);
166432166455
166433166456
/*
166434166457
** Close an iterator opened by sqlite3Fts5IndexQuery().
166435166458
*/
@@ -168735,30 +168758,24 @@
168735168758
/*
168736168759
** Advance the iterator object passed as the only argument. Return true
168737168760
** if the iterator reaches EOF, or false otherwise.
168738168761
*/
168739168762
static int sqlite3Fts5PoslistReaderNext(Fts5PoslistReader *pIter){
168740
- if( sqlite3Fts5PoslistNext64(pIter->a, pIter->n, &pIter->i, &pIter->iPos)
168741
- || (pIter->iCol>=0 && (pIter->iPos >> 32) > pIter->iCol)
168742
- ){
168763
+ if( sqlite3Fts5PoslistNext64(pIter->a, pIter->n, &pIter->i, &pIter->iPos) ){
168743168764
pIter->bEof = 1;
168744168765
}
168745168766
return pIter->bEof;
168746168767
}
168747168768
168748168769
static int sqlite3Fts5PoslistReaderInit(
168749
- int iCol, /* If (iCol>=0), this column only */
168750168770
const u8 *a, int n, /* Poslist buffer to iterate through */
168751168771
Fts5PoslistReader *pIter /* Iterator object to initialize */
168752168772
){
168753168773
memset(pIter, 0, sizeof(*pIter));
168754168774
pIter->a = a;
168755168775
pIter->n = n;
168756
- pIter->iCol = iCol;
168757
- do {
168758
- sqlite3Fts5PoslistReaderNext(pIter);
168759
- }while( pIter->bEof==0 && (pIter->iPos >> 32)<iCol );
168776
+ sqlite3Fts5PoslistReaderNext(pIter);
168760168777
return pIter->bEof;
168761168778
}
168762168779
168763168780
static int sqlite3Fts5PoslistWriterAppend(
168764168781
Fts5Buffer *pBuf,
@@ -169982,18 +169999,10 @@
169982169999
sqlite3_free(p->apExprPhrase);
169983170000
sqlite3_free(p);
169984170001
}
169985170002
}
169986170003
169987
-static int fts5ExprColsetTest(Fts5Colset *pColset, int iCol){
169988
- int i;
169989
- for(i=0; i<pColset->nCol; i++){
169990
- if( pColset->aiCol[i]==iCol ) return 1;
169991
- }
169992
- return 0;
169993
-}
169994
-
169995170004
/*
169996170005
** Argument pTerm must be a synonym iterator. Return the current rowid
169997170006
** that it points to.
169998170007
*/
169999170008
static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){
@@ -170020,10 +170029,11 @@
170020170029
/*
170021170030
** Argument pTerm must be a synonym iterator.
170022170031
*/
170023170032
static int fts5ExprSynonymPoslist(
170024170033
Fts5ExprTerm *pTerm,
170034
+ Fts5Colset *pColset,
170025170035
i64 iRowid,
170026170036
int *pbDel, /* OUT: Caller should sqlite3_free(*pa) */
170027170037
u8 **pa, int *pn
170028170038
){
170029170039
Fts5PoslistReader aStatic[4];
@@ -170038,11 +170048,11 @@
170038170048
Fts5IndexIter *pIter = p->pIter;
170039170049
if( sqlite3Fts5IterEof(pIter)==0 && sqlite3Fts5IterRowid(pIter)==iRowid ){
170040170050
const u8 *a;
170041170051
int n;
170042170052
i64 dummy;
170043
- rc = sqlite3Fts5IterPoslist(pIter, &a, &n, &dummy);
170053
+ rc = sqlite3Fts5IterPoslist(pIter, pColset, &a, &n, &dummy);
170044170054
if( rc!=SQLITE_OK ) goto synonym_poslist_out;
170045170055
if( nIter==nAlloc ){
170046170056
int nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
170047170057
Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc(nByte);
170048170058
if( aNew==0 ){
@@ -170052,11 +170062,11 @@
170052170062
memcpy(aNew, aIter, sizeof(Fts5PoslistReader) * nIter);
170053170063
nAlloc = nAlloc*2;
170054170064
if( aIter!=aStatic ) sqlite3_free(aIter);
170055170065
aIter = aNew;
170056170066
}
170057
- sqlite3Fts5PoslistReaderInit(-1, a, n, &aIter[nIter]);
170067
+ sqlite3Fts5PoslistReaderInit(a, n, &aIter[nIter]);
170058170068
assert( aIter[nIter].bEof==0 );
170059170069
nIter++;
170060170070
}
170061170071
}
170062170072
@@ -170120,17 +170130,11 @@
170120170130
Fts5PoslistWriter writer = {0};
170121170131
Fts5PoslistReader aStatic[4];
170122170132
Fts5PoslistReader *aIter = aStatic;
170123170133
int i;
170124170134
int rc = SQLITE_OK;
170125
- int iCol = -1;
170126170135
170127
- if( pColset && pColset->nCol==1 ){
170128
- iCol = pColset->aiCol[0];
170129
- pColset = 0;
170130
- }
170131
-
170132170136
fts5BufferZero(&pPhrase->poslist);
170133170137
170134170138
/* If the aStatic[] array is not large enough, allocate a large array
170135170139
** using sqlite3_malloc(). This approach could be improved upon. */
170136170140
if( pPhrase->nTerm>(sizeof(aStatic) / sizeof(aStatic[0])) ){
@@ -170146,16 +170150,18 @@
170146170150
i64 dummy;
170147170151
int n = 0;
170148170152
int bFlag = 0;
170149170153
const u8 *a = 0;
170150170154
if( pTerm->pSynonym ){
170151
- rc = fts5ExprSynonymPoslist(pTerm, pNode->iRowid, &bFlag, (u8**)&a, &n);
170155
+ rc = fts5ExprSynonymPoslist(
170156
+ pTerm, pColset, pNode->iRowid, &bFlag, (u8**)&a, &n
170157
+ );
170152170158
}else{
170153
- rc = sqlite3Fts5IterPoslist(pTerm->pIter, &a, &n, &dummy);
170159
+ rc = sqlite3Fts5IterPoslist(pTerm->pIter, pColset, &a, &n, &dummy);
170154170160
}
170155170161
if( rc!=SQLITE_OK ) goto ismatch_out;
170156
- sqlite3Fts5PoslistReaderInit(iCol, a, n, &aIter[i]);
170162
+ sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
170157170163
aIter[i].bFlag = bFlag;
170158170164
if( aIter[i].bEof ) goto ismatch_out;
170159170165
}
170160170166
170161170167
while( 1 ){
@@ -170174,15 +170180,13 @@
170174170180
if( pPos->iPos>iAdj ) iPos = pPos->iPos-i;
170175170181
}
170176170182
}
170177170183
}while( bMatch==0 );
170178170184
170179
- if( pColset==0 || fts5ExprColsetTest(pColset, FTS5_POS2COLUMN(iPos)) ){
170180
- /* Append position iPos to the output */
170181
- rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
170182
- if( rc!=SQLITE_OK ) goto ismatch_out;
170183
- }
170185
+ /* Append position iPos to the output */
170186
+ rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
170187
+ if( rc!=SQLITE_OK ) goto ismatch_out;
170184170188
170185170189
for(i=0; i<pPhrase->nTerm; i++){
170186170190
if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) goto ismatch_out;
170187170191
}
170188170192
}
@@ -170473,65 +170477,10 @@
170473170477
*piLast = fts5ExprSynonymRowid(pTerm, bDesc, &bEof);
170474170478
}
170475170479
return bEof;
170476170480
}
170477170481
170478
-/*
170479
-** IN/OUT parameter (*pa) points to a position list n bytes in size. If
170480
-** the position list contains entries for column iCol, then (*pa) is set
170481
-** to point to the sub-position-list for that column and the number of
170482
-** bytes in it returned. Or, if the argument position list does not
170483
-** contain any entries for column iCol, return 0.
170484
-*/
170485
-static int fts5ExprExtractCol(
170486
- const u8 **pa, /* IN/OUT: Pointer to poslist */
170487
- int n, /* IN: Size of poslist in bytes */
170488
- int iCol /* Column to extract from poslist */
170489
-){
170490
- int iCurrent = 0;
170491
- const u8 *p = *pa;
170492
- const u8 *pEnd = &p[n]; /* One byte past end of position list */
170493
- u8 prev = 0;
170494
-
170495
- while( iCol!=iCurrent ){
170496
- /* Advance pointer p until it points to pEnd or an 0x01 byte that is
170497
- ** not part of a varint */
170498
- while( (prev & 0x80) || *p!=0x01 ){
170499
- prev = *p++;
170500
- if( p==pEnd ) return 0;
170501
- }
170502
- *pa = p++;
170503
- p += fts5GetVarint32(p, iCurrent);
170504
- }
170505
-
170506
- /* Advance pointer p until it points to pEnd or an 0x01 byte that is
170507
- ** not part of a varint */
170508
- assert( (prev & 0x80)==0 );
170509
- while( p<pEnd && ((prev & 0x80) || *p!=0x01) ){
170510
- prev = *p++;
170511
- }
170512
- return p - (*pa);
170513
-}
170514
-
170515
-static int fts5ExprExtractColset (
170516
- Fts5Colset *pColset, /* Colset to filter on */
170517
- const u8 *pPos, int nPos, /* Position list */
170518
- Fts5Buffer *pBuf /* Output buffer */
170519
-){
170520
- int rc = SQLITE_OK;
170521
- int i;
170522
-
170523
- fts5BufferZero(pBuf);
170524
- for(i=0; i<pColset->nCol; i++){
170525
- const u8 *pSub = pPos;
170526
- int nSub = fts5ExprExtractCol(&pSub, nPos, pColset->aiCol[i]);
170527
- if( nSub ){
170528
- fts5BufferAppendBlob(&rc, pBuf, nSub, pSub);
170529
- }
170530
- }
170531
- return rc;
170532
-}
170533170482
170534170483
static int fts5ExprNearTest(
170535170484
int *pRc,
170536170485
Fts5Expr *pExpr, /* Expression that pNear is a part of */
170537170486
Fts5ExprNode *pNode /* The "NEAR" node (FTS5_STRING) */
@@ -170575,38 +170524,19 @@
170575170524
** expressions. */
170576170525
Fts5ExprNearset *pNear = pNode->pNear;
170577170526
Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
170578170527
Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
170579170528
Fts5Colset *pColset = pNear->pColset;
170580
- const u8 *pPos;
170581
- int nPos;
170582170529
int rc;
170583170530
170584170531
assert( pNode->eType==FTS5_TERM );
170585170532
assert( pNear->nPhrase==1 && pPhrase->nTerm==1 );
170586170533
assert( pPhrase->aTerm[0].pSynonym==0 );
170587170534
170588
- rc = sqlite3Fts5IterPoslist(pIter, &pPos, &nPos, &pNode->iRowid);
170589
-
170590
- /* If the term may match any column, then this must be a match.
170591
- ** Return immediately in this case. Otherwise, try to find the
170592
- ** part of the poslist that corresponds to the required column.
170593
- ** If it can be found, return. If it cannot, the next iteration
170594
- ** of the loop will test the next rowid in the database for this
170595
- ** term. */
170596
- if( pColset==0 ){
170597
- assert( pPhrase->poslist.nSpace==0 );
170598
- pPhrase->poslist.p = (u8*)pPos;
170599
- pPhrase->poslist.n = nPos;
170600
- }else if( pColset->nCol==1 ){
170601
- assert( pPhrase->poslist.nSpace==0 );
170602
- pPhrase->poslist.n = fts5ExprExtractCol(&pPos, nPos, pColset->aiCol[0]);
170603
- pPhrase->poslist.p = (u8*)pPos;
170604
- }else if( rc==SQLITE_OK ){
170605
- rc = fts5ExprExtractColset(pColset, pPos, nPos, &pPhrase->poslist);
170606
- }
170607
-
170535
+ rc = sqlite3Fts5IterPoslist(pIter, pColset,
170536
+ (const u8**)&pPhrase->poslist.p, &pPhrase->poslist.n, &pNode->iRowid
170537
+ );
170608170538
pNode->bNomatch = (pPhrase->poslist.n==0);
170609170539
return rc;
170610170540
}
170611170541
170612170542
/*
@@ -172033,11 +171963,10 @@
172033171963
nRet = 0;
172034171964
}
172035171965
return nRet;
172036171966
}
172037171967
172038
-
172039171968
/*
172040171969
** 2014 August 11
172041171970
**
172042171971
** The author disclaims copyright to this source code. In place of
172043171972
** a legal notice, here is a blessing:
@@ -173018,12 +172947,13 @@
173018172947
Fts5Structure *pStruct; /* Database structure for this iterator */
173019172948
Fts5Buffer poslist; /* Buffer containing current poslist */
173020172949
173021172950
int nSeg; /* Size of aSeg[] array */
173022172951
int bRev; /* True to iterate in reverse order */
173023
- int bSkipEmpty; /* True to skip deleted entries */
173024
- int bEof; /* True at EOF */
172952
+ u8 bSkipEmpty; /* True to skip deleted entries */
172953
+ u8 bEof; /* True at EOF */
172954
+ u8 bFiltered; /* True if column-filter already applied */
173025172955
173026172956
i64 iSwitchRowid; /* Firstest rowid of other than aFirst[1] */
173027172957
Fts5CResult *aFirst; /* Current merge state (see above) */
173028172958
Fts5SegIter aSeg[1]; /* Array of segment iterators */
173029172959
};
@@ -173964,11 +173894,12 @@
173964173894
** read. Before returning, set *pnSz to the number of bytes in the position
173965173895
** list, and *pbDel to true if the delete flag is set, or false otherwise.
173966173896
*/
173967173897
static int fts5GetPoslistSize(const u8 *p, int *pnSz, int *pbDel){
173968173898
int nSz;
173969
- int n = fts5GetVarint32(p, nSz);
173899
+ int n = 0;
173900
+ fts5FastGetVarint32(p, n, nSz);
173970173901
assert_nc( nSz>=0 );
173971173902
*pnSz = nSz/2;
173972173903
*pbDel = nSz & 0x0001;
173973173904
return n;
173974173905
}
@@ -173985,17 +173916,16 @@
173985173916
** position list content (if any).
173986173917
*/
173987173918
static void fts5SegIterLoadNPos(Fts5Index *p, Fts5SegIter *pIter){
173988173919
if( p->rc==SQLITE_OK ){
173989173920
int iOff = pIter->iLeafOffset; /* Offset to read at */
173921
+ int nSz;
173990173922
ASSERT_SZLEAF_OK(pIter->pLeaf);
173991
- if( iOff>=pIter->pLeaf->szLeaf ){
173992
- p->rc = FTS5_CORRUPT;
173993
- }else{
173994
- const u8 *a = &pIter->pLeaf->p[iOff];
173995
- pIter->iLeafOffset += fts5GetPoslistSize(a, &pIter->nPos, &pIter->bDel);
173996
- }
173923
+ fts5FastGetVarint32(pIter->pLeaf->p, iOff, nSz);
173924
+ pIter->bDel = (nSz & 0x0001);
173925
+ pIter->nPos = nSz>>1;
173926
+ pIter->iLeafOffset = iOff;
173997173927
}
173998173928
}
173999173929
174000173930
static void fts5SegIterLoadRowid(Fts5Index *p, Fts5SegIter *pIter){
174001173931
u8 *a = pIter->pLeaf->p; /* Buffer to read data from */
@@ -175232,10 +175162,11 @@
175232175162
Fts5IndexIter *pNew;
175233175163
pNew = fts5MultiIterAlloc(p, 2);
175234175164
if( pNew ){
175235175165
Fts5SegIter *pIter = &pNew->aSeg[1];
175236175166
175167
+ pNew->bFiltered = 1;
175237175168
pIter->flags = FTS5_SEGITER_ONETERM;
175238175169
if( pData->szLeaf>0 ){
175239175170
pIter->pLeaf = pData;
175240175171
pIter->iLeafOffset = fts5GetVarint(pData->p, (u64*)&pIter->iRowid);
175241175172
pIter->iEndofDoclist = pData->nn;
@@ -176447,11 +176378,11 @@
176447176378
void *pContext,
176448176379
const u8 *pChunk, int nChunk
176449176380
){
176450176381
assert_nc( nChunk>=0 );
176451176382
if( nChunk>0 ){
176452
- fts5BufferAppendBlob(&p->rc, (Fts5Buffer*)pContext, nChunk, pChunk);
176383
+ fts5BufferSafeAppendBlob((Fts5Buffer*)pContext, pChunk, nChunk);
176453176384
}
176454176385
}
176455176386
176456176387
typedef struct PoslistCallbackCtx PoslistCallbackCtx;
176457176388
struct PoslistCallbackCtx {
@@ -176487,11 +176418,11 @@
176487176418
if( pCtx->eState==2 ){
176488176419
int iCol;
176489176420
fts5FastGetVarint32(pChunk, i, iCol);
176490176421
if( fts5IndexColsetTest(pCtx->pColset, iCol) ){
176491176422
pCtx->eState = 1;
176492
- fts5BufferAppendVarint(&p->rc, pCtx->pBuf, 1);
176423
+ fts5BufferSafeAppendVarint(pCtx->pBuf, 1);
176493176424
}else{
176494176425
pCtx->eState = 0;
176495176426
}
176496176427
}
176497176428
@@ -176499,11 +176430,11 @@
176499176430
while( i<nChunk && pChunk[i]!=0x01 ){
176500176431
while( pChunk[i] & 0x80 ) i++;
176501176432
i++;
176502176433
}
176503176434
if( pCtx->eState ){
176504
- fts5BufferAppendBlob(&p->rc, pCtx->pBuf, i-iStart, &pChunk[iStart]);
176435
+ fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart);
176505176436
}
176506176437
if( i<nChunk ){
176507176438
int iCol;
176508176439
iStart = i;
176509176440
i++;
@@ -176511,11 +176442,11 @@
176511176442
pCtx->eState = 2;
176512176443
}else{
176513176444
fts5FastGetVarint32(pChunk, i, iCol);
176514176445
pCtx->eState = fts5IndexColsetTest(pCtx->pColset, iCol);
176515176446
if( pCtx->eState ){
176516
- fts5BufferAppendBlob(&p->rc, pCtx->pBuf, i-iStart, &pChunk[iStart]);
176447
+ fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart);
176517176448
iStart = i;
176518176449
}
176519176450
}
176520176451
}
176521176452
}while( i<nChunk );
@@ -176532,60 +176463,127 @@
176532176463
Fts5Index *p,
176533176464
Fts5SegIter *pSeg,
176534176465
Fts5Colset *pColset,
176535176466
Fts5Buffer *pBuf
176536176467
){
176537
- if( pColset==0 ){
176538
- fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback);
176539
- }else{
176540
- PoslistCallbackCtx sCtx;
176541
- sCtx.pBuf = pBuf;
176542
- sCtx.pColset = pColset;
176543
- sCtx.eState = pColset ? fts5IndexColsetTest(pColset, 0) : 1;
176544
- assert( sCtx.eState==0 || sCtx.eState==1 );
176545
- fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistFilterCallback);
176468
+ if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos) ){
176469
+ if( pColset==0 ){
176470
+ fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback);
176471
+ }else{
176472
+ PoslistCallbackCtx sCtx;
176473
+ sCtx.pBuf = pBuf;
176474
+ sCtx.pColset = pColset;
176475
+ sCtx.eState = pColset ? fts5IndexColsetTest(pColset, 0) : 1;
176476
+ assert( sCtx.eState==0 || sCtx.eState==1 );
176477
+ fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistFilterCallback);
176478
+ }
176546176479
}
176547176480
}
176481
+
176482
+/*
176483
+** IN/OUT parameter (*pa) points to a position list n bytes in size. If
176484
+** the position list contains entries for column iCol, then (*pa) is set
176485
+** to point to the sub-position-list for that column and the number of
176486
+** bytes in it returned. Or, if the argument position list does not
176487
+** contain any entries for column iCol, return 0.
176488
+*/
176489
+static int fts5IndexExtractCol(
176490
+ const u8 **pa, /* IN/OUT: Pointer to poslist */
176491
+ int n, /* IN: Size of poslist in bytes */
176492
+ int iCol /* Column to extract from poslist */
176493
+){
176494
+ int iCurrent = 0; /* Anything before the first 0x01 is col 0 */
176495
+ const u8 *p = *pa;
176496
+ const u8 *pEnd = &p[n]; /* One byte past end of position list */
176497
+ u8 prev = 0;
176498
+
176499
+ while( iCol!=iCurrent ){
176500
+ /* Advance pointer p until it points to pEnd or an 0x01 byte that is
176501
+ ** not part of a varint */
176502
+ while( (prev & 0x80) || *p!=0x01 ){
176503
+ prev = *p++;
176504
+ if( p==pEnd ) return 0;
176505
+ }
176506
+ *pa = p++;
176507
+ p += fts5GetVarint32(p, iCurrent);
176508
+ }
176509
+
176510
+ /* Advance pointer p until it points to pEnd or an 0x01 byte that is
176511
+ ** not part of a varint */
176512
+ assert( (prev & 0x80)==0 );
176513
+ while( p<pEnd && ((prev & 0x80) || *p!=0x01) ){
176514
+ prev = *p++;
176515
+ }
176516
+ return p - (*pa);
176517
+}
176518
+
176548176519
176549176520
/*
176550176521
** Iterator pMulti currently points to a valid entry (not EOF). This
176551
-** function appends a copy of the position-list of the entry pMulti
176552
-** currently points to to buffer pBuf.
176522
+** function appends the following to buffer pBuf:
176553176523
**
176554
-** If an error occurs, an error code is left in p->rc. It is assumed
176555
-** no error has already occurred when this function is called.
176524
+** * The varint iDelta, and
176525
+** * the position list that currently points to, including the size field.
176526
+**
176527
+** If argument pColset is NULL, then the position list is filtered according
176528
+** to pColset before being appended to the buffer. If this means there are
176529
+** no entries in the position list, nothing is appended to the buffer (not
176530
+** even iDelta).
176531
+**
176532
+** If an error occurs, an error code is left in p->rc.
176556176533
*/
176557
-static int fts5MultiIterPoslist(
176534
+static int fts5AppendPoslist(
176558176535
Fts5Index *p,
176536
+ i64 iDelta,
176559176537
Fts5IndexIter *pMulti,
176560176538
Fts5Colset *pColset,
176561176539
Fts5Buffer *pBuf
176562176540
){
176563176541
if( p->rc==SQLITE_OK ){
176564
- int iSz;
176565
- int iData;
176566
-
176567176542
Fts5SegIter *pSeg = &pMulti->aSeg[ pMulti->aFirst[1].iFirst ];
176568176543
assert( fts5MultiIterEof(p, pMulti)==0 );
176569
-
176570
- /* WRITEPOSLISTSIZE */
176571
- iSz = pBuf->n;
176572
- fts5BufferSafeAppendVarint(pBuf, pSeg->nPos*2);
176573
- iData = pBuf->n;
176574
-
176575
- fts5SegiterPoslist(p, pSeg, pColset, pBuf);
176576
-
176577
- if( pColset ){
176578
- int nActual = pBuf->n - iData;
176579
- if( nActual!=pSeg->nPos ){
176580
- /* WRITEPOSLISTSIZE */
176581
- if( nActual==0 ){
176582
- return 1;
176544
+ assert( pSeg->nPos>0 );
176545
+ if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos+9+9) ){
176546
+ int iSv1;
176547
+ int iSv2;
176548
+ int iData;
176549
+
176550
+ /* Append iDelta */
176551
+ iSv1 = pBuf->n;
176552
+ fts5BufferSafeAppendVarint(pBuf, iDelta);
176553
+
176554
+ /* WRITEPOSLISTSIZE */
176555
+ iSv2 = pBuf->n;
176556
+ fts5BufferSafeAppendVarint(pBuf, pSeg->nPos*2);
176557
+ iData = pBuf->n;
176558
+
176559
+ if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf
176560
+ && (pColset==0 || pColset->nCol==1)
176561
+ ){
176562
+ const u8 *pPos = &pSeg->pLeaf->p[pSeg->iLeafOffset];
176563
+ int nPos;
176564
+ if( pColset ){
176565
+ nPos = fts5IndexExtractCol(&pPos, pSeg->nPos, pColset->aiCol[0]);
176583176566
}else{
176584
- int nReq = sqlite3Fts5GetVarintLen((u32)(nActual*2));
176585
- while( iSz<(iData-nReq) ){ pBuf->p[iSz++] = 0x80; }
176586
- sqlite3Fts5PutVarint(&pBuf->p[iSz], nActual*2);
176567
+ nPos = pSeg->nPos;
176568
+ }
176569
+ fts5BufferSafeAppendBlob(pBuf, pPos, nPos);
176570
+ }else{
176571
+ fts5SegiterPoslist(p, pSeg, pColset, pBuf);
176572
+ }
176573
+
176574
+ if( pColset ){
176575
+ int nActual = pBuf->n - iData;
176576
+ if( nActual!=pSeg->nPos ){
176577
+ if( nActual==0 ){
176578
+ pBuf->n = iSv1;
176579
+ return 1;
176580
+ }else{
176581
+ int nReq = sqlite3Fts5GetVarintLen((u32)(nActual*2));
176582
+ while( iSv2<(iData-nReq) ){ pBuf->p[iSv2++] = 0x80; }
176583
+ sqlite3Fts5PutVarint(&pBuf->p[iSv2], nActual*2);
176584
+ }
176587176585
}
176588176586
}
176589176587
}
176590176588
}
176591176589
@@ -176789,19 +176787,12 @@
176789176787
}
176790176788
}
176791176789
iLastRowid = 0;
176792176790
}
176793176791
176794
- if( 0==sqlite3Fts5BufferGrow(&p->rc, &doclist, 9) ){
176795
- int iSave = doclist.n;
176796
- assert( doclist.n!=0 || iLastRowid==0 );
176797
- fts5BufferSafeAppendVarint(&doclist, iRowid - iLastRowid);
176798
- if( fts5MultiIterPoslist(p, p1, pColset, &doclist) ){
176799
- doclist.n = iSave;
176800
- }else{
176801
- iLastRowid = iRowid;
176802
- }
176792
+ if( !fts5AppendPoslist(p, iRowid-iLastRowid, p1, pColset, &doclist) ){
176793
+ iLastRowid = iRowid;
176803176794
}
176804176795
}
176805176796
176806176797
for(i=0; i<nBuf; i++){
176807176798
if( p->rc==SQLITE_OK ){
@@ -177154,10 +177145,30 @@
177154177145
const char *z = (const char*)fts5MultiIterTerm(pIter, &n);
177155177146
*pn = n-1;
177156177147
return &z[1];
177157177148
}
177158177149
177150
+
177151
+static int fts5IndexExtractColset (
177152
+ Fts5Colset *pColset, /* Colset to filter on */
177153
+ const u8 *pPos, int nPos, /* Position list */
177154
+ Fts5Buffer *pBuf /* Output buffer */
177155
+){
177156
+ int rc = SQLITE_OK;
177157
+ int i;
177158
+
177159
+ fts5BufferZero(pBuf);
177160
+ for(i=0; i<pColset->nCol; i++){
177161
+ const u8 *pSub = pPos;
177162
+ int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]);
177163
+ if( nSub ){
177164
+ fts5BufferAppendBlob(&rc, pBuf, nSub, pSub);
177165
+ }
177166
+ }
177167
+ return rc;
177168
+}
177169
+
177159177170
177160177171
/*
177161177172
** Return a pointer to a buffer containing a copy of the position list for
177162177173
** the current entry. Output variable *pn is set to the size of the buffer
177163177174
** in bytes before returning.
@@ -177165,24 +177176,37 @@
177165177176
** The returned position list does not include the "number of bytes" varint
177166177177
** field that starts the position list on disk.
177167177178
*/
177168177179
static int sqlite3Fts5IterPoslist(
177169177180
Fts5IndexIter *pIter,
177181
+ Fts5Colset *pColset, /* Column filter (or NULL) */
177170177182
const u8 **pp, /* OUT: Pointer to position-list data */
177171177183
int *pn, /* OUT: Size of position-list in bytes */
177172177184
i64 *piRowid /* OUT: Current rowid */
177173177185
){
177174177186
Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
177175177187
assert( pIter->pIndex->rc==SQLITE_OK );
177176177188
*piRowid = pSeg->iRowid;
177177
- *pn = pSeg->nPos;
177178
- if( pSeg->iLeafOffset+pSeg->nPos <= pSeg->pLeaf->szLeaf ){
177179
- *pp = &pSeg->pLeaf->p[pSeg->iLeafOffset];
177189
+ if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){
177190
+ u8 *pPos = &pSeg->pLeaf->p[pSeg->iLeafOffset];
177191
+ if( pColset==0 || pIter->bFiltered ){
177192
+ *pn = pSeg->nPos;
177193
+ *pp = pPos;
177194
+ }else if( pColset->nCol==1 ){
177195
+ *pp = pPos;
177196
+ *pn = fts5IndexExtractCol(pp, pSeg->nPos, pColset->aiCol[0]);
177197
+ }else{
177198
+ fts5BufferZero(&pIter->poslist);
177199
+ fts5IndexExtractColset(pColset, pPos, pSeg->nPos, &pIter->poslist);
177200
+ *pp = pIter->poslist.p;
177201
+ *pn = pIter->poslist.n;
177202
+ }
177180177203
}else{
177181177204
fts5BufferZero(&pIter->poslist);
177182
- fts5SegiterPoslist(pIter->pIndex, pSeg, 0, &pIter->poslist);
177205
+ fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist);
177183177206
*pp = pIter->poslist.p;
177207
+ *pn = pIter->poslist.n;
177184177208
}
177185177209
return fts5IndexReturn(pIter->pIndex);
177186177210
}
177187177211
177188177212
/*
@@ -177375,14 +177399,14 @@
177375177399
while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIdxIter) ){
177376177400
i64 dummy;
177377177401
const u8 *pPos;
177378177402
int nPos;
177379177403
i64 rowid = sqlite3Fts5IterRowid(pIdxIter);
177380
- rc = sqlite3Fts5IterPoslist(pIdxIter, &pPos, &nPos, &dummy);
177404
+ rc = sqlite3Fts5IterPoslist(pIdxIter, 0, &pPos, &nPos, &dummy);
177381177405
if( rc==SQLITE_OK ){
177382177406
Fts5PoslistReader sReader;
177383
- for(sqlite3Fts5PoslistReaderInit(-1, pPos, nPos, &sReader);
177407
+ for(sqlite3Fts5PoslistReaderInit(pPos, nPos, &sReader);
177384177408
sReader.bEof==0;
177385177409
sqlite3Fts5PoslistReaderNext(&sReader)
177386177410
){
177387177411
int iCol = FTS5_POS2COLUMN(sReader.iPos);
177388177412
int iOff = FTS5_POS2OFFSET(sReader.iPos);
@@ -179790,11 +179814,11 @@
179790179814
179791179815
/* Initialize all iterators */
179792179816
for(i=0; i<nIter; i++){
179793179817
const u8 *a;
179794179818
int n = fts5CsrPoslist(pCsr, i, &a);
179795
- sqlite3Fts5PoslistReaderInit(-1, a, n, &aIter[i]);
179819
+ sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
179796179820
}
179797179821
179798179822
while( 1 ){
179799179823
int *aInst;
179800179824
int iBest = -1;
@@ -180541,11 +180565,11 @@
180541180565
sqlite3_context *pCtx, /* Function call context */
180542180566
int nArg, /* Number of args */
180543180567
sqlite3_value **apVal /* Function arguments */
180544180568
){
180545180569
assert( nArg==0 );
180546
- sqlite3_result_text(pCtx, "fts5: 2015-10-10 15:57:20 35e6248abb4435a8b26d270092b856beff867406", -1, SQLITE_TRANSIENT);
180570
+ sqlite3_result_text(pCtx, "fts5: 2015-10-14 12:29:53 a721fc0d89495518fe5612e2e3bbc60befd2e90d", -1, SQLITE_TRANSIENT);
180547180571
}
180548180572
180549180573
static int fts5Init(sqlite3 *db){
180550180574
static const sqlite3_module fts5Mod = {
180551180575
/* iVersion */ 2,
@@ -184045,11 +184069,11 @@
184045184069
i64 dummy;
184046184070
const u8 *pPos; int nPos; /* Position list */
184047184071
i64 iPos = 0; /* 64-bit position read from poslist */
184048184072
int iOff = 0; /* Current offset within position list */
184049184073
184050
- rc = sqlite3Fts5IterPoslist(pCsr->pIter, &pPos, &nPos, &dummy);
184074
+ rc = sqlite3Fts5IterPoslist(pCsr->pIter, 0, &pPos, &nPos, &dummy);
184051184075
if( rc==SQLITE_OK ){
184052184076
if( pTab->eType==FTS5_VOCAB_ROW ){
184053184077
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
184054184078
pCsr->aVal[1]++;
184055184079
}
184056184080
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -325,11 +325,11 @@
325 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
326 ** [sqlite_version()] and [sqlite_source_id()].
327 */
328 #define SQLITE_VERSION "3.9.0"
329 #define SQLITE_VERSION_NUMBER 3009000
330 #define SQLITE_SOURCE_ID "2015-10-10 15:57:20 35e6248abb4435a8b26d270092b856beff867406"
331
332 /*
333 ** CAPI3REF: Run-Time Library Version Numbers
334 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
335 **
@@ -5868,13 +5868,13 @@
5868 ** used with an SQLite version earlier than 3.8.2, the results of attempting
5869 ** to read or write the estimatedRows field are undefined (but are likely
5870 ** to included crashing the application). The estimatedRows field should
5871 ** therefore only be used if [sqlite3_libversion_number()] returns a
5872 ** value greater than or equal to 3008002. Similarly, the idxFlags field
5873 ** was added for version 3.8.12. It may therefore only be used if
5874 ** sqlite3_libversion_number() returns a value greater than or equal to
5875 ** 3008012.
5876 */
5877 struct sqlite3_index_info {
5878 /* Inputs */
5879 int nConstraint; /* Number of entries in aConstraint */
5880 struct sqlite3_index_constraint {
@@ -5898,11 +5898,11 @@
5898 int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */
5899 int orderByConsumed; /* True if output is already ordered */
5900 double estimatedCost; /* Estimated cost of using this index */
5901 /* Fields below are only available in SQLite 3.8.2 and later */
5902 sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
5903 /* Fields below are only available in SQLite 3.8.12 and later */
5904 int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */
5905 };
5906
5907 /*
5908 ** CAPI3REF: Virtual Table Scan Flags
@@ -8158,10 +8158,14 @@
8158 #ifndef _FTS5_H
8159 #define _FTS5_H
8160
8161 /* #include "sqlite3.h" */
8162
 
 
 
 
8163 /*************************************************************************
8164 ** CUSTOM AUXILIARY FUNCTIONS
8165 **
8166 ** Virtual table implementations may overload SQL functions by implementing
8167 ** the sqlite3_module.xFindFunction() method.
@@ -8643,10 +8647,14 @@
8643
8644 /*
8645 ** END OF REGISTRATION API
8646 *************************************************************************/
8647
 
 
 
 
8648 #endif /* _FTS5_H */
8649
8650
8651
8652 /************** End of sqlite3.h *********************************************/
@@ -60993,11 +61001,17 @@
60993 if( (aData[1]==0 && aData[2]==0) || (pSlot = pageFindSlot(pPg,sz,&rc))==0 ){
60994 pData -= sz;
60995 if( pData<pBegin ) return 1;
60996 pSlot = pData;
60997 }
60998 memcpy(pSlot, pCArray->apCell[i], sz);
 
 
 
 
 
 
60999 put2byte(pCellptr, (pSlot - aData));
61000 pCellptr += 2;
61001 }
61002 *ppData = pData;
61003 return 0;
@@ -104303,11 +104317,11 @@
104303 /* Version 3.8.11 and later */
104304 sqlite3_value *(*value_dup)(const sqlite3_value*);
104305 void (*value_free)(sqlite3_value*);
104306 int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
104307 int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
104308 /* Version 3.8.12 and later */
104309 unsigned int (*value_subtype)(sqlite3_value*);
104310 void (*result_subtype)(sqlite3_context*,unsigned int);
104311 };
104312
104313 /*
@@ -104542,11 +104556,11 @@
104542 /* Version 3.8.11 and later */
104543 #define sqlite3_value_dup sqlite3_api->value_dup
104544 #define sqlite3_value_free sqlite3_api->value_free
104545 #define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64
104546 #define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64
104547 /* Version 3.8.12 and later */
104548 #define sqlite3_value_subtype sqlite3_api->value_subtype
104549 #define sqlite3_result_subtype sqlite3_api->result_subtype
104550 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
104551
104552 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
@@ -104957,11 +104971,11 @@
104957 /* Version 3.8.11 and later */
104958 (sqlite3_value*(*)(const sqlite3_value*))sqlite3_value_dup,
104959 sqlite3_value_free,
104960 sqlite3_result_zeroblob64,
104961 sqlite3_bind_zeroblob64,
104962 /* Version 3.8.12 and later */
104963 sqlite3_value_subtype,
104964 sqlite3_result_subtype
104965 };
104966
104967 /*
@@ -111703,11 +111717,11 @@
111703 #endif
111704
111705 #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
111706 /* Forward Declarations */
111707 static void substExprList(sqlite3*, ExprList*, int, ExprList*);
111708 static void substSelect(sqlite3*, Select *, int, ExprList *);
111709
111710 /*
111711 ** Scan through the expression pExpr. Replace every reference to
111712 ** a column in table number iTable with a copy of the iColumn-th
111713 ** entry in pEList. (But leave references to the ROWID column
@@ -111740,11 +111754,11 @@
111740 }
111741 }else{
111742 pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList);
111743 pExpr->pRight = substExpr(db, pExpr->pRight, iTable, pEList);
111744 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
111745 substSelect(db, pExpr->x.pSelect, iTable, pEList);
111746 }else{
111747 substExprList(db, pExpr->x.pList, iTable, pEList);
111748 }
111749 }
111750 return pExpr;
@@ -111763,29 +111777,32 @@
111763 }
111764 static void substSelect(
111765 sqlite3 *db, /* Report malloc errors here */
111766 Select *p, /* SELECT statement in which to make substitutions */
111767 int iTable, /* Table to be replaced */
111768 ExprList *pEList /* Substitute values */
 
111769 ){
111770 SrcList *pSrc;
111771 struct SrcList_item *pItem;
111772 int i;
111773 if( !p ) return;
111774 substExprList(db, p->pEList, iTable, pEList);
111775 substExprList(db, p->pGroupBy, iTable, pEList);
111776 substExprList(db, p->pOrderBy, iTable, pEList);
111777 p->pHaving = substExpr(db, p->pHaving, iTable, pEList);
111778 p->pWhere = substExpr(db, p->pWhere, iTable, pEList);
111779 substSelect(db, p->pPrior, iTable, pEList);
111780 pSrc = p->pSrc;
111781 assert( pSrc ); /* Even for (SELECT 1) we have: pSrc!=0 but pSrc->nSrc==0 */
111782 if( ALWAYS(pSrc) ){
111783 for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
111784 substSelect(db, pItem->pSelect, iTable, pEList);
 
 
 
111785 }
111786 }
111787 }
111788 #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
111789
111790 #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
111791 /*
@@ -111933,11 +111950,11 @@
111933 int iFrom, /* Index in p->pSrc->a[] of the inner subquery */
111934 int isAgg, /* True if outer SELECT uses aggregate functions */
111935 int subqueryIsAgg /* True if the subquery uses aggregate functions */
111936 ){
111937 const char *zSavedAuthContext = pParse->zAuthContext;
111938 Select *pParent;
111939 Select *pSub; /* The inner query or "subquery" */
111940 Select *pSub1; /* Pointer to the rightmost select in sub-query */
111941 SrcList *pSrc; /* The FROM clause of the outer query */
111942 SrcList *pSubSrc; /* The FROM clause of the subquery */
111943 ExprList *pList; /* The result set of the outer query */
@@ -112228,13 +112245,13 @@
112228 **
112229 ** SELECT * FROM tabA, (SELECT * FROM sub1, sub2), tabB;
112230 **
112231 ** The outer query has 3 slots in its FROM clause. One slot of the
112232 ** outer query (the middle slot) is used by the subquery. The next
112233 ** block of code will expand the out query to 4 slots. The middle
112234 ** slot is expanded to two slots in order to make space for the
112235 ** two elements in the FROM clause of the subquery.
112236 */
112237 if( nSubSrc>1 ){
112238 pParent->pSrc = pSrc = sqlite3SrcListEnlarge(db, pSrc, nSubSrc-1,iFrom+1);
112239 if( db->mallocFailed ){
112240 break;
@@ -112269,15 +112286,10 @@
112269 char *zName = sqlite3DbStrDup(db, pList->a[i].zSpan);
112270 sqlite3Dequote(zName);
112271 pList->a[i].zName = zName;
112272 }
112273 }
112274 substExprList(db, pParent->pEList, iParent, pSub->pEList);
112275 if( isAgg ){
112276 substExprList(db, pParent->pGroupBy, iParent, pSub->pEList);
112277 pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
112278 }
112279 if( pSub->pOrderBy ){
112280 /* At this point, any non-zero iOrderByCol values indicate that the
112281 ** ORDER BY column expression is identical to the iOrderByCol'th
112282 ** expression returned by SELECT statement pSub. Since these values
112283 ** do not necessarily correspond to columns in SELECT statement pParent,
@@ -112293,31 +112305,24 @@
112293 }
112294 assert( pParent->pOrderBy==0 );
112295 assert( pSub->pPrior==0 );
112296 pParent->pOrderBy = pOrderBy;
112297 pSub->pOrderBy = 0;
112298 }else if( pParent->pOrderBy ){
112299 substExprList(db, pParent->pOrderBy, iParent, pSub->pEList);
112300 }
112301 if( pSub->pWhere ){
112302 pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
112303 }else{
112304 pWhere = 0;
112305 }
112306 if( subqueryIsAgg ){
112307 assert( pParent->pHaving==0 );
112308 pParent->pHaving = pParent->pWhere;
112309 pParent->pWhere = pWhere;
112310 pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
112311 pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving,
112312 sqlite3ExprDup(db, pSub->pHaving, 0));
112313 assert( pParent->pGroupBy==0 );
112314 pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0);
112315 }else{
112316 pParent->pWhere = substExpr(db, pParent->pWhere, iParent, pSub->pEList);
112317 pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere);
112318 }
 
112319
112320 /* The flattened query is distinct if either the inner or the
112321 ** outer query is distinct.
112322 */
112323 pParent->selFlags |= pSub->selFlags & SF_Distinct;
@@ -112878,19 +112883,23 @@
112878 return WRC_Abort;
112879 }
112880 pTab->nRef++;
112881 #if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
112882 if( pTab->pSelect || IsVirtual(pTab) ){
 
112883 if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
112884 assert( pFrom->pSelect==0 );
112885 if( pFrom->fg.isTabFunc && !IsVirtual(pTab) ){
112886 sqlite3ErrorMsg(pParse, "'%s' is not a function", pTab->zName);
112887 return WRC_Abort;
112888 }
112889 pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
112890 sqlite3SelectSetName(pFrom->pSelect, pTab->zName);
 
 
112891 sqlite3WalkSelect(pWalker, pFrom->pSelect);
 
112892 }
112893 #endif
112894 }
112895
112896 /* Locate the index named by the INDEXED BY clause, if any. */
@@ -158656,10 +158665,14 @@
158656 #ifndef _SQLITE3RBU_H
158657 #define _SQLITE3RBU_H
158658
158659 /* #include "sqlite3.h" ** Required for error code definitions ** */
158660
 
 
 
 
158661 typedef struct sqlite3rbu sqlite3rbu;
158662
158663 /*
158664 ** Open an RBU handle.
158665 **
@@ -158834,10 +158847,14 @@
158834 ** before all database handles that use it have been closed, the results
158835 ** are undefined.
158836 */
158837 SQLITE_API void SQLITE_STDCALL sqlite3rbu_destroy_vfs(const char *zName);
158838
 
 
 
 
158839 #endif /* _SQLITE3RBU_H */
158840
158841 /************** End of sqlite3rbu.h ******************************************/
158842 /************** Continuing where we left off in sqlite3rbu.c *****************/
158843
@@ -164400,11 +164417,11 @@
164400
164401 /*
164402 ** Compare the OBJECT label at pNode against zKey,nKey. Return true on
164403 ** a match.
164404 */
164405 static int jsonLabelCompare(JsonNode *pNode, const char *zKey, int nKey){
164406 if( pNode->jnFlags & JNODE_RAW ){
164407 if( pNode->n!=nKey ) return 0;
164408 return strncmp(pNode->u.zJContent, zKey, nKey)==0;
164409 }else{
164410 if( pNode->n!=nKey+2 ) return 0;
@@ -165589,10 +165606,14 @@
165589 #ifndef _FTS5_H
165590 #define _FTS5_H
165591
165592 /* #include "sqlite3.h" */
165593
 
 
 
 
165594 /*************************************************************************
165595 ** CUSTOM AUXILIARY FUNCTIONS
165596 **
165597 ** Virtual table implementations may overload SQL functions by implementing
165598 ** the sqlite3_module.xFindFunction() method.
@@ -166074,10 +166095,14 @@
166074
166075 /*
166076 ** END OF REGISTRATION API
166077 *************************************************************************/
166078
 
 
 
 
166079 #endif /* _FTS5_H */
166080
166081
166082 /*
166083 ** 2014 May 31
@@ -166332,11 +166357,10 @@
166332 #define FTS5_POS2OFFSET(iPos) (int)(iPos & 0xFFFFFFFF)
166333
166334 typedef struct Fts5PoslistReader Fts5PoslistReader;
166335 struct Fts5PoslistReader {
166336 /* Variables used only by sqlite3Fts5PoslistIterXXX() functions. */
166337 int iCol; /* If (iCol>=0), this column only */
166338 const u8 *a; /* Position list to iterate through */
166339 int n; /* Size of buffer at a[] in bytes */
166340 int i; /* Current offset in a[] */
166341
166342 u8 bFlag; /* For client use (any custom purpose) */
@@ -166344,11 +166368,10 @@
166344 /* Output variables */
166345 u8 bEof; /* Set to true at EOF */
166346 i64 iPos; /* (iCol<<32) + iPos */
166347 };
166348 static int sqlite3Fts5PoslistReaderInit(
166349 int iCol, /* If (iCol>=0), this column only */
166350 const u8 *a, int n, /* Poslist buffer to iterate through */
166351 Fts5PoslistReader *pIter /* Iterator object to initialize */
166352 );
166353 static int sqlite3Fts5PoslistReaderNext(Fts5PoslistReader*);
166354
@@ -166425,11 +166448,11 @@
166425 */
166426 static int sqlite3Fts5IterEof(Fts5IndexIter*);
166427 static int sqlite3Fts5IterNext(Fts5IndexIter*);
166428 static int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch);
166429 static i64 sqlite3Fts5IterRowid(Fts5IndexIter*);
166430 static int sqlite3Fts5IterPoslist(Fts5IndexIter*, const u8 **pp, int *pn, i64 *pi);
166431 static int sqlite3Fts5IterPoslistBuffer(Fts5IndexIter *pIter, Fts5Buffer *pBuf);
166432
166433 /*
166434 ** Close an iterator opened by sqlite3Fts5IndexQuery().
166435 */
@@ -168735,30 +168758,24 @@
168735 /*
168736 ** Advance the iterator object passed as the only argument. Return true
168737 ** if the iterator reaches EOF, or false otherwise.
168738 */
168739 static int sqlite3Fts5PoslistReaderNext(Fts5PoslistReader *pIter){
168740 if( sqlite3Fts5PoslistNext64(pIter->a, pIter->n, &pIter->i, &pIter->iPos)
168741 || (pIter->iCol>=0 && (pIter->iPos >> 32) > pIter->iCol)
168742 ){
168743 pIter->bEof = 1;
168744 }
168745 return pIter->bEof;
168746 }
168747
168748 static int sqlite3Fts5PoslistReaderInit(
168749 int iCol, /* If (iCol>=0), this column only */
168750 const u8 *a, int n, /* Poslist buffer to iterate through */
168751 Fts5PoslistReader *pIter /* Iterator object to initialize */
168752 ){
168753 memset(pIter, 0, sizeof(*pIter));
168754 pIter->a = a;
168755 pIter->n = n;
168756 pIter->iCol = iCol;
168757 do {
168758 sqlite3Fts5PoslistReaderNext(pIter);
168759 }while( pIter->bEof==0 && (pIter->iPos >> 32)<iCol );
168760 return pIter->bEof;
168761 }
168762
168763 static int sqlite3Fts5PoslistWriterAppend(
168764 Fts5Buffer *pBuf,
@@ -169982,18 +169999,10 @@
169982 sqlite3_free(p->apExprPhrase);
169983 sqlite3_free(p);
169984 }
169985 }
169986
169987 static int fts5ExprColsetTest(Fts5Colset *pColset, int iCol){
169988 int i;
169989 for(i=0; i<pColset->nCol; i++){
169990 if( pColset->aiCol[i]==iCol ) return 1;
169991 }
169992 return 0;
169993 }
169994
169995 /*
169996 ** Argument pTerm must be a synonym iterator. Return the current rowid
169997 ** that it points to.
169998 */
169999 static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){
@@ -170020,10 +170029,11 @@
170020 /*
170021 ** Argument pTerm must be a synonym iterator.
170022 */
170023 static int fts5ExprSynonymPoslist(
170024 Fts5ExprTerm *pTerm,
 
170025 i64 iRowid,
170026 int *pbDel, /* OUT: Caller should sqlite3_free(*pa) */
170027 u8 **pa, int *pn
170028 ){
170029 Fts5PoslistReader aStatic[4];
@@ -170038,11 +170048,11 @@
170038 Fts5IndexIter *pIter = p->pIter;
170039 if( sqlite3Fts5IterEof(pIter)==0 && sqlite3Fts5IterRowid(pIter)==iRowid ){
170040 const u8 *a;
170041 int n;
170042 i64 dummy;
170043 rc = sqlite3Fts5IterPoslist(pIter, &a, &n, &dummy);
170044 if( rc!=SQLITE_OK ) goto synonym_poslist_out;
170045 if( nIter==nAlloc ){
170046 int nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
170047 Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc(nByte);
170048 if( aNew==0 ){
@@ -170052,11 +170062,11 @@
170052 memcpy(aNew, aIter, sizeof(Fts5PoslistReader) * nIter);
170053 nAlloc = nAlloc*2;
170054 if( aIter!=aStatic ) sqlite3_free(aIter);
170055 aIter = aNew;
170056 }
170057 sqlite3Fts5PoslistReaderInit(-1, a, n, &aIter[nIter]);
170058 assert( aIter[nIter].bEof==0 );
170059 nIter++;
170060 }
170061 }
170062
@@ -170120,17 +170130,11 @@
170120 Fts5PoslistWriter writer = {0};
170121 Fts5PoslistReader aStatic[4];
170122 Fts5PoslistReader *aIter = aStatic;
170123 int i;
170124 int rc = SQLITE_OK;
170125 int iCol = -1;
170126
170127 if( pColset && pColset->nCol==1 ){
170128 iCol = pColset->aiCol[0];
170129 pColset = 0;
170130 }
170131
170132 fts5BufferZero(&pPhrase->poslist);
170133
170134 /* If the aStatic[] array is not large enough, allocate a large array
170135 ** using sqlite3_malloc(). This approach could be improved upon. */
170136 if( pPhrase->nTerm>(sizeof(aStatic) / sizeof(aStatic[0])) ){
@@ -170146,16 +170150,18 @@
170146 i64 dummy;
170147 int n = 0;
170148 int bFlag = 0;
170149 const u8 *a = 0;
170150 if( pTerm->pSynonym ){
170151 rc = fts5ExprSynonymPoslist(pTerm, pNode->iRowid, &bFlag, (u8**)&a, &n);
 
 
170152 }else{
170153 rc = sqlite3Fts5IterPoslist(pTerm->pIter, &a, &n, &dummy);
170154 }
170155 if( rc!=SQLITE_OK ) goto ismatch_out;
170156 sqlite3Fts5PoslistReaderInit(iCol, a, n, &aIter[i]);
170157 aIter[i].bFlag = bFlag;
170158 if( aIter[i].bEof ) goto ismatch_out;
170159 }
170160
170161 while( 1 ){
@@ -170174,15 +170180,13 @@
170174 if( pPos->iPos>iAdj ) iPos = pPos->iPos-i;
170175 }
170176 }
170177 }while( bMatch==0 );
170178
170179 if( pColset==0 || fts5ExprColsetTest(pColset, FTS5_POS2COLUMN(iPos)) ){
170180 /* Append position iPos to the output */
170181 rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
170182 if( rc!=SQLITE_OK ) goto ismatch_out;
170183 }
170184
170185 for(i=0; i<pPhrase->nTerm; i++){
170186 if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) goto ismatch_out;
170187 }
170188 }
@@ -170473,65 +170477,10 @@
170473 *piLast = fts5ExprSynonymRowid(pTerm, bDesc, &bEof);
170474 }
170475 return bEof;
170476 }
170477
170478 /*
170479 ** IN/OUT parameter (*pa) points to a position list n bytes in size. If
170480 ** the position list contains entries for column iCol, then (*pa) is set
170481 ** to point to the sub-position-list for that column and the number of
170482 ** bytes in it returned. Or, if the argument position list does not
170483 ** contain any entries for column iCol, return 0.
170484 */
170485 static int fts5ExprExtractCol(
170486 const u8 **pa, /* IN/OUT: Pointer to poslist */
170487 int n, /* IN: Size of poslist in bytes */
170488 int iCol /* Column to extract from poslist */
170489 ){
170490 int iCurrent = 0;
170491 const u8 *p = *pa;
170492 const u8 *pEnd = &p[n]; /* One byte past end of position list */
170493 u8 prev = 0;
170494
170495 while( iCol!=iCurrent ){
170496 /* Advance pointer p until it points to pEnd or an 0x01 byte that is
170497 ** not part of a varint */
170498 while( (prev & 0x80) || *p!=0x01 ){
170499 prev = *p++;
170500 if( p==pEnd ) return 0;
170501 }
170502 *pa = p++;
170503 p += fts5GetVarint32(p, iCurrent);
170504 }
170505
170506 /* Advance pointer p until it points to pEnd or an 0x01 byte that is
170507 ** not part of a varint */
170508 assert( (prev & 0x80)==0 );
170509 while( p<pEnd && ((prev & 0x80) || *p!=0x01) ){
170510 prev = *p++;
170511 }
170512 return p - (*pa);
170513 }
170514
170515 static int fts5ExprExtractColset (
170516 Fts5Colset *pColset, /* Colset to filter on */
170517 const u8 *pPos, int nPos, /* Position list */
170518 Fts5Buffer *pBuf /* Output buffer */
170519 ){
170520 int rc = SQLITE_OK;
170521 int i;
170522
170523 fts5BufferZero(pBuf);
170524 for(i=0; i<pColset->nCol; i++){
170525 const u8 *pSub = pPos;
170526 int nSub = fts5ExprExtractCol(&pSub, nPos, pColset->aiCol[i]);
170527 if( nSub ){
170528 fts5BufferAppendBlob(&rc, pBuf, nSub, pSub);
170529 }
170530 }
170531 return rc;
170532 }
170533
170534 static int fts5ExprNearTest(
170535 int *pRc,
170536 Fts5Expr *pExpr, /* Expression that pNear is a part of */
170537 Fts5ExprNode *pNode /* The "NEAR" node (FTS5_STRING) */
@@ -170575,38 +170524,19 @@
170575 ** expressions. */
170576 Fts5ExprNearset *pNear = pNode->pNear;
170577 Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
170578 Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
170579 Fts5Colset *pColset = pNear->pColset;
170580 const u8 *pPos;
170581 int nPos;
170582 int rc;
170583
170584 assert( pNode->eType==FTS5_TERM );
170585 assert( pNear->nPhrase==1 && pPhrase->nTerm==1 );
170586 assert( pPhrase->aTerm[0].pSynonym==0 );
170587
170588 rc = sqlite3Fts5IterPoslist(pIter, &pPos, &nPos, &pNode->iRowid);
170589
170590 /* If the term may match any column, then this must be a match.
170591 ** Return immediately in this case. Otherwise, try to find the
170592 ** part of the poslist that corresponds to the required column.
170593 ** If it can be found, return. If it cannot, the next iteration
170594 ** of the loop will test the next rowid in the database for this
170595 ** term. */
170596 if( pColset==0 ){
170597 assert( pPhrase->poslist.nSpace==0 );
170598 pPhrase->poslist.p = (u8*)pPos;
170599 pPhrase->poslist.n = nPos;
170600 }else if( pColset->nCol==1 ){
170601 assert( pPhrase->poslist.nSpace==0 );
170602 pPhrase->poslist.n = fts5ExprExtractCol(&pPos, nPos, pColset->aiCol[0]);
170603 pPhrase->poslist.p = (u8*)pPos;
170604 }else if( rc==SQLITE_OK ){
170605 rc = fts5ExprExtractColset(pColset, pPos, nPos, &pPhrase->poslist);
170606 }
170607
170608 pNode->bNomatch = (pPhrase->poslist.n==0);
170609 return rc;
170610 }
170611
170612 /*
@@ -172033,11 +171963,10 @@
172033 nRet = 0;
172034 }
172035 return nRet;
172036 }
172037
172038
172039 /*
172040 ** 2014 August 11
172041 **
172042 ** The author disclaims copyright to this source code. In place of
172043 ** a legal notice, here is a blessing:
@@ -173018,12 +172947,13 @@
173018 Fts5Structure *pStruct; /* Database structure for this iterator */
173019 Fts5Buffer poslist; /* Buffer containing current poslist */
173020
173021 int nSeg; /* Size of aSeg[] array */
173022 int bRev; /* True to iterate in reverse order */
173023 int bSkipEmpty; /* True to skip deleted entries */
173024 int bEof; /* True at EOF */
 
173025
173026 i64 iSwitchRowid; /* Firstest rowid of other than aFirst[1] */
173027 Fts5CResult *aFirst; /* Current merge state (see above) */
173028 Fts5SegIter aSeg[1]; /* Array of segment iterators */
173029 };
@@ -173964,11 +173894,12 @@
173964 ** read. Before returning, set *pnSz to the number of bytes in the position
173965 ** list, and *pbDel to true if the delete flag is set, or false otherwise.
173966 */
173967 static int fts5GetPoslistSize(const u8 *p, int *pnSz, int *pbDel){
173968 int nSz;
173969 int n = fts5GetVarint32(p, nSz);
 
173970 assert_nc( nSz>=0 );
173971 *pnSz = nSz/2;
173972 *pbDel = nSz & 0x0001;
173973 return n;
173974 }
@@ -173985,17 +173916,16 @@
173985 ** position list content (if any).
173986 */
173987 static void fts5SegIterLoadNPos(Fts5Index *p, Fts5SegIter *pIter){
173988 if( p->rc==SQLITE_OK ){
173989 int iOff = pIter->iLeafOffset; /* Offset to read at */
 
173990 ASSERT_SZLEAF_OK(pIter->pLeaf);
173991 if( iOff>=pIter->pLeaf->szLeaf ){
173992 p->rc = FTS5_CORRUPT;
173993 }else{
173994 const u8 *a = &pIter->pLeaf->p[iOff];
173995 pIter->iLeafOffset += fts5GetPoslistSize(a, &pIter->nPos, &pIter->bDel);
173996 }
173997 }
173998 }
173999
174000 static void fts5SegIterLoadRowid(Fts5Index *p, Fts5SegIter *pIter){
174001 u8 *a = pIter->pLeaf->p; /* Buffer to read data from */
@@ -175232,10 +175162,11 @@
175232 Fts5IndexIter *pNew;
175233 pNew = fts5MultiIterAlloc(p, 2);
175234 if( pNew ){
175235 Fts5SegIter *pIter = &pNew->aSeg[1];
175236
 
175237 pIter->flags = FTS5_SEGITER_ONETERM;
175238 if( pData->szLeaf>0 ){
175239 pIter->pLeaf = pData;
175240 pIter->iLeafOffset = fts5GetVarint(pData->p, (u64*)&pIter->iRowid);
175241 pIter->iEndofDoclist = pData->nn;
@@ -176447,11 +176378,11 @@
176447 void *pContext,
176448 const u8 *pChunk, int nChunk
176449 ){
176450 assert_nc( nChunk>=0 );
176451 if( nChunk>0 ){
176452 fts5BufferAppendBlob(&p->rc, (Fts5Buffer*)pContext, nChunk, pChunk);
176453 }
176454 }
176455
176456 typedef struct PoslistCallbackCtx PoslistCallbackCtx;
176457 struct PoslistCallbackCtx {
@@ -176487,11 +176418,11 @@
176487 if( pCtx->eState==2 ){
176488 int iCol;
176489 fts5FastGetVarint32(pChunk, i, iCol);
176490 if( fts5IndexColsetTest(pCtx->pColset, iCol) ){
176491 pCtx->eState = 1;
176492 fts5BufferAppendVarint(&p->rc, pCtx->pBuf, 1);
176493 }else{
176494 pCtx->eState = 0;
176495 }
176496 }
176497
@@ -176499,11 +176430,11 @@
176499 while( i<nChunk && pChunk[i]!=0x01 ){
176500 while( pChunk[i] & 0x80 ) i++;
176501 i++;
176502 }
176503 if( pCtx->eState ){
176504 fts5BufferAppendBlob(&p->rc, pCtx->pBuf, i-iStart, &pChunk[iStart]);
176505 }
176506 if( i<nChunk ){
176507 int iCol;
176508 iStart = i;
176509 i++;
@@ -176511,11 +176442,11 @@
176511 pCtx->eState = 2;
176512 }else{
176513 fts5FastGetVarint32(pChunk, i, iCol);
176514 pCtx->eState = fts5IndexColsetTest(pCtx->pColset, iCol);
176515 if( pCtx->eState ){
176516 fts5BufferAppendBlob(&p->rc, pCtx->pBuf, i-iStart, &pChunk[iStart]);
176517 iStart = i;
176518 }
176519 }
176520 }
176521 }while( i<nChunk );
@@ -176532,60 +176463,127 @@
176532 Fts5Index *p,
176533 Fts5SegIter *pSeg,
176534 Fts5Colset *pColset,
176535 Fts5Buffer *pBuf
176536 ){
176537 if( pColset==0 ){
176538 fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback);
176539 }else{
176540 PoslistCallbackCtx sCtx;
176541 sCtx.pBuf = pBuf;
176542 sCtx.pColset = pColset;
176543 sCtx.eState = pColset ? fts5IndexColsetTest(pColset, 0) : 1;
176544 assert( sCtx.eState==0 || sCtx.eState==1 );
176545 fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistFilterCallback);
 
 
176546 }
176547 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176548
176549 /*
176550 ** Iterator pMulti currently points to a valid entry (not EOF). This
176551 ** function appends a copy of the position-list of the entry pMulti
176552 ** currently points to to buffer pBuf.
176553 **
176554 ** If an error occurs, an error code is left in p->rc. It is assumed
176555 ** no error has already occurred when this function is called.
 
 
 
 
 
 
 
176556 */
176557 static int fts5MultiIterPoslist(
176558 Fts5Index *p,
 
176559 Fts5IndexIter *pMulti,
176560 Fts5Colset *pColset,
176561 Fts5Buffer *pBuf
176562 ){
176563 if( p->rc==SQLITE_OK ){
176564 int iSz;
176565 int iData;
176566
176567 Fts5SegIter *pSeg = &pMulti->aSeg[ pMulti->aFirst[1].iFirst ];
176568 assert( fts5MultiIterEof(p, pMulti)==0 );
176569
176570 /* WRITEPOSLISTSIZE */
176571 iSz = pBuf->n;
176572 fts5BufferSafeAppendVarint(pBuf, pSeg->nPos*2);
176573 iData = pBuf->n;
176574
176575 fts5SegiterPoslist(p, pSeg, pColset, pBuf);
176576
176577 if( pColset ){
176578 int nActual = pBuf->n - iData;
176579 if( nActual!=pSeg->nPos ){
176580 /* WRITEPOSLISTSIZE */
176581 if( nActual==0 ){
176582 return 1;
 
 
 
 
 
 
 
 
176583 }else{
176584 int nReq = sqlite3Fts5GetVarintLen((u32)(nActual*2));
176585 while( iSz<(iData-nReq) ){ pBuf->p[iSz++] = 0x80; }
176586 sqlite3Fts5PutVarint(&pBuf->p[iSz], nActual*2);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176587 }
176588 }
176589 }
176590 }
176591
@@ -176789,19 +176787,12 @@
176789 }
176790 }
176791 iLastRowid = 0;
176792 }
176793
176794 if( 0==sqlite3Fts5BufferGrow(&p->rc, &doclist, 9) ){
176795 int iSave = doclist.n;
176796 assert( doclist.n!=0 || iLastRowid==0 );
176797 fts5BufferSafeAppendVarint(&doclist, iRowid - iLastRowid);
176798 if( fts5MultiIterPoslist(p, p1, pColset, &doclist) ){
176799 doclist.n = iSave;
176800 }else{
176801 iLastRowid = iRowid;
176802 }
176803 }
176804 }
176805
176806 for(i=0; i<nBuf; i++){
176807 if( p->rc==SQLITE_OK ){
@@ -177154,10 +177145,30 @@
177154 const char *z = (const char*)fts5MultiIterTerm(pIter, &n);
177155 *pn = n-1;
177156 return &z[1];
177157 }
177158
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177159
177160 /*
177161 ** Return a pointer to a buffer containing a copy of the position list for
177162 ** the current entry. Output variable *pn is set to the size of the buffer
177163 ** in bytes before returning.
@@ -177165,24 +177176,37 @@
177165 ** The returned position list does not include the "number of bytes" varint
177166 ** field that starts the position list on disk.
177167 */
177168 static int sqlite3Fts5IterPoslist(
177169 Fts5IndexIter *pIter,
 
177170 const u8 **pp, /* OUT: Pointer to position-list data */
177171 int *pn, /* OUT: Size of position-list in bytes */
177172 i64 *piRowid /* OUT: Current rowid */
177173 ){
177174 Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
177175 assert( pIter->pIndex->rc==SQLITE_OK );
177176 *piRowid = pSeg->iRowid;
177177 *pn = pSeg->nPos;
177178 if( pSeg->iLeafOffset+pSeg->nPos <= pSeg->pLeaf->szLeaf ){
177179 *pp = &pSeg->pLeaf->p[pSeg->iLeafOffset];
 
 
 
 
 
 
 
 
 
 
 
177180 }else{
177181 fts5BufferZero(&pIter->poslist);
177182 fts5SegiterPoslist(pIter->pIndex, pSeg, 0, &pIter->poslist);
177183 *pp = pIter->poslist.p;
 
177184 }
177185 return fts5IndexReturn(pIter->pIndex);
177186 }
177187
177188 /*
@@ -177375,14 +177399,14 @@
177375 while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIdxIter) ){
177376 i64 dummy;
177377 const u8 *pPos;
177378 int nPos;
177379 i64 rowid = sqlite3Fts5IterRowid(pIdxIter);
177380 rc = sqlite3Fts5IterPoslist(pIdxIter, &pPos, &nPos, &dummy);
177381 if( rc==SQLITE_OK ){
177382 Fts5PoslistReader sReader;
177383 for(sqlite3Fts5PoslistReaderInit(-1, pPos, nPos, &sReader);
177384 sReader.bEof==0;
177385 sqlite3Fts5PoslistReaderNext(&sReader)
177386 ){
177387 int iCol = FTS5_POS2COLUMN(sReader.iPos);
177388 int iOff = FTS5_POS2OFFSET(sReader.iPos);
@@ -179790,11 +179814,11 @@
179790
179791 /* Initialize all iterators */
179792 for(i=0; i<nIter; i++){
179793 const u8 *a;
179794 int n = fts5CsrPoslist(pCsr, i, &a);
179795 sqlite3Fts5PoslistReaderInit(-1, a, n, &aIter[i]);
179796 }
179797
179798 while( 1 ){
179799 int *aInst;
179800 int iBest = -1;
@@ -180541,11 +180565,11 @@
180541 sqlite3_context *pCtx, /* Function call context */
180542 int nArg, /* Number of args */
180543 sqlite3_value **apVal /* Function arguments */
180544 ){
180545 assert( nArg==0 );
180546 sqlite3_result_text(pCtx, "fts5: 2015-10-10 15:57:20 35e6248abb4435a8b26d270092b856beff867406", -1, SQLITE_TRANSIENT);
180547 }
180548
180549 static int fts5Init(sqlite3 *db){
180550 static const sqlite3_module fts5Mod = {
180551 /* iVersion */ 2,
@@ -184045,11 +184069,11 @@
184045 i64 dummy;
184046 const u8 *pPos; int nPos; /* Position list */
184047 i64 iPos = 0; /* 64-bit position read from poslist */
184048 int iOff = 0; /* Current offset within position list */
184049
184050 rc = sqlite3Fts5IterPoslist(pCsr->pIter, &pPos, &nPos, &dummy);
184051 if( rc==SQLITE_OK ){
184052 if( pTab->eType==FTS5_VOCAB_ROW ){
184053 while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
184054 pCsr->aVal[1]++;
184055 }
184056
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -325,11 +325,11 @@
325 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
326 ** [sqlite_version()] and [sqlite_source_id()].
327 */
328 #define SQLITE_VERSION "3.9.0"
329 #define SQLITE_VERSION_NUMBER 3009000
330 #define SQLITE_SOURCE_ID "2015-10-14 12:29:53 a721fc0d89495518fe5612e2e3bbc60befd2e90d"
331
332 /*
333 ** CAPI3REF: Run-Time Library Version Numbers
334 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
335 **
@@ -5868,13 +5868,13 @@
5868 ** used with an SQLite version earlier than 3.8.2, the results of attempting
5869 ** to read or write the estimatedRows field are undefined (but are likely
5870 ** to included crashing the application). The estimatedRows field should
5871 ** therefore only be used if [sqlite3_libversion_number()] returns a
5872 ** value greater than or equal to 3008002. Similarly, the idxFlags field
5873 ** was added for version 3.9.0. It may therefore only be used if
5874 ** sqlite3_libversion_number() returns a value greater than or equal to
5875 ** 3009000.
5876 */
5877 struct sqlite3_index_info {
5878 /* Inputs */
5879 int nConstraint; /* Number of entries in aConstraint */
5880 struct sqlite3_index_constraint {
@@ -5898,11 +5898,11 @@
5898 int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */
5899 int orderByConsumed; /* True if output is already ordered */
5900 double estimatedCost; /* Estimated cost of using this index */
5901 /* Fields below are only available in SQLite 3.8.2 and later */
5902 sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
5903 /* Fields below are only available in SQLite 3.9.0 and later */
5904 int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */
5905 };
5906
5907 /*
5908 ** CAPI3REF: Virtual Table Scan Flags
@@ -8158,10 +8158,14 @@
8158 #ifndef _FTS5_H
8159 #define _FTS5_H
8160
8161 /* #include "sqlite3.h" */
8162
8163 #if 0
8164 extern "C" {
8165 #endif
8166
8167 /*************************************************************************
8168 ** CUSTOM AUXILIARY FUNCTIONS
8169 **
8170 ** Virtual table implementations may overload SQL functions by implementing
8171 ** the sqlite3_module.xFindFunction() method.
@@ -8643,10 +8647,14 @@
8647
8648 /*
8649 ** END OF REGISTRATION API
8650 *************************************************************************/
8651
8652 #if 0
8653 } /* end of the 'extern "C"' block */
8654 #endif
8655
8656 #endif /* _FTS5_H */
8657
8658
8659
8660 /************** End of sqlite3.h *********************************************/
@@ -60993,11 +61001,17 @@
61001 if( (aData[1]==0 && aData[2]==0) || (pSlot = pageFindSlot(pPg,sz,&rc))==0 ){
61002 pData -= sz;
61003 if( pData<pBegin ) return 1;
61004 pSlot = pData;
61005 }
61006 /* pSlot and pCArray->apCell[i] will never overlap on a well-formed
61007 ** database. But they might for a corrupt database. Hence use memmove()
61008 ** since memcpy() sends SIGABORT with overlapping buffers on OpenBSD */
61009 assert( (pSlot+sz)<=pCArray->apCell[i]
61010 || pSlot>=(pCArray->apCell[i]+sz)
61011 || CORRUPT_DB );
61012 memmove(pSlot, pCArray->apCell[i], sz);
61013 put2byte(pCellptr, (pSlot - aData));
61014 pCellptr += 2;
61015 }
61016 *ppData = pData;
61017 return 0;
@@ -104303,11 +104317,11 @@
104317 /* Version 3.8.11 and later */
104318 sqlite3_value *(*value_dup)(const sqlite3_value*);
104319 void (*value_free)(sqlite3_value*);
104320 int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
104321 int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
104322 /* Version 3.9.0 and later */
104323 unsigned int (*value_subtype)(sqlite3_value*);
104324 void (*result_subtype)(sqlite3_context*,unsigned int);
104325 };
104326
104327 /*
@@ -104542,11 +104556,11 @@
104556 /* Version 3.8.11 and later */
104557 #define sqlite3_value_dup sqlite3_api->value_dup
104558 #define sqlite3_value_free sqlite3_api->value_free
104559 #define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64
104560 #define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64
104561 /* Version 3.9.0 and later */
104562 #define sqlite3_value_subtype sqlite3_api->value_subtype
104563 #define sqlite3_result_subtype sqlite3_api->result_subtype
104564 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
104565
104566 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
@@ -104957,11 +104971,11 @@
104971 /* Version 3.8.11 and later */
104972 (sqlite3_value*(*)(const sqlite3_value*))sqlite3_value_dup,
104973 sqlite3_value_free,
104974 sqlite3_result_zeroblob64,
104975 sqlite3_bind_zeroblob64,
104976 /* Version 3.9.0 and later */
104977 sqlite3_value_subtype,
104978 sqlite3_result_subtype
104979 };
104980
104981 /*
@@ -111703,11 +111717,11 @@
111717 #endif
111718
111719 #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
111720 /* Forward Declarations */
111721 static void substExprList(sqlite3*, ExprList*, int, ExprList*);
111722 static void substSelect(sqlite3*, Select *, int, ExprList*, int);
111723
111724 /*
111725 ** Scan through the expression pExpr. Replace every reference to
111726 ** a column in table number iTable with a copy of the iColumn-th
111727 ** entry in pEList. (But leave references to the ROWID column
@@ -111740,11 +111754,11 @@
111754 }
111755 }else{
111756 pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList);
111757 pExpr->pRight = substExpr(db, pExpr->pRight, iTable, pEList);
111758 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
111759 substSelect(db, pExpr->x.pSelect, iTable, pEList, 1);
111760 }else{
111761 substExprList(db, pExpr->x.pList, iTable, pEList);
111762 }
111763 }
111764 return pExpr;
@@ -111763,29 +111777,32 @@
111777 }
111778 static void substSelect(
111779 sqlite3 *db, /* Report malloc errors here */
111780 Select *p, /* SELECT statement in which to make substitutions */
111781 int iTable, /* Table to be replaced */
111782 ExprList *pEList, /* Substitute values */
111783 int doPrior /* Do substitutes on p->pPrior too */
111784 ){
111785 SrcList *pSrc;
111786 struct SrcList_item *pItem;
111787 int i;
111788 if( !p ) return;
111789 do{
111790 substExprList(db, p->pEList, iTable, pEList);
111791 substExprList(db, p->pGroupBy, iTable, pEList);
111792 substExprList(db, p->pOrderBy, iTable, pEList);
111793 p->pHaving = substExpr(db, p->pHaving, iTable, pEList);
111794 p->pWhere = substExpr(db, p->pWhere, iTable, pEList);
111795 pSrc = p->pSrc;
111796 assert( pSrc!=0 );
 
111797 for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
111798 substSelect(db, pItem->pSelect, iTable, pEList, 1);
111799 if( pItem->fg.isTabFunc ){
111800 substExprList(db, pItem->u1.pFuncArg, iTable, pEList);
111801 }
111802 }
111803 }while( doPrior && (p = p->pPrior)!=0 );
111804 }
111805 #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
111806
111807 #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
111808 /*
@@ -111933,11 +111950,11 @@
111950 int iFrom, /* Index in p->pSrc->a[] of the inner subquery */
111951 int isAgg, /* True if outer SELECT uses aggregate functions */
111952 int subqueryIsAgg /* True if the subquery uses aggregate functions */
111953 ){
111954 const char *zSavedAuthContext = pParse->zAuthContext;
111955 Select *pParent; /* Current UNION ALL term of the other query */
111956 Select *pSub; /* The inner query or "subquery" */
111957 Select *pSub1; /* Pointer to the rightmost select in sub-query */
111958 SrcList *pSrc; /* The FROM clause of the outer query */
111959 SrcList *pSubSrc; /* The FROM clause of the subquery */
111960 ExprList *pList; /* The result set of the outer query */
@@ -112228,13 +112245,13 @@
112245 **
112246 ** SELECT * FROM tabA, (SELECT * FROM sub1, sub2), tabB;
112247 **
112248 ** The outer query has 3 slots in its FROM clause. One slot of the
112249 ** outer query (the middle slot) is used by the subquery. The next
112250 ** block of code will expand the outer query FROM clause to 4 slots.
112251 ** The middle slot is expanded to two slots in order to make space
112252 ** for the two elements in the FROM clause of the subquery.
112253 */
112254 if( nSubSrc>1 ){
112255 pParent->pSrc = pSrc = sqlite3SrcListEnlarge(db, pSrc, nSubSrc-1,iFrom+1);
112256 if( db->mallocFailed ){
112257 break;
@@ -112269,15 +112286,10 @@
112286 char *zName = sqlite3DbStrDup(db, pList->a[i].zSpan);
112287 sqlite3Dequote(zName);
112288 pList->a[i].zName = zName;
112289 }
112290 }
 
 
 
 
 
112291 if( pSub->pOrderBy ){
112292 /* At this point, any non-zero iOrderByCol values indicate that the
112293 ** ORDER BY column expression is identical to the iOrderByCol'th
112294 ** expression returned by SELECT statement pSub. Since these values
112295 ** do not necessarily correspond to columns in SELECT statement pParent,
@@ -112293,31 +112305,24 @@
112305 }
112306 assert( pParent->pOrderBy==0 );
112307 assert( pSub->pPrior==0 );
112308 pParent->pOrderBy = pOrderBy;
112309 pSub->pOrderBy = 0;
112310 }
112311 pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
 
 
 
 
 
 
112312 if( subqueryIsAgg ){
112313 assert( pParent->pHaving==0 );
112314 pParent->pHaving = pParent->pWhere;
112315 pParent->pWhere = pWhere;
 
112316 pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving,
112317 sqlite3ExprDup(db, pSub->pHaving, 0));
112318 assert( pParent->pGroupBy==0 );
112319 pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0);
112320 }else{
 
112321 pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere);
112322 }
112323 substSelect(db, pParent, iParent, pSub->pEList, 0);
112324
112325 /* The flattened query is distinct if either the inner or the
112326 ** outer query is distinct.
112327 */
112328 pParent->selFlags |= pSub->selFlags & SF_Distinct;
@@ -112878,19 +112883,23 @@
112883 return WRC_Abort;
112884 }
112885 pTab->nRef++;
112886 #if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
112887 if( pTab->pSelect || IsVirtual(pTab) ){
112888 i16 nCol;
112889 if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
112890 assert( pFrom->pSelect==0 );
112891 if( pFrom->fg.isTabFunc && !IsVirtual(pTab) ){
112892 sqlite3ErrorMsg(pParse, "'%s' is not a function", pTab->zName);
112893 return WRC_Abort;
112894 }
112895 pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
112896 sqlite3SelectSetName(pFrom->pSelect, pTab->zName);
112897 nCol = pTab->nCol;
112898 pTab->nCol = -1;
112899 sqlite3WalkSelect(pWalker, pFrom->pSelect);
112900 pTab->nCol = nCol;
112901 }
112902 #endif
112903 }
112904
112905 /* Locate the index named by the INDEXED BY clause, if any. */
@@ -158656,10 +158665,14 @@
158665 #ifndef _SQLITE3RBU_H
158666 #define _SQLITE3RBU_H
158667
158668 /* #include "sqlite3.h" ** Required for error code definitions ** */
158669
158670 #if 0
158671 extern "C" {
158672 #endif
158673
158674 typedef struct sqlite3rbu sqlite3rbu;
158675
158676 /*
158677 ** Open an RBU handle.
158678 **
@@ -158834,10 +158847,14 @@
158847 ** before all database handles that use it have been closed, the results
158848 ** are undefined.
158849 */
158850 SQLITE_API void SQLITE_STDCALL sqlite3rbu_destroy_vfs(const char *zName);
158851
158852 #if 0
158853 } /* end of the 'extern "C"' block */
158854 #endif
158855
158856 #endif /* _SQLITE3RBU_H */
158857
158858 /************** End of sqlite3rbu.h ******************************************/
158859 /************** Continuing where we left off in sqlite3rbu.c *****************/
158860
@@ -164400,11 +164417,11 @@
164417
164418 /*
164419 ** Compare the OBJECT label at pNode against zKey,nKey. Return true on
164420 ** a match.
164421 */
164422 static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){
164423 if( pNode->jnFlags & JNODE_RAW ){
164424 if( pNode->n!=nKey ) return 0;
164425 return strncmp(pNode->u.zJContent, zKey, nKey)==0;
164426 }else{
164427 if( pNode->n!=nKey+2 ) return 0;
@@ -165589,10 +165606,14 @@
165606 #ifndef _FTS5_H
165607 #define _FTS5_H
165608
165609 /* #include "sqlite3.h" */
165610
165611 #if 0
165612 extern "C" {
165613 #endif
165614
165615 /*************************************************************************
165616 ** CUSTOM AUXILIARY FUNCTIONS
165617 **
165618 ** Virtual table implementations may overload SQL functions by implementing
165619 ** the sqlite3_module.xFindFunction() method.
@@ -166074,10 +166095,14 @@
166095
166096 /*
166097 ** END OF REGISTRATION API
166098 *************************************************************************/
166099
166100 #if 0
166101 } /* end of the 'extern "C"' block */
166102 #endif
166103
166104 #endif /* _FTS5_H */
166105
166106
166107 /*
166108 ** 2014 May 31
@@ -166332,11 +166357,10 @@
166357 #define FTS5_POS2OFFSET(iPos) (int)(iPos & 0xFFFFFFFF)
166358
166359 typedef struct Fts5PoslistReader Fts5PoslistReader;
166360 struct Fts5PoslistReader {
166361 /* Variables used only by sqlite3Fts5PoslistIterXXX() functions. */
 
166362 const u8 *a; /* Position list to iterate through */
166363 int n; /* Size of buffer at a[] in bytes */
166364 int i; /* Current offset in a[] */
166365
166366 u8 bFlag; /* For client use (any custom purpose) */
@@ -166344,11 +166368,10 @@
166368 /* Output variables */
166369 u8 bEof; /* Set to true at EOF */
166370 i64 iPos; /* (iCol<<32) + iPos */
166371 };
166372 static int sqlite3Fts5PoslistReaderInit(
 
166373 const u8 *a, int n, /* Poslist buffer to iterate through */
166374 Fts5PoslistReader *pIter /* Iterator object to initialize */
166375 );
166376 static int sqlite3Fts5PoslistReaderNext(Fts5PoslistReader*);
166377
@@ -166425,11 +166448,11 @@
166448 */
166449 static int sqlite3Fts5IterEof(Fts5IndexIter*);
166450 static int sqlite3Fts5IterNext(Fts5IndexIter*);
166451 static int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch);
166452 static i64 sqlite3Fts5IterRowid(Fts5IndexIter*);
166453 static int sqlite3Fts5IterPoslist(Fts5IndexIter*,Fts5Colset*, const u8**, int*, i64*);
166454 static int sqlite3Fts5IterPoslistBuffer(Fts5IndexIter *pIter, Fts5Buffer *pBuf);
166455
166456 /*
166457 ** Close an iterator opened by sqlite3Fts5IndexQuery().
166458 */
@@ -168735,30 +168758,24 @@
168758 /*
168759 ** Advance the iterator object passed as the only argument. Return true
168760 ** if the iterator reaches EOF, or false otherwise.
168761 */
168762 static int sqlite3Fts5PoslistReaderNext(Fts5PoslistReader *pIter){
168763 if( sqlite3Fts5PoslistNext64(pIter->a, pIter->n, &pIter->i, &pIter->iPos) ){
 
 
168764 pIter->bEof = 1;
168765 }
168766 return pIter->bEof;
168767 }
168768
168769 static int sqlite3Fts5PoslistReaderInit(
 
168770 const u8 *a, int n, /* Poslist buffer to iterate through */
168771 Fts5PoslistReader *pIter /* Iterator object to initialize */
168772 ){
168773 memset(pIter, 0, sizeof(*pIter));
168774 pIter->a = a;
168775 pIter->n = n;
168776 sqlite3Fts5PoslistReaderNext(pIter);
 
 
 
168777 return pIter->bEof;
168778 }
168779
168780 static int sqlite3Fts5PoslistWriterAppend(
168781 Fts5Buffer *pBuf,
@@ -169982,18 +169999,10 @@
169999 sqlite3_free(p->apExprPhrase);
170000 sqlite3_free(p);
170001 }
170002 }
170003
 
 
 
 
 
 
 
 
170004 /*
170005 ** Argument pTerm must be a synonym iterator. Return the current rowid
170006 ** that it points to.
170007 */
170008 static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){
@@ -170020,10 +170029,11 @@
170029 /*
170030 ** Argument pTerm must be a synonym iterator.
170031 */
170032 static int fts5ExprSynonymPoslist(
170033 Fts5ExprTerm *pTerm,
170034 Fts5Colset *pColset,
170035 i64 iRowid,
170036 int *pbDel, /* OUT: Caller should sqlite3_free(*pa) */
170037 u8 **pa, int *pn
170038 ){
170039 Fts5PoslistReader aStatic[4];
@@ -170038,11 +170048,11 @@
170048 Fts5IndexIter *pIter = p->pIter;
170049 if( sqlite3Fts5IterEof(pIter)==0 && sqlite3Fts5IterRowid(pIter)==iRowid ){
170050 const u8 *a;
170051 int n;
170052 i64 dummy;
170053 rc = sqlite3Fts5IterPoslist(pIter, pColset, &a, &n, &dummy);
170054 if( rc!=SQLITE_OK ) goto synonym_poslist_out;
170055 if( nIter==nAlloc ){
170056 int nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
170057 Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc(nByte);
170058 if( aNew==0 ){
@@ -170052,11 +170062,11 @@
170062 memcpy(aNew, aIter, sizeof(Fts5PoslistReader) * nIter);
170063 nAlloc = nAlloc*2;
170064 if( aIter!=aStatic ) sqlite3_free(aIter);
170065 aIter = aNew;
170066 }
170067 sqlite3Fts5PoslistReaderInit(a, n, &aIter[nIter]);
170068 assert( aIter[nIter].bEof==0 );
170069 nIter++;
170070 }
170071 }
170072
@@ -170120,17 +170130,11 @@
170130 Fts5PoslistWriter writer = {0};
170131 Fts5PoslistReader aStatic[4];
170132 Fts5PoslistReader *aIter = aStatic;
170133 int i;
170134 int rc = SQLITE_OK;
 
170135
 
 
 
 
 
170136 fts5BufferZero(&pPhrase->poslist);
170137
170138 /* If the aStatic[] array is not large enough, allocate a large array
170139 ** using sqlite3_malloc(). This approach could be improved upon. */
170140 if( pPhrase->nTerm>(sizeof(aStatic) / sizeof(aStatic[0])) ){
@@ -170146,16 +170150,18 @@
170150 i64 dummy;
170151 int n = 0;
170152 int bFlag = 0;
170153 const u8 *a = 0;
170154 if( pTerm->pSynonym ){
170155 rc = fts5ExprSynonymPoslist(
170156 pTerm, pColset, pNode->iRowid, &bFlag, (u8**)&a, &n
170157 );
170158 }else{
170159 rc = sqlite3Fts5IterPoslist(pTerm->pIter, pColset, &a, &n, &dummy);
170160 }
170161 if( rc!=SQLITE_OK ) goto ismatch_out;
170162 sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
170163 aIter[i].bFlag = bFlag;
170164 if( aIter[i].bEof ) goto ismatch_out;
170165 }
170166
170167 while( 1 ){
@@ -170174,15 +170180,13 @@
170180 if( pPos->iPos>iAdj ) iPos = pPos->iPos-i;
170181 }
170182 }
170183 }while( bMatch==0 );
170184
170185 /* Append position iPos to the output */
170186 rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
170187 if( rc!=SQLITE_OK ) goto ismatch_out;
 
 
170188
170189 for(i=0; i<pPhrase->nTerm; i++){
170190 if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) goto ismatch_out;
170191 }
170192 }
@@ -170473,65 +170477,10 @@
170477 *piLast = fts5ExprSynonymRowid(pTerm, bDesc, &bEof);
170478 }
170479 return bEof;
170480 }
170481
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170482
170483 static int fts5ExprNearTest(
170484 int *pRc,
170485 Fts5Expr *pExpr, /* Expression that pNear is a part of */
170486 Fts5ExprNode *pNode /* The "NEAR" node (FTS5_STRING) */
@@ -170575,38 +170524,19 @@
170524 ** expressions. */
170525 Fts5ExprNearset *pNear = pNode->pNear;
170526 Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
170527 Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
170528 Fts5Colset *pColset = pNear->pColset;
 
 
170529 int rc;
170530
170531 assert( pNode->eType==FTS5_TERM );
170532 assert( pNear->nPhrase==1 && pPhrase->nTerm==1 );
170533 assert( pPhrase->aTerm[0].pSynonym==0 );
170534
170535 rc = sqlite3Fts5IterPoslist(pIter, pColset,
170536 (const u8**)&pPhrase->poslist.p, &pPhrase->poslist.n, &pNode->iRowid
170537 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170538 pNode->bNomatch = (pPhrase->poslist.n==0);
170539 return rc;
170540 }
170541
170542 /*
@@ -172033,11 +171963,10 @@
171963 nRet = 0;
171964 }
171965 return nRet;
171966 }
171967
 
171968 /*
171969 ** 2014 August 11
171970 **
171971 ** The author disclaims copyright to this source code. In place of
171972 ** a legal notice, here is a blessing:
@@ -173018,12 +172947,13 @@
172947 Fts5Structure *pStruct; /* Database structure for this iterator */
172948 Fts5Buffer poslist; /* Buffer containing current poslist */
172949
172950 int nSeg; /* Size of aSeg[] array */
172951 int bRev; /* True to iterate in reverse order */
172952 u8 bSkipEmpty; /* True to skip deleted entries */
172953 u8 bEof; /* True at EOF */
172954 u8 bFiltered; /* True if column-filter already applied */
172955
172956 i64 iSwitchRowid; /* Firstest rowid of other than aFirst[1] */
172957 Fts5CResult *aFirst; /* Current merge state (see above) */
172958 Fts5SegIter aSeg[1]; /* Array of segment iterators */
172959 };
@@ -173964,11 +173894,12 @@
173894 ** read. Before returning, set *pnSz to the number of bytes in the position
173895 ** list, and *pbDel to true if the delete flag is set, or false otherwise.
173896 */
173897 static int fts5GetPoslistSize(const u8 *p, int *pnSz, int *pbDel){
173898 int nSz;
173899 int n = 0;
173900 fts5FastGetVarint32(p, n, nSz);
173901 assert_nc( nSz>=0 );
173902 *pnSz = nSz/2;
173903 *pbDel = nSz & 0x0001;
173904 return n;
173905 }
@@ -173985,17 +173916,16 @@
173916 ** position list content (if any).
173917 */
173918 static void fts5SegIterLoadNPos(Fts5Index *p, Fts5SegIter *pIter){
173919 if( p->rc==SQLITE_OK ){
173920 int iOff = pIter->iLeafOffset; /* Offset to read at */
173921 int nSz;
173922 ASSERT_SZLEAF_OK(pIter->pLeaf);
173923 fts5FastGetVarint32(pIter->pLeaf->p, iOff, nSz);
173924 pIter->bDel = (nSz & 0x0001);
173925 pIter->nPos = nSz>>1;
173926 pIter->iLeafOffset = iOff;
 
 
173927 }
173928 }
173929
173930 static void fts5SegIterLoadRowid(Fts5Index *p, Fts5SegIter *pIter){
173931 u8 *a = pIter->pLeaf->p; /* Buffer to read data from */
@@ -175232,10 +175162,11 @@
175162 Fts5IndexIter *pNew;
175163 pNew = fts5MultiIterAlloc(p, 2);
175164 if( pNew ){
175165 Fts5SegIter *pIter = &pNew->aSeg[1];
175166
175167 pNew->bFiltered = 1;
175168 pIter->flags = FTS5_SEGITER_ONETERM;
175169 if( pData->szLeaf>0 ){
175170 pIter->pLeaf = pData;
175171 pIter->iLeafOffset = fts5GetVarint(pData->p, (u64*)&pIter->iRowid);
175172 pIter->iEndofDoclist = pData->nn;
@@ -176447,11 +176378,11 @@
176378 void *pContext,
176379 const u8 *pChunk, int nChunk
176380 ){
176381 assert_nc( nChunk>=0 );
176382 if( nChunk>0 ){
176383 fts5BufferSafeAppendBlob((Fts5Buffer*)pContext, pChunk, nChunk);
176384 }
176385 }
176386
176387 typedef struct PoslistCallbackCtx PoslistCallbackCtx;
176388 struct PoslistCallbackCtx {
@@ -176487,11 +176418,11 @@
176418 if( pCtx->eState==2 ){
176419 int iCol;
176420 fts5FastGetVarint32(pChunk, i, iCol);
176421 if( fts5IndexColsetTest(pCtx->pColset, iCol) ){
176422 pCtx->eState = 1;
176423 fts5BufferSafeAppendVarint(pCtx->pBuf, 1);
176424 }else{
176425 pCtx->eState = 0;
176426 }
176427 }
176428
@@ -176499,11 +176430,11 @@
176430 while( i<nChunk && pChunk[i]!=0x01 ){
176431 while( pChunk[i] & 0x80 ) i++;
176432 i++;
176433 }
176434 if( pCtx->eState ){
176435 fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart);
176436 }
176437 if( i<nChunk ){
176438 int iCol;
176439 iStart = i;
176440 i++;
@@ -176511,11 +176442,11 @@
176442 pCtx->eState = 2;
176443 }else{
176444 fts5FastGetVarint32(pChunk, i, iCol);
176445 pCtx->eState = fts5IndexColsetTest(pCtx->pColset, iCol);
176446 if( pCtx->eState ){
176447 fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart);
176448 iStart = i;
176449 }
176450 }
176451 }
176452 }while( i<nChunk );
@@ -176532,60 +176463,127 @@
176463 Fts5Index *p,
176464 Fts5SegIter *pSeg,
176465 Fts5Colset *pColset,
176466 Fts5Buffer *pBuf
176467 ){
176468 if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos) ){
176469 if( pColset==0 ){
176470 fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback);
176471 }else{
176472 PoslistCallbackCtx sCtx;
176473 sCtx.pBuf = pBuf;
176474 sCtx.pColset = pColset;
176475 sCtx.eState = pColset ? fts5IndexColsetTest(pColset, 0) : 1;
176476 assert( sCtx.eState==0 || sCtx.eState==1 );
176477 fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistFilterCallback);
176478 }
176479 }
176480 }
176481
176482 /*
176483 ** IN/OUT parameter (*pa) points to a position list n bytes in size. If
176484 ** the position list contains entries for column iCol, then (*pa) is set
176485 ** to point to the sub-position-list for that column and the number of
176486 ** bytes in it returned. Or, if the argument position list does not
176487 ** contain any entries for column iCol, return 0.
176488 */
176489 static int fts5IndexExtractCol(
176490 const u8 **pa, /* IN/OUT: Pointer to poslist */
176491 int n, /* IN: Size of poslist in bytes */
176492 int iCol /* Column to extract from poslist */
176493 ){
176494 int iCurrent = 0; /* Anything before the first 0x01 is col 0 */
176495 const u8 *p = *pa;
176496 const u8 *pEnd = &p[n]; /* One byte past end of position list */
176497 u8 prev = 0;
176498
176499 while( iCol!=iCurrent ){
176500 /* Advance pointer p until it points to pEnd or an 0x01 byte that is
176501 ** not part of a varint */
176502 while( (prev & 0x80) || *p!=0x01 ){
176503 prev = *p++;
176504 if( p==pEnd ) return 0;
176505 }
176506 *pa = p++;
176507 p += fts5GetVarint32(p, iCurrent);
176508 }
176509
176510 /* Advance pointer p until it points to pEnd or an 0x01 byte that is
176511 ** not part of a varint */
176512 assert( (prev & 0x80)==0 );
176513 while( p<pEnd && ((prev & 0x80) || *p!=0x01) ){
176514 prev = *p++;
176515 }
176516 return p - (*pa);
176517 }
176518
176519
176520 /*
176521 ** Iterator pMulti currently points to a valid entry (not EOF). This
176522 ** function appends the following to buffer pBuf:
 
176523 **
176524 ** * The varint iDelta, and
176525 ** * the position list that currently points to, including the size field.
176526 **
176527 ** If argument pColset is NULL, then the position list is filtered according
176528 ** to pColset before being appended to the buffer. If this means there are
176529 ** no entries in the position list, nothing is appended to the buffer (not
176530 ** even iDelta).
176531 **
176532 ** If an error occurs, an error code is left in p->rc.
176533 */
176534 static int fts5AppendPoslist(
176535 Fts5Index *p,
176536 i64 iDelta,
176537 Fts5IndexIter *pMulti,
176538 Fts5Colset *pColset,
176539 Fts5Buffer *pBuf
176540 ){
176541 if( p->rc==SQLITE_OK ){
 
 
 
176542 Fts5SegIter *pSeg = &pMulti->aSeg[ pMulti->aFirst[1].iFirst ];
176543 assert( fts5MultiIterEof(p, pMulti)==0 );
176544 assert( pSeg->nPos>0 );
176545 if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos+9+9) ){
176546 int iSv1;
176547 int iSv2;
176548 int iData;
176549
176550 /* Append iDelta */
176551 iSv1 = pBuf->n;
176552 fts5BufferSafeAppendVarint(pBuf, iDelta);
176553
176554 /* WRITEPOSLISTSIZE */
176555 iSv2 = pBuf->n;
176556 fts5BufferSafeAppendVarint(pBuf, pSeg->nPos*2);
176557 iData = pBuf->n;
176558
176559 if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf
176560 && (pColset==0 || pColset->nCol==1)
176561 ){
176562 const u8 *pPos = &pSeg->pLeaf->p[pSeg->iLeafOffset];
176563 int nPos;
176564 if( pColset ){
176565 nPos = fts5IndexExtractCol(&pPos, pSeg->nPos, pColset->aiCol[0]);
176566 }else{
176567 nPos = pSeg->nPos;
176568 }
176569 fts5BufferSafeAppendBlob(pBuf, pPos, nPos);
176570 }else{
176571 fts5SegiterPoslist(p, pSeg, pColset, pBuf);
176572 }
176573
176574 if( pColset ){
176575 int nActual = pBuf->n - iData;
176576 if( nActual!=pSeg->nPos ){
176577 if( nActual==0 ){
176578 pBuf->n = iSv1;
176579 return 1;
176580 }else{
176581 int nReq = sqlite3Fts5GetVarintLen((u32)(nActual*2));
176582 while( iSv2<(iData-nReq) ){ pBuf->p[iSv2++] = 0x80; }
176583 sqlite3Fts5PutVarint(&pBuf->p[iSv2], nActual*2);
176584 }
176585 }
176586 }
176587 }
176588 }
176589
@@ -176789,19 +176787,12 @@
176787 }
176788 }
176789 iLastRowid = 0;
176790 }
176791
176792 if( !fts5AppendPoslist(p, iRowid-iLastRowid, p1, pColset, &doclist) ){
176793 iLastRowid = iRowid;
 
 
 
 
 
 
 
176794 }
176795 }
176796
176797 for(i=0; i<nBuf; i++){
176798 if( p->rc==SQLITE_OK ){
@@ -177154,10 +177145,30 @@
177145 const char *z = (const char*)fts5MultiIterTerm(pIter, &n);
177146 *pn = n-1;
177147 return &z[1];
177148 }
177149
177150
177151 static int fts5IndexExtractColset (
177152 Fts5Colset *pColset, /* Colset to filter on */
177153 const u8 *pPos, int nPos, /* Position list */
177154 Fts5Buffer *pBuf /* Output buffer */
177155 ){
177156 int rc = SQLITE_OK;
177157 int i;
177158
177159 fts5BufferZero(pBuf);
177160 for(i=0; i<pColset->nCol; i++){
177161 const u8 *pSub = pPos;
177162 int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]);
177163 if( nSub ){
177164 fts5BufferAppendBlob(&rc, pBuf, nSub, pSub);
177165 }
177166 }
177167 return rc;
177168 }
177169
177170
177171 /*
177172 ** Return a pointer to a buffer containing a copy of the position list for
177173 ** the current entry. Output variable *pn is set to the size of the buffer
177174 ** in bytes before returning.
@@ -177165,24 +177176,37 @@
177176 ** The returned position list does not include the "number of bytes" varint
177177 ** field that starts the position list on disk.
177178 */
177179 static int sqlite3Fts5IterPoslist(
177180 Fts5IndexIter *pIter,
177181 Fts5Colset *pColset, /* Column filter (or NULL) */
177182 const u8 **pp, /* OUT: Pointer to position-list data */
177183 int *pn, /* OUT: Size of position-list in bytes */
177184 i64 *piRowid /* OUT: Current rowid */
177185 ){
177186 Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
177187 assert( pIter->pIndex->rc==SQLITE_OK );
177188 *piRowid = pSeg->iRowid;
177189 if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){
177190 u8 *pPos = &pSeg->pLeaf->p[pSeg->iLeafOffset];
177191 if( pColset==0 || pIter->bFiltered ){
177192 *pn = pSeg->nPos;
177193 *pp = pPos;
177194 }else if( pColset->nCol==1 ){
177195 *pp = pPos;
177196 *pn = fts5IndexExtractCol(pp, pSeg->nPos, pColset->aiCol[0]);
177197 }else{
177198 fts5BufferZero(&pIter->poslist);
177199 fts5IndexExtractColset(pColset, pPos, pSeg->nPos, &pIter->poslist);
177200 *pp = pIter->poslist.p;
177201 *pn = pIter->poslist.n;
177202 }
177203 }else{
177204 fts5BufferZero(&pIter->poslist);
177205 fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist);
177206 *pp = pIter->poslist.p;
177207 *pn = pIter->poslist.n;
177208 }
177209 return fts5IndexReturn(pIter->pIndex);
177210 }
177211
177212 /*
@@ -177375,14 +177399,14 @@
177399 while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIdxIter) ){
177400 i64 dummy;
177401 const u8 *pPos;
177402 int nPos;
177403 i64 rowid = sqlite3Fts5IterRowid(pIdxIter);
177404 rc = sqlite3Fts5IterPoslist(pIdxIter, 0, &pPos, &nPos, &dummy);
177405 if( rc==SQLITE_OK ){
177406 Fts5PoslistReader sReader;
177407 for(sqlite3Fts5PoslistReaderInit(pPos, nPos, &sReader);
177408 sReader.bEof==0;
177409 sqlite3Fts5PoslistReaderNext(&sReader)
177410 ){
177411 int iCol = FTS5_POS2COLUMN(sReader.iPos);
177412 int iOff = FTS5_POS2OFFSET(sReader.iPos);
@@ -179790,11 +179814,11 @@
179814
179815 /* Initialize all iterators */
179816 for(i=0; i<nIter; i++){
179817 const u8 *a;
179818 int n = fts5CsrPoslist(pCsr, i, &a);
179819 sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
179820 }
179821
179822 while( 1 ){
179823 int *aInst;
179824 int iBest = -1;
@@ -180541,11 +180565,11 @@
180565 sqlite3_context *pCtx, /* Function call context */
180566 int nArg, /* Number of args */
180567 sqlite3_value **apVal /* Function arguments */
180568 ){
180569 assert( nArg==0 );
180570 sqlite3_result_text(pCtx, "fts5: 2015-10-14 12:29:53 a721fc0d89495518fe5612e2e3bbc60befd2e90d", -1, SQLITE_TRANSIENT);
180571 }
180572
180573 static int fts5Init(sqlite3 *db){
180574 static const sqlite3_module fts5Mod = {
180575 /* iVersion */ 2,
@@ -184045,11 +184069,11 @@
184069 i64 dummy;
184070 const u8 *pPos; int nPos; /* Position list */
184071 i64 iPos = 0; /* 64-bit position read from poslist */
184072 int iOff = 0; /* Current offset within position list */
184073
184074 rc = sqlite3Fts5IterPoslist(pCsr->pIter, 0, &pPos, &nPos, &dummy);
184075 if( rc==SQLITE_OK ){
184076 if( pTab->eType==FTS5_VOCAB_ROW ){
184077 while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
184078 pCsr->aVal[1]++;
184079 }
184080
+12 -4
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -111,11 +111,11 @@
111111
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
112112
** [sqlite_version()] and [sqlite_source_id()].
113113
*/
114114
#define SQLITE_VERSION "3.9.0"
115115
#define SQLITE_VERSION_NUMBER 3009000
116
-#define SQLITE_SOURCE_ID "2015-10-10 15:57:20 35e6248abb4435a8b26d270092b856beff867406"
116
+#define SQLITE_SOURCE_ID "2015-10-14 12:29:53 a721fc0d89495518fe5612e2e3bbc60befd2e90d"
117117
118118
/*
119119
** CAPI3REF: Run-Time Library Version Numbers
120120
** KEYWORDS: sqlite3_version, sqlite3_sourceid
121121
**
@@ -5654,13 +5654,13 @@
56545654
** used with an SQLite version earlier than 3.8.2, the results of attempting
56555655
** to read or write the estimatedRows field are undefined (but are likely
56565656
** to included crashing the application). The estimatedRows field should
56575657
** therefore only be used if [sqlite3_libversion_number()] returns a
56585658
** value greater than or equal to 3008002. Similarly, the idxFlags field
5659
-** was added for version 3.8.12. It may therefore only be used if
5659
+** was added for version 3.9.0. It may therefore only be used if
56605660
** sqlite3_libversion_number() returns a value greater than or equal to
5661
-** 3008012.
5661
+** 3009000.
56625662
*/
56635663
struct sqlite3_index_info {
56645664
/* Inputs */
56655665
int nConstraint; /* Number of entries in aConstraint */
56665666
struct sqlite3_index_constraint {
@@ -5684,11 +5684,11 @@
56845684
int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */
56855685
int orderByConsumed; /* True if output is already ordered */
56865686
double estimatedCost; /* Estimated cost of using this index */
56875687
/* Fields below are only available in SQLite 3.8.2 and later */
56885688
sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
5689
- /* Fields below are only available in SQLite 3.8.12 and later */
5689
+ /* Fields below are only available in SQLite 3.9.0 and later */
56905690
int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */
56915691
};
56925692
56935693
/*
56945694
** CAPI3REF: Virtual Table Scan Flags
@@ -7943,10 +7943,14 @@
79437943
79447944
#ifndef _FTS5_H
79457945
#define _FTS5_H
79467946
79477947
#include "sqlite3.h"
7948
+
7949
+#ifdef __cplusplus
7950
+extern "C" {
7951
+#endif
79487952
79497953
/*************************************************************************
79507954
** CUSTOM AUXILIARY FUNCTIONS
79517955
**
79527956
** Virtual table implementations may overload SQL functions by implementing
@@ -8428,9 +8432,13 @@
84288432
};
84298433
84308434
/*
84318435
** END OF REGISTRATION API
84328436
*************************************************************************/
8437
+
8438
+#ifdef __cplusplus
8439
+} /* end of the 'extern "C"' block */
8440
+#endif
84338441
84348442
#endif /* _FTS5_H */
84358443
84368444
84378445
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -111,11 +111,11 @@
111 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
112 ** [sqlite_version()] and [sqlite_source_id()].
113 */
114 #define SQLITE_VERSION "3.9.0"
115 #define SQLITE_VERSION_NUMBER 3009000
116 #define SQLITE_SOURCE_ID "2015-10-10 15:57:20 35e6248abb4435a8b26d270092b856beff867406"
117
118 /*
119 ** CAPI3REF: Run-Time Library Version Numbers
120 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
121 **
@@ -5654,13 +5654,13 @@
5654 ** used with an SQLite version earlier than 3.8.2, the results of attempting
5655 ** to read or write the estimatedRows field are undefined (but are likely
5656 ** to included crashing the application). The estimatedRows field should
5657 ** therefore only be used if [sqlite3_libversion_number()] returns a
5658 ** value greater than or equal to 3008002. Similarly, the idxFlags field
5659 ** was added for version 3.8.12. It may therefore only be used if
5660 ** sqlite3_libversion_number() returns a value greater than or equal to
5661 ** 3008012.
5662 */
5663 struct sqlite3_index_info {
5664 /* Inputs */
5665 int nConstraint; /* Number of entries in aConstraint */
5666 struct sqlite3_index_constraint {
@@ -5684,11 +5684,11 @@
5684 int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */
5685 int orderByConsumed; /* True if output is already ordered */
5686 double estimatedCost; /* Estimated cost of using this index */
5687 /* Fields below are only available in SQLite 3.8.2 and later */
5688 sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
5689 /* Fields below are only available in SQLite 3.8.12 and later */
5690 int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */
5691 };
5692
5693 /*
5694 ** CAPI3REF: Virtual Table Scan Flags
@@ -7943,10 +7943,14 @@
7943
7944 #ifndef _FTS5_H
7945 #define _FTS5_H
7946
7947 #include "sqlite3.h"
 
 
 
 
7948
7949 /*************************************************************************
7950 ** CUSTOM AUXILIARY FUNCTIONS
7951 **
7952 ** Virtual table implementations may overload SQL functions by implementing
@@ -8428,9 +8432,13 @@
8428 };
8429
8430 /*
8431 ** END OF REGISTRATION API
8432 *************************************************************************/
 
 
 
 
8433
8434 #endif /* _FTS5_H */
8435
8436
8437
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -111,11 +111,11 @@
111 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
112 ** [sqlite_version()] and [sqlite_source_id()].
113 */
114 #define SQLITE_VERSION "3.9.0"
115 #define SQLITE_VERSION_NUMBER 3009000
116 #define SQLITE_SOURCE_ID "2015-10-14 12:29:53 a721fc0d89495518fe5612e2e3bbc60befd2e90d"
117
118 /*
119 ** CAPI3REF: Run-Time Library Version Numbers
120 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
121 **
@@ -5654,13 +5654,13 @@
5654 ** used with an SQLite version earlier than 3.8.2, the results of attempting
5655 ** to read or write the estimatedRows field are undefined (but are likely
5656 ** to included crashing the application). The estimatedRows field should
5657 ** therefore only be used if [sqlite3_libversion_number()] returns a
5658 ** value greater than or equal to 3008002. Similarly, the idxFlags field
5659 ** was added for version 3.9.0. It may therefore only be used if
5660 ** sqlite3_libversion_number() returns a value greater than or equal to
5661 ** 3009000.
5662 */
5663 struct sqlite3_index_info {
5664 /* Inputs */
5665 int nConstraint; /* Number of entries in aConstraint */
5666 struct sqlite3_index_constraint {
@@ -5684,11 +5684,11 @@
5684 int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */
5685 int orderByConsumed; /* True if output is already ordered */
5686 double estimatedCost; /* Estimated cost of using this index */
5687 /* Fields below are only available in SQLite 3.8.2 and later */
5688 sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
5689 /* Fields below are only available in SQLite 3.9.0 and later */
5690 int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */
5691 };
5692
5693 /*
5694 ** CAPI3REF: Virtual Table Scan Flags
@@ -7943,10 +7943,14 @@
7943
7944 #ifndef _FTS5_H
7945 #define _FTS5_H
7946
7947 #include "sqlite3.h"
7948
7949 #ifdef __cplusplus
7950 extern "C" {
7951 #endif
7952
7953 /*************************************************************************
7954 ** CUSTOM AUXILIARY FUNCTIONS
7955 **
7956 ** Virtual table implementations may overload SQL functions by implementing
@@ -8428,9 +8432,13 @@
8432 };
8433
8434 /*
8435 ** END OF REGISTRATION API
8436 *************************************************************************/
8437
8438 #ifdef __cplusplus
8439 } /* end of the 'extern "C"' block */
8440 #endif
8441
8442 #endif /* _FTS5_H */
8443
8444
8445

Keyboard Shortcuts

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