From: dan Date: Sat, 12 Dec 2015 17:31:40 +0000 (+0000) Subject: Add further tests for the changes on this branch. Also fix a memory-leak that could... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2e001ce59a7a4231580b0aab42c30ea8f40871ec;p=thirdparty%2Fsqlite.git Add further tests for the changes on this branch. Also fix a memory-leak that could follow a malloc failure. FossilOrigin-Name: 21526012c274e709d672dbafb9e16158c0749341 --- diff --git a/manifest b/manifest index c2701fc81c..82bf14cf0a 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index c79ee70735..d91ddc4286 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -57b700baa690f73894cd53b8e87839760fe4019b \ No newline at end of file +21526012c274e709d672dbafb9e16158c0749341 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index fab38eed7e..8de1fb20a8 100644 --- a/src/delete.c +++ b/src/delete.c @@ -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); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f1d60d46f1..e9edfed226 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -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); diff --git a/src/where.c b/src/where.c index 27195a7cb9..636652f854 100644 --- a/src/where.c +++ b/src/where.c @@ -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; } diff --git a/test/delete4.test b/test/delete4.test index 2df4c6614c..f00a11a6fe 100644 --- a/test/delete4.test +++ b/test/delete4.test @@ -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 index 0000000000..f6f78211ec --- /dev/null +++ b/test/delete_fault.test @@ -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 diff --git a/test/fordelete.test b/test/fordelete.test index b0d5fa327f..e600deea90 100644 --- a/test/fordelete.test +++ b/test/fordelete.test @@ -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: # diff --git a/test/table.test b/test/table.test index 9f4a0959fa..a9f051039d 100644 --- a/test/table.test +++ b/test/table.test @@ -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;