]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Bug fixes and additional tests for the subquery flattener. (CVS 411)
authordrh <drh@noemail.net>
Sun, 3 Mar 2002 02:49:51 +0000 (02:49 +0000)
committerdrh <drh@noemail.net>
Sun, 3 Mar 2002 02:49:51 +0000 (02:49 +0000)
FossilOrigin-Name: 2c05389eda391e38894fc6969e29766df82a8fec

manifest
manifest.uuid
src/select.c
src/sqliteInt.h
src/vdbe.c
test/insert2.test
test/select6.test
test/vacuum.test
tool/lemon.c

index 8397849c934578ff4103fb4ac995017bda690d97..17db1acb9ebd5afee7b8a47af8e43d5820868d56 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Pager\soptimization:\sdo\snot\swrite\sor\sjournal\sfree\spages.\s\sThis\sresults\sin\na\s2x\sperformance\sgain\sfor\slarge\sINSERTs\sand\sa\s5x\sperformance\sgain\sfor\nlarge\sDELETEs.\s(CVS\s410)
-D 2002-03-02T20:41:58
+C Bug\sfixes\sand\sadditional\stests\sfor\sthe\ssubquery\sflattener.\s(CVS\s411)
+D 2002-03-03T02:49:51
 F Makefile.in 50f1b3351df109b5774771350d8c1b8d3640130d
 F Makefile.template 89e373b2dad0321df00400fa968dc14b61a03296
 F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
@@ -37,11 +37,11 @@ F src/pager.h feb18aab2f6dea439393f23a382699b9b1053c32
 F src/parse.y d62960cdee2d2e7821f277d2fe63d823c86602ba
 F src/printf.c 300a90554345751f26e1fc0c0333b90a66110a1d
 F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
-F src/select.c b99de04f6f2414bb21a065150e0748ccd8329519
+F src/select.c 285a9cfa670c3fc47d8f42c9873be88860a015a1
 F src/shell.c 9f8249ca5b8f8aad40becd778c151b58c0d6109e
 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
 F src/sqlite.h.in a9b5772604265f98f3120573ef29e37b9d917216
-F src/sqliteInt.h df68f09091ab37d904020ac48ca2ea29e4985442
+F src/sqliteInt.h 272c356245e3fdb33e91e87a3f7c0324d118cac9
 F src/table.c 203a09d5d0009eeeb1f670370d52b4ce163a3b52
 F src/tclsqlite.c b9cf346e95291cb4c4f1bf5ac1d77db6b8ad023d
 F src/test1.c 33efd350dca27c52c58c553c04fd3a6a51f13c1f
@@ -51,7 +51,7 @@ F src/threadtest.c 81f0598e0f031c1bd506af337fdc1b7e8dff263f
 F src/tokenize.c 4b5d30590a744b9bb5605a92d1f620ab2e7e75af
 F src/update.c 943b821901efb796dc82d91653621aeeb48d223b
 F src/util.c 00a35b421c92ae0d7cfa51bd87f7d4995f464d19
-F src/vdbe.c 91311e99efe980459a78e8f5b9e5456d772c9e23
+F src/vdbe.c 4989cd3e6f4f699c9b08cd1980d1b588cede5c1f
 F src/vdbe.h f9be1f6e9a336c3ff4d14ea7489ee976e07460cc
 F src/where.c 34d91fd5d822c2663caeb023f72d60df316ebf29
 F test/all.test 7a8a8a7a579ed2bb4d8976d55402f21eacd58049
@@ -67,7 +67,7 @@ F test/func.test 4359344586067e79abf4c710c4737d67ed3cf963
 F test/in.test c09312672e3f0709fa02c8e2e9cd8fb4bd6269aa
 F test/index.test c8a471243bbf878974b99baf5badd59407237cf3
 F test/insert.test c36d534a4ab58c2cd452a273e51b2b0dd1ede1f9
-F test/insert2.test 65c2b2aae0bae7a7bbe500f77981cd916b81e91b
+F test/insert2.test 2f02b1e0dbfba3e8c76496209be5f4010b584181
 F test/intpkey.test 101ec266222e88b24e6f1e204b9b6873404cd4dc
 F test/ioerr.test 57d9bffaca18b34f9e976f786eadc2591d6efc6a
 F test/limit.test a930f3eba2a7691c8397ccab33710b931589566a
@@ -87,7 +87,7 @@ F test/select2.test ed2c1882857106b85478f54f67000e14966be4c4
 F test/select3.test 9469c332250a75a0ef1771fb5da62dc04ec77f18
 F test/select4.test 29a2ffb187f3d8b6ca42a0a6b619e9cabe12e228
 F test/select5.test c2a6c4a003316ee42cbbd689eebef8fdce0db2ac
-F test/select6.test d9fb417d6cab75a072b547ba6303120f327fd6fd
+F test/select6.test 8ccbcd3b53df4735a5bb3a8cd4bf4e495cae26c0
 F test/sort.test 3b996ce7ca385f9cd559944ac0f4027a23aa546b
 F test/subselect.test 335d3dad8d585726c447dfee8d9c4f7383c76b78
 F test/table.test 17b0b6eafa3faaee5545b7a94e6c1ff73f0880f3
@@ -98,10 +98,10 @@ F test/tester.tcl 96db1b49157388edb57e11bf33285e3811a897e4
 F test/trans.test 9e49495c06b1c41f889bf4f0fb195a015b126de0
 F test/unique.test 07776624b82221a80c8b4138ce0dd8b0853bb3ea
 F test/update.test 3cf1ca0565f678063c2dfa9a7948d2d66ae1a778
-F test/vacuum.test 8acf8669f3b627e54149b25165b034aa06c2432e
+F test/vacuum.test 059871b312eb910bbe49dafde1d01490cc2c6bbe
 F test/view.test 4619ebede587102e577e19ce52e9852ec8293cbc
 F test/where.test 032d581c3de4893eba33b569e581c46b941bb02a
-F tool/lemon.c d4b4e127e70633be1bbea49c2ccba5cdb4b77a5f
+F tool/lemon.c a26214e008a7351c0c9fc57c5aab44b403c36c42
 F tool/lempar.c 2ff255186fffb38a43a9f7b010e87eee6308edcc
 F tool/memleak.awk 296dfbce7a9ca499b95ce04e30334e64a50052e0
 F tool/opNames.awk 5ba1f48aa854ee3b7c3d2b54233665bc3e649ea2
@@ -127,7 +127,7 @@ F www/speed.tcl 83457b2bf6bb430900bd48ca3dd98264d9a916a5
 F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
 F www/tclsqlite.tcl 829b393d1ab187fd7a5e978631b3429318885c49
 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P abbb999d4fc3fe142567b6ede5e625e7bf0da714
-R 65be3ccaeb081927d6806e4071f74e0f
+P cf1ebcfb741786f84a596c406f4c492f68cbe881
+R 15fdb1a16caac3bbe9fb9691324e3176
 U drh
-Z 3493ea99db08effd4dc1d635e5b15238
+Z 2b80ac05372abd52845156b2368b8bf6
index 75e1b749c1e6044474a85b0e59e1bf6491fc64f7..e74ffaeaa86604b18004dabe31aa4a1799a67006 100644 (file)
@@ -1 +1 @@
-cf1ebcfb741786f84a596c406f4c492f68cbe881
\ No newline at end of file
+2c05389eda391e38894fc6969e29766df82a8fec
\ No newline at end of file
index 94eb2ae0be9478d1cdf5dd026ffe933436b3e641..fb55a3fe68439866cd8884d6facfed9c8b8c9891 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle SELECT statements in SQLite.
 **
-** $Id: select.c,v 1.71 2002/03/02 17:04:08 drh Exp $
+** $Id: select.c,v 1.72 2002/03/03 02:49:51 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -760,13 +760,17 @@ static void changeTables(Expr *pExpr, int iFrom, int iTo){
   if( pExpr->op==TK_COLUMN && pExpr->iTable==iFrom ){
     pExpr->iTable = iTo;
   }else{
+    static void changeTablesInList(ExprList*, int, int);
     changeTables(pExpr->pLeft, iFrom, iTo);
     changeTables(pExpr->pRight, iFrom, iTo);
-    if( pExpr->pList ){
-      int i;
-      for(i=0; i<pExpr->pList->nExpr; i++){
-        changeTables(pExpr->pList->a[i].pExpr, iFrom, iTo);
-      }
+    changeTablesInList(pExpr->pList, iFrom, iTo);
+  }
+}
+static void changeTablesInList(ExprList *pList, int iFrom, int iTo){
+  if( pList ){
+    int i;
+    for(i=0; i<pList->nExpr; i++){
+      changeTables(pList->a[i].pExpr, iFrom, iTo);
     }
   }
 }
@@ -799,6 +803,7 @@ static void substExpr(Expr *pExpr, int iTable, ExprList *pEList, int iSub){
     pExpr->iTable = pNew->iTable;
     pExpr->iColumn = pNew->iColumn;
     pExpr->iAgg = pNew->iAgg;
+    pExpr->token = pNew->token;
     if( iSub!=iTable ){
       changeTables(pExpr, iSub, iTable);
     }
@@ -908,8 +913,10 @@ int flattenSubquery(Select *p, int iFrom, int isAgg, int subqueryIsAgg){
       pList->a[i].zName = sqliteStrNDup(pExpr->span.z, pExpr->span.n);
     }
   }
-  substExprList(p->pGroupBy, iParent, pSub->pEList, iSub);
-  substExpr(p->pHaving, iParent, pSub->pEList, iSub);
+  if( isAgg ){
+    substExprList(p->pGroupBy, iParent, pSub->pEList, iSub);
+    substExpr(p->pHaving, iParent, pSub->pEList, iSub);
+  }
   substExprList(p->pOrderBy, iParent, pSub->pEList, iSub);
   if( pSub->pWhere ){
     pWhere = sqliteExprDup(pSub->pWhere);
@@ -921,8 +928,25 @@ int flattenSubquery(Select *p, int iFrom, int isAgg, int subqueryIsAgg){
   }
   if( subqueryIsAgg ){
     assert( p->pHaving==0 );
-    p->pHaving = pWhere;
+    p->pHaving = p->pWhere;
+    p->pWhere = pWhere;
     substExpr(p->pHaving, iParent, pSub->pEList, iSub);
+    if( pSub->pHaving ){
+      Expr *pHaving = sqliteExprDup(pSub->pHaving);
+      if( iParent!=iSub ){
+        changeTables(pHaving, iSub, iParent);
+      }
+      if( p->pHaving ){
+        p->pHaving = sqliteExpr(TK_AND, p->pHaving, pHaving, 0);
+      }else{
+        p->pHaving = pHaving;
+      }
+    }
+    assert( p->pGroupBy==0 );
+    p->pGroupBy = sqliteExprListDup(pSub->pGroupBy);
+    if( iParent!=iSub ){
+      changeTablesInList(p->pGroupBy, iSub, iParent);
+    }
   }else if( p->pWhere==0 ){
     p->pWhere = pWhere;
   }else{
@@ -1083,6 +1107,13 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
 **
 ** This routine does NOT free the Select structure passed in.  The
 ** calling function needs to do that.
+**
+** The pParent, parentTab, and *pParentAgg fields are filled in if this
+** SELECT is a subquery.  This routine may try to combine this SELECT
+** with its parent to form a single flat query.  In so doing, it might
+** change the parent query from a non-aggregate to an aggregate query.
+** For that reason, the pParentAgg flag is passed as a pointer, so it
+** can be changed.
 */
 int sqliteSelect(
   Parse *pParse,         /* The parser context */
@@ -1091,7 +1122,7 @@ int sqliteSelect(
   int iParm,             /* Save result in this memory location, if >=0 */
   Select *pParent,       /* Another SELECT for which this is a sub-query */
   int parentTab,         /* Index in pParent->pSrc of this query */
-  int parentAgg          /* True if pParent uses aggregate functions */
+  int *pParentAgg        /* True if pParent uses aggregate functions */
 ){
   int i;
   WhereInfo *pWInfo;
@@ -1254,21 +1285,23 @@ int sqliteSelect(
     if( pTabList->a[i].pSelect==0 ) continue;
     sqliteVdbeAddOp(v, OP_OpenTemp, base+i, 0);
     sqliteSelect(pParse, pTabList->a[i].pSelect, SRT_Table, base+i,
-                 p, i, isAgg);
+                 p, i, &isAgg);
+    pTabList = p->pSrc;
+    pWhere = p->pWhere;
+    pOrderBy = p->pOrderBy;
+    pGroupBy = p->pGroupBy;
+    pHaving = p->pHaving;
+    isDistinct = p->isDistinct;
   }
 
   /* Check to see if this is a subquery that can be "flattened" into its parent.
   ** If flattening is a possiblity, do so and return immediately.  
   */
-  if( flattenSubquery(pParent, parentTab, parentAgg, isAgg) ){
+  if( pParent && pParentAgg &&
+      flattenSubquery(pParent, parentTab, *pParentAgg, isAgg) ){
+    if( isAgg ) *pParentAgg = 1;
     return rc;
   }
-  pTabList = p->pSrc;
-  pWhere = p->pWhere;
-  pOrderBy = p->pOrderBy;
-  pGroupBy = p->pGroupBy;
-  pHaving = p->pHaving;
-  isDistinct = p->isDistinct;
 
   /* Do an analysis of aggregate expressions.
   */
index 3dcda0a66a8f3191d4cfa4d163d3dd69ed1d0b3e..bb6ee1aacd991091bb6fb3d2be87f2ccaf896cea 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.97 2002/03/02 17:04:08 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.98 2002/03/03 02:49:51 drh Exp $
 */
 #include "sqlite.h"
 #include "hash.h"
@@ -589,7 +589,7 @@ void sqliteIdListAddAlias(IdList*, Token*);
 void sqliteIdListDelete(IdList*);
 void sqliteCreateIndex(Parse*, Token*, Token*, IdList*, int, Token*, Token*);
 void sqliteDropIndex(Parse*, Token*);
-int sqliteSelect(Parse*, Select*, int, int, Select*, int, int);
+int sqliteSelect(Parse*, Select*, int, int, Select*, int, int*);
 Select *sqliteSelectNew(ExprList*,IdList*,Expr*,ExprList*,Expr*,ExprList*,
                         int,int,int);
 void sqliteSelectDelete(Select*);
index 5514df12d42f7708fb2823ded2934dee744e489d..1d8989740b74f7087b4483cc265edbef860e4905 100644 (file)
@@ -30,7 +30,7 @@
 ** But other routines are also provided to help in building up
 ** a program instruction by instruction.
 **
-** $Id: vdbe.c,v 1.129 2002/02/28 03:31:11 drh Exp $
+** $Id: vdbe.c,v 1.130 2002/03/03 02:49:51 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -1096,6 +1096,7 @@ int sqliteVdbeList(
   char zAddr[20];
   char zP1[20];
   char zP2[20];
+  char zP3[40];
   static char *azColumnNames[] = {
      "addr", "opcode", "p1", "p2", "p3", 0
   };
@@ -1116,7 +1117,12 @@ int sqliteVdbeList(
     sprintf(zAddr,"%d",i);
     sprintf(zP1,"%d", p->aOp[i].p1);
     sprintf(zP2,"%d", p->aOp[i].p2);
-    azValue[4] = p->aOp[i].p3type!=P3_POINTER ? p->aOp[i].p3 : "";
+    if( p->aOp[i].p3type==P3_POINTER ){
+      sprintf(zP3, "ptr(%#x)", (int)p->aOp[i].p3);
+      azValue[4] = zP3;
+    }else{
+      azValue[4] = p->aOp[i].p3;
+    }
     azValue[1] = zOpName[p->aOp[i].opcode];
     if( xCallback(pArg, 5, azValue, azColumnNames) ){
       rc = SQLITE_ABORT;
index 16261ae19cfee3fbdfc4f9228940109cb39f053e..fca4865edbfdd68a0bdc5cda0d6d32fd48294a18 100644 (file)
@@ -12,7 +12,7 @@
 # focus of this file is testing the INSERT statement that takes is
 # result from a SELECT.
 #
-# $Id: insert2.test,v 1.7 2002/02/19 13:39:23 drh Exp $
+# $Id: insert2.test,v 1.8 2002/03/03 02:49:52 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -112,10 +112,75 @@ do_test insert2-2.3 {
   }
 } {hi 2 1}
 
-do_test insert2-4.0 {
+do_test insert2-3.0 {
   set x [execsql {PRAGMA integrity_check}]
   if {$x==""} {set x ok}
   set x
 } {ok}
 
+# File table t4 with lots of data
+#
+do_test insert2-3.1 {
+  execsql {
+    SELECT * from t4;
+  }
+} {1 2}
+do_test insert2-3.2 {
+  execsql {
+    BEGIN;
+    INSERT INTO t4 VALUES(2,4);
+    INSERT INTO t4 VALUES(3,6);
+    INSERT INTO t4 VALUES(4,8);
+    INSERT INTO t4 VALUES(5,10);
+    INSERT INTO t4 VALUES(6,12);
+    INSERT INTO t4 VALUES(7,14);
+    INSERT INTO t4 VALUES(8,16);
+    INSERT INTO t4 VALUES(9,18);
+    INSERT INTO t4 VALUES(10,20);
+    COMMIT;
+    SELECT count(*) FROM t4;
+  }
+} {10}
+do_test insert2-3.3 {
+  execsql {
+    BEGIN;
+    INSERT INTO t4 SELECT x+(SELECT max(x) FROM t4),y FROM t4;
+    INSERT INTO t4 SELECT x+(SELECT max(x) FROM t4),y FROM t4;
+    INSERT INTO t4 SELECT x+(SELECT max(x) FROM t4),y FROM t4;
+    INSERT INTO t4 SELECT x+(SELECT max(x) FROM t4),y FROM t4;
+    COMMIT;
+    SELECT count(*) FROM t4;
+  }
+} {160}
+do_test insert2-3.4 {
+  execsql {
+    BEGIN;
+    UPDATE t4 SET y='lots of data for the row where x=' || x
+                     || ' and y=' || y || ' - even more data to fill space';
+    COMMIT;
+    SELECT count(*) FROM t4;
+  }
+} {160}
+do_test insert2-3.5 {
+  execsql {
+    BEGIN;
+    INSERT INTO t4 SELECT x+(SELECT max(x)+1 FROM t4),y FROM t4;
+    SELECT count(*) from t4;
+    ROLLBACK;
+  }
+} {320}
+do_test insert2-3.6 {
+  execsql {
+    SELECT count(*) FROM t4;
+  }
+} {160}
+do_test insert2-3.7 {
+  execsql {
+    BEGIN;
+    DELETE FROM t4 WHERE x!=123;
+    SELECT count(*) FROM t4;
+    ROLLBACK;
+  }
+} {1}
+
 finish_test
index fbad950c29c9d3090425f61d1fe8387447aea093..afbff9037bdee53d73ac767202e6a08babd6a9e4 100644 (file)
@@ -12,7 +12,7 @@
 # focus of this file is testing SELECT statements that contain
 # subqueries in their FROM clause.
 #
-# $Id: select6.test,v 1.2 2002/02/18 13:35:33 drh Exp $
+# $Id: select6.test,v 1.3 2002/03/03 02:49:52 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -166,4 +166,103 @@ do_test sqlite6-3.2 {
     ORDER BY [a.q]
   }
 } {1 1 1 2 2 3 3 4 7 4 8 15 5 5 20}
+
+do_test select6-3.3 {
+  execsql {
+    SELECT a,b,a+b FROM (SELECT avg(x) as 'a', avg(y) as 'b' FROM t1)
+  }
+} {10.5 3.7 14.2}
+do_test select6-3.4 {
+  execsql {
+    SELECT a,b,a+b FROM (SELECT avg(x) as 'a', avg(y) as 'b' FROM t1 WHERE y=4)
+  }
+} {11.5 4 15.5}
+do_test select6-3.5 {
+  execsql {
+    SELECT x,y,x+y FROM (SELECT avg(a) as 'x', avg(b) as 'y' FROM t2 WHERE a=4)
+  }
+} {4 3 7}
+do_test select6-3.6 {
+  execsql {
+    SELECT a,b,a+b FROM (SELECT avg(x) as 'a', avg(y) as 'b' FROM t1)
+    WHERE a>10
+  }
+} {10.5 3.7 14.2}
+do_test select6-3.7 {
+  execsql {
+    SELECT a,b,a+b FROM (SELECT avg(x) as 'a', avg(y) as 'b' FROM t1)
+    WHERE a<10
+  }
+} {}
+do_test select6-3.8 {
+  execsql {
+    SELECT a,b,a+b FROM (SELECT avg(x) as 'a', avg(y) as 'b' FROM t1 WHERE y=4)
+    WHERE a>10
+  }
+} {11.5 4 15.5}
+do_test select6-3.9 {
+  execsql {
+    SELECT a,b,a+b FROM (SELECT avg(x) as 'a', avg(y) as 'b' FROM t1 WHERE y=4)
+    WHERE a<10
+  }
+} {}
+do_test select6-3.10 {
+  execsql {
+    SELECT a,b,a+b FROM (SELECT avg(x) as 'a', y as 'b' FROM t1 GROUP BY b)
+    ORDER BY a
+  }
+} {1 1 2 2.5 2 4.5 5.5 3 8.5 11.5 4 15.5 18 5 23}
+do_test select6-3.11 {
+  execsql {
+    SELECT a,b,a+b FROM 
+       (SELECT avg(x) as 'a', y as 'b' FROM t1 GROUP BY b)
+    WHERE b<4 ORDER BY a
+  }
+} {1 1 2 2.5 2 4.5 5.5 3 8.5}
+do_test select6-3.12 {
+  execsql {
+    SELECT a,b,a+b FROM 
+       (SELECT avg(x) as 'a', y as 'b' FROM t1 GROUP BY b HAVING a>1)
+    WHERE b<4 ORDER BY a
+  }
+} {2.5 2 4.5 5.5 3 8.5}
+do_test select6-3.13 {
+  execsql {
+    SELECT a,b,a+b FROM 
+       (SELECT avg(x) as 'a', y as 'b' FROM t1 GROUP BY b HAVING a>1)
+    ORDER BY a
+  }
+} {2.5 2 4.5 5.5 3 8.5 11.5 4 15.5 18 5 23}
+do_test select6-3.14 {
+  execsql {
+    SELECT [count(*)],y FROM (SELECT count(*), y FROM t1 GROUP BY y)
+    ORDER BY [count(*)]
+  }
+} {1 1 2 2 4 3 5 5 8 4}
+do_test select6-3.15 {
+  execsql {
+    SELECT [count(*)],y FROM (SELECT count(*), y FROM t1 GROUP BY y)
+    ORDER BY y
+  }
+} {1 1 2 2 4 3 8 4 5 5}
+
+do_test select6-4.1 {
+  execsql {
+    SELECT a,b,c FROM 
+      (SELECT x AS 'a', y AS 'b', x+y AS 'c' FROM t1 WHERE y=4)
+    WHERE a<10 ORDER BY a;
+  }
+} {8 4 12 9 4 13}
+do_test select6-4.2 {
+  execsql {
+    SELECT y FROM (SELECT DISTINCT y FROM t1) WHERE y<5 ORDER BY y
+  }
+} {1 2 3 4}
+do_test select6-4.3 {
+  execsql {
+    SELECT DISTINCT y FROM (SELECT y FROM t1) WHERE y<5 ORDER BY y
+  }
+} {1 2 3 4}
+
+
 finish_test
index 6cc8838bacf32fd6c529dc079d9eeb2802a3f5d8..83f99484bd4ea1cfa8d93367d93ad9937300dc31 100644 (file)
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the VACUUM statement.
 #
-# $Id: vacuum.test,v 1.6 2001/09/16 00:13:28 drh Exp $
+# $Id: vacuum.test,v 1.7 2002/03/03 02:49:52 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
 
-if {0} {
+# The vacuum command no longer functions.  There is
+# nothing to test.
 
-# Try to vacuum a non-existant table.
-#
-do_test vacuum-1.1 {
-  set v [catch {execsql {VACUUM dummy1}} msg]
-  lappend v $msg
-} {1 {no such table or index: dummy1}}
-
-# It is OK to vacuum sqlite_master...
-#
-do_test vacuum-1.2 {
-  set v [catch {execsql {VACUUM sqlite_master}} msg]
-  lappend v $msg
-} {0 {}}
-
-# Create some tables and indices to test against.
-#
-execsql {CREATE TABLE test1(a int)}
-execsql {CREATE TABLE test2(b int)}
-execsql {CREATE INDEX index1 ON test1(a)}
-execsql {INSERT INTO test1 VALUES(1)}
-execsql {INSERT INTO test1 VALUES(1)}
-execsql {INSERT INTO test1 VALUES(2)}
-execsql {INSERT INTO test1 VALUES(3)}
-execsql {INSERT INTO test2 VALUES(4)}
-
-do_test vacuum-1.3 {
-  set b1 [file mtime testdb/test1.tbl]
-  set b2 [file mtime testdb/test2.tbl]
-  set b3 [file mtime testdb/index1.tbl]
-  after 1000
-  execsql {VACUUM test1}
-  set a1 [file mtime testdb/test1.tbl]
-  set a2 [file mtime testdb/test2.tbl]
-  set a3 [file mtime testdb/index1.tbl]
-  expr {$a1>$b1 && $a2==$b2 && $a3==$b3}
-} {1}
-if {$::tcl_platform(platform)!="windows"} {
-do_test vacuum-1.4 {
-  set b1 [file mtime testdb/test1.tbl]
-  set b2 [file mtime testdb/test2.tbl]
-  set b3 [file mtime testdb/index1.tbl]
-  after 1000
-  execsql {VACUUM}
-  set a1 [file mtime testdb/test1.tbl]
-  set a2 [file mtime testdb/test2.tbl]
-  set a3 [file mtime testdb/index1.tbl]
-  expr {$a1>$b1 && $a2>$b2 && $a3>$b3}
-} {1}
-} ;# End if( platform!=windows )
-
-finish_test
-
-}
+# finish_test
index eae3c09fd4295e33207ff337e19834bc97db79c8..7cb108027ff7eb74154850823fa6e25c1255a4dc 100644 (file)
@@ -3103,13 +3103,16 @@ int mhflag;     /* Output in makeheaders format if true */
     }
 
     /* Print the hash table */
-    fprintf(out,"/* State %d */\n",stp->index); lineno++;
+    if( tablesize>0 ){
+      fprintf(out,"/* State %d */\n",stp->index); lineno++;
+    }
     for(j=0; j<tablesize; j++){
       assert( table[j]!=0 );
-      fprintf(out,"  {%4d,%4d,%4d}, /* ",
+      fprintf(out,"  {%4d,%4d,%4d}, /* %2d: ",
           table[j]->sp->index,
           collide[j]+1,
-          compute_action(lemp,table[j]));
+          compute_action(lemp,table[j]),
+          j+1);
       PrintAction(table[j],out,22);
       fprintf(out," */\n"); 
       lineno++;