]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Further stat4 related tests.
authordan <dan@noemail.net>
Mon, 2 Sep 2013 18:58:11 +0000 (18:58 +0000)
committerdan <dan@noemail.net>
Mon, 2 Sep 2013 18:58:11 +0000 (18:58 +0000)
FossilOrigin-Name: 0a702c4b4c35fdbcb62e3ab88b9e57d7ea0052a8

manifest
manifest.uuid
src/analyze.c
test/analyze9.test
test/permutations.test

index 9680d50eec801eb61f7045b438799b6b666001e1..74678df38daa377af95d543e616b8e87083eefd9 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\stests\sto\scheck\sif\sANALYZE\sis\schoosing\scommon\snon-periodic\ssamples\sfor\sthe\sstat4\stable.
-D 2013-09-02T11:52:11.512
+C Further\sstat4\srelated\stests.
+D 2013-09-02T18:58:11.176
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -157,7 +157,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
 F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
 F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083
-F src/analyze.c 128f85d9bd7e79e93b8b27aa2bb54a43ad0c00f3
+F src/analyze.c 66903e3e5a36eee728c0dc1d574e8cb16059210f
 F src/attach.c fea00cab11c854646a27641a263f5876569a51f9
 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
 F src/backup.c 2f1987981139bd2f6d8c728d64bf09fb387443c3
@@ -308,7 +308,7 @@ F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4
 F test/analyze6.test 19151da2c4e918905d2081b74ac5c4d47fc850ab
 F test/analyze7.test bb1409afc9e8629e414387ef048b8e0e3e0bdc4f
 F test/analyze8.test 093d15c1c888eed5034304a98c992f7360130b88
-F test/analyze9.test bce50d7448d4c51e1a2fd8efdcf895c2e5042e76
+F test/analyze9.test 3b23fc97bcc0f4b5629aacdd8e1aa267114dcc79
 F test/analyzeA.test 1a5c40079894847976d983ca39c707aaa44b6944
 F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
 F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
@@ -716,7 +716,7 @@ F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0
 F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d
 F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
 F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54
-F test/permutations.test c5e7ae8a18cb8a0ced38dbbc9e2463536c1de45b
+F test/permutations.test 47f8c1d3d72ea46863426dcedb1e368f4b6ed70b
 F test/pragma.test 5e7de6c32a5d764f09437d2025f07e4917b9e178
 F test/pragma2.test 224f0381f9411a78ae685cac24c13656a62021b7
 F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
@@ -1109,7 +1109,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P c21f58d84859e479a6cc619671a0df48b2f9692e
-R 9fc61f7137863d5244ff2fd6cc214c12
+P 175842997af134138784bff6f8e93573deb5b36b
+R b9c05f2f20c9bc7024ff33ef435a0342
 U dan
-Z 6c1b0e52f8f47aae31db001aa8668b6b
+Z 4390b50c9d94be4a8d0945a9543a37a9
index 569ff735b6a26756f7f02d1b991d13e68e55e5fd..f4fb99e6d6fc921d591a0bb3d5f9d3c8fc48ad56 100644 (file)
@@ -1 +1 @@
-175842997af134138784bff6f8e93573deb5b36b
\ No newline at end of file
+0a702c4b4c35fdbcb62e3ab88b9e57d7ea0052a8
\ No newline at end of file
index d70f77e779a82b7f0952e274910e68ed5104f475..89dc84f2c18ca45756e296c3474b6f19a42957b3 100644 (file)
@@ -468,14 +468,25 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
     p->nSample = p->mxSample-1;
   }
 
-  /* Figure out where in the a[] array the new sample should be inserted. */
+  /* The "rows less-than" for the rowid column must be greater than that
+  ** for the last sample in the p->a[] array. Otherwise, the samples would
+  ** be out of order. */
+#ifdef SQLITE_ENABLE_STAT4
+  assert( p->nSample==0 
+       || pNew->anLt[p->nCol-1] > p->a[p->nSample-1].anLt[p->nCol-1] );
+#endif
+
+  /* Insert the new sample */
+  pSample = &p->a[p->nSample];
+  sampleCopy(p, pSample, pNew);
+  p->nSample++;
+
+#if 0
   iSeq = pNew->anLt[p->nCol-1];
   for(iPos=p->nSample; iPos>0; iPos--){
     if( iSeq>p->a[iPos-1].anLt[p->nCol-1] ) break;
   }
 
-  /* Insert the new sample */
-  pSample = &p->a[iPos];
   if( iPos!=p->nSample ){
     Stat4Sample *pEnd = &p->a[p->nSample];
     tRowcnt *anEq = pEnd->anEq;
@@ -486,8 +497,8 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
     pSample->anDLt = anDLt;
     pSample->anLt = anLt;
   }
-  p->nSample++;
-  sampleCopy(p, pSample, pNew);
+#endif
+
 
   /* Zero the first nEqZero entries in the anEq[] array. */
   memset(pSample->anEq, 0, sizeof(tRowcnt)*nEqZero);
@@ -584,8 +595,7 @@ static void statPush(
   assert( iChng<p->nCol );
 
   if( p->nRow==0 ){
-    /* anEq[0] is only zero for the very first call to this function.  Do
-    ** appropriate initialization */
+    /* This is the first call to this function. Do initialization. */
     for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
   }else{
     /* Second and subsequent calls get processed here */
index 415d69a56cbf107ef292dfb751b48243064bad31..777e462fdb38b1958eb61b807fd6bf727156a60e 100644 (file)
@@ -705,5 +705,216 @@ do_test 14.3.1 {
 } {}
 check_stat4 14.3.2
 
+do_test 14.4.1 {
+  execsql {DELETE FROM t1}
+  for {set i 1} {$i < 160} {incr i} {
+    set b [expr $i % 10]
+    if {$b==0 || $b==2} {set b 1}
+    execsql { INSERT INTO t1 VALUES($i/10,$b,$i,$i) }
+  }
+} {}
+check_stat4 14.4.2
+db func lrange lrange
+db func lindex lindex
+do_execsql_test 14.4.3 {
+  SELECT lrange(test_decode(sample), 0, 1) AS s FROM sqlite_stat4
+  WHERE lindex(s, 1)=='1' ORDER BY rowid
+} {
+  {0 1} {1 1} {2 1} {3 1} 
+  {4 1} {5 1} {6 1} {7 1} 
+  {8 1} {9 1} {10 1} {11 1} 
+  {12 1} {13 1} {14 1} {15 1}
+}
+
+#-------------------------------------------------------------------------
+# Test that nothing untoward happens if the stat4 table contains entries
+# for indexes that do not exist. Or NULL values in the idx column.
+# Or NULL values in any of the other columns.
+#
+drop_all_tables
+do_execsql_test 15.1 {
+  CREATE TABLE x1(a, b, UNIQUE(a, b));
+  INSERT INTO x1 VALUES(1, 2);
+  INSERT INTO x1 VALUES(3, 4);
+  INSERT INTO x1 VALUES(5, 6);
+  ANALYZE;
+  INSERT INTO sqlite_stat4 VALUES(NULL, NULL, NULL, NULL, NULL, NULL);
+}
+db close
+sqlite3 db test.db
+do_execsql_test 15.2 { SELECT * FROM x1 } {1 2 3 4 5 6}
+
+do_execsql_test 15.3 {
+  INSERT INTO sqlite_stat4 VALUES(42, 42, 42, 42, 42, 42);
+}
+db close
+sqlite3 db test.db
+do_execsql_test 15.4 { SELECT * FROM x1 } {1 2 3 4 5 6}
+
+do_execsql_test 15.5 {
+  UPDATE sqlite_stat1 SET stat = NULL;
+}
+db close
+sqlite3 db test.db
+do_execsql_test 15.6 { SELECT * FROM x1 } {1 2 3 4 5 6}
+
+do_execsql_test 15.7 {
+  ANALYZE;
+  UPDATE sqlite_stat1 SET tbl = 'no such tbl';
+}
+db close
+sqlite3 db test.db
+do_execsql_test 15.8 { SELECT * FROM x1 } {1 2 3 4 5 6}
+
+do_execsql_test 15.9 {
+  ANALYZE;
+  UPDATE sqlite_stat4 SET neq = NULL, nlt=NULL, ndlt=NULL;
+}
+db close
+sqlite3 db test.db
+do_execsql_test 15.10 { SELECT * FROM x1 } {1 2 3 4 5 6}
+
+# This is just for coverage....
+do_execsql_test 15.11 {
+  ANALYZE;
+  UPDATE sqlite_stat1 SET stat = stat || ' unordered';
+}
+db close
+sqlite3 db test.db
+do_execsql_test 15.12 { SELECT * FROM x1 } {1 2 3 4 5 6}
+
+#-------------------------------------------------------------------------
+# Test that allocations used for sqlite_stat4 samples are included in
+# the quantity returned by SQLITE_DBSTATUS_SCHEMA_USED.
+#
+set one [string repeat x 1000]
+set two [string repeat x 2000]
+do_test 16.1 {
+  reset_db
+  execsql {
+    CREATE TABLE t1(a, UNIQUE(a));
+    INSERT INTO t1 VALUES($one);
+    ANALYZE;
+  }
+  set nByte [lindex [sqlite3_db_status db SCHEMA_USED 0] 1]
+
+  reset_db
+  execsql {
+    CREATE TABLE t1(a, UNIQUE(a));
+    INSERT INTO t1 VALUES($two);
+    ANALYZE;
+  }
+  set nByte2 [lindex [sqlite3_db_status db SCHEMA_USED 0] 1]
+
+  expr {$nByte2 > $nByte+950 && $nByte2 < $nByte+1050}
+} {1}
+
+#-------------------------------------------------------------------------
+# Test that stat4 data may be used with partial indexes.
+#
+do_test 17.1 {
+  reset_db
+  execsql {
+    CREATE TABLE t1(a, b, c, d);
+    CREATE INDEX i1 ON t1(a, b) WHERE d IS NOT NULL;
+    INSERT INTO t1 VALUES(-1, -1, -1, NULL);
+    INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
+    INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
+    INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
+    INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
+    INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
+    INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
+  }
+
+  for {set i 0} {$i < 32} {incr i} {
+    if {$i<8} {set b 0} else { set b $i }
+    execsql { INSERT INTO t1 VALUES($i%2, $b, $i/2, 'abc') }
+  }
+  execsql {ANALYZE main.t1}
+} {}
+
+do_catchsql_test 17.1.2 {
+  ANALYZE temp.t1;
+} {1 {no such table: temp.t1}}
+
+do_eqp_test 17.2 {
+  SELECT * FROM t1 WHERE d IS NOT NULL AND a=0 AND b=10 AND c=10;
+} {/USING INDEX i1/}
+do_eqp_test 17.3 {
+  SELECT * FROM t1 WHERE d IS NOT NULL AND a=0 AND b=0 AND c=10;
+} {/USING INDEX i1/}
+
+do_execsql_test 17.4 {
+  CREATE INDEX i2 ON t1(c);
+  ANALYZE main.i2;
+}
+do_eqp_test 17.5 {
+  SELECT * FROM t1 WHERE d IS NOT NULL AND a=0 AND b=10 AND c=10;
+} {/USING INDEX i1/}
+do_eqp_test 17.6 {
+  SELECT * FROM t1 WHERE d IS NOT NULL AND a=0 AND b=0 AND c=10;
+} {/USING INDEX i2/}
+
+#-------------------------------------------------------------------------
+#
+do_test 18.1 {
+  reset_db
+  execsql {
+    CREATE TABLE t1(a, b);
+    CREATE INDEX i1 ON t1(a, b);
+  }
+  for {set i 0} {$i < 9} {incr i} {
+    execsql {
+      INSERT INTO t1 VALUES($i, 0);
+      INSERT INTO t1 VALUES($i, 0);
+      INSERT INTO t1 VALUES($i, 0);
+      INSERT INTO t1 VALUES($i, 0);
+      INSERT INTO t1 VALUES($i, 0);
+      INSERT INTO t1 VALUES($i, 0);
+      INSERT INTO t1 VALUES($i, 0);
+      INSERT INTO t1 VALUES($i, 0);
+      INSERT INTO t1 VALUES($i, 0);
+      INSERT INTO t1 VALUES($i, 0);
+      INSERT INTO t1 VALUES($i, 0);
+      INSERT INTO t1 VALUES($i, 0);
+      INSERT INTO t1 VALUES($i, 0);
+      INSERT INTO t1 VALUES($i, 0);
+      INSERT INTO t1 VALUES($i, 0);
+    }
+  }
+  execsql ANALYZE
+  execsql { SELECT count(*) FROM sqlite_stat4 }
+} {9}
+
+#-------------------------------------------------------------------------
+# For coverage.
+#
+ifcapable view {
+  do_test 19.1 {
+    reset_db 
+    execsql {
+      CREATE TABLE t1(x, y);
+      CREATE INDEX i1 ON t1(x, y);
+      CREATE VIEW v1 AS SELECT * FROM t1;
+      ANALYZE;
+    }
+  } {}
+}
+ifcapable auth {
+  proc authproc {op args} {
+    if {$op == "SQLITE_ANALYZE"} { return "SQLITE_DENY" }
+    return "SQLITE_OK"
+  }
+  do_test 19.2 {
+    reset_db 
+    db auth authproc
+    execsql {
+      CREATE TABLE t1(x, y);
+      CREATE VIEW v1 AS SELECT * FROM t1;
+    }
+    catchsql ANALYZE
+  } {1 {not authorized}}
+}
+
 finish_test
 
index 755565f1d7cedab6f406e9247fbe6a466c002907..b9033932d8b69e3e28456b5f2c95dc7d89916817 100644 (file)
@@ -311,6 +311,14 @@ test_suite "coverage-pager" -description {
   walfault.test  walbak.test  journal2.test    tkt-9d68c883.test
 } 
 
+test_suite "coverage-analyze" -description {
+  Coverage tests for file analyze.c.
+} -files {
+  analyze3.test analyze4.test analyze5.test analyze6.test
+  analyze7.test analyze8.test analyze9.test analyzeA.test
+  analyze.test mallocA.test
+} 
+
 
 lappend ::testsuitelist xxx
 #-------------------------------------------------------------------------