From: drh Date: Wed, 12 Jun 2013 17:17:45 +0000 (+0000) Subject: Merge all changes from trunk. X-Git-Tag: version-3.8.0~130^2~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=37ca04880acc62cc57c3366341ac8596840b52b7;p=thirdparty%2Fsqlite.git Merge all changes from trunk. FossilOrigin-Name: f2e15b1974e55373b5819e3b2326653f890f409f --- 37ca04880acc62cc57c3366341ac8596840b52b7 diff --cc manifest index 8b92ace178,dbb20a50de..4944aabb1c --- a/manifest +++ b/manifest @@@ -1,5 -1,5 +1,5 @@@ - C "make\stest"\snow\spassing. - D 2013-06-12T17:08:06.018 -C Add\sthe\sSQLITE_FTS3_MAX_EXPR_DEPTH\scompile\stime\soption. -D 2013-06-11T14:22:11.456 ++C Merge\sall\schanges\sfrom\strunk. ++D 2013-06-12T17:17:45.907 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@@ -78,11 -78,11 +78,11 @@@ F ext/fts3/README.content fdc666a70d525 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c 931b3c83abdd1ab3bb389b2130431c2a9ff73b91 +F ext/fts3/fts3.c 760fecd100598dc22f9733d472b7cf2e9375c620 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe - F ext/fts3/fts3Int.h 0b167bed9e63151635620a4f639bc62ac6012cba + F ext/fts3/fts3Int.h cb4df04cf886d9920a71df9e8faaa5aae2fa48c6 F ext/fts3/fts3_aux.c b02632f6dd0e375ce97870206d914ea6d8df5ccd - F ext/fts3/fts3_expr.c 193d6fc156d744ab548a2ed06c31869e54dac739 + F ext/fts3/fts3_expr.c f8eb1046063ba342c7114eba175cabb31c4a64e7 F ext/fts3/fts3_hash.c 8dd2d06b66c72c628c2732555a32bc0943114914 F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf F ext/fts3/fts3_icu.c e319e108661147bcca8dd511cd562f33a1ba81b5 @@@ -165,7 -165,7 +165,7 @@@ F src/btmutex.c 976f45a12e37293e32cae02 F src/btree.c 7fba377c29573adfc6091832e27ee1fcbefb51d0 F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2 - F src/build.c 838cbdcbf18de2fd5723ad5864a78cc806f6c75b -F src/build.c 1ecf68522356a90471b07178e186277090d0b027 ++F src/build.c eadda12ec0cae14dcdc13e97fd9a3fd2f02e9e8f F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267 @@@ -289,7 -289,7 +289,7 @@@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb F src/wal.c 436bfceb141b9423c45119e68e444358ee0ed35d F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73 - F src/where.c 58522e12fcb559ac138d1cf51348b6861345968e -F src/where.c 5c4cbc1e5205d8d534c483fa4495c81513b45dea ++F src/where.c 97f5d9c3a9dfa802d91f7723cd1d782a3ce78e7a F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@@ -359,14 -359,14 +359,14 @@@ F test/capi3.test 56ab450125ead38846cba F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 F test/capi3c.test 93d24621c9ff84da9da060f30431e0453db1cdb0 F test/capi3d.test 17b57ca28be3e37e14c2ba8f787d292d84b724a1 -F test/capi3e.test f7408dda65c92b9056199fdc180f893015f83dde +F test/capi3e.test ad90088b18b0367125ff2d4b5400153fd2f99aab F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 F test/check.test 2eb93611139a7dfaed3be80067c7dc5ceb5fb287 -F test/close.test e37610d60e9c9b9979a981f3f50071d7dff28616 +F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815 F test/closure01.test dbb28f1ea9eeaf0a53ec5bc0fed352e479def8c7 F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 - F test/collate1.test fd02c4d8afc71879c4bb952586389961a21fb0ce + F test/collate1.test b709989e6e6ff6e1d2bd64231c2c1d8146846c9e -F test/collate2.test 04cebe4a033be319d6ddbb3bbc69464e01700b49 +F test/collate2.test 285cef1b58ce2b3cf074a386f763ce753c81c97f F test/collate3.test 79558a286362cb9ed603c6fa543f1cda7f563f0f F test/collate4.test 031f7265c13308b724ba3c49f41cc04612bd92b1 F test/collate5.test 65d928034d30d2d263a80f6359f7549ee1598ec6 @@@ -1093,9 -1092,8 +1093,9 @@@ F tool/tostr.awk e75472c2f98dd76e06b8c9 F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 +F tool/wherecosttest.c 4d0393bdbe7230adb712e925863744dd2b7ffc5b F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac - P 25e2cde105a19293bdb9c001b48624e5d7f8c4e5 - R 74299348f4ebeefec70a5406f9e251d7 -P 7e3820e5b989426c64af46f6bf862b91366ae954 -R 5f94a46cd24d5603b852ca86ea7eaf5a -U dan -Z 30f6897d1a48f4a9b1a79c1749e033ce ++P addd7f466d6ff55f82d907286650c26b06e9397b 24fc9d4438a5615dd20af5419456166df83a72ea ++R 400236daf5743c1455f090bd73116cba +U drh - Z ad22135d0c0bd81f6331e3b3327b23e1 ++Z eafccaa2bb28a08ba2c2409a2846f8df diff --cc manifest.uuid index 16f0323d65,87e2685a16..9a98bfb402 --- a/manifest.uuid +++ b/manifest.uuid @@@ -1,1 -1,1 +1,1 @@@ - addd7f466d6ff55f82d907286650c26b06e9397b -24fc9d4438a5615dd20af5419456166df83a72ea ++f2e15b1974e55373b5819e3b2326653f890f409f diff --cc src/where.c index 9886d4e214,e614f4a6d8..abf4ebf56e --- a/src/where.c +++ b/src/where.c @@@ -39,114 -38,7 +39,114 @@@ typedef struct WhereClause WhereClause typedef struct WhereMaskSet WhereMaskSet; typedef struct WhereOrInfo WhereOrInfo; typedef struct WhereAndInfo WhereAndInfo; -typedef struct WhereCost WhereCost; +typedef struct WhereLevel WhereLevel; +typedef struct WhereLoop WhereLoop; +typedef struct WherePath WherePath; +typedef struct WhereTerm WhereTerm; +typedef struct WhereLoopBuilder WhereLoopBuilder; +typedef struct WhereScan WhereScan; + +/* +** Cost X is tracked as 10*log2(X) stored in a 16-bit integer. The +** maximum cost is 64*(2**63) which becomes 6900. So all costs can be +** be stored in a 16-bit unsigned integer without risk of overflow. +*/ +typedef unsigned short int WhereCost; + +/* +** For each nested loop in a WHERE clause implementation, the WhereInfo +** structure contains a single instance of this structure. This structure +** is intended to be private to the where.c module and should not be +** access or modified by other modules. +** +** The pIdxInfo field is used to help pick the best index on a +** virtual table. The pIdxInfo pointer contains indexing +** information for the i-th table in the FROM clause before reordering. +** All the pIdxInfo pointers are freed by whereInfoFree() in where.c. +** All other information in the i-th WhereLevel object for the i-th table +** after FROM clause ordering. +*/ +struct WhereLevel { + int iLeftJoin; /* Memory cell used to implement LEFT OUTER JOIN */ + int iTabCur; /* The VDBE cursor used to access the table */ + int iIdxCur; /* The VDBE cursor used to access pIdx */ + int addrBrk; /* Jump here to break out of the loop */ + int addrNxt; /* Jump here to start the next IN combination */ + int addrCont; /* Jump here to continue with the next loop cycle */ + int addrFirst; /* First instruction of interior of the loop */ + u8 iFrom; /* Which entry in the FROM clause */ + u8 op, p5; /* Opcode and P5 of the opcode that ends the loop */ + int p1, p2; /* Operands of the opcode used to ends the loop */ - union { /* Information that depends on plan.wsFlags */ ++ union { /* Information that depends on pWLoop->wsFlags */ + struct { + int nIn; /* Number of entries in aInLoop[] */ + struct InLoop { + int iCur; /* The VDBE cursor used by this IN operator */ + int addrInTop; /* Top of the IN loop */ + u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */ + } *aInLoop; /* Information about each nested IN operator */ - } in; /* Used when plan.wsFlags&WHERE_IN_ABLE */ ++ } in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */ + Index *pCovidx; /* Possible covering index for WHERE_MULTI_OR */ + } u; + struct WhereLoop *pWLoop; /* The selected WhereLoop object */ +}; + +/* +** Each instance of this object represents a way of evaluating one +** term of a join. The WhereClause object holds a table of these +** objects using (maskSelf,prereq,) as the primary key. Note that the +** same join term might have multiple associated WhereLoop objects. +*/ +struct WhereLoop { + Bitmask prereq; /* Bitmask of other loops that must run first */ + Bitmask maskSelf; /* Bitmask identifying table iTab */ +#ifdef SQLITE_DEBUG + char cId; /* Symbolic ID of this loop for debugging use */ +#endif + u8 iTab; /* Position in FROM clause of table for this loop */ + u8 iSortIdx; /* Sorting index number. 0==None */ + WhereCost rSetup; /* One-time setup cost (ex: create transient index) */ + WhereCost rRun; /* Cost of running each loop */ + WhereCost nOut; /* Estimated number of output rows */ + union { + struct { /* Information for internal btree tables */ + int nEq; /* Number of equality constraints */ + Index *pIndex; /* Index used, or NULL */ + } btree; + struct { /* Information for virtual tables */ + int idxNum; /* Index number */ + u8 needFree; /* True if sqlite3_free(idxStr) is needed */ + u8 isOrdered; /* True if satisfies ORDER BY */ + u16 omitMask; /* Terms that may be omitted */ + char *idxStr; /* Index identifier string */ + } vtab; + } u; + u32 wsFlags; /* WHERE_* flags describing the plan */ + u16 nLTerm; /* Number of entries in aLTerm[] */ + /**** whereLoopXfer() copies fields above ***********************/ +# define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot) + u16 nLSlot; /* Number of slots allocated for aLTerm[] */ + WhereTerm **aLTerm; /* WhereTerms used */ + WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */ + WhereTerm *aLTermSpace[4]; /* Initial aLTerm[] space */ +}; + +/* Forward declaration of methods */ +static int whereLoopResize(sqlite3*, WhereLoop*, int); + +/* +** Each instance of this object holds a sequence of WhereLoop objects +** that implement some or all of the entire query plan. +*/ +struct WherePath { + Bitmask maskLoop; /* Bitmask of all WhereLoop objects in this path */ + Bitmask revLoop; /* aLoop[]s that should be reversed for ORDER BY */ + WhereCost nRow; /* Estimated number of rows generated by this path */ + WhereCost rCost; /* Total cost of this path */ + u8 isOrdered; /* True if this path satisfies ORDER BY */ + u8 isOrderedValid; /* True if the isOrdered field is valid */ + WhereLoop **aLoop; /* Array of WhereLoop objects implementing this path */ +}; /* ** The query generator uses an array of instances of this structure to @@@ -2734,88 -2897,947 +2734,86 @@@ static void disableTerm(WhereLevel *pLe } /* -** This routine decides if pIdx can be used to satisfy the ORDER BY -** clause, either in whole or in part. The return value is the -** cumulative number of terms in the ORDER BY clause that are satisfied -** by the index pIdx and other indices in outer loops. +** Code an OP_Affinity opcode to apply the column affinity string zAff +** to the n registers starting at base. ** -** The table being queried has a cursor number of "base". pIdx is the -** index that is postulated for use to access the table. +** As an optimization, SQLITE_AFF_NONE entries (which are no-ops) at the +** beginning and end of zAff are ignored. If all entries in zAff are +** SQLITE_AFF_NONE, then no code gets generated. ** -** The *pbRev value is set to 0 order 1 depending on whether or not -** pIdx should be run in the forward order or in reverse order. +** This routine makes its own copy of zAff so that the caller is free +** to modify zAff after this routine returns. */ -static int isSortingIndex( - WhereBestIdx *p, /* Best index search context */ - Index *pIdx, /* The index we are testing */ - int base, /* Cursor number for the table to be sorted */ - int *pbRev, /* Set to 1 for reverse-order scan of pIdx */ - int *pbObUnique /* ORDER BY column values will different in every row */ -){ - int i; /* Number of pIdx terms used */ - int j; /* Number of ORDER BY terms satisfied */ - int sortOrder = 2; /* 0: forward. 1: backward. 2: unknown */ - int nTerm; /* Number of ORDER BY terms */ - struct ExprList_item *pOBItem;/* A term of the ORDER BY clause */ - Table *pTab = pIdx->pTable; /* Table that owns index pIdx */ - ExprList *pOrderBy; /* The ORDER BY clause */ - Parse *pParse = p->pParse; /* Parser context */ - sqlite3 *db = pParse->db; /* Database connection */ - int nPriorSat; /* ORDER BY terms satisfied by outer loops */ - int seenRowid = 0; /* True if an ORDER BY rowid term is seen */ - int uniqueNotNull; /* pIdx is UNIQUE with all terms are NOT NULL */ - int outerObUnique; /* Outer loops generate different values in - ** every row for the ORDER BY columns */ - - if( p->i==0 ){ - nPriorSat = 0; - outerObUnique = 1; - }else{ - u32 wsFlags = p->aLevel[p->i-1].plan.wsFlags; - nPriorSat = p->aLevel[p->i-1].plan.nOBSat; - if( (wsFlags & WHERE_ORDERED)==0 ){ - /* This loop cannot be ordered unless the next outer loop is - ** also ordered */ - return nPriorSat; - } - if( OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ){ - /* Only look at the outer-most loop if the OrderByIdxJoin - ** optimization is disabled */ - return nPriorSat; - } - testcase( wsFlags & WHERE_OB_UNIQUE ); - testcase( wsFlags & WHERE_ALL_UNIQUE ); - outerObUnique = (wsFlags & (WHERE_OB_UNIQUE|WHERE_ALL_UNIQUE))!=0; - } - pOrderBy = p->pOrderBy; - assert( pOrderBy!=0 ); - if( pIdx->bUnordered ){ - /* Hash indices (indicated by the "unordered" tag on sqlite_stat1) cannot - ** be used for sorting */ - return nPriorSat; - } - nTerm = pOrderBy->nExpr; - uniqueNotNull = pIdx->onError!=OE_None; - assert( nTerm>0 ); - - /* Argument pIdx must either point to a 'real' named index structure, - ** or an index structure allocated on the stack by bestBtreeIndex() to - ** represent the rowid index that is part of every table. */ - assert( pIdx->zName || (pIdx->nColumn==1 && pIdx->aiColumn[0]==-1) ); - - /* Match terms of the ORDER BY clause against columns of - ** the index. - ** - ** Note that indices have pIdx->nColumn regular columns plus - ** one additional column containing the rowid. The rowid column - ** of the index is also allowed to match against the ORDER BY - ** clause. - */ - j = nPriorSat; - for(i=0,pOBItem=&pOrderBy->a[j]; jnColumn; i++){ - Expr *pOBExpr; /* The expression of the ORDER BY pOBItem */ - CollSeq *pColl; /* The collating sequence of pOBExpr */ - int termSortOrder; /* Sort order for this term */ - int iColumn; /* The i-th column of the index. -1 for rowid */ - int iSortOrder; /* 1 for DESC, 0 for ASC on the i-th index term */ - int isEq; /* Subject to an == or IS NULL constraint */ - int isMatch; /* ORDER BY term matches the index term */ - const char *zColl; /* Name of collating sequence for i-th index term */ - WhereTerm *pConstraint; /* A constraint in the WHERE clause */ - - /* If the next term of the ORDER BY clause refers to anything other than - ** a column in the "base" table, then this index will not be of any - ** further use in handling the ORDER BY. */ - pOBExpr = sqlite3ExprSkipCollate(pOBItem->pExpr); - if( pOBExpr->op!=TK_COLUMN || pOBExpr->iTable!=base ){ - break; - } - - /* Find column number and collating sequence for the next entry - ** in the index */ - if( pIdx->zName && inColumn ){ - iColumn = pIdx->aiColumn[i]; - if( iColumn==pIdx->pTable->iPKey ){ - iColumn = -1; - } - iSortOrder = pIdx->aSortOrder[i]; - zColl = pIdx->azColl[i]; - assert( zColl!=0 ); - }else{ - iColumn = -1; - iSortOrder = 0; - zColl = 0; - } - - /* Check to see if the column number and collating sequence of the - ** index match the column number and collating sequence of the ORDER BY - ** clause entry. Set isMatch to 1 if they both match. */ - if( pOBExpr->iColumn==iColumn ){ - if( zColl ){ - pColl = sqlite3ExprCollSeq(pParse, pOBItem->pExpr); - if( !pColl ) pColl = db->pDfltColl; - isMatch = sqlite3StrICmp(pColl->zName, zColl)==0; - }else{ - isMatch = 1; - } - }else{ - isMatch = 0; - } - - /* termSortOrder is 0 or 1 for whether or not the access loop should - ** run forward or backwards (respectively) in order to satisfy this - ** term of the ORDER BY clause. */ - assert( pOBItem->sortOrder==0 || pOBItem->sortOrder==1 ); - assert( iSortOrder==0 || iSortOrder==1 ); - termSortOrder = iSortOrder ^ pOBItem->sortOrder; - - /* If X is the column in the index and ORDER BY clause, check to see - ** if there are any X= or X IS NULL constraints in the WHERE clause. */ - pConstraint = findTerm(p->pWC, base, iColumn, p->notReady, - WO_EQ|WO_ISNULL|WO_IN, pIdx); - if( pConstraint==0 ){ - isEq = 0; - }else if( (pConstraint->eOperator & WO_IN)!=0 ){ - isEq = 0; - }else if( (pConstraint->eOperator & WO_ISNULL)!=0 ){ - uniqueNotNull = 0; - isEq = 1; /* "X IS NULL" means X has only a single value */ - }else if( pConstraint->prereqRight==0 ){ - isEq = 1; /* Constraint "X=constant" means X has only a single value */ - }else{ - Expr *pRight = pConstraint->pExpr->pRight; - if( pRight->op==TK_COLUMN ){ - WHERETRACE((" .. isOrderedColumn(tab=%d,col=%d)", - pRight->iTable, pRight->iColumn)); - isEq = isOrderedColumn(p, pRight->iTable, pRight->iColumn); - WHERETRACE((" -> isEq=%d\n", isEq)); - - /* If the constraint is of the form X=Y where Y is an ordered value - ** in an outer loop, then make sure the sort order of Y matches the - ** sort order required for X. */ - if( isMatch && isEq>=2 && isEq!=pOBItem->sortOrder+2 ){ - testcase( isEq==2 ); - testcase( isEq==3 ); - break; - } - }else{ - isEq = 0; /* "X=expr" places no ordering constraints on X */ - } - } - if( !isMatch ){ - if( isEq==0 ){ - break; - }else{ - continue; - } - }else if( isEq!=1 ){ - if( sortOrder==2 ){ - sortOrder = termSortOrder; - }else if( termSortOrder!=sortOrder ){ - break; - } - } - j++; - pOBItem++; - if( iColumn<0 ){ - seenRowid = 1; - break; - }else if( pTab->aCol[iColumn].notNull==0 && isEq!=1 ){ - testcase( isEq==0 ); - testcase( isEq==2 ); - testcase( isEq==3 ); - uniqueNotNull = 0; - } - } - if( seenRowid ){ - uniqueNotNull = 1; - }else if( uniqueNotNull==0 || inColumn ){ - uniqueNotNull = 0; +static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){ + Vdbe *v = pParse->pVdbe; + if( zAff==0 ){ + assert( pParse->db->mallocFailed ); + return; } + assert( v!=0 ); - /* If we have not found at least one ORDER BY term that matches the - ** index, then show no progress. */ - if( pOBItem==&pOrderBy->a[nPriorSat] ) return nPriorSat; - - /* Either the outer queries must generate rows where there are no two - ** rows with the same values in all ORDER BY columns, or else this - ** loop must generate just a single row of output. Example: Suppose - ** the outer loops generate A=1 and A=1, and this loop generates B=3 - ** and B=4. Then without the following test, ORDER BY A,B would - ** generate the wrong order output: 1,3 1,4 1,3 1,4 + /* Adjust base and n to skip over SQLITE_AFF_NONE entries at the beginning + ** and end of the affinity string. */ - if( outerObUnique==0 && uniqueNotNull==0 ) return nPriorSat; - *pbObUnique = uniqueNotNull; - - /* Return the necessary scan order back to the caller */ - *pbRev = sortOrder & 1; + while( n>0 && zAff[0]==SQLITE_AFF_NONE ){ + n--; + base++; + zAff++; + } + while( n>1 && zAff[n-1]==SQLITE_AFF_NONE ){ + n--; + } - /* If there was an "ORDER BY rowid" term that matched, or it is only - ** possible for a single row from this table to match, then skip over - ** any additional ORDER BY terms dealing with this table. - */ - if( uniqueNotNull ){ - /* Advance j over additional ORDER BY terms associated with base */ - WhereMaskSet *pMS = p->pWC->pMaskSet; - Bitmask m = ~getMask(pMS, base); - while( ja[j].pExpr)&m)==0 ){ - j++; - } + /* Code the OP_Affinity opcode if there is anything left to do. */ + if( n>0 ){ + sqlite3VdbeAddOp2(v, OP_Affinity, base, n); + sqlite3VdbeChangeP4(v, -1, zAff, n); + sqlite3ExprCacheAffinityChange(pParse, base, n); } - return j; } + /* -** Find the best query plan for accessing a particular table. Write the -** best query plan and its cost into the p->cost. -** -** The lowest cost plan wins. The cost is an estimate of the amount of -** CPU and disk I/O needed to process the requested result. -** Factors that influence cost include: -** -** * The estimated number of rows that will be retrieved. (The -** fewer the better.) -** -** * Whether or not sorting must occur. -** -** * Whether or not there must be separate lookups in the -** index and in the main table. +** Generate code for a single equality term of the WHERE clause. An equality +** term can be either X=expr or X IN (...). pTerm is the term to be +** coded. ** -** If there was an INDEXED BY clause (pSrc->pIndex) attached to the table in -** the SQL statement, then this function only considers plans using the -** named index. If no such plan is found, then the returned cost is -** SQLITE_BIG_DBL. If a plan is found that uses the named index, -** then the cost is calculated in the usual way. +** The current value for the constraint is left in register iReg. ** -** If a NOT INDEXED clause was attached to the table -** in the SELECT statement, then no indexes are considered. However, the -** selected plan may still take advantage of the built-in rowid primary key -** index. +** For a constraint of the form X=expr, the expression is evaluated and its +** result is left on the stack. For constraints of the form X IN (...) +** this routine sets up a loop that will iterate over all values of X. */ -static void bestBtreeIndex(WhereBestIdx *p){ - Parse *pParse = p->pParse; /* The parsing context */ - WhereClause *pWC = p->pWC; /* The WHERE clause */ - struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */ - int iCur = pSrc->iCursor; /* The cursor of the table to be accessed */ - Index *pProbe; /* An index we are evaluating */ - Index *pIdx; /* Copy of pProbe, or zero for IPK index */ - int eqTermMask; /* Current mask of valid equality operators */ - int idxEqTermMask; /* Index mask of valid equality operators */ - Index sPk; /* A fake index object for the primary key */ - tRowcnt aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */ - int aiColumnPk = -1; /* The aColumn[] value for the sPk index */ - int wsFlagMask; /* Allowed flags in p->cost.plan.wsFlag */ - int nPriorSat; /* ORDER BY terms satisfied by outer loops */ - int nOrderBy; /* Number of ORDER BY terms */ - char bSortInit; /* Initializer for bSort in inner loop */ - char bDistInit; /* Initializer for bDist in inner loop */ - - - /* Initialize the cost to a worst-case value */ - memset(&p->cost, 0, sizeof(p->cost)); - p->cost.rCost = SQLITE_BIG_DBL; +static int codeEqualityTerm( + Parse *pParse, /* The parsing context */ + WhereTerm *pTerm, /* The term of the WHERE clause to be coded */ + WhereLevel *pLevel, /* The level of the FROM clause we are working on */ + int iEq, /* Index of the equality term within this level */ + int bRev, /* True for reverse-order IN operations */ + int iTarget /* Attempt to leave results in this register */ +){ + Expr *pX = pTerm->pExpr; + Vdbe *v = pParse->pVdbe; + int iReg; /* Register holding results */ - /* If the pSrc table is the right table of a LEFT JOIN then we may not - ** use an index to satisfy IS NULL constraints on that table. This is - ** because columns might end up being NULL if the table does not match - - ** a circumstance which the index cannot help us discover. Ticket #2177. - */ - if( pSrc->jointype & JT_LEFT ){ - idxEqTermMask = WO_EQ|WO_IN; + assert( iTarget>0 ); + if( pX->op==TK_EQ ){ + iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); + }else if( pX->op==TK_ISNULL ){ + iReg = iTarget; + sqlite3VdbeAddOp2(v, OP_Null, 0, iReg); +#ifndef SQLITE_OMIT_SUBQUERY }else{ - idxEqTermMask = WO_EQ|WO_IN|WO_ISNULL; - } + int eType; + int iTab; + struct InLoop *pIn; + WhereLoop *pLoop = pLevel->pWLoop; - if( pSrc->pIndex ){ - /* An INDEXED BY clause specifies a particular index to use */ - pIdx = pProbe = pSrc->pIndex; - wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE); - eqTermMask = idxEqTermMask; - }else{ - /* There is no INDEXED BY clause. Create a fake Index object in local - ** variable sPk to represent the rowid primary key index. Make this - ** fake index the first in a chain of Index objects with all of the real - ** indices to follow */ - Index *pFirst; /* First of real indices on the table */ - memset(&sPk, 0, sizeof(Index)); - sPk.nColumn = 1; - sPk.aiColumn = &aiColumnPk; - sPk.aiRowEst = aiRowEstPk; - sPk.onError = OE_Replace; - sPk.pTable = pSrc->pTab; - aiRowEstPk[0] = pSrc->pTab->nRowEst; - aiRowEstPk[1] = 1; - pFirst = pSrc->pTab->pIndex; - if( pSrc->notIndexed==0 ){ - /* The real indices of the table are only considered if the - ** NOT INDEXED qualifier is omitted from the FROM clause */ - sPk.pNext = pFirst; - } - pProbe = &sPk; - wsFlagMask = ~( - WHERE_COLUMN_IN|WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_RANGE - ); - eqTermMask = WO_EQ|WO_IN; - pIdx = 0; - } - - nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0; - if( p->i ){ - nPriorSat = p->aLevel[p->i-1].plan.nOBSat; - bSortInit = nPriorSat0; - bDistInit = p->pDistinct!=0; - } - - /* Loop over all indices looking for the best one to use - */ - for(; pProbe; pIdx=pProbe=pProbe->pNext){ - const tRowcnt * const aiRowEst = pProbe->aiRowEst; - WhereCost pc; /* Cost of using pProbe */ - double log10N = (double)1; /* base-10 logarithm of nRow (inexact) */ - - /* The following variables are populated based on the properties of - ** index being evaluated. They are then used to determine the expected - ** cost and number of rows returned. - ** - ** pc.plan.nEq: - ** Number of equality terms that can be implemented using the index. - ** In other words, the number of initial fields in the index that - ** are used in == or IN or NOT NULL constraints of the WHERE clause. - ** - ** nInMul: - ** The "in-multiplier". This is an estimate of how many seek operations - ** SQLite must perform on the index in question. For example, if the - ** WHERE clause is: - ** - ** WHERE a IN (1, 2, 3) AND b IN (4, 5, 6) - ** - ** SQLite must perform 9 lookups on an index on (a, b), so nInMul is - ** set to 9. Given the same schema and either of the following WHERE - ** clauses: - ** - ** WHERE a = 1 - ** WHERE a >= 2 - ** - ** nInMul is set to 1. - ** - ** If there exists a WHERE term of the form "x IN (SELECT ...)", then - ** the sub-select is assumed to return 25 rows for the purposes of - ** determining nInMul. - ** - ** bInEst: - ** Set to true if there was at least one "x IN (SELECT ...)" term used - ** in determining the value of nInMul. Note that the RHS of the - ** IN operator must be a SELECT, not a value list, for this variable - ** to be true. - ** - ** rangeDiv: - ** An estimate of a divisor by which to reduce the search space due - ** to inequality constraints. In the absence of sqlite_stat3 ANALYZE - ** data, a single inequality reduces the search space to 1/4rd its - ** original size (rangeDiv==4). Two inequalities reduce the search - ** space to 1/16th of its original size (rangeDiv==16). - ** - ** bSort: - ** Boolean. True if there is an ORDER BY clause that will require an - ** external sort (i.e. scanning the index being evaluated will not - ** correctly order records). - ** - ** bDist: - ** Boolean. True if there is a DISTINCT clause that will require an - ** external btree. - ** - ** bLookup: - ** Boolean. True if a table lookup is required for each index entry - ** visited. In other words, true if this is not a covering index. - ** This is always false for the rowid primary key index of a table. - ** For other indexes, it is true unless all the columns of the table - ** used by the SELECT statement are present in the index (such an - ** index is sometimes described as a covering index). - ** For example, given the index on (a, b), the second of the following - ** two queries requires table b-tree lookups in order to find the value - ** of column c, but the first does not because columns a and b are - ** both available in the index. - ** - ** SELECT a, b FROM tbl WHERE a = 1; - ** SELECT a, b, c FROM tbl WHERE a = 1; - */ - int bInEst = 0; /* True if "x IN (SELECT...)" seen */ - int nInMul = 1; /* Number of distinct equalities to lookup */ - double rangeDiv = (double)1; /* Estimated reduction in search space */ - int nBound = 0; /* Number of range constraints seen */ - char bSort = bSortInit; /* True if external sort required */ - char bDist = bDistInit; /* True if index cannot help with DISTINCT */ - char bLookup = 0; /* True if not a covering index */ - WhereTerm *pTerm; /* A single term of the WHERE clause */ -#ifdef SQLITE_ENABLE_STAT3 - WhereTerm *pFirstTerm = 0; /* First term matching the index */ -#endif - - WHERETRACE(( - " %s(%s):\n", - pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk") - )); - memset(&pc, 0, sizeof(pc)); - pc.plan.nOBSat = nPriorSat; - - /* Determine the values of pc.plan.nEq and nInMul */ - for(pc.plan.nEq=0; pc.plan.nEqnColumn; pc.plan.nEq++){ - int j = pProbe->aiColumn[pc.plan.nEq]; - pTerm = findTerm(pWC, iCur, j, p->notReady, eqTermMask, pIdx); - if( pTerm==0 ) break; - pc.plan.wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ); - testcase( pTerm->pWC!=pWC ); - if( pTerm->eOperator & WO_IN ){ - Expr *pExpr = pTerm->pExpr; - pc.plan.wsFlags |= WHERE_COLUMN_IN; - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - /* "x IN (SELECT ...)": Assume the SELECT returns 25 rows */ - nInMul *= 25; - bInEst = 1; - }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){ - /* "x IN (value, value, ...)" */ - nInMul *= pExpr->x.pList->nExpr; - } - }else if( pTerm->eOperator & WO_ISNULL ){ - pc.plan.wsFlags |= WHERE_COLUMN_NULL; - } -#ifdef SQLITE_ENABLE_STAT3 - if( pc.plan.nEq==0 && pProbe->aSample ) pFirstTerm = pTerm; -#endif - pc.used |= pTerm->prereqRight; - } - - /* If the index being considered is UNIQUE, and there is an equality - ** constraint for all columns in the index, then this search will find - ** at most a single row. In this case set the WHERE_UNIQUE flag to - ** indicate this to the caller. - ** - ** Otherwise, if the search may find more than one row, test to see if - ** there is a range constraint on indexed column (pc.plan.nEq+1) that - ** can be optimized using the index. - */ - if( pc.plan.nEq==pProbe->nColumn && pProbe->onError!=OE_None ){ - testcase( pc.plan.wsFlags & WHERE_COLUMN_IN ); - testcase( pc.plan.wsFlags & WHERE_COLUMN_NULL ); - if( (pc.plan.wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){ - pc.plan.wsFlags |= WHERE_UNIQUE; - if( p->i==0 || (p->aLevel[p->i-1].plan.wsFlags & WHERE_ALL_UNIQUE)!=0 ){ - pc.plan.wsFlags |= WHERE_ALL_UNIQUE; - } - } - }else if( pProbe->bUnordered==0 ){ - int j; - j = (pc.plan.nEq==pProbe->nColumn ? -1 : pProbe->aiColumn[pc.plan.nEq]); - if( findTerm(pWC, iCur, j, p->notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){ - WhereTerm *pTop, *pBtm; - pTop = findTerm(pWC, iCur, j, p->notReady, WO_LT|WO_LE, pIdx); - pBtm = findTerm(pWC, iCur, j, p->notReady, WO_GT|WO_GE, pIdx); - whereRangeScanEst(pParse, pProbe, pc.plan.nEq, pBtm, pTop, &rangeDiv); - if( pTop ){ - nBound = 1; - pc.plan.wsFlags |= WHERE_TOP_LIMIT; - pc.used |= pTop->prereqRight; - testcase( pTop->pWC!=pWC ); - } - if( pBtm ){ - nBound++; - pc.plan.wsFlags |= WHERE_BTM_LIMIT; - pc.used |= pBtm->prereqRight; - testcase( pBtm->pWC!=pWC ); - } - pc.plan.wsFlags |= (WHERE_COLUMN_RANGE|WHERE_ROWID_RANGE); - } - } - - /* If there is an ORDER BY clause and the index being considered will - ** naturally scan rows in the required order, set the appropriate flags - ** in pc.plan.wsFlags. Otherwise, if there is an ORDER BY clause but - ** the index will scan rows in a different order, set the bSort - ** variable. */ - if( bSort && (pSrc->jointype & JT_LEFT)==0 ){ - int bRev = 2; - int bObUnique = 0; - WHERETRACE((" --> before isSortIndex: nPriorSat=%d\n",nPriorSat)); - pc.plan.nOBSat = isSortingIndex(p, pProbe, iCur, &bRev, &bObUnique); - WHERETRACE((" --> after isSortIndex: bRev=%d bObU=%d nOBSat=%d\n", - bRev, bObUnique, pc.plan.nOBSat)); - if( nPriorSatpDistinct, pc.plan.nEq) - && (pc.plan.wsFlags & WHERE_COLUMN_IN)==0 - ){ - bDist = 0; - pc.plan.wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_DISTINCT; - } - - /* If currently calculating the cost of using an index (not the IPK - ** index), determine if all required column data may be obtained without - ** using the main table (i.e. if the index is a covering - ** index for this query). If it is, set the WHERE_IDX_ONLY flag in - ** pc.plan.wsFlags. Otherwise, set the bLookup variable to true. */ - if( pIdx ){ - Bitmask m = pSrc->colUsed; - int j; - for(j=0; jnColumn; j++){ - int x = pIdx->aiColumn[j]; - if( xaiRowEst[0] ){ - pc.plan.nRow = aiRowEst[0]/2; - nInMul = (int)(pc.plan.nRow / aiRowEst[pc.plan.nEq]); - } - -#ifdef SQLITE_ENABLE_STAT3 - /* If the constraint is of the form x=VALUE or x IN (E1,E2,...) - ** and we do not think that values of x are unique and if histogram - ** data is available for column x, then it might be possible - ** to get a better estimate on the number of rows based on - ** VALUE and how common that value is according to the histogram. - */ - if( pc.plan.nRow>(double)1 && pc.plan.nEq==1 - && pFirstTerm!=0 && aiRowEst[1]>1 ){ - assert( (pFirstTerm->eOperator & (WO_EQ|WO_ISNULL|WO_IN))!=0 ); - if( pFirstTerm->eOperator & (WO_EQ|WO_ISNULL) ){ - testcase( pFirstTerm->eOperator & WO_EQ ); - testcase( pFirstTerm->eOperator & WO_EQUIV ); - testcase( pFirstTerm->eOperator & WO_ISNULL ); - whereEqualScanEst(pParse, pProbe, pFirstTerm->pExpr->pRight, - &pc.plan.nRow); - }else if( bInEst==0 ){ - assert( pFirstTerm->eOperator & WO_IN ); - whereInScanEst(pParse, pProbe, pFirstTerm->pExpr->x.pList, - &pc.plan.nRow); - } - } -#endif /* SQLITE_ENABLE_STAT3 */ - - /* Adjust the number of output rows and downward to reflect rows - ** that are excluded by range constraints. - */ - pc.plan.nRow = pc.plan.nRow/rangeDiv; - if( pc.plan.nRow<1 ) pc.plan.nRow = 1; - - /* Experiments run on real SQLite databases show that the time needed - ** to do a binary search to locate a row in a table or index is roughly - ** log10(N) times the time to move from one row to the next row within - ** a table or index. The actual times can vary, with the size of - ** records being an important factor. Both moves and searches are - ** slower with larger records, presumably because fewer records fit - ** on one page and hence more pages have to be fetched. - ** - ** The ANALYZE command and the sqlite_stat1 and sqlite_stat3 tables do - ** not give us data on the relative sizes of table and index records. - ** So this computation assumes table records are about twice as big - ** as index records - */ - if( (pc.plan.wsFlags&~(WHERE_REVERSE|WHERE_ORDERED|WHERE_OB_UNIQUE)) - ==WHERE_IDX_ONLY - && (pWC->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 - && sqlite3GlobalConfig.bUseCis - && OptimizationEnabled(pParse->db, SQLITE_CoverIdxScan) - ){ - /* This index is not useful for indexing, but it is a covering index. - ** A full-scan of the index might be a little faster than a full-scan - ** of the table, so give this case a cost slightly less than a table - ** scan. */ - pc.rCost = aiRowEst[0]*3 + pProbe->nColumn; - pc.plan.wsFlags |= WHERE_COVER_SCAN|WHERE_COLUMN_RANGE; - }else if( (pc.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){ - /* The cost of a full table scan is a number of move operations equal - ** to the number of rows in the table. - ** - ** We add an additional 4x penalty to full table scans. This causes - ** the cost function to err on the side of choosing an index over - ** choosing a full scan. This 4x full-scan penalty is an arguable - ** decision and one which we expect to revisit in the future. But - ** it seems to be working well enough at the moment. - */ - pc.rCost = aiRowEst[0]*4; - pc.plan.wsFlags &= ~WHERE_IDX_ONLY; - if( pIdx ){ - pc.plan.wsFlags &= ~WHERE_ORDERED; - pc.plan.nOBSat = nPriorSat; - } - }else{ - log10N = estLog(aiRowEst[0]); - pc.rCost = pc.plan.nRow; - if( pIdx ){ - if( bLookup ){ - /* For an index lookup followed by a table lookup: - ** nInMul index searches to find the start of each index range - ** + nRow steps through the index - ** + nRow table searches to lookup the table entry using the rowid - */ - pc.rCost += (nInMul + pc.plan.nRow)*log10N; - }else{ - /* For a covering index: - ** nInMul index searches to find the initial entry - ** + nRow steps through the index - */ - pc.rCost += nInMul*log10N; - } - }else{ - /* For a rowid primary key lookup: - ** nInMult table searches to find the initial entry for each range - ** + nRow steps through the table - */ - pc.rCost += nInMul*log10N; - } - } - - /* Add in the estimated cost of sorting the result. Actual experimental - ** measurements of sorting performance in SQLite show that sorting time - ** adds C*N*log10(N) to the cost, where N is the number of rows to be - ** sorted and C is a factor between 1.95 and 4.3. We will split the - ** difference and select C of 3.0. - */ - if( bSort ){ - double m = estLog(pc.plan.nRow*(nOrderBy - pc.plan.nOBSat)/nOrderBy); - m *= (double)(pc.plan.nOBSat ? 2 : 3); - pc.rCost += pc.plan.nRow*m; - } - if( bDist ){ - pc.rCost += pc.plan.nRow*estLog(pc.plan.nRow)*3; - } - - /**** Cost of using this index has now been computed ****/ - - /* If there are additional constraints on this table that cannot - ** be used with the current index, but which might lower the number - ** of output rows, adjust the nRow value accordingly. This only - ** matters if the current index is the least costly, so do not bother - ** with this step if we already know this index will not be chosen. - ** Also, never reduce the output row count below 2 using this step. - ** - ** It is critical that the notValid mask be used here instead of - ** the notReady mask. When computing an "optimal" index, the notReady - ** mask will only have one bit set - the bit for the current table. - ** The notValid mask, on the other hand, always has all bits set for - ** tables that are not in outer loops. If notReady is used here instead - ** of notValid, then a optimal index that depends on inner joins loops - ** might be selected even when there exists an optimal index that has - ** no such dependency. - */ - if( pc.plan.nRow>2 && pc.rCost<=p->cost.rCost ){ - int k; /* Loop counter */ - int nSkipEq = pc.plan.nEq; /* Number of == constraints to skip */ - int nSkipRange = nBound; /* Number of < constraints to skip */ - Bitmask thisTab; /* Bitmap for pSrc */ - - thisTab = getMask(pWC->pMaskSet, iCur); - for(pTerm=pWC->a, k=pWC->nTerm; pc.plan.nRow>2 && k; k--, pTerm++){ - if( pTerm->wtFlags & TERM_VIRTUAL ) continue; - if( (pTerm->prereqAll & p->notValid)!=thisTab ) continue; - if( pTerm->eOperator & (WO_EQ|WO_IN|WO_ISNULL) ){ - if( nSkipEq ){ - /* Ignore the first pc.plan.nEq equality matches since the index - ** has already accounted for these */ - nSkipEq--; - }else{ - /* Assume each additional equality match reduces the result - ** set size by a factor of 10 */ - pc.plan.nRow /= 10; - } - }else if( pTerm->eOperator & (WO_LT|WO_LE|WO_GT|WO_GE) ){ - if( nSkipRange ){ - /* Ignore the first nSkipRange range constraints since the index - ** has already accounted for these */ - nSkipRange--; - }else{ - /* Assume each additional range constraint reduces the result - ** set size by a factor of 3. Indexed range constraints reduce - ** the search space by a larger factor: 4. We make indexed range - ** more selective intentionally because of the subjective - ** observation that indexed range constraints really are more - ** selective in practice, on average. */ - pc.plan.nRow /= 3; - } - }else if( (pTerm->eOperator & WO_NOOP)==0 ){ - /* Any other expression lowers the output row count by half */ - pc.plan.nRow /= 2; - } - } - if( pc.plan.nRow<2 ) pc.plan.nRow = 2; - } - - - WHERETRACE(( - " nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%08x\n" - " notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f\n" - " used=0x%llx nOBSat=%d\n", - pc.plan.nEq, nInMul, (int)rangeDiv, bSort, bLookup, pc.plan.wsFlags, - p->notReady, log10N, pc.plan.nRow, pc.rCost, pc.used, - pc.plan.nOBSat - )); - - /* If this index is the best we have seen so far, then record this - ** index and its cost in the p->cost structure. - */ - if( (!pIdx || pc.plan.wsFlags) && compareCost(&pc, &p->cost) ){ - p->cost = pc; - p->cost.plan.wsFlags &= wsFlagMask; - p->cost.plan.u.pIdx = pIdx; - } - - /* If there was an INDEXED BY clause, then only that one index is - ** considered. */ - if( pSrc->pIndex ) break; - - /* Reset masks for the next index in the loop */ - wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE); - eqTermMask = idxEqTermMask; - } - - /* If there is no ORDER BY clause and the SQLITE_ReverseOrder flag - ** is set, then reverse the order that the index will be scanned - ** in. This is used for application testing, to help find cases - ** where application behavior depends on the (undefined) order that - ** SQLite outputs rows in in the absence of an ORDER BY clause. */ - if( !p->pOrderBy && pParse->db->flags & SQLITE_ReverseOrder ){ - p->cost.plan.wsFlags |= WHERE_REVERSE; - } - - assert( p->pOrderBy || (p->cost.plan.wsFlags&WHERE_ORDERED)==0 ); - assert( p->cost.plan.u.pIdx==0 || (p->cost.plan.wsFlags&WHERE_ROWID_EQ)==0 ); - assert( pSrc->pIndex==0 - || p->cost.plan.u.pIdx==0 - || p->cost.plan.u.pIdx==pSrc->pIndex - ); - - WHERETRACE((" best index is %s cost=%.1f\n", - p->cost.plan.u.pIdx ? p->cost.plan.u.pIdx->zName : "ipk", - p->cost.rCost)); - - bestOrClauseIndex(p); - bestAutomaticIndex(p); - p->cost.plan.wsFlags |= eqTermMask; -} - -/* -** Find the query plan for accessing table pSrc->pTab. Write the -** best query plan and its cost into the WhereCost object supplied -** as the last parameter. This function may calculate the cost of -** both real and virtual table scans. -** -** This function does not take ORDER BY or DISTINCT into account. Nor -** does it remember the virtual table query plan. All it does is compute -** the cost while determining if an OR optimization is applicable. The -** details will be reconsidered later if the optimization is found to be -** applicable. -*/ -static void bestIndex(WhereBestIdx *p){ -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(p->pSrc->pTab) ){ - sqlite3_index_info *pIdxInfo = 0; - p->ppIdxInfo = &pIdxInfo; - bestVirtualIndex(p); - assert( pIdxInfo!=0 || p->pParse->db->mallocFailed ); - if( pIdxInfo && pIdxInfo->needToFreeIdxStr ){ - sqlite3_free(pIdxInfo->idxStr); - } - sqlite3DbFree(p->pParse->db, pIdxInfo); - }else -#endif - { - bestBtreeIndex(p); - } -} - -/* -** Disable a term in the WHERE clause. Except, do not disable the term -** if it controls a LEFT OUTER JOIN and it did not originate in the ON -** or USING clause of that join. -** -** Consider the term t2.z='ok' in the following queries: -** -** (1) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok' -** (2) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok' -** (3) SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok' -** -** The t2.z='ok' is disabled in the in (2) because it originates -** in the ON clause. The term is disabled in (3) because it is not part -** of a LEFT OUTER JOIN. In (1), the term is not disabled. -** -** IMPLEMENTATION-OF: R-24597-58655 No tests are done for terms that are -** completely satisfied by indices. -** -** Disabling a term causes that term to not be tested in the inner loop -** of the join. Disabling is an optimization. When terms are satisfied -** by indices, we disable them to prevent redundant tests in the inner -** loop. We would get the correct results if nothing were ever disabled, -** but joins might run a little slower. The trick is to disable as much -** as we can without disabling too much. If we disabled in (1), we'd get -** the wrong answer. See ticket #813. -*/ -static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ - if( pTerm - && (pTerm->wtFlags & TERM_CODED)==0 - && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin)) - ){ - pTerm->wtFlags |= TERM_CODED; - if( pTerm->iParent>=0 ){ - WhereTerm *pOther = &pTerm->pWC->a[pTerm->iParent]; - if( (--pOther->nChild)==0 ){ - disableTerm(pLevel, pOther); - } - } - } -} - -/* -** Code an OP_Affinity opcode to apply the column affinity string zAff -** to the n registers starting at base. -** -** As an optimization, SQLITE_AFF_NONE entries (which are no-ops) at the -** beginning and end of zAff are ignored. If all entries in zAff are -** SQLITE_AFF_NONE, then no code gets generated. -** -** This routine makes its own copy of zAff so that the caller is free -** to modify zAff after this routine returns. -*/ -static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){ - Vdbe *v = pParse->pVdbe; - if( zAff==0 ){ - assert( pParse->db->mallocFailed ); - return; - } - assert( v!=0 ); - - /* Adjust base and n to skip over SQLITE_AFF_NONE entries at the beginning - ** and end of the affinity string. - */ - while( n>0 && zAff[0]==SQLITE_AFF_NONE ){ - n--; - base++; - zAff++; - } - while( n>1 && zAff[n-1]==SQLITE_AFF_NONE ){ - n--; - } - - /* Code the OP_Affinity opcode if there is anything left to do. */ - if( n>0 ){ - sqlite3VdbeAddOp2(v, OP_Affinity, base, n); - sqlite3VdbeChangeP4(v, -1, zAff, n); - sqlite3ExprCacheAffinityChange(pParse, base, n); - } -} - - -/* -** Generate code for a single equality term of the WHERE clause. An equality -** term can be either X=expr or X IN (...). pTerm is the term to be -** coded. -** -** The current value for the constraint is left in register iReg. -** -** For a constraint of the form X=expr, the expression is evaluated and its -** result is left on the stack. For constraints of the form X IN (...) -** this routine sets up a loop that will iterate over all values of X. -*/ -static int codeEqualityTerm( - Parse *pParse, /* The parsing context */ - WhereTerm *pTerm, /* The term of the WHERE clause to be coded */ - WhereLevel *pLevel, /* The level of the FROM clause we are working on */ - int iEq, /* Index of the equality term within this level */ - int iTarget /* Attempt to leave results in this register */ -){ - Expr *pX = pTerm->pExpr; - Vdbe *v = pParse->pVdbe; - int iReg; /* Register holding results */ - - assert( iTarget>0 ); - if( pX->op==TK_EQ ){ - iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); - }else if( pX->op==TK_ISNULL ){ - iReg = iTarget; - sqlite3VdbeAddOp2(v, OP_Null, 0, iReg); -#ifndef SQLITE_OMIT_SUBQUERY - }else{ - int eType; - int iTab; - struct InLoop *pIn; - u8 bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0; - - if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 - && pLevel->plan.u.pIdx->aSortOrder[iEq] + if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 + && pLoop->u.btree.pIndex!=0 + && pLoop->u.btree.pIndex->aSortOrder[iEq] ){ testcase( iEq==0 ); -- testcase( iEq==pLevel->plan.u.pIdx->nColumn-1 ); -- testcase( iEq>0 && iEq+1plan.u.pIdx->nColumn ); testcase( bRev ); bRev = !bRev; } @@@ -3555,9 -4578,9 +3553,9 @@@ static Bitmask codeOneLoopStart ** If it is, jump to the next iteration of the loop. */ r1 = sqlite3GetTempReg(pParse); -- testcase( pLevel->plan.wsFlags & WHERE_BTM_LIMIT ); -- testcase( pLevel->plan.wsFlags & WHERE_TOP_LIMIT ); - if( (pLevel->plan.wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 ){ ++ testcase( pLoop->wsFlags & WHERE_BTM_LIMIT ); ++ testcase( pLoop->wsFlags & WHERE_TOP_LIMIT ); + if( (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 ){ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, nEq, r1); sqlite3VdbeAddOp2(v, OP_IsNull, r1, addrCont); }