You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
sqlc supports adding custom database backends through engine plugins. This allows you to use sqlc with databases that aren't natively supported (like MyDB, CockroachDB, or other SQL-compatible databases).
3
+
Engine plugins let you use sqlc with databases that are not built-in. You can add support for other SQL-compatible systems (e.g. CockroachDB, TiDB, or custom engines) by implementing a small external program that parses SQL and returns parameters and result columns.
4
+
5
+
## Why use an engine plugin?
6
+
7
+
- Use sqlc with a database that doesn’t have native support.
8
+
- Reuse an existing SQL parser or dialect in a separate binary.
9
+
- Keep engine-specific logic outside the sqlc core.
10
+
11
+
Data returned by the engine plugin (SQL text, parameters, columns) is passed through to [codegen plugins](../guides/plugins.md) without an extra compiler/AST step. The plugin is the single place that defines how queries are interpreted for that engine.
4
12
5
13
## Overview
6
14
7
-
Engine plugins are external programs that implement the sqlc engine interface:
8
-
-**Process plugins** (Go): Communicate via **Protocol Buffers** over stdin/stdout
9
-
-**WASM plugins** (any language): Communicate via **JSON** over stdin/stdout
15
+
An engine plugin is an external process that implements one RPC:
10
16
11
-
## Compatibility Guarantee
17
+
-**Parse** — accepts the query text and either schema SQL or connection parameters, and returns processed SQL, parameter list, and result columns.
12
18
13
-
For Go process plugins, compatibility is guaranteed at **compile time**:
19
+
Process plugins (e.g. written in Go) talk to sqlc over **stdin/stdout** using **Protocol Buffers**. The schema is defined in `engine/engine.proto`.
20
+
21
+
## Compatibility
22
+
23
+
For Go plugins, compatibility is enforced at **compile time** by importing the engine package:
14
24
15
25
```go
16
26
import"github.com/sqlc-dev/sqlc/pkg/engine"
17
27
```
18
28
19
-
When you import this package:
20
-
- If your plugin compiles successfully → it's compatible with this version of sqlc
21
-
- If types change incompatibly → your plugin won't compile until you update it
29
+
- If the plugin builds, it matches this version of the engine API.
30
+
- If the API changes in a breaking way, the plugin stops compiling until it’s updated.
22
31
23
-
The Protocol Buffer schema ensures binary compatibility. No version negotiation needed.
32
+
No version handshake is required; the proto schema defines the contract.
24
33
25
34
## Configuration
26
35
@@ -29,223 +38,138 @@ The Protocol Buffer schema ensures binary compatibility. No version negotiation
29
38
```yaml
30
39
version: "2"
31
40
32
-
# Define engine plugins
33
41
engines:
34
42
- name: mydb
35
43
process:
36
44
cmd: sqlc-engine-mydb
37
45
env:
38
-
- MYDB_CONNECTION_STRING
46
+
- MYDB_DSN
39
47
40
48
sql:
41
-
- engine: mydb# Use the MyDB engine
49
+
- engine: mydb
42
50
schema: "schema.sql"
43
51
queries: "queries.sql"
44
-
gen:
45
-
go:
46
-
package: db
52
+
codegen:
53
+
- plugin: go
47
54
out: db
48
55
```
49
56
50
-
### Configuration Options
57
+
### Engine options
51
58
52
59
| Field | Description |
53
60
|-------|-------------|
54
-
| `name` | Unique name for the engine (used in `sql[].engine`) |
55
-
| `process.cmd` | Command to run (must be in PATH or absolute path) |
56
-
| `wasm.url` | URL to download WASM module (`file://` or `https://`) |
57
-
| `wasm.sha256` | SHA256 checksum of the WASM module |
58
-
| `env` | Environment variables to pass to the plugin |
61
+
| `name` | Engine name used in `sql[].engine` |
62
+
| `process.cmd` | Command to run (PATH or absolute path) |
63
+
| `env` | Environment variables passed to the plugin |
59
64
60
-
## Creating a Go Engine Plugin
65
+
## Implementing an engine plugin (Go)
61
66
62
-
### 1. Import the SDK
63
-
64
-
```go
65
-
import "github.com/sqlc-dev/sqlc/pkg/engine"
66
-
```
67
-
68
-
### 2. Implement the Handler
67
+
### 1. Dependencies and entrypoint
69
68
70
69
```go
71
70
package main
72
71
73
-
import (
74
-
"github.com/sqlc-dev/sqlc/pkg/engine"
75
-
)
72
+
import "github.com/sqlc-dev/sqlc/pkg/engine"
76
73
77
74
func main() {
78
75
engine.Run(engine.Handler{
79
-
PluginName: "mydb",
80
-
PluginVersion: "1.0.0",
81
-
Parse: handleParse,
82
-
GetCatalog: handleGetCatalog,
83
-
IsReservedKeyword: handleIsReservedKeyword,
84
-
GetCommentSyntax: handleGetCommentSyntax,
85
-
GetDialect: handleGetDialect,
76
+
PluginName: "mydb",
77
+
PluginVersion: "1.0.0",
78
+
Parse: handleParse,
86
79
})
87
80
}
88
81
```
89
82
90
-
### 3. Implement Methods
83
+
The engine API exposes only **Parse**. There are no separate methods for catalog, keywords, comment syntax, or dialect.
Parameter and column types use the `Parameter` and `Column` messages in `engine.proto` (name, position, data_type, nullable, is_array, array_dims; for columns, table_name and schema_name are optional).
167
125
168
-
Returns SQL dialect information for formatting.
126
+
Support for sqlc placeholders (`sqlc.arg()`, `sqlc.narg()`, `sqlc.slice()`, `sqlc.embed()`) is up to the plugin: it can parse and map them into `parameters` (and schema usage) as needed.
See `examples/plugin-based-codegen/` for a complete engine plugin implementation.
153
+
A minimal engine that parses SQLite-style SQL and expands `*` using a schema is in this repository under `examples/plugin-based-codegen/plugins/sqlc-engine-sqlite3/`. It pairs with the Rust codegen example in the same `plugin-based-codegen` sample.
0 commit comments