mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-14 00:22:38 +03:00
Fix a memory leak to do with the recent UNION ALL sub-select optimization. (CVS 5333)
FossilOrigin-Name: 6ee71f4ddb4fa934f58c87dad2d30560af2e55d7
This commit is contained in:
14
manifest
14
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)
|
C Fix\sa\smemory\sleak\sto\sdo\swith\sthe\srecent\sUNION\sALL\ssub-select\soptimization.\s(CVS\s5333)
|
||||||
D 2008-07-01T14:39:35
|
D 2008-07-01T16:05:26
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in 325dfac0a0dd1cb4d975f1ace6453157892e6042
|
F Makefile.in 325dfac0a0dd1cb4d975f1ace6453157892e6042
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -140,7 +140,7 @@ F src/pragma.c 9a95f5b3708f6d3ddd987eab5f369a19ffcb6795
|
|||||||
F src/prepare.c aba51dad52308e3d9d2074d8ff4e612e7f1cab51
|
F src/prepare.c aba51dad52308e3d9d2074d8ff4e612e7f1cab51
|
||||||
F src/printf.c 8b063da9dcde26b7c500a01444b718d86f21bc6e
|
F src/printf.c 8b063da9dcde26b7c500a01444b718d86f21bc6e
|
||||||
F src/random.c 5c754319d38abdd6acd74601ee0105504adc508a
|
F src/random.c 5c754319d38abdd6acd74601ee0105504adc508a
|
||||||
F src/select.c d1b633882c90a8c8f9e8346d20b3f038dfee48bd
|
F src/select.c 8e9951054ae130661b8e45a74e21d5422c9bb8e2
|
||||||
F src/shell.c 484e7297e066f22830f9c15d7abbcdd2acb097b0
|
F src/shell.c 484e7297e066f22830f9c15d7abbcdd2acb097b0
|
||||||
F src/sqlite.h.in 76c144d23f8824e8811e837e9396b9f1361f5902
|
F src/sqlite.h.in 76c144d23f8824e8811e837e9396b9f1361f5902
|
||||||
F src/sqlite3ext.h 1e3887c9bd3ae66cb599e922824b04cd0d0f2c3e
|
F src/sqlite3ext.h 1e3887c9bd3ae66cb599e922824b04cd0d0f2c3e
|
||||||
@@ -449,7 +449,7 @@ F test/select7.test 7906735805cfbee4dddc0bed4c14e68d7f5f9c5f
|
|||||||
F test/select8.test 391de11bdd52339c30580dabbbbe97e3e9a3c79d
|
F test/select8.test 391de11bdd52339c30580dabbbbe97e3e9a3c79d
|
||||||
F test/select9.test b4007b15396cb7ba2615cab31e1973b572e43210
|
F test/select9.test b4007b15396cb7ba2615cab31e1973b572e43210
|
||||||
F test/selectA.test e4501789a1d0fe9d00db15187623fb5b7031357b
|
F test/selectA.test e4501789a1d0fe9d00db15187623fb5b7031357b
|
||||||
F test/selectB.test 37d21b6f1896b2cadac36faf9c0255f07467f669
|
F test/selectB.test effd81c29572fb35d8aa39e4b73dbf194f5f68ea
|
||||||
F test/server1.test f5b790d4c0498179151ca8a7715a65a7802c859c
|
F test/server1.test f5b790d4c0498179151ca8a7715a65a7802c859c
|
||||||
F test/shared.test c6769531e0cb751d46a9838c0532d3786606c0f6
|
F test/shared.test c6769531e0cb751d46a9838c0532d3786606c0f6
|
||||||
F test/shared2.test 0ee9de8964d70e451936a48c41cb161d9134ccf4
|
F test/shared2.test 0ee9de8964d70e451936a48c41cb161d9134ccf4
|
||||||
@@ -596,7 +596,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
|||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||||
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
|
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
P 3ef468e7046b2091b5b6880fe19261ef1ee2887b
|
P a79786a961dba8f4ffaddbe55e6467c14b12f7d6
|
||||||
R 57b50557616e52f60ca94711b38caba6
|
R 486d38d9b6a956a8f41daead08c2e751
|
||||||
U danielk1977
|
U danielk1977
|
||||||
Z 5823aa889da28368a392c306fc60b4e7
|
Z 25057041e9180e7e0042d3e827e454fe
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
a79786a961dba8f4ffaddbe55e6467c14b12f7d6
|
6ee71f4ddb4fa934f58c87dad2d30560af2e55d7
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle SELECT statements in SQLite.
|
** 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"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -1918,6 +1918,7 @@ static int multiSelect(
|
|||||||
int aSetP2[2]; /* Set P2 value of these op to number of columns */
|
int aSetP2[2]; /* Set P2 value of these op to number of columns */
|
||||||
int nSetP2 = 0; /* Number of slots in aSetP2[] used */
|
int nSetP2 = 0; /* Number of slots in aSetP2[] used */
|
||||||
SelectDest dest; /* Alternative data destination */
|
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
|
/* 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.
|
** 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"));
|
VdbeComment((v, "Jump ahead if LIMIT reached"));
|
||||||
}
|
}
|
||||||
rc = sqlite3Select(pParse, p, &dest, 0, 0, 0, aff);
|
rc = sqlite3Select(pParse, p, &dest, 0, 0, 0, aff);
|
||||||
|
pDelete = p->pPrior;
|
||||||
p->pPrior = pPrior;
|
p->pPrior = pPrior;
|
||||||
if( rc ){
|
if( rc ){
|
||||||
goto multi_select_end;
|
goto multi_select_end;
|
||||||
@@ -2076,6 +2078,7 @@ static int multiSelect(
|
|||||||
/* Query flattening in sqlite3Select() might refill p->pOrderBy.
|
/* Query flattening in sqlite3Select() might refill p->pOrderBy.
|
||||||
** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
|
** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
|
||||||
sqlite3ExprListDelete(p->pOrderBy);
|
sqlite3ExprListDelete(p->pOrderBy);
|
||||||
|
pDelete = p->pPrior;
|
||||||
p->pPrior = pPrior;
|
p->pPrior = pPrior;
|
||||||
p->pOrderBy = pOrderBy;
|
p->pOrderBy = pOrderBy;
|
||||||
sqlite3ExprDelete(p->pLimit);
|
sqlite3ExprDelete(p->pLimit);
|
||||||
@@ -2159,6 +2162,7 @@ static int multiSelect(
|
|||||||
p->pOffset = 0;
|
p->pOffset = 0;
|
||||||
intersectdest.iParm = tab2;
|
intersectdest.iParm = tab2;
|
||||||
rc = sqlite3Select(pParse, p, &intersectdest, 0, 0, 0, aff);
|
rc = sqlite3Select(pParse, p, &intersectdest, 0, 0, 0, aff);
|
||||||
|
pDelete = p->pPrior;
|
||||||
p->pPrior = pPrior;
|
p->pPrior = pPrior;
|
||||||
sqlite3ExprDelete(p->pLimit);
|
sqlite3ExprDelete(p->pLimit);
|
||||||
p->pLimit = pLimit;
|
p->pLimit = pLimit;
|
||||||
@@ -2304,6 +2308,7 @@ static int multiSelect(
|
|||||||
multi_select_end:
|
multi_select_end:
|
||||||
pDest->iMem = dest.iMem;
|
pDest->iMem = dest.iMem;
|
||||||
pDest->nMem = dest.nMem;
|
pDest->nMem = dest.nMem;
|
||||||
|
sqlite3SelectDelete(pDelete);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
#endif /* SQLITE_OMIT_COMPOUND_SELECT */
|
#endif /* SQLITE_OMIT_COMPOUND_SELECT */
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# This file implements regression tests for SQLite library.
|
# 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]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@@ -51,61 +51,149 @@ do_test selectB-1.1 {
|
|||||||
}
|
}
|
||||||
} {}
|
} {}
|
||||||
|
|
||||||
test_transform selectB-1.2 {
|
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 * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2)
|
||||||
} {
|
} {
|
||||||
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}
|
} {2 8 14 3 12 21}
|
||||||
|
|
||||||
test_transform selectB-1.3 {
|
test_transform selectB-$ii.3 {
|
||||||
SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2) ORDER BY 1
|
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
|
SELECT a FROM t1 UNION ALL SELECT d FROM t2 ORDER BY 1
|
||||||
} {2 3 8 12 14 21}
|
} {2 3 8 12 14 21}
|
||||||
|
|
||||||
test_transform selectB-1.4 {
|
test_transform selectB-$ii.4 {
|
||||||
SELECT * FROM
|
SELECT * FROM
|
||||||
(SELECT a FROM t1 UNION ALL SELECT d FROM t2)
|
(SELECT a FROM t1 UNION ALL SELECT d FROM t2)
|
||||||
WHERE a>10 ORDER BY 1
|
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
|
SELECT a FROM t1 WHERE a>10 UNION ALL SELECT d FROM t2 WHERE d>10 ORDER BY 1
|
||||||
} {12 14 21}
|
} {12 14 21}
|
||||||
|
|
||||||
test_transform selectB-1.5 {
|
test_transform selectB-$ii.5 {
|
||||||
SELECT * FROM
|
SELECT * FROM
|
||||||
(SELECT a FROM t1 UNION ALL SELECT d FROM t2)
|
(SELECT a FROM t1 UNION ALL SELECT d FROM t2)
|
||||||
WHERE a>10 ORDER BY a
|
WHERE a>10 ORDER BY a
|
||||||
} {
|
} {
|
||||||
SELECT a FROM t1 WHERE a>10
|
SELECT a FROM t1 WHERE a>10
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT d FROM t2 WHERE d>10
|
SELECT d FROM t2 WHERE d>10
|
||||||
ORDER BY a
|
ORDER BY a
|
||||||
} {12 14 21}
|
} {12 14 21}
|
||||||
|
|
||||||
test_transform selectB-1.6 {
|
test_transform selectB-$ii.6 {
|
||||||
SELECT * FROM
|
SELECT * FROM
|
||||||
(SELECT a FROM t1 UNION ALL SELECT d FROM t2 WHERE d > 12)
|
(SELECT a FROM t1 UNION ALL SELECT d FROM t2 WHERE d > 12)
|
||||||
WHERE a>10 ORDER BY a
|
WHERE a>10 ORDER BY a
|
||||||
} {
|
} {
|
||||||
SELECT a FROM t1 WHERE a>10
|
SELECT a FROM t1 WHERE a>10
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT d FROM t2 WHERE d>12 AND d>10
|
SELECT d FROM t2 WHERE d>12 AND d>10
|
||||||
ORDER BY a
|
ORDER BY a
|
||||||
} {14 21}
|
} {14 21}
|
||||||
|
|
||||||
test_transform selectB-1.7 {
|
test_transform selectB-$ii.7 {
|
||||||
SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2) ORDER BY 1 LIMIT 2
|
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
|
SELECT a FROM t1 UNION ALL SELECT d FROM t2 ORDER BY 1 LIMIT 2
|
||||||
} {2 3}
|
} {2 3}
|
||||||
|
|
||||||
test_transform selectB-1.8 {
|
test_transform selectB-$ii.8 {
|
||||||
SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2) ORDER BY 1
|
SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2) ORDER BY 1
|
||||||
LIMIT 2 OFFSET 3
|
LIMIT 2 OFFSET 3
|
||||||
} {
|
} {
|
||||||
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}
|
} {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
|
finish_test
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user