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
|
#include "capi_tester.hpp"
#include "duckdb.h"
using namespace duckdb;
using namespace std;
TEST_CASE("Test the table description in the C API", "[capi]") {
CAPITester tester;
REQUIRE(tester.OpenDatabase(nullptr));
duckdb_table_description table_description = nullptr;
tester.Query("SET threads=1;");
// Test a non-existent table.
auto status = duckdb_table_description_create(tester.connection, nullptr, "test", &table_description);
REQUIRE(status == DuckDBError);
duckdb_table_description_destroy(&table_description);
status = duckdb_table_description_create_ext(tester.connection, "hello", "world", "test", &table_description);
REQUIRE(status == DuckDBError);
duckdb_table_description_destroy(&table_description);
// Create an in-memory table and a table in an external file.
tester.Query("CREATE TABLE test (i INTEGER, j INTEGER default 5)");
auto test_dir = TestDirectoryPath();
auto attach_query = "ATTACH '" + test_dir + "/ext_description.db'";
tester.Query(attach_query);
tester.Query("CREATE TABLE ext_description.test(my_column INTEGER)");
// Test invalid catalog and schema.
status =
duckdb_table_description_create_ext(tester.connection, "non-existent", nullptr, "test", &table_description);
REQUIRE(status == DuckDBError);
duckdb_table_description_destroy(&table_description);
status = duckdb_table_description_create(tester.connection, "non-existent", "test", &table_description);
REQUIRE(status == DuckDBError);
duckdb_table_description_destroy(&table_description);
status = duckdb_table_description_create(tester.connection, nullptr, "test", &table_description);
REQUIRE(status == DuckDBSuccess);
REQUIRE(duckdb_table_description_error(table_description) == nullptr);
bool has_default;
SECTION("Passing nullptr to has_default") {
REQUIRE(duckdb_column_has_default(table_description, 2, nullptr) == DuckDBError);
REQUIRE(duckdb_column_has_default(nullptr, 2, &has_default) == DuckDBError);
}
SECTION("Out of range column for has_default") {
REQUIRE(duckdb_column_has_default(table_description, 2, &has_default) == DuckDBError);
}
SECTION("In range column - not default") {
REQUIRE(duckdb_column_has_default(table_description, 0, &has_default) == DuckDBSuccess);
REQUIRE(has_default == false);
}
SECTION("In range column - default") {
REQUIRE(duckdb_column_has_default(table_description, 1, &has_default) == DuckDBSuccess);
REQUIRE(has_default == true);
}
duckdb_table_description_destroy(&table_description);
// Let's get information about the external table.
status =
duckdb_table_description_create_ext(tester.connection, "ext_description", nullptr, "test", &table_description);
REQUIRE(status == DuckDBSuccess);
REQUIRE(duckdb_table_description_error(table_description) == nullptr);
SECTION("Passing nullptr to get_column_count") {
REQUIRE(duckdb_table_description_get_column_count(nullptr) == 0);
}
SECTION("Passing nullptr to get_name") {
REQUIRE(duckdb_table_description_get_column_name(nullptr, 0) == nullptr);
}
SECTION("Passing nullptr to get_type") {
REQUIRE(duckdb_table_description_get_column_type(nullptr, 0) == nullptr);
}
SECTION("Out of range column for get_name") {
REQUIRE(duckdb_table_description_get_column_name(table_description, 1) == nullptr);
}
SECTION("Out of range column for get_type") {
REQUIRE(duckdb_table_description_get_column_type(table_description, 1) == nullptr);
}
SECTION("get the column count") {
auto column_count = duckdb_table_description_get_column_count(table_description);
REQUIRE(column_count == 1);
}
SECTION("In range column - get the name") {
auto column_name = duckdb_table_description_get_column_name(table_description, 0);
string expected = "my_column";
REQUIRE(!expected.compare(column_name));
duckdb_free(column_name);
}
SECTION("In range column - get the type") {
auto column_type = duckdb_table_description_get_column_type(table_description, 0);
auto type_id = duckdb_get_type_id(column_type);
REQUIRE(type_id == DUCKDB_TYPE_INTEGER);
duckdb_destroy_logical_type(&column_type);
}
duckdb_table_description_destroy(&table_description);
}
TEST_CASE("Test getting the table names of a query in the C API", "[capi]") {
CAPITester tester;
REQUIRE(tester.OpenDatabase(nullptr));
tester.Query("CREATE SCHEMA schema1");
tester.Query("CREATE SCHEMA \"schema.2\"");
tester.Query("CREATE TABLE schema1.\"table.1\"(i INT)");
tester.Query("CREATE TABLE \"schema.2\".\"table.2\"(i INT)");
string query = "SELECT * FROM schema1.\"table.1\", \"schema.2\".\"table.2\"";
auto table_name_values = duckdb_get_table_names(tester.connection, query.c_str(), true);
auto size = duckdb_get_list_size(table_name_values);
REQUIRE(size == 2);
duckdb::unordered_set<string> expected_names = {"schema1.\"table.1\"", "\"schema.2\".\"table.2\""};
for (idx_t i = 0; i < size; i++) {
auto name_value = duckdb_get_list_child(table_name_values, i);
auto name = duckdb_get_varchar(name_value);
REQUIRE(expected_names.count(name) == 1);
duckdb_free(name);
duckdb_destroy_value(&name_value);
}
duckdb_destroy_value(&table_name_values);
tester.Cleanup();
}
|