Skip to content
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ __pycache__
.DS_Store
.*.swp

# Build artifacts
sqlc
*.test

# Devenv
.envrc
.direnv
Expand Down
138 changes: 138 additions & 0 deletions examples/duckdb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# DuckDB Example

This example demonstrates how to use sqlc with DuckDB.

## Overview

DuckDB is an in-process analytical database that supports PostgreSQL-compatible SQL syntax. This integration reuses sqlc's PostgreSQL parser and catalog while providing a DuckDB-specific analyzer that connects to an in-memory DuckDB instance.

## Features

- **PostgreSQL-compatible SQL**: DuckDB uses PostgreSQL-compatible syntax, so you can use familiar SQL constructs
- **In-memory database**: Perfect for testing and development
- **Type-safe Go code**: sqlc generates type-safe Go code from your SQL queries
- **Live database analysis**: The analyzer connects to a DuckDB instance to extract accurate column types

## Configuration

The `sqlc.yaml` file configures sqlc to use the DuckDB engine:

```yaml
version: "2"
sql:
- name: "duckdb_example"
engine: "duckdb" # Use DuckDB engine
schema:
- "schema.sql"
queries:
- "query.sql"
database:
managed: false
uri: ":memory:" # Use in-memory database
analyzer:
database: true # Enable live database analysis
gen:
go:
package: "db"
out: "db"
```

## Database URI

DuckDB supports several URI formats:

- `:memory:` - In-memory database (default if not specified)
- `file.db` - File-based database
- `/path/to/file.db` - Absolute path to database file

## Usage

1. Generate Go code:
```bash
sqlc generate
```

2. Use the generated code in your application:
```go
package main

import (
"context"
"database/sql"
"log"

_ "github.com/marcboeker/go-duckdb"
"yourmodule/db"
)

func main() {
// Open DuckDB connection
conn, err := sql.Open("duckdb", ":memory:")
if err != nil {
log.Fatal(err)
}
defer conn.Close()

// Create tables
schema := `
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name VARCHAR NOT NULL,
email VARCHAR UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
`
if _, err := conn.Exec(schema); err != nil {
log.Fatal(err)
}

// Use generated queries
queries := db.New(conn)
ctx := context.Background()

// Create a user
user, err := queries.CreateUser(ctx, db.CreateUserParams{
Name: "John Doe",
Email: "john@example.com",
})
if err != nil {
log.Fatal(err)
}

log.Printf("Created user: %+v\n", user)

// Get the user
fetchedUser, err := queries.GetUser(ctx, user.ID)
if err != nil {
log.Fatal(err)
}

log.Printf("Fetched user: %+v\n", fetchedUser)
}
```

## Differences from PostgreSQL

While DuckDB supports PostgreSQL-compatible SQL, there are some differences:

1. **Data Types**: DuckDB has its own set of data types, though many are compatible with PostgreSQL
2. **Functions**: Some PostgreSQL functions may not be available or may behave differently
3. **Extensions**: DuckDB uses a different extension system than PostgreSQL

## Benefits of DuckDB

1. **Fast analytical queries**: Optimized for OLAP workloads
2. **Embedded**: No separate server process needed
3. **Portable**: Single file database
4. **PostgreSQL-compatible**: Familiar SQL syntax

## Requirements

- Go 1.24.0 or later
- `github.com/marcboeker/go-duckdb` driver

## Notes

- The DuckDB analyzer uses an in-memory instance to extract query metadata
- Schema migrations are applied to the analyzer instance automatically
- Type inference is done by preparing queries against the DuckDB instance
31 changes: 31 additions & 0 deletions examples/duckdb/db/db.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions examples/duckdb/db/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

161 changes: 161 additions & 0 deletions examples/duckdb/db/query.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions examples/duckdb/query.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-- name: GetUser :one
SELECT id, name, email, created_at
FROM users
WHERE id = $1;

-- name: ListUsers :many
SELECT id, name, email, created_at
FROM users
ORDER BY name;

-- name: CreateUser :one
INSERT INTO users (name, email)
VALUES ($1, $2)
RETURNING id, name, email, created_at;

-- name: GetUserPosts :many
SELECT p.id, p.title, p.content, p.published, p.created_at
FROM posts p
WHERE p.user_id = $1
ORDER BY p.created_at DESC;

-- name: CreatePost :one
INSERT INTO posts (user_id, title, content, published)
VALUES ($1, $2, $3, $4)
RETURNING id, user_id, title, content, published, created_at;
Loading
Loading