Documentation
¶
Overview ¶
Parser for rewriting fragments of foreign code embedded in SQL queries, such as parameter placeholders: `$1` or `:ident`, or code encased in delimiters: `()` `[]` `{}`. It supports the following SQL features:
• ” : single quotes.
• "" : double quotes.
• “ : grave quotes (non-standard).
• -- : line comments.
• /* : block comments.
• :: : Postgres-style cast operator (non-standard).
In addition, it supports the following:
• () : content in parens.
• [] : content in brackets.
• {} : content in braces.
• $1 $2 ... : ordinal parameter placeholders.
• :identifier : named parameter placeholders.
Supporting SQL quotes and comments allows us to correctly ignore text inside special delimiters that happens to be part of a string, quoted identifier, or comment.
Usage ¶
Oversimplified example:
nodes, err := Parse(`select * from some_table where :ident::uuid = id`)
panic(err)
err := TraverseDeep(nodes, func(ptr *Node) error {
name, ok := (*ptr).(NodeNamedParam)
if ok {
// Guaranteed to break the query.
*ptr = name + `_renamed`
}
return nil
})
panic(err)
sql := nodes.String()
The AST now looks like this:
nodes := Nodes{
NodeText(`select * from some_table where `),
NodeNamedParam(`ident_renamed`),
NodeDoubleColon{},
NodeText(`uuid = id`),
}
Index ¶
- func Traverse(nodes Nodes, fun func(*Node) error) error
- func TraverseDeep(nodes Nodes, fun func(*Node) error) error
- type Error
- type Node
- type NodeBraces
- type NodeBrackets
- type NodeCommentBlock
- type NodeCommentLine
- type NodeDoubleColon
- type NodeNamedParam
- type NodeOrdinalParam
- type NodeParens
- type NodeQuoteDouble
- type NodeQuoteGrave
- type NodeQuoteSingle
- type NodeText
- type Nodes
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Error ¶
type Error struct {
Cause error
// contains filtered or unexported fields
}
Parsing error. Includes the parser state corresponding to the place where the error had occurred. The parser state should be used for detailed error printing (but isn't yet).
type Node ¶
Any AST node.
type NodeBrackets ¶
type NodeBrackets []Node
Nodes enclosed in brackets: [].
func (NodeBrackets) String ¶
func (self NodeBrackets) String() string
Implement the `Node` interface.
type NodeCommentBlock ¶
type NodeCommentBlock string
Content of a block comment: /* */.
func (NodeCommentBlock) String ¶
func (self NodeCommentBlock) String() string
Implement the `Node` interface.
type NodeCommentLine ¶
type NodeCommentLine string
Content of a line comment: --, including the newline.
func (NodeCommentLine) String ¶
func (self NodeCommentLine) String() string
Implement the `Node` interface.
type NodeDoubleColon ¶
type NodeDoubleColon struct{}
Postgres type cast operator: ::.
func (NodeDoubleColon) String ¶
func (self NodeDoubleColon) String() string
Implement the `Node` interface.
type NodeNamedParam ¶
type NodeNamedParam string
Named parameter preceded by colon: :identifier.
func (NodeNamedParam) String ¶
func (self NodeNamedParam) String() string
Implement the `Node` interface.
type NodeOrdinalParam ¶
type NodeOrdinalParam uint
Postgres-style ordinal parameter placeholder: $1, $2, $3, ...
func (NodeOrdinalParam) String ¶
func (self NodeOrdinalParam) String() string
Implement the `Node` interface.
type NodeQuoteDouble ¶
type NodeQuoteDouble string
Text inside double quotes: "". Escape sequences are not supported yet.
func (NodeQuoteDouble) String ¶
func (self NodeQuoteDouble) String() string
Implement the `Node` interface.
type NodeQuoteGrave ¶
type NodeQuoteGrave string
Text inside grave quotes: “. Escape sequences are not supported yet.
func (NodeQuoteGrave) String ¶
func (self NodeQuoteGrave) String() string
Implement the `Node` interface.
type NodeQuoteSingle ¶
type NodeQuoteSingle string
Text inside single quotes: ”. Escape sequences are not supported yet.
func (NodeQuoteSingle) String ¶
func (self NodeQuoteSingle) String() string
Implement the `Node` interface.
type Nodes ¶
type Nodes []Node
Arbitrary sequence of AST nodes. This is the main AST type, used by `Parse()`, `Traverse()`, and some other functions.
func CopyDeep ¶
Makes a deep copy of the input AST. Useful when you plan to mutate one but keep the other.
func Parse ¶
Parses a query and returns the AST. For the AST structure, see `Node` and the various node types.
Example:
ast, err := Parse(`select * from some_table where id = :ident`)
panic(err)
// Non-recursive example for simplicity.
for i, node := range ast {
switch node.(type) {
case NodeNamedParam:
ast[i] = NodeOrdinalParam(1)
}
}
sql := ast.String()