Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 27 additions & 8 deletions api/pkgs/@duckdb/node-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,7 @@ available separately as [@duckdb/node-bindings](https://www.npmjs.com/package/@d

### Roadmap

Some features are not yet complete:
* Appending default values row-by-row
* User-defined types & functions
* Profiling info
* Table description
* APIs for Arrow

See the [issues list on GitHub](https://github.com/duckdb/duckdb-node-neo/issues)
Some features are not yet complete. See the [issues list on GitHub](https://github.com/duckdb/duckdb-node-neo/issues)
for the most up-to-date roadmap.

### Supported Platforms
Expand Down Expand Up @@ -883,6 +876,32 @@ appender.flushSync();

See "Specifying Values" above for how to supply values to the appender.

### Scalar Functions

```ts
connection.registerScalarFunction(
DuckDBScalarFunction.create({
name: 'my_add',
mainFunction: (info, input, output) => {
const v0 = input.getColumnVector(0);
const v1 = input.getColumnVector(1);
for (let rowIndex = 0; rowIndex < input.rowCount; rowIndex++) {
output.setItem(
rowIndex,
v0.getItem(rowIndex) + v1.getItem(rowIndex)
);
}
output.flush();
},
returnType: INTEGER,
parameterTypes: [INTEGER, INTEGER],
})
);
const reader = await connection.runAndReadAll('select my_add(2, 3)');
const rows = reader.getRows();
// [ [ 5 ] ]
```

### Extract Statements

```ts
Expand Down
7 changes: 7 additions & 0 deletions api/src/DuckDBConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { DuckDBPreparedStatement } from './DuckDBPreparedStatement';
import { DuckDBPreparedStatementWeakRefCollection } from './DuckDBPreparedStatementWeakRefCollection';
import { DuckDBResult } from './DuckDBResult';
import { DuckDBResultReader } from './DuckDBResultReader';
import { DuckDBScalarFunction } from './DuckDBScalarFunction';
import { DuckDBType } from './DuckDBType';
import { DuckDBValue } from './values';

Expand Down Expand Up @@ -220,4 +221,10 @@ export class DuckDBConnection {
)
);
}
public registerScalarFunction(scalarFunction: DuckDBScalarFunction) {
duckdb.register_scalar_function(
this.connection,
scalarFunction.scalar_function
);
}
}
14 changes: 14 additions & 0 deletions api/src/DuckDBFunctionInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import duckdb from '@duckdb/node-bindings';

export class DuckDBFunctionInfo {
private readonly function_info: duckdb.FunctionInfo;
constructor(function_info: duckdb.FunctionInfo) {
this.function_info = function_info;
}
public getExtraInfo(): object | undefined {
return duckdb.scalar_function_get_extra_info(this.function_info);
}
public setError(error: string) {
duckdb.scalar_function_set_error(this.function_info, error);
}
}
118 changes: 118 additions & 0 deletions api/src/DuckDBScalarFunction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import duckdb from '@duckdb/node-bindings';
import { DuckDBDataChunk } from './DuckDBDataChunk';
import { DuckDBFunctionInfo } from './DuckDBFunctionInfo';
import { DuckDBType } from './DuckDBType';
import { DuckDBVector } from './DuckDBVector';

export type DuckDBScalarMainFunction = (
functionInfo: DuckDBFunctionInfo,
inputDataChunk: DuckDBDataChunk,
outputVector: DuckDBVector
) => void;

export class DuckDBScalarFunction {
readonly scalar_function: duckdb.ScalarFunction;

public constructor() {
this.scalar_function = duckdb.create_scalar_function();
}

public static create({
name,
mainFunction,
returnType,
parameterTypes,
varArgsType,
specialHandling,
volatile,
extraInfo,
}: {
name: string;
mainFunction: DuckDBScalarMainFunction;
returnType: DuckDBType;
parameterTypes?: readonly DuckDBType[];
varArgsType?: DuckDBType;
specialHandling?: boolean;
volatile?: boolean;
extraInfo?: object;
}): DuckDBScalarFunction {
const scalarFunction = new DuckDBScalarFunction();
scalarFunction.setName(name);
scalarFunction.setMainFunction(mainFunction);
scalarFunction.setReturnType(returnType);
if (parameterTypes) {
for (const parameterType of parameterTypes) {
scalarFunction.addParameter(parameterType);
}
}
if (varArgsType) {
scalarFunction.setVarArgs(varArgsType);
}
if (specialHandling) {
scalarFunction.setSpecialHandling();
}
if (volatile) {
scalarFunction.setVolatile();
}
if (extraInfo) {
scalarFunction.setExtraInfo(extraInfo);
}
return scalarFunction;
}

public destroySync() {
duckdb.destroy_scalar_function_sync(this.scalar_function);
}

public setName(name: string) {
duckdb.scalar_function_set_name(this.scalar_function, name);
}

public setMainFunction(mainFunction: DuckDBScalarMainFunction) {
duckdb.scalar_function_set_function(
this.scalar_function,
(info, input, output) => {
const functionInfo = new DuckDBFunctionInfo(info);
const inputDataChunk = new DuckDBDataChunk(input);
const outputVector = DuckDBVector.create(
output,
inputDataChunk.rowCount
);
mainFunction(functionInfo, inputDataChunk, outputVector);
}
);
}

public setReturnType(returnType: DuckDBType) {
duckdb.scalar_function_set_return_type(
this.scalar_function,
returnType.toLogicalType().logical_type
);
}

public addParameter(parameterType: DuckDBType) {
duckdb.scalar_function_add_parameter(
this.scalar_function,
parameterType.toLogicalType().logical_type
);
}

public setVarArgs(varArgsType: DuckDBType) {
duckdb.scalar_function_set_varargs(
this.scalar_function,
varArgsType.toLogicalType().logical_type
);
}

public setSpecialHandling() {
duckdb.scalar_function_set_special_handling(this.scalar_function);
}

public setVolatile() {
duckdb.scalar_function_set_volatile(this.scalar_function);
}

public setExtraInfo(extraInfo: object) {
duckdb.scalar_function_set_extra_info(this.scalar_function, extraInfo);
}
}
3 changes: 3 additions & 0 deletions api/src/duckdb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export * from './DuckDBAppender';
export * from './DuckDBConnection';
export * from './DuckDBDataChunk';
export * from './DuckDBExtractedStatements';
export * from './DuckDBFunctionInfo';
export * from './DuckDBInstance';
export * from './DuckDBInstanceCache';
export * from './DuckDBLogicalType';
Expand All @@ -18,6 +19,8 @@ export * from './DuckDBPendingResult';
export * from './DuckDBPreparedStatement';
export * from './DuckDBPreparedStatementCollection';
export * from './DuckDBResult';
export * from './DuckDBResultReader';
export * from './DuckDBScalarFunction';
export * from './DuckDBType';
export * from './DuckDBTypeId';
export * from './DuckDBValueConverter';
Expand Down
Loading
Loading