Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Further updates to ngqp code. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | nextgen-query-planner |
Files: | files | file ages | folders |
SHA1: |
9844269b3d3729972ccd31c1cb61cb69 |
User & Date: | dan 2013-07-17 18:49:27 |
Context
2013-07-17
| ||
20:03 | Fix a bug preventing the planner from finding sorting indexes. check-in: 6f06ebee56 user: dan tags: nextgen-query-planner | |
18:49 | Further updates to ngqp code. check-in: 9844269b3d user: dan tags: nextgen-query-planner | |
2013-07-16
| ||
20:01 | Updates to use the next-generation-query-planner from the SQLite3 project. This branch is largely broken. check-in: bc9c9f73c5 user: dan tags: nextgen-query-planner | |
Changes
Changes to src/where.c.
933 933 if( iIdxCol<pIdx->nColumn ){ 934 934 iRet = pIdx->aiColumn[iIdxCol]; 935 935 }else if( pPk && iIdxCol<(pIdx->nColumn + pPk->nColumn) ){ 936 936 iRet = pPk->aiColumn[iIdxCol - pIdx->nColumn]; 937 937 } 938 938 return iRet; 939 939 } 940 + 941 +/* 942 +** Return a pointer to a buffer containing the name of the collation 943 +** sequence used with the iIdxCol'th field in index pIdx, including any 944 +** appended PRIMARY KEY fields. 945 +*/ 946 +static char *idxColumnCollation(Index *pIdx, Index *pPk, int iIdxCol){ 947 + char *zColl; 948 + assert( iIdxCol<(pIdx->nColumn + pPk->nColumn) ); 949 + if( iIdxCol<pIdx->nColumn ){ 950 + zColl = pIdx->azColl[iIdxCol]; 951 + }else if( pPk && iIdxCol<(pIdx->nColumn + pPk->nColumn) ){ 952 + zColl = pPk->azColl[iIdxCol - pIdx->nColumn]; 953 + } 954 + return zColl; 955 +} 940 956 941 957 /* 942 958 ** Return the total number of fields in the index pIdx, including any 943 959 ** trailing primary key fields. 944 960 */ 945 961 static int idxColumnCount(Index *pIdx, Index *pPk){ 946 962 return (pIdx->nColumn + (pIdx==pPk ? 0 : pPk->nColumn)); ................................................................................ 977 993 pScan->pWC = pWC; 978 994 if( pIdx && iColumn>=0 ){ 979 995 Index *pPk = sqlite4FindPrimaryKey(pIdx->pTable, 0); 980 996 pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity; 981 997 for(j=0; idxColumnNumber(pIdx, pPk, j)!=iColumn; j++){ 982 998 if( NEVER(j>=idxColumnCount(pIdx, pPk)) ) return 0; 983 999 } 984 - pScan->zCollName = pIdx->azColl[j]; 1000 + pScan->zCollName = idxColumnCollation(pIdx, pPk, j); 985 1001 }else{ 986 1002 pScan->idxaff = 0; 987 1003 pScan->zCollName = 0; 988 1004 } 989 1005 pScan->opMask = opMask; 990 1006 pScan->k = 0; 991 1007 pScan->aEquiv[0] = iCur; ................................................................................ 3019 3035 zAff = sqlite4DbStrDup(pParse->db, sqlite4IndexAffinityStr(v, pIdx)); 3020 3036 if( !zAff ){ 3021 3037 pParse->db->mallocFailed = 1; 3022 3038 } 3023 3039 3024 3040 /* Evaluate the equality constraints 3025 3041 */ 3026 - assert( pIdx->nColumn>=nEq ); 3042 + assert( idxColumnCount(pIdx, sqlite4FindPrimaryKey(pIdx->pTable, 0))>=nEq ); 3027 3043 for(j=0; j<nEq; j++){ 3028 3044 int r1; 3029 3045 pTerm = pLoop->aLTerm[j]; 3030 3046 assert( pTerm!=0 ); 3031 3047 /* The following true for indices with redundant columns. 3032 3048 ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */ 3033 3049 testcase( (pTerm->wtFlags & TERM_CODED)!=0 ); ................................................................................ 3750 3766 */ 3751 3767 WhereClause *pOrWc; /* The OR-clause broken out into subterms */ 3752 3768 SrcList *pOrTab; /* Shortened table list or OR-clause generation */ 3753 3769 Index *pCov = 0; /* Potential covering index (or NULL) */ 3754 3770 int iCovCur = pParse->nTab++; /* Cursor used for index scans (if any) */ 3755 3771 3756 3772 int regReturn = ++pParse->nMem; /* Register used with OP_Gosub */ 3757 - int regRowset = 0; /* Register for RowSet object */ 3758 - int regRowid = 0; /* Register holding rowid */ 3773 + int regKeyset = 0; /* Register for RowSet object */ 3774 + int regKey = 0; /* Register holding key */ 3759 3775 int iLoopBody = sqlite4VdbeMakeLabel(v); /* Start of loop body */ 3760 3776 int iRetInit; /* Address of regReturn init */ 3761 3777 int untestedTerms = 0; /* Some terms not completely tested */ 3762 3778 int ii; /* Loop counter */ 3763 3779 Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ 3764 3780 3765 3781 pTerm = pLoop->aLTerm[0]; ................................................................................ 3788 3804 for(k=1; k<=nNotReady; k++){ 3789 3805 memcpy(&pOrTab->a[k], &origSrc[pLevel[k].iFrom], sizeof(pOrTab->a[k])); 3790 3806 } 3791 3807 }else{ 3792 3808 pOrTab = pWInfo->pTabList; 3793 3809 } 3794 3810 3795 - /* Initialize the rowset register to contain NULL. An SQL NULL is 3796 - ** equivalent to an empty rowset. 3811 + /* Initialize the keyset register to contain NULL. An SQL NULL is 3812 + ** equivalent to an empty keyset. 3797 3813 ** 3798 3814 ** Also initialize regReturn to contain the address of the instruction 3799 3815 ** immediately following the OP_Return at the bottom of the loop. This 3800 3816 ** is required in a few obscure LEFT JOIN cases where control jumps 3801 3817 ** over the top of the loop into the body of it. In this case the 3802 3818 ** correct response for the end-of-loop code (the OP_Return) is to 3803 3819 ** fall through to the next instruction, just as an OP_Next does if 3804 3820 ** called on an uninitialized cursor. 3805 3821 */ 3806 3822 if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ 3807 - regRowset = ++pParse->nMem; 3808 - regRowid = ++pParse->nMem; 3809 - sqlite4VdbeAddOp2(v, OP_Null, 0, regRowset); 3823 + regKeyset = ++pParse->nMem; 3824 + regKey = ++pParse->nMem; 3825 + sqlite4VdbeAddOp2(v, OP_Null, 0, regKeyset); 3810 3826 } 3811 3827 iRetInit = sqlite4VdbeAddOp2(v, OP_Integer, 0, regReturn); 3812 3828 3813 3829 /* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y 3814 3830 ** Then for every term xN, evaluate as the subexpression: xN AND z 3815 3831 ** That way, terms in y that are factored into the disjunction will 3816 3832 ** be picked up by the recursive calls to sqlite4WhereBegin() below. ................................................................................ 3856 3872 if( pSubWInfo ){ 3857 3873 WhereLoop *pSubLoop; 3858 3874 explainOneScan( 3859 3875 pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0 3860 3876 ); 3861 3877 if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ 3862 3878 int iSet = ((ii==pOrWc->nTerm-1)?-1:ii); 3863 - int r; 3864 - r = sqlite4ExprCodeGetColumn(pParse, pTabItem->pTab, -1, iCur, 3865 - regRowid); 3866 - sqlite4VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 3867 - sqlite4VdbeCurrentAddr(v)+2, r, iSet); 3879 + sqlite4VdbeAddOp2(v, OP_RowKey, iCur, regKey); 3880 + sqlite4VdbeAddOp4Int(v, OP_RowSetTest, regKeyset, 3881 + sqlite4VdbeCurrentAddr(v)+2, regKey, iSet); 3868 3882 } 3869 3883 sqlite4VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody); 3870 3884 3871 3885 /* The pSubWInfo->untestedTerms flag means that this OR term 3872 3886 ** contained one or more AND term from a notReady table. The 3873 3887 ** terms from the notReady table could not be tested and will 3874 3888 ** need to be tested later. ................................................................................ 3883 3897 ** If the call to sqlite4WhereBegin() above resulted in a scan that 3884 3898 ** uses an index, and this is either the first OR-connected term 3885 3899 ** processed or the index is the same as that used by all previous 3886 3900 ** terms, set pCov to the candidate covering index. Otherwise, set 3887 3901 ** pCov to NULL to indicate that no candidate covering index will 3888 3902 ** be available. 3889 3903 */ 3904 +#if 0 3890 3905 pSubLoop = pSubWInfo->a[0].pWLoop; 3891 3906 assert( (pSubLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); 3892 3907 if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0 3893 3908 && (ii==0 || pSubLoop->u.btree.pIndex==pCov) 3894 3909 ){ 3895 3910 assert( pSubWInfo->a[0].iIdxCur==iCovCur ); 3896 3911 pCov = pSubLoop->u.btree.pIndex; 3897 3912 }else{ 3898 3913 pCov = 0; 3899 3914 } 3915 +#endif 3900 3916 3901 3917 /* Finish the loop through table entries that match term pOrTerm. */ 3902 3918 sqlite4WhereEnd(pSubWInfo); 3903 3919 } 3904 3920 } 3905 3921 } 3906 3922 pLevel->u.pCovidx = pCov; ................................................................................ 4179 4195 ** (5) The template uses more terms of the same index but has no additional 4180 4196 ** dependencies 4181 4197 */ 4182 4198 static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ 4183 4199 WhereLoop **ppPrev, *p, *pNext = 0; 4184 4200 WhereInfo *pWInfo = pBuilder->pWInfo; 4185 4201 sqlite4 *db = pWInfo->pParse->db; 4202 + 4203 + assert( pTemplate->u.btree.pIndex || !(pTemplate->wsFlags & WHERE_INDEXED) ); 4186 4204 4187 4205 /* If pBuilder->pBest is defined, then only keep track of the single 4188 4206 ** best WhereLoop. pBuilder->pBest->maskSelf==0 indicates that no 4189 4207 ** prior WhereLoops have been evaluated and that the current pTemplate 4190 4208 ** is therefore the first and hence the best and should be retained. 4191 4209 */ 4192 4210 if( (p = pBuilder->pBest)!=0 ){ ................................................................................ 4611 4629 pNew->wsFlags = WHERE_AUTO_INDEX; 4612 4630 pNew->prereq = mExtra | pTerm->prereqRight; 4613 4631 rc = whereLoopInsert(pBuilder, pNew); 4614 4632 } 4615 4633 } 4616 4634 } 4617 4635 #endif /* ifndef SQLITE4_OMIT_AUTOMATIC_INDEX */ 4636 + 4637 + /* If this table has no primary key, then it is either a materialized 4638 + ** view or ephemeral table. Either way, add an entry for a full-scan 4639 + ** of it. */ 4640 + if( pPk==0 ){ 4641 + assert( pSrc->pTab->pSelect || (pSrc->pTab->tabFlags & TF_Ephemeral) ); 4642 + pNew->u.btree.nEq = 0; 4643 + pNew->nLTerm = 0; 4644 + pNew->iSortIdx = 0; 4645 + pNew->rSetup = 0; 4646 + pNew->prereq = mExtra; 4647 + pNew->nOut = rSize; 4648 + pNew->u.btree.pIndex = 0; 4649 + pNew->iSortIdx = 0; 4650 + pNew->wsFlags = 0; 4651 + pNew->rRun = whereCostAdd(rSize,rLogSize) + 16; 4652 + rc = whereLoopInsert(pBuilder, pNew); 4653 + } 4618 4654 4619 4655 /* Loop through the set of indices being considered. */ 4620 4656 for(; rc==SQLITE4_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){ 4621 4657 4622 4658 if( pProbe->eIndexType==SQLITE4_INDEX_FTS5 ) continue; 4623 4659 4624 4660 pNew->u.btree.nEq = 0;