|
|
@@ -400,7 +400,7 @@ extern "C" {
|
|
|
*/
|
|
|
#define SQLITE_VERSION "3.19.0"
|
|
|
#define SQLITE_VERSION_NUMBER 3019000
|
|
|
-#define SQLITE_SOURCE_ID "2017-04-11 01:30:42 a47efb7c8520a01110ce3b3531ebe1bab6720780d67fba001992c44c5807d332"
|
|
|
+#define SQLITE_SOURCE_ID "2017-04-12 17:50:12 c847543f8bb1376fef52bca72b4191162a32eb7e6c5f0cd1aa0ab116b3183396"
|
|
|
|
|
|
/*
|
|
|
** CAPI3REF: Run-Time Library Version Numbers
|
|
|
@@ -69993,7 +69993,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPre
|
|
|
pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
|
|
|
}
|
|
|
|
|
|
- if( bPreserve && pMem->z && pMem->z!=pMem->zMalloc ){
|
|
|
+ if( bPreserve && pMem->z && ALWAYS(pMem->z!=pMem->zMalloc) ){
|
|
|
memcpy(pMem->zMalloc, pMem->z, pMem->n);
|
|
|
}
|
|
|
if( (pMem->flags&MEM_Dyn)!=0 ){
|
|
|
@@ -91622,7 +91622,7 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
|
|
|
return sqlite3AffinityType(pExpr->u.zToken, 0);
|
|
|
}
|
|
|
#endif
|
|
|
- if( op==TK_AGG_COLUMN || op==TK_COLUMN ){
|
|
|
+ if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab ){
|
|
|
return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
|
|
|
}
|
|
|
if( op==TK_SELECT_COLUMN ){
|
|
|
@@ -109185,8 +109185,16 @@ SQLITE_PRIVATE u32 sqlite3FkOldmask(
|
|
|
** UPDATE statement modifies the rowid fields of the table.
|
|
|
**
|
|
|
** If any foreign key processing will be required, this function returns
|
|
|
-** true. If there is no foreign key related processing, this function
|
|
|
-** returns false.
|
|
|
+** non-zero. If there is no foreign key related processing, this function
|
|
|
+** returns zero.
|
|
|
+**
|
|
|
+** For an UPDATE, this function returns 2 if:
|
|
|
+**
|
|
|
+** * There are any FKs for which pTab is the child and the parent table, or
|
|
|
+** * the UPDATE modifies one or more parent keys for which the action is
|
|
|
+** not "NO ACTION" (i.e. is CASCADE, SET DEFAULT or SET NULL).
|
|
|
+**
|
|
|
+** Or, assuming some other foreign key processing is required, 1.
|
|
|
*/
|
|
|
SQLITE_PRIVATE int sqlite3FkRequired(
|
|
|
Parse *pParse, /* Parse context */
|
|
|
@@ -109194,12 +109202,13 @@ SQLITE_PRIVATE int sqlite3FkRequired(
|
|
|
int *aChange, /* Non-NULL for UPDATE operations */
|
|
|
int chngRowid /* True for UPDATE that affects rowid */
|
|
|
){
|
|
|
+ int eRet = 0;
|
|
|
if( pParse->db->flags&SQLITE_ForeignKeys ){
|
|
|
if( !aChange ){
|
|
|
/* A DELETE operation. Foreign key processing is required if the
|
|
|
** table in question is either the child or parent table for any
|
|
|
** foreign key constraint. */
|
|
|
- return (sqlite3FkReferences(pTab) || pTab->pFKey);
|
|
|
+ eRet = (sqlite3FkReferences(pTab) || pTab->pFKey);
|
|
|
}else{
|
|
|
/* This is an UPDATE. Foreign key processing is only required if the
|
|
|
** operation modifies one or more child or parent key columns. */
|
|
|
@@ -109207,16 +109216,22 @@ SQLITE_PRIVATE int sqlite3FkRequired(
|
|
|
|
|
|
/* Check if any child key columns are being modified. */
|
|
|
for(p=pTab->pFKey; p; p=p->pNextFrom){
|
|
|
- if( fkChildIsModified(pTab, p, aChange, chngRowid) ) return 1;
|
|
|
+ if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) return 2;
|
|
|
+ if( fkChildIsModified(pTab, p, aChange, chngRowid) ){
|
|
|
+ eRet = 1;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/* Check if any parent key columns are being modified. */
|
|
|
for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
|
|
|
- if( fkParentIsModified(pTab, p, aChange, chngRowid) ) return 1;
|
|
|
+ if( fkParentIsModified(pTab, p, aChange, chngRowid) ){
|
|
|
+ if( p->aAction[1]!=OE_None ) return 2;
|
|
|
+ eRet = 1;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- return 0;
|
|
|
+ return eRet;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -117331,14 +117346,13 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
|
|
|
){
|
|
|
Select *pNew;
|
|
|
Select standin;
|
|
|
- sqlite3 *db = pParse->db;
|
|
|
- pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
|
|
|
+ pNew = sqlite3DbMallocRawNN(pParse->db, sizeof(*pNew) );
|
|
|
if( pNew==0 ){
|
|
|
- assert( db->mallocFailed );
|
|
|
+ assert( pParse->db->mallocFailed );
|
|
|
pNew = &standin;
|
|
|
}
|
|
|
if( pEList==0 ){
|
|
|
- pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ASTERISK,0));
|
|
|
+ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(pParse->db,TK_ASTERISK,0));
|
|
|
}
|
|
|
pNew->pEList = pEList;
|
|
|
pNew->op = TK_SELECT;
|
|
|
@@ -117351,7 +117365,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
|
|
|
pNew->addrOpenEphm[0] = -1;
|
|
|
pNew->addrOpenEphm[1] = -1;
|
|
|
pNew->nSelectRow = 0;
|
|
|
- if( pSrc==0 ) pSrc = sqlite3DbMallocZero(db, sizeof(*pSrc));
|
|
|
+ if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*pSrc));
|
|
|
pNew->pSrc = pSrc;
|
|
|
pNew->pWhere = pWhere;
|
|
|
pNew->pGroupBy = pGroupBy;
|
|
|
@@ -117362,9 +117376,9 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
|
|
|
pNew->pLimit = pLimit;
|
|
|
pNew->pOffset = pOffset;
|
|
|
pNew->pWith = 0;
|
|
|
- assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 );
|
|
|
- if( db->mallocFailed ) {
|
|
|
- clearSelect(db, pNew, pNew!=&standin);
|
|
|
+ assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || pParse->db->mallocFailed!=0 );
|
|
|
+ if( pParse->db->mallocFailed ) {
|
|
|
+ clearSelect(pParse->db, pNew, pNew!=&standin);
|
|
|
pNew = 0;
|
|
|
}else{
|
|
|
assert( pNew->pSrc!=0 || pParse->nErr>0 );
|
|
|
@@ -124560,7 +124574,7 @@ SQLITE_PRIVATE void sqlite3Update(
|
|
|
*/
|
|
|
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
|
|
int reg;
|
|
|
- if( chngKey || hasFK || pIdx->pPartIdxWhere || pIdx==pPk ){
|
|
|
+ if( chngKey || hasFK>1 || pIdx->pPartIdxWhere || pIdx==pPk ){
|
|
|
reg = ++pParse->nMem;
|
|
|
pParse->nMem += pIdx->nColumn;
|
|
|
}else{
|
|
|
@@ -124915,7 +124929,7 @@ SQLITE_PRIVATE void sqlite3Update(
|
|
|
assert( regNew==regNewRowid+1 );
|
|
|
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
|
|
|
sqlite3VdbeAddOp3(v, OP_Delete, iDataCur,
|
|
|
- OPFLAG_ISUPDATE | ((hasFK || chngKey) ? 0 : OPFLAG_ISNOOP),
|
|
|
+ OPFLAG_ISUPDATE | ((hasFK>1 || chngKey) ? 0 : OPFLAG_ISNOOP),
|
|
|
regNewRowid
|
|
|
);
|
|
|
if( eOnePass==ONEPASS_MULTI ){
|
|
|
@@ -124926,7 +124940,7 @@ SQLITE_PRIVATE void sqlite3Update(
|
|
|
sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
|
|
|
}
|
|
|
#else
|
|
|
- if( hasFK || chngKey ){
|
|
|
+ if( hasFK>1 || chngKey ){
|
|
|
sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0);
|
|
|
}
|
|
|
#endif
|
|
|
@@ -130270,8 +130284,8 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){
|
|
|
** Expression pExpr is one operand of a comparison operator that might
|
|
|
** be useful for indexing. This routine checks to see if pExpr appears
|
|
|
** in any index. Return TRUE (1) if pExpr is an indexed term and return
|
|
|
-** FALSE (0) if not. If TRUE is returned, also set *piCur to the cursor
|
|
|
-** number of the table that is indexed and *piColumn to the column number
|
|
|
+** FALSE (0) if not. If TRUE is returned, also set aiCurCol[0] to the cursor
|
|
|
+** number of the table that is indexed and aiCurCol[1] to the column number
|
|
|
** of the column that is indexed, or XN_EXPR (-2) if an expression is being
|
|
|
** indexed.
|
|
|
**
|
|
|
@@ -130279,18 +130293,37 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){
|
|
|
** true even if that particular column is not indexed, because the column
|
|
|
** might be added to an automatic index later.
|
|
|
*/
|
|
|
-static int exprMightBeIndexed(
|
|
|
+static SQLITE_NOINLINE int exprMightBeIndexed2(
|
|
|
SrcList *pFrom, /* The FROM clause */
|
|
|
- int op, /* The specific comparison operator */
|
|
|
Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */
|
|
|
- Expr *pExpr, /* An operand of a comparison operator */
|
|
|
- int *piCur, /* Write the referenced table cursor number here */
|
|
|
- int *piColumn /* Write the referenced table column number here */
|
|
|
+ int *aiCurCol, /* Write the referenced table cursor and column here */
|
|
|
+ Expr *pExpr /* An operand of a comparison operator */
|
|
|
){
|
|
|
Index *pIdx;
|
|
|
int i;
|
|
|
int iCur;
|
|
|
-
|
|
|
+ for(i=0; mPrereq>1; i++, mPrereq>>=1){}
|
|
|
+ iCur = pFrom->a[i].iCursor;
|
|
|
+ for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
|
|
+ if( pIdx->aColExpr==0 ) continue;
|
|
|
+ for(i=0; i<pIdx->nKeyCol; i++){
|
|
|
+ if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
|
|
|
+ if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
|
|
|
+ aiCurCol[0] = iCur;
|
|
|
+ aiCurCol[1] = XN_EXPR;
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+static int exprMightBeIndexed(
|
|
|
+ SrcList *pFrom, /* The FROM clause */
|
|
|
+ Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */
|
|
|
+ int *aiCurCol, /* Write the referenced table cursor & column here */
|
|
|
+ Expr *pExpr, /* An operand of a comparison operator */
|
|
|
+ int op /* The specific comparison operator */
|
|
|
+){
|
|
|
/* If this expression is a vector to the left or right of a
|
|
|
** inequality constraint (>, <, >= or <=), perform the processing
|
|
|
** on the first element of the vector. */
|
|
|
@@ -130302,26 +130335,13 @@ static int exprMightBeIndexed(
|
|
|
}
|
|
|
|
|
|
if( pExpr->op==TK_COLUMN ){
|
|
|
- *piCur = pExpr->iTable;
|
|
|
- *piColumn = pExpr->iColumn;
|
|
|
+ aiCurCol[0] = pExpr->iTable;
|
|
|
+ aiCurCol[1] = pExpr->iColumn;
|
|
|
return 1;
|
|
|
}
|
|
|
if( mPrereq==0 ) return 0; /* No table references */
|
|
|
if( (mPrereq&(mPrereq-1))!=0 ) return 0; /* Refs more than one table */
|
|
|
- for(i=0; mPrereq>1; i++, mPrereq>>=1){}
|
|
|
- iCur = pFrom->a[i].iCursor;
|
|
|
- for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
|
|
- if( pIdx->aColExpr==0 ) continue;
|
|
|
- for(i=0; i<pIdx->nKeyCol; i++){
|
|
|
- if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
|
|
|
- if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
|
|
|
- *piCur = iCur;
|
|
|
- *piColumn = XN_EXPR;
|
|
|
- return 1;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return 0;
|
|
|
+ return exprMightBeIndexed2(pFrom,mPrereq,aiCurCol,pExpr);
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -130401,7 +130421,7 @@ static void exprAnalyze(
|
|
|
pTerm->iParent = -1;
|
|
|
pTerm->eOperator = 0;
|
|
|
if( allowedOp(op) ){
|
|
|
- int iCur, iColumn;
|
|
|
+ int aiCurCol[2];
|
|
|
Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
|
|
|
Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
|
|
|
u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;
|
|
|
@@ -130412,14 +130432,14 @@ static void exprAnalyze(
|
|
|
pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr;
|
|
|
}
|
|
|
|
|
|
- if( exprMightBeIndexed(pSrc, op, prereqLeft, pLeft, &iCur, &iColumn) ){
|
|
|
- pTerm->leftCursor = iCur;
|
|
|
- pTerm->u.leftColumn = iColumn;
|
|
|
+ if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){
|
|
|
+ pTerm->leftCursor = aiCurCol[0];
|
|
|
+ pTerm->u.leftColumn = aiCurCol[1];
|
|
|
pTerm->eOperator = operatorMask(op) & opMask;
|
|
|
}
|
|
|
if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
|
|
|
if( pRight
|
|
|
- && exprMightBeIndexed(pSrc, op, pTerm->prereqRight, pRight, &iCur,&iColumn)
|
|
|
+ && exprMightBeIndexed(pSrc, pTerm->prereqRight, aiCurCol, pRight, op)
|
|
|
){
|
|
|
WhereTerm *pNew;
|
|
|
Expr *pDup;
|
|
|
@@ -130449,8 +130469,8 @@ static void exprAnalyze(
|
|
|
pNew = pTerm;
|
|
|
}
|
|
|
exprCommute(pParse, pDup);
|
|
|
- pNew->leftCursor = iCur;
|
|
|
- pNew->u.leftColumn = iColumn;
|
|
|
+ pNew->leftCursor = aiCurCol[0];
|
|
|
+ pNew->u.leftColumn = aiCurCol[1];
|
|
|
testcase( (prereqLeft | extraRight) != prereqLeft );
|
|
|
pNew->prereqRight = prereqLeft | extraRight;
|
|
|
pNew->prereqAll = prereqAll;
|
|
|
@@ -182009,6 +182029,7 @@ static const char jsonIsSpace[] = {
|
|
|
** but the definitions need to be repeated for separate compilation. */
|
|
|
typedef sqlite3_uint64 u64;
|
|
|
typedef unsigned int u32;
|
|
|
+ typedef unsigned short int u16;
|
|
|
typedef unsigned char u8;
|
|
|
#endif
|
|
|
|
|
|
@@ -182088,8 +182109,18 @@ struct JsonParse {
|
|
|
u32 *aUp; /* Index of parent of each node */
|
|
|
u8 oom; /* Set to true if out of memory */
|
|
|
u8 nErr; /* Number of errors seen */
|
|
|
+ u16 iDepth; /* Nesting depth */
|
|
|
};
|
|
|
|
|
|
+/*
|
|
|
+** Maximum nesting depth of JSON for this implementation.
|
|
|
+**
|
|
|
+** This limit is needed to avoid a stack overflow in the recursive
|
|
|
+** descent parser. A depth of 2000 is far deeper than any sane JSON
|
|
|
+** should go.
|
|
|
+*/
|
|
|
+#define JSON_MAX_DEPTH 2000
|
|
|
+
|
|
|
/**************************************************************************
|
|
|
** Utility routines for dealing with JsonString objects
|
|
|
**************************************************************************/
|
|
|
@@ -182654,8 +182685,10 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
|
|
|
if( iThis<0 ) return -1;
|
|
|
for(j=i+1;;j++){
|
|
|
while( safe_isspace(z[j]) ){ j++; }
|
|
|
+ if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
|
|
|
x = jsonParseValue(pParse, j);
|
|
|
if( x<0 ){
|
|
|
+ pParse->iDepth--;
|
|
|
if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
|
|
|
return -1;
|
|
|
}
|
|
|
@@ -182668,6 +182701,7 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
|
|
|
if( z[j]!=':' ) return -1;
|
|
|
j++;
|
|
|
x = jsonParseValue(pParse, j);
|
|
|
+ pParse->iDepth--;
|
|
|
if( x<0 ) return -1;
|
|
|
j = x;
|
|
|
while( safe_isspace(z[j]) ){ j++; }
|
|
|
@@ -182684,7 +182718,9 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
|
|
|
if( iThis<0 ) return -1;
|
|
|
for(j=i+1;;j++){
|
|
|
while( safe_isspace(z[j]) ){ j++; }
|
|
|
+ if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
|
|
|
x = jsonParseValue(pParse, j);
|
|
|
+ pParse->iDepth--;
|
|
|
if( x<0 ){
|
|
|
if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
|
|
|
return -1;
|
|
|
@@ -182804,6 +182840,7 @@ static int jsonParse(
|
|
|
i = jsonParseValue(pParse, 0);
|
|
|
if( pParse->oom ) i = -1;
|
|
|
if( i>0 ){
|
|
|
+ assert( pParse->iDepth==0 );
|
|
|
while( safe_isspace(zJson[i]) ) i++;
|
|
|
if( zJson[i] ) i = -1;
|
|
|
}
|
|
|
@@ -185605,7 +185642,7 @@ static void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset*);
|
|
|
static void sqlite3Fts5ParseNodeFree(Fts5ExprNode*);
|
|
|
|
|
|
static void sqlite3Fts5ParseSetDistance(Fts5Parse*, Fts5ExprNearset*, Fts5Token*);
|
|
|
-static void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNearset*, Fts5Colset*);
|
|
|
+static void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNode*, Fts5Colset*);
|
|
|
static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse*, Fts5Colset*);
|
|
|
static void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p);
|
|
|
static void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*);
|
|
|
@@ -185662,12 +185699,12 @@ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
|
|
|
#define FTS5_NOT 3
|
|
|
#define FTS5_TERM 4
|
|
|
#define FTS5_COLON 5
|
|
|
-#define FTS5_LP 6
|
|
|
-#define FTS5_RP 7
|
|
|
-#define FTS5_MINUS 8
|
|
|
-#define FTS5_LCP 9
|
|
|
-#define FTS5_RCP 10
|
|
|
-#define FTS5_STRING 11
|
|
|
+#define FTS5_MINUS 6
|
|
|
+#define FTS5_LCP 7
|
|
|
+#define FTS5_RCP 8
|
|
|
+#define FTS5_STRING 9
|
|
|
+#define FTS5_LP 10
|
|
|
+#define FTS5_RP 11
|
|
|
#define FTS5_COMMA 12
|
|
|
#define FTS5_PLUS 13
|
|
|
#define FTS5_STAR 14
|
|
|
@@ -185803,16 +185840,16 @@ typedef union {
|
|
|
#define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse
|
|
|
#define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse = fts5yypParser->pParse
|
|
|
#define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse = pParse
|
|
|
-#define fts5YYNSTATE 29
|
|
|
-#define fts5YYNRULE 26
|
|
|
-#define fts5YY_MAX_SHIFT 28
|
|
|
-#define fts5YY_MIN_SHIFTREDUCE 45
|
|
|
-#define fts5YY_MAX_SHIFTREDUCE 70
|
|
|
-#define fts5YY_MIN_REDUCE 71
|
|
|
-#define fts5YY_MAX_REDUCE 96
|
|
|
-#define fts5YY_ERROR_ACTION 97
|
|
|
-#define fts5YY_ACCEPT_ACTION 98
|
|
|
-#define fts5YY_NO_ACTION 99
|
|
|
+#define fts5YYNSTATE 33
|
|
|
+#define fts5YYNRULE 27
|
|
|
+#define fts5YY_MAX_SHIFT 32
|
|
|
+#define fts5YY_MIN_SHIFTREDUCE 50
|
|
|
+#define fts5YY_MAX_SHIFTREDUCE 76
|
|
|
+#define fts5YY_MIN_REDUCE 77
|
|
|
+#define fts5YY_MAX_REDUCE 103
|
|
|
+#define fts5YY_ERROR_ACTION 104
|
|
|
+#define fts5YY_ACCEPT_ACTION 105
|
|
|
+#define fts5YY_NO_ACTION 106
|
|
|
/************* End control #defines *******************************************/
|
|
|
|
|
|
/* Define the fts5yytestcase() macro to be a no-op if is not already defined
|
|
|
@@ -185884,50 +185921,54 @@ typedef union {
|
|
|
** fts5yy_default[] Default action for each state.
|
|
|
**
|
|
|
*********** Begin parsing tables **********************************************/
|
|
|
-#define fts5YY_ACTTAB_COUNT (85)
|
|
|
+#define fts5YY_ACTTAB_COUNT (98)
|
|
|
static const fts5YYACTIONTYPE fts5yy_action[] = {
|
|
|
- /* 0 */ 98, 16, 51, 5, 53, 27, 83, 7, 26, 15,
|
|
|
- /* 10 */ 51, 5, 53, 27, 13, 69, 26, 48, 51, 5,
|
|
|
- /* 20 */ 53, 27, 19, 11, 26, 9, 20, 51, 5, 53,
|
|
|
- /* 30 */ 27, 13, 22, 26, 28, 51, 5, 53, 27, 68,
|
|
|
- /* 40 */ 1, 26, 19, 11, 17, 9, 52, 10, 53, 27,
|
|
|
- /* 50 */ 23, 24, 26, 54, 3, 4, 2, 26, 6, 21,
|
|
|
- /* 60 */ 49, 71, 3, 4, 2, 7, 56, 59, 55, 59,
|
|
|
- /* 70 */ 4, 2, 12, 69, 58, 60, 18, 67, 62, 69,
|
|
|
- /* 80 */ 25, 66, 8, 14, 2,
|
|
|
+ /* 0 */ 105, 19, 63, 6, 26, 66, 65, 24, 24, 17,
|
|
|
+ /* 10 */ 63, 6, 26, 16, 65, 54, 24, 18, 63, 6,
|
|
|
+ /* 20 */ 26, 10, 65, 12, 24, 75, 59, 63, 6, 26,
|
|
|
+ /* 30 */ 13, 65, 75, 24, 20, 63, 6, 26, 74, 65,
|
|
|
+ /* 40 */ 56, 24, 27, 63, 6, 26, 73, 65, 21, 24,
|
|
|
+ /* 50 */ 23, 15, 30, 11, 1, 64, 22, 25, 9, 65,
|
|
|
+ /* 60 */ 7, 24, 3, 4, 5, 3, 4, 5, 3, 77,
|
|
|
+ /* 70 */ 4, 5, 3, 61, 23, 15, 60, 11, 80, 12,
|
|
|
+ /* 80 */ 2, 13, 68, 10, 29, 52, 55, 75, 31, 32,
|
|
|
+ /* 90 */ 8, 28, 5, 3, 51, 55, 72, 14,
|
|
|
};
|
|
|
static const fts5YYCODETYPE fts5yy_lookahead[] = {
|
|
|
- /* 0 */ 16, 17, 18, 19, 20, 21, 5, 6, 24, 17,
|
|
|
- /* 10 */ 18, 19, 20, 21, 11, 14, 24, 17, 18, 19,
|
|
|
- /* 20 */ 20, 21, 8, 9, 24, 11, 17, 18, 19, 20,
|
|
|
- /* 30 */ 21, 11, 12, 24, 17, 18, 19, 20, 21, 26,
|
|
|
- /* 40 */ 6, 24, 8, 9, 22, 11, 18, 11, 20, 21,
|
|
|
- /* 50 */ 24, 25, 24, 20, 1, 2, 3, 24, 23, 24,
|
|
|
- /* 60 */ 7, 0, 1, 2, 3, 6, 10, 11, 10, 11,
|
|
|
- /* 70 */ 2, 3, 9, 14, 11, 11, 22, 26, 7, 14,
|
|
|
- /* 80 */ 13, 11, 5, 11, 3,
|
|
|
+ /* 0 */ 16, 17, 18, 19, 20, 22, 22, 24, 24, 17,
|
|
|
+ /* 10 */ 18, 19, 20, 7, 22, 9, 24, 17, 18, 19,
|
|
|
+ /* 20 */ 20, 10, 22, 9, 24, 14, 17, 18, 19, 20,
|
|
|
+ /* 30 */ 9, 22, 14, 24, 17, 18, 19, 20, 26, 22,
|
|
|
+ /* 40 */ 9, 24, 17, 18, 19, 20, 26, 22, 21, 24,
|
|
|
+ /* 50 */ 6, 7, 13, 9, 10, 18, 21, 20, 5, 22,
|
|
|
+ /* 60 */ 5, 24, 3, 1, 2, 3, 1, 2, 3, 0,
|
|
|
+ /* 70 */ 1, 2, 3, 11, 6, 7, 11, 9, 5, 9,
|
|
|
+ /* 80 */ 10, 9, 11, 10, 12, 8, 9, 14, 24, 25,
|
|
|
+ /* 90 */ 23, 24, 2, 3, 8, 9, 9, 9,
|
|
|
};
|
|
|
-#define fts5YY_SHIFT_USE_DFLT (85)
|
|
|
-#define fts5YY_SHIFT_COUNT (28)
|
|
|
+#define fts5YY_SHIFT_USE_DFLT (98)
|
|
|
+#define fts5YY_SHIFT_COUNT (32)
|
|
|
#define fts5YY_SHIFT_MIN (0)
|
|
|
-#define fts5YY_SHIFT_MAX (81)
|
|
|
+#define fts5YY_SHIFT_MAX (90)
|
|
|
static const unsigned char fts5yy_shift_ofst[] = {
|
|
|
- /* 0 */ 34, 34, 34, 34, 34, 14, 20, 3, 36, 1,
|
|
|
- /* 10 */ 59, 64, 64, 65, 65, 53, 61, 56, 58, 63,
|
|
|
- /* 20 */ 68, 67, 70, 67, 71, 72, 67, 77, 81,
|
|
|
+ /* 0 */ 44, 44, 44, 44, 44, 44, 68, 70, 72, 14,
|
|
|
+ /* 10 */ 21, 73, 11, 18, 18, 31, 31, 62, 65, 69,
|
|
|
+ /* 20 */ 90, 77, 86, 6, 39, 53, 55, 59, 39, 87,
|
|
|
+ /* 30 */ 88, 39, 71,
|
|
|
};
|
|
|
-#define fts5YY_REDUCE_USE_DFLT (-17)
|
|
|
-#define fts5YY_REDUCE_COUNT (14)
|
|
|
-#define fts5YY_REDUCE_MIN (-16)
|
|
|
-#define fts5YY_REDUCE_MAX (54)
|
|
|
+#define fts5YY_REDUCE_USE_DFLT (-18)
|
|
|
+#define fts5YY_REDUCE_COUNT (16)
|
|
|
+#define fts5YY_REDUCE_MIN (-17)
|
|
|
+#define fts5YY_REDUCE_MAX (67)
|
|
|
static const signed char fts5yy_reduce_ofst[] = {
|
|
|
- /* 0 */ -16, -8, 0, 9, 17, 28, 26, 35, 33, 13,
|
|
|
- /* 10 */ 13, 22, 54, 13, 51,
|
|
|
+ /* 0 */ -16, -8, 0, 9, 17, 25, 37, -17, 64, -17,
|
|
|
+ /* 10 */ 67, 12, 12, 12, 20, 27, 35,
|
|
|
};
|
|
|
static const fts5YYACTIONTYPE fts5yy_default[] = {
|
|
|
- /* 0 */ 97, 97, 97, 97, 97, 76, 91, 97, 97, 96,
|
|
|
- /* 10 */ 96, 97, 97, 96, 96, 97, 97, 97, 97, 97,
|
|
|
- /* 20 */ 73, 89, 97, 90, 97, 97, 87, 97, 72,
|
|
|
+ /* 0 */ 104, 104, 104, 104, 104, 104, 89, 104, 98, 104,
|
|
|
+ /* 10 */ 104, 103, 103, 103, 103, 104, 104, 104, 104, 104,
|
|
|
+ /* 20 */ 85, 104, 104, 104, 94, 104, 104, 84, 96, 104,
|
|
|
+ /* 30 */ 104, 97, 104,
|
|
|
};
|
|
|
/********** End of lemon-generated parsing tables *****************************/
|
|
|
|
|
|
@@ -186033,11 +186074,11 @@ static void sqlite3Fts5ParserTrace(FILE *TraceFILE, char *zTracePrompt){
|
|
|
** are required. The following table supplies these names */
|
|
|
static const char *const fts5yyTokenName[] = {
|
|
|
"$", "OR", "AND", "NOT",
|
|
|
- "TERM", "COLON", "LP", "RP",
|
|
|
- "MINUS", "LCP", "RCP", "STRING",
|
|
|
+ "TERM", "COLON", "MINUS", "LCP",
|
|
|
+ "RCP", "STRING", "LP", "RP",
|
|
|
"COMMA", "PLUS", "STAR", "error",
|
|
|
"input", "expr", "cnearset", "exprlist",
|
|
|
- "nearset", "colset", "colsetlist", "nearphrases",
|
|
|
+ "colset", "colsetlist", "nearset", "nearphrases",
|
|
|
"phrase", "neardist_opt", "star_opt",
|
|
|
};
|
|
|
#endif /* NDEBUG */
|
|
|
@@ -186047,31 +186088,32 @@ static const char *const fts5yyTokenName[] = {
|
|
|
*/
|
|
|
static const char *const fts5yyRuleName[] = {
|
|
|
/* 0 */ "input ::= expr",
|
|
|
- /* 1 */ "expr ::= expr AND expr",
|
|
|
- /* 2 */ "expr ::= expr OR expr",
|
|
|
- /* 3 */ "expr ::= expr NOT expr",
|
|
|
- /* 4 */ "expr ::= LP expr RP",
|
|
|
- /* 5 */ "expr ::= exprlist",
|
|
|
- /* 6 */ "exprlist ::= cnearset",
|
|
|
- /* 7 */ "exprlist ::= exprlist cnearset",
|
|
|
- /* 8 */ "cnearset ::= nearset",
|
|
|
- /* 9 */ "cnearset ::= colset COLON nearset",
|
|
|
- /* 10 */ "colset ::= MINUS LCP colsetlist RCP",
|
|
|
- /* 11 */ "colset ::= LCP colsetlist RCP",
|
|
|
- /* 12 */ "colset ::= STRING",
|
|
|
- /* 13 */ "colset ::= MINUS STRING",
|
|
|
- /* 14 */ "colsetlist ::= colsetlist STRING",
|
|
|
- /* 15 */ "colsetlist ::= STRING",
|
|
|
- /* 16 */ "nearset ::= phrase",
|
|
|
- /* 17 */ "nearset ::= STRING LP nearphrases neardist_opt RP",
|
|
|
- /* 18 */ "nearphrases ::= phrase",
|
|
|
- /* 19 */ "nearphrases ::= nearphrases phrase",
|
|
|
- /* 20 */ "neardist_opt ::=",
|
|
|
- /* 21 */ "neardist_opt ::= COMMA STRING",
|
|
|
- /* 22 */ "phrase ::= phrase PLUS STRING star_opt",
|
|
|
- /* 23 */ "phrase ::= STRING star_opt",
|
|
|
- /* 24 */ "star_opt ::= STAR",
|
|
|
- /* 25 */ "star_opt ::=",
|
|
|
+ /* 1 */ "colset ::= MINUS LCP colsetlist RCP",
|
|
|
+ /* 2 */ "colset ::= LCP colsetlist RCP",
|
|
|
+ /* 3 */ "colset ::= STRING",
|
|
|
+ /* 4 */ "colset ::= MINUS STRING",
|
|
|
+ /* 5 */ "colsetlist ::= colsetlist STRING",
|
|
|
+ /* 6 */ "colsetlist ::= STRING",
|
|
|
+ /* 7 */ "expr ::= expr AND expr",
|
|
|
+ /* 8 */ "expr ::= expr OR expr",
|
|
|
+ /* 9 */ "expr ::= expr NOT expr",
|
|
|
+ /* 10 */ "expr ::= colset COLON LP expr RP",
|
|
|
+ /* 11 */ "expr ::= LP expr RP",
|
|
|
+ /* 12 */ "expr ::= exprlist",
|
|
|
+ /* 13 */ "exprlist ::= cnearset",
|
|
|
+ /* 14 */ "exprlist ::= exprlist cnearset",
|
|
|
+ /* 15 */ "cnearset ::= nearset",
|
|
|
+ /* 16 */ "cnearset ::= colset COLON nearset",
|
|
|
+ /* 17 */ "nearset ::= phrase",
|
|
|
+ /* 18 */ "nearset ::= STRING LP nearphrases neardist_opt RP",
|
|
|
+ /* 19 */ "nearphrases ::= phrase",
|
|
|
+ /* 20 */ "nearphrases ::= nearphrases phrase",
|
|
|
+ /* 21 */ "neardist_opt ::=",
|
|
|
+ /* 22 */ "neardist_opt ::= COMMA STRING",
|
|
|
+ /* 23 */ "phrase ::= phrase PLUS STRING star_opt",
|
|
|
+ /* 24 */ "phrase ::= STRING star_opt",
|
|
|
+ /* 25 */ "star_opt ::= STAR",
|
|
|
+ /* 26 */ "star_opt ::=",
|
|
|
};
|
|
|
#endif /* NDEBUG */
|
|
|
|
|
|
@@ -186201,16 +186243,16 @@ static void fts5yy_destructor(
|
|
|
sqlite3Fts5ParseNodeFree((fts5yypminor->fts5yy24));
|
|
|
}
|
|
|
break;
|
|
|
- case 20: /* nearset */
|
|
|
- case 23: /* nearphrases */
|
|
|
+ case 20: /* colset */
|
|
|
+ case 21: /* colsetlist */
|
|
|
{
|
|
|
- sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy46));
|
|
|
+ sqlite3_free((fts5yypminor->fts5yy11));
|
|
|
}
|
|
|
break;
|
|
|
- case 21: /* colset */
|
|
|
- case 22: /* colsetlist */
|
|
|
+ case 22: /* nearset */
|
|
|
+ case 23: /* nearphrases */
|
|
|
{
|
|
|
- sqlite3_free((fts5yypminor->fts5yy11));
|
|
|
+ sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy46));
|
|
|
}
|
|
|
break;
|
|
|
case 24: /* phrase */
|
|
|
@@ -186470,23 +186512,24 @@ static const struct {
|
|
|
unsigned char nrhs; /* Number of right-hand side symbols in the rule */
|
|
|
} fts5yyRuleInfo[] = {
|
|
|
{ 16, 1 },
|
|
|
+ { 20, 4 },
|
|
|
+ { 20, 3 },
|
|
|
+ { 20, 1 },
|
|
|
+ { 20, 2 },
|
|
|
+ { 21, 2 },
|
|
|
+ { 21, 1 },
|
|
|
{ 17, 3 },
|
|
|
{ 17, 3 },
|
|
|
{ 17, 3 },
|
|
|
+ { 17, 5 },
|
|
|
{ 17, 3 },
|
|
|
{ 17, 1 },
|
|
|
{ 19, 1 },
|
|
|
{ 19, 2 },
|
|
|
{ 18, 1 },
|
|
|
{ 18, 3 },
|
|
|
- { 21, 4 },
|
|
|
- { 21, 3 },
|
|
|
- { 21, 1 },
|
|
|
- { 21, 2 },
|
|
|
- { 22, 2 },
|
|
|
{ 22, 1 },
|
|
|
- { 20, 1 },
|
|
|
- { 20, 5 },
|
|
|
+ { 22, 5 },
|
|
|
{ 23, 1 },
|
|
|
{ 23, 2 },
|
|
|
{ 25, 0 },
|
|
|
@@ -186561,87 +186604,94 @@ static void fts5yy_reduce(
|
|
|
case 0: /* input ::= expr */
|
|
|
{ sqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy24); }
|
|
|
break;
|
|
|
- case 1: /* expr ::= expr AND expr */
|
|
|
+ case 1: /* colset ::= MINUS LCP colsetlist RCP */
|
|
|
+{
|
|
|
+ fts5yymsp[-3].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
|
|
|
+}
|
|
|
+ break;
|
|
|
+ case 2: /* colset ::= LCP colsetlist RCP */
|
|
|
+{ fts5yymsp[-2].minor.fts5yy11 = fts5yymsp[-1].minor.fts5yy11; }
|
|
|
+ break;
|
|
|
+ case 3: /* colset ::= STRING */
|
|
|
+{
|
|
|
+ fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
|
|
|
+}
|
|
|
+ fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
|
|
|
+ break;
|
|
|
+ case 4: /* colset ::= MINUS STRING */
|
|
|
+{
|
|
|
+ fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
|
|
|
+ fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
|
|
|
+}
|
|
|
+ break;
|
|
|
+ case 5: /* colsetlist ::= colsetlist STRING */
|
|
|
+{
|
|
|
+ fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy11, &fts5yymsp[0].minor.fts5yy0); }
|
|
|
+ fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
|
|
|
+ break;
|
|
|
+ case 6: /* colsetlist ::= STRING */
|
|
|
+{
|
|
|
+ fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
|
|
|
+}
|
|
|
+ fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
|
|
|
+ break;
|
|
|
+ case 7: /* expr ::= expr AND expr */
|
|
|
{
|
|
|
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
|
|
|
}
|
|
|
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
|
|
|
break;
|
|
|
- case 2: /* expr ::= expr OR expr */
|
|
|
+ case 8: /* expr ::= expr OR expr */
|
|
|
{
|
|
|
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
|
|
|
}
|
|
|
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
|
|
|
break;
|
|
|
- case 3: /* expr ::= expr NOT expr */
|
|
|
+ case 9: /* expr ::= expr NOT expr */
|
|
|
{
|
|
|
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
|
|
|
}
|
|
|
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
|
|
|
break;
|
|
|
- case 4: /* expr ::= LP expr RP */
|
|
|
+ case 10: /* expr ::= colset COLON LP expr RP */
|
|
|
+{
|
|
|
+ sqlite3Fts5ParseSetColset(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[-4].minor.fts5yy11);
|
|
|
+ fts5yylhsminor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;
|
|
|
+}
|
|
|
+ fts5yymsp[-4].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
|
|
|
+ break;
|
|
|
+ case 11: /* expr ::= LP expr RP */
|
|
|
{fts5yymsp[-2].minor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;}
|
|
|
break;
|
|
|
- case 5: /* expr ::= exprlist */
|
|
|
- case 6: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==6);
|
|
|
+ case 12: /* expr ::= exprlist */
|
|
|
+ case 13: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==13);
|
|
|
{fts5yylhsminor.fts5yy24 = fts5yymsp[0].minor.fts5yy24;}
|
|
|
fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
|
|
|
break;
|
|
|
- case 7: /* exprlist ::= exprlist cnearset */
|
|
|
+ case 14: /* exprlist ::= exprlist cnearset */
|
|
|
{
|
|
|
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24);
|
|
|
}
|
|
|
fts5yymsp[-1].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
|
|
|
break;
|
|
|
- case 8: /* cnearset ::= nearset */
|
|
|
+ case 15: /* cnearset ::= nearset */
|
|
|
{
|
|
|
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46);
|
|
|
}
|
|
|
fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
|
|
|
break;
|
|
|
- case 9: /* cnearset ::= colset COLON nearset */
|
|
|
+ case 16: /* cnearset ::= colset COLON nearset */
|
|
|
{
|
|
|
- sqlite3Fts5ParseSetColset(pParse, fts5yymsp[0].minor.fts5yy46, fts5yymsp[-2].minor.fts5yy11);
|
|
|
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46);
|
|
|
+ sqlite3Fts5ParseSetColset(pParse, fts5yylhsminor.fts5yy24, fts5yymsp[-2].minor.fts5yy11);
|
|
|
}
|
|
|
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
|
|
|
break;
|
|
|
- case 10: /* colset ::= MINUS LCP colsetlist RCP */
|
|
|
-{
|
|
|
- fts5yymsp[-3].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
|
|
|
-}
|
|
|
- break;
|
|
|
- case 11: /* colset ::= LCP colsetlist RCP */
|
|
|
-{ fts5yymsp[-2].minor.fts5yy11 = fts5yymsp[-1].minor.fts5yy11; }
|
|
|
- break;
|
|
|
- case 12: /* colset ::= STRING */
|
|
|
-{
|
|
|
- fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
|
|
|
-}
|
|
|
- fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
|
|
|
- break;
|
|
|
- case 13: /* colset ::= MINUS STRING */
|
|
|
-{
|
|
|
- fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
|
|
|
- fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
|
|
|
-}
|
|
|
- break;
|
|
|
- case 14: /* colsetlist ::= colsetlist STRING */
|
|
|
-{
|
|
|
- fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy11, &fts5yymsp[0].minor.fts5yy0); }
|
|
|
- fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
|
|
|
- break;
|
|
|
- case 15: /* colsetlist ::= STRING */
|
|
|
-{
|
|
|
- fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
|
|
|
-}
|
|
|
- fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
|
|
|
- break;
|
|
|
- case 16: /* nearset ::= phrase */
|
|
|
+ case 17: /* nearset ::= phrase */
|
|
|
{ fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); }
|
|
|
fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
|
|
|
break;
|
|
|
- case 17: /* nearset ::= STRING LP nearphrases neardist_opt RP */
|
|
|
+ case 18: /* nearset ::= STRING LP nearphrases neardist_opt RP */
|
|
|
{
|
|
|
sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0);
|
|
|
sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy46, &fts5yymsp[-1].minor.fts5yy0);
|
|
|
@@ -186649,40 +186699,40 @@ static void fts5yy_reduce(
|
|
|
}
|
|
|
fts5yymsp[-4].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
|
|
|
break;
|
|
|
- case 18: /* nearphrases ::= phrase */
|
|
|
+ case 19: /* nearphrases ::= phrase */
|
|
|
{
|
|
|
fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53);
|
|
|
}
|
|
|
fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
|
|
|
break;
|
|
|
- case 19: /* nearphrases ::= nearphrases phrase */
|
|
|
+ case 20: /* nearphrases ::= nearphrases phrase */
|
|
|
{
|
|
|
fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy46, fts5yymsp[0].minor.fts5yy53);
|
|
|
}
|
|
|
fts5yymsp[-1].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
|
|
|
break;
|
|
|
- case 20: /* neardist_opt ::= */
|
|
|
+ case 21: /* neardist_opt ::= */
|
|
|
{ fts5yymsp[1].minor.fts5yy0.p = 0; fts5yymsp[1].minor.fts5yy0.n = 0; }
|
|
|
break;
|
|
|
- case 21: /* neardist_opt ::= COMMA STRING */
|
|
|
+ case 22: /* neardist_opt ::= COMMA STRING */
|
|
|
{ fts5yymsp[-1].minor.fts5yy0 = fts5yymsp[0].minor.fts5yy0; }
|
|
|
break;
|
|
|
- case 22: /* phrase ::= phrase PLUS STRING star_opt */
|
|
|
+ case 23: /* phrase ::= phrase PLUS STRING star_opt */
|
|
|
{
|
|
|
fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy53, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
|
|
|
}
|
|
|
fts5yymsp[-3].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
|
|
|
break;
|
|
|
- case 23: /* phrase ::= STRING star_opt */
|
|
|
+ case 24: /* phrase ::= STRING star_opt */
|
|
|
{
|
|
|
fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
|
|
|
}
|
|
|
fts5yymsp[-1].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
|
|
|
break;
|
|
|
- case 24: /* star_opt ::= STAR */
|
|
|
+ case 25: /* star_opt ::= STAR */
|
|
|
{ fts5yymsp[0].minor.fts5yy4 = 1; }
|
|
|
break;
|
|
|
- case 25: /* star_opt ::= */
|
|
|
+ case 26: /* star_opt ::= */
|
|
|
{ fts5yymsp[1].minor.fts5yy4 = 0; }
|
|
|
break;
|
|
|
default:
|
|
|
@@ -190898,25 +190948,110 @@ static Fts5Colset *sqlite3Fts5ParseColset(
|
|
|
return pRet;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+** If argument pOrig is NULL, or if (*pRc) is set to anything other than
|
|
|
+** SQLITE_OK when this function is called, NULL is returned.
|
|
|
+**
|
|
|
+** Otherwise, a copy of (*pOrig) is made into memory obtained from
|
|
|
+** sqlite3Fts5MallocZero() and a pointer to it returned. If the allocation
|
|
|
+** fails, (*pRc) is set to SQLITE_NOMEM and NULL is returned.
|
|
|
+*/
|
|
|
+static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){
|
|
|
+ Fts5Colset *pRet;
|
|
|
+ if( pOrig ){
|
|
|
+ int nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int);
|
|
|
+ pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte);
|
|
|
+ if( pRet ){
|
|
|
+ memcpy(pRet, pOrig, nByte);
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ pRet = 0;
|
|
|
+ }
|
|
|
+ return pRet;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+** Remove from colset pColset any columns that are not also in colset pMerge.
|
|
|
+*/
|
|
|
+static void fts5MergeColset(Fts5Colset *pColset, Fts5Colset *pMerge){
|
|
|
+ int iIn = 0; /* Next input in pColset */
|
|
|
+ int iMerge = 0; /* Next input in pMerge */
|
|
|
+ int iOut = 0; /* Next output slot in pColset */
|
|
|
+
|
|
|
+ while( iIn<pColset->nCol && iMerge<pMerge->nCol ){
|
|
|
+ int iDiff = pColset->aiCol[iIn] - pMerge->aiCol[iMerge];
|
|
|
+ if( iDiff==0 ){
|
|
|
+ pColset->aiCol[iOut++] = pMerge->aiCol[iMerge];
|
|
|
+ iMerge++;
|
|
|
+ iIn++;
|
|
|
+ }else if( iDiff>0 ){
|
|
|
+ iMerge++;
|
|
|
+ }else{
|
|
|
+ iIn++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ pColset->nCol = iOut;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+** Recursively apply colset pColset to expression node pNode and all of
|
|
|
+** its decendents. If (*ppFree) is not NULL, it contains a spare copy
|
|
|
+** of pColset. This function may use the spare copy and set (*ppFree) to
|
|
|
+** zero, or it may create copies of pColset using fts5CloneColset().
|
|
|
+*/
|
|
|
+static void fts5ParseSetColset(
|
|
|
+ Fts5Parse *pParse,
|
|
|
+ Fts5ExprNode *pNode,
|
|
|
+ Fts5Colset *pColset,
|
|
|
+ Fts5Colset **ppFree
|
|
|
+){
|
|
|
+ if( pParse->rc==SQLITE_OK ){
|
|
|
+ assert( pNode->eType==FTS5_TERM || pNode->eType==FTS5_STRING
|
|
|
+ || pNode->eType==FTS5_AND || pNode->eType==FTS5_OR
|
|
|
+ || pNode->eType==FTS5_NOT || pNode->eType==FTS5_EOF
|
|
|
+ );
|
|
|
+ if( pNode->eType==FTS5_STRING || pNode->eType==FTS5_TERM ){
|
|
|
+ Fts5ExprNearset *pNear = pNode->pNear;
|
|
|
+ if( pNear->pColset ){
|
|
|
+ fts5MergeColset(pNear->pColset, pColset);
|
|
|
+ if( pNear->pColset->nCol==0 ){
|
|
|
+ pNode->eType = FTS5_EOF;
|
|
|
+ pNode->xNext = 0;
|
|
|
+ }
|
|
|
+ }else if( *ppFree ){
|
|
|
+ pNear->pColset = pColset;
|
|
|
+ *ppFree = 0;
|
|
|
+ }else{
|
|
|
+ pNear->pColset = fts5CloneColset(&pParse->rc, pColset);
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ int i;
|
|
|
+ assert( pNode->eType!=FTS5_EOF || pNode->nChild==0 );
|
|
|
+ for(i=0; i<pNode->nChild; i++){
|
|
|
+ fts5ParseSetColset(pParse, pNode->apChild[i], pColset, ppFree);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+** Apply colset pColset to expression node pExpr and all of its descendents.
|
|
|
+*/
|
|
|
static void sqlite3Fts5ParseSetColset(
|
|
|
Fts5Parse *pParse,
|
|
|
- Fts5ExprNearset *pNear,
|
|
|
+ Fts5ExprNode *pExpr,
|
|
|
Fts5Colset *pColset
|
|
|
){
|
|
|
+ Fts5Colset *pFree = pColset;
|
|
|
if( pParse->pConfig->eDetail==FTS5_DETAIL_NONE ){
|
|
|
pParse->rc = SQLITE_ERROR;
|
|
|
pParse->zErr = sqlite3_mprintf(
|
|
|
"fts5: column queries are not supported (detail=none)"
|
|
|
);
|
|
|
- sqlite3_free(pColset);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if( pNear ){
|
|
|
- pNear->pColset = pColset;
|
|
|
}else{
|
|
|
- sqlite3_free(pColset);
|
|
|
+ fts5ParseSetColset(pParse, pExpr, pColset, &pFree);
|
|
|
}
|
|
|
+ sqlite3_free(pFree);
|
|
|
}
|
|
|
|
|
|
static void fts5ExprAssignXNext(Fts5ExprNode *pNode){
|
|
|
@@ -195421,23 +195556,23 @@ static int fts5IndexExtractCol(
|
|
|
return p - (*pa);
|
|
|
}
|
|
|
|
|
|
-static int fts5IndexExtractColset (
|
|
|
+static void fts5IndexExtractColset(
|
|
|
+ int *pRc,
|
|
|
Fts5Colset *pColset, /* Colset to filter on */
|
|
|
const u8 *pPos, int nPos, /* Position list */
|
|
|
Fts5Buffer *pBuf /* Output buffer */
|
|
|
){
|
|
|
- int rc = SQLITE_OK;
|
|
|
- int i;
|
|
|
-
|
|
|
- fts5BufferZero(pBuf);
|
|
|
- for(i=0; i<pColset->nCol; i++){
|
|
|
- const u8 *pSub = pPos;
|
|
|
- int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]);
|
|
|
- if( nSub ){
|
|
|
- fts5BufferAppendBlob(&rc, pBuf, nSub, pSub);
|
|
|
+ if( *pRc==SQLITE_OK ){
|
|
|
+ int i;
|
|
|
+ fts5BufferZero(pBuf);
|
|
|
+ for(i=0; i<pColset->nCol; i++){
|
|
|
+ const u8 *pSub = pPos;
|
|
|
+ int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]);
|
|
|
+ if( nSub ){
|
|
|
+ fts5BufferAppendBlob(pRc, pBuf, nSub, pSub);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- return rc;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -195561,8 +195696,9 @@ static void fts5IterSetOutputs_Full(Fts5Iter *pIter, Fts5SegIter *pSeg){
|
|
|
pIter->base.nData = fts5IndexExtractCol(&a, pSeg->nPos,pColset->aiCol[0]);
|
|
|
pIter->base.pData = a;
|
|
|
}else{
|
|
|
+ int *pRc = &pIter->pIndex->rc;
|
|
|
fts5BufferZero(&pIter->poslist);
|
|
|
- fts5IndexExtractColset(pColset, a, pSeg->nPos, &pIter->poslist);
|
|
|
+ fts5IndexExtractColset(pRc, pColset, a, pSeg->nPos, &pIter->poslist);
|
|
|
pIter->base.pData = pIter->poslist.p;
|
|
|
pIter->base.nData = pIter->poslist.n;
|
|
|
}
|
|
|
@@ -201372,7 +201508,7 @@ static void fts5SourceIdFunc(
|
|
|
){
|
|
|
assert( nArg==0 );
|
|
|
UNUSED_PARAM2(nArg, apUnused);
|
|
|
- sqlite3_result_text(pCtx, "fts5: 2017-04-08 09:12:20 a921ada89050ce1d162fd1b0056939573635e2cec7ac0c2a99ae924b3ae593f7", -1, SQLITE_TRANSIENT);
|
|
|
+ sqlite3_result_text(pCtx, "fts5: 2017-04-12 17:50:12 c847543f8bb1376fef52bca72b4191162a32eb7e6c5f0cd1aa0ab116b3183396", -1, SQLITE_TRANSIENT);
|
|
|
}
|
|
|
|
|
|
static int fts5Init(sqlite3 *db){
|