Skip to content

Commit cbec9b5

Browse files
authored
Merge pull request #163 from duckdb/jray/get-list-size-child-and-struct-child
get_list_size, get_list_child, get_struct_child
2 parents 13bccd8 + bcab984 commit cbec9b5

File tree

3 files changed

+65
-7
lines changed

3 files changed

+65
-7
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,10 @@ export function is_null_value(value: Value): boolean;
796796
export function create_null_value(): Value;
797797

798798
// DUCKDB_API idx_t duckdb_get_list_size(duckdb_value value);
799+
export function get_list_size(value: Value): number;
800+
799801
// DUCKDB_API duckdb_value duckdb_get_list_child(duckdb_value value, idx_t index);
802+
export function get_list_child(value: Value, index: number): Value;
800803

801804
// DUCKDB_API duckdb_value duckdb_create_enum_value(duckdb_logical_type type, uint64_t value);
802805
export function create_enum_value(logical_type: LogicalType, value: number): Value;
@@ -805,6 +808,7 @@ export function create_enum_value(logical_type: LogicalType, value: number): Val
805808
export function get_enum_value(value: Value): number;
806809

807810
// DUCKDB_API duckdb_value duckdb_get_struct_child(duckdb_value value, idx_t index);
811+
export function get_struct_child(value: Value, index: number): Value;
808812

809813
// DUCKDB_API duckdb_logical_type duckdb_create_logical_type(duckdb_type type);
810814
export function create_logical_type(type: Type): LogicalType;

bindings/src/duckdb_node_bindings.cpp

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,8 +1213,11 @@ class DuckDBNodeAddon : public Napi::Addon<DuckDBNodeAddon> {
12131213
InstanceMethod("get_map_value", &DuckDBNodeAddon::get_map_value),
12141214
InstanceMethod("is_null_value", &DuckDBNodeAddon::is_null_value),
12151215
InstanceMethod("create_null_value", &DuckDBNodeAddon::create_null_value),
1216+
InstanceMethod("get_list_size", &DuckDBNodeAddon::get_list_size),
1217+
InstanceMethod("get_list_child", &DuckDBNodeAddon::get_list_child),
12161218
InstanceMethod("create_enum_value", &DuckDBNodeAddon::create_enum_value),
12171219
InstanceMethod("get_enum_value", &DuckDBNodeAddon::get_enum_value),
1220+
InstanceMethod("get_struct_child", &DuckDBNodeAddon::get_struct_child),
12181221

12191222
InstanceMethod("create_logical_type", &DuckDBNodeAddon::create_logical_type),
12201223
InstanceMethod("logical_type_get_alias", &DuckDBNodeAddon::logical_type_get_alias),
@@ -2978,6 +2981,9 @@ class DuckDBNodeAddon : public Napi::Addon<DuckDBNodeAddon> {
29782981
auto value = GetValueFromExternal(env, info[0]);
29792982
auto index = info[1].As<Napi::Number>().Uint32Value();
29802983
auto output_key = duckdb_get_map_key(value, index);
2984+
if (!output_key) {
2985+
throw Napi::Error::New(env, "Failed to get map key");
2986+
}
29812987
return CreateExternalForValue(env, output_key);
29822988
}
29832989

@@ -2988,6 +2994,9 @@ class DuckDBNodeAddon : public Napi::Addon<DuckDBNodeAddon> {
29882994
auto value = GetValueFromExternal(env, info[0]);
29892995
auto index = info[1].As<Napi::Number>().Uint32Value();
29902996
auto output_value = duckdb_get_map_value(value, index);
2997+
if (!output_value) {
2998+
throw Napi::Error::New(env, "Failed to get map value");
2999+
}
29913000
return CreateExternalForValue(env, output_value);
29923001
}
29933002

@@ -3009,7 +3018,26 @@ class DuckDBNodeAddon : public Napi::Addon<DuckDBNodeAddon> {
30093018
}
30103019

30113020
// DUCKDB_API idx_t duckdb_get_list_size(duckdb_value value);
3021+
// function get_list_size(value: Value): number
3022+
Napi::Value get_list_size(const Napi::CallbackInfo& info) {
3023+
auto env = info.Env();
3024+
auto value = GetValueFromExternal(env, info[0]);
3025+
auto size = duckdb_get_list_size(value);
3026+
return Napi::Number::New(env, size);
3027+
}
3028+
30123029
// DUCKDB_API duckdb_value duckdb_get_list_child(duckdb_value value, idx_t index);
3030+
// function get_list_child(value: Value, index: number): Value
3031+
Napi::Value get_list_child(const Napi::CallbackInfo& info) {
3032+
auto env = info.Env();
3033+
auto value = GetValueFromExternal(env, info[0]);
3034+
auto index = info[1].As<Napi::Number>().Uint32Value();
3035+
auto output_value = duckdb_get_list_child(value, index);
3036+
if (!output_value) {
3037+
throw Napi::Error::New(env, "Failed to get list child");
3038+
}
3039+
return CreateExternalForValue(env, output_value);
3040+
}
30133041

30143042
// DUCKDB_API duckdb_value duckdb_create_enum_value(duckdb_logical_type type, uint64_t value);
30153043
// function create_enum_value(logical_type: LogicalType, value: number): Value
@@ -3034,6 +3062,17 @@ class DuckDBNodeAddon : public Napi::Addon<DuckDBNodeAddon> {
30343062
}
30353063

30363064
// DUCKDB_API duckdb_value duckdb_get_struct_child(duckdb_value value, idx_t index);
3065+
// function get_struct_child(value: Value, index: number): Value
3066+
Napi::Value get_struct_child(const Napi::CallbackInfo& info) {
3067+
auto env = info.Env();
3068+
auto value = GetValueFromExternal(env, info[0]);
3069+
auto index = info[1].As<Napi::Number>().Uint32Value();
3070+
auto output_value = duckdb_get_struct_child(value, index);
3071+
if (!output_value) {
3072+
throw Napi::Error::New(env, "Failed to get struct child");
3073+
}
3074+
return CreateExternalForValue(env, output_value);
3075+
}
30373076

30383077
// DUCKDB_API duckdb_logical_type duckdb_create_logical_type(duckdb_type type);
30393078
// function create_logical_type(type: Type): LogicalType
@@ -4144,10 +4183,9 @@ NODE_API_ADDON(DuckDBNodeAddon)
41444183
---
41454184
411 total functions
41464185
4147-
234 instance methods
4186+
237 instance methods
41484187
3 unimplemented instance cache functions
41494188
1 unimplemented logical type function
4150-
3 unimplemented value inspection functions
41514189
13 unimplemented scalar function functions
41524190
4 unimplemented scalar function set functions
41534191
12 unimplemented aggregate function functions

bindings/test/values.test.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -221,13 +221,21 @@ suite('values', () => {
221221
});
222222
test('struct', () => {
223223
const int_type = duckdb.create_logical_type(duckdb.Type.INTEGER);
224-
const struct_type = duckdb.create_struct_type([int_type], ['a']);
224+
const varchar_type = duckdb.create_logical_type(duckdb.Type.VARCHAR);
225+
const struct_type = duckdb.create_struct_type([int_type, varchar_type], ['a', 'b']);
225226
const int32_value = duckdb.create_int32(42);
226-
const struct_value = duckdb.create_struct_value(struct_type, [int32_value]);
227+
const varchar_value = duckdb.create_varchar('duck');
228+
const struct_value = duckdb.create_struct_value(struct_type, [int32_value, varchar_value]);
227229
expectLogicalType(
228230
duckdb.get_value_type(struct_value),
229-
STRUCT(ENTRY('a', INTEGER))
231+
STRUCT(ENTRY('a', INTEGER), ENTRY('b', VARCHAR))
230232
);
233+
const struct_child_0 = duckdb.get_struct_child(struct_value, 0);
234+
expectLogicalType(duckdb.get_value_type(struct_child_0), INTEGER);
235+
expect(duckdb.get_int32(struct_child_0)).toBe(42);
236+
const struct_child_1 = duckdb.get_struct_child(struct_value, 1);
237+
expectLogicalType(duckdb.get_value_type(struct_child_1), VARCHAR);
238+
expect(duckdb.get_varchar(struct_child_1)).toBe('duck');
231239
});
232240
test('empty struct', () => {
233241
const struct_type = duckdb.create_struct_type([], []);
@@ -244,9 +252,17 @@ suite('values', () => {
244252
});
245253
test('list', () => {
246254
const int_type = duckdb.create_logical_type(duckdb.Type.INTEGER);
247-
const int32_value = duckdb.create_int32(42);
248-
const list_value = duckdb.create_list_value(int_type, [int32_value]);
255+
const int32_value_0 = duckdb.create_int32(42);
256+
const int32_value_1 = duckdb.create_int32(12345);
257+
const list_value = duckdb.create_list_value(int_type, [int32_value_0, int32_value_1]);
249258
expectLogicalType(duckdb.get_value_type(list_value), LIST(INTEGER));
259+
expect(duckdb.get_list_size(list_value)).toBe(2);
260+
const list_child_0 = duckdb.get_list_child(list_value, 0);
261+
expectLogicalType(duckdb.get_value_type(list_child_0), INTEGER);
262+
expect(duckdb.get_int32(list_child_0)).toBe(42);
263+
const list_child_1 = duckdb.get_list_child(list_value, 1);
264+
expectLogicalType(duckdb.get_value_type(list_child_1), INTEGER);
265+
expect(duckdb.get_int32(list_child_1)).toBe(12345);
250266
});
251267
test('empty list', () => {
252268
const int_type = duckdb.create_logical_type(duckdb.Type.INTEGER);

0 commit comments

Comments
 (0)