From: danielk1977 Date: Tue, 1 Jul 2008 16:05:25 +0000 (+0000) Subject: Fix a memory leak to do with the recent UNION ALL sub-select optimization. (CVS 5333) X-Git-Tag: version-3.6.10~844 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=eca7e01a71e90942907e16994614a076ee7812e3;p=thirdparty%2Fsqlite.git Fix a memory leak to do with the recent UNION ALL sub-select optimization. (CVS 5333) FossilOrigin-Name: 6ee71f4ddb4fa934f58c87dad2d30560af2e55d7 --- diff --git a/manifest b/manifest index 135265649d..4cd7f3e658 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sLIMIT\sand\sOFFSET\sclauses\son\sthe\sparent\squery\swhen\soptimizing\sa\sUNION\sALL\ssub-select.\s(CVS\s5332) -D 2008-07-01T14:39:35 +C Fix\sa\smemory\sleak\sto\sdo\swith\sthe\srecent\sUNION\sALL\ssub-select\soptimization.\s(CVS\s5333) +D 2008-07-01T16:05:26 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 325dfac0a0dd1cb4d975f1ace6453157892e6042 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -140,7 +140,7 @@ F src/pragma.c 9a95f5b3708f6d3ddd987eab5f369a19ffcb6795 F src/prepare.c aba51dad52308e3d9d2074d8ff4e612e7f1cab51 F src/printf.c 8b063da9dcde26b7c500a01444b718d86f21bc6e F src/random.c 5c754319d38abdd6acd74601ee0105504adc508a -F src/select.c d1b633882c90a8c8f9e8346d20b3f038dfee48bd +F src/select.c 8e9951054ae130661b8e45a74e21d5422c9bb8e2 F src/shell.c 484e7297e066f22830f9c15d7abbcdd2acb097b0 F src/sqlite.h.in 76c144d23f8824e8811e837e9396b9f1361f5902 F src/sqlite3ext.h 1e3887c9bd3ae66cb599e922824b04cd0d0f2c3e @@ -449,7 +449,7 @@ F test/select7.test 7906735805cfbee4dddc0bed4c14e68d7f5f9c5f F test/select8.test 391de11bdd52339c30580dabbbbe97e3e9a3c79d F test/select9.test b4007b15396cb7ba2615cab31e1973b572e43210 F test/selectA.test e4501789a1d0fe9d00db15187623fb5b7031357b -F test/selectB.test 37d21b6f1896b2cadac36faf9c0255f07467f669 +F test/selectB.test effd81c29572fb35d8aa39e4b73dbf194f5f68ea F test/server1.test f5b790d4c0498179151ca8a7715a65a7802c859c F test/shared.test c6769531e0cb751d46a9838c0532d3786606c0f6 F test/shared2.test 0ee9de8964d70e451936a48c41cb161d9134ccf4 @@ -596,7 +596,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P 3ef468e7046b2091b5b6880fe19261ef1ee2887b -R 57b50557616e52f60ca94711b38caba6 +P a79786a961dba8f4ffaddbe55e6467c14b12f7d6 +R 486d38d9b6a956a8f41daead08c2e751 U danielk1977 -Z 5823aa889da28368a392c306fc60b4e7 +Z 25057041e9180e7e0042d3e827e454fe diff --git a/manifest.uuid b/manifest.uuid index 0b9e63c5fe..70a3bc9732 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a79786a961dba8f4ffaddbe55e6467c14b12f7d6 \ No newline at end of file +6ee71f4ddb4fa934f58c87dad2d30560af2e55d7 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 7eaa919974..811ded6940 100644 --- a/src/select.c +++ b/src/select.c @@ -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.442 2008/07/01 14:39:35 danielk1977 Exp $ +** $Id: select.c,v 1.443 2008/07/01 16:05:26 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -1918,6 +1918,7 @@ static int multiSelect( int aSetP2[2]; /* Set P2 value of these op to number of columns */ int nSetP2 = 0; /* Number of slots in aSetP2[] used */ SelectDest dest; /* Alternative data destination */ + Select *pDelete = 0; /* Chain of simple selects to delete */ /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT. @@ -2000,6 +2001,7 @@ static int multiSelect( VdbeComment((v, "Jump ahead if LIMIT reached")); } rc = sqlite3Select(pParse, p, &dest, 0, 0, 0, aff); + pDelete = p->pPrior; p->pPrior = pPrior; if( rc ){ goto multi_select_end; @@ -2076,6 +2078,7 @@ static int multiSelect( /* Query flattening in sqlite3Select() might refill p->pOrderBy. ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */ sqlite3ExprListDelete(p->pOrderBy); + pDelete = p->pPrior; p->pPrior = pPrior; p->pOrderBy = pOrderBy; sqlite3ExprDelete(p->pLimit); @@ -2159,6 +2162,7 @@ static int multiSelect( p->pOffset = 0; intersectdest.iParm = tab2; rc = sqlite3Select(pParse, p, &intersectdest, 0, 0, 0, aff); + pDelete = p->pPrior; p->pPrior = pPrior; sqlite3ExprDelete(p->pLimit); p->pLimit = pLimit; @@ -2304,6 +2308,7 @@ static int multiSelect( multi_select_end: pDest->iMem = dest.iMem; pDest->nMem = dest.nMem; + sqlite3SelectDelete(pDelete); return rc; } #endif /* SQLITE_OMIT_COMPOUND_SELECT */ diff --git a/test/selectB.test b/test/selectB.test index de3fb0374f..f988d671b7 100644 --- a/test/selectB.test +++ b/test/selectB.test @@ -10,7 +10,7 @@ #*********************************************************************** # This file implements regression tests for SQLite library. # -# $Id: selectB.test,v 1.2 2008/07/01 14:39:35 danielk1977 Exp $ +# $Id: selectB.test,v 1.3 2008/07/01 16:05:26 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -51,61 +51,149 @@ do_test selectB-1.1 { } } {} -test_transform selectB-1.2 { - SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2) -} { - SELECT a FROM t1 UNION ALL SELECT d FROM t2 -} {2 8 14 3 12 21} - -test_transform selectB-1.3 { - SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2) ORDER BY 1 -} { - SELECT a FROM t1 UNION ALL SELECT d FROM t2 ORDER BY 1 -} {2 3 8 12 14 21} - -test_transform selectB-1.4 { - SELECT * FROM - (SELECT a FROM t1 UNION ALL SELECT d FROM t2) - WHERE a>10 ORDER BY 1 -} { - SELECT a FROM t1 WHERE a>10 UNION ALL SELECT d FROM t2 WHERE d>10 ORDER BY 1 -} {12 14 21} - -test_transform selectB-1.5 { - SELECT * FROM - (SELECT a FROM t1 UNION ALL SELECT d FROM t2) - WHERE a>10 ORDER BY a -} { - SELECT a FROM t1 WHERE a>10 - UNION ALL - SELECT d FROM t2 WHERE d>10 - ORDER BY a -} {12 14 21} - -test_transform selectB-1.6 { - SELECT * FROM - (SELECT a FROM t1 UNION ALL SELECT d FROM t2 WHERE d > 12) - WHERE a>10 ORDER BY a -} { - SELECT a FROM t1 WHERE a>10 - UNION ALL - SELECT d FROM t2 WHERE d>12 AND d>10 - ORDER BY a -} {14 21} - -test_transform selectB-1.7 { - SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2) ORDER BY 1 LIMIT 2 -} { - SELECT a FROM t1 UNION ALL SELECT d FROM t2 ORDER BY 1 LIMIT 2 -} {2 3} - -test_transform selectB-1.8 { - SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2) ORDER BY 1 - LIMIT 2 OFFSET 3 -} { - SELECT a FROM t1 UNION ALL SELECT d FROM t2 ORDER BY 1 LIMIT 2 OFFSET 3 -} {12 14} +for {set ii 1} {$ii <= 2} {incr ii} { + if {$ii == 2} { + do_test selectB-2.1 { + execsql { + CREATE INDEX i1 ON t1(a); + CREATE INDEX i2 ON t2(d); + } + } {} + } + + test_transform selectB-$ii.2 { + SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2) + } { + SELECT a FROM t1 UNION ALL SELECT d FROM t2 + } {2 8 14 3 12 21} + + test_transform selectB-$ii.3 { + SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2) ORDER BY 1 + } { + SELECT a FROM t1 UNION ALL SELECT d FROM t2 ORDER BY 1 + } {2 3 8 12 14 21} + + test_transform selectB-$ii.4 { + SELECT * FROM + (SELECT a FROM t1 UNION ALL SELECT d FROM t2) + WHERE a>10 ORDER BY 1 + } { + SELECT a FROM t1 WHERE a>10 UNION ALL SELECT d FROM t2 WHERE d>10 ORDER BY 1 + } {12 14 21} + + test_transform selectB-$ii.5 { + SELECT * FROM + (SELECT a FROM t1 UNION ALL SELECT d FROM t2) + WHERE a>10 ORDER BY a + } { + SELECT a FROM t1 WHERE a>10 + UNION ALL + SELECT d FROM t2 WHERE d>10 + ORDER BY a + } {12 14 21} + + test_transform selectB-$ii.6 { + SELECT * FROM + (SELECT a FROM t1 UNION ALL SELECT d FROM t2 WHERE d > 12) + WHERE a>10 ORDER BY a + } { + SELECT a FROM t1 WHERE a>10 + UNION ALL + SELECT d FROM t2 WHERE d>12 AND d>10 + ORDER BY a + } {14 21} + + test_transform selectB-$ii.7 { + SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2) ORDER BY 1 + LIMIT 2 + } { + SELECT a FROM t1 UNION ALL SELECT d FROM t2 ORDER BY 1 LIMIT 2 + } {2 3} + + test_transform selectB-$ii.8 { + SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2) ORDER BY 1 + LIMIT 2 OFFSET 3 + } { + SELECT a FROM t1 UNION ALL SELECT d FROM t2 ORDER BY 1 LIMIT 2 OFFSET 3 + } {12 14} + + test_transform selectB-$ii.9 { + SELECT * FROM ( + SELECT a FROM t1 UNION ALL SELECT d FROM t2 UNION ALL SELECT c FROM t1 + ) + } { + SELECT a FROM t1 UNION ALL SELECT d FROM t2 UNION ALL SELECT c FROM t1 + } {2 8 14 3 12 21 6 12 18} + + test_transform selectB-$ii.10 { + SELECT * FROM ( + SELECT a FROM t1 UNION ALL SELECT d FROM t2 UNION ALL SELECT c FROM t1 + ) ORDER BY 1 + } { + SELECT a FROM t1 UNION ALL SELECT d FROM t2 UNION ALL SELECT c FROM t1 + ORDER BY 1 + } {2 3 6 8 12 12 14 18 21} + + test_transform selectB-$ii.11 { + SELECT * FROM ( + SELECT a FROM t1 UNION ALL SELECT d FROM t2 UNION ALL SELECT c FROM t1 + ) WHERE a>=10 ORDER BY 1 LIMIT 3 + } { + SELECT a FROM t1 WHERE a>=10 UNION ALL SELECT d FROM t2 WHERE d>=10 + UNION ALL SELECT c FROM t1 WHERE c>=10 + ORDER BY 1 LIMIT 3 + } {12 12 14} + +} + + +do_test selectB-2.1 { + execsql { + SELECT DISTINCT * FROM + (SELECT c FROM t1 UNION ALL SELECT e FROM t2) + ORDER BY 1; + } +} {6 12 15 18 24} + +do_test selectB-2.2 { + execsql { + SELECT c, count(*) FROM + (SELECT c FROM t1 UNION ALL SELECT e FROM t2) + GROUP BY c ORDER BY 1; + } +} {6 2 12 1 15 1 18 1 24 1} +do_test selectB-2.3 { + execsql { + SELECT c, count(*) FROM + (SELECT c FROM t1 UNION ALL SELECT e FROM t2) + GROUP BY c HAVING count(*)>1; + } +} {6 2} +do_test selectB-2.4 { + execsql { + SELECT t4.c, t3.a FROM + (SELECT c FROM t1 UNION ALL SELECT e FROM t2) AS t4, t1 AS t3 + WHERE t3.a=14 + ORDER BY 1 + } +} {6 14 6 14 12 14 15 14 18 14 24 14} + +do_test selectB-2.5 { + execsql { + SELECT d FROM t2 + EXCEPT + SELECT a FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2) + } +} {} + +do_test selectB-2.6 { + execsql { + SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2) + EXCEPT + SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2) + } +} {} finish_test