sq/libsq/ast/node.go

344 lines
8.4 KiB
Go
Raw Normal View History

2016-10-17 07:14:01 +03:00
package ast
import (
"fmt"
2020-08-06 20:58:47 +03:00
"reflect"
"strings"
2016-10-17 07:14:01 +03:00
"github.com/antlr/antlr4/runtime/Go/antlr/v4"
2016-10-17 07:14:01 +03:00
)
2020-08-06 20:58:47 +03:00
// Node is an AST node.
2016-10-17 07:14:01 +03:00
type Node interface {
2020-08-06 20:58:47 +03:00
// Parent returns the node's parent, which may be nil..
2016-10-17 07:14:01 +03:00
Parent() Node
2020-08-06 20:58:47 +03:00
// SetParent sets the node's parent, returning an error if illegal.
SetParent(n Node) error
// Children returns the node's children (which may be empty).
2016-10-17 07:14:01 +03:00
Children() []Node
2020-08-06 20:58:47 +03:00
// SetChildren sets the node's children, returning an error if illegal.
SetChildren(children []Node) error
// AddChild adds a child node, returning an error if illegal.
AddChild(child Node) error
// Context returns the parse tree context.
2016-10-17 07:14:01 +03:00
Context() antlr.ParseTree
2020-08-06 20:58:47 +03:00
// SetContext sets the parse tree context, returning an error if illegal.
SetContext(ctx antlr.ParseTree) error
// String returns a debug-friendly string representation.
2016-10-17 07:14:01 +03:00
String() string
2020-08-06 20:58:47 +03:00
// Text returns the node's text representation.
2016-10-17 07:14:01 +03:00
Text() string
2020-08-06 20:58:47 +03:00
}
// Tabler is a Node marker interface to indicate that the node can be
// selected from. That is, the node represents a SQL table, view, or
// join table, and can be used like "SELECT * FROM [tabler]".
type Tabler interface {
Node
tabler()
}
// Selector is a Node marker interface for selector node types. A selector node
// models a selector such as ".first_name" or ".actor.last_name".
type Selector interface {
Node
selector()
2020-08-06 20:58:47 +03:00
}
2016-10-17 07:14:01 +03:00
// ResultColumn indicates a column selection expression Node such as a
// column name, or context-appropriate function, e.g. "COUNT(*)".
// See: https://www.sqlite.org/syntax/result-column.html
type ResultColumn interface {
Node
// IsColumn returns true if the expression represents
// a column, e.g. ".first_name" or "actor.first_name".
// This method returns false for functions, e.g. "COUNT(*)".
// REVISIT: We can probably get rid of this?
IsColumn() bool
// String returns a log/debug-friendly representation.
2020-08-06 20:58:47 +03:00
String() string
// Alias returns the column alias, which may be empty.
// For example, given the selector ".first_name:given_name", the
// alias is "given_name".
Alias() string
// Text returns the raw text of the node, e.g. ".actor" or "1*2".
Text() string
2016-10-17 07:14:01 +03:00
}
2020-08-06 20:58:47 +03:00
// baseNode is a base implementation of Node.
type baseNode struct {
2016-10-17 07:14:01 +03:00
parent Node
children []Node
ctx antlr.ParseTree
text string
2016-10-17 07:14:01 +03:00
}
// Parent implements Node.Parent.
2020-08-06 20:58:47 +03:00
func (bn *baseNode) Parent() Node {
2016-10-17 07:14:01 +03:00
return bn.parent
}
// SetParent implements Node.SetParent.
2020-08-06 20:58:47 +03:00
func (bn *baseNode) SetParent(parent Node) error {
2016-10-17 07:14:01 +03:00
bn.parent = parent
return nil
}
// Children implements Node.Children.
2020-08-06 20:58:47 +03:00
func (bn *baseNode) Children() []Node {
2016-10-17 07:14:01 +03:00
return bn.children
}
// AddChild always returns an error. Node implementations should
// implement a type-specific method that only accepts a child of
// an appropriate type for that node.
2020-08-06 20:58:47 +03:00
func (bn *baseNode) AddChild(child Node) error {
return errorf(msgNodeNoAddChild, bn, child)
2016-10-17 07:14:01 +03:00
}
2020-08-06 20:58:47 +03:00
func (bn *baseNode) addChild(child Node) {
2016-10-17 07:14:01 +03:00
bn.children = append(bn.children, child)
}
2020-08-06 20:58:47 +03:00
func (bn *baseNode) SetChildren(children []Node) error {
return errorf(msgNodeNoAddChildren, bn, len(children))
2016-10-17 07:14:01 +03:00
}
2020-08-06 20:58:47 +03:00
func (bn *baseNode) setChildren(children []Node) {
2016-10-17 07:14:01 +03:00
bn.children = children
}
2020-08-06 20:58:47 +03:00
func (bn *baseNode) Text() string {
2016-10-17 07:14:01 +03:00
if bn.ctx == nil {
return ""
}
return bn.ctx.GetText()
}
2020-08-06 20:58:47 +03:00
func (bn *baseNode) Context() antlr.ParseTree {
2016-10-17 07:14:01 +03:00
return bn.ctx
}
2020-08-06 20:58:47 +03:00
func (bn *baseNode) SetContext(ctx antlr.ParseTree) error {
2016-10-17 07:14:01 +03:00
bn.ctx = ctx
return nil
}
// nodeString returns a default value suitable for use by Node.String().
func nodeString(n Node) string {
return fmt.Sprintf("%T: %s", n, n.Text())
}
// nodeReplace replaces old with new. That is, nu becomes a child
2020-08-06 20:58:47 +03:00
// of old's parent.
func nodeReplace(old, nu Node) error {
2016-10-17 07:14:01 +03:00
err := nu.SetContext(old.Context())
if err != nil {
return err
}
parent := old.Parent()
index := nodeChildIndex(parent, old)
2016-10-17 07:14:01 +03:00
if index < 0 {
return errorf("parent %T(%q) does not appear to have child %T(%q)", parent, parent.Text(), old, old.Text())
}
siblings := parent.Children()
siblings[index] = nu
return parent.SetChildren(siblings)
}
// nodesAreOnlyOfType returns an error if the type of any non-nil element
// of nodes is not contained in types.
func nodesAreOnlyOfType(nodes []Node, types ...reflect.Type) error {
m := map[reflect.Type]struct{}{}
typeNames := make([]string, 0, len(types))
for _, typ := range types {
m[typ] = struct{}{}
typeNames = append(typeNames, typ.Name())
}
for i, node := range nodes {
if node == nil {
continue
}
if _, ok := m[reflect.TypeOf(node)]; !ok {
return errorf("node[%d] {%s} is not an allowed type in [%s]", i, node, strings.Join(typeNames, ", "))
}
}
return nil
}
// nodeChildIndex returns the index of child in parent's children, or -1.
func nodeChildIndex(parent, child Node) int {
2020-08-06 20:58:47 +03:00
for i, node := range parent.Children() {
if node == child {
return i
2016-10-17 07:14:01 +03:00
}
}
return -1
}
// nodeFirstChild returns the first child of parent, or nil.
func nodeFirstChild(parent Node) Node { //nolint:unused
if parent == nil {
return nil
}
children := parent.Children()
if len(children) == 0 {
return nil
}
return children[0]
}
// nodeFirstChild returns the last child of parent, or nil.
func nodeLastChild(parent Node) Node {
if parent == nil {
return nil
}
children := parent.Children()
if len(children) == 0 {
return nil
}
return children[len(children)-1]
2016-10-17 07:14:01 +03:00
}
2020-08-06 20:58:47 +03:00
// nodesWithType returns a new slice containing each member of nodes that is
// of the specified type.
func nodesWithType(nodes []Node, typ reflect.Type) []Node {
s := make([]Node, 0)
for _, n := range nodes {
if reflect.TypeOf(n) == typ {
s = append(s, n)
}
}
return s
}
// ExprNode models a SLQ expression such as ".uid > 4".
type ExprNode struct {
2020-08-06 20:58:47 +03:00
baseNode
}
// AddChild implements Node.
func (n *ExprNode) AddChild(child Node) error {
n.addChild(child)
return child.SetParent(n)
}
// SetChildren implements Node.
func (n *ExprNode) SetChildren(children []Node) error {
n.setChildren(children)
return nil
2020-08-06 20:58:47 +03:00
}
// String returns a log/debug-friendly representation.
func (n *ExprNode) String() string {
text := nodeString(n)
2020-08-06 20:58:47 +03:00
return text
}
// OperatorNode is a leaf node in an expression representing an operator such as ">" or "==".
type OperatorNode struct {
2020-08-06 20:58:47 +03:00
baseNode
}
// String returns a log/debug-friendly representation.
func (n *OperatorNode) String() string {
return nodeString(n)
2020-08-06 20:58:47 +03:00
}
// LiteralNode is a leaf node representing a literal such as a number or a string.
type LiteralNode struct {
2020-08-06 20:58:47 +03:00
baseNode
}
// String returns a log/debug-friendly representation.
func (n *LiteralNode) String() string {
return nodeString(n)
2020-08-06 20:58:47 +03:00
}
// WhereNode represents a SQL WHERE clause, i.e. a filter on the SELECT.
type WhereNode struct {
2020-08-06 20:58:47 +03:00
baseNode
}
// String returns a log/debug-friendly representation.
func (n *WhereNode) String() string {
return nodeString(n)
2020-08-06 20:58:47 +03:00
}
// Expr returns the expression that constitutes the SetWhere clause, or nil if no expression.
func (n *WhereNode) Expr() *ExprNode {
if len(n.children) == 0 {
2020-08-06 20:58:47 +03:00
return nil
}
return n.children[0].(*ExprNode)
2020-08-06 20:58:47 +03:00
}
// AddChild implements Node.
func (n *WhereNode) AddChild(node Node) error {
expr, ok := node.(*ExprNode)
2020-08-06 20:58:47 +03:00
if !ok {
return errorf("WHERE child must be %T, but got: %T", expr, node)
2020-08-06 20:58:47 +03:00
}
if len(n.children) > 0 {
2020-08-06 20:58:47 +03:00
return errorf("WHERE has max 1 child: failed to add: %T", node)
}
n.addChild(expr)
2020-08-06 20:58:47 +03:00
return nil
}
// isOperator returns true if the supplied string is a recognized operator, e.g. "!=" or ">".
func isOperator(text string) bool {
switch text {
case "-", "+", "~", "!", "||", "*", "/", "%", "<<", ">>", "&", "<", "<=", ">", ">=", "==", "!=", "&&":
return true
default:
return false
}
}
// Cached results from reflect.TypeOf for node types.
var (
typeAST = reflect.TypeOf((*AST)(nil))
typeSegmentNode = reflect.TypeOf((*SegmentNode)(nil))
typeHandleNode = reflect.TypeOf((*HandleNode)(nil))
typeSelectorNode = reflect.TypeOf((*SelectorNode)(nil))
typeTblSelectorNode = reflect.TypeOf((*TblSelectorNode)(nil))
typeTblColSelectorNode = reflect.TypeOf((*TblColSelectorNode)(nil))
typeColSelectorNode = reflect.TypeOf((*ColSelectorNode)(nil))
typeJoinNode = reflect.TypeOf((*JoinNode)(nil))
typeRowRangeNode = reflect.TypeOf((*RowRangeNode)(nil))
typeOrderByNode = reflect.TypeOf((*OrderByNode)(nil))
typeGroupByNode = reflect.TypeOf((*GroupByNode)(nil))
typeExprNode = reflect.TypeOf((*ExprNode)(nil))
typeFuncNode = reflect.TypeOf((*FuncNode)(nil))
typeUniqueNode = reflect.TypeOf((*UniqueNode)(nil))
2020-08-06 20:58:47 +03:00
)