| | @@ -1165,11 +1165,11 @@ |
| 1165 | 1165 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 1166 | 1166 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 1167 | 1167 | */ |
| 1168 | 1168 | #define SQLITE_VERSION "3.30.0" |
| 1169 | 1169 | #define SQLITE_VERSION_NUMBER 3030000 |
| 1170 | | -#define SQLITE_SOURCE_ID "2019-09-03 16:23:41 3044cf6917ea8324175fc91657e9a5978af9748f72e1914bc361753f0b2d897d" |
| 1170 | +#define SQLITE_SOURCE_ID "2019-09-21 17:31:03 8ea1dc727d391b15d0c4fa858ff68d5b8a63dde46408f24027dac8d28f044cbd" |
| 1171 | 1171 | |
| 1172 | 1172 | /* |
| 1173 | 1173 | ** CAPI3REF: Run-Time Library Version Numbers |
| 1174 | 1174 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 1175 | 1175 | ** |
| | @@ -5900,13 +5900,16 @@ |
| 5900 | 5900 | ** the same inputs within a single SQL statement. Most SQL functions are |
| 5901 | 5901 | ** deterministic. The built-in [random()] SQL function is an example of a |
| 5902 | 5902 | ** function that is not deterministic. The SQLite query planner is able to |
| 5903 | 5903 | ** perform additional optimizations on deterministic functions, so use |
| 5904 | 5904 | ** of the [SQLITE_DETERMINISTIC] flag is recommended where possible. |
| 5905 | +** |
| 5905 | 5906 | ** ^The fourth parameter may also optionally include the [SQLITE_DIRECTONLY] |
| 5906 | 5907 | ** flag, which if present prevents the function from being invoked from |
| 5907 | | -** within VIEWs or TRIGGERs. |
| 5908 | +** within VIEWs or TRIGGERs. For security reasons, the [SQLITE_DIRECTONLY] |
| 5909 | +** flag is recommended for any application-defined SQL function that has |
| 5910 | +** side-effects. |
| 5908 | 5911 | ** |
| 5909 | 5912 | ** ^(The fifth parameter is an arbitrary pointer. The implementation of the |
| 5910 | 5913 | ** function can gain access to this pointer using [sqlite3_user_data()].)^ |
| 5911 | 5914 | ** |
| 5912 | 5915 | ** ^The sixth, seventh and eighth parameters passed to the three |
| | @@ -6026,14 +6029,28 @@ |
| 6026 | 6029 | ** The SQLITE_DETERMINISTIC flag means that the new function will always |
| 6027 | 6030 | ** maps the same inputs into the same output. The abs() function is |
| 6028 | 6031 | ** deterministic, for example, but randomblob() is not. |
| 6029 | 6032 | ** |
| 6030 | 6033 | ** The SQLITE_DIRECTONLY flag means that the function may only be invoked |
| 6031 | | -** from top-level SQL, and cannot be used in VIEWs or TRIGGERs. |
| 6034 | +** from top-level SQL, and cannot be used in VIEWs or TRIGGERs. This is |
| 6035 | +** a security feature which is recommended for all |
| 6036 | +** [application-defined SQL functions] that have side-effects. This flag |
| 6037 | +** prevents an attacker from adding triggers and views to a schema then |
| 6038 | +** tricking a high-privilege application into causing unintended side-effects |
| 6039 | +** while performing ordinary queries. |
| 6040 | +** |
| 6041 | +** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call |
| 6042 | +** [sqlite3_value_subtype()] to inspect the sub-types of its arguments. |
| 6043 | +** Specifying this flag makes no difference for scalar or aggregate user |
| 6044 | +** functions. However, if it is not specified for a user-defined window |
| 6045 | +** function, then any sub-types belonging to arguments passed to the window |
| 6046 | +** function may be discarded before the window function is called (i.e. |
| 6047 | +** sqlite3_value_subtype() will always return 0). |
| 6032 | 6048 | */ |
| 6033 | 6049 | #define SQLITE_DETERMINISTIC 0x000000800 |
| 6034 | 6050 | #define SQLITE_DIRECTONLY 0x000080000 |
| 6051 | +#define SQLITE_SUBTYPE 0x000100000 |
| 6035 | 6052 | |
| 6036 | 6053 | /* |
| 6037 | 6054 | ** CAPI3REF: Deprecated Functions |
| 6038 | 6055 | ** DEPRECATED |
| 6039 | 6056 | ** |
| | @@ -16700,10 +16717,11 @@ |
| 16700 | 16717 | #define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */ |
| 16701 | 16718 | #define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */ |
| 16702 | 16719 | #define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */ |
| 16703 | 16720 | #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */ |
| 16704 | 16721 | #define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */ |
| 16722 | +#define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */ |
| 16705 | 16723 | |
| 16706 | 16724 | /* |
| 16707 | 16725 | ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are |
| 16708 | 16726 | ** used to create the initializers for the FuncDef structures. |
| 16709 | 16727 | ** |
| | @@ -18614,21 +18632,23 @@ |
| 18614 | 18632 | Window **ppThis; /* Pointer to this object in Select.pWin list */ |
| 18615 | 18633 | Window *pNextWin; /* Next window function belonging to this SELECT */ |
| 18616 | 18634 | Expr *pFilter; /* The FILTER expression */ |
| 18617 | 18635 | FuncDef *pFunc; /* The function */ |
| 18618 | 18636 | int iEphCsr; /* Partition buffer or Peer buffer */ |
| 18619 | | - int regAccum; |
| 18620 | | - int regResult; |
| 18637 | + int regAccum; /* Accumulator */ |
| 18638 | + int regResult; /* Interim result */ |
| 18621 | 18639 | int csrApp; /* Function cursor (used by min/max) */ |
| 18622 | 18640 | int regApp; /* Function register (also used by min/max) */ |
| 18623 | 18641 | int regPart; /* Array of registers for PARTITION BY values */ |
| 18624 | 18642 | Expr *pOwner; /* Expression object this window is attached to */ |
| 18625 | 18643 | int nBufferCol; /* Number of columns in buffer table */ |
| 18626 | 18644 | int iArgCol; /* Offset of first argument for this function */ |
| 18627 | 18645 | int regOne; /* Register containing constant value 1 */ |
| 18628 | 18646 | int regStartRowid; |
| 18629 | 18647 | int regEndRowid; |
| 18648 | + u8 bExprArgs; /* Defer evaluation of window function arguments |
| 18649 | + ** due to the SQLITE_SUBTYPE flag */ |
| 18630 | 18650 | }; |
| 18631 | 18651 | |
| 18632 | 18652 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 18633 | 18653 | SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3*, Window*); |
| 18634 | 18654 | SQLITE_PRIVATE void sqlite3WindowUnlinkFromSelect(Window*); |
| | @@ -29214,11 +29234,17 @@ |
| 29214 | 29234 | sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); |
| 29215 | 29235 | break; |
| 29216 | 29236 | } |
| 29217 | 29237 | |
| 29218 | 29238 | case TK_COLLATE: { |
| 29219 | | - sqlite3TreeViewLine(pView, "COLLATE %Q", pExpr->u.zToken); |
| 29239 | + /* COLLATE operators without the EP_Collate flag are intended to |
| 29240 | + ** emulate collation associated with a table column. Explicit |
| 29241 | + ** COLLATE operators that appear in the original SQL always have |
| 29242 | + ** the EP_Collate bit set */ |
| 29243 | + sqlite3TreeViewLine(pView, "%sCOLLATE %Q%s", |
| 29244 | + !ExprHasProperty(pExpr, EP_Collate) ? "SOFT-" : "", |
| 29245 | + pExpr->u.zToken, zFlgs); |
| 29220 | 29246 | sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); |
| 29221 | 29247 | break; |
| 29222 | 29248 | } |
| 29223 | 29249 | |
| 29224 | 29250 | case TK_AGG_FUNCTION: |
| | @@ -74843,11 +74869,17 @@ |
| 74843 | 74869 | testcase( bPreserve && pMem->z==0 ); |
| 74844 | 74870 | |
| 74845 | 74871 | assert( pMem->szMalloc==0 |
| 74846 | 74872 | || pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) ); |
| 74847 | 74873 | if( pMem->szMalloc>0 && bPreserve && pMem->z==pMem->zMalloc ){ |
| 74848 | | - pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n); |
| 74874 | + if( pMem->db ){ |
| 74875 | + pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n); |
| 74876 | + }else{ |
| 74877 | + pMem->zMalloc = sqlite3Realloc(pMem->z, n); |
| 74878 | + if( pMem->zMalloc==0 ) sqlite3_free(pMem->z); |
| 74879 | + pMem->z = pMem->zMalloc; |
| 74880 | + } |
| 74849 | 74881 | bPreserve = 0; |
| 74850 | 74882 | }else{ |
| 74851 | 74883 | if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc); |
| 74852 | 74884 | pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n); |
| 74853 | 74885 | } |
| | @@ -84279,10 +84311,11 @@ |
| 84279 | 84311 | assert( (f & (MEM_Static|MEM_Dyn))==0 ); |
| 84280 | 84312 | }else{ |
| 84281 | 84313 | c = 's'; |
| 84282 | 84314 | } |
| 84283 | 84315 | *(zCsr++) = c; |
| 84316 | + *(zCsr++) = 'x'; |
| 84284 | 84317 | sqlite3_snprintf(100, zCsr, "%d[", pMem->n); |
| 84285 | 84318 | zCsr += sqlite3Strlen30(zCsr); |
| 84286 | 84319 | for(i=0; i<25 && i<pMem->n; i++){ |
| 84287 | 84320 | sqlite3_snprintf(100, zCsr, "%02X", ((int)pMem->z[i] & 0xFF)); |
| 84288 | 84321 | zCsr += sqlite3Strlen30(zCsr); |
| | @@ -85027,11 +85060,10 @@ |
| 85027 | 85060 | ** as the P1 parameter. |
| 85028 | 85061 | */ |
| 85029 | 85062 | case OP_String8: { /* same as TK_STRING, out2 */ |
| 85030 | 85063 | assert( pOp->p4.z!=0 ); |
| 85031 | 85064 | pOut = out2Prerelease(p, pOp); |
| 85032 | | - pOp->opcode = OP_String; |
| 85033 | 85065 | pOp->p1 = sqlite3Strlen30(pOp->p4.z); |
| 85034 | 85066 | |
| 85035 | 85067 | #ifndef SQLITE_OMIT_UTF16 |
| 85036 | 85068 | if( encoding!=SQLITE_UTF8 ){ |
| 85037 | 85069 | rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); |
| | @@ -85051,10 +85083,11 @@ |
| 85051 | 85083 | } |
| 85052 | 85084 | #endif |
| 85053 | 85085 | if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 85054 | 85086 | goto too_big; |
| 85055 | 85087 | } |
| 85088 | + pOp->opcode = OP_String; |
| 85056 | 85089 | assert( rc==SQLITE_OK ); |
| 85057 | 85090 | /* Fall through to the next case, OP_String */ |
| 85058 | 85091 | } |
| 85059 | 85092 | |
| 85060 | 85093 | /* Opcode: String P1 P2 P3 P4 P5 |
| | @@ -100317,10 +100350,11 @@ |
| 100317 | 100350 | if( addrOnce ){ |
| 100318 | 100351 | sqlite3VdbeJumpHere(v, addrOnce); |
| 100319 | 100352 | /* Subroutine return */ |
| 100320 | 100353 | sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn); |
| 100321 | 100354 | sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); |
| 100355 | + sqlite3ClearTempRegCache(pParse); |
| 100322 | 100356 | } |
| 100323 | 100357 | } |
| 100324 | 100358 | #endif /* SQLITE_OMIT_SUBQUERY */ |
| 100325 | 100359 | |
| 100326 | 100360 | /* |
| | @@ -100427,10 +100461,11 @@ |
| 100427 | 100461 | sqlite3VdbeJumpHere(v, addrOnce); |
| 100428 | 100462 | |
| 100429 | 100463 | /* Subroutine return */ |
| 100430 | 100464 | sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn); |
| 100431 | 100465 | sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); |
| 100466 | + sqlite3ClearTempRegCache(pParse); |
| 100432 | 100467 | } |
| 100433 | 100468 | |
| 100434 | 100469 | return rReg; |
| 100435 | 100470 | } |
| 100436 | 100471 | #endif /* SQLITE_OMIT_SUBQUERY */ |
| | @@ -103058,10 +103093,15 @@ |
| 103058 | 103093 | } |
| 103059 | 103094 | } |
| 103060 | 103095 | |
| 103061 | 103096 | /* |
| 103062 | 103097 | ** Mark all temporary registers as being unavailable for reuse. |
| 103098 | +** |
| 103099 | +** Always invoke this procedure after coding a subroutine or co-routine |
| 103100 | +** that might be invoked from other parts of the code, to ensure that |
| 103101 | +** the sub/co-routine does not use registers in common with the code that |
| 103102 | +** invokes the sub/co-routine. |
| 103063 | 103103 | */ |
| 103064 | 103104 | SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse *pParse){ |
| 103065 | 103105 | pParse->nTempReg = 0; |
| 103066 | 103106 | pParse->nRangeReg = 0; |
| 103067 | 103107 | } |
| | @@ -114049,10 +114089,12 @@ |
| 114049 | 114089 | int nNeedle; |
| 114050 | 114090 | int typeHaystack, typeNeedle; |
| 114051 | 114091 | int N = 1; |
| 114052 | 114092 | int isText; |
| 114053 | 114093 | unsigned char firstChar; |
| 114094 | + sqlite3_value *pC1 = 0; |
| 114095 | + sqlite3_value *pC2 = 0; |
| 114054 | 114096 | |
| 114055 | 114097 | UNUSED_PARAMETER(argc); |
| 114056 | 114098 | typeHaystack = sqlite3_value_type(argv[0]); |
| 114057 | 114099 | typeNeedle = sqlite3_value_type(argv[1]); |
| 114058 | 114100 | if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return; |
| | @@ -114061,16 +114103,26 @@ |
| 114061 | 114103 | if( nNeedle>0 ){ |
| 114062 | 114104 | if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){ |
| 114063 | 114105 | zHaystack = sqlite3_value_blob(argv[0]); |
| 114064 | 114106 | zNeedle = sqlite3_value_blob(argv[1]); |
| 114065 | 114107 | isText = 0; |
| 114066 | | - }else{ |
| 114108 | + }else if( typeHaystack!=SQLITE_BLOB && typeNeedle!=SQLITE_BLOB ){ |
| 114067 | 114109 | zHaystack = sqlite3_value_text(argv[0]); |
| 114068 | 114110 | zNeedle = sqlite3_value_text(argv[1]); |
| 114069 | 114111 | isText = 1; |
| 114112 | + }else{ |
| 114113 | + pC1 = sqlite3_value_dup(argv[0]); |
| 114114 | + zHaystack = sqlite3_value_text(pC1); |
| 114115 | + if( zHaystack==0 ) goto endInstrOOM; |
| 114116 | + nHaystack = sqlite3_value_bytes(pC1); |
| 114117 | + pC2 = sqlite3_value_dup(argv[1]); |
| 114118 | + zNeedle = sqlite3_value_text(pC2); |
| 114119 | + if( zNeedle==0 ) goto endInstrOOM; |
| 114120 | + nNeedle = sqlite3_value_bytes(pC2); |
| 114121 | + isText = 1; |
| 114070 | 114122 | } |
| 114071 | | - if( zNeedle==0 || (nHaystack && zHaystack==0) ) return; |
| 114123 | + if( zNeedle==0 || (nHaystack && zHaystack==0) ) goto endInstrOOM; |
| 114072 | 114124 | firstChar = zNeedle[0]; |
| 114073 | 114125 | while( nNeedle<=nHaystack |
| 114074 | 114126 | && (zHaystack[0]!=firstChar || memcmp(zHaystack, zNeedle, nNeedle)!=0) |
| 114075 | 114127 | ){ |
| 114076 | 114128 | N++; |
| | @@ -114080,10 +114132,17 @@ |
| 114080 | 114132 | }while( isText && (zHaystack[0]&0xc0)==0x80 ); |
| 114081 | 114133 | } |
| 114082 | 114134 | if( nNeedle>nHaystack ) N = 0; |
| 114083 | 114135 | } |
| 114084 | 114136 | sqlite3_result_int(context, N); |
| 114137 | +endInstr: |
| 114138 | + sqlite3_value_free(pC1); |
| 114139 | + sqlite3_value_free(pC2); |
| 114140 | + return; |
| 114141 | +endInstrOOM: |
| 114142 | + sqlite3_result_error_nomem(context); |
| 114143 | + goto endInstr; |
| 114085 | 114144 | } |
| 114086 | 114145 | |
| 114087 | 114146 | /* |
| 114088 | 114147 | ** Implementation of the printf() function. |
| 114089 | 114148 | */ |
| | @@ -128983,10 +129042,22 @@ |
| 128983 | 129042 | pNew->iRightJoinTable = pExpr->iRightJoinTable; |
| 128984 | 129043 | ExprSetProperty(pNew, EP_FromJoin); |
| 128985 | 129044 | } |
| 128986 | 129045 | sqlite3ExprDelete(db, pExpr); |
| 128987 | 129046 | pExpr = pNew; |
| 129047 | + |
| 129048 | + /* Ensure that the expression now has an implicit collation sequence, |
| 129049 | + ** just as it did when it was a column of a view or sub-query. */ |
| 129050 | + if( pExpr ){ |
| 129051 | + if( pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE ){ |
| 129052 | + CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pExpr); |
| 129053 | + pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr, |
| 129054 | + (pColl ? pColl->zName : "BINARY") |
| 129055 | + ); |
| 129056 | + } |
| 129057 | + ExprClearProperty(pExpr, EP_Collate); |
| 129058 | + } |
| 128988 | 129059 | } |
| 128989 | 129060 | } |
| 128990 | 129061 | }else{ |
| 128991 | 129062 | if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){ |
| 128992 | 129063 | pExpr->iTable = pSubst->iNewTable; |
| | @@ -130849,10 +130920,23 @@ |
| 130849 | 130920 | ExprList *pList = pF->pExpr->x.pList; |
| 130850 | 130921 | assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) ); |
| 130851 | 130922 | assert( !IsWindowFunc(pF->pExpr) ); |
| 130852 | 130923 | if( ExprHasProperty(pF->pExpr, EP_WinFunc) ){ |
| 130853 | 130924 | Expr *pFilter = pF->pExpr->y.pWin->pFilter; |
| 130925 | + if( pAggInfo->nAccumulator |
| 130926 | + && (pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL) |
| 130927 | + ){ |
| 130928 | + if( regHit==0 ) regHit = ++pParse->nMem; |
| 130929 | + /* If this is the first row of the group (regAcc==0), clear the |
| 130930 | + ** "magnet" register regHit so that the accumulator registers |
| 130931 | + ** are populated if the FILTER clause jumps over the the |
| 130932 | + ** invocation of min() or max() altogether. Or, if this is not |
| 130933 | + ** the first row (regAcc==1), set the magnet register so that the |
| 130934 | + ** accumulators are not populated unless the min()/max() is invoked and |
| 130935 | + ** indicates that they should be. */ |
| 130936 | + sqlite3VdbeAddOp2(v, OP_Copy, regAcc, regHit); |
| 130937 | + } |
| 130854 | 130938 | addrNext = sqlite3VdbeMakeLabel(pParse); |
| 130855 | 130939 | sqlite3ExprIfFalse(pParse, pFilter, addrNext, SQLITE_JUMPIFNULL); |
| 130856 | 130940 | } |
| 130857 | 130941 | if( pList ){ |
| 130858 | 130942 | nArg = pList->nExpr; |
| | @@ -130899,10 +130983,11 @@ |
| 130899 | 130983 | addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v); |
| 130900 | 130984 | } |
| 130901 | 130985 | for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){ |
| 130902 | 130986 | sqlite3ExprCode(pParse, pC->pExpr, pC->iMem); |
| 130903 | 130987 | } |
| 130988 | + |
| 130904 | 130989 | pAggInfo->directMode = 0; |
| 130905 | 130990 | if( addrHitTest ){ |
| 130906 | 130991 | sqlite3VdbeJumpHere(v, addrHitTest); |
| 130907 | 130992 | } |
| 130908 | 130993 | } |
| | @@ -131702,27 +131787,39 @@ |
| 131702 | 131787 | for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){ |
| 131703 | 131788 | pItem->u.x.iAlias = 0; |
| 131704 | 131789 | } |
| 131705 | 131790 | assert( 66==sqlite3LogEst(100) ); |
| 131706 | 131791 | if( p->nSelectRow>66 ) p->nSelectRow = 66; |
| 131792 | + |
| 131793 | + /* If there is both a GROUP BY and an ORDER BY clause and they are |
| 131794 | + ** identical, then it may be possible to disable the ORDER BY clause |
| 131795 | + ** on the grounds that the GROUP BY will cause elements to come out |
| 131796 | + ** in the correct order. It also may not - the GROUP BY might use a |
| 131797 | + ** database index that causes rows to be grouped together as required |
| 131798 | + ** but not actually sorted. Either way, record the fact that the |
| 131799 | + ** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp |
| 131800 | + ** variable. */ |
| 131801 | + if( sSort.pOrderBy && pGroupBy->nExpr==sSort.pOrderBy->nExpr ){ |
| 131802 | + int ii; |
| 131803 | + /* The GROUP BY processing doesn't care whether rows are delivered in |
| 131804 | + ** ASC or DESC order - only that each group is returned contiguously. |
| 131805 | + ** So set the ASC/DESC flags in the GROUP BY to match those in the |
| 131806 | + ** ORDER BY to maximize the chances of rows being delivered in an |
| 131807 | + ** order that makes the ORDER BY redundant. */ |
| 131808 | + for(ii=0; ii<pGroupBy->nExpr; ii++){ |
| 131809 | + u8 sortFlags = sSort.pOrderBy->a[ii].sortFlags & KEYINFO_ORDER_DESC; |
| 131810 | + pGroupBy->a[ii].sortFlags = sortFlags; |
| 131811 | + } |
| 131812 | + if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){ |
| 131813 | + orderByGrp = 1; |
| 131814 | + } |
| 131815 | + } |
| 131707 | 131816 | }else{ |
| 131708 | 131817 | assert( 0==sqlite3LogEst(1) ); |
| 131709 | 131818 | p->nSelectRow = 0; |
| 131710 | 131819 | } |
| 131711 | 131820 | |
| 131712 | | - /* If there is both a GROUP BY and an ORDER BY clause and they are |
| 131713 | | - ** identical, then it may be possible to disable the ORDER BY clause |
| 131714 | | - ** on the grounds that the GROUP BY will cause elements to come out |
| 131715 | | - ** in the correct order. It also may not - the GROUP BY might use a |
| 131716 | | - ** database index that causes rows to be grouped together as required |
| 131717 | | - ** but not actually sorted. Either way, record the fact that the |
| 131718 | | - ** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp |
| 131719 | | - ** variable. */ |
| 131720 | | - if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){ |
| 131721 | | - orderByGrp = 1; |
| 131722 | | - } |
| 131723 | | - |
| 131724 | 131821 | /* Create a label to jump to when we want to abort the query */ |
| 131725 | 131822 | addrEnd = sqlite3VdbeMakeLabel(pParse); |
| 131726 | 131823 | |
| 131727 | 131824 | /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in |
| 131728 | 131825 | ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the |
| | @@ -132074,17 +132171,22 @@ |
| 132074 | 132171 | }else |
| 132075 | 132172 | #endif /* SQLITE_OMIT_BTREECOUNT */ |
| 132076 | 132173 | { |
| 132077 | 132174 | int regAcc = 0; /* "populate accumulators" flag */ |
| 132078 | 132175 | |
| 132079 | | - /* If there are accumulator registers but no min() or max() functions, |
| 132080 | | - ** allocate register regAcc. Register regAcc will contain 0 the first |
| 132081 | | - ** time the inner loop runs, and 1 thereafter. The code generated |
| 132082 | | - ** by updateAccumulator() only updates the accumulator registers if |
| 132083 | | - ** regAcc contains 0. */ |
| 132176 | + /* If there are accumulator registers but no min() or max() functions |
| 132177 | + ** without FILTER clauses, allocate register regAcc. Register regAcc |
| 132178 | + ** will contain 0 the first time the inner loop runs, and 1 thereafter. |
| 132179 | + ** The code generated by updateAccumulator() uses this to ensure |
| 132180 | + ** that the accumulator registers are (a) updated only once if |
| 132181 | + ** there are no min() or max functions or (b) always updated for the |
| 132182 | + ** first row visited by the aggregate, so that they are updated at |
| 132183 | + ** least once even if the FILTER clause means the min() or max() |
| 132184 | + ** function visits zero rows. */ |
| 132084 | 132185 | if( sAggInfo.nAccumulator ){ |
| 132085 | 132186 | for(i=0; i<sAggInfo.nFunc; i++){ |
| 132187 | + if( ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_WinFunc) ) continue; |
| 132086 | 132188 | if( sAggInfo.aFunc[i].pFunc->funcFlags&SQLITE_FUNC_NEEDCOLL ) break; |
| 132087 | 132189 | } |
| 132088 | 132190 | if( i==sAggInfo.nFunc ){ |
| 132089 | 132191 | regAcc = ++pParse->nMem; |
| 132090 | 132192 | sqlite3VdbeAddOp2(v, OP_Integer, 0, regAcc); |
| | @@ -139778,22 +139880,27 @@ |
| 139778 | 139880 | ** LIKE optimization. See, for example: |
| 139779 | 139881 | ** 2018-09-10 https://sqlite.org/src/info/c94369cae9b561b1 |
| 139780 | 139882 | ** 2019-05-02 https://sqlite.org/src/info/b043a54c3de54b28 |
| 139781 | 139883 | ** 2019-06-10 https://sqlite.org/src/info/fd76310a5e843e07 |
| 139782 | 139884 | ** 2019-06-14 https://sqlite.org/src/info/ce8717f0885af975 |
| 139885 | + ** 2019-09-03 https://sqlite.org/src/info/0f0428096f17252a |
| 139783 | 139886 | */ |
| 139784 | 139887 | if( pLeft->op!=TK_COLUMN |
| 139785 | 139888 | || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT |
| 139786 | 139889 | || IsVirtual(pLeft->y.pTab) /* Value might be numeric */ |
| 139787 | 139890 | ){ |
| 139788 | 139891 | int isNum; |
| 139789 | 139892 | double rDummy; |
| 139790 | 139893 | isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8); |
| 139791 | 139894 | if( isNum<=0 ){ |
| 139792 | | - zNew[iTo-1]++; |
| 139793 | | - isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8); |
| 139794 | | - zNew[iTo-1]--; |
| 139895 | + if( iTo==1 && zNew[0]=='-' ){ |
| 139896 | + isNum = +1; |
| 139897 | + }else{ |
| 139898 | + zNew[iTo-1]++; |
| 139899 | + isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8); |
| 139900 | + zNew[iTo-1]--; |
| 139901 | + } |
| 139795 | 139902 | } |
| 139796 | 139903 | if( isNum>0 ){ |
| 139797 | 139904 | sqlite3ExprDelete(db, pPrefix); |
| 139798 | 139905 | sqlite3ValueFree(pVal); |
| 139799 | 139906 | return 0; |
| | @@ -143384,11 +143491,11 @@ |
| 143384 | 143491 | WhereLoop *pLoop, /* The loop to adjust downward */ |
| 143385 | 143492 | LogEst nRow /* Number of rows in the entire table */ |
| 143386 | 143493 | ){ |
| 143387 | 143494 | WhereTerm *pTerm, *pX; |
| 143388 | 143495 | Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf); |
| 143389 | | - int i, j, k; |
| 143496 | + int i, j; |
| 143390 | 143497 | LogEst iReduce = 0; /* pLoop->nOut should not exceed nRow-iReduce */ |
| 143391 | 143498 | |
| 143392 | 143499 | assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); |
| 143393 | 143500 | for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){ |
| 143394 | 143501 | assert( pTerm!=0 ); |
| | @@ -143410,10 +143517,11 @@ |
| 143410 | 143517 | /* In the absence of explicit truth probabilities, use heuristics to |
| 143411 | 143518 | ** guess a reasonable truth probability. */ |
| 143412 | 143519 | pLoop->nOut--; |
| 143413 | 143520 | if( pTerm->eOperator&(WO_EQ|WO_IS) ){ |
| 143414 | 143521 | Expr *pRight = pTerm->pExpr->pRight; |
| 143522 | + int k = 0; |
| 143415 | 143523 | testcase( pTerm->pExpr->op==TK_IS ); |
| 143416 | 143524 | if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){ |
| 143417 | 143525 | k = 10; |
| 143418 | 143526 | }else{ |
| 143419 | 143527 | k = 20; |
| | @@ -147493,12 +147601,19 @@ |
| 147493 | 147601 | /* Append the arguments passed to each window function to the |
| 147494 | 147602 | ** sub-select expression list. Also allocate two registers for each |
| 147495 | 147603 | ** window function - one for the accumulator, another for interim |
| 147496 | 147604 | ** results. */ |
| 147497 | 147605 | for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ |
| 147498 | | - pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); |
| 147499 | | - pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList, 0); |
| 147606 | + ExprList *pArgs = pWin->pOwner->x.pList; |
| 147607 | + if( pWin->pFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){ |
| 147608 | + selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist); |
| 147609 | + pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); |
| 147610 | + pWin->bExprArgs = 1; |
| 147611 | + }else{ |
| 147612 | + pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); |
| 147613 | + pSublist = exprListAppendList(pParse, pSublist, pArgs, 0); |
| 147614 | + } |
| 147500 | 147615 | if( pWin->pFilter ){ |
| 147501 | 147616 | Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0); |
| 147502 | 147617 | pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter); |
| 147503 | 147618 | } |
| 147504 | 147619 | pWin->regAccum = ++pParse->nMem; |
| | @@ -147960,11 +148075,11 @@ |
| 147960 | 148075 | Vdbe *v = sqlite3GetVdbe(pParse); |
| 147961 | 148076 | Window *pWin; |
| 147962 | 148077 | for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ |
| 147963 | 148078 | FuncDef *pFunc = pWin->pFunc; |
| 147964 | 148079 | int regArg; |
| 147965 | | - int nArg = windowArgCount(pWin); |
| 148080 | + int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin); |
| 147966 | 148081 | int i; |
| 147967 | 148082 | |
| 147968 | 148083 | assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED ); |
| 147969 | 148084 | |
| 147970 | 148085 | for(i=0; i<nArg; i++){ |
| | @@ -148002,17 +148117,32 @@ |
| 148002 | 148117 | sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1); |
| 148003 | 148118 | }else if( pFunc->xSFunc!=noopStepFunc ){ |
| 148004 | 148119 | int addrIf = 0; |
| 148005 | 148120 | if( pWin->pFilter ){ |
| 148006 | 148121 | int regTmp; |
| 148007 | | - assert( nArg==0 || nArg==pWin->pOwner->x.pList->nExpr ); |
| 148008 | | - assert( nArg || pWin->pOwner->x.pList==0 ); |
| 148122 | + assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr ); |
| 148123 | + assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 ); |
| 148009 | 148124 | regTmp = sqlite3GetTempReg(pParse); |
| 148010 | 148125 | sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp); |
| 148011 | 148126 | addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1); |
| 148012 | 148127 | VdbeCoverage(v); |
| 148013 | 148128 | sqlite3ReleaseTempReg(pParse, regTmp); |
| 148129 | + } |
| 148130 | + if( pWin->bExprArgs ){ |
| 148131 | + int iStart = sqlite3VdbeCurrentAddr(v); |
| 148132 | + VdbeOp *pOp, *pEnd; |
| 148133 | + |
| 148134 | + nArg = pWin->pOwner->x.pList->nExpr; |
| 148135 | + regArg = sqlite3GetTempRange(pParse, nArg); |
| 148136 | + sqlite3ExprCodeExprList(pParse, pWin->pOwner->x.pList, regArg, 0, 0); |
| 148137 | + |
| 148138 | + pEnd = sqlite3VdbeGetOp(v, -1); |
| 148139 | + for(pOp=sqlite3VdbeGetOp(v, iStart); pOp<=pEnd; pOp++){ |
| 148140 | + if( pOp->opcode==OP_Column && pOp->p1==pWin->iEphCsr ){ |
| 148141 | + pOp->p1 = csr; |
| 148142 | + } |
| 148143 | + } |
| 148014 | 148144 | } |
| 148015 | 148145 | if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ |
| 148016 | 148146 | CollSeq *pColl; |
| 148017 | 148147 | assert( nArg>0 ); |
| 148018 | 148148 | pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr); |
| | @@ -148020,10 +148150,13 @@ |
| 148020 | 148150 | } |
| 148021 | 148151 | sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, |
| 148022 | 148152 | bInverse, regArg, pWin->regAccum); |
| 148023 | 148153 | sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF); |
| 148024 | 148154 | sqlite3VdbeChangeP5(v, (u8)nArg); |
| 148155 | + if( pWin->bExprArgs ){ |
| 148156 | + sqlite3ReleaseTempRange(pParse, regArg, nArg); |
| 148157 | + } |
| 148025 | 148158 | if( addrIf ) sqlite3VdbeJumpHere(v, addrIf); |
| 148026 | 148159 | } |
| 148027 | 148160 | } |
| 148028 | 148161 | } |
| 148029 | 148162 | |
| | @@ -148718,10 +148851,11 @@ |
| 148718 | 148851 | Window *pNew = 0; |
| 148719 | 148852 | if( ALWAYS(p) ){ |
| 148720 | 148853 | pNew = sqlite3DbMallocZero(db, sizeof(Window)); |
| 148721 | 148854 | if( pNew ){ |
| 148722 | 148855 | pNew->zName = sqlite3DbStrDup(db, p->zName); |
| 148856 | + pNew->zBase = sqlite3DbStrDup(db, p->zBase); |
| 148723 | 148857 | pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0); |
| 148724 | 148858 | pNew->pFunc = p->pFunc; |
| 148725 | 148859 | pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0); |
| 148726 | 148860 | pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0); |
| 148727 | 148861 | pNew->eFrmType = p->eFrmType; |
| | @@ -148730,10 +148864,11 @@ |
| 148730 | 148864 | pNew->eExclude = p->eExclude; |
| 148731 | 148865 | pNew->regResult = p->regResult; |
| 148732 | 148866 | pNew->pStart = sqlite3ExprDup(db, p->pStart, 0); |
| 148733 | 148867 | pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0); |
| 148734 | 148868 | pNew->pOwner = pOwner; |
| 148869 | + pNew->bImplicitFrame = p->bImplicitFrame; |
| 148735 | 148870 | } |
| 148736 | 148871 | } |
| 148737 | 148872 | return pNew; |
| 148738 | 148873 | } |
| 148739 | 148874 | |
| | @@ -149273,11 +149408,11 @@ |
| 149273 | 149408 | if( regEnd ){ |
| 149274 | 149409 | sqlite3ExprCode(pParse, pMWin->pEnd, regEnd); |
| 149275 | 149410 | windowCheckValue(pParse, regEnd, 1 + (pMWin->eFrmType==TK_RANGE ? 3 : 0)); |
| 149276 | 149411 | } |
| 149277 | 149412 | |
| 149278 | | - if( pMWin->eStart==pMWin->eEnd && regStart ){ |
| 149413 | + if( pMWin->eFrmType!=TK_RANGE && pMWin->eStart==pMWin->eEnd && regStart ){ |
| 149279 | 149414 | int op = ((pMWin->eStart==TK_FOLLOWING) ? OP_Ge : OP_Le); |
| 149280 | 149415 | int addrGe = sqlite3VdbeAddOp3(v, op, regStart, 0, regEnd); |
| 149281 | 149416 | VdbeCoverageNeverNullIf(v, op==OP_Ge); /* NeverNull because bound <expr> */ |
| 149282 | 149417 | VdbeCoverageNeverNullIf(v, op==OP_Le); /* values previously checked */ |
| 149283 | 149418 | windowAggFinal(&s, 0); |
| | @@ -157734,11 +157869,11 @@ |
| 157734 | 157869 | return SQLITE_MISUSE_BKPT; |
| 157735 | 157870 | } |
| 157736 | 157871 | |
| 157737 | 157872 | assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); |
| 157738 | 157873 | assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY ); |
| 157739 | | - extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY); |
| 157874 | + extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY|SQLITE_SUBTYPE); |
| 157740 | 157875 | enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); |
| 157741 | 157876 | |
| 157742 | 157877 | #ifndef SQLITE_OMIT_UTF16 |
| 157743 | 157878 | /* If SQLITE_UTF16 is specified as the encoding type, transform this |
| 157744 | 157879 | ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the |
| | @@ -164202,11 +164337,12 @@ |
| 164202 | 164337 | iWrite = iVal - *piPrev; |
| 164203 | 164338 | }else{ |
| 164204 | 164339 | iWrite = *piPrev - iVal; |
| 164205 | 164340 | } |
| 164206 | 164341 | assert( *pbFirst || *piPrev==0 ); |
| 164207 | | - assert( *pbFirst==0 || iWrite>0 ); |
| 164342 | + assert_fts3_nc( *pbFirst==0 || iWrite>0 ); |
| 164343 | + assert( *pbFirst==0 || iWrite>=0 ); |
| 164208 | 164344 | *pp += sqlite3Fts3PutVarint(*pp, iWrite); |
| 164209 | 164345 | *piPrev = iVal; |
| 164210 | 164346 | *pbFirst = 1; |
| 164211 | 164347 | } |
| 164212 | 164348 | |
| | @@ -164308,10 +164444,12 @@ |
| 164308 | 164444 | }else{ |
| 164309 | 164445 | fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i2); |
| 164310 | 164446 | fts3PoslistCopy(&p, &p2); |
| 164311 | 164447 | fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); |
| 164312 | 164448 | } |
| 164449 | + |
| 164450 | + assert( (p-aOut)<=((p1?(p1-a1):n1)+(p2?(p2-a2):n2)+FTS3_VARINT_MAX-1) ); |
| 164313 | 164451 | } |
| 164314 | 164452 | |
| 164315 | 164453 | if( rc!=SQLITE_OK ){ |
| 164316 | 164454 | sqlite3_free(aOut); |
| 164317 | 164455 | p = aOut = 0; |
| | @@ -181914,11 +182052,11 @@ |
| 181914 | 182052 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); |
| 181915 | 182053 | if( pStr ){ |
| 181916 | 182054 | if( pStr->zBuf==0 ){ |
| 181917 | 182055 | jsonInit(pStr, ctx); |
| 181918 | 182056 | jsonAppendChar(pStr, '['); |
| 181919 | | - }else{ |
| 182057 | + }else if( pStr->nUsed>1 ){ |
| 181920 | 182058 | jsonAppendChar(pStr, ','); |
| 181921 | 182059 | pStr->pCtx = ctx; |
| 181922 | 182060 | } |
| 181923 | 182061 | jsonAppendValue(pStr, argv[0]); |
| 181924 | 182062 | } |
| | @@ -181962,13 +182100,15 @@ |
| 181962 | 182100 | static void jsonGroupInverse( |
| 181963 | 182101 | sqlite3_context *ctx, |
| 181964 | 182102 | int argc, |
| 181965 | 182103 | sqlite3_value **argv |
| 181966 | 182104 | ){ |
| 181967 | | - int i; |
| 182105 | + unsigned int i; |
| 181968 | 182106 | int inStr = 0; |
| 182107 | + int nNest = 0; |
| 181969 | 182108 | char *z; |
| 182109 | + char c; |
| 181970 | 182110 | JsonString *pStr; |
| 181971 | 182111 | UNUSED_PARAM(argc); |
| 181972 | 182112 | UNUSED_PARAM(argv); |
| 181973 | 182113 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); |
| 181974 | 182114 | #ifdef NEVER |
| | @@ -181975,16 +182115,22 @@ |
| 181975 | 182115 | /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will |
| 181976 | 182116 | ** always have been called to initalize it */ |
| 181977 | 182117 | if( NEVER(!pStr) ) return; |
| 181978 | 182118 | #endif |
| 181979 | 182119 | z = pStr->zBuf; |
| 181980 | | - for(i=1; z[i]!=',' || inStr; i++){ |
| 181981 | | - assert( i<pStr->nUsed ); |
| 181982 | | - if( z[i]=='"' ){ |
| 182120 | + for(i=1; (c = z[i])!=',' || inStr || nNest; i++){ |
| 182121 | + if( i>=pStr->nUsed ){ |
| 182122 | + pStr->nUsed = 1; |
| 182123 | + return; |
| 182124 | + } |
| 182125 | + if( c=='"' ){ |
| 181983 | 182126 | inStr = !inStr; |
| 181984 | | - }else if( z[i]=='\\' ){ |
| 182127 | + }else if( c=='\\' ){ |
| 181985 | 182128 | i++; |
| 182129 | + }else if( !inStr ){ |
| 182130 | + if( c=='{' || c=='[' ) nNest++; |
| 182131 | + if( c=='}' || c==']' ) nNest--; |
| 181986 | 182132 | } |
| 181987 | 182133 | } |
| 181988 | 182134 | pStr->nUsed -= i; |
| 181989 | 182135 | memmove(&z[1], &z[i+1], (size_t)pStr->nUsed-1); |
| 181990 | 182136 | } |
| | @@ -182010,11 +182156,11 @@ |
| 182010 | 182156 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); |
| 182011 | 182157 | if( pStr ){ |
| 182012 | 182158 | if( pStr->zBuf==0 ){ |
| 182013 | 182159 | jsonInit(pStr, ctx); |
| 182014 | 182160 | jsonAppendChar(pStr, '{'); |
| 182015 | | - }else{ |
| 182161 | + }else if( pStr->nUsed>1 ){ |
| 182016 | 182162 | jsonAppendChar(pStr, ','); |
| 182017 | 182163 | pStr->pCtx = ctx; |
| 182018 | 182164 | } |
| 182019 | 182165 | z = (const char*)sqlite3_value_text(argv[0]); |
| 182020 | 182166 | n = (u32)sqlite3_value_bytes(argv[0]); |
| | @@ -182598,18 +182744,18 @@ |
| 182598 | 182744 | { "json_tree", &jsonTreeModule }, |
| 182599 | 182745 | }; |
| 182600 | 182746 | #endif |
| 182601 | 182747 | for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){ |
| 182602 | 182748 | rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg, |
| 182603 | | - SQLITE_UTF8 | SQLITE_DETERMINISTIC, |
| 182749 | + SQLITE_UTF8 | SQLITE_DETERMINISTIC, |
| 182604 | 182750 | (void*)&aFunc[i].flag, |
| 182605 | 182751 | aFunc[i].xFunc, 0, 0); |
| 182606 | 182752 | } |
| 182607 | 182753 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 182608 | 182754 | for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){ |
| 182609 | 182755 | rc = sqlite3_create_window_function(db, aAgg[i].zName, aAgg[i].nArg, |
| 182610 | | - SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0, |
| 182756 | + SQLITE_SUBTYPE | SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0, |
| 182611 | 182757 | aAgg[i].xStep, aAgg[i].xFinal, |
| 182612 | 182758 | aAgg[i].xValue, jsonGroupInverse, 0); |
| 182613 | 182759 | } |
| 182614 | 182760 | #endif |
| 182615 | 182761 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| | @@ -203607,10 +203753,11 @@ |
| 203607 | 203753 | static int sqlite3Fts5ExprNext(Fts5Expr*, i64 iMax); |
| 203608 | 203754 | static int sqlite3Fts5ExprEof(Fts5Expr*); |
| 203609 | 203755 | static i64 sqlite3Fts5ExprRowid(Fts5Expr*); |
| 203610 | 203756 | |
| 203611 | 203757 | static void sqlite3Fts5ExprFree(Fts5Expr*); |
| 203758 | +static int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2); |
| 203612 | 203759 | |
| 203613 | 203760 | /* Called during startup to register a UDF with SQLite */ |
| 203614 | 203761 | static int sqlite3Fts5ExprInit(Fts5Global*, sqlite3*); |
| 203615 | 203762 | |
| 203616 | 203763 | static int sqlite3Fts5ExprPhraseCount(Fts5Expr*); |
| | @@ -207014,11 +207161,11 @@ |
| 207014 | 207161 | assert( zSql || rc==SQLITE_NOMEM ); |
| 207015 | 207162 | if( zSql ){ |
| 207016 | 207163 | rc = sqlite3_declare_vtab(pConfig->db, zSql); |
| 207017 | 207164 | sqlite3_free(zSql); |
| 207018 | 207165 | } |
| 207019 | | - |
| 207166 | + |
| 207020 | 207167 | return rc; |
| 207021 | 207168 | } |
| 207022 | 207169 | |
| 207023 | 207170 | /* |
| 207024 | 207171 | ** Tokenize the text passed via the second and third arguments. |
| | @@ -207601,10 +207748,46 @@ |
| 207601 | 207748 | sqlite3Fts5ParseNodeFree(p->pRoot); |
| 207602 | 207749 | sqlite3_free(p->apExprPhrase); |
| 207603 | 207750 | sqlite3_free(p); |
| 207604 | 207751 | } |
| 207605 | 207752 | } |
| 207753 | + |
| 207754 | +static int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){ |
| 207755 | + Fts5Parse sParse; |
| 207756 | + memset(&sParse, 0, sizeof(sParse)); |
| 207757 | + |
| 207758 | + if( *pp1 ){ |
| 207759 | + Fts5Expr *p1 = *pp1; |
| 207760 | + int nPhrase = p1->nPhrase + p2->nPhrase; |
| 207761 | + |
| 207762 | + p1->pRoot = sqlite3Fts5ParseNode(&sParse, FTS5_AND, p1->pRoot, p2->pRoot,0); |
| 207763 | + p2->pRoot = 0; |
| 207764 | + |
| 207765 | + if( sParse.rc==SQLITE_OK ){ |
| 207766 | + Fts5ExprPhrase **ap = (Fts5ExprPhrase**)sqlite3_realloc( |
| 207767 | + p1->apExprPhrase, nPhrase * sizeof(Fts5ExprPhrase*) |
| 207768 | + ); |
| 207769 | + if( ap==0 ){ |
| 207770 | + sParse.rc = SQLITE_NOMEM; |
| 207771 | + }else{ |
| 207772 | + int i; |
| 207773 | + memmove(&ap[p2->nPhrase], ap, p1->nPhrase*sizeof(Fts5ExprPhrase*)); |
| 207774 | + for(i=0; i<p2->nPhrase; i++){ |
| 207775 | + ap[i] = p2->apExprPhrase[i]; |
| 207776 | + } |
| 207777 | + p1->nPhrase = nPhrase; |
| 207778 | + p1->apExprPhrase = ap; |
| 207779 | + } |
| 207780 | + } |
| 207781 | + sqlite3_free(p2->apExprPhrase); |
| 207782 | + sqlite3_free(p2); |
| 207783 | + }else{ |
| 207784 | + *pp1 = p2; |
| 207785 | + } |
| 207786 | + |
| 207787 | + return sParse.rc; |
| 207788 | +} |
| 207606 | 207789 | |
| 207607 | 207790 | /* |
| 207608 | 207791 | ** Argument pTerm must be a synonym iterator. Return the current rowid |
| 207609 | 207792 | ** that it points to. |
| 207610 | 207793 | */ |
| | @@ -211421,11 +211604,11 @@ |
| 211421 | 211604 | } |
| 211422 | 211605 | |
| 211423 | 211606 | static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){ |
| 211424 | 211607 | Fts5Data *pRet = fts5DataRead(p, iRowid); |
| 211425 | 211608 | if( pRet ){ |
| 211426 | | - if( pRet->szLeaf>pRet->nn ){ |
| 211609 | + if( pRet->nn<4 || pRet->szLeaf>pRet->nn ){ |
| 211427 | 211610 | p->rc = FTS5_CORRUPT; |
| 211428 | 211611 | fts5DataRelease(pRet); |
| 211429 | 211612 | pRet = 0; |
| 211430 | 211613 | } |
| 211431 | 211614 | } |
| | @@ -217765,20 +217948,42 @@ |
| 217765 | 217948 | |
| 217766 | 217949 | /* |
| 217767 | 217950 | ** Implementation of the xBestIndex method for FTS5 tables. Within the |
| 217768 | 217951 | ** WHERE constraint, it searches for the following: |
| 217769 | 217952 | ** |
| 217770 | | -** 1. A MATCH constraint against the special column. |
| 217953 | +** 1. A MATCH constraint against the table column. |
| 217771 | 217954 | ** 2. A MATCH constraint against the "rank" column. |
| 217772 | | -** 3. An == constraint against the rowid column. |
| 217773 | | -** 4. A < or <= constraint against the rowid column. |
| 217774 | | -** 5. A > or >= constraint against the rowid column. |
| 217955 | +** 3. A MATCH constraint against some other column. |
| 217956 | +** 4. An == constraint against the rowid column. |
| 217957 | +** 5. A < or <= constraint against the rowid column. |
| 217958 | +** 6. A > or >= constraint against the rowid column. |
| 217775 | 217959 | ** |
| 217776 | | -** Within the ORDER BY, either: |
| 217960 | +** Within the ORDER BY, the following are supported: |
| 217777 | 217961 | ** |
| 217778 | 217962 | ** 5. ORDER BY rank [ASC|DESC] |
| 217779 | 217963 | ** 6. ORDER BY rowid [ASC|DESC] |
| 217964 | +** |
| 217965 | +** Information for the xFilter call is passed via both the idxNum and |
| 217966 | +** idxStr variables. Specifically, idxNum is a bitmask of the following |
| 217967 | +** flags used to encode the ORDER BY clause: |
| 217968 | +** |
| 217969 | +** FTS5_BI_ORDER_RANK |
| 217970 | +** FTS5_BI_ORDER_ROWID |
| 217971 | +** FTS5_BI_ORDER_DESC |
| 217972 | +** |
| 217973 | +** idxStr is used to encode data from the WHERE clause. For each argument |
| 217974 | +** passed to the xFilter method, the following is appended to idxStr: |
| 217975 | +** |
| 217976 | +** Match against table column: "m" |
| 217977 | +** Match against rank column: "r" |
| 217978 | +** Match against other column: "<column-number>" |
| 217979 | +** Equality constraint against the rowid: "=" |
| 217980 | +** A < or <= against the rowid: "<" |
| 217981 | +** A > or >= against the rowid: ">" |
| 217982 | +** |
| 217983 | +** This function ensures that there is at most one "r" or "=". And that if |
| 217984 | +** there exists an "=" then there is no "<" or ">". |
| 217780 | 217985 | ** |
| 217781 | 217986 | ** Costs are assigned as follows: |
| 217782 | 217987 | ** |
| 217783 | 217988 | ** a) If an unusable MATCH operator is present in the WHERE clause, the |
| 217784 | 217989 | ** cost is unconditionally set to 1e50 (a really big number). |
| | @@ -217803,36 +218008,22 @@ |
| 217803 | 218008 | static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ |
| 217804 | 218009 | Fts5Table *pTab = (Fts5Table*)pVTab; |
| 217805 | 218010 | Fts5Config *pConfig = pTab->pConfig; |
| 217806 | 218011 | const int nCol = pConfig->nCol; |
| 217807 | 218012 | int idxFlags = 0; /* Parameter passed through to xFilter() */ |
| 217808 | | - int bHasMatch; |
| 217809 | | - int iNext; |
| 217810 | 218013 | int i; |
| 217811 | 218014 | |
| 217812 | | - struct Constraint { |
| 217813 | | - int op; /* Mask against sqlite3_index_constraint.op */ |
| 217814 | | - int fts5op; /* FTS5 mask for idxFlags */ |
| 217815 | | - int iCol; /* 0==rowid, 1==tbl, 2==rank */ |
| 217816 | | - int omit; /* True to omit this if found */ |
| 217817 | | - int iConsIndex; /* Index in pInfo->aConstraint[] */ |
| 217818 | | - } aConstraint[] = { |
| 217819 | | - {SQLITE_INDEX_CONSTRAINT_MATCH|SQLITE_INDEX_CONSTRAINT_EQ, |
| 217820 | | - FTS5_BI_MATCH, 1, 1, -1}, |
| 217821 | | - {SQLITE_INDEX_CONSTRAINT_MATCH|SQLITE_INDEX_CONSTRAINT_EQ, |
| 217822 | | - FTS5_BI_RANK, 2, 1, -1}, |
| 217823 | | - {SQLITE_INDEX_CONSTRAINT_EQ, FTS5_BI_ROWID_EQ, 0, 0, -1}, |
| 217824 | | - {SQLITE_INDEX_CONSTRAINT_LT|SQLITE_INDEX_CONSTRAINT_LE, |
| 217825 | | - FTS5_BI_ROWID_LE, 0, 0, -1}, |
| 217826 | | - {SQLITE_INDEX_CONSTRAINT_GT|SQLITE_INDEX_CONSTRAINT_GE, |
| 217827 | | - FTS5_BI_ROWID_GE, 0, 0, -1}, |
| 217828 | | - }; |
| 217829 | | - |
| 217830 | | - int aColMap[3]; |
| 217831 | | - aColMap[0] = -1; |
| 217832 | | - aColMap[1] = nCol; |
| 217833 | | - aColMap[2] = nCol+1; |
| 218015 | + char *idxStr; |
| 218016 | + int iIdxStr = 0; |
| 218017 | + int iCons = 0; |
| 218018 | + |
| 218019 | + int bSeenEq = 0; |
| 218020 | + int bSeenGt = 0; |
| 218021 | + int bSeenLt = 0; |
| 218022 | + int bSeenMatch = 0; |
| 218023 | + int bSeenRank = 0; |
| 218024 | + |
| 217834 | 218025 | |
| 217835 | 218026 | assert( SQLITE_INDEX_CONSTRAINT_EQ<SQLITE_INDEX_CONSTRAINT_MATCH ); |
| 217836 | 218027 | assert( SQLITE_INDEX_CONSTRAINT_GT<SQLITE_INDEX_CONSTRAINT_MATCH ); |
| 217837 | 218028 | assert( SQLITE_INDEX_CONSTRAINT_LE<SQLITE_INDEX_CONSTRAINT_MATCH ); |
| 217838 | 218029 | assert( SQLITE_INDEX_CONSTRAINT_GE<SQLITE_INDEX_CONSTRAINT_MATCH ); |
| | @@ -217843,44 +218034,82 @@ |
| 217843 | 218034 | "recursively defined fts5 content table" |
| 217844 | 218035 | ); |
| 217845 | 218036 | return SQLITE_ERROR; |
| 217846 | 218037 | } |
| 217847 | 218038 | |
| 217848 | | - /* Set idxFlags flags for all WHERE clause terms that will be used. */ |
| 218039 | + idxStr = (char*)sqlite3_malloc(pInfo->nConstraint * 6 + 1); |
| 218040 | + if( idxStr==0 ) return SQLITE_NOMEM; |
| 218041 | + pInfo->idxStr = idxStr; |
| 218042 | + pInfo->needToFreeIdxStr = 1; |
| 218043 | + |
| 217849 | 218044 | for(i=0; i<pInfo->nConstraint; i++){ |
| 217850 | 218045 | struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; |
| 217851 | 218046 | int iCol = p->iColumn; |
| 217852 | | - |
| 217853 | | - if( (p->op==SQLITE_INDEX_CONSTRAINT_MATCH && iCol>=0 && iCol<=nCol) |
| 217854 | | - || (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol==nCol) |
| 218047 | + if( p->op==SQLITE_INDEX_CONSTRAINT_MATCH |
| 218048 | + || (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol>=nCol) |
| 217855 | 218049 | ){ |
| 217856 | 218050 | /* A MATCH operator or equivalent */ |
| 217857 | | - if( p->usable ){ |
| 217858 | | - idxFlags = (idxFlags & 0xFFFF) | FTS5_BI_MATCH | (iCol << 16); |
| 217859 | | - aConstraint[0].iConsIndex = i; |
| 217860 | | - }else{ |
| 218051 | + if( p->usable==0 || iCol<0 ){ |
| 217861 | 218052 | /* As there exists an unusable MATCH constraint this is an |
| 217862 | 218053 | ** unusable plan. Set a prohibitively high cost. */ |
| 217863 | 218054 | pInfo->estimatedCost = 1e50; |
| 218055 | + assert( iIdxStr < pInfo->nConstraint*6 + 1 ); |
| 218056 | + idxStr[iIdxStr] = 0; |
| 217864 | 218057 | return SQLITE_OK; |
| 217865 | | - } |
| 217866 | | - }else if( p->op<=SQLITE_INDEX_CONSTRAINT_MATCH ){ |
| 217867 | | - int j; |
| 217868 | | - for(j=1; j<ArraySize(aConstraint); j++){ |
| 217869 | | - struct Constraint *pC = &aConstraint[j]; |
| 217870 | | - if( iCol==aColMap[pC->iCol] && (p->op & pC->op) && p->usable ){ |
| 217871 | | - pC->iConsIndex = i; |
| 217872 | | - idxFlags |= pC->fts5op; |
| 218058 | + }else{ |
| 218059 | + if( iCol==nCol+1 ){ |
| 218060 | + if( bSeenRank ) continue; |
| 218061 | + idxStr[iIdxStr++] = 'r'; |
| 218062 | + bSeenRank = 1; |
| 218063 | + }else{ |
| 218064 | + bSeenMatch = 1; |
| 218065 | + idxStr[iIdxStr++] = 'm'; |
| 218066 | + if( iCol<nCol ){ |
| 218067 | + sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol); |
| 218068 | + idxStr += strlen(&idxStr[iIdxStr]); |
| 218069 | + assert( idxStr[iIdxStr]=='\0' ); |
| 218070 | + } |
| 218071 | + } |
| 218072 | + pInfo->aConstraintUsage[i].argvIndex = ++iCons; |
| 218073 | + pInfo->aConstraintUsage[i].omit = 1; |
| 218074 | + } |
| 218075 | + } |
| 218076 | + else if( p->usable && bSeenEq==0 |
| 218077 | + && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 |
| 218078 | + ){ |
| 218079 | + idxStr[iIdxStr++] = '='; |
| 218080 | + bSeenEq = 1; |
| 218081 | + pInfo->aConstraintUsage[i].argvIndex = ++iCons; |
| 218082 | + } |
| 218083 | + } |
| 218084 | + |
| 218085 | + if( bSeenEq==0 ){ |
| 218086 | + for(i=0; i<pInfo->nConstraint; i++){ |
| 218087 | + struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; |
| 218088 | + if( p->iColumn<0 && p->usable ){ |
| 218089 | + int op = p->op; |
| 218090 | + if( op==SQLITE_INDEX_CONSTRAINT_LT || op==SQLITE_INDEX_CONSTRAINT_LE ){ |
| 218091 | + if( bSeenLt ) continue; |
| 218092 | + idxStr[iIdxStr++] = '<'; |
| 218093 | + pInfo->aConstraintUsage[i].argvIndex = ++iCons; |
| 218094 | + bSeenLt = 1; |
| 218095 | + }else |
| 218096 | + if( op==SQLITE_INDEX_CONSTRAINT_GT || op==SQLITE_INDEX_CONSTRAINT_GE ){ |
| 218097 | + if( bSeenGt ) continue; |
| 218098 | + idxStr[iIdxStr++] = '>'; |
| 218099 | + pInfo->aConstraintUsage[i].argvIndex = ++iCons; |
| 218100 | + bSeenGt = 1; |
| 217873 | 218101 | } |
| 217874 | 218102 | } |
| 217875 | 218103 | } |
| 217876 | 218104 | } |
| 218105 | + idxStr[iIdxStr] = '\0'; |
| 217877 | 218106 | |
| 217878 | 218107 | /* Set idxFlags flags for the ORDER BY clause */ |
| 217879 | 218108 | if( pInfo->nOrderBy==1 ){ |
| 217880 | 218109 | int iSort = pInfo->aOrderBy[0].iColumn; |
| 217881 | | - if( iSort==(pConfig->nCol+1) && BitFlagTest(idxFlags, FTS5_BI_MATCH) ){ |
| 218110 | + if( iSort==(pConfig->nCol+1) && bSeenMatch ){ |
| 217882 | 218111 | idxFlags |= FTS5_BI_ORDER_RANK; |
| 217883 | 218112 | }else if( iSort==-1 ){ |
| 217884 | 218113 | idxFlags |= FTS5_BI_ORDER_ROWID; |
| 217885 | 218114 | } |
| 217886 | 218115 | if( BitFlagTest(idxFlags, FTS5_BI_ORDER_RANK|FTS5_BI_ORDER_ROWID) ){ |
| | @@ -217890,30 +218119,19 @@ |
| 217890 | 218119 | } |
| 217891 | 218120 | } |
| 217892 | 218121 | } |
| 217893 | 218122 | |
| 217894 | 218123 | /* Calculate the estimated cost based on the flags set in idxFlags. */ |
| 217895 | | - bHasMatch = BitFlagTest(idxFlags, FTS5_BI_MATCH); |
| 217896 | | - if( BitFlagTest(idxFlags, FTS5_BI_ROWID_EQ) ){ |
| 217897 | | - pInfo->estimatedCost = bHasMatch ? 100.0 : 10.0; |
| 217898 | | - if( bHasMatch==0 ) fts5SetUniqueFlag(pInfo); |
| 217899 | | - }else if( BitFlagAllTest(idxFlags, FTS5_BI_ROWID_LE|FTS5_BI_ROWID_GE) ){ |
| 217900 | | - pInfo->estimatedCost = bHasMatch ? 500.0 : 250000.0; |
| 217901 | | - }else if( BitFlagTest(idxFlags, FTS5_BI_ROWID_LE|FTS5_BI_ROWID_GE) ){ |
| 217902 | | - pInfo->estimatedCost = bHasMatch ? 750.0 : 750000.0; |
| 218124 | + if( bSeenEq ){ |
| 218125 | + pInfo->estimatedCost = bSeenMatch ? 100.0 : 10.0; |
| 218126 | + if( bSeenMatch==0 ) fts5SetUniqueFlag(pInfo); |
| 218127 | + }else if( bSeenLt && bSeenGt ){ |
| 218128 | + pInfo->estimatedCost = bSeenMatch ? 500.0 : 250000.0; |
| 218129 | + }else if( bSeenLt || bSeenGt ){ |
| 218130 | + pInfo->estimatedCost = bSeenMatch ? 750.0 : 750000.0; |
| 217903 | 218131 | }else{ |
| 217904 | | - pInfo->estimatedCost = bHasMatch ? 1000.0 : 1000000.0; |
| 217905 | | - } |
| 217906 | | - |
| 217907 | | - /* Assign argvIndex values to each constraint in use. */ |
| 217908 | | - iNext = 1; |
| 217909 | | - for(i=0; i<ArraySize(aConstraint); i++){ |
| 217910 | | - struct Constraint *pC = &aConstraint[i]; |
| 217911 | | - if( pC->iConsIndex>=0 ){ |
| 217912 | | - pInfo->aConstraintUsage[pC->iConsIndex].argvIndex = iNext++; |
| 217913 | | - pInfo->aConstraintUsage[pC->iConsIndex].omit = (unsigned char)pC->omit; |
| 217914 | | - } |
| 218132 | + pInfo->estimatedCost = bSeenMatch ? 1000.0 : 1000000.0; |
| 217915 | 218133 | } |
| 217916 | 218134 | |
| 217917 | 218135 | pInfo->idxNum = idxFlags; |
| 217918 | 218136 | return SQLITE_OK; |
| 217919 | 218137 | } |
| | @@ -218432,31 +218650,29 @@ |
| 218432 | 218650 | ** 3. A full-table scan. |
| 218433 | 218651 | */ |
| 218434 | 218652 | static int fts5FilterMethod( |
| 218435 | 218653 | sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ |
| 218436 | 218654 | int idxNum, /* Strategy index */ |
| 218437 | | - const char *zUnused, /* Unused */ |
| 218655 | + const char *idxStr, /* Unused */ |
| 218438 | 218656 | int nVal, /* Number of elements in apVal */ |
| 218439 | 218657 | sqlite3_value **apVal /* Arguments for the indexing scheme */ |
| 218440 | 218658 | ){ |
| 218441 | 218659 | Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab); |
| 218442 | 218660 | Fts5Config *pConfig = pTab->p.pConfig; |
| 218443 | 218661 | Fts5Cursor *pCsr = (Fts5Cursor*)pCursor; |
| 218444 | 218662 | int rc = SQLITE_OK; /* Error code */ |
| 218445 | | - int iVal = 0; /* Counter for apVal[] */ |
| 218446 | 218663 | int bDesc; /* True if ORDER BY [rank|rowid] DESC */ |
| 218447 | 218664 | int bOrderByRank; /* True if ORDER BY rank */ |
| 218448 | | - sqlite3_value *pMatch = 0; /* <tbl> MATCH ? expression (or NULL) */ |
| 218449 | 218665 | sqlite3_value *pRank = 0; /* rank MATCH ? expression (or NULL) */ |
| 218450 | 218666 | sqlite3_value *pRowidEq = 0; /* rowid = ? expression (or NULL) */ |
| 218451 | 218667 | sqlite3_value *pRowidLe = 0; /* rowid <= ? expression (or NULL) */ |
| 218452 | 218668 | sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */ |
| 218453 | 218669 | int iCol; /* Column on LHS of MATCH operator */ |
| 218454 | 218670 | char **pzErrmsg = pConfig->pzErrmsg; |
| 218455 | | - |
| 218456 | | - UNUSED_PARAM(zUnused); |
| 218457 | | - UNUSED_PARAM(nVal); |
| 218671 | + int i; |
| 218672 | + int iIdxStr = 0; |
| 218673 | + Fts5Expr *pExpr = 0; |
| 218458 | 218674 | |
| 218459 | 218675 | if( pCsr->ePlan ){ |
| 218460 | 218676 | fts5FreeCursorComponents(pCsr); |
| 218461 | 218677 | memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr)); |
| 218462 | 218678 | } |
| | @@ -218465,27 +218681,64 @@ |
| 218465 | 218681 | assert( pCsr->pExpr==0 ); |
| 218466 | 218682 | assert( pCsr->csrflags==0 ); |
| 218467 | 218683 | assert( pCsr->pRank==0 ); |
| 218468 | 218684 | assert( pCsr->zRank==0 ); |
| 218469 | 218685 | assert( pCsr->zRankArgs==0 ); |
| 218686 | + assert( pTab->pSortCsr==0 || nVal==0 ); |
| 218470 | 218687 | |
| 218471 | 218688 | assert( pzErrmsg==0 || pzErrmsg==&pTab->p.base.zErrMsg ); |
| 218472 | 218689 | pConfig->pzErrmsg = &pTab->p.base.zErrMsg; |
| 218473 | 218690 | |
| 218474 | | - /* Decode the arguments passed through to this function. |
| 218475 | | - ** |
| 218476 | | - ** Note: The following set of if(...) statements must be in the same |
| 218477 | | - ** order as the corresponding entries in the struct at the top of |
| 218478 | | - ** fts5BestIndexMethod(). */ |
| 218479 | | - if( BitFlagTest(idxNum, FTS5_BI_MATCH) ) pMatch = apVal[iVal++]; |
| 218480 | | - if( BitFlagTest(idxNum, FTS5_BI_RANK) ) pRank = apVal[iVal++]; |
| 218481 | | - if( BitFlagTest(idxNum, FTS5_BI_ROWID_EQ) ) pRowidEq = apVal[iVal++]; |
| 218482 | | - if( BitFlagTest(idxNum, FTS5_BI_ROWID_LE) ) pRowidLe = apVal[iVal++]; |
| 218483 | | - if( BitFlagTest(idxNum, FTS5_BI_ROWID_GE) ) pRowidGe = apVal[iVal++]; |
| 218484 | | - iCol = (idxNum>>16); |
| 218485 | | - assert( iCol>=0 && iCol<=pConfig->nCol ); |
| 218486 | | - assert( iVal==nVal ); |
| 218691 | + /* Decode the arguments passed through to this function. */ |
| 218692 | + for(i=0; i<nVal; i++){ |
| 218693 | + switch( idxStr[iIdxStr++] ){ |
| 218694 | + case 'r': |
| 218695 | + pRank = apVal[i]; |
| 218696 | + break; |
| 218697 | + case 'm': { |
| 218698 | + const char *zText = (const char*)sqlite3_value_text(apVal[i]); |
| 218699 | + if( zText==0 ) zText = ""; |
| 218700 | + |
| 218701 | + if( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' ){ |
| 218702 | + iCol = 0; |
| 218703 | + do{ |
| 218704 | + iCol = iCol*10 + (idxStr[iIdxStr]-'0'); |
| 218705 | + iIdxStr++; |
| 218706 | + }while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' ); |
| 218707 | + }else{ |
| 218708 | + iCol = pConfig->nCol; |
| 218709 | + } |
| 218710 | + |
| 218711 | + if( zText[0]=='*' ){ |
| 218712 | + /* The user has issued a query of the form "MATCH '*...'". This |
| 218713 | + ** indicates that the MATCH expression is not a full text query, |
| 218714 | + ** but a request for an internal parameter. */ |
| 218715 | + rc = fts5SpecialMatch(pTab, pCsr, &zText[1]); |
| 218716 | + goto filter_out; |
| 218717 | + }else{ |
| 218718 | + char **pzErr = &pTab->p.base.zErrMsg; |
| 218719 | + rc = sqlite3Fts5ExprNew(pConfig, iCol, zText, &pExpr, pzErr); |
| 218720 | + if( rc==SQLITE_OK ){ |
| 218721 | + rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr); |
| 218722 | + pExpr = 0; |
| 218723 | + } |
| 218724 | + if( rc!=SQLITE_OK ) goto filter_out; |
| 218725 | + } |
| 218726 | + |
| 218727 | + break; |
| 218728 | + } |
| 218729 | + case '=': |
| 218730 | + pRowidEq = apVal[i]; |
| 218731 | + break; |
| 218732 | + case '<': |
| 218733 | + pRowidLe = apVal[i]; |
| 218734 | + break; |
| 218735 | + default: assert( idxStr[iIdxStr-1]=='>' ); |
| 218736 | + pRowidGe = apVal[i]; |
| 218737 | + break; |
| 218738 | + } |
| 218739 | + } |
| 218487 | 218740 | bOrderByRank = ((idxNum & FTS5_BI_ORDER_RANK) ? 1 : 0); |
| 218488 | 218741 | pCsr->bDesc = bDesc = ((idxNum & FTS5_BI_ORDER_DESC) ? 1 : 0); |
| 218489 | 218742 | |
| 218490 | 218743 | /* Set the cursor upper and lower rowid limits. Only some strategies |
| 218491 | 218744 | ** actually use them. This is ok, as the xBestIndex() method leaves the |
| | @@ -218508,11 +218761,11 @@ |
| 218508 | 218761 | ** set to FTS5_PLAN_SORTED_MATCH). pSortCsr is the cursor that will |
| 218509 | 218762 | ** return results to the user for this query. The current cursor |
| 218510 | 218763 | ** (pCursor) is used to execute the query issued by function |
| 218511 | 218764 | ** fts5CursorFirstSorted() above. */ |
| 218512 | 218765 | assert( pRowidEq==0 && pRowidLe==0 && pRowidGe==0 && pRank==0 ); |
| 218513 | | - assert( nVal==0 && pMatch==0 && bOrderByRank==0 && bDesc==0 ); |
| 218766 | + assert( nVal==0 && bOrderByRank==0 && bDesc==0 ); |
| 218514 | 218767 | assert( pCsr->iLastRowid==LARGEST_INT64 ); |
| 218515 | 218768 | assert( pCsr->iFirstRowid==SMALLEST_INT64 ); |
| 218516 | 218769 | if( pTab->pSortCsr->bDesc ){ |
| 218517 | 218770 | pCsr->iLastRowid = pTab->pSortCsr->iFirstRowid; |
| 218518 | 218771 | pCsr->iFirstRowid = pTab->pSortCsr->iLastRowid; |
| | @@ -218521,33 +218774,19 @@ |
| 218521 | 218774 | pCsr->iFirstRowid = pTab->pSortCsr->iFirstRowid; |
| 218522 | 218775 | } |
| 218523 | 218776 | pCsr->ePlan = FTS5_PLAN_SOURCE; |
| 218524 | 218777 | pCsr->pExpr = pTab->pSortCsr->pExpr; |
| 218525 | 218778 | rc = fts5CursorFirst(pTab, pCsr, bDesc); |
| 218526 | | - }else if( pMatch ){ |
| 218527 | | - const char *zExpr = (const char*)sqlite3_value_text(apVal[0]); |
| 218528 | | - if( zExpr==0 ) zExpr = ""; |
| 218529 | | - |
| 218779 | + }else if( pCsr->pExpr ){ |
| 218530 | 218780 | rc = fts5CursorParseRank(pConfig, pCsr, pRank); |
| 218531 | 218781 | if( rc==SQLITE_OK ){ |
| 218532 | | - if( zExpr[0]=='*' ){ |
| 218533 | | - /* The user has issued a query of the form "MATCH '*...'". This |
| 218534 | | - ** indicates that the MATCH expression is not a full text query, |
| 218535 | | - ** but a request for an internal parameter. */ |
| 218536 | | - rc = fts5SpecialMatch(pTab, pCsr, &zExpr[1]); |
| 218537 | | - }else{ |
| 218538 | | - char **pzErr = &pTab->p.base.zErrMsg; |
| 218539 | | - rc = sqlite3Fts5ExprNew(pConfig, iCol, zExpr, &pCsr->pExpr, pzErr); |
| 218540 | | - if( rc==SQLITE_OK ){ |
| 218541 | | - if( bOrderByRank ){ |
| 218542 | | - pCsr->ePlan = FTS5_PLAN_SORTED_MATCH; |
| 218543 | | - rc = fts5CursorFirstSorted(pTab, pCsr, bDesc); |
| 218544 | | - }else{ |
| 218545 | | - pCsr->ePlan = FTS5_PLAN_MATCH; |
| 218546 | | - rc = fts5CursorFirst(pTab, pCsr, bDesc); |
| 218547 | | - } |
| 218548 | | - } |
| 218782 | + if( bOrderByRank ){ |
| 218783 | + pCsr->ePlan = FTS5_PLAN_SORTED_MATCH; |
| 218784 | + rc = fts5CursorFirstSorted(pTab, pCsr, bDesc); |
| 218785 | + }else{ |
| 218786 | + pCsr->ePlan = FTS5_PLAN_MATCH; |
| 218787 | + rc = fts5CursorFirst(pTab, pCsr, bDesc); |
| 218549 | 218788 | } |
| 218550 | 218789 | } |
| 218551 | 218790 | }else if( pConfig->zContent==0 ){ |
| 218552 | 218791 | *pConfig->pzErrmsg = sqlite3_mprintf( |
| 218553 | 218792 | "%s: table does not support scanning", pConfig->zName |
| | @@ -218560,19 +218799,21 @@ |
| 218560 | 218799 | rc = sqlite3Fts5StorageStmt( |
| 218561 | 218800 | pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->p.base.zErrMsg |
| 218562 | 218801 | ); |
| 218563 | 218802 | if( rc==SQLITE_OK ){ |
| 218564 | 218803 | if( pCsr->ePlan==FTS5_PLAN_ROWID ){ |
| 218565 | | - sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]); |
| 218804 | + sqlite3_bind_value(pCsr->pStmt, 1, pRowidEq); |
| 218566 | 218805 | }else{ |
| 218567 | 218806 | sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iFirstRowid); |
| 218568 | 218807 | sqlite3_bind_int64(pCsr->pStmt, 2, pCsr->iLastRowid); |
| 218569 | 218808 | } |
| 218570 | 218809 | rc = fts5NextMethod(pCursor); |
| 218571 | 218810 | } |
| 218572 | 218811 | } |
| 218573 | 218812 | |
| 218813 | + filter_out: |
| 218814 | + sqlite3Fts5ExprFree(pExpr); |
| 218574 | 218815 | pConfig->pzErrmsg = pzErrmsg; |
| 218575 | 218816 | return rc; |
| 218576 | 218817 | } |
| 218577 | 218818 | |
| 218578 | 218819 | /* |
| | @@ -219955,11 +220196,11 @@ |
| 219955 | 220196 | int nArg, /* Number of args */ |
| 219956 | 220197 | sqlite3_value **apUnused /* Function arguments */ |
| 219957 | 220198 | ){ |
| 219958 | 220199 | assert( nArg==0 ); |
| 219959 | 220200 | UNUSED_PARAM2(nArg, apUnused); |
| 219960 | | - sqlite3_result_text(pCtx, "fts5: 2019-09-03 16:23:41 3044cf6917ea8324175fc91657e9a5978af9748f72e1914bc361753f0b2d897d", -1, SQLITE_TRANSIENT); |
| 220201 | + sqlite3_result_text(pCtx, "fts5: 2019-09-21 17:31:03 8ea1dc727d391b15d0c4fa858ff68d5b8a63dde46408f24027dac8d28f044cbd", -1, SQLITE_TRANSIENT); |
| 219961 | 220202 | } |
| 219962 | 220203 | |
| 219963 | 220204 | /* |
| 219964 | 220205 | ** Return true if zName is the extension on one of the shadow tables used |
| 219965 | 220206 | ** by this module. |
| | @@ -224723,12 +224964,12 @@ |
| 224723 | 224964 | } |
| 224724 | 224965 | #endif /* SQLITE_CORE */ |
| 224725 | 224966 | #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ |
| 224726 | 224967 | |
| 224727 | 224968 | /************** End of stmt.c ************************************************/ |
| 224728 | | -#if __LINE__!=224728 |
| 224969 | +#if __LINE__!=224969 |
| 224729 | 224970 | #undef SQLITE_SOURCE_ID |
| 224730 | | -#define SQLITE_SOURCE_ID "2019-09-03 16:23:41 3044cf6917ea8324175fc91657e9a5978af9748f72e1914bc361753f0b2dalt2" |
| 224971 | +#define SQLITE_SOURCE_ID "2019-09-21 17:31:03 8ea1dc727d391b15d0c4fa858ff68d5b8a63dde46408f24027dac8d28f04alt2" |
| 224731 | 224972 | #endif |
| 224732 | 224973 | /* Return the source-id for this library */ |
| 224733 | 224974 | SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } |
| 224734 | 224975 | /************************** End of sqlite3.c ******************************/ |
| 224735 | 224976 | |