148d1178aSdrh# 2007 November 23 248d1178aSdrh# 348d1178aSdrh# The author disclaims copyright to this source code. In place of 448d1178aSdrh# a legal notice, here is a blessing: 548d1178aSdrh# 648d1178aSdrh# May you do good and not evil. 748d1178aSdrh# May you find forgiveness for yourself and forgive others. 848d1178aSdrh# May you share freely, never taking more than you give. 948d1178aSdrh# 1048d1178aSdrh#*********************************************************************** 1148d1178aSdrh# 1248d1178aSdrh# The tests in this file ensure that a temporary table is used 1348d1178aSdrh# when required by an "INSERT INTO ... SELECT ..." statement. 1448d1178aSdrh# 15de3e41e3Sdanielk1977# $Id: insert5.test,v 1.5 2008/08/04 03:51:24 danielk1977 Exp $ 1648d1178aSdrh 1748d1178aSdrhset testdir [file dirname $argv0] 1848d1178aSdrhsource $testdir/tester.tcl 1948d1178aSdrh 20284f4acaSdanielk1977ifcapable !subquery { 21284f4acaSdanielk1977 finish_test 22284f4acaSdanielk1977 return 23284f4acaSdanielk1977} 24284f4acaSdanielk1977 2548d1178aSdrh# Return true if the compilation of the sql passed as an argument 2648d1178aSdrh# includes the opcode OpenEphemeral. An "INSERT INTO ... SELECT" 2748d1178aSdrh# statement includes such an opcode if a temp-table is used 2848d1178aSdrh# to store intermediate results. 2948d1178aSdrh# 3048d1178aSdrhproc uses_temp_table {sql} { 3148d1178aSdrh return [expr {[lsearch [execsql "EXPLAIN $sql"] OpenEphemeral]>=0}] 3248d1178aSdrh} 3348d1178aSdrh 3448d1178aSdrh# Construct the sample database. 3548d1178aSdrh# 3648d1178aSdrhdo_test insert5-1.0 { 37*fda06befSmistachkin forcedelete test2.db test2.db-journal 3848d1178aSdrh execsql { 3948d1178aSdrh CREATE TABLE MAIN(Id INTEGER, Id1 INTEGER); 4048d1178aSdrh CREATE TABLE B(Id INTEGER, Id1 INTEGER); 4148d1178aSdrh CREATE VIEW v1 AS SELECT * FROM B; 4248d1178aSdrh CREATE VIEW v2 AS SELECT * FROM MAIN; 4348d1178aSdrh INSERT INTO MAIN(Id,Id1) VALUES(2,3); 4448d1178aSdrh INSERT INTO B(Id,Id1) VALUES(2,3); 4548d1178aSdrh } 4648d1178aSdrh} {} 4748d1178aSdrh 4848d1178aSdrh# Run the query. 4948d1178aSdrh# 50de3e41e3Sdanielk1977ifcapable compound { 5148d1178aSdrh do_test insert5-1.1 { 5248d1178aSdrh execsql { 5348d1178aSdrh INSERT INTO B 5448d1178aSdrh SELECT * FROM B UNION ALL 5548d1178aSdrh SELECT * FROM MAIN WHERE exists (select * FROM B WHERE B.Id = MAIN.Id); 5648d1178aSdrh SELECT * FROM B; 5748d1178aSdrh } 5848d1178aSdrh } {2 3 2 3 2 3} 59de3e41e3Sdanielk1977} else { 60de3e41e3Sdanielk1977 do_test insert5-1.1 { 61de3e41e3Sdanielk1977 execsql { 62de3e41e3Sdanielk1977 INSERT INTO B SELECT * FROM B; 63de3e41e3Sdanielk1977 INSERT INTO B 64de3e41e3Sdanielk1977 SELECT * FROM MAIN WHERE exists (select * FROM B WHERE B.Id = MAIN.Id); 65de3e41e3Sdanielk1977 SELECT * FROM B; 66de3e41e3Sdanielk1977 } 67de3e41e3Sdanielk1977 } {2 3 2 3 2 3} 68de3e41e3Sdanielk1977} 6948d1178aSdrhdo_test insert5-2.1 { 7048d1178aSdrh uses_temp_table { INSERT INTO b SELECT * FROM main } 7148d1178aSdrh} {0} 7248d1178aSdrhdo_test insert5-2.2 { 7348d1178aSdrh uses_temp_table { INSERT INTO b SELECT * FROM b } 7448d1178aSdrh} {1} 7548d1178aSdrhdo_test insert5-2.3 { 7648d1178aSdrh uses_temp_table { INSERT INTO b SELECT (SELECT id FROM b), id1 FROM main } 7748d1178aSdrh} {1} 7848d1178aSdrhdo_test insert5-2.4 { 7948d1178aSdrh uses_temp_table { INSERT INTO b SELECT id1, (SELECT id FROM b) FROM main } 8048d1178aSdrh} {1} 8148d1178aSdrhdo_test insert5-2.5 { 8248d1178aSdrh uses_temp_table { 8348d1178aSdrh INSERT INTO b 8448d1178aSdrh SELECT * FROM main WHERE id = (SELECT id1 FROM b WHERE main.id = b.id) } 8548d1178aSdrh} {1} 8648d1178aSdrhdo_test insert5-2.6 { 8748d1178aSdrh uses_temp_table { INSERT INTO b SELECT * FROM v1 } 8848d1178aSdrh} {1} 8948d1178aSdrhdo_test insert5-2.7 { 9048d1178aSdrh uses_temp_table { INSERT INTO b SELECT * FROM v2 } 9148d1178aSdrh} {0} 9248d1178aSdrhdo_test insert5-2.8 { 9348d1178aSdrh uses_temp_table { 9448d1178aSdrh INSERT INTO b 9548d1178aSdrh SELECT * FROM main WHERE id > 10 AND max(id1, (SELECT id FROM b)) > 10; 9648d1178aSdrh } 9748d1178aSdrh} {1} 9801874bfcSdanielk1977 9901874bfcSdanielk1977# UPDATE: Using a column from the outer query (main.id) in the GROUP BY 10001874bfcSdanielk1977# or ORDER BY of a sub-query is no longer supported. 10101874bfcSdanielk1977# 10201874bfcSdanielk1977# do_test insert5-2.9 { 10301874bfcSdanielk1977# uses_temp_table { 10401874bfcSdanielk1977# INSERT INTO b 10501874bfcSdanielk1977# SELECT * FROM main 10601874bfcSdanielk1977# WHERE id > 10 AND (SELECT count(*) FROM v2 GROUP BY main.id) 10701874bfcSdanielk1977# } 10801874bfcSdanielk1977# } {} 10948d1178aSdrhdo_test insert5-2.9 { 11001874bfcSdanielk1977 catchsql { 11148d1178aSdrh INSERT INTO b 11248d1178aSdrh SELECT * FROM main 11348d1178aSdrh WHERE id > 10 AND (SELECT count(*) FROM v2 GROUP BY main.id) 11448d1178aSdrh } 11501874bfcSdanielk1977} {1 {no such column: main.id}} 11648d1178aSdrh 11748d1178aSdrhfinish_test 118