diff --git a/.gitignore b/.gitignore index 10e134a..c2dd856 100644 --- a/.gitignore +++ b/.gitignore @@ -63,3 +63,11 @@ Release/ *.zip postgresql.log .vscode/ + +# DuckDB related files (should be downloaded, not committed) +duckdb.h +duckdb.hpp +libduckdb*.so +libduckdb*.dylib +libduckdb*.dll +CLAUDE.md diff --git a/Dockerfile b/Dockerfile index 5509bd3..0060236 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ FROM postgres:${POSTGRES_VERSION} AS builder # Set default values for build arguments ARG POSTGRES_VERSION=17 -ARG DUCKDB_VERSION=1.1.3 +ARG DUCKDB_VERSION=1.4.1 # Install build dependencies RUN apt-get update && apt-get install -y \ diff --git a/Makefile b/Makefile index bd72cda..6060e4d 100644 --- a/Makefile +++ b/Makefile @@ -9,22 +9,12 @@ # ########################################################################## -# Check if DUCKDB_VERSION is defined -ifeq ($(DUCKDB_VERSION),) - # Try to read from .duckdb_version file - -include .duckdb_version - - # If still not defined, try to get from environment - ifndef DUCKDB_VERSION - $(error DUCKDB_VERSION is not set. Please set it using: make DUCKDB_VERSION=x.x.x or create a .duckdb_version file) - endif -endif MODULE_big = duckdb_fdw OBJS = connection.o option.o deparse.o sqlite_query.o duckdb_fdw.o sqlite3_api_wrapper.o EXTENSION = duckdb_fdw -DATA = duckdb_fdw--1.0.0.sql duckdb_fdw--1.0.0--1.1.2.sql duckdb_fdw--1.1.2--1.1.3.sql +DATA = duckdb_fdw--1.0.0.sql duckdb_fdw--1.0.0--1.1.2.sql duckdb_fdw--1.1.2--1.1.3.sql duckdb_fdw--1.1.3--1.3.2.sql duckdb_fdw--1.3.2--1.4.1.sql REGRESS = extra/duckdb_fdw_post extra/float4 extra/float8 extra/int4 extra/int8 extra/numeric extra/join extra/limit extra/aggregates extra/prepare extra/select_having extra/select extra/insert extra/update extra/timestamp duckdb_fdw type aggregate selectfunc @@ -53,7 +43,8 @@ ifeq ($(detected_OS),Linux) endif endif -SHLIB_LINK := -L. -lduckdb.$(DUCKDB_VERSION) -lstdc++ +SHLIB_LINK := -L. -lduckdb -lstdc++ + ifdef USE_PGXS PG_CONFIG = pg_config @@ -64,8 +55,8 @@ include $(PGXS) ifndef MAJORVERSION MAJORVERSION := $(basename $(VERSION)) endif -ifeq (,$(findstring $(MAJORVERSION), 10 11 12 13 14 15 16 17)) -$(error PostgreSQL 10, 11, 12, 13, 14, 15, 16 or 17 is required to compile this extension) +ifeq (,$(findstring $(MAJORVERSION), 10 11 12 13 14 15 16 17 18)) +$(error PostgreSQL 10, 11, 12, 13, 14, 15, 16, 17 or 18 is required to compile this extension) endif else @@ -75,6 +66,8 @@ include $(top_builddir)/src/Makefile.global include $(top_srcdir)/contrib/contrib-global.mk endif +SHLIB_LINK += -Wl,-rpath,$(DESTDIR)$(PG_LIB) + ifdef REGRESS_PREFIX REGRESS_PREFIX_SUB = $(REGRESS_PREFIX) else @@ -86,11 +79,11 @@ $(shell mkdir -p results/$(REGRESS_PREFIX_SUB)/extra) install-duckdb: $(shlib) - $(install_bin) -m 755 libduckdb.$(DUCKDB_VERSION)$(DLSUFFIX) $(DESTDIR)$(PG_LIB) + $(install_bin) -m 755 libduckdb$(DLSUFFIX) $(DESTDIR)$(PG_LIB) install: install-duckdb uninstall-duckdb: - rm -f $(DESTDIR)$(PG_LIB)/libduckdb.$(DUCKDB_VERSION)$(DLSUFFIX) + rm -f $(DESTDIR)$(PG_LIB)/libduckdb$(DLSUFFIX) uninstall: uninstall-duckdb \ No newline at end of file diff --git a/README.md b/README.md index 420d571..5451ea6 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,19 @@ # DuckDB Foreign Data Wrapper for PostgreSQL This is a foreign data wrapper (FDW) to connect [PostgreSQL](https://www.postgresql.org/) -to [DuckDB](https://duckdb.org/) database file. This FDW works with PostgreSQL 9.6 ... 16 and works with exact same version of `libduckdb`. +to [DuckDB](https://duckdb.org/) database files through DuckDB's SQLite compatibility layer. This FDW works with PostgreSQL 9.6 ... 18 and uses DuckDB's built-in SQLite API compatibility. PostgreSQL + DuckDB +## Architecture Overview + +**Important Technical Note**: This FDW uses DuckDB's SQLite compatibility layer rather than direct DuckDB API calls. The implementation leverages DuckDB's ability to act as a drop-in replacement for SQLite, providing: + +- SQLite API compatibility (`sqlite3.h`) +- DuckDB's advanced query optimization and performance +- Support for DuckDB's rich data types and functions +- Direct file-based database access + ## Contents 1. [Features](#features) @@ -26,7 +35,7 @@ to [DuckDB](https://duckdb.org/) database file. This FDW works with PostgreSQL 9 ### Common features -- Transactions +- Transactions - Support `TRUNCATE` by deparsing into `DELETE` statement without `WHERE` clause - Allow control over whether foreign servers keep connections open after transaction completion. This is controlled by `keep_connections` and defaults to on - Support list cached connections to foreign servers by using function `duckdb_fdw_get_connections()` @@ -36,15 +45,18 @@ to [DuckDB](https://duckdb.org/) database file. This FDW works with PostgreSQL 9 ### Pushdowning -- *not described* +- WHERE clauses with operators, functions and operators +- Aggregate functions (COUNT, SUM, AVG, MIN, MAX) +- GROUP BY clauses +- ORDER BY clauses +- JOIN operations (inner, left, right, full) +- LIMIT/OFFSET clauses ### Notes about pushdowning -- *not described* - -### Notes about features - -Also see [Limitations](#limitations) +- Pushdown is controlled by DuckDB's query optimizer through the SQLite compatibility layer +- Complex queries may be partially pushed down depending on DuckDB's capabilities +- Some PostgreSQL-specific functions may not push down and will be executed locally ## Supported platforms @@ -56,7 +68,6 @@ Also see [Limitations](#limitations) There's a `duckdb_fdw` rpm available on Pigsty's PGSQL [yum repository](https://repo.pigsty.cc/repo) for el8 and el9 - ### Source installation Prerequisites: @@ -64,6 +75,7 @@ Prerequisites: - `postgresql-server-{version}-dev` - `gcc` - `make` +- `curl` (for download script) #### 1. Download source @@ -72,25 +84,33 @@ git clone https://github.com/alitrack/duckdb_fdw cd duckdb_fdw ``` -#### 2. Download DuckDB library +#### 2. Download DuckDB library using automated script -For example, we want to compile under Linux AMD64 with DuckDB v1.0.0, just download [libduckdb-linux-amd64.zip](https://github.com/duckdb/duckdb/releases/download/v1.0.0/libduckdb-linux-amd64.zip) +The project includes an automated download script that fetches the latest DuckDB version: ```bash -wget -c https://github.com/duckdb/duckdb/releases/download/v1.0.0/libduckdb-linux-amd64.zip -unzip -d . libduckdb-linux-amd64.zip +# Download latest DuckDB library (automatically detects platform) +./download_libduckdb.sh -# you can also put the libduckdb.so to a directory in LD_LIBRARY_PATH, such as /usr/lib64 -cp libduckdb.so $(pg_config --libdir) +# Or download specific version manually +DUCKDB_VERSION=1.4.1 +wget -c https://github.com/duckdb/duckdb/releases/download/v${DUCKDB_VERSION}/libduckdb-linux-amd64.zip +unzip -d . libduckdb-linux-amd64.zip ``` -Beware that this libduckdb.so is build on ubuntu with higher glibc version, to use `duckdb_fdw` on el8 / el9, you have to compile `[libduckdb-src.zip`](https://github.com/duckdb/duckdb/releases/download/v1.0.0/libduckdb-src.zip) from source +**Note**: The download script automatically: + +- Detects your platform (Linux/macOS) and architecture +- Downloads the appropriate DuckDB library + +For Enterprise Linux (RHEL/CentOS 8/9), you may need to compile from source using `libduckdb-src.zip` due to glibc version compatibility. #### 3. Build and install duckdb_fdw Add a directory of `pg_config` to PATH and build and install `duckdb_fdw`. ```sh +# The .duckdb_version file is automatically created by the download script make USE_PGXS=1 make install USE_PGXS=1 ``` @@ -111,23 +131,19 @@ make install - **database** as *string*, **required** DuckDB database path. - - **truncatable** as *boolean*, optional, default *false* Allows foreign tables to be truncated using the `TRUNCATE` command. - - **keep_connections** as *boolean*, optional, default *false* - + Allows to keep connections to DuckDB while there is no SQL operations between PostgreSQL and DuckDB. - - **batch_size** as *integer*, optional, default *1* Specifies the number of rows which should be inserted in a single `INSERT` operation. This setting can be overridden for individual tables. - - **temp_directory** as *string*, optional, default *NULL* - + Specifies the directory to which to write temp files. - + ## CREATE USER MAPPING options There is no user or password conceptions in DuckDB, hence `duckdb_fdw` no need any `CREATE USER MAPPING` command. @@ -145,30 +161,26 @@ In OS `duckdb_fdw` works as executed code with permissions of user of PostgreSQL - **table** as *string*, optional, no default DuckDB table name. Use if not equal to name of foreign table in PostgreSQL. Also see about [identifier case handling](#identifier-case-handling). - - **truncatable** as *boolean*, optional, default from the same `CREATE SERVER` option - - See `CREATE SERVER` options section for details. + See `CREATE SERVER` options section for details. - **batch_size** as *integer*, optional, default from the same `CREATE SERVER` option - See `CREATE SERVER` options section for details. - + See `CREATE SERVER` options section for details. + `duckdb_fdw` accepts the following column-level options via the `CREATE FOREIGN TABLE` command: - **column_name** as *string*, optional, no default This option gives the column name to use for the column on the remote server. Also see about [identifier case handling](#identifier-case-handling). - - **column_type** as *string*, optional, no default Option to convert INT DuckDB column (epoch Unix Time) to be treated/visualized as TIMESTAMP in PostgreSQL. - - **key** as *boolean*, optional, default *false* Indicates a column as a part of primary key or unique key of DuckDB table. - + ## IMPORT FOREIGN SCHEMA options `duckdb_fdw` supports [IMPORT FOREIGN SCHEMA](https://www.postgresql.org/docs/current/sql-importforeignschema.html) @@ -190,13 +202,10 @@ As well as the standard `duckdb_fdw_handler()` and `duckdb_fdw_validator()` functions, `duckdb_fdw` provides the following user-callable utility functions: - SETOF record **duckdb_fdw_get_connections**(server_name text, valid bool) - - bool **duckdb_fdw_disconnect**(text) Closes connection from PostgreSQL to DuckDB in the current session. - - bool **duckdb_fdw_disconnect_all()** - - **duckdb_fdw_version()**; Returns standard "version integer" as `major version * 10000 + minor version * 100 + bugfix`. @@ -221,7 +230,7 @@ You are best advised to use this function outside multi-statement transactions. It is very useful to use command that duckdb_fdw does not support, for example, - add more table or view to DuckDB directly. - + ```sql SELECT duckdb_execute('duckdb_server' ,'create or replace view iris_parquet as select * from parquet_scan(''temp/iris.parquet'');'); @@ -242,7 +251,7 @@ duckdb_server INTO duckdb; - run Copy command on Foreign table -```sql +```sql SELECT duckdb_execute('duckdb_server' ,'CREATE TABLE test (a INTEGER, b INTEGER, c VARCHAR(10)); '); @@ -252,7 +261,7 @@ SELECT duckdb_execute('duckdb_server' ## Identifier case handling -PostgreSQL folds identifiers to lower case by default. DuckDB *behaviour not described*. It's important +PostgreSQL folds identifiers to lower case by default. DuckDB preserves case sensitivity through the SQLite compatibility layer. It's important to be aware of potential issues with table and column names. ## Generated columns @@ -395,30 +404,30 @@ For the table from previous examples ## Tests -All tests are based on `make check`, main testing script see in [test.sh](test.sh) file. We don't profess a specific environment. You can use any POSIX-compliant system. -Testing scripts from PosgreSQL-side is multi-versioned. Hence, you need install PostgreSQL packages in versions listed in [sql](sql) directory. +All tests are based on `make check`, main testing script see in [test.sh](test.sh) file. We don't profess a specific environment. You can use any POSIX-compliant system. +Testing scripts from PosgreSQL-side is multi-versioned. Hence, you need install PostgreSQL packages in versions listed in [sql](sql) directory. PostgreSQL server locale for messages in tests must be *english*. About base testing mechanism see in [PostgreSQL documentation](https://www.postgresql.org/docs/current/regress-run.html). Testing directory have structure as following: ``` +---sql - +---11.7 + +---10.18 | filename1.sql | filename2.sql | - +---12.12 + +---11.13 | filename1.sql | filename2.sql | ................. - \---15.0 + \---14.0 filename1.sql filename2.sql ``` The test cases for each version are based on the test of corresponding version of PostgreSQL. -You can execute test by `test.sh` directly. +You can execute test by `test.sh` directly. The version of PostgreSQL is detected automatically by `$(VERSION)` variable in Makefile. ## Contributing @@ -437,9 +446,9 @@ For pull request, please make sure these items below for testing: ### Source -- https://github.com/pgspider/sqlite_fdw +- https://github.com/alitrack/duckdb_fdw - https://pgxn.org/dist/duckdb_fdw/ - + Reference FDW realisation, `postgres_fdw` - https://git.postgresql.org/gitweb/?p=postgresql.git;a=tree;f=contrib/postgres_fdw;hb=HEAD @@ -460,7 +469,7 @@ Reference FDW realisation, `postgres_fdw` ## Special thanks -Authors of https://github.com/pgspider/sqlite_fdw +Authors of https://github.com/pgspider/sqlite_fdw (base implementation) ## License diff --git a/deparse.c b/deparse.c index 50027f9..a6056d9 100644 --- a/deparse.c +++ b/deparse.c @@ -3410,6 +3410,7 @@ sqlite_append_order_by_clause(List *pathkeys, bool has_final_sort, deparse_expr_ { PathKey *pathkey = lfirst(lcell); Expr *em_expr; + bool compare_it; int sqliteVersion = sqlite3_libversion_number(); if (has_final_sort) @@ -3430,10 +3431,13 @@ sqlite_append_order_by_clause(List *pathkeys, bool has_final_sort, deparse_expr_ appendStringInfoString(buf, delim); sqlite_deparse_expr(em_expr, context); - if (pathkey->pk_strategy == BTLessStrategyNumber) - appendStringInfoString(buf, " ASC"); - else - appendStringInfoString(buf, " DESC"); + +#if PG_VERSION_NUM >= 180000 + compare_it = (pathkey->pk_cmptype == COMPARE_LT); +#else + compare_it = (pathkey->pk_strategy == BTLessStrategyNumber); +#endif + appendStringInfoString(buf, compare_it ? " ASC" : " DESC"); /* * In SQLITE3 Release v3.30.0 (2019-10-04) NULLS FIRST/LAST is @@ -3454,10 +3458,10 @@ sqlite_append_order_by_clause(List *pathkeys, bool has_final_sort, deparse_expr_ * If we need a different behaviour than SQLite default...we show * warning message because NULLS FIRST/LAST is not implemented in * this SQLite version. - */ - if (!pathkey->pk_nulls_first && pathkey->pk_strategy == BTLessStrategyNumber) + */ + if (!pathkey->pk_nulls_first && compare_it) elog(WARNING, "Current Sqlite Version (%d) does not support NULLS LAST for ORDER BY ASC, degraded emitted query to ORDER BY ASC NULLS FIRST (default sqlite behaviour).", sqliteVersion); - else if (pathkey->pk_nulls_first && pathkey->pk_strategy != BTLessStrategyNumber) + else if (pathkey->pk_nulls_first && !compare_it) elog(WARNING, "Current Sqlite Version (%d) does not support NULLS FIRST for ORDER BY DESC, degraded emitted query to ORDER BY DESC NULLS LAST (default sqlite behaviour).", sqliteVersion); } diff --git a/docker-compose.yml b/docker-compose.yml index 0dcc277..a2e1e11 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,7 +4,7 @@ services: context: . args: - POSTGRES_VERSION=17 - - DUCKDB_VERSION=1.1.3 + - DUCKDB_VERSION=1.4.1 ports: - "5432:5432" volumes: diff --git a/download_libduckdb.sh b/download_libduckdb.sh index d17b915..8a42c82 100755 --- a/download_libduckdb.sh +++ b/download_libduckdb.sh @@ -44,8 +44,7 @@ VERSION=$(get_latest_version) # Remove 'v' prefix from version for filename DUCKDB_VERSION=${VERSION#v} -# Save version information to a file that can be sourced by make -echo "DUCKDB_VERSION=$DUCKDB_VERSION" > .duckdb_version + # Construct download URL DOWNLOAD_URL="https://github.com/duckdb/duckdb/releases/download/${VERSION}/libduckdb-${PLATFORM}-${ARCH}.zip" @@ -57,13 +56,5 @@ echo "URL: ${DOWNLOAD_URL}" curl -L -o duckdb-temp.zip "${DOWNLOAD_URL}" unzip -o duckdb-temp.zip - -# Rename library file with version number -mv "libduckdb.${LIB_EXT}" "libduckdb.${DUCKDB_VERSION}.${LIB_EXT}" - rm duckdb-temp.zip -echo "Successfully downloaded and renamed library files:" - -echo "- Version file: libduckdb*${DUCKDB_VERSION}*" - diff --git a/duckdb.h b/duckdb.h deleted file mode 100644 index 30b79fd..0000000 --- a/duckdb.h +++ /dev/null @@ -1,4162 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// DuckDB -// -// duckdb.h -// -// -//===----------------------------------------------------------------------===// -// -// !!!!!!! -// WARNING: this file is autogenerated by scripts/generate_c_api.py, manual changes will be overwritten -// !!!!!!! - -#pragma once - -//! duplicate of duckdb/main/winapi.hpp -#ifndef DUCKDB_API -#ifdef _WIN32 -#ifdef DUCKDB_STATIC_BUILD -#define DUCKDB_API -#else -#if defined(DUCKDB_BUILD_LIBRARY) && !defined(DUCKDB_BUILD_LOADABLE_EXTENSION) -#define DUCKDB_API __declspec(dllexport) -#else -#define DUCKDB_API __declspec(dllimport) -#endif -#endif -#else -#define DUCKDB_API -#endif -#endif - -//! duplicate of duckdb/main/winapi.hpp -#ifndef DUCKDB_EXTENSION_API -#ifdef _WIN32 -#ifdef DUCKDB_STATIC_BUILD -#define DUCKDB_EXTENSION_API -#else -#ifdef DUCKDB_BUILD_LOADABLE_EXTENSION -#define DUCKDB_EXTENSION_API __declspec(dllexport) -#else -#define DUCKDB_EXTENSION_API -#endif -#endif -#else -#define DUCKDB_EXTENSION_API __attribute__((visibility("default"))) -#endif -#endif - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -//===--------------------------------------------------------------------===// -// Enums -//===--------------------------------------------------------------------===// -// WARNING: the numbers of these enums should not be changed, as changing the numbers breaks ABI compatibility -// Always add enums at the END of the enum -//! An enum over DuckDB's internal types. -typedef enum DUCKDB_TYPE { - DUCKDB_TYPE_INVALID = 0, - // bool - DUCKDB_TYPE_BOOLEAN = 1, - // int8_t - DUCKDB_TYPE_TINYINT = 2, - // int16_t - DUCKDB_TYPE_SMALLINT = 3, - // int32_t - DUCKDB_TYPE_INTEGER = 4, - // int64_t - DUCKDB_TYPE_BIGINT = 5, - // uint8_t - DUCKDB_TYPE_UTINYINT = 6, - // uint16_t - DUCKDB_TYPE_USMALLINT = 7, - // uint32_t - DUCKDB_TYPE_UINTEGER = 8, - // uint64_t - DUCKDB_TYPE_UBIGINT = 9, - // float - DUCKDB_TYPE_FLOAT = 10, - // double - DUCKDB_TYPE_DOUBLE = 11, - // duckdb_timestamp, in microseconds - DUCKDB_TYPE_TIMESTAMP = 12, - // duckdb_date - DUCKDB_TYPE_DATE = 13, - // duckdb_time - DUCKDB_TYPE_TIME = 14, - // duckdb_interval - DUCKDB_TYPE_INTERVAL = 15, - // duckdb_hugeint - DUCKDB_TYPE_HUGEINT = 16, - // duckdb_uhugeint - DUCKDB_TYPE_UHUGEINT = 32, - // const char* - DUCKDB_TYPE_VARCHAR = 17, - // duckdb_blob - DUCKDB_TYPE_BLOB = 18, - // decimal - DUCKDB_TYPE_DECIMAL = 19, - // duckdb_timestamp, in seconds - DUCKDB_TYPE_TIMESTAMP_S = 20, - // duckdb_timestamp, in milliseconds - DUCKDB_TYPE_TIMESTAMP_MS = 21, - // duckdb_timestamp, in nanoseconds - DUCKDB_TYPE_TIMESTAMP_NS = 22, - // enum type, only useful as logical type - DUCKDB_TYPE_ENUM = 23, - // list type, only useful as logical type - DUCKDB_TYPE_LIST = 24, - // struct type, only useful as logical type - DUCKDB_TYPE_STRUCT = 25, - // map type, only useful as logical type - DUCKDB_TYPE_MAP = 26, - // duckdb_array, only useful as logical type - DUCKDB_TYPE_ARRAY = 33, - // duckdb_hugeint - DUCKDB_TYPE_UUID = 27, - // union type, only useful as logical type - DUCKDB_TYPE_UNION = 28, - // duckdb_bit - DUCKDB_TYPE_BIT = 29, - // duckdb_time_tz - DUCKDB_TYPE_TIME_TZ = 30, - // duckdb_timestamp - DUCKDB_TYPE_TIMESTAMP_TZ = 31, - // ANY type - DUCKDB_TYPE_ANY = 34, - // duckdb_varint - DUCKDB_TYPE_VARINT = 35, - // SQLNULL type - DUCKDB_TYPE_SQLNULL = 36, -} duckdb_type; -//! An enum over the returned state of different functions. -typedef enum duckdb_state { DuckDBSuccess = 0, DuckDBError = 1 } duckdb_state; -//! An enum over the pending state of a pending query result. -typedef enum duckdb_pending_state { - DUCKDB_PENDING_RESULT_READY = 0, - DUCKDB_PENDING_RESULT_NOT_READY = 1, - DUCKDB_PENDING_ERROR = 2, - DUCKDB_PENDING_NO_TASKS_AVAILABLE = 3 -} duckdb_pending_state; -//! An enum over DuckDB's different result types. -typedef enum duckdb_result_type { - DUCKDB_RESULT_TYPE_INVALID = 0, - DUCKDB_RESULT_TYPE_CHANGED_ROWS = 1, - DUCKDB_RESULT_TYPE_NOTHING = 2, - DUCKDB_RESULT_TYPE_QUERY_RESULT = 3, -} duckdb_result_type; -//! An enum over DuckDB's different statement types. -typedef enum duckdb_statement_type { - DUCKDB_STATEMENT_TYPE_INVALID = 0, - DUCKDB_STATEMENT_TYPE_SELECT = 1, - DUCKDB_STATEMENT_TYPE_INSERT = 2, - DUCKDB_STATEMENT_TYPE_UPDATE = 3, - DUCKDB_STATEMENT_TYPE_EXPLAIN = 4, - DUCKDB_STATEMENT_TYPE_DELETE = 5, - DUCKDB_STATEMENT_TYPE_PREPARE = 6, - DUCKDB_STATEMENT_TYPE_CREATE = 7, - DUCKDB_STATEMENT_TYPE_EXECUTE = 8, - DUCKDB_STATEMENT_TYPE_ALTER = 9, - DUCKDB_STATEMENT_TYPE_TRANSACTION = 10, - DUCKDB_STATEMENT_TYPE_COPY = 11, - DUCKDB_STATEMENT_TYPE_ANALYZE = 12, - DUCKDB_STATEMENT_TYPE_VARIABLE_SET = 13, - DUCKDB_STATEMENT_TYPE_CREATE_FUNC = 14, - DUCKDB_STATEMENT_TYPE_DROP = 15, - DUCKDB_STATEMENT_TYPE_EXPORT = 16, - DUCKDB_STATEMENT_TYPE_PRAGMA = 17, - DUCKDB_STATEMENT_TYPE_VACUUM = 18, - DUCKDB_STATEMENT_TYPE_CALL = 19, - DUCKDB_STATEMENT_TYPE_SET = 20, - DUCKDB_STATEMENT_TYPE_LOAD = 21, - DUCKDB_STATEMENT_TYPE_RELATION = 22, - DUCKDB_STATEMENT_TYPE_EXTENSION = 23, - DUCKDB_STATEMENT_TYPE_LOGICAL_PLAN = 24, - DUCKDB_STATEMENT_TYPE_ATTACH = 25, - DUCKDB_STATEMENT_TYPE_DETACH = 26, - DUCKDB_STATEMENT_TYPE_MULTI = 27, -} duckdb_statement_type; -//! An enum over DuckDB's different result types. -typedef enum duckdb_error_type { - DUCKDB_ERROR_INVALID = 0, - DUCKDB_ERROR_OUT_OF_RANGE = 1, - DUCKDB_ERROR_CONVERSION = 2, - DUCKDB_ERROR_UNKNOWN_TYPE = 3, - DUCKDB_ERROR_DECIMAL = 4, - DUCKDB_ERROR_MISMATCH_TYPE = 5, - DUCKDB_ERROR_DIVIDE_BY_ZERO = 6, - DUCKDB_ERROR_OBJECT_SIZE = 7, - DUCKDB_ERROR_INVALID_TYPE = 8, - DUCKDB_ERROR_SERIALIZATION = 9, - DUCKDB_ERROR_TRANSACTION = 10, - DUCKDB_ERROR_NOT_IMPLEMENTED = 11, - DUCKDB_ERROR_EXPRESSION = 12, - DUCKDB_ERROR_CATALOG = 13, - DUCKDB_ERROR_PARSER = 14, - DUCKDB_ERROR_PLANNER = 15, - DUCKDB_ERROR_SCHEDULER = 16, - DUCKDB_ERROR_EXECUTOR = 17, - DUCKDB_ERROR_CONSTRAINT = 18, - DUCKDB_ERROR_INDEX = 19, - DUCKDB_ERROR_STAT = 20, - DUCKDB_ERROR_CONNECTION = 21, - DUCKDB_ERROR_SYNTAX = 22, - DUCKDB_ERROR_SETTINGS = 23, - DUCKDB_ERROR_BINDER = 24, - DUCKDB_ERROR_NETWORK = 25, - DUCKDB_ERROR_OPTIMIZER = 26, - DUCKDB_ERROR_NULL_POINTER = 27, - DUCKDB_ERROR_IO = 28, - DUCKDB_ERROR_INTERRUPT = 29, - DUCKDB_ERROR_FATAL = 30, - DUCKDB_ERROR_INTERNAL = 31, - DUCKDB_ERROR_INVALID_INPUT = 32, - DUCKDB_ERROR_OUT_OF_MEMORY = 33, - DUCKDB_ERROR_PERMISSION = 34, - DUCKDB_ERROR_PARAMETER_NOT_RESOLVED = 35, - DUCKDB_ERROR_PARAMETER_NOT_ALLOWED = 36, - DUCKDB_ERROR_DEPENDENCY = 37, - DUCKDB_ERROR_HTTP = 38, - DUCKDB_ERROR_MISSING_EXTENSION = 39, - DUCKDB_ERROR_AUTOLOAD = 40, - DUCKDB_ERROR_SEQUENCE = 41, - DUCKDB_INVALID_CONFIGURATION = 42 -} duckdb_error_type; -//! An enum over DuckDB's different cast modes. -typedef enum duckdb_cast_mode { DUCKDB_CAST_NORMAL = 0, DUCKDB_CAST_TRY = 1 } duckdb_cast_mode; - -//===--------------------------------------------------------------------===// -// General type definitions -//===--------------------------------------------------------------------===// - -//! DuckDB's index type. -typedef uint64_t idx_t; - -//! The callback that will be called to destroy data, e.g., -//! bind data (if any), init data (if any), extra data for replacement scans (if any) -typedef void (*duckdb_delete_callback_t)(void *data); - -//! Used for threading, contains a task state. Must be destroyed with `duckdb_destroy_state`. -typedef void *duckdb_task_state; - -//===--------------------------------------------------------------------===// -// Types (no explicit freeing) -//===--------------------------------------------------------------------===// - -//! Days are stored as days since 1970-01-01 -//! Use the duckdb_from_date/duckdb_to_date function to extract individual information -typedef struct { - int32_t days; -} duckdb_date; -typedef struct { - int32_t year; - int8_t month; - int8_t day; -} duckdb_date_struct; - -//! Time is stored as microseconds since 00:00:00 -//! Use the duckdb_from_time/duckdb_to_time function to extract individual information -typedef struct { - int64_t micros; -} duckdb_time; -typedef struct { - int8_t hour; - int8_t min; - int8_t sec; - int32_t micros; -} duckdb_time_struct; - -//! TIME_TZ is stored as 40 bits for int64_t micros, and 24 bits for int32_t offset -typedef struct { - uint64_t bits; -} duckdb_time_tz; -typedef struct { - duckdb_time_struct time; - int32_t offset; -} duckdb_time_tz_struct; - -//! Timestamps are stored as microseconds since 1970-01-01 -//! Use the duckdb_from_timestamp/duckdb_to_timestamp function to extract individual information -typedef struct { - int64_t micros; -} duckdb_timestamp; -typedef struct { - duckdb_date_struct date; - duckdb_time_struct time; -} duckdb_timestamp_struct; -typedef struct { - int32_t months; - int32_t days; - int64_t micros; -} duckdb_interval; - -//! Hugeints are composed of a (lower, upper) component -//! The value of the hugeint is upper * 2^64 + lower -//! For easy usage, the functions duckdb_hugeint_to_double/duckdb_double_to_hugeint are recommended -typedef struct { - uint64_t lower; - int64_t upper; -} duckdb_hugeint; -typedef struct { - uint64_t lower; - uint64_t upper; -} duckdb_uhugeint; - -//! Decimals are composed of a width and a scale, and are stored in a hugeint -typedef struct { - uint8_t width; - uint8_t scale; - duckdb_hugeint value; -} duckdb_decimal; - -//! A type holding information about the query execution progress -typedef struct { - double percentage; - uint64_t rows_processed; - uint64_t total_rows_to_process; -} duckdb_query_progress_type; - -//! The internal representation of a VARCHAR (string_t). If the VARCHAR does not -//! exceed 12 characters, then we inline it. Otherwise, we inline a prefix for faster -//! string comparisons and store a pointer to the remaining characters. This is a non- -//! owning structure, i.e., it does not have to be freed. -typedef struct { - union { - struct { - uint32_t length; - char prefix[4]; - char *ptr; - } pointer; - struct { - uint32_t length; - char inlined[12]; - } inlined; - } value; -} duckdb_string_t; - -//! The internal representation of a list metadata entry contains the list's offset in -//! the child vector, and its length. The parent vector holds these metadata entries, -//! whereas the child vector holds the data -typedef struct { - uint64_t offset; - uint64_t length; -} duckdb_list_entry; - -//! A column consists of a pointer to its internal data. Don't operate on this type directly. -//! Instead, use functions such as duckdb_column_data, duckdb_nullmask_data, -//! duckdb_column_type, and duckdb_column_name, which take the result and the column index -//! as their parameters -typedef struct { - // deprecated, use duckdb_column_data - void *deprecated_data; - // deprecated, use duckdb_nullmask_data - bool *deprecated_nullmask; - // deprecated, use duckdb_column_type - duckdb_type deprecated_type; - // deprecated, use duckdb_column_name - char *deprecated_name; - void *internal_data; -} duckdb_column; - -//! A vector to a specified column in a data chunk. Lives as long as the -//! data chunk lives, i.e., must not be destroyed. -typedef struct _duckdb_vector { - void *internal_ptr; -} * duckdb_vector; - -//===--------------------------------------------------------------------===// -// Types (explicit freeing/destroying) -//===--------------------------------------------------------------------===// - -//! Strings are composed of a char pointer and a size. You must free string.data -//! with `duckdb_free`. -typedef struct { - char *data; - idx_t size; -} duckdb_string; - -//! BLOBs are composed of a byte pointer and a size. You must free blob.data -//! with `duckdb_free`. -typedef struct { - void *data; - idx_t size; -} duckdb_blob; - -//! A query result consists of a pointer to its internal data. -//! Must be freed with 'duckdb_destroy_result'. -typedef struct { - // deprecated, use duckdb_column_count - idx_t deprecated_column_count; - // deprecated, use duckdb_row_count - idx_t deprecated_row_count; - // deprecated, use duckdb_rows_changed - idx_t deprecated_rows_changed; - // deprecated, use duckdb_column_*-family of functions - duckdb_column *deprecated_columns; - // deprecated, use duckdb_result_error - char *deprecated_error_message; - void *internal_data; -} duckdb_result; - -//! A database object. Should be closed with `duckdb_close`. -typedef struct _duckdb_database { - void *internal_ptr; -} * duckdb_database; - -//! A connection to a duckdb database. Must be closed with `duckdb_disconnect`. -typedef struct _duckdb_connection { - void *internal_ptr; -} * duckdb_connection; - -//! A prepared statement is a parameterized query that allows you to bind parameters to it. -//! Must be destroyed with `duckdb_destroy_prepare`. -typedef struct _duckdb_prepared_statement { - void *internal_ptr; -} * duckdb_prepared_statement; - -//! Extracted statements. Must be destroyed with `duckdb_destroy_extracted`. -typedef struct _duckdb_extracted_statements { - void *internal_ptr; -} * duckdb_extracted_statements; - -//! The pending result represents an intermediate structure for a query that is not yet fully executed. -//! Must be destroyed with `duckdb_destroy_pending`. -typedef struct _duckdb_pending_result { - void *internal_ptr; -} * duckdb_pending_result; - -//! The appender enables fast data loading into DuckDB. -//! Must be destroyed with `duckdb_appender_destroy`. -typedef struct _duckdb_appender { - void *internal_ptr; -} * duckdb_appender; - -//! The table description allows querying info about the table. -//! Must be destroyed with `duckdb_table_description_destroy`. -typedef struct _duckdb_table_description { - void *internal_ptr; -} * duckdb_table_description; - -//! Can be used to provide start-up options for the DuckDB instance. -//! Must be destroyed with `duckdb_destroy_config`. -typedef struct _duckdb_config { - void *internal_ptr; -} * duckdb_config; - -//! Holds an internal logical type. -//! Must be destroyed with `duckdb_destroy_logical_type`. -typedef struct _duckdb_logical_type { - void *internal_ptr; -} * duckdb_logical_type; - -//! Holds extra information used when registering a custom logical type. -//! Reserved for future use. -typedef struct _duckdb_create_type_info { - void *internal_ptr; -} * duckdb_create_type_info; - -//! Contains a data chunk from a duckdb_result. -//! Must be destroyed with `duckdb_destroy_data_chunk`. -typedef struct _duckdb_data_chunk { - void *internal_ptr; -} * duckdb_data_chunk; - -//! Holds a DuckDB value, which wraps a type. -//! Must be destroyed with `duckdb_destroy_value`. -typedef struct _duckdb_value { - void *internal_ptr; -} * duckdb_value; - -//! Holds a recursive tree that matches the query plan. -typedef struct _duckdb_profiling_info { - void *internal_ptr; -} * duckdb_profiling_info; - -//===--------------------------------------------------------------------===// -// C API Extension info -//===--------------------------------------------------------------------===// -//! Holds state during the C API extension intialization process -typedef struct _duckdb_extension_info { - void *internal_ptr; -} * duckdb_extension_info; - -//===--------------------------------------------------------------------===// -// Function types -//===--------------------------------------------------------------------===// -//! Additional function info. When setting this info, it is necessary to pass a destroy-callback function. -typedef struct _duckdb_function_info { - void *internal_ptr; -} * duckdb_function_info; - -//===--------------------------------------------------------------------===// -// Scalar function types -//===--------------------------------------------------------------------===// -//! A scalar function. Must be destroyed with `duckdb_destroy_scalar_function`. -typedef struct _duckdb_scalar_function { - void *internal_ptr; -} * duckdb_scalar_function; - -//! A scalar function set. Must be destroyed with `duckdb_destroy_scalar_function_set`. -typedef struct _duckdb_scalar_function_set { - void *internal_ptr; -} * duckdb_scalar_function_set; - -//! The main function of the scalar function. -typedef void (*duckdb_scalar_function_t)(duckdb_function_info info, duckdb_data_chunk input, duckdb_vector output); - -//===--------------------------------------------------------------------===// -// Aggregate function types -//===--------------------------------------------------------------------===// -//! An aggregate function. Must be destroyed with `duckdb_destroy_aggregate_function`. -typedef struct _duckdb_aggregate_function { - void *internal_ptr; -} * duckdb_aggregate_function; - -//! A aggregate function set. Must be destroyed with `duckdb_destroy_aggregate_function_set`. -typedef struct _duckdb_aggregate_function_set { - void *internal_ptr; -} * duckdb_aggregate_function_set; - -//! Aggregate state -typedef struct _duckdb_aggregate_state { - void *internal_ptr; -} * duckdb_aggregate_state; - -//! Returns the aggregate state size -typedef idx_t (*duckdb_aggregate_state_size)(duckdb_function_info info); -//! Initialize the aggregate state -typedef void (*duckdb_aggregate_init_t)(duckdb_function_info info, duckdb_aggregate_state state); -//! Destroy aggregate state (optional) -typedef void (*duckdb_aggregate_destroy_t)(duckdb_aggregate_state *states, idx_t count); -//! Update a set of aggregate states with new values -typedef void (*duckdb_aggregate_update_t)(duckdb_function_info info, duckdb_data_chunk input, - duckdb_aggregate_state *states); -//! Combine aggregate states -typedef void (*duckdb_aggregate_combine_t)(duckdb_function_info info, duckdb_aggregate_state *source, - duckdb_aggregate_state *target, idx_t count); -//! Finalize aggregate states into a result vector -typedef void (*duckdb_aggregate_finalize_t)(duckdb_function_info info, duckdb_aggregate_state *source, - duckdb_vector result, idx_t count, idx_t offset); - -//===--------------------------------------------------------------------===// -// Table function types -//===--------------------------------------------------------------------===// - -//! A table function. Must be destroyed with `duckdb_destroy_table_function`. -typedef struct _duckdb_table_function { - void *internal_ptr; -} * duckdb_table_function; - -//! The bind info of the function. When setting this info, it is necessary to pass a destroy-callback function. -typedef struct _duckdb_bind_info { - void *internal_ptr; -} * duckdb_bind_info; - -//! Additional function init info. When setting this info, it is necessary to pass a destroy-callback function. -typedef struct _duckdb_init_info { - void *internal_ptr; -} * duckdb_init_info; - -//! The bind function of the table function. -typedef void (*duckdb_table_function_bind_t)(duckdb_bind_info info); - -//! The (possibly thread-local) init function of the table function. -typedef void (*duckdb_table_function_init_t)(duckdb_init_info info); - -//! The main function of the table function. -typedef void (*duckdb_table_function_t)(duckdb_function_info info, duckdb_data_chunk output); - -//===--------------------------------------------------------------------===// -// Cast types -//===--------------------------------------------------------------------===// - -//! A cast function. Must be destroyed with `duckdb_destroy_cast_function`. -typedef struct _duckdb_cast_function { - void *internal_ptr; -} * duckdb_cast_function; - -typedef bool (*duckdb_cast_function_t)(duckdb_function_info info, idx_t count, duckdb_vector input, - duckdb_vector output); - -//===--------------------------------------------------------------------===// -// Replacement scan types -//===--------------------------------------------------------------------===// - -//! Additional replacement scan info. When setting this info, it is necessary to pass a destroy-callback function. -typedef struct _duckdb_replacement_scan_info { - void *internal_ptr; -} * duckdb_replacement_scan_info; - -//! A replacement scan function that can be added to a database. -typedef void (*duckdb_replacement_callback_t)(duckdb_replacement_scan_info info, const char *table_name, void *data); - -//===--------------------------------------------------------------------===// -// Arrow-related types -//===--------------------------------------------------------------------===// - -//! Holds an arrow query result. Must be destroyed with `duckdb_destroy_arrow`. -typedef struct _duckdb_arrow { - void *internal_ptr; -} * duckdb_arrow; - -//! Holds an arrow array stream. Must be destroyed with `duckdb_destroy_arrow_stream`. -typedef struct _duckdb_arrow_stream { - void *internal_ptr; -} * duckdb_arrow_stream; - -//! Holds an arrow schema. Remember to release the respective ArrowSchema object. -typedef struct _duckdb_arrow_schema { - void *internal_ptr; -} * duckdb_arrow_schema; - -//! Holds an arrow array. Remember to release the respective ArrowArray object. -typedef struct _duckdb_arrow_array { - void *internal_ptr; -} * duckdb_arrow_array; - -//===--------------------------------------------------------------------===// -// DuckDB extension access -//===--------------------------------------------------------------------===// -//! Passed to C API extension as parameter to the entrypoint -struct duckdb_extension_access { - //! Indicate that an error has occurred - void (*set_error)(duckdb_extension_info info, const char *error); - //! Fetch the database from duckdb to register extensions to - duckdb_database *(*get_database)(duckdb_extension_info info); - //! Fetch the API - const void *(*get_api)(duckdb_extension_info info, const char *version); -}; - -//===--------------------------------------------------------------------===// -// Functions -//===--------------------------------------------------------------------===// - -//===--------------------------------------------------------------------===// -// Open Connect -//===--------------------------------------------------------------------===// - -/*! -Creates a new database or opens an existing database file stored at the given path. -If no path is given a new in-memory database is created instead. -The instantiated database should be closed with 'duckdb_close'. - -* @param path Path to the database file on disk, or `nullptr` or `:memory:` to open an in-memory database. -* @param out_database The result database object. -* @return `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_open(const char *path, duckdb_database *out_database); - -/*! -Extended version of duckdb_open. Creates a new database or opens an existing database file stored at the given path. -The instantiated database should be closed with 'duckdb_close'. - -* @param path Path to the database file on disk, or `nullptr` or `:memory:` to open an in-memory database. -* @param out_database The result database object. -* @param config (Optional) configuration used to start up the database system. -* @param out_error If set and the function returns DuckDBError, this will contain the reason why the start-up failed. -Note that the error must be freed using `duckdb_free`. -* @return `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_open_ext(const char *path, duckdb_database *out_database, duckdb_config config, - char **out_error); - -/*! -Closes the specified database and de-allocates all memory allocated for that database. -This should be called after you are done with any database allocated through `duckdb_open` or `duckdb_open_ext`. -Note that failing to call `duckdb_close` (in case of e.g. a program crash) will not cause data corruption. -Still, it is recommended to always correctly close a database object after you are done with it. - -* @param database The database object to shut down. -*/ -DUCKDB_API void duckdb_close(duckdb_database *database); - -/*! -Opens a connection to a database. Connections are required to query the database, and store transactional state -associated with the connection. -The instantiated connection should be closed using 'duckdb_disconnect'. - -* @param database The database file to connect to. -* @param out_connection The result connection object. -* @return `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_connect(duckdb_database database, duckdb_connection *out_connection); - -/*! -Interrupt running query - -* @param connection The connection to interrupt -*/ -DUCKDB_API void duckdb_interrupt(duckdb_connection connection); - -/*! -Get progress of the running query - -* @param connection The working connection -* @return -1 if no progress or a percentage of the progress -*/ -DUCKDB_API duckdb_query_progress_type duckdb_query_progress(duckdb_connection connection); - -/*! -Closes the specified connection and de-allocates all memory allocated for that connection. - -* @param connection The connection to close. -*/ -DUCKDB_API void duckdb_disconnect(duckdb_connection *connection); - -/*! -Returns the version of the linked DuckDB, with a version postfix for dev versions - -Usually used for developing C extensions that must return this for a compatibility check. -*/ -DUCKDB_API const char *duckdb_library_version(); - -//===--------------------------------------------------------------------===// -// Configuration -//===--------------------------------------------------------------------===// - -/*! -Initializes an empty configuration object that can be used to provide start-up options for the DuckDB instance -through `duckdb_open_ext`. -The duckdb_config must be destroyed using 'duckdb_destroy_config' - -This will always succeed unless there is a malloc failure. - -Note that `duckdb_destroy_config` should always be called on the resulting config, even if the function returns -`DuckDBError`. - -* @param out_config The result configuration object. -* @return `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_create_config(duckdb_config *out_config); - -/*! -This returns the total amount of configuration options available for usage with `duckdb_get_config_flag`. - -This should not be called in a loop as it internally loops over all the options. - -* @return The amount of config options available. -*/ -DUCKDB_API size_t duckdb_config_count(); - -/*! -Obtains a human-readable name and description of a specific configuration option. This can be used to e.g. -display configuration options. This will succeed unless `index` is out of range (i.e. `>= duckdb_config_count`). - -The result name or description MUST NOT be freed. - -* @param index The index of the configuration option (between 0 and `duckdb_config_count`) -* @param out_name A name of the configuration flag. -* @param out_description A description of the configuration flag. -* @return `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_get_config_flag(size_t index, const char **out_name, const char **out_description); - -/*! -Sets the specified option for the specified configuration. The configuration option is indicated by name. -To obtain a list of config options, see `duckdb_get_config_flag`. - -In the source code, configuration options are defined in `config.cpp`. - -This can fail if either the name is invalid, or if the value provided for the option is invalid. - -* @param config The configuration object to set the option on. -* @param name The name of the configuration flag to set. -* @param option The value to set the configuration flag to. -* @return `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_set_config(duckdb_config config, const char *name, const char *option); - -/*! -Destroys the specified configuration object and de-allocates all memory allocated for the object. - -* @param config The configuration object to destroy. -*/ -DUCKDB_API void duckdb_destroy_config(duckdb_config *config); - -//===--------------------------------------------------------------------===// -// Query Execution -//===--------------------------------------------------------------------===// - -/*! -Executes a SQL query within a connection and stores the full (materialized) result in the out_result pointer. -If the query fails to execute, DuckDBError is returned and the error message can be retrieved by calling -`duckdb_result_error`. - -Note that after running `duckdb_query`, `duckdb_destroy_result` must be called on the result object even if the -query fails, otherwise the error stored within the result will not be freed correctly. - -* @param connection The connection to perform the query in. -* @param query The SQL query to run. -* @param out_result The query result. -* @return `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_query(duckdb_connection connection, const char *query, duckdb_result *out_result); - -/*! -Closes the result and de-allocates all memory allocated for that connection. - -* @param result The result to destroy. -*/ -DUCKDB_API void duckdb_destroy_result(duckdb_result *result); - -/*! -Returns the column name of the specified column. The result should not need to be freed; the column names will -automatically be destroyed when the result is destroyed. - -Returns `NULL` if the column is out of range. - -* @param result The result object to fetch the column name from. -* @param col The column index. -* @return The column name of the specified column. -*/ -DUCKDB_API const char *duckdb_column_name(duckdb_result *result, idx_t col); - -/*! -Returns the column type of the specified column. - -Returns `DUCKDB_TYPE_INVALID` if the column is out of range. - -* @param result The result object to fetch the column type from. -* @param col The column index. -* @return The column type of the specified column. -*/ -DUCKDB_API duckdb_type duckdb_column_type(duckdb_result *result, idx_t col); - -/*! -Returns the statement type of the statement that was executed - -* @param result The result object to fetch the statement type from. -* @return duckdb_statement_type value or DUCKDB_STATEMENT_TYPE_INVALID -*/ -DUCKDB_API duckdb_statement_type duckdb_result_statement_type(duckdb_result result); - -/*! -Returns the logical column type of the specified column. - -The return type of this call should be destroyed with `duckdb_destroy_logical_type`. - -Returns `NULL` if the column is out of range. - -* @param result The result object to fetch the column type from. -* @param col The column index. -* @return The logical column type of the specified column. -*/ -DUCKDB_API duckdb_logical_type duckdb_column_logical_type(duckdb_result *result, idx_t col); - -/*! -Returns the number of columns present in a the result object. - -* @param result The result object. -* @return The number of columns present in the result object. -*/ -DUCKDB_API idx_t duckdb_column_count(duckdb_result *result); - -#ifndef DUCKDB_API_NO_DEPRECATED -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -Returns the number of rows present in the result object. - -* @param result The result object. -* @return The number of rows present in the result object. -*/ -DUCKDB_API idx_t duckdb_row_count(duckdb_result *result); - -#endif -/*! -Returns the number of rows changed by the query stored in the result. This is relevant only for INSERT/UPDATE/DELETE -queries. For other queries the rows_changed will be 0. - -* @param result The result object. -* @return The number of rows changed. -*/ -DUCKDB_API idx_t duckdb_rows_changed(duckdb_result *result); - -#ifndef DUCKDB_API_NO_DEPRECATED -/*! -**DEPRECATED**: Prefer using `duckdb_result_get_chunk` instead. - -Returns the data of a specific column of a result in columnar format. - -The function returns a dense array which contains the result data. The exact type stored in the array depends on the -corresponding duckdb_type (as provided by `duckdb_column_type`). For the exact type by which the data should be -accessed, see the comments in [the types section](types) or the `DUCKDB_TYPE` enum. - -For example, for a column of type `DUCKDB_TYPE_INTEGER`, rows can be accessed in the following manner: -```c -int32_t *data = (int32_t *) duckdb_column_data(&result, 0); -printf("Data for row %d: %d\n", row, data[row]); -``` - -* @param result The result object to fetch the column data from. -* @param col The column index. -* @return The column data of the specified column. -*/ -DUCKDB_API void *duckdb_column_data(duckdb_result *result, idx_t col); - -/*! -**DEPRECATED**: Prefer using `duckdb_result_get_chunk` instead. - -Returns the nullmask of a specific column of a result in columnar format. The nullmask indicates for every row -whether or not the corresponding row is `NULL`. If a row is `NULL`, the values present in the array provided -by `duckdb_column_data` are undefined. - -```c -int32_t *data = (int32_t *) duckdb_column_data(&result, 0); -bool *nullmask = duckdb_nullmask_data(&result, 0); -if (nullmask[row]) { - printf("Data for row %d: NULL\n", row); -} else { - printf("Data for row %d: %d\n", row, data[row]); -} -``` - -* @param result The result object to fetch the nullmask from. -* @param col The column index. -* @return The nullmask of the specified column. -*/ -DUCKDB_API bool *duckdb_nullmask_data(duckdb_result *result, idx_t col); - -#endif -/*! -Returns the error message contained within the result. The error is only set if `duckdb_query` returns `DuckDBError`. - -The result of this function must not be freed. It will be cleaned up when `duckdb_destroy_result` is called. - -* @param result The result object to fetch the error from. -* @return The error of the result. -*/ -DUCKDB_API const char *duckdb_result_error(duckdb_result *result); - -/*! -Returns the result error type contained within the result. The error is only set if `duckdb_query` returns -`DuckDBError`. - -* @param result The result object to fetch the error from. -* @return The error type of the result. -*/ -DUCKDB_API duckdb_error_type duckdb_result_error_type(duckdb_result *result); - -//===--------------------------------------------------------------------===// -// Result Functions -//===--------------------------------------------------------------------===// - -#ifndef DUCKDB_API_NO_DEPRECATED -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -Fetches a data chunk from the duckdb_result. This function should be called repeatedly until the result is exhausted. - -The result must be destroyed with `duckdb_destroy_data_chunk`. - -This function supersedes all `duckdb_value` functions, as well as the `duckdb_column_data` and `duckdb_nullmask_data` -functions. It results in significantly better performance, and should be preferred in newer code-bases. - -If this function is used, none of the other result functions can be used and vice versa (i.e. this function cannot be -mixed with the legacy result functions). - -Use `duckdb_result_chunk_count` to figure out how many chunks there are in the result. - -* @param result The result object to fetch the data chunk from. -* @param chunk_index The chunk index to fetch from. -* @return The resulting data chunk. Returns `NULL` if the chunk index is out of bounds. -*/ -DUCKDB_API duckdb_data_chunk duckdb_result_get_chunk(duckdb_result result, idx_t chunk_index); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -Checks if the type of the internal result is StreamQueryResult. - -* @param result The result object to check. -* @return Whether or not the result object is of the type StreamQueryResult -*/ -DUCKDB_API bool duckdb_result_is_streaming(duckdb_result result); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -Returns the number of data chunks present in the result. - -* @param result The result object -* @return Number of data chunks present in the result. -*/ -DUCKDB_API idx_t duckdb_result_chunk_count(duckdb_result result); - -#endif -/*! -Returns the return_type of the given result, or DUCKDB_RETURN_TYPE_INVALID on error - -* @param result The result object -* @return The return_type -*/ -DUCKDB_API duckdb_result_type duckdb_result_return_type(duckdb_result result); - -//===--------------------------------------------------------------------===// -// Safe Fetch Functions -//===--------------------------------------------------------------------===// - -// These functions will perform conversions if necessary. -// On failure (e.g. if conversion cannot be performed or if the value is NULL) a default value is returned. -// Note that these functions are slow since they perform bounds checking and conversion -// For fast access of values prefer using `duckdb_result_get_chunk` -#ifndef DUCKDB_API_NO_DEPRECATED -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -* @return The boolean value at the specified location, or false if the value cannot be converted. -*/ -DUCKDB_API bool duckdb_value_boolean(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -* @return The int8_t value at the specified location, or 0 if the value cannot be converted. -*/ -DUCKDB_API int8_t duckdb_value_int8(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -* @return The int16_t value at the specified location, or 0 if the value cannot be converted. -*/ -DUCKDB_API int16_t duckdb_value_int16(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -* @return The int32_t value at the specified location, or 0 if the value cannot be converted. -*/ -DUCKDB_API int32_t duckdb_value_int32(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -* @return The int64_t value at the specified location, or 0 if the value cannot be converted. -*/ -DUCKDB_API int64_t duckdb_value_int64(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -* @return The duckdb_hugeint value at the specified location, or 0 if the value cannot be converted. -*/ -DUCKDB_API duckdb_hugeint duckdb_value_hugeint(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -* @return The duckdb_uhugeint value at the specified location, or 0 if the value cannot be converted. -*/ -DUCKDB_API duckdb_uhugeint duckdb_value_uhugeint(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -* @return The duckdb_decimal value at the specified location, or 0 if the value cannot be converted. -*/ -DUCKDB_API duckdb_decimal duckdb_value_decimal(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -* @return The uint8_t value at the specified location, or 0 if the value cannot be converted. -*/ -DUCKDB_API uint8_t duckdb_value_uint8(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -* @return The uint16_t value at the specified location, or 0 if the value cannot be converted. -*/ -DUCKDB_API uint16_t duckdb_value_uint16(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -* @return The uint32_t value at the specified location, or 0 if the value cannot be converted. -*/ -DUCKDB_API uint32_t duckdb_value_uint32(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -* @return The uint64_t value at the specified location, or 0 if the value cannot be converted. -*/ -DUCKDB_API uint64_t duckdb_value_uint64(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -* @return The float value at the specified location, or 0 if the value cannot be converted. -*/ -DUCKDB_API float duckdb_value_float(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -* @return The double value at the specified location, or 0 if the value cannot be converted. -*/ -DUCKDB_API double duckdb_value_double(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -* @return The duckdb_date value at the specified location, or 0 if the value cannot be converted. -*/ -DUCKDB_API duckdb_date duckdb_value_date(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -* @return The duckdb_time value at the specified location, or 0 if the value cannot be converted. -*/ -DUCKDB_API duckdb_time duckdb_value_time(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -* @return The duckdb_timestamp value at the specified location, or 0 if the value cannot be converted. -*/ -DUCKDB_API duckdb_timestamp duckdb_value_timestamp(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -* @return The duckdb_interval value at the specified location, or 0 if the value cannot be converted. -*/ -DUCKDB_API duckdb_interval duckdb_value_interval(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATED**: Use duckdb_value_string instead. This function does not work correctly if the string contains null -bytes. - -* @return The text value at the specified location as a null-terminated string, or nullptr if the value cannot be -converted. The result must be freed with `duckdb_free`. -*/ -DUCKDB_API char *duckdb_value_varchar(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -No support for nested types, and for other complex types. -The resulting field "string.data" must be freed with `duckdb_free.` - -* @return The string value at the specified location. Attempts to cast the result value to string. -*/ -DUCKDB_API duckdb_string duckdb_value_string(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATED**: Use duckdb_value_string_internal instead. This function does not work correctly if the string contains -null bytes. - -* @return The char* value at the specified location. ONLY works on VARCHAR columns and does not auto-cast. -If the column is NOT a VARCHAR column this function will return NULL. - -The result must NOT be freed. -*/ -DUCKDB_API char *duckdb_value_varchar_internal(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATED**: Use duckdb_value_string_internal instead. This function does not work correctly if the string contains -null bytes. -* @return The char* value at the specified location. ONLY works on VARCHAR columns and does not auto-cast. -If the column is NOT a VARCHAR column this function will return NULL. - -The result must NOT be freed. -*/ -DUCKDB_API duckdb_string duckdb_value_string_internal(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -* @return The duckdb_blob value at the specified location. Returns a blob with blob.data set to nullptr if the -value cannot be converted. The resulting field "blob.data" must be freed with `duckdb_free.` -*/ -DUCKDB_API duckdb_blob duckdb_value_blob(duckdb_result *result, idx_t col, idx_t row); - -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -* @return Returns true if the value at the specified index is NULL, and false otherwise. -*/ -DUCKDB_API bool duckdb_value_is_null(duckdb_result *result, idx_t col, idx_t row); - -#endif -//===--------------------------------------------------------------------===// -// Helpers -//===--------------------------------------------------------------------===// - -/*! -Allocate `size` bytes of memory using the duckdb internal malloc function. Any memory allocated in this manner -should be freed using `duckdb_free`. - -* @param size The number of bytes to allocate. -* @return A pointer to the allocated memory region. -*/ -DUCKDB_API void *duckdb_malloc(size_t size); - -/*! -Free a value returned from `duckdb_malloc`, `duckdb_value_varchar`, `duckdb_value_blob`, or -`duckdb_value_string`. - -* @param ptr The memory region to de-allocate. -*/ -DUCKDB_API void duckdb_free(void *ptr); - -/*! -The internal vector size used by DuckDB. -This is the amount of tuples that will fit into a data chunk created by `duckdb_create_data_chunk`. - -* @return The vector size. -*/ -DUCKDB_API idx_t duckdb_vector_size(); - -/*! -Whether or not the duckdb_string_t value is inlined. -This means that the data of the string does not have a separate allocation. - -*/ -DUCKDB_API bool duckdb_string_is_inlined(duckdb_string_t string); - -/*! -Get the string length of a string_t - -* @param string The string to get the length of. -* @return The length. -*/ -DUCKDB_API uint32_t duckdb_string_t_length(duckdb_string_t string); - -/*! -Get a pointer to the string data of a string_t - -* @param string The string to get the pointer to. -* @return The pointer. -*/ -DUCKDB_API const char *duckdb_string_t_data(duckdb_string_t *string); - -//===--------------------------------------------------------------------===// -// Date Time Timestamp Helpers -//===--------------------------------------------------------------------===// - -/*! -Decompose a `duckdb_date` object into year, month and date (stored as `duckdb_date_struct`). - -* @param date The date object, as obtained from a `DUCKDB_TYPE_DATE` column. -* @return The `duckdb_date_struct` with the decomposed elements. -*/ -DUCKDB_API duckdb_date_struct duckdb_from_date(duckdb_date date); - -/*! -Re-compose a `duckdb_date` from year, month and date (`duckdb_date_struct`). - -* @param date The year, month and date stored in a `duckdb_date_struct`. -* @return The `duckdb_date` element. -*/ -DUCKDB_API duckdb_date duckdb_to_date(duckdb_date_struct date); - -/*! -Test a `duckdb_date` to see if it is a finite value. - -* @param date The date object, as obtained from a `DUCKDB_TYPE_DATE` column. -* @return True if the date is finite, false if it is ±infinity. -*/ -DUCKDB_API bool duckdb_is_finite_date(duckdb_date date); - -/*! -Decompose a `duckdb_time` object into hour, minute, second and microsecond (stored as `duckdb_time_struct`). - -* @param time The time object, as obtained from a `DUCKDB_TYPE_TIME` column. -* @return The `duckdb_time_struct` with the decomposed elements. -*/ -DUCKDB_API duckdb_time_struct duckdb_from_time(duckdb_time time); - -/*! -Create a `duckdb_time_tz` object from micros and a timezone offset. - -* @param micros The microsecond component of the time. -* @param offset The timezone offset component of the time. -* @return The `duckdb_time_tz` element. -*/ -DUCKDB_API duckdb_time_tz duckdb_create_time_tz(int64_t micros, int32_t offset); - -/*! -Decompose a TIME_TZ objects into micros and a timezone offset. - -Use `duckdb_from_time` to further decompose the micros into hour, minute, second and microsecond. - -* @param micros The time object, as obtained from a `DUCKDB_TYPE_TIME_TZ` column. -*/ -DUCKDB_API duckdb_time_tz_struct duckdb_from_time_tz(duckdb_time_tz micros); - -/*! -Re-compose a `duckdb_time` from hour, minute, second and microsecond (`duckdb_time_struct`). - -* @param time The hour, minute, second and microsecond in a `duckdb_time_struct`. -* @return The `duckdb_time` element. -*/ -DUCKDB_API duckdb_time duckdb_to_time(duckdb_time_struct time); - -/*! -Decompose a `duckdb_timestamp` object into a `duckdb_timestamp_struct`. - -* @param ts The ts object, as obtained from a `DUCKDB_TYPE_TIMESTAMP` column. -* @return The `duckdb_timestamp_struct` with the decomposed elements. -*/ -DUCKDB_API duckdb_timestamp_struct duckdb_from_timestamp(duckdb_timestamp ts); - -/*! -Re-compose a `duckdb_timestamp` from a duckdb_timestamp_struct. - -* @param ts The de-composed elements in a `duckdb_timestamp_struct`. -* @return The `duckdb_timestamp` element. -*/ -DUCKDB_API duckdb_timestamp duckdb_to_timestamp(duckdb_timestamp_struct ts); - -/*! -Test a `duckdb_timestamp` to see if it is a finite value. - -* @param ts The timestamp object, as obtained from a `DUCKDB_TYPE_TIMESTAMP` column. -* @return True if the timestamp is finite, false if it is ±infinity. -*/ -DUCKDB_API bool duckdb_is_finite_timestamp(duckdb_timestamp ts); - -//===--------------------------------------------------------------------===// -// Hugeint Helpers -//===--------------------------------------------------------------------===// - -/*! -Converts a duckdb_hugeint object (as obtained from a `DUCKDB_TYPE_HUGEINT` column) into a double. - -* @param val The hugeint value. -* @return The converted `double` element. -*/ -DUCKDB_API double duckdb_hugeint_to_double(duckdb_hugeint val); - -/*! -Converts a double value to a duckdb_hugeint object. - -If the conversion fails because the double value is too big the result will be 0. - -* @param val The double value. -* @return The converted `duckdb_hugeint` element. -*/ -DUCKDB_API duckdb_hugeint duckdb_double_to_hugeint(double val); - -//===--------------------------------------------------------------------===// -// Unsigned Hugeint Helpers -//===--------------------------------------------------------------------===// - -/*! -Converts a duckdb_uhugeint object (as obtained from a `DUCKDB_TYPE_UHUGEINT` column) into a double. - -* @param val The uhugeint value. -* @return The converted `double` element. -*/ -DUCKDB_API double duckdb_uhugeint_to_double(duckdb_uhugeint val); - -/*! -Converts a double value to a duckdb_uhugeint object. - -If the conversion fails because the double value is too big the result will be 0. - -* @param val The double value. -* @return The converted `duckdb_uhugeint` element. -*/ -DUCKDB_API duckdb_uhugeint duckdb_double_to_uhugeint(double val); - -//===--------------------------------------------------------------------===// -// Decimal Helpers -//===--------------------------------------------------------------------===// - -/*! -Converts a double value to a duckdb_decimal object. - -If the conversion fails because the double value is too big, or the width/scale are invalid the result will be 0. - -* @param val The double value. -* @return The converted `duckdb_decimal` element. -*/ -DUCKDB_API duckdb_decimal duckdb_double_to_decimal(double val, uint8_t width, uint8_t scale); - -/*! -Converts a duckdb_decimal object (as obtained from a `DUCKDB_TYPE_DECIMAL` column) into a double. - -* @param val The decimal value. -* @return The converted `double` element. -*/ -DUCKDB_API double duckdb_decimal_to_double(duckdb_decimal val); - -//===--------------------------------------------------------------------===// -// Prepared Statements -//===--------------------------------------------------------------------===// - -// A prepared statement is a parameterized query that allows you to bind parameters to it. -// * This is useful to easily supply parameters to functions and avoid SQL injection attacks. -// * This is useful to speed up queries that you will execute several times with different parameters. -// Because the query will only be parsed, bound, optimized and planned once during the prepare stage, -// rather than once per execution. -// For example: -// SELECT * FROM tbl WHERE id=? -// Or a query with multiple parameters: -// SELECT * FROM tbl WHERE id=$1 OR name=$2 -/*! -Create a prepared statement object from a query. - -Note that after calling `duckdb_prepare`, the prepared statement should always be destroyed using -`duckdb_destroy_prepare`, even if the prepare fails. - -If the prepare fails, `duckdb_prepare_error` can be called to obtain the reason why the prepare failed. - -* @param connection The connection object -* @param query The SQL query to prepare -* @param out_prepared_statement The resulting prepared statement object -* @return `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_prepare(duckdb_connection connection, const char *query, - duckdb_prepared_statement *out_prepared_statement); - -/*! -Closes the prepared statement and de-allocates all memory allocated for the statement. - -* @param prepared_statement The prepared statement to destroy. -*/ -DUCKDB_API void duckdb_destroy_prepare(duckdb_prepared_statement *prepared_statement); - -/*! -Returns the error message associated with the given prepared statement. -If the prepared statement has no error message, this returns `nullptr` instead. - -The error message should not be freed. It will be de-allocated when `duckdb_destroy_prepare` is called. - -* @param prepared_statement The prepared statement to obtain the error from. -* @return The error message, or `nullptr` if there is none. -*/ -DUCKDB_API const char *duckdb_prepare_error(duckdb_prepared_statement prepared_statement); - -/*! -Returns the number of parameters that can be provided to the given prepared statement. - -Returns 0 if the query was not successfully prepared. - -* @param prepared_statement The prepared statement to obtain the number of parameters for. -*/ -DUCKDB_API idx_t duckdb_nparams(duckdb_prepared_statement prepared_statement); - -/*! -Returns the name used to identify the parameter -The returned string should be freed using `duckdb_free`. - -Returns NULL if the index is out of range for the provided prepared statement. - -* @param prepared_statement The prepared statement for which to get the parameter name from. -*/ -DUCKDB_API const char *duckdb_parameter_name(duckdb_prepared_statement prepared_statement, idx_t index); - -/*! -Returns the parameter type for the parameter at the given index. - -Returns `DUCKDB_TYPE_INVALID` if the parameter index is out of range or the statement was not successfully prepared. - -* @param prepared_statement The prepared statement. -* @param param_idx The parameter index. -* @return The parameter type -*/ -DUCKDB_API duckdb_type duckdb_param_type(duckdb_prepared_statement prepared_statement, idx_t param_idx); - -/*! -Clear the params bind to the prepared statement. -*/ -DUCKDB_API duckdb_state duckdb_clear_bindings(duckdb_prepared_statement prepared_statement); - -/*! -Returns the statement type of the statement to be executed - -* @param statement The prepared statement. -* @return duckdb_statement_type value or DUCKDB_STATEMENT_TYPE_INVALID -*/ -DUCKDB_API duckdb_statement_type duckdb_prepared_statement_type(duckdb_prepared_statement statement); - -//===--------------------------------------------------------------------===// -// Bind Values To Prepared Statements -//===--------------------------------------------------------------------===// - -/*! -Binds a value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_value(duckdb_prepared_statement prepared_statement, idx_t param_idx, - duckdb_value val); - -/*! -Retrieve the index of the parameter for the prepared statement, identified by name -*/ -DUCKDB_API duckdb_state duckdb_bind_parameter_index(duckdb_prepared_statement prepared_statement, idx_t *param_idx_out, - const char *name); - -/*! -Binds a bool value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_boolean(duckdb_prepared_statement prepared_statement, idx_t param_idx, bool val); - -/*! -Binds an int8_t value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_int8(duckdb_prepared_statement prepared_statement, idx_t param_idx, int8_t val); - -/*! -Binds an int16_t value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_int16(duckdb_prepared_statement prepared_statement, idx_t param_idx, int16_t val); - -/*! -Binds an int32_t value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_int32(duckdb_prepared_statement prepared_statement, idx_t param_idx, int32_t val); - -/*! -Binds an int64_t value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_int64(duckdb_prepared_statement prepared_statement, idx_t param_idx, int64_t val); - -/*! -Binds a duckdb_hugeint value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_hugeint(duckdb_prepared_statement prepared_statement, idx_t param_idx, - duckdb_hugeint val); - -/*! -Binds an duckdb_uhugeint value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_uhugeint(duckdb_prepared_statement prepared_statement, idx_t param_idx, - duckdb_uhugeint val); - -/*! -Binds a duckdb_decimal value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_decimal(duckdb_prepared_statement prepared_statement, idx_t param_idx, - duckdb_decimal val); - -/*! -Binds an uint8_t value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_uint8(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint8_t val); - -/*! -Binds an uint16_t value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_uint16(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint16_t val); - -/*! -Binds an uint32_t value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_uint32(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint32_t val); - -/*! -Binds an uint64_t value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_uint64(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint64_t val); - -/*! -Binds a float value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_float(duckdb_prepared_statement prepared_statement, idx_t param_idx, float val); - -/*! -Binds a double value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_double(duckdb_prepared_statement prepared_statement, idx_t param_idx, double val); - -/*! -Binds a duckdb_date value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_date(duckdb_prepared_statement prepared_statement, idx_t param_idx, - duckdb_date val); - -/*! -Binds a duckdb_time value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_time(duckdb_prepared_statement prepared_statement, idx_t param_idx, - duckdb_time val); - -/*! -Binds a duckdb_timestamp value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_timestamp(duckdb_prepared_statement prepared_statement, idx_t param_idx, - duckdb_timestamp val); - -/*! -Binds a duckdb_timestamp value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_timestamp_tz(duckdb_prepared_statement prepared_statement, idx_t param_idx, - duckdb_timestamp val); - -/*! -Binds a duckdb_interval value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_interval(duckdb_prepared_statement prepared_statement, idx_t param_idx, - duckdb_interval val); - -/*! -Binds a null-terminated varchar value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_varchar(duckdb_prepared_statement prepared_statement, idx_t param_idx, - const char *val); - -/*! -Binds a varchar value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_varchar_length(duckdb_prepared_statement prepared_statement, idx_t param_idx, - const char *val, idx_t length); - -/*! -Binds a blob value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_blob(duckdb_prepared_statement prepared_statement, idx_t param_idx, - const void *data, idx_t length); - -/*! -Binds a NULL value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_null(duckdb_prepared_statement prepared_statement, idx_t param_idx); - -//===--------------------------------------------------------------------===// -// Execute Prepared Statements -//===--------------------------------------------------------------------===// - -/*! -Executes the prepared statement with the given bound parameters, and returns a materialized query result. - -This method can be called multiple times for each prepared statement, and the parameters can be modified -between calls to this function. - -Note that the result must be freed with `duckdb_destroy_result`. - -* @param prepared_statement The prepared statement to execute. -* @param out_result The query result. -* @return `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_execute_prepared(duckdb_prepared_statement prepared_statement, - duckdb_result *out_result); - -#ifndef DUCKDB_API_NO_DEPRECATED -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -Executes the prepared statement with the given bound parameters, and returns an optionally-streaming query result. -To determine if the resulting query was in fact streamed, use `duckdb_result_is_streaming` - -This method can be called multiple times for each prepared statement, and the parameters can be modified -between calls to this function. - -Note that the result must be freed with `duckdb_destroy_result`. - -* @param prepared_statement The prepared statement to execute. -* @param out_result The query result. -* @return `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_execute_prepared_streaming(duckdb_prepared_statement prepared_statement, - duckdb_result *out_result); - -#endif -//===--------------------------------------------------------------------===// -// Extract Statements -//===--------------------------------------------------------------------===// - -// A query string can be extracted into multiple SQL statements. Each statement can be prepared and executed separately. -/*! -Extract all statements from a query. -Note that after calling `duckdb_extract_statements`, the extracted statements should always be destroyed using -`duckdb_destroy_extracted`, even if no statements were extracted. - -If the extract fails, `duckdb_extract_statements_error` can be called to obtain the reason why the extract failed. - -* @param connection The connection object -* @param query The SQL query to extract -* @param out_extracted_statements The resulting extracted statements object -* @return The number of extracted statements or 0 on failure. -*/ -DUCKDB_API idx_t duckdb_extract_statements(duckdb_connection connection, const char *query, - duckdb_extracted_statements *out_extracted_statements); - -/*! -Prepare an extracted statement. -Note that after calling `duckdb_prepare_extracted_statement`, the prepared statement should always be destroyed using -`duckdb_destroy_prepare`, even if the prepare fails. - -If the prepare fails, `duckdb_prepare_error` can be called to obtain the reason why the prepare failed. - -* @param connection The connection object -* @param extracted_statements The extracted statements object -* @param index The index of the extracted statement to prepare -* @param out_prepared_statement The resulting prepared statement object -* @return `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_prepare_extracted_statement(duckdb_connection connection, - duckdb_extracted_statements extracted_statements, - idx_t index, - duckdb_prepared_statement *out_prepared_statement); - -/*! -Returns the error message contained within the extracted statements. -The result of this function must not be freed. It will be cleaned up when `duckdb_destroy_extracted` is called. - -* @param extracted_statements The extracted statements to fetch the error from. -* @return The error of the extracted statements. -*/ -DUCKDB_API const char *duckdb_extract_statements_error(duckdb_extracted_statements extracted_statements); - -/*! -De-allocates all memory allocated for the extracted statements. -* @param extracted_statements The extracted statements to destroy. -*/ -DUCKDB_API void duckdb_destroy_extracted(duckdb_extracted_statements *extracted_statements); - -//===--------------------------------------------------------------------===// -// Pending Result Interface -//===--------------------------------------------------------------------===// - -/*! -Executes the prepared statement with the given bound parameters, and returns a pending result. -The pending result represents an intermediate structure for a query that is not yet fully executed. -The pending result can be used to incrementally execute a query, returning control to the client between tasks. - -Note that after calling `duckdb_pending_prepared`, the pending result should always be destroyed using -`duckdb_destroy_pending`, even if this function returns DuckDBError. - -* @param prepared_statement The prepared statement to execute. -* @param out_result The pending query result. -* @return `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_pending_prepared(duckdb_prepared_statement prepared_statement, - duckdb_pending_result *out_result); - -#ifndef DUCKDB_API_NO_DEPRECATED -/*! -**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - -Executes the prepared statement with the given bound parameters, and returns a pending result. -This pending result will create a streaming duckdb_result when executed. -The pending result represents an intermediate structure for a query that is not yet fully executed. - -Note that after calling `duckdb_pending_prepared_streaming`, the pending result should always be destroyed using -`duckdb_destroy_pending`, even if this function returns DuckDBError. - -* @param prepared_statement The prepared statement to execute. -* @param out_result The pending query result. -* @return `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_pending_prepared_streaming(duckdb_prepared_statement prepared_statement, - duckdb_pending_result *out_result); - -#endif -/*! -Closes the pending result and de-allocates all memory allocated for the result. - -* @param pending_result The pending result to destroy. -*/ -DUCKDB_API void duckdb_destroy_pending(duckdb_pending_result *pending_result); - -/*! -Returns the error message contained within the pending result. - -The result of this function must not be freed. It will be cleaned up when `duckdb_destroy_pending` is called. - -* @param pending_result The pending result to fetch the error from. -* @return The error of the pending result. -*/ -DUCKDB_API const char *duckdb_pending_error(duckdb_pending_result pending_result); - -/*! -Executes a single task within the query, returning whether or not the query is ready. - -If this returns DUCKDB_PENDING_RESULT_READY, the duckdb_execute_pending function can be called to obtain the result. -If this returns DUCKDB_PENDING_RESULT_NOT_READY, the duckdb_pending_execute_task function should be called again. -If this returns DUCKDB_PENDING_ERROR, an error occurred during execution. - -The error message can be obtained by calling duckdb_pending_error on the pending_result. - -* @param pending_result The pending result to execute a task within. -* @return The state of the pending result after the execution. -*/ -DUCKDB_API duckdb_pending_state duckdb_pending_execute_task(duckdb_pending_result pending_result); - -/*! -If this returns DUCKDB_PENDING_RESULT_READY, the duckdb_execute_pending function can be called to obtain the result. -If this returns DUCKDB_PENDING_RESULT_NOT_READY, the duckdb_pending_execute_check_state function should be called again. -If this returns DUCKDB_PENDING_ERROR, an error occurred during execution. - -The error message can be obtained by calling duckdb_pending_error on the pending_result. - -* @param pending_result The pending result. -* @return The state of the pending result. -*/ -DUCKDB_API duckdb_pending_state duckdb_pending_execute_check_state(duckdb_pending_result pending_result); - -/*! -Fully execute a pending query result, returning the final query result. - -If duckdb_pending_execute_task has been called until DUCKDB_PENDING_RESULT_READY was returned, this will return fast. -Otherwise, all remaining tasks must be executed first. - -Note that the result must be freed with `duckdb_destroy_result`. - -* @param pending_result The pending result to execute. -* @param out_result The result object. -* @return `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_execute_pending(duckdb_pending_result pending_result, duckdb_result *out_result); - -/*! -Returns whether a duckdb_pending_state is finished executing. For example if `pending_state` is -DUCKDB_PENDING_RESULT_READY, this function will return true. - -* @param pending_state The pending state on which to decide whether to finish execution. -* @return Boolean indicating pending execution should be considered finished. -*/ -DUCKDB_API bool duckdb_pending_execution_is_finished(duckdb_pending_state pending_state); - -//===--------------------------------------------------------------------===// -// Value Interface -//===--------------------------------------------------------------------===// - -/*! -Destroys the value and de-allocates all memory allocated for that type. - -* @param value The value to destroy. -*/ -DUCKDB_API void duckdb_destroy_value(duckdb_value *value); - -/*! -Creates a value from a null-terminated string - -* @param text The null-terminated string -* @return The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_varchar(const char *text); - -/*! -Creates a value from a string - -* @param text The text -* @param length The length of the text -* @return The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_varchar_length(const char *text, idx_t length); - -/*! -Creates a value from a boolean - -* @param input The boolean value -* @return The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_bool(bool input); - -/*! -Creates a value from a int8_t (a tinyint) - -* @param input The tinyint value -* @return The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_int8(int8_t input); - -/*! -Creates a value from a uint8_t (a utinyint) - -* @param input The utinyint value -* @return The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_uint8(uint8_t input); - -/*! -Creates a value from a int16_t (a smallint) - -* @param input The smallint value -* @return The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_int16(int16_t input); - -/*! -Creates a value from a uint16_t (a usmallint) - -* @param input The usmallint value -* @return The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_uint16(uint16_t input); - -/*! -Creates a value from a int32_t (an integer) - -* @param input The integer value -* @return The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_int32(int32_t input); - -/*! -Creates a value from a uint32_t (a uinteger) - -* @param input The uinteger value -* @return The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_uint32(uint32_t input); - -/*! -Creates a value from a uint64_t (a ubigint) - -* @param input The ubigint value -* @return The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_uint64(uint64_t input); - -/*! -Creates a value from an int64 - -* @return The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_int64(int64_t val); - -/*! -Creates a value from a hugeint - -* @param input The hugeint value -* @return The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_hugeint(duckdb_hugeint input); - -/*! -Creates a value from a uhugeint - -* @param input The uhugeint value -* @return The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_uhugeint(duckdb_uhugeint input); - -/*! -Creates a value from a float - -* @param input The float value -* @return The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_float(float input); - -/*! -Creates a value from a double - -* @param input The double value -* @return The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_double(double input); - -/*! -Creates a value from a date - -* @param input The date value -* @return The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_date(duckdb_date input); - -/*! -Creates a value from a time - -* @param input The time value -* @return The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_time(duckdb_time input); - -/*! -Creates a value from a time_tz. -Not to be confused with `duckdb_create_time_tz`, which creates a duckdb_time_tz_t. - -* @param value The time_tz value -* @return The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_time_tz_value(duckdb_time_tz value); - -/*! -Creates a value from a timestamp - -* @param input The timestamp value -* @return The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_timestamp(duckdb_timestamp input); - -/*! -Creates a value from an interval - -* @param input The interval value -* @return The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_interval(duckdb_interval input); - -/*! -Creates a value from a blob - -* @param data The blob data -* @param length The length of the blob data -* @return The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_blob(const uint8_t *data, idx_t length); - -/*! -Returns the boolean value of the given value. - -* @param val A duckdb_value containing a boolean -* @return A boolean, or false if the value cannot be converted -*/ -DUCKDB_API bool duckdb_get_bool(duckdb_value val); - -/*! -Returns the int8_t value of the given value. - -* @param val A duckdb_value containing a tinyint -* @return A int8_t, or MinValue if the value cannot be converted -*/ -DUCKDB_API int8_t duckdb_get_int8(duckdb_value val); - -/*! -Returns the uint8_t value of the given value. - -* @param val A duckdb_value containing a utinyint -* @return A uint8_t, or MinValue if the value cannot be converted -*/ -DUCKDB_API uint8_t duckdb_get_uint8(duckdb_value val); - -/*! -Returns the int16_t value of the given value. - -* @param val A duckdb_value containing a smallint -* @return A int16_t, or MinValue if the value cannot be converted -*/ -DUCKDB_API int16_t duckdb_get_int16(duckdb_value val); - -/*! -Returns the uint16_t value of the given value. - -* @param val A duckdb_value containing a usmallint -* @return A uint16_t, or MinValue if the value cannot be converted -*/ -DUCKDB_API uint16_t duckdb_get_uint16(duckdb_value val); - -/*! -Returns the int32_t value of the given value. - -* @param val A duckdb_value containing a integer -* @return A int32_t, or MinValue if the value cannot be converted -*/ -DUCKDB_API int32_t duckdb_get_int32(duckdb_value val); - -/*! -Returns the uint32_t value of the given value. - -* @param val A duckdb_value containing a uinteger -* @return A uint32_t, or MinValue if the value cannot be converted -*/ -DUCKDB_API uint32_t duckdb_get_uint32(duckdb_value val); - -/*! -Returns the int64_t value of the given value. - -* @param val A duckdb_value containing a bigint -* @return A int64_t, or MinValue if the value cannot be converted -*/ -DUCKDB_API int64_t duckdb_get_int64(duckdb_value val); - -/*! -Returns the uint64_t value of the given value. - -* @param val A duckdb_value containing a ubigint -* @return A uint64_t, or MinValue if the value cannot be converted -*/ -DUCKDB_API uint64_t duckdb_get_uint64(duckdb_value val); - -/*! -Returns the hugeint value of the given value. - -* @param val A duckdb_value containing a hugeint -* @return A duckdb_hugeint, or MinValue if the value cannot be converted -*/ -DUCKDB_API duckdb_hugeint duckdb_get_hugeint(duckdb_value val); - -/*! -Returns the uhugeint value of the given value. - -* @param val A duckdb_value containing a uhugeint -* @return A duckdb_uhugeint, or MinValue if the value cannot be converted -*/ -DUCKDB_API duckdb_uhugeint duckdb_get_uhugeint(duckdb_value val); - -/*! -Returns the float value of the given value. - -* @param val A duckdb_value containing a float -* @return A float, or NAN if the value cannot be converted -*/ -DUCKDB_API float duckdb_get_float(duckdb_value val); - -/*! -Returns the double value of the given value. - -* @param val A duckdb_value containing a double -* @return A double, or NAN if the value cannot be converted -*/ -DUCKDB_API double duckdb_get_double(duckdb_value val); - -/*! -Returns the date value of the given value. - -* @param val A duckdb_value containing a date -* @return A duckdb_date, or MinValue if the value cannot be converted -*/ -DUCKDB_API duckdb_date duckdb_get_date(duckdb_value val); - -/*! -Returns the time value of the given value. - -* @param val A duckdb_value containing a time -* @return A duckdb_time, or MinValue