sqlutil

sqlutil quotes identifiers and string literals when generating SQL query fragments dynamically.

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.QuoteID for quoting identifiers (schema/table/column names).
  • SQLUtil.QuoteValue for 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:

  • WithQuoteIDFunc replaces identifier quoting behavior.
  • WithQuoteValueFunc replaces 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.