]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Enhance the ANALYZE command so that it gathers statistics in the sqlite_stat1
authordrh <drh@noemail.net>
Sat, 25 Sep 2010 22:32:56 +0000 (22:32 +0000)
committerdrh <drh@noemail.net>
Sat, 25 Sep 2010 22:32:56 +0000 (22:32 +0000)
table even for tables that are empty or have no indices.

FossilOrigin-Name: a7645d293801da64a7579737d0a8b48117af2e2c

manifest
manifest.uuid
src/analyze.c
src/build.c
src/sqliteInt.h
src/where.c
test/analyze.test
test/auth.test
test/misc4.test
test/select6.test
test/tkt3757.test

index 6ade0dd8d21818753db27bfa4d345b0fb765cc42..b3ebf022c3a9d03d6d787c6eb079828b6f6e1674 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,8 @@
-C Add\snew\sfile\se_createtable.test.
-D 2010-09-25T17:29:58
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+C Enhance\sthe\sANALYZE\scommand\sso\sthat\sit\sgathers\sstatistics\sin\sthe\ssqlite_stat1\ntable\seven\sfor\stables\sthat\sare\sempty\sor\shave\sno\sindices.
+D 2010-09-25T22:32:56
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in c599a15d268b1db2aeadea19df2adc3bf2eb6bee
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -112,7 +115,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
 F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
 F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
 F src/alter.c 8dc27638e7e2553e80b2b621f232be5eb1e85ef3
-F src/analyze.c da65ce99bb159b10e85a1e460adbe53a88062500
+F src/analyze.c df69779a9bad368de5f5a32b8c733282d8dcbbbe
 F src/attach.c c689d516ee8cc52bf11bef2067d76eb8b716228a
 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
 F src/backup.c d5b0137bc20327af08c14772227cc35134839c30
@@ -121,7 +124,7 @@ F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff
 F src/btree.c d878577184112d982d00ea05afcc7487cd9f06f5
 F src/btree.h 2d1a83ad509047e8cc314fda7e054f99ff52414d
 F src/btreeInt.h c424f2f131cc61ddf130f9bd736b3df12c8a51f0
-F src/build.c 5acc8a7d79ca81102a5d020fbafb7a4162f96d1d
+F src/build.c 99894b89b7943b6f8337757facc4e61cef1d9508
 F src/callback.c a1d1b1c9c85415dff013af033e2fed9c8382d33b
 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
 F src/ctime.c 4f3aadad62c6c9f0d4e5a96718516ac4e3c598df
@@ -177,7 +180,7 @@ F src/select.c b0b124781474e4e0c8f64022875e5e2009e13443
 F src/shell.c 8517fc1f9c59ae4007e6cc8b9af91ab231ea2056
 F src/sqlite.h.in dae3f74d7b2b516967ede39b8e503718b571d9da
 F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
-F src/sqliteInt.h ef7ed8746759c09edd87e5550de973a4da3e4ca7
+F src/sqliteInt.h d8ae67308fec3f2abdce817a630aceae42ad8043
 F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44
 F src/status.c 496913d4e8441195f6f2a75b1c95993a45b9b30b
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -237,7 +240,7 @@ F src/vtab.c 0e8e0cb30dffb078367e843e84e37ef99236c7e4
 F src/wal.c 7081f148cb52b0cf2280e6384196402dc58130a3
 F src/wal.h 96669b645e27cd5a111ba59f0cae7743a207bc3c
 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
-F src/where.c a5040c004496d456761e8f10750f648bbd84e982
+F src/where.c 34c733f9e8ca5e8f611958422e7cc236bc9cf739
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
 F test/all.test 6745008c144bd2956d58864d21f7b304689c1cce
@@ -246,7 +249,7 @@ F test/alter2.test 75f731508f1bf27ba09a6075c66cd02216ba464b
 F test/alter3.test 8677e48d95536f7a6ed86a1a774744dadcc22b07
 F test/alter4.test 1e5dd6b951e9f65ca66422edff02e56df82dd403
 F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
-F test/analyze.test bf692e7db414f268a136bade16c03a1bdbb9240c
+F test/analyze.test c1eb87067fc16ece7c07e823d6395fd831b270c5
 F test/analyze2.test 59dac6c399c0c5d1a90a11ee7cc606743fb6db93
 F test/analyze3.test 6d4f4b0929545a9d1af803a0608a0c51b92a3537
 F test/async.test ad4ba51b77cd118911a3fe1356b0809da9c108c3
@@ -258,7 +261,7 @@ F test/attach.test ce9660e51768fab93cf129787be886c5d6c4fd81
 F test/attach2.test a295d2d7061adcee5884ef4a93c7c96a82765437
 F test/attach3.test bd9830bc3a0d22ed1310c9bff6896927937017dc
 F test/attachmalloc.test 38d2da5fdaf09ba0add57296967a3061e5842584
-F test/auth.test 8f21c160a4562f54f27618e85bac869efcecbcaf
+F test/auth.test 26cc6f219580191539bf335abe03e55e49310846
 F test/auth2.test 270baddc8b9c273682760cffba6739d907bd2882
 F test/auth3.test a4755e6a2a2fea547ffe63c874eb569e60a28eb5
 F test/autoinc.test 85ef3180a737e6580086a018c09c6f1a52759b46
@@ -543,7 +546,7 @@ F test/minmax3.test 66a60eb0f20281b0753249d347c5de0766954cee
 F test/misc1.test e56baf44656dd68d6475a4b44521045a60241e9b
 F test/misc2.test a628db7b03e18973e5d446c67696b03de718c9fd
 F test/misc3.test 72c5dc87a78e7865c5ec7a969fc572913dbe96b6
-F test/misc4.test 91e8ed25c092c2bb4e0bb01864631e2930f8d7de
+F test/misc4.test 9c078510fbfff05a9869a0b6d8b86a623ad2c4f6
 F test/misc5.test 45b2e3ed5f79af2b4f38ae362eaf4c49674575bd
 F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
 F test/misc7.test c5f4e6a82e04e71820c0f9f64f6733f04c8ae0ae
@@ -600,7 +603,7 @@ F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
 F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
 F test/select4.test 44aa6e7110592e18110b0b9cf5c024d37d23be17
 F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535
-F test/select6.test 2b5e8500d8ec3dd4c8e0c99eb1431b3d11fcc24c
+F test/select6.test cc25a8650cf9a4d4f74e586c45a75f9836516b18
 F test/select7.test dad6f00f0d49728a879d6eb6451d4752db0b0abe
 F test/select8.test 391de11bdd52339c30580dabbbbe97e3e9a3c79d
 F test/select9.test 74c0fb2c6eecb0219cbed0cbe3df136f8fbf9343
@@ -736,7 +739,7 @@ F test/tkt35xx.test ed9721bd9eb1693b3b4d3cf2a093fa7f92af0c93
 F test/tkt3630.test 929f64852103054125200bc825c316d5f75d42f7
 F test/tkt3718.test 3b59dcb5c4e7754dacd91e7fd353a61492cc402a
 F test/tkt3731.test 0c5f4cbffe102d43c3b2188af91a9e36348f974b
-F test/tkt3757.test 8f2208930655bbd4f92c14e19e72303a43e098ef
+F test/tkt3757.test 10cd679a88675c880533083fc79ac04324525595
 F test/tkt3761.test b95ea9c98f21cf91325f18a984887e62caceab33
 F test/tkt3762.test 2a9f3b03df44ec49ec0cfa8d5da6574c2a7853df
 F test/tkt3773.test 430b06567ce40285dfd2c4834a2a61816403efeb
@@ -867,7 +870,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 44deaaefeeb95827daeaf84aa5e205b456e75b40
-R f9cdaa74878a8325422c228d4f8c7dbc
-U dan
-Z 39756bc936cfb3dbb51046b9bdefa610
+P 20e16fef55c355a1d7e97d0c390769b941e83fdb
+R 96b44d864f75b35f18ba4c7ab3226d4c
+U drh
+Z e1547e0aba5840882b569e70505d3edd
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.6 (GNU/Linux)
+
+iD8DBQFMnnieoxKgR168RlERAs7CAJ9XFT8WTA9gYf6noiCftlq/XsWqugCfaGoh
+P4TBzZ9lm4AFS3sK2f1UkgA=
+=phK5
+-----END PGP SIGNATURE-----
index 37263b39d62c5084a16714d972833f1e7d689dad..1ebe527711cf628ba276de0939efd33b3e5cdc35 100644 (file)
@@ -1 +1 @@
-20e16fef55c355a1d7e97d0c390769b941e83fdb
\ No newline at end of file
+a7645d293801da64a7579737d0a8b48117af2e2c
\ No newline at end of file
index 59849456fcc89a2f716da3ceb03c46ebcb3e70b3..4b4175fe4c62e0aa7ebc0dbc16f4a2aa5bb9e60c 100644 (file)
@@ -114,6 +114,7 @@ static void analyzeOneTable(
   int topOfLoop;               /* The top of the loop */
   int endOfLoop;               /* The end of the loop */
   int addr;                    /* The address of an instruction */
+  int jZeroRows = 0;           /* Jump from here if number of rows is zero */
   int iDb;                     /* Index of database containing pTab */
   int regTabname = iMem++;     /* Register containing table name */
   int regIdxname = iMem++;     /* Register containing index name */
@@ -132,8 +133,15 @@ static void analyzeOneTable(
 #endif
 
   v = sqlite3GetVdbe(pParse);
-  if( v==0 || NEVER(pTab==0) || pTab->pIndex==0 ){
-    /* Do no analysis for tables that have no indices */
+  if( v==0 || NEVER(pTab==0) ){
+    return;
+  }
+  if( pTab->pSelect ){
+    /* Do not gather statistics on views */
+    return;
+  }
+  if( memcmp(pTab->zName, "sqlite_", 7)==0 ){
+    /* Do not gather statistics on system tables */
     return;
   }
   assert( sqlite3BtreeHoldsAllMutexes(db) );
@@ -150,6 +158,7 @@ static void analyzeOneTable(
   sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
 
   iIdxCur = pParse->nTab++;
+  sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
   for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
     int nCol = pIdx->nColumn;
     KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
@@ -164,10 +173,7 @@ static void analyzeOneTable(
         (char *)pKey, P4_KEYINFO_HANDOFF);
     VdbeComment((v, "%s", pIdx->zName));
 
-    /* Populate the registers containing the table and index names. */
-    if( pTab->pIndex==pIdx ){
-      sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
-    }
+    /* Populate the register containing the index name. */
     sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0);
 
 #ifdef SQLITE_ENABLE_STAT2
@@ -302,8 +308,10 @@ static void analyzeOneTable(
     ** If K>0 then it is always the case the D>0 so division by zero
     ** is never possible.
     */
-    addr = sqlite3VdbeAddOp1(v, OP_IfNot, iMem);
     sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regSampleno);
+    if( jZeroRows==0 ){
+      jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem);
+    }
     for(i=0; i<nCol; i++){
       sqlite3VdbeAddOp4(v, OP_String8, 0, regTemp, 0, " ", 0);
       sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regSampleno, regSampleno);
@@ -317,13 +325,35 @@ static void analyzeOneTable(
     sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regRowid);
     sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regRowid);
     sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
+  }
+
+  /* If the table has no indices, create a single sqlite_stat1 entry
+  ** containing NULL as the index name and the row count as the content.
+  */
+  if( pTab->pIndex==0 ){
+    sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb);
+    VdbeComment((v, "%s", pTab->zName));
+    sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regSampleno);
+    sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
+  }else{
+    assert( jZeroRows>0 );
+    addr = sqlite3VdbeAddOp0(v, OP_Goto);
+    sqlite3VdbeJumpHere(v, jZeroRows);
+  }
+  sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
+  sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
+  sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regRowid);
+  sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regRowid);
+  sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
+  if( pParse->nMem<regRec ) pParse->nMem = regRec;
+  if( jZeroRows ){
     sqlite3VdbeJumpHere(v, addr);
   }
 }
 
 /*
 ** Generate code that will cause the most recent index analysis to
-** be laoded into internal hash tables where is can be used.
+** be loaded into internal hash tables where is can be used.
 */
 static void loadAnalysis(Parse *pParse, int iDb){
   Vdbe *v = sqlite3GetVdbe(pParse);
@@ -453,33 +483,46 @@ struct analysisInfo {
 ** 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
+**     argv[0] = name of the table
+**     argv[1] = name of the index (might be NULL)
+**     argv[2] = results of analysis - on integer for each column
+**
+** Entries for which argv[1]==NULL simply record the number of rows in
+** the table.
 */
 static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
   analysisInfo *pInfo = (analysisInfo*)pData;
   Index *pIndex;
-  int i, c;
+  Table *pTable;
+  int i, c, n;
   unsigned int v;
   const char *z;
 
-  assert( argc==2 );
+  assert( argc==3 );
   UNUSED_PARAMETER2(NotUsed, argc);
 
-  if( argv==0 || argv[0]==0 || argv[1]==0 ){
+  if( argv==0 || argv[0]==0 || argv[2]==0 ){
     return 0;
   }
-  pIndex = sqlite3FindIndex(pInfo->db, argv[0], pInfo->zDatabase);
-  if( pIndex==0 ){
+  pTable = sqlite3FindTable(pInfo->db, argv[0], pInfo->zDatabase);
+  if( pTable==0 ){
     return 0;
   }
-  z = argv[1];
-  for(i=0; *z && i<=pIndex->nColumn; i++){
+  if( argv[1] ){
+    pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
+  }else{
+    pIndex = 0;
+  }
+  n = pIndex ? pIndex->nColumn : 0;
+  z = argv[2];
+  for(i=0; *z && i<=n; i++){
     v = 0;
     while( (c=z[0])>='0' && c<='9' ){
       v = v*10 + c - '0';
       z++;
     }
+    if( i==0 ) pTable->nRowEst = v;
+    if( pIndex==0 ) break;
     pIndex->aiRowEst[i] = v;
     if( *z==' ' ) z++;
   }
@@ -555,7 +598,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
 
   /* Load new statistics out of the sqlite_stat1 table */
   zSql = sqlite3MPrintf(db, 
-      "SELECT idx, stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
+      "SELECT tbl, idx, stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
   if( zSql==0 ){
     rc = SQLITE_NOMEM;
   }else{
index 6acab1ddee92fcb571b5e6b952ca4675d5c35464..ebd077ac5d112a0f49cd9d297f8122be773b29c2 100644 (file)
@@ -802,6 +802,7 @@ void sqlite3StartTable(
   pTable->iPKey = -1;
   pTable->pSchema = db->aDb[iDb].pSchema;
   pTable->nRef = 1;
+  pTable->nRowEst = 1000000;
   assert( pParse->pNewTable==0 );
   pParse->pNewTable = pTable;
 
@@ -2830,14 +2831,14 @@ exit_create_index:
 void sqlite3DefaultRowEst(Index *pIdx){
   unsigned *a = pIdx->aiRowEst;
   int i;
+  unsigned n;
   assert( a!=0 );
-  a[0] = 1000000;
-  for(i=pIdx->nColumn; i>=5; i--){
-    a[i] = 5;
-  }
-  while( i>=1 ){
-    a[i] = 11 - i;
-    i--;
+  a[0] = pIdx->pTable->nRowEst;
+  if( a[0]<10 ) a[0] = 10;
+  n = 10;
+  for(i=1; i<=pIdx->nColumn; i++){
+    a[i] = n;
+    if( n>5 ) n--;
   }
   if( pIdx->onError!=OE_None ){
     a[pIdx->nColumn] = 1;
index 3ebc90082c44d3e6c299a0fc0e52d979eb588ad3..cefc94e8d9e3d31d8322d600fd7ea0f1fddf6686 100644 (file)
@@ -1252,6 +1252,7 @@ struct Table {
   Column *aCol;        /* Information about each column */
   Index *pIndex;       /* List of SQL indexes on this table. */
   int tnum;            /* Root BTree node for this table (see note above) */
+  unsigned nRowEst;    /* Estimated rows in table - from sqlite_stat1 table */
   Select *pSelect;     /* NULL for tables.  Points to definition if a view. */
   u16 nRef;            /* Number of pointers to this Table */
   u8 tabFlags;         /* Mask of TF_* values */
index 8cc547066e1bfdeb9fc9e941dbbda822cc0e148e..4ff77df7d8d9902988a95911840b82cdb9a87eb9 100644 (file)
@@ -1706,7 +1706,7 @@ static void bestAutomaticIndex(
 
   assert( pParse->nQueryLoop >= (double)1 );
   pTable = pSrc->pTab;
-  nTableRow = pTable->pIndex ? pTable->pIndex->aiRowEst[0] : 1000000;
+  nTableRow = pTable->nRowEst;
   logN = estLog(nTableRow);
   costTempIdx = 2*logN*(nTableRow/pParse->nQueryLoop + 1);
   if( costTempIdx>=pCost->rCost ){
@@ -2513,23 +2513,14 @@ static void bestBtreeIndex(
     sPk.nColumn = 1;
     sPk.aiColumn = &aiColumnPk;
     sPk.aiRowEst = aiRowEstPk;
-    aiRowEstPk[1] = 1;
     sPk.onError = OE_Replace;
     sPk.pTable = pSrc->pTab;
+    aiRowEstPk[0] = pSrc->pTab->nRowEst;
+    aiRowEstPk[1] = 1;
     pFirst = pSrc->pTab->pIndex;
     if( pSrc->notIndexed==0 ){
       sPk.pNext = pFirst;
     }
-    /* The aiRowEstPk[0] is an estimate of the total number of rows in the
-    ** table.  Get this information from the ANALYZE information if it is
-    ** available.  If not available, assume the table 1 million rows in size.
-    */
-    if( pFirst ){
-      assert( pFirst->aiRowEst!=0 ); /* Allocated together with pFirst */
-      aiRowEstPk[0] = pFirst->aiRowEst[0];
-    }else{
-      aiRowEstPk[0] = 1000000;
-    }
     pProbe = &sPk;
     wsFlagMask = ~(
         WHERE_COLUMN_IN|WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_RANGE
@@ -4103,7 +4094,7 @@ WhereInfo *sqlite3WhereBegin(
     **
     ** The best strategy is to iterate through table t1 first. However it
     ** is not possible to determine this with a simple greedy algorithm.
-    ** However, since the cost of a linear scan through table t2 is the same 
+    ** Since the cost of a linear scan through table t2 is the same 
     ** as the cost of a linear scan through table t1, a simple greedy 
     ** algorithm may choose to use t2 for the outer loop, which is a much
     ** costlier approach.
index 5bd653a93bf5305f6dd0a3f39cfd0eaeafa8c3f5..177936c2248bca4bb4b4c98ac5f66866687046ad 100644 (file)
@@ -73,7 +73,7 @@ do_test analyze-1.6.3 {
 } {1 {table sqlite_stat1 may not be indexed}}
 do_test analyze-1.7 {
   execsql {
-    SELECT * FROM sqlite_stat1
+    SELECT * FROM sqlite_stat1 WHERE idx NOT NULL
   }
 } {}
 do_test analyze-1.8 {
@@ -83,7 +83,7 @@ do_test analyze-1.8 {
 } {0 {}}
 do_test analyze-1.9 {
   execsql {
-    SELECT * FROM sqlite_stat1
+    SELECT * FROM sqlite_stat1 WHERE idx NOT NULL
   }
 } {}
 do_test analyze-1.10 {
@@ -96,7 +96,7 @@ do_test analyze-1.11 {
   execsql {
     SELECT * FROM sqlite_stat1
   }
-} {}
+} {t1 {} 0}
 do_test analyze-1.12 {
   catchsql {
     ANALYZE t1;
@@ -106,7 +106,7 @@ do_test analyze-1.13 {
   execsql {
     SELECT * FROM sqlite_stat1
   }
-} {}
+} {t1 {} 0}
 
 # Create some indices that can be analyzed.  But do not yet add
 # data.  Without data in the tables, no analysis is done.
@@ -117,21 +117,21 @@ do_test analyze-2.1 {
     ANALYZE main.t1;
     SELECT * FROM sqlite_stat1 ORDER BY idx;
   }
-} {}
+} {t1 {} 0}
 do_test analyze-2.2 {
   execsql {
     CREATE INDEX t1i2 ON t1(b);
     ANALYZE t1;
     SELECT * FROM sqlite_stat1 ORDER BY idx;
   }
-} {}
+} {t1 {} 0}
 do_test analyze-2.3 {
   execsql {
     CREATE INDEX t1i3 ON t1(a,b);
     ANALYZE main;
     SELECT * FROM sqlite_stat1 ORDER BY idx;
   }
-} {}
+} {t1 {} 0}
 
 # Start adding data to the table.  Verify that the analysis
 # is done correctly.
index 8b7cae3e111eb8776587419ff3e2009c7a47b14e..bb974ea3ee3c662c12f51b6a014dba9af6894882 100644 (file)
@@ -1976,12 +1976,12 @@ ifcapable analyze {
       ANALYZE;
     }
     set ::authargs
-  } {t4 {} main {}}
+  } {t4 {} main {} t2 {} main {}}
   do_test auth-1.295 {
     execsql {
       SELECT count(*) FROM sqlite_stat1;
     }
-  } 2
+  } 3
   proc auth {code args} {
     if {$code=="SQLITE_ANALYZE"} {
       set ::authargs [concat $::authargs $args]
@@ -1999,7 +1999,7 @@ ifcapable analyze {
     execsql {
       SELECT count(*) FROM sqlite_stat1;
     }
-  } 2
+  } 3
 } ;# ifcapable analyze
 
 
index 026dd032e3b633337229065f9529a49bc82c1902..59c1d118ac7c5f785b5f4cd7101b0078c1f7f2b2 100644 (file)
@@ -151,7 +151,7 @@ ifcapable subquery {
       
       select a.*, x.*
         from a, (select key,sum(period) from b group by key) as x
-        where a.key=x.key;
+        where a.key=x.key order by 1 desc;
     }
   } {01 data01 01 3 +1 data+1 +1 7}
 
index ef0bfd56602dc6a5a0b7e71e988b50e0f0fdf06b..e0ff165c550e7b3fcb80eaeaddb8116b290970f1 100644 (file)
@@ -458,6 +458,7 @@ do_test select6-8.6 {
 do_test select6-9.1 {
   execsql {
     SELECT a.x, b.x FROM t1 AS a, (SELECT x FROM t1 LIMIT 2) AS b
+     ORDER BY 1, 2
   }
 } {1 1 1 2 2 1 2 2 3 1 3 2 4 1 4 2}
 do_test select6-9.2 {
index 14bfb23be73a1977043be575de013fb81d845a8f..011beb5c8b79f8f1a1b46832dab5bdfce88ea10d 100644 (file)
@@ -35,9 +35,9 @@ do_test tkt3757-1.1 {
      CREATE TABLE t2(a INTEGER, b TEXT);
      INSERT INTO t2 VALUES(2, 'two');
      ANALYZE;
-     SELECT * FROM sqlite_stat1;
+     SELECT * FROM sqlite_stat1 ORDER BY 1, 2;
   }
-} {t1 t1i1 {1 1 1}}
+} {t1 t1i1 {1 1 1} t2 {} 1}
 
 # Modify statistics in order to make the optimizer then that:
 #