File: test_capi_extract.cpp

package info (click to toggle)
duckdb 1.5.1-2
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 299,196 kB
  • sloc: cpp: 865,414; ansic: 57,292; python: 18,871; sql: 12,663; lisp: 11,751; yacc: 7,412; lex: 1,682; sh: 747; makefile: 558
file content (85 lines) | stat: -rw-r--r-- 2,858 bytes parent folder | download | duplicates (3)
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
#include "capi_tester.hpp"

using namespace duckdb;
using namespace std;

TEST_CASE("Test extract statements in C API", "[capi]") {
	CAPITester tester;
	duckdb_result res;
	duckdb_extracted_statements stmts = nullptr;
	duckdb_state status;
	const char *error;
	duckdb_prepared_statement prepared = nullptr;

	REQUIRE(tester.OpenDatabase(nullptr));

	idx_t size = duckdb_extract_statements(tester.connection,
	                                       "CREATE TABLE tbl (col INT); INSERT INTO tbl VALUES (1), (2), (3), (4); "
	                                       "SELECT COUNT(col) FROM tbl WHERE col > $1",
	                                       &stmts);

	REQUIRE(size == 3);
	REQUIRE(stmts != nullptr);

	for (idx_t i = 0; i + 1 < size; i++) {
		status = duckdb_prepare_extracted_statement(tester.connection, stmts, i, &prepared);
		REQUIRE(status == DuckDBSuccess);
		status = duckdb_execute_prepared(prepared, &res);
		REQUIRE(status == DuckDBSuccess);
		duckdb_destroy_prepare(&prepared);
		duckdb_destroy_result(&res);
	}

	duckdb_prepared_statement stmt = nullptr;
	status = duckdb_prepare_extracted_statement(tester.connection, stmts, size - 1, &stmt);
	REQUIRE(status == DuckDBSuccess);
	duckdb_bind_int32(stmt, 1, 1);
	status = duckdb_execute_prepared(stmt, &res);
	REQUIRE(status == DuckDBSuccess);
	REQUIRE(duckdb_value_int64(&res, 0, 0) == 3);
	duckdb_destroy_prepare(&stmt);
	duckdb_destroy_result(&res);
	duckdb_destroy_extracted(&stmts);

	//	 test empty statement is not an error
	size = duckdb_extract_statements(tester.connection, "", &stmts);
	REQUIRE(size == 0);
	error = duckdb_extract_statements_error(stmts);
	REQUIRE(error == nullptr);
	duckdb_destroy_extracted(&stmts);

	//	 test incorrect statement cannot be extracted
	size = duckdb_extract_statements(tester.connection, "This is not valid SQL", &stmts);
	REQUIRE(size == 0);
	error = duckdb_extract_statements_error(stmts);
	REQUIRE(error != nullptr);
	duckdb_destroy_extracted(&stmts);

	// test out of bounds
	size = duckdb_extract_statements(tester.connection, "SELECT CAST($1 AS BIGINT)", &stmts);
	REQUIRE(size == 1);
	status = duckdb_prepare_extracted_statement(tester.connection, stmts, 2, &prepared);
	REQUIRE(status == DuckDBError);
	duckdb_destroy_extracted(&stmts);
}

TEST_CASE("Test invalid PRAGMA in C API", "[capi]") {
	duckdb_database db;
	duckdb_connection con;
	const char *err_msg;

	REQUIRE(duckdb_open(nullptr, &db) == DuckDBSuccess);
	REQUIRE(duckdb_connect(db, &con) == DuckDBSuccess);

	duckdb_extracted_statements stmts;
	auto size = duckdb_extract_statements(con, "PRAGMA something;", &stmts);

	REQUIRE(size == 0);
	err_msg = duckdb_extract_statements_error(stmts);
	REQUIRE(err_msg != nullptr);
	REQUIRE(string(err_msg).find("Catalog Error") != std::string::npos);

	duckdb_destroy_extracted(&stmts);
	duckdb_disconnect(&con);
	duckdb_close(&db);
}