Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Remove some rowid-related dead code from where.c. Fix other code issues in the same file. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
4856f089442ac5fb07f3fc2544a8c08c |
User & Date: | dan 2013-07-29 18:07:05.357 |
Context
2013-07-29
| ||
19:31 | Remove the unused OP_InsertInt opcode from the VDBE. check-in: 3e371e1a44 user: drh tags: trunk | |
18:07 | Remove some rowid-related dead code from where.c. Fix other code issues in the same file. check-in: 4856f08944 user: dan tags: trunk | |
17:57 | Code clarifications: Do not overload the "nField" variable (in the OP_MakeRecord opcode) to mean something other than the number of fields to be encoded. check-in: 20962f1a72 user: drh tags: trunk | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
1422 1423 1424 1425 1426 1427 1428 | ** all members of the RHS set, skipping duplicates. ** ** A cursor is opened on the b-tree object that the RHS of the IN operator ** and pX->iTable is set to the index of that cursor. ** ** The returned value of this function indicates the b-tree type, as follows: ** | | > > > > | | > | > > | < > > > > > > > > > > > > > | 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 | ** all members of the RHS set, skipping duplicates. ** ** A cursor is opened on the b-tree object that the RHS of the IN operator ** and pX->iTable is set to the index of that cursor. ** ** The returned value of this function indicates the b-tree type, as follows: ** ** IN_INDEX_ROWID - The cursor was opened on the PK index of a ** table with an implicit integer primary key. ** IN_INDEX_INDEX_ASC - The cursor was opened on an ascending index. ** IN_INDEX_INDEX_DESC - The cursor was opened on a descending index. ** IN_INDEX_EPH - The cursor was opened on a specially created and ** populated epheremal table. ** ** An existing b-tree might be used if the RHS expression pX is a simple ** subquery such as: ** ** SELECT <column> FROM <table> ** ** If the RHS of the IN operator is a list or a more complex subquery, then ** an ephemeral table might need to be generated from the RHS and then ** pX->iTable made to point to the ephermeral table instead of an ** existing table. ** ** ** ITERATING THROUGH SET MEMBERS ** ** If the prNotFound parameter is 0, then the b-tree will be used to ** iterate through the set members, skipping any duplicates. In this ** case the piCov parameter is always non-zero. An index on column ** <column> of <table> is used in this case if: ** ** 1. The index guarantees the column is unique (i.e. it is a UNIQUE ** or PRIMARY KEY Index), and ** ** 2. The index uses the same collation sequence as the comparison ** performed by expression pX. ** ** 3. The index is a covering index for <column> (either because it ** is a PRIMARY KEY or was created with a COVERING clause). ** ** Restriction (3) could be removed by the calling code in where.c. ** ** Before returning, *piCov is set to the column number of <column> in ** the value associated with the selected covering or primary key index. ** ** SET MEMBERSHIP TESTS ** ** If the prNotFound parameter is not 0, then the b-tree will be used ** for fast set membership tests. In this case an epheremal table must ** be used unless <column> is an INTEGER PRIMARY KEY or an index can ** be found with <column> as its left-most column. ** ** When the b-tree is being used for membership tests, the calling function |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
530 531 532 533 534 535 536 | ** the rowids returned by a WHERE clause. Return FALSE if doing an ** UPDATE or DELETE might change subsequent WHERE clause results. */ int sqlite4WhereOkOnePass(WhereInfo *pWInfo){ return pWInfo->okOnePass; } | < | 530 531 532 533 534 535 536 537 538 539 540 541 542 543 | ** the rowids returned by a WHERE clause. Return FALSE if doing an ** UPDATE or DELETE might change subsequent WHERE clause results. */ int sqlite4WhereOkOnePass(WhereInfo *pWInfo){ return pWInfo->okOnePass; } /* ** Move the content of pSrc into pDest */ static void whereOrMove(WhereOrSet *pDest, WhereOrSet *pSrc){ pDest->n = pSrc->n; memcpy(pDest->a, pSrc->a, pDest->n*sizeof(pDest->a[0])); } |
︙ | ︙ | |||
639 640 641 642 643 644 645 646 | } } /* ** Skip over any TK_COLLATE and/or TK_AS operators at the root of ** an expression. */ | > > > > > | > > | 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 | } } /* ** Skip over any TK_COLLATE and/or TK_AS operators at the root of ** an expression. ** ** NOTE: This function was added when the NGQP was imported from SQLite3. ** At present it is not actually possible for Expr.op to be set to ** TK_COLLATE. But will be if the way Expr objects represent collation ** sequences is changed to match SQLite3. */ static Expr *sqlite4ExprSkipCollate(Expr *pExpr){ assert( pExpr==0 || pExpr->op!=TK_COLLATE ); while( pExpr && (pExpr->op==TK_COLLATE || pExpr->op==TK_AS) ){ pExpr = pExpr->pLeft; } return pExpr; } /* |
︙ | ︙ | |||
3266 3267 3268 3269 3270 3271 3272 | } }else{ const char *zCover = (flags & WHERE_IDX_ONLY) ? " COVERING" : ""; zMsg = sqlite4MAppendf(db, zMsg, "%s USING%s INDEX %s%s", zMsg, zCover, pIdx->zName, zWhere ); } | < < < < < < < < < < < < < < < | 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 | } }else{ const char *zCover = (flags & WHERE_IDX_ONLY) ? " COVERING" : ""; zMsg = sqlite4MAppendf(db, zMsg, "%s USING%s INDEX %s%s", zMsg, zCover, pIdx->zName, zWhere ); } sqlite4DbFree(db, zWhere); } #ifndef SQLITE4_OMIT_VIRTUALTABLE else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ zMsg = sqlite4MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg, pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr); } #endif |
︙ | ︙ | |||
3414 3415 3416 3417 3418 3419 3420 | pLevel->p1 = iCur; pLevel->p2 = sqlite4VdbeCurrentAddr(v); sqlite4ReleaseTempRange(pParse, iReg, nConstraint+2); sqlite4ExprCachePop(pParse, 1); }else #endif /* SQLITE4_OMIT_VIRTUALTABLE */ | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 | pLevel->p1 = iCur; pLevel->p2 = sqlite4VdbeCurrentAddr(v); sqlite4ReleaseTempRange(pParse, iReg, nConstraint+2); sqlite4ExprCachePop(pParse, 1); }else #endif /* SQLITE4_OMIT_VIRTUALTABLE */ if( pLoop->wsFlags & WHERE_INDEXED ){ /* Case 4: A scan using an index. ** ** The WHERE clause may contain zero or more equality ** terms ("==" or "IN" operators) that refer to the N ** left-most columns of the index. It may also contain ** inequality constraints (>, <, >= or <=) on the indexed |
︙ | ︙ | |||
3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 | } /* Loop through table entries that match term pOrTerm. */ pSubWInfo = sqlite4WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY | WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY, iCovCur); assert( pSubWInfo || pParse->nErr || pParse->db->mallocFailed ); if( pSubWInfo ){ explainOneScan( pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0 ); if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ int iSet = ((ii==pOrWc->nTerm-1)?-1:ii); sqlite4VdbeAddOp2(v, OP_RowKey, iCur, regKey); sqlite4VdbeAddOp4Int(v, OP_RowSetTest, regKeyset, | > | 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 | } /* Loop through table entries that match term pOrTerm. */ pSubWInfo = sqlite4WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY | WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY, iCovCur); assert( pSubWInfo || pParse->nErr || pParse->db->mallocFailed ); if( pSubWInfo ){ WhereLoop *pSubLoop; explainOneScan( pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0 ); if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ int iSet = ((ii==pOrWc->nTerm-1)?-1:ii); sqlite4VdbeAddOp2(v, OP_RowKey, iCur, regKey); sqlite4VdbeAddOp4Int(v, OP_RowSetTest, regKeyset, |
︙ | ︙ | |||
3975 3976 3977 3978 3979 3980 3981 | ** If the call to sqlite4WhereBegin() above resulted in a scan that ** uses an index, and this is either the first OR-connected term ** processed or the index is the same as that used by all previous ** terms, set pCov to the candidate covering index. Otherwise, set ** pCov to NULL to indicate that no candidate covering index will ** be available. */ | < < > > > < | > | > > < < < | > > | 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 | ** If the call to sqlite4WhereBegin() above resulted in a scan that ** uses an index, and this is either the first OR-connected term ** processed or the index is the same as that used by all previous ** terms, set pCov to the candidate covering index. Otherwise, set ** pCov to NULL to indicate that no candidate covering index will ** be available. */ pSubLoop = pSubWInfo->a[0].pWLoop; assert( (pSubLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0 && (ii==0 || pSubLoop->u.btree.pIndex==pCov) ){ pCov = pSubLoop->u.btree.pIndex; assert( pCov->eIndexType==SQLITE4_INDEX_PRIMARYKEY || pSubWInfo->a[0].iIdxCur==iCovCur ); }else{ pCov = 0; } /* Finish the loop through table entries that match term pOrTerm. */ sqlite4WhereEnd(pSubWInfo); } } } assert( pLevel->u.pCovidx==0 ); if( pCov && pCov->eIndexType!=SQLITE4_INDEX_PRIMARYKEY ){ pLevel->iIdxCur = iCovCur; pLevel->u.pCovidx = pCov; } if( pAndExpr ){ pAndExpr->pLeft = 0; sqlite4ExprDelete(pParse->db, pAndExpr); } sqlite4VdbeChangeP1(v, iRetInit, sqlite4VdbeCurrentAddr(v)); sqlite4VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk); sqlite4VdbeResolveLabel(v, iLoopBody); if( pWInfo->nLevel>1 ) sqlite4StackFree(pParse->db, pOrTab); if( !untestedTerms ) disableTerm(pLevel, pTerm); }else #endif /* SQLITE4_OMIT_OR_OPTIMIZATION */ { /* Case 6: There is no usable index. We must do a complete ** scan of the entire table. This comes up when scanning ** through b-trees containing materialized sub-queries or ** views. */ static const u8 aStep[] = { OP_Next, OP_Prev }; static const u8 aStart[] = { OP_Rewind, OP_Last }; assert( bRev==0 || bRev==1 ); pLevel->op = aStep[bRev]; pLevel->p1 = iCur; pLevel->p2 = 1 + sqlite4VdbeAddOp2(v, aStart[bRev], iCur, addrBrk); |
︙ | ︙ | |||
4981 4982 4983 4984 4985 4986 4987 | && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0 ){ WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc; WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm]; WhereTerm *pOrTerm; int once = 1; int i, j; | | < < | | | 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 | && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0 ){ WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc; WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm]; WhereTerm *pOrTerm; int once = 1; int i, j; pItem = pWInfo->pTabList->a + pNew->iTab; iCur = pItem->iCursor; sSubBuild = *pBuilder; sSubBuild.pOrderBy = 0; sSubBuild.pOrSet = &sCur; for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){ if( (pOrTerm->eOperator & WO_AND)!=0 ){ sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc; }else if( pOrTerm->leftCursor==iCur ){ tempWC.pWInfo = pWC->pWInfo; tempWC.pOuter = pWC; tempWC.op = TK_AND; tempWC.nTerm = 1; tempWC.a = pOrTerm; sSubBuild.pWC = &tempWC; }else{ continue; } sCur.n = 0; #ifndef SQLITE4_OMIT_VIRTUALTABLE if( IsVirtual(pItem->pTab) ){ rc = whereLoopAddVirtual(&sSubBuild); for(i=0; i<sCur.n; i++) sCur.a[i].prereq |= mExtra; }else #endif { rc = whereLoopAddBtree(&sSubBuild, mExtra); } assert( rc==SQLITE4_OK || sCur.n==0 ); if( sCur.n==0 ){ sSum.n = 0; break; }else if( once ){ whereOrMove(&sSum, &sCur); once = 0; }else{ whereOrMove(&sPrev, &sSum); sSum.n = 0; for(i=0; i<sPrev.n; i++){ for(j=0; j<sCur.n; j++){ whereOrInsert(&sSum, sPrev.a[i].prereq | sCur.a[j].prereq, whereCostAdd(sPrev.a[i].rRun, sCur.a[j].rRun), whereCostAdd(sPrev.a[i].nOut, sCur.a[j].nOut)); } } } } pNew->nLTerm = 1; pNew->aLTerm[0] = pTerm; pNew->wsFlags = WHERE_MULTI_OR; |
︙ | ︙ | |||
5049 5050 5051 5052 5053 5054 5055 | pNew->prereq = sSum.a[i].prereq; rc = whereLoopInsert(pBuilder, pNew); } } } return rc; } | < | 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 | pNew->prereq = sSum.a[i].prereq; rc = whereLoopInsert(pBuilder, pNew); } } } return rc; } /* ** Add all WhereLoop objects for all tables */ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ WhereInfo *pWInfo = pBuilder->pWInfo; Bitmask mExtra = 0; |
︙ | ︙ | |||
5217 5218 5219 5220 5221 5222 5223 | if( sqlite4_stricmp(z1, z2)!=0 ) continue; } obSat |= MASKBIT(i); } if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){ Index *pPk = 0; | < < < < < < | 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 | if( sqlite4_stricmp(z1, z2)!=0 ) continue; } obSat |= MASKBIT(i); } if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){ Index *pPk = 0; if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){ return 0; }else{ isOrderDistinct = pIndex->onError!=OE_None; pPk = sqlite4FindPrimaryKey(pIndex->pTable, 0); nColumn = idxColumnCount(pIndex, pPk); } |
︙ | ︙ | |||
6091 6092 6093 6094 6095 6096 6097 | #endif if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){ int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead; sqlite4OpenPrimaryKey(pParse, pTabItem->iCursor, iDb, pTab, op); testcase( !pWInfo->okOnePass && pTab->nCol==BMS-1 ); testcase( !pWInfo->okOnePass && pTab->nCol==BMS ); | < < < < < < < < | < < < < < < < | 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 | #endif if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){ int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead; sqlite4OpenPrimaryKey(pParse, pTabItem->iCursor, iDb, pTab, op); testcase( !pWInfo->okOnePass && pTab->nCol==BMS-1 ); testcase( !pWInfo->okOnePass && pTab->nCol==BMS ); } #ifndef SQLITE4_OMIT_AUTOMATIC_INDEX if( (pLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){ constructAutomaticIndex(pParse, &pWInfo->sWC, pTabItem, notReady, pLevel); }else #endif if( pLoop->wsFlags & WHERE_INDEXED ){ Index *pIx = pLoop->u.btree.pIndex; |
︙ | ︙ |