Skip to content

Commit 0622dfb

Browse files
authored
Merge pull request #164 from duckdb/jray/create-appender-ext
create appender ext
2 parents cbec9b5 + 54e4e83 commit 0622dfb

File tree

8 files changed

+80
-39
lines changed

8 files changed

+80
-39
lines changed

api/pkgs/@duckdb/node-api/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,7 @@ await connection.run(
644644
`create or replace table target_table(i integer, v varchar)`
645645
);
646646

647-
const appender = await connection.createAppender('main', 'target_table');
647+
const appender = await connection.createAppender('target_table');
648648

649649
appender.appendInteger(42);
650650
appender.appendVarchar('duck');
@@ -670,7 +670,7 @@ await connection.run(
670670
`create or replace table target_table(i integer, v varchar)`
671671
);
672672

673-
const appender = await connection.createAppender('main', 'target_table');
673+
const appender = await connection.createAppender('target_table');
674674

675675
const chunk = DuckDBDataChunk.create([INTEGER, VARCHAR]);
676676
chunk.setColumns([

api/src/DuckDBConnection.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,11 +161,17 @@ export class DuckDBConnection {
161161
);
162162
}
163163
public async createAppender(
164-
schema: string,
165-
table: string
164+
table: string,
165+
schema?: string | null,
166+
catalog?: string | null
166167
): Promise<DuckDBAppender> {
167168
return new DuckDBAppender(
168-
duckdb.appender_create(this.connection, schema, table)
169+
duckdb.appender_create_ext(
170+
this.connection,
171+
catalog ?? null,
172+
schema ?? null,
173+
table
174+
)
169175
);
170176
}
171177
}

api/test/api.test.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,7 +1374,7 @@ describe('api', () => {
13741374
chunk.setColumnValues(0, values);
13751375

13761376
await connection.run('create table target(col0 int)');
1377-
const appender = await connection.createAppender('main', 'target');
1377+
const appender = await connection.createAppender('target');
13781378
appender.appendDataChunk(chunk);
13791379
appender.flush();
13801380

@@ -1408,7 +1408,7 @@ describe('api', () => {
14081408
}
14091409

14101410
await connection.run('create table target1(col0 int)');
1411-
const appender1 = await connection.createAppender('main', 'target1');
1411+
const appender1 = await connection.createAppender('target1');
14121412
appender1.appendDataChunk(chunk);
14131413
appender1.flush();
14141414

@@ -1425,7 +1425,7 @@ describe('api', () => {
14251425
vector.flush();
14261426

14271427
await connection.run('create table target2(col0 int)');
1428-
const appender2 = await connection.createAppender('main', 'target2');
1428+
const appender2 = await connection.createAppender('target2');
14291429
appender2.appendDataChunk(chunk);
14301430
appender2.flush();
14311431

@@ -1447,7 +1447,7 @@ describe('api', () => {
14471447
chunk.setColumnValues(0, values);
14481448

14491449
await connection.run('create table target(col0 varchar)');
1450-
const appender = await connection.createAppender('main', 'target');
1450+
const appender = await connection.createAppender('target');
14511451
appender.appendDataChunk(chunk);
14521452
appender.flush();
14531453

@@ -1483,7 +1483,7 @@ describe('api', () => {
14831483
chunk.setColumnValues(0, values);
14841484

14851485
await connection.run('create table target(col0 blob)');
1486-
const appender = await connection.createAppender('main', 'target');
1486+
const appender = await connection.createAppender('target');
14871487
appender.appendDataChunk(chunk);
14881488
appender.flush();
14891489

@@ -1510,7 +1510,7 @@ describe('api', () => {
15101510
chunk.setColumnValues(0, values);
15111511

15121512
await connection.run('create table target(col0 integer[])');
1513-
const appender = await connection.createAppender('main', 'target');
1513+
const appender = await connection.createAppender('target');
15141514
appender.appendDataChunk(chunk);
15151515
appender.flush();
15161516

@@ -1557,7 +1557,7 @@ describe('api', () => {
15571557
]);
15581558

15591559
await connection.run('create table target(col0 integer[][])');
1560-
const appender = await connection.createAppender('main', 'target');
1560+
const appender = await connection.createAppender('target');
15611561
appender.appendDataChunk(chunk);
15621562
appender.flush();
15631563

@@ -1584,7 +1584,7 @@ describe('api', () => {
15841584
chunk.setColumnValues(0, values);
15851585

15861586
await connection.run('create table target(col0 integer[3])');
1587-
const appender = await connection.createAppender('main', 'target');
1587+
const appender = await connection.createAppender('target');
15881588
appender.appendDataChunk(chunk);
15891589
appender.flush();
15901590

@@ -1611,7 +1611,7 @@ describe('api', () => {
16111611
chunk.setColumnValues(0, values);
16121612

16131613
await connection.run('create table target(col0 varchar[3])');
1614-
const appender = await connection.createAppender('main', 'target');
1614+
const appender = await connection.createAppender('target');
16151615
appender.appendDataChunk(chunk);
16161616
appender.flush();
16171617

@@ -1643,7 +1643,7 @@ describe('api', () => {
16431643
await connection.run(
16441644
'create table target(col0 struct(num integer, str varchar))'
16451645
);
1646-
const appender = await connection.createAppender('main', 'target');
1646+
const appender = await connection.createAppender('target');
16471647
appender.appendDataChunk(chunk);
16481648
appender.flush();
16491649

@@ -1683,7 +1683,7 @@ describe('api', () => {
16831683
int integer\
16841684
)'
16851685
);
1686-
const appender = await connection.createAppender('main', 'target');
1686+
const appender = await connection.createAppender('target');
16871687
appender.appendDataChunk(chunk);
16881688
appender.flush();
16891689

@@ -1720,7 +1720,7 @@ describe('api', () => {
17201720
.map(({ name, type }) => `"${name.replace(`"`, `""`)}" ${type}`)
17211721
.join(', ')})`
17221722
);
1723-
const appender = await connection.createAppender('main', 'target');
1723+
const appender = await connection.createAppender('target');
17241724
appender.appendDataChunk(chunk);
17251725
appender.flush();
17261726

api/test/bench/read.bench.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ for (const full of [false, true]) {
100100
},
101101
{
102102
setup,
103-
iterations: 200,
103+
iterations: 20,
104104
}
105105
);
106106
bench(
@@ -126,7 +126,7 @@ for (const full of [false, true]) {
126126
},
127127
{
128128
setup,
129-
iterations: 200,
129+
iterations: 20,
130130
}
131131
);
132132
bench(
@@ -160,7 +160,7 @@ for (const full of [false, true]) {
160160
},
161161
{
162162
setup,
163-
iterations: 200,
163+
iterations: 20,
164164
}
165165
);
166166

@@ -179,7 +179,7 @@ for (const full of [false, true]) {
179179
},
180180
{
181181
setup,
182-
iterations: 200,
182+
iterations: 20,
183183
}
184184
);
185185
bench(
@@ -205,7 +205,7 @@ for (const full of [false, true]) {
205205
},
206206
{
207207
setup,
208-
iterations: 200,
208+
iterations: 20,
209209
}
210210
);
211211
bench(
@@ -239,7 +239,7 @@ for (const full of [false, true]) {
239239
},
240240
{
241241
setup,
242-
iterations: 200,
242+
iterations: 20,
243243
}
244244
);
245245
bench(
@@ -265,7 +265,7 @@ for (const full of [false, true]) {
265265
},
266266
{
267267
setup,
268-
iterations: 200,
268+
iterations: 20,
269269
}
270270
);
271271
bench(
@@ -291,7 +291,7 @@ for (const full of [false, true]) {
291291
},
292292
{
293293
setup,
294-
iterations: 200,
294+
iterations: 20,
295295
}
296296
);
297297
});

api/test/bench/write.bench.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { bench, describe } from "vitest";
1+
import { bench, describe } from 'vitest';
22
import {
33
DuckDBConnection,
44
DuckDBInstance,
55
DuckDBTimestampValue,
6-
} from "../../src";
6+
} from '../../src';
77

88
let instance: DuckDBInstance;
99
let connection: DuckDBConnection;
@@ -26,7 +26,7 @@ for (const batchSize of [1, 1000]) {
2626
`${batchSize} insert bind`,
2727
async () => {
2828
const query = await connection.prepare(
29-
"INSERT INTO test (timestamp, value) VALUES ($1, $2);"
29+
'INSERT INTO test (timestamp, value) VALUES ($1, $2);'
3030
);
3131

3232
for (let index = 0; index < batchSize; index++) {
@@ -46,7 +46,7 @@ for (const batchSize of [1, 1000]) {
4646
bench(
4747
`${batchSize} row append`,
4848
async () => {
49-
const appender = await connection.createAppender("main", "test");
49+
const appender = await connection.createAppender('test');
5050

5151
for (let index = 0; index < batchSize; index++) {
5252
appender.appendTimestamp(

bindings/pkgs/@duckdb/node-bindings/duckdb.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1054,9 +1054,10 @@ export function validity_set_row_valid(validity: Uint8Array, row_index: number):
10541054
// DUCKDB_API duckdb_profiling_info duckdb_profiling_info_get_child(duckdb_profiling_info info, idx_t index);
10551055

10561056
// DUCKDB_API duckdb_state duckdb_appender_create(duckdb_connection connection, const char *schema, const char *table, duckdb_appender *out_appender);
1057-
export function appender_create(connection: Connection, schema: string, table: string): Appender;
1057+
export function appender_create(connection: Connection, schema: string | null, table: string): Appender;
10581058

10591059
// DUCKDB_API duckdb_state duckdb_appender_create_ext(duckdb_connection connection, const char *catalog, const char *schema, const char *table, duckdb_appender *out_appender);
1060+
export function appender_create_ext(connection: Connection, catalog: string | null, schema: string | null, table: string): Appender;
10601061

10611062
// DUCKDB_API idx_t duckdb_appender_column_count(duckdb_appender appender);
10621063
export function appender_column_count(appender: Appender): number;

bindings/src/duckdb_node_bindings.cpp

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,6 +1273,7 @@ class DuckDBNodeAddon : public Napi::Addon<DuckDBNodeAddon> {
12731273
InstanceMethod("validity_set_row_valid", &DuckDBNodeAddon::validity_set_row_valid),
12741274

12751275
InstanceMethod("appender_create", &DuckDBNodeAddon::appender_create),
1276+
InstanceMethod("appender_create_ext", &DuckDBNodeAddon::appender_create_ext),
12761277
InstanceMethod("appender_column_count", &DuckDBNodeAddon::appender_column_count),
12771278
InstanceMethod("appender_column_type", &DuckDBNodeAddon::appender_column_type),
12781279
InstanceMethod("appender_flush", &DuckDBNodeAddon::appender_flush),
@@ -3707,17 +3708,24 @@ class DuckDBNodeAddon : public Napi::Addon<DuckDBNodeAddon> {
37073708
// DUCKDB_API duckdb_profiling_info duckdb_profiling_info_get_child(duckdb_profiling_info info, idx_t index);
37083709

37093710
// DUCKDB_API duckdb_state duckdb_appender_create(duckdb_connection connection, const char *schema, const char *table, duckdb_appender *out_appender);
3710-
// function appender_create(connection: Connection, schema: string, table: string): Appender
3711+
// function appender_create(connection: Connection, schema: string | null, table: string): Appender
37113712
Napi::Value appender_create(const Napi::CallbackInfo& info) {
37123713
auto env = info.Env();
37133714
auto connection = GetConnectionFromExternal(env, info[0]);
37143715
if (!connection) {
37153716
throw Napi::Error::New(env, "Failed to create appender: connection disconnected");
37163717
}
3717-
std::string schema = info[1].As<Napi::String>();
3718+
std::string schema = info[1].IsNull() ? std::string() : info[1].As<Napi::String>();
37183719
std::string table = info[2].As<Napi::String>();
37193720
duckdb_appender appender;
3720-
if (duckdb_appender_create(connection, schema.c_str(), table.c_str(), &appender)) {
3721+
if (
3722+
duckdb_appender_create(
3723+
connection,
3724+
info[1].IsNull() ? nullptr : schema.c_str(),
3725+
table.c_str(),
3726+
&appender
3727+
)
3728+
) {
37213729
std::string error = duckdb_appender_error(appender);
37223730
duckdb_appender_destroy(&appender);
37233731
throw Napi::Error::New(env, error);
@@ -3726,6 +3734,32 @@ class DuckDBNodeAddon : public Napi::Addon<DuckDBNodeAddon> {
37263734
}
37273735

37283736
// DUCKDB_API duckdb_state duckdb_appender_create_ext(duckdb_connection connection, const char *catalog, const char *schema, const char *table, duckdb_appender *out_appender);
3737+
// function appender_create_ext(connection: Connection, catalog: string | null, schema: string | null, table: string): Appender
3738+
Napi::Value appender_create_ext(const Napi::CallbackInfo& info) {
3739+
auto env = info.Env();
3740+
auto connection = GetConnectionFromExternal(env, info[0]);
3741+
if (!connection) {
3742+
throw Napi::Error::New(env, "Failed to create appender: connection disconnected");
3743+
}
3744+
std::string catalog = info[1].IsNull() ? std::string() : info[1].As<Napi::String>();
3745+
std::string schema = info[2].IsNull() ? std::string() : info[2].As<Napi::String>();
3746+
std::string table = info[3].As<Napi::String>();
3747+
duckdb_appender appender;
3748+
if (
3749+
duckdb_appender_create_ext(
3750+
connection,
3751+
info[1].IsNull() ? nullptr : catalog.c_str(),
3752+
info[2].IsNull() ? nullptr : schema.c_str(),
3753+
table.c_str(),
3754+
&appender
3755+
)
3756+
) {
3757+
std::string error = duckdb_appender_error(appender);
3758+
duckdb_appender_destroy(&appender);
3759+
throw Napi::Error::New(env, error);
3760+
}
3761+
return CreateExternalForAppender(env, appender);
3762+
}
37293763

37303764
// DUCKDB_API idx_t duckdb_appender_column_count(duckdb_appender appender);
37313765
// function appender_column_count(appender: Appender): number
@@ -4183,7 +4217,7 @@ NODE_API_ADDON(DuckDBNodeAddon)
41834217
---
41844218
411 total functions
41854219
4186-
237 instance methods
4220+
238 instance methods
41874221
3 unimplemented instance cache functions
41884222
1 unimplemented logical type function
41894223
13 unimplemented scalar function functions
@@ -4196,7 +4230,7 @@ NODE_API_ADDON(DuckDBNodeAddon)
41964230
5 unimplemented function info functions
41974231
4 unimplemented replacement scan functions
41984232
5 unimplemented profiling info functions
4199-
5 unimplemented appender functions
4233+
4 unimplemented appender functions
42004234
6 unimplemented table description functions
42014235
8 unimplemented tasks functions
42024236
12 unimplemented cast function functions

bindings/test/appender.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { data } from './utils/expectedVectors';
99
suite('appender', () => {
1010
test('error: no table', async () => {
1111
await withConnection(async (connection) => {
12-
expect(() => duckdb.appender_create(connection, 'main', 'bogus_table'))
12+
expect(() => duckdb.appender_create_ext(connection, 'memory', 'main', 'bogus_table'))
1313
.toThrowError(`Table "main.bogus_table" could not be found`);
1414
});
1515
});
@@ -27,7 +27,7 @@ suite('appender', () => {
2727
chunks: [],
2828
});
2929

30-
const appender = duckdb.appender_create(connection, 'main', 'appender_target');
30+
const appender = duckdb.appender_create_ext(connection, 'memory', 'main', 'appender_target');
3131
expect(duckdb.appender_column_count(appender)).toBe(1);
3232
const column_type = duckdb.appender_column_type(appender, 0);
3333
expectLogicalType(column_type, INTEGER);
@@ -92,7 +92,7 @@ suite('appender', () => {
9292
});
9393

9494

95-
const appender = duckdb.appender_create(connection, 'main', 'appender_target');
95+
const appender = duckdb.appender_create_ext(connection, 'memory', 'main', 'appender_target');
9696
expect(duckdb.appender_column_count(appender)).toBe(21);
9797

9898
const expectedLogicalTypes = [
@@ -222,7 +222,7 @@ suite('appender', () => {
222222
chunks: [],
223223
});
224224

225-
const appender = duckdb.appender_create(connection, 'main', 'appender_target');
225+
const appender = duckdb.appender_create_ext(connection, 'memory', 'main', 'appender_target');
226226
expect(duckdb.appender_column_count(appender)).toBe(2);
227227

228228
const source_result = await duckdb.query(connection, 'select int, varchar from test_all_types()');

0 commit comments

Comments
 (0)