From ba1bb5d26c577d8afc33c2ffc1fb2c627b436d57 Mon Sep 17 00:00:00 2001 From: Elliana May Date: Tue, 5 Sep 2023 23:41:42 +0800 Subject: [PATCH 01/10] feat(c): add duckdb_logical_type_get_alias() --- src/include/duckdb.h | 9 +++++ src/main/capi/logical_types-c.cpp | 5 +++ test/api/capi/test_capi_complex_types.cpp | 42 +++++++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/src/include/duckdb.h b/src/include/duckdb.h index 8fa38f7ddc1b..d2e06ffff133 100644 --- a/src/include/duckdb.h +++ b/src/include/duckdb.h @@ -1343,6 +1343,15 @@ This should not be used with `DUCKDB_TYPE_DECIMAL`. */ DUCKDB_API duckdb_logical_type duckdb_create_logical_type(duckdb_type type); +/*! +Returns the alias of a duckdb_logical_type, if one is set, else `NULL` +You must free the result. + +* type: The logical type to return the alias of +* returns: The alias or `NULL` + */ +DUCKDB_API char *duckdb_logical_type_get_alias(duckdb_logical_type type); + /*! Creates a list type from its child type. The resulting type should be destroyed with `duckdb_destroy_logical_type`. diff --git a/src/main/capi/logical_types-c.cpp b/src/main/capi/logical_types-c.cpp index 83906f68c418..ac395ad5123c 100644 --- a/src/main/capi/logical_types-c.cpp +++ b/src/main/capi/logical_types-c.cpp @@ -257,6 +257,11 @@ char *duckdb_struct_type_child_name(duckdb_logical_type type, idx_t index) { return strdup(duckdb::StructType::GetChildName(ltype, index).c_str()); } +char *duckdb_logical_type_get_alias(duckdb_logical_type type) { + auto <ype = *(reinterpret_cast(type)); + return ltype.HasAlias() ? strdup(ltype.GetAlias().c_str()) : nullptr; +} + duckdb_logical_type duckdb_struct_type_child_type(duckdb_logical_type type, idx_t index) { if (!AssertInternalType(type, duckdb::PhysicalType::STRUCT)) { return nullptr; diff --git a/test/api/capi/test_capi_complex_types.cpp b/test/api/capi/test_capi_complex_types.cpp index 7b90b99c7672..2bcda1c32626 100644 --- a/test/api/capi/test_capi_complex_types.cpp +++ b/test/api/capi/test_capi_complex_types.cpp @@ -1,4 +1,6 @@ #include "capi_tester.hpp" +#include "duckdb/main/database_manager.hpp" +#include "duckdb/parser/parsed_data/create_type_info.hpp" using namespace duckdb; using namespace std; @@ -200,3 +202,43 @@ TEST_CASE("Test struct types creation C API", "[capi]") { } duckdb_destroy_logical_type(&logical_type); } + +TEST_CASE("Logical types with aliases", "[capi]") { + CAPITester tester; + + REQUIRE(tester.OpenDatabase(nullptr)); + + Connection *connection = reinterpret_cast(tester.connection); + + connection->BeginTransaction(); + + child_list_t children = {{"hello", LogicalType::VARCHAR}}; + auto id = LogicalType::STRUCT(children); + auto type_name = "test_type"; + id.SetAlias(type_name); + CreateTypeInfo info(type_name, id); + + auto &catalog_name = DatabaseManager::GetDefaultDatabase(*connection->context); + auto &catalog = Catalog::GetCatalog(*connection->context, catalog_name); + catalog.CreateType(*connection->context, info); + + connection->Commit(); + + auto result = tester.Query("SELECT {hello: 'world'}::test_type"); + + REQUIRE(NO_FAIL(*result)); + + auto chunk = result->FetchChunk(0); + REQUIRE(chunk); + + for (idx_t i = 0; i < result->ColumnCount(); i++) { + auto logical_type = duckdb_vector_get_column_type(duckdb_data_chunk_get_vector(chunk->GetChunk(), i)); + REQUIRE(logical_type); + + auto alias = duckdb_logical_type_get_alias(logical_type); + REQUIRE(string(alias) == "test_type"); + duckdb_free(alias); + + duckdb_destroy_logical_type(&logical_type); + } +} From 3988f3e2ef1c0c532a8306900d0726d4ed7ca118 Mon Sep 17 00:00:00 2001 From: Elliana May Date: Thu, 7 Sep 2023 12:22:27 +0800 Subject: [PATCH 02/10] feat(c): add duckdb_result_return_type --- src/include/duckdb.h | 15 +++++++++++++++ src/main/capi/result-c.cpp | 17 +++++++++++++++++ test/api/capi/test_capi_data_chunk.cpp | 16 ++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/src/include/duckdb.h b/src/include/duckdb.h index d2e06ffff133..dca5aad68a73 100644 --- a/src/include/duckdb.h +++ b/src/include/duckdb.h @@ -312,6 +312,13 @@ typedef enum { DUCKDB_PENDING_NO_TASKS_AVAILABLE = 3 } duckdb_pending_state; +typedef enum { + DUCKDB_RESULT_TYPE_CHANGED_ROWS, + DUCKDB_RESULT_TYPE_NOTHING, + DUCKDB_RESULT_TYPE_QUERY_RESULT, + DUCKDB_RESULT_TYPE_INVALID, +} duckdb_result_type; + //===--------------------------------------------------------------------===// // Open/Connect //===--------------------------------------------------------------------===// @@ -627,6 +634,14 @@ Returns the number of data chunks present in the result. */ DUCKDB_API idx_t duckdb_result_chunk_count(duckdb_result result); +/*! +Returns the return_type of the given result, or DUCKDB_RETURN_TYPE_INVALID on error + +* result: The result object +* returns: The return_type + */ +DUCKDB_API duckdb_result_type duckdb_result_return_type(duckdb_result result); + // Safe fetch functions // These functions will perform conversions if necessary. // On failure (e.g. if conversion cannot be performed or if the value is NULL) a default value is returned. diff --git a/src/main/capi/result-c.cpp b/src/main/capi/result-c.cpp index bab21bead0a6..a713b1f98ff2 100644 --- a/src/main/capi/result-c.cpp +++ b/src/main/capi/result-c.cpp @@ -515,3 +515,20 @@ bool duckdb_result_is_streaming(duckdb_result result) { auto &result_data = *(reinterpret_cast(result.internal_data)); return result_data.result->type == duckdb::QueryResultType::STREAM_RESULT; } + +duckdb_result_type duckdb_result_return_type(duckdb_result result) { + if (!result.internal_data || duckdb_result_error(&result) != nullptr) { + return DUCKDB_RESULT_TYPE_INVALID; + } + auto &result_data = *(reinterpret_cast(result.internal_data)); + switch (result_data.result->properties.return_type) { + case duckdb::StatementReturnType::CHANGED_ROWS: + return DUCKDB_RESULT_TYPE_CHANGED_ROWS; + case duckdb::StatementReturnType::NOTHING: + return DUCKDB_RESULT_TYPE_NOTHING; + case duckdb::StatementReturnType::QUERY_RESULT: + return DUCKDB_RESULT_TYPE_QUERY_RESULT; + default: + return DUCKDB_RESULT_TYPE_INVALID; + } +} diff --git a/test/api/capi/test_capi_data_chunk.cpp b/test/api/capi/test_capi_data_chunk.cpp index 4d5c15ffc350..7eafb29079fa 100644 --- a/test/api/capi/test_capi_data_chunk.cpp +++ b/test/api/capi/test_capi_data_chunk.cpp @@ -313,6 +313,22 @@ TEST_CASE("Test DataChunk result fetch in C API", "[capi]") { REQUIRE(!chunk); } +TEST_CASE("Test duckdb_result_return_type", "[capi]") { + CAPITester tester; + duckdb::unique_ptr result; + + REQUIRE(tester.OpenDatabase(nullptr)); + + result = tester.Query("CREATE TABLE t (id INT)"); + REQUIRE(duckdb_result_return_type(result->InternalResult()) == DUCKDB_RESULT_TYPE_NOTHING); + + result = tester.Query("INSERT INTO t VALUES (42)"); + REQUIRE(duckdb_result_return_type(result->InternalResult()) == DUCKDB_RESULT_TYPE_CHANGED_ROWS); + + result = tester.Query("FROM t"); + REQUIRE(duckdb_result_return_type(result->InternalResult()) == DUCKDB_RESULT_TYPE_QUERY_RESULT); +} + TEST_CASE("Test DataChunk populate ListVector in C API", "[capi]") { REQUIRE(duckdb_list_vector_reserve(nullptr, 100) == duckdb_state::DuckDBError); REQUIRE(duckdb_list_vector_set_size(nullptr, 200) == duckdb_state::DuckDBError); From 0ad34a9e8db8993594647a641da5dc873cce54f3 Mon Sep 17 00:00:00 2001 From: Elliana May Date: Thu, 7 Sep 2023 14:03:13 +0800 Subject: [PATCH 03/10] test: add REQUIRE_SUCCESS macro --- test/include/test_helpers.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/include/test_helpers.hpp b/test/include/test_helpers.hpp index 3444f01d3216..739687ab2a49 100644 --- a/test/include/test_helpers.hpp +++ b/test/include/test_helpers.hpp @@ -55,6 +55,7 @@ bool NO_FAIL(duckdb::unique_ptr result); #define REQUIRE_NO_FAIL(result) REQUIRE(NO_FAIL((result))) #define REQUIRE_FAIL(result) REQUIRE((result)->HasError()) +#define REQUIRE_SUCCESS(result) REQUIRE(result == DuckDBSuccess) #define COMPARE_CSV(result, csv, header) \ { \ From 94223aca32ff9f24f615fb64eea177614057d532 Mon Sep 17 00:00:00 2001 From: Elliana May Date: Sun, 17 Sep 2023 10:36:01 +0800 Subject: [PATCH 04/10] feat(c): add statement type determination --- src/include/duckdb.h | 34 +++++++++++++++++++++- src/main/capi/result-c.cpp | 59 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/src/include/duckdb.h b/src/include/duckdb.h index dca5aad68a73..9d26d0d8d95c 100644 --- a/src/include/duckdb.h +++ b/src/include/duckdb.h @@ -313,12 +313,44 @@ typedef enum { } duckdb_pending_state; typedef enum { + DUCKDB_RESULT_TYPE_INVALID, DUCKDB_RESULT_TYPE_CHANGED_ROWS, DUCKDB_RESULT_TYPE_NOTHING, DUCKDB_RESULT_TYPE_QUERY_RESULT, - DUCKDB_RESULT_TYPE_INVALID, } duckdb_result_type; +typedef enum { + DUCKDB_STATEMENT_TYPE_INVALID, + DUCKDB_STATEMENT_TYPE_SELECT, + DUCKDB_STATEMENT_TYPE_INSERT, + DUCKDB_STATEMENT_TYPE_UPDATE, + DUCKDB_STATEMENT_TYPE_EXPLAIN, + DUCKDB_STATEMENT_TYPE_DELETE, + DUCKDB_STATEMENT_TYPE_PREPARE, + DUCKDB_STATEMENT_TYPE_CREATE, + DUCKDB_STATEMENT_TYPE_EXECUTE, + DUCKDB_STATEMENT_TYPE_ALTER, + DUCKDB_STATEMENT_TYPE_TRANSACTION, + DUCKDB_STATEMENT_TYPE_COPY, + DUCKDB_STATEMENT_TYPE_ANALYZE, + DUCKDB_STATEMENT_TYPE_VARIABLE_SET, + DUCKDB_STATEMENT_TYPE_CREATE_FUNC, + DUCKDB_STATEMENT_TYPE_DROP, + DUCKDB_STATEMENT_TYPE_EXPORT, + DUCKDB_STATEMENT_TYPE_PRAGMA, + DUCKDB_STATEMENT_TYPE_SHOW, + DUCKDB_STATEMENT_TYPE_VACUUM, + DUCKDB_STATEMENT_TYPE_CALL, + DUCKDB_STATEMENT_TYPE_SET, + DUCKDB_STATEMENT_TYPE_LOAD, + DUCKDB_STATEMENT_TYPE_RELATION, + DUCKDB_STATEMENT_TYPE_EXTENSION, + DUCKDB_STATEMENT_TYPE_LOGICAL_PLAN, + DUCKDB_STATEMENT_TYPE_ATTACH, + DUCKDB_STATEMENT_TYPE_DETACH, + DUCKDB_STATEMENT_TYPE_MULTI, +} duckdb_statement_type; + //===--------------------------------------------------------------------===// // Open/Connect //===--------------------------------------------------------------------===// diff --git a/src/main/capi/result-c.cpp b/src/main/capi/result-c.cpp index a713b1f98ff2..398b7edcc34b 100644 --- a/src/main/capi/result-c.cpp +++ b/src/main/capi/result-c.cpp @@ -532,3 +532,62 @@ duckdb_result_type duckdb_result_return_type(duckdb_result result) { return DUCKDB_RESULT_TYPE_INVALID; } } + +#define SHORT(name) \ + case duckdb::StatementType::name##_STATEMENT: \ + return DUCKDB_STATEMENT_TYPE_##name; + +static duckdb_statement_type StatementTypeToC(duckdb::StatementType statement_type) { + switch (statement_type) { + SHORT(SELECT) + SHORT(INVALID) + SHORT(INSERT) + SHORT(UPDATE) + SHORT(EXPLAIN) + SHORT(DELETE) + SHORT(PREPARE) + SHORT(CREATE) + SHORT(EXECUTE) + SHORT(ALTER) + SHORT(TRANSACTION) + SHORT(COPY) + SHORT(ANALYZE) + SHORT(VARIABLE_SET) + SHORT(CREATE_FUNC) + SHORT(DROP) + SHORT(EXPORT) + SHORT(PRAGMA) + SHORT(SHOW) + SHORT(VACUUM) + SHORT(CALL) + SHORT(SET) + SHORT(LOAD) + SHORT(RELATION) + SHORT(EXTENSION) + SHORT(LOGICAL_PLAN) + SHORT(ATTACH) + SHORT(DETACH) + SHORT(MULTI) + default: + return DUCKDB_STATEMENT_TYPE_INVALID; + } +} +#undef SHORT + +duckdb_statement_type duckdb_result_statement_type(duckdb_result result) { + if (!result.internal_data || duckdb_result_error(&result) != nullptr) { + return DUCKDB_STATEMENT_TYPE_INVALID; + } + auto &pres = *(reinterpret_cast(result.internal_data)); + + return StatementTypeToC(pres.result->statement_type); +} + +duckdb_statement_type duckdb_prepared_statement_type(duckdb_prepared_statement statement) { + if (!statement) { + return DUCKDB_STATEMENT_TYPE_INVALID; + } + auto &stmt = *(reinterpret_cast(statement)); + + return StatementTypeToC(stmt.statement->GetStatementType()); +} From 16cfaef7993b18729d0d66a542bb2a752d9cc9ad Mon Sep 17 00:00:00 2001 From: Elliana May Date: Mon, 16 Oct 2023 21:58:35 +0800 Subject: [PATCH 05/10] test: add statement type test --- test/api/capi/test_capi_complex_types.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/api/capi/test_capi_complex_types.cpp b/test/api/capi/test_capi_complex_types.cpp index 2bcda1c32626..dd9589f7bb76 100644 --- a/test/api/capi/test_capi_complex_types.cpp +++ b/test/api/capi/test_capi_complex_types.cpp @@ -242,3 +242,18 @@ TEST_CASE("Logical types with aliases", "[capi]") { duckdb_destroy_logical_type(&logical_type); } } + +TEST_CASE("Statement types", "[capi]") { + CAPITester tester; + REQUIRE(tester.OpenDatabase(nullptr)); + + duckdb_prepared_statement prepared; + REQUIRE_SUCCESS(duckdb_prepare(tester.connection, "select ?", &prepared)); + + REQUIRE(duckdb_prepared_statement_type(prepared) == DUCKDB_STATEMENT_TYPE_SELECT); + duckdb_destroy_prepare(&prepared); + + auto result = tester.Query("CREATE TABLE t1 (id int)"); + + REQUIRE(duckdb_result_statement_type(result->InternalResult()) == DUCKDB_STATEMENT_TYPE_CREATE); +} From 0b1c74381379d81e461cf4c47773c4de040a158a Mon Sep 17 00:00:00 2001 From: Elliana May Date: Mon, 16 Oct 2023 21:58:51 +0800 Subject: [PATCH 06/10] add header declarations --- src/include/duckdb.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/include/duckdb.h b/src/include/duckdb.h index 9d26d0d8d95c..27dd3f8fdfb4 100644 --- a/src/include/duckdb.h +++ b/src/include/duckdb.h @@ -535,6 +535,14 @@ Returns `DUCKDB_TYPE_INVALID` if the column is out of range. */ DUCKDB_API duckdb_type duckdb_column_type(duckdb_result *result, idx_t col); +/*! +Returns the statement type of the statement that was executed + +* result: The result object to fetch the statement type from. + * returns: duckdb_statement_type value or DUCKDB_STATEMENT_TYPE_INVALID + */ +DUCKDB_API duckdb_statement_type duckdb_result_statement_type(duckdb_result result); + /*! Returns the logical column type of the specified column. @@ -1018,6 +1026,14 @@ Clear the params bind to the prepared statement. */ DUCKDB_API duckdb_state duckdb_clear_bindings(duckdb_prepared_statement prepared_statement); +/*! +Returns the statement type of the statement to be executed + + * statement: The prepared statement. + * returns: duckdb_statement_type value or DUCKDB_STATEMENT_TYPE_INVALID + */ +DUCKDB_API duckdb_statement_type duckdb_prepared_statement_type(duckdb_prepared_statement statement); + /*! Binds a value to the prepared statement at the specified index. */ From f61fefc2c07bf7834b7ef410f9fb19fb6ed5ea26 Mon Sep 17 00:00:00 2001 From: Elliana May Date: Mon, 23 Oct 2023 16:25:53 +0800 Subject: [PATCH 07/10] chore: expand macro --- src/main/capi/result-c.cpp | 92 ++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 34 deletions(-) diff --git a/src/main/capi/result-c.cpp b/src/main/capi/result-c.cpp index 398b7edcc34b..118fe93e3f21 100644 --- a/src/main/capi/result-c.cpp +++ b/src/main/capi/result-c.cpp @@ -533,46 +533,70 @@ duckdb_result_type duckdb_result_return_type(duckdb_result result) { } } -#define SHORT(name) \ - case duckdb::StatementType::name##_STATEMENT: \ - return DUCKDB_STATEMENT_TYPE_##name; - static duckdb_statement_type StatementTypeToC(duckdb::StatementType statement_type) { switch (statement_type) { - SHORT(SELECT) - SHORT(INVALID) - SHORT(INSERT) - SHORT(UPDATE) - SHORT(EXPLAIN) - SHORT(DELETE) - SHORT(PREPARE) - SHORT(CREATE) - SHORT(EXECUTE) - SHORT(ALTER) - SHORT(TRANSACTION) - SHORT(COPY) - SHORT(ANALYZE) - SHORT(VARIABLE_SET) - SHORT(CREATE_FUNC) - SHORT(DROP) - SHORT(EXPORT) - SHORT(PRAGMA) - SHORT(SHOW) - SHORT(VACUUM) - SHORT(CALL) - SHORT(SET) - SHORT(LOAD) - SHORT(RELATION) - SHORT(EXTENSION) - SHORT(LOGICAL_PLAN) - SHORT(ATTACH) - SHORT(DETACH) - SHORT(MULTI) + case duckdb::StatementType::SELECT_STATEMENT: + return DUCKDB_STATEMENT_TYPE_SELECT; + case duckdb::StatementType::INVALID_STATEMENT: + return DUCKDB_STATEMENT_TYPE_INVALID; + case duckdb::StatementType::INSERT_STATEMENT: + return DUCKDB_STATEMENT_TYPE_INSERT; + case duckdb::StatementType::UPDATE_STATEMENT: + return DUCKDB_STATEMENT_TYPE_UPDATE; + case duckdb::StatementType::EXPLAIN_STATEMENT: + return DUCKDB_STATEMENT_TYPE_EXPLAIN; + case duckdb::StatementType::DELETE_STATEMENT: + return DUCKDB_STATEMENT_TYPE_DELETE; + case duckdb::StatementType::PREPARE_STATEMENT: + return DUCKDB_STATEMENT_TYPE_PREPARE; + case duckdb::StatementType::CREATE_STATEMENT: + return DUCKDB_STATEMENT_TYPE_CREATE; + case duckdb::StatementType::EXECUTE_STATEMENT: + return DUCKDB_STATEMENT_TYPE_EXECUTE; + case duckdb::StatementType::ALTER_STATEMENT: + return DUCKDB_STATEMENT_TYPE_ALTER; + case duckdb::StatementType::TRANSACTION_STATEMENT: + return DUCKDB_STATEMENT_TYPE_TRANSACTION; + case duckdb::StatementType::COPY_STATEMENT: + return DUCKDB_STATEMENT_TYPE_COPY; + case duckdb::StatementType::ANALYZE_STATEMENT: + return DUCKDB_STATEMENT_TYPE_ANALYZE; + case duckdb::StatementType::VARIABLE_SET_STATEMENT: + return DUCKDB_STATEMENT_TYPE_VARIABLE_SET; + case duckdb::StatementType::CREATE_FUNC_STATEMENT: + return DUCKDB_STATEMENT_TYPE_CREATE_FUNC; + case duckdb::StatementType::DROP_STATEMENT: + return DUCKDB_STATEMENT_TYPE_DROP; + case duckdb::StatementType::EXPORT_STATEMENT: + return DUCKDB_STATEMENT_TYPE_EXPORT; + case duckdb::StatementType::PRAGMA_STATEMENT: + return DUCKDB_STATEMENT_TYPE_PRAGMA; + case duckdb::StatementType::SHOW_STATEMENT: + return DUCKDB_STATEMENT_TYPE_SHOW; + case duckdb::StatementType::VACUUM_STATEMENT: + return DUCKDB_STATEMENT_TYPE_VACUUM; + case duckdb::StatementType::CALL_STATEMENT: + return DUCKDB_STATEMENT_TYPE_CALL; + case duckdb::StatementType::SET_STATEMENT: + return DUCKDB_STATEMENT_TYPE_SET; + case duckdb::StatementType::LOAD_STATEMENT: + return DUCKDB_STATEMENT_TYPE_LOAD; + case duckdb::StatementType::RELATION_STATEMENT: + return DUCKDB_STATEMENT_TYPE_RELATION; + case duckdb::StatementType::EXTENSION_STATEMENT: + return DUCKDB_STATEMENT_TYPE_EXTENSION; + case duckdb::StatementType::LOGICAL_PLAN_STATEMENT: + return DUCKDB_STATEMENT_TYPE_LOGICAL_PLAN; + case duckdb::StatementType::ATTACH_STATEMENT: + return DUCKDB_STATEMENT_TYPE_ATTACH; + case duckdb::StatementType::DETACH_STATEMENT: + return DUCKDB_STATEMENT_TYPE_DETACH; + case duckdb::StatementType::MULTI_STATEMENT: + return DUCKDB_STATEMENT_TYPE_MULTI; default: return DUCKDB_STATEMENT_TYPE_INVALID; } } -#undef SHORT duckdb_statement_type duckdb_result_statement_type(duckdb_result result) { if (!result.internal_data || duckdb_result_error(&result) != nullptr) { From 7c52967239386a84864a6d9dbb66ff82902999e0 Mon Sep 17 00:00:00 2001 From: Mark Date: Wed, 8 Nov 2023 14:33:33 +0100 Subject: [PATCH 08/10] No REQUIRE_SUCCESS --- test/api/capi/test_capi_complex_types.cpp | 2 +- test/include/test_helpers.hpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/test/api/capi/test_capi_complex_types.cpp b/test/api/capi/test_capi_complex_types.cpp index dd9589f7bb76..62b737d0f345 100644 --- a/test/api/capi/test_capi_complex_types.cpp +++ b/test/api/capi/test_capi_complex_types.cpp @@ -248,7 +248,7 @@ TEST_CASE("Statement types", "[capi]") { REQUIRE(tester.OpenDatabase(nullptr)); duckdb_prepared_statement prepared; - REQUIRE_SUCCESS(duckdb_prepare(tester.connection, "select ?", &prepared)); + REQUIRE(duckdb_prepare(tester.connection, "select ?", &prepared) == DuckDBSuccess); REQUIRE(duckdb_prepared_statement_type(prepared) == DUCKDB_STATEMENT_TYPE_SELECT); duckdb_destroy_prepare(&prepared); diff --git a/test/include/test_helpers.hpp b/test/include/test_helpers.hpp index 739687ab2a49..3444f01d3216 100644 --- a/test/include/test_helpers.hpp +++ b/test/include/test_helpers.hpp @@ -55,7 +55,6 @@ bool NO_FAIL(duckdb::unique_ptr result); #define REQUIRE_NO_FAIL(result) REQUIRE(NO_FAIL((result))) #define REQUIRE_FAIL(result) REQUIRE((result)->HasError()) -#define REQUIRE_SUCCESS(result) REQUIRE(result == DuckDBSuccess) #define COMPARE_CSV(result, csv, header) \ { \ From 8fc9cebe3d331f64e7f971f29775e3e5cfca2a0f Mon Sep 17 00:00:00 2001 From: Elliana May Date: Fri, 10 Nov 2023 17:01:42 +0800 Subject: [PATCH 09/10] attempt to fix compile error on windows --- src/main/capi/result-c.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/capi/result-c.cpp b/src/main/capi/result-c.cpp index 118fe93e3f21..624d51ed7652 100644 --- a/src/main/capi/result-c.cpp +++ b/src/main/capi/result-c.cpp @@ -611,7 +611,7 @@ duckdb_statement_type duckdb_prepared_statement_type(duckdb_prepared_statement s if (!statement) { return DUCKDB_STATEMENT_TYPE_INVALID; } - auto &stmt = *(reinterpret_cast(statement)); + auto stmt = reinterpret_cast(statement); - return StatementTypeToC(stmt.statement->GetStatementType()); + return StatementTypeToC(stmt->statement->GetStatementType()); } From d454ee9871e4e2e5de9818324b488461d859284b Mon Sep 17 00:00:00 2001 From: Elliana May Date: Sat, 11 Nov 2023 21:46:36 +0800 Subject: [PATCH 10/10] move functions to proper locations --- .../duckdb/main/capi/capi_internal.hpp | 1 + src/main/capi/helper-c.cpp | 65 ++++++++++++++++ src/main/capi/prepared-c.cpp | 9 +++ src/main/capi/result-c.cpp | 74 ------------------- 4 files changed, 75 insertions(+), 74 deletions(-) diff --git a/src/include/duckdb/main/capi/capi_internal.hpp b/src/include/duckdb/main/capi/capi_internal.hpp index 3a9e9a674a27..6ccd852925bd 100644 --- a/src/include/duckdb/main/capi/capi_internal.hpp +++ b/src/include/duckdb/main/capi/capi_internal.hpp @@ -76,5 +76,6 @@ LogicalTypeId ConvertCTypeToCPP(duckdb_type c_type); idx_t GetCTypeSize(duckdb_type type); duckdb_state duckdb_translate_result(unique_ptr result, duckdb_result *out); bool deprecated_materialize_result(duckdb_result *result); +duckdb_statement_type StatementTypeToC(duckdb::StatementType statement_type); } // namespace duckdb diff --git a/src/main/capi/helper-c.cpp b/src/main/capi/helper-c.cpp index cf8001e13e44..c377630af780 100644 --- a/src/main/capi/helper-c.cpp +++ b/src/main/capi/helper-c.cpp @@ -173,6 +173,71 @@ idx_t GetCTypeSize(duckdb_type type) { } // LCOV_EXCL_STOP } +duckdb_statement_type StatementTypeToC(duckdb::StatementType statement_type) { + switch (statement_type) { + case duckdb::StatementType::SELECT_STATEMENT: + return DUCKDB_STATEMENT_TYPE_SELECT; + case duckdb::StatementType::INVALID_STATEMENT: + return DUCKDB_STATEMENT_TYPE_INVALID; + case duckdb::StatementType::INSERT_STATEMENT: + return DUCKDB_STATEMENT_TYPE_INSERT; + case duckdb::StatementType::UPDATE_STATEMENT: + return DUCKDB_STATEMENT_TYPE_UPDATE; + case duckdb::StatementType::EXPLAIN_STATEMENT: + return DUCKDB_STATEMENT_TYPE_EXPLAIN; + case duckdb::StatementType::DELETE_STATEMENT: + return DUCKDB_STATEMENT_TYPE_DELETE; + case duckdb::StatementType::PREPARE_STATEMENT: + return DUCKDB_STATEMENT_TYPE_PREPARE; + case duckdb::StatementType::CREATE_STATEMENT: + return DUCKDB_STATEMENT_TYPE_CREATE; + case duckdb::StatementType::EXECUTE_STATEMENT: + return DUCKDB_STATEMENT_TYPE_EXECUTE; + case duckdb::StatementType::ALTER_STATEMENT: + return DUCKDB_STATEMENT_TYPE_ALTER; + case duckdb::StatementType::TRANSACTION_STATEMENT: + return DUCKDB_STATEMENT_TYPE_TRANSACTION; + case duckdb::StatementType::COPY_STATEMENT: + return DUCKDB_STATEMENT_TYPE_COPY; + case duckdb::StatementType::ANALYZE_STATEMENT: + return DUCKDB_STATEMENT_TYPE_ANALYZE; + case duckdb::StatementType::VARIABLE_SET_STATEMENT: + return DUCKDB_STATEMENT_TYPE_VARIABLE_SET; + case duckdb::StatementType::CREATE_FUNC_STATEMENT: + return DUCKDB_STATEMENT_TYPE_CREATE_FUNC; + case duckdb::StatementType::DROP_STATEMENT: + return DUCKDB_STATEMENT_TYPE_DROP; + case duckdb::StatementType::EXPORT_STATEMENT: + return DUCKDB_STATEMENT_TYPE_EXPORT; + case duckdb::StatementType::PRAGMA_STATEMENT: + return DUCKDB_STATEMENT_TYPE_PRAGMA; + case duckdb::StatementType::SHOW_STATEMENT: + return DUCKDB_STATEMENT_TYPE_SHOW; + case duckdb::StatementType::VACUUM_STATEMENT: + return DUCKDB_STATEMENT_TYPE_VACUUM; + case duckdb::StatementType::CALL_STATEMENT: + return DUCKDB_STATEMENT_TYPE_CALL; + case duckdb::StatementType::SET_STATEMENT: + return DUCKDB_STATEMENT_TYPE_SET; + case duckdb::StatementType::LOAD_STATEMENT: + return DUCKDB_STATEMENT_TYPE_LOAD; + case duckdb::StatementType::RELATION_STATEMENT: + return DUCKDB_STATEMENT_TYPE_RELATION; + case duckdb::StatementType::EXTENSION_STATEMENT: + return DUCKDB_STATEMENT_TYPE_EXTENSION; + case duckdb::StatementType::LOGICAL_PLAN_STATEMENT: + return DUCKDB_STATEMENT_TYPE_LOGICAL_PLAN; + case duckdb::StatementType::ATTACH_STATEMENT: + return DUCKDB_STATEMENT_TYPE_ATTACH; + case duckdb::StatementType::DETACH_STATEMENT: + return DUCKDB_STATEMENT_TYPE_DETACH; + case duckdb::StatementType::MULTI_STATEMENT: + return DUCKDB_STATEMENT_TYPE_MULTI; + default: + return DUCKDB_STATEMENT_TYPE_INVALID; + } +} + } // namespace duckdb void *duckdb_malloc(size_t size) { diff --git a/src/main/capi/prepared-c.cpp b/src/main/capi/prepared-c.cpp index 82b488b7a2d2..5acec78bd87d 100644 --- a/src/main/capi/prepared-c.cpp +++ b/src/main/capi/prepared-c.cpp @@ -320,6 +320,15 @@ duckdb_state duckdb_execute_prepared(duckdb_prepared_statement prepared_statemen return duckdb_translate_result(std::move(result), out_result); } +duckdb_statement_type duckdb_prepared_statement_type(duckdb_prepared_statement statement) { + if (!statement) { + return DUCKDB_STATEMENT_TYPE_INVALID; + } + auto stmt = reinterpret_cast(statement); + + return StatementTypeToC(stmt->statement->GetStatementType()); +} + template void duckdb_destroy(void **wrapper) { if (!wrapper) { diff --git a/src/main/capi/result-c.cpp b/src/main/capi/result-c.cpp index 624d51ed7652..0773406dea52 100644 --- a/src/main/capi/result-c.cpp +++ b/src/main/capi/result-c.cpp @@ -533,71 +533,6 @@ duckdb_result_type duckdb_result_return_type(duckdb_result result) { } } -static duckdb_statement_type StatementTypeToC(duckdb::StatementType statement_type) { - switch (statement_type) { - case duckdb::StatementType::SELECT_STATEMENT: - return DUCKDB_STATEMENT_TYPE_SELECT; - case duckdb::StatementType::INVALID_STATEMENT: - return DUCKDB_STATEMENT_TYPE_INVALID; - case duckdb::StatementType::INSERT_STATEMENT: - return DUCKDB_STATEMENT_TYPE_INSERT; - case duckdb::StatementType::UPDATE_STATEMENT: - return DUCKDB_STATEMENT_TYPE_UPDATE; - case duckdb::StatementType::EXPLAIN_STATEMENT: - return DUCKDB_STATEMENT_TYPE_EXPLAIN; - case duckdb::StatementType::DELETE_STATEMENT: - return DUCKDB_STATEMENT_TYPE_DELETE; - case duckdb::StatementType::PREPARE_STATEMENT: - return DUCKDB_STATEMENT_TYPE_PREPARE; - case duckdb::StatementType::CREATE_STATEMENT: - return DUCKDB_STATEMENT_TYPE_CREATE; - case duckdb::StatementType::EXECUTE_STATEMENT: - return DUCKDB_STATEMENT_TYPE_EXECUTE; - case duckdb::StatementType::ALTER_STATEMENT: - return DUCKDB_STATEMENT_TYPE_ALTER; - case duckdb::StatementType::TRANSACTION_STATEMENT: - return DUCKDB_STATEMENT_TYPE_TRANSACTION; - case duckdb::StatementType::COPY_STATEMENT: - return DUCKDB_STATEMENT_TYPE_COPY; - case duckdb::StatementType::ANALYZE_STATEMENT: - return DUCKDB_STATEMENT_TYPE_ANALYZE; - case duckdb::StatementType::VARIABLE_SET_STATEMENT: - return DUCKDB_STATEMENT_TYPE_VARIABLE_SET; - case duckdb::StatementType::CREATE_FUNC_STATEMENT: - return DUCKDB_STATEMENT_TYPE_CREATE_FUNC; - case duckdb::StatementType::DROP_STATEMENT: - return DUCKDB_STATEMENT_TYPE_DROP; - case duckdb::StatementType::EXPORT_STATEMENT: - return DUCKDB_STATEMENT_TYPE_EXPORT; - case duckdb::StatementType::PRAGMA_STATEMENT: - return DUCKDB_STATEMENT_TYPE_PRAGMA; - case duckdb::StatementType::SHOW_STATEMENT: - return DUCKDB_STATEMENT_TYPE_SHOW; - case duckdb::StatementType::VACUUM_STATEMENT: - return DUCKDB_STATEMENT_TYPE_VACUUM; - case duckdb::StatementType::CALL_STATEMENT: - return DUCKDB_STATEMENT_TYPE_CALL; - case duckdb::StatementType::SET_STATEMENT: - return DUCKDB_STATEMENT_TYPE_SET; - case duckdb::StatementType::LOAD_STATEMENT: - return DUCKDB_STATEMENT_TYPE_LOAD; - case duckdb::StatementType::RELATION_STATEMENT: - return DUCKDB_STATEMENT_TYPE_RELATION; - case duckdb::StatementType::EXTENSION_STATEMENT: - return DUCKDB_STATEMENT_TYPE_EXTENSION; - case duckdb::StatementType::LOGICAL_PLAN_STATEMENT: - return DUCKDB_STATEMENT_TYPE_LOGICAL_PLAN; - case duckdb::StatementType::ATTACH_STATEMENT: - return DUCKDB_STATEMENT_TYPE_ATTACH; - case duckdb::StatementType::DETACH_STATEMENT: - return DUCKDB_STATEMENT_TYPE_DETACH; - case duckdb::StatementType::MULTI_STATEMENT: - return DUCKDB_STATEMENT_TYPE_MULTI; - default: - return DUCKDB_STATEMENT_TYPE_INVALID; - } -} - duckdb_statement_type duckdb_result_statement_type(duckdb_result result) { if (!result.internal_data || duckdb_result_error(&result) != nullptr) { return DUCKDB_STATEMENT_TYPE_INVALID; @@ -606,12 +541,3 @@ duckdb_statement_type duckdb_result_statement_type(duckdb_result result) { return StatementTypeToC(pres.result->statement_type); } - -duckdb_statement_type duckdb_prepared_statement_type(duckdb_prepared_statement statement) { - if (!statement) { - return DUCKDB_STATEMENT_TYPE_INVALID; - } - auto stmt = reinterpret_cast(statement); - - return StatementTypeToC(stmt->statement->GetStatementType()); -}