Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/duckdb/duckdb/llms.txt

Use this file to discover all available pages before exploring further.

Introduction

DuckDB’s C++ API provides a simple and efficient interface for embedding an analytical database directly into C++ applications. The API is designed around three main classes:
  • DuckDB - The database instance
  • Connection - A connection to the database for executing queries
  • QueryResult - Results from executed queries
The C++ API is header-only and requires only including duckdb.hpp.

Basic Usage

Here’s a minimal example demonstrating the core workflow:
#include "duckdb.hpp"

using namespace duckdb;

int main() {
    // Create an in-memory database
    DuckDB db(nullptr);
    
    // Create a connection
    Connection con(db);
    
    // Execute queries
    con.Query("CREATE TABLE integers(i INTEGER)");
    con.Query("INSERT INTO integers VALUES (3)");
    
    // Query and print results
    auto result = con.Query("SELECT * FROM integers");
    result->Print();
}

Database Initialization

You can create a DuckDB instance in several ways:
// In-memory database
DuckDB db(nullptr);

Query Execution

The Connection class provides multiple methods for executing queries:
  • Query() - Executes a query and returns a materialized result
  • SendQuery() - Executes a query and returns a streaming result
  • Prepare() - Prepares a statement for repeated execution

Materialized vs Streaming Results

// Materialized - entire result set is loaded into memory
auto result = con.Query("SELECT * FROM large_table");

// Streaming - results are fetched incrementally
auto stream_result = con.SendQuery("SELECT * FROM large_table");

Result Handling

Query results can be accessed in multiple ways:
auto result = con.Query("SELECT name, age FROM users");

// Print to console
result->Print();

// Iterate over chunks
while (auto chunk = result->Fetch()) {
    for (idx_t row = 0; row < chunk->size(); row++) {
        auto name = chunk->GetValue(0, row);
        auto age = chunk->GetValue(1, row);
        // Process values...
    }
}

// For MaterializedQueryResult, access individual values
if (result->type == QueryResultType::MATERIALIZED_RESULT) {
    auto &materialized = result->Cast<MaterializedQueryResult>();
    auto value = materialized.GetValue(0, 0); // column 0, row 0
}

Error Handling

All query operations check for errors:
auto result = con.Query("SELECT * FROM non_existent_table");

if (result->HasError()) {
    std::cerr << "Error: " << result->GetError() << std::endl;
    return 1;
}

API Reference

Database

DuckDB database instance and configuration

Connection

Connection management and query execution

Query Results

Working with query results and data access

Example Code

For a complete working example, see the embedded C++ example in the DuckDB repository:
#include "duckdb.hpp"

using namespace duckdb;

int main() {
    DuckDB db(nullptr);
    Connection con(db);
    
    con.Query("CREATE TABLE integers(i INTEGER)");
    con.Query("INSERT INTO integers VALUES (3)");
    auto result = con.Query("SELECT * FROM integers");
    result->Print();
}

Next Steps