File: test_appender.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 (87 lines) | stat: -rw-r--r-- 2,299 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
86
87
#include "catch.hpp"
#include "test_helpers.hpp"
#include "duckdb/main/config.hpp"
#include "test_config.hpp"

using namespace duckdb;
using namespace std;

void rand_str(char *dest, idx_t length) {
	char charset[] = "0123456789"
	                 "abcdefghijklmnopqrstuvwxyz"
	                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

	while (length-- > 0) {
		idx_t index = (double)rand() / RAND_MAX * (sizeof charset - 1);
		*dest++ = charset[index];
	}
	*dest = '\0';
}

TEST_CASE("Test repeated appending small chunks to a table", "[memoryleak]") {
	if (!TestConfiguration::TestMemoryLeaks()) {
		return;
	}
	duckdb_database db;
	duckdb_connection con;
	duckdb_state state;
	auto db_path = TestCreatePath("appender_leak_test.db");
	TestDeleteFile(db_path);

	if (duckdb_open(db_path.c_str(), &db) == DuckDBError) {
		// handle error
		FAIL("Failed to open");
	}
	if (duckdb_connect(db, &con) == DuckDBError) {
		// handle error
		FAIL("Failed to connect");
	}

	state =
	    duckdb_query(con, "create table test(col1 varchar, col2 varchar, col3 bigint, col4 bigint, col5 double)", NULL);
	if (state == DuckDBError) {
		FAIL("Failed to create table");
	}
	state = duckdb_query(con, "set memory_limit='100mb'", NULL);
	if (state == DuckDBError) {
		FAIL("Failed to set memory limit");
	}

	long n1 = 0;
	double d1 = 0.5;
	for (int i = 0; i < 100000; i++) {
		duckdb_appender appender;
		if (duckdb_appender_create(con, NULL, "test", &appender) == DuckDBError) {
			FAIL("Failed to create appender");
		}
		for (int j = 0; j < 1000; j++) {
			char str[41];
			rand_str(str, sizeof(str) - 1);
			duckdb_append_varchar(appender, str);
			duckdb_append_varchar(appender, "hello");
			duckdb_append_int64(appender, n1++);
			duckdb_append_int64(appender, n1++);
			duckdb_append_double(appender, d1);
			d1 += 1.25;
			duckdb_appender_end_row(appender);
		}
		state = duckdb_appender_close(appender);
		if (state == DuckDBError) {
			FAIL("Failed to close appender");
		}
		state = duckdb_appender_destroy(&appender);
		if (state == DuckDBError) {
			fprintf(stderr, "err: %d", state);
			FAIL("Failed to destroy appender");
		}
		if (i % 500 == 0) {
			printf("completed %d\n", i);
			duckdb_query(con, "checkpoint", NULL);
		}
	}

	// cleanup
	duckdb_disconnect(&con);
	duckdb_close(&db);
	REQUIRE(1 == 1);
}