go-sqlbuilder

A flexible, driver-independent SQL string builder for Go with a zero-config struct-based ORM.

Library
Go
vv1.43.0
1,727stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
70/100Good
Development Activity64
Maintenance60
Community56
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
75/100Good
Architecture80
Code Quality88
Innovation78
Learning Curve55

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.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search