Help us shape the future of Go! Take the 2026 Go Developer Survey

core

package
v1.20.0-alpha.0 Latest Latest
Warning

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

Go to latest
Published: Oct 29, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package core defines the shared query representation and value utilities used by builders, SQL grammars and execution adapters. It does not depend on a compiler.

Index

Constants

View Source
const (
	DialectMySQL     = "mysql"
	DialectPostgres  = "postgres"
	DialectSqlite    = "sqlite"
	DialectSqlServer = "sqlserver"
)

Dialect names, matching the values carried in database.Config.Driver.

View Source
const (
	BooleanAnd    = "and"
	BooleanOr     = "or"
	BooleanAndNot = "and not"
	BooleanOrNot  = "or not"
)

Boolean connectors. Negation is carried in the connector, never in a separate flag, exactly as Laravel does, so "and not" and "or not" are values of the same field.

Variables

View Source
var BindingTypes = []string{"select", "from", "join", "where", "groupBy", "having", "order", "union", "unionOrder"}

BindingTypes fixes the order of positional binding groups.

Functions

func AsString

func AsString(value any) string

AsString renders a value as a string without panicking on a nil or non-string column.

func CanonicalDialect

func CanonicalDialect(driver string) string

CanonicalDialect maps a driver name onto the dialect string this package switches on.

The four driver modules report their names capitalised and, for SQL Server, with a space ("PostgreSQL", "MySQL", "SQLite", "SQL Server"), while an application's config may carry either that name or the lowercase form. Matching therefore happens on a trimmed, lowercased name with the separators removed and the common aliases folded in. An unknown driver yields "".

func CastBinding

func CastBinding(value any) any

CastBinding preserves standard SQL values while lowering explicit enum cases.

func ExpressionValue

func ExpressionValue(value any) string

ExpressionValue returns the raw SQL of an expression, or "" when value is not one.

func FirstAndLast

func FirstAndLast(values []any) (any, any)

FirstAndLast returns the first and last element, mirroring array_first and array_last.

func GetValueString

func GetValueString(value any) string

GetValueString mirrors PHP's "(string) $this->getValue($value)": an Expression contributes its raw SQL, anything else its string form. MySqlGrammar::whereNull()/whereNotNull() stringify the column this way before sniffing it for a JSON selector, so a raw "items->id" still takes the json_extract path rather than being wrapped as a plain identifier.

func IsArrayValue

func IsArrayValue(value any) bool

IsArrayValue reports whether a value is a PHP array in Laravel's is_array() sense: a Go slice or map. A []byte is a PHP binary string rather than an array, so it is left out. It decides which update values the grammars json-encode before binding.

func IsExpression

func IsExpression(value any) bool

IsExpression reports whether value is a raw SQL expression. Mirrors Grammar::isExpression().

func JoinAny

func JoinAny(values []any) string

JoinAny renders values comma separated, used by the raw in clauses.

func LastDotSegment

func LastDotSegment(value string) string

LastDotSegment mirrors PHP's last(explode('.', $key)): the key after its final dot, or the key itself when it has none. Grammars use it to strip a table qualifier from an update column, so a qualified key such as "users.email" assigns to the bare column.

func NormalizeDriver

func NormalizeDriver(driver string) string

NormalizeDriver reduces a driver name to the lowercased, separator-free form used by dialect identification and grammar selection.

func NormalizeJSONMembershipValue

func NormalizeJSONMembershipValue(value any) (any, error)

NormalizeJSONMembershipValue leaves an ordinary collection for the membership dialect to inspect one scalar at a time. Each element's Valuer is evaluated before its shape is checked.

func NormalizeJSONValue

func NormalizeJSONValue(value any) (any, error)

NormalizeJSONValue prepares an explicit JSON operation. A Valuer's valid JSON text denotes a document; ordinary unquoted SQL text denotes a string scalar. Types that require valid JSON must validate it in Value (as database/types.JSON does). Valuer errors are always preserved. Ordinary whole-column bindings retain the original Valuer and do not use this document preparation.

func RenderLiteral

func RenderLiteral(value any) string

RenderLiteral renders a value as a SQL literal.

The recognised kinds mirror GORM's own statement explainer, which the ToRawSql surface used to delegate to: strings and byte slices are single quoted, numbers and booleans are printed bare, and anything implementing sql/driver.Valuer is rendered through its own driver value.

func ReplacePlaceholders

func ReplacePlaceholders(sql string, driver string) string

ReplacePlaceholders rewrites the grammar's "?" placeholders into the dialect's own form.

The grammars emit "?" for every dialect, exactly as Laravel does. Postgres needs "$1", "$2" and so on, which is what the existing squirrel based builder produced through sq.Dollar. SQL Server needs "@p1", "@p2" and so on, because go-mssqldb "uses native "@" parameter placeholder names and does no pre-processing" and names an ordinal parameter "@pN" (its doc.go). MySQL and SQLite take "?" as it stands and are returned unchanged. A doubled "??" is an escaped literal question mark, used by operators such as "?", and is left as a single "?".

A "?" inside a single- or double-quoted literal is part of that literal's text rather than a binding, so quoting is tracked and such a mark is left exactly as it stands: rewriting it would both corrupt the literal and shift every following placeholder's number. This is the same rule database/db's Raw interpolation follows, so a statement is read the same way by both renderers.

func SortedKeys

func SortedKeys(values map[string]any) []string

SortedKeys returns a map's keys in ascending order. Laravel ksort()s insert and update records so column and placeholder order line up; Go maps are unordered, so sorting is mandatory.

func StringsToAny

func StringsToAny(values []string) []any

StringsToAny converts a string slice to []any.

func ToAnySlice

func ToAnySlice(value any) []any

ToAnySlice normalises any slice or array to []any. Go callers pass []int, []string and other concrete slice types where Laravel would pass a plain array, so the builder must accept them all.

Types

type Aggregate

type Aggregate struct {
	Function string
	Columns  []any
}

Aggregate is the aggregate function and its columns.

type BackedEnum

type BackedEnum interface{ EnumValue() any }

type Expression

type Expression struct {
	Value string
}

Expression is a raw SQL fragment. The grammar emits Value verbatim and records no binding for it.

Mirrors Illuminate\Database\Query\Expression.

func Raw

func Raw(value string) Expression

Raw creates a raw SQL expression.

func (Expression) GetValue

func (e Expression) GetValue() string

GetValue returns the raw SQL. Mirrors Expression::getValue().

type Having

type Having struct {
	Type     HavingType
	Boolean  string
	Column   any
	Operator string
	Value    any
	Values   []any
	Not      bool
	SQL      any
	Query    Query
}

Having is one having descriptor.

type HavingType

type HavingType string

HavingType matches Laravel's $having['type'] strings.

const (
	HavingBasic          HavingType = "Basic"
	HavingRawType        HavingType = "Raw"
	HavingBetweenType    HavingType = "between"
	HavingNullType       HavingType = "Null"
	HavingNotNullType    HavingType = "NotNull"
	HavingBitType        HavingType = "Bitwise"
	HavingExpressionType HavingType = "Expression"
	HavingNestedType     HavingType = "Nested"
)

HavingBitType carries Laravel's "Bitwise" string, the type Builder::having() stamps on a bitwise operator (Builder.php:2507); the Go identifier keeps the descriptive name.

type IndexHint

type IndexHint struct {
	// Type is hint, force or ignore.
	Type string
	// Index is the index name.
	Index string
}

type InsertValue

type InsertValue struct {
	// Column is the column being written.
	Column string
	// Value is the value written to it.
	Value any
}

InsertValue is one column/value pair of an insert record. Laravel's Builder::insertGetId() receives an associative array whose insertion order fixes the column list and the placeholder order; a Go map cannot carry that order, so callers that care about it pass InsertValues.

type InsertValues

type InsertValues []InsertValue

InsertValues is the ordered single record an insertGetId carries. ToInsertGetIdSQL accepts either an InsertValues, which is used exactly as given, or a []map[string]any, whose columns are ordered by name (the historic behaviour of the map-shaped API, and the same ksort an insert performs). Laravel's insertGetId() does not ksort a single record, so the ordered form is what reproduces its SQL.

type Join

type Join interface {
	Query
	JoinType() string
	JoinTable() any
	IsLateral() bool
}

Join adds the join metadata to the compilation view.

type Order

type Order struct {
	Type      OrderType
	Column    any
	Direction string
	SQL       any
}

Order is one order descriptor.

type OrderType

type OrderType string

OrderType matches Laravel's order descriptor: an empty type is a column plus direction, and OrderRaw carries a raw fragment.

const OrderRawType OrderType = "Raw"

type Query

type Query interface {
	State() *State
	CloneForGrammar() Query
	SetError(error)
	Error() error
	ToSQL() string
	GetBindings() []any
	RawBindings(string) []any
	SetBindings([]any, string) error
}

Query is the builder view used by SQL compilers. It contains no execution or fluent API.

type State

type State struct {
	UseWritePdo      bool
	ServerVersion    func() (string, error)
	UseUpsertAlias   bool
	Bindings         map[string][]any
	Aggregate        *Aggregate
	Columns          []any
	Distinct         bool
	DistinctColumns  []any
	From             any
	Joins            []Join
	Wheres           []Where
	Groups           []any
	Havings          []Having
	Orders           []Order
	Limit            *int
	Offset           *int
	IndexHint        *IndexHint
	GroupLimit       int
	GroupLimitSet    bool
	GroupLimitColumn string
	Unions           []Union
	UnionLimit       *int
	UnionOffset      *int
	UnionOrders      []Order
	Lock             any
	InsertColumns    []string
	IsJoinClause     bool
}

State holds the clauses compiled by a grammar, matching Laravel's public builder properties.

type Statement

type Statement struct {
	SQL      string
	Bindings []any
}

Statement is one compiled SQL statement plus its bindings. Laravel returns a map of sql => bindings from compileTruncate because SQLite truncation needs two statements.

type SubQueryBindings

type SubQueryBindings struct {
	Values []any
}

subQueryBindings carries the bindings a subquery-valued assignment contributes when an update is prepared for execution. It is a struct rather than a plain slice so the dialect transforms that json-encode array values can tell it apart from a real array value, mirroring Laravel, where the same role is played by the bindings closure Builder::update() wraps a query value in.

type Union

type Union struct {
	Query Query
	All   bool
}

Union is one union descriptor.

type UnitEnum

type UnitEnum interface{ EnumName() string }

type UpdateValue

type UpdateValue struct {
	// Column is the column or JSON selector being assigned.
	Column string
	// Value is the value assigned to it.
	Value any
}

UpdateValue is one column assignment of an update statement. Laravel's Builder::update() receives an associative array whose insertion order fixes both the SET list and the order of the bound values; a Go map cannot carry that order, so callers that care about it pass UpdateValues.

type UpdateValues

type UpdateValues []UpdateValue

UpdateValues is the ordered list of assignments an update carries. ToUpdateSQL accepts either an UpdateValues, which is used exactly as given, or a plain map[string]any, which is ordered by column name (the historic behaviour of the map-shaped API this replaced, and the same ksort an insert performs). Every grammar iterates the UpdateValues in order, exactly as Laravel's grammars map over the update array.

type UpsertUpdate

type UpsertUpdate struct {
	// Column is the target column.
	Column string
	// Value is the bound value. It is only meaningful when Bound is true.
	Value any
	// Bound reports whether Value should be bound as a parameter.
	Bound bool
}

UpsertUpdate is one upsert update target. Mirrors the assoc array Laravel passes as $update: a bare column means "copy the value from the proposed row", a bound entry means "assign this value".

type Where

type Where struct {
	Type WhereType
	// Boolean is the connector: and, or, "and not" or "or not".
	Boolean string

	// Column is used by Basic, Bitwise, JsonBoolean, In, NotIn, InRaw, NotInRaw, Null, NotNull,
	// between, betweenColumns, Sub, JsonContains, JsonContainsKey, JsonLength, JsonOverlaps,
	// the Date family, Like and Expression.
	Column any
	// First and Second are used by Column.
	First  any
	Second any
	// Operator is used by Basic, Bitwise, Column, Sub, JsonLength, RowValues and the Date family.
	Operator string
	// Value is used by Basic, JsonBoolean, JsonLength, JsonContains, JsonOverlaps, valueBetween,
	// Like, Fulltext and the Date family.
	Value any
	// Values is used by In, NotIn, InRaw, NotInRaw, between, betweenColumns and RowValues.
	Values []any
	// Columns is used by valueBetween, RowValues and Fulltext.
	Columns []any

	// Not is used by between, betweenColumns, valueBetween, JsonContains, JsonContainsKey,
	// JsonLength, JsonOverlaps and Like.
	Not bool
	// CaseSensitive is used by Like.
	CaseSensitive bool
	// Options is used by Fulltext.
	Options []string

	// Query is the child builder for Nested, Sub, Exists and NotExists.
	Query Query
	// SQL is the raw fragment for the raw type.
	SQL any
}

Where is one where descriptor. Laravel stores these as associative arrays holding only the fields relevant to the type; Go needs a single struct, so each field names the types that use it.

type WhereType

type WhereType string

WhereType matches Laravel's $where['type'] strings. The grammar dispatches on the string, so the values must match exactly.

const (
	WhereBasic               WhereType = "Basic"
	WhereBitwise             WhereType = "Bitwise"
	WhereJsonBoolean         WhereType = "JsonBoolean"
	WhereColumnType          WhereType = "Column"
	WhereRawType             WhereType = "Raw"
	WhereInType              WhereType = "In"
	WhereNotInType           WhereType = "NotIn"
	WhereInRawType           WhereType = "InRaw"
	WhereNotInRawType        WhereType = "NotInRaw"
	WhereNullType            WhereType = "Null"
	WhereNotNullType         WhereType = "NotNull"
	WhereBetweenType         WhereType = "between"
	WhereBetweenColsType     WhereType = "betweenColumns"
	WhereValueBetweenType    WhereType = "valueBetween"
	WhereNestedType          WhereType = "Nested"
	WhereSubType             WhereType = "Sub"
	WhereExistsType          WhereType = "Exists"
	WhereNotExistsType       WhereType = "NotExists"
	WhereRowValuesType       WhereType = "RowValues"
	WhereJsonContainsType    WhereType = "JsonContains"
	WhereJsonContainsKeyType WhereType = "JsonContainsKey"
	WhereJsonLengthType      WhereType = "JsonLength"
	WhereJsonOverlapsType    WhereType = "JsonOverlaps"
	WhereFullTextType        WhereType = "Fulltext"
	WhereDateType            WhereType = "Date"
	WhereTimeType            WhereType = "Time"
	WhereDayType             WhereType = "Day"
	WhereMonthType           WhereType = "Month"
	WhereYearType            WhereType = "Year"
	WhereLikeType            WhereType = "Like"
	WhereExpressionType      WhereType = "Expression"
)

Jump to

Keyboard shortcuts

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