This package defines the Abstract Syntax Tree (AST) nodes used by sqlc to represent SQL statements across all supported databases (PostgreSQL, MySQL, SQLite).
All AST nodes implement the Node interface with:
Pos() int- returns the source positionFormat(buf *TrackedBuffer)- formats the node back to SQL
The TrackedBuffer type (pg_query.go) handles SQL formatting with dialect-specific behavior:
astFormat(node Node)- formats any AST nodejoin(list *List, sep string)- joins list items with separatorWriteString(s string)- writes raw SQLQuoteIdent(name string)- quotes identifiers (dialect-specific)TypeName(ns, name string)- formats type names (dialect-specific)
Dialect-specific formatting is handled via the Dialect interface:
type Dialect interface {
QuoteIdent(string) string
TypeName(ns, name string) string
Param(int) string // $1 for PostgreSQL, ? for MySQL
NamedParam(string) string // @name for PostgreSQL, :name for SQLite
Cast(string) string
}When adding a new AST node type:
- Create the node file (e.g.,
variable_expr.go):
package ast
type VariableExpr struct {
Name string
Location int
}
func (n *VariableExpr) Pos() int {
return n.Location
}
func (n *VariableExpr) Format(buf *TrackedBuffer) {
if n == nil {
return
}
buf.WriteString("@")
buf.WriteString(n.Name)
}- Add to
astutils/walk.go- Add a case in the Walk function:
case *ast.VariableExpr:
// Leaf node - no children to traverse- Add to
astutils/rewrite.go- Add a case in the Apply function:
case *ast.VariableExpr:
// Leaf node - no children to traverse- Update the parser/converter - In the relevant engine (e.g.,
dolphin/convert.gofor MySQL)
set(node Node) bool- returns true if node is non-nil and not an empty Listitems(list *List) bool- returns true if list has itemstodo(node) Node- placeholder for unimplemented conversions (returns nil)
SelectStmt- SELECT queries with FromClause, WhereClause, etc.InsertStmt- INSERT with Relation, Cols, SelectStmt, OnConflictClauseUpdateStmt- UPDATE with Relations, TargetList, WhereClauseDeleteStmt- DELETE with Relations, FromClause (for JOINs), Targets
A_Expr- General expression with operator (e.g.,a + b,@param)ColumnRef- Column reference with Fields listFuncCall- Function call with Func, Args, aggregation optionsTypeCast- Type cast with Arg and TypeNameParenExpr- Parenthesized expressionVariableExpr- MySQL user variable (e.g.,@user_id)
RangeVar- Table reference with schema, name, aliasJoinExpr- JOIN with Larg, Rarg, Jointype, Quals/UsingClause
VariableExpr- User variables (@var), distinct from sqlc's@paramsyntaxIntervalExpr- INTERVAL expressionsOnDuplicateKeyUpdate- MySQL's ON DUPLICATE KEY UPDATE clauseParenExpr- Explicit parentheses (TiDB parser wraps expressions)
- MySQL user variables (
@user_id) useVariableExpr- preserved as-is in output - sqlc named parameters (
@param) useA_Exprwith@operator - replaced with? - The
named.IsParamSign()function checks forA_Exprwith@operator
TypeName.Typmodsholds type modifiers likevarchar(255)- For MySQL, only populate Typmods for types where length is user-specified:
- VARCHAR, CHAR, VARBINARY, BINARY - need length
- DATETIME, TIMESTAMP, DATE - internal flen should NOT be output