Table of contents
Part of nurago, a collection of independent Go packages for backend services.
import "github.com/tecnickcom/nurago/pkg/sqlutil"
Package sqlutil quotes identifiers and string literals when generating SQL query fragments dynamically.
What It Provides
New returns a configurable SQLUtil instance exposing:
SQLUtil.QuoteIDfor quoting identifiers (schema/table/column names).SQLUtil.QuoteValuefor quoting string literal values.
The default implementation is mysql-like:
- identifiers are split by “.” and each segment is wrapped in backticks, with embedded backticks escaped as doubled backticks (no other escaping: inside backtick quotes only the backtick is special).
- values are wrapped in single quotes, with embedded single quotes doubled
and control characters escaped (
\0,\n,\r,\\,\Z); the empty string yields an empty quoted literal (two single quotes).
Customization
Use options to adapt quoting rules for different SQL dialects:
WithQuoteIDFuncreplaces identifier quoting behavior.WithQuoteValueFuncreplaces value quoting behavior.
This adapts quoting to Postgres, SQLite, or other dialects.
Important Boundary
This package is intended for quoting identifiers and string literals in dynamic query generation. It is not a replacement for prepared statements and query parameterization. Continue using placeholders and bound parameters for runtime data whenever possible.
Limitations
The default value quoting is correct for MySQL-like databases running in the default SQL mode over an ASCII-compatible, single-byte-safe connection charset (for example utf8mb4 or latin1). It is NOT safe for untrusted input in two situations:
- NO_BACKSLASH_ESCAPES SQL mode: backslash is not an escape character, so the backslash escaping applied here (\n, \, \Z, …) is interpreted literally and silently corrupts the stored value.
- Non-self-synchronizing multibyte charsets (GBK, Big5, SJIS, …): byte-wise escaping is the classic vector for escape-function SQL injection because a lead byte can consume the escaping backslash.
Use bound parameters for untrusted data, and supply WithQuoteValueFunc /
WithQuoteIDFunc to match the exact rules of another dialect or charset.
Usage
u, err := sqlutil.New()
if err != nil {
return err
}
col := u.QuoteID("users.email") // `users`.`email`
val := u.QuoteValue("o'reilly") // 'o''reilly'
query := "SELECT " + col + " FROM " + u.QuoteID("users") + " WHERE " + col + " = " + val
_ = query
When To Use
- A table or column name comes from configuration and cannot be a bind parameter.
- You are generating DDL or a migration statement.
Example
q, err := sqlutil.New()
if err != nil {
log.Fatal(err)
}
o := q.QuoteID("7919")
fmt.Println(o)
// Output:
// `7919`
Full source is in example_sqlutil_test.go. More runnable examples are on pkg.go.dev.
Dependencies
This package reaches no external module: it uses only the Go standard library.