1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
#include "catch.hpp"
#include "duckdb/execution/physical_plan_generator.hpp"
#include "duckdb/optimizer/optimizer.hpp"
#include "duckdb/parallel/thread_context.hpp"
#include "duckdb/planner/planner.hpp"
#include "test_helpers.hpp"
#include "duckdb/parser/parser.hpp"
#include <map>
#include <set>
using namespace duckdb;
using namespace std;
static void test_helper(string sql, duckdb::vector<string> fixtures = duckdb::vector<string>()) {
DuckDB db;
Connection con(db);
for (const auto &fixture : fixtures) {
con.SendQuery(fixture);
}
Parser p;
p.ParseQuery(sql);
for (auto &statement : p.statements) {
con.context->transaction.BeginTransaction();
// Should that be the default "ToString"?
string statement_sql(statement->query.c_str() + statement->stmt_location, statement->stmt_length);
Planner planner(*con.context);
planner.CreatePlan(std::move(statement));
auto plan = std::move(planner.plan);
Optimizer optimizer(*planner.binder, *con.context);
plan = optimizer.Optimize(std::move(plan));
// LogicalOperator's copy utilizes its serialize and deserialize methods
auto new_plan = plan->Copy(*con.context);
auto optimized_plan = optimizer.Optimize(std::move(new_plan));
con.context->transaction.Commit();
}
}
static void test_helper_multi_db(string sql, duckdb::vector<string> fixtures = duckdb::vector<string>()) {
DuckDB db;
Connection con(db);
REQUIRE_NO_FAIL(con.Query("ATTACH DATABASE ':memory:' AS new_db;"));
for (const auto &fixture : fixtures) {
con.SendQuery(fixture);
}
Parser p;
p.ParseQuery(sql);
for (auto &statement : p.statements) {
con.context->transaction.BeginTransaction();
// Should that be the default "ToString"?
string statement_sql(statement->query.c_str() + statement->stmt_location, statement->stmt_length);
Planner planner(*con.context);
planner.CreatePlan(std::move(statement));
auto plan = std::move(planner.plan);
Optimizer optimizer(*planner.binder, *con.context);
plan = optimizer.Optimize(std::move(plan));
// LogicalOperator's copy utilizes its serialize and deserialize methods
auto new_plan = plan->Copy(*con.context);
auto optimized_plan = optimizer.Optimize(std::move(new_plan));
con.context->transaction.Commit();
}
}
TEST_CASE("Test logical_set", "[serialization]") {
test_helper("SET memory_limit='10GB'");
}
TEST_CASE("Test logical_show", "[serialization]") {
test_helper("SHOW SELECT 42");
}
TEST_CASE("Test logical_explain", "[serialization]") {
test_helper("EXPLAIN SELECT 42");
}
TEST_CASE("Test logical_empty_result", "[serialization]") {
test_helper("SELECT * FROM (SELECT 42) WHERE 1>2");
}
TEST_CASE("Test create_table", "[serialization]") {
test_helper("CREATE TABLE tbl (foo INTEGER)");
}
TEST_CASE("Test insert_into", "[serialization]") {
test_helper("INSERT INTO tbl VALUES(1)", {"CREATE TABLE tbl (foo INTEGER)"});
}
TEST_CASE("Test logical_delete", "[serialization]") {
test_helper("DELETE FROM tbl", {"CREATE TABLE tbl (foo INTEGER)"});
}
// TODO: only select for now
// TEST_CASE("Test logical_create_index", "[serialization]") {
// test_helper("CREATE INDEX idx ON tbl (foo)", {"CREATE TABLE tbl (foo INTEGER)"});
//}
// TODO: only select for now
// TEST_CASE("Test logical_create_schema", "[serialization]") {
// test_helper("CREATE SCHEMA test");
//}
// TODO: only select for now
// TEST_CASE("Test logical_create_view", "[serialization]") {
// test_helper("CREATE VIEW test_view AS (SELECT 42)");
//}
TEST_CASE("Test logical_update", "[serialization]") {
test_helper("UPDATE tbl SET foo=42", {"CREATE TABLE tbl (foo INTEGER)"});
}
// TODO(stephwang): revisit this later since it doesn't work yet
// TEST_CASE("Test logical_copy_to_file", "[serialization]") {
// test_helper("COPY tbl TO 'test_table.csv' ( DELIMITER '|', HEADER )", {"CREATE TABLE tbl (foo INTEGER)"});
//}
// TODO(stephwang): revisit this later since it doesn't work yet
// TEST_CASE("Test logical_prepare", "[serialization]") {
// test_helper("PREPARE v1 AS SELECT 42");
//}
TEST_CASE("Test logical_simple with DROP", "[serialization]") {
test_helper("DROP TABLE tbl", {"CREATE TABLE tbl (foo INTEGER)"});
}
TEST_CASE("Test logical_simple with ALTER", "[serialization]") {
test_helper("ALTER TABLE tbl ADD COLUMN bar INTEGER", {"CREATE TABLE tbl (foo INTEGER)"});
}
TEST_CASE("Test logical_simple with LOAD", "[serialization]") {
test_helper("LOAD foo");
}
// below test cases are oriented towards multi-databases
TEST_CASE("Test create_table with catalog", "[serialization]") {
test_helper_multi_db("CREATE TABLE new_db.main.tbl(i INTEGER);");
}
TEST_CASE("Test logical_insert with catalog", "[serialization]") {
test_helper_multi_db("INSERT INTO new_db.main.tbl VALUES(1)", {"CREATE TABLE new_db.main.tbl (foo INTEGER)"});
}
TEST_CASE("Test logical_update with catalog", "[serialization]") {
test_helper_multi_db("UPDATE new_db.main.tbl SET foo=42", {"CREATE TABLE new_db.main.tbl (foo INTEGER)"});
}
|