go-sqlbuilder
A flexible, driver-independent SQL string builder for Go with a zero-config struct-based ORM.
Repository Health
Technical Analysis
go-sqlbuilder is a Go library for constructing SQL strings and their bound arguments programmatically, designed to plug into the standard library’s sql.DB and sql.Stmt without depending on any specific database driver. It ships builders for SELECT, INSERT, UPDATE, DELETE, CREATE TABLE, UNION and CTE statements, a composable Cond type for WHERE clauses, and a special-syntax compiler (Buildf/Build/BuildNamed) that lets arbitrary raw SQL fragments, sub-builders, and positional or named arguments be mixed freely in one format string.
Beyond raw SQL construction, the package’s Struct type acts as a zero-configuration ORM: it derives SELECT/INSERT/UPDATE/DELETE builders directly from Go struct field tags (db, fieldtag, fieldopt, fieldas), including support for expanding or collapsing nested structs into JOIN projections or single JSON columns. Flavor-aware output (MySQL, PostgreSQL, SQLite, SQLServer, CQL, ClickHouse, Presto, Oracle, Informix, Doris) means the same builder can target different placeholder styles and dialect quirks, and the library has been battle-tested in production handling hundreds of millions of daily orders.
What You Get
- Pre-defined builders for SELECT, INSERT, UPDATE, DELETE, CREATE TABLE, UNION/UNION ALL, and CTE statements, each with a fluent chainable API
- A shared Cond type providing WHERE-clause condition methods (Equal, In, Like, Between, IsNull, Exists, And/Or, etc.) reusable and shareable across builders
- Struct-based zero-configuration ORM: generate SELECT/INSERT/UPDATE/DELETE builders directly from Go struct field tags, with Addr() for scanning rows back into structs
- Ten SQL dialect flavors (MySQL, PostgreSQL, SQLite, SQLServer, CQL, ClickHouse, Presto, Oracle, Informix, Doris) with dialect-aware placeholder and clause generation
- A special-syntax freestyle compiler (Buildf/Build/BuildNamed) for interleaving raw SQL, nested builders, and named/positional arguments in one format string
- Clone() support on every builder for defining reusable, concurrency-safe query templates
- Interpolate functions to inline args directly into the SQL string for drivers (e.g. Redis, Elasticsearch-style stores) that can’t bind arguments separately
Common Use Cases
- Building dynamic SQL queries with conditional WHERE clauses that vary based on request parameters, without string concatenation or SQL injection risk
- Acting as a lightweight ORM layer for scanning struct fields to/from database rows without adopting a full-featured ORM’s connection management or migrations
- Sharing a WHERE clause or a base query template across multiple statement types (e.g. reusing a SELECT’s filter in an UPDATE)
- Generating SQL for non-standard or vendor-specific systems (Hive, ClickHouse, Presto) where arbitrary raw SQL fragments need to be spliced into an otherwise standard statement
- Interpolating arguments directly into SQL text for drivers that don’t support separate argument binding
Under The Hood
Architecture go-sqlbuilder is organized as a flat, single-package library (package sqlbuilder) with one file per statement type — select.go, insert.go, update.go, delete.go, createtable.go, union.go, cte.go/ctequery.go — each defining a builder struct that embeds a shared Cond type (cond.go) for WHERE-clause construction and composes onto a common stringBuilder (stringbuilder.go) for efficient string assembly. args.go centralizes argument compilation, resolving the package’s special placeholder syntax via an Args type that every builder funnels through when calling Build(), decoupling SQL text generation from argument binding. flavor.go introduces a Flavor enum that each builder consults to vary placeholder style and dialect-specific clauses (for example, UpdateBuilder.From only emits for Postgres/SQLite/SQLServer flavors). struct.go/structfields.go layer a reflection-based mapping on top of the builders, generating pre-populated builders directly from a Go struct’s tagged fields. There’s no central builder interface enforcing a lifecycle; each builder independently exposes Build()/String() and Clone(), and cross-builder composition works because Args treats other builders as recursively compilable arguments.
Tech Stack Written in plain Go (go.mod targets go 1.18) with no database driver dependency — it only references database/sql/driver and sql.Named types for interop, never database/sql’s execution APIs. Runtime dependencies are minimal and first-party: go-huandu/go-assert, go-huandu/go-clone (backing the builders’ Clone() deep-copy semantics), and go-huandu/xstrings, plus an indirect go-spew used in test diffing. CI runs via GitHub Actions executing the Go test suite, with coverage tracked through Coveralls.
Code Quality Test coverage is extensive — seventeen _test.go files against roughly two dozen source files, essentially one test file per builder or feature area, plus a dedicated fuzz test file exercising the SELECT builder with Go’s native fuzzing support, an uncommon investment for a query-builder library. Exported APIs carry comprehensive godoc comments, including a large number of runnable Example functions used both as documentation and as tests. Errors are surfaced as consistent sentinel values rather than ad hoc strings, and naming is idiomatic Go throughout. Type safety leans on interface{}-typed arguments rather than generics, consistent with the library’s Go 1.18 floor.
API Design The public API favors fluent, chainable builder methods that read close to the SQL they produce, and pairs that with an unusual freestyle compiler — a small format-string language ($?, $0..$n, ${name}, $$) that lets raw fragments, sub-builders, and named or positional arguments be mixed in one call while still producing correctly flavor-aware placeholders. The Struct type extends this into a zero-configuration ORM: no connection setup or config step is required, it purely derives SQL and argument-scan targets from struct tags, which keeps the getting-started path short for anyone already familiar with database/sql. Nested-struct handling (expand vs. noexpand) is a thoughtful, if slightly advanced, escape hatch for JSON columns and JOIN projections.
Used by 3 apps in this directory
highlight.io
Developer Tools · Analytics · Monitoring
Open-source full-stack monitoring that unifies session replay, error tracking, logging, and distributed tracing so you can stop context-switching between tools.
OpenMeter
Invoicing Finance · Developer Tools
Open-source metering and billing engine for AI, agentic, and DevTool monetization — ingest usage events in real time and turn them into accurate invoices automatically.
SigNoz
Monitoring · Analytics
Self-host your entire observability stack — logs, metrics, traces, and LLM monitoring — in one OpenTelemetry-native platform, without the Datadog bill.