]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
The results of ANALYZE are now loaded into internal data structures where
authordrh <drh@noemail.net>
Sat, 23 Jul 2005 03:18:40 +0000 (03:18 +0000)
committerdrh <drh@noemail.net>
Sat, 23 Jul 2005 03:18:40 +0000 (03:18 +0000)
they can be used.  But they are not actually used yet. (CVS 2562)

FossilOrigin-Name: 1996bacfb97180965304e2a6d6784b6ecbbf8575

manifest
manifest.uuid
src/analyze.c
src/build.c
src/prepare.c
src/sqliteInt.h
src/vdbe.c

index 9bed028a6f06444483807256ff7e994d443e4ea7..194373ad8b6f2f8c7bd0fdc824736d94c8fa2ac5 100644 (file)
--- 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
index e2842dd2e204b1f01762f5e668e891382144dab8..b1edcfa6452980339719cde01250b4e0fc6a028b 100644 (file)
@@ -1 +1 @@
-bd7583a5d63412785a9c5de54d25b509da241605
\ No newline at end of file
+1996bacfb97180965304e2a6d6784b6ecbbf8575
\ No newline at end of file
index a3f8e84c836d782e4abd6ff4e3cad125d0e2444a..dfe1150e435dea72a0c095169bdf077ecc5b07d0 100644 (file)
@@ -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 && i<pIndex->nColumn; 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 */
index 8c45ff766cdbbdd135acc0cc3bff4d95653ba4f4..02a5cdd5127c8d542d0b2f60183b39235c0a495e 100644 (file)
@@ -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 <ctype.h>
@@ -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;
index 1d2e6cda3bbb3c34d259a88899ac5d649c3b6bd9..da04cd509f42a9e69ab16c308600843a37f820df 100644 (file)
@@ -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 */
-
index 00867d18bbac28d5fc9b738cacbf67f83c8d223d..d8a0bedeb1cd697078c43f94d300109b386dd051 100644 (file)
@@ -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"
index 79292ec94433f4e7c280e21277d47318e443ff15..4215ae9950d7ad6bddcb4875de710af803b0ea82 100644 (file)
@@ -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 && iDb<db->nDb );
+  sqlite3AnalysisLoad(db, iDb);
+  break;  
+}
+#endif /* SQLITE_OMIT_ANALYZE */
+
 /* Opcode: DropTable P1 * P3
 **
 ** Remove the internal (in-memory) data structures that describe