xref: /sqlite-3.40.0/test/insert5.test (revision fda06bef)
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