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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 53 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ POSTGRESQL_SERVER_URI="postgres://postgres:mysecretpassword@localhost:5432/postg
- `/cmd/` - Main binaries (sqlc, sqlc-gen-json)
- `/internal/cmd/` - Command implementations (vet, generate, etc.)
- `/internal/engine/` - Database engine implementations
- `/clickhouse/` - ClickHouse parser and converter
- `/postgresql/` - PostgreSQL parser and converter
- `/dolphin/` - MySQL parser (uses TiDB parser)
- `/sqlite/` - SQLite parser
Expand Down Expand Up @@ -289,20 +290,71 @@ git push --force-with-lease origin <feature-branch>
- **CI Configuration:** `/.github/workflows/ci.yml`
- **Docker Compose:** `/docker-compose.yml`

## ClickHouse Engine Support

### Implementation Details

The ClickHouse engine was added to support ClickHouse SQL parsing and code generation using the `github.com/AfterShip/clickhouse-sql-parser` library.

**Files involved:**
- `internal/engine/clickhouse/parse.go` - Parser implementation
- `internal/engine/clickhouse/convert.go` - AST converter
- `internal/engine/clickhouse/catalog.go` - Catalog initialization
- `internal/config/config.go` - Engine constant registration
- `internal/compiler/engine.go` - Compiler integration
- `internal/compiler/expand.go` - Quote character handling
- `examples/clickhouse/` - Example project

**Key features:**
- Parses ClickHouse SQL into sqlc's internal AST
- Supports comment syntax: `--` and `/* */`
- Uses backticks for identifier quoting (ClickHouse standard)
- Handles ClickHouse-specific keywords

**Testing:**
```bash
# Test ClickHouse engine (unit tests)
go test ./internal/engine/clickhouse -v

# Test compiler integration
go test ./internal/compiler -v -run TestNewCompilerClickHouse

# Test code generation
cd examples/clickhouse && /path/to/sqlc generate && go mod init github.com/example/clickhouse && go mod tidy && go build ./gen
```

**Test Coverage:**
- Basic SELECT queries with WHERE, ORDER BY, LIMIT
- INSERT statements with VALUES
- Aggregate queries (COUNT, SUM, AVG) with GROUP BY and HAVING
- UNION and UNION ALL queries
- Subqueries and derived tables
- Multiple JOINs (INNER, LEFT, RIGHT, FULL)
- Window functions with OVER clause
- CAST expressions
- CASE expressions
- IS NULL / IS NOT NULL expressions
- Unary expressions (NOT, negation)
- Number literals (int, float, scientific notation)
- String literals and functions
- ClickHouse-specific features (PREWHERE, SAMPLE, array functions)

## Recent Fixes & Improvements

### Fixed Issues

1. **Typo in create_function_stmt.go** - Fixed "Undertand" → "Understand"
2. **Race condition in vet.go** - Fixed Client initialization using `sync.Once`
3. **Nil pointer dereference in parse.go** - Fixed unsafe type assertion in primary key parsing
4. **ClickHouse engine addition** - Added full ClickHouse SQL support with AST parsing

These fixes demonstrate common patterns:
- Using `sync.Once` for thread-safe lazy initialization
- Using comma-ok idiom for safe type assertions: `if val, ok := x.(Type); ok { ... }`
- Adding proper nil checks and defensive programming
- Registering new database engines following the established pattern

---

**Last Updated:** 2025-10-21
**Last Updated:** 2025-11-19
**Maintainer:** Claude Code
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ test:
go test ./...

test-managed:
MYSQL_SERVER_URI="invalid" POSTGRESQL_SERVER_URI="postgres://postgres:mysecretpassword@localhost:5432/postgres" go test -v ./...
MYSQL_SERVER_URI="invalid" POSTGRESQL_SERVER_URI="postgres://postgres:mysecretpassword@localhost:5432/postgres" CLICKHOUSE_SERVER_URI="localhost:9000" go test ./...

vet:
go vet ./...
Expand Down
7 changes: 7 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,10 @@ services:
POSTGRES_DB: postgres
POSTGRES_PASSWORD: mysecretpassword
POSTGRES_USER: postgres

clickhouse:
image: "clickhouse:lts"
ports:
- "9000:9000"
- "8123:8123"
restart: always
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ code ever again.
tutorials/getting-started-mysql.md
tutorials/getting-started-postgresql.md
tutorials/getting-started-sqlite.md
tutorials/getting-started-clickhouse.md

.. toctree::
:maxdepth: 2
Expand Down
7 changes: 4 additions & 3 deletions docs/reference/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Each mapping in the `sql` collection has the following keys:
- `name`:
- An human-friendly identifier for this query set. Optional.
- `engine`:
- One of `postgresql`, `mysql` or `sqlite`.
- One of `postgresql`, `mysql`, `sqlite` or `clickhouse`.
- `schema`:
- Directory of SQL migrations or path to single SQL file; or a list of paths.
- `queries`:
Expand Down Expand Up @@ -134,7 +134,8 @@ The `gen` mapping supports the following keys:
- `out`:
- Output directory for generated code.
- `sql_package`:
- Either `pgx/v4`, `pgx/v5` or `database/sql`. Defaults to `database/sql`.
- Either `pgx/v4`, `pgx/v5`, `database/sql` or `clickhouse/v2`. Defaults to `database/sql`.
- For ClickHouse, use `clickhouse/v2` for the native driver or omit for `database/sql` compatibility.
- `sql_driver`:
- Either `github.com/jackc/pgx/v4`, `github.com/jackc/pgx/v5`, `github.com/lib/pq` or `github.com/go-sql-driver/mysql`. No defaults. Required if query annotation `:copyfrom` is used.
- `emit_db_tags`:
Expand All @@ -158,7 +159,7 @@ The `gen` mapping supports the following keys:
- `emit_methods_with_db_argument`:
- If true, generated methods will accept a DBTX argument instead of storing a DBTX on the `*Queries` struct. Defaults to `false`.
- `emit_pointers_for_null_types`:
- If true, generated types for nullable columns are emitted as pointers (ie. `*string`) instead of `database/sql` null types (ie. `NullString`). Currently only supported for PostgreSQL if `sql_package` is `pgx/v4` or `pgx/v5`, and for SQLite. Defaults to `false`.
- If true, generated types for nullable columns are emitted as pointers (ie. `*string`) instead of `database/sql` null types (ie. `NullString`). Currently only supported for PostgreSQL if `sql_package` is `pgx/v4` or `pgx/v5`, SQLite, and ClickHouse if `sql_package` is `clickhouse/v2`. Defaults to `false`.
- `emit_enum_valid_method`:
- If true, generate a Valid method on enum types,
indicating whether a string is a valid enum value.
Expand Down
83 changes: 81 additions & 2 deletions docs/reference/datatypes.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ If you're unsatisfied with the default, you can override any type using the

## Arrays

PostgreSQL [arrays](https://www.postgresql.org/docs/current/arrays.html) are
materialized as Go slices.
PostgreSQL [arrays](https://www.postgresql.org/docs/current/arrays.html) are materialized as Go slices.

```sql
CREATE TABLE places (
Expand All @@ -27,6 +26,24 @@ type Place struct {
}
```

ClickHouse [array types](https://clickhouse.com/docs/en/sql-reference/data-types/array) are similarly mapped to Go slices:

```sql
CREATE TABLE data (
tags Array(String),
ids Array(UInt32)
);
```

```go
package db

type Data struct {
Tags []string
IDs []uint32
}
```

## Dates and times

All date and time types are returned as `time.Time` structs. For
Expand Down Expand Up @@ -60,6 +77,28 @@ type Author struct {
}
```

ClickHouse `DateTime` and `Date` types are also mapped to `time.Time`:

```sql
CREATE TABLE events (
created_at DateTime,
event_date Date
);
```

```go
package db

import (
"time"
)

type Event struct {
CreatedAt time.Time
EventDate time.Time
}
```

## Enums

PostgreSQL [enums](https://www.postgresql.org/docs/current/datatype-enum.html) are
Expand Down Expand Up @@ -120,6 +159,46 @@ type Author struct {
}
```

ClickHouse uses `Nullable(T)` for nullable columns. When using the native `clickhouse/v2`
driver with `emit_pointers_for_null_types: true`, nullable fields are represented as
pointers. With `database/sql`, they use the standard `sql.Null*` types:

```sql
CREATE TABLE articles (
id UInt64,
title String,
bio Nullable(String)
);
```

With `clickhouse/v2` and `emit_pointers_for_null_types: true`:

```go
package db

type Article struct {
ID uint64
Title string
Bio *string
}
```

With `database/sql`:

```go
package db

import (
"database/sql"
)

type Article struct {
ID uint64
Title string
Bio sql.NullString
}
```

## UUIDs

The Go standard library does not come with a `uuid` package. For UUID support,
Expand Down
18 changes: 9 additions & 9 deletions docs/reference/language-support.rst
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
Database and language support
#############################

========== ======================= ============ ============ ===============
Language Plugin MySQL PostgreSQL SQLite
========== ======================= ============ ============ ===============
Go (built-in) Stable Stable Beta
Go `sqlc-gen-go`_ Stable Stable Beta
Kotlin `sqlc-gen-kotlin`_ Beta Beta Not implemented
Python `sqlc-gen-python`_ Beta Beta Not implemented
TypeScript `sqlc-gen-typescript`_ Beta Beta Not implemented
========== ======================= ============ ============ ===============
========== ======================= ============ ============ =============== ===============
Language Plugin MySQL PostgreSQL SQLite ClickHouse
========== ======================= ============ ============ =============== ===============
Go (built-in) Stable Stable Beta Beta
Go `sqlc-gen-go`_ Stable Stable Beta Beta
Kotlin `sqlc-gen-kotlin`_ Beta Beta Not implemented Not implemented
Python `sqlc-gen-python`_ Beta Beta Not implemented Not implemented
TypeScript `sqlc-gen-typescript`_ Beta Beta Not implemented Not implemented
========== ======================= ============ ============ =============== ===============

Community language support
**************************
Expand Down
Loading
Loading