From: drh Date: Fri, 28 Jun 2013 21:12:20 +0000 (+0000) Subject: Add the SQLITE_DEFAULT_AUTOMATIC_INDEX compile-time option, which if set to X-Git-Tag: version-3.8.0~116 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=986b38792f248b7baf0993a80ce340d2c604a74b;p=thirdparty%2Fsqlite.git Add the SQLITE_DEFAULT_AUTOMATIC_INDEX compile-time option, which if set to zero turns automatic indices off by default. Increase the estimated cost of an automatic index. Additional minor refactoring of the automatic index code. FossilOrigin-Name: 459b3179023c2c45994ea4acbf34ed5f87cf3c18 --- diff --git a/manifest b/manifest index da7be84798..bce73f24e9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sread\stransactions\sto\sbe\sfreely\sopened\sand\sclosed\sby\sSQL\sstatements\srun\sfrom\swithin\sthe\simplementation\sof\suser-functions\sif\sthe\suser-function\sis\scalled\sby\sa\sSELECT\sstatement\sthat\sdoes\snot\saccess\sany\sdatabase\stables\s(e.g.\s"SELECT\suser_function();"). -D 2013-06-28T19:41:43.617 +C Add\sthe\sSQLITE_DEFAULT_AUTOMATIC_INDEX\scompile-time\soption,\swhich\sif\sset\sto\nzero\sturns\sautomatic\sindices\soff\sby\sdefault.\s\sIncrease\sthe\sestimated\scost\nof\san\sautomatic\sindex.\s\sAdditional\sminor\srefactoring\sof\sthe\sautomatic\nindex\scode. +D 2013-06-28T21:12:20.682 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -185,7 +185,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c c48f7f3f170e502fe0cc20748e03c6e0b5a016c2 -F src/main.c fd167de59452bfcca2cba41ac6d484ddcbb7a105 +F src/main.c 648aea1fdd88d9f04367b325129a33609d933f5d F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa @@ -290,7 +290,7 @@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83 F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73 -F src/where.c e110b9efa3a8d21e3bb1a681a5051f0a1d723954 +F src/where.c b0cdc92ae0aeaed2aca53bcd5bcde0a83743d153 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -323,7 +323,7 @@ F test/auth.test 4a4c3b034fff7750513520defa910f376c96ab49 F test/auth2.test a2a371aa6df15f8b0c8109b33d3d7f0f73e4c9aa F test/auth3.test a4755e6a2a2fea547ffe63c874eb569e60a28eb5 F test/autoinc.test bd30d372d00045252f6c2e41b5f41455e1975acf -F test/autoindex1.test 314f12f87667861ac965c41587f9df82c42fff65 +F test/autoindex1.test e19269b74a6f55975a4f2453778f6ef524fd88c9 F test/autovacuum.test 9f22a7733f39c56ef6a5665d10145ac25d8cb574 F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4 F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85 @@ -1098,7 +1098,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 60c19b86797fb8a37f175545929883ebeff7f307 -R 02f6793a0a52da2c43e4543693db9443 -U dan -Z b5c7fa88cc274e57375060b2c2c8b229 +P f308c4851726b4b75636f714466f2314f56e3ec0 +R 4380a773ef3ea80daacb5f7d2d9f9d84 +U drh +Z 670c2d71707208c8f107ef52a342b6f3 diff --git a/manifest.uuid b/manifest.uuid index 9b4d00ace3..a0133200d0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f308c4851726b4b75636f714466f2314f56e3ec0 \ No newline at end of file +459b3179023c2c45994ea4acbf34ed5f87cf3c18 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 831f99c701..5323a6ce7a 100644 --- a/src/main.c +++ b/src/main.c @@ -2451,7 +2451,10 @@ static int openDatabase( db->nextAutovac = -1; db->szMmap = sqlite3GlobalConfig.szMmap; db->nextPagesize = 0; - db->flags |= SQLITE_ShortColNames | SQLITE_AutoIndex | SQLITE_EnableTrigger + db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger +#if !defined(SQLITE_DEAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX + | SQLITE_AutoIndex +#endif #if SQLITE_DEFAULT_FILE_FORMAT<4 | SQLITE_LegacyFileFmt #endif diff --git a/src/where.c b/src/where.c index 7fdfa1a7f7..144e2c834b 100644 --- a/src/where.c +++ b/src/where.c @@ -444,7 +444,7 @@ struct WhereInfo { #define WHERE_IN_ABLE 0x00000800 /* Able to support an IN operator */ #define WHERE_ONEROW 0x00001000 /* Selects no more than one row */ #define WHERE_MULTI_OR 0x00002000 /* OR using multiple indices */ -#define WHERE_TEMP_INDEX 0x00004000 /* Uses an ephemeral index */ +#define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */ /* Convert a WhereCost value (10 times log2(X)) into its integer value X. @@ -2072,7 +2072,7 @@ static void constructAutomaticIndex( assert( nColumn>0 ); pLoop->u.btree.nEq = pLoop->nLTerm = nColumn; pLoop->wsFlags = WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WHERE_INDEXED - | WHERE_TEMP_INDEX; + | WHERE_AUTO_INDEX; /* Count the number of additional columns needed to create a ** covering index. A "covering index" is an index that contains all @@ -3118,13 +3118,12 @@ static void explainOneScan( && ALWAYS(pLoop->u.btree.pIndex!=0) ){ char *zWhere = explainIndexRange(db, pLoop, pItem->pTab); - zMsg = sqlite3MAppendf(db, zMsg, "%s USING %s%sINDEX%s%s%s", zMsg, - ((flags & WHERE_TEMP_INDEX)?"AUTOMATIC ":""), - ((flags & WHERE_IDX_ONLY)?"COVERING ":""), - ((flags & WHERE_TEMP_INDEX)?"":" "), - ((flags & WHERE_TEMP_INDEX)?"": pLoop->u.btree.pIndex->zName), - zWhere - ); + zMsg = sqlite3MAppendf(db, zMsg, + ((flags & WHERE_AUTO_INDEX) ? + "%s USING AUTOMATIC %sINDEX%.0s%s" : + "%s USING %sINDEX %s%s"), + zMsg, ((flags & WHERE_IDX_ONLY) ? "COVERING " : ""), + pLoop->u.btree.pIndex->zName, zWhere); sqlite3DbFree(db, zWhere); }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){ zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg); @@ -3795,7 +3794,7 @@ static Bitmask codeOneLoopStart( ** be available. */ pSubLoop = pSubWInfo->a[0].pWLoop; - assert( (pSubLoop->wsFlags & WHERE_TEMP_INDEX)==0 ); + assert( (pSubLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0 && (ii==0 || pSubLoop->u.btree.pIndex==pCov) ){ @@ -3977,12 +3976,12 @@ static void whereLoopInit(WhereLoop *p){ ** Clear the WhereLoop.u union. Leave WhereLoop.pLTerm intact. */ static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){ - if( p->wsFlags & (WHERE_VIRTUALTABLE|WHERE_TEMP_INDEX) ){ + if( p->wsFlags & (WHERE_VIRTUALTABLE|WHERE_AUTO_INDEX) ){ if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 && p->u.vtab.needFree ){ sqlite3_free(p->u.vtab.idxStr); p->u.vtab.needFree = 0; p->u.vtab.idxStr = 0; - }else if( (p->wsFlags & WHERE_TEMP_INDEX)!=0 && p->u.btree.pIndex!=0 ){ + }else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){ sqlite3DbFree(db, p->u.btree.pIndex->zColAff); sqlite3DbFree(db, p->u.btree.pIndex); p->u.btree.pIndex = 0; @@ -4025,7 +4024,7 @@ static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){ memcpy(pTo->aLTerm, pFrom->aLTerm, pTo->nLTerm*sizeof(pTo->aLTerm[0])); if( pFrom->wsFlags & WHERE_VIRTUALTABLE ){ pFrom->u.vtab.needFree = 0; - }else if( (pFrom->wsFlags & WHERE_TEMP_INDEX)!=0 ){ + }else if( (pFrom->wsFlags & WHERE_AUTO_INDEX)!=0 ){ pFrom->u.btree.pIndex = 0; } return SQLITE_OK; @@ -4498,13 +4497,16 @@ static int whereLoopAddBtree( pNew->nLTerm = 1; pNew->aLTerm[0] = pTerm; /* TUNING: One-time cost for computing the automatic index is - ** approximately 6*N*log2(N) where N is the number of rows in + ** approximately 7*N*log2(N) where N is the number of rows in ** the table being indexed. */ - pNew->rSetup = rLogSize + rSize + 26; assert( 26==whereCost(6) ); - /* TUNING: Each index lookup yields 10 rows in the table */ - pNew->nOut = 33; assert( 33==whereCost(10) ); + pNew->rSetup = rLogSize + rSize + 28; assert( 28==whereCost(7) ); + /* TUNING: Each index lookup yields 20 rows in the table. This + ** is more than the usual guess of 10 rows, since we have no way + ** of knowning how selective the index will ultimately be. It would + ** not be unreasonable to make this value much larger. */ + pNew->nOut = 43; assert( 43==whereCost(20) ); pNew->rRun = whereCostAdd(rLogSize,pNew->nOut); - pNew->wsFlags = WHERE_TEMP_INDEX; + pNew->wsFlags = WHERE_AUTO_INDEX; pNew->prereq = mExtra | pTerm->prereqRight; rc = whereLoopInsert(pBuilder, pNew); } @@ -5881,7 +5883,7 @@ WhereInfo *sqlite3WhereBegin( sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); } #ifndef SQLITE_OMIT_AUTOMATIC_INDEX - if( (pLoop->wsFlags & WHERE_TEMP_INDEX)!=0 ){ + if( (pLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){ constructAutomaticIndex(pParse, &pWInfo->sWC, pTabItem, notReady, pLevel); }else #endif @@ -6004,7 +6006,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){ sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor); } - if( (ws & WHERE_INDEXED)!=0 && (ws & (WHERE_IPK|WHERE_TEMP_INDEX))==0 ){ + if( (ws & WHERE_INDEXED)!=0 && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0 ){ sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur); } } diff --git a/test/autoindex1.test b/test/autoindex1.test index f8f1d9e7c0..3e08a527bc 100644 --- a/test/autoindex1.test +++ b/test/autoindex1.test @@ -94,9 +94,15 @@ do_test autoindex1-212 { # Modify the second table of the join while the join is in progress # +do_execsql_test autoindex1-299 { + UPDATE sqlite_stat1 SET stat='10000' WHERE tbl='t2'; + ANALYZE sqlite_master; + EXPLAIN QUERY PLAN + SELECT b, d FROM t1 CROSS JOIN t2 ON (c=a); +} {/AUTOMATIC COVERING INDEX/} do_test autoindex1-300 { set r {} - db eval {SELECT b, d FROM t1 JOIN t2 ON (c=a)} { + db eval {SELECT b, d FROM t1 CROSS JOIN t2 ON (c=a)} { lappend r $b $d db eval {UPDATE t2 SET d=d+1} }