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(*) >
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
// 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 ONILIKE/NOT ILIKE- Regex operators (
~,~*,!~,!~*) - Array operators (
@>,<@,&&) - Vector operators (
<->,<#>,<=>,<+>) - JSONB field access (
->>,->) IN/NOT INwith array parameters- Row-level locking (
FOR UPDATE,FOR SHARE) POWERandSQRTmath 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
:nameparameter placeholders (sqlx compatible) ON CONFLICT DO UPDATE→ON DUPLICATE KEY UPDATEON CONFLICT DO NOTHING→ON DUPLICATE KEY UPDATE field = field(no-op)ILIKEmaps toLIKE(MariaDB LIKE is case-insensitive by default)- Standard
IN (...)syntax instead of= ANY(:array) RETURNINGclause support for INSERT/DELETE (MariaDB 10.5+, UPDATE not supported)
Returns UnsupportedFeatureError for:
DISTINCT ONFILTERon aggregates- Regex operators (
~,~*,!~,!~*) - Array operators (
@>,<@,&&) - Vector operators (
<->,<#>,<=>,<+>) - JSONB field access (
->>,->) FOR NO KEY UPDATE/FOR KEY SHARE(useFOR UPDATEorFOR SHAREinstead)
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
@nameparameter placeholders LIMIT/OFFSET→OFFSET n ROWS FETCH NEXT m ROWS ONLY(requiresORDER BY)RETURNING→OUTPUT INSERTED.*/OUTPUT DELETED.*LENGTH()→LEN()NOW()→GETDATE()EXTRACT()→DATEPART()!=→<>(preferred SQL Server syntax)
Returns UnsupportedFeatureError for:
ON CONFLICT/ upsert (MERGE is too complex)DISTINCT ONILIKE/NOT ILIKEFILTERon aggregates- Regex operators (
~,~*,!~,!~*) - Array operators (
@>,<@,&&) - Vector operators (
<->,<#>,<=>,<+>) - JSONB field access (
->>,->) - Row-level locking (
FOR UPDATE,FOR SHARE) LIMITwithoutORDER BY(returns error)