]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add further tests for the changes on this branch. Also fix a memory-leak that could...
authordan <dan@noemail.net>
Sat, 12 Dec 2015 17:31:40 +0000 (17:31 +0000)
committerdan <dan@noemail.net>
Sat, 12 Dec 2015 17:31:40 +0000 (17:31 +0000)
FossilOrigin-Name: 21526012c274e709d672dbafb9e16158c0749341

manifest
manifest.uuid
src/delete.c
src/sqliteInt.h
src/where.c
test/delete4.test
test/delete_fault.test [new file with mode: 0644]
test/fordelete.test
test/table.test

index c2701fc81c9b927260d044c929347ea898182f34..82bf14cf0a739d0edafc0e91fe7e130b66036963 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Merge\srecent\schanges\sfrom\strunk.\s\sAlso\sremove\sunused\svariables\sto\spermit\ncompiling\swith\s-Werror.
-D 2015-12-11T13:59:45.914
+C Add\sfurther\stests\sfor\sthe\schanges\son\sthis\sbranch.\sAlso\sfix\sa\smemory-leak\sthat\scould\sfollow\sa\smalloc\sfailure.
+D 2015-12-12T17:31:40.728
 F Makefile.in 28bcd6149e050dff35d4dcfd97e890cd387a499d
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc e8fdca1cb89a1b58b5f4d3a130ea9a3d28cb314d
@@ -291,7 +291,7 @@ F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
 F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
 F src/date.c fb1c99172017dcc8e237339132c91a21a0788584
 F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78
-F src/delete.c 93f68145ac74fd8f7849175e09db4fd70e96b03d
+F src/delete.c a7ada4d4ca96daa71508d73128ffe5f1710f6c33
 F src/expr.c ccb93d7b7e1ac5d187c9b153bae145933f93ee5c
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
 F src/fkey.c 31900763094a3736a5fc887469202eb579fef2d0
@@ -344,7 +344,7 @@ F src/shell.c abbc74ea43dbf2f306ea18282d666683fb5efab2
 F src/sqlite.h.in 7d87d71b9a4689c51fa092f48f16590ff71558e3
 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
 F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d
-F src/sqliteInt.h e93e14407ef5ad4b8eabd7b9a765cfb190722ffb
+F src/sqliteInt.h dd30e0e695e56795ce6cd0694499bb64af48cc16
 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
 F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
@@ -418,7 +418,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
 F src/wal.c cb709aa42fc11b1ea92a00c8c7e6214de0995fa3
 F src/wal.h 907943dfdef10b583e81906679a347e0ec6f1b1b
 F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
-F src/where.c b3b70c8e0f02a4f5f0722322615d93e3f9fb337b
+F src/where.c b7462d37a9819071d252bf167d5e951a2a9c5c1e
 F src/whereInt.h e20801d89e34de1912bb6a3babb30c390da27add
 F src/wherecode.c dfbfe198e418b01f208b489e088edd230c91a4e7
 F src/whereexpr.c eebba8340c90de73b3d3bbe8c43b84559b8e6e2c
@@ -576,7 +576,8 @@ F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
 F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f
 F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
 F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab
-F test/delete4.test fb95a3f0640789cb95ca19f5f9b28731611a6295
+F test/delete4.test dbd922693b52332e5e1f1b748513f11d28414bbc
+F test/delete_fault.test bb4a1ab823f77df32db237ad4e96562d1b06795a
 F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240
 F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d
 F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2
@@ -634,7 +635,7 @@ F test/fkey6.test abb59f866c1b44926fd02d1fdd217d831fe04f48
 F test/fkey7.test 72e915890ee4a005daaf3002cb208e8fe973ac13
 F test/fkey8.test 8f08203458321e6c19a263829de4cfc936274ab0
 F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749
-F test/fordelete.test 3648283f90ab7a8e046d9b0c54e497a80ff7b2a2
+F test/fordelete.test 2b8b9a2d8f430ceacb314b06b020116d3d136931
 F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb
 F test/fts-9fd058691.test 78b887e30ae6816df0e1fed6259de4b5a64ad33c
 F test/fts1a.test 46090311f85da51bb33bd5ce84f7948359c6d8d7
@@ -1058,7 +1059,7 @@ F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
 F test/syscall.test 2aa9e111b79fb385681ff8940124def6f8faab87
 F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04
 F test/tabfunc01.test cc33684f9480fcf1fd5ce287ac28d22971cad1cc
-F test/table.test f85f8694f94ac1275cee81f84bdea66cdcc494c5
+F test/table.test 9ed9aed4a81a0369531b697186ce3a611e57295d
 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
 F test/tclsqlite.test 7fb866443c7deceed22b63948ccd6f76b52ad054
@@ -1410,7 +1411,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 571b64b923c82060f34bf6baa21d72d2a9797e6f e998513e442ce1206b12dc28bdc996d7b5f9f94d
-R 7e34dbe155ea9f60691f4ae03f3a719a
-U drh
-Z abb81097f04b710d8fe83482078029c5
+P 57b700baa690f73894cd53b8e87839760fe4019b
+R 86649e829c9bcb9dbf4e0f992deac233
+U dan
+Z ef334e7566d0d33e4ad81a28a6f57921
index c79ee70735d0bd4f7926e519590bd4f2e7f28cbd..d91ddc4286fc3fabcd1c1c475bd48b2e61fc81a5 100644 (file)
@@ -1 +1 @@
-57b700baa690f73894cd53b8e87839760fe4019b
\ No newline at end of file
+21526012c274e709d672dbafb9e16158c0749341
\ No newline at end of file
index fab38eed7eaa59e702a2bd4b384c934bc2524521..8de1fb20a891d2c79c827483f890d61d100b066d 100644 (file)
@@ -240,6 +240,7 @@ static void deleteSetColUsedSelect(Walker *pWalker, Select *pSelect){
 */
 static void deleteSetColUsed(Parse *pParse, SrcList *pSrc, Expr *pExpr){
   Walker w;
+  assert( pSrc->nSrc==1 );
   memset(&w, 0, sizeof(w));
   w.pParse = pParse;
   w.u.pSrcList = pSrc;
@@ -358,9 +359,10 @@ int deleteFrom(
 
     /* This loop iterates once for each OR-connected term in the WHERE clause */
     for(i=0; rc==SQLITE_OK && (pExpr=sqlite3WhereSplitExpr(pWInfo, i)); i++){
-      if( db->mallocFailed ) break;
-      deleteSetColUsed(pParse, pTabList, pExpr);
-      rc = deleteFrom(pParse, pTabList, pExpr, 0, 0, 0, memCnt, nIdx);
+      if( db->mallocFailed==0 ){
+        deleteSetColUsed(pParse, pTabList, pExpr);
+        rc = deleteFrom(pParse, pTabList, pExpr, 0, 0, 0, memCnt, nIdx);
+      }
       sqlite3ExprDelete(db, pExpr);
     }
     sqlite3WhereInfoFree(db, pWInfo);
index f1d60d46f1562ae4ae296d8d4099f33f1339389c..e9edfed2262875c1ccd8f20fb93570f714dade53 100644 (file)
@@ -3451,7 +3451,7 @@ int sqlite3WhereOkOnePass(WhereInfo*, int*);
 #define ONEPASS_OFF          0    /* Use of ONEPASS not allowed */
 #define ONEPASS_SINGLE       1    /* ONEPASS valid for a single row update */
 #define ONEPASS_MULTI        2    /* ONEPASS is valid for multiple rows */
-#define ONEPASS_SPLIT_DELETE 3
+#define ONEPASS_SPLIT_DELETE 3    /* DELETE should be split into multiple ops */
 void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int);
 int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
 void sqlite3ExprCodeGetColumnToReg(Parse*, Table*, int, int, int);
index 27195a7cb92ae34c9cf9e447d2e1f1100dbd9ffc..636652f8547abea7e0e72677255031bf920e8022 100644 (file)
@@ -1807,9 +1807,11 @@ void sqlite3WhereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
 ** sub-expression iExpr is returned. The caller is responsible for eventually
 ** deleting this object using sqlite3ExprDelete().
 **
-** If an OOM error occurs, NULL is returned. In this case the mallocFailed
-** field of the database handle (pWInfo->pParse->db->mallocFailed) is set 
-** to record the error.
+** If an OOM error occurs, the mallocFailed field of the database handle
+** (pWInfo->pParse->db->mallocFailed) is set to record the error. Even
+** if an OOM error occurs, this function may return a non-NULL pointer. In
+** this case the caller is still responsible for deleting the returned
+** object, even though it is not safe to use.
 */
 Expr *sqlite3WhereSplitExpr(WhereInfo *pWInfo, int iExpr){
   sqlite3 *db = pWInfo->pParse->db;
@@ -4314,6 +4316,13 @@ WhereInfo *sqlite3WhereBegin(
        && 0==(wsFlags & WHERE_VIRTUALTABLE)
     )){
       if( (wsFlags & WHERE_MULTI_OR) && (wctrlFlags & WHERE_ONEPASS_MULTIROW) ){
+        /* This call is being made as part of a DELETE program and the
+        ** optimizer has indicated that the OR-optimization is the best
+        ** approach. In this case it is better to let the caller generate
+        ** a separate loop for each OR'd term than to actually go ahead
+        ** and code the OR-optimized loop. Set the value returned by
+        ** sqlite3WhereOkOnePass() to ONEPASS_SPLIT_DELETE to communicate 
+        ** this to the caller and return early.  */
         pWInfo->eOnePass = ONEPASS_SPLIT_DELETE;
         return pWInfo;
       }
index 2df4c6614c538c914dc076db0113c72ce56607b5..f00a11a6fece999b8b8d62348e2771459cea1852 100644 (file)
@@ -193,4 +193,38 @@ foreach {tn tbl} {
   }
 }
 
+#-------------------------------------------------------------------------
+# Test that nested OR optimizations work.
+#
+do_execsql_test 6.0 {
+  CREATE TABLE t6(a, b, c, d);
+  CREATE INDEX t6a ON t6(a);
+  CREATE INDEX t6b ON t6(b);
+  CREATE INDEX t6c ON t6(c);
+  WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1000 ) 
+  INSERT INTO t6 SELECT i, i*2, i*3, i%2 FROM s;
+}
+
+proc do_61_test {tn sql lDel} {
+  uplevel [list do_execsql_test $tn "
+    BEGIN;
+      $sql;
+      WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1000 ) 
+      SELECT i FROM s EXCEPT SELECT a FROM t6 ORDER BY 1;
+    ROLLBACK;
+  " $lDel]
+}
+
+do_61_test 6.1 {
+  DELETE FROM t6 WHERE a=22 OR b=90 OR (d=0 AND (b=400 OR c=303));
+} {22 45 200}
+
+do_61_test 6.2 {
+  DELETE FROM t6 WHERE a=22 OR b=90 OR (d=1 AND (b=400 OR c=303));
+} {22 45 101}
+
+do_61_test 6.3 {
+  DELETE FROM t6 WHERE (d=0 AND (a=100 OR b=150)) OR (d=1 AND (b=50 OR c=603));
+} {25 100 201}
+
 finish_test
diff --git a/test/delete_fault.test b/test/delete_fault.test
new file mode 100644 (file)
index 0000000..f6f7821
--- /dev/null
@@ -0,0 +1,50 @@
+# 2015 December 10
+#
+# The author disclaims copyright to this source code.  In place of
+# a legal notice, here is a blessing:
+#
+#    May you do good and not evil.
+#    May you find forgiveness for yourself and forgive others.
+#    May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library. The focus
+# of this file is fault-injection into DELETE statements.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set testprefix delete_fault
+
+do_execsql_test 1.0 {
+  CREATE TABLE t6(a, b, c, d);
+  CREATE INDEX t6a ON t6(a);
+  CREATE INDEX t6b ON t6(b);
+  CREATE INDEX t6c ON t6(c);
+  WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1000 ) 
+  INSERT INTO t6 SELECT i, i*2, i*3, i%2 FROM s;
+}
+faultsim_save_and_close
+
+proc deleted_t6_rows {} {
+  db eval {
+    WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1000 ) 
+    SELECT i FROM s EXCEPT SELECT a FROM t6 ORDER BY 1;
+  }
+}
+
+do_faultsim_test 1 -faults oom-t* -prep {
+  faultsim_restore_and_reopen
+} -body {
+  execsql {
+    DELETE FROM t6 WHERE (d=0 AND (a=100 OR b=150)) OR (d=1 AND (b=50 OR c=603))
+  }
+} -test {
+  faultsim_test_result {0 {}}
+  if {$testrc==0} {
+    set lDel [deleted_t6_rows]
+    if {$lDel != "25 100 201"} { error "lDel is $lDel" }
+  }
+}
+
+finish_test
index b0d5fa327fb5e827a763aafeefd8ac6e107d7531..e600deea907659f1626ad1c1839142af93b7bd41 100644 (file)
@@ -108,6 +108,40 @@ foreach {tn where res} {
   do_adp_test 2.3.$tn "DELETE FROM t3 WHERE $where" $res
 }
 
+do_execsql_test 2.4.0 {
+  CREATE TABLE t6(a, b, c, d);
+  CREATE INDEX t6a ON t6(a);
+  CREATE INDEX t6b ON t6(b);
+  CREATE INDEX t6c ON t6(c);
+}
+
+do_adp_test 2.4.1 {
+  DELETE FROM t6 WHERE a=22 OR b=90 OR (d=0 AND (b=400 OR c=303));
+} [lsort {
+  t6* t6a t6b* t6c*
+  t6* t6a* t6b t6c*
+  t6 t6a* t6b t6c*
+  t6 t6a* t6b* t6c
+}]
+
+do_adp_test 2.4.2 {
+  DELETE FROM t6 WHERE a=22 OR b=90 OR (d=1 AND (b=400 OR c=303));
+} [lsort {
+  t6* t6a t6b* t6c*
+  t6* t6a* t6b t6c*
+  t6 t6a* t6b t6c*
+  t6 t6a* t6b* t6c
+}]
+
+do_adp_test 2.4.3 {
+  DELETE FROM t6 WHERE (d=0 AND (a=100 OR b=150)) OR (d=1 AND (b=50 OR c=603));
+} [lsort {
+  t6 t6a t6b* t6c*
+  t6 t6a* t6b t6c*
+  t6 t6a* t6b t6c*
+  t6 t6a* t6b* t6c
+}]
+
 #-------------------------------------------------------------------------
 # Test that a record that consists of the bytes:
 #
index 9f4a0959faa696a1dc5fe5f00d0e26d7e5f5ef57..a9f051039d078307b67d4fdd5f54175d37d64f63 100644 (file)
@@ -837,7 +837,8 @@ do_execsql_test table-19.1 {
 # At one point the DROP TABLE in the following was causing problems on an
 # experimental branch.
 #
-do_execsql_test 20.0 {
+reset_db
+do_execsql_test table-20.0 {
   CREATE TABLE t20(a PRIMARY KEY, b, c);
   CREATE TRIGGER tr6 AFTER INSERT ON t20 BEGIN SELECT 1+1+1; END;
   ANALYZE;