sqlclass

package
v0.5.2 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package sqlclass is locksql's first gate: a conservative, dialect-aware lexer and statement classifier. It does not build an AST. It refuses anything it cannot classify with certainty, and it never rewrites SQL.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ForbiddenFunction added in v0.5.0

func ForbiddenFunction(name string) bool

ForbiddenFunction reports whether name (folded) is on the list of functions refused at every tier, by exact name (not by prefix).

func RedactLiterals added in v0.5.0

func RedactLiterals(d Dialect, sql string) string

RedactLiterals returns sql with every string, number and quoted identifier replaced by '<redacted>', for the record of a statement that may carry a secret. Text that does not lex is replaced whole.

func TokenText added in v0.5.0

func TokenText(t Token) string

TokenText is the text of t a refusal may name: a word or a punctuation sign, "" for a literal or a quoted name.

Types

type Class

type Class int

Class is the privilege class of a statement. Its order matches the profile tiers: Read < Write < DDL < Admin.

const (
	Read Class = iota
	Write
	DDL
	Admin
)

Classes, in increasing order of privilege.

func (Class) String

func (c Class) String() string

type Dialect

type Dialect int

Dialect selects the lexing and classification rules.

const (
	MySQL Dialect = iota
	Postgres
	SQLite
)

Dialects. MySQL also covers MariaDB.

func DialectFor

func DialectFor(engine string) (Dialect, error)

DialectFor maps a config engine name ("mariadb", "mysql", "postgres", "sqlite") to its dialect.

func (Dialect) String

func (d Dialect) String() string

type Refusal

type Refusal = refusal.Error

Refusal is the error Classify and Lex return for a refused statement: a code, a reason and, when known, the offset of the token refused in the text checked (the input without its surrounding blanks). Reason never quotes literal values from the statement.

type Statement

type Statement struct {
	Class Class
	// Kind is the lower-cased leading keyword ("select", "show", "describe",
	// "pragma", "insert", "create", "set", ...). SELECT, WITH, VALUES and
	// TABLE reads are "select"; a WITH that modifies data takes the kind of
	// its first data-modifying keyword ("delete", ...).
	Kind string
	// SQL is the statement as it will run: the input without surrounding
	// blanks and without one trailing ';'. It is never otherwise rewritten.
	SQL string
	// Limit is the row count of the top-level LIMIT/FETCH of a READ select,
	// or -1 when the statement has none (SHOW, DESCRIBE, PRAGMA, writes...).
	Limit int
}

Statement is a classified statement, ready for the policy checks.

func Classify

func Classify(d Dialect, sql string, maxRows int) (Statement, error)

Classify lexes and classifies one statement. A READ select must end with a top-level LIMIT (or PostgreSQL FETCH FIRST) of at most maxRows rows; a maxRows of 0 or less only requires the LIMIT. Classify does not know the profile tier: FORBIDDEN constructs are refused whatever the tier. The error, if any, is a *Refusal.

type TokKind

type TokKind int

TokKind is the lexical kind of a token.

const (
	TokWord        TokKind = iota // keyword or unquoted identifier; Text is upper-cased
	TokNumber                     // numeric literal (or a MySQL identifier starting with a digit); Text is upper-cased
	TokString                     // string literal, E” string or $tag$ body; Text is the raw source with quotes
	TokQuotedIdent                // quoted identifier: "x" (PG, SQLite), `x` (MySQL, SQLite), [x] (SQLite); Text is raw
	TokPunct                      // a single punctuation or operator character
)

Token kinds.

type Token

type Token struct {
	Kind  TokKind
	Text  string
	Depth int
	// Pos and End are the byte offsets of the token in the lexed text.
	Pos, End int
}

Token is one lexical unit. Depth is the parenthesis depth: an opening parenthesis carries the depth it opens, a closing one the depth it returns to, so a top-level token has Depth 0.

func Lex

func Lex(d Dialect, sql string) ([]Token, error)

Lex splits sql into tokens using the quoting rules of the dialect. It refuses (with a *Refusal) comments, variables, assignments, bind parameters, backslashes outside PostgreSQL E” strings, unterminated quotes, unbalanced parentheses and control characters other than blanks (\t \n \v \f \r): SQLite stops reading a statement at a NUL, so what runs could differ from what was classified and approved.

func (Token) Name

func (t Token) Name() string

Name returns the identifier a word or quoted identifier names, folded to upper case for comparisons. It returns "" for other kinds.

Jump to

Keyboard shortcuts

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