| | @@ -1,8 +1,8 @@ |
| 1 | 1 | /****************************************************************************** |
| 2 | 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | | -** version 3.7.17. By combining all the individual C code files into this |
| 3 | +** version 3.8.0. By combining all the individual C code files into this |
| 4 | 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | 8 | ** translation unit. |
| | @@ -668,13 +668,13 @@ |
| 668 | 668 | ** |
| 669 | 669 | ** See also: [sqlite3_libversion()], |
| 670 | 670 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 671 | 671 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 672 | 672 | */ |
| 673 | | -#define SQLITE_VERSION "3.7.17" |
| 674 | | -#define SQLITE_VERSION_NUMBER 3007017 |
| 675 | | -#define SQLITE_SOURCE_ID "2013-06-20 14:17:39 d94db3fd921890ab1d6414ab629410ae50779686" |
| 673 | +#define SQLITE_VERSION "3.8.0" |
| 674 | +#define SQLITE_VERSION_NUMBER 3008000 |
| 675 | +#define SQLITE_SOURCE_ID "2013-06-26 22:46:00 93f632152e464a89322a0130adaf9f342411bf7d" |
| 676 | 676 | |
| 677 | 677 | /* |
| 678 | 678 | ** CAPI3REF: Run-Time Library Version Numbers |
| 679 | 679 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 680 | 680 | ** |
| | @@ -6869,15 +6869,25 @@ |
| 6869 | 6869 | ** <dd>^This is the number of rows inserted into transient indices that |
| 6870 | 6870 | ** were created automatically in order to help joins run faster. |
| 6871 | 6871 | ** A non-zero value in this counter may indicate an opportunity to |
| 6872 | 6872 | ** improvement performance by adding permanent indices that do not |
| 6873 | 6873 | ** need to be reinitialized each time the statement is run.</dd> |
| 6874 | +** |
| 6875 | +** [[SQLITE_STMTSTATUS_VM_STEP]] <dt>SQLITE_STMTSTATUS_VM_STEP</dt> |
| 6876 | +** <dd>^This is the number of virtual machine operations executed |
| 6877 | +** by the prepared statement if that number is less than or equal |
| 6878 | +** to 2147483647. The number of virtual machine operations can be |
| 6879 | +** used as a proxy for the total work done by the prepared statement. |
| 6880 | +** If the number of virtual machine operations exceeds 2147483647 |
| 6881 | +** then the value returned by this statement status code is undefined. |
| 6882 | +** </dd> |
| 6874 | 6883 | ** </dl> |
| 6875 | 6884 | */ |
| 6876 | 6885 | #define SQLITE_STMTSTATUS_FULLSCAN_STEP 1 |
| 6877 | 6886 | #define SQLITE_STMTSTATUS_SORT 2 |
| 6878 | 6887 | #define SQLITE_STMTSTATUS_AUTOINDEX 3 |
| 6888 | +#define SQLITE_STMTSTATUS_VM_STEP 4 |
| 6879 | 6889 | |
| 6880 | 6890 | /* |
| 6881 | 6891 | ** CAPI3REF: Custom Page Cache Object |
| 6882 | 6892 | ** |
| 6883 | 6893 | ** The sqlite3_pcache type is opaque. It is implemented by |
| | @@ -10193,10 +10203,11 @@ |
| 10193 | 10203 | #define SQLITE_DistinctOpt 0x0020 /* DISTINCT using indexes */ |
| 10194 | 10204 | #define SQLITE_CoverIdxScan 0x0040 /* Covering index scans */ |
| 10195 | 10205 | #define SQLITE_OrderByIdxJoin 0x0080 /* ORDER BY of joins via index */ |
| 10196 | 10206 | #define SQLITE_SubqCoroutine 0x0100 /* Evaluate subqueries as coroutines */ |
| 10197 | 10207 | #define SQLITE_Transitive 0x0200 /* Transitive constraints */ |
| 10208 | +#define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */ |
| 10198 | 10209 | #define SQLITE_AllOpts 0xffff /* All optimizations */ |
| 10199 | 10210 | |
| 10200 | 10211 | /* |
| 10201 | 10212 | ** Macros for testing whether or not optimizations are enabled or disabled. |
| 10202 | 10213 | */ |
| | @@ -11143,10 +11154,11 @@ |
| 11143 | 11154 | #define WHERE_FORCE_TABLE 0x0020 /* Do not use an index-only search */ |
| 11144 | 11155 | #define WHERE_ONETABLE_ONLY 0x0040 /* Only code the 1st table in pTabList */ |
| 11145 | 11156 | #define WHERE_AND_ONLY 0x0080 /* Don't use indices for OR terms */ |
| 11146 | 11157 | #define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */ |
| 11147 | 11158 | #define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */ |
| 11159 | +#define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */ |
| 11148 | 11160 | |
| 11149 | 11161 | /* Allowed return values from sqlite3WhereIsDistinct() |
| 11150 | 11162 | */ |
| 11151 | 11163 | #define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */ |
| 11152 | 11164 | #define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */ |
| | @@ -13507,11 +13519,11 @@ |
| 13507 | 13519 | bft doingRerun:1; /* True if rerunning after an auto-reprepare */ |
| 13508 | 13520 | int nChange; /* Number of db changes made since last reset */ |
| 13509 | 13521 | yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ |
| 13510 | 13522 | yDbMask lockMask; /* Subset of btreeMask that requires a lock */ |
| 13511 | 13523 | int iStatement; /* Statement number (or 0 if has not opened stmt) */ |
| 13512 | | - int aCounter[3]; /* Counters used by sqlite3_stmt_status() */ |
| 13524 | + int aCounter[4]; /* Counters used by sqlite3_stmt_status() */ |
| 13513 | 13525 | #ifndef SQLITE_OMIT_TRACE |
| 13514 | 13526 | i64 startTime; /* Time when query started - used for profiling */ |
| 13515 | 13527 | #endif |
| 13516 | 13528 | i64 nFkConstraint; /* Number of imm. FK constraints this VM */ |
| 13517 | 13529 | i64 nStmtDefCons; /* Number of def. constraints when stmt started */ |
| | @@ -65351,16 +65363,17 @@ |
| 65351 | 65363 | u8 encoding = ENC(db); /* The database encoding */ |
| 65352 | 65364 | #ifndef SQLITE_OMIT_PROGRESS_CALLBACK |
| 65353 | 65365 | int checkProgress; /* True if progress callbacks are enabled */ |
| 65354 | 65366 | int nProgressOps = 0; /* Opcodes executed since progress callback. */ |
| 65355 | 65367 | #endif |
| 65368 | + int iCompare = 0; /* Result of last OP_Compare operation */ |
| 65369 | + unsigned nVmStep = 0; /* Number of virtual machine steps */ |
| 65356 | 65370 | Mem *aMem = p->aMem; /* Copy of p->aMem */ |
| 65357 | 65371 | Mem *pIn1 = 0; /* 1st input operand */ |
| 65358 | 65372 | Mem *pIn2 = 0; /* 2nd input operand */ |
| 65359 | 65373 | Mem *pIn3 = 0; /* 3rd input operand */ |
| 65360 | 65374 | Mem *pOut = 0; /* Output operand */ |
| 65361 | | - int iCompare = 0; /* Result of last OP_Compare operation */ |
| 65362 | 65375 | int *aPermute = 0; /* Permutation of columns for OP_Compare */ |
| 65363 | 65376 | i64 lastRowid = db->lastRowid; /* Saved value of the last insert ROWID */ |
| 65364 | 65377 | #ifdef VDBE_PROFILE |
| 65365 | 65378 | u64 start; /* CPU clock count at start of opcode */ |
| 65366 | 65379 | int origPc; /* Program counter at start of opcode */ |
| | @@ -65830,10 +65843,11 @@ |
| 65830 | 65843 | if( db->mallocFailed ) goto no_mem; |
| 65831 | 65844 | #ifdef VDBE_PROFILE |
| 65832 | 65845 | origPc = pc; |
| 65833 | 65846 | start = sqlite3Hwtime(); |
| 65834 | 65847 | #endif |
| 65848 | + nVmStep++; |
| 65835 | 65849 | pOp = &aOp[pc]; |
| 65836 | 65850 | |
| 65837 | 65851 | /* Only allow tracing if SQLITE_DEBUG is defined. |
| 65838 | 65852 | */ |
| 65839 | 65853 | #ifdef SQLITE_DEBUG |
| | @@ -71566,10 +71580,11 @@ |
| 71566 | 71580 | /* This is the only way out of this procedure. We have to |
| 71567 | 71581 | ** release the mutexes on btrees that were acquired at the |
| 71568 | 71582 | ** top. */ |
| 71569 | 71583 | vdbe_return: |
| 71570 | 71584 | db->lastRowid = lastRowid; |
| 71585 | + p->aCounter[SQLITE_STMTSTATUS_VM_STEP-1] += (int)nVmStep; |
| 71571 | 71586 | sqlite3VdbeLeave(p); |
| 71572 | 71587 | return rc; |
| 71573 | 71588 | |
| 71574 | 71589 | /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH |
| 71575 | 71590 | ** is encountered. |
| | @@ -76044,10 +76059,11 @@ |
| 76044 | 76059 | pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags); |
| 76045 | 76060 | pItem->zName = sqlite3DbStrDup(db, pOldItem->zName); |
| 76046 | 76061 | pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan); |
| 76047 | 76062 | pItem->sortOrder = pOldItem->sortOrder; |
| 76048 | 76063 | pItem->done = 0; |
| 76064 | + pItem->bSpanIsTab = pOldItem->bSpanIsTab; |
| 76049 | 76065 | pItem->iOrderByCol = pOldItem->iOrderByCol; |
| 76050 | 76066 | pItem->iAlias = pOldItem->iAlias; |
| 76051 | 76067 | } |
| 76052 | 76068 | return pNew; |
| 76053 | 76069 | } |
| | @@ -100236,19 +100252,20 @@ |
| 100236 | 100252 | sDistinct.eTnctType = WHERE_DISTINCT_NOOP; |
| 100237 | 100253 | } |
| 100238 | 100254 | |
| 100239 | 100255 | if( !isAgg && pGroupBy==0 ){ |
| 100240 | 100256 | /* No aggregate functions and no GROUP BY clause */ |
| 100241 | | - ExprList *pDist = (sDistinct.isTnct ? p->pEList : 0); |
| 100257 | + u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0); |
| 100242 | 100258 | |
| 100243 | 100259 | /* Begin the database scan. */ |
| 100244 | | - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pOrderBy, pDist, 0,0); |
| 100260 | + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pOrderBy, p->pEList, |
| 100261 | + wctrlFlags, 0); |
| 100245 | 100262 | if( pWInfo==0 ) goto select_end; |
| 100246 | 100263 | if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){ |
| 100247 | 100264 | p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo); |
| 100248 | 100265 | } |
| 100249 | | - if( sqlite3WhereIsDistinct(pWInfo) ){ |
| 100266 | + if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){ |
| 100250 | 100267 | sDistinct.eTnctType = sqlite3WhereIsDistinct(pWInfo); |
| 100251 | 100268 | } |
| 100252 | 100269 | if( pOrderBy && sqlite3WhereIsOrdered(pWInfo) ) pOrderBy = 0; |
| 100253 | 100270 | |
| 100254 | 100271 | /* If sorting index that was created by a prior OP_OpenEphemeral |
| | @@ -104664,23 +104681,23 @@ |
| 104664 | 104681 | */ |
| 104665 | 104682 | struct WhereInfo { |
| 104666 | 104683 | Parse *pParse; /* Parsing and code generating context */ |
| 104667 | 104684 | SrcList *pTabList; /* List of tables in the join */ |
| 104668 | 104685 | ExprList *pOrderBy; /* The ORDER BY clause or NULL */ |
| 104669 | | - ExprList *pDistinct; /* DISTINCT ON values, or NULL */ |
| 104686 | + ExprList *pResultSet; /* Result set. DISTINCT operates on these */ |
| 104670 | 104687 | WhereLoop *pLoops; /* List of all WhereLoop objects */ |
| 104671 | 104688 | Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ |
| 104672 | 104689 | WhereCost nRowOut; /* Estimated number of output rows */ |
| 104673 | 104690 | u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ |
| 104674 | 104691 | u8 bOBSat; /* ORDER BY satisfied by indices */ |
| 104675 | 104692 | u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */ |
| 104676 | 104693 | u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */ |
| 104677 | 104694 | u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */ |
| 104695 | + u8 nLevel; /* Number of nested loop */ |
| 104678 | 104696 | int iTop; /* The very beginning of the WHERE loop */ |
| 104679 | 104697 | int iContinue; /* Jump here to continue with next record */ |
| 104680 | 104698 | int iBreak; /* Jump here to break out of the loop */ |
| 104681 | | - int nLevel; /* Number of nested loop */ |
| 104682 | 104699 | int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */ |
| 104683 | 104700 | WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */ |
| 104684 | 104701 | WhereClause sWC; /* Decomposition of the WHERE clause */ |
| 104685 | 104702 | WhereLevel a[1]; /* Information about each nest loop in WHERE */ |
| 104686 | 104703 | }; |
| | @@ -106690,13 +106707,14 @@ |
| 106690 | 106707 | z = (const u8 *)sqlite3_value_blob(pVal); |
| 106691 | 106708 | pColl = db->pDfltColl; |
| 106692 | 106709 | assert( pColl->enc==SQLITE_UTF8 ); |
| 106693 | 106710 | }else{ |
| 106694 | 106711 | pColl = sqlite3GetCollSeq(pParse, SQLITE_UTF8, 0, *pIdx->azColl); |
| 106695 | | - if( pColl==0 ){ |
| 106696 | | - return SQLITE_ERROR; |
| 106697 | | - } |
| 106712 | + /* If the collating sequence was unavailable, we should have failed |
| 106713 | + ** long ago and never reached this point. But we'll check just to |
| 106714 | + ** be doubly sure. */ |
| 106715 | + if( NEVER(pColl==0) ) return SQLITE_ERROR; |
| 106698 | 106716 | z = (const u8 *)sqlite3ValueText(pVal, pColl->enc); |
| 106699 | 106717 | if( !z ){ |
| 106700 | 106718 | return SQLITE_NOMEM; |
| 106701 | 106719 | } |
| 106702 | 106720 | assert( z && pColl && pColl->xCmp ); |
| | @@ -108208,13 +108226,13 @@ |
| 108208 | 108226 | */ |
| 108209 | 108227 | static void whereLoopPrint(WhereLoop *p, SrcList *pTabList){ |
| 108210 | 108228 | int nb = 1+(pTabList->nSrc+7)/8; |
| 108211 | 108229 | struct SrcList_item *pItem = pTabList->a + p->iTab; |
| 108212 | 108230 | Table *pTab = pItem->pTab; |
| 108213 | | - sqlite3DebugPrintf("%c %2d.%0*llx.%0*llx", p->cId, |
| 108231 | + sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, |
| 108214 | 108232 | p->iTab, nb, p->maskSelf, nb, p->prereq); |
| 108215 | | - sqlite3DebugPrintf(" %8s", |
| 108233 | + sqlite3DebugPrintf(" %12s", |
| 108216 | 108234 | pItem->zAlias ? pItem->zAlias : pTab->zName); |
| 108217 | 108235 | if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ |
| 108218 | 108236 | if( p->u.btree.pIndex ){ |
| 108219 | 108237 | const char *zName = p->u.btree.pIndex->zName; |
| 108220 | 108238 | if( zName==0 ) zName = "ipk"; |
| | @@ -108221,26 +108239,26 @@ |
| 108221 | 108239 | if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){ |
| 108222 | 108240 | int i = sqlite3Strlen30(zName) - 1; |
| 108223 | 108241 | while( zName[i]!='_' ) i--; |
| 108224 | 108242 | zName += i; |
| 108225 | 108243 | } |
| 108226 | | - sqlite3DebugPrintf(".%-12s %2d", zName, p->u.btree.nEq); |
| 108244 | + sqlite3DebugPrintf(".%-16s %2d", zName, p->u.btree.nEq); |
| 108227 | 108245 | }else{ |
| 108228 | | - sqlite3DebugPrintf("%16s",""); |
| 108246 | + sqlite3DebugPrintf("%20s",""); |
| 108229 | 108247 | } |
| 108230 | 108248 | }else{ |
| 108231 | 108249 | char *z; |
| 108232 | 108250 | if( p->u.vtab.idxStr ){ |
| 108233 | 108251 | z = sqlite3_mprintf("(%d,\"%s\",%x)", |
| 108234 | 108252 | p->u.vtab.idxNum, p->u.vtab.idxStr, p->u.vtab.omitMask); |
| 108235 | 108253 | }else{ |
| 108236 | 108254 | z = sqlite3_mprintf("(%d,%x)", p->u.vtab.idxNum, p->u.vtab.omitMask); |
| 108237 | 108255 | } |
| 108238 | | - sqlite3DebugPrintf(" %-15s", z); |
| 108256 | + sqlite3DebugPrintf(" %-19s", z); |
| 108239 | 108257 | sqlite3_free(z); |
| 108240 | 108258 | } |
| 108241 | | - sqlite3DebugPrintf(" fg %05x N %d", p->wsFlags, p->nLTerm); |
| 108259 | + sqlite3DebugPrintf(" f %04x N %d", p->wsFlags, p->nLTerm); |
| 108242 | 108260 | sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut); |
| 108243 | 108261 | } |
| 108244 | 108262 | #endif |
| 108245 | 108263 | |
| 108246 | 108264 | /* |
| | @@ -109650,16 +109668,17 @@ |
| 109650 | 109668 | WhereLevel *pLevel = pWInfo->a + iLoop; |
| 109651 | 109669 | pLevel->pWLoop = pWLoop = pFrom->aLoop[iLoop]; |
| 109652 | 109670 | pLevel->iFrom = pWLoop->iTab; |
| 109653 | 109671 | pLevel->iTabCur = pWInfo->pTabList->a[pLevel->iFrom].iCursor; |
| 109654 | 109672 | } |
| 109655 | | - if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY)==0 |
| 109656 | | - && pWInfo->pDistinct |
| 109673 | + if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)!=0 |
| 109674 | + && (pWInfo->wctrlFlags & WHERE_DISTINCTBY)==0 |
| 109675 | + && pWInfo->eDistinct==WHERE_DISTINCT_NOOP |
| 109657 | 109676 | && nRowEst |
| 109658 | 109677 | ){ |
| 109659 | 109678 | Bitmask notUsed; |
| 109660 | | - int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pDistinct, pFrom, |
| 109679 | + int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom, |
| 109661 | 109680 | WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], ¬Used); |
| 109662 | 109681 | if( rc==1 ) pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; |
| 109663 | 109682 | } |
| 109664 | 109683 | if( pFrom->isOrdered ){ |
| 109665 | 109684 | if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){ |
| | @@ -109744,11 +109763,13 @@ |
| 109744 | 109763 | pWInfo->a[0].pWLoop = pLoop; |
| 109745 | 109764 | pLoop->maskSelf = getMask(&pWInfo->sMaskSet, iCur); |
| 109746 | 109765 | pWInfo->a[0].iTabCur = iCur; |
| 109747 | 109766 | pWInfo->nRowOut = 1; |
| 109748 | 109767 | if( pWInfo->pOrderBy ) pWInfo->bOBSat = 1; |
| 109749 | | - if( pWInfo->pDistinct ) pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; |
| 109768 | + if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){ |
| 109769 | + pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; |
| 109770 | + } |
| 109750 | 109771 | #ifdef SQLITE_DEBUG |
| 109751 | 109772 | pLoop->cId = '0'; |
| 109752 | 109773 | #endif |
| 109753 | 109774 | return 1; |
| 109754 | 109775 | } |
| | @@ -109834,14 +109855,14 @@ |
| 109834 | 109855 | ** if there is one. If there is no ORDER BY clause or if this routine |
| 109835 | 109856 | ** is called from an UPDATE or DELETE statement, then pOrderBy is NULL. |
| 109836 | 109857 | */ |
| 109837 | 109858 | SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( |
| 109838 | 109859 | Parse *pParse, /* The parser context */ |
| 109839 | | - SrcList *pTabList, /* A list of all tables to be scanned */ |
| 109860 | + SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */ |
| 109840 | 109861 | Expr *pWhere, /* The WHERE clause */ |
| 109841 | 109862 | ExprList *pOrderBy, /* An ORDER BY clause, or NULL */ |
| 109842 | | - ExprList *pDistinct, /* The select-list for DISTINCT queries - or NULL */ |
| 109863 | + ExprList *pResultSet, /* Result set of the query */ |
| 109843 | 109864 | u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */ |
| 109844 | 109865 | int iIdxCur /* If WHERE_ONETABLE_ONLY is set, index cursor number */ |
| 109845 | 109866 | ){ |
| 109846 | 109867 | int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */ |
| 109847 | 109868 | int nTabList; /* Number of elements in pTabList */ |
| | @@ -109849,18 +109870,26 @@ |
| 109849 | 109870 | Vdbe *v = pParse->pVdbe; /* The virtual database engine */ |
| 109850 | 109871 | Bitmask notReady; /* Cursors that are not yet positioned */ |
| 109851 | 109872 | WhereLoopBuilder sWLB; /* The WhereLoop builder */ |
| 109852 | 109873 | WhereMaskSet *pMaskSet; /* The expression mask set */ |
| 109853 | 109874 | WhereLevel *pLevel; /* A single level in pWInfo->a[] */ |
| 109875 | + WhereLoop *pLoop; /* Pointer to a single WhereLoop object */ |
| 109854 | 109876 | int ii; /* Loop counter */ |
| 109855 | 109877 | sqlite3 *db; /* Database connection */ |
| 109856 | 109878 | int rc; /* Return code */ |
| 109857 | 109879 | |
| 109858 | 109880 | |
| 109859 | 109881 | /* Variable initialization */ |
| 109882 | + db = pParse->db; |
| 109860 | 109883 | memset(&sWLB, 0, sizeof(sWLB)); |
| 109861 | 109884 | sWLB.pOrderBy = pOrderBy; |
| 109885 | + |
| 109886 | + /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via |
| 109887 | + ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ |
| 109888 | + if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){ |
| 109889 | + wctrlFlags &= ~WHERE_WANT_DISTINCT; |
| 109890 | + } |
| 109862 | 109891 | |
| 109863 | 109892 | /* The number of tables in the FROM clause is limited by the number of |
| 109864 | 109893 | ** bits in a Bitmask |
| 109865 | 109894 | */ |
| 109866 | 109895 | testcase( pTabList->nSrc==BMS ); |
| | @@ -109881,11 +109910,10 @@ |
| 109881 | 109910 | ** struct, the contents of WhereInfo.a[], the WhereClause structure |
| 109882 | 109911 | ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte |
| 109883 | 109912 | ** field (type Bitmask) it must be aligned on an 8-byte boundary on |
| 109884 | 109913 | ** some architectures. Hence the ROUND8() below. |
| 109885 | 109914 | */ |
| 109886 | | - db = pParse->db; |
| 109887 | 109915 | nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel)); |
| 109888 | 109916 | pWInfo = sqlite3DbMallocZero(db, nByteWInfo + sizeof(WhereLoop)); |
| 109889 | 109917 | if( db->mallocFailed ){ |
| 109890 | 109918 | sqlite3DbFree(db, pWInfo); |
| 109891 | 109919 | pWInfo = 0; |
| | @@ -109893,11 +109921,11 @@ |
| 109893 | 109921 | } |
| 109894 | 109922 | pWInfo->nLevel = nTabList; |
| 109895 | 109923 | pWInfo->pParse = pParse; |
| 109896 | 109924 | pWInfo->pTabList = pTabList; |
| 109897 | 109925 | pWInfo->pOrderBy = pOrderBy; |
| 109898 | | - pWInfo->pDistinct = pDistinct; |
| 109926 | + pWInfo->pResultSet = pResultSet; |
| 109899 | 109927 | pWInfo->iBreak = sqlite3VdbeMakeLabel(v); |
| 109900 | 109928 | pWInfo->wctrlFlags = wctrlFlags; |
| 109901 | 109929 | pWInfo->savedNQueryLoop = pParse->nQueryLoop; |
| 109902 | 109930 | pMaskSet = &pWInfo->sMaskSet; |
| 109903 | 109931 | sWLB.pWInfo = pWInfo; |
| | @@ -109906,14 +109934,10 @@ |
| 109906 | 109934 | whereLoopInit(sWLB.pNew); |
| 109907 | 109935 | #ifdef SQLITE_DEBUG |
| 109908 | 109936 | sWLB.pNew->cId = '*'; |
| 109909 | 109937 | #endif |
| 109910 | 109938 | |
| 109911 | | - /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via |
| 109912 | | - ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ |
| 109913 | | - if( OptimizationDisabled(db, SQLITE_DistinctOpt) ) pDistinct = 0; |
| 109914 | | - |
| 109915 | 109939 | /* Split the WHERE clause into separate subexpressions where each |
| 109916 | 109940 | ** subexpression is separated by an AND operator. |
| 109917 | 109941 | */ |
| 109918 | 109942 | initMaskSet(pMaskSet); |
| 109919 | 109943 | whereClauseInit(&pWInfo->sWC, pWInfo); |
| | @@ -109930,11 +109954,13 @@ |
| 109930 | 109954 | |
| 109931 | 109955 | /* Special case: No FROM clause |
| 109932 | 109956 | */ |
| 109933 | 109957 | if( nTabList==0 ){ |
| 109934 | 109958 | if( pOrderBy ) pWInfo->bOBSat = 1; |
| 109935 | | - if( pDistinct ) pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; |
| 109959 | + if( wctrlFlags & WHERE_WANT_DISTINCT ){ |
| 109960 | + pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; |
| 109961 | + } |
| 109936 | 109962 | } |
| 109937 | 109963 | |
| 109938 | 109964 | /* Assign a bit from the bitmask to every term in the FROM clause. |
| 109939 | 109965 | ** |
| 109940 | 109966 | ** When assigning bitmask values to FROM clause cursors, it must be |
| | @@ -109977,11 +110003,11 @@ |
| 109977 | 110003 | |
| 109978 | 110004 | /* If the ORDER BY (or GROUP BY) clause contains references to general |
| 109979 | 110005 | ** expressions, then we won't be able to satisfy it using indices, so |
| 109980 | 110006 | ** go ahead and disable it now. |
| 109981 | 110007 | */ |
| 109982 | | - if( pOrderBy && pDistinct ){ |
| 110008 | + if( pOrderBy && (wctrlFlags & WHERE_WANT_DISTINCT)!=0 ){ |
| 109983 | 110009 | for(ii=0; ii<pOrderBy->nExpr; ii++){ |
| 109984 | 110010 | Expr *pExpr = sqlite3ExprSkipCollate(pOrderBy->a[ii].pExpr); |
| 109985 | 110011 | if( pExpr->op!=TK_COLUMN ){ |
| 109986 | 110012 | pWInfo->pOrderBy = pOrderBy = 0; |
| 109987 | 110013 | break; |
| | @@ -109989,21 +110015,18 @@ |
| 109989 | 110015 | break; |
| 109990 | 110016 | } |
| 109991 | 110017 | } |
| 109992 | 110018 | } |
| 109993 | 110019 | |
| 109994 | | - /* Check if the DISTINCT qualifier, if there is one, is redundant. |
| 109995 | | - ** If it is, then set pDistinct to NULL and WhereInfo.eDistinct to |
| 109996 | | - ** WHERE_DISTINCT_UNIQUE to tell the caller to ignore the DISTINCT. |
| 109997 | | - */ |
| 109998 | | - if( pDistinct ){ |
| 109999 | | - if( isDistinctRedundant(pParse,pTabList,&pWInfo->sWC,pDistinct) ){ |
| 110000 | | - pDistinct = 0; |
| 110020 | + if( wctrlFlags & WHERE_WANT_DISTINCT ){ |
| 110021 | + if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){ |
| 110022 | + /* The DISTINCT marking is pointless. Ignore it. */ |
| 110001 | 110023 | pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; |
| 110002 | 110024 | }else if( pOrderBy==0 ){ |
| 110025 | + /* Try to ORDER BY the result set to make distinct processing easier */ |
| 110003 | 110026 | pWInfo->wctrlFlags |= WHERE_DISTINCTBY; |
| 110004 | | - pWInfo->pOrderBy = pDistinct; |
| 110027 | + pWInfo->pOrderBy = pResultSet; |
| 110005 | 110028 | } |
| 110006 | 110029 | } |
| 110007 | 110030 | |
| 110008 | 110031 | /* Construct the WhereLoop objects */ |
| 110009 | 110032 | WHERETRACE(0xffff,("*** Optimizer Start ***\n")); |
| | @@ -110013,15 +110036,15 @@ |
| 110013 | 110036 | |
| 110014 | 110037 | /* Display all of the WhereLoop objects if wheretrace is enabled */ |
| 110015 | 110038 | #ifdef WHERETRACE_ENABLED |
| 110016 | 110039 | if( sqlite3WhereTrace ){ |
| 110017 | 110040 | WhereLoop *p; |
| 110018 | | - int i = 0; |
| 110041 | + int i; |
| 110019 | 110042 | static char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz" |
| 110020 | 110043 | "ABCDEFGHIJKLMNOPQRSTUVWYXZ"; |
| 110021 | | - for(p=pWInfo->pLoops; p; p=p->pNextLoop){ |
| 110022 | | - p->cId = zLabel[(i++)%sizeof(zLabel)]; |
| 110044 | + for(p=pWInfo->pLoops, i=0; p; p=p->pNextLoop, i++){ |
| 110045 | + p->cId = zLabel[i%sizeof(zLabel)]; |
| 110023 | 110046 | whereLoopPrint(p, pTabList); |
| 110024 | 110047 | } |
| 110025 | 110048 | } |
| 110026 | 110049 | #endif |
| 110027 | 110050 | |
| | @@ -110058,15 +110081,36 @@ |
| 110058 | 110081 | sqlite3DebugPrintf(" DISTINCT=unordered"); |
| 110059 | 110082 | break; |
| 110060 | 110083 | } |
| 110061 | 110084 | } |
| 110062 | 110085 | sqlite3DebugPrintf("\n"); |
| 110063 | | - for(ii=0; ii<nTabList; ii++){ |
| 110086 | + for(ii=0; ii<pWInfo->nLevel; ii++){ |
| 110064 | 110087 | whereLoopPrint(pWInfo->a[ii].pWLoop, pTabList); |
| 110065 | 110088 | } |
| 110066 | 110089 | } |
| 110067 | 110090 | #endif |
| 110091 | + /* Attempt to omit tables from the join that do not effect the result */ |
| 110092 | + if( pWInfo->nLevel>=2 |
| 110093 | + && pResultSet!=0 |
| 110094 | + && OptimizationEnabled(db, SQLITE_OmitNoopJoin) |
| 110095 | + ){ |
| 110096 | + Bitmask tabUsed = exprListTableUsage(pMaskSet, pResultSet); |
| 110097 | + if( pOrderBy ) tabUsed |= exprListTableUsage(pMaskSet, pOrderBy); |
| 110098 | + while( pWInfo->nLevel>=2 ){ |
| 110099 | + pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop; |
| 110100 | + if( (pWInfo->pTabList->a[pLoop->iTab].jointype & JT_LEFT)==0 ) break; |
| 110101 | + if( (wctrlFlags & WHERE_WANT_DISTINCT)==0 |
| 110102 | + && (pLoop->wsFlags & WHERE_ONEROW)==0 |
| 110103 | + ){ |
| 110104 | + break; |
| 110105 | + } |
| 110106 | + if( (tabUsed & pLoop->maskSelf)!=0 ) break; |
| 110107 | + WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId)); |
| 110108 | + pWInfo->nLevel--; |
| 110109 | + nTabList--; |
| 110110 | + } |
| 110111 | + } |
| 110068 | 110112 | WHERETRACE(0xffff,("*** Optimizer Finished ***\n")); |
| 110069 | 110113 | pWInfo->pParse->nQueryLoop += pWInfo->nRowOut; |
| 110070 | 110114 | |
| 110071 | 110115 | /* If the caller is an UPDATE or DELETE statement that is requesting |
| 110072 | 110116 | ** to use a one-pass algorithm, determine if this is appropriate. |
| | @@ -110231,11 +110275,11 @@ |
| 110231 | 110275 | */ |
| 110232 | 110276 | sqlite3VdbeResolveLabel(v, pWInfo->iBreak); |
| 110233 | 110277 | |
| 110234 | 110278 | /* Close all of the cursors that were opened by sqlite3WhereBegin. |
| 110235 | 110279 | */ |
| 110236 | | - assert( pWInfo->nLevel==1 || pWInfo->nLevel==pTabList->nSrc ); |
| 110280 | + assert( pWInfo->nLevel<=pTabList->nSrc ); |
| 110237 | 110281 | for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){ |
| 110238 | 110282 | Index *pIdx = 0; |
| 110239 | 110283 | struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom]; |
| 110240 | 110284 | Table *pTab = pTabItem->pTab; |
| 110241 | 110285 | assert( pTab!=0 ); |
| | @@ -119407,10 +119451,11 @@ |
| 119407 | 119451 | sqlite3 *db; /* The database connection */ |
| 119408 | 119452 | const char *zDb; /* logical database name */ |
| 119409 | 119453 | const char *zName; /* virtual table name */ |
| 119410 | 119454 | int nColumn; /* number of named columns in virtual table */ |
| 119411 | 119455 | char **azColumn; /* column names. malloced */ |
| 119456 | + u8 *abNotindexed; /* True for 'notindexed' columns */ |
| 119412 | 119457 | sqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */ |
| 119413 | 119458 | char *zContentTbl; /* content=xxx option, or NULL */ |
| 119414 | 119459 | char *zLanguageid; /* languageid=xxx option, or NULL */ |
| 119415 | 119460 | u8 bAutoincrmerge; /* True if automerge=1 */ |
| 119416 | 119461 | u32 nLeafAdd; /* Number of leaf blocks added this trans */ |
| | @@ -119634,11 +119679,10 @@ |
| 119634 | 119679 | sqlite3_int64, sqlite3_int64, const char *, int, Fts3SegReader**); |
| 119635 | 119680 | SQLITE_PRIVATE int sqlite3Fts3SegReaderPending( |
| 119636 | 119681 | Fts3Table*,int,const char*,int,int,Fts3SegReader**); |
| 119637 | 119682 | SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *); |
| 119638 | 119683 | SQLITE_PRIVATE int sqlite3Fts3AllSegdirs(Fts3Table*, int, int, int, sqlite3_stmt **); |
| 119639 | | -SQLITE_PRIVATE int sqlite3Fts3ReadLock(Fts3Table *); |
| 119640 | 119684 | SQLITE_PRIVATE int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char **, int*, int*); |
| 119641 | 119685 | |
| 119642 | 119686 | SQLITE_PRIVATE int sqlite3Fts3SelectDoctotal(Fts3Table *, sqlite3_stmt **); |
| 119643 | 119687 | SQLITE_PRIVATE int sqlite3Fts3SelectDocsize(Fts3Table *, sqlite3_int64, sqlite3_stmt **); |
| 119644 | 119688 | |
| | @@ -120567,22 +120611,34 @@ |
| 120567 | 120611 | char *zPrefix = 0; /* Prefix parameter value (or NULL) */ |
| 120568 | 120612 | char *zCompress = 0; /* compress=? parameter (or NULL) */ |
| 120569 | 120613 | char *zUncompress = 0; /* uncompress=? parameter (or NULL) */ |
| 120570 | 120614 | char *zContent = 0; /* content=? parameter (or NULL) */ |
| 120571 | 120615 | char *zLanguageid = 0; /* languageid=? parameter (or NULL) */ |
| 120616 | + char **azNotindexed = 0; /* The set of notindexed= columns */ |
| 120617 | + int nNotindexed = 0; /* Size of azNotindexed[] array */ |
| 120572 | 120618 | |
| 120573 | 120619 | assert( strlen(argv[0])==4 ); |
| 120574 | 120620 | assert( (sqlite3_strnicmp(argv[0], "fts4", 4)==0 && isFts4) |
| 120575 | 120621 | || (sqlite3_strnicmp(argv[0], "fts3", 4)==0 && !isFts4) |
| 120576 | 120622 | ); |
| 120577 | 120623 | |
| 120578 | 120624 | nDb = (int)strlen(argv[1]) + 1; |
| 120579 | 120625 | nName = (int)strlen(argv[2]) + 1; |
| 120580 | 120626 | |
| 120581 | | - aCol = (const char **)sqlite3_malloc(sizeof(const char *) * (argc-2) ); |
| 120582 | | - if( !aCol ) return SQLITE_NOMEM; |
| 120583 | | - memset((void *)aCol, 0, sizeof(const char *) * (argc-2)); |
| 120627 | + nByte = sizeof(const char *) * (argc-2); |
| 120628 | + aCol = (const char **)sqlite3_malloc(nByte); |
| 120629 | + if( aCol ){ |
| 120630 | + memset(aCol, 0, nByte); |
| 120631 | + azNotindexed = (char **)sqlite3_malloc(nByte); |
| 120632 | + } |
| 120633 | + if( azNotindexed ){ |
| 120634 | + memset(azNotindexed, 0, nByte); |
| 120635 | + } |
| 120636 | + if( !aCol || !azNotindexed ){ |
| 120637 | + rc = SQLITE_NOMEM; |
| 120638 | + goto fts3_init_out; |
| 120639 | + } |
| 120584 | 120640 | |
| 120585 | 120641 | /* Loop through all of the arguments passed by the user to the FTS3/4 |
| 120586 | 120642 | ** module (i.e. all the column names and special arguments). This loop |
| 120587 | 120643 | ** does the following: |
| 120588 | 120644 | ** |
| | @@ -120617,11 +120673,12 @@ |
| 120617 | 120673 | { "prefix", 6 }, /* 1 -> PREFIX */ |
| 120618 | 120674 | { "compress", 8 }, /* 2 -> COMPRESS */ |
| 120619 | 120675 | { "uncompress", 10 }, /* 3 -> UNCOMPRESS */ |
| 120620 | 120676 | { "order", 5 }, /* 4 -> ORDER */ |
| 120621 | 120677 | { "content", 7 }, /* 5 -> CONTENT */ |
| 120622 | | - { "languageid", 10 } /* 6 -> LANGUAGEID */ |
| 120678 | + { "languageid", 10 }, /* 6 -> LANGUAGEID */ |
| 120679 | + { "notindexed", 10 } /* 7 -> NOTINDEXED */ |
| 120623 | 120680 | }; |
| 120624 | 120681 | |
| 120625 | 120682 | int iOpt; |
| 120626 | 120683 | if( !zVal ){ |
| 120627 | 120684 | rc = SQLITE_NOMEM; |
| | @@ -120683,10 +120740,15 @@ |
| 120683 | 120740 | assert( iOpt==6 ); |
| 120684 | 120741 | sqlite3_free(zLanguageid); |
| 120685 | 120742 | zLanguageid = zVal; |
| 120686 | 120743 | zVal = 0; |
| 120687 | 120744 | break; |
| 120745 | + |
| 120746 | + case 7: /* NOTINDEXED */ |
| 120747 | + azNotindexed[nNotindexed++] = zVal; |
| 120748 | + zVal = 0; |
| 120749 | + break; |
| 120688 | 120750 | } |
| 120689 | 120751 | } |
| 120690 | 120752 | sqlite3_free(zVal); |
| 120691 | 120753 | } |
| 120692 | 120754 | } |
| | @@ -120754,10 +120816,11 @@ |
| 120754 | 120816 | |
| 120755 | 120817 | /* Allocate and populate the Fts3Table structure. */ |
| 120756 | 120818 | nByte = sizeof(Fts3Table) + /* Fts3Table */ |
| 120757 | 120819 | nCol * sizeof(char *) + /* azColumn */ |
| 120758 | 120820 | nIndex * sizeof(struct Fts3Index) + /* aIndex */ |
| 120821 | + nCol * sizeof(u8) + /* abNotindexed */ |
| 120759 | 120822 | nName + /* zName */ |
| 120760 | 120823 | nDb + /* zDb */ |
| 120761 | 120824 | nString; /* Space for azColumn strings */ |
| 120762 | 120825 | p = (Fts3Table*)sqlite3_malloc(nByte); |
| 120763 | 120826 | if( p==0 ){ |
| | @@ -120787,13 +120850,14 @@ |
| 120787 | 120850 | memcpy(p->aIndex, aIndex, sizeof(struct Fts3Index) * nIndex); |
| 120788 | 120851 | p->nIndex = nIndex; |
| 120789 | 120852 | for(i=0; i<nIndex; i++){ |
| 120790 | 120853 | fts3HashInit(&p->aIndex[i].hPending, FTS3_HASH_STRING, 1); |
| 120791 | 120854 | } |
| 120855 | + p->abNotindexed = (u8 *)&p->aIndex[nIndex]; |
| 120792 | 120856 | |
| 120793 | 120857 | /* Fill in the zName and zDb fields of the vtab structure. */ |
| 120794 | | - zCsr = (char *)&p->aIndex[nIndex]; |
| 120858 | + zCsr = (char *)&p->abNotindexed[nCol]; |
| 120795 | 120859 | p->zName = zCsr; |
| 120796 | 120860 | memcpy(zCsr, argv[2], nName); |
| 120797 | 120861 | zCsr += nName; |
| 120798 | 120862 | p->zDb = zCsr; |
| 120799 | 120863 | memcpy(zCsr, argv[1], nDb); |
| | @@ -120810,11 +120874,30 @@ |
| 120810 | 120874 | p->azColumn[iCol] = zCsr; |
| 120811 | 120875 | zCsr += n+1; |
| 120812 | 120876 | assert( zCsr <= &((char *)p)[nByte] ); |
| 120813 | 120877 | } |
| 120814 | 120878 | |
| 120815 | | - if( (zCompress==0)!=(zUncompress==0) ){ |
| 120879 | + /* Fill in the abNotindexed array */ |
| 120880 | + for(iCol=0; iCol<nCol; iCol++){ |
| 120881 | + int n = strlen(p->azColumn[iCol]); |
| 120882 | + for(i=0; i<nNotindexed; i++){ |
| 120883 | + char *zNot = azNotindexed[i]; |
| 120884 | + if( zNot && 0==sqlite3_strnicmp(p->azColumn[iCol], zNot, n) ){ |
| 120885 | + p->abNotindexed[iCol] = 1; |
| 120886 | + sqlite3_free(zNot); |
| 120887 | + azNotindexed[i] = 0; |
| 120888 | + } |
| 120889 | + } |
| 120890 | + } |
| 120891 | + for(i=0; i<nNotindexed; i++){ |
| 120892 | + if( azNotindexed[i] ){ |
| 120893 | + *pzErr = sqlite3_mprintf("no such column: %s", azNotindexed[i]); |
| 120894 | + rc = SQLITE_ERROR; |
| 120895 | + } |
| 120896 | + } |
| 120897 | + |
| 120898 | + if( rc==SQLITE_OK && (zCompress==0)!=(zUncompress==0) ){ |
| 120816 | 120899 | char const *zMiss = (zCompress==0 ? "compress" : "uncompress"); |
| 120817 | 120900 | rc = SQLITE_ERROR; |
| 120818 | 120901 | *pzErr = sqlite3_mprintf("missing %s parameter in fts4 constructor", zMiss); |
| 120819 | 120902 | } |
| 120820 | 120903 | p->zReadExprlist = fts3ReadExprList(p, zUncompress, &rc); |
| | @@ -120851,11 +120934,13 @@ |
| 120851 | 120934 | sqlite3_free(aIndex); |
| 120852 | 120935 | sqlite3_free(zCompress); |
| 120853 | 120936 | sqlite3_free(zUncompress); |
| 120854 | 120937 | sqlite3_free(zContent); |
| 120855 | 120938 | sqlite3_free(zLanguageid); |
| 120939 | + for(i=0; i<nNotindexed; i++) sqlite3_free(azNotindexed[i]); |
| 120856 | 120940 | sqlite3_free((void *)aCol); |
| 120941 | + sqlite3_free((void *)azNotindexed); |
| 120857 | 120942 | if( rc!=SQLITE_OK ){ |
| 120858 | 120943 | if( p ){ |
| 120859 | 120944 | fts3DisconnectMethod((sqlite3_vtab *)p); |
| 120860 | 120945 | }else if( pTokenizer ){ |
| 120861 | 120946 | pTokenizer->pModule->xDestroy(pTokenizer); |
| | @@ -129717,16 +129802,19 @@ |
| 129717 | 129802 | sqlite3_value **apVal, |
| 129718 | 129803 | u32 *aSz |
| 129719 | 129804 | ){ |
| 129720 | 129805 | int i; /* Iterator variable */ |
| 129721 | 129806 | for(i=2; i<p->nColumn+2; i++){ |
| 129722 | | - const char *zText = (const char *)sqlite3_value_text(apVal[i]); |
| 129723 | | - int rc = fts3PendingTermsAdd(p, iLangid, zText, i-2, &aSz[i-2]); |
| 129724 | | - if( rc!=SQLITE_OK ){ |
| 129725 | | - return rc; |
| 129807 | + int iCol = i-2; |
| 129808 | + if( p->abNotindexed[iCol]==0 ){ |
| 129809 | + const char *zText = (const char *)sqlite3_value_text(apVal[i]); |
| 129810 | + int rc = fts3PendingTermsAdd(p, iLangid, zText, iCol, &aSz[iCol]); |
| 129811 | + if( rc!=SQLITE_OK ){ |
| 129812 | + return rc; |
| 129813 | + } |
| 129814 | + aSz[p->nColumn] += sqlite3_value_bytes(apVal[i]); |
| 129726 | 129815 | } |
| 129727 | | - aSz[p->nColumn] += sqlite3_value_bytes(apVal[i]); |
| 129728 | 129816 | } |
| 129729 | 129817 | return SQLITE_OK; |
| 129730 | 129818 | } |
| 129731 | 129819 | |
| 129732 | 129820 | /* |
| | @@ -129869,13 +129957,16 @@ |
| 129869 | 129957 | if( SQLITE_ROW==sqlite3_step(pSelect) ){ |
| 129870 | 129958 | int i; |
| 129871 | 129959 | int iLangid = langidFromSelect(p, pSelect); |
| 129872 | 129960 | rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pSelect, 0)); |
| 129873 | 129961 | for(i=1; rc==SQLITE_OK && i<=p->nColumn; i++){ |
| 129874 | | - const char *zText = (const char *)sqlite3_column_text(pSelect, i); |
| 129875 | | - rc = fts3PendingTermsAdd(p, iLangid, zText, -1, &aSz[i-1]); |
| 129876 | | - aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i); |
| 129962 | + int iCol = i-1; |
| 129963 | + if( p->abNotindexed[iCol]==0 ){ |
| 129964 | + const char *zText = (const char *)sqlite3_column_text(pSelect, i); |
| 129965 | + rc = fts3PendingTermsAdd(p, iLangid, zText, -1, &aSz[iCol]); |
| 129966 | + aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i); |
| 129967 | + } |
| 129877 | 129968 | } |
| 129878 | 129969 | if( rc!=SQLITE_OK ){ |
| 129879 | 129970 | sqlite3_reset(pSelect); |
| 129880 | 129971 | *pRC = rc; |
| 129881 | 129972 | return; |
| | @@ -132113,13 +132204,15 @@ |
| 132113 | 132204 | int iCol; |
| 132114 | 132205 | int iLangid = langidFromSelect(p, pStmt); |
| 132115 | 132206 | rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pStmt, 0)); |
| 132116 | 132207 | memset(aSz, 0, sizeof(aSz[0]) * (p->nColumn+1)); |
| 132117 | 132208 | for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){ |
| 132118 | | - const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1); |
| 132119 | | - rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]); |
| 132120 | | - aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1); |
| 132209 | + if( p->abNotindexed[iCol]==0 ){ |
| 132210 | + const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1); |
| 132211 | + rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]); |
| 132212 | + aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1); |
| 132213 | + } |
| 132121 | 132214 | } |
| 132122 | 132215 | if( p->bHasDocsize ){ |
| 132123 | 132216 | fts3InsertDocsize(&rc, p, aSz); |
| 132124 | 132217 | } |
| 132125 | 132218 | if( rc!=SQLITE_OK ){ |
| | @@ -133918,39 +134011,41 @@ |
| 133918 | 134011 | |
| 133919 | 134012 | assert( pCsr->isRequireSeek==0 ); |
| 133920 | 134013 | iDocid = sqlite3_column_int64(pCsr->pStmt, 0); |
| 133921 | 134014 | |
| 133922 | 134015 | for(i=0; i<p->nColumn && rc==SQLITE_OK; i++){ |
| 133923 | | - const char *zText = (const char *)sqlite3_column_text(pCsr->pStmt, i+1); |
| 133924 | | - sqlite3_tokenizer_cursor *pTC = 0; |
| 133925 | | - |
| 133926 | | - rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC); |
| 133927 | | - while( rc==SQLITE_OK ){ |
| 133928 | | - char const *zToken; /* Buffer containing token */ |
| 133929 | | - int nToken = 0; /* Number of bytes in token */ |
| 133930 | | - int iDum1 = 0, iDum2 = 0; /* Dummy variables */ |
| 133931 | | - int iPos = 0; /* Position of token in zText */ |
| 133932 | | - |
| 133933 | | - rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos); |
| 133934 | | - for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ |
| 133935 | | - Fts3PhraseToken *pPT = pDef->pToken; |
| 133936 | | - if( (pDef->iCol>=p->nColumn || pDef->iCol==i) |
| 133937 | | - && (pPT->bFirst==0 || iPos==0) |
| 133938 | | - && (pPT->n==nToken || (pPT->isPrefix && pPT->n<nToken)) |
| 133939 | | - && (0==memcmp(zToken, pPT->z, pPT->n)) |
| 133940 | | - ){ |
| 133941 | | - fts3PendingListAppend(&pDef->pList, iDocid, i, iPos, &rc); |
| 133942 | | - } |
| 133943 | | - } |
| 133944 | | - } |
| 133945 | | - if( pTC ) pModule->xClose(pTC); |
| 133946 | | - if( rc==SQLITE_DONE ) rc = SQLITE_OK; |
| 133947 | | - } |
| 133948 | | - |
| 133949 | | - for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ |
| 133950 | | - if( pDef->pList ){ |
| 133951 | | - rc = fts3PendingListAppendVarint(&pDef->pList, 0); |
| 134016 | + if( p->abNotindexed[i]==0 ){ |
| 134017 | + const char *zText = (const char *)sqlite3_column_text(pCsr->pStmt, i+1); |
| 134018 | + sqlite3_tokenizer_cursor *pTC = 0; |
| 134019 | + |
| 134020 | + rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC); |
| 134021 | + while( rc==SQLITE_OK ){ |
| 134022 | + char const *zToken; /* Buffer containing token */ |
| 134023 | + int nToken = 0; /* Number of bytes in token */ |
| 134024 | + int iDum1 = 0, iDum2 = 0; /* Dummy variables */ |
| 134025 | + int iPos = 0; /* Position of token in zText */ |
| 134026 | + |
| 134027 | + rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos); |
| 134028 | + for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ |
| 134029 | + Fts3PhraseToken *pPT = pDef->pToken; |
| 134030 | + if( (pDef->iCol>=p->nColumn || pDef->iCol==i) |
| 134031 | + && (pPT->bFirst==0 || iPos==0) |
| 134032 | + && (pPT->n==nToken || (pPT->isPrefix && pPT->n<nToken)) |
| 134033 | + && (0==memcmp(zToken, pPT->z, pPT->n)) |
| 134034 | + ){ |
| 134035 | + fts3PendingListAppend(&pDef->pList, iDocid, i, iPos, &rc); |
| 134036 | + } |
| 134037 | + } |
| 134038 | + } |
| 134039 | + if( pTC ) pModule->xClose(pTC); |
| 134040 | + if( rc==SQLITE_DONE ) rc = SQLITE_OK; |
| 134041 | + } |
| 134042 | + |
| 134043 | + for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ |
| 134044 | + if( pDef->pList ){ |
| 134045 | + rc = fts3PendingListAppendVarint(&pDef->pList, 0); |
| 134046 | + } |
| 133952 | 134047 | } |
| 133953 | 134048 | } |
| 133954 | 134049 | } |
| 133955 | 134050 | |
| 133956 | 134051 | return rc; |
| 133957 | 134052 | |