Documentation
¶
Overview ¶
Package r3sql translates r3 query types into SQL clauses.
Category: Data store dialect.
It converts r3.Filters to WHERE clauses with positional placeholders, r3.Sorts to ORDER BY expressions, and r3.PaginationSpec to LIMIT/OFFSET. This package is used by the SQL engine and drivers; most users do not import it directly.
Index ¶
- Variables
- func IsErrDialectorFailure(err error) bool
- func QuoteDottedIdentifier(path string) string
- func QuoteIdentifier(name string) string
- func SQLToField(col SQLColumn) *r3.FieldSpec
- func SQLToOperator(op SQLClauseOperator) (r3.FilterOperatorSpec, error)
- func SQLToPagination(p *SQLPagination) *r3.PaginationSpec
- func SQLToSort(s SQLSort) (*r3.SortSpec, error)
- func SafeColumnExpr(f *r3.FieldSpec) (string, error)
- type SQLClause
- type SQLClauseOperator
- type SQLClauses
- type SQLColumn
- type SQLPagination
- type SQLSort
Constants ¶
This section is empty.
Variables ¶
var ErrSQLDialectorFailed = errors.New("sql dialector failed")
ErrSQLDialectorFailed is a generic error for r3sql dialector failures.
Functions ¶
func IsErrDialectorFailure ¶
IsErrDialectorFailure checks if the given error is a r3sql failure.
func QuoteDottedIdentifier ¶
QuoteDottedIdentifier quotes a dotted identifier path (e.g., "user.name") by quoting each segment individually and joining with dots.
Examples:
QuoteDottedIdentifier("id") => `"id"`
QuoteDottedIdentifier("user.name") => `"user"."name"`
QuoteDottedIdentifier("a.b.c") => `"a"."b"."c"`
func QuoteIdentifier ¶
QuoteIdentifier wraps a single SQL identifier in double quotes, escaping any embedded double quotes by doubling them (ANSI SQL standard).
This produces identifiers safe for PostgreSQL, SQLite, and MySQL (in ANSI mode). MySQL's default backtick quoting also accepts double-quoted identifiers when ANSI_QUOTES mode is enabled, but all major ORMs (GORM, Bun, go-pg) already handle this correctly when receiving double-quoted identifiers.
Examples:
QuoteIdentifier("id") => `"id"`
QuoteIdentifier("user_name") => `"user_name"`
QuoteIdentifier(`col"name`) => `"col""name"` (escaped)
func SQLToField ¶
SQLToField converts an SQLColumn to a FieldSpec.
func SQLToOperator ¶
func SQLToOperator(op SQLClauseOperator) (r3.FilterOperatorSpec, error)
SQLToOperator converts an SQLClauseOperator back to a FilterOperatorSpec.
func SQLToPagination ¶
func SQLToPagination(p *SQLPagination) *r3.PaginationSpec
SQLToPagination converts SQLPagination to PaginationSpec.
func SafeColumnExpr ¶
SafeColumnExpr validates a FieldSpec as a safe SQL identifier and returns the quoted SQL expression. This is the primary function used by FilterToSQL and SortToSQL to prevent SQL injection via field names.
It performs two layers of defense:
- Validates that the field name contains only safe identifier characters (letters, digits, underscores, dots) via r3.ValidateIdentifier.
- Quotes each identifier segment with double quotes to prevent any remaining edge cases.
Returns an error if the field name is invalid.
Types ¶
type SQLClause ¶
type SQLClause struct {
// Clause is the raw safe SQL string (e.g. "name = ?")
Clause string
// Args is a slice of arguments to be bound to the SQL clause.
// Len of arguments must match the number of placeholders in the clause.
Args []any
// Joins is a slice of joins that are required for the clause.
Joins []SQLColumn
}
SQLClause represents a r3.Filter that can be converted into SQL Clause (used by gorm, sqlx, squirrel, etc.)
func CursorToSQLClause ¶
func CursorToSQLClause(values r3.CursorValues, sorts r3.Sorts, direction r3.CursorDirection) (SQLClause, error)
CursorToSQLClause generates a keyset pagination WHERE clause from decoded cursor values and the current sort specification.
For a single sort column (e.g., created_at DESC), it produces:
WHERE "created_at" < ?
For multiple sort columns (e.g., created_at DESC, id ASC), it produces a compound condition:
WHERE ("created_at" < ?) OR ("created_at" = ? AND "id" > ?)
The direction parameter controls whether comparison operators are > (forward) or < (backward), flipped based on the sort direction of each column.
func FilterToSQL ¶
func FilterToSQL(cf *r3.FilterSpec) (SQLClause, error)
FilterToSQL converts a FilterSpec to an SQLClause.
type SQLClauseOperator ¶
type SQLClauseOperator string
SQLClauseOperator represents a SQL operator. e.g. "=", "LIKE", "IN".
const ( SQLClauseOperatorEq SQLClauseOperator = "=" SQLClauseOperatorNe SQLClauseOperator = "!=" SQLClauseOperatorGt SQLClauseOperator = ">" SQLClauseOperatorGte SQLClauseOperator = ">=" SQLClauseOperatorLt SQLClauseOperator = "<" SQLClauseOperatorLte SQLClauseOperator = "<=" SQLClauseOperatorLike SQLClauseOperator = "LIKE" SQLClauseOperatorNotLike SQLClauseOperator = "NOT LIKE" SQLClauseOperatorILike SQLClauseOperator = "ILIKE" SQLClauseOperatorIn SQLClauseOperator = "IN" SQLClauseOperatorNotIn SQLClauseOperator = "NOT IN" )
List of supported SQL operators.
func OperatorToSQL ¶
func OperatorToSQL(op r3.FilterOperatorSpec) (SQLClauseOperator, error)
OperatorToSQL converts a FilterOperatorSpec to an SQLClauseOperator.
func (SQLClauseOperator) String ¶
func (op SQLClauseOperator) String() string
String so we implement fmt.Stringer.
func (SQLClauseOperator) ToSQL ¶
func (op SQLClauseOperator) ToSQL() string
ToSQL is the string representation that will be used inside generated SQL.
type SQLClauses ¶
type SQLClauses []SQLClause
SQLClauses is a slice of SQLClause.
func FiltersToSQL ¶
func FiltersToSQL(filters r3.Filters) (SQLClauses, error)
FiltersToSQL translates a list of r3.Filters into SQLClauses.
func FiltersToSQLClauses
deprecated
func FiltersToSQLClauses(filters r3.Filters) (SQLClauses, error)
FiltersToSQLClauses is an alias for FiltersToSQL for backward compatibility.
Deprecated: Use FiltersToSQL instead.
func (SQLClauses) Joins ¶
func (cs SQLClauses) Joins() []SQLColumn
Joins is a combined getter for each SQLClause.Joins It will return duplicates-free list.
type SQLColumn ¶
type SQLColumn string
SQLColumn stands for the string type that holds name of the column.
func FieldToSQL ¶
FieldToSQL converts a FieldSpec to an SQLColumn (raw, no quoting). This does NOT validate or quote the identifier. For safe SQL generation from user-supplied field names, use SafeColumnExpr instead.
type SQLPagination ¶
SQLPagination represents pagination in SQL format using LIMIT and OFFSET.
func NewSQLPagination ¶
func NewSQLPagination(limit, offset int) *SQLPagination
NewSQLPagination creates a new SQLPagination with given limit and offset.
func PaginationToSQL ¶
func PaginationToSQL(p *r3.PaginationSpec) *SQLPagination
PaginationToSQL converts a PaginationSpec to SQLPagination.
func (*SQLPagination) String ¶
func (sp *SQLPagination) String() string
String returns the string representation of SQL pagination.
func (*SQLPagination) ToLimitOffset ¶
func (sp *SQLPagination) ToLimitOffset() (int, int)
ToLimitOffset returns the limit and offset values.