1#include "catch.hpp"
2#include "test_helpers.hpp"
3
4using namespace duckdb;
5using namespace std;
6
7TEST_CASE("Test temporary catalog entry creation", "[catalog]") {
8 unique_ptr<QueryResult> result;
9
10 DuckDB db(nullptr);
11 Connection con(db);
12
13 // basic temp table creation works
14 REQUIRE_NO_FAIL(con.Query("CREATE TEMPORARY TABLE integers(i INTEGER) ON COMMIT PRESERVE ROWS"));
15 // we can (but never are required to) prefix temp tables with "temp" schema
16 REQUIRE_NO_FAIL(con.Query("CREATE TEMPORARY TABLE integersx(i INTEGER)"));
17 // we can't prefix temp tables with a schema that is not "temp"
18 REQUIRE_FAIL(con.Query("CREATE TEMPORARY TABLE asdf.integersy(i INTEGER)"));
19 REQUIRE_NO_FAIL(con.Query("CREATE TEMPORARY TABLE s1 AS SELECT 42"));
20
21 REQUIRE_FAIL(con.Query("CREATE TABLE temp.integersy(i INTEGER)"));
22
23 REQUIRE_FAIL(con.Query("CREATE SCHEMA temp"));
24
25 REQUIRE_FAIL(con.Query("DROP TABLE main.integersx"));
26 REQUIRE_NO_FAIL(con.Query("DROP TABLE integersx"));
27
28 REQUIRE_NO_FAIL(con.Query("CREATE TEMPORARY TABLE temp.integersx(i INTEGER)"));
29 REQUIRE_NO_FAIL(con.Query("DROP TABLE temp.integersx"));
30
31 // unsupported because stupid
32 REQUIRE_FAIL(con.Query("CREATE TEMPORARY TABLE integers2(i INTEGER) ON COMMIT DELETE ROWS"));
33
34 // temp table already exists
35 REQUIRE_FAIL(con.Query("CREATE TEMPORARY TABLE integers(i INTEGER)"));
36
37 REQUIRE_NO_FAIL(con.Query("INSERT INTO integers VALUES (42)"));
38 result = con.Query("SELECT i from integers");
39 REQUIRE(CHECK_COLUMN(result, 0, {42}));
40
41 // temp table survives commit
42 REQUIRE_NO_FAIL(con.Query("BEGIN TRANSACTION"));
43 REQUIRE_NO_FAIL(con.Query("CREATE TEMPORARY TABLE integers2(i INTEGER)"));
44 REQUIRE_NO_FAIL(con.Query("CREATE TEMPORARY SEQUENCE seq"));
45 REQUIRE_NO_FAIL(con.Query("CREATE TEMPORARY VIEW v1 AS SELECT 42"));
46 REQUIRE_NO_FAIL(con.Query("INSERT INTO integers2 VALUES (42)"));
47 result = con.Query("SELECT i from integers2");
48 REQUIRE(CHECK_COLUMN(result, 0, {42}));
49 result = con.Query("SELECT nextval('seq')");
50 REQUIRE(CHECK_COLUMN(result, 0, {1}));
51 result = con.Query("SELECT * from v1");
52 REQUIRE(CHECK_COLUMN(result, 0, {42}));
53 REQUIRE_NO_FAIL(con.Query("COMMIT"));
54
55 result = con.Query("SELECT i from integers2");
56 REQUIRE(CHECK_COLUMN(result, 0, {42}));
57 result = con.Query("SELECT nextval('seq')");
58 REQUIRE(CHECK_COLUMN(result, 0, {2}));
59 result = con.Query("SELECT * from v1");
60 REQUIRE(CHECK_COLUMN(result, 0, {42}));
61
62 // temp table does not survive rollback
63 REQUIRE_NO_FAIL(con.Query("BEGIN TRANSACTION"));
64 REQUIRE_NO_FAIL(con.Query("CREATE TEMPORARY TABLE integers3(i INTEGER)"));
65 REQUIRE_NO_FAIL(con.Query("INSERT INTO integers3 VALUES (42)"));
66 result = con.Query("SELECT i from integers3");
67 REQUIRE(CHECK_COLUMN(result, 0, {42}));
68 REQUIRE_NO_FAIL(con.Query("ROLLBACK"));
69
70 REQUIRE_FAIL(con.Query("SELECT i from integers3"));
71
72 Connection con2(db);
73 // table is not visible to other cons
74 REQUIRE_FAIL(con2.Query("INSERT INTO integers VALUES (42)"));
75}
76
77TEST_CASE("Test persistent temporary structures", "[catalog]") {
78 unique_ptr<QueryResult> result;
79
80 // see if temp tables survive restart
81 FileSystem fs;
82 string db_folder = TestCreatePath("temptbls");
83
84 {
85 DuckDB db_p(db_folder);
86 Connection con_p(db_p);
87 REQUIRE_NO_FAIL(con_p.Query("CREATE TEMPORARY TABLE temp.a (i INTEGER)"));
88 REQUIRE_NO_FAIL(con_p.Query("INSERT INTO a VALUES (42)"));
89 REQUIRE_NO_FAIL(con_p.Query("DELETE FROM a"));
90 REQUIRE_NO_FAIL(con_p.Query("DELETE FROM temp.a"));
91 REQUIRE_FAIL(con_p.Query("DELETE FROM asdf.a"));
92
93 REQUIRE_NO_FAIL(con_p.Query("CREATE TEMPORARY SEQUENCE seq"));
94 REQUIRE_NO_FAIL(con_p.Query("CREATE TEMPORARY SEQUENCE seq2"));
95 REQUIRE_NO_FAIL(con_p.Query("DROP SEQUENCE seq2"));
96
97 REQUIRE_NO_FAIL(con_p.Query("CREATE TEMPORARY VIEW v1 AS SELECT 42"));
98 REQUIRE_NO_FAIL(con_p.Query("CREATE TEMPORARY VIEW v2 AS SELECT 42"));
99 REQUIRE_NO_FAIL(con_p.Query("DROP VIEW v2"));
100
101 REQUIRE_NO_FAIL(con_p.Query("INSERT INTO temp.a VALUES (43)"));
102
103 REQUIRE_NO_FAIL(con_p.Query("UPDATE temp.a SET i = 44"));
104 REQUIRE_NO_FAIL(con_p.Query("UPDATE a SET i = 45"));
105
106 REQUIRE_NO_FAIL(con_p.Query("ALTER TABLE a RENAME COLUMN i TO k"));
107
108 result = con_p.Query("SELECT COUNT(k) from a");
109 REQUIRE(CHECK_COLUMN(result, 0, {1}));
110 }
111
112 {
113 DuckDB db_p(db_folder);
114 Connection con_p(db_p);
115 REQUIRE_FAIL(con_p.Query("SELECT * FROM a"));
116 REQUIRE_NO_FAIL(con_p.Query("CREATE TEMPORARY TABLE a (i INTEGER)"));
117 REQUIRE_NO_FAIL(con_p.Query("CREATE TEMPORARY SEQUENCE seq"));
118 REQUIRE_NO_FAIL(con_p.Query("CREATE TEMPORARY VIEW v1 AS SELECT 42"));
119
120 result = con_p.Query("SELECT COUNT(*) from a");
121 REQUIRE(CHECK_COLUMN(result, 0, {0}));
122 }
123}
124