zoobzio January 20, 2026 Edit this page

API Reference

Complete API reference for the github.com/zoobzio/astql package.

Instance Creation

NewFromDBML

func NewFromDBML(project *dbml.Project) (*ASTQL, error)

Creates a new ASTQL instance from a DBML project. Returns an error if the project is nil.

Instance Methods

T

func (a *ASTQL) T(name string, alias ...string) types.Table

Creates a validated table reference. Panics if the table doesn't exist in the schema. Optional single-letter alias (a-z).

TryT

func (a *ASTQL) TryT(name string, alias ...string) (types.Table, error)

Creates a validated table reference. Returns an error instead of panicking.

F

func (a *ASTQL) F(name string) types.Field

Creates a validated field reference. Panics if the field doesn't exist in any table in the schema.

TryF

func (a *ASTQL) TryF(name string) (types.Field, error)

Creates a validated field reference. Returns an error instead of panicking.

P

func (a *ASTQL) P(name string) types.Param

Creates a validated parameter reference. Panics if the name is not a valid SQL identifier.

TryP

func (a *ASTQL) TryP(name string) (types.Param, error)

Creates a validated parameter reference. Returns an error instead of panicking.

C

func (a *ASTQL) C(field types.Field, op types.Operator, param types.Param) types.Condition

Creates a validated condition. Panics if the field doesn't exist in the schema.

TryC

func (a *ASTQL) TryC(field types.Field, op types.Operator, param types.Param) (types.Condition, error)

Creates a validated condition. Returns an error instead of panicking.

And

func (a *ASTQL) And(conditions ...types.ConditionItem) types.ConditionGroup

Creates an AND condition group. Panics if no conditions provided.

Or

func (a *ASTQL) Or(conditions ...types.ConditionItem) types.ConditionGroup

Creates an OR condition group. Panics if no conditions provided.

Null

func (a *ASTQL) Null(field types.Field) types.Condition

Creates an IS NULL condition.

NotNull

func (a *ASTQL) NotNull(field types.Field) types.Condition

Creates an IS NOT NULL condition.

WithTable

func (a *ASTQL) WithTable(field types.Field, tableOrAlias string) types.Field

Prefixes a field with a table name or alias. Panics if tableOrAlias is not a valid table name or single-letter alias.

TryWithTable

func (a *ASTQL) TryWithTable(field types.Field, tableOrAlias string) (types.Field, error)

Prefixes a field with a table name or alias. Returns an error instead of panicking.

AggC

func (a *ASTQL) AggC(aggFunc types.AggregateFunc, field *types.Field, op types.Operator, param types.Param) types.AggregateCondition

Creates a validated aggregate condition for HAVING clauses. Use nil for field to create COUNT(*).

TryAggC

func (a *ASTQL) TryAggC(aggFunc types.AggregateFunc, field *types.Field, op types.Operator, param types.Param) (types.AggregateCondition, error)

Creates a validated aggregate condition. Returns an error instead of panicking.

ValueMap

func (a *ASTQL) ValueMap() map[types.Field]types.Param

Returns an empty map for building INSERT value sets.

JSONBText

func (a *ASTQL) JSONBText(field types.Field, key types.Param) types.Field

Creates a JSONB text extraction field with a parameterized key. Renders as field->>:key_param. PostgreSQL only. The key is passed as a parameter for SQL injection safety.

JSONBPath

func (a *ASTQL) JSONBPath(field types.Field, key types.Param) types.Field

Creates a JSONB path access field with a parameterized key. Renders as field->:key_param. PostgreSQL only. Use with ArrayContains for JSONB array queries. The key is passed as a parameter for SQL injection safety.

Query Builders

Select

func Select(t types.Table) *Builder

Creates a new SELECT query builder.

Insert

func Insert(t types.Table) *Builder

Creates a new INSERT query builder.

Update

func Update(t types.Table) *Builder

Creates a new UPDATE query builder.

Delete

func Delete(t types.Table) *Builder

Creates a new DELETE query builder.

Count

func Count(t types.Table) *Builder

Creates a new COUNT query builder.

Builder Methods

Fields

func (b *Builder) Fields(fields ...types.Field) *Builder

Sets the fields to select. SELECT only.

Where

func (b *Builder) Where(condition types.ConditionItem) *Builder

Sets or adds WHERE conditions. Multiple calls combine with AND.

WhereField

func (b *Builder) WhereField(f types.Field, op types.Operator, p types.Param) *Builder

Shorthand for simple field conditions.

OrderBy

func (b *Builder) OrderBy(f types.Field, direction types.Direction) *Builder

Adds ORDER BY clause.

OrderByNulls

func (b *Builder) OrderByNulls(f types.Field, direction types.Direction, nulls types.NullsOrdering) *Builder

Adds ORDER BY with NULLS FIRST/LAST.

OrderByExpr

func (b *Builder) OrderByExpr(f types.Field, op types.Operator, p types.Param, direction types.Direction) *Builder

Adds ORDER BY with an expression (e.g., vector distance).

Limit

func (b *Builder) Limit(limit int) *Builder

Sets the LIMIT clause with a static value.

LimitParam

func (b *Builder) LimitParam(param types.Param) *Builder

Sets the LIMIT clause with a parameterized value.

Offset

func (b *Builder) Offset(offset int) *Builder

Sets the OFFSET clause with a static value.

OffsetParam

func (b *Builder) OffsetParam(param types.Param) *Builder

Sets the OFFSET clause with a parameterized value.

Set

func (b *Builder) Set(f types.Field, p types.Param) *Builder

Adds a field update. UPDATE only.

SetExpr

func (b *Builder) SetExpr(f types.Field, expr types.FieldExpression) *Builder

Adds a field update with an expression value. UPDATE only. Use this for computed assignments like atomic increments.

// Returns: "items_completed" = "items_completed" + :increment
.SetExpr(instance.F("items_completed"), types.FieldExpression{
    Binary: &types.BinaryExpression{
        Field:    instance.F("items_completed"),
        Operator: "+",
        Param:    instance.P("increment"),
    },
})

Values

func (b *Builder) Values(valueMap map[types.Field]types.Param) *Builder

Adds a row of values. INSERT only. Call multiple times for multiple rows.

Returning

func (b *Builder) Returning(fields ...types.Field) *Builder

Adds RETURNING clause. INSERT, UPDATE, DELETE only.

Distinct

func (b *Builder) Distinct() *Builder

Adds DISTINCT to SELECT.

DistinctOn

func (b *Builder) DistinctOn(fields ...types.Field) *Builder

Adds DISTINCT ON to SELECT. PostgreSQL only.

GroupBy

func (b *Builder) GroupBy(fields ...types.Field) *Builder

Adds GROUP BY clause. SELECT only.

Having

func (b *Builder) Having(conditions ...types.Condition) *Builder

Adds HAVING conditions. Requires GROUP BY.

HavingAgg

func (b *Builder) HavingAgg(conditions ...types.AggregateCondition) *Builder

Adds aggregate HAVING conditions (COUNT(*) > ). Requires GROUP BY.

SelectExpr

func (b *Builder) SelectExpr(expr types.FieldExpression) *Builder

Adds a field expression (aggregate, CASE, window function).

SelectBinaryExpr

func (b *Builder) SelectBinaryExpr(f types.Field, op types.Operator, p types.Param, alias string) *Builder

Adds a binary expression (field param) with an alias to SELECT. Useful for vector distance calculations with pgvector.

// Returns: "embedding" <=> :query_vec AS "score"
.SelectBinaryExpr(instance.F("embedding"), astql.VectorCosineDistance, instance.P("query_vec"), "score")

OnConflict

func (b *Builder) OnConflict(columns ...types.Field) *ConflictBuilder

Starts ON CONFLICT clause. INSERT only.

Join Methods

func (b *Builder) Join(table types.Table, on types.ConditionItem) *Builder
func (b *Builder) InnerJoin(table types.Table, on types.ConditionItem) *Builder
func (b *Builder) LeftJoin(table types.Table, on types.ConditionItem) *Builder
func (b *Builder) RightJoin(table types.Table, on types.ConditionItem) *Builder
func (b *Builder) FullOuterJoin(table types.Table, on types.ConditionItem) *Builder
func (b *Builder) CrossJoin(table types.Table) *Builder

Adds JOIN clauses. SELECT and COUNT only.

Row Locking

func (b *Builder) ForUpdate() *Builder
func (b *Builder) ForNoKeyUpdate() *Builder
func (b *Builder) ForShare() *Builder
func (b *Builder) ForKeyShare() *Builder

Adds row locking. SELECT only.

Build

func (b *Builder) Build() (*types.AST, error)

Returns the constructed AST or an error.

MustBuild

func (b *Builder) MustBuild() *types.AST

Returns the AST or panics on error.

Render

func (b *Builder) Render(renderer Renderer) (*QueryResult, error)

Builds and renders the query to SQL using the specified provider (e.g., postgres.New(), sqlite.New()).

MustRender

func (b *Builder) MustRender(renderer Renderer) *QueryResult

Builds and renders the query with the specified provider or panics on error.

Set Operations

Union / UnionAll

func (b *Builder) Union(other *Builder) *CompoundBuilder
func (b *Builder) UnionAll(other *Builder) *CompoundBuilder

Creates a UNION or UNION ALL between two SELECT queries.

Intersect / IntersectAll

func (b *Builder) Intersect(other *Builder) *CompoundBuilder
func (b *Builder) IntersectAll(other *Builder) *CompoundBuilder

Creates an INTERSECT between two SELECT queries.

Except / ExceptAll

func (b *Builder) Except(other *Builder) *CompoundBuilder
func (b *Builder) ExceptAll(other *Builder) *CompoundBuilder

Creates an EXCEPT between two SELECT queries.

Rendering

Rendering is done through provider instances. Each provider implements the Renderer interface:

type Renderer interface {
    Render(ast *types.AST) (*QueryResult, error)
    RenderCompound(query *types.CompoundQuery) (*QueryResult, error)
}

Use the provider's methods directly or through the builder's Render() method:

// Through builder (recommended)
result, err := query.Render(postgres.New())

// Direct provider use
ast, _ := query.Build()
result, err := postgres.New().Render(ast)

Expression Functions

Aggregates

func Sum(field types.Field) types.FieldExpression
func Avg(field types.Field) types.FieldExpression
func Min(field types.Field) types.FieldExpression
func Max(field types.Field) types.FieldExpression
func CountField(field types.Field) types.FieldExpression
func CountDistinct(field types.Field) types.FieldExpression
func CountStar() types.FieldExpression

Filter Aggregates

func SumFilter(field types.Field, filter types.ConditionItem) types.FieldExpression
func AvgFilter(field types.Field, filter types.ConditionItem) types.FieldExpression
func MinFilter(field types.Field, filter types.ConditionItem) types.FieldExpression
func MaxFilter(field types.Field, filter types.ConditionItem) types.FieldExpression
func CountFieldFilter(field types.Field, filter types.ConditionItem) types.FieldExpression
func CountDistinctFilter(field types.Field, filter types.ConditionItem) types.FieldExpression

Binary Expressions

func BinaryExpr(field types.Field, op types.Operator, param types.Param) types.FieldExpression

Creates a binary expression for field <op> param patterns. Commonly used with vector distance operators to select computed distances as columns.

For selecting binary expressions, prefer the builder method SelectBinaryExpr for cleaner syntax:

// Preferred: using SelectBinaryExpr
.SelectBinaryExpr(instance.F("embedding"), astql.VectorL2Distance, instance.P("query"), "distance")

// Alternative: using BinaryExpr with As
.SelectExpr(astql.As(
    astql.BinaryExpr(instance.F("embedding"), astql.VectorL2Distance, instance.P("query")),
    "distance",
))

// Both render: "embedding" <-> :query AS "distance"

Conditions

func Between(field types.Field, low, high types.Param) types.BetweenCondition
func NotBetween(field types.Field, low, high types.Param) types.BetweenCondition
func CF(left types.Field, op types.Operator, right types.Field) types.FieldComparison

Subqueries

func Sub(builder *Builder) types.Subquery
func CSub(field types.Field, op types.Operator, subquery types.Subquery) types.SubqueryCondition
func CSubExists(op types.Operator, subquery types.Subquery) types.SubqueryCondition

CASE Expression

func Case() *CaseBuilder
func (cb *CaseBuilder) When(condition types.ConditionItem, result types.Param) *CaseBuilder
func (cb *CaseBuilder) Else(result types.Param) *CaseBuilder
func (cb *CaseBuilder) As(alias string) *CaseBuilder
func (cb *CaseBuilder) Build() types.FieldExpression

Null Handling

func Coalesce(values ...types.Param) types.FieldExpression
func NullIf(value1, value2 types.Param) types.FieldExpression

Math Functions

func Round(field types.Field, precision ...types.Param) types.FieldExpression
func Floor(field types.Field) types.FieldExpression
func Ceil(field types.Field) types.FieldExpression
func Abs(field types.Field) types.FieldExpression
func Power(field types.Field, exponent types.Param) types.FieldExpression
func Sqrt(field types.Field) types.FieldExpression

String Functions

func Upper(field types.Field) types.FieldExpression
func Lower(field types.Field) types.FieldExpression
func Trim(field types.Field) types.FieldExpression
func LTrim(field types.Field) types.FieldExpression
func RTrim(field types.Field) types.FieldExpression
func Length(field types.Field) types.FieldExpression
func Substring(field types.Field, start types.Param, length types.Param) types.FieldExpression
func Replace(field types.Field, search types.Param, replacement types.Param) types.FieldExpression
func Concat(fields ...types.Field) types.FieldExpression

Date Functions

func Now() types.FieldExpression                                    // Current timestamp
func CurrentDate() types.FieldExpression                            // Current date
func CurrentTime() types.FieldExpression                            // Current time
func CurrentTimestamp() types.FieldExpression                       // Current timestamp
func Extract(part types.DatePart, field types.Field) types.FieldExpression  // Extract part from date
func DateTrunc(part types.DatePart, field types.Field) types.FieldExpression // Truncate to precision

Date parts: PartYear, PartMonth, PartDay, PartHour, PartMinute, PartSecond, PartWeek, PartQuarter, PartDayOfWeek, PartDayOfYear, PartEpoch.

Type Casting

func Cast(field types.Field, castType types.CastType) types.FieldExpression

Window Functions

func RowNumber() *WindowBuilder
func Rank() *WindowBuilder
func DenseRank() *WindowBuilder
func Ntile(n types.Param) *WindowBuilder
func Lag(field types.Field, offset types.Param, defaultVal ...types.Param) *WindowBuilder
func Lead(field types.Field, offset types.Param, defaultVal ...types.Param) *WindowBuilder
func FirstValue(field types.Field) *WindowBuilder
func LastValue(field types.Field) *WindowBuilder
func SumOver(field types.Field) *WindowBuilder
func AvgOver(field types.Field) *WindowBuilder
func CountOver(field ...types.Field) *WindowBuilder
func MinOver(field types.Field) *WindowBuilder
func MaxOver(field types.Field) *WindowBuilder

Window Specification

func Window() *WindowSpecBuilder
func (wsb *WindowSpecBuilder) PartitionBy(fields ...types.Field) *WindowSpecBuilder
func (wsb *WindowSpecBuilder) OrderBy(field types.Field, direction types.Direction) *WindowSpecBuilder
func (wsb *WindowSpecBuilder) OrderByNulls(field types.Field, direction types.Direction, nulls types.NullsOrdering) *WindowSpecBuilder
func (wsb *WindowSpecBuilder) Rows(start, end types.FrameBound) *WindowSpecBuilder
func (wsb *WindowSpecBuilder) Build() types.WindowSpec

WindowBuilder Methods

func (wb *WindowBuilder) Over(spec types.WindowSpec) *WindowBuilder
func (wb *WindowBuilder) OverBuilder(builder *WindowSpecBuilder) *WindowBuilder
func (wb *WindowBuilder) PartitionBy(fields ...types.Field) *WindowBuilder
func (wb *WindowBuilder) OrderBy(field types.Field, direction types.Direction) *WindowBuilder
func (wb *WindowBuilder) Frame(start, end types.FrameBound) *WindowBuilder
func (wb *WindowBuilder) As(alias string) types.FieldExpression
func (wb *WindowBuilder) Build() types.FieldExpression

Expression Alias

func As(expr types.FieldExpression, alias string) types.FieldExpression

HAVING Helpers

func HavingCount(op types.Operator, value types.Param) types.AggregateCondition
func HavingCountField(field types.Field, op types.Operator, value types.Param) types.AggregateCondition
func HavingCountDistinct(field types.Field, op types.Operator, value types.Param) types.AggregateCondition
func HavingSum(field types.Field, op types.Operator, value types.Param) types.AggregateCondition
func HavingAvg(field types.Field, op types.Operator, value types.Param) types.AggregateCondition
func HavingMin(field types.Field, op types.Operator, value types.Param) types.AggregateCondition
func HavingMax(field types.Field, op types.Operator, value types.Param) types.AggregateCondition

Types

QueryResult

type QueryResult struct {
    SQL            string
    RequiredParams []string
}

Contains the rendered SQL and list of required parameters.

Direction

const (
    ASC  Direction = "ASC"
    DESC Direction = "DESC"
)

Sort direction for ORDER BY.

NullsOrdering

const (
    NullsFirst NullsOrdering = "NULLS FIRST"
    NullsLast  NullsOrdering = "NULLS LAST"
)

NULL ordering for ORDER BY.

Operation

const (
    OpSelect Operation = "SELECT"
    OpInsert Operation = "INSERT"
    OpUpdate Operation = "UPDATE"
    OpDelete Operation = "DELETE"
    OpCount  Operation = "COUNT"
)

Query operation types.

Providers

Renderer Interface

type Renderer interface {
    Render(ast *types.AST) (*types.QueryResult, error)
    RenderCompound(query *types.CompoundQuery) (*types.QueryResult, error)
    Capabilities() render.Capabilities
}

Capabilities

Query dialect capabilities before execution:

type Capabilities struct {
    DistinctOn          bool            // DISTINCT ON (field, ...)
    Upsert              bool            // ON CONFLICT / ON DUPLICATE KEY
    ReturningOnInsert   bool            // RETURNING after INSERT
    ReturningOnUpdate   bool            // RETURNING after UPDATE
    ReturningOnDelete   bool            // RETURNING after DELETE
    CaseInsensitiveLike bool            // ILIKE operator
    RegexOperators      bool            // ~, ~*, !~, !~*
    ArrayOperators      bool            // @>, <@, &&
    InArray             bool            // IN (:array_param)
    RowLocking          RowLockingLevel // FOR UPDATE/SHARE support
}

type RowLockingLevel int

const (
    RowLockingNone  RowLockingLevel = iota // No row locking
    RowLockingBasic                        // FOR UPDATE, FOR SHARE
    RowLockingFull                         // + FOR NO KEY UPDATE, FOR KEY SHARE
)

Example usage:

renderer := postgres.New()
caps := renderer.Capabilities()

if caps.Upsert {
    // Safe to use ON CONFLICT
}

PostgreSQL Provider

import "github.com/zoobzio/astql/postgres"

renderer := postgres.New()
result, err := query.Render(renderer)

Full feature support.

SQLite Provider

import "github.com/zoobzio/astql/sqlite"

renderer := sqlite.New()
result, err := query.Render(renderer)

Returns UnsupportedFeatureError for features not available in SQLite:

  • DISTINCT ON
  • ILIKE / NOT ILIKE
  • Regex operators (~, ~*, !~, !~*)
  • Array operators (@>, <@, &&)
  • Vector operators (<->, <#>, <=>, <+>)
  • JSONB field access (->>, ->)
  • IN / NOT IN with array parameters
  • Row-level locking (FOR UPDATE, FOR SHARE)
  • POWER and SQRT math functions

MariaDB Provider

import "github.com/zoobzio/astql/mariadb"

renderer := mariadb.New()
result, err := query.Render(renderer)

MariaDB-specific behavior:

  • Uses backtick quoting for identifiers: `name`
  • Uses :name parameter placeholders (sqlx compatible)
  • ON CONFLICT DO UPDATEON DUPLICATE KEY UPDATE
  • ON CONFLICT DO NOTHINGON DUPLICATE KEY UPDATE field = field (no-op)
  • ILIKE maps to LIKE (MariaDB LIKE is case-insensitive by default)
  • Standard IN (...) syntax instead of = ANY(:array)
  • RETURNING clause support for INSERT/DELETE (MariaDB 10.5+, UPDATE not supported)

Returns UnsupportedFeatureError for:

  • DISTINCT ON
  • FILTER on aggregates
  • Regex operators (~, ~*, !~, !~*)
  • Array operators (@>, <@, &&)
  • Vector operators (<->, <#>, <=>, <+>)
  • JSONB field access (->>, ->)
  • FOR NO KEY UPDATE / FOR KEY SHARE (use FOR UPDATE or FOR SHARE instead)

SQL Server Provider

import "github.com/zoobzio/astql/mssql"

renderer := mssql.New()
result, err := query.Render(renderer)

SQL Server-specific behavior:

  • Uses square bracket quoting for identifiers: [name]
  • Uses @name parameter placeholders
  • LIMIT/OFFSETOFFSET n ROWS FETCH NEXT m ROWS ONLY (requires ORDER BY)
  • RETURNINGOUTPUT INSERTED.* / OUTPUT DELETED.*
  • LENGTH()LEN()
  • NOW()GETDATE()
  • EXTRACT()DATEPART()
  • !=<> (preferred SQL Server syntax)

Returns UnsupportedFeatureError for:

  • ON CONFLICT / upsert (MERGE is too complex)
  • DISTINCT ON
  • ILIKE / NOT ILIKE
  • FILTER on aggregates
  • Regex operators (~, ~*, !~, !~*)
  • Array operators (@>, <@, &&)
  • Vector operators (<->, <#>, <=>, <+>)
  • JSONB field access (->>, ->)
  • Row-level locking (FOR UPDATE, FOR SHARE)
  • LIMIT without ORDER BY (returns error)