gooq

package module
v0.0.0-...-ef8fc4b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 31, 2026 License: MIT Imports: 8 Imported by: 0

README

gooq

Go Reference Go Report Card CI Go Version

A type-safe, fluent, zero-dependency SQL query builder for Go, inspired by jOOQ. gooq gives you parametric Field[T] columns whose comparison methods reject mismatched types at compile time, positional RecordN row types that preserve each projected column's Go type by position, step interfaces that turn clause order into a compile-time concern (you cannot place WHERE after GROUP BY, but you may omit it entirely), and runtime dialect translation: a query is built once as a detached abstract syntax tree and rendered to dialect-specific SQL for PostgreSQL and SQLite at execution time.

[!WARNING] Alpha. This project is in early, active development. The public API, wire behaviour, and module layout may change without notice between releases, and it has not been hardened for production use. There are no tagged releases yet: dependencies resolve to a commit, so pin an exact commit (a pseudo-version such as v0.0.0-<date>-<commit>) and review the change history before upgrading. See the disclaimer.

Motivation

I have written Go for many years, and I have never found a library that lets me build fully typed, composable SQL queries the way jOOQ does in Java. The Go ecosystem is rich, but each option I tried gave up something essential:

  • SQLBoiler generates typed models from a live schema, which is the right idea, but it follows the Active Record pattern: the generated query surface is shaped around row objects and their relations, which constrains how you express the schema and how far you can go with ad-hoc projections and dynamic query composition.
  • pgx is an excellent PostgreSQL driver, but it is not typed at the query level. Queries are strings, results are scanned by hand, and a schema change does not break the build — it breaks at runtime, often far from the query that is now wrong.
  • GORM does a lot of implicit work through struct tags, hooks, and auto-migration. The "magic" is convenient until it produces surprising behaviour, and much of it resolves through runtime reflection rather than the compiler.
  • ent is powerful, but it is a code-first entity/graph framework with its own DSL; it does not read like SQL and steers you toward its own model of the world.
  • sqlc generates excellent typed Go from hand-written SQL, but the queries are static: there is no dynamic, programmatic query builder for predicates assembled at runtime.
  • squirrel is a fluent builder, but columns are plain strings and values are interface{}, so there is no type safety and no schema awareness.
  • go-jet is the closest in spirit — schema code generation plus a typed-ish builder — but its typing is by category (ColumnString, ColumnInteger, ...) rather than the real Go type via Field[T], it has no step interfaces to enforce clause order at compile time, and the dialect is fixed at generation time rather than chosen at render time.

The gap is real: nothing in Go combines live-database code generation, parametric Field[T] columns, positional RecordN rows, step interfaces that enforce clause order, and runtime dialect translation — the exact combination that makes jOOQ feel like typed SQL rather than "strings with autocomplete". Go 1.18+ generics finally make that design viable.

So I decided to build a port of jOOQ's ideas to Go, adapted to Go's syntactic constraints rather than copied from Java or Kotlin. Some of jOOQ's ergonomics do not translate directly — Go methods cannot have their own type parameters (hence top-level Select1Select22 instead of overloaded select), there is no operator overloading (hence EQ/GT/Like methods), and varargs are not generic (hence the generated RecordN arities). The result keeps jOOQ's core promise — SQL the compiler checks — while staying idiomatic Go.

Features

  • Type-safe columns. A Field[T] accepts only values of its own type T, so db.Book.Price.GT(10) compiles while comparing a price against a string does not.
  • Positional typed results. Select1 through Select22 return SelectFromStep[RecordN[...]], and each fetched row preserves the projected column types by position (row.V1, row.V2, ...).
  • Compile-time clause order. Each builder method returns the interface describing the clauses that may legally follow, encoding the legal SQL grammar in the type system.
  • Runtime dialect translation. One abstract syntax tree renders to PostgreSQL and SQLite through SQLFor or Using, including dialect-specific placeholders, identifier quoting, RETURNING, and upsert syntax.
  • Full DML coverage. SELECT (with joins, GROUP BY, HAVING, ORDER BY, LIMIT/OFFSET), INSERT (with ON CONFLICT upserts and RETURNING), UPDATE, and DELETE.
  • Composable predicates. A Condition is itself a Field[bool], so it can be stored in a variable and combined with And, Or, and Not.
  • Code generation. gooq-gen introspects information_schema and emits typed table accessors.
  • Zero dependencies. The core module imports nothing outside the standard library and ships no database driver; you blank-import your own.

Install

Because there are no tagged releases yet, go get resolves to the latest commit and records a pseudo-version pinned to that commit hash:

go get github.com/cgardev/gooq@latest

To pin a specific commit explicitly:

go get github.com/cgardev/gooq@<commit-hash>

The recorded version in go.mod will look like v0.0.0-<date>-<commit> until the first tagged release.

Quick start

The examples below use a generated db package (see Code generation). For a book table, the generator produces typed accessors such as db.Book.Title (a StringField) and db.Book.Price (a NumericField[float64]).

SELECT
package main

import (
	"context"
	"database/sql"
	"fmt"

	_ "github.com/jackc/pgx/v5/stdlib" // your driver, blank-imported

	"github.com/cgardev/gooq"
	"github.com/cgardev/gooq/example/internal/db"
)

func main() {
	conn, err := sql.Open("pgx", "postgres://localhost:5432/library?sslmode=disable")
	if err != nil {
		panic(err)
	}
	defer conn.Close()

	ctx := context.Background()

	// db.Book.Price is a NumericField[float64], so GT requires a float64;
	// a mismatched type would be a compile error, not a runtime surprise.
	rows, err := gooq.Select2(db.Book.Title, db.Book.Price).
		From(db.Book).
		Where(db.Book.Price.GT(10)).
		OrderBy(db.Book.Title.Asc()).
		Limit(20).
		Fetch(ctx, conn)
	if err != nil {
		panic(err)
	}

	// Each row is a Record2[string, float64]; the column types are preserved
	// by position.
	for _, row := range rows {
		fmt.Printf("%s: %.2f\n", row.V1, row.V2)
	}
}

Fetch returns every matching row. To read a single row, use FetchOne (returns the zero value when nothing matches and gooq.ErrTooManyRows when more than one matches) or FetchSingle (returns sql.ErrNoRows when nothing matches). The conn argument is a gooq.Querier, satisfied by *sql.DB, *sql.Tx, and *sql.Conn.

One AST, two dialects

The query is rendered, not re-built, so the same value produces SQL for every dialect via SQLFor:

q := gooq.Select2(db.Book.Title, db.Book.Price).
	From(db.Book).
	Where(db.Book.Price.GT(10)).
	OrderBy(db.Book.Title.Asc()).
	Limit(20)

pg, args, _ := q.SQLFor(gooq.Postgres())
sq, _, _ := q.SQLFor(gooq.SQLite())

fmt.Println(pg)   // SELECT "book"."title", "book"."price" FROM "book" WHERE "book"."price" > $1 ORDER BY "book"."title" ASC LIMIT 20
fmt.Println(sq)   // SELECT "book"."title", "book"."price" FROM "book" WHERE "book"."price" > ? ORDER BY "book"."title" ASC LIMIT 20
fmt.Println(args) // [10]

Call Using(dialect) to bind a dialect for the terminal SQL, Fetch, FetchOne, and FetchSingle methods; the default is gooq.Postgres().

INSERT with upsert

SetToExcluded sets a column to the value the conflicting INSERT attempted to write (EXCLUDED.col on PostgreSQL and excluded.col on SQLite):

_, err := gooq.InsertInto(db.Book).
	Columns(db.Book.Id, db.Book.Title, db.Book.Price).
	Values(int64(1), "The Go Programming Language", 39.99).
	OnConflict(db.Book.Id).
	DoUpdateSet(gooq.SetToExcluded(db.Book.Title), gooq.SetToExcluded(db.Book.Price)).
	Execute(ctx, conn)

Use OnConflictDoNothing() to ignore the conflict. Returning(cols...) is available on both PostgreSQL and SQLite.

UPDATE
_, err := gooq.Update(db.Book).
	Set(db.Book.Price.Set(29.99)).
	Where(db.Book.Id.EQ(1)).
	Execute(ctx, conn)
DELETE
_, err := gooq.DeleteFrom(db.Book).
	Where(db.Book.Price.LT(5)).
	Returning(db.Book.Id).
	Execute(ctx, conn)

Update, DeleteFrom, and InsertInto all return sql.Result from Execute. To read a RETURNING projection, render the statement with SQL() and run it through QueryRowContext/QueryContext:

query, args, err := gooq.DeleteFrom(db.Book).
	Where(db.Book.Id.EQ(1)).
	Returning(db.Book.Id).
	SQL()
if err != nil {
	panic(err)
}

var id int64
err = conn.QueryRowContext(ctx, query, args...).Scan(&id)
Composable conditions

A Condition is a Field[bool], so predicates can be stored and combined:

cheap := db.Book.Price.LT(10)
goBook := db.Book.Title.Like("Go%")

rows, err := gooq.Select1(db.Book.Id).
	From(db.Book).
	Where(cheap.And(goBook)).
	Fetch(ctx, conn)
Joins with aliased tables
a := db.Author.As("a")

rows, err := gooq.Select2(db.Book.Title, a.Name).
	From(db.Book).
	LeftJoin(a).On(db.Book.AuthorId.EQField(a.Id)).
	Fetch(ctx, conn)

Code generation

The gooq-gen command introspects a live database through the standard information_schema catalog. For each table it writes a <table>.gen.go file containing an embedded gooq.TableImpl, one typed Field per column, an As method for aliasing, and a package-level accessor variable. The example accessor for a book table looks like:

// Code generated by gooq-gen; DO NOT EDIT.

package db

import (
	"github.com/cgardev/gooq"
)

type bookTable struct {
	gooq.TableImpl
	Id       gooq.NumericField[int64]
	Title    gooq.StringField
	Price    gooq.NumericField[float64]
	AuthorId gooq.NumericField[int64]
}

func newBookTable(alias string) *bookTable {
	base := gooq.NewTable("book").WithAlias(alias)
	return &bookTable{
		TableImpl: base,
		Id:        gooq.NewNumericField[int64](base, "id"),
		Title:     gooq.NewStringField(base, "title"),
		Price:     gooq.NewNumericField[float64](base, "price"),
		AuthorId:  gooq.NewNumericField[int64](base, "author_id"),
	}
}

var Book = newBookTable("")

The library itself imports no database driver, so the generator is built with your driver blank-imported. Run it directly with go run:

go run github.com/cgardev/gooq/cmd/gooq-gen -dsn "postgres://localhost:5432/library?sslmode=disable" -o internal/db

Flags: -driver (the database/sql driver name, default postgres), -dsn (required), -schema (default public), -o (output directory, default internal/db), and -package (default db). Because the command opens the connection through database/sql, the chosen driver must be blank-imported into the build, for example _ "github.com/lib/pq" for PostgreSQL or _ "modernc.org/sqlite" for SQLite.

Column type mapping

Non-nullable columns map to the refined field types: integers to gooq.NumericField[int64], floating and fixed-point types to gooq.NumericField[float64], booleans to gooq.Field[bool], temporal types to gooq.Field[time.Time], text types to gooq.StringField, binary types to gooq.Field[[]byte], and json/jsonb to gooq.Field[json.RawMessage].

Nullable columns whose element is a scalar are wrapped in the generic sql.Null[T] type, for example a nullable text column becomes gooq.Field[sql.Null[string]] and a nullable timestamp becomes gooq.Field[sql.Null[time.Time]]. Byte slices already scan NULL as nil, so they are left unwrapped; a nullable json/jsonb column maps to a plain gooq.Field[[]byte], because database/sql cannot scan a NULL driver value into the named json.RawMessage slice type.

Dialects

gooq targets the latest two PostgreSQL majors (18 and 17) and SQLite. The SQLite support is tested with the pure-Go modernc.org/sqlite driver.

Capability Postgres() SQLite()
Bind placeholders $1, $2, ... ?
Identifier quoting "name" "name"
Boolean literals TRUE / FALSE 1 / 0
RETURNING yes yes
Upsert syntax ON CONFLICT (...) DO UPDATE / DO NOTHING ON CONFLICT (...) DO UPDATE / DO NOTHING
Excluded-row reference EXCLUDED.col excluded.col

ILike renders as ILIKE on PostgreSQL and as a plain LIKE on SQLite, whose LIKE is already case-insensitive for ASCII text.

Testing

The dependency-free core module is tested with the standard toolchain:

go test ./...

Database integration tests live in a separate module under ./integration, kept apart on purpose so that consuming gooq never pulls in their dependencies. They start a real PostgreSQL instance through testcontainers, so Docker must be available. Run them from the integration module:

go test ./...        # run inside ./integration; requires Docker

Pass -short to skip the container-backed tests:

go test ./... -short # inside ./integration, skips tests that require Docker

Status and roadmap

[!WARNING] Alpha — read before depending on this. The library is under early, active development and is not hardened for production use. The public API, the generated-code layout, and the module structure may change without notice. No versions are tagged yet, so the module is consumed by commit: every go get resolves to a pseudo-version of the form v0.0.0-<date>-<commit>. Pin an exact commit and review the change history before upgrading.

Implemented and covered by tests:

  • SELECT with joins, WHERE/AND/OR, GROUP BY, HAVING, ORDER BY, and LIMIT/OFFSET
  • INSERT, UPDATE, and DELETE
  • RETURNING on PostgreSQL and SQLite
  • Upserts (ON CONFLICT ... DO UPDATE / DO NOTHING)
  • Field[T] arities Select1 through Select22 with positional RecordN results
  • PostgreSQL and SQLite dialect rendering
  • Schema-driven code generation via gooq-gen

Not yet implemented:

  • Common table expressions (CTEs)
  • Window functions

Acknowledgements and trademarks

gooq is an independent, clean-room reimplementation of jOOQ's design ideas in Go. It contains no jOOQ source code; the Go code here is original. jOOQ's Open Source Edition is published by Data Geekery GmbH under the Apache License 2.0, a permissive licence, and reimplementing an API or design in a new language is well-established practice. This project draws inspiration from that design with gratitude.

jOOQ is a registered trademark of Data Geekery GmbH. gooq is not affiliated with, endorsed by, or sponsored by Data Geekery GmbH or the jOOQ project. The name "jOOQ" is used here only nominatively, to describe the design gooq is inspired by.

License

gooq is released under the MIT License, Copyright (c) 2026 Cristian Garcia. This is your own original work; you are free to license it under MIT.

Documentation

Overview

Package jooq provides a type-safe, fluent SQL query builder for Go inspired by the Java library jOOQ. It combines parametric Field[T] columns, positional RecordN row types, step interfaces that make the clause order a compile-time concern, and runtime dialect translation from a single abstract syntax tree.

The package has no external dependencies. Queries are built as a detached abstract syntax tree and rendered to dialect-specific SQL at execution time, so the same query can target PostgreSQL or SQLite.

Index

Constants

This section is empty.

Variables

View Source
var ErrColumnValueMismatch = errors.New("jooq: column count does not match value count")

ErrColumnValueMismatch is recorded when an inserted row has a different number of values than there are columns.

View Source
var ErrEmptyInsert = errors.New("jooq: INSERT has no columns or values")

ErrEmptyInsert is recorded when an INSERT statement has neither columns nor a DEFAULT VALUES marker.

View Source
var ErrReturningUnsupported = errors.New("jooq: RETURNING is not supported by this dialect")

ErrReturningUnsupported is recorded when a RETURNING clause is requested for a dialect that does not support it. Both supported dialects (PostgreSQL and SQLite) render RETURNING natively, so this sentinel exists as a defensive guard for any dialect whose supportsReturning reports false.

View Source
var ErrTooManyRows = errors.New("jooq: query returned more than one row")

ErrTooManyRows is returned by FetchOne and FetchSingle when a query yields more rows than the caller expected.

View Source
var ErrUsingUnsupported = errors.New("gooq: DELETE ... USING is not supported by this dialect")

ErrUsingUnsupported is recorded when a DELETE ... USING clause is rendered for a dialect that does not support it. Only PostgreSQL supports DELETE ... USING; SQLite does not.

Functions

func BatchExec

func BatchExec(ctx context.Context, db Querier, steps ...interface {
	SQL() (string, []any, error)
}) ([]sql.Result, error)

BatchExec renders and executes each statement in order against the given Querier, returning the result of every executed statement. Each step is any value exposing an SQL method, which every terminal INSERT, UPDATE, and DELETE builder satisfies. Execution stops at the first error: the slice returned alongside a non-nil error holds the results of the steps that ran before the failure. Rendering and execution share no transaction; wrap the call in one by passing a *sql.Tx as the Querier.

func FetchGroups

func FetchGroups[K comparable, S any](ctx context.Context, db Querier, q statement, keyColumn string) (map[K][]S, error)

FetchGroups runs the statement, maps each row into a value of S, and groups the results by the value of keyColumn cast to K. The keyColumn must name one of the columns selected by the statement. Rows that share a key are appended to the same slice in result order.

func FetchInto

func FetchInto[S any](ctx context.Context, db Querier, q statement) ([]S, error)

FetchInto runs the supplied statement and maps every result row into a new value of the struct type S, returning the resulting slice.

Columns are matched to struct fields by the `db` struct tag; a field tagged `db:"col"` receives the value of the result column named "col". When a field has no db tag, its Go field name is matched case-insensitively against the column name. Result columns without a matching exported struct field are skipped. Pointer fields and types implementing the standard library sql.Scanner interface are supported, as are values implementing driver.Valuer. The error returned by rows.Err is propagated.

func FetchMap

func FetchMap[K comparable, S any](ctx context.Context, db Querier, q statement, keyColumn string) (map[K]S, error)

FetchMap runs the statement, maps each row into a value of S, and indexes the results by the value of keyColumn cast to K. The keyColumn must name one of the columns selected by the statement. When two rows share a key, the later row overwrites the earlier one.

func FetchOneInto

func FetchOneInto[S any](ctx context.Context, db Querier, q statement) (S, error)

FetchOneInto runs the statement and returns a single mapped row. It returns the zero value of S and a nil error when no row matches, the single row when exactly one matches, or ErrTooManyRows when more than one row matches.

func ReturningInto

func ReturningInto[S any](ctx context.Context, db Querier, step statement) ([]S, error)

ReturningInto executes a data-manipulation statement that renders a RETURNING clause and maps the returned rows into a slice of the struct type S.

Methods cannot introduce their own type parameters, so the typed RETURNING surface is exposed as a free generic function. The INSERT, UPDATE, and DELETE builders already render a RETURNING projection when Returning was called and already expose a SQL method, so the statement is run through QueryContext and its rows are mapped with the same plan FetchInto uses.

func ReturningOneInto

func ReturningOneInto[S any](ctx context.Context, db Querier, step statement) (S, error)

ReturningOneInto executes a RETURNING statement and returns a single mapped row. It returns the zero value of S and a nil error when no row is returned, the single row when exactly one is returned, or ErrTooManyRows when more than one row is returned.

func WithTx

func WithTx(ctx context.Context, db *sql.DB, fn func(tx *sql.Tx) error) (err error)

WithTx runs fn inside a database transaction. The transaction is started with BeginTx and is committed when fn returns a nil error. When fn returns an error the transaction is rolled back and the returned error joins fn's error with any rollback error. When fn panics the transaction is rolled back and the panic is re-raised after the rollback completes.

The *sql.Tx passed to fn satisfies Querier, so every statement builder can be executed against it and participates in the same transaction.

Types

type AnyField

type AnyField interface {

	// Name returns the unqualified column or expression name.
	Name() string
	// contains filtered or unexported methods
}

AnyField is a type-erased field usable where the element type does not matter: projection column lists, GROUP BY, INSERT column lists, and RETURNING.

func Star

func Star() AnyField

Star returns a field rendering an unqualified "*". It is type-erased because a wildcard has no single column type; use it as the argument to Function or in a projection where the element type does not matter.

type Assignment

type Assignment interface {
	// contains filtered or unexported methods
}

Assignment is a "column = value" pair used by UPDATE ... SET, by INSERT upsert update actions, and by INSERT ... SET. It is produced by Field[T].Set.

func SetToExcluded

func SetToExcluded(f AnyField) Assignment

SetToExcluded builds an upsert assignment that sets a column to the value the conflicting INSERT attempted to write (EXCLUDED.col in PostgreSQL and excluded.col in SQLite). It is used inside DoUpdateSet.

type CaseBuilder

type CaseBuilder[T any] struct {
	// contains filtered or unexported fields
}

CaseBuilder accumulates the branches of a searched CASE expression. It is returned by Case and finalised with End, which yields a typed Field[T].

func Case

func Case[T any]() CaseBuilder[T]

Case begins a searched CASE expression producing values of type T.

func (CaseBuilder[T]) Else

func (c CaseBuilder[T]) Else(v T) CaseBuilder[T]

Else sets the ELSE result of the CASE expression, binding its value as an argument. Calling Else more than once replaces the previous ELSE value.

func (CaseBuilder[T]) End

func (c CaseBuilder[T]) End() Field[T]

End finalises the CASE expression and returns it as a typed Field[T].

func (CaseBuilder[T]) When

func (c CaseBuilder[T]) When(cond Condition, then T) CaseBuilder[T]

When adds a "WHEN condition THEN value" branch whose result value binds as an argument.

func (CaseBuilder[T]) WhenField

func (c CaseBuilder[T]) WhenField(cond Condition, then Field[T]) CaseBuilder[T]

WhenField adds a "WHEN condition THEN field" branch whose result renders as the given field's column or expression rather than binding a value.

type Condition

type Condition interface {
	Field[bool]
	And(other Condition) Condition
	Or(other Condition) Condition
	Not() Condition
}

Condition is a boolean predicate. Mirroring jOOQ, a Condition is itself a Field[bool], so it can be projected, compared, and stored in a variable, in addition to being combined with And, Or, and Not.

func And

func And(conds ...Condition) Condition

And combines the given conditions into a single conjunction rendered as one flat, parenthesized "(a AND b AND c)" group rather than nested pairs. With a single condition it returns that condition unchanged; with no conditions it returns True.

func Exists

func Exists(sub Subquery) Condition

Exists returns a Condition rendering "EXISTS (SELECT ...)" over the given subquery. The subquery renders into the same builder as the surrounding statement, so its bind arguments are numbered in render order.

func False

func False() Condition

False returns a condition that never holds, rendered as the constant predicate "1 = 0".

func Not

func Not(c Condition) Condition

Not negates the given condition, rendering "NOT (condition)".

func NotExists

func NotExists(sub Subquery) Condition

NotExists returns a Condition rendering "NOT EXISTS (SELECT ...)" over the given subquery.

func Or

func Or(conds ...Condition) Condition

Or combines the given conditions into a single disjunction rendered as one flat, parenthesized "(a OR b OR c)" group rather than nested pairs. With a single condition it returns that condition unchanged; with no conditions it returns False.

func RawCondition

func RawCondition(sql string) Condition

RawCondition is an escape hatch that splices verbatim SQL into the query as a boolean predicate, binding no arguments.

func True

func True() Condition

True returns a condition that always holds, rendered as the constant predicate "1 = 1".

type DeleteConditionStep

type DeleteConditionStep interface {
	DeleteReturningStep
	And(c Condition) DeleteConditionStep
	Or(c Condition) DeleteConditionStep
}

DeleteConditionStep allows extending the WHERE predicate.

type DeleteFinalStep

type DeleteFinalStep interface {
	SQL() (string, []any, error)
	SQLFor(d Dialect) (string, []any, error)
	Using(d Dialect) DeleteFinalStep
	Execute(ctx context.Context, db Querier) (sql.Result, error)
	// contains filtered or unexported methods
}

DeleteFinalStep is the terminal state.

type DeleteReturningStep

type DeleteReturningStep interface {
	DeleteFinalStep
	Returning(cols ...AnyField) DeleteFinalStep
}

DeleteReturningStep allows a RETURNING clause before terminal execution.

type DeleteWhereStep

type DeleteWhereStep interface {
	DeleteReturningStep
	Where(c Condition) DeleteConditionStep
	// UsingTable joins a further table into the DELETE through a USING clause,
	// rendered before WHERE. Only PostgreSQL supports DELETE ... USING; the
	// SQLite dialect records ErrUsingUnsupported. This clause is named
	// UsingTable rather than Using because Using is reserved on the terminal
	// step for selecting the rendering dialect.
	UsingTable(t Table) DeleteWhereStep
}

DeleteWhereStep is the entry state after DELETE FROM table.

func DeleteFrom

func DeleteFrom(t Table) DeleteWhereStep

DeleteFrom begins a DELETE from the given table.

type Dialect

type Dialect interface {
	// Name returns the canonical dialect identifier.
	Name() string
	// contains filtered or unexported methods
}

Dialect supplies every database-specific SQL fragment that the otherwise dialect-agnostic abstract syntax tree requires while rendering itself. A single tree is rendered against a chosen Dialect at SQL time, which is how one query can target multiple databases.

The interface is sealed: its operative methods are unexported, so callers obtain dialects only through Postgres and SQLite.

func Postgres

func Postgres() Dialect

Postgres returns the PostgreSQL dialect: double-quoted identifiers, numbered placeholders ($1, $2, ...), native RETURNING, and ON CONFLICT upserts.

func SQLite

func SQLite() Dialect

SQLite returns the SQLite dialect: double-quoted identifiers, anonymous placeholders (?), native RETURNING, and ON CONFLICT upserts.

type Field

type Field[T any] interface {
	Name() string

	// Comparisons against a value of the field's type.
	EQ(v T) Condition
	NE(v T) Condition
	GT(v T) Condition
	LT(v T) Condition
	GE(v T) Condition
	LE(v T) Condition

	// Set membership, nullability, and range.
	In(vs ...T) Condition
	NotIn(vs ...T) Condition
	// InSubquery renders "x IN (SELECT ...)" against the given subquery.
	InSubquery(sub Subquery) Condition
	// NotInSubquery renders "x NOT IN (SELECT ...)" against the given subquery.
	NotInSubquery(sub Subquery) Condition
	IsNull() Condition
	IsNotNull() Condition
	Between(lo, hi T) Condition
	NotBetween(lo, hi T) Condition

	// Field-to-field comparisons. Each compares this field against another
	// field or expression, rendering the right operand as an identifier or
	// expression rather than a bound argument.
	EQField(other Field[T]) Condition
	NEField(other Field[T]) Condition
	GTField(other Field[T]) Condition
	LTField(other Field[T]) Condition
	GEField(other Field[T]) Condition
	LEField(other Field[T]) Condition

	// Aliasing, ordering, and assignment.
	As(alias string) Field[T]
	Asc() OrderField
	Desc() OrderField
	Set(v T) Assignment
	// contains filtered or unexported methods
}

Field is a typed column or expression. Comparison methods take a value of the field's own type T, so the compiler rejects mismatched comparisons. Field is the Go counterpart of jOOQ's Field<T>.

func Abs

func Abs[T any](f Field[T]) Field[T]

Abs returns ABS(field), the absolute value of the numeric field, preserving the field's type.

func Avg

func Avg[T any](f Field[T]) Field[float64]

Avg returns the AVG aggregate of the given field as a Field[float64], since an average is computed in floating point regardless of the operand type.

func Cast

func Cast[T any](f AnyField, sqlType string) Field[T]

Cast converts the given field or expression to the named SQL type, rendered as CAST(expr AS sqltype), and returns it as a Field[T]. The SQL type is spliced verbatim, so the caller supplies a spelling valid for the target dialect.

func Coalesce

func Coalesce[T any](first Field[T], rest ...any) Field[T]

Coalesce returns the first non-null operand, rendered as COALESCE(a, b, ...). The first operand is a typed field; the remaining operands may be values (which bind) or fields and expressions (which render as identifiers), exactly like the field-operand operator variants elsewhere in the builder.

func Concat

func Concat(parts ...any) Field[string]

Concat returns a field that concatenates the given parts using the SQL "||" operator. String literals are bound as arguments, while StringField and Field[string] operands render as their column or expression. Both PostgreSQL and SQLite support the "||" operator.

func Count

func Count(f AnyField) Field[int64]

Count returns the COUNT of the given field's non-null values as a Field[int64].

func CountDistinct

func CountDistinct(f AnyField) Field[int64]

CountDistinct returns COUNT(DISTINCT field), counting the distinct non-null values of the field, as a Field[int64].

func CountStar

func CountStar() Field[int64]

CountStar returns COUNT(*), counting every row regardless of nulls, as a Field[int64].

func Function

func Function[T any](name string, args ...AnyField) Field[T]

Function builds a typed call to an arbitrary SQL function whose arguments are fields or expressions. The result type T is chosen by the caller, mirroring jOOQ's DSL.function. Each argument renders as its own column or expression rather than binding a value.

func Greatest

func Greatest[T any](first Field[T], rest ...any) Field[T]

Greatest returns the greatest of its operands, rendered as GREATEST(a, b, ...). The first operand is a typed field; the remaining operands may be values (which bind) or fields and expressions (which render as identifiers).

func Least

func Least[T any](first Field[T], rest ...any) Field[T]

Least returns the least of its operands, rendered as LEAST(a, b, ...). The first operand is a typed field; the remaining operands may be values (which bind) or fields and expressions (which render as identifiers).

func Length

func Length(f Field[string]) Field[int64]

Length returns LENGTH(field), the character length of the text field, as a Field[int64].

func Lower

func Lower(f Field[string]) Field[string]

Lower returns LOWER(field), the lowercase form of the text field.

func Max

func Max[T any](f Field[T]) Field[T]

Max returns the MAX aggregate of the given field, preserving the field's type.

func Min

func Min[T any](f Field[T]) Field[T]

Min returns the MIN aggregate of the given field, preserving the field's type.

func NewField

func NewField[T any](base TableImpl, name string) Field[T]

NewField builds a typed column field qualified by the owning table's name or alias. Generated table code calls this for each column.

func NullIf

func NullIf[T any](a Field[T], b T) Field[T]

NullIf returns NULLIF(a, b): the SQL NULL when the two operands are equal and the first operand otherwise. The comparison value binds as an argument.

func Raw

func Raw[T any](sql string) Field[T]

Raw is an escape hatch that splices verbatim SQL into the query as a typed field, binding no arguments. The text is emitted exactly as given, so the caller is responsible for any required quoting and for the dialect portability of the fragment.

func RawValue

func RawValue[T any](sql string, args ...any) Field[T]

RawValue is an escape hatch that splices verbatim SQL into the query as a typed field while binding the supplied arguments. Each '?' marker in the SQL text is replaced, in order, by the active dialect's placeholder and consumes one argument from args. Surplus markers or surplus arguments are tolerated: extra markers render with no bound value and extra arguments are ignored, so the marker count and argument count are expected to match.

func Round

func Round[T any](f Field[T]) Field[T]

Round returns ROUND(field), the numeric field rounded to the nearest integer, preserving the field's type.

func ScalarSubquery

func ScalarSubquery[T any](sub Subquery) Field[T]

ScalarSubquery adapts a single-column, single-row subquery to a typed Field[T], so it can be projected, compared, or otherwise used where a scalar expression is expected. The element type T is supplied by the caller and is not verified against the subquery's projection.

func Sum

func Sum[T any](f Field[T]) Field[T]

Sum returns the SUM aggregate of the given field, preserving the field's type.

func Trim

func Trim(f Field[string]) Field[string]

Trim returns TRIM(field), the text field with leading and trailing whitespace removed.

func Upper

func Upper(f Field[string]) Field[string]

Upper returns UPPER(field), the uppercase form of the text field.

type ForeignKeyMeta

type ForeignKeyMeta struct {
	// Name is the constraint name as stored in the database catalog.
	Name string
	// Columns are the local column names that participate in the foreign key,
	// in the order they appear in the constraint definition.
	Columns []string
	// RefTable is the unqualified name of the referenced table.
	RefTable string
	// RefColumns are the referenced column names, aligned positionally with
	// Columns.
	RefColumns []string
}

ForeignKeyMeta describes a single foreign key constraint discovered during code generation and surfaced on the generated table accessors. It is plain data with no behavior so that the core package remains free of external dependencies and the generated metadata can be inspected at runtime.

type InsertConflictActionStep

type InsertConflictActionStep interface {
	DoNothing() InsertReturningStep
	DoUpdateSet(assignments ...Assignment) InsertReturningStep
}

InsertConflictActionStep chooses the action for an ON CONFLICT target.

type InsertFinalStep

type InsertFinalStep interface {
	SQL() (string, []any, error)
	SQLFor(d Dialect) (string, []any, error)
	Using(d Dialect) InsertFinalStep
	Execute(ctx context.Context, db Querier) (sql.Result, error)
	// contains filtered or unexported methods
}

InsertFinalStep is the terminal state.

type InsertOnConflictStep

type InsertOnConflictStep interface {
	InsertReturningStep
	OnConflict(cols ...AnyField) InsertConflictActionStep
	OnConflictDoNothing() InsertReturningStep
	OnDuplicateKeyUpdate(assignments ...Assignment) InsertReturningStep
}

InsertOnConflictStep allows attaching conflict-resolution behavior.

type InsertReturningStep

type InsertReturningStep interface {
	InsertFinalStep
	Returning(cols ...AnyField) InsertFinalStep
}

InsertReturningStep allows a RETURNING clause before terminal execution.

type InsertSetMoreStep

type InsertSetMoreStep interface {
	InsertOnConflictStep
	Set(a Assignment) InsertSetMoreStep
}

InsertSetMoreStep accepts further column assignments.

type InsertSetStep

type InsertSetStep interface {
	Columns(cols ...AnyField) InsertValuesStep
	Set(a Assignment) InsertSetMoreStep
	DefaultValues() InsertFinalStep
}

InsertSetStep is the entry state after INSERT INTO.

func InsertInto

func InsertInto(t Table) InsertSetStep

InsertInto begins an INSERT into the given table.

type InsertValuesStep

type InsertValuesStep interface {
	InsertOnConflictStep
	Values(values ...any) InsertValuesStep
	// Select supplies the inserted rows from a subquery rather than literal
	// value rows. The source SELECT is rendered into the same builder as the
	// INSERT, so its bind arguments interleave correctly.
	Select(sub Subquery) InsertReturningStep
}

InsertValuesStep accepts one or more value rows, or a SELECT statement whose rows are inserted ("INSERT INTO t (cols) SELECT ...").

type NumericField

type NumericField[T any] interface {
	Field[T]
	Add(v T) Field[T]
	Sub(v T) Field[T]
	Mul(v T) Field[T]
	Div(v T) Field[T]
	ModVal(v T) Field[T]

	AddField(other Field[T]) Field[T]
	SubField(other Field[T]) Field[T]
	MulField(other Field[T]) Field[T]
	DivField(other Field[T]) Field[T]
	ModField(other Field[T]) Field[T]

	// Neg returns a field that negates this expression, rendering "-(expr)".
	Neg() Field[T]
}

NumericField is a Field[T] augmented with arithmetic operators that produce new expression fields. Each operator has a value-taking form that binds its argument and a field-taking form (suffixed "Field") that renders the other field or expression as an identifier instead of binding a value.

func NewNumericField

func NewNumericField[T any](base TableImpl, name string) NumericField[T]

NewNumericField builds a qualified numeric column field.

type OrderField

type OrderField interface {

	// NullsFirst orders NULL values before non-NULL values, rendering the
	// "NULLS FIRST" qualifier. It returns the same term for chaining.
	NullsFirst() OrderField
	// NullsLast orders NULL values after non-NULL values, rendering the
	// "NULLS LAST" qualifier. It returns the same term for chaining.
	NullsLast() OrderField
	// contains filtered or unexported methods
}

OrderField is a single ORDER BY term: an expression paired with a sort direction and an optional NULLS ordering. It is produced by Field[T].Asc and Field[T].Desc.

type OverBuilder

type OverBuilder[T any] struct {
	// contains filtered or unexported fields
}

OverBuilder accumulates the PARTITION BY, ORDER BY, and frame components of a window specification. It is returned by WindowField.Over and finalised with End, which yields a typed Field[T].

func (*OverBuilder[T]) End

func (o *OverBuilder[T]) End() Field[T]

End finalises the window specification and returns it as a typed Field[T] usable as a projection column.

func (*OverBuilder[T]) Frame

func (o *OverBuilder[T]) Frame(frame string) *OverBuilder[T]

Frame sets the verbatim frame clause of the window specification, for example "ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW". The clause is spliced verbatim, so the caller supplies a spelling valid for the target dialect; both PostgreSQL and SQLite share the same frame syntax for the common cases.

func (*OverBuilder[T]) OrderBy

func (o *OverBuilder[T]) OrderBy(orders ...OrderField) *OverBuilder[T]

OrderBy adds one or more ORDER BY terms to the window specification, each produced by Field[T].Asc or Field[T].Desc. It returns the same builder for chaining.

func (*OverBuilder[T]) PartitionBy

func (o *OverBuilder[T]) PartitionBy(fields ...AnyField) *OverBuilder[T]

PartitionBy adds one or more PARTITION BY expressions to the window specification. Each field renders as its own column or expression rather than binding a value. It returns the same builder for chaining.

type Querier

type Querier interface {
	QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)
	ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)
}

Querier is the minimal execution surface the library needs. It is satisfied by *sql.DB, *sql.Tx, and *sql.Conn, and by compatible third-party pools such as pgx's stdlib adapter.

type Record1

type Record1[T1 any] struct {
	V1 T1
}

Record1 holds one typed column value.

func (Record1[T1]) Get

func (r Record1[T1]) Get(i int) any

Get returns the i-th column value (zero-based), or nil when out of range.

func (Record1[T1]) Values

func (r Record1[T1]) Values() []any

Values returns the column values in projection order.

type Record2

type Record2[T1, T2 any] struct {
	V1 T1
	V2 T2
}

Record2 holds two typed column values.

func (Record2[T1, T2]) Get

func (r Record2[T1, T2]) Get(i int) any

func (Record2[T1, T2]) Values

func (r Record2[T1, T2]) Values() []any

type Record3

type Record3[T1, T2, T3 any] struct {
	V1 T1
	V2 T2
	V3 T3
}

Record3 holds three typed column values.

func (Record3[T1, T2, T3]) Get

func (r Record3[T1, T2, T3]) Get(i int) any

func (Record3[T1, T2, T3]) Values

func (r Record3[T1, T2, T3]) Values() []any

type Record4

type Record4[T1, T2, T3, T4 any] struct {
	V1 T1
	V2 T2
	V3 T3
	V4 T4
}

Record4 holds four typed column values.

func (Record4[T1, T2, T3, T4]) Get

func (r Record4[T1, T2, T3, T4]) Get(i int) any

func (Record4[T1, T2, T3, T4]) Values

func (r Record4[T1, T2, T3, T4]) Values() []any

type Record5

type Record5[T1, T2, T3, T4, T5 any] struct {
	V1 T1
	V2 T2
	V3 T3
	V4 T4
	V5 T5
}

Record5 holds five typed column values.

func (Record5[T1, T2, T3, T4, T5]) Get

func (r Record5[T1, T2, T3, T4, T5]) Get(i int) any

func (Record5[T1, T2, T3, T4, T5]) Values

func (r Record5[T1, T2, T3, T4, T5]) Values() []any

type Record6

type Record6[T1, T2, T3, T4, T5, T6 any] struct {
	V1 T1
	V2 T2
	V3 T3
	V4 T4
	V5 T5
	V6 T6
}

Record6 holds 6 typed column values.

func (Record6[T1, T2, T3, T4, T5, T6]) Get

func (r Record6[T1, T2, T3, T4, T5, T6]) Get(i int) any

func (Record6[T1, T2, T3, T4, T5, T6]) Values

func (r Record6[T1, T2, T3, T4, T5, T6]) Values() []any

type Record7

type Record7[T1, T2, T3, T4, T5, T6, T7 any] struct {
	V1 T1
	V2 T2
	V3 T3
	V4 T4
	V5 T5
	V6 T6
	V7 T7
}

Record7 holds 7 typed column values.

func (Record7[T1, T2, T3, T4, T5, T6, T7]) Get

func (r Record7[T1, T2, T3, T4, T5, T6, T7]) Get(i int) any

func (Record7[T1, T2, T3, T4, T5, T6, T7]) Values

func (r Record7[T1, T2, T3, T4, T5, T6, T7]) Values() []any

type Record8

type Record8[T1, T2, T3, T4, T5, T6, T7, T8 any] struct {
	V1 T1
	V2 T2
	V3 T3
	V4 T4
	V5 T5
	V6 T6
	V7 T7
	V8 T8
}

Record8 holds 8 typed column values.

func (Record8[T1, T2, T3, T4, T5, T6, T7, T8]) Get

func (r Record8[T1, T2, T3, T4, T5, T6, T7, T8]) Get(i int) any

func (Record8[T1, T2, T3, T4, T5, T6, T7, T8]) Values

func (r Record8[T1, T2, T3, T4, T5, T6, T7, T8]) Values() []any

type Record9

type Record9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any] struct {
	V1 T1
	V2 T2
	V3 T3
	V4 T4
	V5 T5
	V6 T6
	V7 T7
	V8 T8
	V9 T9
}

Record9 holds 9 typed column values.

func (Record9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) Get

func (r Record9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) Get(i int) any

func (Record9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) Values

func (r Record9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) Values() []any

type Record10

type Record10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any] struct {
	V1  T1
	V2  T2
	V3  T3
	V4  T4
	V5  T5
	V6  T6
	V7  T7
	V8  T8
	V9  T9
	V10 T10
}

Record10 holds 10 typed column values.

func (Record10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]) Get

func (r Record10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]) Get(i int) any

func (Record10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]) Values

func (r Record10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]) Values() []any

type Record11

type Record11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any] struct {
	V1  T1
	V2  T2
	V3  T3
	V4  T4
	V5  T5
	V6  T6
	V7  T7
	V8  T8
	V9  T9
	V10 T10
	V11 T11
}

Record11 holds 11 typed column values.

func (Record11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]) Get

func (r Record11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]) Get(i int) any

func (Record11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]) Values

func (r Record11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]) Values() []any

type Record12

type Record12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any] struct {
	V1  T1
	V2  T2
	V3  T3
	V4  T4
	V5  T5
	V6  T6
	V7  T7
	V8  T8
	V9  T9
	V10 T10
	V11 T11
	V12 T12
}

Record12 holds 12 typed column values.

func (Record12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]) Get

func (r Record12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]) Get(i int) any

func (Record12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]) Values

func (r Record12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]) Values() []any

type Record13

type Record13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any] struct {
	V1  T1
	V2  T2
	V3  T3
	V4  T4
	V5  T5
	V6  T6
	V7  T7
	V8  T8
	V9  T9
	V10 T10
	V11 T11
	V12 T12
	V13 T13
}

Record13 holds 13 typed column values.

func (Record13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]) Get

func (r Record13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]) Get(i int) any

func (Record13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]) Values

func (r Record13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]) Values() []any

type Record14

type Record14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any] struct {
	V1  T1
	V2  T2
	V3  T3
	V4  T4
	V5  T5
	V6  T6
	V7  T7
	V8  T8
	V9  T9
	V10 T10
	V11 T11
	V12 T12
	V13 T13
	V14 T14
}

Record14 holds 14 typed column values.

func (Record14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]) Get

func (r Record14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]) Get(i int) any

func (Record14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]) Values

func (r Record14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]) Values() []any

type Record15

type Record15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 any] struct {
	V1  T1
	V2  T2
	V3  T3
	V4  T4
	V5  T5
	V6  T6
	V7  T7
	V8  T8
	V9  T9
	V10 T10
	V11 T11
	V12 T12
	V13 T13
	V14 T14
	V15 T15
}

Record15 holds 15 typed column values.

func (Record15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]) Get

func (r Record15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]) Get(i int) any

func (Record15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]) Values

func (r Record15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]) Values() []any

type Record16

type Record16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16 any] struct {
	V1  T1
	V2  T2
	V3  T3
	V4  T4
	V5  T5
	V6  T6
	V7  T7
	V8  T8
	V9  T9
	V10 T10
	V11 T11
	V12 T12
	V13 T13
	V14 T14
	V15 T15
	V16 T16
}

Record16 holds 16 typed column values.

func (Record16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]) Get

func (r Record16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]) Get(i int) any

func (Record16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]) Values

func (r Record16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]) Values() []any

type Record17

type Record17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17 any] struct {
	V1  T1
	V2  T2
	V3  T3
	V4  T4
	V5  T5
	V6  T6
	V7  T7
	V8  T8
	V9  T9
	V10 T10
	V11 T11
	V12 T12
	V13 T13
	V14 T14
	V15 T15
	V16 T16
	V17 T17
}

Record17 holds 17 typed column values.

func (Record17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]) Get

func (r Record17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]) Get(i int) any

func (Record17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]) Values

func (r Record17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]) Values() []any

type Record18

type Record18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18 any] struct {
	V1  T1
	V2  T2
	V3  T3
	V4  T4
	V5  T5
	V6  T6
	V7  T7
	V8  T8
	V9  T9
	V10 T10
	V11 T11
	V12 T12
	V13 T13
	V14 T14
	V15 T15
	V16 T16
	V17 T17
	V18 T18
}

Record18 holds 18 typed column values.

func (Record18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]) Get

func (r Record18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]) Get(i int) any

func (Record18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]) Values

func (r Record18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]) Values() []any

type Record19

type Record19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 any] struct {
	V1  T1
	V2  T2
	V3  T3
	V4  T4
	V5  T5
	V6  T6
	V7  T7
	V8  T8
	V9  T9
	V10 T10
	V11 T11
	V12 T12
	V13 T13
	V14 T14
	V15 T15
	V16 T16
	V17 T17
	V18 T18
	V19 T19
}

Record19 holds 19 typed column values.

func (Record19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]) Get

func (r Record19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]) Get(i int) any

func (Record19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]) Values

func (r Record19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]) Values() []any

type Record20

type Record20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20 any] struct {
	V1  T1
	V2  T2
	V3  T3
	V4  T4
	V5  T5
	V6  T6
	V7  T7
	V8  T8
	V9  T9
	V10 T10
	V11 T11
	V12 T12
	V13 T13
	V14 T14
	V15 T15
	V16 T16
	V17 T17
	V18 T18
	V19 T19
	V20 T20
}

Record20 holds 20 typed column values.

func (Record20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]) Get

func (r Record20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]) Get(i int) any

func (Record20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]) Values

func (r Record20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]) Values() []any

type Record21

type Record21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21 any] struct {
	V1  T1
	V2  T2
	V3  T3
	V4  T4
	V5  T5
	V6  T6
	V7  T7
	V8  T8
	V9  T9
	V10 T10
	V11 T11
	V12 T12
	V13 T13
	V14 T14
	V15 T15
	V16 T16
	V17 T17
	V18 T18
	V19 T19
	V20 T20
	V21 T21
}

Record21 holds 21 typed column values.

func (Record21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]) Get

func (r Record21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]) Get(i int) any

func (Record21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]) Values

func (r Record21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]) Values() []any

type Record22

type Record22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22 any] struct {
	V1  T1
	V2  T2
	V3  T3
	V4  T4
	V5  T5
	V6  T6
	V7  T7
	V8  T8
	V9  T9
	V10 T10
	V11 T11
	V12 T12
	V13 T13
	V14 T14
	V15 T15
	V16 T16
	V17 T17
	V18 T18
	V19 T19
	V20 T20
	V21 T21
	V22 T22
}

Record22 holds 22 typed column values.

func (Record22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]) Get

func (r Record22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]) Get(i int) any

func (Record22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]) Values

func (r Record22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]) Values() []any

type SelectConditionStep

type SelectConditionStep[R any] interface {
	SelectGroupByStep[R]
	And(c Condition) SelectConditionStep[R]
	Or(c Condition) SelectConditionStep[R]
}

SelectConditionStep allows extending the WHERE predicate with AND/OR.

type SelectFinalStep

type SelectFinalStep[R any] interface {
	Subquery
	// Fetch executes the query and returns every row mapped to R.
	Fetch(ctx context.Context, db Querier) ([]R, error)
	// FetchOne returns the single row, the zero value when no row matches, or
	// ErrTooManyRows when more than one row matches.
	FetchOne(ctx context.Context, db Querier) (R, error)
	// FetchSingle returns the single row, sql.ErrNoRows when none matches, or
	// ErrTooManyRows when more than one matches.
	FetchSingle(ctx context.Context, db Querier) (R, error)
	// FetchOptional returns the single row and true, the zero value and false
	// when no row matches, or ErrTooManyRows when more than one row matches.
	FetchOptional(ctx context.Context, db Querier) (R, bool, error)
	// SQL renders the query using the dialect bound to the query (PostgreSQL by
	// default, or whatever was selected via Using).
	SQL() (string, []any, error)
	// SQLFor renders the query using an explicit dialect.
	SQLFor(d Dialect) (string, []any, error)
	// Using selects the dialect used by SQL, Fetch, FetchOne, and FetchSingle.
	Using(d Dialect) SelectFinalStep[R]

	// Union combines this query with another over the same row type, removing
	// duplicate rows.
	Union(other SelectFinalStep[R]) SelectFinalStep[R]
	// UnionAll combines this query with another over the same row type, keeping
	// duplicate rows.
	UnionAll(other SelectFinalStep[R]) SelectFinalStep[R]
	// Intersect returns the rows common to this query and another over the same
	// row type.
	Intersect(other SelectFinalStep[R]) SelectFinalStep[R]
	// Except returns the rows of this query that do not appear in another over
	// the same row type.
	Except(other SelectFinalStep[R]) SelectFinalStep[R]
}

SelectFinalStep is the terminal state: render the SQL or execute the query. It embeds Subquery so a fully built SELECT can also serve as a sub-expression.

type SelectFromStep

type SelectFromStep[R any] interface {
	Subquery
	From(t Table) SelectJoinStep[R]
	// Distinct marks the query as SELECT DISTINCT. It is idempotent and may be
	// called before From.
	Distinct() SelectFromStep[R]
}

SelectFromStep is the state immediately after the projection is chosen. Distinct may be applied here, before the FROM clause, and returns the same step so the projection can still be followed by From. It embeds Subquery so a SELECT may be used as a sub-expression (EXISTS, IN, or scalar) at any point in its construction.

func Select1

func Select1[T1 any](f1 Field[T1]) SelectFromStep[Record1[T1]]

Select1 begins a SELECT projecting one typed column.

func Select2

func Select2[T1, T2 any](f1 Field[T1], f2 Field[T2]) SelectFromStep[Record2[T1, T2]]

Select2 begins a SELECT projecting two typed columns.

func Select3

func Select3[T1, T2, T3 any](f1 Field[T1], f2 Field[T2], f3 Field[T3]) SelectFromStep[Record3[T1, T2, T3]]

Select3 begins a SELECT projecting three typed columns.

func Select4

func Select4[T1, T2, T3, T4 any](f1 Field[T1], f2 Field[T2], f3 Field[T3], f4 Field[T4]) SelectFromStep[Record4[T1, T2, T3, T4]]

Select4 begins a SELECT projecting four typed columns.

func Select5

func Select5[T1, T2, T3, T4, T5 any](f1 Field[T1], f2 Field[T2], f3 Field[T3], f4 Field[T4], f5 Field[T5]) SelectFromStep[Record5[T1, T2, T3, T4, T5]]

Select5 begins a SELECT projecting five typed columns.

func Select6

func Select6[T1, T2, T3, T4, T5, T6 any](f1 Field[T1], f2 Field[T2], f3 Field[T3], f4 Field[T4], f5 Field[T5], f6 Field[T6]) SelectFromStep[Record6[T1, T2, T3, T4, T5, T6]]

Select6 begins a SELECT projecting 6 typed columns.

func Select7

func Select7[T1, T2, T3, T4, T5, T6, T7 any](f1 Field[T1], f2 Field[T2], f3 Field[T3], f4 Field[T4], f5 Field[T5], f6 Field[T6], f7 Field[T7]) SelectFromStep[Record7[T1, T2, T3, T4, T5, T6, T7]]

Select7 begins a SELECT projecting 7 typed columns.

func Select8

func Select8[T1, T2, T3, T4, T5, T6, T7, T8 any](f1 Field[T1], f2 Field[T2], f3 Field[T3], f4 Field[T4], f5 Field[T5], f6 Field[T6], f7 Field[T7], f8 Field[T8]) SelectFromStep[Record8[T1, T2, T3, T4, T5, T6, T7, T8]]

Select8 begins a SELECT projecting 8 typed columns.

func Select9

func Select9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](f1 Field[T1], f2 Field[T2], f3 Field[T3], f4 Field[T4], f5 Field[T5], f6 Field[T6], f7 Field[T7], f8 Field[T8], f9 Field[T9]) SelectFromStep[Record9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]

Select9 begins a SELECT projecting 9 typed columns.

func Select10

func Select10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](f1 Field[T1], f2 Field[T2], f3 Field[T3], f4 Field[T4], f5 Field[T5], f6 Field[T6], f7 Field[T7], f8 Field[T8], f9 Field[T9], f10 Field[T10]) SelectFromStep[Record10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]

Select10 begins a SELECT projecting 10 typed columns.

func Select11

func Select11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any](f1 Field[T1], f2 Field[T2], f3 Field[T3], f4 Field[T4], f5 Field[T5], f6 Field[T6], f7 Field[T7], f8 Field[T8], f9 Field[T9], f10 Field[T10], f11 Field[T11]) SelectFromStep[Record11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]]

Select11 begins a SELECT projecting 11 typed columns.

func Select12

func Select12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any](f1 Field[T1], f2 Field[T2], f3 Field[T3], f4 Field[T4], f5 Field[T5], f6 Field[T6], f7 Field[T7], f8 Field[T8], f9 Field[T9], f10 Field[T10], f11 Field[T11], f12 Field[T12]) SelectFromStep[Record12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]]

Select12 begins a SELECT projecting 12 typed columns.

func Select13

func Select13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any](f1 Field[T1], f2 Field[T2], f3 Field[T3], f4 Field[T4], f5 Field[T5], f6 Field[T6], f7 Field[T7], f8 Field[T8], f9 Field[T9], f10 Field[T10], f11 Field[T11], f12 Field[T12], f13 Field[T13]) SelectFromStep[Record13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]]

Select13 begins a SELECT projecting 13 typed columns.

func Select14

func Select14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any](f1 Field[T1], f2 Field[T2], f3 Field[T3], f4 Field[T4], f5 Field[T5], f6 Field[T6], f7 Field[T7], f8 Field[T8], f9 Field[T9], f10 Field[T10], f11 Field[T11], f12 Field[T12], f13 Field[T13], f14 Field[T14]) SelectFromStep[Record14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]]

Select14 begins a SELECT projecting 14 typed columns.

func Select15

func Select15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 any](f1 Field[T1], f2 Field[T2], f3 Field[T3], f4 Field[T4], f5 Field[T5], f6 Field[T6], f7 Field[T7], f8 Field[T8], f9 Field[T9], f10 Field[T10], f11 Field[T11], f12 Field[T12], f13 Field[T13], f14 Field[T14], f15 Field[T15]) SelectFromStep[Record15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]]

Select15 begins a SELECT projecting 15 typed columns.

func Select16

func Select16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16 any](f1 Field[T1], f2 Field[T2], f3 Field[T3], f4 Field[T4], f5 Field[T5], f6 Field[T6], f7 Field[T7], f8 Field[T8], f9 Field[T9], f10 Field[T10], f11 Field[T11], f12 Field[T12], f13 Field[T13], f14 Field[T14], f15 Field[T15], f16 Field[T16]) SelectFromStep[Record16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]]

Select16 begins a SELECT projecting 16 typed columns.

func Select17

func Select17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17 any](f1 Field[T1], f2 Field[T2], f3 Field[T3], f4 Field[T4], f5 Field[T5], f6 Field[T6], f7 Field[T7], f8 Field[T8], f9 Field[T9], f10 Field[T10], f11 Field[T11], f12 Field[T12], f13 Field[T13], f14 Field[T14], f15 Field[T15], f16 Field[T16], f17 Field[T17]) SelectFromStep[Record17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]]

Select17 begins a SELECT projecting 17 typed columns.

func Select18

func Select18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18 any](f1 Field[T1], f2 Field[T2], f3 Field[T3], f4 Field[T4], f5 Field[T5], f6 Field[T6], f7 Field[T7], f8 Field[T8], f9 Field[T9], f10 Field[T10], f11 Field[T11], f12 Field[T12], f13 Field[T13], f14 Field[T14], f15 Field[T15], f16 Field[T16], f17 Field[T17], f18 Field[T18]) SelectFromStep[Record18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]]

Select18 begins a SELECT projecting 18 typed columns.

func Select19

func Select19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 any](f1 Field[T1], f2 Field[T2], f3 Field[T3], f4 Field[T4], f5 Field[T5], f6 Field[T6], f7 Field[T7], f8 Field[T8], f9 Field[T9], f10 Field[T10], f11 Field[T11], f12 Field[T12], f13 Field[T13], f14 Field[T14], f15 Field[T15], f16 Field[T16], f17 Field[T17], f18 Field[T18], f19 Field[T19]) SelectFromStep[Record19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]]

Select19 begins a SELECT projecting 19 typed columns.

func Select20

func Select20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20 any](f1 Field[T1], f2 Field[T2], f3 Field[T3], f4 Field[T4], f5 Field[T5], f6 Field[T6], f7 Field[T7], f8 Field[T8], f9 Field[T9], f10 Field[T10], f11 Field[T11], f12 Field[T12], f13 Field[T13], f14 Field[T14], f15 Field[T15], f16 Field[T16], f17 Field[T17], f18 Field[T18], f19 Field[T19], f20 Field[T20]) SelectFromStep[Record20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]]

Select20 begins a SELECT projecting 20 typed columns.

func Select21

func Select21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21 any](f1 Field[T1], f2 Field[T2], f3 Field[T3], f4 Field[T4], f5 Field[T5], f6 Field[T6], f7 Field[T7], f8 Field[T8], f9 Field[T9], f10 Field[T10], f11 Field[T11], f12 Field[T12], f13 Field[T13], f14 Field[T14], f15 Field[T15], f16 Field[T16], f17 Field[T17], f18 Field[T18], f19 Field[T19], f20 Field[T20], f21 Field[T21]) SelectFromStep[Record21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]]

Select21 begins a SELECT projecting 21 typed columns.

func Select22

func Select22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22 any](f1 Field[T1], f2 Field[T2], f3 Field[T3], f4 Field[T4], f5 Field[T5], f6 Field[T6], f7 Field[T7], f8 Field[T8], f9 Field[T9], f10 Field[T10], f11 Field[T11], f12 Field[T12], f13 Field[T13], f14 Field[T14], f15 Field[T15], f16 Field[T16], f17 Field[T17], f18 Field[T18], f19 Field[T19], f20 Field[T20], f21 Field[T21], f22 Field[T22]) SelectFromStep[Record22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]]

Select22 begins a SELECT projecting 22 typed columns.

type SelectGroupByStep

type SelectGroupByStep[R any] interface {
	SelectOrderByStep[R]
	GroupBy(fields ...AnyField) SelectHavingStep[R]
}

SelectGroupByStep allows a GROUP BY clause or skipping to ORDER BY and limit.

type SelectHavingStep

type SelectHavingStep[R any] interface {
	SelectOrderByStep[R]
	Having(c Condition) SelectOrderByStep[R]
}

SelectHavingStep allows a HAVING clause after GROUP BY.

type SelectJoinStep

type SelectJoinStep[R any] interface {
	SelectWhereStep[R]
	Join(t Table) SelectOnStep[R]
	InnerJoin(t Table) SelectOnStep[R]
	LeftJoin(t Table) SelectOnStep[R]
	RightJoin(t Table) SelectOnStep[R]
}

SelectJoinStep allows joining further tables or, by embedding SelectWhereStep, skipping straight to WHERE and beyond.

type SelectLimitStep

type SelectLimitStep[R any] interface {
	SelectLockStep[R]
	Limit(n int64) SelectLimitStep[R]
	Offset(n int64) SelectLimitStep[R]
}

SelectLimitStep allows a LIMIT and/or OFFSET clause, a row-locking clause, or terminal execution. Both Limit and Offset return SelectLimitStep so they may be chained in either order or used independently (a bare OFFSET is legal).

type SelectLockStep

type SelectLockStep[R any] interface {
	SelectFinalStep[R]
	// ForUpdate adds a FOR UPDATE locking clause to the query.
	ForUpdate() SelectLockStep[R]
	// ForShare adds a FOR SHARE locking clause to the query.
	ForShare() SelectLockStep[R]
	// SkipLocked appends SKIP LOCKED to the locking clause, so locked rows are
	// skipped rather than waited on. It is meaningful only after ForUpdate or
	// ForShare.
	SkipLocked() SelectLockStep[R]
}

SelectLockStep allows a row-locking clause (FOR UPDATE / FOR SHARE, optionally SKIP LOCKED) after ORDER BY, LIMIT, and OFFSET, or terminal execution. The locking clause is rendered for PostgreSQL and silently omitted for SQLite, which has no such clause.

type SelectOnStep

type SelectOnStep[R any] interface {
	On(c Condition) SelectJoinStep[R]
}

SelectOnStep requires the join condition before any further clause.

type SelectOrderByStep

type SelectOrderByStep[R any] interface {
	SelectLimitStep[R]
	OrderBy(orders ...OrderField) SelectLimitStep[R]
}

SelectOrderByStep allows an ORDER BY clause or skipping to limit.

type SelectWhereStep

type SelectWhereStep[R any] interface {
	SelectGroupByStep[R]
	Where(c Condition) SelectConditionStep[R]
}

SelectWhereStep allows a WHERE clause or, by embedding SelectGroupByStep, skipping it.

type StringField

type StringField interface {
	Field[string]
	Like(pattern string) Condition
	NotLike(pattern string) Condition
	// ILike performs a case-insensitive match. It maps to ILIKE on PostgreSQL
	// and to a plain LIKE on SQLite, whose LIKE is already case-insensitive for
	// ASCII text.
	ILike(pattern string) Condition
	// Concat returns a field that concatenates this field with the given parts
	// using the SQL "||" operator. String literals are bound as arguments,
	// while StringField and Field[string] operands render as their column or
	// expression.
	Concat(others ...any) Field[string]
}

StringField is a Field[string] augmented with pattern-matching predicates that only make sense for text columns.

func NewStringField

func NewStringField(base TableImpl, name string) StringField

NewStringField builds a qualified text column field.

type Subquery

type Subquery interface {
	// contains filtered or unexported methods
}

Subquery is a SELECT statement usable as a sub-expression. It is sealed through the embedded node interface, so only this package can provide implementations; the concrete *selectBuilder produced by the SelectN constructors satisfies it. The interface keeps the subquery-taking API typed while preserving the seal on the SELECT step chain.

type Table

type Table interface {

	// TableName returns the unqualified table name.
	TableName() string
	// contains filtered or unexported methods
}

Table is a SQL table reference usable in FROM and JOIN clauses. Generated table types embed the exported TableImpl base and expose typed Field columns.

Aliasing is intentionally not part of this interface: a concrete table type declares its own As(alias) method returning its own concrete type, so that the aliased table still exposes typed columns (qualified by the alias). The aliased value continues to satisfy Table for use in FROM and JOIN.

type TableImpl

type TableImpl struct {
	// contains filtered or unexported fields
}

TableImpl is the embeddable base for generated table types. It renders the table reference in a FROM or JOIN position, including an optional schema and alias. External generated code embeds TableImpl, which supplies the unexported render method and thereby satisfies the sealed Table interface.

func NewTable

func NewTable(name string) TableImpl

NewTable creates a table base with the given name.

func (TableImpl) Qualifier

func (t TableImpl) Qualifier() string

Qualifier returns the identifier used to qualify this table's columns: the alias when aliased, otherwise the table name.

func (TableImpl) TableName

func (t TableImpl) TableName() string

TableName returns the unqualified table name.

func (TableImpl) WithAlias

func (t TableImpl) WithAlias(alias string) TableImpl

WithAlias returns a copy of the table base carrying the given alias. Generated table types call this from their own As method, then rebuild their typed columns so that each column is qualified by the alias.

func (TableImpl) WithSchema

func (t TableImpl) WithSchema(schema string) TableImpl

WithSchema returns a copy of the table base qualified by the given schema.

type UniqueKeyMeta

type UniqueKeyMeta struct {
	// Name is the constraint name as stored in the database catalog.
	Name string
	// Columns are the column names that participate in the unique constraint,
	// in the order they appear in the constraint definition.
	Columns []string
}

UniqueKeyMeta describes a single unique constraint discovered during code generation. Like ForeignKeyMeta it is plain data with no behavior.

type UpdateConditionStep

type UpdateConditionStep interface {
	UpdateReturningStep
	And(c Condition) UpdateConditionStep
	Or(c Condition) UpdateConditionStep
}

UpdateConditionStep allows extending the WHERE predicate.

type UpdateFinalStep

type UpdateFinalStep interface {
	SQL() (string, []any, error)
	SQLFor(d Dialect) (string, []any, error)
	Using(d Dialect) UpdateFinalStep
	Execute(ctx context.Context, db Querier) (sql.Result, error)
	// contains filtered or unexported methods
}

UpdateFinalStep is the terminal state.

type UpdateReturningStep

type UpdateReturningStep interface {
	UpdateFinalStep
	Returning(cols ...AnyField) UpdateFinalStep
}

UpdateReturningStep allows a RETURNING clause before terminal execution.

type UpdateSetMoreStep

type UpdateSetMoreStep interface {
	UpdateWhereStep
	Set(a Assignment) UpdateSetMoreStep
	// From joins a further table into the UPDATE through a FROM clause, rendered
	// before WHERE. Supported by PostgreSQL and recent SQLite.
	From(t Table) UpdateWhereStep
}

UpdateSetMoreStep accepts further assignments, a FROM clause, or a WHERE clause.

type UpdateSetStep

type UpdateSetStep interface {
	Set(a Assignment) UpdateSetMoreStep
}

UpdateSetStep is the entry state after UPDATE table.

func Update

func Update(t Table) UpdateSetStep

Update begins an UPDATE of the given table.

type UpdateWhereStep

type UpdateWhereStep interface {
	UpdateReturningStep
	Where(c Condition) UpdateConditionStep
}

UpdateWhereStep allows a WHERE clause or terminal execution.

type WindowField

type WindowField[T any] struct {
	// contains filtered or unexported fields
}

WindowField is a window-function expression awaiting its window specification. It is produced by the ranking, value, and windowed-aggregate constructors and finalised through Over, which yields a typed Field[T] usable as a projection column. When Over is not called the WindowField is not itself a Field; callers must always finalise it with Over().End(), even when the window is empty.

func AvgOver

func AvgOver[T any](f Field[T]) WindowField[float64]

AvgOver returns the AVG(field) aggregate evaluated as a window function, as a WindowField[float64], since an average is computed in floating point regardless of the operand type.

func CountOver

func CountOver(f AnyField) WindowField[int64]

CountOver returns the COUNT(field) aggregate evaluated as a window function, as a WindowField[int64].

func DenseRank

func DenseRank() WindowField[int64]

DenseRank returns the DENSE_RANK() window function, assigning each row a rank within its window without gaps after ties, as a WindowField[int64].

func FirstValue

func FirstValue[T any](f Field[T]) WindowField[T]

FirstValue returns the FIRST_VALUE(field) window function, the value of the field in the first row of the window, preserving the field's type.

func Lag

func Lag[T any](f Field[T]) WindowField[T]

Lag returns the LAG(field) window function, accessing the value of the field in a preceding row of the window, preserving the field's type.

func LastValue

func LastValue[T any](f Field[T]) WindowField[T]

LastValue returns the LAST_VALUE(field) window function, the value of the field in the last row of the window, preserving the field's type.

func Lead

func Lead[T any](f Field[T]) WindowField[T]

Lead returns the LEAD(field) window function, accessing the value of the field in a following row of the window, preserving the field's type.

func Rank

func Rank() WindowField[int64]

Rank returns the RANK() window function, assigning each row a rank within its window with gaps after ties, as a WindowField[int64].

func RowNumber

func RowNumber() WindowField[int64]

RowNumber returns the ROW_NUMBER() window function, assigning each row a distinct sequential number within its window, as a WindowField[int64].

func SumOver

func SumOver[T any](f Field[T]) WindowField[T]

SumOver returns the SUM(field) aggregate evaluated as a window function, preserving the field's type.

func (WindowField[T]) Over

func (w WindowField[T]) Over() *OverBuilder[T]

Over begins the window specification for this window function, returning a builder on which PartitionBy, OrderBy, and Frame may be set before End finalises the expression.

Directories

Path Synopsis
cmd
gooq-gen command
Command gooq-gen generates typed table accessors for the jooq query builder by introspecting a live database schema through the standard information_schema catalog.
Command gooq-gen generates typed table accessors for the jooq query builder by introspecting a live database schema through the standard information_schema catalog.
Package codegen introspects a PostgreSQL database and generates typed table accessors compatible with the jooq query builder package.
Package codegen introspects a PostgreSQL database and generates typed table accessors compatible with the jooq query builder package.
Command example demonstrates the jooq-for-go query builder against the generated table accessors in ./internal/db.
Command example demonstrates the jooq-for-go query builder against the generated table accessors in ./internal/db.
internal
gen command
Command gen produces the repetitive higher-arity Record and Select code for the jooq package.
Command gen produces the repetitive higher-arity Record and Select code for the jooq package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL