From: drh Date: Sat, 23 Jul 2005 03:18:40 +0000 (+0000) Subject: The results of ANALYZE are now loaded into internal data structures where X-Git-Tag: version-3.6.10~3597 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=497e446d76c4a448979d4e3504a24fca07f5192d;p=thirdparty%2Fsqlite.git The results of ANALYZE are now loaded into internal data structures where they can be used. But they are not actually used yet. (CVS 2562) FossilOrigin-Name: 1996bacfb97180965304e2a6d6784b6ecbbf8575 --- diff --git a/manifest b/manifest index 9bed028a6f..194373ad8b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Full-coverage\stesting\sand\sdocumentation\sfor\sthe\sANALYZE\scommand.\s\sThe\nresults\sof\sanalysis\sare\sstill\snot\sloaded\sor\sused,\showever.\s(CVS\s2561) -D 2005-07-23T02:17:03 +C The\sresults\sof\sANALYZE\sare\snow\sloaded\sinto\sinternal\sdata\sstructures\swhere\nthey\scan\sbe\sused.\s\sBut\sthey\sare\snot\sactually\sused\syet.\s(CVS\s2562) +D 2005-07-23T03:18:40 F Makefile.in 22ea9c0fe748f591712d8fe3c6d972c6c173a165 F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -28,12 +28,12 @@ F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.def c413e514217736884254739a105c8c942fdf0c2f F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a F src/alter.c 03041f2464e22532601254f87cb49997fa21dcdf -F src/analyze.c b849c23866b7da98373f7b380f40b2a5f371e962 +F src/analyze.c 443c3449af103145873b6f64d5677df87e5edfdd F src/attach.c 3615dbe960cbee4aa5ea300b8a213dad36527b0f F src/auth.c 18c5a0befe20f3a58a41e3ddd78f372faeeefe1f F src/btree.c ec55bd70052cdd0958f3a0e79ad58d93561acb20 F src/btree.h 41a71ce027db9ddee72cb43df2316bbe3a1d92af -F src/build.c 50e1197f5f70d544dc85b8483766f6194375d04e +F src/build.c 6aec7f0cee28f235aa08bcbeba33e4f68851b681 F src/callback.c 0910b611e0c158f107ee3ff86f8a371654971e2b F src/date.c 7444b0900a28da77e57e3337a636873cff0ae940 F src/delete.c be1fc25c9e109cd8cbab42a43ee696263da7c04b @@ -58,13 +58,13 @@ F src/pager.c ee3bbc4cd590a0266c791b4ed537cbd9a9d03566 F src/pager.h 0d9153d6269d60d04af3dd84a0cc0a96253cf4a4 F src/parse.y d57cdd2adc0923762b40314f08683c836a2e0c90 F src/pragma.c dea86dad2f0e872b29632ae9fba526e539a4ddd8 -F src/prepare.c d53602d2f8e097225ae7c76ec764ae68f759ba47 +F src/prepare.c fa0f6068d9b8ec6d5c419c65d4d8ff747d49c5c6 F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357 F src/random.c 90adff4e73a3b249eb4f1fc2a6ff9cf78c7233a4 F src/select.c c611471052773b94af771693686bd5bcdbbb0dba F src/shell.c 25b3217d7c64e6497225439d261a253a23efff26 F src/sqlite.h.in 7ccf2f61de2a0dca515e73708e561362e6c3d1e3 -F src/sqliteInt.h 2925510c0233bb24c550fc5912fcdf0dd3a4421d +F src/sqliteInt.h ebcf33fa4380cfcb9385bd739037a5445c36fd5a F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9 F src/tclsqlite.c ef3276d0967cc0042bedcc1a7f09e0eb95cd3a8c F src/test1.c 722c1444b5774705eb6eb11163343fc94ffe17f7 @@ -78,7 +78,7 @@ F src/update.c a9d2c5f504212d62da1b094476f1389c0e02f83f F src/utf.c bda5eb85039ef16f2d17004c1e18c96e1ab0a80c F src/util.c 668d31be592753e5b8ea00e69ea8d3eedb29fa22 F src/vacuum.c 829d9e1a6d7c094b80e0899686670932eafd768c -F src/vdbe.c aa8b8d30aa5b1b046a6a5acf502370a064581e09 +F src/vdbe.c 0145d877d0e086d5d4bc28f52552883105373163 F src/vdbe.h 75e466d84d362b0c4498978a9d6b1e6bd32ecf3b F src/vdbeInt.h 9be9a6c43d38124bd03cc5cf05715605b1789fd9 F src/vdbeapi.c 7f392f0792d1258c958083d7de9eae7c3530c9a6 @@ -287,7 +287,7 @@ F www/tclsqlite.tcl 425be741b8ae664f55cb1ef2371aab0a75109cf9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b F www/whentouse.tcl 528299b8316726dbcc5548e9aa0648c8b1bd055b -P a4886b114d2ccb3841d3d219f6b97f67745b13c2 -R 65a6648aca434084253023a9ade3ab6b +P bd7583a5d63412785a9c5de54d25b509da241605 +R fa0725a452365a6cc3e3b5a32a1f47a7 U drh -Z 5c397aa099a763af87ffe475ca34fcef +Z 614161da507000f7e7ba00462a0c3cc8 diff --git a/manifest.uuid b/manifest.uuid index e2842dd2e2..b1edcfa645 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bd7583a5d63412785a9c5de54d25b509da241605 \ No newline at end of file +1996bacfb97180965304e2a6d6784b6ecbbf8575 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index a3f8e84c83..dfe1150e43 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code associated with the ANALYZE command. ** -** @(#) $Id: analyze.c,v 1.3 2005/07/23 02:17:03 drh Exp $ +** @(#) $Id: analyze.c,v 1.4 2005/07/23 03:18:40 drh Exp $ */ #ifndef SQLITE_OMIT_ANALYZE #include "sqliteInt.h" @@ -204,6 +204,15 @@ static void analyzeOneTable( } } +/* +** Generate code that will cause the most recent index analysis to +** be laoded into internal hash tables where is can be used. +*/ +static void loadAnalysis(Parse *pParse, int iDb){ + Vdbe *v = sqlite3GetVdbe(pParse); + sqlite3VdbeAddOp(v, OP_LoadAnalysis, iDb, 0); +} + /* ** Generate code that will do an analysis of an entire database */ @@ -221,6 +230,7 @@ static void analyzeDatabase(Parse *pParse, int iDb){ Table *pTab = (Table*)sqliteHashData(k); analyzeOneTable(pParse, pTab, iStatCur, iMem); } + loadAnalysis(pParse, iDb); } /* @@ -237,6 +247,7 @@ static void analyzeTable(Parse *pParse, Table *pTab){ iStatCur = pParse->nTab++; openStatTable(pParse, iDb, iStatCur, pTab->zName); analyzeOneTable(pParse, pTab, iStatCur, pParse->nMem); + loadAnalysis(pParse, iDb); } /* @@ -299,6 +310,84 @@ void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ } } +/* +** Used to pass information from the analyzer reader through to the +** callback routine. +*/ +typedef struct analysisInfo analysisInfo; +struct analysisInfo { + sqlite3 *db; + const char *zDatabase; +}; + +/* +** This callback is invoked once for each index when reading the +** sqlite_stat1 table. +** +** argv[0] = name of the index +** argv[1] = results of analysis - on integer for each column +*/ +static int analysisLoader(void *pData, int argc, char **argv, char **azNotUsed){ + analysisInfo *pInfo = (analysisInfo*)pData; + Index *pIndex; + int i, c; + unsigned int v; + const char *z; + + assert( argc==2 ); + if( argv[0]==0 || argv[1]==0 ){ + return 0; + } + pIndex = sqlite3FindIndex(pInfo->db, argv[0], pInfo->zDatabase); + if( pIndex==0 ){ + return 0; + } + z = argv[1]; + for(i=0; *z && inColumn; i++){ + v = 0; + while( (c=z[0])>='0' && c<='9' ){ + v = v*10 + c - '0'; + z++; + } + pIndex->aiRowEst[i] = v; + if( *z==' ' ) z++; + } + return 0; +} + +/* +** Load the content of the sqlite_stat1 table into the index hash tables. +*/ +void sqlite3AnalysisLoad(sqlite3 *db, int iDb){ + analysisInfo sInfo; + HashElem *i; + char *zSql; + + /* Clear any prior statistics */ + for(i=sqliteHashFirst(&db->aDb[iDb].idxHash); i; i=sqliteHashNext(i)){ + Index *pIdx = sqliteHashData(i); + int j; + for(j=pIdx->nColumn-1; j>=0; j--){ + pIdx->aiRowEst[j] = 100; + } + } + + /* Check to make sure the sqlite_stat1 table existss */ + sInfo.db = db; + sInfo.zDatabase = db->aDb[iDb].zName; + if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){ + return; + } + + + /* Load new statistics out of the sqlite_stat1 table */ + zSql = sqlite3MPrintf("SELECT idx, stat FROM %Q.sqlite_stat1", + sInfo.zDatabase); + sqlite3SafetyOff(db); + sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); + sqlite3SafetyOn(db); + sqliteFree(zSql); +} #endif /* SQLITE_OMIT_ANALYZE */ diff --git a/src/build.c b/src/build.c index 8c45ff766c..02a5cdd512 100644 --- a/src/build.c +++ b/src/build.c @@ -22,7 +22,7 @@ ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.333 2005/07/23 00:41:49 drh Exp $ +** $Id: build.c,v 1.334 2005/07/23 03:18:40 drh Exp $ */ #include "sqliteInt.h" #include @@ -2180,10 +2180,11 @@ void sqlite3CreateIndex( ** Allocate the index structure. */ pIndex = sqliteMalloc( sizeof(Index) + strlen(zName) + 1 + - (sizeof(int) + sizeof(CollSeq*))*pList->nExpr ); + (sizeof(int)*2 + sizeof(CollSeq*))*pList->nExpr ); if( sqlite3_malloc_failed ) goto exit_create_index; pIndex->aiColumn = (int*)&pIndex->keyInfo.aColl[pList->nExpr]; - pIndex->zName = (char*)&pIndex->aiColumn[pList->nExpr]; + pIndex->aiRowEst = &pIndex->aiColumn[pList->nExpr]; + pIndex->zName = (char*)&pIndex->aiRowEst[pList->nExpr]; strcpy(pIndex->zName, zName); pIndex->pTable = pTab; pIndex->nColumn = pList->nExpr; @@ -2205,6 +2206,7 @@ void sqlite3CreateIndex( goto exit_create_index; } pIndex->aiColumn[i] = j; + pIndex->aiRowEst[i] = 100; if( pList->a[i].pExpr ){ assert( pList->a[i].pExpr->pColl ); pIndex->keyInfo.aColl[i] = pList->a[i].pExpr->pColl; diff --git a/src/prepare.c b/src/prepare.c index 1d2e6cda3b..da04cd509f 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -13,7 +13,7 @@ ** interface, and routines that contribute to loading the database schema ** from disk. ** -** $Id: prepare.c,v 1.1 2005/05/25 04:11:56 danielk1977 Exp $ +** $Id: prepare.c,v 1.2 2005/07/23 03:18:40 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -294,6 +294,11 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); sqlite3SafetyOn(db); sqliteFree(zSql); +#ifndef SQLITE_OMIT_ANALYZE + if( rc==SQLITE_OK ){ + sqlite3AnalysisLoad(db, iDb); + } +#endif sqlite3BtreeCloseCursor(curMain); } if( sqlite3_malloc_failed ){ @@ -526,4 +531,3 @@ int sqlite3_prepare16( return rc; } #endif /* SQLITE_OMIT_UTF16 */ - diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 00867d18bb..d8a0bedeb1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.398 2005/07/23 00:41:49 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.399 2005/07/23 03:18:40 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -745,6 +745,7 @@ struct Index { char *zName; /* Name of this index */ int nColumn; /* Number of columns in the table used by this index */ int *aiColumn; /* Which columns are used by this index. 1st is 0 */ + int *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */ Table *pTable; /* The SQL table being indexed */ int tnum; /* Page containing root of this index in database file */ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ @@ -1570,6 +1571,7 @@ char sqlite3AffinityType(const Token*); void sqlite3Analyze(Parse*, Token*, Token*); int sqlite3InvokeBusyHandler(BusyHandler*); int sqlite3FindDb(sqlite3*, Token*); +void sqlite3AnalysisLoad(sqlite3*,int iDB); #ifdef SQLITE_SSE #include "sseInt.h" diff --git a/src/vdbe.c b/src/vdbe.c index 79292ec944..4215ae9950 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.476 2005/07/21 18:23:20 drh Exp $ +** $Id: vdbe.c,v 1.477 2005/07/23 03:18:40 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -3889,6 +3889,21 @@ case OP_ParseSchema: { /* no-push */ break; } +#ifndef SQLITE_OMIT_ANALYZE +/* Opcode: LoadAnalysis P1 * * +** +** Read the sqlite_stat1 table for database P1 and load the content +** of that table into the internal index hash table. This will cause +** the analysis to be used when preparing all subsequent queries. +*/ +case OP_LoadAnalysis: { /* no-push */ + int iDb = pOp->p1; + assert( iDb>=0 && iDbnDb ); + sqlite3AnalysisLoad(db, iDb); + break; +} +#endif /* SQLITE_OMIT_ANALYZE */ + /* Opcode: DropTable P1 * P3 ** ** Remove the internal (in-memory) data structures that describe