sqlast

package
v0.1.3 Latest Latest
Warning

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

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

Documentation

Overview

Package sqlast parses the read statements an agent may run (SELECT, WITH ... SELECT and EXPLAIN SELECT) into a syntax tree, per dialect, and analyses it: it resolves every column to the base columns it comes from (through aliases, functions, expressions, subqueries, CTEs, set operations and joins), checks functions against an allowlist and decides how PII columns may be used.

The grammar is a deliberately small subset of SQL. Anything outside it is refused: a statement the parser cannot read with certainty never runs.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func HasPlaceholder added in v0.1.2

func HasPlaceholder(d sqlclass.Dialect, sql string) bool

HasPlaceholder reports whether sql holds a placeholder: a plain string literal '${...}', or "${" in any other string form. A statement that cannot be lexed is reported as holding one.

func StringValue added in v0.1.2

func StringValue(d sqlclass.Dialect, text string) (string, bool)

StringValue returns the value of a string-literal token ('...', "..." in MySQL, E'...', N'...', $tag$...$tag$), or false for any other text. Unlike the substitution path it does not refuse backslashes: it serves warnings.

Types

type Analysis

type Analysis struct {
	Outputs []Output
	// Relations are the base relations read, "db.table".
	Relations []string
	// Uses are the PII columns the statement touches.
	Uses []Use
	// KChecks must all pass (k rows or more) before the statement runs.
	KChecks []KCheck
	// PIIFilter is set when a PII column is compared with a constant: row
	// estimates must not reach the agent.
	PIIFilter bool
	// LitFilter is set when a PII column is compared for equality with a
	// literal the agent wrote (not a placeholder, not IS NULL), anywhere in
	// the statement. Its results carry no cell references: the agent chose
	// the value behind them, and the rows it selected may be linked to the
	// literal through any join, subquery or set operation.
	LitFilter    bool
	Replacements []Replacement
	// Values are the placeholders compared with PII columns.
	Values []ValueUse
	// KeyFilters are the non-PII columns compared with = and a literal in
	// WHERE (the console checks whether one is a unique key).
	KeyFilters []Source
}

Analysis is what Analyze finds.

func Analyze

func Analyze(st *Statement, env Env) (*Analysis, error)

Analyze resolves the provenance of every output column of st, checks the functions against the allowlist and, when env.Masking is set, applies the PII usage rules. Errors are *sqlclass.Refusal values.

func (*Analysis) Masked

func (a *Analysis) Masked() bool

Masked reports whether some output is masked.

func (*Analysis) RunSQL

func (a *Analysis) RunSQL(sql string) string

RunSQL is the statement with its replacements applied.

type Between

type Between struct {
	X, Lo, Hi Expr
	Not       bool
	Sp        Span
}

Between is x [NOT] BETWEEN lo AND hi.

func (*Between) Span

func (e *Between) Span() Span

type Binary

type Binary struct {
	Op   string
	L, R Expr
	Sp   Span
}

Binary is a binary operator.

func (*Binary) Span

func (e *Binary) Span() Span

type Body

type Body interface {
	// contains filtered or unexported methods
}

Body is a *Select, a *SetOp or a parenthesised *Query.

type CTE

type CTE struct {
	Name    string
	Columns []string
	Query   *Query
	Sp      Span
}

CTE is one common table expression.

type Case

type Case struct {
	Operand Expr
	Whens   []When
	Else    Expr
	Sp      Span
}

Case is a CASE expression.

func (*Case) Span

func (e *Case) Span() Span

type Cast

type Cast struct {
	X    Expr
	Type string
	Sp   Span
}

Cast is CAST(x AS type), x::type or CONVERT(x, type).

func (*Cast) Span

func (e *Cast) Span() Span

type Catalog

type Catalog interface {
	// Lookup returns the relations a table name (folded parts, as written)
	// may denote: none when it is unknown, several when it is ambiguous.
	Lookup(parts []string) ([]Table, error)
}

Catalog resolves table names.

type Collate

type Collate struct {
	X    Expr
	Name string
	Sp   Span
}

Collate is x COLLATE name.

func (*Collate) Span

func (e *Collate) Span() Span

type ColumnRef

type ColumnRef struct {
	Parts []string
	Sp    Span
}

ColumnRef names a column: [col], [rel, col] or [db, rel, col] (folded).

func (*ColumnRef) Span

func (e *ColumnRef) Span() Span

type Derived

type Derived struct {
	Lateral    bool
	Query      *Query
	Alias      string
	ColAliases []string
	Sp         Span
}

Derived is a subquery in FROM.

type Env

type Env struct {
	Catalog Catalog
	// Rule returns the mask mode of a base column, and whether a rule
	// covers it.
	Rule func(Source) (mode string, masked bool)
	// Masking is false for an unmask plan: provenance and functions are
	// still checked, but not the PII usage rules.
	Masking bool
	// Value resolves a placeholder: the value the human typed for a name, or
	// the value of a referenced cell. ok is false when the console does not
	// know it (yet, for a typed name).
	Value func(kind ValueKind, name string) (value string, ok bool)
}

Env is what Analyze needs besides the statement.

type Exists

type Exists struct {
	Query *Query
	Not   bool
	Sp    Span
}

Exists is [NOT] EXISTS (subquery).

func (*Exists) Span

func (e *Exists) Span() Span

type Expr

type Expr interface{ Span() Span }

Expr is an expression node.

type FuncCall

type FuncCall struct {
	// Name is the folded, dot-joined function name.
	Name     string
	Args     []Expr
	Star     bool // COUNT(*)
	Distinct bool
	// OrderBy is an ordered-set argument: string_agg(x, ',' ORDER BY y),
	// GROUP_CONCAT(x ORDER BY y).
	OrderBy []*OrderItem
	Filter  Expr
	Over    *Window
	Sp      Span
}

FuncCall is a function call, aggregate or window function.

func (*FuncCall) Span

func (e *FuncCall) Span() Span

type In

type In struct {
	X     Expr
	List  []Expr
	Query *Query
	Not   bool
	Sp    Span
}

In is x [NOT] IN (list) or x [NOT] IN (subquery).

func (*In) Span

func (e *In) Span() Span

type IsTest

type IsTest struct {
	X    Expr
	Not  bool
	What string // NULL, TRUE, FALSE, UNKNOWN, DISTINCT
	Y    Expr   // DISTINCT FROM y
	Sp   Span
}

IsTest is x IS [NOT] NULL|TRUE|FALSE|UNKNOWN or IS [NOT] DISTINCT FROM y.

func (*IsTest) Span

func (e *IsTest) Span() Span

type Join

type Join struct {
	Kind        string // INNER, LEFT, RIGHT, FULL, CROSS
	Natural     bool
	Left, Right TableExpr
	On          Expr
	Using       []string
	Sp          Span
}

Join joins two table expressions.

type KCheck

type KCheck struct {
	SQL string
	// Grouped checks the smallest group (its result may be NULL when no
	// group remains); otherwise it counts the rows.
	Grouped bool
}

KCheck is a row-count query the console runs before the statement, to check that a PII filter, grouping or aggregate covers at least k rows.

type Kind

type Kind int

Kind says how a value derives from its sources.

const (
	// KindConst involves no column.
	KindConst Kind = iota
	// KindCount is a row count (COUNT): it reveals no value of its sources.
	KindCount
	// KindIdentity is a value of one of its sources: a plain reference,
	// through aliases, subqueries, CTEs and set operations, or MIN/MAX.
	KindIdentity
	// KindAggregate is another aggregate of its sources (SUM, AVG, ...).
	KindAggregate
	// KindExpr is any other expression of its sources.
	KindExpr
)

Kinds, from the least to the most transformed.

func (Kind) String

func (k Kind) String() string

String describes a Kind.

type Like

type Like struct {
	Op         string
	X, Pattern Expr
	Escape     Expr
	Not        bool
	Sp         Span
}

Like is a pattern match: LIKE, ILIKE, GLOB, REGEXP, RLIKE.

func (*Like) Span

func (e *Like) Span() Span

type Limit

type Limit struct {
	Count, Offset int64
}

Limit is a LIMIT/OFFSET or FETCH FIRST clause; both are literal integers.

type LitKind

type LitKind int

LitKind is the kind of a literal.

const (
	LitString LitKind = iota
	LitNumber
	LitNull
	LitBool
	LitTyped    // DATE '...', TIMESTAMP '...', X'..'
	LitInterval // INTERVAL '1 day', INTERVAL 1 DAY
	LitNiladic  // CURRENT_DATE, CURRENT_TIMESTAMP, ...
)

Literal kinds.

type Literal

type Literal struct {
	Kind LitKind
	// Text is the source text of the literal (with its quotes).
	Text string
	Sp   Span
}

Literal is a constant.

func (*Literal) Span

func (e *Literal) Span() Span

type OrderItem

type OrderItem struct {
	Expr Expr
	Desc bool
}

OrderItem is one ORDER BY entry.

type Output

type Output struct {
	// Label is the column label the engine must report (an alias or a
	// plain column name), "" when the engine chooses it.
	Label string
	Prov  Prov
	// Mask is the mask mode of the column, "" for none.
	Mask string
}

Output is one result column.

type Paren

type Paren struct {
	X  Expr
	Sp Span
}

Paren is a parenthesised expression.

func (*Paren) Span

func (e *Paren) Span() Span

type Prov

type Prov struct {
	Sources []Source
	Kind    Kind
	// Sensitive is set when a source is under a mask rule and the value
	// reveals source values (Kind Identity, Aggregate or Expr).
	Sensitive bool
	// Modes are the mask modes of the sensitive sources.
	Modes []string
	// Lit is set when some values may be literals of the statement (a
	// UNION of a column and a constant, for instance).
	Lit bool
}

Prov is the provenance of a value.

type Query

type Query struct {
	With    *With
	Body    Body
	OrderBy []*OrderItem
	Limit   *Limit
	Sp      Span
}

Query is a full query expression: an optional WITH, a body and the ORDER BY and LIMIT that apply to the whole body.

type Replacement

type Replacement struct {
	Span Span
	Text string
}

Replacement substitutes a token literal with the value it stands for in the statement that runs.

type Select

type Select struct {
	Distinct   bool
	DistinctOn []Expr
	Items      []*SelectItem
	From       []TableExpr
	Where      Expr
	GroupBy    []Expr
	Having     Expr
	Sp         Span
	// Spans of the FROM list, the WHERE condition, the GROUP BY list and
	// the HAVING condition (without their keywords); zero when absent.
	FromSp, WhereSp, GroupSp, HavingSp Span
}

Select is one SELECT core.

type SelectItem

type SelectItem struct {
	Star      bool
	Qualifier []string
	Expr      Expr
	Alias     string
	Sp        Span
}

SelectItem is one select-list entry: an expression with an optional alias, or a star (optionally qualified: t.*).

type SetOp

type SetOp struct {
	Op          string
	All         bool
	Left, Right Body
	Sp          Span
}

SetOp is UNION, INTERSECT or EXCEPT.

type Source

type Source struct {
	DB, Table, Column string
	// View marks a column of a view (or of a relation whose base columns
	// are unknown): rules match it by column name.
	View bool
}

Source is a base column, as the catalog names it. For PostgreSQL DB is the schema.

func (Source) String

func (s Source) String() string

type Span

type Span struct{ Pos, End int }

Span is a byte range [Pos, End) of the statement text.

type Statement

type Statement struct {
	// Explain is set for EXPLAIN SELECT: the console runs the EXPLAIN
	// itself, without ANALYZE.
	Explain bool
	Query   *Query
	// SQL is the statement text the spans refer to.
	SQL     string
	Dialect sqlclass.Dialect
}

Statement is one parsed read statement.

func Parse

func Parse(d sqlclass.Dialect, sql string) (*Statement, error)

Parse parses one read statement: SELECT, WITH ... SELECT or EXPLAIN followed by one of them. Anything else, or any construct outside the supported grammar, is refused with a *sqlclass.Refusal. A trailing ';' and surrounding blanks are dropped, as sqlclass.Classify does.

type Subquery

type Subquery struct {
	Query *Query
	Sp    Span
}

Subquery is a scalar subquery.

func (*Subquery) Span

func (e *Subquery) Span() Span

type Table

type Table struct {
	DB, Name string
	Columns  []string
	View     bool
}

Table is one relation of the catalog.

type TableExpr

type TableExpr interface {
	// contains filtered or unexported methods
}

TableExpr is a *TableName, a *Derived or a *Join.

type TableName

type TableName struct {
	// Parts are the folded name parts: [table], [db, table] or
	// [catalog, schema, table].
	Parts      []string
	Alias      string
	ColAliases []string
	Sp         Span
}

TableName is a named relation: a table, a view or a CTE.

type Tuple

type Tuple struct {
	Items []Expr
	Sp    Span
}

Tuple is a parenthesised list of two or more expressions.

func (*Tuple) Span

func (e *Tuple) Span() Span

type Unary

type Unary struct {
	Op string
	X  Expr
	Sp Span
}

Unary is a prefix operator (NOT, -, +, ~).

func (*Unary) Span

func (e *Unary) Span() Span

type Use

type Use struct {
	Source Source
	Clause string
}

Use is a PII column the statement touches, and where.

type ValueKind added in v0.1.2

type ValueKind int

ValueKind tells a value typed by the human from a cell reference.

const (
	// ValueTyped is '${name}': the human types the value in the console.
	ValueTyped ValueKind = iota + 1
	// ValueRef is '${rN.R.C}': the value of a masked cell the console
	// returned (result N, row R, column C).
	ValueRef
)

func ParsePlaceholder added in v0.1.2

func ParsePlaceholder(body string) (kind ValueKind, name string, isPlaceholder, ok bool)

ParsePlaceholder reads the body of a string literal (without quotes). isPlaceholder reports the "${...}" shape; ok whether the name is valid.

type ValueUse added in v0.1.2

type ValueUse struct {
	Kind ValueKind
	// Name is "email" for '${email}', "r3.1.2" for '${r3.1.2}'.
	Name string
	// Column is the PII column the placeholder is compared with.
	Column Source
	// InList is set inside IN (...).
	InList bool
	Span   Span
}

ValueUse is a placeholder literal compared with a PII column.

type When

type When struct{ Cond, Result Expr }

When is one WHEN ... THEN ... branch.

type Window

type Window struct {
	PartitionBy []Expr
	OrderBy     []*OrderItem
}

Window is an OVER clause.

type With

type With struct {
	Recursive bool
	CTEs      []*CTE
	Sp        Span
}

With is a WITH clause.

Jump to

Keyboard shortcuts

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