### Install dependencies with pnpm Source: https://github.com/duckdb/duckdb-node-neo/blob/main/README.md Install project dependencies using pnpm. ```bash pnpm install ``` -------------------------------- ### Get Basic Information Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Imports the default duckdb module and logs the DuckDB version and configuration option descriptions. ```TypeScript import duckdb from '@duckdb/node-api'; console.log(duckdb.version()); console.log(duckdb.configurationOptionDescriptions()); ``` -------------------------------- ### Create Instance Cache Explicitly Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Imports DuckDBInstanceCache and creates a new cache, then gets or creates an instance for a database file. ```TypeScript import { DuckDBInstanceCache } from '@duckdb/node-api'; const cache = new DuckDBInstanceCache(); const instance = await cache.getOrCreateInstance('my_duckdb.db'); ``` -------------------------------- ### Use startStreamThenRead helper Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Equivalent helper that combines starting a stream and reading the result, providing full cooperative multithreading. ```ts const reader = await connection.startStreamThenRead(sql); ``` -------------------------------- ### Extract and prepare multiple statements with extractStatements Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Extracts multiple SQL statements from a string, prepares each one, binds integer parameters, and runs them. The example uses a template with placeholders and binds values from an array. ```TypeScript const extractedStatements = await connection.extractStatements(` create or replace table numbers as from range(?); from numbers where range < ?; drop table numbers; `); const parameterValues = [10, 7]; const statementCount = extractedStatements.count; for (let stmtIndex = 0; stmtIndex < statementCount; stmtIndex++) { const prepared = await extractedStatements.prepare(stmtIndex); let parameterCount = prepared.parameterCount; for (let paramIndex = 1; paramIndex <= parameterCount; paramIndex++) { prepared.bindInteger(paramIndex, parameterValues.shift()); } const result = await prepared.run(); // ... } ``` -------------------------------- ### Use Instance Cache Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Uses the default instance cache to get or create an instance for a database file, preventing multiple instances from attaching the same database. ```TypeScript const instance = await DuckDBInstance.fromCache('my_duckdb.db'); ``` -------------------------------- ### Get result data in various forms Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Shows how to retrieve result data as rows, row objects, columns, and columns object. ```ts const reader = await connection.runAndReadAll( 'from range(3) select range::int as i, 10 + i as n' ); const rows = reader.getRows(); // [ [0, 10], [1, 11], [2, 12] ] const rowObjects = reader.getRowObjects(); // [ { i: 0, n: 10 }, { i: 1, n: 11 }, { i: 2, n: 12 } ] const columns = reader.getColumns(); // [ [0, 1, 2], [10, 11, 12] ] const columnsObject = reader.getColumnsObject(); // { i: [0, 1, 2], n: [10, 11, 12] } ``` -------------------------------- ### Get chunk data using various methods Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Shows how to retrieve chunk data as rows, row objects, columns, and column objects using chunk.getRows(), chunk.getRowObjects(), chunk.getColumns(), and chunk.getColumnsObject(). ```TypeScript const rows = chunk.getRows(); const rowObjects = chunk.getRowObjects(result.deduplicatedColumnNames()); const columns = chunk.getColumns(); const columnsObject = chunk.getColumnsObject(result.deduplicatedColumnNames()); ``` -------------------------------- ### DuckDBDataChunk.create with VARIANT causes native crash Source: https://github.com/duckdb/duckdb-node-neo/blob/main/tools/capi-v2/README.md JavaScript example showing that creating a chunk with a VARIANT column yields a null handle, leading to a native crash when appended. ```ts const chunk = DuckDBDataChunk.create([INTEGER, VARIANT]); // null handle, no error chunk.setRows([[5, null]]); // writes nothing appender.appendDataChunk(chunk); // native crash ``` -------------------------------- ### Convert JS values to DuckDB values with jsToDuckDBValue Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Shows how to use jsToDuckDBValue to convert plain JS values to DuckDB types, avoiding direct calls to special functions. Includes examples for TIMESTAMP_MS, DATE, and null. ```ts import { jsToDuckDBValue, DATE, TIMESTAMP_MS } from '@duckdb/node-api'; jsToDuckDBValue(new Date('2024-01-15T12:34:56.789Z'), TIMESTAMP_MS); // same as timestampMillisValue(1705322096789n) jsToDuckDBValue(new Date('2024-01-15T00:00:00.000Z'), DATE); // same as dateValue(19737) jsToDuckDBValue(null, DATE); // null, for any type ``` -------------------------------- ### Register table function my_range with bind, init, and main functions Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Registers a table function that generates a range of integers. The bindFunction sets the result column and bind data, initFunction sets init data, and mainFunction writes chunks until rowCount is zero. The example runs a query and expects rows [[0],[1],[2]]. ```TypeScript connection.registerTableFunction( DuckDBTableFunction.create({ name: 'my_range', parameterTypes: [INTEGER], bindFunction: (info) => { const count = info.getParameter(0) as number; info.addResultColumn('n', INTEGER); info.setBindData({ count }); }, initFunction: (info) => { info.setInitData({ nextRow: 0 }); }, mainFunction: (info, output) => { const { count } = info.bindData as { count: number }; const initData = info.initData as { nextRow: number }; const chunkSize = Math.min(2048, count - initData.nextRow); // Set the row count before writing: that is what sizes the // vectors. // A row count of zero reports that the scan is finished. output.rowCount = chunkSize; if (chunkSize > 0) { const column = output.getColumnVector(0); for (let i = 0; i < chunkSize; i++) { column.setItem(i, initData.nextRow + i); } column.flush(); initData.nextRow += chunkSize; } }, }) ); const reader = await connection.runAndReadAll('select * from my_range(3)'); const rows = reader.getRows(); // [ [ 0 ], [ 1 ], [ 2 ] ] ``` -------------------------------- ### Use JSTypeForTypeId to infer JS type by type id Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Shows how to use JSTypeForTypeId to get the JS type when you have a DuckDB type id. The example uses DuckDBTypeId.INTEGER and yields number. ```TypeScript type F = JSTypeForTypeId[DuckDBTypeId.INTEGER]; // number ``` -------------------------------- ### Build and run smoke_v2.c with the V2 preview library Source: https://github.com/duckdb/duckdb-node-neo/blob/main/tools/capi-v2/README.md Commands to fetch the C API headers and the 2.0 preview library, then build and run smoke_v2.c, which opens an in-memory database, runs a query, and reads a chunk back through V2. ```bash python3 tools/capi-v2/compare_api.py --fetch # pull duckdb.h + duckdb_v2.h from the branch python3 tools/capi-v2/compare_api.py # print the comparison report python3 tools/capi-v2/fetch_libduckdb_v2.py # pull the 2.0 preview library for this platform cd tools/capi-v2 && cc -std=c11 -I libduckdb-v2 smoke_v2.c -L libduckdb-v2 -lduckdb \ -Wl,-rpath,@loader_path/libduckdb-v2 -o smoke_v2 && ./smoke_v2 ``` -------------------------------- ### Ways to run SQL with connection and prepared statements Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Overview of the connection and prepared statement methods for running, streaming, and reading results. Includes optional values and types parameters, and notes that startThenRead methods materialize results fully. ```ts // Run to completion but don't yet retrieve any rows. // Optionally take values to bind to SQL parameters, // and (optionally) types of those parameters, // either as an array (for positional parameters), // or an object keyed by parameter name. const result = await connection.run(sql); const result = await connection.run(sql, values); const result = await connection.run(sql, values, types); // Run to completion but don't yet retrieve any rows. // Wrap in a DuckDBDataReader for convenient data retrieval. const reader = await connection.runAndRead(sql); const reader = await connection.runAndRead(sql, values); const reader = await connection.runAndRead(sql, values, types); // Run to completion, wrap in a reader, and read all rows. const reader = await connection.runAndReadAll(sql); const reader = await connection.runAndReadAll(sql, values); const reader = await connection.runAndReadAll(sql, values, types); // Run to completion, wrap in a reader, and read at least // the given number of rows. (Rows are read in chunks, so more than // the target may be read.) const reader = await connection.runAndReadUntil(sql, targetRowCount); const reader = await connection.runAndReadAll(sql, targetRowCount, values); const reader = await connection.runAndReadAll(sql, targetRowCount, values, types); // Create a streaming result and don't yet retrieve any rows. const result = await connection.stream(sql); const result = await connection.stream(sql, values); const result = await connection.stream(sql, values, types); // Create a streaming result and don't yet retrieve any rows. // Wrap in a DuckDBDataReader for convenient data retrieval. const reader = await connection.streamAndRead(sql); const reader = await connection.streamAndRead(sql, values); const reader = await connection.streamAndRead(sql, values, types); // Create a streaming result, wrap in a reader, and read all rows. const reader = await connection.streamAndReadAll(sql); const reader = await connection.streamAndReadAll(sql, values); const reader = await connection.streamAndReadAll(sql, values, types); // Create a streaming result, wrap in a reader, and read at least // the given number of rows. const reader = await connection.streamAndReadUntil(sql, targetRowCount); const reader = await connection.streamAndReadUntil(sql, targetRowCount, values); const reader = await connection.streamAndReadUntil( sql, targetRowCount, values, types ); // Prepared Statements // Prepare a possibly-parametered SQL statement to run later. const prepared = await connection.prepare(sql); // Bind values to the parameters. prepared.bind(values); prepared.bind(values, types); // Run the prepared statement. These mirror the methods on the // connection. const result = prepared.run(); const reader = prepared.runAndRead(); const reader = prepared.runAndReadAll(); const reader = prepared.runAndReadUntil(targetRowCount); const result = prepared.stream(); const reader = prepared.streamAndRead(); const reader = prepared.streamAndReadAll(); const reader = prepared.streamAndReadUntil(targetRowCount); // Pending Results // Create a pending result. const pending = await connection.start(sql); const pending = await connection.start(sql, values); const pending = await connection.start(sql, values, types); // The methods beginning with "startThenRead" provide some, but not // full, cooperative multithreading. They use pending results to split // processing into short tasks, but they fully materialize the result, // which can take some time (and memory). For full cooperative // multithreading, see the "startStreamThenRead" methods below. const reader = await connection.startThenRead(sql); const reader = await connection.startThenRead(sql, values); const reader = await connection.startThenRead(sql, values, types); ``` -------------------------------- ### getColumns Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Gets all columns from a chunk. ```APIDOC ## getColumns ### Description Gets all columns from the chunk as an array of arrays. ### Method getColumns() ### Parameters None ### Returns - **columns** (any[][]) - The columns of the chunk. ### Example ```ts const columns = chunk.getColumns(); ``` ``` -------------------------------- ### Build and test bindings Source: https://github.com/duckdb/duckdb-node-neo/blob/main/README.md Build and test the bindings package. ```bash cd bindings pnpm run build pnpm test ``` -------------------------------- ### Create File-Backed Instance Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Creates an instance that reads from and writes to a database file, creating it if needed. ```TypeScript const instance = await DuckDBInstance.create('my_duckdb.db'); ``` -------------------------------- ### getRows Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Gets all rows from a chunk. ```APIDOC ## getRows ### Description Gets all rows from the chunk as an array of arrays. ### Method getRows() ### Parameters None ### Returns - **rows** (any[][]) - The rows of the chunk. ### Example ```ts const rows = chunk.getRows(); ``` ``` -------------------------------- ### Create environment and open database Source: https://github.com/duckdb/duckdb-node-neo/blob/main/tools/capi-v2/README.md Shows the new required root: a duckdb_v2_environment must be created and passed to duckdb_v2_open. An environment is mandatory, subsumes duckdb_instance_cache, and destroying it while a database is open returns ERROR_RESOURCE_IN_USE. ```c duckdb_v2_create_environment(&env, &err); duckdb_v2_open(env, path, options, option_count, &db, &err); ``` -------------------------------- ### getItem Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Gets a value from a column vector. ```APIDOC ## getItem ### Description Gets the value at the given index from the column vector. ### Method getItem(itemIndex) ### Parameters - **itemIndex** (number) - Required - The zero-based index of the item. ### Returns - **value** (any) - The value at the given index. ### Example ```ts const value = columnVector.getItem(itemIndex); ``` ``` -------------------------------- ### getColumnVector Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Gets a column vector from a chunk. ```APIDOC ## getColumnVector ### Description Gets the column vector at the given index from the chunk. ### Method getColumnVector(columnIndex) ### Parameters - **columnIndex** (number) - Required - The zero-based index of the column. ### Returns - **columnVector** (ColumnVector) - The column vector. ### Example ```ts const columnVector = chunk.getColumnVector(columnIndex); ``` ``` -------------------------------- ### Create Instance with Configuration Options Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Creates an instance with configuration options, here setting the 'threads' option to '4'. ```TypeScript const instance = await DuckDBInstance.create('my_duckdb.db', { threads: '4' }); ``` -------------------------------- ### getColumnsObject Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Gets columns as an object from a chunk. ```APIDOC ## getColumnsObject ### Description Gets all columns from the chunk as an object, using the provided column names. ### Method getColumnsObject(columnNames) ### Parameters - **columnNames** (string[]) - Required - The column names to use as keys. ### Returns - **columnsObject** (object) - The columns as an object. ### Example ```ts const columnsObject = chunk.getColumnsObject(result.deduplicatedColumnNames()); ``` ``` -------------------------------- ### getRowObjects Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Gets rows as objects from a chunk. ```APIDOC ## getRowObjects ### Description Gets all rows from the chunk as an array of objects, using the provided column names. ### Method getRowObjects(columnNames) ### Parameters - **columnNames** (string[]) - Required - The column names to use as keys. ### Returns - **rowObjects** (object[]) - The rows as objects. ### Example ```ts const rowObjects = chunk.getRowObjects(result.deduplicatedColumnNames()); ``` ``` -------------------------------- ### Build and run chunk_probe and chunk_probe_v2 Source: https://github.com/duckdb/duckdb-node-neo/blob/main/tools/capi-v2/README.md Build and run the chunk_probe pair: chunk_probe.c against the current library and chunk_probe_v2.c against the preview library, to test whether a data chunk accepts a VARIANT column on each surface. ```bash cd tools/capi-v2 && cc -std=c11 -I ../../bindings/libduckdb chunk_probe.c \ -L ../../bindings/libduckdb -lduckdb -Wl,-rpath,@loader_path/../../bindings/libduckdb \ -o chunk_probe && ./chunk_probe cd tools/capi-v2 && cc -std=c11 -I libduckdb-v2 chunk_probe_v2.c -L libduckdb-v2 -lduckdb \ -Wl,-rpath,@loader_path/libduckdb-v2 -o chunk_probe_v2 && ./chunk_probe_v2 ``` -------------------------------- ### Inspect result metadata Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Get column names and types from a result. ```ts const columnNames = result.columnNames(); const columnTypes = result.columnTypes(); ``` -------------------------------- ### Build and test API Source: https://github.com/duckdb/duckdb-node-neo/blob/main/README.md Build and test the API package. ```bash cd api pnpm run build pnpm test ``` -------------------------------- ### Create Instance - Import Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Imports the DuckDBInstance class for creating explicit instances. ```TypeScript import { DuckDBInstance } from '@duckdb/node-api'; ``` -------------------------------- ### connection.start Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Creates a pending result for a SQL statement. ```APIDOC ## `connection.start(sql, values?, types?)` ### Description Creates a pending result for the SQL statement. Optionally binds values and types. ### Parameters - `sql` (string) - Required - The SQL statement to execute. - `values` (array or object) - Optional - Values to bind to SQL parameters. - `types` (array or object) - Optional - Types of the bound parameters. ### Returns - `DuckDBPendingResult` - A pending result. ### Example ```ts const pending = await connection.start(sql); const pending = await connection.start(sql, values); const pending = await connection.start(sql, values, types); ``` ``` -------------------------------- ### Run API benchmarks Source: https://github.com/duckdb/duckdb-node-neo/blob/main/README.md Run API benchmarks. ```bash cd api pnpm bench ``` -------------------------------- ### Connect to Instance Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Creates a connection from an existing instance. ```TypeScript const connection = await instance.connect(); ``` -------------------------------- ### Get chunk data one value at a time Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Shows how to iterate over column vectors and items to retrieve each value individually using chunk.getColumnVector() and columnVector.getItem(). ```TypeScript const columns = []; const columnCount = chunk.columnCount; for (let columnIndex = 0; columnIndex < columnCount; columnIndex++) { const columnValues = []; const columnVector = chunk.getColumnVector(columnIndex); const itemCount = columnVector.itemCount; for (let itemIndex = 0; itemIndex < itemCount; itemIndex++) { const value = columnVector.getItem(itemIndex); columnValues.push(value); } columns.push(columnValues); } ``` -------------------------------- ### Ways to run SQL in DuckDB Node.js API Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Shows the various ways to run SQL in the DuckDB Node.js API, including startThenReadAll, startThenReadUntil, startStream, startStreamThenRead variants, and pending result handling from prepared statements. The startStreamThenRead methods are recommended for cooperative multithreading. ```javascript const reader = await connection.startThenReadAll(sql); const reader = await connection.startThenReadAll(sql, values); const reader = await connection.startThenReadAll(sql, values, types); const reader = await connection.startThenReadUntil(sql, targetRowCount); const reader = await connection.startThenReadUntil(sql, targetRowCount, values); const reader = await connection.startThenReadUntil( sql, targetRowCount, values, types ); // Create a pending, streaming result. const pending = await connection.startStream(sql); const pending = await connection.startStream(sql, values); const pending = await connection.startStream(sql, values, types); // The methods beginning with "startStreamThenRead" are the best options // for cooperative multithreading. By creating a streaming result, they // prevent the result from being fully materialized. By using a pending // result, they split processing into short tasks, preventing any single // task from occupying a thread for too long. const reader = await connection.startStreamThenRead(sql); const reader = await connection.startStreamThenRead(sql, values); const reader = await connection.startStreamThenRead(sql, values, types); const reader = await connection.startStreamThenReadAll(sql); const reader = await connection.startStreamThenReadAll(sql, values); const reader = await connection.startStreamThenReadAll(sql, values, types); const reader = await connection.startStreamThenReadUntil(sql, targetRowCount); const reader = await connection.startStreamThenReadUntil( sql, targetRowCount, values ); const reader = await connection.startStreamThenReadUntil( sql, targetRowCount, values, types); // Create a pending result from a prepared statement. const pending = await prepared.start(); const pending = await prepared.startStream(); while (pending.runTask() !== DuckDBPendingResultState.RESULT_READY) { // optionally sleep or do other work between tasks } // Or, run tasks (cooperatively) until the result is ready. await pending.runAllTasks(); // Retrieve the result. If not yet READY, will run until it is. const result = await pending.getResult(); const reader = await pending.read(); const reader = await pending.readAll(); const reader = await pending.readUntil(targetRowCount); ``` -------------------------------- ### prepared.runAndRead Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Runs a prepared statement and returns a reader. ```APIDOC ## `prepared.runAndRead()` ### Description Runs the prepared statement to completion and wraps the result in a `DuckDBDataReader`. ### Returns - `DuckDBDataReader` - A reader for retrieving rows. ### Example ```ts const reader = prepared.runAndRead(); ``` ``` -------------------------------- ### Serialize column names and types to JSON Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Shows how to use reader.columnNamesAndTypesJson() and reader.columnNameAndTypeObjectsJson() to get column metadata as JSON. The output includes typeId and nested type information for arrays, structs, maps, and unions. ```TypeScript const columnNamesAndTypes = reader.columnNamesAndTypesJson(); // { // "columnNames": [ // "int_array", // "struct", // "map", // "union" // ], // "columnTypes": [ // { // "typeId": 24, // "valueType": { // "typeId": 4 // } // }, // { // "typeId": 25, // "entryNames": [ // "a", // "b" // ], // "entryTypes": [ // { // "typeId": 4 // }, // { // "typeId": 17 // } // ] // }, // { // "typeId": 26, // "keyType": { // "typeId": 17 // }, // "valueType": { // "typeId": 17 // } // }, // { // "typeId": 28, // "memberTags": [ // "name", // "age" // ], // "memberTypes": [ // { // "typeId": 17 // }, // { // "typeId": 3 // } // ] // } // ] // } const columnNameAndTypeObjects = reader.columnNameAndTypeObjectsJson(); // [ // { // "columnName": "int_array", // "columnType": { // "typeId": 24, // "valueType": { // "typeId": 4 // } // } // }, // { // "columnName": "struct", // "columnType": { // "typeId": 25, // "entryNames": [ // "a", // "b" // ], // "entryTypes": [ // { // "typeId": 4 // }, // { // "typeId": 17 // } // ] // } // }, // { // "columnName": "map", // "columnType": { // "typeId": 26, // "keyType": { // "typeId": 17 // }, // "valueType": { // "typeId": 17 // } // } // }, // { // "columnName": "union", // "columnType": { // "typeId": 28, // "memberTags": [ // "name", // "age" // ], // "memberTypes": [ // { // "typeId": 17 // }, // { // "typeId": 3 // } // ] // } // } // ] ``` -------------------------------- ### connection.prepare Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Prepares a SQL statement for later execution. ```APIDOC ## `connection.prepare(sql)` ### Description Prepares a possibly-parameterized SQL statement to run later. ### Parameters - `sql` (string) - Required - The SQL statement to prepare. ### Returns - `DuckDBPreparedStatement` - The prepared statement. ### Example ```ts const prepared = await connection.prepare(sql); ``` ``` -------------------------------- ### Connect with Default Instance Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Creates a DuckDBConnection using the default instance. This is the simplest way to connect. ```TypeScript import { DuckDBConnection } from '@duckdb/node-api'; const connection = await DuckDBConnection.create(); ``` -------------------------------- ### Register scalar function my_add with DuckDBScalarFunction Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Registers a scalar function that adds two integers. The mainFunction reads input vectors and writes the sum to the output. The example runs a query and expects rows [[5]]. ```TypeScript 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 ] ] ``` -------------------------------- ### chunk_probe_v2.c output: V2 accepts VARIANT columns Source: https://github.com/duckdb/duckdb-node-neo/blob/main/tools/capi-v2/README.md Output from chunk_probe_v2.c showing that V2's duckdb_v2_data_chunk_create and duckdb_v2_column_data_collection_create_with_connection accept VARIANT columns. ```text [INTEGER] -> code=0 chunk=non-NULL columns=1 [VARIANT] -> code=0 chunk=non-NULL columns=1 [INTEGER, VARIANT] -> code=0 chunk=non-NULL columns=2 column data collection: [INTEGER, VARIANT] -> code=0 collection=non-NULL ``` -------------------------------- ### Set timezone offset for TIMESTAMP_TZ string conversion Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Shows how to set the static `timezoneOffsetInMinutes` property on `DuckDBTimestampTZValue` to control the string representation of TIMESTAMP_TZ values. The default is the local timezone offset at process start. The offset is distinct from DuckDB's `TimeZone` setting. ```typescript DuckDBTimestampTZValue.timezoneOffsetInMinutes = -8 * 60; const pst = DuckDBTimestampTZValue.Epoch.toString(); // 1969-12-31 16:00:00-08 DuckDBTimestampTZValue.timezoneOffsetInMinutes = +1 * 60; const cet = DuckDBTimestampTZValue.Epoch.toString(); // 1970-01-01 01:00:00+01 ``` -------------------------------- ### Retrieve result data from a DuckDB reader Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md This snippet shows how to retrieve result data from a DuckDB reader. First, asynchronously read rows using `readAll()` or `readUntil(targetRowCount)`, then synchronously access the data using the various `get*` methods. Individual values can be read directly with `reader.value(columnIndex, rowIndex)`. ```typescript // From a reader // First, (asynchronously) read some rows: await reader.readAll(); // or: await reader.readUntil(targetRowCount); // Then, (synchronously) get result data for the rows read: const columns = reader.getColumns(); const columnsJS = reader.getColumnsJS(); const columnsJson = reader.getColumnsJson(); const columnsObject = reader.getColumnsObject(); const columnsObjectJS = reader.getColumnsObjectJS(); const columnsObjectJson = reader.getColumnsObjectJson(); const rows = reader.getRows(); const rowsJS = reader.getRowsJS(); const rowsJson = reader.getRowsJson(); const rowObjects = reader.getRowObjects(); const rowObjectsJS = reader.getRowObjectsJS(); const rowObjectsJson = reader.getRowObjectsJson(); // Individual values can also be read directly: const value = reader.value(columnIndex, rowIndex); ``` -------------------------------- ### connection.startThenRead Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Creates a pending result and reads the result with cooperative multithreading. ```APIDOC ## `connection.startThenRead(sql, values?, types?)` ### Description Creates a pending result and then reads the result, providing some cooperative multithreading. The result is fully materialized, which can take time and memory. Optionally binds values and types. ### Parameters - `sql` (string) - Required - The SQL statement to execute. - `values` (array or object) - Optional - Values to bind to SQL parameters. - `types` (array or object) - Optional - Types of the bound parameters. ### Returns - `DuckDBDataReader` - A reader for retrieving rows. ### Example ```ts const reader = await connection.startThenRead(sql); const reader = await connection.startThenRead(sql, values); const reader = await connection.startThenRead(sql, values, types); ``` ``` -------------------------------- ### Register scalar function my_counter with initFunction and volatile Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Registers a scalar function that uses an initFunction to set per-thread state and a mainFunction that increments it. Marking the function volatile is required because the result depends on init state; otherwise DuckDB may evaluate it only once. The example runs a query and expects rows [[0],[1],[2]]. ```TypeScript connection.registerScalarFunction( DuckDBScalarFunction.create({ name: 'my_counter', initFunction: (initInfo) => { initInfo.setState({ next: 0 }); }, mainFunction: (functionInfo, input, output) => { const state = functionInfo.state as { next: number }; for (let rowIndex = 0; rowIndex < input.rowCount; rowIndex++) { output.setItem(rowIndex, state.next++); } output.flush(); }, returnType: INTEGER, volatile: true, }) ); const reader = await connection.runAndReadAll( 'select my_counter() from range(3)' ); const rows = reader.getRows(); // [ [ 0 ], [ 1 ], [ 2 ] ] ``` -------------------------------- ### Parameterize SQL with Positional Parameters Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Prepares a SQL statement with positional parameters ($1, $2, $3), binds values with explicit types, and runs it. Includes a commented alternative using type inference. ```TypeScript const prepared = await connection.prepare('select $1, $2, $3'); prepared.bindVarchar(1, 'duck'); prepared.bindInteger(2, 42); prepared.bindList(3, listValue([10, 11, 12]), LIST(INTEGER)); // OR, with type inference: prepared.bindList(3, [10, 11, 12]); const result = await prepared.run(); ``` -------------------------------- ### connection.runAndReadAll Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Runs a query and reads all data into memory. Returns a reader that can be used to access the result data. ```APIDOC ## connection.runAndReadAll ### Description Runs a query and reads all data into memory. Returns a reader that can be used to access the result data. ### Method Function ### Signature `runAndReadAll(query: string): Promise` ### Parameters - **query** (string) - Required - The SQL query to execute. ### Returns - **Promise** - A reader object with methods to retrieve result data. ### Example ```ts const reader = await connection.runAndReadAll('from test_all_types()'); const rows = reader.getRows(); // OR: const columns = reader.getColumns(); ``` ``` -------------------------------- ### Infer JS types from DuckDB types using JSTypeFor and JsonTypeFor Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Shows how to use the type-level mappings JSTypeFor and JsonTypeFor to get the JavaScript type produced by getRowsJS and the Json methods for given DuckDB types. Note that 64-bit integers, temporal types, DECIMAL, BLOB, BIT, and GEOMETRY render as strings in JSON, and FLOAT/DOUBLE widen to number | string. ```TypeScript import { JSTypeFor, JsonTypeFor, DuckDBBigIntType, DuckDBIntegerType, DuckDBTimestampTZType, } from '@duckdb/node-api'; type A = JSTypeFor; // number type B = JSTypeFor; // bigint type C = JSTypeFor; // Date type D = JsonTypeFor; // string type E = JsonTypeFor; // string ``` -------------------------------- ### prepared.runAndReadUntil Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Runs a prepared statement and reads at least a specified number of rows. ```APIDOC ## `prepared.runAndReadUntil(targetRowCount)` ### Description Runs the prepared statement to completion, wraps the result in a reader, and reads at least the given number of rows. ### Parameters - `targetRowCount` (number) - Required - The minimum number of rows to read. ### Returns - `DuckDBDataReader` - A reader that has read at least the target number of rows. ### Example ```ts const reader = prepared.runAndReadUntil(targetRowCount); ``` ``` -------------------------------- ### prepared.runAndReadAll Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Runs a prepared statement and reads all rows. ```APIDOC ## `prepared.runAndReadAll()` ### Description Runs the prepared statement to completion, wraps the result in a reader, and reads all rows. ### Returns - `DuckDBDataReader` - A reader that has read all rows. ### Example ```ts const reader = prepared.runAndReadAll(); ``` ``` -------------------------------- ### prepared.run Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Runs a prepared statement to completion without retrieving rows. ```APIDOC ## `prepared.run()` ### Description Runs the prepared statement to completion without retrieving rows. ### Returns - `DuckDBResult` - The result of the query. ### Example ```ts const result = prepared.run(); ``` ``` -------------------------------- ### Run SQL Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Runs a SQL query on the connection and returns the result. ```TypeScript const result = await connection.run('from test_all_types()'); ``` -------------------------------- ### connection.runAndRead Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Runs a SQL statement to completion and returns a reader for data retrieval. ```APIDOC ## `connection.runAndRead(sql, values?, types?)` ### Description Runs the SQL statement to completion and wraps the result in a `DuckDBDataReader` for convenient data retrieval. Optionally binds values and types. ### Parameters - `sql` (string) - Required - The SQL statement to execute. - `values` (array or object) - Optional - Values to bind to SQL parameters. - `types` (array or object) - Optional - Types of the bound parameters. ### Returns - `DuckDBDataReader` - A reader for retrieving rows from the result. ### Example ```ts const reader = await connection.runAndRead(sql); const reader = await connection.runAndRead(sql, values); const reader = await connection.runAndRead(sql, values, types); ``` ``` -------------------------------- ### Fetch all chunks from a result Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Shows how to fetch all chunks at once using result.fetchAllChunks(). ```TypeScript const chunks = await result.fetchAllChunks(); ``` -------------------------------- ### chunk_probe.c output: VARIANT chunk returns null handle Source: https://github.com/duckdb/duckdb-node-neo/blob/main/tools/capi-v2/README.md Output from chunk_probe.c showing that duckdb_create_data_chunk returns a null handle for VARIANT columns, while a zero-column chunk is valid. ```text [INTEGER] handle=non-NULL columns=1 [VARIANT] handle=NULL [INTEGER, VARIANT] handle=NULL [] (zero types) handle=non-NULL columns=0 ``` -------------------------------- ### Run and read all data Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Runs a query and reads all data, returning rows or columns. ```ts const reader = await connection.runAndReadAll('from test_all_types()'); const rows = reader.getRows(); // OR: const columns = reader.getColumns(); ``` -------------------------------- ### connection.startStreamThenRead Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Creates a streaming pending result and reads the result with full cooperative multithreading. ```APIDOC ## `connection.startStreamThenRead(sql)` ### Description Creates a streaming pending result and reads the result, providing full cooperative multithreading. ### Parameters - `sql` (string) - Required - The SQL statement to execute. ### Returns - `DuckDBDataReader` - A reader for retrieving rows. ### Example ```ts const reader = await connection.startStreamThenRead(sql); ``` ``` -------------------------------- ### Work with DuckDB chunks Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md This snippet shows how to work with DuckDB chunks. Fetch chunks from a result using `fetchChunk()` or `fetchAllChunks()`, then retrieve data, visit values, or convert values using a `DuckDBValueConverter`. The reader abstracts these low-level manipulations and is recommended for most cases. ```typescript // Using chunks // If desired, one or more chunks can be fetched from a result: const chunk = await result.fetchChunk(); const chunks = await result.fetchAllChunks(); // And then data can be retrieved from each chunk: const columnValues = chunk.getColumnValues(columnIndex); const columns = chunk.getColumns(); const rowValues = chunk.getRowValues(rowIndex); const rows = chunk.getRows(); // Or, values can be visited: chunk.visitColumnValues(columnIndex, (value, rowIndex, columnIndex, type) => { /* ... */ } ); chunk.visitColumns((column, columnIndex, type) => { /* ... */ }); chunk.visitColumnMajor( (value, rowIndex, columnIndex, type) => { /* ... */ } ); chunk.visitRowValues(rowIndex, (value, rowIndex, columnIndex, type) => { /* ... */ } ); chunk.visitRows((row, rowIndex) => { /* ... */ }); chunk.visitRowMajor( (value, rowIndex, columnIndex, type) => { /* ... */ } ); // Or converted: // The `converter` argument implements `DuckDBValueConverter`, // which has the single method convertValue(value, type). const columnValues = chunk.convertColumnValues(columnIndex, converter); const columns = chunk.convertColumns(converter); const rowValues = chunk.convertRowValues(rowIndex, converter); const rows = chunk.convertRows(converter); // The reader abstracts these low-level chunk manipulations // and is recommended for most cases. ``` -------------------------------- ### Append a data chunk with DuckDBDataChunk Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Demonstrates appending a data chunk to a table. The chunk is created with `DuckDBDataChunk.create` and filled using `setColumns` or the commented-out `setRows` alternative. ```ts await connection.run( `create or replace table target_table(i integer, v varchar)` ); const appender = await connection.createAppender('target_table'); const chunk = DuckDBDataChunk.create([INTEGER, VARCHAR]); chunk.setColumns([ [42, 123, 17], ['duck', 'mallad', 'goose'], ]); // OR: // chunk.setRows([ // [42, 'duck'], // [123, 'mallard'], // [17, 'goose'], // ]); appender.appendDataChunk(chunk); appender.flushSync(); ``` -------------------------------- ### DuckDB Node API - Running SQL and Pending Results Source: https://github.com/duckdb/duckdb-node-neo/blob/main/api/pkgs/@duckdb/node-api/README.md Documentation for the DuckDB Node API methods for running SQL queries and managing pending results. ```APIDOC ## startThenReadAll ### Description Executes a SQL query and reads all results into a reader. Accepts optional parameters and types. ### Method startThenReadAll ### Parameters - **sql** (string) - Required - The SQL query to execute. - **values** (array) - Optional - Parameter values for the query. - **types** (array) - Optional - Type information for the parameters. ### Returns - **reader** - A reader object containing the query results. ## startThenReadUntil ### Description Executes a SQL query and reads results until a target row count is reached. Accepts optional parameters and types. ### Method startThenReadUntil ### Parameters - **sql** (string) - Required - The SQL query to execute. - **targetRowCount** (number) - Required - The number of rows to read. - **values** (array) - Optional - Parameter values for the query. - **types** (array) - Optional - Type information for the parameters. ### Returns - **reader** - A reader object containing the query results. ## startStream ### Description Creates a pending, streaming result for a SQL query. Accepts optional parameters and types. ### Method startStream ### Parameters - **sql** (string) - Required - The SQL query to execute. - **values** (array) - Optional - Parameter values for the query. - **types** (array) - Optional - Type information for the parameters. ### Returns - **pending** - A pending result object for streaming. ## startStreamThenRead ### Description Creates a streaming result and reads from it. Best for cooperative multithreading. Accepts optional parameters and types. ### Method startStreamThenRead ### Parameters - **sql** (string) - Required - The SQL query to execute. - **values** (array) - Optional - Parameter values for the query. - **types** (array) - Optional - Type information for the parameters. ### Returns - **reader** - A reader object containing the query results. ## startStreamThenReadAll ### Description Creates a streaming result and reads all results. Accepts optional parameters and types. ### Method startStreamThenReadAll ### Parameters - **sql** (string) - Required - The SQL query to execute. - **values** (array) - Optional - Parameter values for the query. - **types** (array) - Optional - Type information for the parameters. ### Returns - **reader** - A reader object containing the query results. ## startStreamThenReadUntil ### Description Creates a streaming result and reads until a target row count. Accepts optional parameters and types. ### Method startStreamThenReadUntil ### Parameters - **sql** (string) - Required - The SQL query to execute. - **targetRowCount** (number) - Required - The number of rows to read. - **values** (array) - Optional - Parameter values for the query. - **types** (array) - Optional - Type information for the parameters. ### Returns - **reader** - A reader object containing the query results. ## prepared.start ### Description Creates a pending result from a prepared statement. ### Method start ### Parameters None. ### Returns - **pending** - A pending result object. ## prepared.startStream ### Description Creates a pending streaming result from a prepared statement. ### Method startStream ### Parameters None. ### Returns - **pending** - A pending result object for streaming. ## pending.runTask ### Description Runs a single task of the pending result. Returns the state of the result. ### Method runTask ### Parameters None. ### Returns - **DuckDBPendingResultState** - The state of the pending result (e.g., RESULT_READY). ## pending.runAllTasks ### Description Runs tasks cooperatively until the result is ready. ### Method runAllTasks ### Parameters None. ### Returns - **Promise** - Resolves when all tasks are complete. ## pending.getResult ### Description Retrieves the result. If not yet ready, runs until it is. ### Method getResult ### Parameters None. ### Returns - **result** - The result object. ## pending.read ### Description Reads results from the pending result. ### Method read ### Parameters None. ### Returns - **reader** - A reader object containing the query results. ## pending.readAll ### Description Reads all results from the pending result. ### Method readAll ### Parameters None. ### Returns - **reader** - A reader object containing all query results. ## pending.readUntil ### Description Reads results from the pending result until a target row count is reached. ### Method readUntil ### Parameters - **targetRowCount** (number) - Required - The number of rows to read. ### Returns - **reader** - A reader object containing the query results. ```