query

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Aug 25, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package query is the base module's persistence query vocabulary: standard SQL composed as Go values, rendered through the provider's dialect. It has two levels. The composition core is a sealed vocabulary of expressions (Col, Val, Fn, and Raw as the deliberate escape hatch), predicates (the comparison methods on Expression, combined by And, Or, Not), and statements as plain structs — Select and Compound, with CTE lists — rendered by Select.SQL into SQL text and bound arguments, placeholders through the dialect. The read vocabulary sits on top: a Projection of name-to-expression fields and Directives of page, sort, and operator-keyed filters, lowered by Projection.Statements into a count-and-page statement pair over one WHERE clause.

Standard SQL only

The vocabulary composes the SQL every engine accepts, and the portability rules are structural rather than documented: table aliases render without AS, compound branches render without parentheses and carry no tail clauses, WITH belongs to the outermost statement, and paging is the SQL:2008 OFFSET/FETCH form with bound arguments, always under an ORDER BY. Where an engine lacks a standard form, the package defines an optional dialect extension checked at the divergent render site — PagingRenderer is the worked case — and standard emission stays the default. The dialect itself grows nothing speculatively.

The field contract

Directives reference a projection's field names, never SQL. An unknown name or operator is a typed error — UnknownFieldError, UnknownOperatorError — the consumer maps to its own response, and the projection's key field joins every ORDER BY as the tie-breaker, so offset paging is stable. Request-derived text reaches a statement only as a bound argument.

Index

Constants

This section is empty.

Variables

View Source
var ErrInvalidStatement = errors.New("invalid query statement")

ErrInvalidStatement classifies a statement that cannot be rendered — an empty select list, a derived table without an alias, paging without ORDER BY. It is wrapped with the specific defect, so errors.Is matches the class while the message names the fix.

Functions

This section is empty.

Types

type CTE

type CTE struct {
	Name      string
	Columns   []string
	Recursive bool
	Query     Query
}

CTE is one common table expression in a statement's WITH list. Recursive marks it for WITH RECURSIVE — its query is then a Compound whose first branch is the anchor. Columns optionally names the CTE's column list, which a recursive CTE usually needs.

type Column

type Column struct {
	Expr  Expression
	Alias string
}

Column is one select-list entry: an expression and its optional alias.

type Compound

type Compound struct {
	With    []CTE
	Op      SetOp
	All     bool
	Queries []Query
	OrderBy []Order
	Paging  *Paging
}

Compound joins two or more Select branches with one set operator. Branches render without parentheses — the one form every engine accepts — so each compound carries a single operator and deliberate nesting goes through a derived table. ORDER BY and paging attach to the compound; branches carry neither, nor WITH.

func Except

func Except(queries ...Query) Compound

Except composes an EXCEPT of the queries.

func ExceptAll

func ExceptAll(queries ...Query) Compound

ExceptAll composes an EXCEPT ALL of the queries.

func Intersect

func Intersect(queries ...Query) Compound

Intersect composes an INTERSECT of the queries.

func IntersectAll

func IntersectAll(queries ...Query) Compound

IntersectAll composes an INTERSECT ALL of the queries.

func Union

func Union(queries ...Query) Compound

Union composes a UNION of the queries.

func UnionAll

func UnionAll(queries ...Query) Compound

UnionAll composes a UNION ALL of the queries.

func (Compound) SQL

func (c Compound) SQL(d database.Dialect) (string, []any, error)

SQL renders the compound through the dialect, with the same contract as Select.SQL.

type Directives

type Directives struct {
	Page    Page
	Sort    []Sort
	Filters []Filter
	Where   Predicate
}

Directives is one read request against a projection. Filters and Sort reference projected field names — an unknown name is an UnknownFieldError, never SQL. Where optionally carries a composed Predicate beyond the field vocabulary, ANDed with the filters: the door back down to the composition core.

type Expression

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

Expression is one standard-SQL expression: a column reference, a bound value, a function call, a raw fragment, or a subquery. The zero value is empty and fails the statement that renders it. The comparison methods produce Predicate values; Expression.As names it as a select-list column.

func Col

func Col(parts ...string) Expression

Col references a column by its identifier parts. Each part may itself be dotted — Col("o.name") and Col("o", "name") are the same reference — so the structure survives for a dialect quoting extension while call sites keep reading like SQL. Parts render verbatim, dot-joined; an identifier containing a literal dot goes through Raw. An empty part fails the statement.

func Fn

func Fn(name string, args ...any) Expression

Fn composes a function call. Arguments lift like comparison operands — expressions render in place, plain values bind — so Fn("COUNT", Raw("*")) and Fn("COALESCE", Col("nickname"), "") both hold.

func Raw

func Raw(sql string) Expression

Raw is the escape hatch: a consumer-authored SQL fragment rendered verbatim. It is the deliberate seam for SQL the vocabulary does not compose; never route request-derived text through it.

func Val

func Val(v any) Expression

Val binds a value explicitly. Comparison operands lift plain Go values on their own; Val is for a bound value standing alone as an expression, such as a constant select-list column.

func (Expression) As

func (e Expression) As(alias string) Column

As names the expression as a select-list column.

func (Expression) Eq

func (e Expression) Eq(v any) Predicate

Eq compares for equality; the operand lifts like every comparison operand.

func (Expression) Ge

func (e Expression) Ge(v any) Predicate

Ge compares greater-than-or-equal.

func (Expression) Gt

func (e Expression) Gt(v any) Predicate

Gt compares greater-than.

func (Expression) In

func (e Expression) In(vals ...any) Predicate

In tests membership: values lift as bound parameters, expressions render in place, and a single Select or Compound argument becomes IN (subquery). An empty list fails the statement.

func (Expression) IsNotNull

func (e Expression) IsNotNull() Predicate

IsNotNull tests for NOT NULL.

func (Expression) IsNull

func (e Expression) IsNull() Predicate

IsNull tests for NULL.

func (Expression) Le

func (e Expression) Le(v any) Predicate

Le compares less-than-or-equal.

func (Expression) Like

func (e Expression) Like(v any) Predicate

Like matches against a pattern.

func (Expression) Lt

func (e Expression) Lt(v any) Predicate

Lt compares less-than.

func (Expression) Ne

func (e Expression) Ne(v any) Predicate

Ne compares for inequality.

type Field

type Field struct {
	Name string
	Expr Expression
}

Field is one projected field: the contract name directives reference, and the expression that computes it.

type FieldUse

type FieldUse string

FieldUse names the directive position where a projected field was referenced, carried by UnknownFieldError.

const (
	FieldUseSort   FieldUse = "sort"
	FieldUseFilter FieldUse = "filter"
)

type Filter

type Filter struct {
	Field string
	Op    Op
	Value any
}

Filter is one filter directive: a projected field name, an operator, and the value. OpIsNull and OpIsNotNull ignore Value; OpIn requires Value to be a []any.

type Op

type Op string

Op is a filter directive's operator. The values are short strings so a read contract can carry them verbatim.

const (
	OpEq        Op = "eq"
	OpNe        Op = "ne"
	OpGt        Op = "gt"
	OpGe        Op = "ge"
	OpLt        Op = "lt"
	OpLe        Op = "le"
	OpLike      Op = "like"
	OpIsNull    Op = "null"
	OpIsNotNull Op = "notnull"
	OpIn        Op = "in"
)

type Order

type Order struct {
	Expr       Expression
	Descending bool
}

Order is one ORDER BY key. Ascending is the default; Descending renders DESC.

type Page

type Page struct {
	Number int
	Size   int
}

Page is the 1-based page directive of a read: which page, and how many rows per page. Both fields must be at least 1.

type Paging

type Paging struct {
	Offset int
	Fetch  int
}

Paging is the SQL:2008 offset/fetch pair, rendered as bound arguments: OFFSET ? ROWS FETCH NEXT ? ROWS ONLY. Paging always requires ORDER BY. An engine that lacks the standard form renders through PagingRenderer.

type PagingRenderer

type PagingRenderer interface {
	RenderPaging(w Writer, offset, fetch int)
}

PagingRenderer is the dialect render extension for an engine that lacks the SQL:2008 OFFSET/FETCH form. A provider's dialect opts in by implementing it and writes its engine's paging clause — no leading space, offset and fetch bound through the writer rather than interpolated. Absent, the standard form renders. This is the vocabulary's extension pattern: where an engine lacks a standard form, the package defines an optional interface at the divergent render site and standard emission stays the default.

type Predicate

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

Predicate is a boolean expression: a comparison, a null test, a membership test, or a combination. The zero value is empty — an absent WHERE or HAVING — and And and Or drop empty operands, so optional conditions compose without special cases.

func And

func And(preds ...Predicate) Predicate

And conjoins predicates, dropping empty operands; zero remaining operands yield the empty predicate and one passes through unwrapped.

func Not

func Not(p Predicate) Predicate

Not negates a predicate. Negating the empty predicate fails the statement.

func Or

func Or(preds ...Predicate) Predicate

Or disjoins predicates with the same empty-operand rules as And.

type Projection

type Projection struct {
	With   []CTE
	From   TableRef
	Key    Field
	Fields []Field
}

Projection is a read model over one FROM: name-to-expression fields, one key field, and the CTEs the FROM references. It is plain data; every read against it goes through Projection.Statements. The key field is the identity a read pages by — it joins every ORDER BY as the tie-breaker, so offset paging is stable. CTEs declared here hoist to the top of both generated statements, the one placement every engine accepts.

func (Projection) Statements

func (p Projection) Statements(d database.Dialect, dir Directives) (Statements, error)

Statements lowers one read's directives onto the projection: field names resolve to expressions or fail with UnknownFieldError, filters become the shared WHERE clause, sorts gain the key tie-breaker whenever the caller didn't sort by it, and the page directive becomes bound offset/fetch arguments. The returned pair renders through the dialect and shares one WHERE, so the count can never disagree with the page.

type Query

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

Query is a renderable query: Select or Compound. The interface is sealed; the two implementations are the vocabulary's statement level.

type Select

type Select struct {
	With     []CTE
	Distinct bool
	Columns  []Column
	From     TableRef
	Where    Predicate
	GroupBy  []Expression
	Having   Predicate
	OrderBy  []Order
	Paging   *Paging
}

Select is a query specification as a value: build it as a struct literal and render it with Select.SQL. Zero fields are absent clauses. WITH is valid only on the outermost statement, and a subquery orders only when it pages.

func (Select) SQL

func (s Select) SQL(d database.Dialect) (string, []any, error)

SQL renders the statement through the dialect, returning the text and the bound arguments in placeholder order. A structural defect wraps ErrInvalidStatement; a nil dialect panics as a wiring defect.

type SetOp

type SetOp string

SetOp is a compound query's set operator.

const (
	SetUnion     SetOp = "UNION"
	SetIntersect SetOp = "INTERSECT"
	SetExcept    SetOp = "EXCEPT"
)

type Sort

type Sort struct {
	Field      string
	Descending bool
}

Sort is one sort directive, naming a projected field.

type Statement

type Statement struct {
	SQL  string
	Args []any
}

Statement is one rendered statement: the SQL text and its bound arguments in placeholder order.

type Statements

type Statements struct {
	Count Statement
	Page  Statement
}

Statements is a read's pair of statements over one WHERE clause. The consumer runs both: Count for the total, Page for the rows.

type TableRef

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

TableRef is a FROM clause element: a named table, an aliased derived table, or a join tree built by the join methods. The zero value fails the statement that renders it.

func Derived

func Derived(q Query) TableRef

Derived wraps a query as a derived table. It must be aliased with TableRef.As before it renders, and its query carries no WITH — the standard places WITH on the outermost statement; declare CTEs there.

func Table

func Table(name string) TableRef

Table references a named table or view, rendered verbatim.

func (TableRef) As

func (t TableRef) As(alias string) TableRef

As sets the correlation name. Table aliases render without AS — the one spelling every engine accepts. Only a table or derived table takes an alias; aliasing a join fails the statement.

func (TableRef) FullJoin

func (t TableRef) FullJoin(right TableRef, on Predicate) TableRef

FullJoin composes a FULL JOIN with the ON predicate.

func (TableRef) Join

func (t TableRef) Join(right TableRef, on Predicate) TableRef

Join composes an INNER JOIN with the ON predicate.

func (TableRef) LeftJoin

func (t TableRef) LeftJoin(right TableRef, on Predicate) TableRef

LeftJoin composes a LEFT JOIN with the ON predicate.

func (TableRef) RightJoin

func (t TableRef) RightJoin(right TableRef, on Predicate) TableRef

RightJoin composes a RIGHT JOIN with the ON predicate.

type UnknownFieldError

type UnknownFieldError struct {
	Field string
	Use   FieldUse
}

UnknownFieldError reports a sort or filter directive naming a field the projection does not declare. It is the field contract's boundary: the name never reaches the SQL, and a consumer maps the error to its own response with errors.As.

func (*UnknownFieldError) Error

func (e *UnknownFieldError) Error() string

type UnknownOperatorError

type UnknownOperatorError struct {
	Op Op
}

UnknownOperatorError reports a filter directive carrying an operator the vocabulary does not define, mapped by the consumer the same way as UnknownFieldError.

func (*UnknownOperatorError) Error

func (e *UnknownOperatorError) Error() string

type Writer

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

Writer is the surface a dialect render extension writes into: literal SQL text through SQL, bound arguments through Bind.

func (Writer) Bind

func (w Writer) Bind(v any)

Bind binds a value and writes its placeholder.

func (Writer) SQL

func (w Writer) SQL(s string)

SQL writes literal SQL text.

Jump to

Keyboard shortcuts

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