From: drh Date: Tue, 6 Apr 2010 18:28:20 +0000 (+0000) Subject: Progress toward getting automatic indices to work. Still failing in corner X-Git-Tag: version-3.7.2~489^2~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=424aab88ca04ba20a9c760d299d8d221f56cd8fc;p=thirdparty%2Fsqlite.git Progress toward getting automatic indices to work. Still failing in corner cases. FossilOrigin-Name: ac6d0fba78eb9dcd69372e128d4a039aaff4b417 --- diff --git a/manifest b/manifest index 622a5c334d..0b103a9209 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Automatically\sgenerate\stransient\sindices\sfor\stables\sin\sjoins\sthat\swould\notherwise\shave\sto\suse\sa\sfull\stable\sscan. -D 2010-04-06T15:57:05 +C Progress\stoward\sgetting\sautomatic\sindices\sto\swork.\s\sStill\sfailing\sin\scorner\ncases. +D 2010-04-06T18:28:21 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 4f2f967b7e58a35bb74fb7ec8ae90e0f4ca7868b F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -224,7 +224,7 @@ F src/vdbemem.c 2a82f455f6ca6f78b59fb312f96054c04ae0ead1 F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2 F src/vtab.c a0f8a40274e4261696ef57aa806de2776ab72cda F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c 31a93f75fe2f0bfb41013c12ebe4b614a16b7a47 +F src/where.c 4112c8011c638fa1fbf8d187323045eab87f8ca4 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 14165b3e32715b700b5f0cbf8f6e3833dda0be45 @@ -797,18 +797,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 8e1d7ef47f643503aa823d9986a931a83c63648b -R c3a498c4dea21e46007d85650f9619c4 -T *bgcolor * #c0ffc0 -T *branch * experimental -T *sym-experimental * -T -sym-trunk * +P 1b2a04125f964e14f3fb90171c5ab86a0641d1c9 +R 433fe0cd5ce154376aec2fb36719f0c2 U drh -Z 743c66884ea969285e0481b1f9ac3453 +Z cec6b182a87eaa16fdbd37972b0b02d2 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFLu1nVoxKgR168RlERAiZgAJ9KZKlXqjE3tTVU4jPro4jOsxmJOACfV5Zr -zSYpRUw3ZJ23jK06IGLM6Yk= -=lnkH +iD8DBQFLu31IoxKgR168RlERApyUAJwL/bHa+2HOhBjl9MyxsO3K4nUTUACfVW6y +jbuOBT0KqSbZOrc09LW9uY8= +=l9KV -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index dba8430c6c..23f228fb77 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1b2a04125f964e14f3fb90171c5ab86a0641d1c9 \ No newline at end of file +ac6d0fba78eb9dcd69372e128d4a039aaff4b417 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 10121c4e3d..49d536432c 100644 --- a/src/where.c +++ b/src/where.c @@ -1657,6 +1657,7 @@ static void bestTransientIndex( double costTempIdx; /* per-query cost of the transient index */ WhereTerm *pTerm; /* A single term of the WHERE clause */ WhereTerm *pWCEnd; /* End of pWC->a[] */ + Table *pTable; /* Table tht might be indexed */ if( (pCost->plan.wsFlags & WHERE_NOT_FULLSCAN)!=0 ){ /* We already have some kind of index in use for this query. */ @@ -1678,11 +1679,14 @@ static void bestTransientIndex( } /* Search for any equality comparison term */ + pTable = pSrc->pTab; pWCEnd = &pWC->a[pWC->nTerm]; for(pTerm=pWC->a; pTermleftCursor==pSrc->iCursor && (pTerm->prereqRight & notReady)==0 && (pTerm->eOperator & WO_EQ)!=0 + && sqlite3IndexAffinityOk(pTerm->pExpr, + pTable->aCol[pTerm->u.leftColumn].affinity) ){ WHERETRACE(("auto-index reduces cost from %.2f to %.2f\n", pCost->rCost, costTempIdx)); @@ -1719,6 +1723,7 @@ static void constructTransientIndex( int addrTop; /* Top of the index fill loop */ int regRecord; /* Register holding an index record */ int n; /* Column counter */ + CollSeq *pColl; /* Collating sequence to on a column */ /* Generate code to skip over the creation and initialization of the ** transient index on 2nd and subsequent iterations of the loop. */ @@ -1730,16 +1735,21 @@ static void constructTransientIndex( /* Count the number of columns that will be added to the index */ nColumn = 0; + pTable = pSrc->pTab; pWCEnd = &pWC->a[pWC->nTerm]; for(pTerm=pWC->a; pTermleftCursor==pSrc->iCursor && (pTerm->prereqRight & notReady)==0 && (pTerm->eOperator & WO_EQ)!=0 + && sqlite3IndexAffinityOk(pTerm->pExpr, + pTable->aCol[pTerm->u.leftColumn].affinity) ){ nColumn++; } } assert( nColumn>0 ); + pLevel->plan.nEq = nColumn; + pLevel->plan.wsFlags = WHERE_COLUMN_EQ | WO_EQ; /* Construct the Index object to describe this index */ nByte = sizeof(Index); @@ -1754,17 +1764,21 @@ static void constructTransientIndex( pIdx->aSortOrder = (u8*)&pIdx->aiColumn[nColumn]; pIdx->zName = "auto-index"; pIdx->nColumn = nColumn; - pIdx->pTable = pTable = pSrc->pTab; + pIdx->pTable = pTable; n = 0; for(pTerm=pWC->a; pTermleftCursor==pSrc->iCursor && (pTerm->prereqRight & notReady)==0 && (pTerm->eOperator & WO_EQ)!=0 + && sqlite3IndexAffinityOk(pTerm->pExpr, + pTable->aCol[pTerm->u.leftColumn].affinity) ){ int iCol = pTerm->u.leftColumn; + Expr *pX; pIdx->aiColumn[n] = iCol; - pIdx->azColl[n] = pTable->aCol[iCol].zColl; - if( pIdx->azColl[n]==0 ) pIdx->azColl[n] = "BINARY"; + pX = pTerm->pExpr; + pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight); + pIdx->azColl[n] = pColl->zName; n++; } } @@ -1775,6 +1789,7 @@ static void constructTransientIndex( assert( pLevel->iIdxCur>=0 ); sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pLevel->iIdxCur, nColumn+1, 0, (char*)pKeyinfo, P4_KEYINFO_HANDOFF); + VdbeComment((v, "auto-idx for %s", pTable->zName)); /* Fill the transient index with content */ addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); @@ -4060,8 +4075,14 @@ WhereInfo *sqlite3WhereBegin( #endif /* SQLITE_OMIT_EXPLAIN */ pTabItem = &pTabList->a[pLevel->iFrom]; pTab = pTabItem->pTab; + pLevel->iTabCur = pTabItem->iCursor; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ) continue; + if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){ + if( pLevel->plan.wsFlags & WHERE_TEMP_INDEX ){ + constructTransientIndex(pParse, pWC, pTabItem, notReady, pLevel); + } + continue; + } #ifndef SQLITE_OMIT_VIRTUALTABLE if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){ const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); @@ -4084,7 +4105,6 @@ WhereInfo *sqlite3WhereBegin( }else{ sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); } - pLevel->iTabCur = pTabItem->iCursor; if( (pLevel->plan.wsFlags & WHERE_TEMP_INDEX)!=0 ){ constructTransientIndex(pParse, pWC, pTabItem, notReady, pLevel); }else if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){